test/testwm.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 19 Jan 2011 22:20:44 -0800
changeset 5046 4cb778067834
parent 4942 c127755eebee
child 5081 25d4feb7c127
permissions -rw-r--r--
Clearing the API changes for the 1.3.0 release
     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 
   179 static void
   180 print_modifiers(void)
   181 {
   182     int mod;
   183     printf(" modifiers:");
   184     mod = SDL_GetModState();
   185     if(!mod) {
   186         printf(" (none)");
   187         return;
   188     }
   189     if(mod & KMOD_LSHIFT)
   190         printf(" LSHIFT");
   191     if(mod & KMOD_RSHIFT)
   192         printf(" RSHIFT");
   193     if(mod & KMOD_LCTRL)
   194         printf(" LCTRL");
   195     if(mod & KMOD_RCTRL)
   196         printf(" RCTRL");
   197     if(mod & KMOD_LALT)
   198         printf(" LALT");
   199     if(mod & KMOD_RALT)
   200         printf(" RALT");
   201     if(mod & KMOD_LMETA)
   202         printf(" LMETA");
   203     if(mod & KMOD_RMETA)
   204         printf(" RMETA");
   205     if(mod & KMOD_NUM)
   206         printf(" NUM");
   207     if(mod & KMOD_CAPS)
   208         printf(" CAPS");
   209     if(mod & KMOD_MODE)
   210         printf(" MODE");
   211 }
   212 
   213 static void PrintKey(const SDL_keysym *sym, int pressed)
   214 {
   215     /* Print the keycode, name and state */
   216     if ( sym->sym ) {
   217         printf("Key %s:  %d-%s ", pressed ?  "pressed" : "released",
   218                     sym->sym, SDL_GetKeyName(sym->sym));
   219     } else {
   220         printf("Unknown Key (scancode = %d) %s ", sym->scancode,
   221                     pressed ?  "pressed" : "released");
   222     }
   223 
   224     /* Print the translated character, if one exists */
   225     if ( sym->unicode ) {
   226         /* Is it a control-character? */
   227         if ( sym->unicode < ' ' ) {
   228             printf(" (^%c)", sym->unicode+'@');
   229         } else {
   230 #ifdef UNICODE
   231             printf(" (%c)", sym->unicode);
   232 #else
   233             /* This is a Latin-1 program, so only show 8-bits */
   234             if ( !(sym->unicode & 0xFF00) )
   235                 printf(" (%c)", sym->unicode);
   236             else
   237                 printf(" (0x%X)", sym->unicode);
   238 #endif
   239         }
   240     }
   241     print_modifiers();
   242     printf("\n");
   243 }
   244 
   245 
   246 static int (SDLCALL * old_filterfunc) (void *, SDL_Event *);
   247 static void *old_filterdata;
   248 
   249 int SDLCALL
   250 FilterEvents(void *userdata, SDL_Event * event)
   251 {
   252     static int reallyquit = 0;
   253 
   254     if (old_filterfunc) {
   255         old_filterfunc(old_filterdata, event);
   256     }
   257 
   258     switch (event->type) {
   259 
   260     case SDL_ACTIVEEVENT:
   261         /* See what happened */
   262         printf("App %s ", event->active.gain ? "gained" : "lost");
   263         if (event->active.state & SDL_APPACTIVE)
   264             printf("active ");
   265         if (event->active.state & SDL_APPINPUTFOCUS)
   266             printf("input ");
   267         if (event->active.state & SDL_APPMOUSEFOCUS)
   268             printf("mouse ");
   269         printf("focus\n");
   270 
   271         /* See if we are iconified or restored */
   272         if (event->active.state & SDL_APPACTIVE) {
   273             printf("App has been %s\n",
   274                    event->active.gain ? "restored" : "iconified");
   275         }
   276         return (0);
   277 
   278         /* We want to toggle visibility on buttonpress */
   279     case SDL_MOUSEBUTTONDOWN:
   280     case SDL_MOUSEBUTTONUP:
   281         if (event->button.state == SDL_PRESSED) {
   282             visible = !visible;
   283             SDL_ShowCursor(visible);
   284         }
   285         printf("Mouse button %d has been %s at %d,%d\n",
   286                event->button.button,
   287                (event->button.state == SDL_PRESSED) ? "pressed" : "released",
   288                event->button.x, event->button.y);
   289         return (0);
   290 
   291         /* Show relative mouse motion */
   292     case SDL_MOUSEMOTION:
   293 #if 0
   294         printf("Mouse motion: {%d,%d} (%d,%d)\n",
   295                event->motion.x, event->motion.y,
   296                event->motion.xrel, event->motion.yrel);
   297 #endif
   298         return (0);
   299 
   300     case SDL_KEYDOWN:
   301         PrintKey(&event->key.keysym, 1);
   302         if (event->key.keysym.sym == SDLK_ESCAPE) {
   303             HotKey_Quit();
   304         }
   305         if ((event->key.keysym.sym == SDLK_g) &&
   306             (event->key.keysym.mod & KMOD_CTRL)) {
   307             HotKey_ToggleGrab();
   308         }
   309         if ((event->key.keysym.sym == SDLK_z) &&
   310             (event->key.keysym.mod & KMOD_CTRL)) {
   311             HotKey_Iconify();
   312         }
   313         if ((event->key.keysym.sym == SDLK_RETURN) &&
   314             (event->key.keysym.mod & (KMOD_ALT|KMOD_META))) {
   315             HotKey_ToggleFullScreen();
   316         }
   317         return (0);
   318 
   319 	case SDL_KEYUP:
   320 		PrintKey(&event->key.keysym, 0);
   321 		return(0);
   322 
   323         /* Pass the video resize event through .. */
   324     case SDL_VIDEORESIZE:
   325         return (1);
   326 
   327         /* This is important!  Queue it if we want to quit. */
   328     case SDL_QUIT:
   329         if (!reallyquit) {
   330             reallyquit = 1;
   331             printf("Quit requested\n");
   332             return (0);
   333         }
   334         printf("Quit demanded\n");
   335         return (1);
   336 
   337         /* This will never happen because events queued directly
   338            to the event queue are not filtered.
   339          */
   340     case SDL_USEREVENT:
   341         return (1);
   342 
   343         /* Drop all other events */
   344     default:
   345         return (0);
   346     }
   347 }
   348 
   349 int
   350 main(int argc, char *argv[])
   351 {
   352     SDL_Event event;
   353     const char *title;
   354     SDL_Surface *icon;
   355     Uint8 *icon_mask;
   356     int parsed;
   357     int w, h;
   358 
   359     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
   360         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   361         return (1);
   362     }
   363 
   364     /* Check command line arguments */
   365     w = 640;
   366     h = 480;
   367     video_bpp = 8;
   368     video_flags = SDL_SWSURFACE;
   369     parsed = 1;
   370     while (parsed) {
   371         if ((argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0)) {
   372             video_flags |= SDL_FULLSCREEN;
   373             argc -= 1;
   374             argv += 1;
   375         } else if ((argc >= 2) && (strcmp(argv[1], "-resize") == 0)) {
   376             video_flags |= SDL_RESIZABLE;
   377             argc -= 1;
   378             argv += 1;
   379         } else if ((argc >= 2) && (strcmp(argv[1], "-noframe") == 0)) {
   380             video_flags |= SDL_NOFRAME;
   381             argc -= 1;
   382             argv += 1;
   383         } else if ((argc >= 3) && (strcmp(argv[1], "-width") == 0)) {
   384             w = atoi(argv[2]);
   385             argc -= 2;
   386             argv += 2;
   387         } else if ((argc >= 3) && (strcmp(argv[1], "-height") == 0)) {
   388             h = atoi(argv[2]);
   389             argc -= 2;
   390             argv += 2;
   391         } else if ((argc >= 3) && (strcmp(argv[1], "-bpp") == 0)) {
   392             video_bpp = atoi(argv[2]);
   393             argc -= 2;
   394             argv += 2;
   395         } else {
   396             parsed = 0;
   397         }
   398     }
   399 
   400     /* Set the icon -- this must be done before the first mode set */
   401     icon = LoadIconSurface("icon.bmp", &icon_mask);
   402     if (icon != NULL) {
   403         SDL_WM_SetIcon(icon, icon_mask);
   404     }
   405     if (icon_mask != NULL)
   406         free(icon_mask);
   407 
   408     /* Set the title bar */
   409     if (argv[1] == NULL)
   410         title = "Testing  1.. 2.. 3...";
   411     else
   412         title = argv[1];
   413     SDL_WM_SetCaption(title, "testwm");
   414 
   415     /* See if it's really set */
   416     SDL_WM_GetCaption(&title, NULL);
   417     if (title)
   418         printf("Title was set to: %s\n", title);
   419     else
   420         printf("No window title was set!\n");
   421 
   422     /* Initialize the display */
   423     if (SetVideoMode(w, h) < 0) {
   424         quit(1);
   425     }
   426 
   427     /* Set an event filter that discards everything but QUIT */
   428     SDL_GetEventFilter(&old_filterfunc, &old_filterdata);
   429     SDL_SetEventFilter(FilterEvents, NULL);
   430 
   431     /* Loop, waiting for QUIT */
   432     while (SDL_WaitEvent(&event)) {
   433         switch (event.type) {
   434         case SDL_VIDEORESIZE:
   435             printf("Got a resize event: %dx%d\n",
   436                    event.resize.w, event.resize.h);
   437             SetVideoMode(event.resize.w, event.resize.h);
   438             break;
   439         case SDL_USEREVENT:
   440             printf("Handling internal quit request\n");
   441             /* Fall through to the quit handler */
   442         case SDL_QUIT:
   443             printf("Bye bye..\n");
   444             quit(0);
   445         default:
   446             /* This should never happen */
   447             printf("Warning: Event %d wasn't filtered\n", event.type);
   448             break;
   449         }
   450     }
   451     printf("SDL_WaitEvent() error: %s\n", SDL_GetError());
   452     SDL_Quit();
   453     return (255);
   454 }