test/testwm.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 06 Jul 2006 07:17:11 +0000
branchSDL-1.3
changeset 1724 6c63fc2bd986
parent 1686 8d7fecceb9ef
child 1731 875c3cf1a12c
permissions -rw-r--r--
Proof of concept done - Win32 GDI implementation mostly complete.
     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 int SDLCALL
   179 FilterEvents(void *userdata, SDL_Event * event)
   180 {
   181     static int reallyquit = 0;
   182 
   183     switch (event->type) {
   184 
   185     case SDL_ACTIVEEVENT:
   186         /* See what happened */
   187         printf("App %s ", event->active.gain ? "gained" : "lost");
   188         if (event->active.state & SDL_APPACTIVE)
   189             printf("active ");
   190         if (event->active.state & SDL_APPINPUTFOCUS)
   191             printf("input ");
   192         if (event->active.state & SDL_APPMOUSEFOCUS)
   193             printf("mouse ");
   194         printf("focus\n");
   195 
   196         /* See if we are iconified or restored */
   197         if (event->active.state & SDL_APPACTIVE) {
   198             printf("App has been %s\n",
   199                    event->active.gain ? "restored" : "iconified");
   200         }
   201         return (0);
   202 
   203         /* We want to toggle visibility on buttonpress */
   204     case SDL_MOUSEBUTTONDOWN:
   205     case SDL_MOUSEBUTTONUP:
   206         if (event->button.state == SDL_PRESSED) {
   207             visible = !visible;
   208             SDL_ShowCursor(visible);
   209         }
   210         printf("Mouse button %d has been %s\n",
   211                event->button.button,
   212                (event->button.state == SDL_PRESSED) ? "pressed" : "released");
   213         return (0);
   214 
   215         /* Show relative mouse motion */
   216     case SDL_MOUSEMOTION:
   217 #if 0
   218         printf("Mouse motion: {%d,%d} (%d,%d)\n",
   219                event->motion.x, event->motion.y,
   220                event->motion.xrel, event->motion.yrel);
   221 #endif
   222         return (0);
   223 
   224     case SDL_KEYDOWN:
   225         if (event->key.keysym.sym == SDLK_ESCAPE) {
   226             HotKey_Quit();
   227         }
   228         if ((event->key.keysym.sym == SDLK_g) &&
   229             (event->key.keysym.mod & KMOD_CTRL)) {
   230             HotKey_ToggleGrab();
   231         }
   232         if ((event->key.keysym.sym == SDLK_z) &&
   233             (event->key.keysym.mod & KMOD_CTRL)) {
   234             HotKey_Iconify();
   235         }
   236         if ((event->key.keysym.sym == SDLK_RETURN) &&
   237             (event->key.keysym.mod & KMOD_ALT)) {
   238             HotKey_ToggleFullScreen();
   239         }
   240         return (0);
   241 
   242         /* Pass the video resize event through .. */
   243     case SDL_VIDEORESIZE:
   244         return (1);
   245 
   246         /* This is important!  Queue it if we want to quit. */
   247     case SDL_QUIT:
   248         if (!reallyquit) {
   249             reallyquit = 1;
   250             printf("Quit requested\n");
   251             return (0);
   252         }
   253         printf("Quit demanded\n");
   254         return (1);
   255 
   256         /* This will never happen because events queued directly
   257            to the event queue are not filtered.
   258          */
   259     case SDL_USEREVENT:
   260         return (1);
   261 
   262         /* Drop all other events */
   263     default:
   264         return (0);
   265     }
   266 }
   267 
   268 int
   269 main(int argc, char *argv[])
   270 {
   271     SDL_Event event;
   272     char *title;
   273     SDL_Surface *icon;
   274     Uint8 *icon_mask;
   275     int parsed;
   276     int w, h;
   277 
   278     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
   279         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   280         return (1);
   281     }
   282 
   283     /* Check command line arguments */
   284     w = 640;
   285     h = 480;
   286     video_bpp = 8;
   287     video_flags = SDL_SWSURFACE;
   288     parsed = 1;
   289     while (parsed) {
   290         if ((argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0)) {
   291             video_flags |= SDL_FULLSCREEN;
   292             argc -= 1;
   293             argv += 1;
   294         } else if ((argc >= 2) && (strcmp(argv[1], "-resize") == 0)) {
   295             video_flags |= SDL_RESIZABLE;
   296             argc -= 1;
   297             argv += 1;
   298         } else if ((argc >= 2) && (strcmp(argv[1], "-noframe") == 0)) {
   299             video_flags |= SDL_NOFRAME;
   300             argc -= 1;
   301             argv += 1;
   302         } else if ((argc >= 3) && (strcmp(argv[1], "-width") == 0)) {
   303             w = atoi(argv[2]);
   304             argc -= 2;
   305             argv += 2;
   306         } else if ((argc >= 3) && (strcmp(argv[1], "-height") == 0)) {
   307             h = atoi(argv[2]);
   308             argc -= 2;
   309             argv += 2;
   310         } else if ((argc >= 3) && (strcmp(argv[1], "-bpp") == 0)) {
   311             video_bpp = atoi(argv[2]);
   312             argc -= 2;
   313             argv += 2;
   314         } else {
   315             parsed = 0;
   316         }
   317     }
   318 
   319     /* Set the icon -- this must be done before the first mode set */
   320     icon = LoadIconSurface("icon.bmp", &icon_mask);
   321     if (icon != NULL) {
   322         SDL_WM_SetIcon(icon, icon_mask);
   323     }
   324     if (icon_mask != NULL)
   325         free(icon_mask);
   326 
   327     /* Set the title bar */
   328     if (argv[1] == NULL)
   329         title = "Testing  1.. 2.. 3...";
   330     else
   331         title = argv[1];
   332     SDL_WM_SetCaption(title, "testwm");
   333 
   334     /* See if it's really set */
   335     SDL_WM_GetCaption(&title, NULL);
   336     if (title)
   337         printf("Title was set to: %s\n", title);
   338     else
   339         printf("No window title was set!\n");
   340 
   341     /* Initialize the display */
   342     if (SetVideoMode(w, h) < 0) {
   343         quit(1);
   344     }
   345 
   346     /* Set an event filter that discards everything but QUIT */
   347     SDL_SetEventFilter(FilterEvents, NULL);
   348 
   349     /* Ignore key up events, they don't even get filtered */
   350     SDL_EventState(SDL_KEYUP, SDL_IGNORE);
   351 
   352     /* Loop, waiting for QUIT */
   353     while (SDL_WaitEvent(&event)) {
   354         switch (event.type) {
   355         case SDL_VIDEORESIZE:
   356             printf("Got a resize event: %dx%d\n",
   357                    event.resize.w, event.resize.h);
   358             SetVideoMode(event.resize.w, event.resize.h);
   359             break;
   360         case SDL_USEREVENT:
   361             printf("Handling internal quit request\n");
   362             /* Fall through to the quit handler */
   363         case SDL_QUIT:
   364             printf("Bye bye..\n");
   365             quit(0);
   366         default:
   367             /* This should never happen */
   368             printf("Warning: Event %d wasn't filtered\n", event.type);
   369             break;
   370         }
   371     }
   372     printf("SDL_WaitEvent() error: %s\n", SDL_GetError());
   373     SDL_Quit();
   374     return (255);
   375 }