diff options
Diffstat (limited to 'src/wm-tester/test-gravity.c')
-rw-r--r-- | src/wm-tester/test-gravity.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/src/wm-tester/test-gravity.c b/src/wm-tester/test-gravity.c new file mode 100644 index 00000000..8e5b581c --- /dev/null +++ b/src/wm-tester/test-gravity.c @@ -0,0 +1,308 @@ +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <stdio.h> +#include <string.h> + +static int gravities[10] = { + NorthWestGravity, + NorthGravity, + NorthEastGravity, + WestGravity, + CenterGravity, + EastGravity, + SouthWestGravity, + SouthGravity, + SouthEastGravity, + StaticGravity +}; + +typedef struct +{ + int x, y, width, height; +} Rectangle; + +static Window windows[10]; +static int doubled[10] = { 0, }; +static Rectangle window_rects[10]; + +#define WINDOW_WIDTH 100 +#define WINDOW_HEIGHT 100 + +static int x_offset[3] = { 0, - WINDOW_WIDTH/2, -WINDOW_WIDTH }; +static int y_offset[3] = { 0, - WINDOW_HEIGHT/2, -WINDOW_HEIGHT }; +static double screen_x_fraction[3] = { 0, 0.5, 1.0 }; +static double screen_y_fraction[3] = { 0, 0.5, 1.0 }; +static int screen_width; +static int screen_height; + +static const char* +window_gravity_to_string (int gravity) +{ + switch (gravity) + { + case NorthWestGravity: + return "NorthWestGravity"; + case NorthGravity: + return "NorthGravity"; + case NorthEastGravity: + return "NorthEastGravity"; + case WestGravity: + return "WestGravity"; + case CenterGravity: + return "CenterGravity"; + case EastGravity: + return "EastGravity"; + case SouthWestGravity: + return "SouthWestGravity"; + case SouthGravity: + return "SouthGravity"; + case SouthEastGravity: + return "SouthEastGravity"; + case StaticGravity: + return "StaticGravity"; + default: + return "NorthWestGravity"; + } +} + +static void +calculate_position (int i, int doubled, int *x, int *y) +{ + if (i == 9) + { + *x = 150; + *y = 150; + } + else + { + int xoff = x_offset[i % 3]; + int yoff = y_offset[i / 3]; + if (doubled) + { + xoff *= 2; + yoff *= 2; + } + + *x = screen_x_fraction[i % 3] * screen_width + xoff; + *y = screen_y_fraction[i / 3] * screen_height + yoff; + } +} + +static int +find_window (Window window) +{ + int i; + for (i=0; i<10; i++) + { + if (windows[i] == window) + return i; + } + + return -1; +} + +typedef struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +int main (int argc, char **argv) +{ + Display *d; + Window w; + XSizeHints hints; + int i; + int screen; + XEvent ev; + int noframes; + + if (argc > 1 && strcmp (argv[1], "--noframes") == 0) + noframes = 1; + else + noframes = 0; + + d = XOpenDisplay (NULL); + + screen = DefaultScreen (d); + screen_width = DisplayWidth (d, screen); + screen_height = DisplayHeight (d, screen); + + for (i=0; i<10; i++) + { + int x, y; + + calculate_position (i, doubled[i], &x, &y); + + w = XCreateSimpleWindow (d, RootWindow (d, screen), + x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0, + WhitePixel (d, screen), WhitePixel (d, screen)); + + windows[i] = w; + window_rects[i].x = x; + window_rects[i].y = y; + window_rects[i].width = WINDOW_WIDTH; + window_rects[i].height = WINDOW_HEIGHT; + + XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask); + + hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity; + + hints.min_width = WINDOW_WIDTH / 2; + hints.min_height = WINDOW_HEIGHT / 2; + +#if 1 + /* we constrain max size below the "doubled" size so that + * the WM will have to deal with constraints + * at the same time it's dealing with configure request + */ + hints.max_width = WINDOW_WIDTH * 2 - WINDOW_WIDTH / 2; + hints.max_height = WINDOW_HEIGHT * 2 - WINDOW_HEIGHT / 2; +#else + hints.max_width = WINDOW_WIDTH * 2 + WINDOW_WIDTH / 2; + hints.max_height = WINDOW_HEIGHT * 2 + WINDOW_HEIGHT / 2; +#endif + hints.win_gravity = gravities[i]; + + XSetWMNormalHints (d, w, &hints); + + XStoreName (d, w, window_gravity_to_string (hints.win_gravity)); + + if (noframes) + { + MotifWmHints mwm; + Atom mwm_atom; + + mwm.decorations = 0; + mwm.flags = MWM_HINTS_DECORATIONS; + + mwm_atom = XInternAtom (d, "_MOTIF_WM_HINTS", False); + + XChangeProperty (d, w, mwm_atom, mwm_atom, + 32, PropModeReplace, + (unsigned char *)&mwm, + sizeof (MotifWmHints)/sizeof (long)); + } + + XMapWindow (d, w); + } + + while (1) + { + XNextEvent (d, &ev); + + if (ev.xany.type == ConfigureNotify) + { + i = find_window (ev.xconfigure.window); + + if (i >= 0) + { + Window ignored; + + window_rects[i].width = ev.xconfigure.width; + window_rects[i].height = ev.xconfigure.height; + + XClearArea (d, windows[i], 0, 0, + ev.xconfigure.width, + ev.xconfigure.height, + True); + + if (!ev.xconfigure.send_event) + XTranslateCoordinates (d, windows[i], DefaultRootWindow (d), + 0, 0, + &window_rects[i].x, &window_rects[i].y, + &ignored); + else + { + window_rects[i].x = ev.xconfigure.x; + window_rects[i].y = ev.xconfigure.y; + } + } + } + else if (ev.xany.type == Expose) + { + i = find_window (ev.xexpose.window); + + if (i >= 0) + { + GC gc; + XGCValues values; + char buf[256]; + + values.foreground = BlackPixel (d, screen); + + gc = XCreateGC (d, windows[i], + GCForeground, &values); + + sprintf (buf, + "%d,%d", + window_rects[i].x, + window_rects[i].y); + + XDrawString (d, windows[i], gc, 10, 15, + buf, strlen (buf)); + + sprintf (buf, + "%dx%d", + window_rects[i].width, + window_rects[i].height); + + XDrawString (d, windows[i], gc, 10, 35, + buf, strlen (buf)); + + XFreeGC (d, gc); + } + } + else if (ev.xany.type == ButtonPress) + { + i = find_window (ev.xbutton.window); + + if (i >= 0) + { + /* Button 1 = move, 2 = resize, 3 = both at once */ + + if (ev.xbutton.button == Button1) + { + int x, y; + + calculate_position (i, doubled[i], &x, &y); + XMoveWindow (d, windows[i], x, y); + } + else if (ev.xbutton.button == Button2) + { + if (doubled[i]) + XResizeWindow (d, windows[i], WINDOW_WIDTH, WINDOW_HEIGHT); + else + XResizeWindow (d, windows[i], WINDOW_WIDTH*2, WINDOW_HEIGHT*2); + + doubled[i] = !doubled[i]; + } + else if (ev.xbutton.button == Button3) + { + int x, y; + + calculate_position (i, !doubled[i], &x, &y); + + if (doubled[i]) + XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH, WINDOW_HEIGHT); + else + XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH*2, WINDOW_HEIGHT*2); + + doubled[i] = !doubled[i]; + } + } + } + } + + /* This program has an infinite loop above so a return statement would + * just cause compiler warnings. + */ +} + |