| |
| /* 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 int SDLCALL(*old_filterfunc) (void *, SDL_Event *); |
| static void *old_filterdata; |
| |
| int SDLCALL |
| FilterEvents(void *userdata, SDL_Event * event) |
| { |
| static int reallyquit = 0; |
| |
| if (old_filterfunc) { |
| old_filterfunc(old_filterdata, event); |
| } |
| |
| 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: |
| 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); |
| |
| /* 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_GetEventFilter(&old_filterfunc, &old_filterdata); |
| SDL_SetEventFilter(FilterEvents, NULL); |
| |
| /* Ignore key up events, they don't even get filtered */ |
| SDL_EventState(SDL_KEYUP, SDL_IGNORE); |
| |
| /* 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); |
| } |