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