Misc HW & UI patches queue

- Allow loading safely ROMs larger than 4GiB (Gregor)
 - Convert vt82c686 IRQ as named 'intr' (Bernhard)
 - Clarify QDev GPIO API (Peter)
 - Drop unused load_image_gzipped function (Ani)
 - Make TCGCPUOps::cpu_exec_interrupt handler mandatory (Peter)
 - Factor cpu_pause() out (Nicholas)
 - Remove transfer size check from ESP DMA DATA IN / OUT transfers (Mark)
 - Add accelerated cursor composition to Cocoa UI (Akihiko)
 - Fix '-vga help' CLI (Marc-André)
 - Fix displayed errno in ram_block_add (Zhenzhong)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmaWto0ACgkQ4+MsLN6t
 wN54fBAAwfhSQ9PKTYNlnsmJteXAsPCUg8KZwRblkAZs1z/xJX/sFKJF3PZ8fn4r
 Ty+Fiu4Sylfv19mTc/8Bc8pKfHn9zwY7Kb/H5kHjEuFwEZolODHXO8znRV621iZq
 PAeI64dVo5yIgqlAnf6xPSITwe2f75IS0ivIIKYwFsPqeGMUl6dvh/5xqoxis/hQ
 j/1hFLe+jX4whIcOFcqbR3oV3CZy+nMBLJH1/OtvKJ5aC8vFxt5xsKM0xkG94Pmx
 iYhVx4yjULRSSLMaRowqHqEtPB0pmYyuxz0CwjlcI8PU+gUa+dsZLOomD8YenmJR
 FQubQJOKkqlvQ8j7+2okwQs3NDW1TzwsYnvJKB3+EE+DD3Wq/ny5D0eMcnn5NW1Z
 7rO624XhkvLsJlTJzVvuzpulmC+UFb/6S8CyStGPDxWCGrU3WqdZeoqbbhmXzacU
 ck17Cs2Ma4k0OIRYgAVdnwq96cuQCFNNzNq/iakcJs5Lsaa6Cai/YByKf1tBaGRm
 d/mJgN7WAJrOSpiRhNuNlay4O+hX0rn+wLwecbKW9sbKuoo9eHjzi8YAQuw/TVYr
 oMF/McqtWFCUyVt0eHtA3C+1dSW4+qQTDQSvabbXx54otRSEnMSEubgYFsdu3hF4
 P0mZyxPg4nPxy3uoz9hVQ63F45quaXX/B2fwvoYSBl58xuyxY6M=
 =rOg6
 -----END PGP SIGNATURE-----

Merge tag 'hw-misc-20240716' of https://github.com/philmd/qemu into staging

Misc HW & UI patches queue

- Allow loading safely ROMs larger than 4GiB (Gregor)
- Convert vt82c686 IRQ as named 'intr' (Bernhard)
- Clarify QDev GPIO API (Peter)
- Drop unused load_image_gzipped function (Ani)
- Make TCGCPUOps::cpu_exec_interrupt handler mandatory (Peter)
- Factor cpu_pause() out (Nicholas)
- Remove transfer size check from ESP DMA DATA IN / OUT transfers (Mark)
- Add accelerated cursor composition to Cocoa UI (Akihiko)
- Fix '-vga help' CLI (Marc-André)
- Fix displayed errno in ram_block_add (Zhenzhong)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmaWto0ACgkQ4+MsLN6t
# wN54fBAAwfhSQ9PKTYNlnsmJteXAsPCUg8KZwRblkAZs1z/xJX/sFKJF3PZ8fn4r
# Ty+Fiu4Sylfv19mTc/8Bc8pKfHn9zwY7Kb/H5kHjEuFwEZolODHXO8znRV621iZq
# PAeI64dVo5yIgqlAnf6xPSITwe2f75IS0ivIIKYwFsPqeGMUl6dvh/5xqoxis/hQ
# j/1hFLe+jX4whIcOFcqbR3oV3CZy+nMBLJH1/OtvKJ5aC8vFxt5xsKM0xkG94Pmx
# iYhVx4yjULRSSLMaRowqHqEtPB0pmYyuxz0CwjlcI8PU+gUa+dsZLOomD8YenmJR
# FQubQJOKkqlvQ8j7+2okwQs3NDW1TzwsYnvJKB3+EE+DD3Wq/ny5D0eMcnn5NW1Z
# 7rO624XhkvLsJlTJzVvuzpulmC+UFb/6S8CyStGPDxWCGrU3WqdZeoqbbhmXzacU
# ck17Cs2Ma4k0OIRYgAVdnwq96cuQCFNNzNq/iakcJs5Lsaa6Cai/YByKf1tBaGRm
# d/mJgN7WAJrOSpiRhNuNlay4O+hX0rn+wLwecbKW9sbKuoo9eHjzi8YAQuw/TVYr
# oMF/McqtWFCUyVt0eHtA3C+1dSW4+qQTDQSvabbXx54otRSEnMSEubgYFsdu3hF4
# P0mZyxPg4nPxy3uoz9hVQ63F45quaXX/B2fwvoYSBl58xuyxY6M=
# =rOg6
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 17 Jul 2024 04:06:05 AM AEST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]

