test/testwm.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 15 Feb 2004 20:31:27 +0000
changeset 826 3eddf51b649b
parent 609 a30b17e09cc0
child 1151 be9c9c8f6d53
permissions -rw-r--r--
Showed how to toggle fullscreen mode if the API isn't supported
     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 int SetVideoMode(int w, int h)
    17 {
    18 	SDL_Surface *screen;
    19 	int i;
    20 	Uint8 *buffer;
    21 	SDL_Color palette[256];
    22 
    23 	screen = SDL_SetVideoMode(w, h, video_bpp, video_flags);
    24 	if (  screen == NULL ) {
    25 		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
    26 					w, h, video_bpp, SDL_GetError());
    27 		return(-1);
    28 	}
    29 	printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
    30 						"fullscreen" : "windowed");
    31 
    32 	/* Set the surface pixels and refresh! */
    33 	for ( i=0; i<256; ++i ) {
    34 		palette[i].r = 255-i;
    35 		palette[i].g = 255-i;
    36 		palette[i].b = 255-i;
    37 	}
    38 	SDL_SetColors(screen, palette, 0, 256);
    39 	if ( SDL_LockSurface(screen) < 0 ) {
    40 		fprintf(stderr, "Couldn't lock display surface: %s\n",
    41 							SDL_GetError());
    42 		return(-1);
    43 	}
    44 	buffer = (Uint8 *)screen->pixels;
    45 	for ( i=0; i<screen->h; ++i ) {
    46 		memset(buffer,(i*255)/screen->h,
    47 				screen->w*screen->format->BytesPerPixel);
    48 		buffer += screen->pitch;
    49 	}
    50 	SDL_UnlockSurface(screen);
    51 	SDL_UpdateRect(screen, 0, 0, 0, 0);
    52 
    53 	return(0);
    54 }
    55 
    56 SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp)
    57 {
    58 	SDL_Surface *icon;
    59 	Uint8       *pixels;
    60 	Uint8       *mask;
    61 	int          mlen, i, j;
    62 
    63 	*maskp = NULL;
    64 
    65 	/* Load the icon surface */
    66 	icon = SDL_LoadBMP(file);
    67 	if ( icon == NULL ) {
    68 		fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
    69 		return(NULL);
    70 	}
    71 
    72 	/* Check width and height 
    73 	if ( (icon->w%8) != 0 ) {
    74 		fprintf(stderr, "Icon width must be a multiple of 8!\n");
    75 		SDL_FreeSurface(icon);
    76 		return(NULL);
    77 	}
    78 */
    79     
    80     
    81 	if ( icon->format->palette == NULL ) {
    82 		fprintf(stderr, "Icon must have a palette!\n");
    83 		SDL_FreeSurface(icon);
    84 		return(NULL);
    85 	}
    86 
    87 	/* Set the colorkey */
    88 	SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels));
    89 
    90 	/* Create the mask */
    91 	pixels = (Uint8 *)icon->pixels;
    92 	printf("Transparent pixel: (%d,%d,%d)\n",
    93 				icon->format->palette->colors[*pixels].r,
    94 				icon->format->palette->colors[*pixels].g,
    95 				icon->format->palette->colors[*pixels].b);
    96 	mlen = (icon->w*icon->h + 7) / 8;
    97 	mask = (Uint8 *)malloc(mlen);
    98 	if ( mask == NULL ) {
    99 		fprintf(stderr, "Out of memory!\n");
   100 		SDL_FreeSurface(icon);
   101 		return(NULL);
   102 	}
   103 	memset(mask, 0, mlen);
   104 	for ( i=0; i < icon->h; i++)
   105         for (j=0; j < icon->w; j++) {
   106             int pindex = i * icon->pitch + j;
   107             int mindex = i * icon->w + j;
   108             if ( pixels[pindex] != *pixels )
   109                 mask[mindex>>3] |= 1 << (7 - (mindex & 7));
   110         }
   111 	*maskp = mask;
   112 	return(icon);
   113 }
   114 
   115 void HotKey_ToggleFullScreen(void)
   116 {
   117 	SDL_Surface *screen;
   118 
   119 	screen = SDL_GetVideoSurface();
   120 	if ( SDL_WM_ToggleFullScreen(screen) ) {
   121 		printf("Toggled fullscreen mode - now %s\n",
   122 		    (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
   123 	} else {
   124 		printf("Unable to toggle fullscreen mode\n");
   125 		video_flags ^= SDL_FULLSCREEN;
   126 		SetVideoMode(screen->w, screen->h);
   127 	}
   128 }
   129 
   130 void HotKey_ToggleGrab(void)
   131 {
   132 	SDL_GrabMode mode;
   133 
   134 	printf("Ctrl-G: toggling input grab!\n");
   135 	mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
   136 	if ( mode == SDL_GRAB_ON ) {
   137 		printf("Grab was on\n");
   138 	} else {
   139 		printf("Grab was off\n");
   140 	}
   141 	mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON);
   142 	if ( mode == SDL_GRAB_ON ) {
   143 		printf("Grab is now on\n");
   144 	} else {
   145 		printf("Grab is now off\n");
   146 	}
   147 }
   148 
   149 void HotKey_Iconify(void)
   150 {
   151 	printf("Ctrl-Z: iconifying window!\n");
   152 	SDL_WM_IconifyWindow();
   153 }
   154 
   155 void HotKey_Quit(void)
   156 {
   157 	SDL_Event event;
   158 
   159 	printf("Posting internal quit request\n");
   160 	event.type = SDL_USEREVENT;
   161 	SDL_PushEvent(&event);
   162 }
   163 
   164 int FilterEvents(const SDL_Event *event)
   165 {
   166 	static int reallyquit = 0;
   167 
   168 	switch (event->type) {
   169 
   170 		case SDL_ACTIVEEVENT:
   171 			/* See what happened */
   172 			printf("App %s ",
   173 				event->active.gain ? "gained" : "lost");
   174 			if ( event->active.state & SDL_APPACTIVE )
   175 				printf("active ");
   176 			if ( event->active.state & SDL_APPMOUSEFOCUS )
   177 				printf("mouse ");
   178 			if ( event->active.state & SDL_APPINPUTFOCUS )
   179 				printf("input ");
   180 			printf("focus\n");
   181 
   182 			/* See if we are iconified or restored */
   183 			if ( event->active.state & SDL_APPACTIVE ) {
   184 				printf("App has been %s\n",
   185 					event->active.gain ?
   186 						 "restored" : "iconified");
   187 			}
   188 			return(0);
   189 
   190 		/* We want to toggle visibility on buttonpress */
   191 		case SDL_MOUSEBUTTONDOWN:
   192 		case SDL_MOUSEBUTTONUP:
   193 			if ( event->button.state == SDL_PRESSED ) {
   194 				visible = !visible;
   195 				SDL_ShowCursor(visible);
   196 			}
   197 			printf("Mouse button %d has been %s\n",
   198 				event->button.button,
   199 				(event->button.state == SDL_PRESSED) ?
   200 						"pressed" : "released");
   201 			return(0);
   202 
   203 		/* Show relative mouse motion */
   204 		case SDL_MOUSEMOTION:
   205 #if 0
   206 			printf("Mouse relative motion: {%d,%d}\n",
   207 				event->motion.xrel, event->motion.yrel);
   208 #endif
   209 			return(0);
   210 
   211 		case SDL_KEYDOWN:
   212 			if ( event->key.keysym.sym == SDLK_ESCAPE ) {
   213 				HotKey_Quit();
   214 			}
   215 			if ( (event->key.keysym.sym == SDLK_g) &&
   216 			     (event->key.keysym.mod & KMOD_CTRL) ) {
   217 				HotKey_ToggleGrab();
   218 			}
   219 			if ( (event->key.keysym.sym == SDLK_z) &&
   220 			     (event->key.keysym.mod & KMOD_CTRL) ) {
   221 				HotKey_Iconify();
   222 			}
   223 			if ( (event->key.keysym.sym == SDLK_RETURN) &&
   224 			     (event->key.keysym.mod & KMOD_ALT) ) {
   225 				HotKey_ToggleFullScreen();
   226 			}
   227 			return(0);
   228 
   229 		/* Pass the video resize event through .. */
   230 		case SDL_VIDEORESIZE:
   231 			return(1);
   232 
   233 		/* This is important!  Queue it if we want to quit. */
   234 		case SDL_QUIT:
   235 			if ( ! reallyquit ) {
   236 				reallyquit = 1;
   237 				printf("Quit requested\n");
   238 				return(0);
   239 			}
   240 			printf("Quit demanded\n");
   241 			return(1);
   242 
   243 		/* This will never happen because events queued directly
   244 		   to the event queue are not filtered.
   245 		 */
   246 		case SDL_USEREVENT:
   247 			return(1);
   248 
   249 		/* Drop all other events */
   250 		default:
   251 			return(0);
   252 	}
   253 }
   254 
   255 int main(int argc, char *argv[])
   256 {
   257 	SDL_Event event;
   258 	char *title;
   259 	SDL_Surface *icon;
   260 	Uint8 *icon_mask;
   261 	int parsed;
   262 	int w, h;
   263 
   264 	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
   265 		fprintf(stderr,
   266 			"Couldn't initialize SDL: %s\n", SDL_GetError());
   267 		exit(1);
   268 	}
   269 	atexit(SDL_Quit);
   270 
   271 	/* Check command line arguments */
   272 	w = 640;
   273 	h = 480;
   274 	video_bpp = 8;
   275 	video_flags = SDL_SWSURFACE;
   276 	parsed = 1;
   277 	while ( parsed ) {
   278 		if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
   279 			video_flags |= SDL_FULLSCREEN;
   280 			argc -= 1;
   281 			argv += 1;
   282 		} else
   283 		if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) {
   284 			video_flags |= SDL_RESIZABLE;
   285 			argc -= 1;
   286 			argv += 1;
   287 		} else
   288 		if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) {
   289 			video_flags |= SDL_NOFRAME;
   290 			argc -= 1;
   291 			argv += 1;
   292 		} else
   293 		if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) {
   294 			w = atoi(argv[2]);
   295 			argc -= 2;
   296 			argv += 2;
   297 		} else
   298 		if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) {
   299 			h = atoi(argv[2]);
   300 			argc -= 2;
   301 			argv += 2;
   302 		} else
   303 		if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
   304 			video_bpp = atoi(argv[2]);
   305 			argc -= 2;
   306 			argv += 2;
   307 		} else {
   308 			parsed = 0;
   309 		}
   310 	}
   311 
   312 	/* Set the icon -- this must be done before the first mode set */
   313 	icon = LoadIconSurface("icon.bmp", &icon_mask);
   314 	if ( icon != NULL ) {
   315 		SDL_WM_SetIcon(icon, icon_mask);
   316 	}
   317 	if ( icon_mask != NULL )
   318 		free(icon_mask);
   319 
   320 	/* Set the title bar */
   321 	if ( argv[1] == NULL )
   322 		title = "Testing  1.. 2.. 3...";
   323 	else
   324 		title = argv[1];
   325 	SDL_WM_SetCaption(title, "testwm");
   326 
   327 	/* See if it's really set */
   328 	SDL_WM_GetCaption(&title, NULL);
   329 	if ( title )
   330 		printf("Title was set to: %s\n", title);
   331 	else
   332 		printf("No window title was set!\n");
   333 
   334 	/* Initialize the display */
   335 	if ( SetVideoMode(w, h) < 0 ) {
   336 		return(1);
   337 	}
   338 
   339 	/* Set an event filter that discards everything but QUIT */
   340 	SDL_SetEventFilter(FilterEvents);
   341 
   342 	/* Ignore key up events, they don't even get filtered */
   343 	SDL_EventState(SDL_KEYUP, SDL_IGNORE);
   344 
   345 	/* Loop, waiting for QUIT */
   346 	while ( SDL_WaitEvent(&event) ) {
   347 		switch (event.type) {
   348 			case SDL_VIDEORESIZE:
   349 				printf("Got a resize event: %dx%d\n",
   350 				       event.resize.w, event.resize.h);
   351 				SetVideoMode(event.resize.w, event.resize.h);
   352 				break;
   353 			case SDL_USEREVENT:
   354 				printf("Handling internal quit request\n");
   355 				/* Fall through to the quit handler */
   356 			case SDL_QUIT:
   357 				printf("Bye bye..\n");
   358 				return(0);
   359 			default:
   360 				/* This should never happen */
   361 				printf("Warning: Event %d wasn't filtered\n",
   362 								event.type);
   363 				break;
   364 		}
   365 	}
   366 	printf("SDL_WaitEvent() error: %s\n", SDL_GetError());
   367 	return(255);
   368 }