1 /*
2  * Copyright (C) 1998 Janne L�f <jlof@mail.student.oulu.fi>
3  *           (c) 2008, 2009 Sam Hocevar <sam@hocevar.net>
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  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #include <string.h>
21 
22 #include "gdkgl.h"
23 
24 #include <GL/gl.h>
25 #if defined GDK_WINDOWING_WIN32
26 #   include <gdk/gdkwin32.h>
27 #   define PLATFORM "GDK_WINDOWING_WIN32"
28 #elif defined GDK_WINDOWING_X11
29 #   include <gdk/gdkx.h>
30 #   include <GL/glx.h>
31 #   define PLATFORM "GDK_WINDOWING_X11"
32 #elif defined GDK_WINDOWING_FB
33 #   define PLATFORM "GDK_WINDOWING_FB"
34 #elif defined GDK_WINDOWING_QUARTZ
35 #   define PLATFORM "GDK_WINDOWING_QUARTZ"
36 #elif defined GDK_WINDOWING_DIRECTFB
37 #   define PLATFORM "GDK_WINDOWING_DIRECTFB"
38 #endif
39 
40 /*
41  *  The GdkGLContext class
42  */
43 struct _GdkGLContext {
44   GObject     parent;
45 #if defined GDK_WINDOWING_WIN32
46   gboolean  initialised;
47   HGLRC     hglrc;
48   HDC       hdc;
49   HWND      hwnd;
50   GdkGLContext *share;
51   PIXELFORMATDESCRIPTOR pfd;
52 #elif defined GDK_WINDOWING_X11
53   Display    *xdisplay;
54   GLXContext  glxcontext;
55 #endif
56 };
57 
58 struct _GdkGLContextClass {
59   GObjectClass parent_class;
60 };
61 typedef struct _GdkGLContextClass GdkGLContextClass;
62 
63 static GObjectClass *glcontext_parent_class;
64 static void gdk_gl_context_class_init (GdkGLContextClass *class);
65 
66 /*
67  *  The GdkGLPixmap class
68  */
69 struct _GdkGLPixmap {
70   GObject   parent;
71 #if defined GDK_WINDOWING_WIN32
72   gboolean  initialised;
73   HDC       hdc;
74   HBITMAP   hbitmap;
75   GdkPixmap *pixmap;
76 #elif defined GDK_WINDOWING_X11
77   Display   *xdisplay;
78   GLXPixmap glxpixmap;
79   GdkPixmap *front_left;
80 #endif
81 };
82 
83 struct _GdkGLPixmapClass {
84   GObjectClass parent_class;
85 };
86 typedef struct _GdkGLPixmapClass GdkGLPixmapClass;
87 
88 static GObjectClass *glpixmap_parent_class;
89 static void gdk_gl_pixmap_class_init (GdkGLPixmapClass *class);
90 
91 /*
92  *  Local helper functions
93  */
94 #if defined GDK_WINDOWING_WIN32
95 static void fill_pfd(PIXELFORMATDESCRIPTOR *pfd, int *attriblist);
96 #elif defined GDK_WINDOWING_X11
97 static XVisualInfo *get_xvisualinfo(GdkVisual *visual);
98 #endif
99 
100 
101 /*
102  *  Generic GL support
103  */
104 
gdk_gl_query(void)105 gint gdk_gl_query(void)
106 {
107 #if defined GDK_WINDOWING_WIN32
108   return TRUE;
109 #elif defined GDK_WINDOWING_X11
110   return (glXQueryExtension(GDK_DISPLAY(),NULL,NULL) == True) ? TRUE : FALSE;
111 #else
112   return FALSE;
113 #endif
114 }
115 
116 
gdk_gl_get_info()117 gchar *gdk_gl_get_info()
118 {
119   char const *vendor, *version, *extensions;
120 #if defined GDK_WINDOWING_WIN32
121   vendor = glGetString (GL_VENDOR);
122   version = glGetString (GL_VERSION);
123   extensions = glGetString (GL_EXTENSIONS);
124 #elif defined GDK_WINDOWING_X11
125   vendor = glXGetClientString(GDK_DISPLAY(), GLX_VENDOR);
126   version = glXGetClientString(GDK_DISPLAY(), GLX_VERSION);
127   extensions = glXGetClientString(GDK_DISPLAY(), GLX_EXTENSIONS);
128 #else
129   vendor = version = extensions = "unknown";
130 #endif
131   return g_strdup_printf("VENDOR     : %s\n"
132                          "VERSION    : %s\n"
133                          "EXTENSIONS : %s\n",
134                          vendor, version, extensions);
135 }
136 
137 
gdk_gl_choose_visual(int * attrlist)138 GdkVisual *gdk_gl_choose_visual(int *attrlist)
139 {
140 #if defined GDK_WINDOWING_WIN32
141   return gdk_visual_get_system ();
142 #elif defined GDK_WINDOWING_X11
143   Display *dpy;
144   XVisualInfo *vi;
145   GdkVisual *visual;
146 
147   g_return_val_if_fail(attrlist != NULL, NULL);
148 
149   dpy = GDK_DISPLAY();
150   vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrlist);
151   if (!vi)
152     return NULL;
153 
154   visual = gdkx_visual_get(vi->visualid);
155   XFree(vi);
156   return visual;
157 #else
158   g_warning ("gdk_gl_choose_visual not implemented on " PLATFORM);
159   return NULL;
160 #endif
161 }
162 
163 
gdk_gl_get_config(GdkVisual * visual,int attrib)164 int gdk_gl_get_config(GdkVisual *visual, int attrib)
165 {
166 #if defined GDK_WINDOWING_X11
167   Display *dpy;
168   XVisualInfo *vi;
169   int value;
170 
171   g_return_val_if_fail(visual != NULL, -1);
172 
173   dpy = GDK_DISPLAY();
174 
175   vi = get_xvisualinfo(visual);
176 
177   if (glXGetConfig(dpy, vi, attrib, &value) == 0)
178     {
179       XFree(vi);
180       return value;
181     }
182   XFree(vi);
183   return -1;
184 #else
185   g_warning ("gdk_gl_get_config not implemented on " PLATFORM);
186   return 0;
187 #endif
188 }
189 
190 
191 /*
192  *  GL context support
193  */
194 
195 GType
gdk_gl_context_get_type(void)196 gdk_gl_context_get_type (void)
197 {
198   static GType object_type = 0;
199 
200   if (!object_type)
201     {
202       static const GTypeInfo object_info =
203       {
204         sizeof (GdkGLContextClass),
205         (GBaseInitFunc) NULL,
206         (GBaseFinalizeFunc) NULL,
207         (GClassInitFunc) gdk_gl_context_class_init,
208         NULL,           /* class_finalize */
209         NULL,           /* class_data */
210         sizeof (GdkGLContext),
211         0,              /* n_preallocs */
212         (GInstanceInitFunc) NULL,
213       };
214 
215       object_type = g_type_register_static (G_TYPE_OBJECT,
216                                             "GdkGLContext",
217                                             &object_info, 0);
218     }
219   return object_type;
220 }
221 
222 static void
gdk_gl_context_finalize(GObject * object)223 gdk_gl_context_finalize(GObject *object)
224 {
225   GdkGLContext *context;
226 
227   context = GDK_GL_CONTEXT(object);
228 
229 #if defined GDK_WINDOWING_WIN32
230   if (context->hglrc == wglGetCurrentContext ())
231     wglMakeCurrent (NULL, NULL);
232 
233   wglDeleteContext (context->hglrc);
234 
235   if (context->hwnd)
236     ReleaseDC (context->hwnd, context->hdc);
237   else
238     DeleteDC (context->hdc);
239 #elif defined GDK_WINDOWING_X11
240   if (context->glxcontext) {
241     if (context->glxcontext == glXGetCurrentContext())
242       glXMakeCurrent(context->xdisplay, None, NULL);
243 
244     glXDestroyContext(context->xdisplay, context->glxcontext);
245   }
246   context->glxcontext = NULL;
247 #endif
248 
249   (* glcontext_parent_class->finalize)(object);
250 }
251 
252 
253 static void
gdk_gl_context_class_init(GdkGLContextClass * class)254 gdk_gl_context_class_init(GdkGLContextClass *class)
255 {
256   GObjectClass *gobject_class;
257 
258   gobject_class = G_OBJECT_CLASS(class);
259   glcontext_parent_class = g_type_class_peek_parent(class);
260 
261   gobject_class->finalize = gdk_gl_context_finalize;
262 }
263 
264 
265 GdkGLContext *
gdk_gl_context_new(GdkVisual * visual)266 gdk_gl_context_new(GdkVisual *visual)
267 {
268 #if defined GDK_WINDOWING_WIN32 || defined GDK_WINDOWING_X11
269   return gdk_gl_context_share_new(visual, NULL, FALSE);
270 #else
271   g_warning ("gdk_gl_context_new not implemented on " PLATFORM);
272   return NULL;
273 #endif
274 }
275 
276 
277 GdkGLContext *
gdk_gl_context_share_new(GdkVisual * visual,GdkGLContext * sharelist,gint direct)278 gdk_gl_context_share_new(GdkVisual *visual, GdkGLContext *sharelist, gint direct)
279 {
280 #if defined GDK_WINDOWING_WIN32
281   GdkGLContext *context;
282 #elif defined GDK_WINDOWING_X11
283   Display *dpy;
284   XVisualInfo *vi;
285   GLXContext glxcontext;
286   GdkGLContext *context;
287 #else
288   g_warning ("gdk_gl_context_share_new not implemented on " PLATFORM);
289   return NULL;
290 #endif
291 
292   g_return_val_if_fail (visual != NULL, NULL);
293 
294   context = g_object_new(GDK_TYPE_GL_CONTEXT, NULL);
295   if (!context)
296     return NULL;
297 
298 #if defined GDK_WINDOWING_WIN32
299   context->initialised = FALSE;
300   context->hglrc   = NULL;
301   context->hdc     = NULL;
302   context->hwnd    = NULL;
303   context->share   = sharelist ? g_object_ref(sharelist) : NULL;
304 
305   memset (&(context->pfd), 0, sizeof(PIXELFORMATDESCRIPTOR));
306 
307   /* if direct is TRUE, we create a context which renders to the screen,
308      otherwise we create one to render to an offscreen bitmap */
309   context->pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
310   context->pfd.nVersion = 1;
311   if (direct)
312     context->pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
313   else
314     context->pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI;
315   context->pfd.iPixelType = PFD_TYPE_RGBA;
316   context->pfd.cColorBits = 24;
317   context->pfd.cDepthBits = 32;
318   context->pfd.iLayerType = PFD_MAIN_PLANE;
319 #elif defined GDK_WINDOWING_X11
320   dpy = GDK_DISPLAY();
321 
322   vi = get_xvisualinfo(visual);
323 
324   glxcontext = glXCreateContext(dpy, vi, sharelist ? sharelist->glxcontext : 0,
325                                 direct ? True : False);
326 
327   XFree(vi);
328   if (glxcontext == NULL) {
329     g_object_unref(context);
330     return NULL;
331   }
332 
333   context->xdisplay = dpy;
334   context->glxcontext = glxcontext;
335 #endif
336 
337   return context;
338 }
339 
gdk_gl_context_attrlist_share_new(int * attrlist,GdkGLContext * sharelist,gint direct)340 GdkGLContext *gdk_gl_context_attrlist_share_new(int *attrlist, GdkGLContext *sharelist, gint direct)
341 {
342 #if defined GDK_WINDOWING_WIN32
343   GdkGLContext *context;
344 #elif defined GDK_WINDOWING_X11
345   GdkVisual *visual;
346 #else
347   g_warning ("gdk_gl_context_attrlist_share_new not implemented on " PLATFORM);
348   return NULL;
349 #endif
350 
351   g_return_val_if_fail(attrlist != NULL, NULL);
352 
353 #if defined GDK_WINDOWING_WIN32
354   context = g_object_new(GDK_TYPE_GL_CONTEXT, NULL);
355   if (!context)
356     return NULL;
357 
358   context->initialised = FALSE;
359   context->hglrc    = NULL;
360   context->hdc      = NULL;
361   context->hwnd     = NULL;
362   context->share    = sharelist ? g_object_ref(sharelist) : NULL;
363   fill_pfd(&context->pfd, attrlist);
364 
365   return context;
366 #elif defined GDK_WINDOWING_X11
367   visual = gdk_gl_choose_visual(attrlist);
368   if (!visual)
369     return NULL;
370 
371   return gdk_gl_context_share_new(visual, sharelist, direct);
372 #endif
373 }
374 
375 
gdk_gl_make_current(GdkDrawable * drawable,GdkGLContext * context)376 gint gdk_gl_make_current(GdkDrawable *drawable, GdkGLContext *context)
377 {
378   g_return_val_if_fail (GDK_IS_DRAWABLE(drawable), FALSE);
379   g_return_val_if_fail (GDK_IS_GL_CONTEXT(context), FALSE);
380 
381 #if defined GDK_WINDOWING_WIN32
382   if (!context->initialised)
383   {
384     int pf;
385     HWND hwnd = (HWND) gdk_win32_drawable_get_handle (drawable);
386 
387     context->hdc = GetDC (hwnd);
388 
389     pf = ChoosePixelFormat (context->hdc, &context->pfd);
390 
391     if (pf != 0)
392       {
393         SetPixelFormat (context->hdc, pf, &context->pfd);
394         context->hglrc = wglCreateContext (context->hdc);
395       }
396 
397     if (context->share)
398       {
399         if (context->share->hglrc)
400           {
401             if (wglShareLists (context->share->hglrc, context->hglrc) != TRUE)
402                 g_warning ("failed sharing context");
403           }
404         g_object_unref (context->share);
405       }
406 
407     context->initialised = TRUE;
408   }
409 
410   g_return_val_if_fail (context->hdc    != NULL, FALSE);
411   g_return_val_if_fail (context->hglrc  != NULL, FALSE);
412 
413   wglMakeCurrent (context->hdc, context->hglrc);
414 
415   return TRUE;
416 #elif defined GDK_WINDOWING_X11
417   return (glXMakeCurrent(context->xdisplay, GDK_WINDOW_XWINDOW(drawable),
418 			 context->glxcontext) == True) ? TRUE : FALSE;
419 
420 #if 0
421   if (context->glxcontext != None && context->glxcontext == glXGetCurrentContext())
422     {
423       glFlush();
424       return TRUE;
425     }
426   else
427     {
428       return (glXMakeCurrent(context->xdisplay, GDK_WINDOW_XWINDOW(drawable), context->glxcontext) == True) ? TRUE : FALSE;
429     }
430 #endif
431 #else
432   g_warning ("gdk_gl_make_current not implemented on " PLATFORM);
433 #endif
434 }
435 
gdk_gl_swap_buffers(GdkDrawable * drawable)436 void gdk_gl_swap_buffers(GdkDrawable *drawable)
437 {
438 #if defined GDK_WINDOWING_WIN32
439   HDC   hdc;
440   HWND  hwnd;
441 #endif
442 
443   g_return_if_fail (GDK_IS_DRAWABLE(drawable));
444 
445 #if defined GDK_WINDOWING_WIN32
446   hwnd = (HWND) gdk_win32_drawable_get_handle (drawable);
447   hdc  = GetDC (hwnd);
448   if (hdc  == NULL)
449   {
450      g_warning ("gdk_gl_swap_buffers: GetDC failed");
451      return;
452   }
453   SwapBuffers (hdc);
454   ReleaseDC (hwnd, hdc);
455 #elif defined GDK_WINDOWING_X11
456   glXSwapBuffers(GDK_WINDOW_XDISPLAY(drawable), GDK_WINDOW_XWINDOW(drawable));
457 #else
458   g_warning ("gdk_gl_swap_buffers not implemented on " PLATFORM);
459 #endif
460 }
461 
gdk_gl_wait_gdk(void)462 void gdk_gl_wait_gdk(void)
463 {
464 #if defined GDK_WINDOWING_WIN32
465   GdiFlush();
466 #elif defined GDK_WINDOWING_X11
467   glXWaitX();
468 #endif
469 }
470 
gdk_gl_wait_gl(void)471 void gdk_gl_wait_gl (void)
472 {
473 #if defined GDK_WINDOWING_WIN32
474   glFinish();
475 #elif defined GDK_WINDOWING_X11
476   glXWaitGL();
477 #endif
478 }
479 
480 
481 /*
482  *  Pixmap support
483  */
484 
485 GType
gdk_gl_pixmap_get_type(void)486 gdk_gl_pixmap_get_type (void)
487 {
488   static GType object_type = 0;
489 
490   if (!object_type)
491     {
492       static const GTypeInfo object_info =
493       {
494         sizeof (GdkGLPixmapClass),
495         (GBaseInitFunc) NULL,
496         (GBaseFinalizeFunc) NULL,
497         (GClassInitFunc) gdk_gl_pixmap_class_init,
498         NULL,           /* class_finalize */
499         NULL,           /* class_data */
500         sizeof (GdkGLPixmap),
501         0,              /* n_preallocs */
502         (GInstanceInitFunc) NULL,
503       };
504 
505       object_type = g_type_register_static (G_TYPE_OBJECT,
506                                             "GdkGLPixmap",
507                                             &object_info, 0);
508     }
509   return object_type;
510 }
511 
512 static void
gdk_gl_pixmap_finalize(GObject * object)513 gdk_gl_pixmap_finalize(GObject *object)
514 {
515   GdkGLPixmap *pixmap;
516 
517   pixmap = GDK_GL_PIXMAP(object);
518 
519 #if defined GDK_WINDOWING_WIN32
520   glFinish ();
521   SelectObject (pixmap->hdc, pixmap->hbitmap);
522   gdk_pixmap_unref (pixmap->pixmap);
523 #elif defined GDK_WINDOWING_X11
524   if (pixmap->glxpixmap != None) {
525     glXDestroyGLXPixmap(pixmap->xdisplay, pixmap->glxpixmap);
526     glXWaitGL();
527   }
528   pixmap->glxpixmap = None;
529   if (pixmap->front_left) {
530     gdk_pixmap_unref(pixmap->front_left);
531     glXWaitX();
532   }
533   pixmap->front_left = NULL;
534 #endif
535 
536   (* glcontext_parent_class->finalize)(object);
537 }
538 
539 static void
gdk_gl_pixmap_class_init(GdkGLPixmapClass * class)540 gdk_gl_pixmap_class_init(GdkGLPixmapClass *class)
541 {
542   GObjectClass *gobject_class;
543 
544   gobject_class = G_OBJECT_CLASS(class);
545   glpixmap_parent_class = g_type_class_peek_parent(class);
546 
547   gobject_class->finalize = gdk_gl_pixmap_finalize;
548 }
549 
550 GdkGLPixmap *
gdk_gl_pixmap_new(GdkVisual * visual,GdkPixmap * pixmap)551 gdk_gl_pixmap_new(GdkVisual *visual, GdkPixmap *pixmap)
552 {
553   GdkGLPixmap *glpixmap;
554 #ifndef GDK_WINDOWING_WIN32
555   Display *dpy;
556   XVisualInfo *vi;
557   Pixmap xpixmap;
558   GLXPixmap glxpixmap;
559   Window root_return;
560   unsigned int w_ret, h_ret, bw_ret, depth_ret;
561   int x_ret, y_ret;
562 #elif defined GDK_WINDOWING_X11
563 #else
564   g_warning ("gdk_gl_pixmap_new not implemented on " PLATFORM);
565   return NULL;
566 #endif
567 
568   g_return_val_if_fail(GDK_IS_VISUAL(visual), NULL);
569   g_return_val_if_fail(GDK_IS_PIXMAP(pixmap), NULL);
570 
571   glpixmap = g_object_new(GDK_TYPE_GL_PIXMAP, NULL);
572   if (!glpixmap)
573     return NULL;
574 
575 #if defined GDK_WINDOWING_WIN32
576   glpixmap->initialised = FALSE;
577   glpixmap->hdc = NULL;
578   glpixmap->hbitmap = NULL;
579   glpixmap->pixmap = gdk_pixmap_ref (pixmap);
580 #elif defined GDK_WINDOWING_X11
581   dpy = GDK_DISPLAY();
582   xpixmap = (Pixmap)GDK_DRAWABLE_XID(pixmap);
583 
584   g_return_val_if_fail(XGetGeometry(dpy, xpixmap, &root_return,
585 				    &x_ret, &y_ret, &w_ret, &h_ret,
586                                     &bw_ret, &depth_ret), NULL);
587 
588   g_return_val_if_fail((gdk_gl_get_config(visual, GDK_GL_RED_SIZE) +
589 			gdk_gl_get_config(visual, GDK_GL_GREEN_SIZE) +
590 			gdk_gl_get_config(visual, GDK_GL_BLUE_SIZE)) == depth_ret, NULL);
591 
592   vi = get_xvisualinfo(visual);
593   glxpixmap = glXCreateGLXPixmap(dpy, vi, xpixmap);
594   XFree(vi);
595 
596   g_return_val_if_fail(glxpixmap != None, NULL);
597 
598   glpixmap->xdisplay   = dpy;
599   glpixmap->glxpixmap  = glxpixmap;
600   glpixmap->front_left = gdk_pixmap_ref(pixmap);
601 #endif
602 
603   return glpixmap;
604 }
605 
606 
gdk_gl_pixmap_make_current(GdkGLPixmap * glpixmap,GdkGLContext * context)607 gint gdk_gl_pixmap_make_current(GdkGLPixmap *glpixmap, GdkGLContext *context)
608 {
609 #ifndef GDK_WINDOWING_WIN32
610   Display  *dpy;
611   GLXPixmap glxpixmap;
612   GLXContext glxcontext;
613 #elif defined GDK_WINDOWING_X11
614 #else
615   g_warning ("gdk_gl_pixmap_make_current not implemented on " PLATFORM);
616   return 0;
617 #endif
618 
619   g_return_val_if_fail (GDK_IS_GL_PIXMAP(glpixmap), FALSE);
620   g_return_val_if_fail (GDK_IS_GL_CONTEXT(context), FALSE);
621 
622 #if defined GDK_WINDOWING_WIN32
623   if (!context->initialised)
624   {
625     int pf;
626 
627     context->hdc = CreateCompatibleDC (NULL);
628     glpixmap->hdc = context->hdc;
629     glpixmap->hbitmap = SelectObject (context->hdc, (HBITMAP) gdk_win32_drawable_get_handle (glpixmap->pixmap));
630 
631     pf = ChoosePixelFormat (context->hdc, &context->pfd);
632 
633     if (pf != 0)
634       {
635         SetPixelFormat (context->hdc, pf, &context->pfd);
636         context->hglrc = wglCreateContext (context->hdc);
637       }
638 
639     if (context->share)
640       {
641         if (context->share->hglrc)
642           {
643             if (wglShareLists (context->share->hglrc, context->hglrc) != TRUE)
644                 g_warning ("failed sharing context");
645           }
646         gdk_gl_context_unref ((GdkGLContext*)context->share);
647       }
648 
649     context->initialised = TRUE;
650   }
651 
652   g_return_val_if_fail (context->hdc    != NULL, FALSE);
653   g_return_val_if_fail (context->hglrc  != NULL, FALSE);
654 
655   wglMakeCurrent (context->hdc, context->hglrc);
656 
657   return TRUE;
658 #elif defined GDK_WINDOWING_X11
659   dpy        = context->xdisplay;
660   glxpixmap  = glpixmap->glxpixmap;
661   glxcontext = context->glxcontext;
662 
663   return (glXMakeCurrent(dpy, glxpixmap, glxcontext) == True) ? TRUE : FALSE;
664 #endif
665 }
666 
667 /*
668  *  Font support
669  */
670 
gdk_gl_use_gdk_font(GdkFont * font,int first,int count,int list_base)671 void gdk_gl_use_gdk_font(GdkFont *font, int first, int count, int list_base)
672 {
673 #if defined GDK_WINDOWING_WIN32
674   HDC dc = CreateCompatibleDC (NULL);
675   HFONT old_font = SelectObject (dc, (void *)gdk_font_id (font));
676 
677   wglUseFontBitmaps (dc, first, count, list_base);
678 
679   SelectObject (dc, old_font);
680   DeleteDC (dc);
681 #elif defined GDK_WINDOWING_X11
682   g_return_if_fail(font != NULL);
683   glXUseXFont(gdk_font_id(font), first, count, list_base);
684 #else
685   g_warning ("gdk_gl_use_gdk_font not implemented on " PLATFORM);
686 #endif
687 }
688 
689 
690 /*
691  *  Helper functions
692  */
693 
694 #if defined GDK_WINDOWING_WIN32
fill_pfd(PIXELFORMATDESCRIPTOR * pfd,int * attriblist)695 static void fill_pfd(PIXELFORMATDESCRIPTOR *pfd, int *attriblist)
696 {
697   /*
698    * Ripped from glut's win32_x11.c
699    */
700 
701   int *p = attriblist;
702 
703   memset(pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
704   pfd->nSize = (sizeof(PIXELFORMATDESCRIPTOR));
705   pfd->nVersion = 1;
706 
707   /* Defaults. */
708   pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
709   pfd->iPixelType = PFD_TYPE_COLORINDEX;
710   pfd->cColorBits = 32;
711   pfd->cDepthBits = 0;
712   pfd->cAccumBits = 0;
713 
714   while (*p) {
715     switch (*p) {
716     case GDK_GL_USE_GL:
717       pfd->dwFlags |= PFD_SUPPORT_OPENGL;
718       break;
719     case GDK_GL_BUFFER_SIZE:
720       pfd->cColorBits = *(++p);
721       break;
722     case GDK_GL_LEVEL:
723       /* the bReserved flag of the pfd contains the
724          overlay/underlay info. */
725       pfd->bReserved = *(++p);
726       break;
727     case GDK_GL_RGBA:
728       pfd->iPixelType = PFD_TYPE_RGBA;
729       break;
730     case GDK_GL_DOUBLEBUFFER:
731       pfd->dwFlags |= PFD_DOUBLEBUFFER;
732       break;
733     case GDK_GL_STEREO:
734       pfd->dwFlags |= PFD_STEREO;
735       break;
736     case GDK_GL_AUX_BUFFERS:
737       pfd->cAuxBuffers = *(++p);
738       break;
739     case GDK_GL_RED_SIZE:
740       pfd->cRedBits = 8; /* Try to get the maximum. */
741       ++p;
742       break;
743     case GDK_GL_GREEN_SIZE:
744       pfd->cGreenBits = 8;
745       ++p;
746       break;
747     case GDK_GL_BLUE_SIZE:
748       pfd->cBlueBits = 8;
749       ++p;
750       break;
751     case GDK_GL_ALPHA_SIZE:
752       pfd->cAlphaBits = 8;
753       ++p;
754       break;
755     case GDK_GL_DEPTH_SIZE:
756       pfd->cDepthBits = 32;
757       ++p;
758       break;
759     case GDK_GL_STENCIL_SIZE:
760       pfd->cStencilBits = *(++p);
761       break;
762     case GDK_GL_ACCUM_RED_SIZE:
763     case GDK_GL_ACCUM_GREEN_SIZE:
764     case GDK_GL_ACCUM_BLUE_SIZE:
765     case GDK_GL_ACCUM_ALPHA_SIZE:
766       /* I believe that WGL only used the cAccumRedBits,
767          cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields
768          when returning info about the accumulation buffer precision.
769          Only cAccumBits is used for requesting an accumulation
770          buffer. */
771       pfd->cAccumBits += *(++p);
772                 break;
773     }
774     ++p;
775   }
776 }
777 
778 
779 #elif defined GDK_WINDOWING_X11
get_xvisualinfo(GdkVisual * visual)780 static XVisualInfo *get_xvisualinfo(GdkVisual *visual)
781 {
782   Display *dpy;
783   XVisualInfo vinfo_template;
784   XVisualInfo *vi;
785   int nitems_return;
786 
787   dpy = GDK_DISPLAY();
788 
789   /* 'GLX uses VisualInfo records because they uniquely identify
790    * a (VisualID,screen,depth) tuple.'
791    */
792   vinfo_template.visual   = GDK_VISUAL_XVISUAL(visual);
793   vinfo_template.visualid = XVisualIDFromVisual(vinfo_template.visual);
794   vinfo_template.depth    = visual->depth;
795   vinfo_template.screen   = DefaultScreen(dpy);
796   vi = XGetVisualInfo(dpy, VisualIDMask|VisualDepthMask|VisualScreenMask,
797 		      &vinfo_template, &nitems_return);
798 
799   g_assert(vi!=0  && nitems_return==1); /* visualinfo needs to be unique */
800 
801   /* remember to XFree returned XVisualInfo !!! */
802   return vi;
803 }
804 #endif
805 
806