comparison src/video/wincommon/SDL_syswm.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 13ee9f4834ea
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999 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 #include <stdio.h>
29 #include <malloc.h>
30 #include <windows.h>
31
32 #include "SDL_version.h"
33 #include "SDL_error.h"
34 #include "SDL_video.h"
35 #include "SDL_syswm.h"
36 #include "SDL_syswm_c.h"
37 #include "SDL_pixels_c.h"
38
39 #ifdef _WIN32_WCE
40 #define DISABLE_ICON_SUPPORT
41 #endif
42
43 /* RJR: March 28, 2000
44 we need "SDL_cursor_c.h" for mods to WIN_GrabInput */
45 #include "SDL_cursor_c.h"
46
47 /* The screen icon -- needs to be freed on SDL_VideoQuit() */
48 HICON screen_icn = NULL;
49
50 /* Win32 icon mask semantics are different from those of SDL:
51 SDL applies the mask to the icon and copies result to desktop.
52 Win32 applies the mask to the desktop and XORs the icon on.
53 This means that the SDL mask needs to be applied to the icon and
54 then inverted and passed to Win32.
55 */
56 void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
57 {
58 #ifdef DISABLE_ICON_SUPPORT
59 return;
60 #else
61 SDL_Palette *pal_256;
62 SDL_Surface *icon_256;
63 Uint8 *pdata, *pwin32;
64 Uint8 *mdata, *mwin32, m = 0;
65 int icon_len;
66 int icon_plen;
67 int icon_mlen;
68 int icon_pitch;
69 int mask_pitch;
70 SDL_Rect bounds;
71 int i, skip;
72 int row, col;
73 struct /* quasi-BMP format */ Win32Icon {
74 Uint32 biSize;
75 Sint32 biWidth;
76 Sint32 biHeight;
77 Uint16 biPlanes;
78 Uint16 biBitCount;
79 Uint32 biCompression;
80 Uint32 biSizeImage;
81 Sint32 biXPelsPerMeter;
82 Sint32 biYPelsPerMeter;
83 Uint32 biClrUsed;
84 Uint32 biClrImportant;
85 struct /* RGBQUAD -- note it's BGR ordered */ {
86 Uint8 rgbBlue;
87 Uint8 rgbGreen;
88 Uint8 rgbRed;
89 Uint8 rgbReserved;
90 } biColors[256];
91 /* Pixels:
92 Uint8 pixels[]
93 */
94 /* Mask:
95 Uint8 mask[]
96 */
97 } *icon_win32;
98
99 /* Allocate the win32 bmp icon and set everything to zero */
100 icon_pitch = ((icon->w+3)&~3);
101 mask_pitch = ((icon->w+7)/8);
102 icon_plen = icon->h*icon_pitch;
103 icon_mlen = icon->h*mask_pitch;
104 icon_len = sizeof(*icon_win32)+icon_plen+icon_mlen;
105 icon_win32 = (struct Win32Icon *)alloca(icon_len);
106 if ( icon_win32 == NULL ) {
107 return;
108 }
109 memset(icon_win32, 0, icon_len);
110
111 /* Set the basic BMP parameters */
112 icon_win32->biSize = sizeof(*icon_win32)-sizeof(icon_win32->biColors);
113 icon_win32->biWidth = icon->w;
114 icon_win32->biHeight = icon->h*2;
115 icon_win32->biPlanes = 1;
116 icon_win32->biBitCount = 8;
117 icon_win32->biSizeImage = icon_plen+icon_mlen;
118
119 /* Allocate a standard 256 color icon surface */
120 icon_256 = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
121 icon_win32->biBitCount, 0, 0, 0, 0);
122 if ( icon_256 == NULL ) {
123 return;
124 }
125 pal_256 = icon_256->format->palette;
126 if (icon->format->palette &&
127 (icon->format->BitsPerPixel == icon_256->format->BitsPerPixel)){
128 Uint8 black;
129 memcpy(pal_256->colors, icon->format->palette->colors,
130 pal_256->ncolors*sizeof(SDL_Color));
131 /* Make sure that 0 is black! */
132 black = SDL_FindColor(pal_256, 0x00, 0x00, 0x00);
133 pal_256->colors[black] = pal_256->colors[0];
134 pal_256->colors[0].r = 0x00;
135 pal_256->colors[0].g = 0x00;
136 pal_256->colors[0].b = 0x00;
137 } else {
138 SDL_DitherColors(pal_256->colors,
139 icon_256->format->BitsPerPixel);
140 }
141
142 /* Now copy color data to the icon BMP */
143 for ( i=0; i<(1<<icon_win32->biBitCount); ++i ) {
144 icon_win32->biColors[i].rgbRed = pal_256->colors[i].r;
145 icon_win32->biColors[i].rgbGreen = pal_256->colors[i].g;
146 icon_win32->biColors[i].rgbBlue = pal_256->colors[i].b;
147 }
148
149 /* Convert icon to a standard surface format. This may not always
150 be necessary, as Windows supports a variety of BMP formats, but
151 it greatly simplifies our code.
152 */
153 bounds.x = 0;
154 bounds.y = 0;
155 bounds.w = icon->w;
156 bounds.h = icon->h;
157 if ( SDL_LowerBlit(icon, &bounds, icon_256, &bounds) < 0 ) {
158 SDL_FreeSurface(icon_256);
159 return;
160 }
161
162 /* Copy pixels upside-down to icon BMP, masked with the icon mask */
163 if ( SDL_MUSTLOCK(icon_256) || (icon_256->pitch != icon_pitch) ) {
164 SDL_FreeSurface(icon_256);
165 SDL_SetError("Warning: Unexpected icon_256 characteristics");
166 return;
167 }
168 pdata = (Uint8 *)icon_256->pixels;
169 mdata = mask;
170 pwin32 = (Uint8 *)icon_win32+sizeof(*icon_win32)+icon_plen-icon_pitch;
171 skip = icon_pitch - icon->w;
172 for ( row=0; row<icon->h; ++row ) {
173 for ( col=0; col<icon->w; ++col ) {
174 if ( (col%8) == 0 ) {
175 m = *mdata++;
176 }
177 if ( (m&0x80) != 0x00 ) {
178 *pwin32 = *pdata;
179 }
180 m <<= 1;
181 ++pdata;
182 ++pwin32;
183 }
184 pdata += skip;
185 pwin32 += skip;
186 pwin32 -= 2*icon_pitch;
187 }
188 SDL_FreeSurface(icon_256);
189
190 /* Copy mask inverted and upside-down to icon BMP */
191 mdata = mask;
192 mwin32 = (Uint8 *)icon_win32
193 +sizeof(*icon_win32)+icon_plen+icon_mlen-mask_pitch;
194 for ( row=0; row<icon->h; ++row ) {
195 for ( col=0; col<mask_pitch; ++col ) {
196 *mwin32++ = ~*mdata++;
197 }
198 mwin32 -= 2*mask_pitch;
199 }
200
201 /* Finally, create the icon handle and set the window icon */
202 screen_icn = CreateIconFromResourceEx((Uint8 *)icon_win32, icon_len,
203 TRUE, 0x00030000, icon->w, icon->h, LR_DEFAULTCOLOR);
204 if ( screen_icn == NULL ) {
205 SDL_SetError("Couldn't create Win32 icon handle");
206 } else {
207 SetClassLong(SDL_Window, GCL_HICON, (LONG)screen_icn);
208 }
209 #endif /* DISABLE_ICON_SUPPORT */
210 }
211
212 void WIN_SetWMCaption(_THIS, const char *title, const char *icon)
213 {
214 #ifdef _WIN32_WCE
215 /* WinCE uses the UNICODE version */
216 int nLen = strlen(title);
217 LPWSTR lpszW = alloca((nLen+1)*2);
218 MultiByteToWideChar(CP_ACP, 0, title, -1, lpszW, nLen);
219 SetWindowText(SDL_Window, lpszW);
220 #else
221 SetWindowText(SDL_Window, title);
222 #endif
223 }
224
225 int WIN_IconifyWindow(_THIS)
226 {
227 ShowWindow(SDL_Window, SW_MINIMIZE);
228 return(1);
229 }
230
231 SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode)
232 {
233 if ( mode == SDL_GRAB_OFF ) {
234 ClipCursor(NULL);
235 if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
236 /* RJR: March 28, 2000
237 must be leaving relative mode, move mouse from
238 center of window to where it belongs ... */
239 POINT pt;
240 int x, y;
241 SDL_GetMouseState(&x,&y);
242 pt.x = x;
243 pt.y = y;
244 ClientToScreen(SDL_Window, &pt);
245 SetCursorPos(pt.x,pt.y);
246 }
247 } else {
248 ClipCursor(&SDL_bounds);
249 if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
250 /* RJR: March 28, 2000
251 must be entering relative mode, get ready by
252 moving mouse to center of window ... */
253 POINT pt;
254 pt.x = (SDL_VideoSurface->w/2);
255 pt.y = (SDL_VideoSurface->h/2);
256 ClientToScreen(SDL_Window, &pt);
257 SetCursorPos(pt.x, pt.y);
258 }
259 }
260 return(mode);
261 }
262
263 /* If 'info' is the right version, this function fills it and returns 1.
264 Otherwise, in case of a version mismatch, it returns -1.
265 */
266 int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info)
267 {
268 if ( info->version.major <= SDL_MAJOR_VERSION ) {
269 info->window = SDL_Window;
270 return(1);
271 } else {
272 SDL_SetError("Application not compiled with SDL %d.%d\n",
273 SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
274 return(-1);
275 }
276 }