1 /*
2 * color.c:
3 * Color management example.
4 *
5 * written by Naofumi Yasufuku <naofumi@users.sourceforge.net>
6 */
7
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include <gtk/gtk.h>
12
13 #include <gtk/gtkgl.h>
14
15 #ifdef G_OS_WIN32
16 #define WIN32_LEAN_AND_MEAN 1
17 #include <windows.h>
18 #endif
19
20 #include <GL/gl.h>
21 #include <GL/glu.h>
22
23 /*
24 * Colors.
25 */
26
27 #define NUM_COLORS 4
28
29 static GdkColor colors[NUM_COLORS] = {
30 /* pixel red green blue */
31 { 0, 0x0, 0x0, 0x0 }, /* black */
32 { 0, 0xffff, 0x0, 0x0 }, /* red */
33 { 0, 0x0, 0xffff, 0x0 }, /* green */
34 { 0, 0x0, 0x0, 0xffff } /* blue */
35 };
36
37 #define BLACK colors[0].pixel
38 #define RED colors[1].pixel
39 #define GREEN colors[2].pixel
40 #define BLUE colors[3].pixel
41
42 static gboolean
configure_event(GtkWidget * widget,GdkEventConfigure * event,gpointer data)43 configure_event (GtkWidget *widget,
44 GdkEventConfigure *event,
45 gpointer data)
46 {
47 GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
48 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
49
50 /*** OpenGL BEGIN ***/
51 if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
52 goto NO_GL;
53
54 glViewport (0, 0,
55 widget->allocation.width, widget->allocation.height);
56
57 gdk_gl_drawable_gl_end (gldrawable);
58 /*** OpenGL END ***/
59
60 NO_GL:
61
62 return TRUE;
63 }
64
65 static gboolean
expose_event(GtkWidget * widget,GdkEventExpose * event,gpointer data)66 expose_event (GtkWidget *widget,
67 GdkEventExpose *event,
68 gpointer data)
69 {
70 GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
71 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
72
73 /*** OpenGL BEGIN ***/
74 if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
75 goto NO_GL;
76
77 glClear (GL_COLOR_BUFFER_BIT);
78
79 glBegin (GL_TRIANGLES);
80 glIndexi (RED);
81 glColor3f (1.0, 0.0, 0.0);
82 glVertex2i (0, 1);
83 glIndexi (GREEN);
84 glColor3f (0.0, 1.0, 0.0);
85 glVertex2i (-1, -1);
86 glIndexi (BLUE);
87 glColor3f (0.0, 0.0, 1.0);
88 glVertex2i (1, -1);
89 glEnd ();
90
91 if (gdk_gl_drawable_is_double_buffered (gldrawable))
92 gdk_gl_drawable_swap_buffers (gldrawable);
93 else
94 glFlush ();
95
96 gdk_gl_drawable_gl_end (gldrawable);
97 /*** OpenGL END ***/
98
99 NO_GL:
100
101 return TRUE;
102 }
103
104 static void
print_gl_config_attrib(GdkGLConfig * glconfig,const gchar * attrib_str,int attrib,gboolean is_boolean)105 print_gl_config_attrib (GdkGLConfig *glconfig,
106 const gchar *attrib_str,
107 int attrib,
108 gboolean is_boolean)
109 {
110 int value;
111
112 g_print ("%s = ", attrib_str);
113 if (gdk_gl_config_get_attrib (glconfig, attrib, &value))
114 {
115 if (is_boolean)
116 g_print ("%s\n", value == TRUE ? "TRUE" : "FALSE");
117 else
118 g_print ("%d\n", value);
119 }
120 else
121 g_print ("*** Cannot get %s attribute value\n", attrib_str);
122 }
123
124 static void
examine_gl_config_attrib(GdkGLConfig * glconfig)125 examine_gl_config_attrib (GdkGLConfig *glconfig)
126 {
127 g_print ("\nOpenGL visual configurations :\n\n");
128
129 g_print ("gdk_gl_config_is_rgba (glconfig) = %s\n",
130 gdk_gl_config_is_rgba (glconfig) ? "TRUE" : "FALSE");
131 g_print ("gdk_gl_config_is_double_buffered (glconfig) = %s\n",
132 gdk_gl_config_is_double_buffered (glconfig) ? "TRUE" : "FALSE");
133 g_print ("gdk_gl_config_is_stereo (glconfig) = %s\n",
134 gdk_gl_config_is_stereo (glconfig) ? "TRUE" : "FALSE");
135 g_print ("gdk_gl_config_has_alpha (glconfig) = %s\n",
136 gdk_gl_config_has_alpha (glconfig) ? "TRUE" : "FALSE");
137 g_print ("gdk_gl_config_has_depth_buffer (glconfig) = %s\n",
138 gdk_gl_config_has_depth_buffer (glconfig) ? "TRUE" : "FALSE");
139 g_print ("gdk_gl_config_has_stencil_buffer (glconfig) = %s\n",
140 gdk_gl_config_has_stencil_buffer (glconfig) ? "TRUE" : "FALSE");
141 g_print ("gdk_gl_config_has_accum_buffer (glconfig) = %s\n",
142 gdk_gl_config_has_accum_buffer (glconfig) ? "TRUE" : "FALSE");
143
144 g_print ("\n");
145
146 print_gl_config_attrib (glconfig, "GDK_GL_USE_GL", GDK_GL_USE_GL, TRUE);
147 print_gl_config_attrib (glconfig, "GDK_GL_BUFFER_SIZE", GDK_GL_BUFFER_SIZE, FALSE);
148 print_gl_config_attrib (glconfig, "GDK_GL_LEVEL", GDK_GL_LEVEL, FALSE);
149 print_gl_config_attrib (glconfig, "GDK_GL_RGBA", GDK_GL_RGBA, TRUE);
150 print_gl_config_attrib (glconfig, "GDK_GL_DOUBLEBUFFER", GDK_GL_DOUBLEBUFFER, TRUE);
151 print_gl_config_attrib (glconfig, "GDK_GL_STEREO", GDK_GL_STEREO, TRUE);
152 print_gl_config_attrib (glconfig, "GDK_GL_AUX_BUFFERS", GDK_GL_AUX_BUFFERS, FALSE);
153 print_gl_config_attrib (glconfig, "GDK_GL_RED_SIZE", GDK_GL_RED_SIZE, FALSE);
154 print_gl_config_attrib (glconfig, "GDK_GL_GREEN_SIZE", GDK_GL_GREEN_SIZE, FALSE);
155 print_gl_config_attrib (glconfig, "GDK_GL_BLUE_SIZE", GDK_GL_BLUE_SIZE, FALSE);
156 print_gl_config_attrib (glconfig, "GDK_GL_ALPHA_SIZE", GDK_GL_ALPHA_SIZE, FALSE);
157 print_gl_config_attrib (glconfig, "GDK_GL_DEPTH_SIZE", GDK_GL_DEPTH_SIZE, FALSE);
158 print_gl_config_attrib (glconfig, "GDK_GL_STENCIL_SIZE", GDK_GL_STENCIL_SIZE, FALSE);
159 print_gl_config_attrib (glconfig, "GDK_GL_ACCUM_RED_SIZE", GDK_GL_ACCUM_RED_SIZE, FALSE);
160 print_gl_config_attrib (glconfig, "GDK_GL_ACCUM_GREEN_SIZE", GDK_GL_ACCUM_GREEN_SIZE, FALSE);
161 print_gl_config_attrib (glconfig, "GDK_GL_ACCUM_BLUE_SIZE", GDK_GL_ACCUM_BLUE_SIZE, FALSE);
162 print_gl_config_attrib (glconfig, "GDK_GL_ACCUM_ALPHA_SIZE", GDK_GL_ACCUM_ALPHA_SIZE, FALSE);
163
164 g_print ("\n");
165 }
166
167 int
main(int argc,char * argv[])168 main (int argc,
169 char *argv[])
170 {
171 GdkGLConfigMode mode;
172 GdkGLConfig *glconfig;
173 gboolean is_rgba;
174 GdkColormap *colormap;
175 GdkColor color;
176 gboolean success[NUM_COLORS];
177 gint not_allocated;
178 gint major, minor;
179 int i;
180
181 GtkWidget *window;
182 GtkWidget *vbox;
183 GtkWidget *drawing_area;
184 GtkWidget *button;
185
186 /*
187 * Init GTK.
188 */
189
190 gtk_init (&argc, &argv);
191
192 /*
193 * Init GtkGLExt.
194 */
195
196 gtk_gl_init (&argc, &argv);
197
198 /*
199 * Display mode.
200 */
201
202 mode = GDK_GL_MODE_INDEX;
203
204 for (i = 0; i < argc; i++)
205 {
206 if (strcmp (argv[i], "--rgb") == 0)
207 mode = GDK_GL_MODE_RGB;
208 }
209
210 /*
211 * Query OpenGL extension version.
212 */
213
214 gdk_gl_query_version (&major, &minor);
215 g_print ("\nOpenGL extension version - %d.%d\n",
216 major, minor);
217
218 /*
219 * Configure OpenGL-capable visual.
220 */
221
222 /* Try double-buffered visual */
223 glconfig = gdk_gl_config_new_by_mode (mode | GDK_GL_MODE_DOUBLE);
224 if (glconfig == NULL)
225 {
226 g_print ("*** Cannot find the double-buffered visual.\n");
227 g_print ("*** Trying single-buffered visual.\n");
228
229 /* Try single-buffered visual */
230 glconfig = gdk_gl_config_new_by_mode (mode);
231 if (glconfig == NULL)
232 {
233 g_print ("*** No appropriate OpenGL-capable visual found.\n");
234 exit (1);
235 }
236 }
237
238 examine_gl_config_attrib (glconfig);
239
240 is_rgba = gdk_gl_config_is_rgba (glconfig);
241
242 colormap = gdk_gl_config_get_colormap (glconfig);
243
244 /*
245 * Top-level window.
246 */
247
248 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
249 gtk_window_set_title (GTK_WINDOW (window), "color");
250
251 /* Get automatically redrawn if any of their children changed allocation. */
252 gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);
253
254 g_signal_connect (G_OBJECT (window), "delete_event",
255 G_CALLBACK (gtk_main_quit), NULL);
256
257 /*
258 * VBox.
259 */
260
261 vbox = gtk_vbox_new (FALSE, 0);
262 gtk_container_add (GTK_CONTAINER (window), vbox);
263 gtk_widget_show (vbox);
264
265 /*
266 * Drawing area for drawing OpenGL scene.
267 */
268
269 drawing_area = gtk_drawing_area_new ();
270 gtk_widget_set_size_request (drawing_area, 200, 200);
271
272 /* Set OpenGL-capability to the widget. */
273 gtk_widget_set_gl_capability (drawing_area,
274 glconfig,
275 NULL,
276 TRUE,
277 is_rgba ? GDK_GL_RGBA_TYPE : GDK_GL_COLOR_INDEX_TYPE);
278
279 g_signal_connect (G_OBJECT (drawing_area), "configure_event",
280 G_CALLBACK (configure_event), NULL);
281 g_signal_connect (G_OBJECT (drawing_area), "expose_event",
282 G_CALLBACK (expose_event), NULL);
283
284 gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
285
286 gtk_widget_show (drawing_area);
287
288 /*
289 * Simple quit button.
290 */
291
292 button = gtk_button_new_with_label ("Quit");
293
294 g_signal_connect (G_OBJECT (button), "clicked",
295 G_CALLBACK (gtk_main_quit), NULL);
296
297 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
298
299 gtk_widget_show (button);
300
301 /*
302 * Show window.
303 */
304
305 gtk_widget_show (window);
306
307 /*
308 * Allocate colors.
309 */
310
311 if (!is_rgba)
312 {
313 g_print ("\nAllocate colors.\n");
314
315 /* Allocate writable color cells. */
316 not_allocated = gdk_colormap_alloc_colors (colormap, colors, NUM_COLORS,
317 FALSE, FALSE, success);
318 g_print ("Not allocated = %d\n", not_allocated);
319
320 for (i = 0; i < NUM_COLORS; i++)
321 {
322 g_print ("colors[%d] = { %u, 0x%x, 0x%x, 0x%x }\n",
323 i, colors[i].pixel,
324 colors[i].red, colors[i].green, colors[i].blue);
325 }
326 g_print ("\n");
327
328 g_print ("Query colors.\n");
329 for (i = 0; i < NUM_COLORS; i++)
330 {
331 color.pixel = colors[i].pixel;
332 gdk_colormap_query_color (colormap, colors[i].pixel, &color);
333 g_print ("colors[%d] = { %u, 0x%x, 0x%x, 0x%x }\n",
334 i, colors[i].pixel,
335 color.red, color.green, color.blue);
336 }
337 g_print ("\n");
338 }
339
340 /*
341 * Main loop.
342 */
343
344 gtk_main ();
345
346 return 0;
347 }
348