1 /* testgdk -- validation program for GDK
2 * Copyright (C) 2000 Tor Lillqvist
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 /* This program is intended to be used to validate the correctness of
21 * the basic graphics operations in a GDK backend. The results of the
22 * operations are compared against those produced by a correctly
23 * functioning X11 backend (and X11 server).
25 * Obviously, only the most basic operations reasonably be expected to
26 * produce pixel-by-pixel identical results as the X11 backend. We
27 * don't even try to test the correctness of ellipses, tiles or
28 * stipples. Not to mention fonts.
30 * But, for those operations we do test, we should try to test quite
31 * many combinations of parameters.
33 * This is just a quick hack, and could be improved a lot. There are
34 * copy-pasted code snippets all over that need to be factored out
35 * into separate functions.
45 /* CQTESTF -- "Conditionally Quiet TEST with Fail message"
46 * macro that prints PASS or FAIL messages
47 * parms: quiet: if TRUE, only print FAIL messages
48 * expr: the expression to test
49 * failfmt:if expr is FALSE, print this message
50 * (both format and args)
53 #define CQTESTF(quiet, expr, failfmt) \
55 (tmpb ? (quiet ? 0 : printf ("PASS: %d %s\n", __LINE__, #expr)) \
56 : (printf ("FAIL: %d %s", __LINE__, #expr), \
64 /* Variations with less parms */
66 #define CQTEST(quiet, expr) \
67 CQTESTF (quiet, expr, (""))
75 #define TESTF(expr, failfmt) \
76 CQTESTF (FALSE, expr, failfmt)
78 #define QTESTF(expr, failfmt) \
79 CQTESTF (TRUE, expr, failfmt)
81 #define ASSERT(expr) \
84 printf ("That is fatal. Goodbye\n"), exit (1);\
87 #define N(a) (sizeof(a)/sizeof(*a))
89 static int return_value = 0;
91 static gboolean retval;
94 static GdkVisual *system_visual;
95 static GdkVisual *best_visual;
98 static GdkColormap *system_colourmap;
100 static GdkColor white, black, red, green, blue, rand1_colour, rand2_colour;
102 static GdkGC *black_gc, *white_gc, *red_gc, *rand1_gc, *rand2_gc;
103 static GdkGC *gcs[5];
104 static GdkGC *black_bitmap_gc;
109 /* Place breakpoint here to catch failures */
114 test_visual_coherency (gboolean quiet,
117 gboolean retval = TRUE;
119 CQTEST (quiet, visual->type >= GDK_VISUAL_STATIC_GRAY &&
120 visual->type <= GDK_VISUAL_DIRECT_COLOR);
121 CQTEST (quiet, visual->depth >= 1 && visual->depth <= 32);
122 CQTEST (quiet, visual->byte_order == GDK_LSB_FIRST || visual->byte_order ==
136 system_visual = gdk_visual_get_system ();
137 ASSERT (system_visual != NULL);
138 TEST (test_visual_coherency (FALSE, system_visual));
140 best_visual = gdk_visual_get_best ();
141 if (best_visual != system_visual)
142 TEST (test_visual_coherency (TRUE, best_visual));
144 visuals = gdk_list_visuals ();
147 visual = visuals->data;
148 TEST (test_visual_coherency (TRUE, visual));
149 visuals = visuals->next;
153 /* Create a top-level window used by other tests
156 test_first_window (void)
162 wa.window_type = GDK_WINDOW_TOPLEVEL;
163 wa.wclass = GDK_INPUT_OUTPUT;
165 w = gdk_window_new (NULL, &wa, 0);
173 test_colourmaps (void)
175 system_colourmap = gdk_colormap_get_system ();
176 ASSERT (system_colourmap != NULL);
184 ASSERT (gdk_color_white (system_colourmap, &white));
185 ASSERT (gdk_color_black (system_colourmap, &black));
187 red.green = red.blue = 0;
188 TEST (gdk_colormap_alloc_color (system_colourmap, &red, FALSE, TRUE));
190 rand1_colour.red = rand () % 65536;
191 rand1_colour.green = rand () % 65536;
192 rand1_colour.blue = rand () % 65536;
193 TEST (gdk_colormap_alloc_color (system_colourmap, &rand1_colour, FALSE,
196 rand2_colour.red = rand () % 65536;
197 rand2_colour.green = rand () % 65536;
198 rand2_colour.blue = rand () % 65536;
199 TEST (gdk_colormap_alloc_color (system_colourmap, &rand2_colour, FALSE,
204 test_default_gc (GdkGCValues *gcvalues,
207 gboolean retval = TRUE;
209 CQTEST (quiet, gcvalues->foreground.pixel == 0);
210 CQTEST (quiet, gcvalues->background.pixel == 1);
211 CQTEST (quiet, gcvalues->function == GDK_COPY);
212 CQTEST (quiet, gcvalues->fill == GDK_SOLID);
213 CQTEST (quiet, gcvalues->tile == NULL);
214 CQTEST (quiet, gcvalues->stipple == NULL);
215 CQTEST (quiet, gcvalues->clip_mask == NULL);
216 CQTEST (quiet, gcvalues->subwindow_mode == GDK_CLIP_BY_CHILDREN);
217 CQTEST (quiet, gcvalues->line_width == 0);
218 CQTEST (quiet, gcvalues->line_style == GDK_LINE_SOLID);
219 CQTEST (quiet, gcvalues->cap_style == GDK_CAP_BUTT);
220 CQTEST (quiet, gcvalues->join_style == GDK_JOIN_MITER);
225 /* Create GdkGCs with various values,
226 * check that gdk_gc_get_values returns the same,
227 * or something reasonably close.
234 GdkGCValues gcvalues;
236 GdkFunction function;
241 gdk_gc_get_values (gc, &gcvalues);
242 test_default_gc (&gcvalues, FALSE);
245 gdk_gc_set_foreground (gc, &colour);
246 gdk_gc_get_values (gc, &gcvalues);
247 TEST (gcvalues.foreground.pixel == 1234);
250 gdk_gc_set_foreground (gc, &colour);
251 gdk_gc_get_values (gc, &gcvalues);
252 TEST (test_default_gc (&gcvalues, TRUE));
255 gdk_gc_set_background (gc, &colour);
256 gdk_gc_get_values (gc, &gcvalues);
257 TEST (gcvalues.background.pixel == 5678);
260 gdk_gc_set_background (gc, &colour);
261 gdk_gc_get_values (gc, &gcvalues);
262 TEST (test_default_gc (&gcvalues, TRUE));
265 for (function = GDK_COPY; function <= GDK_SET; function++)
267 gdk_gc_set_function (gc, function);
268 gdk_gc_get_values (gc, &gcvalues);
269 QTEST (gcvalues.function == function);
270 gdk_gc_set_function (gc, GDK_COPY);
271 gdk_gc_get_values (gc, &gcvalues);
272 QTEST (test_default_gc (&gcvalues, TRUE));
277 for (fill = GDK_SOLID; fill <= GDK_OPAQUE_STIPPLED; fill++)
279 gdk_gc_set_fill (gc, fill);
280 gdk_gc_get_values (gc, &gcvalues);
281 QTEST (gcvalues.fill == fill);
282 gdk_gc_set_fill (gc, GDK_SOLID);
283 gdk_gc_get_values (gc, &gcvalues);
284 QTEST (test_default_gc (&gcvalues, TRUE));
288 black_gc = gdk_gc_new (w);
289 gdk_gc_copy (black_gc, gc);
290 gdk_gc_get_values (black_gc, &gcvalues);
291 TEST (test_default_gc (&gcvalues, TRUE));
294 gdk_gc_set_foreground (black_gc, &black);
295 gdk_gc_get_values (black_gc, &gcvalues);
296 TEST (gcvalues.foreground.pixel == black.pixel);
298 white_gc = gdk_gc_new (w);
300 gdk_gc_set_foreground (white_gc, &white);
301 gdk_gc_get_values (white_gc, &gcvalues);
302 TEST (gcvalues.foreground.pixel == white.pixel);
304 red_gc = gdk_gc_new (w);
305 gdk_gc_set_foreground (red_gc, &red);
306 gdk_gc_get_values (red_gc, &gcvalues);
307 TEST (gcvalues.foreground.pixel == red.pixel);
309 rand1_gc = gdk_gc_new (w);
310 gdk_gc_set_foreground (rand1_gc, &rand1_colour);
311 gdk_gc_get_values (rand1_gc, &gcvalues);
312 TESTF (gcvalues.foreground.pixel == rand1_colour.pixel,
313 (" %#06x != %#06x", gcvalues.foreground.pixel, rand1_colour.pixel));
315 rand2_gc = gdk_gc_new (w);
316 gdk_gc_set_foreground (rand2_gc, &rand2_colour);
317 gdk_gc_get_values (rand2_gc, &gcvalues);
318 TESTF (gcvalues.foreground.pixel == rand2_colour.pixel,
319 (" %#06x != %#06x", gcvalues.foreground.pixel, rand2_colour.pixel));
327 pixmap = gdk_pixmap_new (NULL, 1, 1, 1);
328 black_bitmap_gc = gdk_gc_new (pixmap);
329 gdk_pixmap_unref (pixmap);
332 /* Create pixmaps, check that properties are as expected.
333 * No graphic operations tested yet.
336 test_pixmaps (gint depth)
343 gboolean retval = TRUE;
345 for (width = 1; width <= 64; width += 2)
346 for (height = 1; height <= 32; height += 3)
348 pixmap = gdk_pixmap_new (NULL, width, height, depth);
349 ASSERT (pixmap != NULL);
350 gdk_window_get_size (pixmap, &w, &h);
351 QTESTF (w == width, (" w:%d", w));
352 QTESTF (h == height, (" h:%d", h));
353 image = gdk_image_get (pixmap, 0, 0, w, h);
354 QTEST (image != NULL);
355 QTEST (image->width == width);
356 QTEST (image->height == height);
357 QTEST (image->depth == depth);
358 gdk_image_destroy (image);
359 gdk_pixmap_unref (pixmap);
370 GdkImageType image_type;
372 gboolean retval = TRUE;
374 for (width = 1; width <= 64; width += 3)
375 for (height = 1; height <= 32; height += 7)
376 for (image_type = GDK_IMAGE_NORMAL;
377 image_type <= GDK_IMAGE_FASTEST;
380 image = gdk_image_new (image_type, system_visual, width, height);
381 if (image == NULL && image_type == GDK_IMAGE_SHARED)
382 /* Ignore failure to create shared image,
383 * display might not be local.
388 ASSERT (image != NULL);
389 QTEST (image->width == width);
390 QTEST (image->height == height);
391 QTEST (image->depth == system_visual->depth);
392 QTEST (image->bpp >= (image->depth-1)/8 + 1);
393 QTEST (image->mem != NULL);
394 gdk_image_destroy (image);
400 /* Test creating temp windows.
403 test_temp_windows (void)
410 gboolean retval = TRUE;
412 wa.window_type = GDK_WINDOW_TEMP;
413 wa.wclass = GDK_INPUT_OUTPUT;
415 for (width = 1; width <= 64; width += 4)
416 for (height = 1; height <= 32; height += 7)
420 window = gdk_window_new (NULL, &wa, 0);
421 ASSERT (window != NULL);
422 gdk_window_get_geometry (window, &x, &y, &w, &h, &d);
423 QTESTF (w == width, ("w:%d", w));
424 QTESTF (h == height, ("h:%d", h));
425 gdk_window_show (window);
426 gdk_window_get_geometry (window, &x, &y, &w, &h, &d);
427 QTESTF (w == width, ("w:%d", w));
428 QTESTF (h == height, ("h:%d", h));
429 gdk_window_resize (window, 37, 19);
430 gdk_window_get_geometry (window, &x, &y, &w, &h, &d);
431 QTESTF (w == 37, ("w:%d", w));
432 QTESTF (h == 19, ("h:%d", h));
433 visual = gdk_window_get_visual (window);
434 QTEST (visual == system_visual);
435 gdk_window_hide (window);
436 gdk_window_unref (window);
442 test_gc_function (GdkFunction function,
451 QTEST (newpixel == (foreground & mask)); break;
453 QTEST (newpixel == ((~oldpixel) & mask)); break;
455 QTEST (newpixel == ((oldpixel ^ foreground) & mask)); break;
457 QTEST (newpixel == 0); break;
459 QTEST (newpixel == ((oldpixel & foreground) & mask)); break;
460 case GDK_AND_REVERSE:
461 QTEST (newpixel == (((~oldpixel) & foreground) & mask)); break;
463 QTEST (newpixel == ((oldpixel & (~foreground)) & mask)); break;
465 QTEST (newpixel == (oldpixel & mask)); break;
467 QTEST (newpixel == ((oldpixel | foreground) & mask)); break;
469 QTEST (newpixel == ((oldpixel ^ (~foreground)) & mask)); break;
471 QTEST (newpixel == (((~oldpixel) | foreground) & mask)); break;
472 case GDK_COPY_INVERT:
473 QTEST (newpixel == ((~foreground) & mask)); break;
475 QTEST (newpixel == ((oldpixel | (~foreground)) & mask)); break;
477 QTEST (newpixel == (((~oldpixel) | (~foreground)) & mask)); break;
479 QTEST (newpixel == ((~0) & mask)); break;
486 test_one_point_on_drawable (GdkDrawable *drawable,
491 GdkGCValues gcvalues;
493 guint32 oldpixels[3][3], newpixel, mask;
497 gdk_gc_get_values (gc, &gcvalues);
499 image = gdk_image_get (drawable, x+-1, y+-1, 3, 3);
500 QTEST (image != NULL);
501 for (xoff = -1; xoff <= 1; xoff++)
502 for (yoff = -1; yoff <= 1; yoff++)
504 oldpixels[xoff+1][yoff+1] = gdk_image_get_pixel (image, xoff+1, yoff+1);
506 gdk_image_destroy (image);
511 mask = (1 << depth) - 1;
513 gdk_draw_point (drawable, gc, x, y);
515 image = gdk_image_get (drawable, x-1, y-1, 3, 3);
516 QTEST (image != NULL);
517 for (xoff = -1; xoff <= 1; xoff++)
518 for (yoff = -1; yoff <= 1; yoff++)
520 newpixel = gdk_image_get_pixel (image, xoff+1, yoff+1);
521 if (xoff == 0 && yoff == 0)
522 test_gc_function (gcvalues.function, oldpixels[1][1], newpixel,
523 gcvalues.foreground.pixel, mask);
525 QTEST (newpixel == oldpixels[xoff+1][yoff+1]);
527 gdk_image_destroy (image);
531 /* Test drawing points.
538 GdkFunction function;
544 pixmap = gdk_pixmap_new (w, width, height, -1);
546 for (i = 0; i < N(gcs); i++)
547 for (j = 0; j < N(gcs); j++)
548 for (function = GDK_COPY; function <= GDK_SET; function++)
550 gdk_draw_rectangle (pixmap, gcs[i], TRUE, 0, 0, width, height);
551 gdk_gc_set_function (gcs[j], function);
552 test_one_point_on_drawable (pixmap, gcs[j], system_visual->depth);
553 gdk_gc_set_function (gcs[j], GDK_COPY);
556 gdk_pixmap_unref (pixmap);
558 pixmap = gdk_pixmap_new (w, width, height, 1);
559 test_one_point_on_drawable (pixmap, black_bitmap_gc, 1);
560 for (function = GDK_COPY; function <= GDK_SET; function++)
562 gdk_gc_set_function (black_bitmap_gc, function);
563 test_one_point_on_drawable (pixmap, black_bitmap_gc, 1);
566 gdk_pixmap_unref (pixmap);
570 test_one_line_on_drawable (GdkDrawable *drawable,
575 GdkImage *oldimage, *newimage;
576 GdkGCValues gcvalues;
579 gint w_up, w_down, w_left, w_right;
581 guint32 oldpixel, newpixel, mask;
583 gdk_gc_get_values (gc, &gcvalues);
584 line_width = gcvalues.line_width > 0 ? gcvalues.line_width : 1;
585 w_up = w_left = line_width/2;
586 w_down = w_right = (line_width & 1) ? line_width/2 : line_width/2-1;
587 gdk_window_get_size (drawable, &w, &h);
588 oldimage = gdk_image_get (drawable, 0, 0, w, h);
593 mask = (1 << depth) - 1;
602 gdk_draw_line (drawable, gc, x1, y1, x2, y2);
603 newimage = gdk_image_get (drawable, 0, 0, w, h);
604 for (x = x1-1; x <= x2+1; x++)
605 for (y = y1-w_up-1; y <= y1+w_down+1; y++)
607 oldpixel = gdk_image_get_pixel (oldimage, x, y);
608 newpixel = gdk_image_get_pixel (newimage, x, y);
609 if (x >= x1 && x < x2 && y >= y1-w_up && y <= y1+w_down)
610 test_gc_function (gcvalues.function, oldpixel, newpixel,
611 gcvalues.foreground.pixel, mask);
613 QTEST (oldpixel == newpixel);
623 gdk_draw_line (drawable, gc, x1, y1, x2, y2);
624 newimage = gdk_image_get (drawable, 0, 0, w, h);
625 for (x = x1-w_left-1; x <= x1+w_right+1; x++)
626 for (y = y1-1; y <= y2+1; y++)
628 oldpixel = gdk_image_get_pixel (oldimage, x, y);
629 newpixel = gdk_image_get_pixel (newimage, x, y);
630 if (x >= x1-w_left && x <= x1+w_right && y >= y1 && y < y2)
631 test_gc_function (gcvalues.function, oldpixel, newpixel,
632 gcvalues.foreground.pixel, mask);
634 QTEST (oldpixel == newpixel);
638 gdk_image_destroy (oldimage);
639 gdk_image_destroy (newimage);
642 /* Test drawing lines.
648 GdkFunction function;
651 gboolean horisontal = TRUE;
653 pixmap = gdk_pixmap_new (w, 30, 30, -1);
655 for (i = 0; i < N(gcs); i++)
656 for (j = 0; j < N(gcs); j++)
657 for (function = GDK_COPY; function <= GDK_SET; function++)
658 for (width = 1; width <= 4; width++)
660 gdk_draw_rectangle (pixmap, gcs[i], TRUE, 0, 0, 30, 30);
661 gdk_gc_set_function (gcs[j], function);
662 gdk_gc_set_line_attributes (gcs[j], width,
663 GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
664 test_one_line_on_drawable (pixmap, gcs[j], system_visual->depth,
666 /* Toggle between horisontal and vertical... */
667 horisontal = !horisontal;
668 gdk_gc_set_function (gcs[j], GDK_COPY);
671 gdk_pixmap_unref (pixmap);
675 test_one_rectangle_on_drawable (GdkDrawable *drawable,
680 GdkImage *oldimage, *newimage;
681 GdkGCValues gcvalues;
684 gint w_up, w_down, w_left, w_right;
686 guint32 oldpixel, newpixel, mask;
689 const gint width = 7;
690 const gint height = 9;
692 gdk_gc_get_values (gc, &gcvalues);
696 line_width = gcvalues.line_width > 0 ? gcvalues.line_width : 1;
697 w_up = w_left = line_width/2;
698 w_down = w_right = (line_width & 1) ? line_width/2 : line_width/2-1;
701 gdk_window_get_size (drawable, &w, &h);
702 oldimage = gdk_image_get (drawable, 0, 0, w, h);
707 mask = (1 << depth) - 1;
709 gdk_draw_rectangle (drawable, gc, filled, x0, y0, width, height);
710 newimage = gdk_image_get (drawable, 0, 0, w, h);
712 for (x = x0 - 1; x <= x0 + width + 1; x++)
713 for (y = y0 - 1; y < y0 + height + 1; y++)
715 oldpixel = gdk_image_get_pixel (oldimage, x, y);
716 newpixel = gdk_image_get_pixel (newimage, x, y);
720 if (x >= x0 && x < x0+width &&
721 y >= y0 && y < y0+height)
722 test_gc_function (gcvalues.function, oldpixel, newpixel,
723 gcvalues.foreground.pixel, mask);
725 QTEST (oldpixel == newpixel);
729 if ((x >= x0-w_left && x <= x0+width+w_right &&
730 y >= y0-w_up && y <= y0+w_down) ||
731 (x >= x0-w_left && x <= x0+width+w_right &&
732 y >= y0+height-w_up && y <= y0+height+w_down) ||
733 (x >= x0-w_left && x <= x0+w_right &&
734 y >= y0-w_up && y <= y0+height+w_down) ||
735 (x >= x0+width-w_left && x <= x0+width+w_right &&
736 y >= y0-w_up && y <= y0+height+w_down))
737 test_gc_function (gcvalues.function, oldpixel, newpixel,
738 gcvalues.foreground.pixel, mask);
740 QTEST (oldpixel == newpixel);
744 gdk_image_destroy (oldimage);
745 gdk_image_destroy (newimage);
748 /* Test drawing rectangles.
751 test_rectangles (void)
754 GdkFunction function;
757 gboolean filled = FALSE;
759 pixmap = gdk_pixmap_new (w, 30, 30, -1);
761 for (i = 0; i < N(gcs); i++)
762 for (j = 0; j < N(gcs); j++)
763 for (function = GDK_COPY; function <= GDK_SET; function++)
764 for (width = 1; width <= 4; width++)
766 gdk_draw_rectangle (pixmap, gcs[i], TRUE, 0, 0, 30, 30);
767 gdk_gc_set_function (gcs[j], function);
768 gdk_gc_set_line_attributes (gcs[j], width,
769 GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
770 test_one_rectangle_on_drawable (pixmap, gcs[j],
771 system_visual->depth, filled);
773 gdk_gc_set_function (gcs[j], GDK_COPY);
776 gdk_pixmap_unref (pixmap);
780 test_some_arcs_on_drawable (GdkDrawable *drawable,
785 GdkImage *oldimage, *newimage;
786 GdkGCValues gcvalues;
789 gint w_up, w_down, w_left, w_right;
791 guint32 oldpixel, newpixel, mask;
795 const gint width = 7;
796 const gint height = 9;
798 gdk_gc_get_values (gc, &gcvalues);
802 line_width = gcvalues.line_width > 0 ? gcvalues.line_width : 1;
803 w_up = w_left = line_width/2;
804 w_down = w_right = (line_width & 1) ? line_width/2 : line_width/2-1;
807 gdk_window_get_size (drawable, &w, &h);
808 oldimage = gdk_image_get (drawable, 0, 0, w, h);
813 mask = (1 << depth) - 1;
816 newimage = gdk_image_get (drawable, 0, 0, w, h);
818 for (x = x0 - 1; x <= x0 + width + 1; x++)
819 for (y = y0 - 1; y < y0 + height + 1; y++)
821 oldpixel = gdk_image_get_pixel (oldimage, x, y);
822 newpixel = gdk_image_get_pixel (newimage, x, y);
834 gdk_image_destroy (oldimage);
835 gdk_image_destroy (newimage);
838 /* Test drawing arcs. Results don't have to be exactly as on X11,
845 GdkFunction function;
848 gboolean filled = FALSE;
850 pixmap = gdk_pixmap_new (w, 30, 30, -1);
852 for (i = 0; i < N(gcs); i++)
853 for (j = 0; j < N(gcs); j++)
854 for (function = GDK_COPY; function <= GDK_SET; function++)
855 for (width = 1; width <= 4; width++)
857 gdk_draw_rectangle (pixmap, gcs[i], TRUE, 0, 0, 30, 30);
858 gdk_gc_set_function (gcs[j], function);
859 gdk_gc_set_line_attributes (gcs[j], width,
860 GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
861 test_some_arcs_on_drawable (pixmap, gcs[j], system_visual->depth,
864 gdk_gc_set_function (gcs[j], GDK_COPY);
867 gdk_pixmap_unref (pixmap);
870 /* Test region operations.
883 test_first_window ();
888 test_pixmaps (system_visual->depth);
889 if (best_visual->depth != system_visual->depth)
890 test_pixmaps (best_visual->depth);
892 test_temp_windows ();
901 main (int argc, char **argv)
903 gdk_init (&argc, &argv);