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 } 444