Remove/mark some unused functions and parameters
[notion.git] / ioncore / kbresize.c
blobe1150a39983101b31bc503b4b8e99d4c5a8d332b
1 /*
2 * ion/ioncore/kbresize.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <math.h>
10 #include <sys/time.h>
11 #include <time.h>
12 #include <limits.h>
14 #include <libtu/minmax.h>
16 #include <libmainloop/signal.h>
18 #include "global.h"
19 #include "resize.h"
20 #include "kbresize.h"
21 #include "grab.h"
22 #include "binding.h"
23 #include "focus.h"
24 #include "bindmaps.h"
27 /*{{{ Resize accelerator */
30 static struct timeval last_action_tv={-1, 0};
31 static struct timeval last_update_tv={-1, 0};
32 static int last_accel_mode=0;
33 static double accel=1, accelinc=30, accelmax=100*100;
34 static long actmax=200, uptmin=50;
35 static int resize_delay=CF_RESIZE_DELAY;
36 /* Here to not have to write other set callback for resize code... */
37 int ioncore_edge_resistance=CF_EDGE_RESISTANCE;
40 static void accel_reset()
42 last_accel_mode=0;
43 accel=1.0;
44 last_action_tv.tv_sec=-1;
45 last_action_tv.tv_usec=-1;
49 void ioncore_set_moveres_accel(ExtlTab tab)
51 int t_max, t_min, rd, er;
52 double step, maxacc;
54 if(extl_table_gets_i(tab, "kbresize_t_max", &t_max))
55 actmax=(t_max>0 ? t_max : INT_MAX);
56 if(extl_table_gets_i(tab, "kbresize_t_min", &t_min))
57 uptmin=(t_min>0 ? t_min : INT_MAX);
58 if(extl_table_gets_d(tab, "kbresize_step", &step))
59 accelinc=(step>0 ? step : 1);
60 if(extl_table_gets_d(tab, "kbresize_maxacc", &maxacc))
61 accelmax=(maxacc>0 ? maxacc*maxacc : 1);
62 if(extl_table_gets_i(tab, "kbresize_delay", &rd))
63 resize_delay=maxof(0, rd);
64 if(extl_table_gets_i(tab, "edge_resistance", &er))
65 ioncore_edge_resistance=maxof(0, er);
69 void ioncore_get_moveres_accel(ExtlTab tab)
71 extl_table_sets_i(tab, "kbresize_t_max", actmax),
72 extl_table_sets_i(tab, "kbresize_t_min", uptmin);
73 extl_table_sets_d(tab, "kbresize_step", accelinc);
74 extl_table_sets_d(tab, "kbresize_maxacc", accelmax);
75 extl_table_sets_d(tab, "kbresize_delay", resize_delay);
76 extl_table_sets_i(tab, "edge_resistance", ioncore_edge_resistance);
80 static int sign(int x)
82 return (x>0 ? 1 : (x<0 ? -1 : 0));
86 static long tvdiffmsec(struct timeval *tv1, struct timeval *tv2)
88 double t1=1000*(double)tv1->tv_sec+(double)tv1->tv_usec/1000;
89 double t2=1000*(double)tv2->tv_sec+(double)tv2->tv_usec/1000;
91 return (int)(t1-t2);
94 void moveresmode_accel(WMoveresMode *mode, int *wu, int *hu, int accel_mode)
96 struct timeval tv;
97 long adiff, udiff;
99 if(mainloop_gettime(&tv)!=0)
100 return;
102 adiff=tvdiffmsec(&tv, &last_action_tv);
103 udiff=tvdiffmsec(&tv, &last_update_tv);
105 if(last_accel_mode==accel_mode && adiff<actmax){
106 if(udiff>uptmin){
107 accel+=accelinc;
108 if(accel>accelmax)
109 accel=accelmax;
110 last_update_tv=tv;
112 }else{
113 accel=1.0;
114 last_update_tv=tv;
117 last_accel_mode=accel_mode;
118 last_action_tv=tv;
120 if(*wu!=0)
121 *wu=(*wu)*ceil(sqrt(accel)/abs(*wu));
122 if(*hu!=0)
123 *hu=(*hu)*ceil(sqrt(accel)/abs(*hu));
127 /*}}}*/
130 /*{{{ Keyboard resize handler */
133 static ExtlExportedFn *moveres_safe_fns[]={
134 (ExtlExportedFn*)&moveresmode_resize,
135 (ExtlExportedFn*)&moveresmode_move,
136 (ExtlExportedFn*)&moveresmode_rqgeom_extl,
137 (ExtlExportedFn*)&moveresmode_geom,
138 (ExtlExportedFn*)&moveresmode_finish,
139 (ExtlExportedFn*)&moveresmode_cancel,
140 NULL
143 static ExtlSafelist moveres_safelist=EXTL_SAFELIST_INIT(moveres_safe_fns);
146 static bool resize_handler(WRegion *reg, XEvent *xev)
148 XKeyEvent *ev=&xev->xkey;
149 WBinding *binding=NULL;
150 WMoveresMode *mode;
152 if(ev->type==KeyRelease)
153 return FALSE;
155 if(reg==NULL)
156 return FALSE;
158 mode=moveres_mode(reg);
160 if(mode==NULL)
161 return FALSE;
163 binding=bindmap_lookup_binding(ioncore_moveres_bindmap,
164 BINDING_KEYPRESS,
165 ev->state, ev->keycode);
167 if(!binding)
168 return FALSE;
170 if(binding!=NULL){
171 extl_protect(&moveres_safelist);
172 extl_call(binding->func, "oo", NULL, mode, reg);
173 extl_unprotect(&moveres_safelist);
176 return (moveres_mode(reg)==NULL);
180 /*}}}*/
183 /*{{{ Resize timer */
186 static WTimer *resize_timer=NULL;
189 static void tmr_end_resize(WTimer *UNUSED(unused), WMoveresMode *mode)
191 if(mode!=NULL)
192 moveresmode_cancel(mode);
196 static bool setup_resize_timer(WMoveresMode *mode)
198 if(resize_timer==NULL){
199 resize_timer=create_timer();
200 if(resize_timer==NULL)
201 return FALSE;
204 timer_set(resize_timer, resize_delay,
205 (WTimerHandler*)tmr_end_resize, (Obj*)mode);
207 return TRUE;
211 static void reset_resize_timer()
213 if(resize_timer!=NULL){
214 timer_reset(resize_timer);
215 destroy_obj((Obj*)resize_timer);
216 resize_timer=NULL;
221 /*}}}*/
224 /*{{{ Misc. */
227 static int limit_and_encode_mode(int *left, int *right,
228 int *top, int *bottom)
230 *left=sign(*left);
231 *right=sign(*right);
232 *top=sign(*top);
233 *bottom=sign(*bottom);
235 return (*left)+(*right)*3+(*top)*9+(*bottom)*27;
239 static void resize_units(WMoveresMode *mode, int *wret, int *hret)
241 WSizeHints *h=&(mode->hints);
242 *wret=1;
243 *hret=1;
244 if(h->inc_set && (h->width_inc>1 || h->height_inc>1)){
245 *wret=h->width_inc;
246 *hret=h->height_inc;
251 /*}}}*/
254 /*{{{ Keyboard resize interface */
257 /*EXTL_DOC
258 * Shrink or grow resize mode target one step in each direction.
259 * Acceptable values for the parameters \var{left}, \var{right}, \var{top}
260 * and \var{bottom} are as follows: -1: shrink along,
261 * 0: do not change, 1: grow along corresponding border.
263 EXTL_EXPORT_MEMBER
264 void moveresmode_resize(WMoveresMode *mode,
265 int left, int right, int top, int bottom)
267 int wu=0, hu=0;
268 int accel_mode=0;
270 if(!setup_resize_timer(mode))
271 return;
273 accel_mode=3*limit_and_encode_mode(&left, &right, &top, &bottom);
274 resize_units(mode, &wu, &hu);
275 moveresmode_accel(mode, &wu, &hu, accel_mode);
277 moveresmode_delta_resize(mode, -left*wu, right*wu, -top*hu, bottom*hu,
278 NULL);
282 /*EXTL_DOC
283 * Move resize mode target one step:
285 * \begin{tabular}{rl}
286 * \hline
287 * \var{horizmul}/\var{vertmul} & effect \\\hline
288 * -1 & Move left/up \\
289 * 0 & No effect \\
290 * 1 & Move right/down \\
291 * \end{tabular}
293 EXTL_EXPORT_MEMBER
294 void moveresmode_move(WMoveresMode *mode, int horizmul, int vertmul)
296 int accel_mode=0, dummy=0;
298 if(!setup_resize_timer(mode))
299 return;
301 accel_mode=1+3*limit_and_encode_mode(&horizmul, &vertmul, &dummy, &dummy);
302 moveresmode_accel(mode, &horizmul, &vertmul, accel_mode);
304 moveresmode_delta_resize(mode, horizmul, horizmul, vertmul, vertmul,
305 NULL);
309 /*EXTL_DOC
310 * Request exact geometry in move/resize mode. For details on parameters,
311 * see \fnref{WRegion.rqgeom}.
313 EXTL_EXPORT_AS(WMoveresMode, rqgeom)
314 ExtlTab moveresmode_rqgeom_extl(WMoveresMode *mode, ExtlTab g)
316 WRQGeomParams rq=RQGEOMPARAMS_INIT;
317 WRectangle res;
319 rqgeomparams_from_table(&rq, &mode->geom, g);
321 moveresmode_rqgeom(mode, &rq, &res);
323 return extl_table_from_rectangle(&res);
326 /*EXTL_DOC
327 * Returns current geometry.
329 EXTL_EXPORT_MEMBER
330 ExtlTab moveresmode_geom(WMoveresMode *mode)
332 return extl_table_from_rectangle(&mode->geom);
336 /*EXTL_DOC
337 * Return from move/resize mode and apply changes unless opaque
338 * move/resize is enabled.
340 EXTL_EXPORT_MEMBER
341 void moveresmode_finish(WMoveresMode *mode)
343 WRegion *reg=moveresmode_target(mode);
344 if(moveresmode_do_end(mode, TRUE)){
345 reset_resize_timer();
346 region_warp(reg);
347 ioncore_grab_remove(resize_handler);
352 /*EXTL_DOC
353 * Return from move/resize cancelling changes if opaque
354 * move/resize has not been enabled.
356 EXTL_EXPORT_MEMBER
357 void moveresmode_cancel(WMoveresMode *mode)
359 WRegion *reg=moveresmode_target(mode);
360 if(moveresmode_do_end(mode, FALSE)){
361 reset_resize_timer();
362 region_warp(reg);
363 ioncore_grab_remove(resize_handler);
368 static void cancel_moveres(WRegion *reg)
370 WMoveresMode *mode=moveres_mode(reg);
371 if(mode!=NULL)
372 moveresmode_cancel(mode);
376 /*EXTL_DOC
377 * Enter move/resize mode for \var{reg}. The bindings set with
378 * \fnref{ioncore.set_bindings} for \type{WMoveresMode} are used in
379 * this mode. Of the functions exported by the Ion C core, only
380 * \fnref{WMoveresMode.resize}, \fnref{WMoveresMode.move},
381 * \fnref{WMoveresMode.cancel} and \fnref{WMoveresMode.end} are
382 * allowed to be called while in this mode.
384 EXTL_EXPORT_MEMBER
385 WMoveresMode *region_begin_kbresize(WRegion *reg)
387 WMoveresMode *mode=region_begin_resize(reg, NULL, FALSE);
389 if(mode==NULL)
390 return NULL;
392 if(!setup_resize_timer(mode))
393 return NULL;
395 accel_reset();
397 ioncore_grab_establish(reg, resize_handler,
398 (GrabKilledHandler*)cancel_moveres, 0);
400 return mode;
404 /*}}}*/