- bugfixes for ui, usb, audio, display

- change default display resolution
 - add horizontal scrolling support
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmHhHcUACgkQTLbY7tPo
 cThE7RAAmWfnog5sqX9jWfXnRmgMSWT1ExBUUlgFFEcwjGnp7OnvXRx5rEN/E8lX
 hxI8769ds7oxwTlRjiOwNfN64xJE1byY3jCRbw2OJI6nDa1ZmrUVQqzOkwBng/SI
 Y6UULkW/fl1ahg73/DW1Oggy97BPGazbo1wi13VM+Xyw8BVceqEyXHdyr7siB34d
 ytZNsQ/InVTrCnL68qoukW9lTb4XRrKdkci22xYTH15Q4r/Bwm55TdWFI8QUbt4T
 G9ec1jsC0aFUniZyaJDH98T9/KIauWzFaGYTxwzHCy0gJoiwSwcnugFcaM3iu0pQ
 Fhq7yGnkzGTXUNspZL2Vf0TF2cPLyJzE0CaM8m6V2U3kcRiGjf6XA7ixQiFxqyoE
 N6XemQNOdwQCAyIJVUZHffMeA1bM352XbO01VpVnBJrdqZ46c5wbVIg73yYTTR96
 CaGGYVya0q7dGw1tf0UG44ipXqx2Lhh6Ml9wRoLpi0wgpqxYM4gTfbw/zYlH+vLg
 jm5XBaWcJoUrBIzFLqXYQds7ZuWEPRsMD3jTZ7krhAqmRODuFLEtvPtWJp4j+bRG
 7v9xmRGBljV6j/yMa/B9d/WiqcZi0LlCP5xJyBQMOAA+MTIQlJfWU7HP/6W3mgn5
 LpqMXAogO1Cdco0GaPcj/j+wrX7LIQb9I1w6eIOFZcahSlRccR4=
 =LOeb
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/kraxel-20220114-pull-request' into staging

- bugfixes for ui, usb, audio, display
- change default display resolution
- add horizontal scrolling support

# gpg: Signature made Fri 14 Jan 2022 06:52:53 GMT
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/kraxel-20220114-pull-request:
  ui/input-legacy: pass horizontal scroll information
  ui/sdl2: pass horizontal scroll information to the device code
  ui/gtk: pass horizontal scroll information to the device code
  ui/cocoa: pass horizontal scroll information to the device code
  ps2: Initial horizontal scroll support
  edid: Added support for 4k@60 Hz monitor
  edid: set default resolution to 1280x800 (WXGA)
  hw/mips/jazz: Inline vga_mmio_init() and remove it
  hw/display/vga-mmio: QOM'ify vga_mmio_init() as TYPE_VGA_MMIO
  hw/display/vga-mmio: Inline vga_mm_init()
  hw/display: Rename VGA_ISA_MM -> VGA_MMIO
  uas: add missing return
  ui: fix gtk clipboard clear assertion
  ui/dbus: fix buffer-overflow detected by ASAN
  hw/audio/intel-hda: fix stream reset
  dsoundaudio: fix crackling audio recordings
  jackaudio: use ifdefs to hide unavailable functions
  ui/vnc.c: Fixed a deadlock bug.
  usb: allow max 8192 bytes for desc
  hw/usb/dev-wacom: add missing HID descriptor

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2022-01-14 13:21:41 +00:00
commit 0b3f07ebf2
27 changed files with 387 additions and 181 deletions

View File

