~ubuntu-branches/debian/sid/gtkglext/sid

« back to all changes in this revision

Viewing changes to examples/gears.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-04-03 17:43:17 UTC
  • Revision ID: james.westby@ubuntu.com-20040403174317-d5gb2d2gftaligp8
Tags: upstream-1.0.6
ImportĀ upstreamĀ versionĀ 1.0.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * 3-D gear wheels.  This program is in the public domain.
 
3
 *
 
4
 * Brian Paul
 
5
 */
 
6
 
 
7
/* Conversion to GLUT by Mark J. Kilgard */
 
8
 
 
9
/* Conversion to GtkGLExt by Naofumi Yasufuku */
 
10
 
 
11
#include <stdlib.h>
 
12
#include <string.h>
 
13
#include <math.h>
 
14
 
 
15
#include <gtk/gtk.h>
 
16
#include <gdk/gdkkeysyms.h>
 
17
 
 
18
#include <gtk/gtkgl.h>
 
19
 
 
20
#ifdef G_OS_WIN32
 
21
#define WIN32_LEAN_AND_MEAN 1
 
22
#include <windows.h>
 
23
#endif
 
24
 
 
25
#include <GL/gl.h>
 
26
#include <GL/glu.h>
 
27
 
 
28
/*
 
29
 * Draw a gear wheel.  You'll probably want to call this function when
 
30
 * building a display list since we do a lot of trig here.
 
31
 *
 
32
 * Input:  inner_radius - radius of hole at center
 
33
 * outer_radius - radius at center of teeth
 
34
 * width - width of gear
 
35
 * teeth - number of teeth
 
36
 * tooth_depth - depth of tooth
 
37
 */
 
38
 
 
39
static void
 
40
gear(GLfloat inner_radius,
 
41
     GLfloat outer_radius,
 
42
     GLfloat width,
 
43
     GLint   teeth,
 
44
     GLfloat tooth_depth)
 
45
{
 
46
  GLint i;
 
47
  GLfloat r0, r1, r2;
 
48
  GLfloat angle, da;
 
49
  GLfloat u, v, len;
 
50
 
 
51
  r0 = inner_radius;
 
52
  r1 = outer_radius - tooth_depth / 2.0;
 
53
  r2 = outer_radius + tooth_depth / 2.0;
 
54
 
 
55
  da = 2.0 * G_PI / teeth / 4.0;
 
56
 
 
57
  glShadeModel(GL_FLAT);
 
58
 
 
59
  glNormal3f(0.0, 0.0, 1.0);
 
60
 
 
61
  /* draw front face */
 
62
  glBegin(GL_QUAD_STRIP);
 
63
  for (i = 0; i <= teeth; i++) {
 
64
    angle = i * 2.0 * G_PI / teeth;
 
65
    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
66
    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
67
    if (i < teeth) {
 
68
      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
69
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
 
70
    }
 
71
  }
 
72
  glEnd();
 
73
 
 
74
  /* draw front sides of teeth */
 
75
  glBegin(GL_QUADS);
 
76
  da = 2.0 * G_PI / teeth / 4.0;
 
77
  for (i = 0; i < teeth; i++) {
 
78
    angle = i * 2.0 * G_PI / teeth;
 
79
 
 
80
    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
81
    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
82
    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
 
83
    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
 
84
  }
 
85
  glEnd();
 
86
 
 
87
  glNormal3f(0.0, 0.0, -1.0);
 
88
 
 
89
  /* draw back face */
 
90
  glBegin(GL_QUAD_STRIP);
 
91
  for (i = 0; i <= teeth; i++) {
 
92
    angle = i * 2.0 * G_PI / teeth;
 
93
    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
94
    glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
95
    if (i < teeth) {
 
96
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
 
97
      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
98
    }
 
99
  }
 
100
  glEnd();
 
101
 
 
102
  /* draw back sides of teeth */
 
103
  glBegin(GL_QUADS);
 
104
  da = 2.0 * G_PI / teeth / 4.0;
 
105
  for (i = 0; i < teeth; i++) {
 
106
    angle = i * 2.0 * G_PI / teeth;
 
107
 
 
108
    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
 
109
    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
 
110
    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
111
    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
112
  }
 
113
  glEnd();
 
114
 
 
115
  /* draw outward faces of teeth */
 
116
  glBegin(GL_QUAD_STRIP);
 
117
  for (i = 0; i < teeth; i++) {
 
118
    angle = i * 2.0 * G_PI / teeth;
 
119
 
 
120
    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
121
    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
122
    u = r2 * cos(angle + da) - r1 * cos(angle);
 
123
    v = r2 * sin(angle + da) - r1 * sin(angle);
 
124
    len = sqrt(u * u + v * v);
 
125
    u /= len;
 
126
    v /= len;
 
127
    glNormal3f(v, -u, 0.0);
 
128
    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
129
    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
130
    glNormal3f(cos(angle), sin(angle), 0.0);
 
131
    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
 
132
    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
 
133
    u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
 
134
    v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
 
135
    glNormal3f(v, -u, 0.0);
 
136
    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
 
137
    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
 
138
    glNormal3f(cos(angle), sin(angle), 0.0);
 
139
  }
 
140
 
 
141
  glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
 
142
  glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
 
143
 
 
144
  glEnd();
 
145
 
 
146
  glShadeModel(GL_SMOOTH);
 
147
 
 
148
  /* draw inside radius cylinder */
 
149
  glBegin(GL_QUAD_STRIP);
 
150
  for (i = 0; i <= teeth; i++) {
 
151
    angle = i * 2.0 * G_PI / teeth;
 
152
    glNormal3f(-cos(angle), -sin(angle), 0.0);
 
153
    glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
154
    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
155
  }
 
156
  glEnd();
 
157
 
 
158
}
 
