00001 #include <X11/Xlib.h>
00002 #include <X11/Xutil.h>
00003 #include <stdio.h>
00004 #include <string.h>
00005
00006 static int gravities[10] = {
00007 NorthWestGravity,
00008 NorthGravity,
00009 NorthEastGravity,
00010 WestGravity,
00011 CenterGravity,
00012 EastGravity,
00013 SouthWestGravity,
00014 SouthGravity,
00015 SouthEastGravity,
00016 StaticGravity
00017 };
00018
00019 typedef struct
00020 {
00021 int x, y, width, height;
00022 } Rectangle;
00023
00024 static Window windows[10];
00025 static int doubled[10] = { 0, };
00026 static Rectangle window_rects[10];
00027
00028 #define WINDOW_WIDTH 100
00029 #define WINDOW_HEIGHT 100
00030
00031 static int x_offset[3] = { 0, - WINDOW_WIDTH/2, -WINDOW_WIDTH };
00032 static int y_offset[3] = { 0, - WINDOW_HEIGHT/2, -WINDOW_HEIGHT };
00033 static double screen_x_fraction[3] = { 0, 0.5, 1.0 };
00034 static double screen_y_fraction[3] = { 0, 0.5, 1.0 };
00035 static int screen_width;
00036 static int screen_height;
00037
00038 static const char*
00039 window_gravity_to_string (int gravity)
00040 {
00041 switch (gravity)
00042 {
00043 case NorthWestGravity:
00044 return "NorthWestGravity";
00045 case NorthGravity:
00046 return "NorthGravity";
00047 case NorthEastGravity:
00048 return "NorthEastGravity";
00049 case WestGravity:
00050 return "WestGravity";
00051 case CenterGravity:
00052 return "CenterGravity";
00053 case EastGravity:
00054 return "EastGravity";
00055 case SouthWestGravity:
00056 return "SouthWestGravity";
00057 case SouthGravity:
00058 return "SouthGravity";
00059 case SouthEastGravity:
00060 return "SouthEastGravity";
00061 case StaticGravity:
00062 return "StaticGravity";
00063 default:
00064 return "NorthWestGravity";
00065 }
00066 }
00067
00068 static void
00069 calculate_position (int i, int doubled, int *x, int *y)
00070 {
00071 if (i == 9)
00072 {
00073 *x = 150;
00074 *y = 150;
00075 }
00076 else
00077 {
00078 int xoff = x_offset[i % 3];
00079 int yoff = y_offset[i / 3];
00080 if (doubled)
00081 {
00082 xoff *= 2;
00083 yoff *= 2;
00084 }
00085
00086 *x = screen_x_fraction[i % 3] * screen_width + xoff;
00087 *y = screen_y_fraction[i / 3] * screen_height + yoff;
00088 }
00089 }
00090
00091 static int
00092 find_window (Window window)
00093 {
00094 int i;
00095 for (i=0; i<10; i++)
00096 {
00097 if (windows[i] == window)
00098 return i;
00099 }
00100
00101 return -1;
00102 }
00103
00104 typedef struct {
00105 unsigned long flags;
00106 unsigned long functions;
00107 unsigned long decorations;
00108 long input_mode;
00109 unsigned long status;
00110 } MotifWmHints, MwmHints;
00111
00112 #define MWM_HINTS_FUNCTIONS (1L << 0)
00113 #define MWM_HINTS_DECORATIONS (1L << 1)
00114 #define MWM_HINTS_INPUT_MODE (1L << 2)
00115 #define MWM_HINTS_STATUS (1L << 3)
00116
00117 int main (int argc, char **argv)
00118 {
00119 Display *d;
00120 Window w;
00121 XSizeHints hints;
00122 int i;
00123 int screen;
00124 XEvent ev;
00125 int noframes;
00126
00127 if (argc > 1 && strcmp (argv[1], "--noframes") == 0)
00128 noframes = 1;
00129 else
00130 noframes = 0;
00131
00132 d = XOpenDisplay (NULL);
00133
00134 screen = DefaultScreen (d);
00135 screen_width = DisplayWidth (d, screen);
00136 screen_height = DisplayHeight (d, screen);
00137
00138 for (i=0; i<10; i++)
00139 {
00140 int x, y;
00141
00142 calculate_position (i, doubled[i], &x, &y);
00143
00144 w = XCreateSimpleWindow (d, RootWindow (d, screen),
00145 x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
00146 WhitePixel (d, screen), WhitePixel (d, screen));
00147
00148 windows[i] = w;
00149 window_rects[i].x = x;
00150 window_rects[i].y = y;
00151 window_rects[i].width = WINDOW_WIDTH;
00152 window_rects[i].height = WINDOW_HEIGHT;
00153
00154 XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask);
00155
00156 hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity;
00157
00158 hints.min_width = WINDOW_WIDTH / 2;
00159 hints.min_height = WINDOW_HEIGHT / 2;
00160
00161 #if 1
00162
00163
00164
00165
00166 hints.max_width = WINDOW_WIDTH * 2 - WINDOW_WIDTH / 2;
00167 hints.max_height = WINDOW_HEIGHT * 2 - WINDOW_HEIGHT / 2;
00168 #else
00169 hints.max_width = WINDOW_WIDTH * 2 + WINDOW_WIDTH / 2;
00170 hints.max_height = WINDOW_HEIGHT * 2 + WINDOW_HEIGHT / 2;
00171 #endif
00172 hints.win_gravity = gravities[i];
00173
00174 XSetWMNormalHints (d, w, &hints);
00175
00176 XStoreName (d, w, window_gravity_to_string (hints.win_gravity));
00177
00178 if (noframes)
00179 {
00180 MotifWmHints mwm;
00181 Atom mwm_atom;
00182
00183 mwm.decorations = 0;
00184 mwm.flags = MWM_HINTS_DECORATIONS;
00185
00186 mwm_atom = XInternAtom (d, "_MOTIF_WM_HINTS", False);
00187
00188 XChangeProperty (d, w, mwm_atom, mwm_atom,
00189 32, PropModeReplace,
00190 (unsigned char *)&mwm,
00191 sizeof (MotifWmHints)/sizeof (long));
00192 }
00193
00194 XMapWindow (d, w);
00195 }
00196
00197 while (1)
00198 {
00199 XNextEvent (d, &ev);
00200
00201 if (ev.xany.type == ConfigureNotify)
00202 {
00203 i = find_window (ev.xconfigure.window);
00204
00205 if (i >= 0)
00206 {
00207 Window ignored;
00208
00209 window_rects[i].width = ev.xconfigure.width;
00210 window_rects[i].height = ev.xconfigure.height;
00211
00212 XClearArea (d, windows[i], 0, 0,
00213 ev.xconfigure.width,
00214 ev.xconfigure.height,
00215 True);
00216
00217 if (!ev.xconfigure.send_event)
00218 XTranslateCoordinates (d, windows[i], DefaultRootWindow (d),
00219 0, 0,
00220 &window_rects[i].x, &window_rects[i].y,
00221 &ignored);
00222 else
00223 {
00224 window_rects[i].x = ev.xconfigure.x;
00225 window_rects[i].y = ev.xconfigure.y;
00226 }
00227 }
00228 }
00229 else if (ev.xany.type == Expose)
00230 {
00231 i = find_window (ev.xexpose.window);
00232
00233 if (i >= 0)
00234 {
00235 GC gc;
00236 XGCValues values;
00237 char buf[256];
00238
00239 values.foreground = BlackPixel (d, screen);
00240
00241 gc = XCreateGC (d, windows[i],
00242 GCForeground, &values);
00243
00244 sprintf (buf,
00245 "%d,%d",
00246 window_rects[i].x,
00247 window_rects[i].y);
00248
00249 XDrawString (d, windows[i], gc, 10, 15,
00250 buf, strlen (buf));
00251
00252 sprintf (buf,
00253 "%dx%d",
00254 window_rects[i].width,
00255 window_rects[i].height);
00256
00257 XDrawString (d, windows[i], gc, 10, 35,
00258 buf, strlen (buf));
00259
00260 XFreeGC (d, gc);
00261 }
00262 }
00263 else if (ev.xany.type == ButtonPress)
00264 {
00265 i = find_window (ev.xbutton.window);
00266
00267 if (i >= 0)
00268 {
00269
00270
00271 if (ev.xbutton.button == Button1)
00272 {
00273 int x, y;
00274
00275 calculate_position (i, doubled[i], &x, &y);
00276 XMoveWindow (d, windows[i], x, y);
00277 }
00278 else if (ev.xbutton.button == Button2)
00279 {
00280 if (doubled[i])
00281 XResizeWindow (d, windows[i], WINDOW_WIDTH, WINDOW_HEIGHT);
00282 else
00283 XResizeWindow (d, windows[i], WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
00284
00285 doubled[i] = !doubled[i];
00286 }
00287 else if (ev.xbutton.button == Button3)
00288 {
00289 int x, y;
00290
00291 calculate_position (i, !doubled[i], &x, &y);
00292
00293 if (doubled[i])
00294 XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
00295 else
00296 XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
00297
00298 doubled[i] = !doubled[i];
00299 }
00300 }
00301 }
00302 }
00303
00304
00305
00306
00307 }
00308