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