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