@ -536,13 +536,12 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
HRESULT hr;
DWORD cpos, rpos, act_size;
DWORD rpos, act_size;
size_t req_size;
int err;
void *ret;
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(
dscb, &cpos, ds->first_time ? &rpos : NULL);
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, NULL, &rpos);
if (FAILED(hr)) {
dsound_logerr(hr, "Could not get capture buffer position\n");
*size = 0;
@ -554,7 +553,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
ds->first_time = false;
}
req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
req_size = audio_ring_dist(rpos, hw->pos_emul, hw->size_emul);
req_size = MIN(*size, MIN(req_size, hw->size_emul - hw->pos_emul));
if (req_size == 0) {

View File

@ -622,6 +622,7 @@ static void qjack_enable_in(HWVoiceIn *hw, bool enable)
ji->c.enabled = enable;
}
#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
static int qjack_thread_creator(jack_native_thread_t *thread,
const pthread_attr_t *attr, void *(*function)(void *), void *arg)
{
@ -635,6 +636,7 @@ static int qjack_thread_creator(jack_native_thread_t *thread,
return ret;
}
#endif
static void *qjack_init(Audiodev *dev)
{
@ -687,7 +689,9 @@ static void register_audio_jack(void)
{
qemu_mutex_init(&qjack_shutdown_lock);
audio_driver_register(&jack_driver);
#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
jack_set_thread_creator(qjack_thread_creator);
#endif
jack_set_error_function(qjack_error);
jack_set_info_function(qjack_info);
}

View File

@ -7,7 +7,7 @@ CONFIG_ISA_BUS=y
CONFIG_PCI=y
CONFIG_PCI_DEVICES=y
CONFIG_VGA_ISA=y
CONFIG_VGA_ISA_MM=y
CONFIG_VGA_MMIO=y
CONFIG_VGA_CIRRUS=y
CONFIG_VMWARE_VGA=y
CONFIG_SERIAL=y

View File

@ -581,7 +581,7 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3
if (st->ctl & 0x01) {
/* reset */
dprint(d, 1, "st #%d: reset\n", reg->stream);
st->ctl = SD_STS_FIFO_READY << 24;
st->ctl = SD_STS_FIFO_READY << 24 | SD_CTL_STREAM_RESET;
}
if ((st->ctl & 0x02) != (old & 0x02)) {
uint32_t stnr = (st->ctl >> 20) & 0x0f;

View File

@ -49,7 +49,7 @@ config VGA_ISA
depends on ISA_BUS
select VGA
config VGA_ISA_MM
config VGA_MMIO
bool
select VGA

View File

@ -24,6 +24,9 @@ static const struct edid_mode {
{ .xres = 2048, .yres = 1152 },
{ .xres = 1920, .yres = 1080, .dta = 31 },
/* dea/dta extension timings (all @ 60 Hz) */
{ .xres = 3840, .yres = 2160, .dta = 97 },
/* additional standard timings 3 (all @ 60Hz) */
{ .xres = 1920, .yres = 1200, .xtra3 = 10, .bit = 0 },
{ .xres = 1600, .yres = 1200, .xtra3 = 9, .bit = 2 },
@ -401,10 +404,10 @@ void qemu_edid_generate(uint8_t *edid, size_t size,
info->name = "QEMU Monitor";
}
if (!info->prefx) {
info->prefx = 1024;
info->prefx = 1280;
}
if (!info->prefy) {
info->prefy = 768;
info->prefy = 800;
}
if (info->prefx >= 4096 || info->prefy >= 4096) {
large_screen = 1;

View File

@ -18,7 +18,7 @@ softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xenfb.c'))
softmmu_ss.add(when: 'CONFIG_VGA_PCI', if_true: files('vga-pci.c'))
softmmu_ss.add(when: 'CONFIG_VGA_ISA', if_true: files('vga-isa.c'))
softmmu_ss.add(when: 'CONFIG_VGA_ISA_MM', if_true: files('vga-isa-mm.c'))
softmmu_ss.add(when: 'CONFIG_VGA_MMIO', if_true: files('vga-mmio.c'))
softmmu_ss.add(when: 'CONFIG_VMWARE_VGA', if_true: files('vmware_vga.c'))
softmmu_ss.add(when: 'CONFIG_BOCHS_DISPLAY', if_true: files('bochs-display.c'))

View File

@ -1,114 +0,0 @@
/*
* QEMU ISA MM VGA Emulator.
*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/units.h"
#include "migration/vmstate.h"
#include "hw/display/vga.h"
#include "vga_int.h"
#include "ui/pixel_ops.h"
#define VGA_RAM_SIZE (8 * MiB)
typedef struct ISAVGAMMState {
VGACommonState vga;
int it_shift;
} ISAVGAMMState;
/* Memory mapped interface */
static uint64_t vga_mm_read(void *opaque, hwaddr addr, unsigned size)
{
ISAVGAMMState *s = opaque;
return vga_ioport_read(&s->vga, addr >> s->it_shift) &
MAKE_64BIT_MASK(0, size * 8);
}
static void vga_mm_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
ISAVGAMMState *s = opaque;
vga_ioport_write(&s->vga, addr >> s->it_shift,
value & MAKE_64BIT_MASK(0, size * 8));
}
static const MemoryRegionOps vga_mm_ctrl_ops = {
.read = vga_mm_read,
.write = vga_mm_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,
.impl.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void vga_mm_init(ISAVGAMMState *s, hwaddr vram_base,
hwaddr ctrl_base, int it_shift,
MemoryRegion *address_space)
{
MemoryRegion *s_ioport_ctrl, *vga_io_memory;
s->it_shift = it_shift;
s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl));
memory_region_init_io(s_ioport_ctrl, NULL, &vga_mm_ctrl_ops, s,
"vga-mm-ctrl", 0x100000);
memory_region_set_flush_coalesced(s_ioport_ctrl);
vga_io_memory = g_malloc(sizeof(*vga_io_memory));
/* XXX: endianness? */
memory_region_init_io(vga_io_memory, NULL, &vga_mem_ops, &s->vga,
"vga-mem", 0x20000);
vmstate_register(NULL, 0, &vmstate_vga_common, s);
memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl);
s->vga.bank_offset = 0;
memory_region_add_subregion(address_space,
vram_base + 0x000a0000, vga_io_memory);
memory_region_set_coalescing(vga_io_memory);
}
int isa_vga_mm_init(hwaddr vram_base,
hwaddr ctrl_base, int it_shift,
MemoryRegion *address_space)
{
ISAVGAMMState *s;
s = g_malloc0(sizeof(*s));
s->vga.vram_size_mb = VGA_RAM_SIZE / MiB;
s->vga.global_vmstate = true;
vga_common_init(&s->vga, NULL);
vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s);
memory_region_add_subregion(address_space,
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
&s->vga.vram);
return 0;
}

139
hw/display/vga-mmio.c Normal file
View File

@ -0,0 +1,139 @@
/*
* QEMU MMIO VGA Emulator.
*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/display/vga.h"
#include "hw/qdev-properties.h"
#include "vga_int.h"
/*
* QEMU interface:
* + sysbus MMIO region 0: VGA I/O registers
* + sysbus MMIO region 1: VGA MMIO registers
* + sysbus MMIO region 2: VGA memory
*/
OBJECT_DECLARE_SIMPLE_TYPE(VGAMmioState, VGA_MMIO)
struct VGAMmioState {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
VGACommonState vga;
MemoryRegion iomem;
MemoryRegion lowmem;
uint8_t it_shift;
};
static uint64_t vga_mm_read(void *opaque, hwaddr addr, unsigned size)
{
VGAMmioState *s = opaque;
return vga_ioport_read(&s->vga, addr >> s->it_shift) &
MAKE_64BIT_MASK(0, size * 8);
}
static void vga_mm_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
VGAMmioState *s = opaque;
vga_ioport_write(&s->vga, addr >> s->it_shift,
value & MAKE_64BIT_MASK(0, size * 8));
}
static const MemoryRegionOps vga_mm_ctrl_ops = {
.read = vga_mm_read,
.write = vga_mm_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,
.impl.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void vga_mmio_reset(DeviceState *dev)
{
VGAMmioState *s = VGA_MMIO(dev);
vga_common_reset(&s->vga);
}
static void vga_mmio_realizefn(DeviceState *dev, Error **errp)
{
VGAMmioState *s = VGA_MMIO(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
memory_region_init_io(&s->iomem, OBJECT(dev), &vga_mm_ctrl_ops, s,
"vga-mmio", 0x100000);
memory_region_set_flush_coalesced(&s->iomem);
sysbus_init_mmio(sbd, &s->iomem);
/* XXX: endianness? */
memory_region_init_io(&s->lowmem, OBJECT(dev), &vga_mem_ops, &s->vga,
"vga-lowmem", 0x20000);
memory_region_set_coalescing(&s->lowmem);
sysbus_init_mmio(sbd, &s->lowmem);
s->vga.bank_offset = 0;
s->vga.global_vmstate = true;
vga_common_init(&s->vga, OBJECT(dev));
sysbus_init_mmio(sbd, &s->vga.vram);
s->vga.con = graphic_console_init(dev, 0, s->vga.hw_ops, &s->vga);
}
static Property vga_mmio_properties[] = {
DEFINE_PROP_UINT8("it_shift", VGAMmioState, it_shift, 0),
DEFINE_PROP_UINT32("vgamem_mb", VGAMmioState, vga.vram_size_mb, 8),
DEFINE_PROP_END_OF_LIST(),
};
static void vga_mmio_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = vga_mmio_realizefn;
dc->reset = vga_mmio_reset;
dc->vmsd = &vmstate_vga_common;
device_class_set_props(dc, vga_mmio_properties);
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}
static const TypeInfo vga_mmio_info = {
.name = TYPE_VGA_MMIO,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(VGAMmioState),
.class_init = vga_mmio_class_initfn,
};
static void vga_mmio_register_types(void)
{
type_register_static(&vga_mmio_info);
}
type_init(vga_mmio_register_types)

View File

@ -123,6 +123,7 @@ typedef struct {
int mouse_dx; /* current values, needed for 'poll' mode */
int mouse_dy;
int mouse_dz;
int mouse_dw;
uint8_t mouse_buttons;
} PS2MouseState;
@ -715,7 +716,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
/* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
const int needed = s->mouse_type ? 4 : 3;
unsigned int b;
int dx1, dy1, dz1;
int dx1, dy1, dz1, dw1;
if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
return 0;
@ -724,6 +725,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
dx1 = s->mouse_dx;
dy1 = s->mouse_dy;
dz1 = s->mouse_dz;
dw1 = s->mouse_dw;
/* XXX: increase range to 8 bits ? */
if (dx1 > 127)
dx1 = 127;
@ -740,6 +742,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
/* extra byte for IMPS/2 or IMEX */
switch(s->mouse_type) {
default:
/* Just ignore the wheels if not supported */
s->mouse_dz = 0;
s->mouse_dw = 0;
break;
case 3:
if (dz1 > 127)
@ -747,13 +752,41 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
else if (dz1 < -127)
dz1 = -127;
ps2_queue_noirq(&s->common, dz1 & 0xff);
s->mouse_dz -= dz1;
s->mouse_dw = 0;
break;
case 4:
if (dz1 > 7)
dz1 = 7;
else if (dz1 < -7)
dz1 = -7;
b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
/*
* This matches what the Linux kernel expects for exps/2 in
* drivers/input/mouse/psmouse-base.c. Note, if you happen to
* press/release the 4th or 5th buttons at the same moment as a
* horizontal wheel scroll, those button presses will get lost. I'm not
* sure what to do about that, since by this point we don't know
* whether those buttons actually changed state.
*/
if (dw1 != 0) {
if (dw1 > 31) {
dw1 = 31;
} else if (dw1 < -31) {
dw1 = -31;
}
/*
* linux kernel expects first 6 bits to represent the value
* for horizontal scroll
*/
b = (dw1 & 0x3f) | 0x40;
s->mouse_dw -= dw1;
} else {
if (dz1 > 7) {
dz1 = 7;
} else if (dz1 < -7) {
dz1 = -7;
}
b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
s->mouse_dz -= dz1;
}
ps2_queue_noirq(&s->common, b);
break;
}
@ -764,7 +797,6 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
/* update deltas */
s->mouse_dx -= dx1;
s->mouse_dy -= dy1;
s->mouse_dz -= dz1;
return 1;
}
@ -806,6 +838,12 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
} else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
s->mouse_dz++;
}
if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
s->mouse_dw--;
} else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) {
s->mouse_dw++;
}
} else {
s->mouse_buttons &= ~bmap[btn->button];
}
@ -833,8 +871,10 @@ static void ps2_mouse_sync(DeviceState *dev)
/* if not remote, send event. Multiple events are sent if
too big deltas */
while (ps2_mouse_send_packet(s)) {
if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
if (s->mouse_dx == 0 && s->mouse_dy == 0
&& s->mouse_dz == 0 && s->mouse_dw == 0) {
break;
}
}
}
}
@ -1036,6 +1076,7 @@ static void ps2_mouse_reset(void *opaque)
s->mouse_dx = 0;
s->mouse_dy = 0;
s->mouse_dz = 0;
s->mouse_dw = 0;
s->mouse_buttons = 0;
}