* tag 'hw-misc-20240716' of https://github.com/philmd/qemu:
  system/physmem: use return value of ram_block_discard_require() as errno
  vl: fix "type is NULL" in -vga help
  ui/console: Remove dpy_cursor_define_supported()
  ui/cocoa: Add cursor composition
  ui/console: Convert mouse visibility parameter into bool
  ui/cocoa: Release CGColorSpace
  esp: remove transfer size check from DMA DATA IN and DATA OUT transfers
  system/cpus: Add cpu_pause() function
  accel/tcg: Make cpu_exec_interrupt hook mandatory
  loader: remove load_image_gzipped function as its not used anywhere
  include/hw/qdev-core.h: Correct and clarify gpio doc comments
  hw/isa/vt82c686: Turn "intr" irq into a named gpio
  hw/core/loader: allow loading larger ROMs

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-07-17 07:59:12 +10:00
commit a9f2ffa0f5
27 changed files with 200 additions and 119 deletions

View File

@ -857,8 +857,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
else {
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
if (tcg_ops->cpu_exec_interrupt &&
tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
if (tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
if (!tcg_ops->need_replay_interrupt ||
tcg_ops->need_replay_interrupt(interrupt_request)) {
replay_interrupt();
@ -1080,6 +1079,7 @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
/* Check mandatory TCGCPUOps handlers */
#ifndef CONFIG_USER_ONLY
assert(cpu->cc->tcg_ops->cpu_exec_halt);
assert(cpu->cc->tcg_ops->cpu_exec_interrupt);
#endif /* !CONFIG_USER_ONLY */
cpu->cc->tcg_ops->initialize();
tcg_target_initialized = true;

View File

@ -845,19 +845,6 @@ ssize_t load_image_gzipped_buffer(const char *filename, uint64_t max_sz,
return ret;
}
/* Load a gzip-compressed kernel. */
ssize_t load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz)
{
ssize_t bytes;
uint8_t *data;
bytes = load_image_gzipped_buffer(filename, max_sz, &data);
if (bytes != -1) {
rom_add_blob_fixed(filename, data, bytes, addr);
g_free(data);
}
return bytes;
}
/* The PE/COFF MS-DOS stub magic number */
#define EFI_PE_MSDOS_MAGIC "MZ"
@ -1076,8 +1063,8 @@ ssize_t rom_add_file(const char *file, const char *fw_dir,
{
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
Rom *rom;
ssize_t rc;
int fd = -1;
gsize size;
g_autoptr(GError) gerr = NULL;
char devpath[100];
if (as && mr) {
@ -1095,10 +1082,10 @@ ssize_t rom_add_file(const char *file, const char *fw_dir,
rom->path = g_strdup(file);
}
fd = open(rom->path, O_RDONLY | O_BINARY);
if (fd == -1) {
fprintf(stderr, "Could not open option rom '%s': %s\n",
rom->path, strerror(errno));
if (!g_file_get_contents(rom->path, (gchar **) &rom->data,
&size, &gerr)) {
fprintf(stderr, "rom: file %-20s: error %s\n",
rom->name, gerr->message);
goto err;
}
@ -1107,23 +1094,8 @@ ssize_t rom_add_file(const char *file, const char *fw_dir,
rom->fw_file = g_strdup(file);
}
rom->addr = addr;
rom->romsize = lseek(fd, 0, SEEK_END);
if (rom->romsize == -1) {
fprintf(stderr, "rom: file %-20s: get size error: %s\n",
rom->name, strerror(errno));
goto err;
}
rom->romsize = size;
rom->datasize = rom->romsize;
rom->data = g_malloc0(rom->datasize);
lseek(fd, 0, SEEK_SET);
rc = read(fd, rom->data, rom->datasize);
if (rc != rom->datasize) {
fprintf(stderr, "rom: file %-20s: read error: rc=%zd (expected %zd)\n",
rom->name, rc, rom->datasize);
goto err;
}
close(fd);
rom_insert(rom);
if (rom->fw_file && fw_cfg) {
const char *basename;
@ -1160,9 +1132,6 @@ ssize_t rom_add_file(const char *file, const char *fw_dir,
return 0;
err:
if (fd != -1)
close(fd);
rom_free(rom);
return -1;
}

View File

@ -742,7 +742,7 @@ static void ati_mm_write(void *opaque, hwaddr addr,
if (!s->cursor_guest_mode &&
(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(t & BIT(31))) {
dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
s->regs.cur_hv_pos & 0xffff, 1);
s->regs.cur_hv_pos & 0xffff, true);
}
break;
}

View File

@ -307,10 +307,6 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
return 1;
}
if (!dpy_cursor_define_supported(qxl->vga.con)) {
return 0;
}
if (qxl->debug > 1 && cmd->type != QXL_CURSOR_MOVE) {
fprintf(stderr, "%s", __func__);
qxl_log_cmd_cursor(qxl, cmd, ext->group_id);

View File

@ -109,8 +109,7 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
s->cursor.pos.x = cursor->pos.x;
s->cursor.pos.y = cursor->pos.y;
}
dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y,
cursor->resource_id ? 1 : 0);
dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y, cursor->resource_id);
}
struct virtio_gpu_simple_resource *

View File

@ -904,10 +904,8 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
caps |= SVGA_CAP_RECT_FILL;
#endif
#ifdef HW_MOUSE_ACCEL
if (dpy_cursor_define_supported(s->vga.con)) {
caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
SVGA_CAP_CURSOR_BYPASS;
}
caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
SVGA_CAP_CURSOR_BYPASS;
#endif
ret = caps;
break;
@ -1167,7 +1165,7 @@ static void vmsvga_reset(DeviceState *dev)
s->enable = 0;
s->config = 0;
s->svgaid = SVGA_ID;
s->cursor.on = 0;
s->cursor.on = false;
s->redraw_fifo_last = 0;
s->syncing = 0;

View File

@ -719,7 +719,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
ISABus *isa_bus;
int i;
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
qdev_init_gpio_out_named(dev, &s->cpu_intr, "intr", 1);
qdev_init_gpio_in_named(dev, via_isa_pirq, "pirq", PCI_NUM_PINS);
isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),

View File

@ -299,7 +299,7 @@ static void mips_fuloong2e_init(MachineState *machine)
object_resolve_path_component(OBJECT(pci_dev),
"rtc"),
"date");
qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]);
qdev_connect_gpio_out_named(DEVICE(pci_dev), "intr", 0, env->irq[5]);
dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
pci_ide_create_devs(PCI_DEVICE(dev));

