Blame


1 038e9089 2004-03-21 devnull /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
2 038e9089 2004-03-21 devnull #include <stdio.h>
3 038e9089 2004-03-21 devnull #include <X11/X.h>
4 038e9089 2004-03-21 devnull #include <X11/Xos.h>
5 038e9089 2004-03-21 devnull #include <X11/Xlib.h>
6 038e9089 2004-03-21 devnull #include <X11/Xutil.h>
7 038e9089 2004-03-21 devnull #include "dat.h"
8 038e9089 2004-03-21 devnull #include "fns.h"
9 038e9089 2004-03-21 devnull
10 038e9089 2004-03-21 devnull int
11 038e9089 2004-03-21 devnull nobuttons(XButtonEvent *e) /* Einstuerzende */
12 038e9089 2004-03-21 devnull {
13 038e9089 2004-03-21 devnull int state;
14 038e9089 2004-03-21 devnull
15 038e9089 2004-03-21 devnull state = (e->state & AllButtonMask);
16 038e9089 2004-03-21 devnull return (e->type == ButtonRelease) && (state & (state - 1)) == 0;
17 038e9089 2004-03-21 devnull }
18 038e9089 2004-03-21 devnull
19 038e9089 2004-03-21 devnull int
20 038e9089 2004-03-21 devnull grab(Window w, Window constrain, int mask, Cursor curs, int t)
21 038e9089 2004-03-21 devnull {
22 038e9089 2004-03-21 devnull int status;
23 038e9089 2004-03-21 devnull
24 ac33a34a 2005-07-13 devnull if(t == 0)
25 038e9089 2004-03-21 devnull t = timestamp();
26 038e9089 2004-03-21 devnull status = XGrabPointer(dpy, w, False, mask,
27 038e9089 2004-03-21 devnull GrabModeAsync, GrabModeAsync, constrain, curs, t);
28 038e9089 2004-03-21 devnull return status;
29 038e9089 2004-03-21 devnull }
30 038e9089 2004-03-21 devnull
31 038e9089 2004-03-21 devnull void
32 038e9089 2004-03-21 devnull ungrab(XButtonEvent *e)
33 038e9089 2004-03-21 devnull {
34 038e9089 2004-03-21 devnull XEvent ev;
35 038e9089 2004-03-21 devnull
36 ac33a34a 2005-07-13 devnull if(!nobuttons(e))
37 ac33a34a 2005-07-13 devnull for(;;){
38 038e9089 2004-03-21 devnull XMaskEvent(dpy, ButtonMask | ButtonMotionMask, &ev);
39 ac33a34a 2005-07-13 devnull if(ev.type == MotionNotify)
40 038e9089 2004-03-21 devnull continue;
41 038e9089 2004-03-21 devnull e = &ev.xbutton;
42 ac33a34a 2005-07-13 devnull if(nobuttons(e))
43 038e9089 2004-03-21 devnull break;
44 038e9089 2004-03-21 devnull }
45 038e9089 2004-03-21 devnull XUngrabPointer(dpy, e->time);
46 038e9089 2004-03-21 devnull curtime = e->time;
47 038e9089 2004-03-21 devnull }
48 038e9089 2004-03-21 devnull
49 038e9089 2004-03-21 devnull static void
50 038e9089 2004-03-21 devnull drawstring(Display *dpy, ScreenInfo *s, Menu *m, int wide, int high, int i, int selected)
51 038e9089 2004-03-21 devnull {
52 038e9089 2004-03-21 devnull int tx, ty;
53 038e9089 2004-03-21 devnull
54 038e9089 2004-03-21 devnull tx = (wide - XTextWidth(font, m->item[i], strlen(m->item[i])))/2;
55 038e9089 2004-03-21 devnull ty = i*high + font->ascent + 1;
56 038e9089 2004-03-21 devnull XFillRectangle(dpy, s->menuwin, selected ? s->gcmenubgs : s->gcmenubg, 0, i*high, wide, high);
57 038e9089 2004-03-21 devnull XDrawString(dpy, s->menuwin, selected ? s->gcmenufgs : s->gcmenufg, tx, ty, m->item[i], strlen(m->item[i]));
58 038e9089 2004-03-21 devnull }
59 038e9089 2004-03-21 devnull
60 038e9089 2004-03-21 devnull int
61 038e9089 2004-03-21 devnull menuhit(XButtonEvent *e, Menu *m)
62 038e9089 2004-03-21 devnull {
63 038e9089 2004-03-21 devnull XEvent ev;
64 038e9089 2004-03-21 devnull int i, n, cur, old, wide, high, status, drawn, warp;
65 038e9089 2004-03-21 devnull int x, y, dx, dy, xmax, ymax;
66 038e9089 2004-03-21 devnull ScreenInfo *s;
67 038e9089 2004-03-21 devnull
68 ac33a34a 2005-07-13 devnull if(font == 0)
69 038e9089 2004-03-21 devnull return -1;
70 038e9089 2004-03-21 devnull s = getscreen(e->root);
71 ac33a34a 2005-07-13 devnull if(s == 0 || e->window == s->menuwin) /* ugly event mangling */
72 038e9089 2004-03-21 devnull return -1;
73 038e9089 2004-03-21 devnull
74 038e9089 2004-03-21 devnull dx = 0;
75 ac33a34a 2005-07-13 devnull for(n = 0; m->item[n]; n++){
76 038e9089 2004-03-21 devnull wide = XTextWidth(font, m->item[n], strlen(m->item[n])) + 4;
77 ac33a34a 2005-07-13 devnull if(wide > dx)
78 038e9089 2004-03-21 devnull dx = wide;
79 038e9089 2004-03-21 devnull }
80 038e9089 2004-03-21 devnull wide = dx;
81 038e9089 2004-03-21 devnull cur = m->lasthit;
82 ac33a34a 2005-07-13 devnull if(cur >= n)
83 038e9089 2004-03-21 devnull cur = n - 1;
84 038e9089 2004-03-21 devnull
85 038e9089 2004-03-21 devnull high = font->ascent + font->descent + 1;
86 038e9089 2004-03-21 devnull dy = n*high;
87 038e9089 2004-03-21 devnull x = e->x - wide/2;
88 038e9089 2004-03-21 devnull y = e->y - cur*high - high/2;
89 038e9089 2004-03-21 devnull warp = 0;
90 038e9089 2004-03-21 devnull xmax = DisplayWidth(dpy, s->num);
91 038e9089 2004-03-21 devnull ymax = DisplayHeight(dpy, s->num);
92 ac33a34a 2005-07-13 devnull if(x < 0){
93 038e9089 2004-03-21 devnull e->x -= x;
94 038e9089 2004-03-21 devnull x = 0;
95 038e9089 2004-03-21 devnull warp++;
96 038e9089 2004-03-21 devnull }
97 ac33a34a 2005-07-13 devnull if(x+wide >= xmax){
98 038e9089 2004-03-21 devnull e->x -= x+wide-xmax;
99 038e9089 2004-03-21 devnull x = xmax-wide;
100 038e9089 2004-03-21 devnull warp++;
101 038e9089 2004-03-21 devnull }
102 ac33a34a 2005-07-13 devnull if(y < 0){
103 038e9089 2004-03-21 devnull e->y -= y;
104 038e9089 2004-03-21 devnull y = 0;
105 038e9089 2004-03-21 devnull warp++;
106 038e9089 2004-03-21 devnull }
107 ac33a34a 2005-07-13 devnull if(y+dy >= ymax){
108 038e9089 2004-03-21 devnull e->y -= y+dy-ymax;
109 038e9089 2004-03-21 devnull y = ymax-dy;
110 038e9089 2004-03-21 devnull warp++;
111 038e9089 2004-03-21 devnull }
112 ac33a34a 2005-07-13 devnull if(warp)
113 038e9089 2004-03-21 devnull setmouse(e->x, e->y, s);
114 038e9089 2004-03-21 devnull XMoveResizeWindow(dpy, s->menuwin, x, y, dx, dy);
115 038e9089 2004-03-21 devnull XSelectInput(dpy, s->menuwin, MenuMask);
116 038e9089 2004-03-21 devnull XMapRaised(dpy, s->menuwin);
117 038e9089 2004-03-21 devnull status = grab(s->menuwin, None, MenuGrabMask, None, e->time);
118 ac33a34a 2005-07-13 devnull if(status != GrabSuccess){
119 038e9089 2004-03-21 devnull /* graberror("menuhit", status); */
120 038e9089 2004-03-21 devnull XUnmapWindow(dpy, s->menuwin);
121 038e9089 2004-03-21 devnull return -1;
122 038e9089 2004-03-21 devnull }
123 038e9089 2004-03-21 devnull drawn = 0;
124 ac33a34a 2005-07-13 devnull for(;;){
125 038e9089 2004-03-21 devnull XMaskEvent(dpy, MenuMask, &ev);
126 ac33a34a 2005-07-13 devnull switch (ev.type){
127 038e9089 2004-03-21 devnull default:
128 aa808685 2004-04-19 devnull fprintf(stderr, "rio: menuhit: unknown ev.type %d\n", ev.type);
129 038e9089 2004-03-21 devnull break;
130 038e9089 2004-03-21 devnull case ButtonPress:
131 038e9089 2004-03-21 devnull break;
132 038e9089 2004-03-21 devnull case ButtonRelease:
133 ac33a34a 2005-07-13 devnull if(ev.xbutton.button != e->button)
134 038e9089 2004-03-21 devnull break;
135 038e9089 2004-03-21 devnull x = ev.xbutton.x;
136 038e9089 2004-03-21 devnull y = ev.xbutton.y;
137 038e9089 2004-03-21 devnull i = y/high;
138 ac33a34a 2005-07-13 devnull if(cur >= 0 && y >= cur*high-3 && y < (cur+1)*high+3)
139 038e9089 2004-03-21 devnull i = cur;
140 ac33a34a 2005-07-13 devnull if(x < 0 || x > wide || y < -3)
141 038e9089 2004-03-21 devnull i = -1;
142 ac33a34a 2005-07-13 devnull else if(i < 0 || i >= n)
143 038e9089 2004-03-21 devnull i = -1;
144 038e9089 2004-03-21 devnull else
145 038e9089 2004-03-21 devnull m->lasthit = i;
146 ac33a34a 2005-07-13 devnull if(!nobuttons(&ev.xbutton))
147 038e9089 2004-03-21 devnull i = -1;
148 038e9089 2004-03-21 devnull ungrab(&ev.xbutton);
149 038e9089 2004-03-21 devnull XUnmapWindow(dpy, s->menuwin);
150 038e9089 2004-03-21 devnull return i;
151 038e9089 2004-03-21 devnull case MotionNotify:
152 ac33a34a 2005-07-13 devnull if(!drawn)
153 038e9089 2004-03-21 devnull break;
154 038e9089 2004-03-21 devnull x = ev.xbutton.x;
155 038e9089 2004-03-21 devnull y = ev.xbutton.y;
156 038e9089 2004-03-21 devnull old = cur;
157 038e9089 2004-03-21 devnull cur = y/high;
158 ac33a34a 2005-07-13 devnull if(old >= 0 && y >= old*high-3 && y < (old+1)*high+3)
159 038e9089 2004-03-21 devnull cur = old;
160 ac33a34a 2005-07-13 devnull if(x < 0 || x > wide || y < -3)
161 038e9089 2004-03-21 devnull cur = -1;
162 ac33a34a 2005-07-13 devnull else if(cur < 0 || cur >= n)
163 038e9089 2004-03-21 devnull cur = -1;
164 ac33a34a 2005-07-13 devnull if(cur == old)
165 038e9089 2004-03-21 devnull break;
166 ac33a34a 2005-07-13 devnull if(old >= 0 && old < n)
167 038e9089 2004-03-21 devnull drawstring(dpy, s, m, wide, high, old, 0);
168 ac33a34a 2005-07-13 devnull if(cur >= 0 && cur < n)
169 038e9089 2004-03-21 devnull drawstring(dpy, s, m, wide, high, cur, 1);
170 038e9089 2004-03-21 devnull break;
171 038e9089 2004-03-21 devnull case Expose:
172 038e9089 2004-03-21 devnull XClearWindow(dpy, s->menuwin);
173 ac33a34a 2005-07-13 devnull for(i = 0; i < n; i++)
174 038e9089 2004-03-21 devnull drawstring(dpy, s, m, wide, high, i, cur==i);
175 038e9089 2004-03-21 devnull drawn = 1;
176 038e9089 2004-03-21 devnull }
177 038e9089 2004-03-21 devnull }
178 038e9089 2004-03-21 devnull }
179 038e9089 2004-03-21 devnull
180 038e9089 2004-03-21 devnull Client *
181 038e9089 2004-03-21 devnull selectwin(int release, int *shift, ScreenInfo *s)
182 038e9089 2004-03-21 devnull {
183 038e9089 2004-03-21 devnull XEvent ev;
184 038e9089 2004-03-21 devnull XButtonEvent *e;
185 038e9089 2004-03-21 devnull int status;
186 038e9089 2004-03-21 devnull Window w;
187 038e9089 2004-03-21 devnull Client *c;
188 038e9089 2004-03-21 devnull
189 038e9089 2004-03-21 devnull status = grab(s->root, s->root, ButtonMask, s->target, 0);
190 ac33a34a 2005-07-13 devnull if(status != GrabSuccess){
191 038e9089 2004-03-21 devnull graberror("selectwin", status); /* */
192 038e9089 2004-03-21 devnull return 0;
193 038e9089 2004-03-21 devnull }
194 038e9089 2004-03-21 devnull w = None;
195 ac33a34a 2005-07-13 devnull for(;;){
196 038e9089 2004-03-21 devnull XMaskEvent(dpy, ButtonMask, &ev);
197 038e9089 2004-03-21 devnull e = &ev.xbutton;
198 ac33a34a 2005-07-13 devnull switch (ev.type){
199 038e9089 2004-03-21 devnull case ButtonPress:
200 ac33a34a 2005-07-13 devnull if(e->button != Button3){
201 038e9089 2004-03-21 devnull ungrab(e);
202 038e9089 2004-03-21 devnull return 0;
203 038e9089 2004-03-21 devnull }
204 038e9089 2004-03-21 devnull w = e->subwindow;
205 ac33a34a 2005-07-13 devnull if(!release){
206 038e9089 2004-03-21 devnull c = getclient(w, 0);
207 ac33a34a 2005-07-13 devnull if(c == 0)
208 038e9089 2004-03-21 devnull ungrab(e);
209 ac33a34a 2005-07-13 devnull if(shift != 0)
210 038e9089 2004-03-21 devnull *shift = (e->state&ShiftMask) != 0;
211 038e9089 2004-03-21 devnull return c;
212 038e9089 2004-03-21 devnull }
213 038e9089 2004-03-21 devnull break;
214 038e9089 2004-03-21 devnull case ButtonRelease:
215 038e9089 2004-03-21 devnull ungrab(e);
216 ac33a34a 2005-07-13 devnull if(e->button != Button3 || e->subwindow != w)
217 038e9089 2004-03-21 devnull return 0;
218 ac33a34a 2005-07-13 devnull if(shift != 0)
219 038e9089 2004-03-21 devnull *shift = (e->state&ShiftMask) != 0;
220 038e9089 2004-03-21 devnull return getclient(w, 0);
221 038e9089 2004-03-21 devnull }
222 038e9089 2004-03-21 devnull }
223 038e9089 2004-03-21 devnull }
224 038e9089 2004-03-21 devnull
225 c005568a 2004-03-30 devnull int
226 c005568a 2004-03-30 devnull sweepcalc(Client *c, int x, int y, BorderOrient bl, int ignored)
227 038e9089 2004-03-21 devnull {
228 038e9089 2004-03-21 devnull int dx, dy, sx, sy;
229 038e9089 2004-03-21 devnull
230 038e9089 2004-03-21 devnull dx = x - c->x;
231 038e9089 2004-03-21 devnull dy = y - c->y;
232 038e9089 2004-03-21 devnull sx = sy = 1;
233 e62ba5ec 2004-03-21 devnull x += dx;
234 ac33a34a 2005-07-13 devnull if(dx < 0){
235 038e9089 2004-03-21 devnull dx = -dx;
236 038e9089 2004-03-21 devnull sx = -1;
237 038e9089 2004-03-21 devnull }
238 e62ba5ec 2004-03-21 devnull y += dy;
239 ac33a34a 2005-07-13 devnull if(dy < 0){
240 038e9089 2004-03-21 devnull dy = -dy;
241 038e9089 2004-03-21 devnull sy = -1;
242 038e9089 2004-03-21 devnull }
243 038e9089 2004-03-21 devnull
244 038e9089 2004-03-21 devnull dx -= 2*BORDER;
245 038e9089 2004-03-21 devnull dy -= 2*BORDER;
246 038e9089 2004-03-21 devnull
247 ac33a34a 2005-07-13 devnull if(!c->is9term){
248 ac33a34a 2005-07-13 devnull if(dx < c->min_dx)
249 038e9089 2004-03-21 devnull dx = c->min_dx;
250 ac33a34a 2005-07-13 devnull if(dy < c->min_dy)
251 038e9089 2004-03-21 devnull dy = c->min_dy;
252 038e9089 2004-03-21 devnull }
253 038e9089 2004-03-21 devnull
254 ac33a34a 2005-07-13 devnull if(c->size.flags & PResizeInc){
255 038e9089 2004-03-21 devnull dx = c->min_dx + (dx-c->min_dx)/c->size.width_inc*c->size.width_inc;
256 038e9089 2004-03-21 devnull dy = c->min_dy + (dy-c->min_dy)/c->size.height_inc*c->size.height_inc;
257 038e9089 2004-03-21 devnull }
258 038e9089 2004-03-21 devnull
259 ac33a34a 2005-07-13 devnull if(c->size.flags & PMaxSize){
260 ac33a34a 2005-07-13 devnull if(dx > c->size.max_width)
261 038e9089 2004-03-21 devnull dx = c->size.max_width;
262 ac33a34a 2005-07-13 devnull if(dy > c->size.max_height)
263 038e9089 2004-03-21 devnull dy = c->size.max_height;
264 038e9089 2004-03-21 devnull }
265 038e9089 2004-03-21 devnull c->dx = sx*(dx + 2*BORDER);
266 038e9089 2004-03-21 devnull c->dy = sy*(dy + 2*BORDER);
267 c005568a 2004-03-30 devnull
268 c005568a 2004-03-30 devnull return ignored;
269 038e9089 2004-03-21 devnull }
270 038e9089 2004-03-21 devnull
271 c005568a 2004-03-30 devnull int
272 c005568a 2004-03-30 devnull dragcalc(Client *c, int x, int y, BorderOrient bl, int ignored)
273 038e9089 2004-03-21 devnull {
274 e62ba5ec 2004-03-21 devnull c->x += x;
275 e62ba5ec 2004-03-21 devnull c->y += y;
276 c005568a 2004-03-30 devnull
277 c005568a 2004-03-30 devnull return ignored;
278 1cb3fa80 2004-03-29 devnull }
279 1cb3fa80 2004-03-29 devnull
280 c005568a 2004-03-30 devnull int
281 c005568a 2004-03-30 devnull pullcalc(Client *c, int x, int y, BorderOrient bl, int init)
282 1cb3fa80 2004-03-29 devnull {
283 c005568a 2004-03-30 devnull int dx, dy, sx, sy, px, py, spx, spy, rdx, rdy, xoff, yoff, xcorn, ycorn;
284 c005568a 2004-03-30 devnull
285 c005568a 2004-03-30 devnull px = c->x;
286 c005568a 2004-03-30 devnull py = c->y;
287 c005568a 2004-03-30 devnull dx = c->dx;
288 c005568a 2004-03-30 devnull dy = c->dy;
289 c005568a 2004-03-30 devnull sx = sy = 1;
290 c005568a 2004-03-30 devnull spx = spy = 0;
291 c005568a 2004-03-30 devnull xoff = yoff = 0;
292 c005568a 2004-03-30 devnull xcorn = ycorn = 0;
293 c005568a 2004-03-30 devnull
294 ac33a34a 2005-07-13 devnull switch(bl){
295 1cb3fa80 2004-03-29 devnull case BorderN:
296 c005568a 2004-03-30 devnull py = y;
297 c005568a 2004-03-30 devnull dy = (c->y + c->dy) - y;
298 c005568a 2004-03-30 devnull spy = 1;
299 c005568a 2004-03-30 devnull yoff = y - c->y;
300 1cb3fa80 2004-03-29 devnull break;
301 1cb3fa80 2004-03-29 devnull case BorderS:
302 c005568a 2004-03-30 devnull dy = y - c->y;
303 c005568a 2004-03-30 devnull yoff = (c->y + c->dy) - y;
304 1cb3fa80 2004-03-29 devnull break;
305 1cb3fa80 2004-03-29 devnull case BorderE:
306 c005568a 2004-03-30 devnull dx = x - c->x;
307 c005568a 2004-03-30 devnull xoff = (c->x + c->dx) - x;
308 1cb3fa80 2004-03-29 devnull break;
309 1cb3fa80 2004-03-29 devnull case BorderW:
310 c005568a 2004-03-30 devnull px = x;
311 c005568a 2004-03-30 devnull dx = (c->x + c->dx) - x;
312 c005568a 2004-03-30 devnull spx = 1;
313 c005568a 2004-03-30 devnull xoff = x - c->x;
314 1cb3fa80 2004-03-29 devnull break;
315 c005568a 2004-03-30 devnull case BorderNNW:
316 c005568a 2004-03-30 devnull case BorderWNW:
317 c005568a 2004-03-30 devnull px = x;
318 c005568a 2004-03-30 devnull dx = (c->x + c->dx) - x;
319 c005568a 2004-03-30 devnull spx = 1;
320 c005568a 2004-03-30 devnull py = y;
321 c005568a 2004-03-30 devnull dy = (c->y + c->dy) - y;
322 c005568a 2004-03-30 devnull spy = 1;
323 c005568a 2004-03-30 devnull xoff = x - c->x;
324 c005568a 2004-03-30 devnull yoff = y - c->y;
325 1cb3fa80 2004-03-29 devnull break;
326 c005568a 2004-03-30 devnull case BorderNNE:
327 c005568a 2004-03-30 devnull case BorderENE:
328 c005568a 2004-03-30 devnull dx = x - c->x;
329 c005568a 2004-03-30 devnull py = y;
330 c005568a 2004-03-30 devnull dy = (c->y + c->dy) - y;
331 c005568a 2004-03-30 devnull spy = 1;
332 c005568a 2004-03-30 devnull xoff = (c->x + c->dx) - x;
333 c005568a 2004-03-30 devnull yoff = y - c->y;
334 1cb3fa80 2004-03-29 devnull break;
335 c005568a 2004-03-30 devnull case BorderSSE:
336 c005568a 2004-03-30 devnull case BorderESE:
337 c005568a 2004-03-30 devnull dx = x - c->x;
338 c005568a 2004-03-30 devnull dy = y - c->y;
339 c005568a 2004-03-30 devnull xoff = (c->x + c->dx) - x;
340 c005568a 2004-03-30 devnull yoff = (c->y + c->dy) - y;
341 1cb3fa80 2004-03-29 devnull break;
342 c005568a 2004-03-30 devnull case BorderSSW:
343 c005568a 2004-03-30 devnull case BorderWSW:
344 c005568a 2004-03-30 devnull px = x;
345 c005568a 2004-03-30 devnull dx = (c->x + c->dx) - x;
346 c005568a 2004-03-30 devnull spx = 1;
347 c005568a 2004-03-30 devnull dy = y - c->y;
348 c005568a 2004-03-30 devnull xoff = x - c->x;
349 c005568a 2004-03-30 devnull yoff = (c->y + c->dy) - y;
350 c005568a 2004-03-30 devnull break;
351 1cb3fa80 2004-03-29 devnull default:
352 c005568a 2004-03-30 devnull break;
353 c005568a 2004-03-30 devnull }
354 ac33a34a 2005-07-13 devnull switch(bl){
355 c005568a 2004-03-30 devnull case BorderNNW:
356 c005568a 2004-03-30 devnull case BorderNNE:
357 c005568a 2004-03-30 devnull case BorderSSW:
358 c005568a 2004-03-30 devnull case BorderSSE:
359 c005568a 2004-03-30 devnull xcorn = 1;
360 c005568a 2004-03-30 devnull break;
361 c005568a 2004-03-30 devnull case BorderWNW:
362 c005568a 2004-03-30 devnull case BorderENE:
363 c005568a 2004-03-30 devnull case BorderWSW:
364 c005568a 2004-03-30 devnull case BorderESE:
365 c005568a 2004-03-30 devnull ycorn = 1;
366 1cb3fa80 2004-03-29 devnull break;
367 c005568a 2004-03-30 devnull }
368 ac33a34a 2005-07-13 devnull if(!init
369 3ddda821 2004-12-28 devnull || xoff < 0 || (xcorn && xoff > CORNER) || (!xcorn && xoff > BORDER)
370 ac33a34a 2005-07-13 devnull || yoff < 0 || (ycorn && yoff > CORNER) || (!ycorn && yoff > BORDER)){
371 c005568a 2004-03-30 devnull xoff = 0;
372 c005568a 2004-03-30 devnull yoff = 0;
373 c005568a 2004-03-30 devnull init = 0;
374 c005568a 2004-03-30 devnull }
375 c005568a 2004-03-30 devnull
376 ac33a34a 2005-07-13 devnull if(debug) fprintf(stderr, "c %dx%d+%d+%d m +%d+%d r %dx%d+%d+%d sp (%d,%d) bl %d\n",
377 c005568a 2004-03-30 devnull c->dx, c->dy, c->x, c->y, x, y, dx, dy, px, py, spx, spy, bl);
378 ac33a34a 2005-07-13 devnull if(dx < 0){
379 c005568a 2004-03-30 devnull dx = -dx;
380 c005568a 2004-03-30 devnull sx = -1;
381 c005568a 2004-03-30 devnull }
382 ac33a34a 2005-07-13 devnull if(dy < 0){
383 c005568a 2004-03-30 devnull dy = -dy;
384 c005568a 2004-03-30 devnull sy = -1;
385 c005568a 2004-03-30 devnull }
386 c005568a 2004-03-30 devnull
387 c005568a 2004-03-30 devnull /* remember requested size;
388 3ddda821 2004-12-28 devnull * after applying size hints we may have to correct position
389 3ddda821 2004-12-28 devnull */
390 c005568a 2004-03-30 devnull rdx = sx*dx;
391 c005568a 2004-03-30 devnull rdy = sy*dy;
392 c005568a 2004-03-30 devnull
393 c005568a 2004-03-30 devnull /* apply size hints */
394 c005568a 2004-03-30 devnull dx -= (2*BORDER - xoff);
395 c005568a 2004-03-30 devnull dy -= (2*BORDER - yoff);
396 c005568a 2004-03-30 devnull
397 ac33a34a 2005-07-13 devnull if(!c->is9term){
398 ac33a34a 2005-07-13 devnull if(dx < c->min_dx)
399 c005568a 2004-03-30 devnull dx = c->min_dx;
400 ac33a34a 2005-07-13 devnull if(dy < c->min_dy)
401 c005568a 2004-03-30 devnull dy = c->min_dy;
402 c005568a 2004-03-30 devnull }
403 c005568a 2004-03-30 devnull
404 ac33a34a 2005-07-13 devnull if(c->size.flags & PResizeInc){
405 c005568a 2004-03-30 devnull dx = c->min_dx + (dx-c->min_dx)/c->size.width_inc*c->size.width_inc;
406 c005568a 2004-03-30 devnull dy = c->min_dy + (dy-c->min_dy)/c->size.height_inc*c->size.height_inc;
407 c005568a 2004-03-30 devnull }
408 c005568a 2004-03-30 devnull
409 ac33a34a 2005-07-13 devnull if(c->size.flags & PMaxSize){
410 ac33a34a 2005-07-13 devnull if(dx > c->size.max_width)
411 c005568a 2004-03-30 devnull dx = c->size.max_width;
412 ac33a34a 2005-07-13 devnull if(dy > c->size.max_height)
413 c005568a 2004-03-30 devnull dy = c->size.max_height;
414 1cb3fa80 2004-03-29 devnull }
415 c005568a 2004-03-30 devnull
416 c005568a 2004-03-30 devnull /* set size and position */
417 c005568a 2004-03-30 devnull c->dx = sx*(dx + 2*BORDER );
418 c005568a 2004-03-30 devnull c->dy = sy*(dy + 2*BORDER );
419 c005568a 2004-03-30 devnull c->x = px;
420 c005568a 2004-03-30 devnull c->y = py;
421 fa325e9b 2020-01-10 cross
422 c005568a 2004-03-30 devnull /* compensate position for size changed due to size hints */
423 7934b1c6 2004-04-05 devnull if(spx)
424 7934b1c6 2004-04-05 devnull c->x -= c->dx - rdx;
425 7934b1c6 2004-04-05 devnull if(spy)
426 7934b1c6 2004-04-05 devnull c->y -= c->dy - rdy;
427 c005568a 2004-03-30 devnull
428 c005568a 2004-03-30 devnull return init;
429 038e9089 2004-03-21 devnull }
430 038e9089 2004-03-21 devnull
431 038e9089 2004-03-21 devnull static void
432 038e9089 2004-03-21 devnull xcopy(int fwd, Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, int dx, int dy, int x1, int y1)
433 038e9089 2004-03-21 devnull {
434 038e9089 2004-03-21 devnull if(fwd)
435 038e9089 2004-03-21 devnull XCopyArea(dpy, src, dst, gc, x, y, dx, dy, x1, y1);
436 038e9089 2004-03-21 devnull else
437 038e9089 2004-03-21 devnull XCopyArea(dpy, dst, src, gc, x1, y1, dx, dy, x, y);
438 038e9089 2004-03-21 devnull }
439 038e9089 2004-03-21 devnull
440 038e9089 2004-03-21 devnull void
441 038e9089 2004-03-21 devnull drawbound(Client *c, int drawing)
442 038e9089 2004-03-21 devnull {
443 038e9089 2004-03-21 devnull int x, y, dx, dy;
444 038e9089 2004-03-21 devnull ScreenInfo *s;
445 c005568a 2004-03-30 devnull
446 ac33a34a 2005-07-13 devnull if(debug) fprintf(stderr, "drawbound %d %dx%d+%d+%d\n", drawing, c->dx, c->dy, c->x, c->y);
447 fa325e9b 2020-01-10 cross
448 038e9089 2004-03-21 devnull s = c->screen;
449 038e9089 2004-03-21 devnull x = c->x;
450 038e9089 2004-03-21 devnull y = c->y;
451 038e9089 2004-03-21 devnull dx = c->dx;
452 038e9089 2004-03-21 devnull dy = c->dy;
453 ac33a34a 2005-07-13 devnull if(dx < 0){
454 038e9089 2004-03-21 devnull x += dx;
455 038e9089 2004-03-21 devnull dx = -dx;
456 038e9089 2004-03-21 devnull }
457 ac33a34a 2005-07-13 devnull if(dy < 0){
458 038e9089 2004-03-21 devnull y += dy;
459 038e9089 2004-03-21 devnull dy = -dy;
460 038e9089 2004-03-21 devnull }
461 ac33a34a 2005-07-13 devnull if(dx <= 2 || dy <= 2)
462 038e9089 2004-03-21 devnull return;
463 038e9089 2004-03-21 devnull
464 038e9089 2004-03-21 devnull if(solidsweep){
465 038e9089 2004-03-21 devnull if(drawing == -1){
466 038e9089 2004-03-21 devnull XUnmapWindow(dpy, s->sweepwin);
467 038e9089 2004-03-21 devnull return;
468 038e9089 2004-03-21 devnull }
469 fa325e9b 2020-01-10 cross
470 038e9089 2004-03-21 devnull x += BORDER;
471 038e9089 2004-03-21 devnull y += BORDER;
472 038e9089 2004-03-21 devnull dx -= 2*BORDER;
473 038e9089 2004-03-21 devnull dy -= 2*BORDER;
474 038e9089 2004-03-21 devnull
475 038e9089 2004-03-21 devnull if(drawing){
476 038e9089 2004-03-21 devnull XMoveResizeWindow(dpy, s->sweepwin, x, y, dx, dy);
477 038e9089 2004-03-21 devnull XSelectInput(dpy, s->sweepwin, MenuMask);
478 038e9089 2004-03-21 devnull XMapRaised(dpy, s->sweepwin);
479 038e9089 2004-03-21 devnull }
480 038e9089 2004-03-21 devnull return;
481 038e9089 2004-03-21 devnull }
482 038e9089 2004-03-21 devnull
483 038e9089 2004-03-21 devnull if(drawing == -1)
484 038e9089 2004-03-21 devnull return;
485 038e9089 2004-03-21 devnull
486 038e9089 2004-03-21 devnull xcopy(drawing, dpy, s->root, s->bkup[0], s->gccopy, x, y, dx, BORDER, 0, 0);
487 038e9089 2004-03-21 devnull xcopy(drawing, dpy, s->root, s->bkup[0], s->gccopy, x, y+dy-BORDER, dx, BORDER, dx, 0);
488 038e9089 2004-03-21 devnull xcopy(drawing, dpy, s->root, s->bkup[1], s->gccopy, x, y, BORDER, dy, 0, 0);
489 038e9089 2004-03-21 devnull xcopy(drawing, dpy, s->root, s->bkup[1], s->gccopy, x+dx-BORDER, y, BORDER, dy, 0, dy);
490 038e9089 2004-03-21 devnull
491 038e9089 2004-03-21 devnull if(drawing){
492 038e9089 2004-03-21 devnull XFillRectangle(dpy, s->root, s->gcred, x, y, dx, BORDER);
493 038e9089 2004-03-21 devnull XFillRectangle(dpy, s->root, s->gcred, x, y+dy-BORDER, dx, BORDER);
494 038e9089 2004-03-21 devnull XFillRectangle(dpy, s->root, s->gcred, x, y, BORDER, dy);
495 038e9089 2004-03-21 devnull XFillRectangle(dpy, s->root, s->gcred, x+dx-BORDER, y, BORDER, dy);
496 038e9089 2004-03-21 devnull }
497 038e9089 2004-03-21 devnull }
498 038e9089 2004-03-21 devnull
499 038e9089 2004-03-21 devnull void
500 038e9089 2004-03-21 devnull misleep(int msec)
501 038e9089 2004-03-21 devnull {
502 038e9089 2004-03-21 devnull struct timeval t;
503 038e9089 2004-03-21 devnull
504 038e9089 2004-03-21 devnull t.tv_sec = msec/1000;
505 038e9089 2004-03-21 devnull t.tv_usec = (msec%1000)*1000;
506 038e9089 2004-03-21 devnull select(0, 0, 0, 0, &t);
507 038e9089 2004-03-21 devnull }
508 038e9089 2004-03-21 devnull
509 038e9089 2004-03-21 devnull int
510 c005568a 2004-03-30 devnull sweepdrag(Client *c, int but, XButtonEvent *e0, BorderOrient bl, int (*recalc)(Client*, int, int, BorderOrient, int))
511 038e9089 2004-03-21 devnull {
512 038e9089 2004-03-21 devnull XEvent ev;
513 038e9089 2004-03-21 devnull int idle;
514 038e9089 2004-03-21 devnull int cx, cy, rx, ry;
515 038e9089 2004-03-21 devnull int ox, oy, odx, ody;
516 038e9089 2004-03-21 devnull XButtonEvent *e;
517 c005568a 2004-03-30 devnull int notmoved;
518 038e9089 2004-03-21 devnull
519 c005568a 2004-03-30 devnull notmoved = 1;
520 038e9089 2004-03-21 devnull ox = c->x;
521 038e9089 2004-03-21 devnull oy = c->y;
522 038e9089 2004-03-21 devnull odx = c->dx;
523 038e9089 2004-03-21 devnull ody = c->dy;
524 038e9089 2004-03-21 devnull c->x -= BORDER;
525 038e9089 2004-03-21 devnull c->y -= BORDER;
526 038e9089 2004-03-21 devnull c->dx += 2*BORDER;
527 038e9089 2004-03-21 devnull c->dy += 2*BORDER;
528 ac33a34a 2005-07-13 devnull if(bl != BorderUnknown || e0 == 0)
529 1cb3fa80 2004-03-29 devnull getmouse(&cx, &cy, c->screen);
530 038e9089 2004-03-21 devnull else
531 c005568a 2004-03-30 devnull getmouse(&c->x, &c->y, c->screen);
532 038e9089 2004-03-21 devnull XGrabServer(dpy);
533 ac33a34a 2005-07-13 devnull if(bl != BorderUnknown){
534 c005568a 2004-03-30 devnull notmoved = recalc(c, cx, cy, bl, notmoved);
535 c005568a 2004-03-30 devnull }
536 038e9089 2004-03-21 devnull drawbound(c, 1);
537 038e9089 2004-03-21 devnull idle = 0;
538 ac33a34a 2005-07-13 devnull for(;;){
539 ac33a34a 2005-07-13 devnull if(XCheckMaskEvent(dpy, ButtonMask, &ev) == 0){
540 038e9089 2004-03-21 devnull getmouse(&rx, &ry, c->screen);
541 ac33a34a 2005-07-13 devnull if(rx != cx || ry != cy || ++idle > 300){
542 038e9089 2004-03-21 devnull drawbound(c, 0);
543 ac33a34a 2005-07-13 devnull if(rx == cx && ry == cy){
544 038e9089 2004-03-21 devnull XUngrabServer(dpy);
545 038e9089 2004-03-21 devnull XFlush(dpy);
546 038e9089 2004-03-21 devnull misleep(500);
547 038e9089 2004-03-21 devnull XGrabServer(dpy);
548 038e9089 2004-03-21 devnull idle = 0;
549 038e9089 2004-03-21 devnull }
550 7934b1c6 2004-04-05 devnull if(e0 || bl != BorderUnknown)
551 c005568a 2004-03-30 devnull notmoved = recalc(c, rx, ry, bl, notmoved);
552 e62ba5ec 2004-03-21 devnull else
553 c005568a 2004-03-30 devnull notmoved = recalc(c, rx-cx, ry-cy, bl, notmoved);
554 038e9089 2004-03-21 devnull cx = rx;
555 038e9089 2004-03-21 devnull cy = ry;
556 038e9089 2004-03-21 devnull drawbound(c, 1);
557 038e9089 2004-03-21 devnull XFlush(dpy);
558 038e9089 2004-03-21 devnull }
559 038e9089 2004-03-21 devnull misleep(50);
560 038e9089 2004-03-21 devnull continue;
561 038e9089 2004-03-21 devnull }
562 038e9089 2004-03-21 devnull e = &ev.xbutton;
563 ac33a34a 2005-07-13 devnull switch (ev.type){
564 038e9089 2004-03-21 devnull case ButtonPress:
565 038e9089 2004-03-21 devnull case ButtonRelease:
566 038e9089 2004-03-21 devnull drawbound(c, 0);
567 038e9089 2004-03-21 devnull ungrab(e);
568 038e9089 2004-03-21 devnull XUngrabServer(dpy);
569 ac33a34a 2005-07-13 devnull if(e->button != but && c->init)
570 038e9089 2004-03-21 devnull goto bad;
571 ac33a34a 2005-07-13 devnull if(c->dx < 0){
572 038e9089 2004-03-21 devnull c->x += c->dx;
573 038e9089 2004-03-21 devnull c->dx = -c->dx;
574 038e9089 2004-03-21 devnull }
575 ac33a34a 2005-07-13 devnull if(c->dy < 0){
576 038e9089 2004-03-21 devnull c->y += c->dy;
577 038e9089 2004-03-21 devnull c->dy = -c->dy;
578 038e9089 2004-03-21 devnull }
579 038e9089 2004-03-21 devnull c->x += BORDER;
580 038e9089 2004-03-21 devnull c->y += BORDER;
581 038e9089 2004-03-21 devnull c->dx -= 2*BORDER;
582 038e9089 2004-03-21 devnull c->dy -= 2*BORDER;
583 ac33a34a 2005-07-13 devnull if(c->dx < 4 || c->dy < 4 || c->dx < c->min_dx || c->dy < c->min_dy)
584 038e9089 2004-03-21 devnull goto bad;
585 038e9089 2004-03-21 devnull return 1;
586 038e9089 2004-03-21 devnull }
587 038e9089 2004-03-21 devnull }
588 038e9089 2004-03-21 devnull bad:
589 ac33a34a 2005-07-13 devnull if(debug) fprintf(stderr, "sweepdrag bad\n");
590 038e9089 2004-03-21 devnull c->x = ox;
591 038e9089 2004-03-21 devnull c->y = oy;
592 038e9089 2004-03-21 devnull c->dx = odx;
593 038e9089 2004-03-21 devnull c->dy = ody;
594 038e9089 2004-03-21 devnull drawbound(c, -1);
595 038e9089 2004-03-21 devnull return 0;
596 038e9089 2004-03-21 devnull }
597 038e9089 2004-03-21 devnull
598 038e9089 2004-03-21 devnull int
599 1cb3fa80 2004-03-29 devnull sweep(Client *c, int but, XButtonEvent *ignored)
600 038e9089 2004-03-21 devnull {
601 038e9089 2004-03-21 devnull XEvent ev;
602 038e9089 2004-03-21 devnull int status;
603 038e9089 2004-03-21 devnull XButtonEvent *e;
604 038e9089 2004-03-21 devnull ScreenInfo *s;
605 038e9089 2004-03-21 devnull
606 038e9089 2004-03-21 devnull s = c->screen;
607 3e3817f7 2004-04-06 devnull c->dx = 0;
608 3e3817f7 2004-04-06 devnull c->dy = 0;
609 038e9089 2004-03-21 devnull status = grab(s->root, s->root, ButtonMask, s->sweep0, 0);
610 ac33a34a 2005-07-13 devnull if(status != GrabSuccess){
611 038e9089 2004-03-21 devnull graberror("sweep", status); /* */
612 038e9089 2004-03-21 devnull return 0;
613 038e9089 2004-03-21 devnull }
614 038e9089 2004-03-21 devnull
615 038e9089 2004-03-21 devnull XMaskEvent(dpy, ButtonMask, &ev);
616 038e9089 2004-03-21 devnull e = &ev.xbutton;
617 ac33a34a 2005-07-13 devnull if(e->button != but){
618 038e9089 2004-03-21 devnull ungrab(e);
619 038e9089 2004-03-21 devnull return 0;
620 038e9089 2004-03-21 devnull }
621 038e9089 2004-03-21 devnull XChangeActivePointerGrab(dpy, ButtonMask, s->boxcurs, e->time);
622 7934b1c6 2004-04-05 devnull return sweepdrag(c, but, e, BorderUnknown, sweepcalc);
623 038e9089 2004-03-21 devnull }
624 038e9089 2004-03-21 devnull
625 038e9089 2004-03-21 devnull int
626 1cb3fa80 2004-03-29 devnull pull(Client *c, int but, XButtonEvent *e)
627 038e9089 2004-03-21 devnull {
628 038e9089 2004-03-21 devnull int status;
629 038e9089 2004-03-21 devnull ScreenInfo *s;
630 c005568a 2004-03-30 devnull BorderOrient bl;
631 038e9089 2004-03-21 devnull
632 c005568a 2004-03-30 devnull bl = borderorient(c, e->x, e->y);
633 c005568a 2004-03-30 devnull /* assert(bl > BorderUnknown && bl < NBorder); */
634 c005568a 2004-03-30 devnull
635 038e9089 2004-03-21 devnull s = c->screen;
636 1cb3fa80 2004-03-29 devnull status = grab(s->root, s->root, ButtonMask, s->bordcurs[bl], 0);
637 ac33a34a 2005-07-13 devnull if(status != GrabSuccess){
638 1cb3fa80 2004-03-29 devnull graberror("pull", status); /* */
639 1cb3fa80 2004-03-29 devnull return 0;
640 1cb3fa80 2004-03-29 devnull }
641 1cb3fa80 2004-03-29 devnull
642 1cb3fa80 2004-03-29 devnull return sweepdrag(c, but, 0, bl, pullcalc);
643 1cb3fa80 2004-03-29 devnull }
644 1cb3fa80 2004-03-29 devnull
645 1cb3fa80 2004-03-29 devnull int
646 1cb3fa80 2004-03-29 devnull drag(Client *c, int but)
647 1cb3fa80 2004-03-29 devnull {
648 1cb3fa80 2004-03-29 devnull int status;
649 1cb3fa80 2004-03-29 devnull ScreenInfo *s;
650 1cb3fa80 2004-03-29 devnull
651 1cb3fa80 2004-03-29 devnull s = c->screen;
652 038e9089 2004-03-21 devnull status = grab(s->root, s->root, ButtonMask, s->boxcurs, 0);
653 ac33a34a 2005-07-13 devnull if(status != GrabSuccess){
654 038e9089 2004-03-21 devnull graberror("drag", status); /* */
655 038e9089 2004-03-21 devnull return 0;
656 038e9089 2004-03-21 devnull }
657 7934b1c6 2004-04-05 devnull return sweepdrag(c, but, 0, BorderUnknown, dragcalc);
658 038e9089 2004-03-21 devnull }
659 038e9089 2004-03-21 devnull
660 038e9089 2004-03-21 devnull void
661 038e9089 2004-03-21 devnull getmouse(int *x, int *y, ScreenInfo *s)
662 038e9089 2004-03-21 devnull {
663 038e9089 2004-03-21 devnull Window dw1, dw2;
664 038e9089 2004-03-21 devnull int t1, t2;
665 038e9089 2004-03-21 devnull unsigned int t3;
666 038e9089 2004-03-21 devnull
667 038e9089 2004-03-21 devnull XQueryPointer(dpy, s->root, &dw1, &dw2, x, y, &t1, &t2, &t3);
668 ac33a34a 2005-07-13 devnull if(debug) fprintf(stderr, "getmouse: %d %d\n", *x, *y);
669 038e9089 2004-03-21 devnull }
670 038e9089 2004-03-21 devnull
671 038e9089 2004-03-21 devnull void
672 038e9089 2004-03-21 devnull setmouse(int x, int y, ScreenInfo *s)
673 038e9089 2004-03-21 devnull {
674 038e9089 2004-03-21 devnull XWarpPointer(dpy, None, s->root, None, None, None, None, x, y);
675 038e9089 2004-03-21 devnull }