159
 
 
160
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
 
161
static GLint gear1, gear2, gear3;
 
162
static GLfloat angle = 0.0;
 
163
 
 
164
static GTimer *timer = NULL;
 
165
static gint frames = 0;
 
166
 
 
167
static gboolean is_sync = TRUE;
 
168
 
 
169
static gboolean
 
170
draw (GtkWidget      *widget,
 
171
      GdkEventExpose *event,
 
172
      gpointer        data)
 
173
{
 
174
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
 
175
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
 
176
 
 
177
  /*** OpenGL BEGIN ***/
 
178
  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
 
179
    return FALSE;
 
180
 
 
181
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
182
 
 
183
  glPushMatrix ();
 
184
    glRotatef (view_rotx, 1.0, 0.0, 0.0);
 
185
    glRotatef (view_roty, 0.0, 1.0, 0.0);
 
186
    glRotatef (view_rotz, 0.0, 0.0, 1.0);
 
187
 
 
188
    glPushMatrix ();
 
189
      glTranslatef (-3.0, -2.0, 0.0);
 
190
      glRotatef (angle, 0.0, 0.0, 1.0);
 
191
      glCallList (gear1);
 
192
    glPopMatrix ();
 
193
 
 
194
    glPushMatrix ();
 
195
      glTranslatef (3.1, -2.0, 0.0);
 
196
      glRotatef (-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
 
197
      glCallList (gear2);
 
198
    glPopMatrix ();
 
199
 
 
200
    glPushMatrix ();
 
201
      glTranslatef (-3.1, 4.2, 0.0);
 
202
      glRotatef (-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
 
203
      glCallList (gear3);
 
204
    glPopMatrix ();
 
205
 
 
206
  glPopMatrix ();
 
207
 
 
208
  if (gdk_gl_drawable_is_double_buffered (gldrawable))
 
209
    gdk_gl_drawable_swap_buffers (gldrawable);
 
210
  else
 
211
    glFlush ();
 
212
 
 
213
  gdk_gl_drawable_gl_end (gldrawable);
 
214
  /*** OpenGL END ***/
 
215
 
 
216
  frames++;
 
217
 
 
218
  {
 
219
    gdouble seconds = g_timer_elapsed (timer, NULL);
 
220
    if (seconds >= 5.0) {
 
221
      gdouble fps = frames / seconds;
 
222
      g_print ("%d frames in %6.3f seconds = %6.3f FPS\n", frames, seconds, fps);
 
223
      g_timer_reset (timer);
 
224
      frames = 0;
 
225
    }
 
226
  }
 
227
 
 
228
  return TRUE;
 
229
}
 
230
 
 
231
/* new window size or exposure */
 
232
static gboolean
 
233
reshape (GtkWidget         *widget,
 
234
         GdkEventConfigure *event,
 
235
         gpointer           data)
 
236
{
 
237
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
 
238
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
 
239
 
 
240
  GLfloat h = (GLfloat) (widget->allocation.height) / (GLfloat) (widget->allocation.width);
 
241
 
 
242
  /*** OpenGL BEGIN ***/
 
243
  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
 
244
    return FALSE;
 
245
 
 
246
  glViewport (0, 0, widget->allocation.width, widget->allocation.height);
 
247
  glMatrixMode (GL_PROJECTION);
 
248
  glLoadIdentity ();
 
249
  glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
 
250
  glMatrixMode (GL_MODELVIEW);
 
251
  glLoadIdentity ();
 
252
  glTranslatef (0.0, 0.0, -40.0);
 
253
 
 
254
  gdk_gl_drawable_gl_end (gldrawable);
 
255
  /*** OpenGL END ***/
 
256
 
 
257
  return TRUE;
 
258
}
 
259
 
 
260
static void
 
261
init(GtkWidget *widget,
 
262
     gpointer   data)
 
263
{
 
264
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
 
265
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
 
266
 
 
267
  static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
 
268
  static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
 
269
  static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
 
270
  static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
 
271
 
 
272
  /*** OpenGL BEGIN ***/
 
273
  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
 
274
    return;
 
275
 
 
276
  glLightfv (GL_LIGHT0, GL_POSITION, pos);
 
277
  glEnable (GL_CULL_FACE);
 
278
  glEnable (GL_LIGHTING);
 
279
  glEnable (GL_LIGHT0);
 
280
  glEnable (GL_DEPTH_TEST);
 
281
 
 
282
  /* make the gears */
 
283
  gear1 = glGenLists (1);
 
284
  glNewList (gear1, GL_COMPILE);
 
285
    glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
 
286
    gear (1.0, 4.0, 1.0, 20, 0.7);
 
287
  glEndList ();
 
288
 
 
289
  gear2 = glGenLists (1);
 
290
  glNewList (gear2, GL_COMPILE);
 
291
    glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
 
292
    gear (0.5, 2.0, 2.0, 10, 0.7);
 
293
  glEndList ();
 
294
 
 
295
  gear3 = glGenLists (1);
 
296
  glNewList (gear3, GL_COMPILE);
 
297
    glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
 
298
    gear (1.3, 2.0, 0.5, 10, 0.7);
 
299
  glEndList ();
 
300
 
 
301
  glEnable (GL_NORMALIZE);
 
302
 
 
303
  g_print ("\n");
 
304
  g_print ("GL_RENDERER   = %s\n", (char *) glGetString (GL_RENDERER));
 
305
  g_print ("GL_VERSION    = %s\n", (char *) glGetString (GL_VERSION));
 
306
  g_print ("GL_VENDOR     = %s\n", (char *) glGetString (GL_VENDOR));
 
307
  g_print ("GL_EXTENSIONS = %s\n", (char *) glGetString (GL_EXTENSIONS));
 
308
  g_print ("\n");
 
309
 
 
310
  gdk_gl_drawable_gl_end (gldrawable);
 
311
  /*** OpenGL END ***/
 
312
 
 
313
  /* create timer */
 
314
  if (timer == NULL)
 
315
    timer = g_timer_new ();
 
316
 
 
317
  g_timer_start (timer);
 
318
}
 
319
 
 
320
static gboolean
 
321
idle (GtkWidget *widget)
 
322
{
 
323
  angle += 2.0;
 
324
 
 
325
  /* Invalidate the whole window. */
 
326
  gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
 
327
 
 
328
  /* Update synchronously (fast). */
 
329
  if (is_sync)
 
330
    gdk_window_process_updates (widget->window, FALSE);
 
331
 
 
332
  return TRUE;
 
333
}
 
334
 
 
335
static guint idle_id = 0;
 
336
 
 
337
static void
 
338
idle_add (GtkWidget *widget)
 
339
{
 
340
  if (idle_id == 0)
 
341
    {
 
342
      idle_id = g_idle_add_full (GDK_PRIORITY_REDRAW,
 
343
                                 (GSourceFunc) idle,
 
344
                                 widget,
 
345
                                 NULL);
 
346
    }
 
347
}
 
348
 
 
349
static void
 
350
idle_remove (GtkWidget *widget)
 
351
{
 
352
  if (idle_id != 0)
 
353
    {
 
354
      g_source_remove (idle_id);
 
355
      idle_id = 0;
 
356
    }
 
357
}
 
358
 
 
359
static gboolean
 
360
map (GtkWidget   *widget,
 
361
     GdkEventAny *event,
 
362
     gpointer     data)
 
363
{
 
364
  idle_add (widget);
 
365
 
 
366
  return TRUE;
 
367
}
 
368
 
 
369
static gboolean
 
370
unmap (GtkWidget   *widget,
 
371
       GdkEventAny *event,
 
372
       gpointer     data)
 
373
{
 
374
  idle_remove (widget);
 
375
 
 
376
  return TRUE;
 
377
}
 
378
 
 
379
static gboolean
 
380
visible (GtkWidget          *widget,
 
381
         GdkEventVisibility *event,
 
382
         gpointer            data)
 
383
{
 
384
  if (event->state == GDK_VISIBILITY_FULLY_OBSCURED)
 
385
    idle_remove (widget);
 
386
  else
 
387
    idle_add (widget);
 
388
 
 
389
  return TRUE;
 
390
}
 
391
 
 
392
/* change view angle, exit upon ESC */
 
393
static gboolean
 
394
key (GtkWidget   *widget,
 
395
     GdkEventKey *event,
 
396
     gpointer     data)
 
397
{
 
398
  switch (event->keyval)
 
399
    {
 
400
    case GDK_z:
 
401
      view_rotz += 5.0;
 
402
      break;
 
403
    case GDK_Z:
 
404
      view_rotz -= 5.0;
 
405
      break;
 
406
    case GDK_Up:
 
407
      view_rotx += 5.0;
 
408
      break;
 
409
    case GDK_Down:
 
410
      view_rotx -= 5.0;
 
411
      break;
 
412
    case GDK_Left:
 
413
      view_roty += 5.0;
 
414
      break;
 
415
    case GDK_Right:
 
416
      view_roty -= 5.0;
 
417
      break;
 
418
    case GDK_Escape:
 
419
      gtk_main_quit ();
 
420
      break;
 
421
    default:
 
422
      return FALSE;
 
423
    }
 
424
 
 
425
  gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
 
426
 
 
427
  return TRUE;
 
428
}
 
429
 
 
430
int
 
431
main (int   argc,
 
432
      char *argv[])
 
433
{
 
434
  GdkGLConfig *glconfig;
 
435
  GtkWidget *window;
 
436
  GtkWidget *vbox;
 
437
  GtkWidget *drawing_area;
 
438
  GtkWidget *button;
 
439
  int i;
 
440
 
 
441
  /*
 
442
   * Init GTK.
 
443
   */
 
444
 
 
445
  gtk_init (&argc, &argv);
 
446
 
 
447
  /*
 
448
   * Init GtkGLExt.
 
449
   */
 
450
 
 
451
  gtk_gl_init (&argc, &argv);
 
452
 
 
453
  /*
 
454
   * Command line options.
 
455
   */
 
456
 
 
457
  for (i = 0; i < argc; i++)
 
458
    {
 
459
      if (strcmp (argv[i], "--async") == 0)
 
460
        is_sync = FALSE;
 
461
    }
 
462
 
 
463
  /*
 
464
   * Configure OpenGL-capable visual.
 
465
   */
 
466
 
 
467
  /* Try double-buffered visual */
 
468
  glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB    |
 
469
                                        GDK_GL_MODE_DEPTH  |
 
470
                                        GDK_GL_MODE_DOUBLE);
 
471
  if (glconfig == NULL)
 
472
    {
 
473
      g_print ("*** Cannot find the double-buffered visual.\n");
 
474
      g_print ("*** Trying single-buffered visual.\n");
 
475
 
 
476
      /* Try single-buffered visual */
 
477
      glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB   |
 
478
                                            GDK_GL_MODE_DEPTH);
 
479
      if (glconfig == NULL)
 
480
        {
 
481
          g_print ("*** No appropriate OpenGL-capable visual found.\n");
 
482
          exit (1);
 
483
        }
 
484
    }
 
485
 
 
486
  /*
 
487
   * Top-level window.
 
488
   */
 
489
 
 
490
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
491
  gtk_window_set_title (GTK_WINDOW (window), "gears");
 
492
 
 
493
  /* Get automatically redrawn if any of their children changed allocation. */
 
494
  gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);
 