View File

@ -153,8 +153,9 @@ static void amigaone_init(MachineState *machine)
object_property_add_alias(OBJECT(machine), "rtc-time",
object_resolve_path_component(via, "rtc"),
"date");
qdev_connect_gpio_out(DEVICE(via), 0,
qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT));
qdev_connect_gpio_out_named(DEVICE(via), "intr", 0,
qdev_get_gpio_in(DEVICE(cpu),
PPC6xx_INPUT_INT));
for (i = 0; i < PCI_NUM_PINS; i++) {
qdev_connect_gpio_out(dev, i, qdev_get_gpio_in_named(DEVICE(via),
"pirq", i));

View File

@ -195,8 +195,8 @@ static void pegasos2_init(MachineState *machine)
object_property_add_alias(OBJECT(machine), "rtc-time",
object_resolve_path_component(via, "rtc"),
"date");
qdev_connect_gpio_out(DEVICE(via), 0,
qdev_get_gpio_in_named(pm->mv, "gpp", 31));
qdev_connect_gpio_out_named(DEVICE(via), "intr", 0,
qdev_get_gpio_in_named(pm->mv, "gpp", 31));
dev = PCI_DEVICE(object_resolve_path_component(via, "ide"));
pci_ide_create_devs(dev);

View File

@ -594,7 +594,7 @@ static void esp_do_dma(ESPState *s)
if (!s->current_req) {
return;
}
if (s->async_len == 0 && esp_get_tc(s) && s->ti_size) {
if (s->async_len == 0 && esp_get_tc(s)) {
/* Defer until data is available. */
return;
}
@ -647,7 +647,7 @@ static void esp_do_dma(ESPState *s)
if (!s->current_req) {
return;
}
if (s->async_len == 0 && esp_get_tc(s) && s->ti_size) {
if (s->async_len == 0 && esp_get_tc(s)) {
/* Defer until data is available. */
return;
}

View File

@ -984,6 +984,14 @@ void cpu_reset_interrupt(CPUState *cpu, int mask);
*/
void cpu_exit(CPUState *cpu);
/**
* cpu_pause:
* @cpu: The CPU to pause.
*
* Pauses CPU, i.e. puts CPU into stopped state.
*/
void cpu_pause(CPUState *cpu);
/**
* cpu_resume:
* @cpu: The CPU to resume.

View File

@ -77,15 +77,13 @@ ssize_t load_image_targphys(const char *filename, hwaddr,
ssize_t load_image_mr(const char *filename, MemoryRegion *mr);
/* This is the limit on the maximum uncompressed image size that
* load_image_gzipped_buffer() and load_image_gzipped() will read. It prevents
* load_image_gzipped_buffer() will read. It prevents
* g_malloc() in those functions from allocating a huge amount of memory.
*/
#define LOAD_IMAGE_MAX_GUNZIP_BYTES (256 << 20)
ssize_t load_image_gzipped_buffer(const char *filename, uint64_t max_sz,
uint8_t **buffer);
ssize_t load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz);
/**
* unpack_efi_zboot_image:
* @buffer: pointer to a variable holding the address of a buffer containing the

View File

@ -624,8 +624,9 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
* @name: Name of the input GPIO array
* @n: Number of the GPIO line in that array (which must be in range)
*
* Returns the qemu_irq corresponding to a named input GPIO line
* (which the device has set up with qdev_init_gpio_in_named()).
* Returns the qemu_irq corresponding to a single input GPIO line
* in a named array of input GPIO lines on a device (which the device
* has set up with qdev_init_gpio_in_named()).
* The @name string must correspond to an input GPIO array which exists on
* the device, and the index @n of the GPIO line must be valid (i.e.
* be at least 0 and less than the total number of input GPIOs in that
@ -673,15 +674,15 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
* GPIO lines
* @dev: Device whose GPIO to connect
* @name: Name of the output GPIO array
* @n: Number of the anonymous output GPIO line (which must be in range)
* @n: Number of the output GPIO line within that array (which must be in range)
* @input_pin: qemu_irq to connect the output line to
*
* This function connects an anonymous output GPIO line on a device
* up to an arbitrary qemu_irq, so that when the device asserts that
* output GPIO line, the qemu_irq's callback is invoked.
* This function connects a single GPIO output in a named array of output
* GPIO lines on a device up to an arbitrary qemu_irq, so that when the
* device asserts that output GPIO line, the qemu_irq's callback is invoked.
* The @name string must correspond to an output GPIO array which exists on
* the device, and the index @n of the GPIO line must be valid (i.e.
* be at least 0 and less than the total number of input GPIOs in that
* be at least 0 and less than the total number of output GPIOs in that
* array); this function will assert() if passed an invalid name or index.
*
* Outbound GPIO lines can be connected to any qemu_irq, but the common
@ -796,7 +797,7 @@ void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
* @dev: Device to create output GPIOs for
* @pins: Pointer to qemu_irq or qemu_irq array for the GPIO lines
* @name: Name to give this array of GPIO lines
* @n: Number of GPIO lines to create
* @n: Number of GPIO lines to create in this array
*
* Like qdev_init_gpio_out(), but creates an array of GPIO output lines
* with a name. Code using the device can then connect these GPIO lines

View File

@ -233,7 +233,7 @@ typedef struct DisplayChangeListenerOps {
/* optional */
void (*dpy_mouse_set)(DisplayChangeListener *dcl,
int x, int y, int on);
int x, int y, bool on);
/* optional */
void (*dpy_cursor_define)(DisplayChangeListener *dcl,
QEMUCursor *cursor);
@ -322,9 +322,8 @@ void dpy_gfx_replace_surface(QemuConsole *con,
void dpy_text_cursor(QemuConsole *con, int x, int y);
void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
void dpy_text_resize(QemuConsole *con, int w, int h);
void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
void dpy_mouse_set(QemuConsole *con, int x, int y, bool on);
void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
bool dpy_cursor_define_supported(QemuConsole *con);
bool dpy_gfx_check_format(QemuConsole *con,
pixman_format_code_t format);

View File

@ -1070,7 +1070,8 @@ if get_option('attr').allowed()
endif
endif
cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
cocoa = dependency('appleframeworks',
modules: ['Cocoa', 'CoreVideo', 'QuartzCore'],
required: get_option('cocoa'))
vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))

