2 /* Test out the multi-threaded event handling functions */
9 #include "SDL_thread.h"
11 /* Are we done yet? */
14 /* Is the cursor visible? */
15 static int visible
= 1;
17 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
18 static void quit(int rc
)
24 SDL_Surface
*LoadIconSurface(char *file
, Uint8
**maskp
)
33 /* Load the icon surface */
34 icon
= SDL_LoadBMP(file
);
36 fprintf(stderr
, "Couldn't load %s: %s\n", file
, SDL_GetError());
40 /* Check width and height */
41 if ( (icon
->w
%8) != 0 ) {
42 fprintf(stderr
, "Icon width must be a multiple of 8!\n");
43 SDL_FreeSurface(icon
);
46 if ( icon
->format
->palette
== NULL
) {
47 fprintf(stderr
, "Icon must have a palette!\n");
48 SDL_FreeSurface(icon
);
52 /* Set the colorkey */
53 SDL_SetColorKey(icon
, SDL_SRCCOLORKEY
, *((Uint8
*)icon
->pixels
));
56 pixels
= (Uint8
*)icon
->pixels
;
57 printf("Transparent pixel: (%d,%d,%d)\n",
58 icon
->format
->palette
->colors
[*pixels
].r
,
59 icon
->format
->palette
->colors
[*pixels
].g
,
60 icon
->format
->palette
->colors
[*pixels
].b
);
61 mlen
= icon
->w
*icon
->h
;
62 mask
= (Uint8
*)malloc(mlen
/8);
64 fprintf(stderr
, "Out of memory!\n");
65 SDL_FreeSurface(icon
);
68 memset(mask
, 0, mlen
/8);
69 for ( i
=0; i
<mlen
; ) {
70 if ( pixels
[i
] != *pixels
)
80 int SDLCALL
FilterEvents(const SDL_Event
*event
)
82 static int reallyquit
= 0;
84 switch (event
->type
) {
87 /* See what happened */
89 event
->active
.gain
? "gained" : "lost");
90 if ( event
->active
.state
& SDL_APPACTIVE
)
92 if ( event
->active
.state
& SDL_APPMOUSEFOCUS
)
94 if ( event
->active
.state
& SDL_APPINPUTFOCUS
)
98 /* See if we are iconified or restored */
99 if ( event
->active
.state
& SDL_APPACTIVE
) {
100 printf("App has been %s\n",
102 "restored" : "iconified");
106 /* This is important! Queue it if we want to quit. */
108 if ( ! reallyquit
) {
110 printf("Quit requested\n");
113 printf("Quit demanded\n");
116 /* Mouse and keyboard events go to threads */
117 case SDL_MOUSEMOTION
:
118 case SDL_MOUSEBUTTONDOWN
:
119 case SDL_MOUSEBUTTONUP
:
124 /* Drop all other events */
130 int SDLCALL
HandleMouse(void *unused
)
132 SDL_Event events
[10];
136 /* Handle mouse events here */
137 mask
= (SDL_MOUSEMOTIONMASK
|SDL_MOUSEBUTTONDOWNMASK
|SDL_MOUSEBUTTONUPMASK
);
139 found
= SDL_PeepEvents(events
, 10, SDL_GETEVENT
, mask
);
140 for ( i
=0; i
<found
; ++i
) {
141 switch(events
[i
].type
) {
142 /* We want to toggle visibility on buttonpress */
143 case SDL_MOUSEBUTTONDOWN
:
144 case SDL_MOUSEBUTTONUP
:
145 if ( events
[i
].button
.state
== SDL_PRESSED
) {
147 SDL_ShowCursor(visible
);
149 printf("Mouse button %d has been %s\n",
150 events
[i
].button
.button
,
151 (events
[i
].button
.state
== SDL_PRESSED
) ?
152 "pressed" : "released");
154 /* Show relative mouse motion */
155 case SDL_MOUSEMOTION
:
156 printf("Mouse relative motion: {%d,%d}\n",
157 events
[i
].motion
.xrel
, events
[i
].motion
.yrel
);
161 /* Give up some CPU to allow events to arrive */
167 int SDLCALL
HandleKeyboard(void *unused
)
169 SDL_Event events
[10];
173 /* Handle mouse events here */
174 mask
= (SDL_KEYDOWNMASK
|SDL_KEYUPMASK
);
176 found
= SDL_PeepEvents(events
, 10, SDL_GETEVENT
, mask
);
177 for ( i
=0; i
<found
; ++i
) {
178 switch(events
[i
].type
) {
179 /* We want to toggle visibility on buttonpress */
182 printf("Key '%c' (keysym==%d) has been %s\n",
183 events
[i
].key
.keysym
.unicode
,
184 (int) events
[i
].key
.keysym
.sym
,
185 (events
[i
].key
.state
== SDL_PRESSED
) ?
186 "pressed" : "released");
188 /* Allow hitting <ESC> to quit the app */
189 if ( events
[i
].key
.keysym
.sym
== SDLK_ESCAPE
) {
193 /* skip events now that aren't KEYUPs... */
194 if (events
[i
].key
.state
== SDL_PRESSED
)
197 if ( events
[i
].key
.keysym
.sym
== SDLK_f
) {
199 printf("attempting to toggle fullscreen...\n");
200 rc
= SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
201 printf("SDL_WM_ToggleFullScreen returned %d.\n", rc
);
204 if ( events
[i
].key
.keysym
.sym
== SDLK_g
) {
206 m
= SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
?
207 SDL_GRAB_OFF
: SDL_GRAB_ON
;
208 printf("attempting to toggle input grab to %s...\n",
209 m
== SDL_GRAB_ON
? "ON" : "OFF");
211 printf("attempt finished.\n");
217 /* Give up some CPU to allow events to arrive */
223 int main(int argc
, char *argv
[])
230 SDL_Color palette
[256];
234 SDL_Thread
*mouse_thread
;
235 SDL_Thread
*keybd_thread
;
237 /* Set the options, based on command line arguments */
238 init_flags
= SDL_INIT_VIDEO
;
240 video_flags
= SDL_SWSURFACE
;
243 /* If the threaded option is enabled, and the SDL library hasn't
244 been compiled with threaded events enabled, then the mouse and
245 keyboard won't respond.
247 if ( (argc
>= 2) && (strcmp(argv
[1], "-threaded") == 0) ) {
248 init_flags
|= SDL_INIT_EVENTTHREAD
;
251 printf("Running with threaded events\n");
253 if ( (argc
>= 2) && (strcmp(argv
[1], "-fullscreen") == 0) ) {
254 video_flags
|= SDL_FULLSCREEN
;
258 if ( (argc
>= 3) && (strcmp(argv
[1], "-bpp") == 0) ) {
259 video_bpp
= atoi(argv
[2]);
267 /* Initialize SDL with the requested flags */
268 if ( SDL_Init(init_flags
) < 0 ) {
270 "Couldn't initialize SDL: %s\n", SDL_GetError());
274 /* Set the icon -- this must be done before the first mode set */
275 icon
= LoadIconSurface("icon.bmp", &icon_mask
);
276 if ( icon
!= NULL
) {
277 SDL_WM_SetIcon(icon
, icon_mask
);
279 if ( icon_mask
!= NULL
)
282 /* Initialize the display */
283 screen
= SDL_SetVideoMode(640, 480, video_bpp
, video_flags
);
284 if ( screen
== NULL
) {
285 fprintf(stderr
, "Couldn't set 640x480x%d video mode: %s\n",
286 video_bpp
, SDL_GetError());
289 printf("Running in %s mode\n", screen
->flags
& SDL_FULLSCREEN
?
290 "fullscreen" : "windowed");
292 /* Enable printable characters */
293 SDL_EnableUNICODE(1);
295 /* Set an event filter that discards everything but QUIT */
296 SDL_SetEventFilter(FilterEvents
);
298 /* Create the event handling threads */
299 mouse_thread
= SDL_CreateThread(HandleMouse
, NULL
);
300 keybd_thread
= SDL_CreateThread(HandleKeyboard
, NULL
);
302 /* Set the surface pixels and refresh! */
303 for ( i
=0; i
<256; ++i
) {
304 palette
[i
].r
= 255-i
;
305 palette
[i
].g
= 255-i
;
306 palette
[i
].b
= 255-i
;
308 SDL_SetColors(screen
, palette
, 0, 256);
309 if ( SDL_LockSurface(screen
) < 0 ) {
310 fprintf(stderr
, "Couldn't lock display surface: %s\n",
314 buffer
= (Uint8
*)screen
->pixels
;
315 for ( i
=0; i
<screen
->h
; ++i
) {
316 memset(buffer
,(i
*255)/screen
->h
,
317 screen
->w
*screen
->format
->BytesPerPixel
);
318 buffer
+= screen
->pitch
;
320 SDL_UnlockSurface(screen
);
321 SDL_UpdateRect(screen
, 0, 0, 0, 0);
323 /* Loop, waiting for QUIT */
325 if ( ! (init_flags
& SDL_INIT_EVENTTHREAD
) ) {
326 SDL_PumpEvents(); /* Needed when event thread is off */
328 if ( SDL_PeepEvents(NULL
, 0, SDL_PEEKEVENT
, SDL_QUITMASK
) ) {
331 /* Give up some CPU so the events can accumulate */
334 SDL_WaitThread(mouse_thread
, NULL
);
335 SDL_WaitThread(keybd_thread
, NULL
);