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