Mercurial > hg > index.fcgi > keynav-9pba
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 } |