add hooks to override the old sys popup boxy things so comp can do

something fancy on suspend, resume, hibernate, logout, reboot,
shutdown. much nicer now. much more polished.



SVN revision: 75929
devs/princeamd/enlightenment-0.17-elive
Carsten Haitzler 11 years ago
parent 3f3466c415
commit cb5e1e563b
  1. 74
      data/themes/default.edc
  2. 352
      src/bin/e_sys.c
  3. 7
      src/bin/e_sys.h
  4. 90
      src/modules/comp/e_mod_comp.c

@ -38383,6 +38383,18 @@ collections {
color: 0 0 0 255;
}
}
part { name: "suspender"; type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 0 0 0 255;
}
}
}
programs {
program { name: "save-on";
@ -38414,6 +38426,68 @@ collections {
transition: ACCELERATE 0.25 CURRENT;
target: "shadow";
}
program { name: "suspend";
signal: "e,state,sys,suspend";
source: "e";
action: STATE_SET "visible" 0.0;
transition: ACCELERATE 0.5 CURRENT;
target: "suspender";
after: "suspend_done";
}
program { name: "suspend_done";
action: SIGNAL_EMIT "e,state,sys,suspend,done" "e";
}
program { name: "hibernate";
signal: "e,state,sys,hibernate";
source: "e";
action: STATE_SET "visible" 0.0;
transition: ACCELERATE 0.5 CURRENT;
target: "suspender";
after: "hibernate_done";
}
program { name: "hibernate_done";
action: SIGNAL_EMIT "e,state,sys,hibernate,done" "e";
}
program { name: "resume";
signal: "e,state,sys,resume";
source: "e";
action: STATE_SET "default" 0.0;
transition: DECELERATE 1.0 CURRENT;
target: "suspender";
}
program { name: "reboot";
signal: "e,state,sys,reboot";
source: "e";
action: STATE_SET "visible" 0.0;
transition: ACCELERATE 0.5 CURRENT;
target: "suspender";
after: "reboot_done";
}
program { name: "reboot_done";
action: SIGNAL_EMIT "e,state,sys,reboot,done" "e";
}
program { name: "halt";
signal: "e,state,sys,halt";
source: "e";
action: STATE_SET "visible" 0.0;
transition: ACCELERATE 0.5 CURRENT;
target: "suspender";
after: "halt_done";
}
program { name: "halt_done";
action: SIGNAL_EMIT "e,state,sys,halt,done" "e";
}
program { name: "logout";
signal: "e,state,sys,logout";
source: "e";
action: STATE_SET "visible" 0.0;
transition: ACCELERATE 0.5 CURRENT;
target: "suspender";
after: "logout_done";
}
program { name: "logout_done";
action: SIGNAL_EMIT "e,state,sys,logout,done" "e";
}
}
}

