test/testwm.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1659 14717b52abc0
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

The headers are being converted to automatically generate doxygen documentation.
     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 (const 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) ?
   213                 "pressed" : "released");
   214         return (0);
   215 
   216         /* Show relative mouse motion */
   217     case SDL_MOUSEMOTION:
   218 #if 0
   219         printf ("Mouse motion: {%d,%d} (%d,%d)\n",
   220                 event->motion.x, event->motion.y,
   221                 event->motion.xrel, event->motion.yrel);
   222 #endif
   223         return (0);
   224 
   225     case SDL_KEYDOWN:
   226         if (event->key.keysym.sym == SDLK_ESCAPE) {
   227             HotKey_Quit ();
   228         }
   229         if ((event->key.keysym.sym == SDLK_g) &&
   230             (event->key.keysym.mod & KMOD_CTRL)) {
   231             HotKey_ToggleGrab ();
   232         }
   233         if ((event->key.keysym.sym == SDLK_z) &&
   234             (event->key.keysym.mod & KMOD_CTRL)) {
   235             HotKey_Iconify ();
   236         }
   237         if ((event->key.keysym.sym == SDLK_RETURN) &&
   238             (event->key.keysym.mod & KMOD_ALT)) {
   239             HotKey_ToggleFullScreen ();
   240         }
   241         return (0);
   242 
   243         /* Pass the video resize event through .. */
   244     case SDL_VIDEORESIZE:
   245         return (1);
   246 
   247         /* This is important!  Queue it if we want to quit. */
   248     case SDL_QUIT:
   249         if (!reallyquit) {
   250             reallyquit = 1;
   251             printf ("Quit requested\n");
   252             return (0);
   253         }
   254         printf ("Quit demanded\n");
   255         return (1);
   256 
   257         /* This will never happen because events queued directly
   258            to the event queue are not filtered.
   259          */
   260     case SDL_USEREVENT:
   261         return (1);
   262 
   263         /* Drop all other events */
   264     default:
   265         return (0);
   266     }
   267 }
   268 
   269 int
   270 main (int argc, char *argv[])
   271 {
   272     SDL_Event event;
   273     char *title;
   274     SDL_Surface *icon;
   275     Uint8 *icon_mask;
   276     int parsed;
   277     int w, h;
   278 
   279     if (SDL_Init (SDL_INIT_VIDEO) < 0) {
   280         fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError ());
   281         return (1);
   282     }
   283 
   284     /* Check command line arguments */
   285     w = 640;
   286     h = 480;
   287     video_bpp = 8;
   288     video_flags = SDL_SWSURFACE;
   289     parsed = 1;
   290     while (parsed) {
   291         if ((argc >= 2) && (strcmp (argv[1], "-fullscreen") == 0)) {
   292             video_flags |= SDL_FULLSCREEN;
   293             argc -= 1;
   294             argv += 1;
   295         } else if ((argc >= 2) && (strcmp (argv[1], "-resize") == 0)) {
   296             video_flags |= SDL_RESIZABLE;
   297             argc -= 1;
   298             argv += 1;
   299         } else if ((argc >= 2) && (strcmp (argv[1], "-noframe") == 0)) {
   300             video_flags |= SDL_NOFRAME;
   301             argc -= 1;
   302             argv += 1;
   303         } else if ((argc >= 3) && (strcmp (argv[1], "-width") == 0)) {
   304             w = atoi (argv[2]);
   305             argc -= 2;
   306             argv += 2;
   307         } else if ((argc >= 3) && (strcmp (argv[1], "-height") == 0)) {
   308             h = atoi (argv[2]);
   309             argc -= 2;
   310             argv += 2;
   311         } else if ((argc >= 3) && (strcmp (argv[1], "-bpp") == 0)) {
   312             video_bpp = atoi (argv[2]);
   313             argc -= 2;
   314             argv += 2;
   315         } else {
   316             parsed = 0;
   317         }
   318     }
   319 
   320     /* Set the icon -- this must be done before the first mode set */
   321     icon = LoadIconSurface ("icon.bmp", &icon_mask);
   322     if (icon != NULL) {
   323         SDL_WM_SetIcon (icon, icon_mask);
   324     }
   325     if (icon_mask != NULL)
   326         free (icon_mask);
   327 
   328     /* Set the title bar */
   329     if (argv[1] == NULL)
   330         title = "Testing  1.. 2.. 3...";
   331     else
   332         title = argv[1];
   333     SDL_WM_SetCaption (title, "testwm");
   334 
   335     /* See if it's really set */
   336     SDL_WM_GetCaption (&title, NULL);
   337     if (title)
   338         printf ("Title was set to: %s\n", title);
   339     else
   340         printf ("No window title was set!\n");
   341 
   342     /* Initialize the display */
   343     if (SetVideoMode (w, h) < 0) {
   344         quit (1);
   345     }
   346 
   347     /* Set an event filter that discards everything but QUIT */
   348     SDL_SetEventFilter (FilterEvents);
   349 
   350     /* Ignore key up events, they don't even get filtered */
   351     SDL_EventState (SDL_KEYUP, SDL_IGNORE);
   352 
   353     /* Loop, waiting for QUIT */
   354     while (SDL_WaitEvent (&event)) {
   355         switch (event.type) {
   356         case SDL_VIDEORESIZE:
   357             printf ("Got a resize event: %dx%d\n",
   358                     event.resize.w, event.resize.h);
   359             SetVideoMode (event.resize.w, event.resize.h);
   360             break;
   361         case SDL_USEREVENT:
   362             printf ("Handling internal quit request\n");
   363             /* Fall through to the quit handler */
   364         case SDL_QUIT:
   365             printf ("Bye bye..\n");
   366             quit (0);
   367         default:
   368             /* This should never happen */
   369             printf ("Warning: Event %d wasn't filtered\n", event.type);
   370             break;
   371         }
   372     }
   373     printf ("SDL_WaitEvent() error: %s\n", SDL_GetError ());
   374     SDL_Quit ();
   375     return (255);
   376 }