Mercurial > sdl-ios-xcode
comparison src/events/SDL_mouse.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 | 003c1b5b07da |
children | c4e697245676 |
comparison
equal
deleted
inserted
replaced
2709:fd3f0f1147e7 | 2710:44e49d3fa6cf |
---|---|
26 #include "SDL_events.h" | 26 #include "SDL_events.h" |
27 #include "SDL_events_c.h" | 27 #include "SDL_events_c.h" |
28 #include "default_cursor.h" | 28 #include "default_cursor.h" |
29 | 29 |
30 | 30 |
31 static int SDL_num_mice; | 31 static int SDL_num_mice = 0; |
32 static int SDL_current_mouse; | 32 static int SDL_current_mouse = -1; |
33 static SDL_Mouse **SDL_mice; | 33 static SDL_Mouse **SDL_mice = NULL; |
34 static int *SDL_IdIndex = NULL; | |
35 static int SDL_highestId = -1; | |
36 static int last_x, last_y; /* the last reported x and y coordinates by the system cursor */ | |
37 int x_max, y_max; /* current window width and height */ | |
34 | 38 |
35 | 39 |
36 /* Public functions */ | 40 /* Public functions */ |
37 int | 41 int |
38 SDL_MouseInit(void) | 42 SDL_MouseInit(void) |
48 } | 52 } |
49 return SDL_mice[index]; | 53 return SDL_mice[index]; |
50 } | 54 } |
51 | 55 |
52 int | 56 int |
53 SDL_AddMouse(const SDL_Mouse * mouse, int index) | 57 SDL_SetMouseIndexId(int id, int index) |
58 { | |
59 if (id < 0) { | |
60 SDL_SetError("Invalid Mouse ID"); | |
61 return -1; | |
62 } | |
63 if (id > SDL_highestId) { | |
64 int *indexes; | |
65 indexes = (int *) SDL_realloc(SDL_IdIndex, (id + 1) * sizeof(int)); | |
66 if (!indexes) { | |
67 SDL_OutOfMemory(); | |
68 return -1; | |
69 } | |
70 SDL_IdIndex = indexes; | |
71 SDL_IdIndex[id] = index; | |
72 SDL_highestId = id; | |
73 } else { | |
74 SDL_IdIndex[id] = index; | |
75 } | |
76 return 1; | |
77 } | |
78 | |
79 SDL_Mouse * | |
80 SDL_GetMouseByID(int id) | |
81 { | |
82 if (id < 0 || id > SDL_highestId) { | |
83 return NULL; | |
84 } | |
85 return SDL_GetMouse(SDL_IdIndex[id]); | |
86 } | |
87 | |
88 int | |
89 SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name, int pressure_max, | |
90 int pressure_min, int ends) | |
54 { | 91 { |
55 SDL_Mouse **mice; | 92 SDL_Mouse **mice; |
56 int selected_mouse; | 93 int selected_mouse; |
94 int length; | |
57 | 95 |
58 /* Add the mouse to the list of mice */ | 96 /* Add the mouse to the list of mice */ |
59 if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) { | 97 if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) { |
60 mice = | 98 mice = |
61 (SDL_Mouse **) SDL_realloc(SDL_mice, | 99 (SDL_Mouse **) SDL_realloc(SDL_mice, |
73 SDL_OutOfMemory(); | 111 SDL_OutOfMemory(); |
74 return -1; | 112 return -1; |
75 } | 113 } |
76 *SDL_mice[index] = *mouse; | 114 *SDL_mice[index] = *mouse; |
77 | 115 |
78 /* Create the default cursor for the mouse */ | 116 /* we're setting the mouse properties */ |
117 length = 0; | |
118 length = SDL_strlen(name); | |
119 SDL_mice[index]->name = SDL_malloc((length + 1) * sizeof(char)); | |
120 SDL_strlcpy(SDL_mice[index]->name, name, length); | |
121 SDL_mice[index]->pressure_max = pressure_max; | |
122 SDL_mice[index]->pressure_min = pressure_min; | |
79 SDL_mice[index]->cursor_shown = SDL_TRUE; | 123 SDL_mice[index]->cursor_shown = SDL_TRUE; |
80 selected_mouse = SDL_SelectMouse(index); | 124 selected_mouse = SDL_SelectMouse(index); |
81 SDL_mice[index]->cur_cursor = NULL; | 125 SDL_mice[index]->cur_cursor = NULL; |
82 SDL_mice[index]->def_cursor = | 126 SDL_mice[index]->def_cursor = |
83 SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, | 127 SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, |
84 DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); | 128 DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); |
85 SDL_SetCursor(SDL_mice[index]->def_cursor); | 129 SDL_SetCursor(SDL_mice[index]->def_cursor); |
130 /* we're assuming that all mice are in the computer sensing zone */ | |
131 SDL_mice[index]->proximity = SDL_TRUE; | |
132 /* we're assuming that all mice are working in the absolute position mode | |
133 thanx to that, the users that don't want to use many mice don't have to | |
134 worry about anything */ | |
135 SDL_mice[index]->relative_mode = SDL_FALSE; | |
136 SDL_mice[index]->current_end = 0; | |
137 SDL_mice[index]->total_ends = ends; | |
86 SDL_SelectMouse(selected_mouse); | 138 SDL_SelectMouse(selected_mouse); |
87 | 139 |
88 return index; | 140 return index; |
89 } | 141 } |
90 | 142 |
96 if (!mouse) { | 148 if (!mouse) { |
97 return; | 149 return; |
98 } | 150 } |
99 | 151 |
100 mouse->def_cursor = NULL; | 152 mouse->def_cursor = NULL; |
153 SDL_free(mouse->name); | |
101 while (mouse->cursors) { | 154 while (mouse->cursors) { |
102 SDL_FreeCursor(mouse->cursors); | 155 SDL_FreeCursor(mouse->cursors); |
103 } | 156 } |
104 | 157 |
105 if (mouse->FreeMouse) { | 158 if (mouse->FreeMouse) { |
153 } | 206 } |
154 return SDL_current_mouse; | 207 return SDL_current_mouse; |
155 } | 208 } |
156 | 209 |
157 SDL_WindowID | 210 SDL_WindowID |
158 SDL_GetMouseFocusWindow() | 211 SDL_GetMouseFocusWindow(int index) |
159 { | 212 { |
160 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | 213 SDL_Mouse *mouse = SDL_GetMouse(index); |
161 | 214 |
162 if (!mouse) { | 215 if (!mouse) { |
163 return 0; | 216 return 0; |
164 } | 217 } |
165 return mouse->focus; | 218 return mouse->focus; |
175 return 1; | 228 return 1; |
176 } | 229 } |
177 } | 230 } |
178 | 231 |
179 int | 232 int |
180 SDL_SetRelativeMouseMode(SDL_bool enabled) | 233 SDL_SetRelativeMouseMode(int index, SDL_bool enabled) |
181 { | 234 { |
182 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | 235 SDL_Mouse *mouse = SDL_GetMouse(index); |
183 | 236 |
184 if (!mouse) { | 237 if (!mouse) { |
185 return -1; | 238 return -1; |
186 } | 239 } |
187 | 240 |
203 } | 256 } |
204 return 0; | 257 return 0; |
205 } | 258 } |
206 | 259 |
207 SDL_bool | 260 SDL_bool |
208 SDL_GetRelativeMouseMode() | 261 SDL_GetRelativeMouseMode(int index) |
209 { | 262 { |
210 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | 263 SDL_Mouse *mouse = SDL_GetMouse(index); |
211 | 264 |
212 if (!mouse) { | 265 if (!mouse) { |
213 return SDL_FALSE; | 266 return SDL_FALSE; |
214 } | 267 } |
215 return mouse->relative_mode; | 268 return mouse->relative_mode; |
216 } | 269 } |
217 | 270 |
218 Uint8 | 271 Uint8 |
219 SDL_GetMouseState(int *x, int *y) | 272 SDL_GetMouseState(int index, int *x, int *y) |
220 { | 273 { |
221 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | 274 SDL_Mouse *mouse = SDL_GetMouse(index); |
222 | 275 |
223 if (!mouse) { | 276 if (!mouse) { |
224 if (x) { | 277 if (x) { |
225 *x = 0; | 278 *x = 0; |
226 } | 279 } |
238 } | 291 } |
239 return mouse->buttonstate; | 292 return mouse->buttonstate; |
240 } | 293 } |
241 | 294 |
242 Uint8 | 295 Uint8 |
243 SDL_GetRelativeMouseState(int *x, int *y) | 296 SDL_GetRelativeMouseState(int index, int *x, int *y) |
244 { | 297 { |
245 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | 298 SDL_Mouse *mouse = SDL_GetMouse(index); |
246 | 299 |
247 if (!mouse) { | 300 if (!mouse) { |
248 if (x) { | 301 if (x) { |
249 *x = 0; | 302 *x = 0; |
250 } | 303 } |
264 mouse->ydelta = 0; | 317 mouse->ydelta = 0; |
265 return mouse->buttonstate; | 318 return mouse->buttonstate; |
266 } | 319 } |
267 | 320 |
268 void | 321 void |
269 SDL_SetMouseFocus(int index, SDL_WindowID windowID) | 322 SDL_SetMouseFocus(int id, SDL_WindowID windowID) |
270 { | 323 { |
271 SDL_Mouse *mouse = SDL_GetMouse(index); | 324 SDL_Mouse *mouse = SDL_GetMouseByID(id); |
272 int i; | 325 int i, index; |
273 SDL_bool focus; | 326 SDL_bool focus; |
274 | 327 |
275 if (!mouse || (mouse->focus == windowID)) { | 328 if (!mouse || (mouse->focus == windowID)) { |
276 return; | 329 return; |
277 } | 330 } |
331 | |
332 index = SDL_IdIndex[id]; | |
278 | 333 |
279 /* See if the current window has lost focus */ | 334 /* See if the current window has lost focus */ |
280 if (mouse->focus) { | 335 if (mouse->focus) { |
281 focus = SDL_FALSE; | 336 focus = SDL_FALSE; |
282 for (i = 0; i < SDL_num_mice; ++i) { | 337 for (i = 0; i < SDL_num_mice; ++i) { |
313 } | 368 } |
314 } | 369 } |
315 } | 370 } |
316 | 371 |
317 int | 372 int |
318 SDL_SendMouseMotion(int index, int relative, int x, int y) | 373 SDL_SendProximity(int id, int x, int y, int type) |
319 { | 374 { |
320 SDL_Mouse *mouse = SDL_GetMouse(index); | 375 SDL_Mouse *mouse = SDL_GetMouseByID(id); |
376 int posted = 0; | |
377 last_x = x; | |
378 last_y = y; | |
379 if (SDL_ProcessEvents[type] == SDL_ENABLE) { | |
380 SDL_Event event; | |
381 event.proximity.which = (Uint8) index; | |
382 event.proximity.x = x; | |
383 event.proximity.y = y; | |
384 event.proximity.cursor = mouse->current_end; | |
385 event.proximity.type = type; | |
386 posted = (SDL_PushEvent(&event) > 0); | |
387 if (type == SDL_PROXIMITYIN) { | |
388 mouse->proximity = SDL_TRUE; | |
389 } else { | |
390 mouse->proximity = SDL_FALSE; | |
391 } | |
392 } | |
393 return posted; | |
394 } | |
395 | |
396 int | |
397 SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure) | |
398 { | |
399 SDL_Mouse *mouse = SDL_GetMouseByID(id); | |
321 int posted; | 400 int posted; |
322 int xrel; | 401 int xrel; |
323 int yrel; | 402 int yrel; |
324 | 403 |
404 /* while using the relative mode and many windows, we have to be sure, | |
405 that the pointers find themselves inside the windows */ | |
406 if (x > x_max) { | |
407 x = x_max; | |
408 } | |
409 if (y > y_max) { | |
410 y = y_max; | |
411 } | |
412 | |
325 if (!mouse || mouse->flush_motion) { | 413 if (!mouse || mouse->flush_motion) { |
326 return 0; | 414 return 0; |
327 } | 415 } |
328 | 416 |
329 if (relative) { | 417 /* if the mouse is out of proximity we don't to want to have any motion from it */ |
330 /* Push the cursor around */ | 418 if (mouse->proximity == SDL_FALSE) { |
331 xrel = x; | 419 last_x = x; |
332 yrel = y; | 420 last_y = y; |
333 x = (mouse->x + xrel); | 421 return 0; |
334 y = (mouse->y + yrel); | 422 } |
335 } else { | 423 |
336 xrel = x - mouse->x; | 424 /* the relative motion is calculated regarding the system cursor last position */ |
337 yrel = y - mouse->y; | 425 |
338 } | 426 xrel = x - last_x; |
427 yrel = y - last_y; | |
339 | 428 |
340 /* Drop events that don't change state */ | 429 /* Drop events that don't change state */ |
341 if (!xrel && !yrel) { | 430 if (!xrel && !yrel) { |
342 #if 0 | 431 #if 0 |
343 printf("Mouse event didn't change state - dropped!\n"); | 432 printf("Mouse event didn't change state - dropped!\n"); |
344 #endif | 433 #endif |
345 return 0; | 434 return 0; |
346 } | 435 } |
347 | 436 |
348 /* Update internal mouse state */ | 437 /* Update internal mouse coordinates */ |
349 if (!mouse->relative_mode) { | 438 if (mouse->relative_mode == SDL_FALSE) { |
350 mouse->x = x; | 439 mouse->x = x; |
351 mouse->y = y; | 440 mouse->y = y; |
441 } else { | |
442 if (mouse->x + xrel > x_max) { | |
443 mouse->x = x_max; | |
444 } else if (mouse->x + xrel < 0) { | |
445 mouse->x = 0; | |
446 } else { | |
447 mouse->x += xrel; | |
448 } | |
449 if (mouse->y + yrel > y_max) { | |
450 mouse->y = y_max; | |
451 } else if (mouse->y + yrel < 0) { | |
452 mouse->y = 0; | |
453 } else { | |
454 mouse->y += yrel; | |
455 } | |
352 } | 456 } |
353 mouse->xdelta += xrel; | 457 mouse->xdelta += xrel; |
354 mouse->ydelta += yrel; | 458 mouse->ydelta += yrel; |
459 mouse->pressure = pressure; | |
355 | 460 |
356 /* Move the mouse cursor, if needed */ | 461 /* Move the mouse cursor, if needed */ |
357 if (mouse->cursor_shown && !mouse->relative_mode && | 462 if (mouse->cursor_shown && !mouse->relative_mode && |
358 mouse->MoveCursor && mouse->cur_cursor) { | 463 mouse->MoveCursor && mouse->cur_cursor) { |
359 mouse->MoveCursor(mouse->cur_cursor); | 464 mouse->MoveCursor(mouse->cur_cursor); |
360 } | 465 } |
361 | 466 |
362 /* Post the event, if desired */ | 467 /* Post the event, if desired */ |
363 posted = 0; | 468 posted = 0; |
364 if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) { | 469 if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE && |
470 mouse->proximity == SDL_TRUE) { | |
365 SDL_Event event; | 471 SDL_Event event; |
366 event.motion.type = SDL_MOUSEMOTION; | 472 event.motion.type = SDL_MOUSEMOTION; |
367 event.motion.which = (Uint8) index; | 473 event.motion.which = (Uint8) index; |
368 event.motion.state = mouse->buttonstate; | 474 event.motion.state = mouse->buttonstate; |
369 event.motion.x = mouse->x; | 475 event.motion.x = mouse->x; |
370 event.motion.y = mouse->y; | 476 event.motion.y = mouse->y; |
477 event.motion.pressure = mouse->pressure; | |
371 event.motion.xrel = xrel; | 478 event.motion.xrel = xrel; |
372 event.motion.yrel = yrel; | 479 event.motion.yrel = yrel; |
373 event.motion.windowID = mouse->focus; | 480 event.motion.windowID = mouse->focus; |
481 event.motion.pressure_max = mouse->pressure_max; | |
482 event.motion.pressure_min = mouse->pressure_min; | |
483 event.motion.cursor = mouse->current_end; | |
374 posted = (SDL_PushEvent(&event) > 0); | 484 posted = (SDL_PushEvent(&event) > 0); |
375 } | 485 } |
486 last_x = x; | |
487 last_y = y; | |
376 return posted; | 488 return posted; |
377 } | 489 } |
378 | 490 |
379 int | 491 int |
380 SDL_SendMouseButton(int index, Uint8 state, Uint8 button) | 492 SDL_SendMouseButton(int id, Uint8 state, Uint8 button) |
381 { | 493 { |
382 SDL_Mouse *mouse = SDL_GetMouse(index); | 494 SDL_Mouse *mouse = SDL_GetMouseByID(id); |
383 int posted; | 495 int posted; |
384 Uint8 type; | 496 Uint8 type; |
385 | 497 |
386 if (!mouse) { | 498 if (!mouse) { |
387 return 0; | 499 return 0; |
396 } | 508 } |
397 type = SDL_MOUSEBUTTONDOWN; | 509 type = SDL_MOUSEBUTTONDOWN; |
398 mouse->buttonstate |= SDL_BUTTON(button); | 510 mouse->buttonstate |= SDL_BUTTON(button); |
399 break; | 511 break; |
400 case SDL_RELEASED: | 512 case SDL_RELEASED: |
401 if (!(mouse->buttonstate & SDL_BUTTON(button))) { | |
402 /* Ignore this event, no state change */ | |
403 return 0; | |
404 } | |
405 type = SDL_MOUSEBUTTONUP; | 513 type = SDL_MOUSEBUTTONUP; |
406 mouse->buttonstate &= ~SDL_BUTTON(button); | 514 mouse->buttonstate &= ~SDL_BUTTON(button); |
407 break; | 515 break; |
408 default: | 516 default: |
409 /* Invalid state -- bail */ | 517 /* Invalid state -- bail */ |
461 | 569 |
462 if (mouse->WarpMouse) { | 570 if (mouse->WarpMouse) { |
463 mouse->WarpMouse(mouse, windowID, x, y); | 571 mouse->WarpMouse(mouse, windowID, x, y); |
464 } else { | 572 } else { |
465 SDL_SetMouseFocus(SDL_current_mouse, windowID); | 573 SDL_SetMouseFocus(SDL_current_mouse, windowID); |
466 SDL_SendMouseMotion(SDL_current_mouse, 0, x, y); | 574 SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0); |
467 } | 575 } |
468 } | 576 } |
469 | 577 |
470 SDL_Cursor * | 578 SDL_Cursor * |
471 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, | 579 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, |
647 } | 755 } |
648 } | 756 } |
649 return shown; | 757 return shown; |
650 } | 758 } |
651 | 759 |
760 char * | |
761 SDL_GetMouseName(int index) | |
762 { | |
763 SDL_Mouse *mouse = SDL_GetMouse(index); | |
764 if (!mouse) { | |
765 return NULL; | |
766 } | |
767 return mouse->name; | |
768 } | |
769 | |
770 void | |
771 SDL_UpdateCoordinates(int x, int y) | |
772 { | |
773 x_max = x; | |
774 y_max = y; | |
775 } | |
776 | |
777 void | |
778 SDL_ChangeEnd(int id, int end) | |
779 { | |
780 SDL_Mouse *mouse = SDL_GetMouseByID(id); | |
781 | |
782 if (mouse) { | |
783 mouse->current_end = end; | |
784 } | |
785 } | |
786 | |
787 int | |
788 SDL_GetCursorsNumber(int index) | |
789 { | |
790 SDL_Mouse *mouse = SDL_GetMouse(index); | |
791 | |
792 if (!mouse) { | |
793 return -1; | |
794 } | |
795 return mouse->total_ends; | |
796 } | |
797 | |
798 int | |
799 SDL_GetCurrentCursor(int index) | |
800 { | |
801 SDL_Mouse *mouse = SDL_GetMouse(index); | |
802 | |
803 if (!mouse) { | |
804 return -1; | |
805 } | |
806 return mouse->current_end; | |
807 } | |
808 | |
652 /* vi: set ts=4 sw=4 expandtab: */ | 809 /* vi: set ts=4 sw=4 expandtab: */ |