mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 12:32:05 +00:00
01ce961c00
Check heightp not *heightp before assigning to heightp https://bugzilla.gnome.org/show_bug.cgi?id=602349
258 lines
5.7 KiB
C
258 lines
5.7 KiB
C
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <stdlib.h>
|
|
#include <glib.h>
|
|
|
|
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.
|
|
*/
|
|
}
|
|
|