src/video/photon/SDL_ph_wm.c
author Sam Lantinga <slouken@lokigames.com>
Thu, 10 May 2001 18:42:17 +0000
changeset 19 8cc4dbfab9ab
parent 0 74212992fb08
child 190 e4af2c852c09
permissions -rw-r--r--
Date: Thu, 19 Apr 2001 08:36:54 +0300
From: "Mike Gorchak" <mike@malva.com.ua>
Subject: Patches for QNX RtP

Here my patch for QNX RtP/Photon for SDL-1.2.

Detailed description of my changes:

SDL/configure.in:
If Photon detected declare define ENABLE_PHOTON.

SDL/src/video/SDL_sysvideo.h:
Added extern to ph_bootstrap.

SDL/src/video/SDL_video.c:
Added ph_bootstrap to bootstrap array.

SDL/src/video/photon/SDL_ph_events.c:
Declare DISABLE_X11 if compiled for Photon.

SDL/src/video/photon/SDL_ph_image.c:
Fixed segment violation on exit. Please update BUGS file.

SDL/src/video/photon/SDL_ph_video.c:
1. Enabling window manager.
2. Added to device capabilities Photon Window Manager functions:
SetCaption and IconifyWindow.
3. Renamed X11_bootstrap to ph_bootstrap.
4. Removed SEGFAULT termination of programs if Photon not available.

SDL/src/video/photon/SDL_ph_wm.c:
1. Declare DISABLE_X11 if compiled for Photon.
2. Added ph_SetCaption and ph_IconifyWindow code. (Thanks to
'phearbear' for iconify window source).
3. Some stubers for other wm functions.

Thanks !

----------------------------
Mike Gorchak
CJSC Malva
System Programmer
     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@devolution.com
    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 	int result=0;
   237         int myerr;
   238         int num;
   239         PtConnectionClient_t *Client=0;
   240         WmMsg_t* Message=malloc(sizeof(WmMsg_t));
   241         WmReply_t *Reply=malloc(sizeof(WmReply_t));
   242         WmApiContext_t MsgStruct=malloc(sizeof(WmApiContext_t));
   243         WmWindowDefinition_t **WNDDEF=malloc(sizeof(WmWindowDefinition_t)*2);
   244 	
   245 	SDL_Lock_EventThread();
   246 
   247         PtInit("/dev/photon");
   248 
   249         Client=PtConnectionFindName("pwm",0,0);
   250 
   251         if(!Client)
   252         {
   253            return result;
   254         }
   255 
   256         MsgStruct->input_group=PhInputGroup(0);
   257         MsgStruct->connection=PtConnectionFindName("pwm",0,0);
   258         myerr=WmGetFocusList(MsgStruct,2,&num,WNDDEF);
   259 
   260         Message->hdr.type=WM_REQUEST_WIN_ACTION;
   261         Message->hdr.subtype=Pt_ACTION_MIN;	   
   262         Message->hdr.rid=WNDDEF[0]->rid;
   263         myerr=WmSendMessage(Client,Message,Reply,0);
   264 
   265         free(Message);
   266         free(Reply);
   267 
   268 	SDL_Unlock_EventThread();
   269 
   270 	return(result);
   271 }
   272 
   273 SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
   274 {
   275 #if 0 /*big*/
   276 	int numtries, result;
   277 
   278 	if ( this->screen == NULL ) {
   279 		return(SDL_GRAB_OFF);
   280 	}
   281 	if ( ! SDL_Window ) {
   282 		return(mode);	/* Will be set later on mode switch */
   283 	}
   284 	if ( mode == SDL_GRAB_OFF ) {
   285 		XUngrabPointer(SDL_Display, CurrentTime);
   286 		if ( this->screen->flags & SDL_FULLSCREEN ) {
   287 			/* Rebind the mouse to the fullscreen window */
   288 			for ( numtries = 0; numtries < 10; ++numtries ) {
   289 				result = XGrabPointer(SDL_Display, FSwindow,
   290 						True, 0,
   291 						GrabModeAsync, GrabModeAsync,
   292 						FSwindow, None, CurrentTime);
   293 				if ( result == AlreadyGrabbed ) {
   294 					break;
   295 				}
   296 				SDL_Delay(100);
   297 			}
   298 		}
   299 #ifdef GRAB_FULLSCREEN
   300 		if ( !(this->screen->flags & SDL_FULLSCREEN) )
   301 #endif
   302 		XUngrabKeyboard(SDL_Display, CurrentTime);
   303 	} else {
   304 		if ( this->screen->flags & SDL_FULLSCREEN ) {
   305 			/* Unbind the mouse from the fullscreen window */
   306 			XUngrabPointer(SDL_Display, CurrentTime);
   307 		}
   308 		/* Try to grab the mouse */
   309 		for ( numtries = 0; numtries < 10; ++numtries ) {
   310 			result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
   311 						GrabModeAsync, GrabModeAsync,
   312 						SDL_Window, None, CurrentTime);
   313 			if ( result != AlreadyGrabbed ) {
   314 				break;
   315 			}
   316 			SDL_Delay(100);
   317 		}
   318 #ifdef GRAB_FULLSCREEN
   319 		if ( !(this->screen->flags & SDL_FULLSCREEN) )
   320 #endif
   321 		XGrabKeyboard(SDL_Display, WMwindow, True,
   322 			GrabModeAsync, GrabModeAsync, CurrentTime);
   323 	}
   324 	XSync(SDL_Display, False);
   325 
   326 
   327 #endif /*big*/
   328 	return(mode);
   329 }
   330 
   331 SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
   332 {
   333 #if 0
   334 	SDL_Lock_EventThread();
   335 	mode = X11_GrabInputNoLock(this, mode);
   336 	SDL_Unlock_EventThread();
   337 #endif
   338 	return(mode);
   339 }
   340 
   341 /* If 'info' is the right version, this function fills it and returns 1.
   342    Otherwise, in case of a version mismatch, it returns -1.
   343 */
   344 static void lock_display(void)
   345 {
   346 	SDL_Lock_EventThread();
   347 }
   348 static void unlock_display(void)
   349 {
   350 #if 0
   351 	/* Make sure any X11 transactions are completed */
   352 	SDL_VideoDevice *this = current_video;
   353 	XSync(SDL_Display, False);
   354 #endif
   355 	SDL_Unlock_EventThread();
   356 }
   357 int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
   358 {
   359 #if 0
   360 	if ( info->version.major <= SDL_MAJOR_VERSION ) {
   361 		info->subsystem = SDL_SYSWM_X11;
   362 		info->info.x11.display = SDL_Display;
   363 		info->info.x11.window = SDL_Window;
   364 		if ( SDL_VERSIONNUM(info->version.major,
   365 		                    info->version.minor,
   366 		                    info->version.patch) >= 1002 ) {
   367 			info->info.x11.fswindow = FSwindow;
   368 			info->info.x11.wmwindow = WMwindow;
   369 		}
   370 		info->info.x11.lock_func = lock_display;
   371 		info->info.x11.unlock_func = unlock_display;
   372 		return(1);
   373 	} else {
   374 		SDL_SetError("Application not compiled with SDL %d.%d\n",
   375 					SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   376 		return(-1);
   377 	}
   378 #endif
   379    return -1; // for now ...
   380 }
   381 
   382