3 #endif /* ifdef HAVE_CONFIG_H */
8 #include "Ecore_DirectFB.h"
9 #include "ecore_directfb_private.h"
10 #include "ecore_directfb_keys.h"
12 #include "ecore_private.h"
17 /* with this you can create windows of directfb and handle events through ecore
19 * - handle all event types
22 int _ecore_directfb_log_dom = -1;
24 static int _ecore_directfb_init_count = 0;
26 static int _window_event_fd = 0;
27 static int _input_event_fd = 0;
29 static int _ecore_directfb_fullscreen_window_id = 0;
30 static int _cursor_x = 0;
31 static int _cursor_y = 0;
33 EAPI int ECORE_DIRECTFB_EVENT_POSITION = 0;
34 EAPI int ECORE_DIRECTFB_EVENT_SIZE = 0;
35 EAPI int ECORE_DIRECTFB_EVENT_CLOSE = 0;
36 EAPI int ECORE_DIRECTFB_EVENT_DESTROYED = 0;
37 EAPI int ECORE_DIRECTFB_EVENT_GOT_FOCUS = 0;
38 EAPI int ECORE_DIRECTFB_EVENT_LOST_FOCUS = 0;
39 EAPI int ECORE_DIRECTFB_EVENT_KEY_DOWN = 0;
40 EAPI int ECORE_DIRECTFB_EVENT_KEY_UP = 0;
41 EAPI int ECORE_DIRECTFB_EVENT_BUTTON_DOWN = 0;
42 EAPI int ECORE_DIRECTFB_EVENT_BUTTON_UP = 0;
43 EAPI int ECORE_DIRECTFB_EVENT_MOTION = 0;
44 EAPI int ECORE_DIRECTFB_EVENT_ENTER = 0;
45 EAPI int ECORE_DIRECTFB_EVENT_LEAVE = 0;
46 EAPI int ECORE_DIRECTFB_EVENT_WHEEL = 0;
48 static Ecore_Fd_Handler *_window_event_fd_handler_handle = NULL;
49 static Ecore_Fd_Handler *_input_event_fd_handler_handle = NULL;
51 /* this hash is to store all the possible key names for fast lookup */
52 static Eina_Hash *_ecore_directfb_key_symbols_hash = NULL;
54 static IDirectFB *_dfb = NULL; // the main interface
55 static IDirectFBEventBuffer *_window_event; // the main event buffer (all windows are attached to this)
56 static IDirectFBEventBuffer *_input_event; // the main event buffer (all windows are attached to this)
57 static IDirectFBDisplayLayer *_layer; // the main layer
58 static DFBResult _err; // useful for DFBCHECK
64 /* free ecore directfb events functions */
65 /****************************************/
68 _ecore_directfb_event_free_key_down(void *data __UNUSED__, void *ev)
70 Ecore_DirectFB_Event_Key_Up *e;
86 _ecore_directfb_event_free_key_up(void *data __UNUSED__, void *ev)
88 Ecore_DirectFB_Event_Key_Up *e;
103 /* directfb window input events handler */
104 /****************************************/
107 _ecore_directfb_event_handle_motion(DFBEvent *evt)
109 Ecore_DirectFB_Event_Motion *e;
110 e = calloc(1, sizeof(Ecore_DirectFB_Event_Motion));
116 switch(evt->input.axis)
119 e->x = _cursor_x = evt->input.axisabs;
124 e->y = _cursor_y = evt->input.axisabs;
129 //_ecore_directfb_event_handle_wheel(evt);
135 e->win = _ecore_directfb_fullscreen_window_id;
141 e->x = evt->window.x;
142 e->y = evt->window.y;
143 e->win = evt->window.window_id;
150 ecore_event_add(ECORE_DIRECTFB_EVENT_MOTION, e, NULL, NULL);
154 _ecore_directfb_event_handle_key_down(DFBEvent *evt)
156 Ecore_DirectFB_Event_Key_Down *e;
157 unsigned int key_symbol;
160 e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Down));
165 key_symbol = evt->input.key_symbol;
166 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
170 ERR("Symbol %0X of class DFEC_INPUT not found.", evt->input.key_symbol);
174 e->name = strdup(k->name);
175 e->string = strdup(k->string);
176 e->key_compose = NULL;
177 e->win = _ecore_directfb_fullscreen_window_id;
182 key_symbol = evt->window.key_symbol;
183 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
187 ERR("Symbol %0X of class DFEC_WINDOW not found.", evt->window.key_symbol);
191 e->name = strdup(k->name);
192 e->string = strdup(k->string);
193 e->key_compose = NULL;
194 e->win = evt->window.window_id;
202 ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, e, _ecore_directfb_event_free_key_down, NULL);
206 _ecore_directfb_event_handle_key_up(DFBEvent *evt)
208 Ecore_DirectFB_Event_Key_Up *e;
209 unsigned int key_symbol;
212 e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Up));
217 key_symbol = evt->input.key_symbol;
218 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
222 ERR("Symbol %0X of class DFEC_INPUT not found.", evt->input.key_symbol);
226 e->name = strdup(k->name);
227 e->string = strdup(k->string);
228 e->key_compose = NULL;
229 e->win = _ecore_directfb_fullscreen_window_id;
234 key_symbol = evt->window.key_symbol;
235 k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
239 ERR("Symbol %0X of class DFEC_WINDOW not found.", evt->window.key_symbol);
243 e->name = strdup(k->name);
244 e->string = strdup(k->string);
245 e->key_compose = NULL;
246 e->win = evt->window.window_id;
253 ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_UP, e, _ecore_directfb_event_free_key_up, NULL);
257 _ecore_directfb_event_handle_button_down(DFBEvent *evt)
259 Ecore_DirectFB_Event_Button_Down *e;
260 e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Down));
265 e->button = evt->input.button + 1;
267 DFBCHECK(_layer->GetCursorPosition(_layer,&e->x,&e->y));
270 e->win = _ecore_directfb_fullscreen_window_id;
276 e->button = evt->window.button + 1;
278 e->x = evt->window.x;
279 e->y = evt->window.y;
280 e->win = evt->window.window_id;
288 ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, e, NULL, NULL);
292 _ecore_directfb_event_handle_button_up(DFBEvent *evt)
294 Ecore_DirectFB_Event_Button_Up *e;
295 e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Up));
300 e->button = evt->input.button + 1;
304 e->win = _ecore_directfb_fullscreen_window_id;
310 e->button = evt->window.button + 1;
312 e->x = evt->window.x;
313 e->y = evt->window.y;
314 e->win = evt->window.window_id;
321 ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, e, NULL, NULL);
325 _ecore_directfb_event_handle_enter(DFBWindowEvent *evt)
327 Ecore_DirectFB_Event_Enter *e;
328 e = calloc(1, sizeof(Ecore_DirectFB_Event_Enter));
333 e->win = evt->window_id;
336 ecore_event_add(ECORE_DIRECTFB_EVENT_ENTER, e, NULL, NULL);
340 _ecore_directfb_event_handle_leave(DFBWindowEvent *evt)
342 Ecore_DirectFB_Event_Leave *e;
343 e = calloc(1, sizeof(Ecore_DirectFB_Event_Leave));
348 e->win = evt->window_id;
351 ecore_event_add(ECORE_DIRECTFB_EVENT_LEAVE, e, NULL, NULL);
355 _ecore_directfb_event_handle_wheel(DFBWindowEvent *evt)
357 Ecore_DirectFB_Event_Wheel *e;
358 e = calloc(1, sizeof(Ecore_DirectFB_Event_Wheel));
360 // currently there's no direction (only up/down);
364 e->win = evt->window_id;
367 ecore_event_add(ECORE_DIRECTFB_EVENT_WHEEL, e, NULL, NULL);
371 _ecore_directfb_event_handle_got_focus(DFBWindowEvent *evt)
373 Ecore_DirectFB_Event_Got_Focus *e;
374 e = calloc(1, sizeof(Ecore_DirectFB_Event_Got_Focus));
376 e->win = evt->window_id;
379 ecore_event_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, e, NULL, NULL);
383 _ecore_directfb_event_handle_lost_focus(DFBWindowEvent *evt)
385 Ecore_DirectFB_Event_Lost_Focus *e;
386 e = calloc(1, sizeof(Ecore_DirectFB_Event_Lost_Focus));
388 e->win = evt->window_id;
391 ecore_event_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, e, NULL, NULL);
394 /* inputs and windows fds handlers */
395 /***********************************/
396 /* TODO fix this to handle windows and input events (fullscreen/window mode)
397 * in fullscreen theres no window_id so get the id from a global var (only one fullscreen
398 * window at a time */
401 _ecore_directfb_input_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
406 v = read(_input_event_fd, &evt, sizeof(DFBEvent));
413 /* we are getting duplicate events, only parse if we are in fullscreen */
414 //if(_ecore_directfb_fullscreen_window_id == 0) break;
415 if(evt.input.type == DIET_KEYPRESS)
416 _ecore_directfb_event_handle_key_down(&evt);
418 if(evt.input.type == DIET_KEYRELEASE)
419 _ecore_directfb_event_handle_key_up(&evt);
421 if(evt.input.type == DIET_BUTTONPRESS)
422 _ecore_directfb_event_handle_button_down(&evt);
424 if(evt.input.type == DIET_BUTTONRELEASE)
425 _ecore_directfb_event_handle_button_up(&evt);
427 if(evt.input.type == DIET_AXISMOTION)
428 _ecore_directfb_event_handle_motion(&evt);
434 _ecore_directfb_window_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
439 v = read(_window_event_fd, &evt, sizeof(DFBEvent));
446 if(evt.window.type & DWET_POSITION)
449 if(evt.window.type & DWET_SIZE)
452 if(evt.window.type & DWET_CLOSE)
455 if(evt.window.type & DWET_DESTROYED)
458 if(evt.window.type & DWET_GOTFOCUS)
459 _ecore_directfb_event_handle_got_focus(&evt.window);
461 if(evt.window.type & DWET_LOSTFOCUS)
462 _ecore_directfb_event_handle_lost_focus(&evt.window);
464 if(evt.window.type & DWET_KEYDOWN)
465 _ecore_directfb_event_handle_key_down(&evt);
467 if(evt.window.type & DWET_KEYUP)
468 _ecore_directfb_event_handle_key_up(&evt);
470 if(evt.window.type & DWET_BUTTONDOWN)
471 _ecore_directfb_event_handle_button_down(&evt);
473 if(evt.window.type & DWET_BUTTONUP)
474 _ecore_directfb_event_handle_button_up(&evt);
476 if(evt.window.type & DWET_MOTION)
477 _ecore_directfb_event_handle_motion(&evt);
479 if(evt.window.type & DWET_ENTER)
480 _ecore_directfb_event_handle_enter(&evt.window);
482 if(evt.window.type & DWET_LEAVE)
483 _ecore_directfb_event_handle_leave(&evt.window);
485 if(evt.window.type & DWET_WHEEL)
486 _ecore_directfb_event_handle_wheel(&evt.window);
495 ecore_directfb_interface_get(void)
500 EAPI Ecore_DirectFB_Window *
501 ecore_directfb_window_new(int x, int y, int w, int h)
503 Ecore_DirectFB_Window *window;
504 IDirectFBWindow *dfb_window;
505 IDirectFBSurface *dfb_surface = NULL;
506 DFBWindowDescription desc;
509 memset(&desc, 0, sizeof(DFBWindowDescription));
510 desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
515 desc.caps = DWCAPS_ALPHACHANNEL;
517 DFBCHECK(_layer->CreateWindow(_layer, &desc, &dfb_window));
519 dfb_window->AttachEventBuffer(dfb_window, _window_event);
520 dfb_window->SetOptions(dfb_window,DWOP_NONE);
521 dfb_window->SetOpacity(dfb_window, 0xFF);
523 DFBCHECK(dfb_window->GetID(dfb_window, &id));
524 DFBCHECK(dfb_window->GetSurface(dfb_window,&dfb_surface));
526 window = malloc(sizeof(Ecore_DirectFB_Window));
528 window->window = dfb_window;
529 window->surface = dfb_surface;
530 window->cursor = NULL;
536 ecore_directfb_window_free(Ecore_DirectFB_Window *ecore_window)
538 DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
539 DFBCHECK(ecore_window->window->Release(ecore_window->window));
544 ecore_directfb_window_move(Ecore_DirectFB_Window *ecore_window, int x, int y)
546 DFBCHECK(ecore_window->window->MoveTo(ecore_window->window, x, y));
550 ecore_directfb_window_resize(Ecore_DirectFB_Window *ecore_window, int w, int h)
552 DFBCHECK(ecore_window->window->Resize(ecore_window->window, w, h));
556 ecore_directfb_window_focus(Ecore_DirectFB_Window *ecore_window)
558 DFBCHECK(ecore_window->window->RequestFocus(ecore_window->window));
562 ecore_directfb_window_hide(Ecore_DirectFB_Window *ecore_window)
564 DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0));
568 ecore_directfb_window_show(Ecore_DirectFB_Window *ecore_window)
570 DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0xFF));
574 ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *ecore_window, Eina_Bool set)
576 DFBWindowOptions opts;
578 DFBCHECK(ecore_window->window->GetOptions(ecore_window->window, &opts));
582 opts |= DWOP_ALPHACHANNEL;
583 DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
587 opts &= ~DWOP_SHAPED;
588 opts &= ~DWOP_ALPHACHANNEL;
589 DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
594 ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *ecore_window, Eina_Bool show)
598 /* create an empty cursor and set it */
599 IDirectFBSurface *cursor;
600 DFBSurfaceDescription desc;
602 memset(&desc, 0, sizeof(DFBSurfaceDescription));
603 desc.flags = (DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PIXELFORMAT);
606 desc.pixelformat = DSPF_A1;
608 DFBCHECK(_dfb->CreateSurface(_dfb,&desc,&cursor));
609 DFBCHECK(cursor->Clear(cursor,0,0,0,0));
610 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor, 0, 0));
614 /* we already have a cursor surface so set it*/
615 if(ecore_window->cursor)
617 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, ecore_window->cursor->surface, ecore_window->cursor->hot_x, ecore_window->cursor->hot_y));
619 /* or just set the default directfb cursor */
622 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
628 ecore_directfb_window_cursor_set(Ecore_DirectFB_Window *ecore_window, Ecore_DirectFB_Cursor *cursor)
630 if((!cursor) && (ecore_window->cursor))
632 ecore_window->cursor = NULL;
633 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
639 ecore_window->cursor = cursor;
640 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor->surface, cursor->hot_x, cursor->hot_y));
645 ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *ecore_window, Eina_Bool on)
647 // always release the surface (we are going to get a new one in both cases)
648 DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
651 DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_EXCLUSIVE));
652 DFBCHECK(_layer->GetSurface(_layer,&ecore_window->surface));
653 DFBCHECK(_dfb->CreateInputEventBuffer(_dfb, DICAPS_ALL, DFB_FALSE, &_input_event));
654 DFBCHECK(_input_event->CreateFileDescriptor(_input_event,&_input_event_fd));
655 /* the event of axismove sends one axis at a time, so we must store both */
656 DFBCHECK(_layer->GetCursorPosition(_layer,&_cursor_x,&_cursor_y));
658 _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);
659 _ecore_directfb_fullscreen_window_id = ecore_window->id;
663 ecore_main_fd_handler_del(_input_event_fd_handler_handle);
664 DFBCHECK(_input_event->Release(_input_event));
665 DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED));
666 DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface));
667 _ecore_directfb_fullscreen_window_id = 0;
672 ecore_directfb_window_size_get(Ecore_DirectFB_Window *ecore_window, int *w, int *h)
674 DFBCHECK(ecore_window->surface->GetSize(ecore_window->surface,w,h));
679 ecore_directfb_init(const char *name __UNUSED__)
683 if (++_ecore_directfb_init_count != 1)
684 return _ecore_directfb_init_count;
686 _ecore_directfb_log_dom = eina_log_domain_register
687 ("ecore_directfb", ECORE_DIRECTFB_DEFAULT_LOG_COLOR);
688 if(_ecore_directfb_log_dom < 0)
690 EINA_LOG_ERR("Impossible to create a log domain for the Ecore directFB module.");
691 return _ecore_directfb_init_count--;
694 DFBCHECK(DirectFBInit(NULL,NULL));
695 DFBCHECK(DirectFBCreate(&_dfb));
697 DFBCHECK(_dfb->GetDisplayLayer(_dfb, DLID_PRIMARY, &_layer));
698 DFBCHECK(_layer->SetCooperativeLevel(_layer, DLSCL_SHARED));
700 /* window events and fd */
701 DFBCHECK(_dfb->CreateEventBuffer(_dfb, &_window_event));
702 DFBCHECK(_window_event->CreateFileDescriptor(_window_event,&_window_event_fd));
703 _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);
705 /* register ecore directfb events */
706 ECORE_DIRECTFB_EVENT_POSITION = ecore_event_type_new();
707 ECORE_DIRECTFB_EVENT_SIZE = ecore_event_type_new();
708 ECORE_DIRECTFB_EVENT_CLOSE = ecore_event_type_new();
709 ECORE_DIRECTFB_EVENT_DESTROYED = ecore_event_type_new();
710 ECORE_DIRECTFB_EVENT_GOT_FOCUS = ecore_event_type_new();
711 ECORE_DIRECTFB_EVENT_LOST_FOCUS = ecore_event_type_new();
712 ECORE_DIRECTFB_EVENT_KEY_DOWN = ecore_event_type_new();
713 ECORE_DIRECTFB_EVENT_KEY_UP = ecore_event_type_new();
714 ECORE_DIRECTFB_EVENT_BUTTON_DOWN = ecore_event_type_new();
715 ECORE_DIRECTFB_EVENT_BUTTON_UP = ecore_event_type_new();
716 ECORE_DIRECTFB_EVENT_MOTION = ecore_event_type_new();
717 ECORE_DIRECTFB_EVENT_ENTER = ecore_event_type_new();
718 ECORE_DIRECTFB_EVENT_LEAVE = ecore_event_type_new();
719 ECORE_DIRECTFB_EVENT_WHEEL = ecore_event_type_new();
721 /* create the hash table for the keynames */
722 _ecore_directfb_key_symbols_hash = eina_hash_int32_new(free);
723 for(i = 0; i < _ecore_directfb_key_symbols_count; i++)
726 k = malloc(sizeof(struct keymap));
727 k->name = _ecore_directfb_key_symbols[i].name;
728 k->string = _ecore_directfb_key_symbols[i].string;
729 eina_hash_add(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id, k);
731 /* create the hash for the windows(key = windowid, val = Ecore_DirectFB_Window struct) */
732 return _ecore_directfb_init_count;
736 ecore_directfb_shutdown(void)
738 if (--_ecore_directfb_init_count != 0)
739 return _ecore_directfb_init_count;
741 ecore_main_fd_handler_del(_window_event_fd_handler_handle);
742 eina_hash_free(_ecore_directfb_key_symbols_hash);
744 if(_ecore_directfb_fullscreen_window_id)
746 DFBCHECK(_input_event->Release(_input_event));
747 ecore_main_fd_handler_del(_input_event_fd_handler_handle);
750 DFBCHECK(_window_event->Release(_window_event));
751 DFBCHECK(_layer->Release(_layer));
752 DFBCHECK(_dfb->Release(_dfb));
753 eina_log_domain_unregister(_ecore_directfb_log_dom);
754 _ecore_directfb_log_dom = -1;
755 return _ecore_directfb_init_count;