Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
552 lines (466 loc) · 12.4 KB

SDL_mouse.c

File metadata and controls

552 lines (466 loc) · 12.4 KB
 
Apr 26, 2001
Apr 26, 2001
1
/*
Apr 8, 2011
Apr 8, 2011
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Apr 26, 2001
Apr 26, 2001
20
*/
Feb 21, 2006
Feb 21, 2006
21
#include "SDL_config.h"
Apr 26, 2001
Apr 26, 2001
22
23
24
25
26
/* General mouse handling code for SDL */
#include "SDL_events.h"
#include "SDL_events_c.h"
Jul 10, 2006
Jul 10, 2006
27
#include "default_cursor.h"
Jan 21, 2010
Jan 21, 2010
28
#include "../video/SDL_sysvideo.h"
Apr 26, 2001
Apr 26, 2001
29
30
Feb 21, 2011
Feb 21, 2011
31
/* The mouse state */
May 10, 2010
May 10, 2010
32
static SDL_Mouse SDL_mouse;
Jul 10, 2006
Jul 10, 2006
33
34
May 10, 2010
May 10, 2010
35
/* Public functions */
Jul 10, 2006
Jul 10, 2006
36
int
May 10, 2010
May 10, 2010
37
SDL_MouseInit(void)
Jul 10, 2006
Jul 10, 2006
38
{
Feb 22, 2011
Feb 22, 2011
39
40
41
42
SDL_Mouse *mouse = SDL_GetMouse();
mouse->cursor_shown = SDL_TRUE;
May 10, 2010
May 10, 2010
43
return (0);
Jul 10, 2006
Jul 10, 2006
44
45
}
Feb 28, 2011
Feb 28, 2011
46
47
48
49
50
51
52
53
54
55
56
void
SDL_SetDefaultCursor(SDL_Cursor * cursor)
{
SDL_Mouse *mouse = SDL_GetMouse();
mouse->def_cursor = cursor;
if (!mouse->cur_cursor) {
SDL_SetCursor(cursor);
}
}
Feb 21, 2011
Feb 21, 2011
57
58
59
60
61
62
SDL_Mouse *
SDL_GetMouse(void)
{
return &SDL_mouse;
}
Jan 21, 2010
Jan 21, 2010
63
SDL_Window *
May 10, 2010
May 10, 2010
64
SDL_GetMouseFocus(void)
Aug 20, 2002
Aug 20, 2002
65
{
Feb 21, 2011
Feb 21, 2011
66
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
67
68
return mouse->focus;
Aug 20, 2002
Aug 20, 2002
69
70
}
Jul 10, 2006
Jul 10, 2006
71
void
May 10, 2010
May 10, 2010
72
SDL_SetMouseFocus(SDL_Window * window)
Jul 10, 2006
Jul 10, 2006
73
{
Feb 21, 2011
Feb 21, 2011
74
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
75
May 10, 2010
May 10, 2010
76
if (mouse->focus == window) {
Jul 10, 2006
Jul 10, 2006
77
78
79
80
81
return;
}
/* See if the current window has lost focus */
if (mouse->focus) {
May 10, 2010
May 10, 2010
82
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
Jul 10, 2006
Jul 10, 2006
83
84
}
Jan 21, 2010
Jan 21, 2010
85
mouse->focus = window;
Jul 10, 2006
Jul 10, 2006
86
87
if (mouse->focus) {
May 10, 2010
May 10, 2010
88
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
Jul 10, 2006
Jul 10, 2006
89
90
91
92
}
}
int
Jul 6, 2010
Jul 6, 2010
93
SDL_SendMouseMotion(SDL_Window * window, int relative, int x, int y)
Jul 10, 2006
Jul 10, 2006
94
{
Feb 21, 2011
Feb 21, 2011
95
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
96
97
98
int posted;
int xrel;
int yrel;
Dec 8, 2008
Dec 8, 2008
99
int x_max = 0, y_max = 0;
Jul 10, 2006
Jul 10, 2006
100
Jul 6, 2010
Jul 6, 2010
101
102
103
104
if (window) {
SDL_SetMouseFocus(window);
}
Aug 25, 2008
Aug 25, 2008
105
/* the relative motion is calculated regarding the system cursor last position */
Dec 6, 2008
Dec 6, 2008
106
107
108
if (relative) {
xrel = x;
yrel = y;
Dec 8, 2008
Dec 8, 2008
109
110
x = (mouse->last_x + x);
y = (mouse->last_y + y);
Dec 6, 2008
Dec 6, 2008
111
} else {
Dec 8, 2008
Dec 8, 2008
112
113
xrel = x - mouse->last_x;
yrel = y - mouse->last_y;
Dec 6, 2008
Dec 6, 2008
114
}
Aug 25, 2008
Aug 25, 2008
115
Jul 10, 2006
Jul 10, 2006
116
117
/* Drop events that don't change state */
if (!xrel && !yrel) {
Jan 29, 2006
Jan 29, 2006
118
#if 0
Jul 10, 2006
Jul 10, 2006
119
printf("Mouse event didn't change state - dropped!\n");
Jan 29, 2006
Jan 29, 2006
120
#endif
Jul 10, 2006
Jul 10, 2006
121
122
123
return 0;
}
Aug 25, 2008
Aug 25, 2008
124
125
/* Update internal mouse coordinates */
if (mouse->relative_mode == SDL_FALSE) {
Jul 10, 2006
Jul 10, 2006
126
127
mouse->x = x;
mouse->y = y;
Aug 25, 2008
Aug 25, 2008
128
} else {
Dec 8, 2008
Dec 8, 2008
129
130
131
mouse->x += xrel;
mouse->y += yrel;
}
Dec 7, 2008
Dec 7, 2008
132
Dec 8, 2008
Dec 8, 2008
133
SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
Feb 21, 2011
Feb 21, 2011
134
135
--x_max;
--y_max;
Dec 7, 2008
Dec 7, 2008
136
Dec 8, 2008
Dec 8, 2008
137
138
/* make sure that the pointers find themselves inside the windows */
/* only check if mouse->xmax is set ! */
Feb 21, 2011
Feb 21, 2011
139
if (mouse->x > x_max) {
Dec 8, 2008
Dec 8, 2008
140
mouse->x = x_max;
Feb 21, 2011
Feb 21, 2011
141
142
}
if (mouse->x < 0) {
Dec 8, 2008
Dec 8, 2008
143
144
145
mouse->x = 0;
}
Feb 21, 2011
Feb 21, 2011
146
if (mouse->y > y_max) {
Dec 8, 2008
Dec 8, 2008
147
mouse->y = y_max;
Feb 21, 2011
Feb 21, 2011
148
149
}
if (mouse->y < 0) {
Dec 8, 2008
Dec 8, 2008
150
mouse->y = 0;
Jul 10, 2006
Jul 10, 2006
151
}
Dec 8, 2008
Dec 8, 2008
152
Jul 10, 2006
Jul 10, 2006
153
154
155
mouse->xdelta += xrel;
mouse->ydelta += yrel;
May 10, 2010
May 10, 2010
156
#if 0 /* FIXME */
Jul 10, 2006
Jul 10, 2006
157
158
159
160
161
/* Move the mouse cursor, if needed */
if (mouse->cursor_shown && !mouse->relative_mode &&
mouse->MoveCursor && mouse->cur_cursor) {
mouse->MoveCursor(mouse->cur_cursor);
}
May 10, 2010
May 10, 2010
162
#endif
Jul 10, 2006
Jul 10, 2006
163
164
165
/* Post the event, if desired */
posted = 0;
May 10, 2010
May 10, 2010
166
if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) {
Jul 10, 2006
Jul 10, 2006
167
168
SDL_Event event;
event.motion.type = SDL_MOUSEMOTION;
May 10, 2010
May 10, 2010
169
event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
Jul 10, 2006
Jul 10, 2006
170
171
172
event.motion.state = mouse->buttonstate;
event.motion.x = mouse->x;
event.motion.y = mouse->y;
Jun 9, 2009
Jun 9, 2009
173
174
event.motion.xrel = xrel;
event.motion.yrel = yrel;
Jul 10, 2006
Jul 10, 2006
175
176
posted = (SDL_PushEvent(&event) > 0);
}
Apr 28, 2009
Apr 28, 2009
177
178
mouse->last_x = mouse->x;
mouse->last_y = mouse->y;
Jul 10, 2006
Jul 10, 2006
179
180
181
182
return posted;
}
int
Jul 6, 2010
Jul 6, 2010
183
SDL_SendMouseButton(SDL_Window * window, Uint8 state, Uint8 button)
Jul 10, 2006
Jul 10, 2006
184
{
Feb 21, 2011
Feb 21, 2011
185
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
186
int posted;
Mar 25, 2010
Mar 25, 2010
187
Uint32 type;
Jul 10, 2006
Jul 10, 2006
188
Jul 6, 2010
Jul 6, 2010
189
190
191
192
if (window) {
SDL_SetMouseFocus(window);
}
Jul 10, 2006
Jul 10, 2006
193
194
195
196
197
198
199
200
201
202
203
/* Figure out which event to perform */
switch (state) {
case SDL_PRESSED:
if (mouse->buttonstate & SDL_BUTTON(button)) {
/* Ignore this event, no state change */
return 0;
}
type = SDL_MOUSEBUTTONDOWN;
mouse->buttonstate |= SDL_BUTTON(button);
break;
case SDL_RELEASED:
Aug 26, 2008
Aug 26, 2008
204
if (!(mouse->buttonstate & SDL_BUTTON(button))) {
Aug 25, 2008
Aug 25, 2008
205
206
207
/* Ignore this event, no state change */
return 0;
}
Jul 10, 2006
Jul 10, 2006
208
209
210
211
212
213
214
215
216
217
type = SDL_MOUSEBUTTONUP;
mouse->buttonstate &= ~SDL_BUTTON(button);
break;
default:
/* Invalid state -- bail */
return 0;
}
/* Post the event, if desired */
posted = 0;
Mar 25, 2010
Mar 25, 2010
218
if (SDL_GetEventState(type) == SDL_ENABLE) {
Jul 10, 2006
Jul 10, 2006
219
220
221
222
223
224
SDL_Event event;
event.type = type;
event.button.state = state;
event.button.button = button;
event.button.x = mouse->x;
event.button.y = mouse->y;
Jan 21, 2010
Jan 21, 2010
225
event.button.windowID = mouse->focus ? mouse->focus->id : 0;
Jul 10, 2006
Jul 10, 2006
226
227
228
229
230
231
posted = (SDL_PushEvent(&event) > 0);
}
return posted;
}
int
Jul 6, 2010
Jul 6, 2010
232
SDL_SendMouseWheel(SDL_Window * window, int x, int y)
Jul 10, 2006
Jul 10, 2006
233
{
Feb 21, 2011
Feb 21, 2011
234
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
235
236
int posted;
Jul 6, 2010
Jul 6, 2010
237
238
239
240
if (window) {
SDL_SetMouseFocus(window);
}
May 10, 2010
May 10, 2010
241
if (!x && !y) {
Jul 10, 2006
Jul 10, 2006
242
243
244
245
246
return 0;
}
/* Post the event, if desired */
posted = 0;
Mar 25, 2010
Mar 25, 2010
247
if (SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE) {
Jul 10, 2006
Jul 10, 2006
248
249
SDL_Event event;
event.type = SDL_MOUSEWHEEL;
May 10, 2010
May 10, 2010
250
event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
Jul 6, 2007
Jul 6, 2007
251
252
event.wheel.x = x;
event.wheel.y = y;
Jul 10, 2006
Jul 10, 2006
253
254
255
256
257
258
posted = (SDL_PushEvent(&event) > 0);
}
return posted;
}
void
May 10, 2010
May 10, 2010
259
SDL_MouseQuit(void)
Jul 10, 2006
Jul 10, 2006
260
{
May 10, 2010
May 10, 2010
261
}
Jul 10, 2006
Jul 10, 2006
262
May 10, 2010
May 10, 2010
263
264
265
Uint8
SDL_GetMouseState(int *x, int *y)
{
Feb 21, 2011
Feb 21, 2011
266
SDL_Mouse *mouse = SDL_GetMouse();
May 10, 2010
May 10, 2010
267
268
269
270
271
272
if (x) {
*x = mouse->x;
}
if (y) {
*y = mouse->y;
Jul 10, 2006
Jul 10, 2006
273
}
May 10, 2010
May 10, 2010
274
275
276
277
278
279
return mouse->buttonstate;
}
Uint8
SDL_GetRelativeMouseState(int *x, int *y)
{
Feb 21, 2011
Feb 21, 2011
280
SDL_Mouse *mouse = SDL_GetMouse();
May 10, 2010
May 10, 2010
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
if (x) {
*x = mouse->xdelta;
}
if (y) {
*y = mouse->ydelta;
}
mouse->xdelta = 0;
mouse->ydelta = 0;
return mouse->buttonstate;
}
void
SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
{
Feb 21, 2011
Feb 21, 2011
296
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
297
298
if (mouse->WarpMouse) {
Feb 21, 2011
Feb 21, 2011
299
mouse->WarpMouse(window, x, y);
Jul 10, 2006
Jul 10, 2006
300
} else {
Jul 6, 2010
Jul 6, 2010
301
SDL_SendMouseMotion(window, 0, x, y);
May 10, 2010
May 10, 2010
302
303
304
305
306
307
}
}
int
SDL_SetRelativeMouseMode(SDL_bool enabled)
{
Feb 21, 2011
Feb 21, 2011
308
SDL_Mouse *mouse = SDL_GetMouse();
May 10, 2010
May 10, 2010
309
Feb 28, 2011
Feb 28, 2011
310
311
312
313
314
315
316
317
318
319
320
321
if (enabled == mouse->relative_mode) {
return 0;
}
if (!mouse->SetRelativeMouseMode) {
SDL_Unsupported();
return -1;
}
if (mouse->SetRelativeMouseMode(enabled) < 0) {
return -1;
}
May 10, 2010
May 10, 2010
322
323
324
325
326
327
328
/* Set the relative mode */
mouse->relative_mode = enabled;
if (!enabled) {
/* Restore the expected mouse position */
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
Jul 10, 2006
Jul 10, 2006
329
}
May 10, 2010
May 10, 2010
330
Feb 28, 2011
Feb 28, 2011
331
332
333
/* Flush pending mouse motion */
SDL_FlushEvent(SDL_MOUSEMOTION);
May 10, 2010
May 10, 2010
334
335
336
337
338
339
340
341
342
/* Update cursor visibility */
SDL_SetCursor(NULL);
return 0;
}
SDL_bool
SDL_GetRelativeMouseMode()
{
Feb 21, 2011
Feb 21, 2011
343
SDL_Mouse *mouse = SDL_GetMouse();
May 10, 2010
May 10, 2010
344
345
return mouse->relative_mode;
Jul 10, 2006
Jul 10, 2006
346
347
348
349
350
351
}
SDL_Cursor *
SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
int w, int h, int hot_x, int hot_y)
{
Feb 21, 2011
Feb 21, 2011
352
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
353
354
355
356
SDL_Surface *surface;
SDL_Cursor *cursor;
int x, y;
Uint32 *pixel;
May 10, 2010
May 10, 2010
357
Uint8 datab = 0, maskb = 0;
Jul 10, 2006
Jul 10, 2006
358
359
360
361
362
363
364
365
const Uint32 black = 0xFF000000;
const Uint32 white = 0xFFFFFFFF;
const Uint32 transparent = 0x00000000;
/* Make sure the width is a multiple of 8 */
w = ((w + 7) & ~7);
/* Create the surface from a bitmap */
Mar 11, 2011
Mar 11, 2011
366
367
368
369
370
surface = SDL_CreateRGBSurface(0, w, h, 32,
0x00FF0000,
0x0000FF00,
0x000000FF,
0xFF000000);
Jul 10, 2006
Jul 10, 2006
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
if (!surface) {
return NULL;
}
for (y = 0; y < h; ++y) {
pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
for (x = 0; x < w; ++x) {
if ((x % 8) == 0) {
datab = *data++;
maskb = *mask++;
}
if (maskb & 0x80) {
*pixel++ = (datab & 0x80) ? black : white;
} else {
*pixel++ = (datab & 0x80) ? black : transparent;
}
datab <<= 1;
maskb <<= 1;
}
}
Mar 11, 2011
Mar 11, 2011
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
cursor = SDL_CreateColorCursor(surface, hot_x, hot_y);
SDL_FreeSurface(surface);
return cursor;
}
SDL_Cursor *
SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Surface *temp = NULL;
SDL_Cursor *cursor;
if (!surface) {
SDL_SetError("Passed NULL cursor surface");
return NULL;
}
if (!mouse->CreateCursor) {
SDL_SetError("Cursors are not currently supported");
return NULL;
}
/* Sanity check the hot spot */
if ((hot_x < 0) || (hot_y < 0) ||
(hot_x >= surface->w) || (hot_y >= surface->h)) {
SDL_SetError("Cursor hot spot doesn't lie within cursor");
return NULL;
}
if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
if (!temp) {
return NULL;
}
surface = temp;
}
Jul 10, 2006
Jul 10, 2006
430
431
432
433
434
435
cursor = mouse->CreateCursor(surface, hot_x, hot_y);
if (cursor) {
cursor->next = mouse->cursors;
mouse->cursors = cursor;
}
Mar 11, 2011
Mar 11, 2011
436
437
438
if (temp) {
SDL_FreeSurface(temp);
}
Jul 10, 2006
Jul 10, 2006
439
440
441
442
443
444
445
446
447
448
449
return cursor;
}
/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
if this is desired for any reason. This is used when setting
the video mode and when the SDL window gains the mouse focus.
*/
void
SDL_SetCursor(SDL_Cursor * cursor)
{
Feb 21, 2011
Feb 21, 2011
450
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
451
452
453
454
/* Set the new cursor */
if (cursor) {
/* Make sure the cursor is still valid for this mouse */
Feb 28, 2011
Feb 28, 2011
455
456
457
458
459
460
461
462
463
464
if (cursor != mouse->def_cursor) {
SDL_Cursor *found;
for (found = mouse->cursors; found; found = found->next) {
if (found == cursor) {
break;
}
}
if (!found) {
SDL_SetError("Cursor not associated with the current mouse");
return;
Jul 10, 2006
Jul 10, 2006
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
}
}
mouse->cur_cursor = cursor;
} else {
cursor = mouse->cur_cursor;
}
if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
if (mouse->ShowCursor) {
mouse->ShowCursor(cursor);
}
} else {
if (mouse->ShowCursor) {
mouse->ShowCursor(NULL);
}
}
}
SDL_Cursor *
SDL_GetCursor(void)
{
Feb 21, 2011
Feb 21, 2011
486
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
487
488
489
490
491
492
493
494
495
496
if (!mouse) {
return NULL;
}
return mouse->cur_cursor;
}
void
SDL_FreeCursor(SDL_Cursor * cursor)
{
Feb 21, 2011
Feb 21, 2011
497
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
SDL_Cursor *curr, *prev;
if (!cursor) {
return;
}
if (cursor == mouse->def_cursor) {
return;
}
if (cursor == mouse->cur_cursor) {
SDL_SetCursor(mouse->def_cursor);
}
for (prev = NULL, curr = mouse->cursors; curr;
prev = curr, curr = curr->next) {
if (curr == cursor) {
if (prev) {
prev->next = curr->next;
} else {
mouse->cursors = curr->next;
}
if (mouse->FreeCursor) {
mouse->FreeCursor(curr);
}
return;
}
}
Apr 26, 2001
Apr 26, 2001
526
527
}
Jul 10, 2006
Jul 10, 2006
528
529
int
SDL_ShowCursor(int toggle)
Apr 26, 2001
Apr 26, 2001
530
{
Feb 21, 2011
Feb 21, 2011
531
SDL_Mouse *mouse = SDL_GetMouse();
Jul 10, 2006
Jul 10, 2006
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
SDL_bool shown;
if (!mouse) {
return 0;
}
shown = mouse->cursor_shown;
if (toggle >= 0) {
if (toggle) {
mouse->cursor_shown = SDL_TRUE;
} else {
mouse->cursor_shown = SDL_FALSE;
}
if (mouse->cursor_shown != shown) {
SDL_SetCursor(NULL);
}
}
return shown;
Apr 26, 2001
Apr 26, 2001
550
551
}
Jul 10, 2006
Jul 10, 2006
552
/* vi: set ts=4 sw=4 expandtab: */