[WM_ROT] Fixed floating mode window rotation bug that window doesn't send ROTATION_DO...
[platform/core/uifw/e17.git] / src / bin / e_sys.c
1 #include "e.h"
2
3 /* local subsystem functions */
4 static Eina_Bool _e_sys_cb_timer(void *data);
5 static Eina_Bool _e_sys_cb_exit(void *data, int type, void *event);
6 static void      _e_sys_cb_logout_logout(void *data, E_Dialog *dia);
7 static void      _e_sys_cb_logout_wait(void *data, E_Dialog *dia);
8 static void      _e_sys_cb_logout_abort(void *data, E_Dialog *dia);
9 static Eina_Bool _e_sys_cb_logout_timer(void *data);
10 static void      _e_sys_logout_after(void);
11 static void      _e_sys_logout_begin(E_Sys_Action a_after, Eina_Bool raw);
12 static void      _e_sys_current_action(void);
13 static void      _e_sys_action_failed(void);
14 static int       _e_sys_action_do(E_Sys_Action a, char *param, Eina_Bool raw);
15 static void      _e_sys_dialog_cb_delete(E_Obj_Dialog *od);
16
17 static Ecore_Event_Handler *_e_sys_exe_exit_handler = NULL;
18 static Ecore_Exe *_e_sys_halt_check_exe = NULL;
19 static Ecore_Exe *_e_sys_reboot_check_exe = NULL;
20 static Ecore_Exe *_e_sys_suspend_check_exe = NULL;
21 static Ecore_Exe *_e_sys_hibernate_check_exe = NULL;
22 static int _e_sys_can_halt = 0;
23 static int _e_sys_can_reboot = 0;
24 static int _e_sys_can_suspend = 0;
25 static int _e_sys_can_hibernate = 0;
26
27 static E_Sys_Action _e_sys_action_current = E_SYS_NONE;
28 static E_Sys_Action _e_sys_action_after = E_SYS_NONE;
29 static Eina_Bool _e_sys_action_after_raw = EINA_FALSE;
30 static Ecore_Exe *_e_sys_exe = NULL;
31 static double _e_sys_begin_time = 0.0;
32 static double _e_sys_logout_begin_time = 0.0;
33 static Ecore_Timer *_e_sys_logout_timer = NULL;
34 static E_Obj_Dialog *_e_sys_dialog = NULL;
35 static E_Dialog *_e_sys_logout_confirm_dialog = NULL;
36 static Ecore_Timer *_e_sys_susp_hib_check_timer = NULL;
37 static double _e_sys_susp_hib_check_last_tick = 0.0;
38 static void (*_e_sys_suspend_func) (void) = NULL;
39 static void (*_e_sys_hibernate_func) (void) = NULL;
40 static void (*_e_sys_reboot_func) (void) = NULL;
41 static void (*_e_sys_shutdown_func) (void) = NULL;
42 static void (*_e_sys_logout_func) (void) = NULL;
43 static void (*_e_sys_resume_func) (void) = NULL;
44
45 static const int E_LOGOUT_AUTO_TIME = 60;
46 static const int E_LOGOUT_WAIT_TIME = 15;
47
48 /* externally accessible functions */
49 EINTERN int
50 e_sys_init(void)
51 {
52    /* this is not optimal - but it does work cleanly */
53    _e_sys_exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
54                                                      _e_sys_cb_exit, NULL);
55    /* delay this for 1.0 seconds while the rest of e starts up */
56    ecore_timer_add(1.0, _e_sys_cb_timer, NULL);
57    return 1;
58 }
59
60 EINTERN int
61 e_sys_shutdown(void)
62 {
63    if (_e_sys_exe_exit_handler)
64      ecore_event_handler_del(_e_sys_exe_exit_handler);
65    _e_sys_exe_exit_handler = NULL;
66    _e_sys_halt_check_exe = NULL;
67    _e_sys_reboot_check_exe = NULL;
68    _e_sys_suspend_check_exe = NULL;
69    _e_sys_hibernate_check_exe = NULL;
70    return 1;
71 }
72
73 EAPI int
74 e_sys_action_possible_get(E_Sys_Action a)
75 {
76    switch (a)
77      {
78       case E_SYS_EXIT:
79       case E_SYS_RESTART:
80       case E_SYS_EXIT_NOW:
81         return 1;
82
83       case E_SYS_LOGOUT:
84         return 1;
85
86       case E_SYS_HALT:
87       case E_SYS_HALT_NOW:
88         return _e_sys_can_halt;
89
90       case E_SYS_REBOOT:
91         return _e_sys_can_reboot;
92
93       case E_SYS_SUSPEND:
94         return _e_sys_can_suspend;
95
96       case E_SYS_HIBERNATE:
97         return _e_sys_can_hibernate;
98
99       default:
100         return 0;
101      }
102    return 0;
103 }
104
105 EAPI int
106 e_sys_action_do(E_Sys_Action a, char *param)
107 {
108    int ret = 0;
109
110    if (_e_sys_action_current != E_SYS_NONE)
111      {
112         _e_sys_current_action();
113         return 0;
114      }
115    switch (a)
116      {
117       case E_SYS_EXIT:
118       case E_SYS_RESTART:
119       case E_SYS_EXIT_NOW:
120       case E_SYS_LOGOUT:
121       case E_SYS_SUSPEND:
122       case E_SYS_HIBERNATE:
123       case E_SYS_HALT_NOW:
124         ret = _e_sys_action_do(a, param, EINA_FALSE);
125         break;
126
127       case E_SYS_HALT:
128         if (!e_util_immortal_check())
129           {
130              if (_e_sys_shutdown_func) _e_sys_shutdown_func();
131              else _e_sys_logout_begin(a, EINA_FALSE);
132           }
133         return 1;
134         break;
135       case E_SYS_REBOOT:
136         if (!e_util_immortal_check())
137           {
138              if (_e_sys_reboot_func) _e_sys_reboot_func();
139              else _e_sys_logout_begin(a, EINA_FALSE);
140           }
141         return 1;
142         break;
143
144       default:
145         break;
146      }
147
148    if (ret) _e_sys_action_current = a;
149    else _e_sys_action_current = E_SYS_NONE;
150
151    return ret;
152 }
153
154 EAPI int
155 e_sys_action_raw_do(E_Sys_Action a, char *param)
156 {
157    int ret = 0;
158
159    if (_e_sys_action_current != E_SYS_NONE)
160      {
161         _e_sys_current_action();
162         return 0;
163      }
164    switch (a)
165      {
166       case E_SYS_EXIT:
167       case E_SYS_RESTART:
168       case E_SYS_EXIT_NOW:
169       case E_SYS_LOGOUT:
170       case E_SYS_SUSPEND:
171       case E_SYS_HIBERNATE:
172       case E_SYS_HALT_NOW:
173         ret = _e_sys_action_do(a, param, EINA_TRUE);
174         break;
175
176       case E_SYS_HALT:
177       case E_SYS_REBOOT:
178         if (!e_util_immortal_check()) _e_sys_logout_begin(a, EINA_TRUE);
179         return 1;
180         break;
181
182       default:
183         break;
184      }
185
186    if (ret) _e_sys_action_current = a;
187    else _e_sys_action_current = E_SYS_NONE;
188
189    return ret;
190 }
191
192 static Eina_List *extra_actions = NULL;
193
194 EAPI E_Sys_Con_Action *
195 e_sys_con_extra_action_register(const char *label,
196                                 const char *icon_group,
197                                 const char *button_name,
198                                 void (*func)(void *data),
199                                 const void *data)
200 {
201    E_Sys_Con_Action *sca;
202
203    sca = E_NEW(E_Sys_Con_Action, 1);
204    if (label)
205      sca->label = eina_stringshare_add(label);
206    if (icon_group)
207      sca->icon_group = eina_stringshare_add(icon_group);
208    if (button_name)
209      sca->button_name = eina_stringshare_add(button_name);
210    sca->func = func;
211    sca->data = data;
212    extra_actions = eina_list_append(extra_actions, sca);
213    return sca;
214 }
215
216 EAPI void
217 e_sys_con_extra_action_unregister(E_Sys_Con_Action *sca)
218 {
219    extra_actions = eina_list_remove(extra_actions, sca);
220    if (sca->label) eina_stringshare_del(sca->label);
221    if (sca->icon_group) eina_stringshare_del(sca->icon_group);
222    if (sca->button_name) eina_stringshare_del(sca->button_name);
223    free(sca);
224 }
225
226 EAPI const Eina_List *
227 e_sys_con_extra_action_list_get(void)
228 {
229    return extra_actions;
230 }
231
232 EAPI void
233 e_sys_handlers_set(void (*suspend_func) (void),
234                    void (*hibernate_func) (void),
235                    void (*reboot_func) (void),
236                    void (*shutdown_func) (void),
237                    void (*logout_func) (void),
238                    void (*resume_func) (void))
239 {
240    _e_sys_suspend_func = suspend_func;
241    _e_sys_hibernate_func = hibernate_func;
242    _e_sys_reboot_func = reboot_func;
243    _e_sys_shutdown_func = shutdown_func;
244    _e_sys_logout_func = logout_func;
245    _e_sys_resume_func = resume_func;
246 }
247
248 static Eina_Bool
249 _e_sys_susp_hib_check_timer_cb(void *data __UNUSED__)
250 {
251    double t = ecore_time_unix_get();
252
253    if ((t - _e_sys_susp_hib_check_last_tick) > 0.2)
254      {
255         _e_sys_susp_hib_check_timer = NULL;
256         if (_e_sys_dialog)
257           {
258              e_object_del(E_OBJECT(_e_sys_dialog));
259              _e_sys_dialog = NULL;
260           }
261         if (_e_sys_resume_func) _e_sys_resume_func();
262         return EINA_FALSE;
263      }
264    _e_sys_susp_hib_check_last_tick = t;
265    return EINA_TRUE;
266 }
267
268 static void
269 _e_sys_susp_hib_check(void)
270 {
271    if (_e_sys_susp_hib_check_timer)
272      ecore_timer_del(_e_sys_susp_hib_check_timer);
273    _e_sys_susp_hib_check_last_tick = ecore_time_unix_get();
274    _e_sys_susp_hib_check_timer = 
275      ecore_timer_add(0.1, _e_sys_susp_hib_check_timer_cb, NULL);
276 }
277
278 /* local subsystem functions */
279 static Eina_Bool
280 _e_sys_cb_timer(void *data __UNUSED__)
281 {
282    /* exec out sys helper and ask it to test if we are allowed to do these
283     * things
284     */
285    char buf[4096];
286
287    e_init_status_set(_("Checking System Permissions"));
288    snprintf(buf, sizeof(buf),
289             "%s/enlightenment/utils/enlightenment_sys -t halt",
290             e_prefix_lib_get());
291    _e_sys_halt_check_exe = ecore_exe_run(buf, NULL);
292    snprintf(buf, sizeof(buf),
293             "%s/enlightenment/utils/enlightenment_sys -t reboot",
294             e_prefix_lib_get());
295    _e_sys_reboot_check_exe = ecore_exe_run(buf, NULL);
296    snprintf(buf, sizeof(buf),
297             "%s/enlightenment/utils/enlightenment_sys -t suspend",
298             e_prefix_lib_get());
299    _e_sys_suspend_check_exe = ecore_exe_run(buf, NULL);
300    snprintf(buf, sizeof(buf),
301             "%s/enlightenment/utils/enlightenment_sys -t hibernate",
302             e_prefix_lib_get());
303    _e_sys_hibernate_check_exe = ecore_exe_run(buf, NULL);
304    return ECORE_CALLBACK_CANCEL;
305 }
306
307 static Eina_Bool
308 _e_sys_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
309 {
310    Ecore_Exe_Event_Del *ev;
311
312    ev = event;
313    if ((_e_sys_exe) && (ev->exe == _e_sys_exe))
314      {
315         if (ev->exit_code != 0) _e_sys_action_failed();
316         if (((_e_sys_action_current != E_SYS_HALT) &&
317              (_e_sys_action_current != E_SYS_HALT_NOW) &&
318              (_e_sys_action_current != E_SYS_REBOOT)) ||
319             (ev->exit_code != 0))
320           {
321              if (_e_sys_dialog)
322                {
323                   e_object_del(E_OBJECT(_e_sys_dialog));
324                   _e_sys_dialog = NULL;
325                }
326           }
327         _e_sys_action_current = E_SYS_NONE;
328         _e_sys_exe = NULL;
329         return ECORE_CALLBACK_RENEW;
330      }
331    if ((_e_sys_halt_check_exe) && (ev->exe == _e_sys_halt_check_exe))
332      {
333         e_init_status_set(_("System Check Done"));
334         /* exit_code: 0 == OK, 5 == suid root removed, 7 == group id error
335          * 10 == permission denied, 20 == action undefined */
336         if (ev->exit_code == 0)
337           {
338              _e_sys_can_halt = 1;
339              _e_sys_halt_check_exe = NULL;
340           }
341      }
342    else if ((_e_sys_reboot_check_exe) && (ev->exe == _e_sys_reboot_check_exe))
343      {
344         e_init_status_set(_("System Check Done"));
345         if (ev->exit_code == 0)
346           {
347              _e_sys_can_reboot = 1;
348              _e_sys_reboot_check_exe = NULL;
349           }
350      }
351    else if ((_e_sys_suspend_check_exe) && (ev->exe == _e_sys_suspend_check_exe))
352      {
353         e_init_status_set(_("System Check Done"));
354         if (ev->exit_code == 0)
355           {
356              _e_sys_can_suspend = 1;
357              _e_sys_suspend_check_exe = NULL;
358           }
359      }
360    else if ((_e_sys_hibernate_check_exe) && (ev->exe == _e_sys_hibernate_check_exe))
361      {
362         e_init_status_set(_("System Check Done"));
363         if (ev->exit_code == 0)
364           {
365              _e_sys_can_hibernate = 1;
366              _e_sys_hibernate_check_exe = NULL;
367           }
368      }
369    return ECORE_CALLBACK_RENEW;
370 }
371
372 static void
373 _e_sys_cb_logout_logout(void *data __UNUSED__, E_Dialog *dia)
374 {
375    if (_e_sys_logout_timer)
376      {
377         ecore_timer_del(_e_sys_logout_timer);
378         _e_sys_logout_timer = NULL;
379      }
380    _e_sys_logout_begin_time = 0.0;
381    _e_sys_logout_after();
382    e_object_del(E_OBJECT(dia));
383    _e_sys_logout_confirm_dialog = NULL;
384 }
385
386 static void
387 _e_sys_cb_logout_wait(void *data __UNUSED__, E_Dialog *dia)
388 {
389    if (_e_sys_logout_timer) ecore_timer_del(_e_sys_logout_timer);
390    _e_sys_logout_timer = ecore_timer_add(0.5, _e_sys_cb_logout_timer, NULL);
391    _e_sys_logout_begin_time = ecore_time_get();
392    e_object_del(E_OBJECT(dia));
393    _e_sys_logout_confirm_dialog = NULL;
394 }
395
396 static void
397 _e_sys_cb_logout_abort(void *data __UNUSED__, E_Dialog *dia)
398 {
399    if (_e_sys_logout_timer)
400      {
401         ecore_timer_del(_e_sys_logout_timer);
402         _e_sys_logout_timer = NULL;
403      }
404    _e_sys_logout_begin_time = 0.0;
405    e_object_del(E_OBJECT(dia));
406    _e_sys_logout_confirm_dialog = NULL;
407    _e_sys_action_current = E_SYS_NONE;
408    _e_sys_action_after = E_SYS_NONE;
409    _e_sys_action_after_raw = EINA_FALSE;
410    if (_e_sys_dialog)
411      {
412         e_object_del(E_OBJECT(_e_sys_dialog));
413         _e_sys_dialog = NULL;
414      }
415 }
416
417 static void
418 _e_sys_logout_confirm_dialog_update(int remaining)
419 {
420    char txt[4096];
421
422    if (!_e_sys_logout_confirm_dialog)
423      {
424         fputs("ERROR: updating logout confirm dialog, but none exists!\n",
425               stderr);
426         return;
427      }
428
429    snprintf(txt, sizeof(txt),
430             _("Logout is taking too long.<br>"
431               "Some applications refuse to close.<br>"
432               "Do you want to finish the logout<br>"
433               "anyway without closing these<br>"
434               "applications first?<br><br>"
435               "Auto logout in %d seconds."), remaining);
436
437    e_dialog_text_set(_e_sys_logout_confirm_dialog, txt);
438 }
439
440 static Eina_Bool
441 _e_sys_cb_logout_timer(void *data __UNUSED__)
442 {
443    Eina_List *l;
444    E_Border *bd;
445    int pending = 0;
446
447    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
448      {
449         if (!bd->internal) pending++;
450      }
451    if (pending == 0) goto after;
452    else if (_e_sys_logout_confirm_dialog)
453      {
454         int remaining = E_LOGOUT_AUTO_TIME -
455           round(ecore_loop_time_get() - _e_sys_logout_begin_time);
456         /* it has taken 60 (E_LOGOUT_AUTO_TIME) seconds of waiting the
457          * confirm dialog and we still have apps that will not go
458          * away. Do the action as user may be far away or forgot it.
459          *
460          * NOTE: this is the behavior for many operating systems and I
461          *       guess the reason is people that hit "shutdown" and
462          *       put their laptops in their backpacks in the hope
463          *       everything will be turned off properly.
464          */
465         if (remaining > 0)
466           {
467              _e_sys_logout_confirm_dialog_update(remaining);
468              return ECORE_CALLBACK_RENEW;
469           }
470         else
471           {
472              _e_sys_cb_logout_logout(NULL, _e_sys_logout_confirm_dialog);
473              return ECORE_CALLBACK_CANCEL;
474           }
475      }
476    else
477      {
478         /* it has taken 15 seconds of waiting and we still have apps that
479          * will not go away
480          */
481         double now = ecore_loop_time_get();
482         if ((now - _e_sys_logout_begin_time) > E_LOGOUT_WAIT_TIME)
483           {
484              E_Dialog *dia;
485
486              dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_sys_error_logout_slow");
487              if (dia)
488                {
489                   _e_sys_logout_confirm_dialog = dia;
490                   e_dialog_title_set(dia, _("Logout problems"));
491                   e_dialog_icon_set(dia, "system-log-out", 64);
492                   e_dialog_button_add(dia, _("Logout now"), NULL,
493                                       _e_sys_cb_logout_logout, NULL);
494                   e_dialog_button_add(dia, _("Wait longer"), NULL,
495                                       _e_sys_cb_logout_wait, NULL);
496                   e_dialog_button_add(dia, _("Cancel Logout"), NULL,
497                                       _e_sys_cb_logout_abort, NULL);
498                   e_dialog_button_focus_num(dia, 1);
499                   _e_sys_logout_confirm_dialog_update(E_LOGOUT_AUTO_TIME);
500                   e_win_centered_set(dia->win, 1);
501                   e_dialog_show(dia);
502                   _e_sys_logout_begin_time = now;
503                }
504              return ECORE_CALLBACK_RENEW;
505           }
506      }
507    return ECORE_CALLBACK_RENEW;
508 after:
509    _e_sys_logout_after();
510    _e_sys_logout_timer = NULL;
511    return ECORE_CALLBACK_CANCEL;
512 }
513
514 static void
515 _e_sys_logout_after(void)
516 {
517    if (_e_sys_dialog)
518      {
519         e_object_del(E_OBJECT(_e_sys_dialog));
520         _e_sys_dialog = NULL;
521      }
522    _e_sys_action_current = _e_sys_action_after;
523    _e_sys_action_do(_e_sys_action_after, NULL, _e_sys_action_after_raw);
524    _e_sys_action_after = E_SYS_NONE;
525    _e_sys_action_after_raw = EINA_FALSE;
526 }
527
528 static void
529 _e_sys_logout_begin(E_Sys_Action a_after, Eina_Bool raw)
530 {
531    Eina_List *l;
532    E_Border *bd;
533    E_Obj_Dialog *od;
534
535    /* start logout - at end do the a_after action */
536    if (!raw)
537      {
538         od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
539                               _("Logout in progress"), "E", "_sys_logout");
540         e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/logout");
541         e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
542                                        _("Logout in progress.<br>"
543                                          "<hilight>Please wait.</hilight>"));
544         e_obj_dialog_show(od);
545         e_obj_dialog_icon_set(od, "system-log-out");
546         if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
547         _e_sys_dialog = od;
548      }
549    _e_sys_action_after = a_after;
550    _e_sys_action_after_raw = raw;
551    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
552      {
553         e_border_act_close_begin(bd);
554      }
555    /* and poll to see if all pending windows are gone yet every 0.5 sec */
556    _e_sys_logout_begin_time = ecore_time_get();
557    if (_e_sys_logout_timer) ecore_timer_del(_e_sys_logout_timer);
558    _e_sys_logout_timer = ecore_timer_add(0.5, _e_sys_cb_logout_timer, NULL);
559 }
560
561 static void
562 _e_sys_current_action(void)
563 {
564    /* display dialog that currently an action is in progress */
565    E_Dialog *dia;
566
567    dia = e_dialog_new(e_container_current_get(e_manager_current_get()),
568                       "E", "_sys_error_action_busy");
569    if (!dia) return;
570
571    e_dialog_title_set(dia, _("Enlightenment is busy with another request"));
572    e_dialog_icon_set(dia, "enlightenment/sys", 64);
573    switch (_e_sys_action_current)
574      {
575       case E_SYS_LOGOUT:
576         e_dialog_text_set(dia, _("Logging out.<br>"
577                                  "You cannot perform other system actions<br>"
578                                  "once a logout has begun."));
579         break;
580
581       case E_SYS_HALT:
582       case E_SYS_HALT_NOW:
583         e_dialog_text_set(dia, _("Powering off.<br>"
584                                  "You cannot do any other system actions<br>"
585                                  "once a shutdown has been started."));
586         break;
587
588       case E_SYS_REBOOT:
589         e_dialog_text_set(dia, _("Resetting.<br>"
590                                  "You cannot do any other system actions<br>"
591                                  "once a reboot has begun."));
592         break;
593
594       case E_SYS_SUSPEND:
595         e_dialog_text_set(dia, _("Suspending.<br>"
596                                  "Until suspend is complete you cannot perform<br>"
597                                  "any other system actions."));
598         break;
599
600       case E_SYS_HIBERNATE:
601         e_dialog_text_set(dia, _("Hibernating.<br>"
602                                  "You cannot perform any other system actions<br>"
603                                  "until this is complete."));
604         break;
605
606       default:
607         e_dialog_text_set(dia, _("EEK! This should not happen"));
608         break;
609      }
610    e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
611    e_dialog_button_focus_num(dia, 0);
612    e_win_centered_set(dia->win, 1);
613    e_dialog_show(dia);
614 }
615
616 static void
617 _e_sys_action_failed(void)
618 {
619    /* display dialog that the current action failed */
620    E_Dialog *dia;
621
622    dia = e_dialog_new(e_container_current_get(e_manager_current_get()),
623                       "E", "_sys_error_action_failed");
624    if (!dia) return;
625
626    e_dialog_title_set(dia, _("Enlightenment is busy with another request"));
627    e_dialog_icon_set(dia, "enlightenment/sys", 64);
628    switch (_e_sys_action_current)
629      {
630       case E_SYS_HALT:
631       case E_SYS_HALT_NOW:
632         e_dialog_text_set(dia, _("Power off failed."));
633         break;
634
635       case E_SYS_REBOOT:
636         e_dialog_text_set(dia, _("Reset failed."));
637         break;
638
639       case E_SYS_SUSPEND:
640         e_dialog_text_set(dia, _("Suspend failed."));
641         break;
642
643       case E_SYS_HIBERNATE:
644         e_dialog_text_set(dia, _("Hibernate failed."));
645         break;
646
647       default:
648         e_dialog_text_set(dia, _("EEK! This should not happen"));
649         break;
650      }
651    e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
652    e_dialog_button_focus_num(dia, 0);
653    e_win_centered_set(dia->win, 1);
654    e_dialog_show(dia);
655 }
656
657 static int
658 _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, Eina_Bool raw)
659 {
660    char buf[PATH_MAX];
661    E_Obj_Dialog *od;
662
663    switch (a)
664      {
665       case E_SYS_EXIT:
666         // XXX TODO: check for e_fm_op_registry entries and confirm
667         if (!e_util_immortal_check())
668           ecore_main_loop_quit();
669         else
670           return 0;
671         break;
672
673       case E_SYS_RESTART:
674         // XXX TODO: check for e_fm_op_registry entries and confirm
675         // FIXME: we dont   share out immortal info to restarted e. :(
676 //      if (!e_util_immortal_check())
677       {
678          restart = 1;
679          ecore_main_loop_quit();
680       }
681 //        else
682 //          return 0;
683       break;
684
685       case E_SYS_EXIT_NOW:
686         exit(0);
687         break;
688
689       case E_SYS_LOGOUT:
690         // XXX TODO: check for e_fm_op_registry entries and confirm
691         if (raw)
692           {
693              _e_sys_logout_begin(E_SYS_EXIT, raw);
694           }
695         else
696           {
697              if (_e_sys_logout_func)
698                {
699                   _e_sys_logout_func();
700                   return 0;
701                }
702              else
703                {
704                   _e_sys_logout_begin(E_SYS_EXIT, raw);
705                }
706           }
707         break;
708
709       case E_SYS_HALT:
710       case E_SYS_HALT_NOW:
711         /* shutdown -h now */
712         if (e_util_immortal_check()) return 0;
713         snprintf(buf, sizeof(buf),
714                  "%s/enlightenment/utils/enlightenment_sys halt",
715                  e_prefix_lib_get());
716         if (_e_sys_exe)
717           {
718              if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
719                _e_sys_current_action();
720              return 0;
721           }
722         else
723           {
724              if (raw)
725                {
726                   _e_sys_begin_time = ecore_time_get();
727                   _e_sys_exe = ecore_exe_run(buf, NULL);
728                }
729              else
730                {
731                   if (_e_sys_shutdown_func)
732                     {
733                        _e_sys_shutdown_func();
734                        return 0;
735                     }
736                   else
737                     {
738                        _e_sys_begin_time = ecore_time_get();
739                        _e_sys_exe = ecore_exe_run(buf, NULL);
740                        od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
741                                              _("Power off"), "E", "_sys_halt");
742                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/halt");
743                        e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
744                                                       _("Power off.<br>"
745                                                         "<hilight>Please wait.</hilight>"));
746                        e_obj_dialog_show(od);
747                        e_obj_dialog_icon_set(od, "system-shutdown");
748                        if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
749                        e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
750                        _e_sys_dialog = od;
751                     }
752                }
753              /* FIXME: display halt status */
754           }
755         break;
756
757       case E_SYS_REBOOT:
758         /* shutdown -r now */
759         if (e_util_immortal_check()) return 0;
760         snprintf(buf, sizeof(buf),
761                  "%s/enlightenment/utils/enlightenment_sys reboot",
762                  e_prefix_lib_get());
763         if (_e_sys_exe)
764           {
765              if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
766                _e_sys_current_action();
767              return 0;
768           }
769         else
770           {
771              if (raw)
772                {
773                   _e_sys_begin_time = ecore_time_get();
774                   _e_sys_exe = ecore_exe_run(buf, NULL);
775                }
776              else
777                {
778                   if (_e_sys_reboot_func)
779                     {
780                        _e_sys_reboot_func();
781                        return 0;
782                     }
783                   else
784                     {
785                        _e_sys_begin_time = ecore_time_get();
786                        _e_sys_exe = ecore_exe_run(buf, NULL);
787                        od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
788                                              _("Resetting"), "E", "_sys_reboot");
789                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/reboot");
790                        e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
791                                                       _("Resetting.<br>"
792                                                         "<hilight>Please wait.</hilight>"));
793                        e_obj_dialog_show(od);
794                        e_obj_dialog_icon_set(od, "system-restart");
795                        if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
796                        e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
797                        _e_sys_dialog = od;
798                     }
799                }
800              /* FIXME: display reboot status */
801           }
802         break;
803
804       case E_SYS_SUSPEND:
805         /* /etc/acpi/sleep.sh force */
806         snprintf(buf, sizeof(buf),
807                  "%s/enlightenment/utils/enlightenment_sys suspend",
808                  e_prefix_lib_get());
809         if (_e_sys_exe)
810           {
811              if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
812                _e_sys_current_action();
813              return 0;
814           }
815         else
816           {
817              if (raw)
818                {
819                   _e_sys_susp_hib_check();
820                   if (e_config->desklock_on_suspend)
821                     e_desklock_show(EINA_TRUE);
822                   _e_sys_begin_time = ecore_time_get();
823                   _e_sys_exe = ecore_exe_run(buf, NULL);
824                }
825              else
826                {
827                   if (_e_sys_suspend_func)
828                     {
829                        _e_sys_suspend_func();
830                        return 0;
831                     }
832                   else
833                     {
834                        if (e_config->desklock_on_suspend)
835                          e_desklock_show(EINA_TRUE);
836                        
837                        _e_sys_susp_hib_check();
838                        
839                        _e_sys_begin_time = ecore_time_get();
840                        _e_sys_exe = ecore_exe_run(buf, NULL);
841                        od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
842                                              _("Suspending"), "E", "_sys_suspend");
843                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/suspend");
844                        e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
845                                                       _("Suspending.<br>"
846                                                         "<hilight>Please wait.</hilight>"));
847                        e_obj_dialog_show(od);
848                        e_obj_dialog_icon_set(od, "system-suspend");
849                        if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
850                        e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
851                        _e_sys_dialog = od;
852                     }
853                }
854              /* FIXME: display suspend status */
855           }
856         break;
857
858       case E_SYS_HIBERNATE:
859         /* /etc/acpi/hibernate.sh force */
860         snprintf(buf, sizeof(buf),
861                  "%s/enlightenment/utils/enlightenment_sys hibernate",
862                  e_prefix_lib_get());
863         if (_e_sys_exe)
864           {
865              if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
866                _e_sys_current_action();
867              return 0;
868           }
869         else
870           {
871              if (_e_sys_hibernate_func)
872                {
873                   _e_sys_hibernate_func();
874                   return 0;
875                }
876              else
877                {
878                   if (raw)
879                     {
880                        if (e_config->desklock_on_suspend)
881                          e_desklock_show(EINA_TRUE);
882                        
883                        _e_sys_susp_hib_check();
884                        _e_sys_begin_time = ecore_time_get();
885                        _e_sys_exe = ecore_exe_run(buf, NULL);
886                     }
887                   else
888                     {
889                        if (e_config->desklock_on_suspend)
890                          e_desklock_show(EINA_TRUE);
891                        
892                        _e_sys_susp_hib_check();
893                        
894                        _e_sys_begin_time = ecore_time_get();
895                        _e_sys_exe = ecore_exe_run(buf, NULL);
896                        od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
897                                              _("Hibernating"), "E", "_sys_hibernate");
898                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/hibernate");
899                        e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
900                                                       _("Hibernating.<br>"
901                                                         "<hilight>Please wait.</hilight>"));
902                        e_obj_dialog_show(od);
903                        e_obj_dialog_icon_set(od, "system-suspend-hibernate");
904                        if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
905                        _e_sys_dialog = od;
906                        e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
907                     }
908                }
909              /* FIXME: display hibernate status */
910           }
911         break;
912
913       default:
914         return 0;
915      }
916    return 1;
917 }
918    
919 static void
920 _e_sys_dialog_cb_delete(E_Obj_Dialog *od __UNUSED__)
921 {
922    /* If we don't NULL out the _e_sys_dialog, then the
923     * ECORE_EXE_EVENT_DEL callback will trigger and segv if the window
924     * is deleted in some other way. */
925    _e_sys_dialog = NULL;
926 }