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