discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=a31e8a70fb367e0ccb8f4eb7215902eb73433766

commit a31e8a70fb367e0ccb8f4eb7215902eb73433766
Author: discomfitor <michael.blumenkra...@gmail.com>
Date:   Fri Oct 25 14:20:45 2013 +0100

    break out desklock into display server-able hooks
    
    if we're running in a non-X environment, we can't very well expect that 
using X calls to hide/show windows for desklock is going to work as expected. 
now a compositor backend can add a pre or post desklock hook to hide/show its 
clients as necessary
---
 src/bin/e_comp_x.c   |  92 +++++++++++++++++++++++++++++++++++++++++-
 src/bin/e_desklock.c | 111 +++++++++++++++++++++++----------------------------
 src/bin/e_desklock.h |   7 ++++
 3 files changed, 149 insertions(+), 61 deletions(-)

diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index 0b473ae..f3b8f53 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -24,6 +24,10 @@ struct _Frame_Extents
 
 struct _E_Comp_Data
 {
+   Ecore_X_Window lock_win;
+   Ecore_X_Window lock_grab_break_wnd;
+   Ecore_Event_Handler *lock_key_handler;
+
    Eina_List *retry_clients;
    Ecore_Timer *retry_timer;
    Eina_Bool restack : 1;
@@ -4624,6 +4628,91 @@ _e_comp_x_grab_cb(E_Comp *c)
 }
 
 static Eina_Bool
+_e_comp_x_desklock_key_down(E_Comp *comp, int t EINA_UNUSED, Ecore_Event_Key 
*ev)
+{
+   return (ev->window == comp->comp_data->lock_win);
+}
+
+static void
+_e_comp_x_desklock_hide(void)
+{
+   E_Comp *comp;
+   const Eina_List *l;
+
+   EINA_LIST_FOREACH(e_comp_list(), l, comp)
+     {
+        if (comp->comp_data->lock_win)
+          {
+             e_grabinput_release(comp->comp_data->lock_win, 
comp->comp_data->lock_win);
+             ecore_x_window_free(comp->comp_data->lock_win);
+             comp->comp_data->lock_win = 0;
+          }
+
+        if (comp->comp_data->lock_grab_break_wnd)
+          ecore_x_window_show(comp->comp_data->lock_grab_break_wnd);
+        comp->comp_data->lock_grab_break_wnd = 0;
+        E_FREE_FUNC(comp->comp_data->lock_key_handler, 
ecore_event_handler_del);
+        e_comp_override_del(comp);
+     }
+}
+
+static Eina_Bool
+_e_comp_x_desklock_show(void)
+{
+   E_Comp *comp;
+   const Eina_List *l;
+
+   EINA_LIST_FOREACH(e_comp_list(), l, comp)
+     {
+        Ecore_X_Window win;
+
+        win = comp->comp_data->lock_win =
+          ecore_x_window_input_new(comp->man->root, 0, 0, 1, 1);
+        ecore_x_window_show(win);
+        if (!e_grabinput_get(win, 0, win))
+          {
+             Ecore_X_Window *windows;
+             int wnum, i;
+
+             windows = ecore_x_window_children_get(comp->man->root, &wnum);
+             if (!windows) goto fail;
+             for (i = 0; i < wnum; i++)
+               {
+                  Ecore_X_Window_Attributes att;
+
+                  memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
+                  ecore_x_window_attributes_get(windows[i], &att);
+                  if (att.visible)
+                    {
+                       ecore_x_window_hide(windows[i]);
+                       if (e_grabinput_get(win, 0, win))
+                         {
+                            comp->comp_data->lock_grab_break_wnd = windows[i];
+                            free(windows);
+                            goto works;
+                         }
+                       ecore_x_window_show(windows[i]);
+                    }
+               }
+             free(windows);
+          }
+works:
+        e_comp_override_add(comp);
+        e_comp_ignore_win_add(E_PIXMAP_TYPE_X, comp->comp_data->lock_win);
+        comp->comp_data->lock_key_handler =
+          ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, 
(Ecore_Event_Handler_Cb)_e_comp_x_desklock_key_down, comp);
+     }
+   return EINA_TRUE;
+fail:
+   /* everything failed - can't lock */
+   e_util_dialog_show(_("Lock Failed"),
+                      _("Locking the desktop failed because some 
application<br>"
+                        "has grabbed either the keyboard or the mouse or 
both<br>"
+                        "and their grab is unable to be broken."));
+   return EINA_FALSE;
+}
+
+static Eina_Bool
 _e_comp_x_setup(E_Comp *c, Ecore_X_Window root, int w, int h)
 {
    Ecore_X_Window_Attributes att;
@@ -4933,7 +5022,8 @@ e_comp_x_init(void)
    e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, 
_e_comp_x_hook_client_focus_unset, NULL);
    e_client_hook_add(E_CLIENT_HOOK_EVAL_END, _e_comp_x_hook_client_eval_end, 
NULL);
 