View File

@ -568,6 +568,22 @@ void cpu_thread_signal_destroyed(CPUState *cpu)
qemu_cond_signal(&qemu_cpu_cond);
}
void cpu_pause(CPUState *cpu)
{
if (qemu_cpu_is_self(cpu)) {
qemu_cpu_stop(cpu, true);
} else {
cpu->stop = true;
qemu_cpu_kick(cpu);
}
}
void cpu_resume(CPUState *cpu)
{
cpu->stop = false;
cpu->stopped = false;
qemu_cpu_kick(cpu);
}
static bool all_vcpus_paused(void)
{
@ -588,12 +604,7 @@ void pause_all_vcpus(void)
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
CPU_FOREACH(cpu) {
if (qemu_cpu_is_self(cpu)) {
qemu_cpu_stop(cpu, true);
} else {
cpu->stop = true;
qemu_cpu_kick(cpu);
}
cpu_pause(cpu);
}
/* We need to drop the replay_lock so any vCPU threads woken up
@ -613,13 +624,6 @@ void pause_all_vcpus(void)
bql_lock();
}
void cpu_resume(CPUState *cpu)
{
cpu->stop = false;
cpu->stopped = false;
qemu_cpu_kick(cpu);
}
void resume_all_vcpus(void)
{
CPUState *cpu;

View File

@ -1845,11 +1845,14 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
}
if (new_block->flags & RAM_GUEST_MEMFD) {
int ret;
assert(kvm_enabled());
assert(new_block->guest_memfd < 0);
if (ram_block_discard_require(true) < 0) {
error_setg_errno(errp, errno,
ret = ram_block_discard_require(true);
if (ret < 0) {
error_setg_errno(errp, -ret,
"cannot set up private guest memory: discard currently blocked");
error_append_hint(errp, "Are you using assigned devices?\n");
goto out_free;

View File

@ -1000,9 +1000,16 @@ static bool vga_interface_available(VGAInterfaceType t)
const VGAInterfaceInfo *ti = &vga_interfaces[t];
assert(t < VGA_TYPE_MAX);
return !ti->class_names[0] ||
module_object_class_by_name(ti->class_names[0]) ||
module_object_class_by_name(ti->class_names[1]);
if (!ti->class_names[0] || module_object_class_by_name(ti->class_names[0])) {
return true;
}
if (ti->class_names[1] && module_object_class_by_name(ti->class_names[1])) {
return true;
}
return false;
}
static const char *

View File

@ -155,6 +155,11 @@ static void tc37x_initfn(Object *obj)
set_feature(&cpu->env, TRICORE_FEATURE_162);
}
static bool tricore_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
/* Interrupts are not implemented */
return false;
}
#include "hw/core/sysemu-cpu-ops.h"
@ -169,6 +174,7 @@ static const TCGCPUOps tricore_tcg_ops = {
.synchronize_from_tb = tricore_cpu_synchronize_from_tb,
.restore_state_to_opc = tricore_restore_state_to_opc,
.tlb_fill = tricore_cpu_tlb_fill,
.cpu_exec_interrupt = tricore_cpu_exec_interrupt,
.cpu_exec_halt = tricore_cpu_has_work,
};

