2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
12 #include "Ecore_DirectFB.h"
13 #include "ecore_directfb_private.h"
14 #include "ecore_directfb_keys.h"
16 #include "ecore_private.h"
21 /* with this you can create windows of directfb and handle events through ecore
23 * - handle all event types
26 int _ecore_directfb_log_dom = -1;
29 static int _ecore_directfb_init_count = 0;
31 static int _window_event_fd = 0;
32 static int _input_event_fd = 0;
34 static int _ecore_directfb_fullscreen_window_id = 0;
35 static int _cursor_x = 0;
36 static int _cursor_y = 0;
38 EAPI int ECORE_DIRECTFB_EVENT_POSITION = 0;
39 EAPI int ECORE_DIRECTFB_EVENT_SIZE = 0;
40 EAPI int ECORE_DIRECTFB_EVENT_CLOSE = 0;
41 EAPI int ECORE_DIRECTFB_EVENT_DESTROYED = 0;
42 EAPI int ECORE_DIRECTFB_EVENT_GOT_FOCUS = 0;
43 EAPI int ECORE_DIRECTFB_EVENT_LOST_FOCUS = 0;
44 EAPI int ECORE_DIRECTFB_EVENT_KEY_DOWN = 0;
45 EAPI int ECORE_DIRECTFB_EVENT_KEY_UP = 0;
46 EAPI int ECORE_DIRECTFB_EVENT_BUTTON_DOWN = 0;
47 EAPI int ECORE_DIRECTFB_EVENT_BUTTON_UP = 0;
48 EAPI int ECORE_DIRECTFB_EVENT_MOTION = 0;
49 EAPI int ECORE_DIRECTFB_EVENT_ENTER = 0;
50 EAPI int ECORE_DIRECTFB_EVENT_LEAVE = 0;
51 EAPI int ECORE_DIRECTFB_EVENT_WHEEL = 0;
54 static Ecore_Fd_Handler *_window_event_fd_handler_handle = NULL;
55 static Ecore_Fd_Handler *_input_event_fd_handler_handle = NULL;
57 /* this hash is to store all the possible key names for fast lookup */
58 static Eina_Hash *_ecore_directfb_key_symbols_hash = NULL;
61 static IDirectFB *_dfb = NULL; // the main interface
62 static IDirectFBEventBuffer *_window_event; // the main event buffer (all windows are attached to this)
63 static IDirectFBEventBuffer *_input_event; // the main event buffer (all windows are attached to this)
64 static IDirectFBDisplayLayer *_layer; // the main layer
65 static DFBResult _err; // usefull for DFBCHECK
72 /* free ecore directfb events functions */
73 /****************************************/
76 _ecore_directfb_event_free_key_down(void *data __UNUSED__, void *ev)
78 Ecore_DirectFB_Event_Key_Up *e;
81 if(e->name) free(e->name);
82 if (e->string) free(e->string);
83 if (e->key_compose) free(e->key_compose);
88 _ecore_directfb_event_free_key_up(void *data __UNUSED__, void *ev)
90 Ecore_DirectFB_Event_Key_Up *e;
93 if(e->name) free(e->name);
94 if (e->string) free(e->string);
95 if (e->key_compose) free(e->key_compose);
100 /* directfb window input events handler */
101 /****************************************/
104 _ecore_directfb_event_handle_motion(DFBEvent *evt)
107 Ecore_DirectFB_Event_Motion *e;
108 e = calloc(1, sizeof(Ecore_DirectFB_Event_Motion));
114 switch(evt->input.axis)
117 e->x = _cursor_x = evt->input.axisabs;
121 e->y = _cursor_y = evt->input.axisabs;
125 //_ecore_directfb_event_handle_wheel(evt);
130 e->win = _ecore_directfb_fullscreen_window_id;
136 e->x = evt->window.x;
137 e->y = evt->window.y;
138 e->win = evt->window.window_id;
144 ecore_event_add(ECORE_DIRECTFB_EVENT_MOTION, e, NULL, NULL);
147 _ecore_directfb_event_handle_key_down(DFBEvent *evt)
150 Ecore_DirectFB_Event_Key_Down *e;
151 unsigned int key_symbol;
154 e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Down));
159 key_symbol = evt->input.key_symbol;
160 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
164 ERR("error en el numero, %0X", evt->input.key_symbol);
167 e->name = strdup(k->name);
168 e->string = strdup(k->string);
169 e->key_compose = NULL;
170 e->win = _ecore_directfb_fullscreen_window_id;
175 key_symbol = evt->window.key_symbol;
176 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
180 ERR("error en el numero, %0X", evt->window.key_symbol);
183 e->name = strdup(k->name);
184 e->string = strdup(k->string);
185 e->key_compose = NULL;
186 e->win = evt->window.window_id;
193 ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, e, _ecore_directfb_event_free_key_down, NULL);
196 _ecore_directfb_event_handle_key_up(DFBEvent *evt)
198 Ecore_DirectFB_Event_Key_Up *e;
199 unsigned int key_symbol;
202 e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Up));
207 key_symbol = evt->input.key_symbol;
208 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
213 ERR("error en el numero, %0X", evt->input.key_symbol);
216 e->name = strdup(k->name);
217 e->string = strdup(k->string);
218 e->key_compose = NULL;
219 e->win = _ecore_directfb_fullscreen_window_id;
224 key_symbol = evt->window.key_symbol;
225 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
229 ERR("error en el numero, %0X", evt->window.key_symbol);
232 e->name = strdup(k->name);
233 e->string = strdup(k->string);
234 e->key_compose = NULL;
235 e->win = evt->window.window_id;
241 ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_UP, e, _ecore_directfb_event_free_key_up, NULL);
246 _ecore_directfb_event_handle_button_down(DFBEvent *evt)
248 Ecore_DirectFB_Event_Button_Down *e;
249 e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Down));
254 e->button = evt->input.button + 1;
256 DFBCHECK(_layer->GetCursorPosition(_layer,&e->x,&e->y));
259 e->win = _ecore_directfb_fullscreen_window_id;
265 e->button = evt->window.button + 1;
267 e->x = evt->window.x;
268 e->y = evt->window.y;
269 e->win = evt->window.window_id;
276 ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, e, NULL, NULL);
281 _ecore_directfb_event_handle_button_up(DFBEvent *evt)
283 Ecore_DirectFB_Event_Button_Up *e;
284 e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Up));
289 e->button = evt->input.button + 1;
293 e->win = _ecore_directfb_fullscreen_window_id;
299 e->button = evt->window.button + 1;
301 e->x = evt->window.x;
302 e->y = evt->window.y;
303 e->win = evt->window.window_id;
309 ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, e, NULL, NULL);
314 _ecore_directfb_event_handle_enter(DFBWindowEvent *evt)
316 Ecore_DirectFB_Event_Enter *e;
317 e = calloc(1, sizeof(Ecore_DirectFB_Event_Enter));
322 e->win = evt->window_id;
325 ecore_event_add(ECORE_DIRECTFB_EVENT_ENTER, e, NULL, NULL);
330 _ecore_directfb_event_handle_leave(DFBWindowEvent *evt)
332 Ecore_DirectFB_Event_Leave *e;
333 e = calloc(1, sizeof(Ecore_DirectFB_Event_Leave));
338 e->win = evt->window_id;
341 ecore_event_add(ECORE_DIRECTFB_EVENT_LEAVE, e, NULL, NULL);
346 _ecore_directfb_event_handle_wheel(DFBWindowEvent *evt)
348 Ecore_DirectFB_Event_Wheel *e;
349 e = calloc(1, sizeof(Ecore_DirectFB_Event_Wheel));
351 // currently there's no direction (only up/down);
355 e->win = evt->window_id;
358 ecore_event_add(ECORE_DIRECTFB_EVENT_WHEEL, e, NULL, NULL);
363 _ecore_directfb_event_handle_got_focus(DFBWindowEvent *evt)
365 Ecore_DirectFB_Event_Got_Focus *e;
366 e = calloc(1, sizeof(Ecore_DirectFB_Event_Got_Focus));
368 e->win = evt->window_id;
371 ecore_event_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, e, NULL, NULL);
376 _ecore_directfb_event_handle_lost_focus(DFBWindowEvent *evt)
378 Ecore_DirectFB_Event_Lost_Focus *e;
379 e = calloc(1, sizeof(Ecore_DirectFB_Event_Lost_Focus));
381 e->win = evt->window_id;
384 ecore_event_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, e, NULL, NULL);
389 /* inputs and windows fds handlers */
390 /***********************************/
391 /* TODO fix this to handle windows and input events (fullscreen/window mode)
392 * in fullscreen theres no window_id so get the id from a global var (only one fullscreen
393 * window at a time */
397 _ecore_directfb_input_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
402 v = read(_input_event_fd, &evt, sizeof(DFBEvent));
406 /* we are getting duplicate events, only parse if we are in fullscreen */
407 //if(_ecore_directfb_fullscreen_window_id == 0) break;
408 if(evt.input.type == DIET_KEYPRESS)
409 _ecore_directfb_event_handle_key_down(&evt);
410 if(evt.input.type == DIET_KEYRELEASE)
411 _ecore_directfb_event_handle_key_up(&evt);
412 if(evt.input.type == DIET_BUTTONPRESS)
413 _ecore_directfb_event_handle_button_down(&evt);
414 if(evt.input.type == DIET_BUTTONRELEASE)
415 _ecore_directfb_event_handle_button_up(&evt);
416 if(evt.input.type == DIET_AXISMOTION)
417 _ecore_directfb_event_handle_motion(&evt);
423 _ecore_directfb_window_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
428 v = read(_window_event_fd, &evt, sizeof(DFBEvent));
432 if(evt.window.type & DWET_POSITION)
434 if(evt.window.type & DWET_SIZE)
436 if(evt.window.type & DWET_CLOSE)
438 if(evt.window.type & DWET_DESTROYED)
440 if(evt.window.type & DWET_GOTFOCUS)
441 _ecore_directfb_event_handle_got_focus(&evt.window);
442 if(evt.window.type & DWET_LOSTFOCUS)
443 _ecore_directfb_event_handle_lost_focus(&evt.window);
444 if(evt.window.type & DWET_KEYDOWN)
445 _ecore_directfb_event_handle_key_down(&evt);
446 if(evt.window.type & DWET_KEYUP)
447 _ecore_directfb_event_handle_key_up(&evt);
448 if(evt.window.type & DWET_BUTTONDOWN)
449 _ecore_directfb_event_handle_button_down(&evt);
450 if(evt.window.type & DWET_BUTTONUP)
451 _ecore_directfb_event_handle_button_up(&evt);
452 if(evt.window.type & DWET_MOTION)
453 _ecore_directfb_event_handle_motion(&evt);
454 if(evt.window.type & DWET_ENTER)
455 _ecore_directfb_event_handle_enter(&evt.window);
456 if(evt.window.type & DWET_LEAVE)
457 _ecore_directfb_event_handle_leave(&evt.window);
458 if(evt.window.type & DWET_WHEEL)
459 _ecore_directfb_event_handle_wheel(&evt.window);
468 ecore_directfb_interface_get(void)
475 EAPI Ecore_DirectFB_Window *
476 ecore_directfb_window_new(int x, int y, int w, int h)
478 Ecore_DirectFB_Window *window;
479 IDirectFBWindow *dfb_window;
480 IDirectFBSurface *dfb_surface = NULL;
481 DFBWindowDescription desc;
484 memset(&desc, 0, sizeof(DFBWindowDescription));
485 desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
490 desc.caps = DWCAPS_ALPHACHANNEL;
492 DFBCHECK(_layer->CreateWindow(_layer, &desc, &dfb_window));
494 dfb_window->AttachEventBuffer(dfb_window, _window_event);
495 dfb_window->SetOptions(dfb_window,DWOP_NONE);
496 dfb_window->SetOpacity(dfb_window, 0xFF);
498 DFBCHECK(dfb_window->GetID(dfb_window, &id));
499 DFBCHECK(dfb_window->GetSurface(dfb_window,&dfb_surface));
501 window = malloc(sizeof(Ecore_DirectFB_Window));
503 window->window = dfb_window;
504 window->surface = dfb_surface;
505 window->cursor = NULL;
511 ecore_directfb_window_free(Ecore_DirectFB_Window *ecore_window)
513 DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
514 DFBCHECK(ecore_window->window->Release(ecore_window->window));
520 ecore_directfb_window_move(Ecore_DirectFB_Window *ecore_window, int x, int y)
522 DFBCHECK(ecore_window->window->MoveTo(ecore_window->window, x, y));
526 ecore_directfb_window_resize(Ecore_DirectFB_Window *ecore_window, int w, int h)
528 DFBCHECK(ecore_window->window->Resize(ecore_window->window, w, h));
532 ecore_directfb_window_focus(Ecore_DirectFB_Window *ecore_window)
534 DFBCHECK(ecore_window->window->RequestFocus(ecore_window->window));
538 ecore_directfb_window_hide(Ecore_DirectFB_Window *ecore_window)
540 DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window,0));
545 ecore_directfb_window_show(Ecore_DirectFB_Window *ecore_window)
547 DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0xFF));
551 ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *ecore_window, int set)
553 DFBWindowOptions opts;
555 DFBCHECK(ecore_window->window->GetOptions(ecore_window->window, &opts));
559 opts |= DWOP_ALPHACHANNEL;
560 DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
564 opts &= ~DWOP_SHAPED;
565 opts &= ~DWOP_ALPHACHANNEL;
566 DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
571 ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *ecore_window, int show)
575 /* create an empty cursor and set it */
576 IDirectFBSurface *cursor;
577 DFBSurfaceDescription desc;
579 memset(&desc, 0, sizeof(DFBSurfaceDescription));
580 desc.flags = (DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PIXELFORMAT);
583 desc.pixelformat = DSPF_A1;
585 DFBCHECK(_dfb->CreateSurface(_dfb,&desc,&cursor));
586 DFBCHECK(cursor->Clear(cursor,0,0,0,0));
587 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor, 0, 0));
591 /* we already have a cursor surface so set it*/
592 if(ecore_window->cursor)
594 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, ecore_window->cursor->surface, ecore_window->cursor->hot_x, ecore_window->cursor->hot_y));
596 /* or just set the default directfb cursor */
599 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
606 ecore_directfb_window_cursor_set(Ecore_DirectFB_Window *ecore_window, Ecore_DirectFB_Cursor *cursor)
608 if( (!cursor) && (ecore_window->cursor))
610 ecore_window->cursor = NULL;
611 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
616 ecore_window->cursor = cursor;
617 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor->surface, cursor->hot_x, cursor->hot_y));
624 ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *ecore_window, int on)
626 // always release the surface (we are going to get a new one in both cases)
627 DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
630 DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_EXCLUSIVE));
631 DFBCHECK(_layer->GetSurface(_layer,&ecore_window->surface));
632 DFBCHECK(_dfb->CreateInputEventBuffer(_dfb, DICAPS_ALL, DFB_FALSE, &_input_event));
633 DFBCHECK(_input_event->CreateFileDescriptor(_input_event,&_input_event_fd));
634 /* the event of axismove sends one axis at a time, so we must store both */
635 DFBCHECK(_layer->GetCursorPosition(_layer,&_cursor_x,&_cursor_y));
637 _input_event_fd_handler_handle = ecore_main_fd_handler_add(_input_event_fd,ECORE_FD_READ,_ecore_directfb_input_event_fd_handler, NULL,NULL,NULL);
638 _ecore_directfb_fullscreen_window_id = ecore_window->id;
642 DFBCHECK(_input_event->Release(_input_event));
643 DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED));
644 DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface));
645 ecore_main_fd_handler_del(_input_event_fd_handler_handle);
646 _ecore_directfb_fullscreen_window_id = 0;
652 ecore_directfb_window_size_get(Ecore_DirectFB_Window *ecore_window, int *w, int *h)
654 DFBCHECK(ecore_window->surface->GetSize(ecore_window->surface,w,h));
659 ecore_directfb_init(const char *name __UNUSED__)
663 if (++_ecore_directfb_init_count != 1) return _ecore_directfb_init_count;
664 _ecore_directfb_log_dom = eina_log_domain_register("EcoreDirectFB", ECORE_DIRECTFB_DEFAULT_LOG_COLOR);
665 if(_ecore_directfb_log_dom < 0)
667 EINA_LOG_ERR("Impossible to create a log domain for the Ecore directFB module.");
668 return _ecore_directfb_init_count--;
670 DFBCHECK(DirectFBInit(NULL,NULL));
671 DFBCHECK(DirectFBCreate(&_dfb));
673 DFBCHECK(_dfb->GetDisplayLayer(_dfb, DLID_PRIMARY, &_layer));
674 DFBCHECK(_layer->SetCooperativeLevel(_layer, DLSCL_SHARED));
677 /* window events and fd */
678 DFBCHECK(_dfb->CreateEventBuffer(_dfb, &_window_event));
679 DFBCHECK(_window_event->CreateFileDescriptor(_window_event,&_window_event_fd));
680 _window_event_fd_handler_handle = ecore_main_fd_handler_add(_window_event_fd,ECORE_FD_READ,_ecore_directfb_window_event_fd_handler, NULL,NULL,NULL);
682 /* register ecore directfb events */
683 ECORE_DIRECTFB_EVENT_POSITION = ecore_event_type_new();
684 ECORE_DIRECTFB_EVENT_SIZE = ecore_event_type_new();;
685 ECORE_DIRECTFB_EVENT_CLOSE = ecore_event_type_new();;
686 ECORE_DIRECTFB_EVENT_DESTROYED = ecore_event_type_new();;
687 ECORE_DIRECTFB_EVENT_GOT_FOCUS = ecore_event_type_new();;
688 ECORE_DIRECTFB_EVENT_LOST_FOCUS = ecore_event_type_new();;
689 ECORE_DIRECTFB_EVENT_KEY_DOWN = ecore_event_type_new();;
690 ECORE_DIRECTFB_EVENT_KEY_UP = ecore_event_type_new();;
691 ECORE_DIRECTFB_EVENT_BUTTON_DOWN = ecore_event_type_new();;
692 ECORE_DIRECTFB_EVENT_BUTTON_UP = ecore_event_type_new();;
693 ECORE_DIRECTFB_EVENT_MOTION = ecore_event_type_new();;
694 ECORE_DIRECTFB_EVENT_ENTER = ecore_event_type_new();;
695 ECORE_DIRECTFB_EVENT_LEAVE = ecore_event_type_new();;
696 ECORE_DIRECTFB_EVENT_WHEEL = ecore_event_type_new();;
698 /* create the hash table for the keynames */
699 _ecore_directfb_key_symbols_hash = eina_hash_int32_new(free);
700 for(i=0; i<_ecore_directfb_key_symbols_count; i++)
703 k = malloc(sizeof(struct keymap));
704 k->name = _ecore_directfb_key_symbols[i].name;
705 k->string = _ecore_directfb_key_symbols[i].string;
706 eina_hash_add(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id, k);
708 /* create the hash for the windows(key = windowid, val = Ecore_DirectFB_Window struct) */
709 return _ecore_directfb_init_count;
713 ecore_directfb_shutdown(void)
715 if (--_ecore_directfb_init_count != 0) return _ecore_directfb_init_count;
717 ecore_main_fd_handler_del(_window_event_fd_handler_handle);
718 eina_hash_free(_ecore_directfb_key_symbols_hash);
720 if(_ecore_directfb_fullscreen_window_id)
722 DFBCHECK(_input_event->Release(_input_event));
723 ecore_main_fd_handler_del(_input_event_fd_handler_handle);
725 DFBCHECK(_window_event->Release(_window_event));
726 DFBCHECK(_layer->Release(_layer));
727 DFBCHECK(_dfb->Release(_dfb));
728 eina_log_domain_unregister(_ecore_directfb_log_dom);
729 _ecore_directfb_log_dom = -1;
730 return _ecore_directfb_init_count;