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