Changeset 26925 in vbox
- Timestamp:
- Mar 1, 2010 8:22:59 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/DevPS2.cpp
r26690 r26925 57 57 #include "../Builtins.h" 58 58 59 #define PCKBD_SAVED_STATE_VERSION 459 #define PCKBD_SAVED_STATE_VERSION 5 60 60 61 61 … … 167 167 MOUSE_PROT_PS2 = 0, 168 168 MOUSE_PROT_IMPS2 = 3, 169 MOUSE_PROT_IMEX = 4, 170 MOUSE_PROT_LIFEBOOK = 5 169 MOUSE_PROT_IMEX = 4 171 170 }; 172 171 173 /** Mouse flags */ 172 /** @name Mouse flags */ 173 /** @{ */ 174 /** IMEX horizontal scroll-wheel mode is active */ 174 175 # define MOUSE_REPORT_HORIZONTAL 0x01 175 176 /** @name Extended mouse button values for Lifebook mode177 * @{ */178 /** Downwards scrollwheel movement of one step. Doesn't affect the mouse179 * buttons */180 # define MOUSE_EXT_VSCROLL_DN 4181 /** Upwards scrollwheel movement of one step. */182 # define MOUSE_EXT_VSCROLL_UP 5183 /** Leftwards scrollwheel movement of one step. */184 # define MOUSE_EXT_HSCROLL_BW 6185 /** Rightwards scrollwheel movement of one step. */186 # define MOUSE_EXT_HSCROLL_FW 7187 176 /** @} */ 188 177 … … 225 214 uint8_t mouse_sample_rate; 226 215 uint8_t mouse_wrap; 227 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 =IMEX */216 uint8_t mouse_type; /* MOUSE_PROT_PS2, *_IMPS/2, *_IMEX */ 228 217 uint8_t mouse_detect_state; 229 218 int32_t mouse_dx; /* current values, needed for 'poll' mode */ … … 232 221 int32_t mouse_dw; 233 222 int32_t mouse_flags; 234 uint32_t mouse_cx; /** @todo r=bird: cx/cy? aren't these absolute coordinates? 'c' usually means 'count of'. mouse_abs_x or just mouse_x would probably be clearer. */235 uint32_t mouse_cy;236 223 uint8_t mouse_buttons; 237 224 uint8_t mouse_buttons_reported; 238 uint8_t mouse_last_button;239 225 240 226 /** Pointer to the device instance - RC. */ … … 679 665 } 680 666 681 static bool kbd_mouse_test_set_button(KBDState *s, unsigned cIndex)682 {683 unsigned fButtonMask = 1 << (cIndex - 1);684 685 AssertReturn(3 <= cIndex && cIndex <= 5, false);686 if ( (s->mouse_buttons & fButtonMask)687 && !(s->mouse_buttons_reported & fButtonMask))688 {689 s->mouse_last_button = cIndex;690 kbd_mouse_set_reported_buttons(s, fButtonMask, 0x1c);691 return true;692 }693 return false;694 }695 696 static bool kbd_mouse_test_clear_last_button(KBDState *s)697 {698 unsigned fButtonMask = 1 << (s->mouse_last_button - 1);699 700 if ( s->mouse_last_button != 0701 && !(s->mouse_buttons & fButtonMask))702 {703 s->mouse_last_button = 0;704 kbd_mouse_set_reported_buttons(s, 0, fButtonMask);705 return true;706 }707 return false;708 }709 710 667 /** 711 668 * Send a single relative packet in 3-byte PS/2 format, optionally with our … … 723 680 { 724 681 int aux = fToCmdQueue ? 1 : 2; 725 int dx1 = 726 : s->mouse_dx > 0 ? RT_MIN(s->mouse_dx, 255) : 0;727 int dy1 = 728 : s->mouse_dy > 0 ? RT_MIN(s->mouse_dy, 255) : 0;682 int dx1 = s->mouse_dx < 0 ? RT_MAX(s->mouse_dx, -256) 683 : RT_MIN(s->mouse_dx, 255); 684 int dy1 = s->mouse_dy < 0 ? RT_MAX(s->mouse_dy, -256) 685 : RT_MIN(s->mouse_dy, 255); 729 686 unsigned int b; 730 687 unsigned fButtonsPacked; … … 733 690 s->mouse_dy -= dy1; 734 691 kbd_mouse_set_reported_buttons(s, fButtonsLow, 0x03); 735 /* When we are not in lifebook mode, we just set the third bit 736 * in the first packet byte if the middle button is pressed, 737 * as per the PS/2 protocol. */ 738 if (s->mouse_type != MOUSE_PROT_LIFEBOOK) 739 { 740 fButtonsPacked = (s->mouse_buttons & 0x04 ? 0x04 : 0); 741 kbd_mouse_set_reported_buttons(s, s->mouse_buttons, 0x04); 742 } 743 else 744 { 745 if (kbd_mouse_test_set_button(s, 3)) 746 fButtonsPacked = 1; 747 else if (kbd_mouse_test_set_button(s, 4)) 748 fButtonsPacked = 2; 749 else if (kbd_mouse_test_set_button(s, 5)) 750 fButtonsPacked = 3; 751 /* Release event for buttons in the range 3-5. */ 752 else if (kbd_mouse_test_clear_last_button(s)) 753 fButtonsPacked = 0; 754 else if (s->mouse_dz < 0) 755 { 756 ++s->mouse_dz; 757 fButtonsPacked = MOUSE_EXT_VSCROLL_DN; 758 } 759 else if (s->mouse_dz > 0) 760 { 761 --s->mouse_dz; 762 fButtonsPacked = MOUSE_EXT_VSCROLL_UP; 763 } 764 else if (s->mouse_dw < 0) 765 { 766 ++s->mouse_dw; 767 fButtonsPacked = MOUSE_EXT_HSCROLL_BW; 768 } 769 else if (s->mouse_dw > 0) 770 { 771 --s->mouse_dw; 772 fButtonsPacked = MOUSE_EXT_HSCROLL_FW; 773 } 774 else 775 fButtonsPacked = s->mouse_last_button; 776 } 692 fButtonsPacked = (s->mouse_buttons & 0x04 ? 0x04 : 0); 693 kbd_mouse_set_reported_buttons(s, s->mouse_buttons, 0x04); 777 694 LogRel3(("%s: dx1=%d, dy1=%d, fButtonsLow=0x%x, fButtonsPacked=0x%x\n", 778 695 __PRETTY_FUNCTION__, dx1, dy1, fButtonsLow, fButtonsPacked)); … … 788 705 int aux = fToCmdQueue ? 1 : 2; 789 706 790 int dz1 = 791 : s->mouse_dz > 0 ? RT_MIN(s->mouse_dz, 127) : 0;707 int dz1 = s->mouse_dz < 0 ? RT_MAX(s->mouse_dz, -127) 708 : RT_MIN(s->mouse_dz, 127); 792 709 s->mouse_dz -= dz1; 793 710 kbd_queue(s, dz1 & 0xff, aux); … … 800 717 if (s->mouse_dw) 801 718 { 802 int dw1 = s->mouse_dw < 0 ? RT_MAX(s->mouse_dw, -32)803 : s->mouse_dw > 0 ? RT_MIN(s->mouse_dw, 32) : 0;719 int dw1 = s->mouse_dw < 0 ? RT_MAX(s->mouse_dw, -31) 720 : RT_MIN(s->mouse_dw, 32); 804 721 s->mouse_dw -= dw1; 805 722 kbd_queue(s, 0x40 | (dw1 & 0x3f), aux); … … 807 724 else if (s->mouse_flags & MOUSE_REPORT_HORIZONTAL && s->mouse_dz) 808 725 { 809 int dz1 = s->mouse_dz < 0 ? RT_MAX(s->mouse_dz, -32)810 : s->mouse_dz > 0 ? RT_MIN(s->mouse_dz, 32) : 0;726 int dz1 = s->mouse_dz < 0 ? RT_MAX(s->mouse_dz, -31) 727 : RT_MIN(s->mouse_dz, 32); 811 728 s->mouse_dz -= dz1; 812 729 kbd_queue(s, 0x80 | (dz1 & 0x3f), aux); … … 814 731 else 815 732 { 816 int dz1 = s->mouse_dz < 0 ? RT_MAX(s->mouse_dz, -8)817 : s->mouse_dz > 0 ? RT_MIN(s->mouse_dz, 8) : 0;733 int dz1 = s->mouse_dz < 0 ? RT_MAX(s->mouse_dz, -7) 734 : RT_MIN(s->mouse_dz, 8); 818 735 s->mouse_dz -= dz1; 819 736 kbd_mouse_set_reported_buttons(s, s->mouse_buttons, 0x18); … … 829 746 * event queue)? 830 747 */ 831 static void kbd_mouse_send_ rel_packet(KBDState *s, bool fToCmdQueue)748 static void kbd_mouse_send_packet(KBDState *s, bool fToCmdQueue) 832 749 { 833 750 kbd_mouse_send_rel3_packet(s, fToCmdQueue); … … 838 755 } 839 756 840 /** 841 * Send a single absolute packet in 6-byte lifebook format to the PS/2 842 * controller. 843 * @param s keyboard state object 844 * @param fToCmdQueue Which queue. 845 */ 846 static void kbd_mouse_send_abs_packet(KBDState *s, bool fToCmdQueue) 847 { 848 int aux = fToCmdQueue ? 1 : 2; 849 unsigned cx1 = s->mouse_cx * 4095 / 0xffff; 850 unsigned cy1 = 4095 - (s->mouse_cy * 4095 / 0xffff); 851 unsigned fButtons = s->mouse_buttons & 0x03; 852 unsigned int b[6]; 853 854 LogRel3(("%s: cx1=%d, cy1=%d, fButtons=0x%x\n", __PRETTY_FUNCTION__, 855 cx1, cy1, fButtons)); 856 b[0] = fButtons; 857 Assert((b[0] & 0xf8) == 0); 858 kbd_queue(s, b[0], aux); 859 b[1] = ((cy1 << 2) & 0xc0) | (cx1 >> 6); 860 kbd_queue(s, b[1], aux); 861 b[2] = ((cx1 << 2) & 0xc0) | (cx1 & 0x3f); 862 Assert(((b[2] & 0x30) << 2) == (b[2] & 0xc0)); 863 kbd_queue(s, b[2], aux); 864 b[3] = 0xc0; 865 kbd_queue(s, b[3], aux); /* This byte is really wasted in the protocol */ 866 b[4] = ((cx1 << 2) & 0xc0) | (cy1 >> 6); 867 Assert((b[4] & 0xc0) == (b[2] & 0xc0)); 868 kbd_queue(s, b[4], aux); 869 b[5] = ((cy1 << 2) & 0xc0) | (cy1 & 0x3f); 870 Assert( (((b[5] & 0x30) << 2) == (b[1] & 0xc0)) 871 && ((b[5] & 0xc0) == (b[1] & 0xc0))); 872 kbd_queue(s, b[5], aux); 873 } 874 875 static bool kbd_mouse_rel_unreported(KBDState *s) 757 static bool kbd_mouse_unreported(KBDState *s) 876 758 { 877 759 return s->mouse_dx … … 882 764 } 883 765 884 /**885 * Send a single packet in (IM)PS/2, IMEX or Lifebook format to the PS/2886 * controller.887 * @param s keyboard state object888 * @param fToCmdQueue is this the result of a poll on the mouse controller?889 */890 static void kbd_mouse_send_packet(KBDState *s, bool fToCmdQueue)891 {892 if ( kbd_mouse_rel_unreported(s)893 || (s->mouse_type != MOUSE_PROT_LIFEBOOK))894 kbd_mouse_send_rel_packet(s, fToCmdQueue);895 else896 kbd_mouse_send_abs_packet(s, fToCmdQueue);897 }898 899 766 #ifdef IN_RING3 900 767 static size_t kbd_mouse_event_queue_free(KBDState *s) … … 920 787 s->mouse_dz += dz; 921 788 if ( ( (s->mouse_type == MOUSE_PROT_IMEX) 922 && s->mouse_flags & MOUSE_REPORT_HORIZONTAL) 923 || (s->mouse_type == MOUSE_PROT_LIFEBOOK)) 789 && s->mouse_flags & MOUSE_REPORT_HORIZONTAL)) 924 790 s->mouse_dw += dw; 925 791 s->mouse_buttons = buttons_state; … … 927 793 /* if not remote, send event. Multiple events are sent if 928 794 too big deltas */ 929 while ( kbd_mouse_ rel_unreported(s)795 while ( kbd_mouse_unreported(s) 930 796 && kbd_mouse_event_queue_free(s) > 4) 931 kbd_mouse_send_rel_packet(s, false); 932 } 933 934 static void pc_kbd_mouse_event_abs(void *opaque, unsigned cx, unsigned cy) 935 { 936 LogRel3(("%s: cx=%d, cy=%d\n", __PRETTY_FUNCTION__, cx, cy)); 937 KBDState *s = (KBDState*)opaque; 938 939 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) 940 return; 941 942 if (s->mouse_type != MOUSE_PROT_LIFEBOOK) 943 return; 944 945 s->mouse_cx = cx; 946 s->mouse_cy = cy; 947 948 if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && 949 (s->mouse_event_queue.count < (MOUSE_EVENT_QUEUE_SIZE - 4))) 950 /* if not remote, send event */ 951 kbd_mouse_send_abs_packet(s, false); 797 kbd_mouse_send_packet(s, false); 952 798 } 953 799 #endif /* IN_RING3 */ … … 1124 970 kbd_queue(s, AUX_ACK, 1); 1125 971 } 1126 else if (val == 6) /* Lifebook off magic knock */1127 {1128 #ifdef IN_RING31129 LogRelFlowFunc(("switching mouse device to basic PS/2 mode\n"));1130 s->mouse_type = MOUSE_PROT_PS2;1131 s->Mouse.pDrv->pfnAbsModeChange(s->Mouse.pDrv, false);1132 #else1133 return VINF_IOM_HC_IOPORT_WRITE;1134 #endif1135 kbd_queue(s, AUX_NACK, 1);1136 }1137 else if (val == 8) /* Lifebook on magic knock */1138 {1139 #ifdef IN_RING31140 LogRelFlowFunc(("switching mouse device to touch screen mode\n"));1141 s->mouse_type = MOUSE_PROT_LIFEBOOK;1142 s->Mouse.pDrv->pfnAbsModeChange(s->Mouse.pDrv, true);1143 #else1144 return VINF_IOM_HC_IOPORT_WRITE;1145 #endif1146 kbd_queue(s, AUX_NACK, 1);1147 }1148 972 else 1149 973 kbd_queue(s, AUX_NACK, 1); … … 1228 1052 s->mouse_wrap = 0; 1229 1053 s->mouse_type = MOUSE_PROT_PS2; 1230 if (s->Mouse.pDrv)1231 s->Mouse.pDrv->pfnAbsModeChange(s->Mouse.pDrv, false);1232 1054 s->mouse_detect_state = 0; 1233 1055 s->mouse_dx = 0; … … 1236 1058 s->mouse_dw = 0; 1237 1059 s->mouse_flags = 0; 1238 s->mouse_cx = 0x8000;1239 s->mouse_cy = 0x8000;1240 1060 s->mouse_buttons = 0; 1241 1061 s->mouse_buttons_reported = 0; 1242 s->mouse_last_button = 0;1243 1062 q = &s->queue; 1244 1063 q->rptr = 0; … … 1278 1097 qemu_put_be32s(f, &s->mouse_dw); 1279 1098 qemu_put_be32s(f, &s->mouse_flags); 1280 qemu_put_be32s(f, &s->mouse_cx);1281 qemu_put_be32s(f, &s->mouse_cy);1282 1099 qemu_put_8s(f, &s->mouse_buttons); 1283 1100 qemu_put_8s(f, &s->mouse_buttons_reported); 1284 qemu_put_8s(f, &s->mouse_last_button);1285 1101 1286 1102 /* XXX: s->scancode_set isn't being saved, but we only really support set 2, … … 1316 1132 { 1317 1133 uint32_t u32, i; 1134 uint8_t u8Dummy; 1135 uint32_t u32Dummy; 1318 1136 int rc; 1319 1137 KBDState *s = (KBDState*)opaque; 1320 1138 1139 #if 0 1140 /** @todo enable this and remove the "if (version_id == 4)" code at some 1141 * later time */ 1142 /* Version 4 was never created by any publicly released version of VBox */ 1143 AssertReturn(version_id != 4, VERR_NOT_SUPPORTED); 1144 #endif 1321 1145 if (version_id < 2 || version_id > PCKBD_SAVED_STATE_VERSION) 1322 1146 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; … … 1332 1156 qemu_get_8s(f, &s->mouse_wrap); 1333 1157 qemu_get_8s(f, &s->mouse_type); 1334 if (s->mouse_type == MOUSE_PROT_LIFEBOOK && s->Mouse.pDrv)1335 s->Mouse.pDrv->pfnAbsModeChange(s->Mouse.pDrv, true);1336 1158 qemu_get_8s(f, &s->mouse_detect_state); 1337 1159 qemu_get_be32s(f, (uint32_t *)&s->mouse_dx); … … 1344 1166 } 1345 1167 qemu_get_8s(f, &s->mouse_buttons); 1168 if (version_id == 4) 1169 { 1170 SSMR3GetU32(f, &u32Dummy); 1171 SSMR3GetU32(f, &u32Dummy); 1172 } 1346 1173 if (version_id > 3) 1347 {1348 SSMR3GetU32(f, &s->mouse_cx);1349 SSMR3GetU32(f, &s->mouse_cy);1350 1174 SSMR3GetU8(f, &s->mouse_buttons_reported); 1351 SSMR3GetU8(f, &s->mouse_last_button);1352 }1175 if (version_id == 4) 1176 SSMR3GetU8(f, &u8Dummy); 1353 1177 s->queue.count = 0; 1354 1178 s->queue.rptr = 0; … … 1678 1502 static DECLCALLBACK(int) kbdMousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtons) 1679 1503 { 1680 KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Mouse.IPort); 1681 int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 1682 AssertReleaseRC(rc); 1683 1684 if (uX != pThis->mouse_cx || uY != pThis->mouse_cy) 1685 pc_kbd_mouse_event_abs(pThis, uX, uY); 1686 if (iDeltaZ || iDeltaW || fButtons != pThis->mouse_buttons) 1687 pc_kbd_mouse_event(pThis, 0, 0, iDeltaZ, iDeltaW, fButtons); 1688 1689 PDMCritSectLeave(&pThis->CritSect); 1690 return VINF_SUCCESS; 1504 AssertFailedReturn(VERR_NOT_SUPPORTED); 1691 1505 } 1692 1506
Note:
See TracChangeset
for help on using the changeset viewer.