testgdk.c

Go to the documentation of this file.
00001 /* testgdk -- validation program for GDK
00002  * Copyright (C) 2000 Tor Lillqvist
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /* This program is intended to be used to validate the correctness of
00021  * the basic graphics operations in a GDK backend. The results of the
00022  * operations are compared against those produced by a correctly
00023  * functioning X11 backend (and X11 server).
00024  *
00025  * Obviously, only the most basic operations reasonably be expected to
00026  * produce pixel-by-pixel identical results as the X11 backend. We
00027  * don't even try to test the correctness of ellipses, tiles or
00028  * stipples. Not to mention fonts.
00029  *
00030  * But, for those operations we do test, we should try to test quite
00031  * many combinations of parameters.
00032  *
00033  * This is just a quick hack, and could be improved a lot. There are
00034  * copy-pasted code snippets all over that need to be factored out
00035  * into separate functions.
00036  */
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <time.h>
00042 
00043 #include <gdk/gdk.h>
00044 
00045 /* CQTESTF -- "Conditionally Quiet TEST with Fail message"
00046  * macro that prints PASS or FAIL messages
00047  * parms:       quiet:  if TRUE, only print FAIL messages
00048  *              expr:   the expression to test
00049  *              failfmt:if expr is FALSE, print this message
00050  *                      (both format and args)
00051  */
00052 
00053 #define CQTESTF(quiet, expr, failfmt) \
00054   (tmpb = (expr), \
00055    (tmpb ? (quiet ? 0 : printf ("PASS: %d %s\n", __LINE__, #expr)) \
00056          : (printf ("FAIL: %d %s", __LINE__, #expr), \
00057          printf failfmt, \
00058          printf ("\n"), \
00059          retval = FALSE, \
00060          error (), \
00061          return_value++)), \
00062    tmpb)
00063 
00064 /* Variations with less parms */
00065 
00066 #define CQTEST(quiet, expr) \
00067   CQTESTF (quiet, expr, (""))
00068 
00069 #define TEST(expr) \
00070   CQTEST (FALSE, expr)
00071 
00072 #define QTEST(expr) \
00073   CQTEST (TRUE, expr)
00074 
00075 #define TESTF(expr, failfmt) \
00076   CQTESTF (FALSE, expr, failfmt)
00077 
00078 #define QTESTF(expr, failfmt) \
00079   CQTESTF (TRUE, expr, failfmt)
00080 
00081 #define ASSERT(expr) \
00082   do { \
00083     if (!QTEST (expr)) \
00084       printf ("That is fatal. Goodbye\n"), exit (1);\
00085   } while (0)
00086 
00087 #define N(a) (sizeof(a)/sizeof(*a))
00088 
00089 static int return_value = 0;
00090 
00091 static gboolean retval;
00092 static gboolean tmpb;
00093 
00094 static GdkVisual *system_visual;
00095 static GdkVisual *best_visual;
00096 static GdkWindow *w;
00097 
00098 static GdkColormap *system_colourmap;
00099 
00100 static GdkColor white, black, red, green, blue, rand1_colour, rand2_colour;
00101 
00102 static GdkGC *black_gc, *white_gc, *red_gc, *rand1_gc, *rand2_gc;
00103 static GdkGC *gcs[5];
00104 static GdkGC *black_bitmap_gc;
00105 
00106 static int error(void)
00107 {
00108    /* Place breakpoint here to catch failures */
00109    return 0;
00110 }
00111 
00112 static gboolean test_visual_coherency(gboolean quiet, GdkVisual * visual)
00113 {
00114    gboolean retval = TRUE;
00115 
00116    CQTEST(quiet, visual->type >= GDK_VISUAL_STATIC_GRAY &&
00117           visual->type <= GDK_VISUAL_DIRECT_COLOR);
00118    CQTEST(quiet, visual->depth >= 1 && visual->depth <= 32);
00119    CQTEST(quiet, visual->byte_order == GDK_LSB_FIRST
00120           || visual->byte_order == GDK_MSB_FIRST);
00121 
00122    return retval;
00123 }
00124 
00125 /* Test visuals
00126  */
00127 static void test_visuals(void)
00128 {
00129    GdkVisual *visual;
00130    GList *visuals;
00131 
00132    system_visual = gdk_visual_get_system();
00133    ASSERT(system_visual != NULL);
00134    TEST(test_visual_coherency(FALSE, system_visual));
00135 
00136    best_visual = gdk_visual_get_best();
00137    if (best_visual != system_visual)
00138       TEST(test_visual_coherency(TRUE, best_visual));
00139 
00140    visuals = gdk_list_visuals();
00141    while (visuals) {
00142       visual = visuals->data;
00143       TEST(test_visual_coherency(TRUE, visual));
00144       visuals = visuals->next;
00145    }
00146 }
00147 
00148 /* Create a top-level window used by other tests
00149  */
00150 static void test_first_window(void)
00151 {
00152    GdkWindowAttr wa;
00153 
00154    wa.width = 100;
00155    wa.height = 100;
00156    wa.window_type = GDK_WINDOW_TOPLEVEL;
00157    wa.wclass = GDK_INPUT_OUTPUT;
00158 
00159    w = gdk_window_new(NULL, &wa, 0);
00160 
00161    ASSERT(w != NULL);
00162 }
00163 
00164 /* Test colourmaps.
00165  */
00166 static void test_colourmaps(void)
00167 {
00168    system_colourmap = gdk_colormap_get_system();
00169    ASSERT(system_colourmap != NULL);
00170 }
00171 
00172 /* Test colours.
00173  */
00174 static void test_colours(void)
00175 {
00176    ASSERT(gdk_color_white(system_colourmap, &white));
00177    ASSERT(gdk_color_black(system_colourmap, &black));
00178    red.red = 65535;
00179    red.green = red.blue = 0;
00180    TEST(gdk_colormap_alloc_color(system_colourmap, &red, FALSE, TRUE));
00181 
00182    rand1_colour.red = rand() % 65536;
00183    rand1_colour.green = rand() % 65536;
00184    rand1_colour.blue = rand() % 65536;
00185    TEST(gdk_colormap_alloc_color(system_colourmap, &rand1_colour, FALSE,
00186                                  TRUE));
00187 
00188    rand2_colour.red = rand() % 65536;
00189    rand2_colour.green = rand() % 65536;
00190    rand2_colour.blue = rand() % 65536;
00191    TEST(gdk_colormap_alloc_color(system_colourmap, &rand2_colour, FALSE,
00192                                  TRUE));
00193 }
00194 
00195 static gboolean test_default_gc(GdkGCValues * gcvalues, gboolean quiet)
00196 {
00197    gboolean retval = TRUE;
00198 
00199    CQTEST(quiet, gcvalues->foreground.pixel == 0);
00200    CQTEST(quiet, gcvalues->background.pixel == 1);
00201    CQTEST(quiet, gcvalues->function == GDK_COPY);
00202    CQTEST(quiet, gcvalues->fill == GDK_SOLID);
00203    CQTEST(quiet, gcvalues->tile == NULL);
00204    CQTEST(quiet, gcvalues->stipple == NULL);
00205    CQTEST(quiet, gcvalues->clip_mask == NULL);
00206    CQTEST(quiet, gcvalues->subwindow_mode == GDK_CLIP_BY_CHILDREN);
00207    CQTEST(quiet, gcvalues->line_width == 0);
00208    CQTEST(quiet, gcvalues->line_style == GDK_LINE_SOLID);
00209    CQTEST(quiet, gcvalues->cap_style == GDK_CAP_BUTT);
00210    CQTEST(quiet, gcvalues->join_style == GDK_JOIN_MITER);
00211 
00212    return retval;
00213 }
00214 
00215 /* Create GdkGCs with various values,
00216  * check that gdk_gc_get_values returns the same,
00217  * or something reasonably close.
00218  */
00219 static void test_gcs(void)
00220 {
00221    GdkPixmap *pixmap;
00222    GdkGC *gc;
00223    GdkGCValues gcvalues;
00224    GdkColor colour;
00225    GdkFunction function;
00226    GdkFill fill;
00227    gboolean retval;
00228 
00229    gc = gdk_gc_new(w);
00230    gdk_gc_get_values(gc, &gcvalues);
00231    test_default_gc(&gcvalues, FALSE);
00232 
00233    colour.pixel = 1234;
00234    gdk_gc_set_foreground(gc, &colour);
00235    gdk_gc_get_values(gc, &gcvalues);
00236    TEST(gcvalues.foreground.pixel == 1234);
00237 
00238    colour.pixel = 0;
00239    gdk_gc_set_foreground(gc, &colour);
00240    gdk_gc_get_values(gc, &gcvalues);
00241    TEST(test_default_gc(&gcvalues, TRUE));
00242 
00243    colour.pixel = 5678;
00244    gdk_gc_set_background(gc, &colour);
00245    gdk_gc_get_values(gc, &gcvalues);
00246    TEST(gcvalues.background.pixel == 5678);
00247 
00248    colour.pixel = 1;
00249    gdk_gc_set_background(gc, &colour);
00250    gdk_gc_get_values(gc, &gcvalues);
00251    TEST(test_default_gc(&gcvalues, TRUE));
00252 
00253    retval = TRUE;
00254    for (function = GDK_COPY; function <= GDK_SET; function++) {
00255       gdk_gc_set_function(gc, function);
00256       gdk_gc_get_values(gc, &gcvalues);
00257       QTEST(gcvalues.function == function);
00258       gdk_gc_set_function(gc, GDK_COPY);
00259       gdk_gc_get_values(gc, &gcvalues);
00260       QTEST(test_default_gc(&gcvalues, TRUE));
00261    }
00262    TEST(retval);
00263 
00264    retval = TRUE;
00265    for (fill = GDK_SOLID; fill <= GDK_OPAQUE_STIPPLED; fill++) {
00266       gdk_gc_set_fill(gc, fill);
00267       gdk_gc_get_values(gc, &gcvalues);
00268       QTEST(gcvalues.fill == fill);
00269       gdk_gc_set_fill(gc, GDK_SOLID);
00270       gdk_gc_get_values(gc, &gcvalues);
00271       QTEST(test_default_gc(&gcvalues, TRUE));
00272    }
00273    TEST(retval);
00274 
00275    black_gc = gdk_gc_new(w);
00276    gdk_gc_copy(black_gc, gc);
00277    gdk_gc_get_values(black_gc, &gcvalues);
00278    TEST(test_default_gc(&gcvalues, TRUE));
00279    gdk_gc_unref(gc);
00280 
00281    gdk_gc_set_foreground(black_gc, &black);
00282    gdk_gc_get_values(black_gc, &gcvalues);
00283    TEST(gcvalues.foreground.pixel == black.pixel);
00284 
00285    white_gc = gdk_gc_new(w);
00286 
00287    gdk_gc_set_foreground(white_gc, &white);
00288    gdk_gc_get_values(white_gc, &gcvalues);
00289    TEST(gcvalues.foreground.pixel == white.pixel);
00290 
00291    red_gc = gdk_gc_new(w);
00292    gdk_gc_set_foreground(red_gc, &red);
00293    gdk_gc_get_values(red_gc, &gcvalues);
00294    TEST(gcvalues.foreground.pixel == red.pixel);
00295 
00296    rand1_gc = gdk_gc_new(w);
00297    gdk_gc_set_foreground(rand1_gc, &rand1_colour);
00298    gdk_gc_get_values(rand1_gc, &gcvalues);
00299    TESTF(gcvalues.foreground.pixel == rand1_colour.pixel,
00300          (" %#06x != %#06x", gcvalues.foreground.pixel,
00301           rand1_colour.pixel));
00302 
00303    rand2_gc = gdk_gc_new(w);
00304    gdk_gc_set_foreground(rand2_gc, &rand2_colour);
00305    gdk_gc_get_values(rand2_gc, &gcvalues);
00306    TESTF(gcvalues.foreground.pixel == rand2_colour.pixel,
00307          (" %#06x != %#06x", gcvalues.foreground.pixel,
00308           rand2_colour.pixel));
00309 
00310    gcs[0] = black_gc;
00311    gcs[1] = white_gc;
00312    gcs[2] = red_gc;
00313    gcs[3] = rand1_gc;
00314    gcs[4] = rand2_gc;
00315 
00316    pixmap = gdk_pixmap_new(NULL, 1, 1, 1);
00317    black_bitmap_gc = gdk_gc_new(pixmap);
00318    gdk_pixmap_unref(pixmap);
00319 }
00320 
00321 /* Create pixmaps, check that properties are as expected.
00322  * No graphic operations tested yet.
00323  */
00324 static void test_pixmaps(gint depth)
00325 {
00326    GdkPixmap *pixmap;
00327    GdkImage *image;
00328    GdkGC *gc;
00329    gint width, height;
00330    gint w, h;
00331    gboolean retval = TRUE;
00332 
00333    for (width = 1; width <= 64; width += 2)
00334       for (height = 1; height <= 32; height += 3) {
00335          pixmap = gdk_pixmap_new(NULL, width, height, depth);
00336          ASSERT(pixmap != NULL);
00337          gdk_window_get_size(pixmap, &w, &h);
00338          QTESTF(w == width, (" w:%d", w));
00339          QTESTF(h == height, (" h:%d", h));
00340          image = gdk_image_get(pixmap, 0, 0, w, h);
00341          QTEST(image != NULL);
00342          QTEST(image->width == width);
00343          QTEST(image->height == height);
00344          QTEST(image->depth == depth);
00345          gdk_image_destroy(image);
00346          gdk_pixmap_unref(pixmap);
00347       }
00348    TEST(retval);
00349 }
00350 
00351 /* Ditto for images.
00352  */
00353 static void test_images(void)
00354 {
00355    GdkImage *image;
00356    GdkImageType image_type;
00357    gint width, height;
00358    gboolean retval = TRUE;
00359 
00360    for (width = 1; width <= 64; width += 3)
00361       for (height = 1; height <= 32; height += 7)
00362          for (image_type = GDK_IMAGE_NORMAL;
00363               image_type <= GDK_IMAGE_FASTEST; image_type++) {
00364             image =
00365                 gdk_image_new(image_type, system_visual, width, height);
00366             if (image == NULL && image_type == GDK_IMAGE_SHARED)
00367                /* Ignore failure to create shared image,
00368                 * display might not be local.
00369                 */
00370                ;
00371             else {
00372                ASSERT(image != NULL);
00373                QTEST(image->width == width);
00374                QTEST(image->height == height);
00375                QTEST(image->depth == system_visual->depth);
00376                QTEST(image->bpp >= (image->depth - 1) / 8 + 1);
00377                QTEST(image->mem != NULL);
00378                gdk_image_destroy(image);
00379             }
00380          }
00381    TEST(retval);
00382 }
00383 
00384 /* Test creating temp windows.
00385  */
00386 static void test_temp_windows(void)
00387 {
00388    GdkWindow *window;
00389    GdkWindowAttr wa;
00390    GdkVisual *visual;
00391    gint width, height;
00392    gint w, h, x, y, d;
00393    gboolean retval = TRUE;
00394 
00395    wa.window_type = GDK_WINDOW_TEMP;
00396    wa.wclass = GDK_INPUT_OUTPUT;
00397 
00398    for (width = 1; width <= 64; width += 4)
00399       for (height = 1; height <= 32; height += 7) {
00400          wa.width = width;
00401          wa.height = height;
00402          window = gdk_window_new(NULL, &wa, 0);
00403          ASSERT(window != NULL);
00404          gdk_window_get_geometry(window, &x, &y, &w, &h, &d);
00405          QTESTF(w == width, ("w:%d", w));
00406          QTESTF(h == height, ("h:%d", h));
00407          gdk_window_show(window);
00408          gdk_window_get_geometry(window, &x, &y, &w, &h, &d);
00409          QTESTF(w == width, ("w:%d", w));
00410          QTESTF(h == height, ("h:%d", h));
00411          gdk_window_resize(window, 37, 19);
00412          gdk_window_get_geometry(window, &x, &y, &w, &h, &d);
00413          QTESTF(w == 37, ("w:%d", w));
00414          QTESTF(h == 19, ("h:%d", h));
00415          visual = gdk_window_get_visual(window);
00416          QTEST(visual == system_visual);
00417          gdk_window_hide(window);
00418          gdk_window_unref(window);
00419       }
00420    TEST(retval);
00421 }
00422 
00423 static void
00424 test_gc_function(GdkFunction function,
00425                  guint32 oldpixel,
00426                  guint32 newpixel, guint32 foreground, guint32 mask)
00427 {
00428    switch (function) {
00429    case GDK_COPY:
00430       QTEST(newpixel == (foreground & mask));
00431       break;
00432    case GDK_INVERT:
00433       QTEST(newpixel == ((~oldpixel) & mask));
00434       break;
00435    case GDK_XOR:
00436       QTEST(newpixel == ((oldpixel ^ foreground) & mask));
00437       break;
00438    case GDK_CLEAR:
00439       QTEST(newpixel == 0);
00440       break;
00441    case GDK_AND:
00442       QTEST(newpixel == ((oldpixel & foreground) & mask));
00443       break;
00444    case GDK_AND_REVERSE:
00445       QTEST(newpixel == (((~oldpixel) & foreground) & mask));
00446       break;
00447    case GDK_AND_INVERT:
00448       QTEST(newpixel == ((oldpixel & (~foreground)) & mask));
00449       break;
00450    case GDK_NOOP:
00451       QTEST(newpixel == (oldpixel & mask));
00452       break;
00453    case GDK_OR:
00454       QTEST(newpixel == ((oldpixel | foreground) & mask));
00455       break;
00456    case GDK_EQUIV:
00457       QTEST(newpixel == ((oldpixel ^ (~foreground)) & mask));
00458       break;
00459    case GDK_OR_REVERSE:
00460       QTEST(newpixel == (((~oldpixel) | foreground) & mask));
00461       break;
00462    case GDK_COPY_INVERT:
00463       QTEST(newpixel == ((~foreground) & mask));
00464       break;
00465    case GDK_OR_INVERT:
00466       QTEST(newpixel == ((oldpixel | (~foreground)) & mask));
00467       break;
00468    case GDK_NAND:
00469       QTEST(newpixel == (((~oldpixel) | (~foreground)) & mask));
00470       break;
00471    case GDK_SET:
00472       QTEST(newpixel == ((~0) & mask));
00473       break;
00474    default:
00475       ASSERT(FALSE);
00476    }
00477 }
00478 
00479 static void
00480 test_one_point_on_drawable(GdkDrawable * drawable, GdkGC * gc, int depth)
00481 {
00482    GdkImage *image;
00483    GdkGCValues gcvalues;
00484    gint xoff, yoff;
00485    guint32 oldpixels[3][3], newpixel, mask;
00486    const gint x = 4;
00487    const gint y = 5;
00488 
00489    gdk_gc_get_values(gc, &gcvalues);
00490 
00491    image = gdk_image_get(drawable, x + -1, y + -1, 3, 3);
00492    QTEST(image != NULL);
00493    for (xoff = -1; xoff <= 1; xoff++)
00494       for (yoff = -1; yoff <= 1; yoff++) {
00495          oldpixels[xoff + 1][yoff + 1] =
00496              gdk_image_get_pixel(image, xoff + 1, yoff + 1);
00497       }
00498    gdk_image_destroy(image);
00499 
00500    if (depth == 32)
00501       mask = 0xFFFFFFFF;
00502    else
00503       mask = (1 << depth) - 1;
00504 
00505    gdk_draw_point(drawable, gc, x, y);
00506 
00507    image = gdk_image_get(drawable, x - 1, y - 1, 3, 3);
00508    QTEST(image != NULL);
00509    for (xoff = -1; xoff <= 1; xoff++)
00510       for (yoff = -1; yoff <= 1; yoff++) {
00511          newpixel = gdk_image_get_pixel(image, xoff + 1, yoff + 1);
00512          if (xoff == 0 && yoff == 0)
00513             test_gc_function(gcvalues.function, oldpixels[1][1], newpixel,
00514                              gcvalues.foreground.pixel, mask);
00515          else
00516             QTEST(newpixel == oldpixels[xoff + 1][yoff + 1]);
00517       }
00518    gdk_image_destroy(image);
00519 }
00520 
00521 
00522 /* Test drawing points.
00523  */
00524 static void test_points(void)
00525 {
00526    GdkPixmap *pixmap;
00527    GdkWindow *window;
00528    GdkFunction function;
00529    gint width, height;
00530    int i, j;
00531 
00532    width = 8;
00533    height = 8;
00534    pixmap = gdk_pixmap_new(w, width, height, -1);
00535 
00536    for (i = 0; i < N(gcs); i++)
00537       for (j = 0; j < N(gcs); j++)
00538          for (function = GDK_COPY; function <= GDK_SET; function++) {
00539             gdk_draw_rectangle(pixmap, gcs[i], TRUE, 0, 0, width, height);
00540             gdk_gc_set_function(gcs[j], function);
00541             test_one_point_on_drawable(pixmap, gcs[j],
00542                                        system_visual->depth);
00543             gdk_gc_set_function(gcs[j], GDK_COPY);
00544          }
00545 
00546    gdk_pixmap_unref(pixmap);
00547 
00548    pixmap = gdk_pixmap_new(w, width, height, 1);
00549    test_one_point_on_drawable(pixmap, black_bitmap_gc, 1);
00550    for (function = GDK_COPY; function <= GDK_SET; function++) {
00551       gdk_gc_set_function(black_bitmap_gc, function);
00552       test_one_point_on_drawable(pixmap, black_bitmap_gc, 1);
00553    }
00554 
00555    gdk_pixmap_unref(pixmap);
00556 }
00557 
00558 static void
00559 test_one_line_on_drawable(GdkDrawable * drawable,
00560                           GdkGC * gc, int depth, gboolean horisontal)
00561 {
00562    GdkImage *oldimage, *newimage;
00563    GdkGCValues gcvalues;
00564    gint line_width;
00565    gint w, h;
00566    gint w_up, w_down, w_left, w_right;
00567    gint x, y;
00568    guint32 oldpixel, newpixel, mask;
00569 
00570    gdk_gc_get_values(gc, &gcvalues);
00571    line_width = gcvalues.line_width > 0 ? gcvalues.line_width : 1;
00572    w_up = w_left = line_width / 2;
00573    w_down = w_right =
00574        (line_width & 1) ? line_width / 2 : line_width / 2 - 1;
00575    gdk_window_get_size(drawable, &w, &h);
00576    oldimage = gdk_image_get(drawable, 0, 0, w, h);
00577 
00578    if (depth == 32)
00579       mask = 0xFFFFFFFF;
00580    else
00581       mask = (1 << depth) - 1;
00582 
00583    if (horisontal) {
00584       const gint x1 = 10;
00585       const gint y1 = 10;
00586       const gint x2 = 13;
00587       const gint y2 = y1;
00588 
00589       gdk_draw_line(drawable, gc, x1, y1, x2, y2);
00590       newimage = gdk_image_get(drawable, 0, 0, w, h);
00591       for (x = x1 - 1; x <= x2 + 1; x++)
00592          for (y = y1 - w_up - 1; y <= y1 + w_down + 1; y++) {
00593             oldpixel = gdk_image_get_pixel(oldimage, x, y);
00594             newpixel = gdk_image_get_pixel(newimage, x, y);
00595             if (x >= x1 && x < x2 && y >= y1 - w_up && y <= y1 + w_down)
00596                test_gc_function(gcvalues.function, oldpixel, newpixel,
00597                                 gcvalues.foreground.pixel, mask);
00598             else
00599                QTEST(oldpixel == newpixel);
00600          }
00601    } else {                     /* vertical */
00602 
00603       const gint x1 = 10;
00604       const gint y1 = 10;
00605       const gint x2 = 10;
00606       const gint y2 = 13;
00607 
00608       gdk_draw_line(drawable, gc, x1, y1, x2, y2);
00609       newimage = gdk_image_get(drawable, 0, 0, w, h);
00610       for (x = x1 - w_left - 1; x <= x1 + w_right + 1; x++)
00611          for (y = y1 - 1; y <= y2 + 1; y++) {
00612             oldpixel = gdk_image_get_pixel(oldimage, x, y);
00613             newpixel = gdk_image_get_pixel(newimage, x, y);
00614             if (x >= x1 - w_left && x <= x1 + w_right && y >= y1 && y < y2)
00615                test_gc_function(gcvalues.function, oldpixel, newpixel,
00616                                 gcvalues.foreground.pixel, mask);
00617             else
00618                QTEST(oldpixel == newpixel);
00619          }
00620    }
00621 
00622    gdk_image_destroy(oldimage);
00623    gdk_image_destroy(newimage);
00624 }
00625 
00626 /* Test drawing lines.
00627  */
00628 static void test_lines(void)
00629 {
00630    GdkPixmap *pixmap;
00631    GdkFunction function;
00632    gint width;
00633    int i, j;
00634    gboolean horisontal = TRUE;
00635 
00636    pixmap = gdk_pixmap_new(w, 30, 30, -1);
00637 
00638    for (i = 0; i < N(gcs); i++)
00639       for (j = 0; j < N(gcs); j++)
00640          for (function = GDK_COPY; function <= GDK_SET; function++)
00641             for (width = 1; width <= 4; width++) {
00642                gdk_draw_rectangle(pixmap, gcs[i], TRUE, 0, 0, 30, 30);
00643                gdk_gc_set_function(gcs[j], function);
00644                gdk_gc_set_line_attributes(gcs[j], width,
00645                                           GDK_LINE_SOLID, GDK_CAP_BUTT,
00646                                           GDK_JOIN_MITER);
00647                test_one_line_on_drawable(pixmap, gcs[j],
00648                                          system_visual->depth, horisontal);
00649                /* Toggle between horisontal and vertical... */
00650                horisontal = !horisontal;
00651                gdk_gc_set_function(gcs[j], GDK_COPY);
00652             }
00653 
00654    gdk_pixmap_unref(pixmap);
00655 }
00656 
00657 static void
00658 test_one_rectangle_on_drawable(GdkDrawable * drawable,
00659                                GdkGC * gc, int depth, gboolean filled)
00660 {
00661    GdkImage *oldimage, *newimage;
00662    GdkGCValues gcvalues;
00663    gint line_width;
00664    gint w, h;
00665    gint w_up, w_down, w_left, w_right;
00666    gint x, y;
00667    guint32 oldpixel, newpixel, mask;
00668    const gint x0 = 10;
00669    const gint y0 = 13;
00670    const gint width = 7;
00671    const gint height = 9;
00672 
00673    gdk_gc_get_values(gc, &gcvalues);
00674 
00675    if (!filled) {
00676       line_width = gcvalues.line_width > 0 ? gcvalues.line_width : 1;
00677       w_up = w_left = line_width / 2;
00678       w_down = w_right =
00679           (line_width & 1) ? line_width / 2 : line_width / 2 - 1;
00680    }
00681 
00682    gdk_window_get_size(drawable, &w, &h);
00683    oldimage = gdk_image_get(drawable, 0, 0, w, h);
00684 
00685    if (depth == 32)
00686       mask = 0xFFFFFFFF;
00687    else
00688       mask = (1 << depth) - 1;
00689 
00690    gdk_draw_rectangle(drawable, gc, filled, x0, y0, width, height);
00691    newimage = gdk_image_get(drawable, 0, 0, w, h);
00692 
00693    for (x = x0 - 1; x <= x0 + width + 1; x++)
00694       for (y = y0 - 1; y < y0 + height + 1; y++) {
00695          oldpixel = gdk_image_get_pixel(oldimage, x, y);
00696          newpixel = gdk_image_get_pixel(newimage, x, y);
00697 
00698          if (filled) {
00699             if (x >= x0 && x < x0 + width && y >= y0 && y < y0 + height)
00700                test_gc_function(gcvalues.function, oldpixel, newpixel,
00701                                 gcvalues.foreground.pixel, mask);
00702             else
00703                QTEST(oldpixel == newpixel);
00704          } else {
00705             if ((x >= x0 - w_left && x <= x0 + width + w_right &&
00706                  y >= y0 - w_up && y <= y0 + w_down) ||
00707                 (x >= x0 - w_left && x <= x0 + width + w_right &&
00708                  y >= y0 + height - w_up && y <= y0 + height + w_down) ||
00709                 (x >= x0 - w_left && x <= x0 + w_right &&
00710                  y >= y0 - w_up && y <= y0 + height + w_down) ||
00711                 (x >= x0 + width - w_left && x <= x0 + width + w_right &&
00712                  y >= y0 - w_up && y <= y0 + height + w_down))
00713                test_gc_function(gcvalues.function, oldpixel, newpixel,
00714                                 gcvalues.foreground.pixel, mask);
00715             else
00716                QTEST(oldpixel == newpixel);
00717          }
00718       }
00719 
00720    gdk_image_destroy(oldimage);
00721    gdk_image_destroy(newimage);
00722 }
00723 
00724 /* Test drawing rectangles.
00725  */
00726 static void test_rectangles(void)
00727 {
00728    GdkPixmap *pixmap;
00729    GdkFunction function;
00730    gint width;
00731    int i, j;
00732    gboolean filled = FALSE;
00733 
00734    pixmap = gdk_pixmap_new(w, 30, 30, -1);
00735 
00736    for (i = 0; i < N(gcs); i++)
00737       for (j = 0; j < N(gcs); j++)
00738          for (function = GDK_COPY; function <= GDK_SET; function++)
00739             for (width = 1; width <= 4; width++) {
00740                gdk_draw_rectangle(pixmap, gcs[i], TRUE, 0, 0, 30, 30);
00741                gdk_gc_set_function(gcs[j], function);
00742                gdk_gc_set_line_attributes(gcs[j], width,
00743                                           GDK_LINE_SOLID, GDK_CAP_BUTT,
00744                                           GDK_JOIN_MITER);
00745                test_one_rectangle_on_drawable(pixmap, gcs[j],
00746                                               system_visual->depth,
00747                                               filled);
00748                filled = !filled;
00749                gdk_gc_set_function(gcs[j], GDK_COPY);
00750             }
00751 
00752    gdk_pixmap_unref(pixmap);
00753 }
00754 
00755 static void
00756 test_some_arcs_on_drawable(GdkDrawable * drawable,
00757                            GdkGC * gc, int depth, gboolean filled)
00758 {
00759    GdkImage *oldimage, *newimage;
00760    GdkGCValues gcvalues;
00761    gint line_width;
00762    gint w, h;
00763    gint w_up, w_down, w_left, w_right;
00764    gint x, y;
00765    guint32 oldpixel, newpixel, mask;
00766    /* XXX */
00767    const gint x0 = 10;
00768    const gint y0 = 13;
00769    const gint width = 7;
00770    const gint height = 9;
00771 
00772    gdk_gc_get_values(gc, &gcvalues);
00773 
00774    if (!filled) {
00775       line_width = gcvalues.line_width > 0 ? gcvalues.line_width : 1;
00776       w_up = w_left = line_width / 2;
00777       w_down = w_right =
00778           (line_width & 1) ? line_width / 2 : line_width / 2 - 1;
00779    }
00780 
00781    gdk_window_get_size(drawable, &w, &h);
00782    oldimage = gdk_image_get(drawable, 0, 0, w, h);
00783 
00784    if (depth == 32)
00785       mask = 0xFFFFFFFF;
00786    else
00787       mask = (1 << depth) - 1;
00788 
00789    /* XXX */
00790    newimage = gdk_image_get(drawable, 0, 0, w, h);
00791 
00792    for (x = x0 - 1; x <= x0 + width + 1; x++)
00793       for (y = y0 - 1; y < y0 + height + 1; y++) {
00794          oldpixel = gdk_image_get_pixel(oldimage, x, y);
00795          newpixel = gdk_image_get_pixel(newimage, x, y);
00796 
00797          if (filled) {
00798             /* XXX */
00799          } else {
00800             /* XXX */
00801          }
00802       }
00803 
00804    gdk_image_destroy(oldimage);
00805    gdk_image_destroy(newimage);
00806 }
00807 
00808 /* Test drawing arcs. Results don't have to be exactly as on X11,
00809  * but "close".
00810  */
00811 static void test_arcs(void)
00812 {
00813    GdkPixmap *pixmap;
00814    GdkFunction function;
00815    gint width;
00816    int i, j;
00817    gboolean filled = FALSE;
00818 
00819    pixmap = gdk_pixmap_new(w, 30, 30, -1);
00820 
00821    for (i = 0; i < N(gcs); i++)
00822       for (j = 0; j < N(gcs); j++)
00823          for (function = GDK_COPY; function <= GDK_SET; function++)
00824             for (width = 1; width <= 4; width++) {
00825                gdk_draw_rectangle(pixmap, gcs[i], TRUE, 0, 0, 30, 30);
00826                gdk_gc_set_function(gcs[j], function);
00827                gdk_gc_set_line_attributes(gcs[j], width,
00828                                           GDK_LINE_SOLID, GDK_CAP_BUTT,
00829                                           GDK_JOIN_MITER);
00830                test_some_arcs_on_drawable(pixmap, gcs[j],
00831                                           system_visual->depth, filled);
00832                filled = !filled;
00833                gdk_gc_set_function(gcs[j], GDK_COPY);
00834             }
00835 
00836    gdk_pixmap_unref(pixmap);
00837 }
00838 
00839 /* Test region operations.
00840  */
00841 static void test_regions(void)
00842 {
00843 }
00844 
00845 static void tests(void)
00846 {
00847    srand(time(NULL));
00848 
00849    test_visuals();
00850    test_first_window();
00851    test_colourmaps();
00852    test_colours();
00853    test_gcs();
00854    test_pixmaps(1);
00855    test_pixmaps(system_visual->depth);
00856    if (best_visual->depth != system_visual->depth)
00857       test_pixmaps(best_visual->depth);
00858    test_images();
00859    test_temp_windows();
00860    test_points();
00861    test_lines();
00862    test_rectangles();
00863    test_arcs();
00864    test_regions();
00865 }
00866 
00867 int main(int argc, char **argv)
00868 {
00869    gdk_init(&argc, &argv);
00870 
00871    tests();
00872 
00873    return return_value;
00874 }

Generated on Tue Jul 5 14:14:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1