View File

@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#include <crt_externs.h>
#include "qemu/help-texts.h"
@ -79,12 +80,16 @@ static void cocoa_switch(DisplayChangeListener *dcl,
DisplaySurface *surface);
static void cocoa_refresh(DisplayChangeListener *dcl);
static void cocoa_mouse_set(DisplayChangeListener *dcl, int x, int y, bool on);
static void cocoa_cursor_define(DisplayChangeListener *dcl, QEMUCursor *cursor);
static const DisplayChangeListenerOps dcl_ops = {
.dpy_name = "cocoa",
.dpy_gfx_update = cocoa_update,
.dpy_gfx_switch = cocoa_switch,
.dpy_refresh = cocoa_refresh,
.dpy_mouse_set = cocoa_mouse_set,
.dpy_cursor_define = cocoa_cursor_define,
};
static DisplayChangeListener dcl = {
.ops = &dcl_ops,
@ -307,6 +312,12 @@ static void handleAnyDeviceErrors(Error * err)
BOOL isMouseGrabbed;
BOOL isAbsoluteEnabled;
CFMachPortRef eventsTap;
CGColorSpaceRef colorspace;
CALayer *cursorLayer;
QEMUCursor *cursor;
int mouseX;
int mouseY;
bool mouseOn;
}
- (void) switchSurface:(pixman_image_t *)image;
- (void) grabMouse;
@ -359,9 +370,16 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
[trackingArea release];
screen.width = frameRect.size.width;
screen.height = frameRect.size.height;
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_14_0
[self setClipsToBounds:YES];
#endif
[self setWantsLayer:YES];
cursorLayer = [[CALayer alloc] init];
[cursorLayer setAnchorPoint:CGPointMake(0, 1)];
[cursorLayer setAutoresizingMask:kCALayerMaxXMargin |
kCALayerMinYMargin];
[[self layer] addSublayer:cursorLayer];
}
return self;
@ -379,6 +397,9 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
CFRelease(eventsTap);
}
CGColorSpaceRelease(colorspace);
[cursorLayer release];
cursor_unref(cursor);
[super dealloc];
}
@ -423,6 +444,72 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
[NSCursor unhide];
}
- (void)setMouseX:(int)x y:(int)y on:(bool)on
{
CGPoint position;
mouseX = x;
mouseY = y;
mouseOn = on;
position.x = mouseX;
position.y = screen.height - mouseY;
[CATransaction begin];
[CATransaction setDisableActions:YES];
[cursorLayer setPosition:position];
[cursorLayer setHidden:!mouseOn];
[CATransaction commit];
}
- (void)setCursor:(QEMUCursor *)given_cursor
{
CGDataProviderRef provider;
CGImageRef image;
CGRect bounds = CGRectZero;
cursor_unref(cursor);
cursor = given_cursor;
if (!cursor) {
return;
}
cursor_ref(cursor);
bounds.size.width = cursor->width;
bounds.size.height = cursor->height;
provider = CGDataProviderCreateWithData(
NULL,
cursor->data,
cursor->width * cursor->height * 4,
NULL
);
image = CGImageCreate(
cursor->width, //width
cursor->height, //height
8, //bitsPerComponent
32, //bitsPerPixel
cursor->width * 4, //bytesPerRow
colorspace, //colorspace
kCGBitmapByteOrder32Little | kCGImageAlphaFirst, //bitmapInfo
provider, //provider
NULL, //decode
0, //interpolate
kCGRenderingIntentDefault //intent
);
CGDataProviderRelease(provider);
[CATransaction begin];
[CATransaction setDisableActions:YES];
[cursorLayer setBounds:bounds];
[cursorLayer setContents:(id)image];
[CATransaction commit];
CGImageRelease(image);
}
- (void) drawRect:(NSRect) rect
{
COCOA_DEBUG("QemuCocoaView: drawRect\n");
@ -456,7 +543,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
DIV_ROUND_UP(bitsPerPixel, 8) * 2, //bitsPerComponent
bitsPerPixel, //bitsPerPixel
stride, //bytesPerRow
CGColorSpaceCreateWithName(kCGColorSpaceSRGB), //colorspace
colorspace, //colorspace
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, //bitmapInfo
dataProviderRef, //provider
NULL, //decode
@ -2012,6 +2099,21 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
[pool release];
}
static void cocoa_mouse_set(DisplayChangeListener *dcl, int x, int y, bool on)
{
dispatch_async(dispatch_get_main_queue(), ^{
[cocoaView setMouseX:x y:y on:on];
});
}
static void cocoa_cursor_define(DisplayChangeListener *dcl, QEMUCursor *cursor)
{
dispatch_async(dispatch_get_main_queue(), ^{
BQL_LOCK_GUARD();
[cocoaView setCursor:qemu_console_get_cursor(dcl->con)];
});
}
static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

