blob: 6d47eaea021c7dfe40eca3263f4dad989ddbe000 [file] [log] [blame]
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#define DISABLE_X11
#include <stdlib.h>
#include <string.h>
#include <Ph.h>
#include <photon/PpProto.h>
#include <photon/PhWm.h>
#include <photon/wmapi.h>
#include "SDL_version.h"
#include "SDL_error.h"
#include "SDL_timer.h"
#include "SDL_video.h"
#include "SDL_syswm.h"
#include "SDL_events_c.h"
#include "SDL_pixels_c.h"
#include "SDL_ph_modes_c.h"
#include "SDL_ph_wm_c.h"
/* This is necessary for working properly with Enlightenment, etc. */
#define USE_ICON_WINDOW
void ph_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
{
#if 0 /*big*/
int ncolors;
PhImage_t *image;
PgColor_t* palette;
image = PhCreateImage( image,
icon->w,
icon->h,
Pg_IMAGE_DIRECT_888,
NULL, 0, 0 );
/* ---------------------------------------- */
SDL_Surface *sicon;
// XWMHints *wmhints;
// XImage *icon_image;
// Pixmap icon_pixmap;
// Pixmap mask_pixmap;
// GC GC;
// XGCValues GCvalues;
int i, b, dbpp;
SDL_Rect bounds;
Uint8 *LSBmask, *color_tried;
Visual *dvis;
/* Lock the event thread, in multi-threading environments */
SDL_Lock_EventThread();
/* The icon must use the default visual, depth and colormap of the
screen, so it might need a conversion */
// ? dbpp = DefaultDepth(SDL_Display, SDL_Screen);
switch(dbpp) {
case 15:
dbpp = 16; break;
case 24:
dbpp = 32; break;
}
dvis = DefaultVisual(SDL_Display, SDL_Screen);
/* The Visual struct is supposed to be opaque but we cheat a little */
sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
dbpp,
dvis->red_mask, dvis->green_mask,
dvis->blue_mask, 0);
if ( sicon == NULL ) {
goto done;
}
/* If we already have allocated colours from the default colormap,
copy them */
if(SDL_Visual == dvis && SDL_XColorMap == SDL_DisplayColormap
&& this->screen->format->palette && sicon->format->palette) {
memcpy(sicon->format->palette->colors,
this->screen->format->palette->colors,
this->screen->format->palette->ncolors * sizeof(SDL_Color));
}
bounds.x = 0;
bounds.y = 0;
bounds.w = icon->w;
bounds.h = icon->h;
if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 )
goto done;
/* Lock down the colors used in the colormap */
color_tried = NULL;
if ( sicon->format->BitsPerPixel == 8 ) {
SDL_Palette *palette;
Uint8 *p;
XColor wanted;
palette = sicon->format->palette;
color_tried = malloc(palette->ncolors);
if ( color_tried == NULL ) {
goto done;
}
if ( SDL_iconcolors != NULL ) {
free(SDL_iconcolors);
}
SDL_iconcolors = malloc(palette->ncolors
* sizeof(*SDL_iconcolors));
if ( SDL_iconcolors == NULL ) {
free(color_tried);
goto done;
}
memset(color_tried, 0, palette->ncolors);
memset(SDL_iconcolors, 0,
palette->ncolors * sizeof(*SDL_iconcolors));
p = (Uint8 *)sicon->pixels;
for ( i = sicon->w*sicon->h; i > 0; --i, ++p ) {
if ( ! color_tried[*p] ) {
wanted.pixel = *p;
wanted.red = (palette->colors[*p].r<<8);
wanted.green = (palette->colors[*p].g<<8);
wanted.blue = (palette->colors[*p].b<<8);
wanted.flags = (DoRed|DoGreen|DoBlue);
if (XAllocColor(SDL_Display,
SDL_DisplayColormap, &wanted)) {
++SDL_iconcolors[wanted.pixel];
}
color_tried[*p] = 1;
}
}
}
if ( color_tried != NULL ) {
free(color_tried);
}
/* Translate mask data to LSB order and set the icon mask */
i = (sicon->w/8)*sicon->h;
LSBmask = (Uint8 *)malloc(i);
if ( LSBmask == NULL ) {
goto done;
}
memset(LSBmask, 0, i);
while ( --i >= 0 ) {
for ( b=0; b<8; ++b )
LSBmask[i] |= (((mask[i]>>b)&0x01)<<(7-b));
}
mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
LSBmask, sicon->w, sicon->h, 1L, 0L, 1);
/* Transfer the image to an X11 pixmap */
icon_image = XCreateImage(SDL_Display,
DefaultVisual(SDL_Display, SDL_Screen),
DefaultDepth(SDL_Display, SDL_Screen),
ZPixmap, 0, (char *)sicon->pixels, sicon->w, sicon->h,
((sicon->format)->BytesPerPixel == 3) ? 32 :
(sicon->format)->BytesPerPixel*8, 0);
icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
DefaultDepth(SDL_Display, SDL_Screen));
GC = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
XPutImage(SDL_Display, icon_pixmap, GC, icon_image,
0, 0, 0, 0, sicon->w, sicon->h);
XFreeGC(SDL_Display, GC);
XDestroyImage(icon_image);
free(LSBmask);
sicon->pixels = NULL;
#ifdef USE_ICON_WINDOW
/* Create an icon window and set the pixmap as its background */
icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
0, 0, sicon->w, sicon->h, 0,
CopyFromParent, CopyFromParent);
XSetWindowBackgroundPixmap(SDL_Display, icon_window, icon_pixmap);
XClearWindow(SDL_Display, icon_window);
#endif
/* Set the window icon to the icon pixmap (and icon window) */
wmhints = XAllocWMHints();
wmhints->flags = (IconPixmapHint | IconMaskHint);
wmhints->icon_pixmap = icon_pixmap;
wmhints->icon_mask = mask_pixmap;
#ifdef USE_ICON_WINDOW
wmhints->flags |= IconWindowHint;
wmhints->icon_window = icon_window;
#endif
XSetWMHints(SDL_Display, WMwindow, wmhints);
XFree(wmhints);
XSync(SDL_Display, False);
done:
SDL_Unlock_EventThread();
if ( sicon != NULL ) {
SDL_FreeSurface(sicon);
}
#endif /*big*/
return;
}
/* Set window caption */
void ph_SetCaption(_THIS, const char *title, const char *icon)
{
SDL_Lock_EventThread();
if ( title != NULL ) {
PtSetResource(window, Pt_ARG_WINDOW_TITLE, title, 0);
}
SDL_Unlock_EventThread();
}
/* Iconify current window */
int ph_IconifyWindow(_THIS)
{
PhWindowEvent_t windowevent;
SDL_Lock_EventThread();
memset( &windowevent, 0, sizeof (event) );
windowevent.event_f = Ph_WM_HIDE;
windowevent.event_state = Ph_WM_EVSTATE_HIDE;
windowevent.rid = PtWidgetRid( window );
PtForwardWindowEvent( &windowevent );
SDL_Unlock_EventThread();
return 0;
}
SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
{
return(mode);
}
SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
{
short abs_x, abs_y;
SDL_Lock_EventThread();
/* mode = ph_GrabInputNoLock(this, mode);*/
if( mode == SDL_GRAB_OFF )
{
PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_FALSE,
Ph_WM_STATE_ISALTKEY );
}
else
{
PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_TRUE,
Ph_WM_STATE_ISALTKEY );
PtGetAbsPosition( window, &abs_x, &abs_y );
PhMoveCursorAbs( PhInputGroup( NULL ),
abs_x + SDL_VideoSurface->w/2,
abs_y + SDL_VideoSurface->h/2 );
}
SDL_Unlock_EventThread();
return(mode);
}
int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
{
if (info->version.major <= SDL_MAJOR_VERSION)
{
return 1;
}
else
{
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return -1;
}
}