e_client: use e_client_visibility_set/get funtions
[platform/upstream/enlightenment.git] / src / bin / e_policy_wl_display.c
1 #include "e_policy_wl_display_intern.h"
2 #include "e_dbus_conn_intern.h"
3 #include "e_client_intern.h"
4
5 typedef struct _E_Display_Dbus_Info
6 {
7    Eldbus_Connection *edbus_conn;
8    Eldbus_Connection_Type edbus_conn_type;
9    Ecore_Event_Handler *dbus_init_done_handler;
10 } E_Display_Dbus_Info;
11
12 #define BUS_NAME "org.enlightenment.wm"
13
14 #define DEVICED_DEST "org.tizen.system.deviced"
15 #define DEVICED_PATH "/Org/Tizen/System/DeviceD/Display"
16 #define DEVICED_IFACE "org.tizen.system.deviced.display"
17 #define DEVICED_LOCK_STATE "lockstate"
18 #define DEVICED_UNLOCK_STATE "unlockstate"
19
20 #define DEVICED_LCDON "lcdon"
21 #define DEVICED_STAY_CUR_STATE "staycurstate"
22 #define DEVICED_SLEEP_MARGIN "sleepmargin"
23
24 /* static global variables */
25 static E_Display_Dbus_Info _e_display_dbus_info;
26 static Eina_List *_display_control_hooks = NULL;
27 static Eina_List *_display_control_handlers = NULL;
28
29 /* for screen mode */
30 static Eina_List *_screen_mode_client_list = NULL;
31 static E_Display_Screen_Mode _e_display_screen_mode;
32
33 /* static functions */
34 static Eina_Bool _e_policy_display_dbus_init(void);
35 static void      _e_policy_display_dbus_shutdown(void);
36 static void      _e_policy_display_dbus_request_name_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED);
37
38 static Eina_Bool _e_policy_wl_display_client_add_to_list(Eina_List** list, E_Client *ec);
39 static Eina_Bool _e_policy_wl_display_client_remove_from_list(Eina_List** list, E_Client *ec);
40
41 static void _e_policy_wl_display_hook_client_del(void *d EINA_UNUSED, E_Client *ec);
42 static void _e_policy_wl_display_hook_client_visibility(void *d EINA_UNUSED, E_Client *ec);
43
44 static Eina_Bool _e_policy_wl_display_cb_client_remove(void *d EINA_UNUSED, int type EINA_UNUSED, void *event);
45
46
47 /* for screen mode */
48 static E_Client *_e_policy_wl_display_screen_mode_find_visible_window(void);
49 static void      _e_policy_wl_display_screen_mode_send(E_Display_Screen_Mode mode);
50
51 static Eina_Bool
52 _e_policy_display_cb_dbus_init_done(void *data, int type, void *event)
53 {
54    E_DBus_Conn_Init_Done_Event *e = event;
55
56    if (e->status == E_DBUS_CONN_INIT_SUCCESS && e->conn_type == _e_display_dbus_info.edbus_conn_type)
57      {
58         _e_display_dbus_info.edbus_conn = e_dbus_conn_connection_ref(_e_display_dbus_info.edbus_conn_type);
59
60         if (_e_display_dbus_info.edbus_conn)
61           eldbus_name_request(_e_display_dbus_info.edbus_conn,
62                              BUS_NAME, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
63                              _e_policy_display_dbus_request_name_cb, NULL);
64      }
65
66    ecore_event_handler_del(_e_display_dbus_info.dbus_init_done_handler);
67    _e_display_dbus_info.dbus_init_done_handler = NULL;
68
69    return ECORE_CALLBACK_PASS_ON;
70 }
71
72 static Eina_Bool
73 _e_policy_display_dbus_init(void)
74 {
75    _e_display_dbus_info.edbus_conn = NULL;
76    _e_display_dbus_info.edbus_conn_type = ELDBUS_CONNECTION_TYPE_SYSTEM;
77    _e_display_dbus_info.dbus_init_done_handler = NULL;
78
79    if (e_dbus_conn_init() <= 0) return EINA_FALSE;
80
81    _e_display_dbus_info.dbus_init_done_handler = ecore_event_handler_add(E_EVENT_DBUS_CONN_INIT_DONE, _e_policy_display_cb_dbus_init_done, NULL);
82    e_dbus_conn_dbus_init(_e_display_dbus_info.edbus_conn_type);
83
84    return EINA_TRUE;
85 }
86
87 static void
88 _e_policy_display_dbus_shutdown(void)
89 {
90    if (_e_display_dbus_info.dbus_init_done_handler)
91      {
92         ecore_event_handler_del(_e_display_dbus_info.dbus_init_done_handler);
93         _e_display_dbus_info.dbus_init_done_handler = NULL;
94      }
95
96
97    if (_e_display_dbus_info.edbus_conn)
98      {
99         eldbus_name_release(_e_display_dbus_info.edbus_conn, BUS_NAME, NULL, NULL);
100         e_dbus_conn_connection_unref(_e_display_dbus_info.edbus_conn);
101         _e_display_dbus_info.edbus_conn = NULL;
102      }
103
104    e_dbus_conn_shutdown();
105 }
106
107 static void
108 _e_policy_display_dbus_request_name_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
109 {
110    unsigned int flag;
111
112    if (eldbus_message_error_get(msg, NULL, NULL))
113      {
114         ERR("Could not request bus name");
115         return;
116      }
117
118    if (!eldbus_message_arguments_get(msg, "u", &flag))
119      {
120         ERR("Could not get arguments on on_name_request");
121         return;
122      }
123
124    if (!(flag & ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER))
125      {
126         WRN("Name already in use\n");
127      }
128 }
129
130 static Eina_Bool
131 _e_policy_wl_display_client_add_to_list(Eina_List** list, E_Client *ec)
132 {
133    if (!ec) return EINA_FALSE;
134
135    if (eina_list_data_find(*list, ec) == ec)
136      return EINA_TRUE;
137
138    *list = eina_list_append(*list, ec);
139
140    return EINA_TRUE;
141 }
142
143 static Eina_Bool
144 _e_policy_wl_display_client_remove_from_list(Eina_List** list, E_Client *ec)
145 {
146    if (!ec) return EINA_FALSE;
147
148    if (!eina_list_data_find(*list, ec))
149      return EINA_FALSE;
150
151    *list = eina_list_remove(*list, ec);
152
153    return EINA_TRUE;
154 }
155
156 static void
157 _e_policy_wl_display_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
158 {
159    _e_policy_wl_display_client_remove_from_list(&_screen_mode_client_list, ec);
160 }
161
162 static void
163 _e_policy_wl_display_hook_client_visibility(void *d EINA_UNUSED, E_Client *ec)
164 {
165    if (ec->visibility.changed)
166      {
167         e_policy_display_screen_mode_apply();
168      }
169 }
170
171 static Eina_Bool
172 _e_policy_wl_display_cb_client_remove(void *d EINA_UNUSED, int type EINA_UNUSED, void *event)
173 {
174    e_policy_display_screen_mode_apply();
175    return ECORE_CALLBACK_PASS_ON;
176 }
177
178 static E_Client *
179 _e_policy_wl_display_screen_mode_find_visible_window(void)
180 {
181    Eina_List *l = NULL;
182    E_Client *ec = NULL;
183    int ec_visibility;
184
185    if (_screen_mode_client_list == NULL) return NULL;
186
187    EINA_LIST_FOREACH(_screen_mode_client_list, l, ec)
188      {
189         if (e_object_is_del(E_OBJECT(ec)))
190           ec_visibility = E_VISIBILITY_FULLY_OBSCURED;
191         else
192           ec_visibility = e_client_visibility_get(ec);
193
194         if ((ec_visibility == E_VISIBILITY_UNOBSCURED) ||
195             (ec_visibility == E_VISIBILITY_PARTIALLY_OBSCURED))
196           {
197              break;
198           }
199      }
200
201    return ec;
202 }
203
204 static void
205 _e_policy_wl_display_screen_mode_send(E_Display_Screen_Mode mode)
206 {
207    Eldbus_Message *msg;
208    Eina_Bool ret;
209    unsigned int timeout = 0;
210
211    if (!_e_display_dbus_info.edbus_conn) return;
212
213    if (mode == E_DISPLAY_SCREEN_MODE_ALWAYS_ON)
214      {
215         msg = eldbus_message_method_call_new(DEVICED_DEST,
216                                              DEVICED_PATH,
217                                              DEVICED_IFACE,
218                                              DEVICED_LOCK_STATE);
219         if (!msg) return;
220
221         ret = eldbus_message_arguments_append(msg, "sssi",
222                                               DEVICED_LCDON,
223                                               DEVICED_STAY_CUR_STATE,
224                                               "",
225                                               timeout);
226      }
227    else
228      {
229         msg = eldbus_message_method_call_new(DEVICED_DEST,
230                                              DEVICED_PATH,
231                                              DEVICED_IFACE,
232                                              DEVICED_UNLOCK_STATE);
233         if (!msg) return;
234
235         ret = eldbus_message_arguments_append(msg, "ss",
236                                               DEVICED_LCDON,
237                                               DEVICED_SLEEP_MARGIN);
238      }
239
240    if (!ret)
241      {
242         if (msg)
243           eldbus_message_unref(msg);
244
245         return;
246      }
247
248    _e_display_screen_mode = mode;
249    ELOGF("TZPOL", "SCR_MODE | Send screen mode:%d to system", NULL, mode);
250
251    eldbus_connection_send(_e_display_dbus_info.edbus_conn, msg, NULL, NULL, -1);
252 }
253
254 EINTERN Eina_Bool
255 e_policy_display_init(void)
256 {
257    if (!_e_policy_display_dbus_init()) return EINA_FALSE;
258
259    _e_display_screen_mode = E_DISPLAY_SCREEN_MODE_DEFAULT;
260
261    /* hook functions */
262    E_CLIENT_HOOK_APPEND(_display_control_hooks, E_CLIENT_HOOK_DEL, _e_policy_wl_display_hook_client_del, NULL);
263    E_CLIENT_HOOK_APPEND(_display_control_hooks, E_CLIENT_HOOK_EVAL_VISIBILITY, _e_policy_wl_display_hook_client_visibility, NULL);
264
265    /* handler functions */
266    E_LIST_HANDLER_APPEND(_display_control_handlers, E_EVENT_CLIENT_REMOVE, _e_policy_wl_display_cb_client_remove, NULL);
267
268    return EINA_TRUE;
269 }
270
271 EINTERN void
272 e_policy_display_shutdown(void)
273 {
274    E_FREE_LIST(_display_control_hooks, e_client_hook_del);
275    E_FREE_LIST(_display_control_handlers, ecore_event_handler_del);
276
277    if (_screen_mode_client_list) eina_list_free(_screen_mode_client_list);
278
279    _e_policy_display_dbus_shutdown();
280 }
281
282 EINTERN void
283 e_policy_display_screen_mode_set(E_Client *ec, int mode)
284 {
285    if (!ec) return;
286    if (e_object_is_del(E_OBJECT(ec))) return;
287
288    if (mode == 0)
289      {
290         _e_policy_wl_display_client_remove_from_list(&_screen_mode_client_list, ec);
291         e_policy_display_screen_mode_apply();
292      }
293    else
294      {
295         _e_policy_wl_display_client_add_to_list(&_screen_mode_client_list, ec);
296         e_policy_display_screen_mode_apply();
297      }
298 }
299
300 EINTERN void
301 e_policy_display_screen_mode_apply(void)
302 {
303    E_Client *ec = NULL;
304
305    ec = _e_policy_wl_display_screen_mode_find_visible_window();
306    if (ec)
307      {
308         if (_e_display_screen_mode == E_DISPLAY_SCREEN_MODE_DEFAULT)
309           {
310              ELOGF("TZPOL", "SCR_MODE | Request to change screen mode:%d", ec, E_DISPLAY_SCREEN_MODE_ALWAYS_ON);
311              _e_policy_wl_display_screen_mode_send(E_DISPLAY_SCREEN_MODE_ALWAYS_ON);
312           }
313      }
314    else
315      {
316         if (_e_display_screen_mode == E_DISPLAY_SCREEN_MODE_ALWAYS_ON)
317           {
318              ELOGF("TZPOL", "SCR_MODE | Request to change screen mode:%d", NULL, E_DISPLAY_SCREEN_MODE_DEFAULT);
319              _e_policy_wl_display_screen_mode_send(E_DISPLAY_SCREEN_MODE_DEFAULT);
320           }
321      }
322 }
323