-
+   e_desklock_show_hook_add(_e_comp_x_desklock_show);
+   e_desklock_hide_hook_add(_e_comp_x_desklock_hide);
    if (!e_randr_init()) return 0;
    if (!e_atoms_init()) return 0;
    if (!_e_comp_x_screens_setup()) return EINA_FALSE;
diff --git a/src/bin/e_desklock.c b/src/bin/e_desklock.c
index 009871b..6028f6a 100644
--- a/src/bin/e_desklock.c
+++ b/src/bin/e_desklock.c
@@ -30,10 +30,8 @@ struct _E_Desklock_Popup_Data
 struct _E_Desklock_Data
 {
    Eina_List           *elock_wnd_list;
-   Ecore_X_Window       elock_wnd;
    Eina_List           *handlers;
    Ecore_Event_Handler *move_handler;
-   Ecore_X_Window       elock_grab_break_wnd;
    char                 passwd[PASSWD_LEN];
    int                  state;
    Eina_Bool            selected : 1;
@@ -77,6 +75,9 @@ static Ecore_Event_Handler *_e_desklock_run_handler = NULL;
 static Ecore_Job *job = NULL;
 static Eina_List *tasks = NULL;
 
+static Eina_List *show_cbs = NULL;
+static Eina_List *hide_cbs = NULL;
+
 /***********************************************************************/
 
 static Eina_Bool _e_desklock_cb_key_down(void *data, int type, void *event);
@@ -197,6 +198,34 @@ _user_wallpaper_get(E_Zone *zone)
    return e_theme_edje_file_get("base/theme/desklock", 
"e/desklock/background");
 }
 