495
 
 
496
  g_signal_connect (G_OBJECT (window), "delete_event",
 
497
                    G_CALLBACK (gtk_main_quit), NULL);
 
498
 
 
499
  /*
 
500
   * VBox.
 
501
   */
 
502
 
 
503
  vbox = gtk_vbox_new (FALSE, 0);
 
504
  gtk_container_add (GTK_CONTAINER (window), vbox);
 
505
  gtk_widget_show (vbox);
 
506
 
 
507
  /*
 
508
   * Drawing area for drawing OpenGL scene.
 
509
   */
 
510
 
 
511
  drawing_area = gtk_drawing_area_new ();
 
512
  gtk_widget_set_size_request (drawing_area, 300, 300);
 
513
 
 
514
  /* Set OpenGL-capability to the widget. */
 
515
  gtk_widget_set_gl_capability (drawing_area,
 
516
                                glconfig,
 
517
                                NULL,
 
518
                                TRUE,
 
519
                                GDK_GL_RGBA_TYPE);
 
520
 
 
521
  gtk_widget_add_events (drawing_area,
 
522
                         GDK_VISIBILITY_NOTIFY_MASK);
 
523
 
 
524
  g_signal_connect_after (G_OBJECT (drawing_area), "realize",
 
525
                          G_CALLBACK (init), NULL);
 
