1 /*
2 * Copyright (C) 2001-2015, AdaCore
3 * Copyright (C) 1997-1998 Janne L�f <jlof@mail.student.oulu.fi>
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 <stdarg.h>
21
22 #include "gdkgl.h"
23 #include "gtkglarea.h"
24
25 static void gtk_gl_area_class_init (GtkGLAreaClass *klass);
26 static void gtk_gl_area_init (GtkGLArea *glarea);
27 static void gtk_gl_area_destroy (GObject *object); /* change to finalize? */
28
29 static GtkDrawingAreaClass *parent_class = NULL;
30
31
32 GType
gtk_gl_area_get_type(void)33 gtk_gl_area_get_type (void)
34 {
35 static GType object_type = 0;
36
37 if (!object_type)
38 {
39 static const GTypeInfo object_info =
40 {
41 sizeof (GtkGLAreaClass),
42 (GBaseInitFunc) NULL,
43 (GBaseFinalizeFunc) NULL,
44 (GClassInitFunc) gtk_gl_area_class_init,
45 NULL, /* class_finalize */
46 NULL, /* class_data */
47 sizeof (GtkGLArea),
48 0, /* n_preallocs */
49 (GInstanceInitFunc) gtk_gl_area_init,
50 };
51
52 object_type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
53 "GtkGLArea",
54 &object_info, 0);
55 }
56 return object_type;
57 }
58
59 static void
gtk_gl_area_class_init(GtkGLAreaClass * klass)60 gtk_gl_area_class_init (GtkGLAreaClass *klass)
61 {
62 GObjectClass *object_class;
63
64 parent_class = g_type_class_peek_parent(klass);
65 object_class = (GObjectClass*) klass;
66
67 object_class->finalize = gtk_gl_area_destroy;
68 }
69
70
71 static void
gtk_gl_area_init(GtkGLArea * gl_area)72 gtk_gl_area_init (GtkGLArea *gl_area)
73 {
74 gl_area->glcontext = NULL;
75 gtk_widget_set_double_buffered(GTK_WIDGET(gl_area), FALSE);
76 }
77
78
79
80 GtkWidget*
gtk_gl_area_new_vargs(GtkGLArea * share,...)81 gtk_gl_area_new_vargs(GtkGLArea *share, ...)
82 {
83 GtkWidget *glarea;
84 va_list ap;
85 int i;
86 gint *attrlist;
87
88 va_start(ap, share);
89 i=1;
90 while (va_arg(ap, int) != GDK_GL_NONE) /* get number of arguments */
91 i++;
92 va_end(ap);
93
94 attrlist = g_new(int,i);
95
96 va_start(ap,share);
97 i=0;
98 while ( (attrlist[i] = va_arg(ap, int)) != GDK_GL_NONE) /* copy args to list */
99 i++;
100 va_end(ap);
101
102 glarea = gtk_gl_area_share_new(attrlist, share);
103
104 g_free(attrlist);
105
106 return glarea;
107 }
108
109 GtkWidget*
gtk_gl_area_new(int * attrlist)110 gtk_gl_area_new (int *attrlist)
111 {
112 return gtk_gl_area_share_new(attrlist, NULL);
113 }
114
115 GtkWidget*
gtk_gl_area_share_new(int * attrlist,GtkGLArea * share)116 gtk_gl_area_share_new (int *attrlist, GtkGLArea *share)
117 {
118 GdkGLContext *glcontext;
119 GtkGLArea *gl_area;
120 #if defined GDK_WINDOWING_X11
121 GdkVisual *visual;
122 #endif
123
124 g_return_val_if_fail(share == NULL || GTK_IS_GL_AREA(share), NULL);
125
126 #if defined GDK_WINDOWING_X11
127 visual = gdk_gl_choose_visual(attrlist);
128 if (visual == NULL)
129 return NULL;
130
131 glcontext = gdk_gl_context_share_new(visual, share ? share->glcontext : NULL, TRUE);
132 #else
133 glcontext = gdk_gl_context_attrlist_share_new(attrlist, share ? share->glcontext : NULL, TRUE);
134 #endif
135 if (glcontext == NULL)
136 return NULL;
137
138 #if defined GDK_WINDOWING_X11
139 /* use colormap and visual suitable for OpenGL rendering */
140 // gtk_widget_push_colormap(gdk_colormap_new(visual,TRUE));
141 // gtk_widget_push_visual(visual);
142 #endif
143
144 gl_area = g_object_new(GTK_TYPE_GL_AREA, NULL);
145 gl_area->glcontext = glcontext;
146
147 #if defined GDK_WINDOWING_X11
148 /* pop back defaults */
149 // gtk_widget_pop_visual();
150 // gtk_widget_pop_colormap();
151 #endif
152
153 return GTK_WIDGET(gl_area);
154 }
155
156
157 static void
gtk_gl_area_destroy(GObject * object)158 gtk_gl_area_destroy(GObject *object)
159 {
160 GtkGLArea *gl_area;
161
162 g_return_if_fail (object != NULL);
163 g_return_if_fail (GTK_IS_GL_AREA(object));
164
165 gl_area = GTK_GL_AREA(object);
166
167 if (gl_area->glcontext)
168 g_object_unref(gl_area->glcontext);
169 gl_area->glcontext = NULL;
170
171 if (G_OBJECT_GET_CLASS (parent_class)->finalize)
172 (* G_OBJECT_GET_CLASS (parent_class)->finalize) (object);
173 }
174
175
gtk_gl_area_make_current(GtkGLArea * gl_area)176 gint gtk_gl_area_make_current(GtkGLArea *gl_area)
177 {
178 g_return_val_if_fail(gl_area != NULL, FALSE);
179 g_return_val_if_fail(GTK_IS_GL_AREA (gl_area), FALSE);
180 // g_return_val_if_fail(GTK_WIDGET_REALIZED(gl_area), FALSE);
181
182 return gdk_gl_make_current(gtk_widget_get_window(GTK_WIDGET(gl_area)), gl_area->glcontext);
183 }
184
gtk_gl_area_swap_buffers(GtkGLArea * gl_area)185 void gtk_gl_area_swap_buffers(GtkGLArea *gl_area)
186 {
187 g_return_if_fail(gl_area != NULL);
188 g_return_if_fail(GTK_IS_GL_AREA(gl_area));
189 // g_return_if_fail(GTK_WIDGET_REALIZED(gl_area));
190
191 gdk_gl_swap_buffers(gtk_widget_get_window (GTK_WIDGET (gl_area)));
192 }
193