Simple lua repl for testing
[notion.git] / ioncore / saveload.c
blob81dd1dba239897356e9692245f0911b1da042299
1 /*
2 * ion/ioncore/saveload.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
10 #include <time.h>
11 #include <unistd.h>
13 #include <libtu/objp.h>
14 #include <libextl/readconfig.h>
15 #include <libextl/extl.h>
17 #include "common.h"
18 #include "global.h"
19 #include "region.h"
20 #include "screen.h"
21 #include "saveload.h"
22 #include "names.h"
23 #include "attach.h"
24 #include "reginfo.h"
25 #include "extlconv.h"
26 #include "group-ws.h"
29 static bool loading_layout=FALSE;
30 static bool layout_load_error=FALSE;
33 /*{{{ Session management module support */
36 static SMAddCallback *add_cb;
37 static SMCfgCallback *cfg_cb;
40 void ioncore_set_sm_callbacks(SMAddCallback *add, SMCfgCallback *cfg)
42 add_cb=add;
43 cfg_cb=cfg;
47 void ioncore_get_sm_callbacks(SMAddCallback **add, SMCfgCallback **cfg)
49 *add=add_cb;
50 *cfg=cfg_cb;
54 /*}}}*/
57 /*{{{ Load support functions */
60 static WPHolder **current_ph_p=NULL;
63 WPHolder *ioncore_get_load_pholder()
65 if(current_ph_p==NULL){
66 return NULL;
67 }else{
68 WPHolder *ph=*current_ph_p;
69 *current_ph_p=NULL;
70 return ph;
75 WRegion *create_region_load(WWindow *par, const WFitParams *fp,
76 ExtlTab tab, WPHolder **sm_ph_p)
78 char *objclass=NULL, *name=NULL;
79 WRegionLoadCreateFn* fn=NULL;
80 WRegClassInfo *info=NULL;
81 WRegion *reg=NULL;
82 bool grouped=FALSE;
83 char *grouped_name=NULL;
84 WPHolder **old_ph_p;
86 if(!extl_table_gets_s(tab, "type", &objclass))
87 return NULL;
89 if(objclass==NULL)
90 return NULL;
92 info=ioncore_lookup_regclass(objclass, FALSE);
93 if(info!=NULL)
94 fn=info->lc_fn;
96 if(fn==NULL){
97 warn(TR("Unknown class \"%s\", cannot create region."),
98 objclass);
99 layout_load_error=loading_layout;
100 return NULL;
103 free(objclass);
105 old_ph_p=current_ph_p;
106 current_ph_p=sm_ph_p;
108 reg=fn(par, fp, tab);
110 current_ph_p=old_ph_p;
112 if(reg!=NULL){
113 if(!OBJ_IS(reg, WClientWin)){
114 if(extl_table_gets_s(tab, "name", &name)){
115 region_set_name(reg, name);
116 free(name);
121 return reg;
125 /*}}}*/
128 /*{{{ Save support functions */
131 bool region_supports_save(WRegion *reg)
133 return HAS_DYN(reg, region_get_configuration);
137 ExtlTab region_get_base_configuration(WRegion *reg)
139 const char *name;
140 ExtlTab tab;
142 tab=extl_create_table();
144 extl_table_sets_s(tab, "type", OBJ_TYPESTR(reg));
146 name=region_name(reg);
148 if(name!=NULL && !OBJ_IS(reg, WClientWin))
149 extl_table_sets_s(tab, "name", name);
151 return tab;
155 static bool get_config_clientwins=TRUE;
158 ExtlTab region_get_configuration(WRegion *reg)
160 ExtlTab tab=extl_table_none();
161 if(get_config_clientwins || !OBJ_IS(reg, WClientWin)){
162 CALL_DYN_RET(tab, ExtlTab, region_get_configuration, reg, (reg));
164 return tab;
168 /*EXTL_DOC
169 * Get configuration tree. If \var{clientwins} is unset, client windows
170 * are filtered out.
172 EXTL_EXPORT_AS(WRegion, get_configuration)
173 ExtlTab region_get_configuration_extl(WRegion *reg, bool clientwins)
175 ExtlTab tab;
177 get_config_clientwins=clientwins;
179 tab=region_get_configuration(reg);
181 get_config_clientwins=TRUE;
183 return tab;
187 /*}}}*/
190 /*{{{ save_workspaces, load_workspaces */
193 static const char backup_msg[]=DUMMY_TR(
194 "There were errors loading layout. Backing up current layout savefile as\n"
195 "%s.\n"
196 "If you are _not_ running under a session manager and wish to restore your\n"
197 "old layout, copy this backup file over the layout savefile found in the\n"
198 "same directory while Ion is not running and after having fixed your other\n"
199 "configuration files that are causing this problem. (Maybe a missing\n"
200 "module?)");
203 bool ioncore_init_layout()
205 ExtlTab tab;
206 WScreen *scr;
207 bool ok;
208 int n=0;
210 ok=extl_read_savefile("saved_layout", &tab);
212 loading_layout=TRUE;
213 layout_load_error=FALSE;
215 FOR_ALL_SCREENS(scr){
216 ExtlTab scrtab=extl_table_none();
217 bool scrok=FALSE;
219 /* Potential Xinerama or such support should set the screen ID
220 * of the root window to less than zero, and number its own
221 * fake screens up from 0.
223 if(screen_id(scr)<0)
224 continue;
226 if(ok)
227 scrok=extl_table_geti_t(tab, screen_id(scr), &scrtab);
229 n+=(TRUE==screen_init_layout(scr, scrtab));
231 if(scrok)
232 extl_unref_table(scrtab);
235 loading_layout=FALSE;
237 if(layout_load_error){
238 time_t t=time(NULL);
239 char tm[]="saved_layout.backup-YYYYMMDDHHMMSS\0\0\0\0";
240 char *backup;
242 strftime(tm+20, 15, "%Y%m%d%H%M%S", localtime(&t));
243 backup=extl_get_savefile(tm);
244 if(backup==NULL){
245 warn(TR("Unable to get file for layout backup."));
246 return FALSE;
248 if(access(backup, F_OK)==0){
249 warn(TR("Backup file %s already exists."), backup);
250 free(backup);
251 return FALSE;
253 warn(TR(backup_msg), backup);
254 if(!extl_serialise(backup, tab))
255 warn(TR("Failed backup."));
256 free(backup);
259 if(n==0){
260 warn(TR("Unable to initialise layout on any screen."));
261 return FALSE;
262 }else{
263 return TRUE;
268 bool ioncore_save_layout()
270 WScreen *scr=NULL;
271 ExtlTab tab=extl_create_table();
272 bool ret;
274 if(tab==extl_table_none())
275 return FALSE;
277 FOR_ALL_SCREENS(scr){
278 ExtlTab scrtab;
280 /* See note above */
281 if(screen_id(scr)<0)
282 continue;
284 scrtab=region_get_configuration((WRegion*)scr);
286 if(scrtab==extl_table_none()){
287 warn(TR("Unable to get configuration for screen %d."),
288 screen_id(scr));
289 }else{
290 extl_table_seti_t(tab, screen_id(scr), scrtab);
291 extl_unref_table(scrtab);
295 ret=extl_write_savefile("saved_layout", tab);
297 extl_unref_table(tab);
299 if(!ret)
300 warn(TR("Unable to save layout."));
302 return ret;
306 /*}}}*/