View File

@ -49,7 +49,8 @@ typedef struct QemuGraphicConsole {
uint32_t head;
QEMUCursor *cursor;
int cursor_x, cursor_y, cursor_on;
int cursor_x, cursor_y;
bool cursor_on;
} QemuGraphicConsole;
typedef QemuConsoleClass QemuGraphicConsoleClass;
@ -957,7 +958,7 @@ void dpy_text_resize(QemuConsole *con, int w, int h)
}
}
void dpy_mouse_set(QemuConsole *c, int x, int y, int on)
void dpy_mouse_set(QemuConsole *c, int x, int y, bool on)
{
QemuGraphicConsole *con = QEMU_GRAPHIC_CONSOLE(c);
DisplayState *s = c->ds;
@ -1000,19 +1001,6 @@ void dpy_cursor_define(QemuConsole *c, QEMUCursor *cursor)
}
}
bool dpy_cursor_define_supported(QemuConsole *con)
{
DisplayState *s = con->ds;
DisplayChangeListener *dcl;
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_cursor_define) {
return true;
}
}
return false;
}
QEMUGLContext dpy_gl_ctx_create(QemuConsole *con,
struct QEMUGLParams *qparams)
{

View File

@ -726,7 +726,7 @@ static void dbus_gfx_switch(DisplayChangeListener *dcl,
}
static void dbus_mouse_set(DisplayChangeListener *dcl,
int x, int y, int on)
int x, int y, bool on)
{
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);

