/* * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #ifdef HAVE_CONFIG_H # include #endif /* ifdef HAVE_CONFIG_H */ #include #include #include "Ecore_DirectFB.h" #include "ecore_directfb_private.h" #include "ecore_directfb_keys.h" #include "Ecore.h" #include "ecore_private.h" /* ecore_directfb */ /******************/ /* About */ /* with this you can create windows of directfb and handle events through ecore * TODO: * - handle all event types * - * */ int _ecore_directfb_log_dom = -1; static int _ecore_directfb_init_count = 0; static int _window_event_fd = 0; static int _input_event_fd = 0; static int _ecore_directfb_fullscreen_window_id = 0; static int _cursor_x = 0; static int _cursor_y = 0; EAPI int ECORE_DIRECTFB_EVENT_POSITION = 0; EAPI int ECORE_DIRECTFB_EVENT_SIZE = 0; EAPI int ECORE_DIRECTFB_EVENT_CLOSE = 0; EAPI int ECORE_DIRECTFB_EVENT_DESTROYED = 0; EAPI int ECORE_DIRECTFB_EVENT_GOT_FOCUS = 0; EAPI int ECORE_DIRECTFB_EVENT_LOST_FOCUS = 0; EAPI int ECORE_DIRECTFB_EVENT_KEY_DOWN = 0; EAPI int ECORE_DIRECTFB_EVENT_KEY_UP = 0; EAPI int ECORE_DIRECTFB_EVENT_BUTTON_DOWN = 0; EAPI int ECORE_DIRECTFB_EVENT_BUTTON_UP = 0; EAPI int ECORE_DIRECTFB_EVENT_MOTION = 0; EAPI int ECORE_DIRECTFB_EVENT_ENTER = 0; EAPI int ECORE_DIRECTFB_EVENT_LEAVE = 0; EAPI int ECORE_DIRECTFB_EVENT_WHEEL = 0; static Ecore_Fd_Handler *_window_event_fd_handler_handle = NULL; static Ecore_Fd_Handler *_input_event_fd_handler_handle = NULL; /* this hash is to store all the possible key names for fast lookup */ static Eina_Hash *_ecore_directfb_key_symbols_hash = NULL; static IDirectFB *_dfb = NULL; // the main interface static IDirectFBEventBuffer *_window_event; // the main event buffer (all windows are attached to this) static IDirectFBEventBuffer *_input_event; // the main event buffer (all windows are attached to this) static IDirectFBDisplayLayer *_layer; // the main layer static DFBResult _err; // usefull for DFBCHECK /*******************/ /* local functions */ /*******************/ /* free ecore directfb events functions */ /****************************************/ static void _ecore_directfb_event_free_key_down(void *data __UNUSED__, void *ev) { Ecore_DirectFB_Event_Key_Up *e; e = ev; if(e->name) free(e->name); if (e->string) free(e->string); if (e->key_compose) free(e->key_compose); free(e); } /* _ecore_directfb_event_free_key_down */ static void _ecore_directfb_event_free_key_up(void *data __UNUSED__, void *ev) { Ecore_DirectFB_Event_Key_Up *e; e = ev; if(e->name) free(e->name); if (e->string) free(e->string); if (e->key_compose) free(e->key_compose); free(e); } /* _ecore_directfb_event_free_key_up */ /* directfb window input events handler */ /****************************************/ static void _ecore_directfb_event_handle_motion(DFBEvent *evt) { Ecore_DirectFB_Event_Motion *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Motion)); switch(evt->clazz) { case DFEC_INPUT: e->modifiers = 0; switch(evt->input.axis) { case DIAI_X: e->x = _cursor_x = evt->input.axisabs; e->y = _cursor_y; break; case DIAI_Y: e->y = _cursor_y = evt->input.axisabs; e->x = _cursor_x; break; case DIAI_Z: //_ecore_directfb_event_handle_wheel(evt); return; default: return; } /* switch */ e->win = _ecore_directfb_fullscreen_window_id; e->time = 0; break; case DFEC_WINDOW: e->modifiers = 0; e->x = evt->window.x; e->y = evt->window.y; e->win = evt->window.window_id; e->time = 0; break; default: break; } /* switch */ ecore_event_add(ECORE_DIRECTFB_EVENT_MOTION, e, NULL, NULL); } /* _ecore_directfb_event_handle_motion */ static void _ecore_directfb_event_handle_key_down(DFBEvent *evt) { Ecore_DirectFB_Event_Key_Down *e; unsigned int key_symbol; struct keymap *k; e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Down)); switch(evt->clazz) { case DFEC_INPUT: key_symbol = evt->input.key_symbol; k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol); if(!k) { ERR("Symbol %0X of class DFEC_INPUT not found.", evt->input.key_symbol); return; } e->name = strdup(k->name); e->string = strdup(k->string); e->key_compose = NULL; e->win = _ecore_directfb_fullscreen_window_id; e->time = 0; break; case DFEC_WINDOW: key_symbol = evt->window.key_symbol; k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol); if(!k) { ERR("Symbol %0X of class DFEC_WINDOW not found.", evt->window.key_symbol); return; } e->name = strdup(k->name); e->string = strdup(k->string); e->key_compose = NULL; e->win = evt->window.window_id; e->time = 0; break; default: break; } /* switch */ ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, e, _ecore_directfb_event_free_key_down, NULL); } /* _ecore_directfb_event_handle_key_down */ static void _ecore_directfb_event_handle_key_up(DFBEvent *evt) { Ecore_DirectFB_Event_Key_Up *e; unsigned int key_symbol; struct keymap *k; e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Up)); switch(evt->clazz) { case DFEC_INPUT: key_symbol = evt->input.key_symbol; k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol); if(!k) { ERR("Symbol %0X of class DFEC_INPUT not found.", evt->input.key_symbol); return; } e->name = strdup(k->name); e->string = strdup(k->string); e->key_compose = NULL; e->win = _ecore_directfb_fullscreen_window_id; e->time = 0; break; case DFEC_WINDOW: key_symbol = evt->window.key_symbol; k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol); if(!k) { ERR("Symbol %0X of class DFEC_WINDOW not found.", evt->window.key_symbol); return; } e->name = strdup(k->name); e->string = strdup(k->string); e->key_compose = NULL; e->win = evt->window.window_id; e->time = 0; break; default: break; } /* switch */ ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_UP, e, _ecore_directfb_event_free_key_up, NULL); } /* _ecore_directfb_event_handle_key_up */ static void _ecore_directfb_event_handle_button_down(DFBEvent *evt) { Ecore_DirectFB_Event_Button_Down *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Down)); switch(evt->clazz) { case DFEC_INPUT: e->button = evt->input.button + 1; e->modifiers = 0; DFBCHECK(_layer->GetCursorPosition(_layer,&e->x,&e->y)); e->x = _cursor_x; e->y = _cursor_y; e->win = _ecore_directfb_fullscreen_window_id; e->time = 0; break; case DFEC_WINDOW: e->button = evt->window.button + 1; e->modifiers = 0; e->x = evt->window.x; e->y = evt->window.y; e->win = evt->window.window_id; e->time = 0; break; default: break; } /* switch */ ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, e, NULL, NULL); } /* _ecore_directfb_event_handle_button_down */ static void _ecore_directfb_event_handle_button_up(DFBEvent *evt) { Ecore_DirectFB_Event_Button_Up *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Up)); switch(evt->clazz) { case DFEC_INPUT: e->button = evt->input.button + 1; e->modifiers = 0; e->x = _cursor_x; e->y = _cursor_y; e->win = _ecore_directfb_fullscreen_window_id; e->time = 0; break; case DFEC_WINDOW: e->button = evt->window.button + 1; e->modifiers = 0; e->x = evt->window.x; e->y = evt->window.y; e->win = evt->window.window_id; e->time = 0; break; default: break; } /* switch */ ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, e, NULL, NULL); } /* _ecore_directfb_event_handle_button_up */ static void _ecore_directfb_event_handle_enter(DFBWindowEvent *evt) { Ecore_DirectFB_Event_Enter *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Enter)); e->modifiers = 0; e->x = evt->x; e->y = evt->y; e->win = evt->window_id; e->time = 0; ecore_event_add(ECORE_DIRECTFB_EVENT_ENTER, e, NULL, NULL); } /* _ecore_directfb_event_handle_enter */ static void _ecore_directfb_event_handle_leave(DFBWindowEvent *evt) { Ecore_DirectFB_Event_Leave *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Leave)); e->modifiers = 0; e->x = evt->x; e->y = evt->y; e->win = evt->window_id; e->time = 0; ecore_event_add(ECORE_DIRECTFB_EVENT_LEAVE, e, NULL, NULL); } /* _ecore_directfb_event_handle_leave */ static void _ecore_directfb_event_handle_wheel(DFBWindowEvent *evt) { Ecore_DirectFB_Event_Wheel *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Wheel)); // currently there's no direction (only up/down); e->direction = 0; e->z = evt->step; e->modifiers = 0; e->win = evt->window_id; e->time = 0; ecore_event_add(ECORE_DIRECTFB_EVENT_WHEEL, e, NULL, NULL); } /* _ecore_directfb_event_handle_wheel */ static void _ecore_directfb_event_handle_got_focus(DFBWindowEvent *evt) { Ecore_DirectFB_Event_Got_Focus *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Got_Focus)); e->win = evt->window_id; e->time = 0; ecore_event_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, e, NULL, NULL); } /* _ecore_directfb_event_handle_got_focus */ static void _ecore_directfb_event_handle_lost_focus(DFBWindowEvent *evt) { Ecore_DirectFB_Event_Lost_Focus *e; e = calloc(1, sizeof(Ecore_DirectFB_Event_Lost_Focus)); e->win = evt->window_id; e->time = 0; ecore_event_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, e, NULL, NULL); } /* _ecore_directfb_event_handle_lost_focus */ /* inputs and windows fds handlers */ /***********************************/ /* TODO fix this to handle windows and input events (fullscreen/window mode) * in fullscreen theres no window_id so get the id from a global var (only one fullscreen * window at a time */ static Eina_Bool _ecore_directfb_input_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__) { DFBEvent evt; int v = 0; v = read(_input_event_fd, &evt, sizeof(DFBEvent)); if (v < 0) return EINA_TRUE; if (v < 1) return EINA_TRUE; /* we are getting duplicate events, only parse if we are in fullscreen */ //if(_ecore_directfb_fullscreen_window_id == 0) break; if(evt.input.type == DIET_KEYPRESS) _ecore_directfb_event_handle_key_down(&evt); if(evt.input.type == DIET_KEYRELEASE) _ecore_directfb_event_handle_key_up(&evt); if(evt.input.type == DIET_BUTTONPRESS) _ecore_directfb_event_handle_button_down(&evt); if(evt.input.type == DIET_BUTTONRELEASE) _ecore_directfb_event_handle_button_up(&evt); if(evt.input.type == DIET_AXISMOTION) _ecore_directfb_event_handle_motion(&evt); return EINA_TRUE; } /* _ecore_directfb_input_event_fd_handler */ static Eina_Bool _ecore_directfb_window_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__) { DFBEvent evt; int v = 0; v = read(_window_event_fd, &evt, sizeof(DFBEvent)); if (v < 0) return EINA_TRUE; if (v < 1) return EINA_TRUE; if(evt.window.type & DWET_POSITION) INF("position"); if(evt.window.type & DWET_SIZE) INF("size"); if(evt.window.type & DWET_CLOSE) INF("close"); if(evt.window.type & DWET_DESTROYED) INF("destroyed"); if(evt.window.type & DWET_GOTFOCUS) _ecore_directfb_event_handle_got_focus(&evt.window); if(evt.window.type & DWET_LOSTFOCUS) _ecore_directfb_event_handle_lost_focus(&evt.window); if(evt.window.type & DWET_KEYDOWN) _ecore_directfb_event_handle_key_down(&evt); if(evt.window.type & DWET_KEYUP) _ecore_directfb_event_handle_key_up(&evt); if(evt.window.type & DWET_BUTTONDOWN) _ecore_directfb_event_handle_button_down(&evt); if(evt.window.type & DWET_BUTTONUP) _ecore_directfb_event_handle_button_up(&evt); if(evt.window.type & DWET_MOTION) _ecore_directfb_event_handle_motion(&evt); if(evt.window.type & DWET_ENTER) _ecore_directfb_event_handle_enter(&evt.window); if(evt.window.type & DWET_LEAVE) _ecore_directfb_event_handle_leave(&evt.window); if(evt.window.type & DWET_WHEEL) _ecore_directfb_event_handle_wheel(&evt.window); return EINA_TRUE; } /* _ecore_directfb_window_event_fd_handler */ /* api functions */ /*****************/ EAPI IDirectFB * ecore_directfb_interface_get(void) { return _dfb; } /* ecore_directfb_interface_get */ EAPI Ecore_DirectFB_Window * ecore_directfb_window_new(int x, int y, int w, int h) { Ecore_DirectFB_Window *window; IDirectFBWindow *dfb_window; IDirectFBSurface *dfb_surface = NULL; DFBWindowDescription desc; DFBWindowID id; memset(&desc, 0, sizeof(DFBWindowDescription)); desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS); desc.posx = x; desc.posy = y; desc.width = w; desc.height = h; desc.caps = DWCAPS_ALPHACHANNEL; DFBCHECK(_layer->CreateWindow(_layer, &desc, &dfb_window)); dfb_window->AttachEventBuffer(dfb_window, _window_event); dfb_window->SetOptions(dfb_window,DWOP_NONE); dfb_window->SetOpacity(dfb_window, 0xFF); DFBCHECK(dfb_window->GetID(dfb_window, &id)); DFBCHECK(dfb_window->GetSurface(dfb_window,&dfb_surface)); window = malloc(sizeof(Ecore_DirectFB_Window)); window->id = id; window->window = dfb_window; window->surface = dfb_surface; window->cursor = NULL; return window; } /* ecore_directfb_window_new */ EAPI void ecore_directfb_window_free(Ecore_DirectFB_Window *ecore_window) { DFBCHECK(ecore_window->surface->Release(ecore_window->surface)); DFBCHECK(ecore_window->window->Release(ecore_window->window)); free(ecore_window); } /* ecore_directfb_window_free */ EAPI void ecore_directfb_window_move(Ecore_DirectFB_Window *ecore_window, int x, int y) { DFBCHECK(ecore_window->window->MoveTo(ecore_window->window, x, y)); } /* ecore_directfb_window_move */ EAPI void ecore_directfb_window_resize(Ecore_DirectFB_Window *ecore_window, int w, int h) { DFBCHECK(ecore_window->window->Resize(ecore_window->window, w, h)); } /* ecore_directfb_window_resize */ EAPI void ecore_directfb_window_focus(Ecore_DirectFB_Window *ecore_window) { DFBCHECK(ecore_window->window->RequestFocus(ecore_window->window)); } /* ecore_directfb_window_focus */ EAPI void ecore_directfb_window_hide(Ecore_DirectFB_Window *ecore_window) { DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window,0)); } /* ecore_directfb_window_hide */ EAPI void ecore_directfb_window_show(Ecore_DirectFB_Window *ecore_window) { DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0xFF)); } /* ecore_directfb_window_show */ EAPI void ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *ecore_window, int set) { DFBWindowOptions opts; DFBCHECK(ecore_window->window->GetOptions(ecore_window->window, &opts)); if(set) { opts |= DWOP_SHAPED; opts |= DWOP_ALPHACHANNEL; DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts)); } else { opts &= ~DWOP_SHAPED; opts &= ~DWOP_ALPHACHANNEL; DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts)); } } /* ecore_directfb_window_shaped_set */ EAPI void ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *ecore_window, int show) { if(!show) { /* create an empty cursor and set it */ IDirectFBSurface *cursor; DFBSurfaceDescription desc; memset(&desc, 0, sizeof(DFBSurfaceDescription)); desc.flags = (DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PIXELFORMAT); desc.width = 1; desc.height = 1; desc.pixelformat = DSPF_A1; DFBCHECK(_dfb->CreateSurface(_dfb,&desc,&cursor)); DFBCHECK(cursor->Clear(cursor,0,0,0,0)); DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor, 0, 0)); } else { /* we already have a cursor surface so set it*/ if(ecore_window->cursor) { DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, ecore_window->cursor->surface, ecore_window->cursor->hot_x, ecore_window->cursor->hot_y)); } /* or just set the default directfb cursor */ else { DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0)); } } } /* ecore_directfb_window_cursor_show */ EAPI void ecore_directfb_window_cursor_set(Ecore_DirectFB_Window *ecore_window, Ecore_DirectFB_Cursor *cursor) { if((!cursor) && (ecore_window->cursor)) { ecore_window->cursor = NULL; DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0)); return; } if(cursor) { ecore_window->cursor = cursor; DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor->surface, cursor->hot_x, cursor->hot_y)); } } /* ecore_directfb_window_cursor_set */ EAPI void ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *ecore_window, int on) { // always release the surface (we are going to get a new one in both cases) DFBCHECK(ecore_window->surface->Release(ecore_window->surface)); if(on) { DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_EXCLUSIVE)); DFBCHECK(_layer->GetSurface(_layer,&ecore_window->surface)); DFBCHECK(_dfb->CreateInputEventBuffer(_dfb, DICAPS_ALL, DFB_FALSE, &_input_event)); DFBCHECK(_input_event->CreateFileDescriptor(_input_event,&_input_event_fd)); /* the event of axismove sends one axis at a time, so we must store both */ DFBCHECK(_layer->GetCursorPosition(_layer,&_cursor_x,&_cursor_y)); _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); _ecore_directfb_fullscreen_window_id = ecore_window->id; } else { ecore_main_fd_handler_del(_input_event_fd_handler_handle); DFBCHECK(_input_event->Release(_input_event)); DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED)); DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface)); _ecore_directfb_fullscreen_window_id = 0; } } /* ecore_directfb_window_fullscreen_set */ EAPI void ecore_directfb_window_size_get(Ecore_DirectFB_Window *ecore_window, int *w, int *h) { DFBCHECK(ecore_window->surface->GetSize(ecore_window->surface,w,h)); return; } /* ecore_directfb_window_size_get */ EAPI int ecore_directfb_init(const char *name __UNUSED__) { int i = 0; if (++_ecore_directfb_init_count != 1) return _ecore_directfb_init_count; _ecore_directfb_log_dom = eina_log_domain_register("EcoreDirectFB", ECORE_DIRECTFB_DEFAULT_LOG_COLOR); if(_ecore_directfb_log_dom < 0) { EINA_LOG_ERR("Impossible to create a log domain for the Ecore directFB module."); return _ecore_directfb_init_count--; } DFBCHECK(DirectFBInit(NULL,NULL)); DFBCHECK(DirectFBCreate(&_dfb)); DFBCHECK(_dfb->GetDisplayLayer(_dfb, DLID_PRIMARY, &_layer)); DFBCHECK(_layer->SetCooperativeLevel(_layer, DLSCL_SHARED)); /* window events and fd */ DFBCHECK(_dfb->CreateEventBuffer(_dfb, &_window_event)); DFBCHECK(_window_event->CreateFileDescriptor(_window_event,&_window_event_fd)); _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); /* register ecore directfb events */ ECORE_DIRECTFB_EVENT_POSITION = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_SIZE = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_CLOSE = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_DESTROYED = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_GOT_FOCUS = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_LOST_FOCUS = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_KEY_DOWN = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_KEY_UP = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_BUTTON_DOWN = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_BUTTON_UP = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_MOTION = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_ENTER = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_LEAVE = ecore_event_type_new(); ECORE_DIRECTFB_EVENT_WHEEL = ecore_event_type_new(); /* create the hash table for the keynames */ _ecore_directfb_key_symbols_hash = eina_hash_int32_new(free); for(i = 0; i < _ecore_directfb_key_symbols_count; i++) { struct keymap *k; k = malloc(sizeof(struct keymap)); k->name = _ecore_directfb_key_symbols[i].name; k->string = _ecore_directfb_key_symbols[i].string; eina_hash_add(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id, k); } /* create the hash for the windows(key = windowid, val = Ecore_DirectFB_Window struct) */ return _ecore_directfb_init_count; } /* ecore_directfb_init */ EAPI int ecore_directfb_shutdown(void) { if (--_ecore_directfb_init_count != 0) return _ecore_directfb_init_count; ecore_main_fd_handler_del(_window_event_fd_handler_handle); eina_hash_free(_ecore_directfb_key_symbols_hash); if(_ecore_directfb_fullscreen_window_id) { DFBCHECK(_input_event->Release(_input_event)); ecore_main_fd_handler_del(_input_event_fd_handler_handle); } DFBCHECK(_window_event->Release(_window_event)); DFBCHECK(_layer->Release(_layer)); DFBCHECK(_dfb->Release(_dfb)); eina_log_domain_unregister(_ecore_directfb_log_dom); _ecore_directfb_log_dom = -1; return _ecore_directfb_init_count; } /* ecore_directfb_shutdown */