src/video/photon/SDL_ph_wm.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Dec 2001 12:38:15 +0000
changeset 252 e8157fcb3114
parent 190 e4af2c852c09
child 266 c6abdda2f666
permissions -rw-r--r--
Updated the source with the correct e-mail address
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #define DISABLE_X11
    29 
    30 #include <stdlib.h>
    31 #include <string.h>
    32 #include <Ph.h>
    33 #include <photon/PpProto.h>
    34 #include <photon/PhWm.h>
    35 #include <photon/wmapi.h>
    36 #include "SDL_version.h"
    37 #include "SDL_error.h"
    38 #include "SDL_timer.h"
    39 #include "SDL_video.h"
    40 #include "SDL_syswm.h"
    41 #include "SDL_events_c.h"
    42 #include "SDL_pixels_c.h"
    43 #include "SDL_ph_modes_c.h"
    44 #include "SDL_ph_wm_c.h"
    45 
    46 /* This is necessary for working properly with Enlightenment, etc. */
    47 #define USE_ICON_WINDOW
    48 
    49 void ph_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
    50 {
    51 
    52 #if 0 /*big*/
    53 	int ncolors;
    54 	PhImage_t *image;
    55 	PgColor_t* palette;
    56 
    57 	image = PhCreateImage( image,
    58                           	icon->w,
    59                           	icon->h,
    60                           	Pg_IMAGE_DIRECT_888,
    61                           	NULL, 0, 0 );
    62 
    63 /* ---------------------------------------- */
    64 	SDL_Surface *sicon;
    65 //	XWMHints *wmhints;
    66 //	XImage *icon_image;
    67 //	Pixmap icon_pixmap;
    68 //	Pixmap mask_pixmap;
    69 //	GC GC;
    70 //	XGCValues GCvalues;
    71 	int i, b, dbpp;
    72 	SDL_Rect bounds;
    73 	Uint8 *LSBmask, *color_tried;
    74 	Visual *dvis;
    75 
    76 	/* Lock the event thread, in multi-threading environments */
    77 	SDL_Lock_EventThread();
    78 
    79 	/* The icon must use the default visual, depth and colormap of the
    80 	   screen, so it might need a conversion */
    81 // ?	dbpp = DefaultDepth(SDL_Display, SDL_Screen);
    82 	switch(dbpp) {
    83 	case 15:
    84 	    dbpp = 16; break;
    85 	case 24:
    86 	    dbpp = 32; break;
    87 	}
    88 	dvis = DefaultVisual(SDL_Display, SDL_Screen);
    89 
    90 	/* The Visual struct is supposed to be opaque but we cheat a little */
    91 	sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
    92 				     dbpp,
    93 				     dvis->red_mask, dvis->green_mask,
    94 				     dvis->blue_mask, 0);
    95 
    96 	if ( sicon == NULL ) {
    97 		goto done;
    98 	}
    99 	/* If we already have allocated colours from the default colormap,
   100 	   copy them */
   101 	if(SDL_Visual == dvis && SDL_XColorMap == SDL_DisplayColormap
   102 	   && this->screen->format->palette && sicon->format->palette) {
   103 	    memcpy(sicon->format->palette->colors,
   104 		   this->screen->format->palette->colors,
   105 		   this->screen->format->palette->ncolors * sizeof(SDL_Color));
   106 	}
   107 
   108 	bounds.x = 0;
   109 	bounds.y = 0;
   110 	bounds.w = icon->w;
   111 	bounds.h = icon->h;
   112 	if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 )
   113 		goto done;
   114 
   115 	/* Lock down the colors used in the colormap */
   116 	color_tried = NULL;
   117 	if ( sicon->format->BitsPerPixel == 8 ) {
   118 		SDL_Palette *palette;
   119 		Uint8 *p;
   120 		XColor wanted;
   121 
   122 		palette = sicon->format->palette;
   123 		color_tried = malloc(palette->ncolors);
   124 		if ( color_tried == NULL ) {
   125 			goto done;
   126 		}
   127 		if ( SDL_iconcolors != NULL ) {
   128 			free(SDL_iconcolors);
   129 		}
   130 		SDL_iconcolors = malloc(palette->ncolors
   131 					* sizeof(*SDL_iconcolors));
   132 		if ( SDL_iconcolors == NULL ) {
   133 			free(color_tried);
   134 			goto done;
   135 		}
   136 		memset(color_tried, 0, palette->ncolors);
   137 		memset(SDL_iconcolors, 0,
   138 		       palette->ncolors * sizeof(*SDL_iconcolors));
   139 
   140 		p = (Uint8 *)sicon->pixels; 
   141 		for ( i = sicon->w*sicon->h; i > 0; --i, ++p ) {
   142 			if ( ! color_tried[*p] ) {
   143 				wanted.pixel = *p;
   144 				wanted.red   = (palette->colors[*p].r<<8);
   145 				wanted.green = (palette->colors[*p].g<<8);
   146 				wanted.blue  = (palette->colors[*p].b<<8);
   147 				wanted.flags = (DoRed|DoGreen|DoBlue);
   148 				if (XAllocColor(SDL_Display,
   149 						SDL_DisplayColormap, &wanted)) {
   150 					++SDL_iconcolors[wanted.pixel];
   151 				}
   152 				color_tried[*p] = 1;
   153 			}
   154 		}
   155 	}
   156 	if ( color_tried != NULL ) {
   157 		free(color_tried);
   158 	}
   159 
   160 	/* Translate mask data to LSB order and set the icon mask */
   161 	i = (sicon->w/8)*sicon->h;
   162 	LSBmask = (Uint8 *)malloc(i);
   163 	if ( LSBmask == NULL ) {
   164 		goto done;
   165 	}
   166 	memset(LSBmask, 0, i);
   167 	while ( --i >= 0 ) {
   168 		for ( b=0; b<8; ++b )
   169 			LSBmask[i] |= (((mask[i]>>b)&0x01)<<(7-b));
   170 	}
   171 	mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
   172 					LSBmask, sicon->w, sicon->h, 1L, 0L, 1);
   173 
   174 	/* Transfer the image to an X11 pixmap */
   175 	icon_image = XCreateImage(SDL_Display,
   176 			DefaultVisual(SDL_Display, SDL_Screen),
   177 			DefaultDepth(SDL_Display, SDL_Screen),
   178 			ZPixmap, 0, (char *)sicon->pixels, sicon->w, sicon->h,
   179 			((sicon->format)->BytesPerPixel == 3) ? 32 :
   180 				(sicon->format)->BytesPerPixel*8, 0);
   181 	icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
   182 			DefaultDepth(SDL_Display, SDL_Screen));
   183 	GC = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
   184 	XPutImage(SDL_Display, icon_pixmap, GC, icon_image,
   185 					0, 0, 0, 0, sicon->w, sicon->h);
   186 	XFreeGC(SDL_Display, GC);
   187 	XDestroyImage(icon_image);
   188 	free(LSBmask);
   189 	sicon->pixels = NULL;
   190 
   191 #ifdef USE_ICON_WINDOW
   192 	/* Create an icon window and set the pixmap as its background */
   193 	icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
   194 					0, 0, sicon->w, sicon->h, 0,
   195 					CopyFromParent, CopyFromParent);
   196 	XSetWindowBackgroundPixmap(SDL_Display, icon_window, icon_pixmap);
   197 	XClearWindow(SDL_Display, icon_window);
   198 #endif
   199 
   200 	/* Set the window icon to the icon pixmap (and icon window) */
   201 	wmhints = XAllocWMHints();
   202 	wmhints->flags = (IconPixmapHint | IconMaskHint);
   203 	wmhints->icon_pixmap = icon_pixmap;
   204 	wmhints->icon_mask = mask_pixmap;
   205 #ifdef USE_ICON_WINDOW
   206 	wmhints->flags |= IconWindowHint;
   207 	wmhints->icon_window = icon_window;
   208 #endif
   209 	XSetWMHints(SDL_Display, WMwindow, wmhints);
   210 	XFree(wmhints);
   211 	XSync(SDL_Display, False);
   212 
   213   done:
   214 	SDL_Unlock_EventThread();
   215 	if ( sicon != NULL ) {
   216 		SDL_FreeSurface(sicon);
   217 	}
   218 	
   219 #endif /*big*/
   220 	return;
   221 }
   222 
   223 /* Set window caption */
   224 void ph_SetCaption(_THIS, const char *title, const char *icon)
   225 {
   226 	SDL_Lock_EventThread();
   227 	if ( title != NULL ) {
   228 		PtSetResource(window, Pt_ARG_WINDOW_TITLE, title, 0);
   229 	}
   230 	SDL_Unlock_EventThread();
   231 }
   232 
   233 /* Iconify the window (stolen from PhHotKey sources by phearbear ;-) */
   234 int ph_IconifyWindow(_THIS)
   235 {
   236 #if 1 /* Code submitted by Luca <barbato_luca@yahoo.com> */
   237 	WmApiContext_t context=WmCreateContext();
   238 	WmWindowDefinition_t
   239 **wininfo=malloc(sizeof(WmWindowDefinition_t)*2);
   240 	int num;									
   241 	SDL_Lock_EventThread();
   242 	WmGetFocusList(context,2,&num,wininfo);
   243 	WmPerformFrameAction(context, wininfo[0]->rid,Pt_ACTION_MIN);
   244 
   245 	WmDestroyContext (context);   
   246 	SDL_Unlock_EventThread();	 
   247 	free(wininfo);		   
   248 	return (0);   
   249 #else
   250 	int result=0;
   251         int myerr;
   252         int num;
   253         PtConnectionClient_t *Client=0;
   254         WmMsg_t* Message=malloc(sizeof(WmMsg_t));
   255         WmReply_t *Reply=malloc(sizeof(WmReply_t));
   256         WmApiContext_t MsgStruct=malloc(sizeof(WmApiContext_t));
   257         WmWindowDefinition_t **WNDDEF=malloc(sizeof(WmWindowDefinition_t)*2);
   258 	
   259 	SDL_Lock_EventThread();
   260 
   261         PtInit("/dev/photon");
   262 
   263         Client=PtConnectionFindName("pwm",0,0);
   264 
   265         if(!Client)
   266         {
   267            return result;
   268         }
   269 
   270         MsgStruct->input_group=PhInputGroup(0);
   271         MsgStruct->connection=PtConnectionFindName("pwm",0,0);
   272         myerr=WmGetFocusList(MsgStruct,2,&num,WNDDEF);
   273 
   274         Message->hdr.type=WM_REQUEST_WIN_ACTION;
   275         Message->hdr.subtype=Pt_ACTION_MIN;	   
   276         Message->hdr.rid=WNDDEF[0]->rid;
   277         myerr=WmSendMessage(Client,Message,Reply,0);
   278 
   279         free(Message);
   280         free(Reply);
   281 
   282 	SDL_Unlock_EventThread();
   283 
   284 	return(result);
   285 #endif /* 1 */
   286 }
   287 
   288 SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
   289 {
   290 #if 0 /*big*/
   291 	int numtries, result;
   292 
   293 	if ( this->screen == NULL ) {
   294 		return(SDL_GRAB_OFF);
   295 	}
   296 	if ( ! SDL_Window ) {
   297 		return(mode);	/* Will be set later on mode switch */
   298 	}
   299 	if ( mode == SDL_GRAB_OFF ) {
   300 		XUngrabPointer(SDL_Display, CurrentTime);
   301 		if ( this->screen->flags & SDL_FULLSCREEN ) {
   302 			/* Rebind the mouse to the fullscreen window */
   303 			for ( numtries = 0; numtries < 10; ++numtries ) {
   304 				result = XGrabPointer(SDL_Display, FSwindow,
   305 						True, 0,
   306 						GrabModeAsync, GrabModeAsync,
   307 						FSwindow, None, CurrentTime);
   308 				if ( result == AlreadyGrabbed ) {
   309 					break;
   310 				}
   311 				SDL_Delay(100);
   312 			}
   313 		}
   314 #ifdef GRAB_FULLSCREEN
   315 		if ( !(this->screen->flags & SDL_FULLSCREEN) )
   316 #endif
   317 		XUngrabKeyboard(SDL_Display, CurrentTime);
   318 	} else {
   319 		if ( this->screen->flags & SDL_FULLSCREEN ) {
   320 			/* Unbind the mouse from the fullscreen window */
   321 			XUngrabPointer(SDL_Display, CurrentTime);
   322 		}
   323 		/* Try to grab the mouse */
   324 		for ( numtries = 0; numtries < 10; ++numtries ) {
   325 			result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
   326 						GrabModeAsync, GrabModeAsync,
   327 						SDL_Window, None, CurrentTime);
   328 			if ( result != AlreadyGrabbed ) {
   329 				break;
   330 			}
   331 			SDL_Delay(100);
   332 		}
   333 #ifdef GRAB_FULLSCREEN
   334 		if ( !(this->screen->flags & SDL_FULLSCREEN) )
   335 #endif
   336 		XGrabKeyboard(SDL_Display, WMwindow, True,
   337 			GrabModeAsync, GrabModeAsync, CurrentTime);
   338 	}
   339 	XSync(SDL_Display, False);
   340 
   341 
   342 #endif /*big*/
   343 	return(mode);
   344 }
   345 
   346 SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
   347 {
   348 #if 0
   349 	SDL_Lock_EventThread();
   350 	mode = X11_GrabInputNoLock(this, mode);
   351 	SDL_Unlock_EventThread();
   352 #endif
   353 	return(mode);
   354 }
   355 
   356 /* If 'info' is the right version, this function fills it and returns 1.
   357    Otherwise, in case of a version mismatch, it returns -1.
   358 */
   359 static void lock_display(void)
   360 {
   361 	SDL_Lock_EventThread();
   362 }
   363 static void unlock_display(void)
   364 {
   365 #if 0
   366 	/* Make sure any X11 transactions are completed */
   367 	SDL_VideoDevice *this = current_video;
   368 	XSync(SDL_Display, False);
   369 #endif
   370 	SDL_Unlock_EventThread();
   371 }
   372 int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
   373 {
   374 #if 0
   375 	if ( info->version.major <= SDL_MAJOR_VERSION ) {
   376 		info->subsystem = SDL_SYSWM_X11;
   377 		info->info.x11.display = SDL_Display;
   378 		info->info.x11.window = SDL_Window;
   379 		if ( SDL_VERSIONNUM(info->version.major,
   380 		                    info->version.minor,
   381 		                    info->version.patch) >= 1002 ) {
   382 			info->info.x11.fswindow = FSwindow;
   383 			info->info.x11.wmwindow = WMwindow;
   384 		}
   385 		info->info.x11.lock_func = lock_display;
   386 		info->info.x11.unlock_func = unlock_display;
   387 		return(1);
   388 	} else {
   389 		SDL_SetError("Application not compiled with SDL %d.%d\n",
   390 					SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   391 		return(-1);
   392 	}
   393 #endif
   394    return -1; // for now ...
   395 }
   396 
   397