testboxes.c

Go to the documentation of this file.
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 
00003 /* Metacity box operation testing program */
00004 
00005 /* 
00006  * Copyright (C) 2005 Elijah Newren
00007  * 
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00021  * 02111-1307, USA.
00022  */
00023 
00024 #include "boxes.h"
00025 #include <glib.h>
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <X11/Xutil.h> /* Just for the definition of the various gravities */
00029 #include <time.h>      /* To initialize random seed */
00030 
00031 #define NUM_RANDOM_RUNS 10000
00032 
00033 static void
00034 init_random_ness ()
00035 {
00036   srand(time(NULL));
00037 }
00038 
00039 static void
00040 get_random_rect (MetaRectangle *rect)
00041 {
00042   rect->x = rand () % 1600;
00043   rect->y = rand () % 1200;
00044   rect->width  = rand () % 1600 + 1;
00045   rect->height = rand () % 1200 + 1;
00046 }
00047 
00048 static MetaRectangle*
00049 new_meta_rect (int x, int y, int width, int height)
00050 {
00051   MetaRectangle* temporary;
00052   temporary = g_new (MetaRectangle, 1);
00053   temporary->x = x;
00054   temporary->y = y;
00055   temporary->width  = width;
00056   temporary->height = height;
00057 
00058   return temporary;
00059 }
00060 
00061 static MetaStrut*
00062 new_meta_strut (int x, int y, int width, int height, int side)
00063 {
00064   MetaStrut* temporary;
00065   temporary = g_new (MetaStrut, 1);
00066   temporary->rect = meta_rect(x, y, width, height);
00067   temporary->side = side;
00068 
00069   return temporary;
00070 }
00071 
00072 static MetaEdge*
00073 new_screen_edge (int x, int y, int width, int height, int side_type)
00074 {
00075   MetaEdge* temporary;
00076   temporary = g_new (MetaEdge, 1);
00077   temporary->rect.x = x;
00078   temporary->rect.y = y;
00079   temporary->rect.width  = width;
00080   temporary->rect.height = height;
00081   temporary->side_type = side_type;
00082   temporary->edge_type = META_EDGE_SCREEN;
00083 
00084   return temporary;
00085 }
00086 
00087 static MetaEdge*
00088 new_xinerama_edge (int x, int y, int width, int height, int side_type)
00089 {
00090   MetaEdge* temporary;
00091   temporary = g_new (MetaEdge, 1);
00092   temporary->rect.x = x;
00093   temporary->rect.y = y;
00094   temporary->rect.width  = width;
00095   temporary->rect.height = height;
00096   temporary->side_type = side_type;
00097   temporary->edge_type = META_EDGE_XINERAMA;
00098 
00099   return temporary;
00100 }
00101 
00102 static void
00103 test_area ()
00104 {
00105   MetaRectangle temp;
00106   int i;
00107   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00108     {
00109       get_random_rect (&temp);
00110       g_assert (meta_rectangle_area (&temp) == temp.width * temp.height);
00111     }
00112 
00113   temp = meta_rect (0, 0, 5, 7);
00114   g_assert (meta_rectangle_area (&temp) == 35);
00115 
00116   printf ("%s passed.\n", G_STRFUNC);
00117 }
00118 
00119 static void
00120 test_intersect ()
00121 {
00122   MetaRectangle a = {100, 200,  50,  40};
00123   MetaRectangle b = {  0,  50, 110, 152};
00124   MetaRectangle c = {  0,   0,  10,  10};
00125   MetaRectangle d = {100, 100,  50,  50};
00126   MetaRectangle b_intersect_d = {100, 100, 10, 50};
00127   MetaRectangle temp;
00128   MetaRectangle temp2;
00129 
00130   meta_rectangle_intersect (&a, &b, &temp);
00131   temp2 = meta_rect (100, 200, 10, 2);
00132   g_assert (meta_rectangle_equal (&temp, &temp2));
00133   g_assert (meta_rectangle_area (&temp) == 20);
00134 
00135   meta_rectangle_intersect (&a, &c, &temp);
00136   g_assert (meta_rectangle_area (&temp) == 0);
00137 
00138   meta_rectangle_intersect (&a, &d, &temp);
00139   g_assert (meta_rectangle_area (&temp) == 0);
00140 
00141   meta_rectangle_intersect (&b, &d, &b);
00142   g_assert (meta_rectangle_equal (&b, &b_intersect_d));
00143 
00144   printf ("%s passed.\n", G_STRFUNC);
00145 }
00146 
00147 static void
00148 test_equal ()
00149 {
00150   MetaRectangle a = {10, 12, 4, 18};
00151   MetaRectangle b = a;
00152   MetaRectangle c = {10, 12, 4, 19};
00153   MetaRectangle d = {10, 12, 7, 18};
00154   MetaRectangle e = {10, 62, 4, 18};
00155   MetaRectangle f = {27, 12, 4, 18};
00156 
00157   g_assert ( meta_rectangle_equal (&a, &b));
00158   g_assert (!meta_rectangle_equal (&a, &c));
00159   g_assert (!meta_rectangle_equal (&a, &d));
00160   g_assert (!meta_rectangle_equal (&a, &e));
00161   g_assert (!meta_rectangle_equal (&a, &f));
00162 
00163   printf ("%s passed.\n", G_STRFUNC);
00164 }
00165 
00166 static void
00167 test_overlap_funcs ()
00168 {
00169   MetaRectangle temp1, temp2;
00170   int i;
00171   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00172     {
00173       get_random_rect (&temp1);
00174       get_random_rect (&temp2);
00175       g_assert (meta_rectangle_overlap (&temp1, &temp2) ==
00176                 (meta_rectangle_horiz_overlap (&temp1, &temp2) &&
00177                  meta_rectangle_vert_overlap (&temp1, &temp2)));
00178     }
00179 
00180   temp1 = meta_rect ( 0, 0, 10, 10);
00181   temp2 = meta_rect (20, 0, 10,  5);
00182   g_assert (!meta_rectangle_overlap (&temp1, &temp2));
00183   g_assert (!meta_rectangle_horiz_overlap (&temp1, &temp2));
00184   g_assert ( meta_rectangle_vert_overlap (&temp1, &temp2));
00185 
00186   printf ("%s passed.\n", G_STRFUNC);
00187 }
00188 
00189 static void
00190 test_basic_fitting ()
00191 {
00192   MetaRectangle temp1, temp2, temp3;
00193   int i;
00194   /* Four cases:
00195    *   case   temp1 fits temp2    temp1 could fit temp2
00196    *     1           Y                      Y
00197    *     2           N                      Y
00198    *     3           Y                      N
00199    *     4           N                      N
00200    * Of the four cases, case 3 is impossible.  An alternate way of looking
00201    * at this table is that either the middle column must be no, or the last
00202    * column must be yes.  So we test that.  Also, we can repeat the test
00203    * reversing temp1 and temp2.
00204    */
00205   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00206     {
00207       get_random_rect (&temp1);
00208       get_random_rect (&temp2);
00209       g_assert (meta_rectangle_contains_rect (&temp1, &temp2) == FALSE ||
00210                 meta_rectangle_could_fit_rect (&temp1, &temp2) == TRUE);
00211       g_assert (meta_rectangle_contains_rect (&temp2, &temp1) == FALSE ||
00212                 meta_rectangle_could_fit_rect (&temp2, &temp1) == TRUE);
00213     }
00214 
00215   temp1 = meta_rect ( 0, 0, 10, 10);
00216   temp2 = meta_rect ( 5, 5,  5,  5);
00217   temp3 = meta_rect ( 8, 2,  3,  7);
00218   g_assert ( meta_rectangle_contains_rect (&temp1, &temp2));
00219   g_assert (!meta_rectangle_contains_rect (&temp2, &temp1));
00220   g_assert (!meta_rectangle_contains_rect (&temp1, &temp3));
00221   g_assert ( meta_rectangle_could_fit_rect (&temp1, &temp3));
00222   g_assert (!meta_rectangle_could_fit_rect (&temp3, &temp2));
00223 
00224   printf ("%s passed.\n", G_STRFUNC);
00225 }
00226 
00227 static void
00228 free_strut_list (GSList *struts)
00229 {
00230   GSList *tmp = struts;
00231   while (tmp)
00232     {
00233       g_free (tmp->data);
00234       tmp = tmp->next;
00235     }
00236   g_slist_free (struts);
00237 }
00238 
00239 static GSList*
00240 get_strut_list (int which)
00241 {
00242   GSList *ans;
00243   MetaDirection wc = 0; /* wc == who cares? ;-) */
00244 
00245   ans = NULL;
00246 
00247   g_assert (which >=0 && which <= 6);
00248   switch (which)
00249     {
00250     case 0:
00251       break;
00252     case 1:
00253       ans = g_slist_prepend (ans, new_meta_strut (   0,    0, 1600,   20, wc));
00254       ans = g_slist_prepend (ans, new_meta_strut ( 400, 1160, 1600,   40, wc));
00255       break;
00256     case 2:
00257       ans = g_slist_prepend (ans, new_meta_strut (   0,    0, 1600,   20, wc));
00258       ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100,  400,  100, wc));
00259       ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150,  150,   50, wc));
00260       break;
00261     case 3:
00262       ans = g_slist_prepend (ans, new_meta_strut (   0,    0, 1600,   20, wc));
00263       ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100,  400,  100, wc));
00264       ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150,   80,   50, wc));
00265       ans = g_slist_prepend (ans, new_meta_strut ( 700,  525,  200,  150, wc));
00266       break;
00267     case 4:
00268       ans = g_slist_prepend (ans, new_meta_strut (   0,    0,  800, 1200, wc));
00269       ans = g_slist_prepend (ans, new_meta_strut ( 800,    0, 1600,   20, wc));
00270       break;
00271     case 5:
00272       ans = g_slist_prepend (ans, new_meta_strut ( 800,    0, 1600,   20, wc));
00273       ans = g_slist_prepend (ans, new_meta_strut (   0,    0,  800, 1200, wc));
00274       ans = g_slist_prepend (ans, new_meta_strut ( 800,   10,  800, 1200, wc));
00275       break;
00276     case 6:
00277       ans = g_slist_prepend (ans, new_meta_strut (   0,    0, 1600,   40, wc));
00278       ans = g_slist_prepend (ans, new_meta_strut (   0,    0, 1600,   20, wc));
00279       break;
00280     }
00281 
00282   return ans;
00283 }
00284 
00285 static GList*
00286 get_screen_region (int which)
00287 {
00288   GList *ret;
00289   GSList *struts;
00290   MetaRectangle basic_rect;
00291 
00292   basic_rect = meta_rect (0, 0, 1600, 1200);
00293   ret = NULL;
00294 
00295   struts = get_strut_list (which);
00296   ret = meta_rectangle_get_minimal_spanning_set_for_region (&basic_rect, struts);
00297   free_strut_list (struts);
00298 
00299   return ret;
00300 }
00301 
00302 static GList*
00303 get_screen_edges (int which)
00304 {
00305   GList *ret;
00306   GSList *struts;
00307   MetaRectangle basic_rect;
00308 
00309   basic_rect = meta_rect (0, 0, 1600, 1200);
00310   ret = NULL;
00311 
00312   struts = get_strut_list (which);
00313   ret = meta_rectangle_find_onscreen_edges (&basic_rect, struts);
00314   free_strut_list (struts);
00315 
00316   return ret;
00317 }
00318 
00319 static GList*
00320 get_xinerama_edges (int which_xinerama_set, int which_strut_set)
00321 {
00322   GList *ret;
00323   GSList *struts;
00324   GList *xins;
00325 
00326   xins = NULL;
00327   g_assert (which_xinerama_set >=0 && which_xinerama_set <= 3);
00328   switch (which_xinerama_set)
00329     {
00330     case 0:
00331       xins = g_list_prepend (xins, new_meta_rect (  0,   0, 1600, 1200));
00332       break;
00333     case 1:
00334       xins = g_list_prepend (xins, new_meta_rect (  0,   0,  800, 1200));
00335       xins = g_list_prepend (xins, new_meta_rect (800,   0,  800, 1200));
00336       break;
00337     case 2:
00338       xins = g_list_prepend (xins, new_meta_rect (  0,   0, 1600,  600));
00339       xins = g_list_prepend (xins, new_meta_rect (  0, 600, 1600,  600));
00340       break;
00341     case 3:
00342       xins = g_list_prepend (xins, new_meta_rect (  0,   0, 1600,  600));
00343       xins = g_list_prepend (xins, new_meta_rect (  0, 600,  800,  600));
00344       xins = g_list_prepend (xins, new_meta_rect (800, 600,  800,  600));
00345       break;
00346     }
00347 
00348   ret = NULL;
00349 
00350   struts = get_strut_list (which_strut_set);
00351   ret = meta_rectangle_find_nonintersected_xinerama_edges (xins, struts);
00352 
00353   free_strut_list (struts);
00354   meta_rectangle_free_list_and_elements (xins);
00355 
00356   return ret;
00357 }
00358 
00359 #if 0
00360 static void
00361 test_merge_regions ()
00362 {
00363   /* logarithmically distributed random number of struts (range?)
00364    * logarithmically distributed random size of struts (up to screen size???)
00365    * uniformly distributed location of center of struts (within screen)
00366    * merge all regions that are possible
00367    * print stats on problem setup
00368    *   number of (non-completely-occluded?) struts 
00369    *   percentage of screen covered
00370    *   length of resulting non-minimal spanning set
00371    *   length of resulting minimal spanning set
00372    * print stats on merged regions:
00373    *   number boxes merged
00374    *   number of those merges that were of the form A contains B
00375    *   number of those merges that were of the form A partially contains B
00376    *   number of those merges that were of the form A is adjacent to B
00377    */
00378 
00379   GList* region;
00380   GList* compare;
00381   int num_contains, num_merged, num_part_contains, num_adjacent;
00382 
00383   num_contains = num_merged = num_part_contains = num_adjacent = 0;
00384   compare = region = get_screen_region (2);
00385   g_assert (region);
00386 
00387   printf ("Merging stats:\n");
00388   printf ("  Length of initial list: %d\n", g_list_length (region));
00389 #ifdef PRINT_DEBUG
00390   char rect1[RECT_LENGTH], rect2[RECT_LENGTH];
00391   char region_list[(RECT_LENGTH + 2) * g_list_length (region)];
00392   meta_rectangle_region_to_string (region, ", ", region_list);
00393   printf ("  Initial rectangles: %s\n", region_list);
00394 #endif
00395 
00396   while (compare && compare->next)
00397     {
00398       MetaRectangle *a = compare->data;
00399       GList *other = compare->next;
00400 
00401       g_assert (a->width > 0 && a->height > 0);
00402 
00403       while (other)
00404         {
00405           MetaRectangle *b = other->data;
00406           GList *delete_me = NULL;
00407 
00408           g_assert (b->width > 0 && b->height > 0);
00409 
00410 #ifdef PRINT_DEBUG
00411           printf ("    -- Comparing %s to %s --\n",
00412                   meta_rectangle_to_string (a, rect1),
00413                   meta_rectangle_to_string (b, rect2));
00414 #endif
00415 
00416           /* If a contains b, just remove b */
00417           if (meta_rectangle_contains_rect (a, b))
00418             {
00419               delete_me = other;
00420               num_contains++;
00421               num_merged++;
00422             }
00423           /* If b contains a, just remove a */
00424           else if (meta_rectangle_contains_rect (a, b))
00425             {
00426               delete_me = compare;
00427               num_contains++;
00428               num_merged++;
00429             }
00430           /* If a and b might be mergeable horizontally */
00431           else if (a->y == b->y && a->height == b->height)
00432             {
00433               /* If a and b overlap */
00434               if (meta_rectangle_overlap (a, b))
00435                 {
00436                   int new_x = MIN (a->x, b->x);
00437                   a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
00438                   a->x = new_x;
00439                   delete_me = other;
00440                   num_part_contains++;
00441                   num_merged++;
00442                 }
00443               /* If a and b are adjacent */
00444               else if (a->x + a->width == b->x || a->x == b->x + b->width)
00445                 {
00446                   int new_x = MIN (a->x, b->x);
00447                   a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
00448                   a->x = new_x;
00449                   delete_me = other;
00450                   num_adjacent++;
00451                   num_merged++;
00452                 }
00453             }
00454           /* If a and b might be mergeable vertically */
00455           else if (a->x == b->x && a->width == b->width)
00456             {
00457               /* If a and b overlap */
00458               if (meta_rectangle_overlap (a, b))
00459                 {
00460                   int new_y = MIN (a->y, b->y);
00461                   a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
00462                   a->y = new_y;
00463                   delete_me = other;
00464                   num_part_contains++;
00465                   num_merged++;
00466                 }
00467               /* If a and b are adjacent */
00468               else if (a->y + a->height == b->y || a->y == b->y + b->height)
00469                 {
00470                   int new_y = MIN (a->y, b->y);
00471                   a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
00472                   a->y = new_y;
00473                   delete_me = other;
00474                   num_adjacent++;
00475                   num_merged++;
00476                 }
00477             }
00478 
00479           other = other->next;
00480 
00481           /* Delete any rectangle in the list that is no longer wanted */
00482           if (delete_me != NULL)
00483             {
00484 #ifdef PRINT_DEBUG
00485               MetaRectangle *bla = delete_me->data;
00486               printf ("    Deleting rect %s\n",
00487                       meta_rectangle_to_string (bla, rect1));
00488 #endif
00489 
00490               /* Deleting the rect we're compare others to is a little tricker */
00491               if (compare == delete_me)
00492                 {
00493                   compare = compare->next;
00494                   other = compare->next;
00495                   a = compare->data;
00496                 }
00497 
00498               /* Okay, we can free it now */
00499               g_free (delete_me->data);
00500               region = g_list_delete_link (region, delete_me);
00501             }
00502 
00503 #ifdef PRINT_DEBUG
00504           char region_list[(RECT_LENGTH + 2) * g_list_length (region)];
00505           meta_rectangle_region_to_string (region, ", ", region_list);
00506           printf ("      After comparison, new list is: %s\n", region_list);
00507 #endif
00508         }
00509 
00510       compare = compare->next;
00511     }
00512 
00513   printf ("  Num rectangles contained in others          : %d\n", 
00514           num_contains);
00515   printf ("  Num rectangles partially contained in others: %d\n", 
00516           num_part_contains);
00517   printf ("  Num rectangles adjacent to others           : %d\n", 
00518           num_adjacent);
00519   printf ("  Num rectangles merged with others           : %d\n",
00520           num_merged);
00521 #ifdef PRINT_DEBUG
00522   char region_list2[(RECT_LENGTH + 2) * g_list_length (region)];
00523   meta_rectangle_region_to_string (region, ", ", region_list2);
00524   printf ("  Final rectangles: %s\n", region_list2);
00525 #endif
00526 
00527   meta_rectangle_free_spanning_set (region);
00528   region = NULL;
00529 
00530   printf ("%s passed.\n", G_STRFUNC);
00531 }
00532 #endif
00533 
00534 static void
00535 verify_lists_are_equal (GList *code, GList *answer)
00536 {
00537   int which = 0;
00538 
00539   while (code && answer)
00540     {
00541       MetaRectangle *a = code->data;
00542       MetaRectangle *b = answer->data;
00543 
00544       if (a->x      != b->x     ||
00545           a->y      != b->y     ||
00546           a->width  != b->width ||
00547           a->height != b->height)
00548         {
00549           g_error ("%dth item in code answer answer lists do not match; "
00550                    "code rect: %d,%d + %d,%d; answer rect: %d,%d + %d,%d\n",
00551                    which,
00552                    a->x, a->y, a->width, a->height,
00553                    b->x, b->y, b->width, b->height);
00554         }
00555 
00556       code = code->next;
00557       answer = answer->next;
00558 
00559       which++;
00560     }
00561 
00562   /* Ought to be at the end of both lists; check if we aren't */
00563   if (code)
00564     {
00565       MetaRectangle *tmp = code->data;
00566       g_error ("code list longer than answer list by %d items; "
00567                "first extra item: %d,%d +%d,%d\n",
00568                g_list_length (code),
00569                tmp->x, tmp->y, tmp->width, tmp->height);
00570     }
00571 
00572   if (answer)
00573     {
00574       MetaRectangle *tmp = answer->data;
00575       g_error ("answer list longer than code list by %d items; "
00576                "first extra item: %d,%d +%d,%d\n",
00577                g_list_length (answer),
00578                tmp->x, tmp->y, tmp->width, tmp->height);
00579     }
00580 }
00581 
00582 static void
00583 test_regions_okay ()
00584 {
00585   GList* region;
00586   GList* tmp;
00587 
00588   /*************************************************************/  
00589   /* Make sure test region 0 has the right spanning rectangles */
00590   /*************************************************************/  
00591   region = get_screen_region (0);
00592   tmp = NULL;
00593   tmp = g_list_prepend (tmp, new_meta_rect (0, 0, 1600, 1200));
00594   verify_lists_are_equal (region, tmp);
00595   meta_rectangle_free_list_and_elements (tmp);
00596   meta_rectangle_free_list_and_elements (region);
00597 
00598   /*************************************************************/  
00599   /* Make sure test region 1 has the right spanning rectangles */
00600   /*************************************************************/  
00601   region = get_screen_region (1);
00602   tmp = NULL;
00603   tmp = g_list_prepend (tmp, new_meta_rect (0, 20,  400, 1180));
00604   tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 1600, 1140));
00605   verify_lists_are_equal (region, tmp);
00606   meta_rectangle_free_list_and_elements (tmp);
00607   meta_rectangle_free_list_and_elements (region);
00608 
00609   /*************************************************************/
00610   /* Make sure test region 2 has the right spanning rectangles */
00611   /*************************************************************/  
00612   region = get_screen_region (2);
00613   tmp = NULL;
00614   tmp = g_list_prepend (tmp, new_meta_rect (   0,   20,  300, 1180));
00615   tmp = g_list_prepend (tmp, new_meta_rect ( 450,   20,  350, 1180));
00616   tmp = g_list_prepend (tmp, new_meta_rect (1200,   20,  400, 1180));
00617   tmp = g_list_prepend (tmp, new_meta_rect (   0,   20,  800, 1130));
00618   tmp = g_list_prepend (tmp, new_meta_rect (   0,   20, 1600, 1080));
00619   verify_lists_are_equal (region, tmp);
00620   meta_rectangle_free_list_and_elements (tmp);
00621   meta_rectangle_free_list_and_elements (region);
00622 
00623   /*************************************************************/
00624   /* Make sure test region 3 has the right spanning rectangles */
00625   /*************************************************************/  
00626   region = get_screen_region (3);
00627   tmp = NULL;
00628   tmp = g_list_prepend (tmp, new_meta_rect ( 380,  675,  420,  525)); /* 220500 */
00629   tmp = g_list_prepend (tmp, new_meta_rect (   0,   20,  300, 1180)); /* 354000 */
00630   tmp = g_list_prepend (tmp, new_meta_rect ( 380,   20,  320, 1180)); /* 377600 */
00631   tmp = g_list_prepend (tmp, new_meta_rect (   0,  675,  800,  475)); /* 380000 */
00632   tmp = g_list_prepend (tmp, new_meta_rect (1200,   20,  400, 1180)); /* 472000 */
00633   tmp = g_list_prepend (tmp, new_meta_rect (   0,  675, 1600,  425)); /* 680000 */
00634   tmp = g_list_prepend (tmp, new_meta_rect ( 900,   20,  700, 1080)); /* 756000 */
00635   tmp = g_list_prepend (tmp, new_meta_rect (   0,   20,  700, 1130)); /* 791000 */
00636   tmp = g_list_prepend (tmp, new_meta_rect (   0,   20, 1600,  505)); /* 808000 */
00637 #if 0
00638   printf ("Got to here...\n");
00639   char region_list[(RECT_LENGTH+2) * g_list_length (region)];
00640   char tmp_list[   (RECT_LENGTH+2) * g_list_length (tmp)];
00641   meta_rectangle_region_to_string (region, ", ", region_list);
00642   meta_rectangle_region_to_string (region, ", ", tmp_list);
00643   printf ("%s vs. %s\n", region_list, tmp_list);
00644 #endif
00645   verify_lists_are_equal (region, tmp);
00646   meta_rectangle_free_list_and_elements (tmp);
00647   meta_rectangle_free_list_and_elements (region);
00648 
00649   /*************************************************************/
00650   /* Make sure test region 4 has the right spanning rectangles */
00651   /*************************************************************/  
00652   region = get_screen_region (4);
00653   tmp = NULL;
00654   tmp = g_list_prepend (tmp, new_meta_rect ( 800,   20,  800, 1180));
00655   verify_lists_are_equal (region, tmp);
00656   meta_rectangle_free_list_and_elements (tmp);
00657   meta_rectangle_free_list_and_elements (region);
00658 
00659   /*************************************************************/
00660   /* Make sure test region 5 has the right spanning rectangles */
00661   /*************************************************************/  
00662   printf ("The next test intentionally causes a warning, "
00663           "but it can be ignored.\n");
00664   region = get_screen_region (5);
00665   verify_lists_are_equal (region, NULL);
00666 
00667   /* FIXME: Still to do:
00668    *   - Create random struts and check the regions somehow
00669    */
00670 
00671   printf ("%s passed.\n", G_STRFUNC);
00672 }
00673 
00674 static void
00675 test_region_fitting ()
00676 {
00677   GList* region;
00678   MetaRectangle rect;
00679 
00680   /* See test_basic_fitting() for how/why these automated random tests work */
00681   int i;
00682   region = get_screen_region (3);
00683   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00684     {
00685       get_random_rect (&rect);
00686       g_assert (meta_rectangle_contained_in_region (region, &rect) == FALSE ||
00687                 meta_rectangle_could_fit_in_region (region, &rect) == TRUE);
00688     }
00689   meta_rectangle_free_list_and_elements (region);
00690 
00691   /* Do some manual tests too */
00692   region = get_screen_region (1);
00693 
00694   rect = meta_rect (50, 50, 400, 400);
00695   g_assert (meta_rectangle_could_fit_in_region (region, &rect));
00696   g_assert (meta_rectangle_contained_in_region (region, &rect));
00697 
00698   rect = meta_rect (250, 0, 500, 1150);
00699   g_assert (!meta_rectangle_could_fit_in_region (region, &rect));
00700   g_assert (!meta_rectangle_contained_in_region (region, &rect));
00701 
00702   rect = meta_rect (250, 0, 400, 400);
00703   g_assert (meta_rectangle_could_fit_in_region (region, &rect));
00704   g_assert (!meta_rectangle_contained_in_region (region, &rect));
00705 
00706   meta_rectangle_free_list_and_elements (region);
00707 
00708   region = get_screen_region (2);
00709   rect = meta_rect (1000, 50, 600, 1100);
00710   g_assert (meta_rectangle_could_fit_in_region (region, &rect));
00711   g_assert (!meta_rectangle_contained_in_region (region, &rect));
00712 
00713   meta_rectangle_free_list_and_elements (region);
00714 
00715   printf ("%s passed.\n", G_STRFUNC);
00716 }
00717 
00718 static void
00719 test_clamping_to_region ()
00720 {
00721   GList* region;
00722   MetaRectangle rect;
00723   MetaRectangle min_size;
00724   FixedDirections fixed_directions;
00725   int i;
00726 
00727   min_size.height = min_size.width = 1;
00728   fixed_directions = 0;
00729 
00730   region = get_screen_region (3);
00731   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00732     {
00733       MetaRectangle temp;
00734       get_random_rect (&rect);
00735       temp = rect;
00736       meta_rectangle_clamp_to_fit_into_region (region,
00737                                                fixed_directions,
00738                                                &rect,
00739                                                &min_size);
00740       g_assert (meta_rectangle_could_fit_in_region (region, &rect) == TRUE);
00741       g_assert (rect.x == temp.x && rect.y == temp.y);
00742     }
00743   meta_rectangle_free_list_and_elements (region);
00744 
00745   /* Do some manual tests too */
00746   region = get_screen_region (1);
00747 
00748   rect = meta_rect (50, 50, 10000, 10000);
00749   meta_rectangle_clamp_to_fit_into_region (region,
00750                                            fixed_directions,
00751                                            &rect,
00752                                            &min_size);
00753   g_assert (rect.width == 1600 && rect.height == 1140);
00754 
00755   rect = meta_rect (275, -50, 410, 10000);
00756   meta_rectangle_clamp_to_fit_into_region (region,
00757                                            fixed_directions,
00758                                            &rect,
00759                                            &min_size);
00760   g_assert (rect.width == 400 && rect.height == 1180);
00761 
00762   rect = meta_rect (50, 50, 10000, 10000);
00763   min_size.height = 1170;
00764   meta_rectangle_clamp_to_fit_into_region (region,
00765                                            fixed_directions,
00766                                            &rect,
00767                                            &min_size);
00768   g_assert (rect.width == 400 && rect.height == 1180);
00769 
00770   printf ("The next test intentionally causes a warning, "
00771           "but it can be ignored.\n");
00772   rect = meta_rect (50, 50, 10000, 10000);
00773   min_size.width = 600;  min_size.height = 1170;
00774   meta_rectangle_clamp_to_fit_into_region (region,
00775                                            fixed_directions,
00776                                            &rect,
00777                                            &min_size);
00778   g_assert (rect.width == 600 && rect.height == 1170);
00779 
00780   rect = meta_rect (350, 50, 100, 1100);
00781   min_size.width = 1;  min_size.height = 1;
00782   fixed_directions = FIXED_DIRECTION_X;
00783   meta_rectangle_clamp_to_fit_into_region (region,
00784                                            fixed_directions,
00785                                            &rect,
00786                                            &min_size);
00787   g_assert (rect.width == 100 && rect.height == 1100);
00788 
00789   rect = meta_rect (300, 70, 500, 1100);
00790   min_size.width = 1;  min_size.height = 1;
00791   fixed_directions = FIXED_DIRECTION_Y;
00792   meta_rectangle_clamp_to_fit_into_region (region,
00793                                            fixed_directions,
00794                                            &rect,
00795                                            &min_size);
00796   g_assert (rect.width == 400 && rect.height == 1100);
00797 
00798   printf ("The next test intentionally causes a warning, "
00799           "but it can be ignored.\n");
00800   rect = meta_rect (300, 70, 999999, 999999);
00801   min_size.width = 100;  min_size.height = 200;
00802   fixed_directions = FIXED_DIRECTION_Y;
00803   meta_rectangle_clamp_to_fit_into_region (region,
00804                                            fixed_directions,
00805                                            &rect,
00806                                            &min_size);
00807   g_assert (rect.width == 100 && rect.height == 999999);
00808 
00809   meta_rectangle_free_list_and_elements (region);
00810 
00811   printf ("%s passed.\n", G_STRFUNC);
00812 }
00813 
00814 static gboolean
00815 rect_overlaps_region (const GList         *spanning_rects,
00816                       const MetaRectangle *rect)
00817 {
00818   /* FIXME: Should I move this to boxes.[ch]? */
00819   const GList *temp;
00820   gboolean     overlaps;
00821 
00822   temp = spanning_rects;
00823   overlaps = FALSE;
00824   while (!overlaps && temp != NULL)
00825     {
00826       overlaps = overlaps || meta_rectangle_overlap (temp->data, rect);
00827       temp = temp->next;
00828     }
00829 
00830   return overlaps;
00831 }
00832 
00833 gboolean time_to_print = FALSE;
00834 
00835 static void
00836 test_clipping_to_region ()
00837 {
00838   GList* region;
00839   MetaRectangle rect, temp;
00840   FixedDirections fixed_directions = 0;
00841   int i;
00842 
00843   region = get_screen_region (3);
00844   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00845     {
00846       get_random_rect (&rect);
00847       if (rect_overlaps_region (region, &rect))
00848         {
00849           meta_rectangle_clip_to_region (region, 0, &rect);
00850           g_assert (meta_rectangle_contained_in_region (region, &rect) == TRUE);
00851         }
00852     }
00853   meta_rectangle_free_list_and_elements (region);
00854 
00855   /* Do some manual tests too */
00856   region = get_screen_region (2);
00857 
00858   rect = meta_rect (-50, -10, 10000, 10000);
00859   meta_rectangle_clip_to_region (region,
00860                                  fixed_directions,
00861                                  &rect);
00862   g_assert (meta_rectangle_equal (region->data, &rect));
00863 
00864   rect = meta_rect (300, 1000, 400, 200);
00865   temp = meta_rect (300, 1000, 400, 150);
00866   meta_rectangle_clip_to_region (region,
00867                                  fixed_directions,
00868                                  &rect);
00869   g_assert (meta_rectangle_equal (&rect, &temp));
00870 
00871   rect = meta_rect (400, 1000, 300, 200);
00872   temp = meta_rect (450, 1000, 250, 200);
00873   meta_rectangle_clip_to_region (region,
00874                                  fixed_directions,
00875                                  &rect);
00876   g_assert (meta_rectangle_equal (&rect, &temp));
00877 
00878   rect = meta_rect (400, 1000, 300, 200);
00879   temp = meta_rect (400, 1000, 300, 150);
00880   meta_rectangle_clip_to_region (region,
00881                                  FIXED_DIRECTION_X,
00882                                  &rect);
00883   g_assert (meta_rectangle_equal (&rect, &temp));
00884 
00885   rect = meta_rect (400, 1000, 300, 200);
00886   temp = meta_rect (400, 1000, 300, 150);
00887   meta_rectangle_clip_to_region (region,
00888                                  FIXED_DIRECTION_X,
00889                                  &rect);
00890   g_assert (meta_rectangle_equal (&rect, &temp));
00891 
00892   meta_rectangle_free_list_and_elements (region);
00893 
00894   printf ("%s passed.\n", G_STRFUNC);
00895 }
00896 
00897 static void
00898 test_shoving_into_region ()
00899 {
00900   GList* region;
00901   MetaRectangle rect, temp;
00902   FixedDirections fixed_directions = 0;
00903   int i;
00904 
00905   region = get_screen_region (3);
00906   for (i = 0; i < NUM_RANDOM_RUNS; i++)
00907     {
00908       get_random_rect (&rect);
00909       if (meta_rectangle_could_fit_in_region (region, &rect))
00910         {
00911           meta_rectangle_shove_into_region (region, 0, &rect);
00912           g_assert (meta_rectangle_contained_in_region (region, &rect));
00913         }
00914     }
00915   meta_rectangle_free_list_and_elements (region);
00916 
00917   /* Do some manual tests too */
00918   region = get_screen_region (2);
00919 
00920   rect = meta_rect (300, 1000, 400, 200);
00921   temp = meta_rect (300,  950, 400, 200);
00922   meta_rectangle_shove_into_region (region,
00923                                     fixed_directions,
00924                                     &rect);
00925   g_assert (meta_rectangle_equal (&rect, &temp));
00926 
00927   rect = meta_rect (425, 1000, 300, 200);
00928   temp = meta_rect (450, 1000, 300, 200);
00929   meta_rectangle_shove_into_region (region,
00930                                     fixed_directions,
00931                                     &rect);
00932   g_assert (meta_rectangle_equal (&rect, &temp));
00933 
00934   rect = meta_rect (425, 1000, 300, 200);
00935   temp = meta_rect (425,  950, 300, 200);
00936   meta_rectangle_shove_into_region (region,
00937                                     FIXED_DIRECTION_X,
00938                                     &rect);
00939   g_assert (meta_rectangle_equal (&rect, &temp));
00940 
00941   rect = meta_rect ( 300, 1000, 400, 200);
00942   temp = meta_rect (1200, 1000, 400, 200);
00943   meta_rectangle_shove_into_region (region,
00944                                     FIXED_DIRECTION_Y,
00945                                     &rect);
00946   g_assert (meta_rectangle_equal (&rect, &temp));
00947 
00948   rect = meta_rect ( 800, 1150, 400,  50);  /* Completely "offscreen" :) */
00949   temp = meta_rect ( 800, 1050, 400,  50);
00950   meta_rectangle_shove_into_region (region,
00951                                     0,
00952                                     &rect);
00953   g_assert (meta_rectangle_equal (&rect, &temp));
00954 
00955   rect = meta_rect (-1000,  0, 400, 150);  /* Offscreen in 2 directions */
00956   temp = meta_rect (    0, 20, 400, 150);
00957   meta_rectangle_shove_into_region (region,
00958                                     0,
00959                                     &rect);
00960   g_assert (meta_rectangle_equal (&rect, &temp));
00961 
00962   meta_rectangle_free_list_and_elements (region);
00963 
00964   printf ("%s passed.\n", G_STRFUNC);
00965 }
00966 
00967 static void
00968 verify_edge_lists_are_equal (GList *code, GList *answer)
00969 {
00970   int which = 0;
00971 
00972   while (code && answer)
00973     {
00974       MetaEdge *a = code->data;
00975       MetaEdge *b = answer->data;
00976 
00977       if (!meta_rectangle_equal (&a->rect, &b->rect) ||
00978           a->side_type != b->side_type ||
00979           a->edge_type != b->edge_type)
00980         {
00981           g_error ("%dth item in code answer answer lists do not match; "
00982                    "code rect: %d,%d + %d,%d; answer rect: %d,%d + %d,%d\n",
00983                    which,
00984                    a->rect.x, a->rect.y, a->rect.width, a->rect.height,
00985                    b->rect.x, b->rect.y, b->rect.width, b->rect.height);
00986         }
00987 
00988       code = code->next;
00989       answer = answer->next;
00990 
00991       which++;
00992     }
00993 
00994   /* Ought to be at the end of both lists; check if we aren't */
00995   if (code)
00996     {
00997       MetaEdge *tmp = code->data;
00998       g_error ("code list longer than answer list by %d items; "
00999                "first extra item rect: %d,%d +%d,%d\n",
01000                g_list_length (code),
01001                tmp->rect.x, tmp->rect.y, tmp->rect.width, tmp->rect.height);
01002     }
01003 
01004   if (answer)
01005     {
01006       MetaEdge *tmp = answer->data;
01007       g_error ("answer list longer than code list by %d items; "
01008                "first extra item rect: %d,%d +%d,%d\n",
01009                g_list_length (answer),
01010                tmp->rect.x, tmp->rect.y, tmp->rect.width, tmp->rect.height);
01011     }
01012 }
01013 
01014 static void
01015 test_find_onscreen_edges ()
01016 {
01017   GList* edges;
01018   GList* tmp;
01019 
01020   int left   = META_DIRECTION_LEFT;
01021   int right  = META_DIRECTION_RIGHT;
01022   int top    = META_DIRECTION_TOP;
01023   int bottom = META_DIRECTION_BOTTOM;
01024 
01025   /*************************************************/  
01026   /* Make sure test region 0 has the correct edges */
01027   /*************************************************/  
01028   edges = get_screen_edges (0);
01029   tmp = NULL;
01030   tmp = g_list_prepend (tmp, new_screen_edge (   0, 1200, 1600, 0, bottom));
01031   tmp = g_list_prepend (tmp, new_screen_edge (   0,    0, 1600, 0, top));
01032   tmp = g_list_prepend (tmp, new_screen_edge (1600,    0, 0, 1200, right));
01033   tmp = g_list_prepend (tmp, new_screen_edge (   0,    0, 0, 1200, left));
01034   verify_edge_lists_are_equal (edges, tmp);
01035   meta_rectangle_free_list_and_elements (tmp);
01036   meta_rectangle_free_list_and_elements (edges);
01037 
01038   /*************************************************/  
01039   /* Make sure test region 1 has the correct edges */
01040   /*************************************************/  
01041   edges = get_screen_edges (1);
01042   tmp = NULL;
01043   tmp = g_list_prepend (tmp, new_screen_edge (   0, 1200,  400, 0, bottom));
01044   tmp = g_list_prepend (tmp, new_screen_edge ( 400, 1160, 1200, 0, bottom));
01045   tmp = g_list_prepend (tmp, new_screen_edge (   0,   20, 1600, 0, top));
01046   tmp = g_list_prepend (tmp, new_screen_edge (1600,   20, 0, 1140, right));
01047   tmp = g_list_prepend (tmp, new_screen_edge ( 400, 1160, 0,   40, right));
01048   tmp = g_list_prepend (tmp, new_screen_edge (   0,   20, 0, 1180, left));
01049   verify_edge_lists_are_equal (edges, tmp);
01050   meta_rectangle_free_list_and_elements (tmp);
01051   meta_rectangle_free_list_and_elements (edges);
01052 
01053   /*************************************************/  
01054   /* Make sure test region 2 has the correct edges */
01055   /*************************************************/  
01056   edges = get_screen_edges (2);
01057   tmp = NULL;
01058   tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200,  400, 0, bottom));
01059   tmp = g_list_prepend (tmp, new_screen_edge ( 450, 1200,  350, 0, bottom));
01060   tmp = g_list_prepend (tmp, new_screen_edge (   0, 1200,  300, 0, bottom));
01061   tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150,  150, 0, bottom));
01062   tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100,  400, 0, bottom));
01063   tmp = g_list_prepend (tmp, new_screen_edge (   0,   20, 1600, 0, top));
01064   tmp = g_list_prepend (tmp, new_screen_edge (1600,   20, 0, 1180, right));
01065   tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 0,  100, right));
01066   tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 0,   50, right));
01067   tmp = g_list_prepend (tmp, new_screen_edge (1200, 1100, 0,  100, left));
01068   tmp = g_list_prepend (tmp, new_screen_edge ( 450, 1150, 0,   50, left));
01069   tmp = g_list_prepend (tmp, new_screen_edge (   0,   20, 0, 1180, left));
01070   verify_edge_lists_are_equal (edges, tmp);
01071   meta_rectangle_free_list_and_elements (tmp);
01072   meta_rectangle_free_list_and_elements (edges);
01073 
01074   /*************************************************/  
01075   /* Make sure test region 3 has the correct edges */
01076   /*************************************************/  
01077   edges = get_screen_edges (3);
01078   tmp = NULL;
01079   tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200,  400, 0, bottom));
01080   tmp = g_list_prepend (tmp, new_screen_edge ( 380, 1200,  420, 0, bottom));
01081   tmp = g_list_prepend (tmp, new_screen_edge (   0, 1200,  300, 0, bottom));
01082   tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150,   80, 0, bottom));
01083   tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100,  400, 0, bottom));
01084   tmp = g_list_prepend (tmp, new_screen_edge ( 700,  525, 200,  0, bottom));
01085   tmp = g_list_prepend (tmp, new_screen_edge ( 700,  675, 200,  0, top));
01086   tmp = g_list_prepend (tmp, new_screen_edge (   0,   20, 1600, 0, top));
01087   tmp = g_list_prepend (tmp, new_screen_edge (1600,   20, 0, 1180, right));
01088   tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 0,  100, right));
01089   tmp = g_list_prepend (tmp, new_screen_edge ( 700,  525, 0,  150, right));
01090   tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 0,   50, right));
01091   tmp = g_list_prepend (tmp, new_screen_edge (1200, 1100, 0,  100, left));
01092   tmp = g_list_prepend (tmp, new_screen_edge ( 900,  525, 0,  150, left));
01093   tmp = g_list_prepend (tmp, new_screen_edge ( 380, 1150, 0,   50, left));
01094   tmp = g_list_prepend (tmp, new_screen_edge (   0,   20, 0, 1180, left));
01095 
01096 #if 0
01097   #define FUDGE 50 /* number of edges */
01098   char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
01099   meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
01100   meta_rectangle_edge_list_to_string (tmp,   "\n ", big_buffer2);
01101   printf("Generated edge list:\n %s\nComparison edges list:\n %s\n", 
01102          big_buffer1, big_buffer2);
01103 #endif
01104 
01105   verify_edge_lists_are_equal (edges, tmp);
01106   meta_rectangle_free_list_and_elements (tmp);
01107   meta_rectangle_free_list_and_elements (edges);
01108 
01109   /*************************************************/  
01110   /* Make sure test region 4 has the correct edges */
01111   /*************************************************/  
01112   edges = get_screen_edges (4);
01113   tmp = NULL;
01114   tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1200, 800,  0, bottom));
01115   tmp = g_list_prepend (tmp, new_screen_edge ( 800,   20, 800,  0, top));
01116   tmp = g_list_prepend (tmp, new_screen_edge (1600,   20, 0, 1180, right));
01117   tmp = g_list_prepend (tmp, new_screen_edge ( 800,   20, 0, 1180, left));
01118   verify_edge_lists_are_equal (edges, tmp);
01119   meta_rectangle_free_list_and_elements (tmp);
01120   meta_rectangle_free_list_and_elements (edges);
01121 
01122   /*************************************************/  
01123   /* Make sure test region 5 has the correct edges */
01124   /*************************************************/  
01125   edges = get_screen_edges (5);
01126   tmp = NULL;
01127   verify_edge_lists_are_equal (edges, tmp);
01128   meta_rectangle_free_list_and_elements (tmp);
01129   meta_rectangle_free_list_and_elements (edges);
01130 
01131   /*************************************************/  
01132   /* Make sure test region 6 has the correct edges */
01133   /*************************************************/  
01134   edges = get_screen_edges (6);
01135   tmp = NULL;
01136   tmp = g_list_prepend (tmp, new_screen_edge (   0, 1200, 1600,  0, bottom));
01137   tmp = g_list_prepend (tmp, new_screen_edge (   0,   40, 1600,  0, top));
01138   tmp = g_list_prepend (tmp, new_screen_edge (1600,   40, 0,  1160, right));
01139   tmp = g_list_prepend (tmp, new_screen_edge (   0,   40, 0,  1160, left));
01140   verify_edge_lists_are_equal (edges, tmp);
01141   meta_rectangle_free_list_and_elements (tmp);
01142   meta_rectangle_free_list_and_elements (edges);
01143 
01144   printf ("%s passed.\n", G_STRFUNC);
01145 }
01146 
01147 static void
01148 test_find_nonintersected_xinerama_edges ()
01149 {
01150   GList* edges;
01151   GList* tmp;
01152 
01153   int left   = META_DIRECTION_LEFT;
01154   int right  = META_DIRECTION_RIGHT;
01155   int top    = META_DIRECTION_TOP;
01156   int bottom = META_DIRECTION_BOTTOM;
01157 
01158   /*************************************************************************/  
01159   /* Make sure test xinerama set 0 for with region 0 has the correct edges */
01160   /*************************************************************************/  
01161   edges = get_xinerama_edges (0, 0);
01162   tmp = NULL;
01163   verify_edge_lists_are_equal (edges, tmp);
01164   meta_rectangle_free_list_and_elements (tmp);
01165   meta_rectangle_free_list_and_elements (edges);
01166 
01167   /*************************************************************************/  
01168   /* Make sure test xinerama set 2 for with region 1 has the correct edges */
01169   /*************************************************************************/  
01170   edges = get_xinerama_edges (2, 1);
01171   tmp = NULL;
01172   tmp = g_list_prepend (tmp, new_xinerama_edge (   0,  600, 1600, 0, bottom));
01173   tmp = g_list_prepend (tmp, new_xinerama_edge (   0,  600, 1600, 0, top));
01174   verify_edge_lists_are_equal (edges, tmp);
01175   meta_rectangle_free_list_and_elements (tmp);
01176   meta_rectangle_free_list_and_elements (edges);
01177 
01178   /*************************************************************************/  
01179   /* Make sure test xinerama set 1 for with region 2 has the correct edges */
01180   /*************************************************************************/  
01181   edges = get_xinerama_edges (1, 2);
01182   tmp = NULL;
01183   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,   20, 0, 1080, right));
01184   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,   20, 0, 1180, left));
01185 #if 0
01186   #define FUDGE 50
01187   char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
01188   meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
01189   meta_rectangle_edge_list_to_string (tmp,   "\n ", big_buffer2);
01190   printf("Generated edge list:\n %s\nComparison edges list:\n %s\n", 
01191          big_buffer1, big_buffer2);
01192 #endif
01193   verify_edge_lists_are_equal (edges, tmp);
01194   meta_rectangle_free_list_and_elements (tmp);
01195   meta_rectangle_free_list_and_elements (edges);
01196 
01197   /*************************************************************************/  
01198   /* Make sure test xinerama set 3 for with region 3 has the correct edges */
01199   /*************************************************************************/  
01200   edges = get_xinerama_edges (3, 3);
01201   tmp = NULL;
01202   tmp = g_list_prepend (tmp, new_xinerama_edge ( 900,  600,  700, 0, bottom));
01203   tmp = g_list_prepend (tmp, new_xinerama_edge (   0,  600,  700, 0, bottom));
01204   tmp = g_list_prepend (tmp, new_xinerama_edge ( 900,  600,  700, 0, top));
01205   tmp = g_list_prepend (tmp, new_xinerama_edge (   0,  600,  700, 0, top));
01206   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,  675, 0,  425, right));
01207   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,  675, 0,  525, left));
01208   verify_edge_lists_are_equal (edges, tmp);
01209   meta_rectangle_free_list_and_elements (tmp);
01210   meta_rectangle_free_list_and_elements (edges);
01211 
01212   /*************************************************************************/  
01213   /* Make sure test xinerama set 3 for with region 4 has the correct edges */
01214   /*************************************************************************/  
01215   edges = get_xinerama_edges (3, 4);
01216   tmp = NULL;
01217   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,  600,  800, 0, bottom));
01218   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,  600,  800, 0, top));
01219   tmp = g_list_prepend (tmp, new_xinerama_edge ( 800,  600,  0, 600, right));
01220   verify_edge_lists_are_equal (edges, tmp);
01221   meta_rectangle_free_list_and_elements (tmp);
01222   meta_rectangle_free_list_and_elements (edges);
01223 
01224   /*************************************************************************/  
01225   /* Make sure test xinerama set 3 for with region 5has the correct edges */
01226   /*************************************************************************/  
01227   edges = get_xinerama_edges (3, 5);
01228   tmp = NULL;
01229   verify_edge_lists_are_equal (edges, tmp);
01230   meta_rectangle_free_list_and_elements (tmp);
01231   meta_rectangle_free_list_and_elements (edges);
01232 
01233   printf ("%s passed.\n", G_STRFUNC);
01234 }
01235 
01236 static void
01237 test_gravity_resize ()
01238 {
01239   MetaRectangle oldrect, rect, temp;
01240 
01241   rect.x = -500;  /* Some random amount not equal to oldrect.x to ensure that
01242                    * the resize is done with respect to oldrect instead of rect
01243                    */
01244   oldrect = meta_rect ( 50,  300, 250, 400);
01245   temp    = meta_rect ( 50,  300,  20,   5);
01246   meta_rectangle_resize_with_gravity (&oldrect,
01247                                       &rect,
01248                                       NorthWestGravity,
01249                                       20,
01250                                       5);
01251   g_assert (meta_rectangle_equal (&rect, &temp));
01252 
01253   rect = meta_rect ( 50,  300, 250, 400);
01254   temp = meta_rect (165,  300,  20,   5);
01255   meta_rectangle_resize_with_gravity (&rect,
01256                                       &rect,
01257                                       NorthGravity,
01258                                       20,
01259                                       5);
01260   g_assert (meta_rectangle_equal (&rect, &temp));
01261 
01262   rect = meta_rect ( 50,  300, 250, 400);
01263   temp = meta_rect (280,  300,  20,   5);
01264   meta_rectangle_resize_with_gravity (&rect,
01265                                       &rect,
01266                                       NorthEastGravity,
01267                                       20,
01268                                       5);
01269   g_assert (meta_rectangle_equal (&rect, &temp));
01270 
01271   rect = meta_rect ( 50,  300, 250, 400);
01272   temp = meta_rect ( 50,  695,  50,   5);
01273   meta_rectangle_resize_with_gravity (&rect,
01274                                       &rect,
01275                                       SouthWestGravity,
01276                                       50,
01277                                       5);
01278   g_assert (meta_rectangle_equal (&rect, &temp));
01279 
01280   rect = meta_rect ( 50,  300, 250, 400);
01281   temp = meta_rect (150,  695,  50,   5);
01282   meta_rectangle_resize_with_gravity (&rect,
01283                                       &rect,
01284                                       SouthGravity,
01285                                       50,
01286                                       5);
01287   g_assert (meta_rectangle_equal (&rect, &temp));
01288 
01289   rect = meta_rect ( 50,  300, 250, 400);
01290   temp = meta_rect (250,  695,  50,   5);
01291   meta_rectangle_resize_with_gravity (&rect,
01292                                       &rect,
01293                                       SouthEastGravity,
01294                                       50,
01295                                       5);
01296   g_assert (meta_rectangle_equal (&rect, &temp));
01297 
01298   rect = meta_rect (167,  738, 237, 843);
01299   temp = meta_rect (167, 1113, 832,  93);
01300   meta_rectangle_resize_with_gravity (&rect,
01301                                       &rect,
01302                                       WestGravity,
01303                                       832,
01304                                       93);
01305   g_assert (meta_rectangle_equal (&rect, &temp));
01306 
01307   rect = meta_rect ( 167,  738, 237, 843);
01308   temp = meta_rect (-131, 1113, 833,  93);
01309   meta_rectangle_resize_with_gravity (&rect,
01310                                       &rect,
01311                                       CenterGravity,
01312                                       832,
01313                                       93);
01314   g_assert (meta_rectangle_equal (&rect, &temp));
01315 
01316   rect = meta_rect (300, 1000, 400, 200);
01317   temp = meta_rect (270,  994, 430, 212);
01318   meta_rectangle_resize_with_gravity (&rect,
01319                                       &rect,
01320                                       EastGravity,
01321                                       430,
01322                                       211);
01323   g_assert (meta_rectangle_equal (&rect, &temp));
01324 
01325   rect = meta_rect (300, 1000, 400, 200);
01326   temp = meta_rect (300, 1000, 430, 211);
01327   meta_rectangle_resize_with_gravity (&rect,
01328                                       &rect,
01329                                       StaticGravity,
01330                                       430,
01331                                       211);
01332   g_assert (meta_rectangle_equal (&rect, &temp));
01333 
01334   printf ("%s passed.\n", G_STRFUNC);
01335 }
01336 
01337 static void
01338 test_find_closest_point_to_line ()
01339 {
01340   double x1, y1, x2, y2, px, py, rx, ry;
01341   double answer_x, answer_y;
01342 
01343   x1 =  3.0;  y1 =  49.0;
01344   x2 =  2.0;  y2 = - 1.0;
01345   px = -2.6;  py =  19.1;
01346   answer_x = 2.4; answer_y = 19;
01347   meta_rectangle_find_linepoint_closest_to_point (x1,  y1,
01348                                                   x2,  y2,
01349                                                   px,  py,
01350                                                   &rx, &ry);
01351   g_assert (rx == answer_x && ry == answer_y);
01352 
01353   /* Special test for x1 == x2, so that slop of line is infinite */
01354   x1 =  3.0;  y1 =  49.0;
01355   x2 =  3.0;  y2 = - 1.0;
01356   px = -2.6;  py =  19.1;
01357   answer_x = 3.0; answer_y = 19.1;
01358   meta_rectangle_find_linepoint_closest_to_point (x1,  y1,
01359                                                   x2,  y2,
01360                                                   px,  py,
01361                                                   &rx, &ry);
01362   g_assert (rx == answer_x && ry == answer_y);
01363 
01364   /* Special test for y1 == y2, so perp line has slope of infinity */
01365   x1 =  3.14;  y1 =   7.0;
01366   x2 =  2.718; y2 =   7.0;
01367   px = -2.6;   py =  19.1;
01368   answer_x = -2.6; answer_y = 7;
01369   meta_rectangle_find_linepoint_closest_to_point (x1,  y1,
01370                                                   x2,  y2,
01371                                                   px,  py,
01372                                                   &rx, &ry);
01373   g_assert (rx == answer_x && ry == answer_y);
01374 
01375   /* Test when we the point we want to be closest to is actually on the line */
01376   x1 =  3.0;  y1 =  49.0;
01377   x2 =  2.0;  y2 = - 1.0;
01378   px =  2.4;  py =  19.0;
01379   answer_x = 2.4; answer_y = 19;
01380   meta_rectangle_find_linepoint_closest_to_point (x1,  y1,
01381                                                   x2,  y2,
01382                                                   px,  py,
01383                                                   &rx, &ry);
01384   g_assert (rx == answer_x && ry == answer_y);
01385 
01386   printf ("%s passed.\n", G_STRFUNC);
01387 }
01388 
01389 int
01390 main()
01391 {
01392   init_random_ness ();
01393   test_area ();
01394   test_intersect ();
01395   test_equal ();
01396   test_overlap_funcs ();
01397   test_basic_fitting ();
01398 
01399   test_regions_okay ();
01400   test_region_fitting ();
01401 
01402   test_clamping_to_region ();
01403   test_clipping_to_region ();
01404   test_shoving_into_region ();
01405 
01406   /* And now the functions dealing with edges more than boxes */
01407   test_find_onscreen_edges ();
01408   test_find_nonintersected_xinerama_edges ();
01409 
01410   /* And now the misfit functions that don't quite fit in anywhere else... */
01411   test_gravity_resize ();
01412   test_find_closest_point_to_line ();
01413 
01414   printf ("All tests passed.\n");
01415   return 0;
01416 }

Generated on Sat Aug 23 22:04:17 2008 for metacity by  doxygen 1.5.5