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