Mercurial > sdl-ios-xcode
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: */ |