diff options
Diffstat (limited to 'mousetsr.c')
| -rw-r--r-- | mousetsr.c | 68 |
1 files changed, 58 insertions, 10 deletions
@@ -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; } } |
