src/video/photon/SDL_ph_wm.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 18 Jan 2002 18:14:03 +0000
changeset 266 c6abdda2f666
parent 252 e8157fcb3114
child 283 3d8b6b9f1e18
permissions -rw-r--r--
Added QNX cleanups by Mike Gorchak (thanks!)
     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 current window */
   234 int ph_IconifyWindow(_THIS)
   235 {
   236    WmApiContext_t context=WmCreateContext();
   237    WmWindowDefinition_t **wininfo=malloc(sizeof(WmWindowDefinition_t)*2);
   238    int num;
   239 
   240    SDL_Lock_EventThread();
   241    WmGetFocusList(context,2,&num,wininfo);
   242    WmPerformFrameAction(context, wininfo[0]->rid,Pt_ACTION_MIN);
   243 
   244    WmDestroyContext (context);   
   245    SDL_Unlock_EventThread();	 
   246    free(wininfo);		   
   247 
   248    return (0);   
   249 }
   250 
   251 SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
   252 {
   253    return(mode);
   254 }
   255 
   256 SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
   257 {
   258    return(mode);
   259 }
   260 
   261 int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
   262 {
   263    if (info->version.major <= SDL_MAJOR_VERSION)
   264    {
   265       return 1;
   266    }
   267    else
   268    {
   269       SDL_SetError("Application not compiled with SDL %d.%d\n",
   270                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   271       return -1;
   272    }
   273 }