+EAPI void
+e_desklock_show_hook_add(E_Desklock_Show_Cb cb)
+{
+   EINA_SAFETY_ON_NULL_RETURN(cb);
+   show_cbs = eina_list_append(show_cbs, cb);
+}
+
+EAPI void
+e_desklock_show_hook_del(E_Desklock_Show_Cb cb)
+{
+   EINA_SAFETY_ON_NULL_RETURN(cb);
+   show_cbs = eina_list_remove(show_cbs, cb);
+}
+
+EAPI void
+e_desklock_hide_hook_add(E_Desklock_Hide_Cb cb)
+{
+   EINA_SAFETY_ON_NULL_RETURN(cb);
+   hide_cbs = eina_list_append(hide_cbs, cb);
+}
+
+EAPI void
+e_desklock_hide_hook_del(E_Desklock_Hide_Cb cb)
+{
+   EINA_SAFETY_ON_NULL_RETURN(cb);
+   hide_cbs = eina_list_remove(hide_cbs, cb);
+}
+
 EAPI int
 e_desklock_show_autolocked(void)
 {
@@ -208,12 +237,14 @@ e_desklock_show_autolocked(void)
 EAPI int
 e_desklock_show(Eina_Bool suspend)
 {
-   Eina_List *managers, *l, *l3;
+   Eina_List *l, *l3;
    E_Manager *man;
    int total_zone_num;
    E_Event_Desklock *ev;
+   E_Desklock_Show_Cb show_cb;
+   E_Desklock_Hide_Cb hide_cb;
 
-   if (_e_custom_desklock_exe) return 0;
+   if (_e_desklock_state) return EINA_TRUE;
 
    if (e_config->desklock_use_custom_desklock && 
e_config->desklock_custom_desklock_cmd && 
e_config->desklock_custom_desklock_cmd[0])
      {
@@ -260,58 +291,14 @@ e_desklock_show(Eina_Bool suspend)
 
 #endif
 
-   edd = E_NEW(E_Desklock_Data, 1);
-   if (!edd) return 0;
-   edd->elock_wnd = ecore_x_window_input_new(e_manager_current_get()->root, 0, 
0, 1, 1);
-   ecore_x_window_show(edd->elock_wnd);
-   managers = e_manager_list();
    e_menu_hide_all();
-   if (!e_grabinput_get(edd->elock_wnd, 0, edd->elock_wnd))
+   EINA_LIST_FOREACH(show_cbs, l, show_cb)
      {
-        EINA_LIST_FOREACH(managers, l, man)
-          {
-             Ecore_X_Window *windows;
-             int wnum;
-
-             windows = ecore_x_window_children_get(man->root, &wnum);
-             if (windows)
-               {
-                  int i;
-
-                  for (i = 0; i < wnum; i++)
-                    {
-                       Ecore_X_Window_Attributes att;
-
-                       memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
-                       ecore_x_window_attributes_get(windows[i], &att);
-                       if (att.visible)
-                         {
-                            ecore_x_window_hide(windows[i]);
-                            if (e_grabinput_get(edd->elock_wnd, 0, 
edd->elock_wnd))
-                              {
-                                 edd->elock_grab_break_wnd = windows[i];
-                                 free(windows);
-                                 goto works;
-                              }
-                            ecore_x_window_show(windows[i]);
-                         }
-                    }
-                  free(windows);
-               }
-          }
-        /* everything failed - can't lock */
-        e_util_dialog_show(_("Lock Failed"),
-                           _("Locking the desktop failed because some 
application<br>"
-                             "has grabbed either the keyboard or the mouse or 
both<br>"
-                             "and their grab is unable to be broken."));
-        ecore_x_window_free(edd->elock_wnd);
-        E_FREE(edd);
-        return 0;
+        if (!show_cb()) goto fail;
      }
-works:
+   edd = E_NEW(E_Desklock_Data, 1);
+   if (!edd) return 0;
    //e_comp_block_window_add();
-   E_LIST_FOREACH(e_comp_list(), e_comp_override_add);
-   e_comp_ignore_win_add(E_PIXMAP_TYPE_X, edd->elock_wnd);
    if (e_config->desklock_language)
      e_intl_language_set(e_config->desklock_language);
 
@@ -319,7 +306,7 @@ works:
      e_xkb_layout_set(e_config->xkb.lock_layout);
 
    total_zone_num = _e_desklock_zone_num_get();
-   EINA_LIST_FOREACH(managers, l, man)
+   EINA_LIST_FOREACH(e_manager_list(), l, man)
      {
         E_Zone *zone;
         EINA_LIST_FOREACH(man->comp->zones, l3, zone)
@@ -346,12 +333,19 @@ works:
    e_util_env_set("E_DESKLOCK_LOCKED", "locked");
    _e_desklock_state = EINA_TRUE;
    return 1;
+fail:
+   EINA_LIST_FOREACH(hide_cbs, l, hide_cb)
+     hide_cb();
+   E_FREE(edd);
+   return 0;
 }
 
 EAPI void
 e_desklock_hide(void)
 {
+   Eina_List *l;
    E_Event_Desklock *ev;
+   E_Desklock_Hide_Cb hide_cb;
 
    if ((!edd) && (!_e_custom_desklock_exe)) return;
 
@@ -380,16 +374,14 @@ e_desklock_hide(void)
      }
 
    if (!edd) return;
-   if (edd->elock_grab_break_wnd)
-     ecore_x_window_show(edd->elock_grab_break_wnd);
+
+   EINA_LIST_FOREACH(hide_cbs, l, hide_cb)
+     hide_cb();
 
    E_FREE_LIST(edd->elock_wnd_list, _e_desklock_popup_free);
    E_FREE_LIST(edd->handlers, ecore_event_handler_del);
    if (edd->move_handler) ecore_event_handler_del(edd->move_handler);
 
-   e_grabinput_release(edd->elock_wnd, edd->elock_wnd);
-   ecore_x_window_free(edd->elock_wnd);
-
    E_FREE(edd);
 
    if (_e_desklock_autolock_time > 0.0)
@@ -615,8 +607,7 @@ _e_desklock_cb_key_down(void *data __UNUSED__, int type 
__UNUSED__, void *event)
 {
    Ecore_Event_Key *ev = event;
 
-   if ((ev->window != edd->elock_wnd) ||
-       (edd->state == E_DESKLOCK_STATE_CHECKING)) return 1;
+   if (edd->state == E_DESKLOCK_STATE_CHECKING) return ECORE_CALLBACK_DONE;
 
    if (!strcmp(ev->key, "Escape"))
      {
diff --git a/src/bin/e_desklock.h b/src/bin/e_desklock.h
index ee1a6a0..2952ca4 100644
--- a/src/bin/e_desklock.h
+++ b/src/bin/e_desklock.h
@@ -1,6 +1,8 @@
 #ifdef E_TYPEDEFS
 
 typedef struct _E_Event_Desklock E_Event_Desklock;
+typedef Eina_Bool (*E_Desklock_Show_Cb)(void);
+typedef void (*E_Desklock_Hide_Cb)(void);
 
 typedef enum _E_Desklock_Background_Method {
     E_DESKLOCK_BACKGROUND_METHOD_THEME_DESKLOCK = 0,
@@ -26,6 +28,11 @@ EAPI int e_desklock_show_autolocked(void);
 EAPI void e_desklock_hide(void);
 EAPI Eina_Bool e_desklock_state_get(void);
 
+EAPI void e_desklock_show_hook_add(E_Desklock_Show_Cb cb);
+EAPI void e_desklock_show_hook_del(E_Desklock_Show_Cb cb);
+EAPI void e_desklock_hide_hook_add(E_Desklock_Hide_Cb cb);
+EAPI void e_desklock_hide_hook_del(E_Desklock_Hide_Cb cb);
+
 extern EAPI int E_EVENT_DESKLOCK;
 
 #endif

-- 


Reply via email to