Mercurial > sdl-ios-xcode
annotate src/video/SDL_cursor.c @ 320:66f815c147ed
Date: Thu, 28 Mar 2002 09:20:03 +0200
From: "Mike Gorchak" <mike@malva.ua>
Subject: New QNX patch.
Hi !
1. Removed warning (possible bug) with invalid type, passing to the function
in ph_WarpedMotion.
2. Rewritten handler of Ph_WM_RESIZE message, now works, but buggy (old
handler doesn't work at all).
3. Added stub handler for Ph_WM_MAX (maximize) message.
4. Added more #ifdef HAVE_OPENGL to disable OpenGL stuff when it not needed.
5. Added support for SDL_NOFRAME and SDL_RESIZABLE flags (in OpenGL windows
too).
6. Added cosmetic changes, if no SDL_RESIZABLE flag defined, disable resize
handlers in window border and maximize button at caption.
7. Fixed my bug with invalid arguments count passed to PtCreateWidget call.
8. Fixed some palette problems.
9. Updated README.QNX file.
And I changed testgl.c test application:
10. Added in testgl.c application support for SDL_NOFRAME flag and
option -noframe.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 28 Mar 2002 16:20:10 +0000 |
parents | f6ffac90895c |
children | 5c74ac147358 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
113
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* General cursor handling code for SDL */ | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 | |
34 #include "SDL_mutex.h" | |
35 #include "SDL_error.h" | |
36 #include "SDL_video.h" | |
37 #include "SDL_mouse.h" | |
38 #include "SDL_blit.h" | |
39 #include "SDL_events_c.h" | |
40 #include "SDL_sysvideo.h" | |
41 #include "SDL_sysevents.h" | |
42 #include "SDL_cursor_c.h" | |
43 #include "SDL_pixels_c.h" | |
44 #include "default_cursor.h" | |
45 | |
46 /* These are static for our cursor handling code */ | |
47 volatile int SDL_cursorstate = CURSOR_VISIBLE; | |
48 SDL_Cursor *SDL_cursor = NULL; | |
49 static SDL_Cursor *SDL_defcursor = NULL; | |
50 SDL_mutex *SDL_cursorlock = NULL; | |
51 | |
52 /* Public functions */ | |
53 void SDL_CursorQuit(void) | |
54 { | |
55 if ( SDL_cursor != NULL ) { | |
56 SDL_Cursor *cursor; | |
57 | |
58 SDL_cursorstate &= ~CURSOR_VISIBLE; | |
59 if ( SDL_cursor != SDL_defcursor ) { | |
60 SDL_FreeCursor(SDL_cursor); | |
61 } | |
62 SDL_cursor = NULL; | |
63 if ( SDL_defcursor != NULL ) { | |
64 cursor = SDL_defcursor; | |
65 SDL_defcursor = NULL; | |
66 SDL_FreeCursor(cursor); | |
67 } | |
68 } | |
69 if ( SDL_cursorlock != NULL ) { | |
70 SDL_DestroyMutex(SDL_cursorlock); | |
71 SDL_cursorlock = NULL; | |
72 } | |
73 } | |
74 int SDL_CursorInit(Uint32 multithreaded) | |
75 { | |
76 /* We don't have mouse focus, and the cursor isn't drawn yet */ | |
77 SDL_cursorstate = CURSOR_VISIBLE; | |
78 | |
79 /* Create the default cursor */ | |
80 if ( SDL_defcursor == NULL ) { | |
81 SDL_defcursor = SDL_CreateCursor(default_cdata, default_cmask, | |
82 DEFAULT_CWIDTH, DEFAULT_CHEIGHT, | |
83 DEFAULT_CHOTX, DEFAULT_CHOTY); | |
84 SDL_SetCursor(SDL_defcursor); | |
85 } | |
86 | |
87 /* Create a lock if necessary */ | |
88 if ( multithreaded ) { | |
89 SDL_cursorlock = SDL_CreateMutex(); | |
90 } | |
91 | |
92 /* That's it! */ | |
93 return(0); | |
94 } | |
95 | |
96 /* Multi-thread support for cursors */ | |
97 #ifndef SDL_LockCursor | |
98 void SDL_LockCursor(void) | |
99 { | |
100 if ( SDL_cursorlock ) { | |
101 SDL_mutexP(SDL_cursorlock); | |
102 } | |
103 } | |
104 #endif | |
105 #ifndef SDL_UnlockCursor | |
106 void SDL_UnlockCursor(void) | |
107 { | |
108 if ( SDL_cursorlock ) { | |
109 SDL_mutexV(SDL_cursorlock); | |
110 } | |
111 } | |
112 #endif | |
113 | |
114 /* Software cursor drawing support */ | |
115 SDL_Cursor * SDL_CreateCursor (Uint8 *data, Uint8 *mask, | |
116 int w, int h, int hot_x, int hot_y) | |
117 { | |
118 SDL_VideoDevice *video = current_video; | |
119 int savelen; | |
120 int i; | |
121 SDL_Cursor *cursor; | |
122 | |
123 /* Make sure the width is a multiple of 8 */ | |
124 w = ((w+7)&~7); | |
125 | |
126 /* Sanity check the hot spot */ | |
127 if ( (hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h) ) { | |
128 SDL_SetError("Cursor hot spot doesn't lie within cursor"); | |
129 return(NULL); | |
130 } | |
131 | |
132 /* Allocate memory for the cursor */ | |
133 cursor = (SDL_Cursor *)malloc(sizeof *cursor); | |
134 if ( cursor == NULL ) { | |
135 SDL_OutOfMemory(); | |
136 return(NULL); | |
137 } | |
138 savelen = (w*4)*h; | |
139 cursor->area.x = 0; | |
140 cursor->area.y = 0; | |
141 cursor->area.w = w; | |
142 cursor->area.h = h; | |
143 cursor->hot_x = hot_x; | |
144 cursor->hot_y = hot_y; | |
145 cursor->data = (Uint8 *)malloc((w/8)*h*2); | |
146 cursor->mask = cursor->data+((w/8)*h); | |
147 cursor->save[0] = (Uint8 *)malloc(savelen*2); | |
148 cursor->save[1] = cursor->save[0] + savelen; | |
149 cursor->wm_cursor = NULL; | |
150 if ( ! cursor->data || ! cursor->save[0] ) { | |
151 SDL_FreeCursor(cursor); | |
152 SDL_OutOfMemory(); | |
153 return(NULL); | |
154 } | |
155 for ( i=((w/8)*h)-1; i>=0; --i ) { | |
156 cursor->data[i] = data[i]; | |
157 cursor->mask[i] = mask[i] | data[i]; | |
158 } | |
159 memset(cursor->save[0], 0, savelen*2); | |
160 | |
161 /* If the window manager gives us a good cursor, we're done! */ | |
162 if ( video->CreateWMCursor ) { | |
163 cursor->wm_cursor = video->CreateWMCursor(video, data, mask, | |
164 w, h, hot_x, hot_y); | |
165 } else { | |
166 cursor->wm_cursor = NULL; | |
167 } | |
168 return(cursor); | |
169 } | |
170 | |
171 /* SDL_SetCursor(NULL) can be used to force the cursor redraw, | |
172 if this is desired for any reason. This is used when setting | |
173 the video mode and when the SDL window gains the mouse focus. | |
174 */ | |
175 void SDL_SetCursor (SDL_Cursor *cursor) | |
176 { | |
177 SDL_VideoDevice *video = current_video; | |
178 SDL_VideoDevice *this = current_video; | |
179 | |
180 /* Make sure that the video subsystem has been initialized */ | |
181 if ( ! video ) { | |
182 return; | |
183 } | |
184 | |
185 /* Prevent the event thread from moving the mouse */ | |
186 SDL_LockCursor(); | |
187 | |
188 /* Set the new cursor */ | |
189 if ( cursor && (cursor != SDL_cursor) ) { | |
190 /* Erase the current mouse position */ | |
191 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { | |
192 SDL_EraseCursor(SDL_VideoSurface); | |
193 } else if ( video->MoveWMCursor ) { | |
194 /* If the video driver is moving the cursor directly, | |
195 it needs to hide the old cursor before (possibly) | |
196 showing the new one. (But don't erase NULL cursor) | |
197 */ | |
198 if ( SDL_cursor ) { | |
199 video->ShowWMCursor(this, NULL); | |
200 } | |
201 } | |
202 SDL_cursor = cursor; | |
203 } | |
204 | |
205 /* Draw the new mouse cursor */ | |
206 if ( SDL_cursor && (SDL_cursorstate&CURSOR_VISIBLE) ) { | |
207 /* Use window manager cursor if possible */ | |
208 if ( SDL_cursor->wm_cursor && | |
209 video->ShowWMCursor(this, SDL_cursor->wm_cursor) ) | |
210 SDL_cursorstate &= ~CURSOR_USINGSW; | |
211 else { | |
212 SDL_cursorstate |= CURSOR_USINGSW; | |
213 if ( video->ShowWMCursor ) { | |
214 video->ShowWMCursor(this, NULL); | |
215 } | |
216 { int x, y; | |
217 SDL_GetMouseState(&x, &y); | |
218 SDL_cursor->area.x = (x - SDL_cursor->hot_x); | |
219 SDL_cursor->area.y = (y - SDL_cursor->hot_y); | |
220 } | |
221 SDL_DrawCursor(SDL_VideoSurface); | |
222 } | |
223 } else { | |
224 /* Erase window manager mouse (cursor not visible) */ | |
225 if ( SDL_cursor && (SDL_cursorstate & CURSOR_USINGSW) ) { | |
226 SDL_EraseCursor(SDL_VideoSurface); | |
227 } else { | |
228 if ( video ) { | |
229 video->ShowWMCursor(this, NULL); | |
230 } | |
231 } | |
232 } | |
233 SDL_UnlockCursor(); | |
234 } | |
235 | |
236 SDL_Cursor * SDL_GetCursor (void) | |
237 { | |
238 return(SDL_cursor); | |
239 } | |
240 | |
241 void SDL_FreeCursor (SDL_Cursor *cursor) | |
242 { | |
243 if ( cursor ) { | |
244 if ( cursor == SDL_cursor ) { | |
245 SDL_SetCursor(SDL_defcursor); | |
246 } | |
247 if ( cursor != SDL_defcursor ) { | |
77
1e7e61b9b0f9
Don't crash if freeing a cursor after quit...
Sam Lantinga <slouken@lokigames.com>
parents:
1
diff
changeset
|
248 SDL_VideoDevice *video = current_video; |
1e7e61b9b0f9
Don't crash if freeing a cursor after quit...
Sam Lantinga <slouken@lokigames.com>
parents:
1
diff
changeset
|
249 SDL_VideoDevice *this = current_video; |
1e7e61b9b0f9
Don't crash if freeing a cursor after quit...
Sam Lantinga <slouken@lokigames.com>
parents:
1
diff
changeset
|
250 |
0 | 251 if ( cursor->data ) { |
252 free(cursor->data); | |
253 } | |
254 if ( cursor->save[0] ) { | |
255 free(cursor->save[0]); | |
256 } | |
77
1e7e61b9b0f9
Don't crash if freeing a cursor after quit...
Sam Lantinga <slouken@lokigames.com>
parents:
1
diff
changeset
|
257 if ( video && cursor->wm_cursor ) { |
0 | 258 video->FreeWMCursor(this, cursor->wm_cursor); |
259 } | |
260 free(cursor); | |
261 } | |
262 } | |
263 } | |
264 | |
265 int SDL_ShowCursor (int toggle) | |
266 { | |
267 int showing; | |
268 | |
269 showing = (SDL_cursorstate & CURSOR_VISIBLE); | |
270 if ( toggle >= 0 ) { | |
271 SDL_LockCursor(); | |
272 if ( toggle ) { | |
273 SDL_cursorstate |= CURSOR_VISIBLE; | |
274 } else { | |
275 SDL_cursorstate &= ~CURSOR_VISIBLE; | |
276 } | |
277 SDL_UnlockCursor(); | |
278 if ( (SDL_cursorstate & CURSOR_VISIBLE) != showing ) { | |
279 SDL_VideoDevice *video = current_video; | |
280 SDL_VideoDevice *this = current_video; | |
281 | |
282 SDL_SetCursor(NULL); | |
283 if ( video && video->CheckMouseMode ) { | |
284 video->CheckMouseMode(this); | |
285 } | |
286 } | |
287 } else { | |
288 /* Query current state */ ; | |
289 } | |
290 return(showing ? 1 : 0); | |
291 } | |
292 | |
293 void SDL_WarpMouse (Uint16 x, Uint16 y) | |
294 { | |
295 SDL_VideoDevice *video = current_video; | |
296 SDL_VideoDevice *this = current_video; | |
297 | |
298 /* This generates a mouse motion event */ | |
299 if ( video->WarpWMCursor ) { | |
300 video->WarpWMCursor(this, x, y); | |
301 } else { | |
302 x += (this->screen->offset % this->screen->pitch) / | |
303 this->screen->format->BytesPerPixel; | |
304 y += (this->screen->offset / this->screen->pitch); | |
305 SDL_PrivateMouseMotion(0, 0, x, y); | |
306 } | |
307 } | |
308 | |
309 void SDL_MoveCursor(int x, int y) | |
310 { | |
311 SDL_VideoDevice *video = current_video; | |
312 | |
313 /* Erase and update the current mouse position */ | |
314 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { | |
315 /* Erase and redraw mouse cursor in new position */ | |
316 SDL_LockCursor(); | |
317 SDL_EraseCursor(SDL_VideoSurface); | |
318 SDL_cursor->area.x = (x - SDL_cursor->hot_x); | |
319 SDL_cursor->area.y = (y - SDL_cursor->hot_y); | |
320 SDL_DrawCursor(SDL_VideoSurface); | |
321 SDL_UnlockCursor(); | |
322 } else if ( video->MoveWMCursor ) { | |
323 video->MoveWMCursor(video, x, y); | |
324 } | |
325 } | |
326 | |
327 /* Keep track of the current cursor colors */ | |
328 static int palette_changed = 1; | |
329 static Uint32 pixels8[2]; | |
330 | |
331 void SDL_CursorPaletteChanged(void) | |
332 { | |
333 palette_changed = 1; | |
334 } | |
335 | |
336 void SDL_MouseRect(SDL_Rect *area) | |
337 { | |
338 int clip_diff; | |
339 | |
340 *area = SDL_cursor->area; | |
341 if ( area->x < 0 ) { | |
342 area->w += area->x; | |
343 area->x = 0; | |
344 } | |
345 if ( area->y < 0 ) { | |
346 area->h += area->y; | |
347 area->y = 0; | |
348 } | |
349 clip_diff = (area->x+area->w)-SDL_VideoSurface->w; | |
350 if ( clip_diff > 0 ) { | |
113
e21ac1dd30f1
Fixed crash if mouse is outside of the screen bounds for some reason
Sam Lantinga <slouken@lokigames.com>
parents:
77
diff
changeset
|
351 area->w = area->w < clip_diff ? 0 : area->w-clip_diff; |
0 | 352 } |
353 clip_diff = (area->y+area->h)-SDL_VideoSurface->h; | |
354 if ( clip_diff > 0 ) { | |
113
e21ac1dd30f1
Fixed crash if mouse is outside of the screen bounds for some reason
Sam Lantinga <slouken@lokigames.com>
parents:
77
diff
changeset
|
355 area->h = area->h < clip_diff ? 0 : area->h-clip_diff; |
0 | 356 } |
357 } | |
358 | |
359 static void SDL_DrawCursorFast(SDL_Surface *screen, SDL_Rect *area) | |
360 { | |
361 const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 }; | |
362 int i, w, h; | |
363 Uint8 *data, datab; | |
364 Uint8 *mask, maskb; | |
365 | |
366 data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; | |
367 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; | |
368 switch (screen->format->BytesPerPixel) { | |
369 | |
370 case 1: { | |
371 Uint8 *dst; | |
372 int dstskip; | |
373 | |
374 if ( palette_changed ) { | |
375 pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255); | |
376 pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0); | |
377 palette_changed = 0; | |
378 } | |
379 dst = (Uint8 *)screen->pixels + | |
380 (SDL_cursor->area.y+area->y)*screen->pitch + | |
381 SDL_cursor->area.x; | |
382 dstskip = screen->pitch-area->w; | |
383 | |
384 for ( h=area->h; h; h-- ) { | |
385 for ( w=area->w/8; w; w-- ) { | |
386 maskb = *mask++; | |
387 datab = *data++; | |
388 for ( i=0; i<8; ++i ) { | |
389 if ( maskb & 0x80 ) { | |
390 *dst = pixels8[datab>>7]; | |
391 } | |
392 maskb <<= 1; | |
393 datab <<= 1; | |
394 dst++; | |
395 } | |
396 } | |
397 dst += dstskip; | |
398 } | |
399 } | |
400 break; | |
401 | |
402 case 2: { | |
403 Uint16 *dst; | |
404 int dstskip; | |
405 | |
406 dst = (Uint16 *)screen->pixels + | |
407 (SDL_cursor->area.y+area->y)*screen->pitch/2 + | |
408 SDL_cursor->area.x; | |
409 dstskip = (screen->pitch/2)-area->w; | |
410 | |
411 for ( h=area->h; h; h-- ) { | |
412 for ( w=area->w/8; w; w-- ) { | |
413 maskb = *mask++; | |
414 datab = *data++; | |
415 for ( i=0; i<8; ++i ) { | |
416 if ( maskb & 0x80 ) { | |
417 *dst = pixels[datab>>7]; | |
418 } | |
419 maskb <<= 1; | |
420 datab <<= 1; | |
421 dst++; | |
422 } | |
423 } | |
424 dst += dstskip; | |
425 } | |
426 } | |
427 break; | |
428 | |
429 case 3: { | |
430 Uint8 *dst; | |
431 int dstskip; | |
432 | |
433 dst = (Uint8 *)screen->pixels + | |
434 (SDL_cursor->area.y+area->y)*screen->pitch + | |
435 SDL_cursor->area.x*3; | |
436 dstskip = screen->pitch-area->w*3; | |
437 | |
438 for ( h=area->h; h; h-- ) { | |
439 for ( w=area->w/8; w; w-- ) { | |
440 maskb = *mask++; | |
441 datab = *data++; | |
442 for ( i=0; i<8; ++i ) { | |
443 if ( maskb & 0x80 ) { | |
444 memset(dst,pixels[datab>>7],3); | |
445 } | |
446 maskb <<= 1; | |
447 datab <<= 1; | |
448 dst += 3; | |
449 } | |
450 } | |
451 dst += dstskip; | |
452 } | |
453 } | |
454 break; | |
455 | |
456 case 4: { | |
457 Uint32 *dst; | |
458 int dstskip; | |
459 | |
460 dst = (Uint32 *)screen->pixels + | |
461 (SDL_cursor->area.y+area->y)*screen->pitch/4 + | |
462 SDL_cursor->area.x; | |
463 dstskip = (screen->pitch/4)-area->w; | |
464 | |
465 for ( h=area->h; h; h-- ) { | |
466 for ( w=area->w/8; w; w-- ) { | |
467 maskb = *mask++; | |
468 datab = *data++; | |
469 for ( i=0; i<8; ++i ) { | |
470 if ( maskb & 0x80 ) { | |
471 *dst = pixels[datab>>7]; | |
472 } | |
473 maskb <<= 1; | |
474 datab <<= 1; | |
475 dst++; | |
476 } | |
477 } | |
478 dst += dstskip; | |
479 } | |
480 } | |
481 break; | |
482 } | |
483 } | |
484 | |
485 static void SDL_DrawCursorSlow(SDL_Surface *screen, SDL_Rect *area) | |
486 { | |
487 const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 }; | |
488 int h; | |
489 int x, minx, maxx; | |
490 Uint8 *data, datab = 0; | |
491 Uint8 *mask, maskb = 0; | |
492 Uint8 *dst; | |
493 int dstbpp, dstskip; | |
494 | |
495 data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; | |
496 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; | |
497 dstbpp = screen->format->BytesPerPixel; | |
498 dst = (Uint8 *)screen->pixels + | |
499 (SDL_cursor->area.y+area->y)*screen->pitch + | |
500 SDL_cursor->area.x*dstbpp; | |
501 dstskip = screen->pitch-SDL_cursor->area.w*dstbpp; | |
502 | |
503 minx = area->x; | |
504 maxx = area->x+area->w; | |
505 if ( screen->format->BytesPerPixel == 1 ) { | |
506 if ( palette_changed ) { | |
507 pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255); | |
508 pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0); | |
509 palette_changed = 0; | |
510 } | |
511 for ( h=area->h; h; h-- ) { | |
512 for ( x=0; x<SDL_cursor->area.w; ++x ) { | |
513 if ( (x%8) == 0 ) { | |
514 maskb = *mask++; | |
515 datab = *data++; | |
516 } | |
517 if ( (x >= minx) && (x < maxx) ) { | |
518 if ( maskb & 0x80 ) { | |
519 memset(dst, pixels8[datab>>7], dstbpp); | |
520 } | |
521 } | |
522 maskb <<= 1; | |
523 datab <<= 1; | |
524 dst += dstbpp; | |
525 } | |
526 dst += dstskip; | |
527 } | |
528 } else { | |
529 for ( h=area->h; h; h-- ) { | |
530 for ( x=0; x<SDL_cursor->area.w; ++x ) { | |
531 if ( (x%8) == 0 ) { | |
532 maskb = *mask++; | |
533 datab = *data++; | |
534 } | |
535 if ( (x >= minx) && (x < maxx) ) { | |
536 if ( maskb & 0x80 ) { | |
537 memset(dst, pixels[datab>>7], dstbpp); | |
538 } | |
539 } | |
540 maskb <<= 1; | |
541 datab <<= 1; | |
542 dst += dstbpp; | |
543 } | |
544 dst += dstskip; | |
545 } | |
546 } | |
547 } | |
548 | |
549 /* This handles the ugly work of converting the saved cursor background from | |
550 the pixel format of the shadow surface to that of the video surface. | |
551 This is only necessary when blitting from a shadow surface of a different | |
552 pixel format than the video surface, and using a software rendered cursor. | |
553 */ | |
554 static void SDL_ConvertCursorSave(SDL_Surface *screen, int w, int h) | |
555 { | |
556 SDL_BlitInfo info; | |
557 SDL_loblit RunBlit; | |
558 | |
559 /* Make sure we can steal the blit mapping */ | |
560 if ( screen->map->dst != SDL_VideoSurface ) { | |
561 return; | |
562 } | |
563 | |
564 /* Set up the blit information */ | |
565 info.s_pixels = SDL_cursor->save[1]; | |
566 info.s_width = w; | |
567 info.s_height = h; | |
568 info.s_skip = 0; | |
569 info.d_pixels = SDL_cursor->save[0]; | |
570 info.d_width = w; | |
571 info.d_height = h; | |
572 info.d_skip = 0; | |
573 info.aux_data = screen->map->sw_data->aux_data; | |
574 info.src = screen->format; | |
575 info.table = screen->map->table; | |
576 info.dst = SDL_VideoSurface->format; | |
577 RunBlit = screen->map->sw_data->blit; | |
578 | |
579 /* Run the actual software blit */ | |
580 RunBlit(&info); | |
581 } | |
582 | |
583 void SDL_DrawCursorNoLock(SDL_Surface *screen) | |
584 { | |
585 SDL_Rect area; | |
586 | |
587 /* Get the mouse rectangle, clipped to the screen */ | |
588 SDL_MouseRect(&area); | |
589 if ( (area.w == 0) || (area.h == 0) ) { | |
590 return; | |
591 } | |
592 | |
593 /* Copy mouse background */ | |
594 { int w, h, screenbpp; | |
595 Uint8 *src, *dst; | |
596 | |
597 /* Set up the copy pointers */ | |
598 screenbpp = screen->format->BytesPerPixel; | |
599 if ( (screen == SDL_VideoSurface) || | |
600 FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { | |
601 dst = SDL_cursor->save[0]; | |
602 } else { | |
603 dst = SDL_cursor->save[1]; | |
604 } | |
605 src = (Uint8 *)screen->pixels + area.y * screen->pitch + | |
606 area.x * screenbpp; | |
607 | |
608 /* Perform the copy */ | |
609 w = area.w*screenbpp; | |
610 h = area.h; | |
611 while ( h-- ) { | |
612 memcpy(dst, src, w); | |
613 dst += w; | |
614 src += screen->pitch; | |
615 } | |
616 } | |
617 | |
618 /* Draw the mouse cursor */ | |
619 area.x -= SDL_cursor->area.x; | |
620 area.y -= SDL_cursor->area.y; | |
621 if ( (area.x == 0) && (area.w == SDL_cursor->area.w) ) { | |
622 SDL_DrawCursorFast(screen, &area); | |
623 } else { | |
624 SDL_DrawCursorSlow(screen, &area); | |
625 } | |
626 } | |
627 | |
628 void SDL_DrawCursor(SDL_Surface *screen) | |
629 { | |
630 /* Lock the screen if necessary */ | |
631 if ( screen == NULL ) { | |
632 return; | |
633 } | |
634 if ( SDL_MUSTLOCK(screen) ) { | |
635 if ( SDL_LockSurface(screen) < 0 ) { | |
636 return; | |
637 } | |
638 } | |
639 | |
640 SDL_DrawCursorNoLock(screen); | |
641 | |
642 /* Unlock the screen and update if necessary */ | |
643 if ( SDL_MUSTLOCK(screen) ) { | |
644 SDL_UnlockSurface(screen); | |
645 } | |
646 if ( (screen == SDL_VideoSurface) && | |
647 ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { | |
648 SDL_VideoDevice *video = current_video; | |
649 SDL_VideoDevice *this = current_video; | |
650 SDL_Rect area; | |
651 | |
652 SDL_MouseRect(&area); | |
653 | |
654 /* This can be called before a video mode is set */ | |
655 if ( video->UpdateRects ) { | |
656 video->UpdateRects(this, 1, &area); | |
657 } | |
658 } | |
659 } | |
660 | |
661 void SDL_EraseCursorNoLock(SDL_Surface *screen) | |
662 { | |
663 SDL_Rect area; | |
664 | |
665 /* Get the mouse rectangle, clipped to the screen */ | |
666 SDL_MouseRect(&area); | |
667 if ( (area.w == 0) || (area.h == 0) ) { | |
668 return; | |
669 } | |
670 | |
671 /* Copy mouse background */ | |
672 { int w, h, screenbpp; | |
673 Uint8 *src, *dst; | |
674 | |
675 /* Set up the copy pointers */ | |
676 screenbpp = screen->format->BytesPerPixel; | |
677 if ( (screen == SDL_VideoSurface) || | |
678 FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { | |
679 src = SDL_cursor->save[0]; | |
680 } else { | |
681 src = SDL_cursor->save[1]; | |
682 } | |
683 dst = (Uint8 *)screen->pixels + area.y * screen->pitch + | |
684 area.x * screenbpp; | |
685 | |
686 /* Perform the copy */ | |
687 w = area.w*screenbpp; | |
688 h = area.h; | |
689 while ( h-- ) { | |
690 memcpy(dst, src, w); | |
691 src += w; | |
692 dst += screen->pitch; | |
693 } | |
694 | |
695 /* Perform pixel conversion on cursor background */ | |
696 if ( src > SDL_cursor->save[1] ) { | |
697 SDL_ConvertCursorSave(screen, area.w, area.h); | |
698 } | |
699 } | |
700 } | |
701 | |
702 void SDL_EraseCursor(SDL_Surface *screen) | |
703 { | |
704 /* Lock the screen if necessary */ | |
705 if ( screen == NULL ) { | |
706 return; | |
707 } | |
708 if ( SDL_MUSTLOCK(screen) ) { | |
709 if ( SDL_LockSurface(screen) < 0 ) { | |
710 return; | |
711 } | |
712 } | |
713 | |
714 SDL_EraseCursorNoLock(screen); | |
715 | |
716 /* Unlock the screen and update if necessary */ | |
717 if ( SDL_MUSTLOCK(screen) ) { | |
718 SDL_UnlockSurface(screen); | |
719 } | |
720 if ( (screen == SDL_VideoSurface) && | |
721 ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { | |
722 SDL_VideoDevice *video = current_video; | |
723 SDL_VideoDevice *this = current_video; | |
724 SDL_Rect area; | |
725 | |
726 SDL_MouseRect(&area); | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
727 if ( video->UpdateRects ) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
728 video->UpdateRects(this, 1, &area); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
729 } |
0 | 730 } |
731 } | |
732 | |
733 /* Reset the cursor on video mode change | |
734 FIXME: Keep track of all cursors, and reset them all. | |
735 */ | |
736 void SDL_ResetCursor(void) | |
737 { | |
738 int savelen; | |
739 | |
740 if ( SDL_cursor ) { | |
741 savelen = SDL_cursor->area.w*4*SDL_cursor->area.h; | |
742 SDL_cursor->area.x = 0; | |
743 SDL_cursor->area.y = 0; | |
744 memset(SDL_cursor->save[0], 0, savelen); | |
745 } | |
746 } |