#include #include #include #include static void calc_rects (XRectangle *rects, int width, int height) { int w = (width - 21) / 3; int h = (height - 21) / 3; int i; i = 0; while (i < 9) { rects[i].width = w; rects[i].height = h; ++i; } /* NW */ rects[0].x = 0; rects[0].y = 0; /* N */ rects[1].x = width / 2 - w / 2; rects[1].y = 0; /* NE */ rects[2].x = width - w; rects[2].y = 0; /* E */ rects[3].x = width - w; rects[3].y = height / 2 - h / 2; /* SE */ rects[4].x = width - w; rects[4].y = height - h; /* S */ rects[5].x = width / 2 - w / 2; rects[5].y = height - h; /* SW */ rects[6].x = 0; rects[6].y = height - h; /* W */ rects[7].x = 0; rects[7].y = height / 2 - h / 2; /* Center */ rects[8].x = width / 2 - w / 2; rects[8].y = height / 2 - h / 2; } static Bool all_events (Display *display, XEvent *event, XPointer arg) { return True; } static void get_size (Display *d, Drawable draw, int *xp, int *yp, int *widthp, int *heightp) { int x, y; unsigned int width=0, height=0, border=0, depth=0; Window root; XGetGeometry (d, draw, &root, &x, &y, &width, &height, &border, &depth); if (xp) *xp = x; if (yp) *yp = y; if (widthp) *widthp = width; if (heightp) *heightp = height; } int main (int argc, char **argv) { Display *d; Window w, cw; XSizeHints hints; int screen; XEvent ev; int x, y, width, height; Pixmap pix; GC gc; XGCValues gc_vals; XSetWindowAttributes set_attrs; XWindowChanges changes; XRectangle rects[9]; gboolean redraw_pending; unsigned int mask; d = XOpenDisplay (NULL); screen = DefaultScreen (d); /* Print some debug spew to show how StaticGravity works */ w = XCreateSimpleWindow (d, RootWindow (d, screen), 0, 0, 100, 100, 0, WhitePixel (d, screen), WhitePixel (d, screen)); cw = XCreateSimpleWindow (d, w, 0, 0, 100, 100, 0, WhitePixel (d, screen), WhitePixel (d, screen)); set_attrs.win_gravity = StaticGravity; XChangeWindowAttributes (d, cw, CWWinGravity, &set_attrs); get_size (d, w, &x, &y, &width, &height); g_print ("Parent is %d,%d %d x %d before configuring parent\n", x, y, width, height); get_size (d, cw, &x, &y, &width, &height); g_print ("Child is %d,%d %d x %d before configuring parent\n", x, y, width, height); changes.x = 10; changes.y = 10; changes.width = 110; changes.height = 110; /* last mask wins */ mask = CWX | CWY; mask = CWWidth | CWHeight; mask = CWX | CWY | CWWidth | CWHeight; XConfigureWindow (d, w, mask, &changes); XSync (d, False); get_size (d, w, &x, &y, &width, &height); g_print ("Parent is %d,%d %d x %d after configuring parent\n", x, y, width, height); get_size (d, cw, &x, &y, &width, &height); g_print ("Child is %d,%d %d x %d after configuring parent\n", x, y, width, height); XDestroyWindow (d, w); /* The window that gets displayed */ x = 20; y = 20; width = 100; height = 100; calc_rects (rects, width, height); w = XCreateSimpleWindow (d, RootWindow (d, screen), x, y, width, height, 0, WhitePixel (d, screen), WhitePixel (d, screen)); set_attrs.bit_gravity = StaticGravity; XChangeWindowAttributes (d, w, CWBitGravity, &set_attrs); XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask); hints.flags = PMinSize; hints.min_width = 100; hints.min_height = 100; XSetWMNormalHints (d, w, &hints); XMapWindow (d, w); redraw_pending = FALSE; while (1) { XNextEvent (d, &ev); switch (ev.xany.type) { case ButtonPress: if (ev.xbutton.button == 3) { g_print ("Exiting on button 3 press\n"); exit (0); } break; case ConfigureNotify: x = ev.xconfigure.x; y = ev.xconfigure.y; width = ev.xconfigure.width; height = ev.xconfigure.height; redraw_pending = TRUE; break; case Expose: redraw_pending = TRUE; break; default: break; } /* Primitive event compression */ if (XCheckIfEvent (d, &ev, all_events, NULL)) { XPutBackEvent (d, &ev); } else if (redraw_pending) { calc_rects (rects, width, height); pix = XCreatePixmap (d, w, width, height, DefaultDepth (d, screen)); gc_vals.foreground = WhitePixel (d, screen); gc = XCreateGC (d, pix, GCForeground, &gc_vals); XFillRectangle (d, pix, gc, 0, 0, width, height); /* Draw rectangles at each gravity point */ gc_vals.foreground = BlackPixel (d, screen); XChangeGC (d, gc, GCForeground, &gc_vals); XFillRectangles (d, pix, gc, rects, G_N_ELEMENTS (rects)); XCopyArea (d, pix, w, gc, 0, 0, width, height, 0, 0); XFreePixmap (d, pix); XFreeGC (d, gc); redraw_pending = FALSE; } } /* This program has an infinite loop above so a return statement would * just cause compiler warnings. */ }