src/video/wincommon/SDL_syswm.c
changeset 0 74212992fb08
child 36 13ee9f4834ea
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/wincommon/SDL_syswm.c	Thu Apr 26 16:45:43 2001 +0000
     1.3 @@ -0,0 +1,276 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997, 1998, 1999  Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Library General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Library General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Library General Public
    1.19 +    License along with this library; if not, write to the Free
    1.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@devolution.com
    1.24 +*/
    1.25 +
    1.26 +#ifdef SAVE_RCSID
    1.27 +static char rcsid =
    1.28 + "@(#) $Id$"
    1.29 +#endif
    1.30 +
    1.31 +#include <stdio.h>
    1.32 +#include <malloc.h>
    1.33 +#include <windows.h>
    1.34 +
    1.35 +#include "SDL_version.h"
    1.36 +#include "SDL_error.h"
    1.37 +#include "SDL_video.h"
    1.38 +#include "SDL_syswm.h"
    1.39 +#include "SDL_syswm_c.h"
    1.40 +#include "SDL_pixels_c.h"
    1.41 +
    1.42 +#ifdef _WIN32_WCE
    1.43 +#define DISABLE_ICON_SUPPORT
    1.44 +#endif
    1.45 +
    1.46 +/*	RJR: March 28, 2000
    1.47 +	we need "SDL_cursor_c.h" for mods to WIN_GrabInput */
    1.48 +#include "SDL_cursor_c.h"
    1.49 +
    1.50 +/* The screen icon -- needs to be freed on SDL_VideoQuit() */
    1.51 +HICON   screen_icn = NULL;
    1.52 +
    1.53 +/* Win32 icon mask semantics are different from those of SDL:
    1.54 +     SDL applies the mask to the icon and copies result to desktop.
    1.55 +     Win32 applies the mask to the desktop and XORs the icon on.
    1.56 +   This means that the SDL mask needs to be applied to the icon and
    1.57 +   then inverted and passed to Win32.
    1.58 +*/
    1.59 +void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
    1.60 +{
    1.61 +#ifdef DISABLE_ICON_SUPPORT
    1.62 +	return;
    1.63 +#else
    1.64 +	SDL_Palette *pal_256;
    1.65 +	SDL_Surface *icon_256;
    1.66 +	Uint8 *pdata, *pwin32;
    1.67 +	Uint8 *mdata, *mwin32, m = 0;
    1.68 +	int icon_len;
    1.69 +	int icon_plen;
    1.70 +	int icon_mlen;
    1.71 +	int icon_pitch;
    1.72 +	int mask_pitch;
    1.73 +	SDL_Rect bounds;
    1.74 +	int i, skip;
    1.75 +	int row, col;
    1.76 +	struct /* quasi-BMP format */ Win32Icon {
    1.77 +		Uint32 biSize;
    1.78 +		Sint32 biWidth;
    1.79 +		Sint32 biHeight;
    1.80 +		Uint16 biPlanes;
    1.81 +		Uint16 biBitCount;
    1.82 +		Uint32 biCompression;
    1.83 +		Uint32 biSizeImage;
    1.84 +		Sint32 biXPelsPerMeter;
    1.85 +		Sint32 biYPelsPerMeter;
    1.86 +		Uint32 biClrUsed;
    1.87 +		Uint32 biClrImportant;
    1.88 +		struct /* RGBQUAD -- note it's BGR ordered */ {
    1.89 +			Uint8 rgbBlue;
    1.90 +			Uint8 rgbGreen;
    1.91 +			Uint8 rgbRed;
    1.92 +			Uint8 rgbReserved;
    1.93 +		} biColors[256];
    1.94 +		/* Pixels:
    1.95 +		Uint8 pixels[]
    1.96 +		*/
    1.97 +		/* Mask:
    1.98 +		Uint8 mask[]
    1.99 +		*/
   1.100 +	} *icon_win32;
   1.101 +	
   1.102 +	/* Allocate the win32 bmp icon and set everything to zero */
   1.103 +	icon_pitch = ((icon->w+3)&~3);
   1.104 +	mask_pitch = ((icon->w+7)/8);
   1.105 +	icon_plen = icon->h*icon_pitch;
   1.106 +	icon_mlen = icon->h*mask_pitch;
   1.107 +	icon_len = sizeof(*icon_win32)+icon_plen+icon_mlen;
   1.108 +	icon_win32 = (struct Win32Icon *)alloca(icon_len);
   1.109 +	if ( icon_win32 == NULL ) {
   1.110 +		return;
   1.111 +	}
   1.112 +	memset(icon_win32, 0, icon_len);
   1.113 +
   1.114 +	/* Set the basic BMP parameters */
   1.115 +	icon_win32->biSize = sizeof(*icon_win32)-sizeof(icon_win32->biColors);
   1.116 +	icon_win32->biWidth = icon->w;
   1.117 +	icon_win32->biHeight = icon->h*2;
   1.118 +	icon_win32->biPlanes = 1;
   1.119 +	icon_win32->biBitCount = 8;
   1.120 +	icon_win32->biSizeImage = icon_plen+icon_mlen;
   1.121 +
   1.122 +	/* Allocate a standard 256 color icon surface */
   1.123 +	icon_256 = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
   1.124 +					 icon_win32->biBitCount, 0, 0, 0, 0);
   1.125 +	if ( icon_256 == NULL ) {
   1.126 +		return;
   1.127 +	}
   1.128 +	pal_256 = icon_256->format->palette;
   1.129 +	if (icon->format->palette && 
   1.130 +		(icon->format->BitsPerPixel == icon_256->format->BitsPerPixel)){
   1.131 +		Uint8 black;
   1.132 +		memcpy(pal_256->colors, icon->format->palette->colors,
   1.133 +					pal_256->ncolors*sizeof(SDL_Color));
   1.134 +		/* Make sure that 0 is black! */
   1.135 +		black = SDL_FindColor(pal_256, 0x00, 0x00, 0x00);
   1.136 +		pal_256->colors[black] = pal_256->colors[0];
   1.137 +		pal_256->colors[0].r = 0x00;
   1.138 +		pal_256->colors[0].g = 0x00;
   1.139 +		pal_256->colors[0].b = 0x00;
   1.140 +	} else {
   1.141 +		SDL_DitherColors(pal_256->colors,
   1.142 +					icon_256->format->BitsPerPixel);
   1.143 +	}
   1.144 +
   1.145 +	/* Now copy color data to the icon BMP */
   1.146 +	for ( i=0; i<(1<<icon_win32->biBitCount); ++i ) {
   1.147 +		icon_win32->biColors[i].rgbRed = pal_256->colors[i].r;
   1.148 +		icon_win32->biColors[i].rgbGreen = pal_256->colors[i].g;
   1.149 +		icon_win32->biColors[i].rgbBlue = pal_256->colors[i].b;
   1.150 +	}
   1.151 +
   1.152 +	/* Convert icon to a standard surface format.  This may not always
   1.153 +	   be necessary, as Windows supports a variety of BMP formats, but
   1.154 +	   it greatly simplifies our code.
   1.155 +	*/ 
   1.156 +        bounds.x = 0;
   1.157 +        bounds.y = 0;
   1.158 +        bounds.w = icon->w;
   1.159 +        bounds.h = icon->h;
   1.160 +        if ( SDL_LowerBlit(icon, &bounds, icon_256, &bounds) < 0 ) {
   1.161 +		SDL_FreeSurface(icon_256);
   1.162 +                return;
   1.163 +	}
   1.164 +
   1.165 +	/* Copy pixels upside-down to icon BMP, masked with the icon mask */
   1.166 +	if ( SDL_MUSTLOCK(icon_256) || (icon_256->pitch != icon_pitch) ) {
   1.167 +		SDL_FreeSurface(icon_256);
   1.168 +		SDL_SetError("Warning: Unexpected icon_256 characteristics");
   1.169 +		return;
   1.170 +	}
   1.171 +	pdata = (Uint8 *)icon_256->pixels;
   1.172 +	mdata = mask;
   1.173 +	pwin32 = (Uint8 *)icon_win32+sizeof(*icon_win32)+icon_plen-icon_pitch;
   1.174 +	skip = icon_pitch - icon->w;
   1.175 +	for ( row=0; row<icon->h; ++row ) {
   1.176 +		for ( col=0; col<icon->w; ++col ) {
   1.177 +			if ( (col%8) == 0 ) {
   1.178 +				m = *mdata++;
   1.179 +			}
   1.180 +			if ( (m&0x80) != 0x00 ) {
   1.181 +				*pwin32 = *pdata;
   1.182 +			}
   1.183 +			m <<= 1;
   1.184 +			++pdata;
   1.185 +			++pwin32;
   1.186 +		}
   1.187 +		pdata  += skip;
   1.188 +		pwin32 += skip;
   1.189 +		pwin32 -= 2*icon_pitch;
   1.190 +	}
   1.191 +	SDL_FreeSurface(icon_256);
   1.192 +
   1.193 +	/* Copy mask inverted and upside-down to icon BMP */
   1.194 +	mdata = mask;
   1.195 +	mwin32 = (Uint8 *)icon_win32
   1.196 +			+sizeof(*icon_win32)+icon_plen+icon_mlen-mask_pitch;
   1.197 +	for ( row=0; row<icon->h; ++row ) {
   1.198 +		for ( col=0; col<mask_pitch; ++col ) {
   1.199 +			*mwin32++ = ~*mdata++;
   1.200 +		}
   1.201 +		mwin32 -= 2*mask_pitch;
   1.202 +	}
   1.203 +
   1.204 +	/* Finally, create the icon handle and set the window icon */
   1.205 +	screen_icn = CreateIconFromResourceEx((Uint8 *)icon_win32, icon_len,
   1.206 +			TRUE, 0x00030000, icon->w, icon->h, LR_DEFAULTCOLOR);
   1.207 +	if ( screen_icn == NULL ) {
   1.208 +		SDL_SetError("Couldn't create Win32 icon handle");
   1.209 +	} else {
   1.210 +		SetClassLong(SDL_Window, GCL_HICON, (LONG)screen_icn);
   1.211 +	}
   1.212 +#endif /* DISABLE_ICON_SUPPORT */
   1.213 +}
   1.214 +
   1.215 +void WIN_SetWMCaption(_THIS, const char *title, const char *icon)
   1.216 +{
   1.217 +#ifdef _WIN32_WCE
   1.218 +	/* WinCE uses the UNICODE version */
   1.219 +	int nLen = strlen(title);
   1.220 +	LPWSTR lpszW = alloca((nLen+1)*2);
   1.221 +	MultiByteToWideChar(CP_ACP, 0, title, -1, lpszW, nLen);
   1.222 +	SetWindowText(SDL_Window, lpszW);
   1.223 +#else
   1.224 +	SetWindowText(SDL_Window, title);
   1.225 +#endif
   1.226 +}
   1.227 +
   1.228 +int WIN_IconifyWindow(_THIS)
   1.229 +{
   1.230 +	ShowWindow(SDL_Window, SW_MINIMIZE);
   1.231 +	return(1);
   1.232 +}
   1.233 +
   1.234 +SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode)
   1.235 +{
   1.236 +	if ( mode == SDL_GRAB_OFF ) {
   1.237 +		ClipCursor(NULL);
   1.238 +		if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
   1.239 +		/*	RJR: March 28, 2000
   1.240 +			must be leaving relative mode, move mouse from
   1.241 +			center of window to where it belongs ... */
   1.242 +			POINT pt;
   1.243 +			int x, y;
   1.244 +			SDL_GetMouseState(&x,&y);
   1.245 +			pt.x = x;
   1.246 +			pt.y = y;
   1.247 +			ClientToScreen(SDL_Window, &pt);
   1.248 +			SetCursorPos(pt.x,pt.y);
   1.249 +		}
   1.250 +	} else {
   1.251 +		ClipCursor(&SDL_bounds);
   1.252 +		if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
   1.253 +		/*	RJR: March 28, 2000
   1.254 +			must be entering relative mode, get ready by
   1.255 +			moving mouse to	center of window ... */
   1.256 +			POINT pt;
   1.257 +			pt.x = (SDL_VideoSurface->w/2);
   1.258 +			pt.y = (SDL_VideoSurface->h/2);
   1.259 +			ClientToScreen(SDL_Window, &pt);
   1.260 +			SetCursorPos(pt.x, pt.y);
   1.261 +		}
   1.262 +	}
   1.263 +	return(mode);
   1.264 +}
   1.265 +
   1.266 +/* If 'info' is the right version, this function fills it and returns 1.
   1.267 +   Otherwise, in case of a version mismatch, it returns -1.
   1.268 +*/
   1.269 +int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info)
   1.270 +{
   1.271 +	if ( info->version.major <= SDL_MAJOR_VERSION ) {
   1.272 +		info->window = SDL_Window;
   1.273 +		return(1);
   1.274 +	} else {
   1.275 +		SDL_SetError("Application not compiled with SDL %d.%d\n",
   1.276 +					SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   1.277 +		return(-1);
   1.278 +	}
   1.279 +}