2001-08-19 02:29:38 +00:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <stdio.h>
|
2003-03-08 23:43:17 +00:00
|
|
|
#include <string.h>
|
2001-08-19 02:29:38 +00:00
|
|
|
|
2006-01-20 22:03:56 +00:00
|
|
|
static int gravities[10] = {
|
2001-08-19 02:29:38 +00:00
|
|
|
NorthWestGravity,
|
|
|
|
NorthGravity,
|
|
|
|
NorthEastGravity,
|
|
|
|
WestGravity,
|
|
|
|
CenterGravity,
|
|
|
|
EastGravity,
|
|
|
|
SouthWestGravity,
|
|
|
|
SouthGravity,
|
|
|
|
SouthEastGravity,
|
|
|
|
StaticGravity
|
|
|
|
};
|
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int x, y, width, height;
|
|
|
|
} Rectangle;
|
|
|
|
|
2006-01-20 22:03:56 +00:00
|
|
|
static Window windows[10];
|
|
|
|
static int doubled[10] = { 0, };
|
|
|
|
static Rectangle window_rects[10];
|
2001-08-19 02:29:38 +00:00
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
#define WINDOW_WIDTH 100
|
|
|
|
#define WINDOW_HEIGHT 100
|
|
|
|
|
2006-01-20 22:03:56 +00:00
|
|
|
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;
|
2001-08-19 02:29:38 +00:00
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
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";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-21 21:44:35 +00:00
|
|
|
static void
|
2003-03-08 23:43:17 +00:00
|
|
|
calculate_position (int i, int doubled, int *x, int *y)
|
2001-08-19 02:29:38 +00:00
|
|
|
{
|
|
|
|
if (i == 9)
|
|
|
|
{
|
|
|
|
*x = 150;
|
|
|
|
*y = 150;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-03-08 23:43:17 +00:00
|
|
|
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;
|
2001-08-19 02:29:38 +00:00
|
|
|
}
|
2003-03-08 23:43:17 +00:00
|
|
|
|
|
|
|
return -1;
|
2001-08-19 02:29:38 +00:00
|
|
|
}
|
|
|
|
|
2003-03-29 20:04:19 +00:00
|
|
|
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)
|
|
|
|
|
2001-08-19 02:29:38 +00:00
|
|
|
int main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
Display *d;
|
|
|
|
Window w;
|
|
|
|
XSizeHints hints;
|
|
|
|
int i;
|
|
|
|
int screen;
|
|
|
|
XEvent ev;
|
2003-03-29 20:04:19 +00:00
|
|
|
int noframes;
|
|
|
|
|
|
|
|
if (argc > 1 && strcmp (argv[1], "--noframes") == 0)
|
|
|
|
noframes = 1;
|
|
|
|
else
|
|
|
|
noframes = 0;
|
2001-08-19 02:29:38 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
calculate_position (i, doubled[i], &x, &y);
|
2001-08-19 02:29:38 +00:00
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
w = XCreateSimpleWindow (d, RootWindow (d, screen),
|
|
|
|
x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
|
|
|
|
WhitePixel (d, screen), WhitePixel (d, screen));
|
2001-08-19 02:29:38 +00:00
|
|
|
|
|
|
|
windows[i] = w;
|
2003-03-08 23:43:17 +00:00
|
|
|
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);
|
2001-08-19 02:29:38 +00:00
|
|
|
|
|
|
|
hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity;
|
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
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
|
2001-08-19 02:29:38 +00:00
|
|
|
hints.win_gravity = gravities[i];
|
|
|
|
|
|
|
|
XSetWMNormalHints (d, w, &hints);
|
2003-03-08 23:43:17 +00:00
|
|
|
|
|
|
|
XStoreName (d, w, window_gravity_to_string (hints.win_gravity));
|
2003-03-29 20:04:19 +00:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
2003-03-08 23:43:17 +00:00
|
|
|
|
2001-08-19 02:29:38 +00:00
|
|
|
XMapWindow (d, w);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
XNextEvent (d, &ev);
|
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
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)
|
2001-08-19 02:29:38 +00:00
|
|
|
{
|
2003-03-08 23:43:17 +00:00
|
|
|
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;
|
2001-08-19 02:29:38 +00:00
|
|
|
|
2003-03-08 23:43:17 +00:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
}
|
2001-08-19 02:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
2006-01-20 22:03:56 +00:00
|
|
|
|
|
|
|
/* This program has an infinite loop above so a return statement would
|
|
|
|
* just cause compiler warnings.
|
|
|
|
*/
|
2001-08-19 02:29:38 +00:00
|
|
|
}
|
|
|
|
|