526
  g_signal_connect (G_OBJECT (drawing_area), "configure_event",
 
527
                    G_CALLBACK (reshape), NULL);
 
528
  g_signal_connect (G_OBJECT (drawing_area), "expose_event",
 
529
                    G_CALLBACK (draw), NULL);
 
530
  g_signal_connect (G_OBJECT (drawing_area), "map_event",
 
531
                    G_CALLBACK (map), NULL);
 
532
  g_signal_connect (G_OBJECT (drawing_area), "unmap_event",
 
533
                    G_CALLBACK (unmap), NULL);
 
534
  g_signal_connect (G_OBJECT (drawing_area), "visibility_notify_event",
 
535
                    G_CALLBACK (visible), NULL);
 
536
 
 
537
  g_signal_connect_swapped (G_OBJECT (window), "key_press_event",
 
538
                            G_CALLBACK (key), drawing_area);
 
539
 
 
540
  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
 
541
 
 
542
  gtk_widget_show (drawing_area);
 
543
 
 
544
  /*
 
545
   * Simple quit button.
 
546
   */
 
547
 
 
548
  button = gtk_button_new_with_label ("Quit");
 
549
 
 
550
  g_signal_connect (G_OBJECT (button), "clicked",
 
551
                    G_CALLBACK (gtk_main_quit), NULL);
 
552
 
 
553
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
 
554
 
 
555
  gtk_widget_show (button);
 
556
 
 
557
  /*
 
558
   * Show window.
 
559
   */
 
560
 
 
561
  gtk_widget_show (window);
 
562
 
 
563
  /*
 
564
   * Main loop.
 
565
   */
 
566
 
 
567
  gtk_main ();
 
568
 
 
569
  return 0;
 
570
}