test/testwm.c
author Sam Lantinga
Mon, 28 Sep 2009 07:04:25 +0000
branchSDL-1.2
changeset 4257 14195cfdb66e
parent 1779 67fc81efcfc3
permissions -rw-r--r--
Added keyboard output for debugging bug #659
     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 }