comparison src/video/win32/SDL_win32mouse.c @ 2710:44e49d3fa6cf

Final merge of Google Summer of Code 2008 work... Many-mouse and tablet support by Szymon Wilczek, mentored by Ryan C. Gordon Everything concerning the project is noted on the wiki: http://wilku.ravenlord.ws/doku.php?id=start
author Sam Lantinga <slouken@libsdl.org>
date Mon, 25 Aug 2008 06:33:00 +0000
parents c121d94672cb
children 0e2b65f32298
comparison
equal deleted inserted replaced
2709:fd3f0f1147e7 2710:44e49d3fa6cf
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 18
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21 */ 21 */
22
23 /* we need to define it, so that raw input is included*/
24
25 #if (_WIN32_WINNT < 0x0501)
26 #undef _WIN32_WINNT
27 #define _WIN32_WINNT 0x0501
28 #endif
29
22 #include "SDL_config.h" 30 #include "SDL_config.h"
23 31
24 #include "SDL_win32video.h" 32 #include "SDL_win32video.h"
25 33
26 #include "../../events/SDL_mouse_c.h" 34 #include "../../events/SDL_mouse_c.h"
35
36 #include <wintab.h>
37
38 #define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
39 #define PACKETMODE 0
40 #include <pktdef.h>
41 extern HANDLE *mice;
42 extern int total_mice;
43 extern int tablet;
27 44
28 void 45 void
29 WIN_InitMouse(_THIS) 46 WIN_InitMouse(_THIS)
30 { 47 {
48 int index = 0;
49 RAWINPUTDEVICELIST *deviceList = NULL;
50 int devCount = 0;
51 int i;
52 int tmp = 0;
53 char *buffer = NULL;
54 char *tab = "wacom"; /* since windows does't give us handles to tablets, we have to detect a tablet by it's name */
55 const char *rdp = "rdp_mou";
31 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 56 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
32 SDL_Mouse mouse; 57
33 58 /* we're checking for the number of rawinput devices */
34 SDL_zero(mouse); 59 if (GetRawInputDeviceList(NULL, &devCount, sizeof(RAWINPUTDEVICELIST))) {
35 data->mouse = SDL_AddMouse(&mouse, -1); 60 return;
61 }
62
63 deviceList = SDL_malloc(sizeof(RAWINPUTDEVICELIST) * devCount);
64
65 /* we're getting the raw input device list */
66 GetRawInputDeviceList(deviceList, &devCount, sizeof(RAWINPUTDEVICELIST));
67 mice = SDL_malloc(devCount * sizeof(HANDLE));
68
69 /* we're getting the details of the devices */
70 for (i = 0; i < devCount; ++i) {
71 int is_rdp = 0;
72 int j;
73 int k;
74 char *default_device_name = "Pointing device xx";
75 const char *reg_key_root = "System\\CurrentControlSet\\Enum\\";
76 char *device_name = SDL_malloc(256 * sizeof(char));
77 char *key_name = NULL;
78 char *tmp_name = NULL;
79 LONG rc = 0;
80 HKEY hkey;
81 DWORD regtype = REG_SZ;
82 DWORD out = 256 * sizeof(char);
83 SDL_Mouse mouse;
84 int l;
85 if (deviceList[i].dwType != RIM_TYPEMOUSE) { /* if a device isn't a mouse type we don't want it */
86 continue;
87 }
88 if (GetRawInputDeviceInfoA
89 (deviceList[i].hDevice, RIDI_DEVICENAME, NULL, &tmp) < 0) {
90 continue;
91 }
92 buffer = SDL_malloc((tmp + 1) * sizeof(char));
93 key_name = SDL_malloc(tmp + sizeof(reg_key_root) * sizeof(char));
94
95 /* we're getting the device registry path and polishing it to get it's name,
96 surely there must be an easier way, but we haven't found it yet */
97 if (GetRawInputDeviceInfoA
98 (deviceList[i].hDevice, RIDI_DEVICENAME, buffer, &tmp) < 0) {
99 continue;
100 }
101 buffer += 4;
102 tmp -= 4;
103 tmp_name = buffer;
104 for (j = 0; j < tmp; ++j) {
105 if (*tmp_name == '#') {
106 *tmp_name = '\\';
107 }
108
109 else if (*tmp_name == '{') {
110 break;
111 }
112 ++tmp_name;
113 }
114 *tmp_name = '\0';
115 SDL_memcpy(key_name, reg_key_root, SDL_strlen(reg_key_root));
116 SDL_memcpy(key_name + (SDL_strlen(reg_key_root)), buffer, j + 1);
117 l = SDL_strlen(key_name);
118 is_rdp = 0;
119 if (l >= 7) {
120 for (j = 0; j < l - 7; ++j) {
121 for (k = 0; k < 7; ++k) {
122 if (rdp[k] !=
123 SDL_tolower((unsigned char) key_name[j + k])) {
124 break;
125 }
126 }
127 if (k == 7) {
128 is_rdp = 1;
129 break;
130 }
131 }
132 }
133 if (is_rdp == 1) {
134 SDL_free(buffer);
135 SDL_free(key_name);
136 SDL_free(device_name);
137 is_rdp = 0;
138 continue;
139 }
140
141 /* we're opening the registry key to get the mouse name */
142 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &hkey);
143 if (rc != ERROR_SUCCESS) {
144 SDL_memcpy(device_name, default_device_name,
145 SDL_strlen(default_device_name));
146 }
147 rc = RegQueryValueExA(hkey, "DeviceDesc", NULL, &regtype, device_name,
148 &out);
149 RegCloseKey(hkey);
150 if (rc != ERROR_SUCCESS) {
151 SDL_memcpy(device_name, default_device_name,
152 SDL_strlen(default_device_name));
153 }
154
155 /* we're saving the handle to the device */
156 mice[index] = deviceList[i].hDevice;
157 SDL_zero(mouse);
158 SDL_SetMouseIndexId(index, index);
159 l = SDL_strlen(device_name);
160
161 /* we're checking if the device isn't by any chance a tablet */
162 if (tablet == -1) {
163 for (j = 0; j < l - 5; ++j) {
164 for (k = 0; k < 5; ++k) {
165 if (tab[k] !=
166 SDL_tolower((unsigned char) device_name[j + k])) {
167 break;
168 }
169 }
170 if (k == 5) {
171 tablet = index;
172 break;
173 }
174 }
175 }
176
177 /* if it's a tablet, let's read it's maximum and minimum pressure */
178 if (tablet == index) {
179 AXIS pressure;
180 int cursors;
181 WTInfo(WTI_DEVICES, DVC_NPRESSURE, &pressure);
182 WTInfo(WTI_DEVICES, DVC_NCSRTYPES, &cursors);
183 data->mouse =
184 SDL_AddMouse(&mouse, index, device_name, pressure.axMax,
185 pressure.axMin, cursors);
186 } else {
187 data->mouse = SDL_AddMouse(&mouse, index, device_name, 0, 0, 1);
188 }
189 ++index;
190 SDL_free(buffer);
191 SDL_free(key_name);
192 }
193 total_mice = index;
194 SDL_free(deviceList);
36 } 195 }
37 196
38 void 197 void
39 WIN_QuitMouse(_THIS) 198 WIN_QuitMouse(_THIS)
40 { 199 {
41 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 200 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
42 201
43 SDL_DelMouse(data->mouse); 202 /* let's delete all of the mice */
203 SDL_MouseQuit();
44 } 204 }
45 205
46 /* vi: set ts=4 sw=4 expandtab: */ 206 /* vi: set ts=4 sw=4 expandtab: */