@ -8,10 +8,10 @@ static void _e_sys_cb_logout_wait(void *data, E_Dialog *dia);
static void _e_sys_cb_logout_abort(void *data, E_Dialog *dia);
static Eina_Bool _e_sys_cb_logout_timer(void *data);
static void _e_sys_logout_after(void);
static void _e_sys_logout_begin(E_Sys_Action a_after);
static void _e_sys_logout_begin(E_Sys_Action a_after, Eina_Bool raw);
static void _e_sys_current_action(void);
static void _e_sys_action_failed(void);
static int _e_sys_action_do(E_Sys_Action a, char *param);
static int _e_sys_action_do(E_Sys_Action a, char *param, Eina_Bool raw);
static void _e_sys_dialog_cb_delete(E_Obj_Dialog *od);
static Ecore_Event_Handler *_e_sys_exe_exit_handler = NULL;
@ -26,12 +26,21 @@ static int _e_sys_can_hibernate = 0;
static E_Sys_Action _e_sys_action_current = E_SYS_NONE;
static E_Sys_Action _e_sys_action_after = E_SYS_NONE;
static Eina_Bool _e_sys_action_after_raw = EINA_FALSE;
static Ecore_Exe *_e_sys_exe = NULL;
static double _e_sys_begin_time = 0.0;
static double _e_sys_logout_begin_time = 0.0;
static Ecore_Timer *_e_sys_logout_timer = NULL;
static E_Obj_Dialog *_e_sys_dialog = NULL;
static E_Dialog *_e_sys_logout_confirm_dialog = NULL;
static Ecore_Timer *_e_sys_susp_hib_check_timer = NULL;
static double _e_sys_susp_hib_check_last_tick = 0.0;
static void (*_e_sys_suspend_func) (void) = NULL;
static void (*_e_sys_hibernate_func) (void) = NULL;
static void (*_e_sys_reboot_func) (void) = NULL;
static void (*_e_sys_shutdown_func) (void) = NULL;
static void (*_e_sys_logout_func) (void) = NULL;
static void (*_e_sys_resume_func) (void) = NULL;
static const int E_LOGOUT_AUTO_TIME = 60;
static const int E_LOGOUT_WAIT_TIME = 15;
@ -112,12 +121,61 @@ e_sys_action_do(E_Sys_Action a, char *param)
case E_SYS_SUSPEND:
case E_SYS_HIBERNATE:
case E_SYS_HALT_NOW:
ret = _e_sys_action_do(a, param);
ret = _e_sys_action_do(a, param, EINA_FALSE);
break;
case E_SYS_HALT:
if (!e_util_immortal_check())
{
if (_e_sys_shutdown_func) _e_sys_shutdown_func();
else _e_sys_logout_begin(a, EINA_FALSE);
}
return 1;
break;
case E_SYS_REBOOT:
if (!e_util_immortal_check())
{
if (_e_sys_reboot_func) _e_sys_reboot_func();
else _e_sys_logout_begin(a, EINA_FALSE);
}
return 1;
break;
default:
break;
}
if (ret) _e_sys_action_current = a;
else _e_sys_action_current = E_SYS_NONE;
return ret;
}
EAPI int
e_sys_action_raw_do(E_Sys_Action a, char *param)
{
int ret = 0;
if (_e_sys_action_current != E_SYS_NONE)
{
_e_sys_current_action();
return 0;
}
switch (a)
{
case E_SYS_EXIT:
case E_SYS_RESTART:
case E_SYS_EXIT_NOW:
case E_SYS_LOGOUT:
case E_SYS_SUSPEND:
case E_SYS_HIBERNATE:
case E_SYS_HALT_NOW:
ret = _e_sys_action_do(a, param, EINA_TRUE);
break;
case E_SYS_HALT:
case E_SYS_REBOOT:
if (!e_util_immortal_check()) _e_sys_logout_begin(a);
if (!e_util_immortal_check()) _e_sys_logout_begin(a, EINA_TRUE);
return 1;
break;
@ -171,6 +229,52 @@ e_sys_con_extra_action_list_get(void)
return extra_actions;
}
EAPI void
e_sys_handlers_set(void (*suspend_func) (void),
void (*hibernate_func) (void),
void (*reboot_func) (void),
void (*shutdown_func) (void),
void (*logout_func) (void),
void (*resume_func) (void))
{
_e_sys_suspend_func = suspend_func;
_e_sys_hibernate_func = hibernate_func;
_e_sys_reboot_func = reboot_func;
_e_sys_shutdown_func = shutdown_func;
_e_sys_logout_func = logout_func;
_e_sys_resume_func = resume_func;
}
static Eina_Bool
_e_sys_susp_hib_check_timer_cb(void *data __UNUSED__)
{
double t = ecore_time_unix_get();
if ((t - _e_sys_susp_hib_check_last_tick) > 0.2)
{
_e_sys_susp_hib_check_timer = NULL;
if (_e_sys_dialog)
{
e_object_del(E_OBJECT(_e_sys_dialog));
_e_sys_dialog = NULL;
}
if (_e_sys_resume_func) _e_sys_resume_func();
return EINA_FALSE;
}
_e_sys_susp_hib_check_last_tick = t;
return EINA_TRUE;
}
static void
_e_sys_susp_hib_check(void)
{
if (_e_sys_susp_hib_check_timer)
ecore_timer_del(_e_sys_susp_hib_check_timer);
_e_sys_susp_hib_check_last_tick = ecore_time_unix_get();
_e_sys_susp_hib_check_timer =
ecore_timer_add(0.1, _e_sys_susp_hib_check_timer_cb, NULL);
}
/* local subsystem functions */
static Eina_Bool
_e_sys_cb_timer(void *data __UNUSED__)
@ -302,6 +406,7 @@ _e_sys_cb_logout_abort(void *data __UNUSED__, E_Dialog *dia)
_e_sys_logout_confirm_dialog = NULL;
_e_sys_action_current = E_SYS_NONE;
_e_sys_action_after = E_SYS_NONE;
_e_sys_action_after_raw = EINA_FALSE;
if (_e_sys_dialog)
{
e_object_del(E_OBJECT(_e_sys_dialog));
@ -415,29 +520,34 @@ _e_sys_logout_after(void)
_e_sys_dialog = NULL;
}
_e_sys_action_current = _e_sys_action_after;
_e_sys_action_do(_e_sys_action_after, NULL);
_e_sys_action_do(_e_sys_action_after, NULL, _e_sys_action_after_raw);
_e_sys_action_after = E_SYS_NONE;
_e_sys_action_after_raw = EINA_FALSE;
}
static void
_e_sys_logout_begin(E_Sys_Action a_after)
_e_sys_logout_begin(E_Sys_Action a_after, Eina_Bool raw)
{
Eina_List *l;
E_Border *bd;
E_Obj_Dialog *od;
/* start logout - at end do the a_after action */
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Logout in progress"), "E", "_sys_logout");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/logout");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Logout in progress.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-log-out");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
_e_sys_dialog = od;
if (!raw)
{
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Logout in progress"), "E", "_sys_logout");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/logout");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Logout in progress.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-log-out");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
_e_sys_dialog = od;
}
_e_sys_action_after = a_after;
_e_sys_action_after_raw = raw;
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
e_border_act_close_begin(bd);
@ -545,7 +655,7 @@ _e_sys_action_failed(void)
}
static int
_e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
_e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, Eina_Bool raw)
{
char buf[PATH_MAX];
E_Obj_Dialog *od;
@ -578,7 +688,22 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
case E_SYS_LOGOUT:
// XXX TODO: check for e_fm_op_registry entries and confirm
_e_sys_logout_begin(E_SYS_EXIT);
if (raw)
{
_e_sys_logout_begin(E_SYS_EXIT, raw);
}
else
{
if (_e_sys_logout_func)
{
_e_sys_logout_func();
return 0;
}
else
{
_e_sys_logout_begin(E_SYS_EXIT, raw);
}
}
break;
case E_SYS_HALT:
@ -596,19 +721,35 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
}
else
{
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Power off"), "E", "_sys_halt");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/halt");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Power off.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-shutdown");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
_e_sys_dialog = od;
if (raw)
{
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
}
else
{
if (_e_sys_shutdown_func)
{
_e_sys_shutdown_func();
return 0;
}
else
{
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Power off"), "E", "_sys_halt");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/halt");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Power off.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-shutdown");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
_e_sys_dialog = od;
}
}
/* FIXME: display halt status */
}
break;
@ -627,19 +768,35 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
}
else
{
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Resetting"), "E", "_sys_reboot");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/reboot");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Resetting.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-restart");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
_e_sys_dialog = od;
if (raw)
{
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
}
else
{
if (_e_sys_reboot_func)
{
_e_sys_reboot_func();
return 0;
}
else
{
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Resetting"), "E", "_sys_reboot");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/reboot");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Resetting.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-restart");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
_e_sys_dialog = od;
}
}
/* FIXME: display reboot status */
}
break;
@ -657,21 +814,43 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
}
else
{
if (e_config->desklock_on_suspend) e_desklock_show(EINA_TRUE);
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Suspending"), "E", "_sys_suspend");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/suspend");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Suspending.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-suspend");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
_e_sys_dialog = od;
if (raw)
{
_e_sys_susp_hib_check();
if (e_config->desklock_on_suspend)
e_desklock_show(EINA_TRUE);
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
}
else
{
if (_e_sys_suspend_func)
{
_e_sys_suspend_func();
return 0;
}
else
{
if (e_config->desklock_on_suspend)
e_desklock_show(EINA_TRUE);
_e_sys_susp_hib_check();
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Suspending"), "E", "_sys_suspend");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/suspend");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Suspending.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-suspend");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
_e_sys_dialog = od;
}
}
/* FIXME: display suspend status */
}
break;
@ -689,21 +868,44 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
}
else
{
if (e_config->desklock_on_suspend) e_desklock_show(EINA_TRUE);
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Hibernating"), "E", "_sys_hibernate");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/hibernate");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Hibernating.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-suspend-hibernate");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
_e_sys_dialog = od;
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
if (_e_sys_hibernate_func)
{
_e_sys_hibernate_func();
return 0;
}
else
{
if (raw)
{
if (e_config->desklock_on_suspend)
e_desklock_show(EINA_TRUE);
_e_sys_susp_hib_check();
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
}
else
{
if (e_config->desklock_on_suspend)
e_desklock_show(EINA_TRUE);
_e_sys_susp_hib_check();
_e_sys_begin_time = ecore_time_get();
_e_sys_exe = ecore_exe_run(buf, NULL);
od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
_("Hibernating"), "E", "_sys_hibernate");
e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/hibernate");
e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
_("Hibernating.<br>"
"<hilight>Please wait.</hilight>"));
e_obj_dialog_show(od);
e_obj_dialog_icon_set(od, "system-suspend-hibernate");
if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
_e_sys_dialog = od;
e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
}
}
/* FIXME: display hibernate status */
}
break;
@ -713,7 +915,7 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
}
return 1;
}
static void
_e_sys_dialog_cb_delete(E_Obj_Dialog *od __UNUSED__)
{

@ -35,6 +35,7 @@ EINTERN int e_sys_init(void);
EINTERN int e_sys_shutdown(void);
EAPI int e_sys_action_possible_get(E_Sys_Action a);
EAPI int e_sys_action_do(E_Sys_Action a, char *param);
EAPI int e_sys_action_raw_do(E_Sys_Action a, char *param);
EAPI E_Sys_Con_Action *e_sys_con_extra_action_register(const char *label,
const char *icon_group,
@ -43,6 +44,12 @@ EAPI E_Sys_Con_Action *e_sys_con_extra_action_register(const char *label,
const void *data);
EAPI void e_sys_con_extra_action_unregister(E_Sys_Con_Action *sca);
EAPI const Eina_List *e_sys_con_extra_action_list_get(void);
EAPI void e_sys_handlers_set(void (*suspend_func) (void),
void (*hibernate_func) (void),
void (*reboot_func) (void),
void (*shutdown_func) (void),
void (*logout_func) (void),
void (*resume_func) (void));
#endif
#endif

@ -3636,11 +3636,99 @@ _e_mod_comp_del(E_Comp *c)
//////////////////////////////////////////////////////////////////////////
static void
_e_mod_comp_sys_done_cb(void *data, Evas_Object *obj, const char *sig, const char *src)
{
edje_object_signal_callback_del(obj, sig, src, _e_mod_comp_sys_done_cb);
e_sys_action_raw_do((E_Sys_Action)(long)data, NULL);
}
static void
_e_mod_comp_sys_emit_cb_wait(E_Sys_Action a, const char *sig, const char *rep)
{
Eina_List *l, *ll;
E_Comp_Zone *cz;
E_Comp *c;
Eina_Bool first = EINA_TRUE;
EINA_LIST_FOREACH(compositors, l, c)
{
EINA_LIST_FOREACH(c->zones, ll, cz)
{
edje_object_signal_emit(cz->base, sig, "e");
edje_object_signal_emit(cz->over, sig, "e");
if ((rep) && (first))
edje_object_signal_callback_add(cz->over, rep, "e",
_e_mod_comp_sys_done_cb,
(void *)(long)a);
first = EINA_FALSE;
}
}
}
static void
_e_mod_comp_sys_suspend(void)
{
_e_mod_comp_sys_emit_cb_wait(E_SYS_SUSPEND,
"e,state,sys,suspend",
"e,state,sys,suspend,done");
}
static void
_e_mod_comp_sys_hibernate(void)
{
_e_mod_comp_sys_emit_cb_wait(E_SYS_HIBERNATE,
"e,state,sys,hibernate",
"e,state,sys,hibernate,done");
}
static void
_e_mod_comp_sys_reboot(void)
{
_e_mod_comp_sys_emit_cb_wait(E_SYS_REBOOT,
"e,state,sys,reboot",
"e,state,sys,reboot,done");
}
static void
_e_mod_comp_sys_shutdown(void)
{
_e_mod_comp_sys_emit_cb_wait(E_SYS_HALT,
"e,state,sys,halt",
"e,state,sys,halt,done");
}
static void
_e_mod_comp_sys_logout(void)
{
_e_mod_comp_sys_emit_cb_wait(E_SYS_LOGOUT,
"e,state,sys,logout",
"e,state,sys,logout,done");
}
static void
_e_mod_comp_sys_resume(void)
{
_e_mod_comp_sys_emit_cb_wait(E_SYS_SUSPEND,
"e,state,sys,resume",
NULL);
}
//////////////////////////////////////////////////////////////////////////
Eina_Bool
e_mod_comp_init(void)
{
Eina_List *l;
E_Manager *man;
e_sys_handlers_set(_e_mod_comp_sys_suspend,
_e_mod_comp_sys_hibernate,
_e_mod_comp_sys_reboot,
_e_mod_comp_sys_shutdown,
_e_mod_comp_sys_logout,
_e_mod_comp_sys_resume);
windows = eina_hash_string_superfast_new(NULL);
borders = eina_hash_string_superfast_new(NULL);
@ -3744,6 +3832,8 @@ e_mod_comp_shutdown(void)
damages = NULL;
windows = NULL;
borders = NULL;
e_sys_handlers_set(NULL, NULL, NULL, NULL, NULL, NULL);
}
void

Loading…
Cancel
Save