test/threadwin.c
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
child 1712 931d111e737a
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
    14 /* Is the cursor visible? */
    14 /* Is the cursor visible? */
    15 static int visible = 1;
    15 static int visible = 1;
    16 
    16 
    17 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    17 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    18 static void
    18 static void
    19 quit (int rc)
    19 quit(int rc)
    20 {
    20 {
    21     SDL_Quit ();
    21     SDL_Quit();
    22     exit (rc);
    22     exit(rc);
    23 }
    23 }
    24 
    24 
    25 SDL_Surface *
    25 SDL_Surface *
    26 LoadIconSurface (char *file, Uint8 ** maskp)
    26 LoadIconSurface(char *file, Uint8 ** maskp)
    27 {
    27 {
    28     SDL_Surface *icon;
    28     SDL_Surface *icon;
    29     Uint8 *pixels;
    29     Uint8 *pixels;
    30     Uint8 *mask;
    30     Uint8 *mask;
    31     int mlen, i;
    31     int mlen, i;
    32 
    32 
    33     *maskp = NULL;
    33     *maskp = NULL;
    34 
    34 
    35     /* Load the icon surface */
    35     /* Load the icon surface */
    36     icon = SDL_LoadBMP (file);
    36     icon = SDL_LoadBMP(file);
    37     if (icon == NULL) {
    37     if (icon == NULL) {
    38         fprintf (stderr, "Couldn't load %s: %s\n", file, SDL_GetError ());
    38         fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
    39         return (NULL);
    39         return (NULL);
    40     }
    40     }
    41 
    41 
    42     /* Check width and height */
    42     /* Check width and height */
    43     if ((icon->w % 8) != 0) {
    43     if ((icon->w % 8) != 0) {
    44         fprintf (stderr, "Icon width must be a multiple of 8!\n");
    44         fprintf(stderr, "Icon width must be a multiple of 8!\n");
    45         SDL_FreeSurface (icon);
    45         SDL_FreeSurface(icon);
    46         return (NULL);
    46         return (NULL);
    47     }
    47     }
    48     if (icon->format->palette == NULL) {
    48     if (icon->format->palette == NULL) {
    49         fprintf (stderr, "Icon must have a palette!\n");
    49         fprintf(stderr, "Icon must have a palette!\n");
    50         SDL_FreeSurface (icon);
    50         SDL_FreeSurface(icon);
    51         return (NULL);
    51         return (NULL);
    52     }
    52     }
    53 
    53 
    54     /* Set the colorkey */
    54     /* Set the colorkey */
    55     SDL_SetColorKey (icon, SDL_SRCCOLORKEY, *((Uint8 *) icon->pixels));
    55     SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *) icon->pixels));
    56 
    56 
    57     /* Create the mask */
    57     /* Create the mask */
    58     pixels = (Uint8 *) icon->pixels;
    58     pixels = (Uint8 *) icon->pixels;
    59     printf ("Transparent pixel: (%d,%d,%d)\n",
    59     printf("Transparent pixel: (%d,%d,%d)\n",
    60             icon->format->palette->colors[*pixels].r,
    60            icon->format->palette->colors[*pixels].r,
    61             icon->format->palette->colors[*pixels].g,
    61            icon->format->palette->colors[*pixels].g,
    62             icon->format->palette->colors[*pixels].b);
    62            icon->format->palette->colors[*pixels].b);
    63     mlen = icon->w * icon->h;
    63     mlen = icon->w * icon->h;
    64     mask = (Uint8 *) malloc (mlen / 8);
    64     mask = (Uint8 *) malloc(mlen / 8);
    65     if (mask == NULL) {
    65     if (mask == NULL) {
    66         fprintf (stderr, "Out of memory!\n");
    66         fprintf(stderr, "Out of memory!\n");
    67         SDL_FreeSurface (icon);
    67         SDL_FreeSurface(icon);
    68         return (NULL);
    68         return (NULL);
    69     }
    69     }
    70     memset (mask, 0, mlen / 8);
    70     memset(mask, 0, mlen / 8);
    71     for (i = 0; i < mlen;) {
    71     for (i = 0; i < mlen;) {
    72         if (pixels[i] != *pixels)
    72         if (pixels[i] != *pixels)
    73             mask[i / 8] |= 0x01;
    73             mask[i / 8] |= 0x01;
    74         ++i;
    74         ++i;
    75         if ((i % 8) != 0)
    75         if ((i % 8) != 0)
    78     *maskp = mask;
    78     *maskp = mask;
    79     return (icon);
    79     return (icon);
    80 }
    80 }
    81 
    81 
    82 int SDLCALL
    82 int SDLCALL
    83 FilterEvents (const SDL_Event * event)
    83 FilterEvents(const SDL_Event * event)
    84 {
    84 {
    85     static int reallyquit = 0;
    85     static int reallyquit = 0;
    86 
    86 
    87     switch (event->type) {
    87     switch (event->type) {
    88 
    88 
    89     case SDL_ACTIVEEVENT:
    89     case SDL_ACTIVEEVENT:
    90         /* See what happened */
    90         /* See what happened */
    91         printf ("App %s ", event->active.gain ? "gained" : "lost");
    91         printf("App %s ", event->active.gain ? "gained" : "lost");
    92         if (event->active.state & SDL_APPACTIVE)
    92         if (event->active.state & SDL_APPACTIVE)
    93             printf ("active ");
    93             printf("active ");
    94         if (event->active.state & SDL_APPMOUSEFOCUS)
    94         if (event->active.state & SDL_APPMOUSEFOCUS)
    95             printf ("mouse ");
    95             printf("mouse ");
    96         if (event->active.state & SDL_APPINPUTFOCUS)
    96         if (event->active.state & SDL_APPINPUTFOCUS)
    97             printf ("input ");
    97             printf("input ");
    98         printf ("focus\n");
    98         printf("focus\n");
    99 
    99 
   100         /* See if we are iconified or restored */
   100         /* See if we are iconified or restored */
   101         if (event->active.state & SDL_APPACTIVE) {
   101         if (event->active.state & SDL_APPACTIVE) {
   102             printf ("App has been %s\n",
   102             printf("App has been %s\n",
   103                     event->active.gain ? "restored" : "iconified");
   103                    event->active.gain ? "restored" : "iconified");
   104         }
   104         }
   105         return (0);
   105         return (0);
   106 
   106 
   107         /* This is important!  Queue it if we want to quit. */
   107         /* This is important!  Queue it if we want to quit. */
   108     case SDL_QUIT:
   108     case SDL_QUIT:
   109         if (!reallyquit) {
   109         if (!reallyquit) {
   110             reallyquit = 1;
   110             reallyquit = 1;
   111             printf ("Quit requested\n");
   111             printf("Quit requested\n");
   112             return (0);
   112             return (0);
   113         }
   113         }
   114         printf ("Quit demanded\n");
   114         printf("Quit demanded\n");
   115         return (1);
   115         return (1);
   116 
   116 
   117         /* Mouse and keyboard events go to threads */
   117         /* Mouse and keyboard events go to threads */
   118     case SDL_MOUSEMOTION:
   118     case SDL_MOUSEMOTION:
   119     case SDL_MOUSEBUTTONDOWN:
   119     case SDL_MOUSEBUTTONDOWN:
   127         return (0);
   127         return (0);
   128     }
   128     }
   129 }
   129 }
   130 
   130 
   131 int SDLCALL
   131 int SDLCALL
   132 HandleMouse (void *unused)
   132 HandleMouse(void *unused)
   133 {
   133 {
   134     SDL_Event events[10];
   134     SDL_Event events[10];
   135     int i, found;
   135     int i, found;
   136     Uint32 mask;
   136     Uint32 mask;
   137 
   137 
   138     /* Handle mouse events here */
   138     /* Handle mouse events here */
   139     mask =
   139     mask =
   140         (SDL_MOUSEMOTIONMASK | SDL_MOUSEBUTTONDOWNMASK |
   140         (SDL_MOUSEMOTIONMASK | SDL_MOUSEBUTTONDOWNMASK |
   141          SDL_MOUSEBUTTONUPMASK);
   141          SDL_MOUSEBUTTONUPMASK);
   142     while (!done) {
   142     while (!done) {
   143         found = SDL_PeepEvents (events, 10, SDL_GETEVENT, mask);
   143         found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
   144         for (i = 0; i < found; ++i) {
   144         for (i = 0; i < found; ++i) {
   145             switch (events[i].type) {
   145             switch (events[i].type) {
   146                 /* We want to toggle visibility on buttonpress */
   146                 /* We want to toggle visibility on buttonpress */
   147             case SDL_MOUSEBUTTONDOWN:
   147             case SDL_MOUSEBUTTONDOWN:
   148             case SDL_MOUSEBUTTONUP:
   148             case SDL_MOUSEBUTTONUP:
   149                 if (events[i].button.state == SDL_PRESSED) {
   149                 if (events[i].button.state == SDL_PRESSED) {
   150                     visible = !visible;
   150                     visible = !visible;
   151                     SDL_ShowCursor (visible);
   151                     SDL_ShowCursor(visible);
   152                 }
   152                 }
   153                 printf ("Mouse button %d has been %s\n",
   153                 printf("Mouse button %d has been %s\n",
   154                         events[i].button.button,
   154                        events[i].button.button,
   155                         (events[i].button.state == SDL_PRESSED) ?
   155                        (events[i].button.state == SDL_PRESSED) ?
   156                         "pressed" : "released");
   156                        "pressed" : "released");
   157                 break;
   157                 break;
   158                 /* Show relative mouse motion */
   158                 /* Show relative mouse motion */
   159             case SDL_MOUSEMOTION:
   159             case SDL_MOUSEMOTION:
   160                 printf ("Mouse relative motion: {%d,%d}\n",
   160                 printf("Mouse relative motion: {%d,%d}\n",
   161                         events[i].motion.xrel, events[i].motion.yrel);
   161                        events[i].motion.xrel, events[i].motion.yrel);
   162                 break;
   162                 break;
   163             }
   163             }
   164         }
   164         }
   165         /* Give up some CPU to allow events to arrive */
   165         /* Give up some CPU to allow events to arrive */
   166         SDL_Delay (20);
   166         SDL_Delay(20);
   167     }
   167     }
   168     return (0);
   168     return (0);
   169 }
   169 }
   170 
   170 
   171 int SDLCALL
   171 int SDLCALL
   172 HandleKeyboard (void *unused)
   172 HandleKeyboard(void *unused)
   173 {
   173 {
   174     SDL_Event events[10];
   174     SDL_Event events[10];
   175     int i, found;
   175     int i, found;
   176     Uint32 mask;
   176     Uint32 mask;
   177 
   177 
   178     /* Handle mouse events here */
   178     /* Handle mouse events here */
   179     mask = (SDL_KEYDOWNMASK | SDL_KEYUPMASK);
   179     mask = (SDL_KEYDOWNMASK | SDL_KEYUPMASK);
   180     while (!done) {
   180     while (!done) {
   181         found = SDL_PeepEvents (events, 10, SDL_GETEVENT, mask);
   181         found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
   182         for (i = 0; i < found; ++i) {
   182         for (i = 0; i < found; ++i) {
   183             switch (events[i].type) {
   183             switch (events[i].type) {
   184                 /* We want to toggle visibility on buttonpress */
   184                 /* We want to toggle visibility on buttonpress */
   185             case SDL_KEYDOWN:
   185             case SDL_KEYDOWN:
   186             case SDL_KEYUP:
   186             case SDL_KEYUP:
   187                 printf ("Key '%c' has been %s\n",
   187                 printf("Key '%c' has been %s\n",
   188                         events[i].key.keysym.unicode,
   188                        events[i].key.keysym.unicode,
   189                         (events[i].key.state == SDL_PRESSED) ?
   189                        (events[i].key.state == SDL_PRESSED) ?
   190                         "pressed" : "released");
   190                        "pressed" : "released");
   191 
   191 
   192                 /* Allow hitting <ESC> to quit the app */
   192                 /* Allow hitting <ESC> to quit the app */
   193                 if (events[i].key.keysym.sym == SDLK_ESCAPE) {
   193                 if (events[i].key.keysym.sym == SDLK_ESCAPE) {
   194                     done = 1;
   194                     done = 1;
   195                 }
   195                 }
   198                 if (events[i].key.state == SDL_PRESSED)
   198                 if (events[i].key.state == SDL_PRESSED)
   199                     break;
   199                     break;
   200 
   200 
   201                 if (events[i].key.keysym.sym == SDLK_f) {
   201                 if (events[i].key.keysym.sym == SDLK_f) {
   202                     int rc = 0;
   202                     int rc = 0;
   203                     printf ("attempting to toggle fullscreen...\n");
   203                     printf("attempting to toggle fullscreen...\n");
   204                     rc = SDL_WM_ToggleFullScreen (SDL_GetVideoSurface ());
   204                     rc = SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
   205                     printf ("SDL_WM_ToggleFullScreen returned %d.\n", rc);
   205                     printf("SDL_WM_ToggleFullScreen returned %d.\n", rc);
   206                 }
   206                 }
   207 
   207 
   208                 if (events[i].key.keysym.sym == SDLK_g) {
   208                 if (events[i].key.keysym.sym == SDLK_g) {
   209                     SDL_GrabMode m;
   209                     SDL_GrabMode m;
   210                     m = SDL_WM_GrabInput (SDL_GRAB_QUERY) ==
   210                     m = SDL_WM_GrabInput(SDL_GRAB_QUERY) ==
   211                         SDL_GRAB_ON ? SDL_GRAB_OFF : SDL_GRAB_ON;
   211                         SDL_GRAB_ON ? SDL_GRAB_OFF : SDL_GRAB_ON;
   212                     printf
   212                     printf
   213                         ("attempting to toggle input grab to %s...\n",
   213                         ("attempting to toggle input grab to %s...\n",
   214                          m == SDL_GRAB_ON ? "ON" : "OFF");
   214                          m == SDL_GRAB_ON ? "ON" : "OFF");
   215                     SDL_WM_GrabInput (m);
   215                     SDL_WM_GrabInput(m);
   216                     printf ("attempt finished.\n");
   216                     printf("attempt finished.\n");
   217                 }
   217                 }
   218 
   218 
   219                 break;
   219                 break;
   220             }
   220             }
   221         }
   221         }
   222         /* Give up some CPU to allow events to arrive */
   222         /* Give up some CPU to allow events to arrive */
   223         SDL_Delay (20);
   223         SDL_Delay(20);
   224     }
   224     }
   225     return (0);
   225     return (0);
   226 }
   226 }
   227 
   227 
   228 int
   228 int
   229 main (int argc, char *argv[])
   229 main(int argc, char *argv[])
   230 {
   230 {
   231     SDL_Surface *screen;
   231     SDL_Surface *screen;
   232     SDL_Surface *icon;
   232     SDL_Surface *icon;
   233     Uint8 *icon_mask;
   233     Uint8 *icon_mask;
   234     int i, parsed;
   234     int i, parsed;
   248     while (parsed) {
   248     while (parsed) {
   249         /* If the threaded option is enabled, and the SDL library hasn't
   249         /* If the threaded option is enabled, and the SDL library hasn't
   250            been compiled with threaded events enabled, then the mouse and
   250            been compiled with threaded events enabled, then the mouse and
   251            keyboard won't respond.
   251            keyboard won't respond.
   252          */
   252          */
   253         if ((argc >= 2) && (strcmp (argv[1], "-threaded") == 0)) {
   253         if ((argc >= 2) && (strcmp(argv[1], "-threaded") == 0)) {
   254             init_flags |= SDL_INIT_EVENTTHREAD;
   254             init_flags |= SDL_INIT_EVENTTHREAD;
   255             argc -= 1;
   255             argc -= 1;
   256             argv += 1;
   256             argv += 1;
   257             printf ("Running with threaded events\n");
   257             printf("Running with threaded events\n");
   258         } else if ((argc >= 2) && (strcmp (argv[1], "-fullscreen") == 0)) {
   258         } else if ((argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0)) {
   259             video_flags |= SDL_FULLSCREEN;
   259             video_flags |= SDL_FULLSCREEN;
   260             argc -= 1;
   260             argc -= 1;
   261             argv += 1;
   261             argv += 1;
   262         } else if ((argc >= 3) && (strcmp (argv[1], "-bpp") == 0)) {
   262         } else if ((argc >= 3) && (strcmp(argv[1], "-bpp") == 0)) {
   263             video_bpp = atoi (argv[2]);
   263             video_bpp = atoi(argv[2]);
   264             argc -= 2;
   264             argc -= 2;
   265             argv += 2;
   265             argv += 2;
   266         } else {
   266         } else {
   267             parsed = 0;
   267             parsed = 0;
   268         }
   268         }
   269     }
   269     }
   270 
   270 
   271     /* Initialize SDL with the requested flags */
   271     /* Initialize SDL with the requested flags */
   272     if (SDL_Init (init_flags) < 0) {
   272     if (SDL_Init(init_flags) < 0) {
   273         fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError ());
   273         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   274         return (1);
   274         return (1);
   275     }
   275     }
   276 
   276 
   277     /* Set the icon -- this must be done before the first mode set */
   277     /* Set the icon -- this must be done before the first mode set */
   278     icon = LoadIconSurface ("icon.bmp", &icon_mask);
   278     icon = LoadIconSurface("icon.bmp", &icon_mask);
   279     if (icon != NULL) {
   279     if (icon != NULL) {
   280         SDL_WM_SetIcon (icon, icon_mask);
   280         SDL_WM_SetIcon(icon, icon_mask);
   281     }
   281     }
   282     if (icon_mask != NULL)
   282     if (icon_mask != NULL)
   283         free (icon_mask);
   283         free(icon_mask);
   284 
   284 
   285     /* Initialize the display */
   285     /* Initialize the display */
   286     screen = SDL_SetVideoMode (640, 480, video_bpp, video_flags);
   286     screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags);
   287     if (screen == NULL) {
   287     if (screen == NULL) {
   288         fprintf (stderr, "Couldn't set 640x480x%d video mode: %s\n",
   288         fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
   289                  video_bpp, SDL_GetError ());
   289                 video_bpp, SDL_GetError());
   290         quit (1);
   290         quit(1);
   291     }
   291     }
   292     printf ("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
   292     printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
   293             "fullscreen" : "windowed");
   293            "fullscreen" : "windowed");
   294 
   294 
   295     /* Enable printable characters */
   295     /* Enable printable characters */
   296     SDL_EnableUNICODE (1);
   296     SDL_EnableUNICODE(1);
   297 
   297 
   298     /* Set an event filter that discards everything but QUIT */
   298     /* Set an event filter that discards everything but QUIT */
   299     SDL_SetEventFilter (FilterEvents);
   299     SDL_SetEventFilter(FilterEvents);
   300 
   300 
   301     /* Create the event handling threads */
   301     /* Create the event handling threads */
   302     mouse_thread = SDL_CreateThread (HandleMouse, NULL);
   302     mouse_thread = SDL_CreateThread(HandleMouse, NULL);
   303     keybd_thread = SDL_CreateThread (HandleKeyboard, NULL);
   303     keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);
   304 
   304 
   305     /* Set the surface pixels and refresh! */
   305     /* Set the surface pixels and refresh! */
   306     for (i = 0; i < 256; ++i) {
   306     for (i = 0; i < 256; ++i) {
   307         palette[i].r = 255 - i;
   307         palette[i].r = 255 - i;
   308         palette[i].g = 255 - i;
   308         palette[i].g = 255 - i;
   309         palette[i].b = 255 - i;
   309         palette[i].b = 255 - i;
   310     }
   310     }
   311     SDL_SetColors (screen, palette, 0, 256);
   311     SDL_SetColors(screen, palette, 0, 256);
   312     if (SDL_LockSurface (screen) < 0) {
   312     if (SDL_LockSurface(screen) < 0) {
   313         fprintf (stderr, "Couldn't lock display surface: %s\n",
   313         fprintf(stderr, "Couldn't lock display surface: %s\n",
   314                  SDL_GetError ());
   314                 SDL_GetError());
   315         quit (2);
   315         quit(2);
   316     }
   316     }
   317     buffer = (Uint8 *) screen->pixels;
   317     buffer = (Uint8 *) screen->pixels;
   318     for (i = 0; i < screen->h; ++i) {
   318     for (i = 0; i < screen->h; ++i) {
   319         memset (buffer, (i * 255) / screen->h,
   319         memset(buffer, (i * 255) / screen->h,
   320                 screen->w * screen->format->BytesPerPixel);
   320                screen->w * screen->format->BytesPerPixel);
   321         buffer += screen->pitch;
   321         buffer += screen->pitch;
   322     }
   322     }
   323     SDL_UnlockSurface (screen);
   323     SDL_UnlockSurface(screen);
   324     SDL_UpdateRect (screen, 0, 0, 0, 0);
   324     SDL_UpdateRect(screen, 0, 0, 0, 0);
   325 
   325 
   326     /* Loop, waiting for QUIT */
   326     /* Loop, waiting for QUIT */
   327     while (!done) {
   327     while (!done) {
   328         if (!(init_flags & SDL_INIT_EVENTTHREAD)) {
   328         if (!(init_flags & SDL_INIT_EVENTTHREAD)) {
   329             SDL_PumpEvents ();  /* Needed when event thread is off */
   329             SDL_PumpEvents();   /* Needed when event thread is off */
   330         }
   330         }
   331         if (SDL_PeepEvents (NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK)) {
   331         if (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK)) {
   332             done = 1;
   332             done = 1;
   333         }
   333         }
   334         /* Give up some CPU so the events can accumulate */
   334         /* Give up some CPU so the events can accumulate */
   335         SDL_Delay (20);
   335         SDL_Delay(20);
   336     }
   336     }
   337     SDL_WaitThread (mouse_thread, NULL);
   337     SDL_WaitThread(mouse_thread, NULL);
   338     SDL_WaitThread (keybd_thread, NULL);
   338     SDL_WaitThread(keybd_thread, NULL);
   339     SDL_Quit ();
   339     SDL_Quit();
   340     return (0);
   340     return (0);
   341 }
   341 }