aboutsummaryrefslogtreecommitdiff
path: root/mousetsr.c
diff options
context:
space:
mode:
Diffstat (limited to 'mousetsr.c')
-rw-r--r--mousetsr.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/mousetsr.c b/mousetsr.c
index b386c89..0965b6b 100644
--- a/mousetsr.c
+++ b/mousetsr.c
@@ -1546,14 +1546,13 @@ void __declspec(naked) __far int33_isr(void)
}
#if USE_SERIAL
-static void handle_serial_ms_packet()
+static void handle_serial_m_packet()
{
int x = (int8_t) ((data.cur_packet[1] & SERMOUSE_MS_X_LO_MASK)
| ((data.cur_packet[0] & SERMOUSE_MS_X_HI_MASK) << SERMOUSE_MS_X_HI_SHIFT));
int y = (int8_t) ((data.cur_packet[2] & SERMOUSE_MS_Y_LO_MASK)
| ((data.cur_packet[0] & SERMOUSE_MS_Y_HI_MASK) << SERMOUSE_MS_Y_HI_SHIFT));
unsigned buttons = 0;
- // Unused:
bool abs = false;
char wheeln = 0;
int z = 0;
@@ -1562,25 +1561,62 @@ static void handle_serial_ms_packet()
buttons |= INT33_BUTTON_MASK_LEFT;
if (data.cur_packet[0] & SERMOUSE_MS_BUTTON_RIGHT)
buttons |= INT33_BUTTON_MASK_RIGHT;
-
+ if (data.num_buttons >= 3 && (data.buttons & INT33_BUTTON_MASK_CENTER))
+ buttons |= INT33_BUTTON_MASK_CENTER; // preserve status of mid button for now
#if TRACE_PROTO
- dprintf("serial decoded packet buttons=%x x=%d y=%d\n", buttons, x, y);
+ dprintf("serial decoded M packet buttons=%x x=%d y=%d\n", buttons, x, y);
#endif /* TRACE_PROTO */
handle_mouse_event(buttons, abs, x, y, wheeln, z);
}
+static void handle_serial_m3_packet()
+{
+ // No need to send mouse movement as it will have been processed
+ // back when we received the 3rd byte.
+ // Instead focus on wheel and mid mouse button which come in the 4rd byte.
+ int x = 0;
+ int y = 0;
+ // Preserve old button state for most part
+ unsigned buttons = data.buttons & (INT33_BUTTON_MASK_LEFT|INT33_BUTTON_MASK_RIGHT);
+ bool abs = false;
+ char wheeln = 0; // only one wheel supported for now
+ int z = sign_extend(data.cur_packet[3] & SERMOUSE_MS_Z_LO_MASK, 4);
+
+ if (data.cur_packet[3] & SERMOUSE_MS_BUTTON_CENTER) {
+ buttons |= INT33_BUTTON_MASK_CENTER;
+ }
+
+#if TRACE_PROTO
+ dprintf("serial decoded M3 packet buttons=%x z=%d\n", buttons, z);
+#endif /* TRACE_PROTO */
+
+ // Only send 2nd event if really necessary
+ if (buttons != data.buttons || z) {
+ handle_mouse_event(buttons, abs, x, y, wheeln, z);
+ }
+}
+
static void handle_serial_data(uint8_t byte)
{
// TODO: not checking cur_packet_ticks for now, don't think it necessary for serial
// due to different synchronization
// Depending on the serial protocol now...
- switch (data.device_id) {
- case 'M':
- case '3':
+ if (data.device_id == SERMOUSE_DEVICE_ID_MS) {
// All these protocols use bit #6 (MSB since we use 7 data bits) as Start-of-Frame indicator
if (byte & (1 << 6)) {
+ if (data.buttons & INT33_BUTTON_MASK_CENTER && data.cur_packet_bytes == 3) {
+ // Was the previous packet a 3byte one and the middle button is down?
+ // Assume the mouse just skipped the 4th byte and release the middle button
+ // TODO I am not sure if this hack is required
+#if TRACE_PROTO
+ dputs("serial releasing mid button");
+#endif /* TRACE_PROTO */
+ handle_mouse_event(data.buttons & ~INT33_BUTTON_MASK_CENTER, false, 0, 0, 0, 0);
+ }
+
+ // Prepare for new packet
data.cur_packet_bytes = 0;
}
@@ -1592,12 +1628,24 @@ static void handle_serial_data(uint8_t byte)
data.cur_packet[data.cur_packet_bytes] = byte;
data.cur_packet_bytes++;
+ // However there is no End-of-Frame indicator.
+ // We do not know if this is going to be a 3 byte or 4 byte packet
+ // (apparently 4-byte packet mouses may send up a 3-byte packet
+ // if no wheel or extra buttons are modified)
+ // So we will send a "main" mouse event when we receive the 3rd byte
+ // and then follow up with a second mouse event if we receive the 4rd.
+
+ if (data.cur_packet_bytes == 3) {
+ // send main mouse event now
+ handle_serial_m_packet();
+ } else if (data.cur_packet_bytes == 4) {
+ // handle the 4th byte
+ handle_serial_m3_packet();
+ }
+
if (data.cur_packet_bytes >= data.packet_size) {
- handle_serial_ms_packet();
data.cur_packet_bytes = 0;
}
-
- break;
}
}