ps2: Initial horizontal scroll support
This change adds support for horizontal scroll to ps/2 mouse device code. The code is implemented to match the logic of linux kernel which is used as a reference. Signed-off-by: Dmitry Petrov <dpetroff@gmail.com> Message-Id: <20220108153947.171861-2-dpetroff@gmail.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
f0602b7099
commit
64ebbb7d62
@ -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;
|
||||
}
|
||||
|
||||
|
@ -905,7 +905,7 @@
|
||||
##
|
||||
{ 'enum' : 'InputButton',
|
||||
'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side',
|
||||
'extra' ] }
|
||||
'extra', 'wheel-left', 'wheel-right' ] }
|
||||
|
||||
##
|
||||
# @InputAxis:
|
||||
|
Loading…
Reference in New Issue
Block a user