2 #include "e_mod_main.h"
3 #include "e_mod_pol_pingpong.h"
5 #define PONG_WAIT_TIME 2.0
10 Ecore_Timer *t_pong_wait;
14 static Eina_List *_handlers = NULL;
15 static Eina_List *_pp_wins = NULL;
17 static void _cb_client_mouse_down(void *data, Evas *e, Evas_Object *o, void *event);
20 _pp_win_add(E_Client *ec)
24 ppw = E_NEW(PP_Win, 1);
25 EINA_SAFETY_ON_NULL_RETURN_VAL(ppw, NULL);
29 evas_object_event_callback_add(ec->frame,
30 EVAS_CALLBACK_MOUSE_DOWN,
31 _cb_client_mouse_down,
34 _pp_wins = eina_list_append(_pp_wins, ppw);
40 _pp_win_del(PP_Win *ppw)
43 ecore_timer_del(ppw->t_pong_wait);
45 evas_object_event_callback_del(ppw->ec->frame,
46 EVAS_CALLBACK_MOUSE_DOWN,
47 _cb_client_mouse_down);
52 _pp_win_find(E_Client *ec)
57 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
59 EINA_LIST_FOREACH(_pp_wins, l, ppw)
69 _pp_win_remove(E_Client *ec)
73 ppw = _pp_win_find(ec);
76 _pp_wins = eina_list_remove(_pp_wins, ppw);
81 _cb_pong_check(void *data)
83 PP_Win *ppw = (PP_Win *)data;
84 E_Client* ec = ppw->ec;
86 EINA_SAFETY_ON_FALSE_RETURN_VAL(ppw->ping_sent, ECORE_CALLBACK_CANCEL);
88 ppw->t_pong_wait = NULL;
89 ppw->ping_sent = EINA_FALSE;
91 ELOGF("PP", "PONG CHK | pid:%d name:%s ping_ok:%u",
92 ec, ec->netwm.pid, ec->icccm.name, ec->ping_ok);
94 if (ec->ping_ok) return ECORE_CALLBACK_CANCEL;
96 /* TODO: kill the unresponsive client here */
99 return ECORE_CALLBACK_CANCEL;
103 _ping_send(PP_Win *ppw)
105 E_Client *ec = ppw->ec;
107 /* if ping is already sent, do nothing */
108 if (ppw->t_pong_wait)
110 ELOGF("PP", "PING SKIP | pid:%d name:%s",
111 ec, ec->netwm.pid, ec->icccm.name);
115 ELOGF("PP", "PING SENT | pid:%d name:%s",
116 ec, ec->netwm.pid, ec->icccm.name);
119 evas_object_smart_callback_call(ec->frame, "ping", NULL);
121 ppw->t_pong_wait = ecore_timer_add(PONG_WAIT_TIME,
124 ppw->ping_sent = EINA_TRUE;
130 _cb_client_mouse_down(void *data,
132 Evas_Object *o EINA_UNUSED,
135 PP_Win *ppw = (PP_Win *)data;
136 E_Client *ec = ppw->ec;
139 if (!ec->visible) return;
140 if (e_client_util_ignored_get(ec)) return;
141 if (!evas_object_visible_get(ec->frame)) return;
142 if (ec->visibility.obscured == E_VISIBILITY_UNKNOWN ||
143 ec->visibility.obscured == E_VISIBILITY_PARTIALLY_OBSCURED) return;
144 if (evas_object_data_get(ec->frame, "comp_skip")) return;
146 /* send ping to visible top-level window */
147 res = _ping_send(ppw);
150 /* get a list of tizen remote surface providers which is used in given ec */
151 if (!ec->remote_surface.consumer) return;
153 Eina_List *tzrs_provs, *l;
157 tzrs_provs = e_comp_wl_remote_surface_providers_get(ec);
158 if (!tzrs_provs) return;
160 EINA_LIST_FOREACH(tzrs_provs, l, prov_ec)
162 /* check remote surface provider */
163 if (!prov_ec->remote_surface.provider) continue;
164 if (prov_ec->comp_data->remote_surface.onscreen_parent != ec) continue;
165 if (prov_ec->visible) continue;
166 if (evas_object_visible_get(prov_ec->frame)) continue;
167 if (prov_ec->comp_data->mapped) continue;
169 prov_ppw = _pp_win_find(prov_ec);
171 prov_ppw = _pp_win_add(prov_ec);
173 /* send ping to invisible tizen remote surface provider */
174 _ping_send(prov_ppw);
177 eina_list_free(tzrs_provs);
181 _cb_client_show(void *data EINA_UNUSED,
182 int type EINA_UNUSED,
186 E_Event_Client *ev = (E_Event_Client *)event;
187 E_Client *ec = ev->ec;
189 ppw = _pp_win_find(ec);
190 if (ppw) return ECORE_CALLBACK_PASS_ON;
192 ppw = _pp_win_add(ec);
193 EINA_SAFETY_ON_NULL_RETURN_VAL(ppw, ECORE_CALLBACK_PASS_ON);
195 return ECORE_CALLBACK_PASS_ON;
199 _cb_client_hide(void *data EINA_UNUSED,
200 int type EINA_UNUSED,
203 E_Event_Client *ev = (E_Event_Client *)event;
206 _pp_win_remove(ev->ec);
208 return ECORE_CALLBACK_PASS_ON;
212 _cb_client_del(void *data EINA_UNUSED,
213 int type EINA_UNUSED,
216 E_Event_Client *ev = (E_Event_Client *)event;
219 _pp_win_remove(ev->ec);
221 return ECORE_CALLBACK_PASS_ON;
225 e_mod_pol_pingpong_init(void)
227 if (!e_mod_pol_conf_use_pingpoing_policy_get()) return;
229 E_LIST_HANDLER_APPEND(_handlers, E_EVENT_CLIENT_SHOW, _cb_client_show, NULL);
230 E_LIST_HANDLER_APPEND(_handlers, E_EVENT_CLIENT_HIDE, _cb_client_hide, NULL);
231 E_LIST_HANDLER_APPEND(_handlers, E_EVENT_CLIENT_REMOVE, _cb_client_del, NULL);
235 e_mod_pol_pingpong_shutdown(void)
237 if (!e_mod_pol_conf_use_pingpoing_policy_get()) return;
239 E_FREE_LIST(_pp_wins, _pp_win_del);
240 E_FREE_LIST(_handlers, ecore_event_handler_del);