Home | History | Annotate | Download | only in test
      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 quit(int rc)
     18 {
     19 	SDL_Quit();
     20 	exit(rc);
     21 }
     22 
     23 int 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 
     63 SDL_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 
    122 void 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 
    137 void 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 
    156 void HotKey_Iconify(void)
    157 {
    158 	printf("Ctrl-Z: iconifying window!\n");
    159 	SDL_WM_IconifyWindow();
    160 }
    161 
    162 void 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 
    171 static 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 
    204 static 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 
    236 int 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 
    333 int 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