SDL-1.2.14
[sdl_omap.git] / test / testwm.c
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 static Uint8  video_bpp;
14 static Uint32 video_flags;
15
16 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
17 static void quit(int rc)
18 {
19         SDL_Quit();
20         exit(rc);
21 }
22
23 int SetVideoMode(int w, int h)
24 {
25         SDL_Surface *screen;
26         int i;
27         Uint8 *buffer;
28         SDL_Color palette[256];
29
30         screen = SDL_SetVideoMode(w, h, video_bpp, video_flags);
31         if (  screen == NULL ) {
32                 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
33                                         w, h, video_bpp, SDL_GetError());
34                 return(-1);
35         }
36         printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
37                                                 "fullscreen" : "windowed");
38
39         /* Set the surface pixels and refresh! */
40         for ( i=0; i<256; ++i ) {
41                 palette[i].r = 255-i;
42                 palette[i].g = 255-i;
43                 palette[i].b = 255-i;
44         }
45         SDL_SetColors(screen, palette, 0, 256);
46         if ( SDL_LockSurface(screen) < 0 ) {
47                 fprintf(stderr, "Couldn't lock display surface: %s\n",
48                                                         SDL_GetError());
49                 return(-1);
50         }
51         buffer = (Uint8 *)screen->pixels;
52         for ( i=0; i<screen->h; ++i ) {
53                 memset(buffer,(i*255)/screen->h,
54                                 screen->w*screen->format->BytesPerPixel);
55                 buffer += screen->pitch;
56         }
57         SDL_UnlockSurface(screen);
58         SDL_UpdateRect(screen, 0, 0, 0, 0);
59
60         return(0);
61 }
62
63 SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp)
64 {
65         SDL_Surface *icon;
66         Uint8       *pixels;
67         Uint8       *mask;
68         int          mlen, i, j;
69
70         *maskp = NULL;
71
72         /* Load the icon surface */
73         icon = SDL_LoadBMP(file);
74         if ( icon == NULL ) {
75                 fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
76                 return(NULL);
77         }
78
79         /* Check width and height 
80         if ( (icon->w%8) != 0 ) {
81                 fprintf(stderr, "Icon width must be a multiple of 8!\n");
82                 SDL_FreeSurface(icon);
83                 return(NULL);
84         }
85 */
86     
87     
88         if ( icon->format->palette == NULL ) {
89                 fprintf(stderr, "Icon must have a palette!\n");
90                 SDL_FreeSurface(icon);
91                 return(NULL);
92         }
93
94         /* Set the colorkey */
95         SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels));
96
97         /* Create the mask */
98         pixels = (Uint8 *)icon->pixels;
99         printf("Transparent pixel: (%d,%d,%d)\n",
100                                 icon->format->palette->colors[*pixels].r,
101                                 icon->format->palette->colors[*pixels].g,
102                                 icon->format->palette->colors[*pixels].b);
103         mlen = (icon->w*icon->h + 7) / 8;
104         mask = (Uint8 *)malloc(mlen);
105         if ( mask == NULL ) {
106                 fprintf(stderr, "Out of memory!\n");
107                 SDL_FreeSurface(icon);
108                 return(NULL);
109         }
110         memset(mask, 0, mlen);
111         for ( i=0; i < icon->h; i++)
112         for (j=0; j < icon->w; j++) {
113             int pindex = i * icon->pitch + j;
114             int mindex = i * icon->w + j;
115             if ( pixels[pindex] != *pixels )
116                 mask[mindex>>3] |= 1 << (7 - (mindex & 7));
117         }
118         *maskp = mask;
119         return(icon);
120 }
121
122 void HotKey_ToggleFullScreen(void)
123 {
124         SDL_Surface *screen;
125
126         screen = SDL_GetVideoSurface();
127         if ( SDL_WM_ToggleFullScreen(screen) ) {
128                 printf("Toggled fullscreen mode - now %s\n",
129                     (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
130         } else {
131                 printf("Unable to toggle fullscreen mode\n");
132                 video_flags ^= SDL_FULLSCREEN;
133                 SetVideoMode(screen->w, screen->h);
134         }
135 }
136
137 void HotKey_ToggleGrab(void)
138 {
139         SDL_GrabMode mode;
140
141         printf("Ctrl-G: toggling input grab!\n");
142         mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
143         if ( mode == SDL_GRAB_ON ) {
144                 printf("Grab was on\n");
145         } else {
146                 printf("Grab was off\n");
147         }
148         mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON);
149         if ( mode == SDL_GRAB_ON ) {
150                 printf("Grab is now on\n");
151         } else {
152                 printf("Grab is now off\n");
153         }
154 }
155
156 void HotKey_Iconify(void)
157 {
158         printf("Ctrl-Z: iconifying window!\n");
159         SDL_WM_IconifyWindow();
160 }
161
162 void HotKey_Quit(void)
163 {
164         SDL_Event event;
165
166         printf("Posting internal quit request\n");
167         event.type = SDL_USEREVENT;
168         SDL_PushEvent(&event);
169 }
170
171 static void print_modifiers(void)
172 {
173         int mod;
174         printf(" modifiers:");
175         mod = SDL_GetModState();
176         if(!mod) {
177                 printf(" (none)");
178                 return;
179         }
180         if(mod & KMOD_LSHIFT)
181                 printf(" LSHIFT");
182         if(mod & KMOD_RSHIFT)
183                 printf(" RSHIFT");
184         if(mod & KMOD_LCTRL)
185                 printf(" LCTRL");
186         if(mod & KMOD_RCTRL)
187                 printf(" RCTRL");
188         if(mod & KMOD_LALT)
189                 printf(" LALT");
190         if(mod & KMOD_RALT)
191                 printf(" RALT");
192         if(mod & KMOD_LMETA)
193                 printf(" LMETA");
194         if(mod & KMOD_RMETA)
195                 printf(" RMETA");
196         if(mod & KMOD_NUM)
197                 printf(" NUM");
198         if(mod & KMOD_CAPS)
199                 printf(" CAPS");
200         if(mod & KMOD_MODE)
201                 printf(" MODE");
202 }
203
204 static void PrintKey(const SDL_keysym *sym, int pressed)
205 {
206         /* Print the keycode, name and state */
207         if ( sym->sym ) {
208                 printf("Key %s:  %d-%s ", pressed ?  "pressed" : "released",
209                                         sym->sym, SDL_GetKeyName(sym->sym));
210         } else {
211                 printf("Unknown Key (scancode = %d) %s ", sym->scancode,
212                                         pressed ?  "pressed" : "released");
213         }
214
215         /* Print the translated character, if one exists */
216         if ( sym->unicode ) {
217                 /* Is it a control-character? */
218                 if ( sym->unicode < ' ' ) {
219                         printf(" (^%c)", sym->unicode+'@');
220                 } else {
221 #ifdef UNICODE
222                         printf(" (%c)", sym->unicode);
223 #else
224                         /* This is a Latin-1 program, so only show 8-bits */
225                         if ( !(sym->unicode & 0xFF00) )
226                                 printf(" (%c)", sym->unicode);
227                         else
228                                 printf(" (0x%X)", sym->unicode);
229 #endif
230                 }
231         }
232         print_modifiers();
233         printf("\n");
234 }
235
236 int SDLCALL FilterEvents(const SDL_Event *event)
237 {
238         static int reallyquit = 0;
239
240         switch (event->type) {
241
242                 case SDL_ACTIVEEVENT:
243                         /* See what happened */
244                         printf("App %s ",
245                                 event->active.gain ? "gained" : "lost");
246                         if ( event->active.state & SDL_APPACTIVE )
247                                 printf("active ");
248                         if ( event->active.state & SDL_APPINPUTFOCUS )
249                                 printf("input ");
250                         if ( event->active.state & SDL_APPMOUSEFOCUS )
251                                 printf("mouse ");
252                         printf("focus\n");
253
254                         /* See if we are iconified or restored */
255                         if ( event->active.state & SDL_APPACTIVE ) {
256                                 printf("App has been %s\n",
257                                         event->active.gain ?
258                                                  "restored" : "iconified");
259                         }
260                         return(0);
261
262                 /* We want to toggle visibility on buttonpress */
263                 case SDL_MOUSEBUTTONDOWN:
264                 case SDL_MOUSEBUTTONUP:
265                         if ( event->button.state == SDL_PRESSED ) {
266                                 visible = !visible;
267                                 SDL_ShowCursor(visible);
268                         }
269                         printf("Mouse button %d has been %s\n",
270                                 event->button.button,
271                                 (event->button.state == SDL_PRESSED) ?
272                                                 "pressed" : "released");
273                         return(0);
274
275                 /* Show relative mouse motion */
276                 case SDL_MOUSEMOTION:
277 #if 0
278                         printf("Mouse motion: {%d,%d} (%d,%d)\n",
279                                 event->motion.x, event->motion.y,
280                                 event->motion.xrel, event->motion.yrel);
281 #endif
282                         return(0);
283
284                 case SDL_KEYDOWN:
285                         PrintKey(&event->key.keysym, 1);
286                         if ( event->key.keysym.sym == SDLK_ESCAPE ) {
287                                 HotKey_Quit();
288                         }
289                         if ( (event->key.keysym.sym == SDLK_g) &&
290                              (event->key.keysym.mod & KMOD_CTRL) ) {
291                                 HotKey_ToggleGrab();
292                         }
293                         if ( (event->key.keysym.sym == SDLK_z) &&
294                              (event->key.keysym.mod & KMOD_CTRL) ) {
295                                 HotKey_Iconify();
296                         }
297                         if ( (event->key.keysym.sym == SDLK_RETURN) &&
298                              (event->key.keysym.mod & KMOD_ALT) ) {
299                                 HotKey_ToggleFullScreen();
300                         }
301                         return(0);
302
303                 case SDL_KEYUP:
304                         PrintKey(&event->key.keysym, 0);
305                         return(0);
306
307                 /* Pass the video resize event through .. */
308                 case SDL_VIDEORESIZE:
309                         return(1);
310
311                 /* This is important!  Queue it if we want to quit. */
312                 case SDL_QUIT:
313                         if ( ! reallyquit ) {
314                                 reallyquit = 1;
315                                 printf("Quit requested\n");
316                                 return(0);
317                         }
318                         printf("Quit demanded\n");
319                         return(1);
320
321                 /* This will never happen because events queued directly
322                    to the event queue are not filtered.
323                  */
324                 case SDL_USEREVENT:
325                         return(1);
326
327                 /* Drop all other events */
328                 default:
329                         return(0);
330         }
331 }
332
333 int main(int argc, char *argv[])
334 {
335         SDL_Event event;
336         char *title;
337         SDL_Surface *icon;
338         Uint8 *icon_mask;
339         int parsed;
340         int w, h;
341
342         if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
343                 fprintf(stderr,
344                         "Couldn't initialize SDL: %s\n", SDL_GetError());
345                 return(1);
346         }
347
348         /* Check command line arguments */
349         w = 640;
350         h = 480;
351         video_bpp = 8;
352         video_flags = SDL_SWSURFACE;
353         parsed = 1;
354         while ( parsed ) {
355                 if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
356                         video_flags |= SDL_FULLSCREEN;
357                         argc -= 1;
358                         argv += 1;
359                 } else
360                 if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) {
361                         video_flags |= SDL_RESIZABLE;
362                         argc -= 1;
363                         argv += 1;
364                 } else
365                 if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) {
366                         video_flags |= SDL_NOFRAME;
367                         argc -= 1;
368                         argv += 1;
369                 } else
370                 if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) {
371                         w = atoi(argv[2]);
372                         argc -= 2;
373                         argv += 2;
374                 } else
375                 if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) {
376                         h = atoi(argv[2]);
377                         argc -= 2;
378                         argv += 2;
379                 } else
380                 if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
381                         video_bpp = atoi(argv[2]);
382                         argc -= 2;
383                         argv += 2;
384                 } else {
385                         parsed = 0;
386                 }
387         }
388
389         /* Set the icon -- this must be done before the first mode set */
390         icon = LoadIconSurface("icon.bmp", &icon_mask);
391         if ( icon != NULL ) {
392                 SDL_WM_SetIcon(icon, icon_mask);
393         }
394         if ( icon_mask != NULL )
395                 free(icon_mask);
396
397         /* Set the title bar */
398         if ( argv[1] == NULL )
399                 title = "Testing  1.. 2.. 3...";
400         else
401                 title = argv[1];
402         SDL_WM_SetCaption(title, "testwm");
403
404         /* See if it's really set */
405         SDL_WM_GetCaption(&title, NULL);
406         if ( title )
407                 printf("Title was set to: %s\n", title);
408         else
409                 printf("No window title was set!\n");
410
411         /* Initialize the display */
412         if ( SetVideoMode(w, h) < 0 ) {
413                 quit(1);
414         }
415
416         /* Set an event filter that discards everything but QUIT */
417         SDL_SetEventFilter(FilterEvents);
418
419         /* Loop, waiting for QUIT */
420         while ( SDL_WaitEvent(&event) ) {
421                 switch (event.type) {
422                         case SDL_VIDEORESIZE:
423                                 printf("Got a resize event: %dx%d\n",
424                                        event.resize.w, event.resize.h);
425                                 SetVideoMode(event.resize.w, event.resize.h);
426                                 break;
427                         case SDL_USEREVENT:
428                                 printf("Handling internal quit request\n");
429                                 /* Fall through to the quit handler */
430                         case SDL_QUIT:
431                                 printf("Bye bye..\n");
432                                 quit(0);
433                         default:
434                                 /* This should never happen */
435                                 printf("Warning: Event %d wasn't filtered\n",
436                                                                 event.type);
437                                 break;
438                 }
439         }
440         printf("SDL_WaitEvent() error: %s\n", SDL_GetError());
441         SDL_Quit();
442         return(255);
443 }