summaryrefslogtreecommitdiff
path: root/src/wm-tester/test-gravity.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wm-tester/test-gravity.c')
-rw-r--r--src/wm-tester/test-gravity.c308
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.
+ */
+}
+