comparison keynav.c @ 1:0d5dc7c29c78

fix tabbing
author paulo@thepaulopc
date Thu, 17 Jun 2010 00:50:35 -0700
parents ab8a496afb67
children 640c5e9ea6ad
comparison
equal deleted inserted replaced
0:7d47d1446018 1:ae68ab46d51c
25 int ninegrid_n_switch = 0; 25 int ninegrid_n_switch = 0;
26 int ninegrid = 0; 26 int ninegrid = 0;
27 27
28 struct /* undo stack */ 28 struct /* undo stack */
29 { 29 {
30 int x[N_UNDO]; 30 int x[N_UNDO];
31 int y[N_UNDO]; 31 int y[N_UNDO];
32 int w[N_UNDO]; 32 int w[N_UNDO];
33 int h[N_UNDO]; 33 int h[N_UNDO];
34 int ninegrid[N_UNDO]; 34 int ninegrid[N_UNDO];
35 } u; 35 } u;
36 36
37 void toggleninegrid() { 37 void toggleninegrid() {
38 if (ninegrid) 38 if (ninegrid)
39 ninegrid = 0; 39 ninegrid = 0;
40 else 40 else
41 ninegrid = 1; 41 ninegrid = 1;
42 } 42 }
43 43
44 void stats(int hits, int moves) { 44 void stats(int hits, int moves) {
45 allhits += hits; 45 allhits += hits;
46 allmoves += moves; 46 allmoves += moves;
47 allclicks++; 47 allclicks++;
48 printf("hits=%d, moves=%d \n", hits, moves); 48 printf("hits=%d, moves=%d \n", hits, moves);
49 printf("total hits=%d, total moves=%d, total clicks=%d, avg. hit/click=%.2f, avg. moves/click=%.2f \n", allhits, allmoves, allclicks, (float)allhits/(float)allclicks, (float)allmoves/(float)allclicks); 49 printf("total hits=%d, total moves=%d, total clicks=%d, avg. hit/click=%.2f, avg. moves/click=%.2f \n", allhits, allmoves, allclicks, (float)allhits/(float)allclicks, (float)allmoves/(float)allclicks);
50 fflush(stdout); fflush(stderr); // force buffers to write out 50 fflush(stdout); fflush(stderr); // force buffers to write out
51 } 51 }
52 52
53 void grab(char *keyname, int mods) { 53 void grab(char *keyname, int mods) {
54 int key; 54 int key;
55 55
56 key = XKeysymToKeycode(dpy, XStringToKeysym(keyname)); 56 key = XKeysymToKeycode(dpy, XStringToKeysym(keyname));
57 XGrabKey(dpy, key, mods, root, False, 57 XGrabKey(dpy, key, mods, root, False,
58 GrabModeAsync, GrabModeAsync); 58 GrabModeAsync, GrabModeAsync);
59 XGrabKey(dpy, key, mods | CAPSLOCKMASK, root, False, 59 XGrabKey(dpy, key, mods | CAPSLOCKMASK, root, False,
60 GrabModeAsync, GrabModeAsync); 60 GrabModeAsync, GrabModeAsync);
61 XGrabKey(dpy, key, mods | NUMLOCKMASK, root, False, 61 XGrabKey(dpy, key, mods | NUMLOCKMASK, root, False,
62 GrabModeAsync, GrabModeAsync); 62 GrabModeAsync, GrabModeAsync);
63 XGrabKey(dpy, key, mods | CAPSLOCKMASK | NUMLOCKMASK, root, False, 63 XGrabKey(dpy, key, mods | CAPSLOCKMASK | NUMLOCKMASK, root, False,
64 GrabModeAsync, GrabModeAsync); 64 GrabModeAsync, GrabModeAsync);
65 } 65 }
66 66
67 void ungrab(char *keyname, int mod) { 67 void ungrab(char *keyname, int mod) {
68 int key; 68 int key;
69 69
70 key = XKeysymToKeycode(dpy, XStringToKeysym(keyname)); 70 key = XKeysymToKeycode(dpy, XStringToKeysym(keyname));
71 XUngrabKey(dpy, key, mod, root); 71 XUngrabKey(dpy, key, mod, root);
72 XUngrabKey(dpy, key, mod | CAPSLOCKMASK, root); 72 XUngrabKey(dpy, key, mod | CAPSLOCKMASK, root);
73 XUngrabKey(dpy, key, mod | NUMLOCKMASK, root); 73 XUngrabKey(dpy, key, mod | NUMLOCKMASK, root);
74 XUngrabKey(dpy, key, mod | CAPSLOCKMASK | NUMLOCKMASK, root); 74 XUngrabKey(dpy, key, mod | CAPSLOCKMASK | NUMLOCKMASK, root);
75 } 75 }
76 76
77 void buttondown(int i) { 77 void buttondown(int i) {
78 XTestFakeButtonEvent(dpy, i, True, 50); 78 XTestFakeButtonEvent(dpy, i, True, 50);
79 } 79 }
80 80
81 void buttonup(int i) { 81 void buttonup(int i) {
82 XTestFakeButtonEvent(dpy, i, False, 50); 82 XTestFakeButtonEvent(dpy, i, False, 50);
83 } 83 }
84 84
85 void warppointer(int x, int y, int w, int h) { 85 void warppointer(int x, int y, int w, int h) {
86 XWarpPointer(dpy, None, root, 0, 0, 0, 0, x + w/2, y + h/2); 86 XWarpPointer(dpy, None, root, 0, 0, 0, 0, x + w/2, y + h/2);
87 } 87 }
88 88
89 /* operations for undo */ 89 /* operations for undo */
90 void undo_stack_push(int x, int y, int w, int h) { 90 void undo_stack_push(int x, int y, int w, int h) {
91 int i; 91 int i;
92 92
93 if (x >= 0 && y >= 0 && w > 0 && h > 0) { 93 if (x >= 0 && y >= 0 && w > 0 && h > 0) {
94 fprintf(stderr,"undo_stack_push success: @(%d,%d) #(%d,%d)\n", x, y, w, h); 94 fprintf(stderr,"undo_stack_push success: @(%d,%d) #(%d,%d)\n", x, y, w, h);
95 for (i=N_UNDO-1; i>0; i--) { 95 for (i=N_UNDO-1; i>0; i--) {
96 u.x[i] = u.x[i-1]; 96 u.x[i] = u.x[i-1];
97 u.y[i] = u.y[i-1]; 97 u.y[i] = u.y[i-1];
98 u.w[i] = u.w[i-1]; 98 u.w[i] = u.w[i-1];
99 u.h[i] = u.h[i-1]; 99 u.h[i] = u.h[i-1];
100 u.ninegrid[i] = u.ninegrid[i-1]; 100 u.ninegrid[i] = u.ninegrid[i-1];
101 } 101 }
102 u.x[0] = x; 102 u.x[0] = x;
103 u.y[0] = y; 103 u.y[0] = y;
104 u.w[0] = w; 104 u.w[0] = w;
105 u.h[0] = h; 105 u.h[0] = h;
106 u.ninegrid[0] = ninegrid; 106 u.ninegrid[0] = ninegrid;
107 } 107 }
108 } 108 }
109 109
110 int undo_stack_pop(int *x, int *y, int *w, int *h, int *ninegrid) { 110 int undo_stack_pop(int *x, int *y, int *w, int *h, int *ninegrid) {
111 int i; 111 int i;
112 int ret = 0; 112 int ret = 0;
113 113
114 int rx = u.x[0]; 114 int rx = u.x[0];
115 int ry = u.y[0]; 115 int ry = u.y[0];
116 int rw = u.w[0]; 116 int rw = u.w[0];
117 int rh = u.h[0]; 117 int rh = u.h[0];
118 int rninegrid = u.ninegrid[0]; 118 int rninegrid = u.ninegrid[0];
119 119
120 if (rx >= 0 && ry >= 0 && rw > 0 && rh > 0) { 120 if (rx >= 0 && ry >= 0 && rw > 0 && rh > 0) {
121 fprintf(stderr,"undo_stack_pop success: @(%d,%d) #(%d,%d)\n", *x, *y, *w, *h); 121 fprintf(stderr,"undo_stack_pop success: @(%d,%d) #(%d,%d)\n", *x, *y, *w, *h);
122 ret = 1; // return success 122 ret = 1; // return success
123 for (i=0; i<N_UNDO-1; i++) { 123 for (i=0; i<N_UNDO-1; i++) {
124 u.x[i] = u.x[i+1]; 124 u.x[i] = u.x[i+1];
125 u.y[i] = u.y[i+1]; 125 u.y[i] = u.y[i+1];
126 u.w[i] = u.w[i+1]; 126 u.w[i] = u.w[i+1];
127 u.h[i] = u.h[i+1]; 127 u.h[i] = u.h[i+1];
128 u.ninegrid[i] = u.ninegrid[i+1]; 128 u.ninegrid[i] = u.ninegrid[i+1];
129 } 129 }
130 u.x[N_UNDO-1] = -1; 130 u.x[N_UNDO-1] = -1;
131 u.y[N_UNDO-1] = -1; 131 u.y[N_UNDO-1] = -1;
132 u.w[N_UNDO-1] = -1; 132 u.w[N_UNDO-1] = -1;
133 u.h[N_UNDO-1] = -1; 133 u.h[N_UNDO-1] = -1;
134 u.ninegrid[N_UNDO-1] = -1; 134 u.ninegrid[N_UNDO-1] = -1;
135 *x = rx; 135 *x = rx;
136 *y = ry; 136 *y = ry;
137 *w = rw; 137 *w = rw;
138 *h = rh; 138 *h = rh;
139 *ninegrid = rninegrid; 139 *ninegrid = rninegrid;
140 } 140 }
141 return ret; 141 return ret;
142 } 142 }
143 143
144 void undo_stack_reset() { 144 void undo_stack_reset() {
145 int i; 145 int i;
146 146
147 for (i=0; i<N_UNDO; i++) { 147 for (i=0; i<N_UNDO; i++) {
148 u.x[i] = -1; 148 u.x[i] = -1;
149 u.y[i] = -1; 149 u.y[i] = -1;
150 u.w[i] = -1; 150 u.w[i] = -1;
151 u.h[i] = -1; 151 u.h[i] = -1;
152 } 152 }
153 } 153 }
154 /* =-=-=-=-=-= */ 154 /* =-=-=-=-=-= */
155 155
156 int chk_keysym(int keysym, char *str) { 156 int chk_keysym(int keysym, char *str) {
157 int ret = 0; 157 int ret = 0;
158 158
159 if (XStringToKeysym(str) == keysym) 159 if (XStringToKeysym(str) == keysym)
160 ret = 1; 160 ret = 1;
161 161
162 return ret; 162 return ret;
163 } 163 }
164 164
165 GC creategc(Window win) { 165 GC creategc(Window win) {
166 GC gc; 166 GC gc;
167 XGCValues values; 167 XGCValues values;
168 168
169 gc = XCreateGC(dpy, win, 0, &values); 169 gc = XCreateGC(dpy, win, 0, &values);
170 XSetForeground(dpy, gc, BlackPixel(dpy, 0)); 170 XSetForeground(dpy, gc, BlackPixel(dpy, 0));
171 XSetBackground(dpy, gc, WhitePixel(dpy, 0)); 171 XSetBackground(dpy, gc, WhitePixel(dpy, 0));
172 XSetLineAttributes(dpy, gc, LINEWIDTH, LineSolid, CapButt, JoinBevel); 172 XSetLineAttributes(dpy, gc, LINEWIDTH, LineSolid, CapButt, JoinBevel);
173 XSetFillStyle(dpy, gc, FillSolid); 173 XSetFillStyle(dpy, gc, FillSolid);
174 174
175 return gc; 175 return gc;
176 } 176 }
177 177
178 void drawquadrants(Window win, int w, int h) { 178 void drawquadrants(Window win, int w, int h) {
179 GC gc; 179 GC gc;
180 XRectangle clip[20]; 180 XRectangle clip[20];
181 int idx = 0; 181 int idx = 0;
182 Colormap colormap; 182 Colormap colormap;
183 XColor color; 183 XColor color;
184 184
185 gc = creategc(win); 185 gc = creategc(win);
186 colormap = DefaultColormap(dpy, 0); 186 colormap = DefaultColormap(dpy, 0);
187 187
188 if (drag) 188 if (drag)
189 XAllocNamedColor(dpy, colormap, DRAG_COLOR, &color, &color); 189 XAllocNamedColor(dpy, colormap, DRAG_COLOR, &color, &color);
190 else 190 else
191 XAllocNamedColor(dpy, colormap, NORM_COLOR, &color, &color); 191 XAllocNamedColor(dpy, colormap, NORM_COLOR, &color, &color);
192 192
193 /*left*/ clip[idx].x = 0; clip[idx].y = 0; clip[idx].width = BORDER; clip[idx].height = h; 193 /*left*/ clip[idx].x = 0; clip[idx].y = 0; clip[idx].width = BORDER; clip[idx].height = h;
194 idx++;
195 /*right*/ clip[idx].x = w-BORDER; clip[idx].y = 0; clip[idx].width = BORDER; clip[idx].height = h;
196 idx++;
197 /*top*/ clip[idx].x = 0; clip[idx].y = 0; clip[idx].width = w; clip[idx].height = BORDER;
198 idx++;
199 /*bottom*/ clip[idx].x = 0; clip[idx].y = h-BORDER; clip[idx].width = w; clip[idx].height = BORDER;
200 idx++;
201
202 if (ninegrid) {
203 /*1st horiz*/
204 clip[idx].x = 0; clip[idx].y = h/3 - BORDER/2;
205 clip[idx].width = w; clip[idx].height = BORDER;
206 idx++; 194 idx++;
207 /*2nd horiz*/ 195 /*right*/ clip[idx].x = w-BORDER; clip[idx].y = 0; clip[idx].width = BORDER; clip[idx].height = h;
208 clip[idx].x = 0; clip[idx].y = h*2/3 - BORDER/2;
209 clip[idx].width = w; clip[idx].height = BORDER;
210 idx++; 196 idx++;
211 /*1st vert*/ 197 /*top*/ clip[idx].x = 0; clip[idx].y = 0; clip[idx].width = w; clip[idx].height = BORDER;
212 clip[idx].x = w/3 - BORDER/2; clip[idx].y = 0;
213 clip[idx].width = BORDER; clip[idx].height = h;
214 idx++; 198 idx++;
215 /*2nd vert*/ 199 /*bottom*/ clip[idx].x = 0; clip[idx].y = h-BORDER; clip[idx].width = w; clip[idx].height = BORDER;
216 clip[idx].x = w*2/3 - BORDER/2; clip[idx].y = 0;
217 clip[idx].width = BORDER; clip[idx].height = h;
218 idx++; 200 idx++;
219 } else { 201
220 /*horiz*/ 202 if (ninegrid) {
221 clip[idx].x = 0; clip[idx].y = h/2 - BORDER/2; 203 /*1st horiz*/
222 clip[idx].width = w; clip[idx].height = BORDER; 204 clip[idx].x = 0; clip[idx].y = h/3 - BORDER/2;
223 idx++; 205 clip[idx].width = w; clip[idx].height = BORDER;
224 /*vert*/ 206 idx++;
225 clip[idx].x = w/2 - BORDER/2; clip[idx].y = 0; 207 /*2nd horiz*/
226 clip[idx].width = BORDER; clip[idx].height = h; 208 clip[idx].x = 0; clip[idx].y = h*2/3 - BORDER/2;
227 idx++; 209 clip[idx].width = w; clip[idx].height = BORDER;
228 } 210 idx++;
229 211 /*1st vert*/
230 XShapeCombineRectangles(dpy, win, ShapeBounding, 0, 0, clip, idx, ShapeSet, 0); 212 clip[idx].x = w/3 - BORDER/2; clip[idx].y = 0;
231 213 clip[idx].width = BORDER; clip[idx].height = h;
232 XFillRectangle(dpy, win, gc, 0, 0, w, h); 214 idx++;
233 215 /*2nd vert*/
234 XSetForeground(dpy, gc, color.pixel); 216 clip[idx].x = w*2/3 - BORDER/2; clip[idx].y = 0;
235 XDrawLine(dpy, win, gc, BORDER - PEN, BORDER - PEN, w - PEN, BORDER - PEN); //top line 217 clip[idx].width = BORDER; clip[idx].height = h;
236 XDrawLine(dpy, win, gc, BORDER - PEN, h - PEN, w - PEN, h - PEN); //bottom line 218 idx++;
237 XDrawLine(dpy, win, gc, BORDER - PEN, BORDER - PEN, BORDER - PEN, h - PEN); //left line 219 } else {
238 XDrawLine(dpy, win, gc, w - PEN, BORDER - PEN, w - PEN, h - PEN); //left line 220 /*horiz*/
239 221 clip[idx].x = 0; clip[idx].y = h/2 - BORDER/2;
240 if (ninegrid) { 222 clip[idx].width = w; clip[idx].height = BORDER;
241 XDrawLine(dpy, win, gc, w/3, 0, w/3, h); // 1st vert line 223 idx++;
242 XDrawLine(dpy, win, gc, w*2/3, 0, w*2/3, h); // 2nd vert line 224 /*vert*/
243 XDrawLine(dpy, win, gc, 0, h/3, w, h/3); // 1st horiz line 225 clip[idx].x = w/2 - BORDER/2; clip[idx].y = 0;
244 XDrawLine(dpy, win, gc, 0, h*2/3, w, h*2/3); // 2nd horiz line 226 clip[idx].width = BORDER; clip[idx].height = h;
245 } else { 227 idx++;
246 XDrawLine(dpy, win, gc, w/2, 0, w/2, h); // vert line 228 }
247 XDrawLine(dpy, win, gc, 0, h/2, w, h/2); // horiz line 229
248 } 230 XShapeCombineRectangles(dpy, win, ShapeBounding, 0, 0, clip, idx, ShapeSet, 0);
249 231
250 XFlush(dpy); 232 XFillRectangle(dpy, win, gc, 0, 0, w, h);
233
234 XSetForeground(dpy, gc, color.pixel);
235 XDrawLine(dpy, win, gc, BORDER - PEN, BORDER - PEN, w - PEN, BORDER - PEN); //top line
236 XDrawLine(dpy, win, gc, BORDER - PEN, h - PEN, w - PEN, h - PEN); //bottom line
237 XDrawLine(dpy, win, gc, BORDER - PEN, BORDER - PEN, BORDER - PEN, h - PEN); //left line
238 XDrawLine(dpy, win, gc, w - PEN, BORDER - PEN, w - PEN, h - PEN); //left line
239
240 if (ninegrid) {
241 XDrawLine(dpy, win, gc, w/3, 0, w/3, h); // 1st vert line
242 XDrawLine(dpy, win, gc, w*2/3, 0, w*2/3, h); // 2nd vert line
243 XDrawLine(dpy, win, gc, 0, h/3, w, h/3); // 1st horiz line
244 XDrawLine(dpy, win, gc, 0, h*2/3, w, h*2/3); // 2nd horiz line
245 } else {
246 XDrawLine(dpy, win, gc, w/2, 0, w/2, h); // vert line
247 XDrawLine(dpy, win, gc, 0, h/2, w, h/2); // horiz line
248 }
249
250 XFlush(dpy);
251 } 251 }
252 252
253 int handlekey(int keysym, int mod, int *moves, int *x, int *y, int *w, int *h) { 253 int handlekey(int keysym, int mod, int *moves, int *x, int *y, int *w, int *h) {
254 int ret = 1; 254 int ret = 1;
255 int ox = *x; 255 int ox = *x;
256 int oy = *y; 256 int oy = *y;
257 int ow = *w; 257 int ow = *w;
258 int oh = *h;; 258 int oh = *h;;
259 259
260 if (mod & SHIFTMASK || mod & SHIFTMASK & NUMLOCKMASK || mod & SHIFTMASK & CAPSLOCKMASK || mod & SHIFTMASK & CAPSLOCKMASK & NUMLOCKMASK) { 260 if (mod & SHIFTMASK || mod & SHIFTMASK & NUMLOCKMASK || mod & SHIFTMASK & CAPSLOCKMASK || mod & SHIFTMASK & CAPSLOCKMASK & NUMLOCKMASK) {
261 if (chk_keysym(keysym, KEY_CENTER)) 261 if (chk_keysym(keysym, KEY_CENTER))
262 toggleninegrid(); 262 toggleninegrid();
263 if (chk_keysym(keysym, KEY_LEFT) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_DOWNLEFT)) { 263 if (chk_keysym(keysym, KEY_LEFT) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_DOWNLEFT)) {
264 if (*x > 0) *x -= *w; // shift left 264 if (*x > 0) *x -= *w; // shift left
265 }
266 if (chk_keysym(keysym, KEY_DOWN) || chk_keysym(keysym, KEY_DOWNLEFT) || chk_keysym(keysym, KEY_DOWNRIGHT)) {
267 if ((*y + *h) < attr.height) *y += *h; // shift down
268 }
269 if (chk_keysym(keysym, KEY_UP) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_UPRIGHT)) {
270 if (*y > 0) *y -= *h; // shift up
271 }
272 if (chk_keysym(keysym, KEY_RIGHT) || chk_keysym(keysym, KEY_UPRIGHT) || chk_keysym(keysym, KEY_DOWNRIGHT)) {
273 if ((*x + *w) < attr.width) *x += *w; // shift right
274 }
275 } else {
276 if (ninegrid) {
277 if (chk_keysym(keysym, KEY_UPLEFT)) {
278 *w /= 3; *h /= 3; // split upper left
279 } else if (chk_keysym(keysym, KEY_UP)) {
280 *w /= 3; *h /= 3; // split up
281 *x += *w;
282 } else if (chk_keysym(keysym, KEY_UPRIGHT)) {
283 *w /= 3; *h /= 3; // split upper right
284 *x += *w * 2;
285 } else if (chk_keysym(keysym, KEY_LEFT)) {
286 *w /= 3; *h /= 3; // split left
287 *y += *h;
288 } else if (chk_keysym(keysym, KEY_CENTER)) {
289 *w /= 3; *h /= 3; // split center
290 *x += *w; *y += *h;
291 } else if (chk_keysym(keysym, KEY_RIGHT)) {
292 *w /= 3; *h /= 3; // split right
293 *x += *w * 2; *y += *h;
294 } else if (chk_keysym(keysym, KEY_DOWNLEFT)) {
295 *w /= 3; *h /= 3; // split bottom left
296 *y += *h * 2;
297 } else if (chk_keysym(keysym, KEY_DOWN)) {
298 *w /= 3; *h /= 3; // split down
299 *x += *w; *y += *h * 2;
300 } else if (chk_keysym(keysym, KEY_DOWNRIGHT)) {
301 *w /= 3; *h /= 3; // split bottom right
302 *x += *w * 2; *y += *h * 2;
303 }
304 } else {
305 if (chk_keysym(keysym, KEY_LEFT) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_DOWNLEFT)) {
306 *w /= 2; // split left
307 }
308 if (chk_keysym(keysym, KEY_DOWN) || chk_keysym(keysym, KEY_DOWNLEFT) || chk_keysym(keysym, KEY_DOWNRIGHT)) {
309 *h /= 2; // split down
310 *y += *h;
311 }
312 if (chk_keysym(keysym, KEY_UP) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_UPRIGHT)) {
313 *h /= 2; // split up
314 }
315 if (chk_keysym(keysym, KEY_RIGHT) || chk_keysym(keysym, KEY_UPRIGHT) || chk_keysym(keysym, KEY_DOWNRIGHT)) {
316 *w /= 2; // split right
317 *x += *w;
318 }
319 }
320 }
321
322 if (ox != *x || oy != *y || ow != *w || oh != *h) {
323 undo_stack_push(ox, oy, ow, oh);
324 *moves += 1;
325 }
326 else if (chk_keysym(keysym, KEY_UNDO)) {
327 int i, j;
328
329 if (mod & SHIFTMASK) j = 0;
330 else j = SHIFT_N_UNDO-1;
331
332 for (i=j; i<SHIFT_N_UNDO; i++) {
333 undo_stack_pop(x, y, w, h, &ninegrid);
334 *moves -= 1;
335 }
336 ret = 2;
337 }
338
339 if (*w < 1 || *h < 1) {
340 fprintf(stderr,"OOPS. Area too small. Giving up :(\n");
341 return 0;
342 }
343
344 if (drag && !(mod & WARPMASK) || !drag && (mod & WARPMASK))
345 warppointer(*x, *y, *w, *h);
346
347 fprintf(stderr,"Box: @(%d,%d) #(%d,%d)\n", *x, *y, *w, *h);
348
349 return ret;
350 }
351
352 void startmousekey(int from_undo) {
353 int keysym;
354 int done = 0;
355 int x,y,w,h;
356 int warp = 0;
357 int click = 0;
358 int k, hits, moves;
359 int mod;
360
361 Window zone;
362
363 // disable trigger keygrab
364 ungrab(KEY_TRIGGER, TRIGGERMASK);
365 ungrab(KEY_UNDO, TRIGGERMASK);
366
367 // grab keyboard
368 XGrabKeyboard(dpy, root, False, GrabModeAsync, GrabModeAsync, CurrentTime);
369
370 // init stuff
371 hits = moves = 0;
372 if (from_undo && undo_stack_pop(&x, &y, &w, &h, &ninegrid));
373 /* null -- only check for undo_stack_pop success */
374 else {
375 undo_stack_reset();
376 if (ninegrid_default)
377 ninegrid = 1;
378 x = y = 0;
379 w = attr.width;
380 h = attr.height;
381 }
382
383 zone = XCreateSimpleWindow(dpy, root, x, y, w, h, 1, BlackPixel(dpy, 0), WhitePixel(dpy, 0));
384
385 { /* Tell the window manager not to manage us */
386 unsigned long valuemask;
387 XSetWindowAttributes winattr;
388 winattr.override_redirect = 1;
389 XChangeWindowAttributes(dpy, zone, CWOverrideRedirect, &winattr);
390 }
391
392 drawquadrants(zone, w, h);
393 XMapWindow(dpy, zone);
394 drawquadrants(zone, w, h);
395
396 fprintf(stderr,"Starting quadrants...\n");
397 while (!done) {
398 XEvent e;
399 XNextEvent(dpy, &e);
400 if (e.type == KeyPress) {
401 keysym = XKeycodeToKeysym(dpy, e.xkey.keycode, 0);
402 mod = e.xkey.state;
403 if (chk_keysym(keysym, KEY_Q_CLICK)) {
404 done++;
405 click = 1;
406 } else if (chk_keysym(keysym, KEY_Q_RCLICK)) {
407 done++;
408 click = 3;
409 } else if (chk_keysym(keysym, KEY_QW_CLICK)) {
410 done++;
411 warp = 1;
412 click = 1;
413 } else if (chk_keysym(keysym, KEY_Q_MCLICK)) {
414 done++;
415 click = 2;
416 } else if (chk_keysym(keysym, KEY_QW_RCLICK)) {
417 done++;
418 warp = 1;
419 click = 3;
420 } else if (chk_keysym(keysym, KEY_HIDE)) {
421 done++;
422 warp = 1;
423 x = w; y = h;
424 } else if (chk_keysym(keysym, KEY_ESCAPE)) {
425 warp = 0;
426 done++;
427 } else if (!drag && chk_keysym(keysym, KEY_ONE)) {
428 buttondown(1);
429 buttonup(1);
430 } else if (!drag && chk_keysym(keysym, KEY_TWO)) {
431 buttondown(2);
432 buttonup(2);
433 } else if (!drag && chk_keysym(keysym, KEY_THREE)) {
434 buttondown(3);
435 buttonup(3);
436 } else {
437 if (k = handlekey(keysym, mod, &moves, &x, &y, &w, &h)) {
438 if (ninegrid_default && ninegrid_n_switch && k < 2 && moves >= ninegrid_n_switch)
439 ninegrid = 0;
440 hits++;
441 XMoveResizeWindow(dpy, zone, x, y, w, h);
442 drawquadrants(zone, w, h);
443 } else
444 done++;
445 }
446 }
447 }
448
449 // end mouse key
450 XUngrabKeyboard(dpy, CurrentTime);
451 XDestroyWindow(dpy, zone);
452 undo_stack_push(x, y, w, h);
453
454 if (warp)
455 warppointer(x, y, w, h);
456 if (click == 1) {
457 if (!drag)
458 buttondown(1);
459 if (mod & DRAGMASK && !drag)
460 drag = 1;
461 else if (mod & DRAGMASK) {
462 buttonup(1);
463 buttondown(1);
464 } else {
465 buttonup(1);
466 drag = 0;
467 }
468 } else if (click) {
469 buttondown(click);
470 buttonup(click);
265 } 471 }
266 if (chk_keysym(keysym, KEY_DOWN) || chk_keysym(keysym, KEY_DOWNLEFT) || chk_keysym(keysym, KEY_DOWNRIGHT)) { 472
267 if ((*y + *h) < attr.height) *y += *h; // shift down 473 if (click) stats(hits, moves);
268 } 474
269 if (chk_keysym(keysym, KEY_UP) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_UPRIGHT)) { 475 // loop back if in drag mode
270 if (*y > 0) *y -= *h; // shift up 476 if (drag) {
271 } 477 usleep(50);
272 if (chk_keysym(keysym, KEY_RIGHT) || chk_keysym(keysym, KEY_UPRIGHT) || chk_keysym(keysym, KEY_DOWNRIGHT)) { 478 startmousekey(0);
273 if ((*x + *w) < attr.width) *x += *w; // shift right 479 }
274 } 480
275 } else { 481 // re-enable trigger keygrabs
276 if (ninegrid) { 482 grab(KEY_TRIGGER, TRIGGERMASK);
277 if (chk_keysym(keysym, KEY_UPLEFT)) { 483 grab(KEY_UNDO, TRIGGERMASK);
278 *w /= 3; *h /= 3; // split upper left
279 } else if (chk_keysym(keysym, KEY_UP)) {
280 *w /= 3; *h /= 3; // split up
281 *x += *w;
282 } else if (chk_keysym(keysym, KEY_UPRIGHT)) {
283 *w /= 3; *h /= 3; // split upper right
284 *x += *w * 2;
285 } else if (chk_keysym(keysym, KEY_LEFT)) {
286 *w /= 3; *h /= 3; // split left
287 *y += *h;
288 } else if (chk_keysym(keysym, KEY_CENTER)) {
289 *w /= 3; *h /= 3; // split center
290 *x += *w; *y += *h;
291 } else if (chk_keysym(keysym, KEY_RIGHT)) {
292 *w /= 3; *h /= 3; // split right
293 *x += *w * 2; *y += *h;
294 } else if (chk_keysym(keysym, KEY_DOWNLEFT)) {
295 *w /= 3; *h /= 3; // split bottom left
296 *y += *h * 2;
297 } else if (chk_keysym(keysym, KEY_DOWN)) {
298 *w /= 3; *h /= 3; // split down
299 *x += *w; *y += *h * 2;
300 } else if (chk_keysym(keysym, KEY_DOWNRIGHT)) {
301 *w /= 3; *h /= 3; // split bottom right
302 *x += *w * 2; *y += *h * 2;
303 }
304 } else {
305 if (chk_keysym(keysym, KEY_LEFT) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_DOWNLEFT)) {
306 *w /= 2; // split left
307 }
308 if (chk_keysym(keysym, KEY_DOWN) || chk_keysym(keysym, KEY_DOWNLEFT) || chk_keysym(keysym, KEY_DOWNRIGHT)) {
309 *h /= 2; // split down
310 *y += *h;
311 }
312 if (chk_keysym(keysym, KEY_UP) || chk_keysym(keysym, KEY_UPLEFT) || chk_keysym(keysym, KEY_UPRIGHT)) {
313 *h /= 2; // split up
314 }
315 if (chk_keysym(keysym, KEY_RIGHT) || chk_keysym(keysym, KEY_UPRIGHT) || chk_keysym(keysym, KEY_DOWNRIGHT)) {
316 *w /= 2; // split right
317 *x += *w;
318 }
319 }
320 }
321
322 if (ox != *x || oy != *y || ow != *w || oh != *h) {
323 undo_stack_push(ox, oy, ow, oh);
324 *moves += 1;
325 }
326 else if (chk_keysym(keysym, KEY_UNDO)) {
327 int i, j;
328
329 if (mod & SHIFTMASK) j = 0;
330 else j = SHIFT_N_UNDO-1;
331
332 for (i=j; i<SHIFT_N_UNDO; i++) {
333 undo_stack_pop(x, y, w, h, &ninegrid);
334 *moves -= 1;
335 }
336 ret = 2;
337 }
338
339 if (*w < 1 || *h < 1) {
340 fprintf(stderr,"OOPS. Area too small. Giving up :(\n");
341 return 0;
342 }
343
344 if (drag && !(mod & WARPMASK) || !drag && (mod & WARPMASK))
345 warppointer(*x, *y, *w, *h);
346
347 fprintf(stderr,"Box: @(%d,%d) #(%d,%d)\n", *x, *y, *w, *h);
348
349 return ret;
350 }
351
352 void startmousekey(int from_undo) {
353 int keysym;
354 int done = 0;
355 int x,y,w,h;
356 int warp = 0;
357 int click = 0;
358 int k, hits, moves;
359 int mod;
360
361 Window zone;
362
363 // disable trigger keygrab
364 ungrab(KEY_TRIGGER, TRIGGERMASK);
365 ungrab(KEY_UNDO, TRIGGERMASK);
366
367 // grab keyboard
368 XGrabKeyboard(dpy, root, False, GrabModeAsync, GrabModeAsync, CurrentTime);
369
370 // init stuff
371 hits = moves = 0;
372 if (from_undo && undo_stack_pop(&x, &y, &w, &h, &ninegrid));
373 /* null -- only check for undo_stack_pop success */
374 else {
375 undo_stack_reset();
376 if (ninegrid_default)
377 ninegrid = 1;
378 x = y = 0;
379 w = attr.width;
380 h = attr.height;
381 }
382
383 zone = XCreateSimpleWindow(dpy, root, x, y, w, h, 1, BlackPixel(dpy, 0), WhitePixel(dpy, 0));
384
385 { /* Tell the window manager not to manage us */
386 unsigned long valuemask;
387 XSetWindowAttributes winattr;
388 winattr.override_redirect = 1;
389 XChangeWindowAttributes(dpy, zone, CWOverrideRedirect, &winattr);
390 }
391
392 drawquadrants(zone, w, h);
393 XMapWindow(dpy, zone);
394 drawquadrants(zone, w, h);
395
396 fprintf(stderr,"Starting quadrants...\n");
397 while (!done) {
398 XEvent e;
399 XNextEvent(dpy, &e);
400 if (e.type == KeyPress) {
401 keysym = XKeycodeToKeysym(dpy, e.xkey.keycode, 0);
402 mod = e.xkey.state;
403 if (chk_keysym(keysym, KEY_Q_CLICK)) {
404 done++;
405 click = 1;
406 } else if (chk_keysym(keysym, KEY_Q_RCLICK)) {
407 done++;
408 click = 3;
409 } else if (chk_keysym(keysym, KEY_QW_CLICK)) {
410 done++;
411 warp = 1;
412 click = 1;
413 } else if (chk_keysym(keysym, KEY_Q_MCLICK)) {
414 done++;
415 click = 2;
416 } else if (chk_keysym(keysym, KEY_QW_RCLICK)) {
417 done++;
418 warp = 1;
419 click = 3;
420 } else if (chk_keysym(keysym, KEY_HIDE)) {
421 done++;
422 warp = 1;
423 x = w; y = h;
424 } else if (chk_keysym(keysym, KEY_ESCAPE)) {
425 warp = 0;
426 done++;
427 } else if (!drag && chk_keysym(keysym, KEY_ONE)) {
428 buttondown(1);
429 buttonup(1);
430 } else if (!drag && chk_keysym(keysym, KEY_TWO)) {
431 buttondown(2);
432 buttonup(2);
433 } else if (!drag && chk_keysym(keysym, KEY_THREE)) {
434 buttondown(3);
435 buttonup(3);
436 } else {
437 if (k = handlekey(keysym, mod, &moves, &x, &y, &w, &h)) {
438 if (ninegrid_default && ninegrid_n_switch && k < 2 && moves >= ninegrid_n_switch)
439 ninegrid = 0;
440 hits++;
441 XMoveResizeWindow(dpy, zone, x, y, w, h);
442 drawquadrants(zone, w, h);
443 } else
444 done++;
445 }
446 }
447 }
448
449 // end mouse key
450 XUngrabKeyboard(dpy, CurrentTime);
451 XDestroyWindow(dpy, zone);
452 undo_stack_push(x, y, w, h);
453
454 if (warp)
455 warppointer(x, y, w, h);
456 if (click == 1) {
457 if (!drag)
458 buttondown(1);
459 if (mod & DRAGMASK && !drag)
460 drag = 1;
461 else if (mod & DRAGMASK) {
462 buttonup(1);
463 buttondown(1);
464 } else {
465 buttonup(1);
466 drag = 0;
467 }
468 } else if (click) {
469 buttondown(click);
470 buttonup(click);
471 }
472
473 if (click) stats(hits, moves);
474
475 // loop back if in drag mode
476 if (drag) {
477 usleep(50);
478 startmousekey(0);
479 }
480
481 // re-enable trigger keygrabs
482 grab(KEY_TRIGGER, TRIGGERMASK);
483 grab(KEY_UNDO, TRIGGERMASK);
484 } 484 }
485 485
486 int main(int argc, char **argv) { 486 int main(int argc, char **argv) {
487 char *pcDisplay; 487 char *pcDisplay;
488 488
489 if ((dpy = XOpenDisplay(pcDisplay = getenv("DISPLAY"))) == NULL) { 489 if ((dpy = XOpenDisplay(pcDisplay = getenv("DISPLAY"))) == NULL) {
490 fprintf(stderr,"Error: Can't open display: %s", pcDisplay); 490 fprintf(stderr,"Error: Can't open display: %s", pcDisplay);
491 exit(1); 491 exit(1);
492 } 492 }
493 fprintf(stderr,"Display: %s\n", pcDisplay); 493 fprintf(stderr,"Display: %s\n", pcDisplay);
494 494
495 // parse options 495 // parse options
496 if (argc > 1) 496 if (argc > 1)
497 if (argv[1][0] && argv[1][0] == '-') 497 if (argv[1][0] && argv[1][0] == '-')
498 if (argv[1][1] && argv[1][1] == 'n') { 498 if (argv[1][1] && argv[1][1] == 'n') {
499 ninegrid_default = 1; 499 ninegrid_default = 1;
500 fprintf(stderr,"nine-grid default mode \n"); 500 fprintf(stderr,"nine-grid default mode \n");
501 if (argv[2]) { 501 if (argv[2]) {
502 ninegrid_n_switch = atoi(argv[2]); 502 ninegrid_n_switch = atoi(argv[2]);
503 fprintf(stderr,"nine-grid autoswitch num: %d \n", ninegrid_n_switch); 503 fprintf(stderr,"nine-grid autoswitch num: %d \n", ninegrid_n_switch);
504 } 504 }
505 } 505 }
506 506
507 root = XDefaultRootWindow(dpy); 507 root = XDefaultRootWindow(dpy);
508 XGetWindowAttributes(dpy, root, &attr); 508 XGetWindowAttributes(dpy, root, &attr);
509 509
510 // these are the trigger keygrabs 510 // these are the trigger keygrabs
511 grab(KEY_TRIGGER, TRIGGERMASK); 511 grab(KEY_TRIGGER, TRIGGERMASK);
512 grab(KEY_UNDO, TRIGGERMASK); 512 grab(KEY_UNDO, TRIGGERMASK);
513 513
514 while (1) { 514 while (1) {
515 XEvent e; 515 XEvent e;
516 XNextEvent(dpy, &e); 516 XNextEvent(dpy, &e);
517 if (e.type == KeyPress) 517 if (e.type == KeyPress)
518 if (chk_keysym(XKeycodeToKeysym(dpy, e.xkey.keycode, 0), KEY_UNDO)) 518 if (chk_keysym(XKeycodeToKeysym(dpy, e.xkey.keycode, 0), KEY_UNDO))
519 startmousekey(1); 519 startmousekey(1);
520 else 520 else
521 startmousekey(0); 521 startmousekey(0);
522 } 522 }
523 } 523 }