View File

@ -446,7 +446,7 @@ static GdkDevice *gd_get_pointer(GdkDisplay *dpy)
}
static void gd_mouse_set(DisplayChangeListener *dcl,
int x, int y, int visible)
int x, int y, bool visible)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
GdkDisplay *dpy;

View File

@ -49,7 +49,7 @@ static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
static SDL_Cursor *sdl_cursor_normal;
static SDL_Cursor *sdl_cursor_hidden;
static int absolute_enabled;
static int guest_cursor;
static bool guest_cursor;
static int guest_x, guest_y;
static SDL_Cursor *guest_sprite;
static Notifier mouse_mode_notifier;
@ -729,7 +729,7 @@ void sdl2_poll_events(struct sdl2_console *scon)
}
static void sdl_mouse_warp(DisplayChangeListener *dcl,
int x, int y, int on)
int x, int y, bool on)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);

View File

@ -254,7 +254,7 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
static SimpleSpiceCursor*
qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd,
QEMUCursor *c,
int on)
bool on)
{
size_t size = c ? c->width * c->height * 4 : 0;
SimpleSpiceCursor *update;
@ -448,7 +448,8 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
qemu_mutex_lock(&ssd->lock);
if (ssd->cursor) {
g_free(ssd->ptr_define);
ssd->ptr_define = qemu_spice_create_cursor_update(ssd, ssd->cursor, 0);
ssd->ptr_define =
qemu_spice_create_cursor_update(ssd, ssd->cursor, false);
}
qemu_mutex_unlock(&ssd->lock);
}
@ -476,7 +477,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque)
ssd->mouse_x = -1;
ssd->mouse_y = -1;
qemu_mutex_unlock(&ssd->lock);
dpy_mouse_set(ssd->dcl.con, x, y, 1);
dpy_mouse_set(ssd->dcl.con, x, y, true);
} else {
qemu_mutex_unlock(&ssd->lock);
}
@ -747,7 +748,7 @@ static void display_refresh(DisplayChangeListener *dcl)
}
static void display_mouse_set(DisplayChangeListener *dcl,
int x, int y, int on)
int x, int y, bool on)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
@ -774,7 +775,7 @@ static void display_mouse_define(DisplayChangeListener *dcl,
g_free(ssd->ptr_move);
ssd->ptr_move = NULL;
g_free(ssd->ptr_define);
ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0);
ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, false);
qemu_mutex_unlock(&ssd->lock);
qemu_spice_wakeup(ssd);
}

View File

@ -981,7 +981,7 @@ int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
}
static void vnc_mouse_set(DisplayChangeListener *dcl,
int x, int y, int visible)
int x, int y, bool visible)
{
/* can we ask the client(s) to move the pointer ??? */
}