test-gravity.c

Go to the documentation of this file.
00001 #include <X11/Xlib.h>
00002 #include <X11/Xutil.h>
00003 #include <stdio.h>
00004 #include <string.h>
00005 
00006 static int gravities[10] = {
00007   NorthWestGravity, 
00008   NorthGravity,  
00009   NorthEastGravity,
00010   WestGravity,      
00011   CenterGravity, 
00012   EastGravity,
00013   SouthWestGravity,
00014   SouthGravity,
00015   SouthEastGravity,
00016   StaticGravity
00017 };
00018 
00019 typedef struct
00020 {
00021   int x, y, width, height;
00022 } Rectangle;
00023 
00024 static Window windows[10];
00025 static int doubled[10] = { 0, };
00026 static Rectangle window_rects[10];
00027 
00028 #define WINDOW_WIDTH 100
00029 #define WINDOW_HEIGHT 100
00030 
00031 static int x_offset[3] = { 0, - WINDOW_WIDTH/2,  -WINDOW_WIDTH };
00032 static int y_offset[3] = { 0, - WINDOW_HEIGHT/2,  -WINDOW_HEIGHT };
00033 static double screen_x_fraction[3] = { 0, 0.5, 1.0 };
00034 static double screen_y_fraction[3] = { 0, 0.5, 1.0 };
00035 static int screen_width;
00036 static int screen_height;
00037 
00038 static const char*
00039 window_gravity_to_string (int gravity)
00040 {
00041   switch (gravity)
00042     {
00043     case NorthWestGravity:
00044       return "NorthWestGravity";
00045     case NorthGravity:
00046       return "NorthGravity";
00047     case NorthEastGravity:
00048       return "NorthEastGravity";
00049     case WestGravity:
00050       return "WestGravity";
00051     case CenterGravity:
00052       return "CenterGravity";
00053     case EastGravity:
00054       return "EastGravity";
00055     case SouthWestGravity:
00056       return "SouthWestGravity";
00057     case SouthGravity:
00058       return "SouthGravity";
00059     case SouthEastGravity:
00060       return "SouthEastGravity";
00061     case StaticGravity:
00062       return "StaticGravity";
00063     default:
00064       return "NorthWestGravity";
00065     }
00066 }
00067 
00068 static void
00069 calculate_position (int i, int doubled, int *x, int *y)
00070 {
00071   if (i == 9)
00072     {
00073       *x = 150;
00074       *y = 150;
00075     }
00076   else 
00077     {
00078       int xoff = x_offset[i % 3];
00079       int yoff = y_offset[i / 3];
00080       if (doubled)
00081         {
00082           xoff *= 2;
00083           yoff *= 2;
00084         }
00085       
00086       *x = screen_x_fraction[i % 3] * screen_width + xoff;
00087       *y = screen_y_fraction[i / 3] * screen_height + yoff;
00088     }
00089 }
00090 
00091 static int
00092 find_window (Window window)
00093 {
00094   int i;
00095   for (i=0; i<10; i++)
00096     {
00097       if (windows[i] == window)
00098         return i;
00099     }
00100 
00101   return -1;
00102 }
00103 
00104 typedef struct {
00105     unsigned long flags;
00106     unsigned long functions;
00107     unsigned long decorations;
00108     long input_mode;
00109     unsigned long status;
00110 } MotifWmHints, MwmHints;
00111 
00112 #define MWM_HINTS_FUNCTIONS     (1L << 0)
00113 #define MWM_HINTS_DECORATIONS   (1L << 1)
00114 #define MWM_HINTS_INPUT_MODE    (1L << 2)
00115 #define MWM_HINTS_STATUS        (1L << 3)
00116 
00117 int main (int argc, char **argv)
00118 {
00119   Display *d;
00120   Window w;
00121   XSizeHints hints;
00122   int i;
00123   int screen;
00124   XEvent ev;
00125   int noframes;
00126   
00127   if (argc > 1 && strcmp (argv[1], "--noframes") == 0)
00128     noframes = 1;
00129   else
00130     noframes = 0;
00131   
00132   d = XOpenDisplay (NULL);
00133 
00134   screen = DefaultScreen (d);
00135   screen_width = DisplayWidth (d, screen);
00136   screen_height = DisplayHeight (d, screen);
00137 
00138   for (i=0; i<10; i++)
00139     {
00140       int x, y;
00141       
00142       calculate_position (i, doubled[i], &x, &y);
00143 
00144       w = XCreateSimpleWindow (d, RootWindow (d, screen), 
00145                                x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 
00146                                WhitePixel (d, screen), WhitePixel (d, screen));
00147 
00148       windows[i] = w;
00149       window_rects[i].x = x;
00150       window_rects[i].y = y;
00151       window_rects[i].width = WINDOW_WIDTH;
00152       window_rects[i].height = WINDOW_HEIGHT;
00153       
00154       XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask);
00155       
00156       hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity;
00157       
00158       hints.min_width = WINDOW_WIDTH / 2;
00159       hints.min_height = WINDOW_HEIGHT / 2;
00160 
00161 #if 1
00162       /* we constrain max size below the "doubled" size so that
00163        * the WM will have to deal with constraints
00164        * at the same time it's dealing with configure request
00165        */
00166       hints.max_width = WINDOW_WIDTH * 2 - WINDOW_WIDTH / 2;
00167       hints.max_height = WINDOW_HEIGHT * 2 - WINDOW_HEIGHT / 2;
00168 #else
00169       hints.max_width = WINDOW_WIDTH * 2 + WINDOW_WIDTH / 2;
00170       hints.max_height = WINDOW_HEIGHT * 2 + WINDOW_HEIGHT / 2;
00171 #endif
00172       hints.win_gravity = gravities[i];
00173       
00174       XSetWMNormalHints (d, w, &hints);
00175 
00176       XStoreName (d, w, window_gravity_to_string (hints.win_gravity));
00177 
00178       if (noframes)
00179         {
00180           MotifWmHints mwm;
00181           Atom mwm_atom;
00182           
00183           mwm.decorations = 0;
00184           mwm.flags = MWM_HINTS_DECORATIONS;
00185           
00186           mwm_atom = XInternAtom (d, "_MOTIF_WM_HINTS", False);
00187 
00188           XChangeProperty (d, w, mwm_atom, mwm_atom,
00189                            32, PropModeReplace,
00190                            (unsigned char *)&mwm,
00191                            sizeof (MotifWmHints)/sizeof (long));
00192         }
00193       
00194       XMapWindow (d, w);
00195     }
00196 
00197   while (1)
00198     {
00199       XNextEvent (d, &ev);
00200 
00201       if (ev.xany.type == ConfigureNotify)
00202         {
00203           i = find_window (ev.xconfigure.window);
00204           
00205           if (i >= 0)
00206             {
00207               Window ignored;
00208               
00209               window_rects[i].width = ev.xconfigure.width;
00210               window_rects[i].height = ev.xconfigure.height;
00211               
00212               XClearArea (d, windows[i], 0, 0,
00213                           ev.xconfigure.width,
00214                           ev.xconfigure.height,
00215                           True);
00216 
00217               if (!ev.xconfigure.send_event)
00218                 XTranslateCoordinates (d, windows[i], DefaultRootWindow (d),
00219                                        0, 0,
00220                                        &window_rects[i].x, &window_rects[i].y,
00221                                        &ignored);
00222               else
00223                 {
00224                   window_rects[i].x = ev.xconfigure.x;
00225                   window_rects[i].y = ev.xconfigure.y;
00226                 }
00227             }
00228         }
00229       else if (ev.xany.type == Expose)
00230         {          
00231           i = find_window (ev.xexpose.window);
00232           
00233           if (i >= 0)
00234             {
00235               GC gc;
00236               XGCValues values;
00237               char buf[256];
00238               
00239               values.foreground = BlackPixel (d, screen);
00240               
00241               gc = XCreateGC (d, windows[i],
00242                               GCForeground, &values);
00243 
00244               sprintf (buf,
00245                        "%d,%d",
00246                        window_rects[i].x,
00247                        window_rects[i].y);
00248               
00249               XDrawString (d, windows[i], gc, 10, 15,
00250                            buf, strlen (buf));
00251 
00252               sprintf (buf,
00253                        "%dx%d",
00254                        window_rects[i].width,
00255                        window_rects[i].height);
00256               
00257               XDrawString (d, windows[i], gc, 10, 35,
00258                            buf, strlen (buf));
00259               
00260               XFreeGC (d, gc);
00261             }
00262         }
00263       else if (ev.xany.type == ButtonPress)
00264         {
00265           i = find_window (ev.xbutton.window);
00266 
00267           if (i >= 0)
00268             {
00269               /* Button 1 = move, 2 = resize, 3 = both at once */
00270                   
00271               if (ev.xbutton.button == Button1) 
00272                 { 
00273                   int x, y;
00274                       
00275                   calculate_position (i, doubled[i], &x, &y);
00276                   XMoveWindow (d, windows[i], x, y); 
00277                 }
00278               else if (ev.xbutton.button == Button2)
00279                 {
00280                   if (doubled[i])
00281                     XResizeWindow (d, windows[i], WINDOW_WIDTH, WINDOW_HEIGHT);
00282                   else
00283                     XResizeWindow (d, windows[i], WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
00284 
00285                   doubled[i] = !doubled[i];
00286                 }
00287               else if (ev.xbutton.button == Button3)
00288                 {
00289                   int x, y;
00290                       
00291                   calculate_position (i, !doubled[i], &x, &y);
00292 
00293                   if (doubled[i])
00294                     XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
00295                   else
00296                     XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
00297 
00298                   doubled[i] = !doubled[i];
00299                 }
00300             }
00301         }
00302     }
00303 
00304   /* This program has an infinite loop above so a return statement would
00305    * just cause compiler warnings.
00306    */
00307 }
00308 

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