Mercurial > sdl-ios-xcode
annotate test/testwm.c @ 615:7ec821f3cbd0
Date: Thu, 17 Apr 2003 23:27:34 -0400
From: Darrell Walisser
Subject: Yet another OS X cursor bug
The synopsis:
1. Call SDL_ShowCursor(0);
2. Call SDL_SetVideoMode();
3. Call SDL_GetEvent();
3. Call SDL_ShowCursor(1);
The result: Sometimes the cursor doesn't come back! Ack! Oddly enough,
it does come back when mousing over the dock or clicking in the menu
bar. But that's besides the point.
The reason why this is happening is a flaw in the handling of
activation/deactivation events. The short explanation is that the
HideCursor() and ShowCursor() calls must be balanced, but if the cursor
was initially hidden, HideCursor() was called again on the activate
event - so now the next ShowCursor() fails (as does the next, and the
next, for some reason).
So, here's the patch. All it does is keep track of the
HideCursor()/ShowCursor() calls so that they will always be balanced.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 20 Apr 2003 05:41:16 +0000 |
parents | a30b17e09cc0 |
children | 3eddf51b649b |
rev | line source |
---|---|
0 | 1 |
2 /* Test out the window manager interaction functions */ | |
3 | |
4 #include <stdio.h> | |
5 #include <stdlib.h> | |
6 #include <string.h> | |
7 | |
8 #include "SDL.h" | |
9 | |
10 /* Is the cursor visible? */ | |
11 static int visible = 1; | |
12 | |
13 SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) | |
14 { | |
15 SDL_Surface *icon; | |
16 Uint8 *pixels; | |
17 Uint8 *mask; | |
591 | 18 int mlen, i, j; |
0 | 19 |
20 *maskp = NULL; | |
21 | |
22 /* Load the icon surface */ | |
23 icon = SDL_LoadBMP(file); | |
24 if ( icon == NULL ) { | |
25 fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); | |
26 return(NULL); | |
27 } | |
28 | |
591 | 29 /* Check width and height |
0 | 30 if ( (icon->w%8) != 0 ) { |
31 fprintf(stderr, "Icon width must be a multiple of 8!\n"); | |
32 SDL_FreeSurface(icon); | |
33 return(NULL); | |
34 } | |
591 | 35 */ |
36 | |
37 | |
0 | 38 if ( icon->format->palette == NULL ) { |
39 fprintf(stderr, "Icon must have a palette!\n"); | |
40 SDL_FreeSurface(icon); | |
41 return(NULL); | |
42 } | |
43 | |
44 /* Set the colorkey */ | |
45 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels)); | |
46 | |
47 /* Create the mask */ | |
48 pixels = (Uint8 *)icon->pixels; | |
49 printf("Transparent pixel: (%d,%d,%d)\n", | |
50 icon->format->palette->colors[*pixels].r, | |
51 icon->format->palette->colors[*pixels].g, | |
52 icon->format->palette->colors[*pixels].b); | |
591 | 53 mlen = (icon->w*icon->h + 7) / 8; |
54 mask = (Uint8 *)malloc(mlen); | |
0 | 55 if ( mask == NULL ) { |
56 fprintf(stderr, "Out of memory!\n"); | |
57 SDL_FreeSurface(icon); | |
58 return(NULL); | |
59 } | |
591 | 60 memset(mask, 0, mlen); |
61 for ( i=0; i < icon->h; i++) | |
62 for (j=0; j < icon->w; j++) { | |
63 int pindex = i * icon->pitch + j; | |
64 int mindex = i * icon->w + j; | |
65 if ( pixels[pindex] != *pixels ) | |
66 mask[mindex>>3] |= 1 << (7 - (mindex & 7)); | |
67 } | |
0 | 68 *maskp = mask; |
69 return(icon); | |
70 } | |
71 | |
72 void HotKey_ToggleFullScreen(void) | |
73 { | |
74 SDL_Surface *screen; | |
75 | |
76 screen = SDL_GetVideoSurface(); | |
77 if ( SDL_WM_ToggleFullScreen(screen) ) { | |
78 printf("Toggled fullscreen mode - now %s\n", | |
79 (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed"); | |
80 } else { | |
81 printf("Unable to toggle fullscreen mode\n"); | |
82 } | |
83 } | |
84 | |
85 void HotKey_ToggleGrab(void) | |
86 { | |
87 SDL_GrabMode mode; | |
88 | |
89 printf("Ctrl-G: toggling input grab!\n"); | |
90 mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); | |
91 if ( mode == SDL_GRAB_ON ) { | |
92 printf("Grab was on\n"); | |
93 } else { | |
94 printf("Grab was off\n"); | |
95 } | |
609
a30b17e09cc0
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
591
diff
changeset
|
96 mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON); |
0 | 97 if ( mode == SDL_GRAB_ON ) { |
98 printf("Grab is now on\n"); | |
99 } else { | |
100 printf("Grab is now off\n"); | |
101 } | |
102 } | |
103 | |
104 void HotKey_Iconify(void) | |
105 { | |
106 printf("Ctrl-Z: iconifying window!\n"); | |
107 SDL_WM_IconifyWindow(); | |
108 } | |
109 | |
110 void HotKey_Quit(void) | |
111 { | |
112 SDL_Event event; | |
113 | |
114 printf("Posting internal quit request\n"); | |
115 event.type = SDL_USEREVENT; | |
116 SDL_PushEvent(&event); | |
117 } | |
118 | |
119 int FilterEvents(const SDL_Event *event) | |
120 { | |
121 static int reallyquit = 0; | |
122 | |
123 switch (event->type) { | |
124 | |
125 case SDL_ACTIVEEVENT: | |
126 /* See what happened */ | |
127 printf("App %s ", | |
128 event->active.gain ? "gained" : "lost"); | |
129 if ( event->active.state & SDL_APPACTIVE ) | |
130 printf("active "); | |
131 if ( event->active.state & SDL_APPMOUSEFOCUS ) | |
132 printf("mouse "); | |
133 if ( event->active.state & SDL_APPINPUTFOCUS ) | |
134 printf("input "); | |
135 printf("focus\n"); | |
136 | |
137 /* See if we are iconified or restored */ | |
138 if ( event->active.state & SDL_APPACTIVE ) { | |
139 printf("App has been %s\n", | |
140 event->active.gain ? | |
141 "restored" : "iconified"); | |
142 } | |
143 return(0); | |
144 | |
145 /* We want to toggle visibility on buttonpress */ | |
146 case SDL_MOUSEBUTTONDOWN: | |
147 case SDL_MOUSEBUTTONUP: | |
148 if ( event->button.state == SDL_PRESSED ) { | |
149 visible = !visible; | |
150 SDL_ShowCursor(visible); | |
151 } | |
152 printf("Mouse button %d has been %s\n", | |
153 event->button.button, | |
154 (event->button.state == SDL_PRESSED) ? | |
155 "pressed" : "released"); | |
156 return(0); | |
157 | |
158 /* Show relative mouse motion */ | |
159 case SDL_MOUSEMOTION: | |
160 #if 0 | |
161 printf("Mouse relative motion: {%d,%d}\n", | |
162 event->motion.xrel, event->motion.yrel); | |
163 #endif | |
164 return(0); | |
165 | |
166 case SDL_KEYDOWN: | |
167 if ( event->key.keysym.sym == SDLK_ESCAPE ) { | |
168 HotKey_Quit(); | |
169 } | |
170 if ( (event->key.keysym.sym == SDLK_g) && | |
171 (event->key.keysym.mod & KMOD_CTRL) ) { | |
172 HotKey_ToggleGrab(); | |
173 } | |
174 if ( (event->key.keysym.sym == SDLK_z) && | |
175 (event->key.keysym.mod & KMOD_CTRL) ) { | |
176 HotKey_Iconify(); | |
177 } | |
178 if ( (event->key.keysym.sym == SDLK_RETURN) && | |
179 (event->key.keysym.mod & KMOD_ALT) ) { | |
180 HotKey_ToggleFullScreen(); | |
181 } | |
182 return(0); | |
183 | |
184 /* Pass the video resize event through .. */ | |
185 case SDL_VIDEORESIZE: | |
186 return(1); | |
187 | |
188 /* This is important! Queue it if we want to quit. */ | |
189 case SDL_QUIT: | |
190 if ( ! reallyquit ) { | |
191 reallyquit = 1; | |
192 printf("Quit requested\n"); | |
193 return(0); | |
194 } | |
195 printf("Quit demanded\n"); | |
196 return(1); | |
197 | |
198 /* This will never happen because events queued directly | |
199 to the event queue are not filtered. | |
200 */ | |
201 case SDL_USEREVENT: | |
202 return(1); | |
203 | |
204 /* Drop all other events */ | |
205 default: | |
206 return(0); | |
207 } | |
208 } | |
209 | |
210 static Uint8 video_bpp; | |
211 static Uint32 video_flags; | |
212 | |
213 int SetVideoMode(int w, int h) | |
214 { | |
215 SDL_Surface *screen; | |
216 int i; | |
217 Uint8 *buffer; | |
218 SDL_Color palette[256]; | |
219 | |
220 screen = SDL_SetVideoMode(w, h, video_bpp, video_flags); | |
221 if ( screen == NULL ) { | |
222 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", | |
223 w, h, video_bpp, SDL_GetError()); | |
224 return(-1); | |
225 } | |
226 printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ? | |
227 "fullscreen" : "windowed"); | |
228 | |
229 /* Set the surface pixels and refresh! */ | |
230 for ( i=0; i<256; ++i ) { | |
231 palette[i].r = 255-i; | |
232 palette[i].g = 255-i; | |
233 palette[i].b = 255-i; | |
234 } | |
235 SDL_SetColors(screen, palette, 0, 256); | |
236 if ( SDL_LockSurface(screen) < 0 ) { | |
237 fprintf(stderr, "Couldn't lock display surface: %s\n", | |
238 SDL_GetError()); | |
239 return(-1); | |
240 } | |
241 buffer = (Uint8 *)screen->pixels; | |
242 for ( i=0; i<screen->h; ++i ) { | |
243 memset(buffer,(i*255)/screen->h, | |
244 screen->w*screen->format->BytesPerPixel); | |
245 buffer += screen->pitch; | |
246 } | |
247 SDL_UnlockSurface(screen); | |
248 SDL_UpdateRect(screen, 0, 0, 0, 0); | |
249 | |
250 return(0); | |
251 } | |
252 | |
253 int main(int argc, char *argv[]) | |
254 { | |
255 SDL_Event event; | |
256 char *title; | |
257 SDL_Surface *icon; | |
258 Uint8 *icon_mask; | |
259 int parsed; | |
87
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
260 int w, h; |
0 | 261 |
262 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { | |
263 fprintf(stderr, | |
264 "Couldn't initialize SDL: %s\n", SDL_GetError()); | |
265 exit(1); | |
266 } | |
267 atexit(SDL_Quit); | |
268 | |
269 /* Check command line arguments */ | |
87
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
270 w = 640; |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
271 h = 480; |
0 | 272 video_bpp = 8; |
273 video_flags = SDL_SWSURFACE; | |
274 parsed = 1; | |
275 while ( parsed ) { | |
276 if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) { | |
277 video_flags |= SDL_FULLSCREEN; | |
278 argc -= 1; | |
279 argv += 1; | |
280 } else | |
281 if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) { | |
282 video_flags |= SDL_RESIZABLE; | |
283 argc -= 1; | |
284 argv += 1; | |
285 } else | |
286 if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) { | |
287 video_flags |= SDL_NOFRAME; | |
288 argc -= 1; | |
289 argv += 1; | |
290 } else | |
87
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
291 if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) { |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
292 w = atoi(argv[2]); |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
293 argc -= 2; |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
294 argv += 2; |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
295 } else |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
296 if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) { |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
297 h = atoi(argv[2]); |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
298 argc -= 2; |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
299 argv += 2; |
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
300 } else |
0 | 301 if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) { |
302 video_bpp = atoi(argv[2]); | |
303 argc -= 2; | |
304 argv += 2; | |
305 } else { | |
306 parsed = 0; | |
307 } | |
308 } | |
309 | |
310 /* Set the icon -- this must be done before the first mode set */ | |
311 icon = LoadIconSurface("icon.bmp", &icon_mask); | |
312 if ( icon != NULL ) { | |
313 SDL_WM_SetIcon(icon, icon_mask); | |
314 } | |
315 if ( icon_mask != NULL ) | |
316 free(icon_mask); | |
317 | |
318 /* Set the title bar */ | |
319 if ( argv[1] == NULL ) | |
320 title = "Testing 1.. 2.. 3..."; | |
321 else | |
322 title = argv[1]; | |
323 SDL_WM_SetCaption(title, "testwm"); | |
324 | |
325 /* See if it's really set */ | |
326 SDL_WM_GetCaption(&title, NULL); | |
327 if ( title ) | |
328 printf("Title was set to: %s\n", title); | |
329 else | |
330 printf("No window title was set!\n"); | |
331 | |
332 /* Initialize the display */ | |
87
3ef4bc90c388
Added -width and -height command line options
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
333 if ( SetVideoMode(w, h) < 0 ) { |
0 | 334 return(1); |
335 } | |
336 | |
337 /* Set an event filter that discards everything but QUIT */ | |
338 SDL_SetEventFilter(FilterEvents); | |
339 | |
340 /* Ignore key up events, they don't even get filtered */ | |
341 SDL_EventState(SDL_KEYUP, SDL_IGNORE); | |
342 | |
343 /* Loop, waiting for QUIT */ | |
344 while ( SDL_WaitEvent(&event) ) { | |
345 switch (event.type) { | |
346 case SDL_VIDEORESIZE: | |
347 printf("Got a resize event: %dx%d\n", | |
348 event.resize.w, event.resize.h); | |
349 SetVideoMode(event.resize.w, event.resize.h); | |
350 break; | |
351 case SDL_USEREVENT: | |
352 printf("Handling internal quit request\n"); | |
353 /* Fall through to the quit handler */ | |
354 case SDL_QUIT: | |
355 printf("Bye bye..\n"); | |
356 return(0); | |
357 default: | |
358 /* This should never happen */ | |
359 printf("Warning: Event %d wasn't filtered\n", | |
360 event.type); | |
361 break; | |
362 } | |
363 } | |
364 printf("SDL_WaitEvent() error: %s\n", SDL_GetError()); | |
365 return(255); | |
366 } |