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