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: */