]> git.decadent.org.uk Git - ion3.git/blob - ioncore/conf.c
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / ioncore / conf.c
1 /*
2  * ion/ioncore/conf.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <libtu/map.h>
16 #include <libtu/minmax.h>
17 #include <libtu/objp.h>
18 #include <libtu/map.h>
19 #include <libextl/readconfig.h>
20
21 #include "common.h"
22 #include "global.h"
23 #include "modules.h"
24 #include "rootwin.h"
25 #include "bindmaps.h"
26 #include "kbresize.h"
27 #include "reginfo.h"
28 #include "group-ws.h"
29 #include "llist.h"
30
31
32 StringIntMap frame_idxs[]={
33     {"last", LLIST_INDEX_LAST},
34     {"next",  LLIST_INDEX_AFTER_CURRENT},
35     {"next-act",  LLIST_INDEX_AFTER_CURRENT_ACT},
36     END_STRINGINTMAP
37 };
38
39 static bool get_winprop_fn_set=FALSE;
40 static ExtlFn get_winprop_fn;
41
42 static bool get_layout_fn_set=FALSE;
43 static ExtlFn get_layout_fn;
44
45
46 /*EXTL_DOC
47  * Set ioncore basic settings. The table \var{tab} may contain the
48  * following fields.
49  * 
50  * \begin{tabularx}{\linewidth}{lX}
51  *  \tabhead{Field & Description}
52  *  \var{opaque_resize} & (boolean) Controls whether interactive move and
53  *                        resize operations simply draw a rubberband during
54  *                        the operation (false) or immediately affect the 
55  *                        object in question at every step (true). \\
56  *  \var{warp} &          (boolean) Should focusing operations move the 
57  *                        pointer to the object to be focused? \\
58  *  \var{switchto} &      (boolean) Should a managing \type{WMPlex} switch
59  *                        to a newly mapped client window? \\
60  *  \var{screen_notify} & (boolean) Should notification tooltips be displayed
61  *                        for hidden workspaces with activity? \\
62  *  \var{frame_default_index} & (string) Specifies where to add new regions
63  *                        on the mutually exclusive list of a frame. One of
64  *                        ''last'', ''next'' (for after current), ''next-act''
65  *                        (for after current and anything with activity right
66  *                        after it). \\
67  *  \var{dblclick_delay} & (integer) Delay between clicks of a double click.\\
68  *  \var{kbresize_delay} & (integer) Delay in milliseconds for ending keyboard
69  *                         resize mode after inactivity. \\
70  *  \var{kbresize_t_max} & (integer) Controls keyboard resize acceleration. 
71  *                         See description below for details. \\
72  *  \var{kbresize_t_min} & (integer) See below. \\
73  *  \var{kbresize_step} & (floating point) See below. \\
74  *  \var{kbresize_maxacc} & (floating point) See below. \\
75  *  \var{framed_transients} & (boolean) Put transients in nested frames. \\
76  *  \var{float_placement_method} & (string) How to place floating frames.
77  *                          One of ''udlr'' (up-down, then left-right), 
78  *                          ''lrud'' (left-right, then up-down) or ''random''. \\
79  * \end{tabularx}
80  * 
81  * When a keyboard resize function is called, and at most \var{kbresize_t_max} 
82  * milliseconds has passed from a previous call, acceleration factor is reset 
83  * to 1.0. Otherwise, if at least \var{kbresize_t_min} milliseconds have 
84  * passed from the from previous acceleration update or reset the squere root
85  * of the acceleration factor is incremented by \var{kbresize_step}. The 
86  * maximum acceleration factor (pixels/call modulo size hints) is given by 
87  * \var{kbresize_maxacc}. The default values are (200, 50, 30, 100). 
88  */
89 EXTL_EXPORT
90 void ioncore_set(ExtlTab tab)
91 {
92     int dd, rd;
93     char *wst, *tmp;
94     ExtlTab t;
95     ExtlFn fn;
96     
97     extl_table_gets_b(tab, "opaque_resize", &(ioncore_g.opaque_resize));
98     extl_table_gets_b(tab, "warp", &(ioncore_g.warp_enabled));
99     extl_table_gets_b(tab, "switchto", &(ioncore_g.switchto_new));
100     extl_table_gets_b(tab, "screen_notify", &(ioncore_g.screen_notify));
101     extl_table_gets_b(tab, "framed_transients", &(ioncore_g.framed_transients));
102     
103     if(extl_table_gets_s(tab, "frame_default_index", &tmp)){
104         ioncore_g.frame_default_index=stringintmap_value(frame_idxs, 
105                                                          tmp,
106                                                          ioncore_g.frame_default_index);
107         free(tmp);
108     }
109     
110     if(extl_table_gets_i(tab, "dblclick_delay", &dd))
111         ioncore_g.dblclick_delay=maxof(0, dd);
112     
113     ioncore_set_moveres_accel(tab);
114     
115     ioncore_groupws_set(tab);
116     
117     /* Internal -- therefore undocumented above */
118     if(extl_table_gets_f(tab, "_get_winprop", &fn)){
119         if(get_winprop_fn_set)
120             extl_unref_fn(get_winprop_fn);
121         get_winprop_fn=fn;
122         get_winprop_fn_set=TRUE;
123     }
124     
125     if(extl_table_gets_f(tab, "_get_layout", &fn)){
126         if(get_layout_fn_set)
127             extl_unref_fn(get_layout_fn);
128         get_layout_fn=fn;
129         get_layout_fn_set=TRUE;
130     }
131     
132 }
133
134
135 /*EXTL_DOC
136  * Get ioncore basic settings. For details see \fnref{ioncore.set}.
137  */
138 EXTL_SAFE
139 EXTL_EXPORT
140 ExtlTab ioncore_get()
141 {
142     ExtlTab tab=extl_create_table();
143     
144     extl_table_sets_b(tab, "opaque_resize", ioncore_g.opaque_resize);
145     extl_table_sets_b(tab, "warp", ioncore_g.warp_enabled);
146     extl_table_sets_b(tab, "switchto", ioncore_g.switchto_new);
147     extl_table_sets_i(tab, "dblclick_delay", ioncore_g.dblclick_delay);
148     extl_table_sets_b(tab, "screen_notify", ioncore_g.screen_notify);
149
150     extl_table_sets_s(tab, "frame_default_index", 
151                       stringintmap_key(frame_idxs, 
152                                        ioncore_g.frame_default_index,
153                                        NULL));
154     
155     ioncore_get_moveres_accel(tab);
156     
157     ioncore_groupws_get(tab);
158     
159     return tab;
160 }
161
162
163 ExtlTab ioncore_get_winprop(WClientWin *cwin)
164 {
165     ExtlTab tab=extl_table_none();
166     
167     if(get_winprop_fn_set){
168         extl_protect(NULL);
169         extl_call(get_winprop_fn, "o", "t", cwin, &tab);
170         extl_unprotect(NULL);
171     }
172     
173     return tab;
174 }
175
176
177 ExtlTab ioncore_get_layout(const char *layout)
178 {
179     ExtlTab tab=extl_table_none();
180     
181     if(get_layout_fn_set){
182         extl_protect(NULL);
183         extl_call(get_layout_fn, "s", "t", layout, &tab);
184         extl_unprotect(NULL);
185     }
186     
187     return tab;
188 }
189     
190
191 /*EXTL_DOC
192  * Get important directories (userdir, sessiondir, searchpath).
193  */
194 EXTL_SAFE
195 EXTL_EXPORT
196 ExtlTab ioncore_get_paths(ExtlTab tab)
197 {
198     tab=extl_create_table();
199     extl_table_sets_s(tab, "userdir", extl_userdir());
200     extl_table_sets_s(tab, "sessiondir", extl_sessiondir());
201     extl_table_sets_s(tab, "searchpath", extl_searchpath());
202     return tab;
203 }
204
205
206 /*EXTL_DOC
207  * Set important directories (sessiondir, searchpath).
208  */
209 EXTL_EXPORT
210 bool ioncore_set_paths(ExtlTab tab)
211 {
212     char *s;
213
214     if(extl_table_gets_s(tab, "userdir", &s)){
215         warn(TR("User directory can not be set."));
216         free(s);
217         return FALSE;
218     }
219     
220     if(extl_table_gets_s(tab, "sessiondir", &s)){
221         extl_set_sessiondir(s);
222         free(s);
223         return FALSE;
224     }
225
226     if(extl_table_gets_s(tab, "searchpath", &s)){
227         extl_set_searchpath(s);
228         free(s);
229         return FALSE;
230     }
231     
232     return TRUE;
233 }
234
235
236 /* Exports these in ioncore. */
237
238 /*EXTL_DOC
239  * Lookup script \var{file}. If \var{try_in_dir} is set, it is tried
240  * before the standard search path.
241  */
242 EXTL_SAFE
243 EXTL_EXPORT_AS(ioncore, lookup_script)
244 char *extl_lookup_script(const char *file, const char *sp);
245
246
247 /*EXTL_DOC
248  * Get a file name to save (session) data in. The string \var{basename} 
249  * should contain no path or extension components.
250  */
251 EXTL_SAFE
252 EXTL_EXPORT_AS(ioncore, get_savefile)
253 char *extl_get_savefile(const char *basename);
254
255
256 /*EXTL_DOC
257  * Write \var{tab} in file with basename \var{basename} in the
258  * session directory.
259  */
260 EXTL_SAFE
261 EXTL_EXPORT_AS(ioncore, write_savefile)
262 bool extl_write_savefile(const char *basename, ExtlTab tab);
263
264
265 /*EXTL_DOC
266  * Read a savefile.
267  */
268 EXTL_SAFE
269 EXTL_EXPORT_AS(ioncore, read_savefile)
270 ExtlTab extl_extl_read_savefile(const char *basename);
271
272     
273
274 bool ioncore_read_main_config(const char *cfgfile)
275 {
276     bool ret;
277     int unset=0;
278
279     if(cfgfile==NULL)
280         cfgfile="cfg_ion";
281     
282     ret=extl_read_config(cfgfile, ".", TRUE);
283     
284     unset+=(ioncore_screen_bindmap->nbindings==0);
285     unset+=(ioncore_mplex_bindmap->nbindings==0);
286     unset+=(ioncore_frame_bindmap->nbindings==0);
287     
288     if(unset>0){
289         warn(TR("Some bindmaps were empty, loading ioncore_efbb."));
290         extl_read_config("ioncore_efbb", NULL, TRUE);
291     }
292     
293     return (ret && unset==0);
294 }