4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
14 #include <libmainloop/select.h>
15 #include <libmainloop/exec.h>
28 void ioncore_setup_display(int xscr
)
35 display
=XDisplayName(ioncore_g
.display
);
37 /* %ui, UINT_MAX is used to ensure there is enough space for the screen
40 libtu_asprintf(&tmp
, "DISPLAY=%s.0123456789a", display
);
53 snprintf(tmp
+strlen(tmp
), 11, ".%u", (unsigned)xscr
);
57 /* No need to free it, we'll execve soon */
64 void ioncore_setup_environ(const WExecP
*p
)
68 ioncore_setup_display(p
->target
!=NULL
69 ? region_rootwin_of(p
->target
)->xscr
72 /* Set up working directory */
81 WHook
*ioncore_exec_environ_hook
=NULL
;
84 static void setup_exec(void *execp
)
86 hook_call_p(ioncore_exec_environ_hook
, execp
, NULL
);
97 int ioncore_do_exec_on(WRegion
*reg
, const char *cmd
, const char *wd
,
106 return mainloop_popen_bgread(cmd
, setup_exec
, (void*)&p
,
107 extl_fn_none(), errh
);
112 * Run \var{cmd} with the environment variable DISPLAY set to point to the
113 * X display the WM is running on. No specific screen is set unlike with
114 * \fnref{WRootWin.exec_on}. The PID of the (shell executing the) new
115 * process is returned.
119 int ioncore_exec(const char *cmd
)
121 return ioncore_do_exec_on(NULL
, cmd
, NULL
, extl_fn_none());
126 * Run \var{cmd} in directory \var{wd} with a read pipe connected to its
128 * When data is received through one of these pipes, \var{h} or \var{errh}
129 * is called with that data. When the pipe is closed, the handler is called
130 * with \code{nil} argument. The PID of the new process is returned, or
135 int ioncore_popen_bgread(const char *cmd
, ExtlFn h
, ExtlFn errh
,
144 return mainloop_popen_bgread(cmd
, setup_exec
, (void*)&p
, h
, errh
);
152 /*{{{ Exit, restart, snapshot */
155 static void (*smhook
)(int what
);
157 bool ioncore_set_smhook(void (*fn
)(int what
))
164 void ioncore_do_exit()
171 bool ioncore_do_snapshot(bool save_layout
)
173 if(save_layout
&& !ioncore_save_layout())
177 hook_call_v(ioncore_snapshot_hook
);
178 extl_unprotect(NULL
);
184 void ioncore_emergency_snapshot()
187 warn(TR("Not saving state: running under session manager."));
189 ioncore_do_snapshot(TRUE
);
194 static char *other
=NULL
;
196 static void set_other(const char *s
)
200 other
=(s
==NULL
? NULL
: scopy(s
));
204 void ioncore_do_restart()
208 if(ioncore_g
.display
!=NULL
)
209 ioncore_setup_display(-1);
210 mainloop_do_exec(other
);
213 execvp(ioncore_g
.argv
[0], ioncore_g
.argv
);
214 die_err_obj(ioncore_g
.argv
[0]);
219 * Causes the window manager to simply exit without saving
223 void ioncore_resign()
226 smhook(IONCORE_SM_RESIGN
);
234 * End session saving it first.
237 void ioncore_shutdown()
240 smhook(IONCORE_SM_SHUTDOWN
);
242 ioncore_do_snapshot(ioncore_g
.autosave_layout
);
249 * Restart, saving session first.
252 void ioncore_restart()
257 smhook(IONCORE_SM_RESTART
);
259 ioncore_do_snapshot(ioncore_g
.autosave_layout
);
260 ioncore_do_restart();
266 * Attempt to restart another window manager \var{cmd}.
269 void ioncore_restart_other(const char *cmd
)
274 smhook(IONCORE_SM_RESTART_OTHER
);
276 ioncore_do_snapshot(ioncore_g
.autosave_layout
);
277 ioncore_do_restart();
286 void ioncore_snapshot()
289 smhook(IONCORE_SM_SNAPSHOT
);
291 ioncore_do_snapshot(TRUE
);