1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 
7 #include <Elementary.h>
8 
9 #include "../../static_libs/buildsystem/buildsystem.h"
10 #include "elm_priv.h"
11 #include "elm_widget_web.h"
12 
13 #define MY_CLASS elm_web_class_get()
14 
15 #define MY_CLASS_NAME "Elm_Web"
16 #define MY_CLASS_NAME_LEGACY "elm_web"
17 
18 typedef struct _Elm_Web_Module Elm_Web_Module;
19 struct _Elm_Web_Module
20 {
21    void (*unneed_web)(void);
22    Eina_Bool (*need_web)(void);
23 
24    void (*window_features_ref)(Elm_Web_Window_Features *wf);
25    void (*window_features_unref)(Elm_Web_Window_Features *wf);
26    Eina_Bool (*window_features_property_get)(const Elm_Web_Window_Features *wf,
27                                              Elm_Web_Window_Feature_Flag flag);
28    void (*window_features_region_get)(const Elm_Web_Window_Features *wf,
29                                       Evas_Coord *x,
30                                       Evas_Coord *y,
31                                       Evas_Coord *w,
32                                       Evas_Coord *h);
33 
34    const Efl_Class *(*class_get)(void);
35 
36    Eina_Module *m;
37 };
38 
39 static Elm_Web_Module ewm = {
40   NULL,
41   NULL,
42 
43   NULL,
44   NULL,
45   NULL,
46   NULL,
47 
48   NULL,
49 
50   NULL
51 };
52 
53 static const char SIG_URI_CHANGED[] = "uri,changed"; // deprecated, use "url,changed" instead.
54 static const char SIG_URL_CHANGED[] = "url,changed";
55 
56 static const Evas_Smart_Cb_Description _elm_web_smart_callbacks[] = {
57    { SIG_URI_CHANGED, "s" },
58    { SIG_URL_CHANGED, "s" },
59    { SIG_WIDGET_FOCUSED, ""}, /**< handled by elm_widget */
60    { SIG_WIDGET_UNFOCUSED, ""}, /**< handled by elm_widget */
61    { NULL, NULL }
62 };
63 
64 // FIXME: init/shutdown module below
65 void
_elm_unneed_web(void)66 _elm_unneed_web(void)
67 {
68    if (!ewm.unneed_web) return ;
69    ewm.unneed_web();
70 }
71 
72 EAPI Eina_Bool
elm_need_web(void)73 elm_need_web(void)
74 {
75    if (!ewm.need_web) return EINA_FALSE;
76    return ewm.need_web();
77 }
78 
79 EAPI Evas_Object *
elm_web_add(Evas_Object * parent)80 elm_web_add(Evas_Object *parent)
81 {
82    if (!parent || !ewm.class_get) return NULL;
83 
84    return elm_legacy_add(ewm.class_get(), parent);
85 }
86 
87 EAPI const Efl_Class *
elm_web_real_class_get(void)88 elm_web_real_class_get(void)
89 {
90    if (!ewm.class_get) return NULL;
91 
92    return ewm.class_get();
93 }
94 
95 EOLIAN static Eo *
_elm_web_efl_object_constructor(Eo * obj,Elm_Web_Data * sd)96 _elm_web_efl_object_constructor(Eo *obj, Elm_Web_Data *sd)
97 {
98    obj = efl_constructor(efl_super(obj, MY_CLASS));
99    sd->obj = obj;
100    efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
101    evas_object_smart_callbacks_descriptions_set(obj, _elm_web_smart_callbacks);
102    efl_access_object_role_set(obj, EFL_ACCESS_ROLE_HTML_CONTAINER);
103    legacy_object_focus_handle(obj);
104    return obj;
105 }
106 
107 EAPI Eina_Bool
elm_web_uri_set(Evas_Object * obj,const char * url)108 elm_web_uri_set(Evas_Object *obj, const char *url)
109 {
110    ELM_WEB_CHECK(obj) EINA_FALSE;
111 
112    return elm_obj_web_url_set(obj, url);
113 }
114 
115 EAPI const char *
elm_web_uri_get(const Evas_Object * obj)116 elm_web_uri_get(const Evas_Object *obj)
117 {
118    return elm_obj_web_url_get((Eo *) obj);
119 }
120 
121 // FIXME: override with module function
122 EAPI void
elm_web_window_features_ref(Elm_Web_Window_Features * wf)123 elm_web_window_features_ref(Elm_Web_Window_Features *wf)
124 {
125    if (!ewm.window_features_ref) return ;
126    ewm.window_features_ref(wf);
127 }
128 
129 EAPI void
elm_web_window_features_unref(Elm_Web_Window_Features * wf)130 elm_web_window_features_unref(Elm_Web_Window_Features *wf)
131 {
132    if (!ewm.window_features_unref) return ;
133    ewm.window_features_unref(wf);
134 }
135 
136 EAPI Eina_Bool
elm_web_window_features_property_get(const Elm_Web_Window_Features * wf,Elm_Web_Window_Feature_Flag flag)137 elm_web_window_features_property_get(const Elm_Web_Window_Features *wf,
138                                      Elm_Web_Window_Feature_Flag flag)
139 {
140    if (!ewm.window_features_property_get) return EINA_FALSE;
141    return ewm.window_features_property_get(wf, flag);
142 }
143 
144 EAPI void
elm_web_window_features_region_get(const Elm_Web_Window_Features * wf,Evas_Coord * x,Evas_Coord * y,Evas_Coord * w,Evas_Coord * h)145 elm_web_window_features_region_get(const Elm_Web_Window_Features *wf,
146                                    Evas_Coord *x,
147                                    Evas_Coord *y,
148                                    Evas_Coord *w,
149                                    Evas_Coord *h)
150 {
151    if (x) *x = 0;
152    if (y) *y = 0;
153    if (w) *w = 0;
154    if (h) *h = 0;
155 
156    if (!ewm.window_features_region_get) return;
157    ewm.window_features_region_get(wf, x, y, w, h);
158 }
159 
160 
161 static inline void
_convert_web_zoom_mode(Elm_Web_Zoom_Mode * legacy_mode,Efl_Ui_Zoom_Mode * mode,Eina_Bool to_legacy)162 _convert_web_zoom_mode(Elm_Web_Zoom_Mode *legacy_mode, Efl_Ui_Zoom_Mode *mode, Eina_Bool to_legacy)
163 {
164    #define CONVERT(LEGACY_MODE, NEW_MODE) \
165       if (to_legacy  && *mode == NEW_MODE) \
166         { \
167            *legacy_mode =LEGACY_MODE; \
168            return; \
169         } \
170       if (!to_legacy && *legacy_mode == LEGACY_MODE) \
171         { \
172            *mode = NEW_MODE; \
173            return; \
174         } \
175 
176    CONVERT(ELM_WEB_ZOOM_MODE_MANUAL,    EFL_UI_ZOOM_MODE_MANUAL)
177    CONVERT(ELM_WEB_ZOOM_MODE_AUTO_FIT,  EFL_UI_ZOOM_MODE_AUTO_FIT)
178    CONVERT(ELM_WEB_ZOOM_MODE_AUTO_FILL, EFL_UI_ZOOM_MODE_AUTO_FILL)
179    CONVERT(ELM_WEB_ZOOM_MODE_LAST,      EFL_UI_ZOOM_MODE_LAST)
180    CONVERT(ELM_WEB_ZOOM_MODE_LAST,      EFL_UI_ZOOM_MODE_AUTO_FIT_IN)
181 
182    #undef CONVERT
183 }
184 
185 EAPI void
elm_web_zoom_mode_set(Evas_Object * obj,Elm_Web_Zoom_Mode mode)186 elm_web_zoom_mode_set(Evas_Object *obj, Elm_Web_Zoom_Mode mode)
187 {
188    Efl_Ui_Zoom_Mode new_mode = EFL_UI_ZOOM_MODE_MANUAL;;
189 
190    _convert_web_zoom_mode(&mode, &new_mode, EINA_FALSE);
191 
192    efl_ui_zoom_mode_set(obj, new_mode);
193 }
194 
195 EAPI Elm_Web_Zoom_Mode
elm_web_zoom_mode_get(const Evas_Object * obj)196 elm_web_zoom_mode_get(const Evas_Object *obj)
197 {
198    Efl_Ui_Zoom_Mode new_mode = efl_ui_zoom_mode_get(obj);;
199    Elm_Web_Zoom_Mode mode = ELM_WEB_ZOOM_MODE_MANUAL;
200 
201    _convert_web_zoom_mode(&mode, &new_mode, EINA_TRUE);
202 
203    return mode;
204 }
205 
206 EAPI void
elm_web_zoom_set(Evas_Object * obj,double zoom)207 elm_web_zoom_set(Evas_Object *obj, double zoom)
208 {
209    efl_ui_zoom_level_set(obj, zoom);
210 }
211 
212 EAPI double
elm_web_zoom_get(const Evas_Object * obj)213 elm_web_zoom_get(const Evas_Object *obj)
214 {
215    return efl_ui_zoom_level_get(obj);
216 }
217 
218 static void
_elm_web_class_constructor(Efl_Class * klass)219 _elm_web_class_constructor(Efl_Class *klass)
220 {
221    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
222 }
223 
224 #if defined(_WIN32) || defined(__CYGWIN__)
225 # define EFL_SHARED_EXTENSION ".dll"
226 #else
227 # define EFL_SHARED_EXTENSION ".so"
228 #endif
229 
230 Eina_Bool
_elm_web_init(const char * engine)231 _elm_web_init(const char *engine)
232 {
233    char buf[PATH_MAX];
234 
235      if (!bs_mod_get(buf, sizeof(buf), "elementary/web", engine))
236        snprintf(buf, sizeof(buf),
237                 "%s/elementary/modules/web/%s/%s/module"EFL_SHARED_EXTENSION,
238                 _elm_lib_dir, engine, MODULE_ARCH);
239 
240    if (ewm.m)
241      {
242         // Check if the module is already open
243         if (!strcmp(buf, eina_module_file_get(ewm.m)))
244           return EINA_TRUE;
245 
246         // We are leaking reference on purpose here, as we can't be sure that
247         // the web engine is not leaking state around preventing a clean exit.
248         // Only future elm_web object created from now will use the new engine.
249         ewm.unneed_web = NULL;
250         ewm.need_web = NULL;
251         ewm.window_features_ref = NULL;
252         ewm.window_features_unref = NULL;
253         ewm.window_features_property_get = NULL;
254         ewm.window_features_region_get = NULL;
255         ewm.class_get = NULL;
256      }
257 
258    ewm.m = eina_module_new(buf);
259    if (!ewm.m) return EINA_FALSE;
260 
261    if (!eina_module_load(ewm.m))
262      {
263         eina_module_free(ewm.m);
264         ewm.m = NULL;
265         return EINA_FALSE;
266      }
267 
268    ewm.unneed_web = eina_module_symbol_get(ewm.m, "ewm_unneed_web");
269    ewm.need_web = eina_module_symbol_get(ewm.m, "ewm_need_web");
270    ewm.window_features_ref = eina_module_symbol_get(ewm.m, "ewm_window_features_ref");
271    ewm.window_features_unref = eina_module_symbol_get(ewm.m, "ewm_window_features_unref");
272    ewm.window_features_property_get = eina_module_symbol_get(ewm.m, "ewm_window_features_property_get");
273    ewm.window_features_region_get = eina_module_symbol_get(ewm.m, "ewm_window_features_region_get");
274    ewm.class_get = eina_module_symbol_get(ewm.m, "ewm_class_get");
275 
276    // Only the class_get is mandatory
277    if (!ewm.class_get) return EINA_FALSE;
278    return EINA_TRUE;
279 }
280 
281 #undef ELM_WEB_CLASS
282 #define ELM_WEB_CLASS elm_web_class_get()
283 
284 #include "elm_web_eo.c"
285