Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_directfb / ecore_directfb.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4
5 #include <stdio.h>
6 #include <string.h>
7
8 #include "Ecore_DirectFB.h"
9 #include "ecore_directfb_private.h"
10 #include "ecore_directfb_keys.h"
11 #include "Ecore.h"
12 #include "ecore_private.h"
13
14 /* ecore_directfb */
15 /******************/
16 /* About */
17 /* with this you can create windows of directfb and handle events through ecore
18  * TODO:
19  * - handle all event types
20  * -
21  * */
22 int _ecore_directfb_log_dom = -1;
23
24 static int _ecore_directfb_init_count = 0;
25
26 static int _window_event_fd = 0;
27 static int _input_event_fd = 0;
28
29 static int _ecore_directfb_fullscreen_window_id = 0;
30 static int _cursor_x = 0;
31 static int _cursor_y = 0;
32
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;
47
48 static Ecore_Fd_Handler *_window_event_fd_handler_handle = NULL;
49 static Ecore_Fd_Handler *_input_event_fd_handler_handle = NULL;
50
51 /* this hash is to store all the possible key names for fast lookup */
52 static Eina_Hash *_ecore_directfb_key_symbols_hash = NULL;
53
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
59
60 /*******************/
61 /* local functions */
62 /*******************/
63
64 /* free ecore directfb events functions */
65 /****************************************/
66
67 static void
68 _ecore_directfb_event_free_key_down(void *data __UNUSED__, void *ev)
69 {
70    Ecore_DirectFB_Event_Key_Up *e;
71
72    e = ev;
73    if(e->name)
74       free(e->name);
75
76    if (e->string)
77       free(e->string);
78
79    if (e->key_compose)
80       free(e->key_compose);
81
82    free(e);
83 }
84
85 static void
86 _ecore_directfb_event_free_key_up(void *data __UNUSED__, void *ev)
87 {
88    Ecore_DirectFB_Event_Key_Up *e;
89
90    e = ev;
91    if(e->name)
92       free(e->name);
93
94    if (e->string)
95       free(e->string);
96
97    if (e->key_compose)
98       free(e->key_compose);
99
100    free(e);
101 }
102
103 /* directfb window input events handler */
104 /****************************************/
105
106 static void
107 _ecore_directfb_event_handle_motion(DFBEvent *evt)
108 {
109    Ecore_DirectFB_Event_Motion *e;
110    e = calloc(1, sizeof(Ecore_DirectFB_Event_Motion));
111
112    switch(evt->clazz)
113      {
114       case DFEC_INPUT:
115          e->modifiers = 0;
116          switch(evt->input.axis)
117            {
118             case DIAI_X:
119                e->x = _cursor_x = evt->input.axisabs;
120                e->y = _cursor_y;
121                break;
122
123             case DIAI_Y:
124                e->y = _cursor_y = evt->input.axisabs;
125                e->x = _cursor_x;
126                break;
127
128             case DIAI_Z:
129                //_ecore_directfb_event_handle_wheel(evt);
130                return;
131
132             default:
133                return;
134            }
135          e->win = _ecore_directfb_fullscreen_window_id;
136          e->time = 0;
137          break;
138
139       case DFEC_WINDOW:
140          e->modifiers = 0;
141          e->x = evt->window.x;
142          e->y = evt->window.y;
143          e->win = evt->window.window_id;
144          e->time = 0;
145          break;
146
147       default:
148          break;
149      }
150    ecore_event_add(ECORE_DIRECTFB_EVENT_MOTION, e, NULL, NULL);
151 }
152
153 static void
154 _ecore_directfb_event_handle_key_down(DFBEvent *evt)
155 {
156    Ecore_DirectFB_Event_Key_Down *e;
157    unsigned int key_symbol;
158    struct keymap *k;
159
160    e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Down));
161
162    switch(evt->clazz)
163      {
164       case DFEC_INPUT:
165          key_symbol = evt->input.key_symbol;
166          k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
167
168          if(!k)
169            {
170               ERR("Symbol %0X of class DFEC_INPUT not found.", evt->input.key_symbol);
171               return;
172            }
173
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;
178          e->time = 0;
179          break;
180
181       case DFEC_WINDOW:
182          key_symbol = evt->window.key_symbol;
183          k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
184
185          if(!k)
186            {
187               ERR("Symbol %0X of class DFEC_WINDOW not found.", evt->window.key_symbol);
188               return;
189            }
190
191          e->name = strdup(k->name);
192          e->string = strdup(k->string);
193          e->key_compose = NULL;
194          e->win = evt->window.window_id;
195          e->time = 0;
196          break;
197
198       default:
199          break;
200      }
201
202    ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, e, _ecore_directfb_event_free_key_down, NULL);
203 }
204
205 static void
206 _ecore_directfb_event_handle_key_up(DFBEvent *evt)
207 {
208    Ecore_DirectFB_Event_Key_Up *e;
209    unsigned int key_symbol;
210    struct keymap *k;
211
212    e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Up));
213
214    switch(evt->clazz)
215      {
216       case DFEC_INPUT:
217          key_symbol = evt->input.key_symbol;
218          k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
219
220          if(!k)
221            {
222               ERR("Symbol %0X of class DFEC_INPUT not found.", evt->input.key_symbol);
223               return;
224            }
225
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;
230          e->time = 0;
231          break;
232
233       case DFEC_WINDOW:
234          key_symbol = evt->window.key_symbol;
235          k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
236
237          if(!k)
238            {
239               ERR("Symbol %0X of class DFEC_WINDOW not found.", evt->window.key_symbol);
240               return;
241            }
242
243          e->name = strdup(k->name);
244          e->string = strdup(k->string);
245          e->key_compose = NULL;
246          e->win = evt->window.window_id;
247          e->time = 0;
248          break;
249
250       default:
251          break;
252      }
253    ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_UP, e, _ecore_directfb_event_free_key_up, NULL);
254 }
255
256 static void
257 _ecore_directfb_event_handle_button_down(DFBEvent *evt)
258 {
259    Ecore_DirectFB_Event_Button_Down *e;
260    e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Down));
261
262    switch(evt->clazz)
263      {
264       case DFEC_INPUT:
265          e->button = evt->input.button + 1;
266          e->modifiers = 0;
267          DFBCHECK(_layer->GetCursorPosition(_layer,&e->x,&e->y));
268          e->x = _cursor_x;
269          e->y = _cursor_y;
270          e->win = _ecore_directfb_fullscreen_window_id;
271          e->time = 0;
272
273          break;
274
275       case DFEC_WINDOW:
276          e->button = evt->window.button + 1;
277          e->modifiers = 0;
278          e->x = evt->window.x;
279          e->y = evt->window.y;
280          e->win = evt->window.window_id;
281          e->time = 0;
282          break;
283
284       default:
285          break;
286      }
287
288    ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, e, NULL, NULL);
289 }
290
291 static void
292 _ecore_directfb_event_handle_button_up(DFBEvent *evt)
293 {
294    Ecore_DirectFB_Event_Button_Up *e;
295    e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Up));
296
297    switch(evt->clazz)
298      {
299       case DFEC_INPUT:
300          e->button = evt->input.button + 1;
301          e->modifiers = 0;
302          e->x = _cursor_x;
303          e->y = _cursor_y;
304          e->win = _ecore_directfb_fullscreen_window_id;
305          e->time = 0;
306
307          break;
308
309       case DFEC_WINDOW:
310          e->button = evt->window.button + 1;
311          e->modifiers = 0;
312          e->x = evt->window.x;
313          e->y = evt->window.y;
314          e->win = evt->window.window_id;
315          e->time = 0;
316          break;
317
318       default:
319          break;
320      }
321    ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, e, NULL, NULL);
322 }
323
324 static void
325 _ecore_directfb_event_handle_enter(DFBWindowEvent *evt)
326 {
327    Ecore_DirectFB_Event_Enter *e;
328    e = calloc(1, sizeof(Ecore_DirectFB_Event_Enter));
329
330    e->modifiers = 0;
331    e->x = evt->x;
332    e->y = evt->y;
333    e->win = evt->window_id;
334    e->time = 0;
335
336    ecore_event_add(ECORE_DIRECTFB_EVENT_ENTER, e, NULL, NULL);
337 }
338
339 static void
340 _ecore_directfb_event_handle_leave(DFBWindowEvent *evt)
341 {
342    Ecore_DirectFB_Event_Leave *e;
343    e = calloc(1, sizeof(Ecore_DirectFB_Event_Leave));
344
345    e->modifiers = 0;
346    e->x = evt->x;
347    e->y = evt->y;
348    e->win = evt->window_id;
349    e->time = 0;
350
351    ecore_event_add(ECORE_DIRECTFB_EVENT_LEAVE, e, NULL, NULL);
352 }
353
354 static void
355 _ecore_directfb_event_handle_wheel(DFBWindowEvent *evt)
356 {
357    Ecore_DirectFB_Event_Wheel *e;
358    e = calloc(1, sizeof(Ecore_DirectFB_Event_Wheel));
359
360    // currently there's no direction (only up/down);
361    e->direction = 0;
362    e->z = evt->step;
363    e->modifiers = 0;
364    e->win = evt->window_id;
365    e->time = 0;
366
367    ecore_event_add(ECORE_DIRECTFB_EVENT_WHEEL, e, NULL, NULL);
368 }
369
370 static void
371 _ecore_directfb_event_handle_got_focus(DFBWindowEvent *evt)
372 {
373    Ecore_DirectFB_Event_Got_Focus *e;
374    e = calloc(1, sizeof(Ecore_DirectFB_Event_Got_Focus));
375
376    e->win = evt->window_id;
377    e->time = 0;
378
379    ecore_event_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, e, NULL, NULL);
380 }
381
382 static void
383 _ecore_directfb_event_handle_lost_focus(DFBWindowEvent *evt)
384 {
385    Ecore_DirectFB_Event_Lost_Focus *e;
386    e = calloc(1, sizeof(Ecore_DirectFB_Event_Lost_Focus));
387
388    e->win = evt->window_id;
389    e->time = 0;
390
391    ecore_event_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, e, NULL, NULL);
392 }
393
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 */
399
400 static Eina_Bool
401 _ecore_directfb_input_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
402 {
403    DFBEvent evt;
404    int v = 0;
405
406    v = read(_input_event_fd, &evt, sizeof(DFBEvent));
407    if (v < 0)
408       return EINA_TRUE;
409
410    if (v < 1)
411       return EINA_TRUE;
412
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);
417
418    if(evt.input.type == DIET_KEYRELEASE)
419       _ecore_directfb_event_handle_key_up(&evt);
420
421    if(evt.input.type == DIET_BUTTONPRESS)
422       _ecore_directfb_event_handle_button_down(&evt);
423
424    if(evt.input.type == DIET_BUTTONRELEASE)
425       _ecore_directfb_event_handle_button_up(&evt);
426
427    if(evt.input.type == DIET_AXISMOTION)
428       _ecore_directfb_event_handle_motion(&evt);
429
430    return EINA_TRUE;
431 }
432
433 static Eina_Bool
434 _ecore_directfb_window_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
435 {
436    DFBEvent evt;
437    int v = 0;
438
439    v = read(_window_event_fd, &evt, sizeof(DFBEvent));
440    if (v < 0)
441       return EINA_TRUE;
442
443    if (v < 1)
444       return EINA_TRUE;
445
446    if(evt.window.type & DWET_POSITION)
447       INF("position");
448
449    if(evt.window.type & DWET_SIZE)
450       INF("size");
451
452    if(evt.window.type & DWET_CLOSE)
453       INF("close");
454
455    if(evt.window.type & DWET_DESTROYED)
456       INF("destroyed");
457
458    if(evt.window.type & DWET_GOTFOCUS)
459       _ecore_directfb_event_handle_got_focus(&evt.window);
460
461    if(evt.window.type & DWET_LOSTFOCUS)
462       _ecore_directfb_event_handle_lost_focus(&evt.window);
463
464    if(evt.window.type & DWET_KEYDOWN)
465       _ecore_directfb_event_handle_key_down(&evt);
466
467    if(evt.window.type & DWET_KEYUP)
468       _ecore_directfb_event_handle_key_up(&evt);
469
470    if(evt.window.type & DWET_BUTTONDOWN)
471       _ecore_directfb_event_handle_button_down(&evt);
472
473    if(evt.window.type & DWET_BUTTONUP)
474       _ecore_directfb_event_handle_button_up(&evt);
475
476    if(evt.window.type & DWET_MOTION)
477       _ecore_directfb_event_handle_motion(&evt);
478
479    if(evt.window.type & DWET_ENTER)
480       _ecore_directfb_event_handle_enter(&evt.window);
481
482    if(evt.window.type & DWET_LEAVE)
483       _ecore_directfb_event_handle_leave(&evt.window);
484
485    if(evt.window.type & DWET_WHEEL)
486       _ecore_directfb_event_handle_wheel(&evt.window);
487
488    return EINA_TRUE;
489 }
490
491 /* api functions */
492 /*****************/
493
494 EAPI IDirectFB *
495 ecore_directfb_interface_get(void)
496 {
497    return _dfb;
498 }
499
500 EAPI Ecore_DirectFB_Window *
501 ecore_directfb_window_new(int x, int y, int w, int h)
502 {
503    Ecore_DirectFB_Window *window;
504    IDirectFBWindow *dfb_window;
505    IDirectFBSurface *dfb_surface = NULL;
506    DFBWindowDescription desc;
507    DFBWindowID id;
508
509    memset(&desc, 0, sizeof(DFBWindowDescription));
510    desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
511    desc.posx = x;
512    desc.posy = y;
513    desc.width = w;
514    desc.height = h;
515    desc.caps = DWCAPS_ALPHACHANNEL;
516
517    DFBCHECK(_layer->CreateWindow(_layer, &desc, &dfb_window));
518
519    dfb_window->AttachEventBuffer(dfb_window, _window_event);
520    dfb_window->SetOptions(dfb_window,DWOP_NONE);
521    dfb_window->SetOpacity(dfb_window, 0xFF);
522
523    DFBCHECK(dfb_window->GetID(dfb_window, &id));
524    DFBCHECK(dfb_window->GetSurface(dfb_window,&dfb_surface));
525
526    window = malloc(sizeof(Ecore_DirectFB_Window));
527    window->id = id;
528    window->window = dfb_window;
529    window->surface = dfb_surface;
530    window->cursor = NULL;
531
532    return window;
533 }
534
535 EAPI void
536 ecore_directfb_window_free(Ecore_DirectFB_Window *ecore_window)
537 {
538    DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
539    DFBCHECK(ecore_window->window->Release(ecore_window->window));
540    free(ecore_window);
541 }
542
543 EAPI void
544 ecore_directfb_window_move(Ecore_DirectFB_Window *ecore_window, int x, int y)
545 {
546    DFBCHECK(ecore_window->window->MoveTo(ecore_window->window, x, y));
547 }
548
549 EAPI void
550 ecore_directfb_window_resize(Ecore_DirectFB_Window *ecore_window, int w, int h)
551 {
552    DFBCHECK(ecore_window->window->Resize(ecore_window->window, w, h));
553 }
554
555 EAPI void
556 ecore_directfb_window_focus(Ecore_DirectFB_Window *ecore_window)
557 {
558    DFBCHECK(ecore_window->window->RequestFocus(ecore_window->window));
559 }
560
561 EAPI void
562 ecore_directfb_window_hide(Ecore_DirectFB_Window *ecore_window)
563 {
564    DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0));
565 }
566
567 EAPI void
568 ecore_directfb_window_show(Ecore_DirectFB_Window *ecore_window)
569 {
570    DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0xFF));
571 }
572
573 EAPI void
574 ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *ecore_window, Eina_Bool set)
575 {
576    DFBWindowOptions opts;
577
578    DFBCHECK(ecore_window->window->GetOptions(ecore_window->window, &opts));
579    if(set)
580      {
581         opts |= DWOP_SHAPED;
582         opts |= DWOP_ALPHACHANNEL;
583         DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
584      }
585    else
586      {
587         opts &= ~DWOP_SHAPED;
588         opts &= ~DWOP_ALPHACHANNEL;
589         DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
590      }
591 }
592
593 EAPI void
594 ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *ecore_window, Eina_Bool show)
595 {
596    if(!show)
597      {
598         /* create an empty cursor and set it */
599         IDirectFBSurface *cursor;
600         DFBSurfaceDescription desc;
601
602         memset(&desc, 0, sizeof(DFBSurfaceDescription));
603         desc.flags = (DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PIXELFORMAT);
604         desc.width = 1;
605         desc.height = 1;
606         desc.pixelformat = DSPF_A1;
607
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));
611      }
612    else
613      {
614         /* we already have a cursor surface so set it*/
615         if(ecore_window->cursor)
616           {
617              DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, ecore_window->cursor->surface, ecore_window->cursor->hot_x, ecore_window->cursor->hot_y));
618           }
619         /* or just set the default directfb cursor */
620         else
621           {
622              DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
623           }
624      }
625 }
626
627 EAPI void
628 ecore_directfb_window_cursor_set(Ecore_DirectFB_Window *ecore_window, Ecore_DirectFB_Cursor *cursor)
629 {
630    if((!cursor) && (ecore_window->cursor))
631      {
632         ecore_window->cursor = NULL;
633         DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
634         return;
635      }
636
637    if(cursor)
638      {
639         ecore_window->cursor = cursor;
640         DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor->surface, cursor->hot_x, cursor->hot_y));
641      }
642 }
643
644 EAPI void
645 ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *ecore_window, Eina_Bool on)
646 {
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));
649    if(on)
650      {
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));
657
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;
660      }
661    else
662      {
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;
668      }
669 }
670
671 EAPI void
672 ecore_directfb_window_size_get(Ecore_DirectFB_Window *ecore_window, int *w, int *h)
673 {
674    DFBCHECK(ecore_window->surface->GetSize(ecore_window->surface,w,h));
675    return;
676 }
677
678 EAPI int
679 ecore_directfb_init(const char *name __UNUSED__)
680 {
681    int i = 0;
682
683    if (++_ecore_directfb_init_count != 1)
684       return _ecore_directfb_init_count;
685
686    _ecore_directfb_log_dom = eina_log_domain_register
687      ("ecore_directfb", ECORE_DIRECTFB_DEFAULT_LOG_COLOR);
688    if(_ecore_directfb_log_dom < 0)
689      {
690         EINA_LOG_ERR("Impossible to create a log domain for the Ecore directFB module.");
691         return _ecore_directfb_init_count--;
692      }
693
694    DFBCHECK(DirectFBInit(NULL,NULL));
695    DFBCHECK(DirectFBCreate(&_dfb));
696
697    DFBCHECK(_dfb->GetDisplayLayer(_dfb, DLID_PRIMARY, &_layer));
698    DFBCHECK(_layer->SetCooperativeLevel(_layer, DLSCL_SHARED));
699
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);
704
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();
720
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++)
724      {
725         struct keymap *k;
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);
730      }
731    /* create the hash for the windows(key = windowid, val = Ecore_DirectFB_Window struct) */
732    return _ecore_directfb_init_count;
733 }
734
735 EAPI int
736 ecore_directfb_shutdown(void)
737 {
738    if (--_ecore_directfb_init_count != 0)
739       return _ecore_directfb_init_count;
740
741    ecore_main_fd_handler_del(_window_event_fd_handler_handle);
742    eina_hash_free(_ecore_directfb_key_symbols_hash);
743
744    if(_ecore_directfb_fullscreen_window_id)
745      {
746         DFBCHECK(_input_event->Release(_input_event));
747         ecore_main_fd_handler_del(_input_event_fd_handler_handle);
748      }
749
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;
756 }
757