| |
| /* Test out the window manager interaction functions */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "SDL.h" |
| |
| /* Is the cursor visible? */ |
| static int visible = 1; |
| |
| static Uint8 video_bpp; |
| static Uint32 video_flags; |
| |
| /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
| static void quit(int rc) |
| { |
| SDL_Quit(); |
| exit(rc); |
| } |
| |
| int SetVideoMode(int w, int h) |
| { |
| SDL_Surface *screen; |
| int i; |
| Uint8 *buffer; |
| SDL_Color palette[256]; |
| |
| screen = SDL_SetVideoMode(w, h, video_bpp, video_flags); |
| if ( screen == NULL ) { |
| fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", |
| w, h, video_bpp, SDL_GetError()); |
| return(-1); |
| } |
| printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ? |
| "fullscreen" : "windowed"); |
| |
| /* Set the surface pixels and refresh! */ |
| for ( i=0; i<256; ++i ) { |
| palette[i].r = 255-i; |
| palette[i].g = 255-i; |
| palette[i].b = 255-i; |
| } |
| SDL_SetColors(screen, palette, 0, 256); |
| if ( SDL_LockSurface(screen) < 0 ) { |
| fprintf(stderr, "Couldn't lock display surface: %s\n", |
| SDL_GetError()); |
| return(-1); |
| } |
| buffer = (Uint8 *)screen->pixels; |
| for ( i=0; i<screen->h; ++i ) { |
| memset(buffer,(i*255)/screen->h, |
| screen->w*screen->format->BytesPerPixel); |
| buffer += screen->pitch; |
| } |
| SDL_UnlockSurface(screen); |
| SDL_UpdateRect(screen, 0, 0, 0, 0); |
| |
| return(0); |
| } |
| |
| SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) |
| { |
| SDL_Surface *icon; |
| Uint8 *pixels; |
| Uint8 *mask; |
| int mlen, i, j; |
| |
| *maskp = NULL; |
| |
| /* Load the icon surface */ |
| icon = SDL_LoadBMP(file); |
| if ( icon == NULL ) { |
| fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); |
| return(NULL); |
| } |
| |
| /* Check width and height |
| if ( (icon->w%8) != 0 ) { |
| fprintf(stderr, "Icon width must be a multiple of 8!\n"); |
| SDL_FreeSurface(icon); |
| return(NULL); |
| } |
| */ |
| |
| |
| if ( icon->format->palette == NULL ) { |
| fprintf(stderr, "Icon must have a palette!\n"); |
| SDL_FreeSurface(icon); |
| return(NULL); |
| } |
| |
| /* Set the colorkey */ |
| SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels)); |
| |
| /* Create the mask */ |
| pixels = (Uint8 *)icon->pixels; |
| printf("Transparent pixel: (%d,%d,%d)\n", |
| icon->format->palette->colors[*pixels].r, |
| icon->format->palette->colors[*pixels].g, |
| icon->format->palette->colors[*pixels].b); |
| mlen = (icon->w*icon->h + 7) / 8; |
| mask = (Uint8 *)malloc(mlen); |
| if ( mask == NULL ) { |
| fprintf(stderr, "Out of memory!\n"); |
| SDL_FreeSurface(icon); |
| return(NULL); |
| } |
| memset(mask, 0, mlen); |
| for ( i=0; i < icon->h; i++) |
| for (j=0; j < icon->w; j++) { |
| int pindex = i * icon->pitch + j; |
| int mindex = i * icon->w + j; |
| if ( pixels[pindex] != *pixels ) |
| mask[mindex>>3] |= 1 << (7 - (mindex & 7)); |
| } |
| *maskp = mask; |
| return(icon); |
| } |
| |
| void HotKey_ToggleFullScreen(void) |
| { |
| SDL_Surface *screen; |
| |
| screen = SDL_GetVideoSurface(); |
| if ( SDL_WM_ToggleFullScreen(screen) ) { |
| printf("Toggled fullscreen mode - now %s\n", |
| (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed"); |
| } else { |
| printf("Unable to toggle fullscreen mode\n"); |
| video_flags ^= SDL_FULLSCREEN; |
| SetVideoMode(screen->w, screen->h); |
| } |
| } |
| |
| void HotKey_ToggleGrab(void) |
| { |
| SDL_GrabMode mode; |
| |
| printf("Ctrl-G: toggling input grab!\n"); |
| mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); |
| if ( mode == SDL_GRAB_ON ) { |
| printf("Grab was on\n"); |
| } else { |
| printf("Grab was off\n"); |
| } |
| mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON); |
| if ( mode == SDL_GRAB_ON ) { |
| printf("Grab is now on\n"); |
| } else { |
| printf("Grab is now off\n"); |
| } |
| } |
| |
| void HotKey_Iconify(void) |
| { |
| printf("Ctrl-Z: iconifying window!\n"); |
| SDL_WM_IconifyWindow(); |
| } |
| |
| void HotKey_Quit(void) |
| { |
| SDL_Event event; |
| |
| printf("Posting internal quit request\n"); |
| event.type = SDL_USEREVENT; |
| SDL_PushEvent(&event); |
| } |
| |
| static void print_modifiers(void) |
| { |
| int mod; |
| printf(" modifiers:"); |
| mod = SDL_GetModState(); |
| if(!mod) { |
| printf(" (none)"); |
| return; |
| } |
| if(mod & KMOD_LSHIFT) |
| printf(" LSHIFT"); |
| if(mod & KMOD_RSHIFT) |
| printf(" RSHIFT"); |
| if(mod & KMOD_LCTRL) |
| printf(" LCTRL"); |
| if(mod & KMOD_RCTRL) |
| printf(" RCTRL"); |
| if(mod & KMOD_LALT) |
| printf(" LALT"); |
| if(mod & KMOD_RALT) |
| printf(" RALT"); |
| if(mod & KMOD_LMETA) |
| printf(" LMETA"); |
| if(mod & KMOD_RMETA) |
| printf(" RMETA"); |
| if(mod & KMOD_NUM) |
| printf(" NUM"); |
| if(mod & KMOD_CAPS) |
| printf(" CAPS"); |
| if(mod & KMOD_MODE) |
| printf(" MODE"); |
| } |
| |
| static void PrintKey(const SDL_keysym *sym, int pressed) |
| { |
| /* Print the keycode, name and state */ |
| if ( sym->sym ) { |
| printf("Key %s: %d-%s ", pressed ? "pressed" : "released", |
| sym->sym, SDL_GetKeyName(sym->sym)); |
| } else { |
| printf("Unknown Key (scancode = %d) %s ", sym->scancode, |
| pressed ? "pressed" : "released"); |
| } |
| |
| /* Print the translated character, if one exists */ |
| if ( sym->unicode ) { |
| /* Is it a control-character? */ |
| if ( sym->unicode < ' ' ) { |
| printf(" (^%c)", sym->unicode+'@'); |
| } else { |
| #ifdef UNICODE |
| printf(" (%c)", sym->unicode); |
| #else |
| /* This is a Latin-1 program, so only show 8-bits */ |
| if ( !(sym->unicode & 0xFF00) ) |
| printf(" (%c)", sym->unicode); |
| else |
| printf(" (0x%X)", sym->unicode); |
| #endif |
| } |
| } |
| print_modifiers(); |
| printf("\n"); |
| } |
| |
| int SDLCALL FilterEvents(const SDL_Event *event) |
| { |
| static int reallyquit = 0; |
| |
| switch (event->type) { |
| |
| case SDL_ACTIVEEVENT: |
| /* See what happened */ |
| printf("App %s ", |
| event->active.gain ? "gained" : "lost"); |
| if ( event->active.state & SDL_APPACTIVE ) |
| printf("active "); |
| if ( event->active.state & SDL_APPINPUTFOCUS ) |
| printf("input "); |
| if ( event->active.state & SDL_APPMOUSEFOCUS ) |
| printf("mouse "); |
| printf("focus\n"); |
| |
| /* See if we are iconified or restored */ |
| if ( event->active.state & SDL_APPACTIVE ) { |
| printf("App has been %s\n", |
| event->active.gain ? |
| "restored" : "iconified"); |
| } |
| return(0); |
| |
| /* We want to toggle visibility on buttonpress */ |
| case SDL_MOUSEBUTTONDOWN: |
| case SDL_MOUSEBUTTONUP: |
| if ( event->button.state == SDL_PRESSED ) { |
| visible = !visible; |
| SDL_ShowCursor(visible); |
| } |
| printf("Mouse button %d has been %s\n", |
| event->button.button, |
| (event->button.state == SDL_PRESSED) ? |
| "pressed" : "released"); |
| return(0); |
| |
| /* Show relative mouse motion */ |
| case SDL_MOUSEMOTION: |
| #if 0 |
| printf("Mouse motion: {%d,%d} (%d,%d)\n", |
| event->motion.x, event->motion.y, |
| event->motion.xrel, event->motion.yrel); |
| #endif |
| return(0); |
| |
| case SDL_KEYDOWN: |
| PrintKey(&event->key.keysym, 1); |
| if ( event->key.keysym.sym == SDLK_ESCAPE ) { |
| HotKey_Quit(); |
| } |
| if ( (event->key.keysym.sym == SDLK_g) && |
| (event->key.keysym.mod & KMOD_CTRL) ) { |
| HotKey_ToggleGrab(); |
| } |
| if ( (event->key.keysym.sym == SDLK_z) && |
| (event->key.keysym.mod & KMOD_CTRL) ) { |
| HotKey_Iconify(); |
| } |
| if ( (event->key.keysym.sym == SDLK_RETURN) && |
| (event->key.keysym.mod & KMOD_ALT) ) { |
| HotKey_ToggleFullScreen(); |
| } |
| return(0); |
| |
| case SDL_KEYUP: |
| PrintKey(&event->key.keysym, 0); |
| return(0); |
| |
| /* Pass the video resize event through .. */ |
| case SDL_VIDEORESIZE: |
| return(1); |
| |
| /* This is important! Queue it if we want to quit. */ |
| case SDL_QUIT: |
| if ( ! reallyquit ) { |
| reallyquit = 1; |
| printf("Quit requested\n"); |
| return(0); |
| } |
| printf("Quit demanded\n"); |
| return(1); |
| |
| /* This will never happen because events queued directly |
| to the event queue are not filtered. |
| */ |
| case SDL_USEREVENT: |
| return(1); |
| |
| /* Drop all other events */ |
| default: |
| return(0); |
| } |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| SDL_Event event; |
| char *title; |
| SDL_Surface *icon; |
| Uint8 *icon_mask; |
| int parsed; |
| int w, h; |
| |
| if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { |
| fprintf(stderr, |
| "Couldn't initialize SDL: %s\n", SDL_GetError()); |
| return(1); |
| } |
| |
| /* Check command line arguments */ |
| w = 640; |
| h = 480; |
| video_bpp = 8; |
| video_flags = SDL_SWSURFACE; |
| parsed = 1; |
| while ( parsed ) { |
| if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) { |
| video_flags |= SDL_FULLSCREEN; |
| argc -= 1; |
| argv += 1; |
| } else |
| if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) { |
| video_flags |= SDL_RESIZABLE; |
| argc -= 1; |
| argv += 1; |
| } else |
| if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) { |
| video_flags |= SDL_NOFRAME; |
| argc -= 1; |
| argv += 1; |
| } else |
| if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) { |
| w = atoi(argv[2]); |
| argc -= 2; |
| argv += 2; |
| } else |
| if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) { |
| h = atoi(argv[2]); |
| argc -= 2; |
| argv += 2; |
| } else |
| if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) { |
| video_bpp = atoi(argv[2]); |
| argc -= 2; |
| argv += 2; |
| } else { |
| parsed = 0; |
| } |
| } |
| |
| /* Set the icon -- this must be done before the first mode set */ |
| icon = LoadIconSurface("icon.bmp", &icon_mask); |
| if ( icon != NULL ) { |
| SDL_WM_SetIcon(icon, icon_mask); |
| } |
| if ( icon_mask != NULL ) |
| free(icon_mask); |
| |
| /* Set the title bar */ |
| if ( argv[1] == NULL ) |
| title = "Testing 1.. 2.. 3..."; |
| else |
| title = argv[1]; |
| SDL_WM_SetCaption(title, "testwm"); |
| |
| /* See if it's really set */ |
| SDL_WM_GetCaption(&title, NULL); |
| if ( title ) |
| printf("Title was set to: %s\n", title); |
| else |
| printf("No window title was set!\n"); |
| |
| /* Initialize the display */ |
| if ( SetVideoMode(w, h) < 0 ) { |
| quit(1); |
| } |
| |
| /* Set an event filter that discards everything but QUIT */ |
| SDL_SetEventFilter(FilterEvents); |
| |
| /* Loop, waiting for QUIT */ |
| while ( SDL_WaitEvent(&event) ) { |
| switch (event.type) { |
| case SDL_VIDEORESIZE: |
| printf("Got a resize event: %dx%d\n", |
| event.resize.w, event.resize.h); |
| SetVideoMode(event.resize.w, event.resize.h); |
| break; |
| case SDL_USEREVENT: |
| printf("Handling internal quit request\n"); |
| /* Fall through to the quit handler */ |
| case SDL_QUIT: |
| printf("Bye bye..\n"); |
| quit(0); |
| default: |
| /* This should never happen */ |
| printf("Warning: Event %d wasn't filtered\n", |
| event.type); |
| break; |
| } |
| } |
| printf("SDL_WaitEvent() error: %s\n", SDL_GetError()); |
| SDL_Quit(); |
| return(255); |
| } |