Add input event source information
[apps/native/widget/widget.git] / src / virtual_window.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE
18
19 #include <Elementary.h>
20 #include <string.h>
21 #include <Ecore_Evas.h>
22 #include <Ecore_X.h>
23 #include <Evas.h>
24 #include <dlfcn.h>
25 #include <Eina.h>
26 #include <math.h>
27
28 #include <X11/Xlib.h>
29
30 #include <dlog.h>
31 #include <widget_errno.h>
32 #include <widget_service.h>
33 #include <widget_service_internal.h>
34 #include <widget_conf.h>
35 #include <widget_buffer.h>
36 #include <widget_provider.h>
37 #include <widget_util.h>
38
39 #include "widget.h"
40 #include "widget_internal.h"
41 #include "debug.h"
42 #include "binder.h"
43
44 #define IS_GBAR 1
45
46 #define PUBLIC __attribute__((visibility("default")))
47 #define WIDGET_WIN_TAG "dynamic,box,win"
48
49 #define WIDGET_DEFAULT_WIDTH 1
50 #define WIDGET_DEFAULT_HEIGHT 1
51
52 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
53 {
54         Evas_Object *o, *ho;
55
56         o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
57         if (!o) return NULL;
58
59         ho = evas_object_data_get(o, "_elm_access_target");
60         return ho;
61 }
62
63 static inline void apply_orientation(int degree, int *x, int *y, input_event_source_e source)
64 {
65         int _x;
66         int _y;
67         int _angle;
68
69         if (source == INPUT_EVENT_SOURCE_VIEWER) {
70                 /* Already rotated */
71                 return;
72         }
73
74         switch (degree) {
75         case 0:
76                 return;
77         case 90:
78                 _x = *x;
79                 _y = *y;
80
81                 *x = -_y;
82                 *y = _x;
83                 return;
84         case 180:
85                 _x = *x;
86                 _y = *y;
87                 _angle = degree;
88
89                 *x = -_x;
90                 *y = -_y;
91                 return;
92         case 270:
93                 _x = *x;
94                 _y = *y;
95                 _angle = degree;
96
97                 *x = _y;
98                 *y = -_x;
99                 return;
100         default:
101                 _x = *x;
102                 _y = *y;
103                 _angle = degree;
104
105                 *x = (double)_x * cos((double)_angle) - (double)_y * sin((double)_angle);
106                 *y = (double)_x * sin((double)_angle) + (double)_y * cos((double)_angle);
107                 return;
108         }
109 }
110
111 /**
112  * @note
113  * Every user event (mouse) on the buffer will be passed via this event callback
114  */
115 static int event_handler_cb(widget_buffer_h handler, struct widget_buffer_event_data *event_info, void *data)
116 {
117         vwin_info_t info = data;
118         Elm_Access_Action_Info action_info;
119         Elm_Access_Action_Type action_type;
120         int ret = 0;
121         Evas_Object *parent_elm;
122         KeySym *key_symbol;
123         unsigned int flags = 0;
124         double timestamp;
125
126         if (!info->handle) {
127                 /* Just ignore this event */
128                 return 0;
129         }
130
131         if (WIDGET_CONF_USE_GETTIMEOFDAY) {
132                 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
133                         struct timeval tv;
134
135                         if (gettimeofday(&tv, NULL) < 0) {
136                                 ErrPrint("gettimeofday: %d\n", errno);
137                         } else {
138                                 timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
139                                 timestamp -= event_info->timestamp;
140
141                                 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
142                                         DbgPrint("Dropped %lf\n", timestamp);
143                                         return 0;
144                                 }
145                         }
146                 }
147
148                 /**
149                  * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
150                  * Evas only use the monotic time for animating objects
151                  */
152                 timestamp = ecore_time_get() * 1000.0f;
153         } else {
154                 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
155                         timestamp = ecore_time_get();
156
157                         timestamp -= event_info->timestamp;
158                         if (timestamp > WIDGET_CONF_EVENT_FILTER) {
159                                 DbgPrint("Dropped %lf\n", timestamp);
160                                 return 0;
161                         }
162                 }
163
164                 timestamp = event_info->timestamp * 1000.0f;
165         }
166
167         /**
168          * @note
169          * Feed up events
170          */
171         switch (event_info->type) {
172         case WIDGET_BUFFER_EVENT_ON_HOLD:
173                 flags = evas_event_default_flags_get(info->e);
174                 flags |= EVAS_EVENT_FLAG_ON_HOLD;
175                 evas_event_default_flags_set(info->e, flags);
176                 ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
177                 break;
178         case WIDGET_BUFFER_EVENT_OFF_HOLD:
179                 flags = evas_event_default_flags_get(info->e);
180                 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
181                 evas_event_default_flags_set(info->e, flags);
182                 break;
183         case WIDGET_BUFFER_EVENT_ON_SCROLL:
184                 flags = evas_event_default_flags_get(info->e);
185                 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
186                 evas_event_default_flags_set(info->e, flags);
187                 break;
188         case WIDGET_BUFFER_EVENT_OFF_SCROLL:
189                 flags = evas_event_default_flags_get(info->e);
190                 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
191                 evas_event_default_flags_set(info->e, flags);
192                 break;
193         case WIDGET_BUFFER_EVENT_ENTER:
194                 evas_event_feed_mouse_in(info->e, timestamp, NULL);
195                 break;
196         case WIDGET_BUFFER_EVENT_LEAVE:
197                 evas_event_feed_mouse_out(info->e, timestamp, NULL);
198                 break;
199         case WIDGET_BUFFER_EVENT_DOWN:
200                 apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, event_info->info.pointer.source);
201
202                 if (info->pressed) {
203                         ErrPrint("MOUSE UP is not called\n");
204                         ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
205                         evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
206                         evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
207                 }
208
209                 /**
210                  * @note
211                  * Before processing the DOWN event,
212                  * Reset the evas event flags regarding ON_HOLD option.
213                  * It can be re-enabled while processing down-move-up events.
214                  */
215                 flags = evas_event_default_flags_get(info->e);
216                 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
217                 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
218                 evas_event_default_flags_set(info->e, flags);
219                 /**
220                  * @note
221                  * Calculate the event occurred X & Y on the buffer
222                  */
223                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
224                 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
225                 info->pressed = 1;
226                 ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
227                 break;
228         case WIDGET_BUFFER_EVENT_MOVE:
229                 apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, event_info->info.pointer.source);
230                 /**
231                  * @note
232                  * Calculate the event occurred X & Y on the buffer
233                  */
234                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
235                 break;
236         case WIDGET_BUFFER_EVENT_UP:
237                 apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, event_info->info.pointer.source);
238                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
239                 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
240                 info->pressed = 0;
241                 /**
242                  * @note
243                  * We have to keep the event flags, so we should not clear them from here.
244                  * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
245                  * so if we reset them from here, those kind of callbacks will fails to do their job properly.
246                  */
247                 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
248                 break;
249         case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
250                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
251                 if (!parent_elm) {
252                         ret = WIDGET_ACCESS_STATUS_ERROR;
253                         break;
254                 }
255                 memset(&action_info, 0, sizeof(action_info));
256                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
257                 /**
258                  * @note
259                  * Calculate the event occurred X & Y on the buffer
260                  */
261                 action_info.x = event_info->info.access.x;
262                 action_info.y = event_info->info.access.y;
263                 ret = elm_access_action(parent_elm, action_type, &action_info);
264                 if (ret == EINA_TRUE) {
265                         if (!get_highlighted_object(parent_elm)) {
266                                 ErrPrint("Highlighted object is not found\n");
267                                 ret = WIDGET_ACCESS_STATUS_ERROR;
268                         } else {
269                                 DbgPrint("Highlighted object is found\n");
270                                 ret = WIDGET_ACCESS_STATUS_DONE;
271                         }
272                 } else {
273                         ErrPrint("Action error\n");
274                         ret = WIDGET_ACCESS_STATUS_ERROR;
275                 }
276                 break;
277         case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
278                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
279                 if (!parent_elm) {
280                         ret = WIDGET_ACCESS_STATUS_ERROR;
281                         break;
282                 }
283                 memset(&action_info, 0, sizeof(action_info));
284                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
285                 action_info.highlight_cycle = EINA_FALSE;
286                 ret = elm_access_action(parent_elm, action_type, &action_info);
287                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
288                 break;
289         case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
290                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
291                 if (!parent_elm) {
292                         ret = WIDGET_ACCESS_STATUS_ERROR;
293                         break;
294                 }
295                 memset(&action_info, 0, sizeof(action_info));
296                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
297                 action_info.highlight_cycle = EINA_FALSE;
298                 ret = elm_access_action(parent_elm, action_type, &action_info);
299                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
300                 break;
301         case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
302                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
303                 if (!parent_elm) {
304                         ret = WIDGET_ACCESS_STATUS_ERROR;
305                         break;
306                 }
307                 memset(&action_info, 0, sizeof(action_info));
308                 action_type = ELM_ACCESS_ACTION_ACTIVATE;
309                 ret = elm_access_action(parent_elm, action_type, &action_info);
310                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
311                 break;
312         case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
313                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
314                 if (!parent_elm) {
315                         ret = WIDGET_ACCESS_STATUS_ERROR;
316                         break;
317                 }
318                 memset(&action_info, 0, sizeof(action_info));
319                 action_type = ELM_ACCESS_ACTION_UP;
320                 ret = elm_access_action(parent_elm, action_type, &action_info);
321                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
322                 break;
323         case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
324                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
325                 if (!parent_elm) {
326                         ret = WIDGET_ACCESS_STATUS_ERROR;
327                         break;
328                 }
329                 memset(&action_info, 0, sizeof(action_info));
330                 action_type = ELM_ACCESS_ACTION_DOWN;
331                 ret = elm_access_action(parent_elm, action_type, &action_info);
332                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
333                 break;
334         case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
335                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
336                 if (!parent_elm) {
337                         ret = WIDGET_ACCESS_STATUS_ERROR;
338                         break;
339                 }
340                 memset(&action_info, 0, sizeof(action_info));
341                 action_type = ELM_ACCESS_ACTION_SCROLL;
342                 action_info.x = event_info->info.access.x;
343                 action_info.y = event_info->info.access.y;
344                 action_info.mouse_type = event_info->info.access.mouse_type;
345                 ret = elm_access_action(parent_elm, action_type, &action_info);
346                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
347                 break;
348         case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
349                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
350                 if (!parent_elm) {
351                         ret = WIDGET_ACCESS_STATUS_ERROR;
352                         break;
353                 }
354                 memset(&action_info, 0, sizeof(action_info));
355                 action_type = ELM_ACCESS_ACTION_SCROLL;
356                 action_info.x = event_info->info.access.x;
357                 action_info.y = event_info->info.access.y;
358                 action_info.mouse_type = event_info->info.access.mouse_type;
359                 ret = elm_access_action(parent_elm, action_type, &action_info);
360                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
361                 break;
362         case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
363                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
364                 if (!parent_elm) {
365                         ret = WIDGET_ACCESS_STATUS_ERROR;
366                         break;
367                 }
368                 memset(&action_info, 0, sizeof(action_info));
369                 action_type = ELM_ACCESS_ACTION_SCROLL;
370                 action_info.x = event_info->info.access.x;
371                 action_info.y = event_info->info.access.y;
372                 action_info.mouse_type = event_info->info.access.mouse_type;
373                 ret = elm_access_action(parent_elm, action_type, &action_info);
374                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
375                 break;
376         case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
377                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
378                 if (!parent_elm) {
379                         ret = WIDGET_ACCESS_STATUS_ERROR;
380                         break;
381                 }
382                 memset(&action_info, 0, sizeof(action_info));
383                 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
384                 ret = elm_access_action(parent_elm, action_type, &action_info);
385                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
386                 break;
387         case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
388                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
389                 if (!parent_elm) {
390                         ret = WIDGET_ACCESS_STATUS_ERROR;
391                         break;
392                 }
393                 memset(&action_info, 0, sizeof(action_info));
394                 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
395                 action_info.x = event_info->info.access.x;
396                 action_info.y = event_info->info.access.y;
397                 action_info.mouse_type = event_info->info.access.mouse_type;
398                 ret = elm_access_action(parent_elm, action_type, &action_info);
399                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
400                 break;
401         case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
402                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
403                 if (!parent_elm) {
404                         ret = WIDGET_ACCESS_STATUS_ERROR;
405                         break;
406                 }
407                 memset(&action_info, 0, sizeof(action_info));
408                 action_type = ELM_ACCESS_ACTION_MOUSE;
409                 action_info.x = event_info->info.access.x;
410                 action_info.y = event_info->info.access.y;
411                 action_info.mouse_type = event_info->info.access.mouse_type;
412                 ret = elm_access_action(parent_elm, action_type, &action_info);
413                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
414                 break;
415         case WIDGET_BUFFER_EVENT_ACCESS_BACK:
416                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
417                 if (!parent_elm) {
418                         ret = WIDGET_ACCESS_STATUS_ERROR;
419                         break;
420                 }
421                 memset(&action_info, 0, sizeof(action_info));
422                 action_type = ELM_ACCESS_ACTION_BACK;
423                 action_info.x = event_info->info.access.x;
424                 action_info.y = event_info->info.access.y;
425                 action_info.mouse_type = event_info->info.access.mouse_type;
426                 ret = elm_access_action(parent_elm, action_type, &action_info);
427                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
428                 break;
429         case WIDGET_BUFFER_EVENT_ACCESS_OVER:
430                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
431                 if (!parent_elm) {
432                         ret = WIDGET_ACCESS_STATUS_ERROR;
433                         break;
434                 }
435                 memset(&action_info, 0, sizeof(action_info));
436                 action_type = ELM_ACCESS_ACTION_OVER;
437                 action_info.x = event_info->info.access.x;
438                 action_info.y = event_info->info.access.y;
439                 action_info.mouse_type = event_info->info.access.mouse_type;
440                 ret = elm_access_action(parent_elm, action_type, &action_info);
441                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
442                 break;
443         case WIDGET_BUFFER_EVENT_ACCESS_READ:
444                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
445                 if (!parent_elm) {
446                         ret = WIDGET_ACCESS_STATUS_ERROR;
447                         break;
448                 }
449                 memset(&action_info, 0, sizeof(action_info));
450                 action_type = ELM_ACCESS_ACTION_READ;
451                 action_info.x = event_info->info.access.x;
452                 action_info.y = event_info->info.access.y;
453                 action_info.mouse_type = event_info->info.access.mouse_type;
454                 ret = elm_access_action(parent_elm, action_type, &action_info);
455                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
456                 break;
457         case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
458                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
459                 if (!parent_elm) {
460                         ret = WIDGET_ACCESS_STATUS_ERROR;
461                         break;
462                 }
463                 memset(&action_info, 0, sizeof(action_info));
464                 action_type = ELM_ACCESS_ACTION_ENABLE;
465                 action_info.x = event_info->info.access.x;
466                 action_info.y = event_info->info.access.y;
467                 action_info.mouse_type = event_info->info.access.mouse_type;
468                 ret = elm_access_action(parent_elm, action_type, &action_info);
469                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
470                 break;
471         case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
472                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
473                 if (!parent_elm) {
474                         ret = WIDGET_ACCESS_STATUS_ERROR;
475                         break;
476                 }
477                 memset(&action_info, 0, sizeof(action_info));
478                 action_type = ELM_ACCESS_ACTION_DISABLE;
479                 action_info.x = event_info->info.access.x;
480                 action_info.y = event_info->info.access.y;
481                 action_info.mouse_type = event_info->info.access.mouse_type;
482                 ret = elm_access_action(parent_elm, action_type, &action_info);
483                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
484                 break;
485         case WIDGET_BUFFER_EVENT_KEY_DOWN:
486                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
487                 if (!parent_elm) {
488                         ret = WIDGET_ACCESS_STATUS_ERROR;
489                         break;
490                 }
491
492                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
493                 if (key_symbol) {
494                         char *key_name;
495                         char *key_string;
496
497                         key_string = XKeysymToString(*key_symbol);
498                         key_name = XKeysymToString(*key_symbol);
499                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
500                         XFree(key_symbol);
501                         XFree(key_name);
502                         XFree(key_string);
503                 }
504                 ret = WIDGET_KEY_STATUS_ERROR;
505                 break;
506         case WIDGET_BUFFER_EVENT_KEY_UP:
507                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
508                 if (!parent_elm) {
509                         ret = WIDGET_ACCESS_STATUS_ERROR;
510                         break;
511                 }
512
513                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
514                 if (key_symbol) {
515                         char *key_name;
516                         char *key_string;
517
518                         key_string = XKeysymToString(*key_symbol);
519                         key_name = XKeysymToString(*key_symbol);
520                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
521                         XFree(key_symbol);
522                         XFree(key_name);
523                         XFree(key_string);
524                 }
525                 ret = WIDGET_KEY_STATUS_ERROR;
526                 break;
527         case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
528                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
529                 if (!parent_elm) {
530                         ret = WIDGET_ACCESS_STATUS_ERROR;
531                         break;
532                 }
533
534                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
535                 if (key_symbol) {
536                         char *key_name;
537                         char *key_string;
538
539                         key_string = XKeysymToString(*key_symbol);
540                         key_name = XKeysymToString(*key_symbol);
541                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
542                         XFree(key_symbol);
543                         XFree(key_name);
544                         XFree(key_string);
545                 }
546                 ret = WIDGET_KEY_STATUS_ERROR;
547                 break;
548         case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
549                 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
550                 if (!parent_elm) {
551                         ret = WIDGET_ACCESS_STATUS_ERROR;
552                         break;
553                 }
554
555                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
556                 if (key_symbol) {
557                         char *key_name;
558                         char *key_string;
559
560                         key_string = XKeysymToString(*key_symbol);
561                         key_name = XKeysymToString(*key_symbol);
562                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
563                         XFree(key_symbol);
564                         XFree(key_name);
565                         XFree(key_string);
566                 }
567                 ret = WIDGET_KEY_STATUS_ERROR;
568                 break;
569         default:
570                 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
571                 break;
572         }
573
574         return ret;
575 }
576
577 static void pre_render_cb(void *data, Evas *e, void *event_info)
578 {
579         vwin_info_t info = data;
580
581         if (!info->handle) {
582                 return;
583         }
584
585         if (widget_conf_premultiplied_alpha()) {
586                 Evas_Coord w;
587                 Evas_Coord h;
588
589                 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
590                 evas_damage_rectangle_add(e, 0, 0, w, h);
591         }
592
593         if (info->type == VWIN_GEM) {
594                 widget_buffer_pre_render(info->handle);
595         } else if (info->type == VWIN_PIXMAP) {
596                 /**
597                  * Only the pixmap type Ecore_Evas uses this variable
598                  */
599         } else if (info->type == VWIN_SW_BUF) {
600                 /* Do nothing */
601         }
602 }
603
604 static void post_render_cb(void *data, Evas *e, void *event_info)
605 {
606         vwin_info_t info = data;
607
608         if (!info->handle) {
609                 return;
610         }
611
612         if (widget_conf_premultiplied_alpha()) {
613                 void *canvas;
614                 int x, y, w, h;
615
616                 // Get a pointer of a buffer of the virtual canvas
617                 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
618                 if (!canvas) {
619                         ErrPrint("Failed to get pixel canvas\n");
620                         return;
621                 }
622
623                 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
624                 evas_data_argb_unpremul(canvas, w * h);
625         }
626
627         if (info->type == VWIN_GEM) {
628                 widget_buffer_post_render(info->handle);
629         } else if (info->type == VWIN_PIXMAP) {
630                 int idx;
631                 unsigned int front_resource_id;
632
633                 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
634
635                 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
636                         if (front_resource_id == info->resource_array[idx]) {
637                                 /**
638                                  */
639                                 widget_send_updated_by_idx(info->handle, idx);
640                                 break;
641                         }
642                 }
643
644                 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
645                         /* Send updated event for PRIMARY BUFFER */
646                         if (front_resource_id == widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER)) {
647                                 widget_send_updated_by_idx(info->handle, WIDGET_PRIMARY_BUFFER);
648                         } else {
649                                 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER));
650                         }
651                 }
652         } else if (info->type == VWIN_SW_BUF) {
653                 widget_viewer_sync_buffer(info->handle);
654         }
655 }
656
657 static int pre_orientation_cb(const char *id, void *data)
658 {
659         vwin_info_t info = data;
660         const char *path;
661         int orientation;
662
663         /* Try provider_app first */
664         if (!id) {
665                 return WIDGET_ERROR_INVALID_PARAMETER;
666         }
667
668         path = widget_util_uri_to_path(id);
669         if (path && strcmp(info->id, path)) {
670                 /* Skip */
671                 DbgPrint("SKIP: Pre orientation event callback is called [%s], %s\n", id, info->id);
672                 return WIDGET_ERROR_INVALID_PARAMETER;
673         }
674
675         DbgPrint("Pre orientation event callback is called [%s]\n", id);
676         orientation = widget_get_orientation(path);
677         if (orientation < 0) {
678                 ErrPrint("Failed to get orientation: %X\n", orientation);
679         } else {
680                 info->orientation = orientation;
681         }
682
683         return WIDGET_ERROR_NONE;
684 }
685
686 static int pre_destroy_cb(const char *id, void *data)
687 {
688         vwin_info_t info = data;
689         const char *path = NULL;
690
691         if (id) {
692                 path = widget_util_uri_to_path(id);
693
694                 if (path && strcmp(info->id, path)) {
695                         /* Skip */
696                         DbgPrint("SKIP: Pre destroy event callback is called [%s], %s\n", id, info->id);
697                         return WIDGET_ERROR_INVALID_PARAMETER;
698                 }
699         }
700
701         DbgPrint("Pre destroy event callback is called [%s]\n", id);
702
703         if (info->ee) {
704                 DbgPrint("Toggle manual render mode to prevent from unwanted rendering");
705                 ecore_evas_manual_render_set(info->ee, EINA_TRUE);
706         }
707
708         return WIDGET_ERROR_NONE;
709 }
710
711 static void ecore_evas_free_cb(Ecore_Evas *ee)
712 {
713         vwin_info_t info;
714
715         info = ecore_evas_data_get(ee, "dynamic,box,info");
716         if (!info) {
717                 DbgPrint("Info is not valid\n");
718                 return;
719         }
720
721         widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
722
723         if (info->e) {
724                 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
725                 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
726         }
727
728         info->deleted = 1;
729         info->ee = NULL;
730 }
731
732 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
733 PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
734 #else /* WIDGET_FEATURE_GBAR_SUPPORTED */
735 PUBLIC Evas *widget_get_evas(const char *id)
736 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
737 {
738         vwin_info_t info;
739         int orientation;
740
741         /**
742          * @TODO
743          * If the evas object is already created,
744          * this function should returns ERROR.
745          */
746
747         if (!id) {
748                 ErrPrint("Invalid parameter\n");
749                 return NULL;
750         }
751
752         info = calloc(1, sizeof(*info));
753         if (!info) {
754                 ErrPrint("Heap: %d\n", errno);
755                 return NULL;
756         }
757
758         info->id = strdup(id);
759         if (!info->id) {
760                 ErrPrint("Heap: %d\n", errno);
761                 free(info);
762                 return NULL;
763         }
764
765 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
766         info->is_gbar = is_gbar;
767 #else
768         info->is_gbar = 0;
769 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
770
771         /**
772          * Acquire a buffer for canvas.
773          */
774         info->handle = widget_create_buffer(info->id, info->is_gbar,
775                         binder_widget_auto_align(),
776                         event_handler_cb, info);
777
778         if (!info->handle) {
779                 ErrPrint("Failed to create a widget buffer\n");
780                 free(info->id);
781                 free(info);
782                 return NULL;
783         }
784
785         /**
786          * Size information must be initialized before call the ecore_evas_buffer_new.
787          */
788         info->w = WIDGET_DEFAULT_WIDTH;
789         info->h = WIDGET_DEFAULT_HEIGHT;
790
791         info->ee = binder_ecore_evas_new(info);
792         if (!info->ee) {
793                 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
794                 widget_destroy_buffer(info->handle);
795                 free(info->id);
796                 free(info);
797                 return NULL;
798         }
799
800         ecore_evas_data_set(info->ee, "dynamic,box,info", info);
801
802         /**
803          * @note
804          * Free callback must be prepared before use the ecore_evas_free()
805          */
806         ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
807
808         info->e = ecore_evas_get(info->ee);
809         if (!info->e) {
810                 ErrPrint("Failed to get evas\n");
811                 ecore_evas_free(info->ee);
812                 return NULL;
813         }
814
815         pre_render_cb(info, NULL, NULL);
816         ecore_evas_alpha_set(info->ee, EINA_TRUE);
817         post_render_cb(info, NULL, NULL);
818
819         ecore_evas_manual_render_set(info->ee, EINA_FALSE);
820         ecore_evas_resize(info->ee, info->w, info->h);
821
822         evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
823         evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
824
825         widget_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
826         widget_add_pre_callback(WIDGET_PRE_ORIENTATION_CALLBACK, pre_orientation_cb, info);
827
828         orientation = widget_get_orientation(info->id);
829         if (orientation < 0) {
830                 ErrPrint("Failed to get orientation[%s]: %X\n", info->id, orientation);
831         } else {
832                 info->orientation = orientation;
833         }
834
835         return info->e;
836 }
837
838 /* End of a file */