comparison src/events/SDL_mouse.c @ 1671:89f7510fe17a SDL-1.3

Moved the cursor handling into the mouse code. Added support for multiple mice, potentially dynamically added and removed.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 09 Jun 2006 06:42:42 +0000
parents eef792d31de8
children 7688a73b25b1
comparison
equal deleted inserted replaced
1670:eef792d31de8 1671:89f7510fe17a
24 /* General mouse handling code for SDL */ 24 /* General mouse handling code for SDL */
25 25
26 #include "SDL_events.h" 26 #include "SDL_events.h"
27 #include "SDL_events_c.h" 27 #include "SDL_events_c.h"
28 #include "SDL_mouse_c.h" 28 #include "SDL_mouse_c.h"
29 #include "default_cursor.h"
29 30
30 31
31 static int SDL_num_mice; 32 static int SDL_num_mice;
32 static int SDL_current_mouse; 33 static int SDL_current_mouse;
33 static SDL_Mouse *SDL_mice; 34 static SDL_Mouse **SDL_mice;
34 35
35 36
36 /* Public functions */ 37 /* Public functions */
37 int 38 int
38 SDL_MouseInit(void) 39 SDL_MouseInit(void)
39 { 40 {
40 return (0); 41 return (0);
41 } 42 }
42 43
43 int 44 SDL_Mouse *
44 SDL_AddMouse(SDL_WindowID focus, int x, int y, Uint8 buttonstate) 45 SDL_GetMouse(int index)
45 { 46 {
46 SDL_Mouse *new_mice; 47 if (index < 0 || index >= SDL_num_mice) {
47 int index; 48 return NULL;
48 SDL_Mouse *mouse; 49 }
49 50 return SDL_mice[index];
50 new_mice = 51 }
51 (SDL_Mouse *) SDL_realloc(SDL_mice, 52
52 (SDL_num_mice + 1) * sizeof(*new_mice)); 53 int
53 if (!new_mice) { 54 SDL_AddMouse(const SDL_Mouse * mouse, int index)
55 {
56 SDL_Mouse **mice;
57 SDL_Cursor *cursor;
58 int selected_mouse;
59
60 /* Add the mouse to the list of mice */
61 if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
62 mice =
63 (SDL_Mouse **) SDL_realloc(SDL_mice,
64 (SDL_num_mice + 1) * sizeof(*mice));
65 if (!mice) {
66 SDL_OutOfMemory();
67 return -1;
68 }
69
70 SDL_mice = mice;
71 index = SDL_num_mice++;
72 }
73 SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
74 if (!SDL_mice[index]) {
54 SDL_OutOfMemory(); 75 SDL_OutOfMemory();
55 return -1; 76 return -1;
56 } 77 }
57 78 *SDL_mice[index] = *mouse;
58 index = SDL_num_mice++; 79
59 mouse = &SDL_mice[index]; 80 /* Create the default cursor for the mouse */
60 mouse->focus = focus; 81 SDL_mice[index]->cursor_shown = SDL_TRUE;
61 mouse->x = x; 82 selected_mouse = SDL_SelectMouse(index);
62 mouse->y = y; 83 SDL_mice[index]->cur_cursor = NULL;
63 mouse->xdelta = 0; 84 SDL_mice[index]->def_cursor =
64 mouse->ydelta = 0; 85 SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
65 mouse->buttonstate = buttonstate; 86 DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
87 SDL_SetCursor(SDL_mice[index]->def_cursor);
88 SDL_SelectMouse(selected_mouse);
66 89
67 return index; 90 return index;
68 } 91 }
69 92
70 SDL_Mouse * 93 void
71 SDL_GetMouse(int index) 94 SDL_DelMouse(int index)
72 { 95 {
73 if (index < 0 || index >= SDL_num_mice) { 96 SDL_Mouse *mouse = SDL_GetMouse(index);
74 return NULL; 97
75 } 98 if (!mouse) {
76 return &SDL_mice[index]; 99 return;
100 }
101
102 mouse->def_cursor = NULL;
103 while (mouse->cursors) {
104 SDL_FreeCursor(mouse->cursors);
105 }
106
107 if (mouse->FreeMouse) {
108 mouse->FreeMouse(mouse);
109 }
110 SDL_free(mouse);
111
112 SDL_mice[index] = NULL;
113 }
114
115 void
116 SDL_ResetMouse(int index)
117 {
118 SDL_Mouse *mouse = SDL_GetMouse(index);
119
120 if (!mouse) {
121 return;
122 }
123
124 /* FIXME */
77 } 125 }
78 126
79 void 127 void
80 SDL_MouseQuit(void) 128 SDL_MouseQuit(void)
81 { 129 {
130 int i;
131
132 for (i = 0; i < SDL_num_mice; ++i) {
133 SDL_DelMouse(i);
134 }
82 SDL_num_mice = 0; 135 SDL_num_mice = 0;
83 SDL_current_mouse = 0; 136 SDL_current_mouse = 0;
84 137
85 if (SDL_mice) { 138 if (SDL_mice) {
86 SDL_free(SDL_mice); 139 SDL_free(SDL_mice);
199 #endif 252 #endif
200 return 0; 253 return 0;
201 } 254 }
202 255
203 /* Update internal mouse state */ 256 /* Update internal mouse state */
257 mouse->x = x;
258 mouse->y = y;
204 mouse->xdelta += xrel; 259 mouse->xdelta += xrel;
205 mouse->ydelta += yrel; 260 mouse->ydelta += yrel;
261
262 /* Move the mouse cursor, if needed */
263 if (mouse->MoveCursor && mouse->cur_cursor) {
264 mouse->MoveCursor(mouse->cur_cursor);
265 }
206 266
207 /* Post the event, if desired */ 267 /* Post the event, if desired */
208 posted = 0; 268 posted = 0;
209 if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) { 269 if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) {
210 SDL_Event event; 270 SDL_Event event;
223 } 283 }
224 return posted; 284 return posted;
225 } 285 }
226 286
227 int 287 int
228 SDL_PrivateMouseButton(int index, SDL_WindowID windowID, Uint8 state, 288 SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state,
229 Uint8 button) 289 Uint8 button)
230 { 290 {
231 SDL_Mouse *mouse = SDL_GetMouse(index); 291 SDL_Mouse *mouse = SDL_GetMouse(index);
232 int posted; 292 int posted;
233 Uint8 type; 293 Uint8 type;
234 294
280 } 340 }
281 } 341 }
282 return posted; 342 return posted;
283 } 343 }
284 344
345 void
346 SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
347 {
348 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
349
350 if (!mouse) {
351 return;
352 }
353
354 if (mouse->WarpMouse) {
355 mouse->WarpMouse(mouse, windowID, x, y);
356 } else {
357 SDL_SendMouseMotion(SDL_current_mouse, windowID, 0, x, y);
358 }
359 }
360
361 SDL_Cursor *
362 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
363 int w, int h, int hot_x, int hot_y)
364 {
365 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
366 SDL_Surface *surface;
367 SDL_Cursor *cursor;
368 int x, y;
369 Uint32 *pixel;
370 Uint8 datab, maskb;
371 const Uint32 black = 0xFF000000;
372 const Uint32 white = 0xFFFFFFFF;
373 const Uint32 transparent = 0x00000000;
374
375 if (!mouse) {
376 SDL_SetError("No mice are initialized");
377 return NULL;
378 }
379
380 if (!mouse->CreateCursor) {
381 SDL_SetError("Current mouse doesn't have cursor support");
382 return NULL;
383 }
384
385 /* Sanity check the hot spot */
386 if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
387 SDL_SetError("Cursor hot spot doesn't lie within cursor");
388 return NULL;
389 }
390
391 /* Make sure the width is a multiple of 8 */
392 w = ((w + 7) & ~7);
393
394 /* Create the surface from a bitmap */
395 surface =
396 SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
397 0xFF000000);
398 if (!surface) {
399 return NULL;
400 }
401 for (y = 0; y < h; ++y) {
402 pixel =
403 (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch +
404 x * 4);
405 for (x = 0; x < w; ++x) {
406 if ((x % 8) == 0) {
407 datab = *data++;
408 maskb = *mask++;
409 }
410 if (maskb & 0x80) {
411 *pixel++ = (datab & 0x80) ? black : white;
412 } else {
413 *pixel++ = (datab & 0x80) ? black : transparent;
414 }
415 datab <<= 1;
416 maskb <<= 1;
417 }
418 }
419
420 cursor = mouse->CreateCursor(surface, hot_x, hot_y);
421 if (cursor) {
422 cursor->mouse = mouse;
423 cursor->next = mouse->cursors;
424 mouse->cursors = cursor;
425 }
426
427 SDL_FreeSurface(surface);
428
429 return cursor;
430 }
431
432 /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
433 if this is desired for any reason. This is used when setting
434 the video mode and when the SDL window gains the mouse focus.
435 */
436 void
437 SDL_SetCursor(SDL_Cursor * cursor)
438 {
439 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
440
441 if (!mouse) {
442 SDL_SetError("No mice are initialized");
443 return;
444 }
445
446 /* Set the new cursor */
447 if (cursor) {
448 /* Make sure the cursor is still valid for this mouse */
449 SDL_Cursor *found;
450 for (found = mouse->cursors; found; found = found->next) {
451 if (found == cursor) {
452 break;
453 }
454 }
455 if (!found) {
456 SDL_SetError("Cursor not associated with the current mouse");
457 return;
458 }
459 mouse->cur_cursor = cursor;
460 } else {
461 cursor = mouse->cur_cursor;
462 }
463
464 if (cursor && mouse->cursor_shown) {
465 if (mouse->ShowCursor) {
466 mouse->ShowCursor(cursor);
467 }
468 } else {
469 if (mouse->ShowCursor) {
470 mouse->ShowCursor(NULL);
471 }
472 }
473 }
474
475 SDL_Cursor *
476 SDL_GetCursor(void)
477 {
478 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
479
480 if (!mouse) {
481 return NULL;
482 }
483 return mouse->cur_cursor;
484 }
485
486 void
487 SDL_FreeCursor(SDL_Cursor * cursor)
488 {
489 SDL_Mouse *mouse;
490 SDL_Cursor *curr, *prev;
491
492 if (!cursor) {
493 return;
494 }
495 mouse = cursor->mouse;
496
497 if (cursor == mouse->def_cursor) {
498 return;
499 }
500 if (cursor == mouse->cur_cursor) {
501 SDL_SetCursor(mouse->def_cursor);
502 }
503
504 for (prev = NULL, curr = mouse->cursors; curr;
505 prev = curr, curr = curr->next) {
506 if (curr == cursor) {
507 if (prev) {
508 prev->next = curr->next;
509 } else {
510 mouse->cursors = curr->next;
511 }
512
513 if (mouse->FreeCursor) {
514 mouse->FreeCursor(curr);
515 }
516 return;
517 }
518 }
519 }
520
521 int
522 SDL_ShowCursor(int toggle)
523 {
524 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
525 SDL_bool shown;
526
527 if (!mouse) {
528 return 0;
529 }
530
531 shown = mouse->cursor_shown;
532 if (toggle >= 0) {
533 if (toggle) {
534 mouse->cursor_shown = SDL_TRUE;
535 } else {
536 mouse->cursor_shown = SDL_FALSE;
537 }
538 if (mouse->cursor_shown != shown) {
539 SDL_SetCursor(NULL);
540 }
541 }
542 return shown;
543 }
544
285 /* vi: set ts=4 sw=4 expandtab: */ 545 /* vi: set ts=4 sw=4 expandtab: */