2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
19 #include <Elementary.h>
21 #include <Ecore_Evas.h>
29 #include <sys/types.h>
35 #include <widget_errno.h>
36 #include <widget_service.h>
37 #include <widget_service_internal.h>
38 #include <widget_conf.h>
39 #include <widget_buffer.h>
40 #include <widget_provider.h>
41 #include <widget_provider_buffer.h>
42 #include <widget_util.h>
46 #include "widget_internal.h"
52 #define PUBLIC __attribute__((visibility("default")))
53 #define WIDGET_WIN_TAG "dynamic,box,win"
54 #define WIN_INFO_TAG "dynamic,box,info"
56 #define WIDGET_DEFAULT_WIDTH 1
57 #define WIDGET_DEFAULT_HEIGHT 1
59 #define MOUSE_BUTTON_LEFT 1
63 * Supported touch devices are limited to 32.
64 * Because of count of bits of integer type. (32 bits)
68 #define IS_PRESSED(info, device) (((device) < MAX_DEVICE) ? (((info)->pressed & (0x01 << (device))) == (0x01 << (device))) : 0)
74 #define SET_PRESSED(info, device) ((void)(((device) < MAX_DEVICE) && (((info)->pressed |= (0x01 << (device))))))
75 #define SET_RELEASED(info, device) ((void)(((device) < MAX_DEVICE) && (((info)->pressed &= (~(0x01 << (device)))))))
77 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
81 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
84 ho = evas_object_data_get(o, "_elm_access_target");
88 static inline void apply_orientation(int degree, int *x, int *y, int width, int height, input_event_source_e source)
94 if (source == INPUT_EVENT_SOURCE_VIEWER) {
120 * This rotation formular is not work correctly.
121 * The pointer should be rotated by other way.
122 * This is not what we want.
126 *x = (double)_x * cos((double)_angle) - (double)_y * sin((double)_angle);
127 *y = (double)_x * sin((double)_angle) + (double)_y * cos((double)_angle);
132 static inline int processing_events(vwin_info_t info, widget_buffer_event_data_t event_info, double timestamp)
134 Elm_Access_Action_Info action_info;
135 Elm_Access_Action_Type action_type;
136 Evas_Object *parent_elm;
138 unsigned int flags = 0;
144 switch (event_info->type) {
145 case WIDGET_BUFFER_EVENT_ON_HOLD:
146 flags = evas_event_default_flags_get(info->e);
147 flags |= EVAS_EVENT_FLAG_ON_HOLD;
148 evas_event_default_flags_set(info->e, flags);
149 ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
150 if (info->pressed == 0) {
151 info->flags.field.on_hold_before_down = 1;
154 case WIDGET_BUFFER_EVENT_OFF_HOLD:
155 flags = evas_event_default_flags_get(info->e);
156 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
157 evas_event_default_flags_set(info->e, flags);
159 case WIDGET_BUFFER_EVENT_ON_SCROLL:
160 flags = evas_event_default_flags_get(info->e);
161 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
162 evas_event_default_flags_set(info->e, flags);
163 if (info->pressed == 0) {
164 info->flags.field.on_scroll_before_down = 1;
167 case WIDGET_BUFFER_EVENT_OFF_SCROLL:
168 flags = evas_event_default_flags_get(info->e);
169 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
170 evas_event_default_flags_set(info->e, flags);
172 case WIDGET_BUFFER_EVENT_ENTER:
173 evas_event_feed_mouse_in(info->e, timestamp, NULL);
175 case WIDGET_BUFFER_EVENT_LEAVE:
176 evas_event_feed_mouse_out(info->e, timestamp, NULL);
178 case WIDGET_BUFFER_EVENT_DOWN:
179 apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, info->w, info->h, event_info->info.pointer.source);
181 if (IS_PRESSED(info, event_info->info.pointer.device)) {
182 ErrPrint("MOUSE UP is not called\n");
183 ErrPrint("UP[%s] %dx%d - %lf (%d)\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, event_info->info.pointer.device);
184 if (event_info->info.pointer.device > 0) {
188 evas_event_feed_multi_up(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
189 0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
190 0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
191 EVAS_BUTTON_NONE, timestamp, NULL); /* button_flags, timestamp, ... */
193 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
194 evas_event_feed_mouse_up(info->e, MOUSE_BUTTON_LEFT, EVAS_BUTTON_NONE, timestamp, NULL);
200 * Before processing the DOWN event,
201 * Reset the evas event flags regarding ON_HOLD option.
202 * It can be re-enabled while processing down-move-up events.
203 * However if those events are occurred right before DOWN,
205 * Some speicific cases, the ON_HOLD(ON_SCROLL) event can be delievered
206 * before MOUSE_DOWN event.
208 flags = evas_event_default_flags_get(info->e);
209 if (!info->flags.field.on_hold_before_down) {
210 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
212 if (!info->flags.field.on_scroll_before_down) {
213 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
215 evas_event_default_flags_set(info->e, flags);
219 * Reset flags after dealing with the ON_HOLD/ON_SCROLL event
221 info->flags.field.on_scroll_before_down = 0;
222 info->flags.field.on_hold_before_down = 0;
225 * Calculate the event occurred X & Y on the buffer
227 if (event_info->info.pointer.device > 0) {
228 evas_event_feed_multi_down(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
229 0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
230 0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
231 EVAS_BUTTON_NONE, timestamp, NULL); /* button_flags, timestamp, ... */
233 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
234 evas_event_feed_mouse_down(info->e, MOUSE_BUTTON_LEFT, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
237 SET_PRESSED(info, event_info->info.pointer.device);
238 ErrPrint("DOWN[%s] %dx%d - %lf (%d)\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, event_info->info.pointer.device);
240 case WIDGET_BUFFER_EVENT_MOVE:
241 apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, info->w, info->h, event_info->info.pointer.source);
244 * Calculate the event occurred X & Y on the buffer
246 if (event_info->info.pointer.device > 0) {
247 evas_event_feed_multi_move(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
248 0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
249 0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
250 timestamp, NULL); /* timestamp, ... */
252 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
255 case WIDGET_BUFFER_EVENT_UP:
256 apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, info->w, info->h, event_info->info.pointer.source);
258 if (event_info->info.pointer.device > 0) {
259 evas_event_feed_multi_up(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
260 0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
261 0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
262 EVAS_BUTTON_NONE, timestamp, NULL); /* button_flags, timestamp, ... */
264 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
265 evas_event_feed_mouse_up(info->e, MOUSE_BUTTON_LEFT, EVAS_BUTTON_NONE, timestamp, NULL);
267 SET_RELEASED(info, event_info->info.pointer.device);
270 * We have to keep the event flags, so we should not clear them from here.
271 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
272 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
274 ErrPrint("UP[%s] %dx%d - %lf (%d)\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, event_info->info.pointer.device);
276 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
277 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
279 ret = WIDGET_ACCESS_STATUS_ERROR;
282 memset(&action_info, 0, sizeof(action_info));
283 action_type = 0; //ELM_ACCESS_ACTION_HIGHLIGHT;
286 * Calculate the event occurred X & Y on the buffer
288 action_info.x = event_info->info.access.x;
289 action_info.y = event_info->info.access.y;
290 ret = elm_access_action(parent_elm, action_type, &action_info);
291 if (ret == EINA_TRUE) {
292 if (!get_highlighted_object(parent_elm)) {
293 ErrPrint("Highlighted object is not found\n");
294 ret = WIDGET_ACCESS_STATUS_ERROR;
296 DbgPrint("Highlighted object is found\n");
297 ret = WIDGET_ACCESS_STATUS_DONE;
300 ErrPrint("Action error\n");
301 ret = WIDGET_ACCESS_STATUS_ERROR;
304 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
305 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
307 ret = WIDGET_ACCESS_STATUS_ERROR;
310 memset(&action_info, 0, sizeof(action_info));
311 action_type = 0; //ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
312 action_info.highlight_cycle = EINA_FALSE;
313 ret = elm_access_action(parent_elm, action_type, &action_info);
314 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
316 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
317 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
319 ret = WIDGET_ACCESS_STATUS_ERROR;
322 memset(&action_info, 0, sizeof(action_info));
323 action_type = 0; //ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
324 action_info.highlight_cycle = EINA_FALSE;
325 ret = elm_access_action(parent_elm, action_type, &action_info);
326 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
328 case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
329 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
331 ret = WIDGET_ACCESS_STATUS_ERROR;
334 memset(&action_info, 0, sizeof(action_info));
335 action_type = 0; //ELM_ACCESS_ACTION_ACTIVATE;
336 ret = elm_access_action(parent_elm, action_type, &action_info);
337 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
339 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
340 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
342 ret = WIDGET_ACCESS_STATUS_ERROR;
345 memset(&action_info, 0, sizeof(action_info));
346 action_type = 0; //ELM_ACCESS_ACTION_UP;
347 ret = elm_access_action(parent_elm, action_type, &action_info);
348 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
350 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
351 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
353 ret = WIDGET_ACCESS_STATUS_ERROR;
356 memset(&action_info, 0, sizeof(action_info));
357 action_type = 0; //ELM_ACCESS_ACTION_DOWN;
358 ret = elm_access_action(parent_elm, action_type, &action_info);
359 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
361 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
362 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
364 ret = WIDGET_ACCESS_STATUS_ERROR;
367 memset(&action_info, 0, sizeof(action_info));
368 action_type = 0; //ELM_ACCESS_ACTION_SCROLL;
369 action_info.x = event_info->info.access.x;
370 action_info.y = event_info->info.access.y;
371 action_info.mouse_type = event_info->info.access.mouse_type;
372 ret = elm_access_action(parent_elm, action_type, &action_info);
373 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
375 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
376 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
378 ret = WIDGET_ACCESS_STATUS_ERROR;
381 memset(&action_info, 0, sizeof(action_info));
382 action_type = 0; //ELM_ACCESS_ACTION_SCROLL;
383 action_info.x = event_info->info.access.x;
384 action_info.y = event_info->info.access.y;
385 action_info.mouse_type = event_info->info.access.mouse_type;
386 ret = elm_access_action(parent_elm, action_type, &action_info);
387 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
389 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
390 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
392 ret = WIDGET_ACCESS_STATUS_ERROR;
395 memset(&action_info, 0, sizeof(action_info));
396 action_type = 0; //ELM_ACCESS_ACTION_SCROLL;
397 action_info.x = event_info->info.access.x;
398 action_info.y = event_info->info.access.y;
399 action_info.mouse_type = event_info->info.access.mouse_type;
400 ret = elm_access_action(parent_elm, action_type, &action_info);
401 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
403 case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
404 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
406 ret = WIDGET_ACCESS_STATUS_ERROR;
409 memset(&action_info, 0, sizeof(action_info));
410 action_type = 0; //ELM_ACCESS_ACTION_UNHIGHLIGHT;
411 ret = elm_access_action(parent_elm, action_type, &action_info);
412 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
414 case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
415 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
417 ret = WIDGET_ACCESS_STATUS_ERROR;
420 memset(&action_info, 0, sizeof(action_info));
421 action_type = 0; //ELM_ACCESS_ACTION_VALUE_CHANGE;
422 action_info.x = event_info->info.access.x;
423 action_info.y = event_info->info.access.y;
424 action_info.mouse_type = event_info->info.access.mouse_type;
425 ret = elm_access_action(parent_elm, action_type, &action_info);
426 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
428 case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
429 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
431 ret = WIDGET_ACCESS_STATUS_ERROR;
434 memset(&action_info, 0, sizeof(action_info));
435 action_type = 0; //ELM_ACCESS_ACTION_MOUSE;
436 action_info.x = event_info->info.access.x;
437 action_info.y = event_info->info.access.y;
438 action_info.mouse_type = event_info->info.access.mouse_type;
439 ret = elm_access_action(parent_elm, action_type, &action_info);
440 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
442 case WIDGET_BUFFER_EVENT_ACCESS_BACK:
443 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
445 ret = WIDGET_ACCESS_STATUS_ERROR;
448 memset(&action_info, 0, sizeof(action_info));
449 action_type = 0; //ELM_ACCESS_ACTION_BACK;
450 action_info.x = event_info->info.access.x;
451 action_info.y = event_info->info.access.y;
452 action_info.mouse_type = event_info->info.access.mouse_type;
453 ret = elm_access_action(parent_elm, action_type, &action_info);
454 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
456 case WIDGET_BUFFER_EVENT_ACCESS_OVER:
457 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
459 ret = WIDGET_ACCESS_STATUS_ERROR;
462 memset(&action_info, 0, sizeof(action_info));
463 action_type = 0; //ELM_ACCESS_ACTION_OVER;
464 action_info.x = event_info->info.access.x;
465 action_info.y = event_info->info.access.y;
466 action_info.mouse_type = event_info->info.access.mouse_type;
467 ret = elm_access_action(parent_elm, action_type, &action_info);
468 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
470 case WIDGET_BUFFER_EVENT_ACCESS_READ:
471 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
473 ret = WIDGET_ACCESS_STATUS_ERROR;
476 memset(&action_info, 0, sizeof(action_info));
477 action_type = 0; //ELM_ACCESS_ACTION_READ;
478 action_info.x = event_info->info.access.x;
479 action_info.y = event_info->info.access.y;
480 action_info.mouse_type = event_info->info.access.mouse_type;
481 ret = elm_access_action(parent_elm, action_type, &action_info);
482 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
484 case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
485 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
487 ret = WIDGET_ACCESS_STATUS_ERROR;
490 memset(&action_info, 0, sizeof(action_info));
491 action_type = 0; //ELM_ACCESS_ACTION_ENABLE;
492 action_info.x = event_info->info.access.x;
493 action_info.y = event_info->info.access.y;
494 action_info.mouse_type = event_info->info.access.mouse_type;
495 ret = elm_access_action(parent_elm, action_type, &action_info);
496 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
498 case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
499 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
501 ret = WIDGET_ACCESS_STATUS_ERROR;
504 memset(&action_info, 0, sizeof(action_info));
505 action_type = 0; //ELM_ACCESS_ACTION_DISABLE;
506 action_info.x = event_info->info.access.x;
507 action_info.y = event_info->info.access.y;
508 action_info.mouse_type = event_info->info.access.mouse_type;
509 ret = elm_access_action(parent_elm, action_type, &action_info);
510 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
512 case WIDGET_BUFFER_EVENT_KEY_DOWN:
513 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
515 ret = WIDGET_ACCESS_STATUS_ERROR;
519 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
524 key_string = XKeysymToString(*key_symbol);
525 key_name = XKeysymToString(*key_symbol);
526 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
531 ret = WIDGET_KEY_STATUS_ERROR;
533 case WIDGET_BUFFER_EVENT_KEY_UP:
534 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
536 ret = WIDGET_ACCESS_STATUS_ERROR;
540 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
545 key_string = XKeysymToString(*key_symbol);
546 key_name = XKeysymToString(*key_symbol);
547 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
552 ret = WIDGET_KEY_STATUS_ERROR;
554 case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
555 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
557 ret = WIDGET_ACCESS_STATUS_ERROR;
561 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
566 key_string = XKeysymToString(*key_symbol);
567 key_name = XKeysymToString(*key_symbol);
568 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
573 ret = WIDGET_KEY_STATUS_ERROR;
575 case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
576 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
578 ret = WIDGET_ACCESS_STATUS_ERROR;
582 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
587 key_string = XKeysymToString(*key_symbol);
588 key_name = XKeysymToString(*key_symbol);
589 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
594 ret = WIDGET_KEY_STATUS_ERROR;
597 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
604 static Eina_Bool pended_event_consumer_cb(void *data)
606 vwin_info_t info = data;
607 widget_buffer_event_data_t event_info;
609 event_info = eina_list_nth(info->pended_events_list, 0);
611 info->pended_events_consumer = NULL;
612 return ECORE_CALLBACK_CANCEL;
615 DbgPrint("Consuming delayed events\n");
616 (void)processing_events(info, event_info, event_info->timestamp);
618 info->pended_events_list = eina_list_remove(info->pended_events_list, event_info);
620 return ECORE_CALLBACK_RENEW;
625 * Every user event (mouse) on the buffer will be passed via this event callback
627 static int event_handler_cb(widget_buffer_h handler, widget_buffer_event_data_t event_info, void *data)
629 vwin_info_t info = data;
634 * If the feeds event is accessibility or key event,
635 * "return 0" will confusing the viewer,
636 * because it will waiting result of event processing to do handles state properly.
639 if (!info || info->state != VWIN_INFO_CREATED || !info->handle || info->flags.field.deleted) {
640 /* Just ignore this event */
644 if (event_info->type == WIDGET_BUFFER_EVENT_FRAME_SKIP_CLEARED) {
646 * Increase the count_of_rendering only if it meets conditions.
647 * Or do not increase it to prevent from overflow problem.
648 * If we trying to increase the count_of_rendering variable, it could be overflowed.
649 * These conditions will prevents count_of_rendering from overflow issue.
651 if (info->pended_events_list && !info->pended_events_consumer) {
652 info->pended_events_consumer = ecore_timer_add(0.0001f, pended_event_consumer_cb, info);
653 if (info->pended_events_consumer) {
654 ErrPrint("Failed to create a pended event consumer\n");
661 if (WIDGET_CONF_USE_GETTIMEOFDAY) {
662 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
665 if (gettimeofday(&tv, NULL) < 0) {
666 ErrPrint("gettimeofday: %d\n", errno);
668 timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
669 timestamp -= event_info->timestamp;
671 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
672 DbgPrint("Dropped %lf\n", timestamp);
679 * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
680 * Evas only use the monotic time for animating objects
682 timestamp = ecore_time_get() * 1000.0f;
684 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
685 timestamp = ecore_time_get();
687 timestamp -= event_info->timestamp;
688 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
689 DbgPrint("Dropped %lf\n", timestamp);
694 timestamp = event_info->timestamp * 1000.0f;
697 if ((info->w <= 1 && info->h <= 1) || widget_provider_buffer_frame_skip(info->handle) > 0 || info->pended_events_list) {
698 widget_buffer_event_data_t _ev_info;
699 _ev_info = malloc(sizeof(*_ev_info));
701 memcpy(_ev_info, event_info, sizeof(*_ev_info));
702 info->pended_events_list = eina_list_append(info->pended_events_list, _ev_info);
703 _ev_info->timestamp = timestamp;
706 * Push events to pending list,.
707 * Consuming it first.
709 DbgPrint("Canvas is not prepared. pending the events (%dx%d)\n", info->w, info->h);
712 ErrPrint("malloc: %d\n", errno);
716 return processing_events(info, event_info, timestamp);
719 static void pre_render_cb(void *data, Evas *e, void *event_info)
721 vwin_info_t info = data;
723 if (!info || info->state != VWIN_INFO_CREATED || !info->handle) {
727 if (WIDGET_CONF_PREMULTIPLIED_COLOR) {
731 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
732 evas_damage_rectangle_add(e, 0, 0, w, h);
735 if (info->type == VWIN_GEM) {
736 widget_buffer_pre_render(info->handle);
737 } else if (info->type == VWIN_PIXMAP) {
739 * Only the pixmap type Ecore_Evas uses this variable
741 } else if (info->type == VWIN_SW_BUF) {
746 static inline void dump_to_file(void *buffer, int size, const char *fname)
750 fd = open(fname, O_WRONLY | O_CREAT, 0644);
752 if (write(fd, buffer, size) != size) {
753 ErrPrint("write: %d\n", errno);
757 ErrPrint("close: %d\n", errno);
762 static void post_render_cb(void *data, Evas *e, void *event_info)
764 vwin_info_t info = data;
767 if (!info || info->state != VWIN_INFO_CREATED || !info->handle) {
771 ee_key = WIDGET_CONF_EE_KEY_FOR_UPDATE;
774 value = ecore_evas_data_get(info->ee, ee_key);
775 if (value && strcmp(value, "true")) {
776 DbgPrint("Frame skipped[%s]\n", value);
779 ecore_evas_data_set(info->ee, ee_key, "false");
782 if (info->type == VWIN_PIXMAP) {
784 unsigned int front_resource_id;
786 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
788 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
789 if (front_resource_id == info->resource_array[idx]) {
794 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
795 idx = WIDGET_PRIMARY_BUFFER;
798 /* Send updated event for PRIMARY BUFFER */
799 if (front_resource_id == widget_viewer_get_resource_id(info->handle, idx)) {
800 if (info->ctrl_mode.dump_to_file) {
804 snprintf(fname, sizeof(fname) - 1, "/tmp/%s.%u.%lf.raw", widget_util_basename(info->id), front_resource_id, ecore_time_get());
805 canvas = widget_provider_buffer_dump_frame(info->handle, idx);
810 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
811 size = w * h * sizeof(int);
813 dump_to_file(canvas, size, fname);
817 widget_send_updated_by_idx(info->handle, idx);
819 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, idx));
822 if (WIDGET_CONF_PREMULTIPLIED_COLOR) {
826 // Get a pointer of a buffer of the virtual canvas
827 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
829 ErrPrint("Failed to get pixel canvas\n");
833 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
834 evas_data_argb_unpremul(canvas, w * h);
837 if (info->ctrl_mode.dump_to_file) {
843 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
845 ErrPrint("Failed to get pixel canvas\n");
853 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
854 size = w * h * sizeof(int);
856 snprintf(fname, sizeof(fname) - 1, "/tmp/%s.%lf.raw", widget_util_basename(info->id), ecore_time_get());
857 dump_to_file(canvas, size, fname);
860 if (info->type == VWIN_GEM) {
861 widget_buffer_post_render(info->handle);
862 } else if (info->type == VWIN_SW_BUF) {
863 widget_viewer_sync_buffer(info->handle);
868 static int pre_ctrl_mode_cb(const char *id, void *data)
870 vwin_info_t info = data;
875 /* Try provider_app first */
876 if (!info || info->state != VWIN_INFO_CREATED || !id || !info->id) {
877 return WIDGET_ERROR_INVALID_PARAMETER;
880 path = widget_util_uri_to_path(id);
881 if (path && strcmp(info->id, path)) {
883 DbgPrint("SKIP: Pre orientation event callback is called [%s], %s\n", id, info->id);
884 return WIDGET_ERROR_INVALID_PARAMETER;
887 widget_get_last_ctrl_mode(path, &cmd, &value);
889 if (cmd == WIDGET_CTRL_MODE_DUMP_FRAME) {
890 info->ctrl_mode.dump_to_file = !!value;
891 DbgPrint("CtrlMode: DumpToFile: %d\n", info->ctrl_mode.dump_to_file);
894 return WIDGET_ERROR_NONE;
897 static int pre_orientation_cb(const char *id, void *data)
899 vwin_info_t info = data;
903 /* Try provider_app first */
904 if (!info || info->state != VWIN_INFO_CREATED || !id || !info->id) {
905 return WIDGET_ERROR_INVALID_PARAMETER;
908 path = widget_util_uri_to_path(id);
909 if (path && strcmp(info->id, path)) {
911 DbgPrint("SKIP: Pre orientation event callback is called [%s], %s\n", id, info->id);
912 return WIDGET_ERROR_INVALID_PARAMETER;
915 DbgPrint("Pre orientation event callback is called [%s]\n", id);
916 orientation = widget_get_orientation(path);
917 if (orientation < 0) {
918 ErrPrint("Failed to get orientation: %X\n", orientation);
920 info->orientation = orientation;
923 return WIDGET_ERROR_NONE;
926 static int pre_destroy_cb(const char *id, void *data)
928 vwin_info_t info = data;
929 const char *path = NULL;
931 if (!info || info->state != VWIN_INFO_CREATED) {
932 return WIDGET_ERROR_INVALID_PARAMETER;
936 path = widget_util_uri_to_path(id);
938 if (path && strcmp(info->id, path)) {
940 DbgPrint("SKIP: Pre destroy event callback is called [%s], %s\n", id, info->id);
941 return WIDGET_ERROR_INVALID_PARAMETER;
945 DbgPrint("Pre destroy event callback is called [%s]\n", id);
948 DbgPrint("Toggle manual render mode to prevent from unwanted rendering");
949 ecore_evas_manual_render_set(info->ee, EINA_TRUE);
952 return WIDGET_ERROR_NONE;
955 static void ecore_evas_free_cb(Ecore_Evas *ee)
959 info = ecore_evas_data_get(ee, WIN_INFO_TAG);
961 DbgPrint("Info is not valid\n");
965 if (info->pended_events_consumer) {
966 widget_buffer_event_data_t event_info;
968 DbgPrint("Clearing pended event consumer\n");
969 ecore_timer_del(info->pended_events_consumer);
970 info->pended_events_consumer = NULL;
972 EINA_LIST_FREE(info->pended_events_list, event_info) {
977 widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
978 widget_del_pre_callback(WIDGET_PRE_CTRL_MODE_CALLBACK, pre_ctrl_mode_cb, info);
981 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
982 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
985 info->flags.field.deleted = 1;
989 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
990 PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
991 #else /* WIDGET_FEATURE_GBAR_SUPPORTED */
992 PUBLIC Evas *widget_get_evas(const char *id)
993 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
1000 * If the evas object is already created,
1001 * this function should returns ERROR.
1005 ErrPrint("Invalid parameter\n");
1009 info = calloc(1, sizeof(*info));
1011 ErrPrint("Heap: %d\n", errno);
1015 info->state = VWIN_INFO_CREATED;
1017 info->id = strdup(id);
1019 ErrPrint("Heap: %d\n", errno);
1020 info->state = VWIN_INFO_DESTROYED;
1025 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
1026 info->flags.field.is_gbar = is_gbar;
1028 info->flags.field.is_gbar = 0;
1029 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
1032 * Acquire a buffer for canvas.
1034 info->handle = widget_create_buffer(info->id, info->flags.field.is_gbar,
1035 binder_widget_auto_align(),
1036 event_handler_cb, info);
1038 if (!info->handle) {
1039 ErrPrint("Failed to create a widget buffer\n");
1040 info->state = VWIN_INFO_DESTROYED;
1047 * Size information must be initialized before call the ecore_evas_buffer_new.
1049 info->w = WIDGET_DEFAULT_WIDTH;
1050 info->h = WIDGET_DEFAULT_HEIGHT;
1052 info->ee = binder_ecore_evas_new(info);
1054 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
1055 widget_destroy_buffer(info->handle);
1056 info->state = VWIN_INFO_DESTROYED;
1062 ecore_evas_data_set(info->ee, WIN_INFO_TAG, info);
1066 * Free callback must be prepared before use the ecore_evas_free()
1068 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
1070 info->e = ecore_evas_get(info->ee);
1072 ErrPrint("Failed to get evas\n");
1073 ecore_evas_free(info->ee);
1077 pre_render_cb(info, NULL, NULL);
1078 ecore_evas_alpha_set(info->ee, EINA_TRUE);
1079 post_render_cb(info, NULL, NULL);
1081 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
1082 ecore_evas_resize(info->ee, info->w, info->h);
1084 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
1085 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
1087 widget_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
1088 widget_add_pre_callback(WIDGET_PRE_ORIENTATION_CALLBACK, pre_orientation_cb, info);
1089 widget_add_pre_callback(WIDGET_PRE_CTRL_MODE_CALLBACK, pre_ctrl_mode_cb, info);
1091 orientation = widget_get_orientation(info->id);
1092 if (orientation < 0) {
1093 ErrPrint("Failed to get orientation[%s]: %X\n", info->id, orientation);
1095 info->orientation = orientation;