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