View File

@ -16,7 +16,7 @@ config JAZZ
select I8254
select I8257
select PCSPK
select VGA_ISA_MM
select VGA_MMIO
select G364FB
select DP8393X
select ESP

View File

@ -43,6 +43,7 @@
#include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/display/vga.h"
#include "hw/display/bochs-vbe.h"
#include "hw/audio/pcspk.h"
#include "hw/input/i8042.h"
#include "hw/sysbus.h"
@ -274,7 +275,13 @@ static void mips_jazz_init(MachineState *machine,
}
break;
case JAZZ_PICA61:
isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
dev = qdev_new(TYPE_VGA_MMIO);
qdev_prop_set_uint8(dev, "it_shift", 0);
sysbus = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(sysbus, &error_fatal);
sysbus_mmio_map(sysbus, 0, 0x60000000);
sysbus_mmio_map(sysbus, 1, 0x400a0000);
sysbus_mmio_map(sysbus, 2, VBE_DISPI_LFB_PHYSICAL_ADDRESS);
break;
default:
break;

View File

@ -632,7 +632,8 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
bool msos = (dev->flags & (1 << USB_DEV_FLAG_MSOS_DESC_IN_USE));
const USBDesc *desc = usb_device_get_usb_desc(dev);
const USBDescDevice *other_dev;
uint8_t buf[256];
size_t buflen = USB_DESC_MAX_LEN;
g_autofree uint8_t *buf = g_malloc(buflen);
uint8_t type = value >> 8;
uint8_t index = value & 0xff;
int flags, ret = -1;
@ -650,36 +651,36 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
switch(type) {
case USB_DT_DEVICE:
ret = usb_desc_device(&desc->id, dev->device, msos, buf, sizeof(buf));
ret = usb_desc_device(&desc->id, dev->device, msos, buf, buflen);
trace_usb_desc_device(dev->addr, len, ret);
break;
case USB_DT_CONFIG:
if (index < dev->device->bNumConfigurations) {
ret = usb_desc_config(dev->device->confs + index, flags,
buf, sizeof(buf));
buf, buflen);
}
trace_usb_desc_config(dev->addr, index, len, ret);
break;
case USB_DT_STRING:
ret = usb_desc_string(dev, index, buf, sizeof(buf));
ret = usb_desc_string(dev, index, buf, buflen);
trace_usb_desc_string(dev->addr, index, len, ret);
break;
case USB_DT_DEVICE_QUALIFIER:
if (other_dev != NULL) {
ret = usb_desc_device_qualifier(other_dev, buf, sizeof(buf));
ret = usb_desc_device_qualifier(other_dev, buf, buflen);
}
trace_usb_desc_device_qualifier(dev->addr, len, ret);
break;
case USB_DT_OTHER_SPEED_CONFIG:
if (other_dev != NULL && index < other_dev->bNumConfigurations) {
ret = usb_desc_config(other_dev->confs + index, flags,
buf, sizeof(buf));
buf, buflen);
buf[0x01] = USB_DT_OTHER_SPEED_CONFIG;
}
trace_usb_desc_other_speed_config(dev->addr, index, len, ret);
break;
case USB_DT_BOS:
ret = usb_desc_bos(desc, buf, sizeof(buf));
ret = usb_desc_bos(desc, buf, buflen);
trace_usb_desc_bos(dev->addr, len, ret);
break;

