1 #include "ecore_private.h"
2 #include "Ecore_DirectFB.h"
3 #include "ecore_directfb_private.h"
4 #include "ecore_directfb_keys.h"
10 /* with this you can create windows of directfb and handle events through ecore
12 * - handle all event types
16 static int _ecore_directfb_key_symbols_count = sizeof(_ecore_directfb_key_symbols)/sizeof(Ecore_DirectFB_Key_Symbols);
17 static int _ecore_directfb_init_count = 0;
19 static int _window_event_fd = 0;
20 static int _input_event_fd = 0;
22 static int _ecore_directfb_fullscreen_window_id = 0;
23 static int _cursor_x = 0;
24 static int _cursor_y = 0;
26 EAPI int ECORE_DIRECTFB_EVENT_POSITION = 0;
27 EAPI int ECORE_DIRECTFB_EVENT_SIZE = 0;
28 EAPI int ECORE_DIRECTFB_EVENT_CLOSE = 0;
29 EAPI int ECORE_DIRECTFB_EVENT_DESTROYED = 0;
30 EAPI int ECORE_DIRECTFB_EVENT_GOT_FOCUS = 0;
31 EAPI int ECORE_DIRECTFB_EVENT_LOST_FOCUS = 0;
32 EAPI int ECORE_DIRECTFB_EVENT_KEY_DOWN = 0;
33 EAPI int ECORE_DIRECTFB_EVENT_KEY_UP = 0;
34 EAPI int ECORE_DIRECTFB_EVENT_BUTTON_DOWN = 0;
35 EAPI int ECORE_DIRECTFB_EVENT_BUTTON_UP = 0;
36 EAPI int ECORE_DIRECTFB_EVENT_MOTION = 0;
37 EAPI int ECORE_DIRECTFB_EVENT_ENTER = 0;
38 EAPI int ECORE_DIRECTFB_EVENT_LEAVE = 0;
39 EAPI int ECORE_DIRECTFB_EVENT_WHEEL = 0;
42 static Ecore_Fd_Handler *_window_event_fd_handler_handle = NULL;
43 static Ecore_Fd_Handler *_input_event_fd_handler_handle = NULL;
45 /* this hash is to store all the possible key names for fast lookup */
46 static Ecore_Hash *_ecore_directfb_key_symbols_hash = NULL;
49 static IDirectFB *_dfb = NULL; // the main interface
50 static IDirectFBEventBuffer *_window_event; // the main event buffer (all windows are attached to this)
51 static IDirectFBEventBuffer *_input_event; // the main event buffer (all windows are attached to this)
52 static IDirectFBDisplayLayer *_layer; // the main layer
53 static DFBResult _err; // usefull for DFBCHECK
60 /* free ecore directfb events functions */
61 /****************************************/
64 _ecore_directfb_event_free_key_down(void *data __UNUSED__, void *ev)
66 Ecore_DirectFB_Event_Key_Up *e;
69 if(e->name) free(e->name);
70 if (e->string) free(e->string);
71 if (e->key_compose) free(e->key_compose);
76 _ecore_directfb_event_free_key_up(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);
91 _ecore_directfb_hash_compare(void *key1, void *key2)
93 if(*(unsigned int*)key1 == *(unsigned int*)key2)
100 unsigned int _ecore_directfb_hash_create(void *key)
102 return *(unsigned int*)key % ecore_prime_table[_ecore_directfb_key_symbols_hash->size];
106 /* directfb window input events handler */
107 /****************************************/
110 _ecore_directfb_event_handle_motion(DFBEvent *evt)
113 Ecore_DirectFB_Event_Motion *e;
114 e = calloc(1, sizeof(Ecore_DirectFB_Event_Motion));
120 switch(evt->input.axis)
123 e->x = _cursor_x = evt->input.axisabs;
127 e->y = _cursor_y = evt->input.axisabs;
131 //_ecore_directfb_event_handle_wheel(evt);
136 e->win = _ecore_directfb_fullscreen_window_id;
142 e->x = evt->window.x;
143 e->y = evt->window.y;
144 e->win = evt->window.window_id;
150 ecore_event_add(ECORE_DIRECTFB_EVENT_MOTION, e, NULL, NULL);
153 _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 = ecore_hash_get(_ecore_directfb_key_symbols_hash, &key_symbol);
170 printf("error en el numero, %0X\n", evt->input.key_symbol);
173 e->name = strdup(k->name);
174 e->string = strdup(k->string);
175 e->key_compose = NULL;
176 e->win = _ecore_directfb_fullscreen_window_id;
181 key_symbol = evt->window.key_symbol;
182 k = ecore_hash_get(_ecore_directfb_key_symbols_hash, &key_symbol);
186 printf("error en el numero, %0X\n", evt->window.key_symbol);
189 e->name = strdup(k->name);
190 e->string = strdup(k->string);
191 e->key_compose = NULL;
192 e->win = evt->window.window_id;
199 ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, e, _ecore_directfb_event_free_key_down, NULL);
202 _ecore_directfb_event_handle_key_up(DFBEvent *evt)
204 Ecore_DirectFB_Event_Key_Up *e;
205 unsigned int key_symbol;
208 e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Up));
213 key_symbol = evt->input.key_symbol;
214 k = ecore_hash_get(_ecore_directfb_key_symbols_hash, &key_symbol);
219 printf("error en el numero, %0X\n", evt->input.key_symbol);
222 e->name = strdup(k->name);
223 e->string = strdup(k->string);
224 e->key_compose = NULL;
225 e->win = _ecore_directfb_fullscreen_window_id;
230 key_symbol = evt->window.key_symbol;
231 k = ecore_hash_get(_ecore_directfb_key_symbols_hash, &key_symbol);
235 printf("error en el numero, %0X\n", evt->window.key_symbol);
238 e->name = strdup(k->name);
239 e->string = strdup(k->string);
240 e->key_compose = NULL;
241 e->win = evt->window.window_id;
247 ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_UP, e, _ecore_directfb_event_free_key_up, NULL);
252 _ecore_directfb_event_handle_button_down(DFBEvent *evt)
254 Ecore_DirectFB_Event_Button_Down *e;
255 e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Down));
260 e->button = evt->input.button + 1;
262 DFBCHECK(_layer->GetCursorPosition(_layer,&e->x,&e->y));
265 e->win = _ecore_directfb_fullscreen_window_id;
271 e->button = evt->window.button + 1;
273 e->x = evt->window.x;
274 e->y = evt->window.y;
275 e->win = evt->window.window_id;
282 ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, e, NULL, NULL);
287 _ecore_directfb_event_handle_button_up(DFBEvent *evt)
289 Ecore_DirectFB_Event_Button_Up *e;
290 e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Up));
295 e->button = evt->input.button + 1;
299 e->win = _ecore_directfb_fullscreen_window_id;
305 e->button = evt->window.button + 1;
307 e->x = evt->window.x;
308 e->y = evt->window.y;
309 e->win = evt->window.window_id;
315 ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, e, NULL, NULL);
320 _ecore_directfb_event_handle_enter(DFBWindowEvent *evt)
322 Ecore_DirectFB_Event_Enter *e;
323 e = calloc(1, sizeof(Ecore_DirectFB_Event_Enter));
328 e->win = evt->window_id;
331 ecore_event_add(ECORE_DIRECTFB_EVENT_ENTER, e, NULL, NULL);
336 _ecore_directfb_event_handle_leave(DFBWindowEvent *evt)
338 Ecore_DirectFB_Event_Leave *e;
339 e = calloc(1, sizeof(Ecore_DirectFB_Event_Leave));
344 e->win = evt->window_id;
347 ecore_event_add(ECORE_DIRECTFB_EVENT_LEAVE, e, NULL, NULL);
352 _ecore_directfb_event_handle_wheel(DFBWindowEvent *evt)
354 Ecore_DirectFB_Event_Wheel *e;
355 e = calloc(1, sizeof(Ecore_DirectFB_Event_Wheel));
357 // currently there's no direction (only up/down);
361 e->win = evt->window_id;
364 ecore_event_add(ECORE_DIRECTFB_EVENT_WHEEL, e, NULL, NULL);
369 _ecore_directfb_event_handle_got_focus(DFBWindowEvent *evt)
371 Ecore_DirectFB_Event_Got_Focus *e;
372 e = calloc(1, sizeof(Ecore_DirectFB_Event_Got_Focus));
374 e->win = evt->window_id;
377 ecore_event_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, e, NULL, NULL);
382 _ecore_directfb_event_handle_lost_focus(DFBWindowEvent *evt)
384 Ecore_DirectFB_Event_Lost_Focus *e;
385 e = calloc(1, sizeof(Ecore_DirectFB_Event_Lost_Focus));
387 e->win = evt->window_id;
390 ecore_event_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, e, NULL, NULL);
395 /* inputs and windows fds handlers */
396 /***********************************/
397 /* TODO fix this to handle windows and input events (fullscreen/window mode)
398 * in fullscreen theres no window_id so get the id from a global var (only one fullscreen
399 * window at a time */
403 _ecore_directfb_input_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
408 v = read(_input_event_fd, &evt, sizeof(DFBEvent));
412 /* we are getting duplicate events, only parse if we are in fullscreen */
413 //if(_ecore_directfb_fullscreen_window_id == 0) break;
414 if(evt.input.type == DIET_KEYPRESS)
415 _ecore_directfb_event_handle_key_down(&evt);
416 if(evt.input.type == DIET_KEYRELEASE)
417 _ecore_directfb_event_handle_key_up(&evt);
418 if(evt.input.type == DIET_BUTTONPRESS)
419 _ecore_directfb_event_handle_button_down(&evt);
420 if(evt.input.type == DIET_BUTTONRELEASE)
421 _ecore_directfb_event_handle_button_up(&evt);
422 if(evt.input.type == DIET_AXISMOTION)
423 _ecore_directfb_event_handle_motion(&evt);
429 _ecore_directfb_window_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
434 v = read(_window_event_fd, &evt, sizeof(DFBEvent));
438 if(evt.window.type & DWET_POSITION)
439 printf("position\n");
440 if(evt.window.type & DWET_SIZE)
442 if(evt.window.type & DWET_CLOSE)
444 if(evt.window.type & DWET_DESTROYED)
445 printf("destroyed\n");
446 if(evt.window.type & DWET_GOTFOCUS)
447 _ecore_directfb_event_handle_got_focus(&evt.window);
448 if(evt.window.type & DWET_LOSTFOCUS)
449 _ecore_directfb_event_handle_lost_focus(&evt.window);
450 if(evt.window.type & DWET_KEYDOWN)
451 _ecore_directfb_event_handle_key_down(&evt);
452 if(evt.window.type & DWET_KEYUP)
453 _ecore_directfb_event_handle_key_up(&evt);
454 if(evt.window.type & DWET_BUTTONDOWN)
455 _ecore_directfb_event_handle_button_down(&evt);
456 if(evt.window.type & DWET_BUTTONUP)
457 _ecore_directfb_event_handle_button_up(&evt);
458 if(evt.window.type & DWET_MOTION)
459 _ecore_directfb_event_handle_motion(&evt);
460 if(evt.window.type & DWET_ENTER)
461 _ecore_directfb_event_handle_enter(&evt.window);
462 if(evt.window.type & DWET_LEAVE)
463 _ecore_directfb_event_handle_leave(&evt.window);
464 if(evt.window.type & DWET_WHEEL)
465 _ecore_directfb_event_handle_wheel(&evt.window);
474 ecore_directfb_interface_get(void)
481 EAPI Ecore_DirectFB_Window *
482 ecore_directfb_window_new(int x, int y, int w, int h)
484 Ecore_DirectFB_Window *window;
485 IDirectFBWindow *dfb_window;
486 IDirectFBSurface *dfb_surface = NULL;
487 DFBWindowDescription desc;
490 memset(&desc, 0, sizeof(DFBWindowDescription));
491 desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
496 desc.caps = DWCAPS_ALPHACHANNEL;
498 DFBCHECK(_layer->CreateWindow(_layer, &desc, &dfb_window));
500 dfb_window->AttachEventBuffer(dfb_window, _window_event);
501 dfb_window->SetOptions(dfb_window,DWOP_NONE);
502 dfb_window->SetOpacity(dfb_window, 0xFF);
504 DFBCHECK(dfb_window->GetID(dfb_window, &id));
505 DFBCHECK(dfb_window->GetSurface(dfb_window,&dfb_surface));
507 window = malloc(sizeof(Ecore_DirectFB_Window));
509 window->window = dfb_window;
510 window->surface = dfb_surface;
511 window->cursor = NULL;
517 ecore_directfb_window_del(Ecore_DirectFB_Window *ecore_window)
519 DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
520 DFBCHECK(ecore_window->window->Release(ecore_window->window));
526 ecore_directfb_window_move(Ecore_DirectFB_Window *ecore_window, int x, int y)
528 DFBCHECK(ecore_window->window->MoveTo(ecore_window->window, x, y));
532 ecore_directfb_window_resize(Ecore_DirectFB_Window *ecore_window, int w, int h)
534 DFBCHECK(ecore_window->window->Resize(ecore_window->window, w, h));
538 ecore_directfb_window_focus(Ecore_DirectFB_Window *ecore_window)
540 DFBCHECK(ecore_window->window->RequestFocus(ecore_window->window));
544 ecore_directfb_window_hide(Ecore_DirectFB_Window *ecore_window)
546 DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window,0));
551 ecore_directfb_window_show(Ecore_DirectFB_Window *ecore_window)
553 DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0xFF));
557 ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *ecore_window, int set)
559 DFBWindowOptions opts;
561 DFBCHECK(ecore_window->window->GetOptions(ecore_window->window, &opts));
565 opts |= DWOP_ALPHACHANNEL;
566 DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
570 opts &= ~DWOP_SHAPED;
571 opts &= ~DWOP_ALPHACHANNEL;
572 DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
577 ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *ecore_window, int show)
581 /* create an empty cursor and set it */
582 IDirectFBSurface *cursor;
583 DFBSurfaceDescription desc;
585 memset(&desc, 0, sizeof(DFBSurfaceDescription));
586 desc.flags = (DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PIXELFORMAT);
589 desc.pixelformat = DSPF_A1;
591 DFBCHECK(_dfb->CreateSurface(_dfb,&desc,&cursor));
592 DFBCHECK(cursor->Clear(cursor,0,0,0,0));
593 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor, 0, 0));
597 /* we already have a cursor surface so set it*/
598 if(ecore_window->cursor)
600 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, ecore_window->cursor->surface, ecore_window->cursor->hot_x, ecore_window->cursor->hot_y));
602 /* or just set the default directfb cursor */
605 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
612 ecore_directfb_window_cursor_set(Ecore_DirectFB_Window *ecore_window, Ecore_DirectFB_Cursor *cursor)
614 if( (!cursor) && (ecore_window->cursor))
616 ecore_window->cursor = NULL;
617 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
622 ecore_window->cursor = cursor;
623 DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor->surface, cursor->hot_x, cursor->hot_y));
630 ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *ecore_window, int on)
632 // always release the surface (we are going to get a new one in both cases)
633 DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
636 DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_EXCLUSIVE));
637 DFBCHECK(_layer->GetSurface(_layer,&ecore_window->surface));
638 DFBCHECK(_dfb->CreateInputEventBuffer(_dfb, DICAPS_ALL, DFB_FALSE, &_input_event));
639 DFBCHECK(_input_event->CreateFileDescriptor(_input_event,&_input_event_fd));
640 /* the event of axismove sends one axis at a time, so we must store both */
641 DFBCHECK(_layer->GetCursorPosition(_layer,&_cursor_x,&_cursor_y));
643 _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);
644 _ecore_directfb_fullscreen_window_id = ecore_window->id;
648 DFBCHECK(_input_event->Release(_input_event));
649 DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED));
650 DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface));
651 ecore_main_fd_handler_del(_input_event_fd_handler_handle);
652 _ecore_directfb_fullscreen_window_id = 0;
658 ecore_directfb_window_size_get(Ecore_DirectFB_Window *ecore_window, int *w, int *h)
660 DFBCHECK(ecore_window->surface->GetSize(ecore_window->surface,w,h));
665 ecore_directfb_init(const char *name)
669 _ecore_directfb_init_count++;
670 if (_ecore_directfb_init_count > 1) return _ecore_directfb_init_count;
672 DFBCHECK(DirectFBInit(NULL,NULL));
673 DFBCHECK(DirectFBCreate(&_dfb));
675 DFBCHECK(_dfb->GetDisplayLayer(_dfb, DLID_PRIMARY, &_layer));
676 DFBCHECK(_layer->SetCooperativeLevel(_layer, DLSCL_SHARED));
679 /* window events and fd */
680 DFBCHECK(_dfb->CreateEventBuffer(_dfb, &_window_event));
681 DFBCHECK(_window_event->CreateFileDescriptor(_window_event,&_window_event_fd));
682 _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);
684 /* register ecore directfb events */
685 ECORE_DIRECTFB_EVENT_POSITION = ecore_event_type_new();
686 ECORE_DIRECTFB_EVENT_SIZE = ecore_event_type_new();;
687 ECORE_DIRECTFB_EVENT_CLOSE = ecore_event_type_new();;
688 ECORE_DIRECTFB_EVENT_DESTROYED = ecore_event_type_new();;
689 ECORE_DIRECTFB_EVENT_GOT_FOCUS = ecore_event_type_new();;
690 ECORE_DIRECTFB_EVENT_LOST_FOCUS = ecore_event_type_new();;
691 ECORE_DIRECTFB_EVENT_KEY_DOWN = ecore_event_type_new();;
692 ECORE_DIRECTFB_EVENT_KEY_UP = ecore_event_type_new();;
693 ECORE_DIRECTFB_EVENT_BUTTON_DOWN = ecore_event_type_new();;
694 ECORE_DIRECTFB_EVENT_BUTTON_UP = ecore_event_type_new();;
695 ECORE_DIRECTFB_EVENT_MOTION = ecore_event_type_new();;
696 ECORE_DIRECTFB_EVENT_ENTER = ecore_event_type_new();;
697 ECORE_DIRECTFB_EVENT_LEAVE = ecore_event_type_new();;
698 ECORE_DIRECTFB_EVENT_WHEEL = ecore_event_type_new();;
700 /* create the hash table for the keynames */
701 _ecore_directfb_key_symbols_hash = ecore_hash_new(_ecore_directfb_hash_create,_ecore_directfb_hash_compare);
702 for(i=0; i<_ecore_directfb_key_symbols_count; i++)
705 k = malloc(sizeof(struct keymap));
706 k->name = _ecore_directfb_key_symbols[i].name;
707 k->string = _ecore_directfb_key_symbols[i].string;
708 ecore_hash_set(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id, k);
710 /* create the hash for the windows(key = windowid, val = Ecore_DirectFB_Window struct) */
711 return _ecore_directfb_init_count;
715 ecore_directfb_shutdown(void)
719 _ecore_directfb_init_count--;
720 if (_ecore_directfb_init_count > 0) return _ecore_directfb_init_count;
721 if (_ecore_directfb_init_count < 0)
723 _ecore_directfb_init_count = 0;
726 ecore_main_fd_handler_del(_window_event_fd_handler_handle);
727 /* free the key symbol names hash */
728 for(i=0; i<_ecore_directfb_key_symbols_count; i++)
731 k = ecore_hash_get(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id);
732 ecore_hash_remove(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id);
736 if(_ecore_directfb_fullscreen_window_id)
738 DFBCHECK(_input_event->Release(_input_event));
739 ecore_main_fd_handler_del(_input_event_fd_handler_handle);
741 DFBCHECK(_window_event->Release(_window_event));
742 DFBCHECK(_layer->Release(_layer));
743 DFBCHECK(_dfb->Release(_dfb));