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