View File

@ -199,6 +199,7 @@ struct USBDesc {
const USBDescMSOS *msos;
};
#define USB_DESC_MAX_LEN 8192
#define USB_DESC_FLAG_SUPER (1 << 1)
/* little helpers */

View File

@ -908,6 +908,7 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
p->status = USB_RET_STALL;
break;
}
return;
err_stream:
error_report("%s: invalid stream %d", __func__, p->stream);

View File

@ -69,6 +69,65 @@ static const USBDescStrings desc_strings = {
[STR_SERIALNUMBER] = "1",
};
static const uint8_t qemu_wacom_hid_report_descriptor[] = {
0x05, 0x01, /* Usage Page (Desktop) */
0x09, 0x02, /* Usage (Mouse) */
0xa1, 0x01, /* Collection (Application) */
0x85, 0x01, /* Report ID (1) */
0x09, 0x01, /* Usage (Pointer) */
0xa1, 0x00, /* Collection (Physical) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 0x01, /* Usage Minimum (01h) */
0x29, 0x03, /* Usage Maximum (03h) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x95, 0x03, /* Report Count (3) */
0x75, 0x01, /* Report Size (1) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */
0x75, 0x05, /* Report Size (5) */
0x81, 0x01, /* Input (Constant) */
0x05, 0x01, /* Usage Page (Desktop) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x09, 0x38, /* Usage (Wheel) */
0x15, 0x81, /* Logical Minimum (-127) */
0x25, 0x7f, /* Logical Maximum (127) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x03, /* Report Count (3) */
0x81, 0x06, /* Input (Data, Variable, Relative) */
0x95, 0x03, /* Report Count (3) */
0x81, 0x01, /* Input (Constant) */
0xc0, /* End Collection */
0xc0, /* End Collection */
0x05, 0x0d, /* Usage Page (Digitizer) */
0x09, 0x01, /* Usage (Digitizer) */
0xa1, 0x01, /* Collection (Application) */
0x85, 0x02, /* Report ID (2) */
0xa1, 0x00, /* Collection (Physical) */
0x06, 0x00, 0xff,/* Usage Page (ff00h), vendor-defined */
0x09, 0x01, /* Usage (01h) */
0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xff, 0x00,/* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x07, /* Report Count (7) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0xc0, /* End Collection */
0x09, 0x01, /* Usage (01h) */
0x85, 0x63, /* Report ID (99) */
0x95, 0x07, /* Report Count (7) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x09, 0x01, /* Usage (01h) */
0x85, 0x02, /* Report ID (2) */
0x95, 0x01, /* Report Count (1) */
0xb1, 0x02, /* Feature (Variable) */
0x09, 0x01, /* Usage (01h) */
0x85, 0x03, /* Report ID (3) */
0x95, 0x01, /* Report Count (1) */
0xb1, 0x02, /* Feature (Variable) */
0xc0 /* End Collection */
};
static const USBDescIface desc_iface_wacom = {
.bInterfaceNumber = 0,
.bNumEndpoints = 1,
@ -86,7 +145,7 @@ static const USBDescIface desc_iface_wacom = {
0x00, /* u8 country_code */
0x01, /* u8 num_descriptors */
USB_DT_REPORT, /* u8 type: Report */
0x6e, 0, /* u16 len */
sizeof(qemu_wacom_hid_report_descriptor), 0, /* u16 len */
},
},
},
@ -266,6 +325,17 @@ static void usb_wacom_handle_control(USBDevice *dev, USBPacket *p,
}
switch (request) {
case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
switch (value >> 8) {
case 0x22:
memcpy(data, qemu_wacom_hid_report_descriptor,
sizeof(qemu_wacom_hid_report_descriptor));
p->actual_length = sizeof(qemu_wacom_hid_report_descriptor);
break;
default:
return;
}
break;
case WACOM_SET_REPORT:
if (s->mouse_grabbed) {
qemu_remove_mouse_event_handler(s->eh_entry);

View File

@ -9,8 +9,6 @@
#ifndef QEMU_HW_DISPLAY_VGA_H
#define QEMU_HW_DISPLAY_VGA_H
#include "exec/hwaddr.h"
/*
* modules can reference this symbol to avoid being loaded
* into system emulators without vga support
@ -24,8 +22,6 @@ enum vga_retrace_method {
extern enum vga_retrace_method vga_retrace_method;
int isa_vga_mm_init(hwaddr vram_base,
hwaddr ctrl_base, int it_shift,
MemoryRegion *address_space);
#define TYPE_VGA_MMIO "vga-mmio"
#endif

View File

@ -147,8 +147,8 @@ struct VirtIOGPUBaseClass {
DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \
DEFINE_PROP_BIT("edid", _state, _conf.flags, \
VIRTIO_GPU_FLAG_EDID_ENABLED, true), \
DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \
DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800)
typedef struct VGPUDMABuf {
QemuDmaBuf buf;

View File

@ -905,7 +905,7 @@
##
{ 'enum' : 'InputButton',
'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side',
'extra' ] }
'extra', 'wheel-left', 'wheel-right' ] }
##
# @InputAxis:

View File

@ -10,8 +10,8 @@
#include "hw/display/edid.h"
static qemu_edid_info info = {
.prefx = 1024,
.prefy = 768,
.prefx = 1280,
.prefy = 800,
};
static void usage(FILE *out)

View File

@ -970,21 +970,27 @@ QemuCocoaView *cocoaView;
*/
/*
* When deltaY is zero, it means that this scrolling event was
* either horizontal, or so fine that it only appears in
* scrollingDeltaY. So we drop the event.
* We shouldn't have got a scroll event when deltaY and delta Y
* are zero, hence no harm in dropping the event
*/
if ([event deltaY] != 0) {
if ([event deltaY] != 0 || [event deltaX] != 0) {
/* Determine if this is a scroll up or scroll down event */
buttons = ([event deltaY] > 0) ?
if ([event deltaY] != 0) {
buttons = ([event deltaY] > 0) ?
INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
} else if ([event deltaX] != 0) {
buttons = ([event deltaX] > 0) ?
INPUT_BUTTON_WHEEL_LEFT : INPUT_BUTTON_WHEEL_RIGHT;
}
qemu_input_queue_btn(dcl.con, buttons, true);
qemu_input_event_sync();
qemu_input_queue_btn(dcl.con, buttons, false);
qemu_input_event_sync();
}
/*
* Since deltaY also reports scroll wheel events we prevent mouse
* Since deltaX/deltaY also report scroll wheel events we prevent mouse
* movement code from executing.
*/
mouse_event = false;

View File

@ -405,6 +405,7 @@ dbus_vc_class_init(ObjectClass *oc, void *data)
static const TypeInfo dbus_vc_type_info = {
.name = TYPE_CHARDEV_VC,
.parent = TYPE_CHARDEV_DBUS,
.class_size = sizeof(DBusVCClass),
.class_init = dbus_vc_class_init,
};

View File

@ -83,7 +83,7 @@ static void gd_clipboard_update_info(GtkDisplayState *gd,
if (info != qemu_clipboard_info(s)) {
gd->cbpending[s] = 0;
if (!self_update) {
GtkTargetList *list;
g_autoptr(GtkTargetList) list = NULL;
GtkTargetEntry *targets;
gint n_targets;
@ -94,15 +94,16 @@ static void gd_clipboard_update_info(GtkDisplayState *gd,
targets = gtk_target_table_new_from_list(list, &n_targets);
gtk_clipboard_clear(gd->gtkcb[s]);
gd->cbowner[s] = true;
gtk_clipboard_set_with_data(gd->gtkcb[s],
targets, n_targets,
gd_clipboard_get_data,
gd_clipboard_clear,
gd);
if (targets) {
gd->cbowner[s] = true;
gtk_clipboard_set_with_data(gd->gtkcb[s],
targets, n_targets,
gd_clipboard_get_data,
gd_clipboard_clear,
gd);
gtk_target_table_free(targets, n_targets);
gtk_target_list_unref(list);
gtk_target_table_free(targets, n_targets);
}
}
return;
}

View File

@ -968,33 +968,63 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
void *opaque)
{
VirtualConsole *vc = opaque;
InputButton btn;
InputButton btn_vertical;
InputButton btn_horizontal;
bool has_vertical = false;
bool has_horizontal = false;
if (scroll->direction == GDK_SCROLL_UP) {
btn = INPUT_BUTTON_WHEEL_UP;
btn_vertical = INPUT_BUTTON_WHEEL_UP;
has_vertical = true;
} else if (scroll->direction == GDK_SCROLL_DOWN) {
btn = INPUT_BUTTON_WHEEL_DOWN;
btn_vertical = INPUT_BUTTON_WHEEL_DOWN;
has_vertical = true;
} else if (scroll->direction == GDK_SCROLL_LEFT) {
btn_horizontal = INPUT_BUTTON_WHEEL_LEFT;
has_horizontal = true;
} else if (scroll->direction == GDK_SCROLL_RIGHT) {
btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT;
has_horizontal = true;
} else if (scroll->direction == GDK_SCROLL_SMOOTH) {
gdouble delta_x, delta_y;
if (!gdk_event_get_scroll_deltas((GdkEvent *)scroll,
&delta_x, &delta_y)) {
return TRUE;
}
if (delta_y == 0) {
return TRUE;
} else if (delta_y > 0) {
btn = INPUT_BUTTON_WHEEL_DOWN;
if (delta_y > 0) {
btn_vertical = INPUT_BUTTON_WHEEL_DOWN;
has_vertical = true;
} else if (delta_y < 0) {
btn_vertical = INPUT_BUTTON_WHEEL_UP;
has_vertical = true;
} else if (delta_x > 0) {
btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT;
has_horizontal = true;
} else if (delta_x < 0) {
btn_horizontal = INPUT_BUTTON_WHEEL_LEFT;
has_horizontal = true;
} else {
btn = INPUT_BUTTON_WHEEL_UP;
return TRUE;
}
} else {
return TRUE;
}
qemu_input_queue_btn(vc->gfx.dcl.con, btn, true);
qemu_input_event_sync();
qemu_input_queue_btn(vc->gfx.dcl.con, btn, false);
qemu_input_event_sync();
if (has_vertical) {
qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, true);
qemu_input_event_sync();
qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, false);
qemu_input_event_sync();
}
if (has_horizontal) {
qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, true);
qemu_input_event_sync();
qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, false);
qemu_input_event_sync();
}
return TRUE;
}

View File

@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/qapi-commands-ui.h"
#include "ui/console.h"
#include "keymaps.h"
@ -179,6 +180,20 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
1,
s->buttons);
}
if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
s->axis[INPUT_AXIS_X],
s->axis[INPUT_AXIS_Y],
-2,
s->buttons);
}
if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) {
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
s->axis[INPUT_AXIS_X],
s->axis[INPUT_AXIS_Y],
2,
s->buttons);
}
break;
case INPUT_EVENT_KIND_ABS:
move = evt->u.abs.data;

View File

@ -33,6 +33,7 @@
#include "sysemu/runstate-action.h"
#include "sysemu/sysemu.h"
#include "ui/win32-kbd-hook.h"
#include "qemu/log.h"
static int sdl2_num_outputs;
static struct sdl2_console *sdl2_console;
@ -535,6 +536,10 @@ static void handle_mousewheel(SDL_Event *ev)
btn = INPUT_BUTTON_WHEEL_UP;
} else if (wev->y < 0) {
btn = INPUT_BUTTON_WHEEL_DOWN;
} else if (wev->x < 0) {
btn = INPUT_BUTTON_WHEEL_RIGHT;
} else if (wev->x > 0) {
btn = INPUT_BUTTON_WHEEL_LEFT;
} else {
return;
}

View File

@ -1354,12 +1354,12 @@ void vnc_disconnect_finish(VncState *vs)
/* last client gone */
vnc_update_server_surface(vs->vd);
}
vnc_unlock_output(vs);
if (vs->cbpeer.notifier.notify) {
qemu_clipboard_peer_unregister(&vs->cbpeer);
}
vnc_unlock_output(vs);
qemu_mutex_destroy(&vs->output_mutex);
if (vs->bh != NULL) {
qemu_bh_delete(vs->bh);