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