46699e4ce0de7d50f6d894db5a0681b5c8ffa7d7
[platform/upstream/enlightenment.git] / src / bin / e_input_thread_client.c
1 #include "e_input_thread_client_intern.h"
2 #include "e_comp_canvas.h"
3 #include "e_comp_input_intern.h"
4
5 struct _E_Input_Thread_Client
6 {
7    EINA_INLIST;
8    void *ec;
9    struct wl_resource *surface;
10    E_Layer layer;
11    E_Visibility visibility;
12    Eina_Bool layer_block;
13    Eina_Bool layer_pending;
14    Eina_Bool is_video;
15    Eina_Bool deleted;
16    Eina_Bool is_cursor;
17    Eina_Stringshare *icccm_name;
18    Eina_Stringshare *netwm_name;
19    Eina_Stringshare *icccm_title;
20 };
21
22 static Eina_List *_itc_list = NULL;
23
24 ///////////////////////////////////////////
25 EINTERN void
26 e_input_thread_client_init()
27 {
28
29 }
30
31 EINTERN void
32 e_input_thread_client_shutdown()
33 {
34    if (_itc_list)
35      eina_list_free(_itc_list);
36
37    _itc_list = NULL;
38 }
39
40 EINTERN E_Input_Thread_Client *
41 e_input_thread_client_new(E_Client *ec, struct wl_resource *surface)
42 {
43    E_Input_Thread_Client *itc = E_NEW(E_Input_Thread_Client, 1);
44    EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
45
46    itc->ec = ec;
47    itc->surface = surface;
48    itc->layer = E_LAYER_CLIENT_NORMAL;
49    itc->visibility = E_VISIBILITY_UNKNOWN;
50
51    _itc_list = eina_list_append(_itc_list, itc);
52    INF("[%s] iec(%p), ec(%p), surface(%p)\n", __func__, itc, ec, surface);
53
54    return itc;
55 }
56
57 EINTERN void
58 e_input_thread_client_free(E_Input_Thread_Client *iec)
59 {
60    EINA_SAFETY_ON_NULL_RETURN(iec);
61
62    INF("[%s] iec(%p), ec(%p)", __func__, iec, iec->ec);
63
64    _itc_list = eina_list_remove(_itc_list, iec);
65
66    E_FREE(iec);
67 }
68
69 EINTERN void
70 e_input_thread_client_del(E_Input_Thread_Client *iec)
71 {
72    EINA_SAFETY_ON_NULL_RETURN(iec);
73
74    iec->deleted = 1;
75 }
76
77 EINTERN void
78 e_input_thread_client_visibility_set(E_Input_Thread_Client *iec, E_Visibility visibility)
79 {
80    EINA_SAFETY_ON_NULL_RETURN(iec);
81
82    iec->visibility = visibility;
83    INF("[%s] iec(%p), visibility(%d)\n", __func__, iec, visibility);
84 }
85
86 E_API E_Visibility
87 e_input_thread_client_visibility_get(E_Input_Thread_Client *iec)
88 {
89    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, E_VISIBILITY_UNKNOWN);
90
91    return iec->visibility;
92 }
93
94 E_API Eina_Bool
95 e_input_thread_client_video_mode_get(E_Input_Thread_Client *iec)
96 {
97    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, EINA_FALSE);
98
99    return iec->is_video;
100 }
101
102 EINTERN void
103 e_input_thread_client_video_set(E_Input_Thread_Client *iec, Eina_Bool is_video)
104 {
105    EINA_SAFETY_ON_NULL_RETURN(iec);
106
107    iec->is_video = is_video;
108    INF("[%s] iec(%p), video(%d)\n", __func__, iec, is_video);
109 }
110
111 E_API Eina_Bool
112 e_input_thread_client_visible_get(E_Input_Thread_Client *iec)
113 {
114    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, EINA_FALSE);
115
116    return iec->visibility;
117 }
118
119 EINTERN void
120 e_input_thread_client_icccm_name_set(E_Input_Thread_Client *iec, char *name)
121 {
122    EINA_SAFETY_ON_NULL_RETURN(iec);
123
124    eina_stringshare_replace(&iec->icccm_name, name);
125    INF("[%s] iec(%p), name(%s)\n", __func__, iec, name);
126 }
127
128 E_API Eina_Stringshare *
129 e_input_thread_client_icccm_name_get(E_Input_Thread_Client *iec)
130 {
131    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
132
133    return iec->icccm_name;
134 }
135
136 EINTERN void
137 e_input_thread_client_icccm_title_set(E_Input_Thread_Client *iec, char *title)
138 {
139    EINA_SAFETY_ON_NULL_RETURN(iec);
140
141    eina_stringshare_replace(&iec->icccm_title, title);
142
143    INF("[%s] iec(%p), title(%s)\n", __func__, iec, title);
144 }
145
146 E_API Eina_Stringshare *
147 e_input_thread_client_icccm_title_get(E_Input_Thread_Client *iec)
148 {
149    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
150
151    return iec->icccm_title;
152 }
153
154 EINTERN void
155 e_input_thread_client_netwm_name_set(E_Input_Thread_Client *iec, char *name)
156 {
157    EINA_SAFETY_ON_NULL_RETURN(iec);
158
159    eina_stringshare_replace(&iec->icccm_name, name);
160
161    INF("[%s] iec(%p), name(%s)\n", __func__, iec, name);
162 }
163
164 E_API Eina_Stringshare *
165 e_input_thread_client_netwm_name_get(E_Input_Thread_Client *iec)
166 {
167    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
168
169    return iec->icccm_name;
170 }
171
172 E_API Eina_Stringshare *
173 e_input_thread_client_util_name_get(E_Input_Thread_Client *iec)
174 {
175    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
176
177    if (iec->netwm_name)
178      return iec->netwm_name;
179    else if (iec->icccm_title)
180      return iec->icccm_title;
181
182    return NULL;
183 }
184
185 E_API Eina_Bool e_input_thread_client_cursor_mode_get(E_Input_Thread_Client *iec)
186 {
187    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, EINA_FALSE);
188
189    return iec->is_cursor;
190 }
191
192 EINTERN void e_input_thread_client_layer_set(E_Input_Thread_Client *iec, E_Layer layer)
193 {
194    EINA_SAFETY_ON_NULL_RETURN(iec);
195
196    iec->layer = layer;
197    INF("[%s] iec(%p), layer(%d)\n", __func__, iec, layer);
198 }
199
200 EINTERN void e_input_thread_client_layer_block_set(E_Input_Thread_Client *iec, Eina_Bool block)
201 {
202    EINA_SAFETY_ON_NULL_RETURN(iec);
203
204    iec->layer_block = block;
205    INF("[%s] iec(%p), layer_block(%d)\n", __func__, iec, iec->layer_block);
206 }
207
208 EINTERN void e_input_thread_client_layer_pending_set(E_Input_Thread_Client *iec, Eina_Bool pending)
209 {
210    EINA_SAFETY_ON_NULL_RETURN(iec);
211
212    iec->layer_pending = pending;
213    INF("[%s] iec(%p), layer_pending(%d)\n", __func__, iec, iec->layer_pending);
214 }
215
216 EINTERN void e_input_thread_client_is_cursor_set(E_Input_Thread_Client *iec, Eina_Bool is_cursor)
217 {
218    EINA_SAFETY_ON_NULL_RETURN(iec);
219
220    iec->is_cursor = is_cursor;
221    INF("[%s] iec(%p), is_cursor(%d)\n", __func__, iec, iec->is_cursor);
222 }
223
224 EINTERN E_Input_Thread_Client * e_input_thread_client_get(E_Client *ec)
225 {
226    Eina_List *l;
227    void *list_data;
228    E_Input_Thread_Client *itc = NULL;
229
230    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
231
232    EINA_LIST_FOREACH(_itc_list, l, list_data)
233      {
234         itc = (E_Input_Thread_Client *)list_data;
235         if (itc && itc->ec == ec)
236           return itc;
237      }
238
239    return NULL;
240 }
241
242 EINTERN Eina_Inlist * e_input_thread_client_Inlist_get(E_Client *ec)
243 {
244    E_Input_Thread_Client *iec = e_input_thread_client_get(ec);
245    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
246
247    return &(iec->__in_list);
248 }
249
250 E_API E_Input_Thread_Client *e_input_thread_client_above_get(E_Input_Thread_Client *iec)
251 {
252    unsigned int x;
253    E_Input_Thread_Client *iec2;
254
255    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
256    if (EINA_INLIST_GET(iec)->next) //check current layer
257      {
258         EINA_INLIST_FOREACH(EINA_INLIST_GET(iec)->next, iec2)
259           {
260              if (iec == iec2)
261                {
262                   INF("[%s] iec: %p\n", __func__, iec);
263                   continue;
264                }
265              if (!iec2->deleted)
266                return iec2;
267           }
268      }
269    if (iec->layer == E_LAYER_CLIENT_CURSOR) return NULL;
270    if (e_comp_canvas_client_layer_map(iec->layer) == 9999) return NULL;
271
272    for (x = e_comp_canvas_layer_map(iec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
273      {
274         if (!e_comp_input->layers[x].clients) continue;
275         EINA_INLIST_FOREACH(e_comp_input->layers[x].clients, iec2)
276           {
277              if (iec == iec2)
278                {
279                   INF("EC exist above layer. ec layer_map:%d, cur layer_map:%d", e_comp_canvas_layer_map(iec->layer), x);
280                   continue;
281                }
282              if (!iec2->deleted)
283                {
284                   return iec2;
285                }
286           }
287      }
288
289    return NULL;
290 }
291
292 E_API E_Input_Thread_Client *e_input_thread_client_below_get(E_Input_Thread_Client *iec)
293 {
294    unsigned int x;
295    E_Input_Thread_Client *iec2;
296    Eina_Inlist *l;
297    E_Layer iec_layer, iec_layer_cw;
298    int cw_layer;
299
300    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
301    if (EINA_INLIST_GET(iec)->prev) //check current layer
302      {
303         for (l = EINA_INLIST_GET(iec)->prev; l; l = l->prev)
304           {
305              iec2 = EINA_INLIST_CONTAINER_GET(l, E_Input_Thread_Client);
306              if (iec == iec2)
307                {
308                   INF("CHECK the ec inlist prev");
309                   continue;
310                }
311              if (!iec2->deleted)
312                return iec2;
313           }
314      }
315
316    // check layer validation
317    iec_layer = iec->layer;
318    if (iec->layer_block || iec->layer_pending)
319      {
320         cw_layer = iec->layer;
321         if (cw_layer >= 0)
322           {
323              iec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
324              if (iec_layer != iec_layer_cw)
325                {
326                   INF("LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)", iec_layer, iec_layer_cw, iec->layer_block, iec->layer_pending);
327                   iec_layer = iec_layer_cw;
328                }
329           }
330      }
331
332    if (iec_layer == E_LAYER_CLIENT_DESKTOP) return NULL;
333    if (e_comp_canvas_client_layer_map(iec_layer) == 9999) return NULL;
334
335    /* go down the layers until we find one */
336    x = e_comp_canvas_layer_map(iec_layer);
337    if (x > 0) x--;
338
339    for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
340      {
341         if (!e_comp_input->layers[x].clients) continue;
342         EINA_INLIST_REVERSE_FOREACH(e_comp_input->layers[x].clients, iec2)
343           {
344              if (iec == iec2)
345                {
346                   INF("EC exist below layer. ec layer_map:%d, cur layer_map:%d", e_comp_canvas_layer_map(iec_layer), x);
347                   continue;
348                }
349              if (!iec2->deleted)
350                return iec2;
351           }
352      }
353
354    return NULL;
355 }
356
357 E_API E_Input_Thread_Client *e_input_thread_client_bottom_get()
358 {
359    unsigned int x;
360    for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
361      {
362         E_Input_Thread_Client *iec2;
363         if (!e_comp_input->layers[x].clients) continue;
364
365         EINA_INLIST_FOREACH(e_comp_input->layers[x].clients, iec2)
366           if (!iec2->deleted)
367             return iec2;
368      }
369
370    return NULL;
371 }
372
373 E_API E_Input_Thread_Client *e_input_thread_client_top_get()
374 {
375    unsigned int x;
376    for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
377      {
378         E_Input_Thread_Client *iec2;
379         if (!e_comp_input->layers[x].clients) continue;
380
381         EINA_INLIST_REVERSE_FOREACH(e_comp_input->layers[x].clients, iec2)
382           if (!iec2->deleted)
383             return iec2;
384      }
385
386    return NULL;
387 }
388
389 E_API E_Input_Thread_Client *e_input_thread_client_focused_get()
390 {
391    return e_input_thread_client_get(e_comp_input->focused_ec);
392 }
393
394 E_API E_Input_Thread_Client *e_input_thread_client_from_surface_resource(struct wl_resource *surface_resource)
395 {
396    Eina_List *l;
397    void *list_data;
398    E_Input_Thread_Client *itc = NULL;
399
400    EINA_SAFETY_ON_NULL_RETURN_VAL(surface_resource, NULL);
401
402    EINA_LIST_FOREACH(_itc_list, l, list_data)
403      {
404         itc = (E_Input_Thread_Client *)list_data;
405         if (itc && itc->surface == surface_resource)
406           return itc;
407      }
408
409    return NULL;
410 }
411
412 E_API struct wl_resource *e_input_thread_client_wl_resource_get(E_Input_Thread_Client *iec)
413 {
414    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
415
416    return iec->surface;
417 }