1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include "Elementary.h"
6 #include "private.h"
7
8 int _elm_ext_log_dom = -1;
9
10 static int init_count = 0;
11
12 void
external_elm_init(void)13 external_elm_init(void)
14 {
15 int argc = 0;
16 char **argv = NULL;
17
18 init_count++;
19 DBG("elm_real_init\n");
20 if (init_count > 1) return;
21 ecore_app_args_get(&argc, &argv);
22 elm_init(argc, argv);
23 }
24
25 static void
external_elm_shutdown(void)26 external_elm_shutdown(void)
27 {
28 init_count--;
29 DBG("elm_real_shutdown\n");
30 if (init_count > 0) return;
31 elm_shutdown();
32 }
33
34 void
external_signal(void * data EINA_UNUSED,Evas_Object * obj,const char * sig,const char * source)35 external_signal(void *data EINA_UNUSED, Evas_Object *obj, const char *sig,
36 const char *source)
37 {
38 char *_signal = strdup(sig);
39 char *p = _signal;
40 Evas_Object *content;
41 Edje_External_Type *type;
42
43 if (!p) goto on_error;
44
45 while ((*p!='\0') && (*p!=']'))
46 p++;
47
48
49 if ((*p=='\0') || (*(p+1)!=':'))
50 {
51 ERR("Invalid External Signal received: '%s' '%s'", sig, source);
52 goto on_error;
53 }
54
55 *p = '\0';
56 p+=2; //jump ']' and ':'
57
58 type = evas_object_data_get(obj, "Edje_External_Type");
59 if (!type)
60 {
61 ERR("no external type for object %p", obj);
62 goto on_error;
63 }
64 if (!type->content_get)
65 {
66 ERR("external type '%s' from module '%s' does not provide content_get()",
67 type->module_name, type->module);
68 goto on_error;
69 }
70
71 content = type->content_get(type->data, obj, _signal);
72 if (content)
73 edje_object_signal_emit(content, sig + (p - _signal), source);
74
75 on_error:
76 free(_signal);
77 return;
78 }
79
80 const char *
external_translate(void * data EINA_UNUSED,const char * orig)81 external_translate(void *data EINA_UNUSED, const char *orig)
82 {
83 // in future, mark all params as translatable and use dgettext()
84 // with "elementary" text domain here.
85 return orig;
86 }
87
88 typedef struct {
89 const char *emission;
90 const char *source;
91 Evas_Object *edje;
92 } Elm_External_Signals_Proxy_Context;
93
94 static void
_external_signal_proxy_free_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)95 _external_signal_proxy_free_cb(void *data, Evas *e EINA_UNUSED,
96 Evas_Object *obj EINA_UNUSED,
97 void *event_info EINA_UNUSED)
98 {
99 Elm_External_Signals_Proxy_Context *ctxt = data;
100 external_elm_shutdown();
101 free(ctxt);
102 }
103
104 static void
_external_signal_proxy_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)105 _external_signal_proxy_cb(void *data, Evas_Object *obj EINA_UNUSED,
106 void *event_info EINA_UNUSED)
107 {
108 Elm_External_Signals_Proxy_Context *ctxt = data;
109 // TODO: Is it worth to check Evas_Smart_Cb_Description and do something
110 // TODO: with event_info given its description?
111 edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source);
112 }
113
114 Eina_Bool
external_common_param_get(void * data EINA_UNUSED,const Evas_Object * obj,Edje_External_Param * param)115 external_common_param_get(void *data EINA_UNUSED, const Evas_Object *obj,
116 Edje_External_Param *param)
117 {
118 if (!strcmp(param->name, "style"))
119 {
120 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
121 {
122 param->s = elm_object_style_get(obj);
123 return EINA_TRUE;
124 }
125 }
126 else if (!strcmp(param->name, "disabled"))
127 {
128 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
129 {
130 param->i = elm_object_disabled_get(obj);
131 return EINA_TRUE;
132 }
133 }
134 return EINA_FALSE;
135 }
136
137 Eina_Bool
external_common_param_set(void * data EINA_UNUSED,Evas_Object * obj,const Edje_External_Param * param)138 external_common_param_set(void *data EINA_UNUSED, Evas_Object *obj,
139 const Edje_External_Param *param)
140 {
141 if (!strcmp(param->name, "style"))
142 {
143 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
144 {
145 elm_object_style_set(obj, param->s);
146 return EINA_TRUE;
147 }
148 }
149 else if (!strcmp(param->name, "disabled"))
150 {
151 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
152 {
153 elm_object_disabled_set(obj, param->i);
154 return EINA_TRUE;
155 }
156 }
157 return EINA_FALSE;
158 }
159
160 void
external_signals_proxy(Evas_Object * obj,Evas_Object * edje,const char * part_name)161 external_signals_proxy(Evas_Object *obj, Evas_Object *edje, const char *part_name)
162 {
163 const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
164 unsigned int cls_count, inst_count, total;
165 Elm_External_Signals_Proxy_Context *ctxt;
166
167 evas_object_smart_callbacks_descriptions_get
168 (obj, &cls_descs, &cls_count, &inst_descs, &inst_count);
169
170 total = cls_count + inst_count;
171 if (!total) return;
172 ctxt = malloc(sizeof(Elm_External_Signals_Proxy_Context) * total);
173 if (!ctxt) return;
174 evas_object_event_callback_add
175 (obj, EVAS_CALLBACK_FREE, _external_signal_proxy_free_cb, ctxt);
176
177 for (; cls_count > 0; cls_count--, cls_descs++, ctxt++)
178 {
179 const Evas_Smart_Cb_Description *d = *cls_descs;
180 ctxt->emission = d->name;
181 ctxt->source = part_name;
182 ctxt->edje = edje;
183 evas_object_smart_callback_add
184 (obj, d->name, _external_signal_proxy_cb, ctxt);
185 }
186
187 for (; inst_count > 0; inst_count--, inst_descs++, ctxt++)
188 {
189 const Evas_Smart_Cb_Description *d = *inst_descs;
190 ctxt->emission = d->name;
191 ctxt->source = part_name;
192 ctxt->edje = edje;
193 evas_object_smart_callback_add
194 (obj, d->name, _external_signal_proxy_cb, ctxt);
195 }
196 }
197
198 void
external_common_params_parse(void * mem,void * data EINA_UNUSED,Evas_Object * obj EINA_UNUSED,const Eina_List * params)199 external_common_params_parse(void *mem, void *data EINA_UNUSED,
200 Evas_Object *obj EINA_UNUSED,
201 const Eina_List *params)
202 {
203 Elm_Params *p;
204 const Eina_List *l;
205 Edje_External_Param *param;
206
207 p = mem;
208 EINA_LIST_FOREACH(params, l, param)
209 {
210 if (!strcmp(param->name, "style"))
211 p->style = eina_stringshare_add(param->s);
212 else if (!strcmp(param->name, "disabled"))
213 {
214 p->disabled = param->i;
215 p->disabled_exists = EINA_TRUE;
216 }
217 }
218 }
219
220 void
external_common_state_set(void * data EINA_UNUSED,Evas_Object * obj,const void * from_params,const void * to_params,float pos EINA_UNUSED)221 external_common_state_set(void *data EINA_UNUSED, Evas_Object *obj,
222 const void *from_params, const void *to_params,
223 float pos EINA_UNUSED)
224 {
225 const Elm_Params *p;
226 if (to_params) p = to_params;
227 else if (from_params) p = from_params;
228 else return;
229
230 if (p->style)
231 elm_object_style_set(obj, p->style);
232 if (p->disabled_exists)
233 elm_object_disabled_set(obj, p->disabled);
234 }
235
236 Evas_Object *
external_common_param_icon_get(Evas_Object * obj,const Edje_External_Param * p)237 external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *p)
238 {
239 Evas_Object *edje, *parent_widget, *icon;
240 const char *file;
241
242 if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
243 return NULL;
244
245 edje = evas_object_smart_parent_get(obj);
246 edje_object_file_get(edje, &file, NULL);
247
248 parent_widget = elm_widget_parent_widget_get(obj);
249 if (!parent_widget)
250 parent_widget = edje;
251 icon = elm_icon_add(parent_widget);
252
253 if ((edje_file_group_exists(file, p->s)) &&
254 (elm_image_file_set(icon, file, p->s)))
255 return icon;
256 if (elm_icon_standard_set(icon, p->s))
257 return icon;
258
259 ERR("Failed to set icon: '%s'", p->s);
260 evas_object_del(icon);
261 return NULL;
262 }
263
264 void
external_common_icon_param_parse(Evas_Object ** icon,Evas_Object * obj,const Eina_List * params)265 external_common_icon_param_parse(Evas_Object **icon, Evas_Object *obj,
266 const Eina_List *params)
267 {
268 Edje_External_Param *p = edje_external_param_find(params, "icon");
269 *icon = external_common_param_icon_get(obj, p);
270 }
271
272 Evas_Object *
external_common_param_elm_layout_get(Evas_Object * obj,const Edje_External_Param * p)273 external_common_param_elm_layout_get(Evas_Object *obj,
274 const Edje_External_Param *p)
275 {
276 Evas_Object *edje, *parent_widget, *ret;
277 const char *file;
278
279 if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
280 return NULL;
281
282 edje = evas_object_smart_parent_get(obj);
283 edje_object_file_get(edje, &file, NULL);
284
285 parent_widget = elm_widget_parent_widget_get(obj);
286 if (parent_widget)
287 {
288 ret = elm_layout_add(parent_widget);
289 if (elm_layout_file_set(ret, file, p->s))
290 return ret;
291 }
292 else
293 {
294 ret = edje_object_add(evas_object_evas_get(edje));
295 if (edje_object_file_set(ret, file, p->s))
296 return ret;
297 }
298 evas_object_del(ret);
299 return NULL;
300 }
301
302 void
external_common_params_free(void * params)303 external_common_params_free(void *params)
304 {
305 Elm_Params *p = params;
306 if (p->style)
307 eina_stringshare_del(p->style);
308 }
309
310 #define DEFINE_TYPE(type_name) \
311 extern const Edje_External_Type external_##type_name##_type;
312 #include "modules.inc"
313 #undef DEFINE_TYPE
314
315 static Edje_External_Type_Info elm_external_types[] =
316 {
317 #define DEFINE_TYPE(type_name) \
318 { "elm/"#type_name, &external_##type_name##_type },
319 #include "modules.inc"
320 #undef DEFINE_TYPE
321 { NULL, NULL }
322 };
323
324 static Eina_Bool
elm_mod_init(void)325 elm_mod_init(void)
326 {
327 _elm_ext_log_dom = eina_log_domain_register("elm-externals",
328 EINA_COLOR_LIGHTBLUE);
329 edje_external_type_array_register(elm_external_types);
330 return EINA_TRUE;
331 }
332
333 static void
elm_mod_shutdown(void)334 elm_mod_shutdown(void)
335 {
336 edje_external_type_array_unregister(elm_external_types);
337 if (_elm_ext_log_dom >= 0) eina_log_domain_unregister(_elm_ext_log_dom);
338 _elm_ext_log_dom = -1;
339 }
340
341 EINA_MODULE_INIT(elm_mod_init);
342 EINA_MODULE_SHUTDOWN(elm_mod_shutdown);
343