Mercurial > sdl-ios-xcode
comparison src/video/gtk/SDL_gtkvideo.c @ 4404:b8de86ee2ad6 SDL-1.2-olpc
First shot at GTK+ video target for the OLPC laptops. Seriously incomplete,
but it's enough to get some bits to a window...
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 19 Apr 2007 07:12:30 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4403:6b794fb2060d | 4404:b8de86ee2ad6 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2006 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 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 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 #include "SDL_config.h" | |
23 | |
24 /* | |
25 * GTK+ SDL video driver implementation; this is a little like a pared-down | |
26 * version of the X11 driver. You almost certainly do NOT want this target | |
27 * on a desktop machine. This was written for the One Laptop Per Child | |
28 * project so they wouldn't need to use the SDL_WINDOWID hack with the X11 | |
29 * driver and compete for the event queue. | |
30 * | |
31 * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion | |
32 * of this was cut-and-pasted from the dummy video target just to have a | |
33 * starting point for the bare minimum to fill in, and some was lifted from | |
34 * the x11 target. | |
35 */ | |
36 | |
37 #include "SDL_video.h" | |
38 #include "SDL_mouse.h" | |
39 #include "../SDL_sysvideo.h" | |
40 #include "../SDL_pixels_c.h" | |
41 #include "../../events/SDL_events_c.h" | |
42 | |
43 #include "SDL_gtkvideo.h" | |
44 #include "SDL_gtkevents_c.h" | |
45 #include "SDL_gtkmouse_c.h" | |
46 | |
47 #define GTKPLUSVID_DRIVER_NAME "gtk" | |
48 | |
49 /* Initialization/Query functions */ | |
50 static int GTKPLUS_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
51 static SDL_Rect **GTKPLUS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
52 static SDL_Surface *GTKPLUS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
53 static int GTKPLUS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | |
54 static void GTKPLUS_VideoQuit(_THIS); | |
55 | |
56 /* Hardware surface functions */ | |
57 static int GTKPLUS_AllocHWSurface(_THIS, SDL_Surface *surface); | |
58 static int GTKPLUS_LockHWSurface(_THIS, SDL_Surface *surface); | |
59 static void GTKPLUS_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
60 static void GTKPLUS_FreeHWSurface(_THIS, SDL_Surface *surface); | |
61 static void GTKPLUS_SetCaption(_THIS, const char *title, const char *icon); | |
62 | |
63 /* etc. */ | |
64 static void GTKPLUS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | |
65 | |
66 /* GTKPLUS driver bootstrap functions */ | |
67 | |
68 static int do_gtk_init(void) | |
69 { | |
70 static int initted = 0; | |
71 if (!initted) { /* !!! FIXME: I can't see a way to deinit gtk... */ | |
72 int tmpargc = 0; | |
73 char *args[] = { NULL, NULL }; | |
74 char **tmpargv = args; | |
75 initted = (gtk_init_check(&tmpargc, &tmpargv)); | |
76 } | |
77 return initted; | |
78 } | |
79 | |
80 | |
81 static int GTKPLUS_Available(void) | |
82 { | |
83 return 1; /* !!! FIXME */ | |
84 } | |
85 | |
86 static void GTKPLUS_DeleteDevice(SDL_VideoDevice *device) | |
87 { | |
88 SDL_free(device->hidden); | |
89 SDL_free(device); | |
90 } | |
91 | |
92 static SDL_VideoDevice *GTKPLUS_CreateDevice(int devindex) | |
93 { | |
94 SDL_VideoDevice *device; | |
95 | |
96 /* Initialize all variables that we clean on shutdown */ | |
97 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); | |
98 if ( device ) { | |
99 SDL_memset(device, 0, (sizeof *device)); | |
100 device->hidden = (struct SDL_PrivateVideoData *) | |
101 SDL_malloc((sizeof *device->hidden)); | |
102 } | |
103 if ( (device == NULL) || (device->hidden == NULL) ) { | |
104 SDL_OutOfMemory(); | |
105 if ( device ) { | |
106 SDL_free(device); | |
107 } | |
108 return(0); | |
109 } | |
110 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | |
111 | |
112 device->handles_any_size = 1; | |
113 | |
114 /* Set the function pointers */ | |
115 device->VideoInit = GTKPLUS_VideoInit; | |
116 device->ListModes = GTKPLUS_ListModes; | |
117 device->SetVideoMode = GTKPLUS_SetVideoMode; | |
118 device->CreateYUVOverlay = NULL; | |
119 device->SetColors = GTKPLUS_SetColors; | |
120 device->UpdateRects = GTKPLUS_UpdateRects; | |
121 device->VideoQuit = GTKPLUS_VideoQuit; | |
122 device->AllocHWSurface = GTKPLUS_AllocHWSurface; | |
123 device->CheckHWBlit = NULL; | |
124 device->FillHWRect = NULL; | |
125 device->SetHWColorKey = NULL; | |
126 device->SetHWAlpha = NULL; | |
127 device->LockHWSurface = GTKPLUS_LockHWSurface; | |
128 device->UnlockHWSurface = GTKPLUS_UnlockHWSurface; | |
129 device->FlipHWSurface = NULL; | |
130 device->FreeHWSurface = GTKPLUS_FreeHWSurface; | |
131 device->SetCaption = GTKPLUS_SetCaption; | |
132 device->SetIcon = NULL; | |
133 device->IconifyWindow = NULL; | |
134 device->GrabInput = NULL; | |
135 device->GetWMInfo = NULL; | |
136 device->InitOSKeymap = GTKPLUS_InitOSKeymap; | |
137 device->PumpEvents = GTKPLUS_PumpEvents; | |
138 | |
139 device->free = GTKPLUS_DeleteDevice; | |
140 | |
141 return device; | |
142 } | |
143 | |
144 VideoBootStrap GTKPLUS_bootstrap = { | |
145 GTKPLUSVID_DRIVER_NAME, "SDL GTK+ video driver", | |
146 GTKPLUS_Available, GTKPLUS_CreateDevice | |
147 }; | |
148 | |
149 | |
150 static int add_visual(_THIS, int depth, GdkVisualType vistype) | |
151 { | |
152 GdkVisual *vi = gdk_visual_get_best_with_both(depth, vistype); | |
153 if(vi != NULL) { | |
154 g_object_ref(vi); | |
155 this->hidden->visuals[this->hidden->nvisuals++] = vi; | |
156 } | |
157 return(this->hidden->nvisuals); | |
158 } | |
159 | |
160 static int GTKPLUS_GetVideoModes(_THIS) | |
161 { | |
162 const gint screen_w = gdk_screen_width(); | |
163 const gint screen_h = gdk_screen_height(); | |
164 int i, n; | |
165 | |
166 { | |
167 /* It's interesting to note that if we allow 32 bit depths (on X11), | |
168 we get a visual with an alpha mask on composite servers. | |
169 static int depth_list[] = { 32, 24, 16, 15, 8 }; | |
170 */ | |
171 static int depth_list[] = { 24, 16, 15, 8 }; | |
172 int use_directcolor = 1; | |
173 | |
174 /* Search for the visuals in deepest-first order, so that the first | |
175 will be the richest one */ | |
176 if ( SDL_getenv("SDL_VIDEO_GTK_NODIRECTCOLOR") ) { | |
177 use_directcolor = 0; | |
178 } | |
179 this->hidden->nvisuals = 0; | |
180 for ( i=0; i<SDL_arraysize(depth_list); ++i ) { | |
181 if ( depth_list[i] > 8 ) { | |
182 if ( use_directcolor ) { | |
183 add_visual(this, depth_list[i], GDK_VISUAL_DIRECT_COLOR); | |
184 } | |
185 add_visual(this, depth_list[i], GDK_VISUAL_TRUE_COLOR); | |
186 } else { | |
187 add_visual(this, depth_list[i], GDK_VISUAL_PSEUDO_COLOR); | |
188 add_visual(this, depth_list[i], GDK_VISUAL_STATIC_COLOR); | |
189 } | |
190 } | |
191 if ( this->hidden->nvisuals == 0 ) { | |
192 SDL_SetError("Found no sufficiently capable GTK+ visuals"); | |
193 return -1; | |
194 } | |
195 } | |
196 | |
197 return 0; | |
198 } | |
199 | |
200 | |
201 int GTKPLUS_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
202 { | |
203 GdkVisual *sysvis = NULL; | |
204 int i; | |
205 | |
206 if (!do_gtk_init()) { | |
207 return -1; | |
208 } | |
209 | |
210 /* Get the available video modes */ | |
211 if(GTKPLUS_GetVideoModes(this) < 0) | |
212 return -1; | |
213 | |
214 /* Determine the current screen size */ | |
215 this->info.current_w = gdk_screen_width(); | |
216 this->info.current_h = gdk_screen_height(); | |
217 | |
218 /* Determine the default screen depth: | |
219 Use the default visual (or at least one with the same depth) */ | |
220 this->hidden->display_colormap = gdk_colormap_get_system(); /* !!! FIXME: refcount? */ | |
221 sysvis = gdk_visual_get_system(); /* !!! FIXME: refcount? */ | |
222 | |
223 for(i = 0; i < this->hidden->nvisuals; i++) { | |
224 if(this->hidden->visuals[i]->depth == sysvis->depth) | |
225 break; | |
226 } | |
227 | |
228 if(i == this->hidden->nvisuals) { | |
229 /* default visual was useless, take the deepest one instead */ | |
230 i = 0; | |
231 } | |
232 | |
233 this->hidden->visual = this->hidden->visuals[i]; | |
234 if ( this->hidden->visual == sysvis ) { /* !!! FIXME: same pointer? */ | |
235 this->hidden->colormap = this->hidden->display_colormap; | |
236 g_object_ref(this->hidden->colormap); | |
237 } else { | |
238 this->hidden->colormap = gdk_colormap_new(this->hidden->visual, FALSE); | |
239 } | |
240 | |
241 // !!! FIXME: this is not a public GDK symbol!! | |
242 vformat->BitsPerPixel = _gdk_windowing_get_bits_for_depth( | |
243 gdk_display_get_default(), | |
244 this->hidden->visuals[i]->depth); | |
245 this->hidden->depth = vformat->BitsPerPixel; | |
246 | |
247 if ( vformat->BitsPerPixel > 8 ) { | |
248 vformat->Rmask = this->hidden->visual->red_mask; | |
249 vformat->Gmask = this->hidden->visual->green_mask; | |
250 vformat->Bmask = this->hidden->visual->blue_mask; | |
251 } | |
252 if ( this->hidden->depth == 32 ) { | |
253 vformat->Amask = (0xFFFFFFFF & ~(vformat->Rmask|vformat->Gmask|vformat->Bmask)); | |
254 } | |
255 | |
256 #if 0 | |
257 /* Create the fullscreen and managed windows */ | |
258 create_aux_windows(this); | |
259 | |
260 /* Create the blank cursor */ | |
261 SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, | |
262 BLANK_CWIDTH, BLANK_CHEIGHT, | |
263 BLANK_CHOTX, BLANK_CHOTY); | |
264 | |
265 /* Allow environment override of screensaver disable. */ | |
266 env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); | |
267 this->hidden->allow_screensaver = ( (env && SDL_atoi(env)) ? 1 : 0 ); | |
268 #endif | |
269 | |
270 /* We're done! */ | |
271 gdk_flush(); /* just in case. */ | |
272 | |
273 /* Fill in some window manager capabilities */ | |
274 this->info.wm_available = 1; | |
275 | |
276 return(0); | |
277 } | |
278 | |
279 | |
280 static GdkVisual *find_visual(_THIS, int bpp) | |
281 { | |
282 GdkDisplay *display = gdk_display_get_default(); | |
283 int i; | |
284 for ( i = 0; i < this->hidden->nvisuals; i++ ) { | |
285 const int videpth = this->hidden->visuals[i]->depth; | |
286 // !!! FIXME: this is not a public GDK symbol!! | |
287 const int depth = _gdk_windowing_get_bits_for_depth(display, videpth); | |
288 if ( depth == bpp ) | |
289 break; | |
290 } | |
291 | |
292 if ( i == this->hidden->nvisuals ) { | |
293 SDL_SetError("No matching visual for requested depth"); | |
294 return NULL; /* should never happen */ | |
295 } | |
296 return this->hidden->visuals[i]; | |
297 } | |
298 | |
299 | |
300 SDL_Rect **GTKPLUS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
301 { | |
302 if ((flags & SDL_OPENGL) == 0) { | |
303 if (find_visual(this, format->BitsPerPixel) != NULL) { | |
304 return (SDL_Rect **) -1; /* !!! FIXME: maybe not right. */ | |
305 } | |
306 } | |
307 return NULL; /* unsupported. */ | |
308 } | |
309 | |
310 | |
311 SDL_Surface *GTKPLUS_SetVideoMode(_THIS, SDL_Surface *current, | |
312 int width, int height, int bpp, Uint32 flags) | |
313 { | |
314 Uint32 Amask = 0; | |
315 int vis_change = 0; | |
316 GtkWindow *win = NULL; | |
317 GdkImage *img = NULL; | |
318 GdkVisual *sysvis = gdk_visual_get_system(); /* !!! FIXME: refcount? */ | |
319 GdkVisual *vis = find_visual(this, bpp); | |
320 if (vis == NULL) { | |
321 return(NULL); | |
322 } | |
323 | |
324 if (flags & SDL_OPENGL) { | |
325 SDL_SetError("No OpenGL support in the GTK+ target"); | |
326 return(NULL); | |
327 } | |
328 | |
329 /* These are the only flags we allow here... */ | |
330 flags &= /*SDL_FULLSCREEN |*/ SDL_RESIZABLE | SDL_NOFRAME | SDL_HWPALETTE; | |
331 | |
332 vis_change = (vis != this->hidden->visual); | |
333 this->hidden->visual = vis; | |
334 this->hidden->depth = vis->depth; | |
335 | |
336 /* Allocate the new pixel format for this video mode */ | |
337 if ( this->hidden->depth == 32 ) { | |
338 Amask = (0xFFFFFFFF & ~(vis->red_mask|vis->green_mask|vis->blue_mask)); | |
339 } else { | |
340 Amask = 0; | |
341 } | |
342 if ( ! SDL_ReallocFormat(current, bpp, | |
343 vis->red_mask, vis->green_mask, vis->blue_mask, Amask) ) { | |
344 return NULL; | |
345 } | |
346 | |
347 /* Create the appropriate colormap */ | |
348 g_object_unref(this->hidden->colormap); | |
349 this->hidden->colormap = NULL; | |
350 | |
351 if ( this->hidden->visual->type == GDK_VISUAL_PSEUDO_COLOR ) { | |
352 int ncolors; | |
353 | |
354 /* Allocate the pixel flags */ | |
355 ncolors = this->hidden->visual->colormap_size; | |
356 | |
357 #if 0 | |
358 SDL_XPixels = SDL_malloc(ncolors * sizeof(int)); | |
359 if(SDL_XPixels == NULL) { | |
360 SDL_OutOfMemory(); | |
361 return -1; | |
362 } | |
363 SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels)); | |
364 #endif | |
365 | |
366 /* always allocate a private colormap on non-default visuals */ | |
367 if ( this->hidden->visual != sysvis ) { | |
368 flags |= SDL_HWPALETTE; | |
369 } | |
370 if ( flags & SDL_HWPALETTE ) { | |
371 current->flags |= SDL_HWPALETTE; | |
372 this->hidden->colormap = gdk_colormap_new(this->hidden->visual, TRUE); | |
373 } else { | |
374 this->hidden->colormap = this->hidden->display_colormap; | |
375 g_object_ref(this->hidden->colormap); | |
376 } | |
377 } else if ( this->hidden->visual->type == GDK_VISUAL_DIRECT_COLOR ) { | |
378 | |
379 /* Create a colormap which we can manipulate for gamma */ | |
380 this->hidden->colormap = gdk_colormap_new(this->hidden->visual, TRUE); | |
381 gdk_flush(); | |
382 | |
383 /* Initialize the colormap to the identity mapping */ | |
384 SDL_GetGammaRamp(0, 0, 0); | |
385 this->screen = current; | |
386 #if 0 // !!! FIXME | |
387 GTKPLUS_SetGammaRamp(this, this->gamma); | |
388 #endif | |
389 this->screen = NULL; | |
390 } else { | |
391 /* Create a read-only colormap for our window */ | |
392 this->hidden->colormap = gdk_colormap_new(this->hidden->visual, FALSE); | |
393 } | |
394 | |
395 #if 0 // !!! FIXME | |
396 /* Recreate the auxiliary windows, if needed (required for GL) */ | |
397 if ( vis_change ) | |
398 create_aux_windows(this); | |
399 | |
400 if(current->flags & SDL_HWPALETTE) { | |
401 /* Since the full-screen window might have got a nonzero background | |
402 colour (0 is white on some displays), we should reset the | |
403 background to 0 here since that is what the user expects | |
404 with a private colormap */ | |
405 XSetWindowBackground(SDL_Display, FSwindow, 0); | |
406 XClearWindow(SDL_Display, FSwindow); | |
407 } | |
408 | |
409 /* resize the (possibly new) window manager window */ | |
410 if( !SDL_windowid ) { | |
411 X11_SetSizeHints(this, w, h, flags); | |
412 window_w = w; | |
413 window_h = h; | |
414 XResizeWindow(SDL_Display, WMwindow, w, h); | |
415 } | |
416 #endif | |
417 | |
418 if ( this->hidden->gdkimage ) { | |
419 g_object_unref(this->hidden->gdkimage); | |
420 this->hidden->gdkimage = NULL; | |
421 } | |
422 | |
423 img = this->hidden->gdkimage = gdk_image_new(GDK_IMAGE_FASTEST, | |
424 vis, width, height); | |
425 if (img == NULL) { | |
426 SDL_SetError("Couldn't allocate buffer for requested mode"); | |
427 return(NULL); | |
428 } | |
429 gdk_image_set_colormap(this->hidden->gdkimage, this->hidden->colormap); | |
430 | |
431 SDL_memset(img->mem, 0, height * img->bpl); | |
432 | |
433 if ( this->hidden->gtkwindow == NULL ) { | |
434 this->hidden->gtkdrawingarea = gtk_drawing_area_new(); | |
435 if ( this->hidden->gtkdrawingarea == NULL ) { | |
436 SDL_SetError("Couldn't create drawing area for requested mode"); | |
437 g_object_unref(this->hidden->gdkimage); | |
438 this->hidden->gdkimage = NULL; | |
439 return(NULL); | |
440 } | |
441 | |
442 this->hidden->gtkwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
443 if ( this->hidden->gtkwindow == NULL ) { | |
444 SDL_SetError("Couldn't create window for requested mode"); | |
445 g_object_unref(this->hidden->gdkimage); | |
446 g_object_unref(this->hidden->gtkdrawingarea); | |
447 this->hidden->gdkimage = NULL; | |
448 this->hidden->gtkdrawingarea = NULL; | |
449 return(NULL); | |
450 } | |
451 | |
452 gtk_window_set_title(GTK_WINDOW(this->hidden->gtkwindow), ""); | |
453 gtk_widget_set_app_paintable(this->hidden->gtkwindow, TRUE); | |
454 gtk_widget_set_app_paintable(this->hidden->gtkdrawingarea, TRUE); | |
455 gtk_widget_set_double_buffered(this->hidden->gtkwindow, FALSE); | |
456 gtk_widget_set_double_buffered(this->hidden->gtkdrawingarea, FALSE); | |
457 | |
458 GTKPLUS_ConnectSignals(this); | |
459 | |
460 gtk_container_add(GTK_CONTAINER(this->hidden->gtkwindow), | |
461 this->hidden->gtkdrawingarea); | |
462 } | |
463 | |
464 win = GTK_WINDOW(this->hidden->gtkwindow); | |
465 gtk_widget_set_colormap(this->hidden->gtkdrawingarea, this->hidden->colormap); | |
466 | |
467 // !!! FIXME | |
468 #if 0 | |
469 /* Cache the window in the server, when possible */ | |
470 { | |
471 Screen *xscreen; | |
472 XSetWindowAttributes a; | |
473 | |
474 xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen); | |
475 a.backing_store = DoesBackingStore(xscreen); | |
476 if ( a.backing_store != NotUseful ) { | |
477 XChangeWindowAttributes(SDL_Display, SDL_Window, | |
478 CWBackingStore, &a); | |
479 } | |
480 } | |
481 | |
482 /* Update the internal keyboard state */ | |
483 X11_SetKeyboardState(SDL_Display, NULL); | |
484 | |
485 /* When the window is first mapped, ignore non-modifier keys */ | |
486 { | |
487 Uint8 *keys = SDL_GetKeyState(NULL); | |
488 for ( i = 0; i < SDLK_LAST; ++i ) { | |
489 switch (i) { | |
490 case SDLK_NUMLOCK: | |
491 case SDLK_CAPSLOCK: | |
492 case SDLK_LCTRL: | |
493 case SDLK_RCTRL: | |
494 case SDLK_LSHIFT: | |
495 case SDLK_RSHIFT: | |
496 case SDLK_LALT: | |
497 case SDLK_RALT: | |
498 case SDLK_LMETA: | |
499 case SDLK_RMETA: | |
500 case SDLK_MODE: | |
501 break; | |
502 default: | |
503 keys[i] = SDL_RELEASED; | |
504 break; | |
505 } | |
506 } | |
507 } | |
508 | |
509 /* Map them both and go fullscreen, if requested */ | |
510 if ( ! SDL_windowid ) { | |
511 XMapWindow(SDL_Display, SDL_Window); | |
512 XMapWindow(SDL_Display, WMwindow); | |
513 X11_WaitMapped(this, WMwindow); | |
514 if ( flags & SDL_FULLSCREEN ) { | |
515 current->flags |= SDL_FULLSCREEN; | |
516 X11_EnterFullScreen(this); | |
517 } else { | |
518 current->flags &= ~SDL_FULLSCREEN; | |
519 } | |
520 } | |
521 #endif | |
522 | |
523 if ((flags & SDL_FULLSCREEN) == 0) { | |
524 gtk_window_unfullscreen(win); | |
525 } else { | |
526 gtk_window_fullscreen(win); | |
527 flags &= ~SDL_RESIZABLE; | |
528 flags |= SDL_NOFRAME; | |
529 } | |
530 | |
531 gtk_window_set_resizable(win, (flags & SDL_RESIZABLE) ? TRUE : FALSE); | |
532 gtk_window_set_decorated(win, (flags & SDL_NOFRAME) ? FALSE : TRUE); | |
533 gtk_window_resize(win, width, height); | |
534 gtk_widget_set_size_request(this->hidden->gtkdrawingarea, width, height); | |
535 gtk_widget_show(this->hidden->gtkdrawingarea); | |
536 gtk_widget_show(this->hidden->gtkwindow); | |
537 | |
538 /* Set up the new mode framebuffer */ | |
539 current->w = width; | |
540 current->h = height; | |
541 //current->format->depth = vis->bits_per_rgb; | |
542 current->flags = flags | SDL_PREALLOC; | |
543 current->pitch = img->bpl; | |
544 current->pixels = this->hidden->gdkimage->mem; | |
545 | |
546 /* We're done */ | |
547 return(current); | |
548 } | |
549 | |
550 static void GTKPLUS_SetCaption(_THIS, const char *title, const char *icon) | |
551 { | |
552 gtk_window_set_title(GTK_WINDOW(this->hidden->gtkwindow), | |
553 (const gchar *) title); | |
554 } | |
555 | |
556 /* We don't actually allow hardware surfaces. */ | |
557 static int GTKPLUS_AllocHWSurface(_THIS, SDL_Surface *surface) | |
558 { | |
559 return(-1); | |
560 } | |
561 | |
562 static void GTKPLUS_FreeHWSurface(_THIS, SDL_Surface *surface) | |
563 { | |
564 } | |
565 | |
566 /* We need to wait for vertical retrace on page flipped displays */ | |
567 static int GTKPLUS_LockHWSurface(_THIS, SDL_Surface *surface) | |
568 { | |
569 return(0); | |
570 } | |
571 | |
572 static void GTKPLUS_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
573 { | |
574 } | |
575 | |
576 static void GTKPLUS_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | |
577 { | |
578 if ( (this->hidden->gtkdrawingarea != NULL) && | |
579 (GTK_WIDGET_DRAWABLE(this->hidden->gtkdrawingarea)) && | |
580 (numrects > 0) ) { | |
581 GdkDrawable *draw = GDK_DRAWABLE(this->hidden->gtkdrawingarea->window); | |
582 if (this->hidden->gc == NULL) { | |
583 this->hidden->gc = gdk_gc_new(draw); | |
584 } | |
585 | |
586 if (this->hidden->gc != NULL) { | |
587 GdkImage *img = this->hidden->gdkimage; | |
588 const SDL_Rect *r = rects; | |
589 int i; | |
590 for (i = 0; i < numrects; i++, r++) { | |
591 const gint x = r->x; | |
592 const gint y = r->y; | |
593 gdk_draw_image(draw, this->hidden->gc, img, | |
594 x, y, x, y, r->w, r->h); | |
595 } | |
596 gdk_flush(); /* transfer the GdkImage so we can make changes. */ | |
597 } | |
598 } | |
599 } | |
600 | |
601 int GTKPLUS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
602 { | |
603 /* !!! FIXME */ | |
604 return(0); | |
605 } | |
606 | |
607 /* Note: If we are terminated, this could be called in the middle of | |
608 another SDL video routine -- notably UpdateRects. | |
609 */ | |
610 void GTKPLUS_VideoQuit(_THIS) | |
611 { | |
612 int i; | |
613 | |
614 gdk_flush(); | |
615 | |
616 if (this->hidden->gc != NULL) { | |
617 g_object_unref(this->hidden->gc); | |
618 this->hidden->gc = NULL; | |
619 } | |
620 | |
621 if ( this->hidden->gtkwindow ) { | |
622 /* this deletes the drawing area widget, too. */ | |
623 gtk_widget_destroy(this->hidden->gtkwindow); | |
624 this->hidden->gtkwindow = NULL; | |
625 } | |
626 | |
627 if ( this->hidden->gdkimage ) { | |
628 g_object_unref(this->hidden->gdkimage); | |
629 this->hidden->gdkimage = NULL; | |
630 } | |
631 | |
632 for (i = 0; i < this->hidden->nvisuals; i++) { | |
633 g_object_unref(this->hidden->visuals[i]); | |
634 this->hidden->visuals[i] = NULL; | |
635 } | |
636 this->hidden->nvisuals = 0; | |
637 | |
638 g_object_unref(this->hidden->colormap); | |
639 this->hidden->colormap = NULL; | |
640 | |
641 gdk_flush(); | |
642 } | |
643 |