comparison src/video/cybergfx/SDL_cgxwm.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children e8157fcb3114
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 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 "SDL_version.h"
29 #include "SDL_error.h"
30 #include "SDL_timer.h"
31 #include "SDL_video.h"
32 #include "SDL_syswm.h"
33 #include "SDL_events_c.h"
34 #include "SDL_pixels_c.h"
35 #include "SDL_cgxmodes_c.h"
36 #include "SDL_cgxwm_c.h"
37
38 /* This is necessary for working properly with Enlightenment, etc. */
39 #define USE_ICON_WINDOW
40
41 void CGX_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
42 {
43 #if 0
44 SDL_Surface *sicon;
45 XWMHints *wmhints;
46 XImage *icon_image;
47 Pixmap icon_pixmap;
48 Pixmap mask_pixmap;
49 #ifdef USE_ICON_WINDOW
50 Window icon_window;
51 #endif
52 GC GC;
53 XGCValues GCvalues;
54 int i, b, dbpp;
55 SDL_Rect bounds;
56 Uint8 *LSBmask, *color_tried;
57 Visual *dvis;
58
59 /* Lock the event thread, in multi-threading environments */
60 SDL_Lock_EventThread();
61
62 /* The icon must use the default visual, depth and colormap of the
63 screen, so it might need a conversion */
64 dbpp = DefaultDepth(SDL_Display, SDL_Screen);
65 switch(dbpp) {
66 case 15:
67 dbpp = 16; break;
68 case 24:
69 dbpp = 32; break;
70 }
71 dvis = DefaultVisual(SDL_Display, SDL_Screen);
72
73 /* The Visual struct is supposed to be opaque but we cheat a little */
74 sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
75 dbpp,
76 dvis->red_mask, dvis->green_mask,
77 dvis->blue_mask, 0);
78
79 if ( sicon == NULL ) {
80 goto done;
81 }
82 /* If we already have allocated colours from the default colormap,
83 copy them */
84 if(SDL_Visual == dvis && SDL_XColorMap == SDL_DisplayColormap
85 && this->screen->format->palette && sicon->format->palette) {
86 memcpy(sicon->format->palette->colors,
87 this->screen->format->palette->colors,
88 this->screen->format->palette->ncolors * sizeof(SDL_Color));
89 }
90
91 bounds.x = 0;
92 bounds.y = 0;
93 bounds.w = icon->w;
94 bounds.h = icon->h;
95 if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 )
96 goto done;
97
98 /* Lock down the colors used in the colormap */
99 color_tried = NULL;
100 if ( sicon->format->BitsPerPixel == 8 ) {
101 SDL_Palette *palette;
102 Uint8 *p;
103 XColor wanted;
104
105 palette = sicon->format->palette;
106 color_tried = malloc(palette->ncolors);
107 if ( color_tried == NULL ) {
108 goto done;
109 }
110 if ( SDL_iconcolors != NULL ) {
111 free(SDL_iconcolors);
112 }
113 SDL_iconcolors = malloc(palette->ncolors
114 * sizeof(*SDL_iconcolors));
115 if ( SDL_iconcolors == NULL ) {
116 free(color_tried);
117 goto done;
118 }
119 memset(color_tried, 0, palette->ncolors);
120 memset(SDL_iconcolors, 0,
121 palette->ncolors * sizeof(*SDL_iconcolors));
122
123 p = (Uint8 *)sicon->pixels;
124 for ( i = sicon->w*sicon->h; i > 0; --i, ++p ) {
125 if ( ! color_tried[*p] ) {
126 wanted.pixel = *p;
127 wanted.red = (palette->colors[*p].r<<8);
128 wanted.green = (palette->colors[*p].g<<8);
129 wanted.blue = (palette->colors[*p].b<<8);
130 wanted.flags = (DoRed|DoGreen|DoBlue);
131 if (XAllocColor(SDL_Display,
132 SDL_DisplayColormap, &wanted)) {
133 ++SDL_iconcolors[wanted.pixel];
134 }
135 color_tried[*p] = 1;
136 }
137 }
138 }
139 if ( color_tried != NULL ) {
140 free(color_tried);
141 }
142
143 /* Translate mask data to LSB order and set the icon mask */
144 i = (sicon->w/8)*sicon->h;
145 LSBmask = (Uint8 *)malloc(i);
146 if ( LSBmask == NULL ) {
147 goto done;
148 }
149 memset(LSBmask, 0, i);
150 while ( --i >= 0 ) {
151 for ( b=0; b<8; ++b )
152 LSBmask[i] |= (((mask[i]>>b)&0x01)<<(7-b));
153 }
154 mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
155 LSBmask, sicon->w, sicon->h, 1L, 0L, 1);
156
157 /* Transfer the image to an X11 pixmap */
158 icon_image = XCreateImage(SDL_Display,
159 DefaultVisual(SDL_Display, SDL_Screen),
160 DefaultDepth(SDL_Display, SDL_Screen),
161 ZPixmap, 0, (char *)sicon->pixels, sicon->w, sicon->h,
162 ((sicon->format)->BytesPerPixel == 3) ? 32 :
163 (sicon->format)->BytesPerPixel*8, 0);
164 icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
165 DefaultDepth(SDL_Display, SDL_Screen));
166 GC = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
167 XPutImage(SDL_Display, icon_pixmap, GC, icon_image,
168 0, 0, 0, 0, sicon->w, sicon->h);
169 XFreeGC(SDL_Display, GC);
170 XDestroyImage(icon_image);
171 free(LSBmask);
172 sicon->pixels = NULL;
173
174 #ifdef USE_ICON_WINDOW
175 /* Create an icon window and set the pixmap as its background */
176 icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
177 0, 0, sicon->w, sicon->h, 0,
178 CopyFromParent, CopyFromParent);
179 XSetWindowBackgroundPixmap(SDL_Display, icon_window, icon_pixmap);
180 XClearWindow(SDL_Display, icon_window);
181 #endif
182
183 /* Set the window icon to the icon pixmap (and icon window) */
184 wmhints = XAllocWMHints();
185 wmhints->flags = (IconPixmapHint | IconMaskHint);
186 wmhints->icon_pixmap = icon_pixmap;
187 wmhints->icon_mask = mask_pixmap;
188 #ifdef USE_ICON_WINDOW
189 wmhints->flags |= IconWindowHint;
190 wmhints->icon_window = icon_window;
191 #endif
192 XSetWMHints(SDL_Display, WMwindow, wmhints);
193 XFree(wmhints);
194 XSync(SDL_Display, False);
195
196 done:
197 SDL_Unlock_EventThread();
198 if ( sicon != NULL ) {
199 SDL_FreeSurface(sicon);
200 }
201 #endif
202 return;
203 }
204
205 void CGX_SetCaption(_THIS, const char *title, const char *icon)
206 {
207 if(SDL_Window)
208 SetWindowTitles(SDL_Window,(char *)title,NULL);
209 }
210
211 /* Iconify the window */
212 int CGX_IconifyWindow(_THIS)
213 {
214 #if 0
215 int result;
216
217 SDL_Lock_EventThread();
218 result = XIconifyWindow(SDL_Display, WMwindow, SDL_Screen);
219 XSync(SDL_Display, False);
220 SDL_Unlock_EventThread();
221 return(result);
222 #else
223 return 0;
224 #endif
225 }
226
227 #if 0
228 SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode)
229 {
230 int numtries, result;
231
232 if ( this->screen == NULL ) {
233 return(SDL_GRAB_OFF);
234 }
235 if ( ! SDL_Window ) {
236 return(mode); /* Will be set later on mode switch */
237 }
238 if ( mode == SDL_GRAB_OFF ) {
239 XUngrabPointer(SDL_Display, CurrentTime);
240 if ( this->screen->flags & SDL_FULLSCREEN ) {
241 /* Rebind the mouse to the fullscreen window */
242 for ( numtries = 0; numtries < 10; ++numtries ) {
243 result = XGrabPointer(SDL_Display, FSwindow,
244 True, 0,
245 GrabModeAsync, GrabModeAsync,
246 FSwindow, None, CurrentTime);
247 if ( result == AlreadyGrabbed ) {
248 break;
249 }
250 SDL_Delay(100);
251 }
252 }
253 #ifdef GRAB_FULLSCREEN
254 if ( !(this->screen->flags & SDL_FULLSCREEN) )
255 #endif
256 XUngrabKeyboard(SDL_Display, CurrentTime);
257 } else {
258 if ( this->screen->flags & SDL_FULLSCREEN ) {
259 /* Unbind the mouse from the fullscreen window */
260 XUngrabPointer(SDL_Display, CurrentTime);
261 }
262 /* Try to grab the mouse */
263 for ( numtries = 0; numtries < 10; ++numtries ) {
264 result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
265 GrabModeAsync, GrabModeAsync,
266 SDL_Window, None, CurrentTime);
267 if ( result != AlreadyGrabbed ) {
268 break;
269 }
270 SDL_Delay(100);
271 }
272 #ifdef GRAB_FULLSCREEN
273 if ( !(this->screen->flags & SDL_FULLSCREEN) )
274 #endif
275 XGrabKeyboard(SDL_Display, WMwindow, True,
276 GrabModeAsync, GrabModeAsync, CurrentTime);
277 }
278 XSync(SDL_Display, False);
279
280 return(mode);
281 }
282
283 SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode)
284 {
285 SDL_Lock_EventThread();
286 mode = X11_GrabInputNoLock(this, mode);
287 SDL_Unlock_EventThread();
288
289 return(mode);
290 }
291
292 /* If 'info' is the right version, this function fills it and returns 1.
293 Otherwise, in case of a version mismatch, it returns -1.
294 */
295 static void lock_display(void)
296 {
297 SDL_Lock_EventThread();
298 }
299 static void unlock_display(void)
300 {
301 /* Make sure any X11 transactions are completed */
302 SDL_VideoDevice *this = current_video;
303 XSync(SDL_Display, False);
304 SDL_Unlock_EventThread();
305 }
306
307 #endif
308
309 int CGX_GetWMInfo(_THIS, SDL_SysWMinfo *info)
310 {
311 if ( info->version.major <= SDL_MAJOR_VERSION ) {
312 #if 0
313 info->subsystem = SDL_SYSWM_X11;
314 info->info.x11.display = SDL_Display;
315 info->info.x11.window = SDL_Window;
316 if ( SDL_VERSIONNUM(info->version.major,
317 info->version.minor,
318 info->version.patch) >= 1002 ) {
319 info->info.x11.fswindow = FSwindow;
320 info->info.x11.wmwindow = WMwindow;
321 }
322 info->info.x11.lock_func = lock_display;
323 info->info.x11.unlock_func = unlock_display;
324 #endif
325 return(1);
326 } else {
327 SDL_SetError("Application not compiled with SDL %d.%d\n",
328 SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
329 return(-1);
330 }
331 }