5 #include <tbm_bufmgr.h>
6 #include <tbm_surface.h>
9 #include "e_mod_main.h"
10 #include "eom-server-protocol.h"
11 #include "Ecore_Drm.h"
13 #define NUM_MAIN_BUF 2
16 typedef struct _E_Eom E_Eom, *E_EomPtr;
17 typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr;
18 typedef struct _E_Eom_Event_Data E_EomEventData, *E_EomEventDataPtr;
19 typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr;
20 typedef struct _E_Eom_Fake_Buffers E_EomFakeBuffers, *E_EomFakeBuffersPtr;
21 typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr;
24 struct _E_Eom_Out_Mode
33 eom_output_type_e type;
34 eom_output_mode_e mode;
37 unsigned int phys_width;
38 unsigned int phys_height;
40 tdm_output_conn_status status;
41 unsigned int mirror_run;
42 eom_output_attribute_e attribute;
43 eom_output_attribute_state_e attribute_state;
45 /* external output data */
46 char *ext_output_name;
48 E_EomOutMode src_mode;
49 E_Comp_Wl_Output *wl_output;
51 /* internal output data */
52 char *int_output_name;
54 E_EomOutMode dst_mode;
59 struct wl_global *global;
60 Eina_List *eom_clients;
68 unsigned int output_count;
72 enum wl_eom_mode eom_mode;
73 enum wl_eom_attribute eom_attribute;
74 enum wl_eom_attribute_state eom_attribute_state;
75 enum wl_eom_status eom_status;
77 /*data related to cooperating with clients */
80 /* external output data */
81 char *ext_output_name;
84 E_EomOutMode src_mode;
85 E_Comp_Wl_Output *wl_output;
87 /* internal output data */
88 char *int_output_name;
90 E_EomOutMode dst_mode;
94 struct _E_Eom_Event_Data
100 /* mirror mode data*/
101 tbm_surface_h dst_buffers[NUM_MAIN_BUF];
105 /* extended mode data */
106 Eina_List *client_buffers_list;
109 struct _E_Eom_Client_Buffer
111 E_Comp_Wl_Buffer *wl_buffer;
112 tbm_surface_h tbm_buffer;
117 struct _E_Eom_Fake_Buffers
119 tbm_surface_h fake_buffers[NUM_MAIN_BUF];
120 int current_fake_buffer;
124 static E_EomEventData g_eom_event_data;
125 E_EomPtr g_eom = NULL;
126 E_EomFakeBuffers fake_buffers;
128 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "EOM Module" };
129 static int eom_output_attributes[NUM_ATTR][NUM_ATTR] =
136 /* handle external output */
137 static E_Comp_Wl_Output *_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id);
138 static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height);
139 static tdm_output * _e_eom_hal_output_get(const char *id);
140 static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height);
141 static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height);
142 static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name);
143 /* handle internal output, pp */
144 static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height);
145 static tbm_surface_h _e_eom_root_internal_tdm_surface_get(const char *name);
146 static Eina_Bool _e_eom_pp_src_to_dst( tbm_surface_h src_buffer);
148 static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data);
149 static void _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED,
150 unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED,
153 /* clients buffers */
154 static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer);
155 static void _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer);
156 static void _e_eom_client_buffers_list_free();
157 static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list();
160 /*eom utils functions*/
161 static int _e_eom_get_time_in_mseconds();
162 static void _e_eom_create_fake_buffers(int width, int height);
164 static inline enum wl_eom_mode
165 _e_eom_get_eom_mode()
167 return g_eom->eom_mode;
171 _e_eom_set_eom_mode(enum wl_eom_mode mode)
173 g_eom->eom_mode = mode;
176 static inline enum wl_eom_attribute_state
177 _e_eom_get_eom_attribute_state()
179 return g_eom->eom_attribute_state;
183 _e_eom_set_eom_attribute_state(enum wl_eom_attribute_state attribute_state)
185 g_eom->eom_attribute_state = attribute_state;
188 static inline enum wl_eom_attribute
189 _e_eom_get_eom_attribute()
191 return g_eom->eom_attribute;
194 static inline Eina_Bool
195 _e_eom_set_eom_attribute(enum wl_eom_attribute attribute)
197 if (attribute == WL_EOM_ATTRIBUTE_NONE || g_eom->eom_attribute == WL_EOM_ATTRIBUTE_NONE)
199 g_eom->eom_attribute = attribute;
203 if (eom_output_attributes[g_eom->eom_attribute - 1][attribute - 1] == 1)
205 g_eom->eom_attribute = attribute;
212 static inline enum wl_eom_status
213 _e_eom_get_eom_status()
215 return g_eom->eom_status;
219 _e_eom_set_eom_status(enum wl_eom_status status)
221 g_eom->eom_status = status;
225 _e_eom_pp_cb(tbm_surface_h surface, void *user_data)
227 tdm_error tdm_err = TDM_ERROR_NONE;
228 E_EomEventDataPtr eom_data = NULL;
230 if (user_data == NULL)
232 EOM_DBG("ERROR: PP EVENT: user data is NULL\n");
236 eom_data = (E_EomEventDataPtr)user_data;
238 tdm_buffer_remove_release_handler(eom_data->dst_buffers[eom_data->pp_buffer],
239 _e_eom_pp_cb, eom_data);
241 /* TODO: lock that flag??? */
242 /* If a client has committed its buffer stop mirror mode */
243 if (g_eom->is_mirror_mode == 0)
246 tbm_surface_h src_buffer;
247 src_buffer = _e_eom_root_internal_tdm_surface_get(g_eom->int_output_name);
248 if (src_buffer == EINA_FALSE)
250 EOM_DBG("ERROR: PP EVENT: get root tdm surfcae\n");
254 g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer;
256 tdm_err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer],
257 _e_eom_pp_cb, &g_eom_event_data);
258 if (tdm_err != TDM_ERROR_NONE)
260 EOM_DBG ("ERROR: PP EVENT: set pp hadler:%d\n", tdm_err );
264 tdm_err = tdm_pp_attach(eom_data->pp, src_buffer, g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]);
265 if (tdm_err != TDM_ERROR_NONE)
267 printf ("ERROR: pp attach:%d\n", tdm_err);
271 tdm_err = tdm_pp_commit(g_eom_event_data.pp);
272 if (tdm_err != TDM_ERROR_NONE)
274 EOM_DBG ("ERROR: PP EVENT: pp commit:%d\n", tdm_err );
280 _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED,
281 unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED,
284 E_EomClientBufferPtr client_buffer = NULL;
285 E_EomEventDataPtr eom_data = NULL;
286 tdm_error err = TDM_ERROR_NONE;
288 if (user_data == NULL)
290 EOM_ERR("ERROR: EVENT: user_data is NULL\n");
294 eom_data = (E_EomEventDataPtr)user_data;
296 /* TODO: Maybe better to separating that callback on to mirror and extended callbacks */
297 if (g_eom->is_mirror_mode == 1)
299 if (eom_data->current_buffer == 1)
301 eom_data->current_buffer = 0;
303 err = tdm_layer_set_buffer(eom_data->layer,
304 eom_data->dst_buffers[!eom_data->pp_buffer]);
305 if (err != TDM_ERROR_NONE)
307 EOM_ERR("ERROR: EVENT: set buffer 0\n");
313 eom_data->current_buffer = 1;
315 err = tdm_layer_set_buffer(eom_data->layer,
316 eom_data->dst_buffers[!eom_data->pp_buffer]);
317 if (err != TDM_ERROR_NONE)
319 EOM_ERR("ERROR: EVENT: set buffer 1\n");
324 err = tdm_output_commit(eom_data->output, 0, _e_eom_commit_cb, eom_data);
325 if (err != TDM_ERROR_NONE)
327 EOM_ERR("ERROR: EVENT: commit\n");
333 client_buffer = _e_eom_get_client_buffer_from_list();
334 if (client_buffer == NULL)
336 EOM_ERR("ERROR: EVENT: client buffer is NULL\n");
340 err = tdm_layer_set_buffer(eom_data->layer, client_buffer->tbm_buffer);
341 if (err != TDM_ERROR_NONE)
343 EOM_ERR("ERROR: EVENT: set buffer 1\n");
347 err = tdm_output_commit(eom_data->output, 0, _e_eom_commit_cb, eom_data);
348 if (err != TDM_ERROR_NONE)
350 EOM_ERR("ERROR: EVENT: commit\n");
356 static E_Comp_Wl_Output *
357 _e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id)
359 E_Comp_Wl_Output *output = NULL, *o = NULL;
366 EINA_LIST_FOREACH(outputs, l, o)
368 char *temp_id = NULL;
369 temp_id = strchr(o->id, '/');
373 if (strcmp(o->id, id) == 0)
378 loc = temp_id - o->id;
380 if (strncmp(o->id, id, loc) == 0)
391 _e_eom_set_up_external_output(const char *output_name, int width, int height)
393 tdm_error tdm_err = TDM_ERROR_NONE;
394 E_EomEventDataPtr eom_data = NULL;
395 tdm_output *hal_output = NULL;
396 tdm_layer *hal_layer = NULL;
397 Eina_Bool ret = EINA_FALSE;
398 tdm_info_layer layer_info;
400 eom_data = &g_eom_event_data;
402 hal_output = _e_eom_hal_output_get(output_name);
403 if (hal_output == NULL)
405 EOM_ERR("ERROR: get hal output for, (%s)\n", output_name);
409 hal_layer = _e_eom_hal_layer_get(hal_output, width, height);
410 if (hal_layer == NULL)
412 EOM_ERR("ERROR: get hal layer\n");
416 ret = _e_eom_create_output_buffers(eom_data, width, height);
417 if (ret == EINA_FALSE)
419 EOM_ERR("ERROR: create buffers \n");
423 /* TODO: Models commited clients buffers */
424 _e_eom_create_fake_buffers(width, height);
426 tdm_err = tdm_layer_get_info(hal_layer, &layer_info);
427 if (tdm_err != TDM_ERROR_NONE)
429 EOM_ERR ("ERROR: get layer info: %d", tdm_err);
433 EOM_DBG("LAYER INFO: %dx%d, pos (x:%d, y:%d, w:%d, h:%d, dpos (x:%d, y:%d, w:%d, h:%d))",
434 layer_info.src_config.size.h, layer_info.src_config.size.v,
435 layer_info.src_config.pos.x, layer_info.src_config.pos.y,
436 layer_info.src_config.pos.w, layer_info.src_config.pos.h,
437 layer_info.dst_pos.x, layer_info.dst_pos.y,
438 layer_info.dst_pos.w, layer_info.dst_pos.h);
440 g_eom->dst_mode.w = width;
441 g_eom->dst_mode.h = height;
442 /* TODO: free that memory */
443 g_eom->ext_output_name = strdup(output_name);
445 eom_data->layer = hal_layer;
446 eom_data->output = hal_output;
447 eom_data->current_buffer = 0;
449 tdm_err = tdm_layer_set_buffer(hal_layer, eom_data->dst_buffers[eom_data->current_buffer]);
450 if (tdm_err != TDM_ERROR_NONE)
452 EOM_ERR("ERROR: set buffer on layer:%d\n", tdm_err);
456 tdm_err = tdm_output_set_dpms(hal_output, TDM_OUTPUT_DPMS_ON);
457 if (tdm_err != TDM_ERROR_NONE)
459 EOM_ERR("ERROR: failed set DPMS on:%d\n", tdm_err);
463 tdm_err = tdm_output_commit(hal_output, 0, _e_eom_commit_cb, eom_data);
464 if (tdm_err != TDM_ERROR_NONE)
466 EOM_ERR("ERROR: commit crtc:%d\n", tdm_err);
474 * TODO: add deinitialization
480 _e_eom_deinit_external_output()
482 tdm_error err = TDM_ERROR_NONE;
485 if (g_eom_event_data.layer)
487 err = tdm_layer_unset_buffer(g_eom_event_data.layer);
488 if (err != TDM_ERROR_NONE)
489 EOM_DBG("EXT OUTPUT DEINIT: fail unset buffer:%d\n", err);
491 EOM_DBG("EXT OUTPUT DEINIT: ok unset buffer:%d\n", err);
493 err = tdm_output_commit(g_eom_event_data.output, 0, NULL, &g_eom_event_data);
494 if (err != TDM_ERROR_NONE)
495 EOM_DBG ("EXT OUTPUT DEINIT: fail commit:%d\n", err);
497 EOM_DBG("EXT OUTPUT DEINIT: ok commit:%d\n", err);
499 /* TODO: do I need to do DPMS off? */
500 err = tdm_output_set_dpms(g_eom_event_data.output, TDM_OUTPUT_DPMS_OFF);
501 if (err != TDM_ERROR_NONE)
502 EOM_ERR("EXT OUTPUT DEINIT: failed set DPMS off:%d\n", err);
504 for (i = 0; i < NUM_MAIN_BUF; i++)
506 tdm_buffer_remove_release_handler(g_eom_event_data.dst_buffers[i],
507 _e_eom_pp_cb, &g_eom_event_data);
508 if (g_eom_event_data.dst_buffers[i])
509 tbm_surface_destroy(g_eom_event_data.dst_buffers[i]);
513 if (g_eom->int_output_name)
515 free(g_eom->int_output_name);
516 g_eom->int_output_name = NULL;
519 if (g_eom->ext_output_name)
521 free(g_eom->ext_output_name);
522 g_eom->ext_output_name = NULL;
525 if (g_eom->wl_output)
526 g_eom->wl_output = NULL;
530 _e_eom_hal_output_get(const char *id)
532 Ecore_Drm_Output *drm_output = NULL, *o = NULL;
533 const tdm_output_mode *big_mode = NULL;
534 const tdm_output_mode *modes = NULL;
535 Ecore_Drm_Device *dev = NULL;
536 tdm_output *output = NULL;
537 tdm_error err = TDM_ERROR_NONE;
538 const Eina_List *l, *ll;
544 * TODO: Temporary take into account only HDMI
546 EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
548 /* EINA_LIST_FOREACH(dev->external_outputs, ll, o)*/
549 EINA_LIST_FOREACH(dev->outputs, ll, o)
551 if ((ecore_drm_output_name_get(o)) && (strcmp(id, ecore_drm_output_name_get(o)) == 0))
556 if (drm_output == NULL)
558 EOM_ERR("ERROR: drm output was not found\n");
562 crtc_id = ecore_drm_output_crtc_id_get(drm_output);
565 EOM_ERR("ERROR: crtc is 0\n");
569 output = tdm_display_get_output(g_eom->dpy, crtc_id, NULL);
572 EOM_ERR("ERROR: there is no HAL output for:%d\n", crtc_id);
576 int min_w, min_h, max_w, max_h, preferred_align;
577 err = tdm_output_get_available_size(output, &min_w, &min_h, &max_w, &max_h, &preferred_align);
578 if (err != TDM_ERROR_NONE)
580 EOM_ERR("ERROR: Gent get geometry for hal output");
584 EOM_DBG("HAL size min:%dx%d max:%dx%d alighn:%d\n",
585 min_w, min_h, max_w, max_h, preferred_align);
588 * Force TDM to make setCrtc onto new buffer
590 err = tdm_output_get_available_modes(output, &modes, &count);
591 if (err != TDM_ERROR_NONE)
593 EOM_ERR("Get availvable modes filed\n");
597 big_mode = &modes[0];
599 for (i = 0; i < count; i++)
601 if ((modes[i].vdisplay + modes[i].hdisplay) >=
602 (big_mode->vdisplay + big_mode->hdisplay))
603 big_mode = &modes[i];
606 if (big_mode == NULL)
608 EOM_ERR("no Big mode\n");
612 EOM_DBG("BIG_MODE: %dx%d\n", big_mode->hdisplay, big_mode->vdisplay);
614 err = tdm_output_set_mode(output, big_mode);
615 if (err != TDM_ERROR_NONE)
617 EOM_ERR("set Mode failed\n");
621 EOM_DBG("Created output: %p\n", output);
626 _e_eom_hal_layer_get(tdm_output *output, int width, int height)
630 tdm_layer *layer = NULL;
631 tdm_error err = TDM_ERROR_NONE;
632 tdm_layer_capability capa;
633 tdm_info_layer layer_info;
636 err = tdm_output_get_layer_count(output, &count);
637 if (err != TDM_ERROR_NONE)
639 EOM_DBG ("tdm_output_get_layer_count fail(%d)\n", err);
643 for (i = 0; i < count; i++)
645 layer = (tdm_layer *)tdm_output_get_layer(output, i, &err);
646 if (err != TDM_ERROR_NONE)
648 EOM_DBG ("tdm_output_get_layer fail(%d)\n", err);
652 err = tdm_layer_get_capabilities(layer, &capa);
653 if (err != TDM_ERROR_NONE)
655 EOM_DBG ("tdm_layer_get_capabilities fail(%d)\n", err);
659 if (capa & TDM_LAYER_CAPABILITY_PRIMARY)
661 EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d\n", i);
666 memset(&layer_info, 0x0, sizeof(tdm_info_layer));
667 layer_info.src_config.size.h = width;
668 layer_info.src_config.size.v = height;
669 layer_info.src_config.pos.x = 0;
670 layer_info.src_config.pos.y = 0;
671 layer_info.src_config.pos.w = width;
672 layer_info.src_config.pos.h = height;
673 layer_info.src_config.format = TBM_FORMAT_ARGB8888;
674 layer_info.dst_pos.x = 0;
675 layer_info.dst_pos.y = 0;
676 layer_info.dst_pos.w = width;
677 layer_info.dst_pos.h = height;
678 layer_info.transform = TDM_TRANSFORM_NORMAL;
680 err = tdm_layer_set_info(layer, &layer_info);
681 if (err != TDM_ERROR_NONE)
683 EOM_DBG ("tdm_layer_set_info fail(%d)\n", err);
691 /* TODO: Models commited clients buffers */
693 _e_eom_create_fake_buffers(int width, int height)
695 tbm_surface_info_s buffer_info;
696 tbm_surface_h buffer = NULL;
698 buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
701 EOM_DBG("can not create fake_buffer\n");
705 memset(&buffer_info, 0x0, sizeof(tbm_surface_info_s));
706 if (tbm_surface_map(buffer,
707 TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE,
708 &buffer_info) != TBM_SURFACE_ERROR_NONE)
710 EOM_DBG("can not mmap fake_buffer\n");
714 memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size);
715 tbm_surface_unmap(buffer);
717 fake_buffers.fake_buffers[0] = buffer;
724 _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height)
726 tbm_surface_info_s buffer_info;
727 tbm_surface_h buffer = NULL;
730 * TODO: Add support of other formats
732 buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
735 EOM_DBG("can not create dst_buffer\n");
740 * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst()
743 memset(&buffer_info, 0x0, sizeof(tbm_surface_info_s));
744 if (tbm_surface_map(buffer,
745 TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE,
746 &buffer_info) != TBM_SURFACE_ERROR_NONE)
748 EOM_DBG("can not mmap buffer\n");
752 memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size);
753 tbm_surface_unmap(buffer);
755 eom_data->dst_buffers[0] = buffer;
758 * TODO: Add support of other formats
760 buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
763 EOM_DBG("can not create dst_buffer\n");
768 * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst()
770 memset(&buffer_info, 0x00, sizeof(tbm_surface_info_s));
771 if (tbm_surface_map(buffer,
772 TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE,
773 &buffer_info) != TBM_SURFACE_ERROR_NONE)
775 EOM_DBG("can not mmap buffer\n");
779 memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size);
780 tbm_surface_unmap(buffer);
782 eom_data->dst_buffers[1] = buffer;
789 * Add deinitialization
794 static enum wl_eom_type
795 _e_eom_output_name_to_eom_type(const char *output_name)
797 enum wl_eom_type eom_type;
799 if (output_name == NULL)
800 return WL_EOM_TYPE_NONE;
802 /* TODO: Add other external outputs */
803 if (strcmp(output_name, "HDMI-A-0") == 0)
804 eom_type = WL_EOM_TYPE_HDMIA;
806 eom_type = WL_EOM_TYPE_NONE;
812 _e_eom_mirror_start(const char *output_name, int width, int height)
814 tbm_surface_info_s src_buffer_info;
815 tbm_surface_h src_buffer = NULL;
816 Eina_Bool ret = EINA_FALSE;
818 src_buffer = _e_eom_root_internal_tdm_surface_get(output_name);
819 if (src_buffer == NULL)
821 EOM_ERR("ERROR: get root tdm surfcae\n");
825 tbm_surface_get_info(src_buffer, &src_buffer_info );
827 EOM_DBG("FRAMEBUFFER TDM: %dx%d bpp:%d size:%d",
828 src_buffer_info.width, src_buffer_info.height,
829 src_buffer_info.bpp, src_buffer_info.size);
831 g_eom->src_mode.w = width;
832 g_eom->src_mode.h = height;
833 /* TODO: free that memory */
834 g_eom->int_output_name = strdup(output_name);
836 ret = _e_eom_pp_src_to_dst(src_buffer);
837 if (ret == EINA_FALSE)
839 EOM_ERR("ERROR: init pp\n");
840 return ret == EINA_FALSE;
847 _e_eom_root_internal_tdm_surface_get(const char *name)
849 Ecore_Drm_Output *primary_output = NULL;
850 Ecore_Drm_Device *dev;
854 EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
856 primary_output = ecore_drm_device_output_name_find(dev, name);
859 if (primary_output == NULL)
861 EOM_ERR("ERROR: get primary output\n");
865 /* I think it is more convenient than one upon, but E took first
866 * output as primary and it can be not internal output
868 primary_output = ecore_drm_output_primary_get();
871 EOM_ERR("ERROR: get primary output\n");
876 fb = ecore_drm_display_output_primary_layer_fb_get(primary_output);
877 if (primary_output == NULL)
879 EOM_ERR("ERROR: get primary frambuffer\n");
883 /*EOM_DBG("FRAMEBUFFER ECORE_DRM: is_client:%d mode%dx%d\n", fb->from_client, fb->w, fb->h);*/
885 return (tbm_surface_h)fb->hal_buffer;
889 _e_eom_pp_src_to_dst( tbm_surface_h src_buffer)
891 tdm_error err = TDM_ERROR_NONE;
895 pp = tdm_display_create_pp(g_eom->dpy, &err);
896 if (err != TDM_ERROR_NONE)
898 EOM_ERR("ERROR: create pp:%d\n", err);
902 g_eom_event_data.pp = pp;
904 pp_info.src_config.size.h = g_eom->src_mode.w; /*1440*/
905 pp_info.src_config.size.v = g_eom->src_mode.h; /*2560*/
906 pp_info.src_config.pos.x = 0;
907 pp_info.src_config.pos.y = 0;
908 pp_info.src_config.pos.w = g_eom->src_mode.w; /*1440*/
909 pp_info.src_config.pos.h = g_eom->src_mode.h; /*2560*/
910 pp_info.src_config.format = TBM_FORMAT_ARGB8888;
911 pp_info.dst_config.size.h = g_eom->dst_mode.w; /*1960*/
912 pp_info.dst_config.size.v = g_eom->dst_mode.h; /*1080*/
913 pp_info.dst_config.pos.x = 0;
914 pp_info.dst_config.pos.y = 0;
915 pp_info.dst_config.pos.w = g_eom->dst_mode.w; /*1960*/
916 pp_info.dst_config.pos.h = g_eom->dst_mode.h; /*1080*/
917 pp_info.dst_config.format = TBM_FORMAT_ARGB8888;
918 pp_info.transform = TDM_TRANSFORM_NORMAL;/*TDM_TRANSFORM_NORMAL*/
922 err = tdm_pp_set_info(pp, &pp_info);
923 if (err != TDM_ERROR_NONE)
925 EOM_ERR("ERROR: set pp info:%d\n", err);
929 g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer;
930 EOM_DBG("PP: curr:%d pp:%d\n",
931 g_eom_event_data.current_buffer,
932 g_eom_event_data.pp_buffer);
934 err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer],
935 _e_eom_pp_cb, &g_eom_event_data);
936 if (err != TDM_ERROR_NONE)
938 EOM_ERR ("ERROR: set pp hadler:%d\n", err);
942 err = tdm_pp_attach(pp, src_buffer,
943 g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]);
944 if (err != TDM_ERROR_NONE)
946 EOM_ERR("ERROR: pp attach:%d\n", err);
950 err = tdm_pp_commit(g_eom_event_data.pp);
951 if (err != TDM_ERROR_NONE)
953 EOM_ERR("ERROR: pp commit:%d\n", err);
963 _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
965 enum wl_eom_type eom_type = WL_EOM_TYPE_NONE;
966 struct wl_resource *resource_iterator;
967 E_Comp_Wl_Output *wl_output = NULL;
968 Ecore_Drm_Event_Output *e;
973 if (!(e = event)) goto end;
975 if (!e->plug) goto end;
977 EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n",
978 e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug);
980 snprintf(buff, sizeof(buff), "%s", e->name);
982 if (strcmp(e->name, "HDMI-A-0") == 0)
986 /* Get e_comp_wl_output */
987 wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, buff);
990 EOM_ERR("ERROR: there is no wl_output:(%s)\n", buff);
994 /* Initialize external output */
995 ret = _e_eom_set_up_external_output(buff, e->w, e->h);
998 EOM_ERR("ERROR: initialize external output\n");
1002 g_eom->is_external_init = 1;
1004 g_eom->wl_output = wl_output;
1006 _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_ACTIVE);
1007 _e_eom_set_eom_status(WL_EOM_STATUS_CONNECTION);
1008 _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE);
1009 _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR);
1013 g_eom->is_external_init = 0;
1014 g_eom->is_internal_grab = 0;
1015 g_eom->wl_output = NULL;
1018 _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_INACTIVE);
1019 _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION);
1020 _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE);
1021 _e_eom_set_eom_mode(WL_EOM_MODE_NONE);
1023 _e_eom_deinit_external_output();
1026 eom_type = _e_eom_output_name_to_eom_type(buff);
1027 if (eom_type == WL_EOM_TYPE_NONE)
1029 EOM_ERR("ERROR: eom_type is NONE\n");
1033 EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator)
1035 if (resource_iterator)
1037 wl_eom_send_output_type(resource_iterator,
1040 _e_eom_get_eom_status());
1042 wl_eom_send_output_attribute(resource_iterator,
1044 _e_eom_get_eom_attribute(),
1045 _e_eom_get_eom_attribute_state(),
1048 wl_eom_send_output_mode(resource_iterator,
1050 _e_eom_get_eom_mode());
1054 else if (strcmp(e->name, "DSI-0") == 0 && g_eom->is_external_init && flag == 2)
1056 /*TODO: add support of internal and external output of same size */
1057 ret = _e_eom_mirror_start(buff, e->w, e->h);
1060 EOM_ERR("ERROR: get root surfcae\n");
1064 g_eom->is_internal_grab = 1;
1065 g_eom->is_mirror_mode = 1;
1071 return ECORE_CALLBACK_PASS_ON;
1075 _e_eom_client_buffer_change(void *data, int type, void *event)
1077 E_Comp_Wl_Buffer *external_wl_buffer = NULL;
1078 E_EomClientBufferPtr client_buffer = NULL;
1079 E_Event_Client *ev = event;
1080 E_Client *ec = NULL;
1082 tbm_surface_h external_tbm_buffer = NULL;
1083 tbm_surface_info_s surface_info;
1087 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1088 EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
1091 if (e_object_is_del(E_OBJECT(ec)))
1093 EOM_ERR("ERROR: BUFF CHANGE: ec objects is del\n");
1094 return ECORE_CALLBACK_PASS_ON;
1097 /* TODO: Remove all 1, 0 etc. Write my own enume or use
1100 * TODO: Make all goto same, not err, end, ret etc.
1102 /*We are not interested in non external clients*/
1103 if (e_client_is_external_output_client(ec) != EINA_TRUE)
1105 EOM_ERR("ERROR: BUFF CHANGE: ec is not external\n");
1106 return ECORE_CALLBACK_PASS_ON;
1109 if (ec->pixmap == NULL)
1110 return ECORE_CALLBACK_PASS_ON;
1112 external_wl_buffer = e_pixmap_resource_get(ec->pixmap);
1113 if (external_wl_buffer == NULL)
1115 EOM_ERR("ERROR:BUFF CHANGE: wl buffer is NULL\n");
1116 return ECORE_CALLBACK_PASS_ON;
1119 EOM_DBG("BUFF CHANGE: wl_buff:%dx%d",
1120 external_wl_buffer->w,
1121 external_wl_buffer->h);
1123 if (external_wl_buffer->w == 1 && external_wl_buffer->h == 1)
1125 EOM_ERR("ERROR:BUFF CHANGE: skip first 1x1 client buffer\n");
1126 return ECORE_CALLBACK_PASS_ON;
1129 /*TODO: wayland_tbm_server_get_surface is implicit declarated */
1130 /*external_tbm_buffer = wayland_tbm_server_get_surface(NULL,
1131 external_wl_buffer->resource);
1132 if (external_tbm_buffer == NULL)
1134 EOM_ERR("ERROR: BUFF CHANGE: client tbm buffer is NULL\n");
1135 return ECORE_CALLBACK_PASS_ON;
1138 EOM_DBG("BUFF CHANGE: tbm_buffer %p", external_tbm_buffer);
1141 /* mmap that buffer to get width and height for test's sake */
1143 memset(&surface_info, 0, sizeof(tbm_surface_info_s));
1144 ret = tbm_surface_map(external_tbm_buffer, TBM_SURF_OPTION_READ |
1145 TBM_SURF_OPTION_WRITE, &surface_info);
1146 if (ret != TBM_SURFACE_ERROR_NONE)
1148 EOM_ERR("BUFF CHANGE: failed mmap buffer: %d", ret);
1149 //return ECORE_CALLBACK_PASS_ON;
1152 EOM_DBG("BUFF CHANGE: tbm_buffer: %dx%d", surface_info.width, surface_info.height);
1154 tbm_surface_unmap(external_tbm_buffer);
1157 /* TODO: Must find proper way of getting tbm_surface */
1158 /*client_buffer = _e_eom_create_client_buffer(external_wl_buffer, external_tbm_buffer);*/
1159 client_buffer = _e_eom_create_client_buffer(external_wl_buffer, fake_buffers.fake_buffers[0]);
1160 if (client_buffer == NULL)
1162 EOM_ERR("ERROR: BUFF CHANGE: alloc client buffer");
1163 return ECORE_CALLBACK_PASS_ON;
1166 _e_eom_add_client_buffer_to_list(client_buffer);
1168 /* Stop mirror mode */
1169 g_eom->is_mirror_mode = 0;
1171 return ECORE_CALLBACK_PASS_ON;
1175 _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer)
1177 _e_eom_client_buffers_list_free();
1179 g_eom_event_data.client_buffers_list = eina_list_append(g_eom_event_data.client_buffers_list, client_buffer);
1183 _e_eom_client_buffers_list_free()
1185 E_EomClientBufferPtr *buffer = NULL;
1188 /* TODO: I am not sure if it is thread safe */
1189 EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer)
1193 /* I am not sure if it is necessary */
1194 /* tbm_surface_internal_unref(buffer->tbm_buffer); */
1196 /* TODO: Do we need reference that buffer? */
1197 /*e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/
1199 g_eom_event_data.client_buffers_list = eina_list_remove(g_eom_event_data.client_buffers_list, buffer);
1205 static E_EomClientBufferPtr
1206 _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer)
1208 E_EomClientBufferPtr buffer = NULL;
1210 buffer = malloc(sizeof(E_EomClientBuffer));
1214 buffer->wl_buffer = wl_buffer;
1215 buffer->tbm_buffer = tbm_buffer;
1216 /* TODO: It is not used right now */
1217 buffer->stamp = _e_eom_get_time_in_mseconds();
1219 /* I am not sure if it is necessary */
1220 /* tbm_surface_internal_ref(tbm_buffer); */
1222 /* TODO: Do we need reference that buffer? */
1223 /*e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/
1228 static E_EomClientBufferPtr
1229 _e_eom_get_client_buffer_from_list()
1231 E_EomClientBufferPtr buffer = NULL;
1234 /* TODO: Have to describe how that list works*/
1235 /* There must be only one buffer */
1236 EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer)
1246 _e_eom_get_time_in_mseconds()
1250 clock_gettime(CLOCK_MONOTONIC, &tp);
1252 return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000));
1256 _e_eom_ecore_drm_activate_cb(void *data, int type EINA_UNUSED, void *event)
1259 Ecore_Drm_Event_Activate *e = NULL;
1260 E_EomPtr eom = NULL;
1262 EOM_DBG("_e_eom_ecore_drm_activate_cb called\n");
1264 if ((!event) || (!data)) goto end;
1268 EOM_DBG("e->active:%d\n", e->active);
1281 return ECORE_CALLBACK_PASS_ON;
1285 _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute)
1287 Eina_Bool ret = EINA_FALSE;
1289 /* TODO: Add notifications when more prior client changes eom state */
1290 ret = _e_eom_set_eom_attribute(attribute);
1291 if (ret == EINA_FALSE)
1293 EOM_DBG("set attribute FAILED\n");
1295 wl_eom_send_output_attribute(resource,
1297 _e_eom_get_eom_attribute(),
1298 _e_eom_get_eom_attribute_state(),
1299 WL_EOM_ERROR_OUTPUT_OCCUPIED);
1303 EOM_DBG("set attribute OK\n");
1305 wl_eom_send_output_attribute(resource,
1307 _e_eom_get_eom_attribute(),
1308 _e_eom_get_eom_attribute_state(),
1311 /* If client has set WL_EOM_ATTRIBUTE_NONE, eom will be
1312 * switched to mirror mode
1314 if (attribute == WL_EOM_ATTRIBUTE_NONE && g_eom->is_mirror_mode == 0)
1316 g_eom->is_mirror_mode = 1;
1318 _e_eom_client_buffers_list_free();
1320 ret = _e_eom_mirror_start(g_eom->int_output_name,
1323 if (ret == EINA_FALSE)
1325 EOM_ERR("ERROR: restore mirror mode after a client disconnection\n");
1336 _e_eom_wl_request_get_output_info_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id)
1338 EOM_DBG("output:%d\n", output_id);
1343 E_EomOutputPtr output = NULL;
1345 EINA_LIST_FOREACH(g_eom->outputs, l, output)
1347 if (output->id == output_id)
1349 EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n",
1350 output->id, output->type, output->mode, output->w, output->h,
1351 output->phys_width, output->phys_height, output->status);
1352 wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h,
1353 output->phys_width, output->phys_height, output->status);
1359 static const struct wl_eom_interface _e_eom_wl_implementation =
1361 _e_eom_wl_request_set_attribute_cb,
1362 _e_eom_wl_request_get_output_info_cb
1365 /* wl_eom global object destroy function */
1367 _e_eom_wl_resource_destory_cb(struct wl_resource *resource)
1369 struct wl_resource *resource_iterator = NULL;
1370 Eina_List *l = NULL;
1373 EOM_DBG("client unbind\n");
1375 ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE);
1376 if (ret == EINA_FALSE)
1377 EOM_DBG("Restore attribute: Failed\n");
1379 EOM_DBG("Restore attribute: OK\n");
1381 /* If a client has been disconnected and eom has not been
1382 * restored to mirror mode, start mirror mode
1384 if (g_eom->is_mirror_mode == 0)
1386 g_eom->is_mirror_mode = 1;
1388 _e_eom_client_buffers_list_free();
1390 ret = _e_eom_mirror_start(g_eom->int_output_name,
1393 if (ret == EINA_FALSE)
1395 EOM_ERR("ERROR: restore mirror mode after a client disconnection\n");
1399 /* Notify eom clients that eom state has been changed */
1400 EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator)
1402 if (resource_iterator)
1404 wl_eom_send_output_attribute(resource_iterator,
1406 _e_eom_get_eom_attribute(),
1407 _e_eom_get_eom_attribute_state(),
1415 /* wl_eom global object bind function */
1417 _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1419 enum wl_eom_type eom_type = WL_EOM_TYPE_NONE;
1420 struct wl_resource *resource = NULL;
1424 EOM_ERR("ERROR: data is NULL");
1428 E_EomPtr eom = data;
1430 resource = wl_resource_create(client,
1434 if (resource == NULL)
1436 EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id);
1437 wl_client_post_no_memory(client);
1441 wl_resource_set_implementation(resource,
1442 &_e_eom_wl_implementation,
1444 _e_eom_wl_resource_destory_cb);
1446 eom_type = _e_eom_output_name_to_eom_type(g_eom->ext_output_name);
1448 wl_eom_send_output_type(resource,
1451 _e_eom_get_eom_status());
1453 wl_eom_send_output_attribute(resource,
1455 _e_eom_get_eom_attribute(),
1456 _e_eom_get_eom_attribute_state(),
1459 wl_eom_send_output_mode(resource,
1461 _e_eom_get_eom_mode());
1463 EOM_DBG("send - output count : %d\n", g_eom->output_count);
1464 wl_eom_send_output_count(resource,
1465 g_eom->output_count);
1470 E_EomOutputPtr output = NULL;
1472 EINA_LIST_FOREACH(g_eom->outputs, l, output)
1474 EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n",
1475 output->id, output->type, output->mode, output->w, output->h,
1476 output->phys_width, output->phys_height, output->status);
1477 wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h,
1478 output->phys_width, output->phys_height, output->status);
1482 g_eom->eom_clients = eina_list_append(g_eom->eom_clients, resource);
1488 Ecore_Event_Handler *h = NULL;
1490 if (g_eom == NULL) return;
1492 if (g_eom->handlers)
1494 EINA_LIST_FREE(g_eom->handlers, h)
1495 ecore_event_handler_del(h);
1498 if (g_eom->dpy) tdm_display_deinit(g_eom->dpy);
1499 if (g_eom->bufmgr) tbm_bufmgr_deinit(g_eom->bufmgr);
1501 if (g_eom->global) wl_global_destroy(g_eom->global);
1507 _e_eom_output_info_get(tdm_display *dpy)
1509 tdm_error ret = TDM_ERROR_NONE;
1513 ret = tdm_display_get_output_count(dpy, &count);
1514 if (ret != TDM_ERROR_NONE)
1516 EOM_ERR("tdm_display_get_output_count fail\n");
1522 EOM_DBG("output count is 1. device doesn't support external outputs.\n");
1526 g_eom->output_count = count - 1;
1527 EOM_DBG("external output count : %d\n", g_eom->output_count);
1529 for (i = 0; i < count; i++)
1531 const tdm_output_mode *mode = NULL;
1532 E_EomOutputPtr new_output = NULL;
1533 unsigned int mmWidth, mmHeight;
1534 tdm_output_conn_status status;
1535 tdm_output *output = NULL;
1536 tdm_output_type type;
1538 output = tdm_display_get_output(dpy, i, &ret);
1539 if (ret != TDM_ERROR_NONE)
1541 EOM_ERR("tdm_display_get_output fail(ret:%d)", ret);
1547 EOM_ERR("tdm_display_get_output fail(no output:%d)", ret);
1551 ret = tdm_output_get_output_type(output, &type);
1552 if (ret != TDM_ERROR_NONE)
1554 EOM_ERR("tdm_output_get_output_type fail(%d)", ret);
1557 /* skip main output */
1558 /* TODO: need more check about main display*/
1559 if ((type == TDM_OUTPUT_TYPE_DSI) || (type == TDM_OUTPUT_TYPE_LVDS))
1562 new_output = E_NEW(E_EomOutput, 1);
1563 if (new_output == NULL)
1565 EOM_ERR("calloc fail");
1569 ret = tdm_output_get_conn_status(output, &status);
1570 if (ret != TDM_ERROR_NONE)
1572 EOM_ERR("tdm_output_get_conn_status fail(%d)", ret);
1577 new_output->type = type;
1578 new_output->status = status;
1579 new_output->mode = EOM_OUTPUT_MODE_NONE;
1581 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
1583 EOM_DBG("create(%d)output, type:%d, status:%d",
1584 new_output->id, new_output->type, new_output->status);
1585 g_eom->outputs = eina_list_append(g_eom->outputs, new_output);
1588 new_output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
1590 ret = tdm_output_get_mode(output, &mode);
1591 if (ret != TDM_ERROR_NONE)
1593 EOM_ERR("tdm_output_get_mode fail(%d)", ret);
1604 new_output->w = mode->hdisplay;
1605 new_output->h = mode->vdisplay;
1608 ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight);
1609 if (ret != TDM_ERROR_NONE)
1611 EOM_ERR("tdm_output_get_conn_status fail(%d)", ret);
1615 new_output->phys_width = mmWidth;
1616 new_output->phys_height = mmHeight;
1618 EOM_DBG("create(%d)output, type:%d, status:%d, w:%d, h:%d, mm_w:%d, mm_h:%d",
1619 new_output->id, new_output->type, new_output->status,
1620 new_output->w, new_output->h, new_output->phys_width, new_output->phys_height);
1622 g_eom->outputs = eina_list_append(g_eom->outputs, new_output);
1631 E_EomOutputPtr output;
1633 EINA_LIST_FOREACH(g_eom->outputs, l, output)
1637 eina_list_free(g_eom->outputs);
1644 _e_eom_init_internal()
1646 tdm_error ret = TDM_ERROR_NONE;
1648 g_eom->dpy = tdm_display_init(&ret);
1649 if (ret != TDM_ERROR_NONE)
1651 EOM_ERR("tdm_display_init fail\n");
1655 ret = tdm_display_get_fd(g_eom->dpy, &g_eom->fd);
1656 if (ret != TDM_ERROR_NONE)
1658 EOM_ERR("tdm_display_get_fd fail\n");
1662 g_eom->bufmgr = tbm_bufmgr_init(g_eom->fd);
1665 EOM_ERR("tbm_bufmgr_init fail\n");
1669 if (_e_eom_output_info_get(g_eom->dpy) != EINA_TRUE)
1671 EOM_ERR("_e_eom_output_info_get fail\n");
1679 tbm_bufmgr_deinit(g_eom->bufmgr);
1682 tdm_display_deinit(g_eom->dpy);
1690 Eina_Bool ret = EINA_FALSE;
1692 EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err);
1694 g_eom = E_NEW(E_Eom, 1);
1695 EINA_SAFETY_ON_NULL_RETURN_VAL(g_eom, EINA_FALSE);
1697 g_eom->global = wl_global_create(e_comp_wl->wl.disp,
1703 EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err);
1705 ret = _e_eom_init_internal();
1706 if (ret == EINA_FALSE)
1708 EOM_ERR("failed init_internal()");
1712 E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_ACTIVATE, _e_eom_ecore_drm_activate_cb, g_eom);
1713 E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_ecore_drm_output_cb, g_eom);
1714 E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_eom_client_buffer_change, NULL);
1716 g_eom->is_external_init = 0;
1717 g_eom->is_internal_grab = 0;
1718 g_eom->ext_output_name = NULL;
1719 g_eom->int_output_name = NULL;
1721 _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_NONE);
1722 _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE);
1723 _e_eom_set_eom_status(WL_EOM_STATUS_NONE);
1724 _e_eom_set_eom_mode(WL_EOM_MODE_NONE);
1734 e_modapi_init(E_Module *m)
1736 return (_e_eom_init() ? m : NULL);
1740 e_modapi_shutdown(E_Module *m EINA_UNUSED)
1747 e_modapi_save(E_Module *m EINA_UNUSED)
1749 /* Save something to be kept */