src/video/photon/SDL_ph_wm.c
changeset 0 74212992fb08
child 19 8cc4dbfab9ab
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/photon/SDL_ph_wm.c	Thu Apr 26 16:45:43 2001 +0000
     1.3 @@ -0,0 +1,363 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Library General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Library General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Library General Public
    1.19 +    License along with this library; if not, write to the Free
    1.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@devolution.com
    1.24 +*/
    1.25 +
    1.26 +#ifdef SAVE_RCSID
    1.27 +static char rcsid =
    1.28 + "@(#) $Id$";
    1.29 +#endif
    1.30 +
    1.31 +#include <stdlib.h>
    1.32 +#include <string.h>
    1.33 +#include <Ph.h>
    1.34 +#include "SDL_version.h"
    1.35 +#include "SDL_error.h"
    1.36 +#include "SDL_timer.h"
    1.37 +#include "SDL_video.h"
    1.38 +#include "SDL_syswm.h"
    1.39 +#include "SDL_events_c.h"
    1.40 +#include "SDL_pixels_c.h"
    1.41 +#include "SDL_ph_modes_c.h"
    1.42 +#include "SDL_ph_wm_c.h"
    1.43 +
    1.44 +/* This is necessary for working properly with Enlightenment, etc. */
    1.45 +#define USE_ICON_WINDOW
    1.46 +
    1.47 +void ph_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
    1.48 +{
    1.49 +
    1.50 +#if 0 /*big*/
    1.51 +	int ncolors;
    1.52 +	PhImage_t *image;
    1.53 +	PgColor_t* palette;
    1.54 +
    1.55 +	image = PhCreateImage( image,
    1.56 +                          	icon->w,
    1.57 +                          	icon->h,
    1.58 +                          	Pg_IMAGE_DIRECT_888,
    1.59 +                          	NULL, 0, 0 );
    1.60 +
    1.61 +/* ---------------------------------------- */
    1.62 +	SDL_Surface *sicon;
    1.63 +//	XWMHints *wmhints;
    1.64 +//	XImage *icon_image;
    1.65 +//	Pixmap icon_pixmap;
    1.66 +//	Pixmap mask_pixmap;
    1.67 +//	GC GC;
    1.68 +//	XGCValues GCvalues;
    1.69 +	int i, b, dbpp;
    1.70 +	SDL_Rect bounds;
    1.71 +	Uint8 *LSBmask, *color_tried;
    1.72 +	Visual *dvis;
    1.73 +
    1.74 +	/* Lock the event thread, in multi-threading environments */
    1.75 +	SDL_Lock_EventThread();
    1.76 +
    1.77 +	/* The icon must use the default visual, depth and colormap of the
    1.78 +	   screen, so it might need a conversion */
    1.79 +// ?	dbpp = DefaultDepth(SDL_Display, SDL_Screen);
    1.80 +	switch(dbpp) {
    1.81 +	case 15:
    1.82 +	    dbpp = 16; break;
    1.83 +	case 24:
    1.84 +	    dbpp = 32; break;
    1.85 +	}
    1.86 +	dvis = DefaultVisual(SDL_Display, SDL_Screen);
    1.87 +
    1.88 +	/* The Visual struct is supposed to be opaque but we cheat a little */
    1.89 +	sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
    1.90 +				     dbpp,
    1.91 +				     dvis->red_mask, dvis->green_mask,
    1.92 +				     dvis->blue_mask, 0);
    1.93 +
    1.94 +	if ( sicon == NULL ) {
    1.95 +		goto done;
    1.96 +	}
    1.97 +	/* If we already have allocated colours from the default colormap,
    1.98 +	   copy them */
    1.99 +	if(SDL_Visual == dvis && SDL_XColorMap == SDL_DisplayColormap
   1.100 +	   && this->screen->format->palette && sicon->format->palette) {
   1.101 +	    memcpy(sicon->format->palette->colors,
   1.102 +		   this->screen->format->palette->colors,
   1.103 +		   this->screen->format->palette->ncolors * sizeof(SDL_Color));
   1.104 +	}
   1.105 +
   1.106 +	bounds.x = 0;
   1.107 +	bounds.y = 0;
   1.108 +	bounds.w = icon->w;
   1.109 +	bounds.h = icon->h;
   1.110 +	if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 )
   1.111 +		goto done;
   1.112 +
   1.113 +	/* Lock down the colors used in the colormap */
   1.114 +	color_tried = NULL;
   1.115 +	if ( sicon->format->BitsPerPixel == 8 ) {
   1.116 +		SDL_Palette *palette;
   1.117 +		Uint8 *p;
   1.118 +		XColor wanted;
   1.119 +
   1.120 +		palette = sicon->format->palette;
   1.121 +		color_tried = malloc(palette->ncolors);
   1.122 +		if ( color_tried == NULL ) {
   1.123 +			goto done;
   1.124 +		}
   1.125 +		if ( SDL_iconcolors != NULL ) {
   1.126 +			free(SDL_iconcolors);
   1.127 +		}
   1.128 +		SDL_iconcolors = malloc(palette->ncolors
   1.129 +					* sizeof(*SDL_iconcolors));
   1.130 +		if ( SDL_iconcolors == NULL ) {
   1.131 +			free(color_tried);
   1.132 +			goto done;
   1.133 +		}
   1.134 +		memset(color_tried, 0, palette->ncolors);
   1.135 +		memset(SDL_iconcolors, 0,
   1.136 +		       palette->ncolors * sizeof(*SDL_iconcolors));
   1.137 +
   1.138 +		p = (Uint8 *)sicon->pixels; 
   1.139 +		for ( i = sicon->w*sicon->h; i > 0; --i, ++p ) {
   1.140 +			if ( ! color_tried[*p] ) {
   1.141 +				wanted.pixel = *p;
   1.142 +				wanted.red   = (palette->colors[*p].r<<8);
   1.143 +				wanted.green = (palette->colors[*p].g<<8);
   1.144 +				wanted.blue  = (palette->colors[*p].b<<8);
   1.145 +				wanted.flags = (DoRed|DoGreen|DoBlue);
   1.146 +				if (XAllocColor(SDL_Display,
   1.147 +						SDL_DisplayColormap, &wanted)) {
   1.148 +					++SDL_iconcolors[wanted.pixel];
   1.149 +				}
   1.150 +				color_tried[*p] = 1;
   1.151 +			}
   1.152 +		}
   1.153 +	}
   1.154 +	if ( color_tried != NULL ) {
   1.155 +		free(color_tried);
   1.156 +	}
   1.157 +
   1.158 +	/* Translate mask data to LSB order and set the icon mask */
   1.159 +	i = (sicon->w/8)*sicon->h;
   1.160 +	LSBmask = (Uint8 *)malloc(i);
   1.161 +	if ( LSBmask == NULL ) {
   1.162 +		goto done;
   1.163 +	}
   1.164 +	memset(LSBmask, 0, i);
   1.165 +	while ( --i >= 0 ) {
   1.166 +		for ( b=0; b<8; ++b )
   1.167 +			LSBmask[i] |= (((mask[i]>>b)&0x01)<<(7-b));
   1.168 +	}
   1.169 +	mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
   1.170 +					LSBmask, sicon->w, sicon->h, 1L, 0L, 1);
   1.171 +
   1.172 +	/* Transfer the image to an X11 pixmap */
   1.173 +	icon_image = XCreateImage(SDL_Display,
   1.174 +			DefaultVisual(SDL_Display, SDL_Screen),
   1.175 +			DefaultDepth(SDL_Display, SDL_Screen),
   1.176 +			ZPixmap, 0, (char *)sicon->pixels, sicon->w, sicon->h,
   1.177 +			((sicon->format)->BytesPerPixel == 3) ? 32 :
   1.178 +				(sicon->format)->BytesPerPixel*8, 0);
   1.179 +	icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
   1.180 +			DefaultDepth(SDL_Display, SDL_Screen));
   1.181 +	GC = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
   1.182 +	XPutImage(SDL_Display, icon_pixmap, GC, icon_image,
   1.183 +					0, 0, 0, 0, sicon->w, sicon->h);
   1.184 +	XFreeGC(SDL_Display, GC);
   1.185 +	XDestroyImage(icon_image);
   1.186 +	free(LSBmask);
   1.187 +	sicon->pixels = NULL;
   1.188 +
   1.189 +#ifdef USE_ICON_WINDOW
   1.190 +	/* Create an icon window and set the pixmap as its background */
   1.191 +	icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
   1.192 +					0, 0, sicon->w, sicon->h, 0,
   1.193 +					CopyFromParent, CopyFromParent);
   1.194 +	XSetWindowBackgroundPixmap(SDL_Display, icon_window, icon_pixmap);
   1.195 +	XClearWindow(SDL_Display, icon_window);
   1.196 +#endif
   1.197 +
   1.198 +	/* Set the window icon to the icon pixmap (and icon window) */
   1.199 +	wmhints = XAllocWMHints();
   1.200 +	wmhints->flags = (IconPixmapHint | IconMaskHint);
   1.201 +	wmhints->icon_pixmap = icon_pixmap;
   1.202 +	wmhints->icon_mask = mask_pixmap;
   1.203 +#ifdef USE_ICON_WINDOW
   1.204 +	wmhints->flags |= IconWindowHint;
   1.205 +	wmhints->icon_window = icon_window;
   1.206 +#endif
   1.207 +	XSetWMHints(SDL_Display, WMwindow, wmhints);
   1.208 +	XFree(wmhints);
   1.209 +	XSync(SDL_Display, False);
   1.210 +
   1.211 +  done:
   1.212 +	SDL_Unlock_EventThread();
   1.213 +	if ( sicon != NULL ) {
   1.214 +		SDL_FreeSurface(sicon);
   1.215 +	}
   1.216 +	
   1.217 +#endif /*big*/
   1.218 +	return;
   1.219 +}
   1.220 +
   1.221 +void ph_SetCaption(_THIS, const char *title, const char *icon)
   1.222 +{
   1.223 +
   1.224 +#if 0
   1.225 +	XTextProperty titleprop, iconprop;
   1.226 +
   1.227 +	/* Lock the event thread, in multi-threading environments */
   1.228 +	SDL_Lock_EventThread();
   1.229 +
   1.230 +	if ( title != NULL ) {
   1.231 +		XStringListToTextProperty((char **)&title, 1, &titleprop);
   1.232 +		XSetWMName(SDL_Display, WMwindow, &titleprop);
   1.233 +		XFree(titleprop.value);
   1.234 +	}
   1.235 +	if ( icon != NULL ) {
   1.236 +		XStringListToTextProperty((char **)&icon, 1, &iconprop);
   1.237 +		XSetWMIconName(SDL_Display, WMwindow, &iconprop);
   1.238 +		XFree(iconprop.value);
   1.239 +	}
   1.240 +	XSync(SDL_Display, False);
   1.241 +
   1.242 +	SDL_Unlock_EventThread();
   1.243 +#endif
   1.244 +}
   1.245 +
   1.246 +/* Iconify the window */
   1.247 +int ph_IconifyWindow(_THIS)
   1.248 +{
   1.249 +	int result;
   1.250 +	
   1.251 +#if 0
   1.252 +	SDL_Lock_EventThread();
   1.253 +	result = XIconifyWindow(SDL_Display, WMwindow, SDL_Screen);
   1.254 +	XSync(SDL_Display, False);
   1.255 +	SDL_Unlock_EventThread();
   1.256 +#endif
   1.257 +	return(result);
   1.258 +}
   1.259 +
   1.260 +SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
   1.261 +{
   1.262 +#if 0 /*big*/
   1.263 +	int numtries, result;
   1.264 +
   1.265 +	if ( this->screen == NULL ) {
   1.266 +		return(SDL_GRAB_OFF);
   1.267 +	}
   1.268 +	if ( ! SDL_Window ) {
   1.269 +		return(mode);	/* Will be set later on mode switch */
   1.270 +	}
   1.271 +	if ( mode == SDL_GRAB_OFF ) {
   1.272 +		XUngrabPointer(SDL_Display, CurrentTime);
   1.273 +		if ( this->screen->flags & SDL_FULLSCREEN ) {
   1.274 +			/* Rebind the mouse to the fullscreen window */
   1.275 +			for ( numtries = 0; numtries < 10; ++numtries ) {
   1.276 +				result = XGrabPointer(SDL_Display, FSwindow,
   1.277 +						True, 0,
   1.278 +						GrabModeAsync, GrabModeAsync,
   1.279 +						FSwindow, None, CurrentTime);
   1.280 +				if ( result == AlreadyGrabbed ) {
   1.281 +					break;
   1.282 +				}
   1.283 +				SDL_Delay(100);
   1.284 +			}
   1.285 +		}
   1.286 +#ifdef GRAB_FULLSCREEN
   1.287 +		if ( !(this->screen->flags & SDL_FULLSCREEN) )
   1.288 +#endif
   1.289 +		XUngrabKeyboard(SDL_Display, CurrentTime);
   1.290 +	} else {
   1.291 +		if ( this->screen->flags & SDL_FULLSCREEN ) {
   1.292 +			/* Unbind the mouse from the fullscreen window */
   1.293 +			XUngrabPointer(SDL_Display, CurrentTime);
   1.294 +		}
   1.295 +		/* Try to grab the mouse */
   1.296 +		for ( numtries = 0; numtries < 10; ++numtries ) {
   1.297 +			result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
   1.298 +						GrabModeAsync, GrabModeAsync,
   1.299 +						SDL_Window, None, CurrentTime);
   1.300 +			if ( result != AlreadyGrabbed ) {
   1.301 +				break;
   1.302 +			}
   1.303 +			SDL_Delay(100);
   1.304 +		}
   1.305 +#ifdef GRAB_FULLSCREEN
   1.306 +		if ( !(this->screen->flags & SDL_FULLSCREEN) )
   1.307 +#endif
   1.308 +		XGrabKeyboard(SDL_Display, WMwindow, True,
   1.309 +			GrabModeAsync, GrabModeAsync, CurrentTime);
   1.310 +	}
   1.311 +	XSync(SDL_Display, False);
   1.312 +
   1.313 +
   1.314 +#endif /*big*/
   1.315 +	return(mode);
   1.316 +}
   1.317 +
   1.318 +SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
   1.319 +{
   1.320 +#if 0
   1.321 +	SDL_Lock_EventThread();
   1.322 +	mode = X11_GrabInputNoLock(this, mode);
   1.323 +	SDL_Unlock_EventThread();
   1.324 +#endif
   1.325 +	return(mode);
   1.326 +}
   1.327 +
   1.328 +/* If 'info' is the right version, this function fills it and returns 1.
   1.329 +   Otherwise, in case of a version mismatch, it returns -1.
   1.330 +*/
   1.331 +static void lock_display(void)
   1.332 +{
   1.333 +	SDL_Lock_EventThread();
   1.334 +}
   1.335 +static void unlock_display(void)
   1.336 +{
   1.337 +#if 0
   1.338 +	/* Make sure any X11 transactions are completed */
   1.339 +	SDL_VideoDevice *this = current_video;
   1.340 +	XSync(SDL_Display, False);
   1.341 +	SDL_Unlock_EventThread();
   1.342 +#endif
   1.343 +}
   1.344 +int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
   1.345 +{
   1.346 +#if 0
   1.347 +	if ( info->version.major <= SDL_MAJOR_VERSION ) {
   1.348 +		info->subsystem = SDL_SYSWM_X11;
   1.349 +		info->info.x11.display = SDL_Display;
   1.350 +		info->info.x11.window = SDL_Window;
   1.351 +		if ( SDL_VERSIONNUM(info->version.major,
   1.352 +		                    info->version.minor,
   1.353 +		                    info->version.patch) >= 1002 ) {
   1.354 +			info->info.x11.fswindow = FSwindow;
   1.355 +			info->info.x11.wmwindow = WMwindow;
   1.356 +		}
   1.357 +		info->info.x11.lock_func = lock_display;
   1.358 +		info->info.x11.unlock_func = unlock_display;
   1.359 +		return(1);
   1.360 +	} else {
   1.361 +		SDL_SetError("Application not compiled with SDL %d.%d\n",
   1.362 +					SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   1.363 +		return(-1);
   1.364 +	}
   1.365 +#endif
   1.366 +}