src/video/photon/SDL_ph_wm.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 06 Mar 2002 11:23:08 +0000
changeset 297 f6ffac90895c
parent 291 68a8a8237c09
child 315 3333b6e68289
permissions -rw-r--r--
Updated copyright information for 2002
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@297
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  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@252
    20
    slouken@libsdl.org
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@266
   233
/* Iconify current window */
slouken@19
   234
int ph_IconifyWindow(_THIS)
slouken@19
   235
{
slouken@283
   236
	PhWindowEvent_t windowevent;
slouken@0
   237
slouken@283
   238
	SDL_Lock_EventThread();
slouken@283
   239
	memset( &windowevent, 0, sizeof (event) );
slouken@283
   240
	windowevent.event_f = Ph_WM_HIDE;
slouken@283
   241
	windowevent.event_state = Ph_WM_EVSTATE_HIDE;
slouken@283
   242
	windowevent.rid = PtWidgetRid( window );
slouken@283
   243
	PtForwardWindowEvent( &windowevent );
slouken@283
   244
	SDL_Unlock_EventThread();
slouken@291
   245
        
slouken@291
   246
        return 0;
slouken@0
   247
}
slouken@0
   248
slouken@0
   249
SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
slouken@0
   250
{
slouken@266
   251
   return(mode);
slouken@0
   252
}
slouken@0
   253
slouken@0
   254
SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
slouken@0
   255
{
slouken@283
   256
	short abs_x, abs_y;
slouken@283
   257
slouken@283
   258
	SDL_Lock_EventThread();
slouken@283
   259
/*	mode = ph_GrabInputNoLock(this, mode);*/
slouken@283
   260
slouken@283
   261
	if( mode == SDL_GRAB_OFF )
slouken@283
   262
	{
slouken@283
   263
		PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_FALSE,
slouken@283
   264
				Ph_WM_STATE_ISALTKEY );
slouken@283
   265
	}
slouken@283
   266
	else
slouken@283
   267
	{
slouken@283
   268
		PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_TRUE,
slouken@283
   269
				Ph_WM_STATE_ISALTKEY );
slouken@283
   270
slouken@283
   271
		PtGetAbsPosition( window, &abs_x, &abs_y );
slouken@283
   272
		PhMoveCursorAbs( PhInputGroup( NULL ),
slouken@283
   273
				abs_x + SDL_VideoSurface->w/2,
slouken@283
   274
				abs_y + SDL_VideoSurface->h/2 );
slouken@283
   275
	}
slouken@283
   276
slouken@283
   277
	SDL_Unlock_EventThread();
slouken@283
   278
	return(mode);
slouken@0
   279
}
slouken@0
   280
slouken@0
   281
int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
slouken@0
   282
{
slouken@266
   283
   if (info->version.major <= SDL_MAJOR_VERSION)
slouken@266
   284
   {
slouken@266
   285
      return 1;
slouken@266
   286
   }
slouken@266
   287
   else
slouken@266
   288
   {
slouken@266
   289
      SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@266
   290
                    SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@266
   291
      return -1;
slouken@266
   292
   }
slouken@0
   293
}