[M67 Dev][Product TV] Enable Cursor with ecore-wl2
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / ubrowser / window.cc
1 // Copyright 2014 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "window.h"
6
7 #include <assert.h>
8 #include <ewk_view.h>
9 #include <ewk_console_message.h>
10 #include <ewk_policy_decision.h>
11 #include <ewk_user_media.h>
12 #include <Elementary.h>
13
14 #include "browser.h"
15 #include "logger.h"
16 #include "window_ui.h"
17
18 Window::Window(Browser& browser, int width, int height, bool incognito)
19     : browser_(browser)
20     , is_fullscreen_(false) {
21   window_ = elm_win_util_standard_add("ubrowser", "uBrowser");
22   evas_object_resize(window_, width, height);
23   elm_win_autodel_set(window_, EINA_TRUE);
24
25   Evas_Object* conform = elm_conformant_add(window_);
26   evas_object_size_hint_weight_set(conform,
27                                    EVAS_HINT_EXPAND,
28                                    EVAS_HINT_EXPAND);
29   elm_win_resize_object_add(window_, conform);
30   evas_object_show(conform);
31
32   Evas_Object *box = elm_box_add(window_);
33   elm_object_content_set(conform, box);
34   evas_object_show(box);
35
36   ui_ = new WindowUI(*this, browser_);
37
38   elm_box_pack_end(box, ui_->GetURLBar());
39   evas_object_show(ui_->GetURLBar());
40
41   Evas* evas = evas_object_evas_get(window_);
42   if (incognito)
43     web_view_ = ewk_view_add_in_incognito_mode(evas);
44   else
45     web_view_ = ewk_view_add(evas);
46   evas_object_resize(web_view_, width, height);
47   evas_object_size_hint_align_set(web_view_, EVAS_HINT_FILL, EVAS_HINT_FILL);
48   evas_object_size_hint_weight_set(web_view_, EVAS_HINT_EXPAND,
49                                    EVAS_HINT_EXPAND);
50   elm_box_pack_end(box, web_view_);
51   evas_object_show(web_view_);
52
53   elm_box_pack_end(box, ui_->GetNavBar());
54   evas_object_show(ui_->GetNavBar());
55
56   evas_object_smart_callback_add(web_view_, "title,changed",
57                                  &Window::OnTitleChanged, this);
58   evas_object_smart_callback_add(web_view_, "url,changed",
59                                  &Window::OnURLChanged, this);
60   evas_object_smart_callback_add(web_view_, "load,progress,started",
61                                  &Window::OnLoadStarted, this);
62   evas_object_smart_callback_add(web_view_, "load,progress,finished",
63                                  &Window::OnLoadFinished, this);
64   evas_object_smart_callback_add(web_view_, "create,window",
65                                  &Window::OnNewWindowRequest, this);
66   evas_object_smart_callback_add(web_view_, "console,message",
67                                  &Window::OnConsoleMessage, NULL);
68   evas_object_smart_callback_add(web_view_, "policy,newwindow,decide",
69                                  &Window::OnNewWindowPolicyDecide, NULL);
70   evas_object_smart_callback_add(web_view_, "back,forward,list,changed",
71                                  &Window::OnBackForwardListChanged, this);
72   evas_object_smart_callback_add(window_, "delete,request",
73                                  &Window::OnWindowDelRequest, this);
74   evas_object_smart_callback_add(web_view_, "usermedia,permission,request",
75                                  &Window::OnUserMediaPermissionRequest, this);
76   evas_object_smart_callback_add(web_view_, "fullscreen,enterfullscreen",
77                                  &Window::OnEnterFullScreenRequest, this);
78   evas_object_smart_callback_add(web_view_, "fullscreen,exitfullscreen",
79                                  &Window::OnExitFullScreenRequest, this);
80
81   ewk_view_quota_permission_request_callback_set(
82       web_view_, &Window::OnQuotaPermissionRequest, this);
83
84   ewk_settings_form_profile_data_enabled_set(GetEwkSettings(), true);
85   ewk_settings_form_candidate_data_enabled_set(GetEwkSettings(), true);
86
87   // Auto fit is already turned on for mobile, enable it for "ubrowser --mobile" as well.
88   ewk_settings_auto_fitting_set(GetEwkSettings(), !browser_.IsDesktop());
89
90   if (elm_win_wm_rotation_supported_get(window_)) {
91     static const int rots[] = {0, 90, 270};
92     elm_win_wm_rotation_available_rotations_set(
93         window_, rots, (sizeof(rots) / sizeof(int)));
94     evas_object_smart_callback_add(window_, "wm,rotation,changed",
95                                    &Window::OnOrientationChanged, this);
96   }
97
98   EnableMouseEvents(browser_.IsDesktop());
99   EnableTouchEvents(!browser_.IsDesktop());
100
101   evas_object_show(window_);
102 }
103
104 Window::~Window() {
105   assert(!window_);
106   // deleting view will release context
107   evas_object_del(web_view_);
108   delete ui_;
109 }
110
111 Ewk_Settings* Window::GetEwkSettings() const {
112   return ewk_view_settings_get(web_view_);
113 }
114
115 void Window::LoadURL(std::string url) {
116   const static std::string http = "http://";
117   const static std::string https = "https://";
118   const static std::string file = "file://";
119   const static std::string about = "about:";
120   if (url.compare(0, 1, "/") == 0) {
121     url = "file://" + url;
122   } else if (url.compare(0, http.length(), http) != 0 &&
123       url.compare(0, https.length(), https) != 0 &&
124       url.compare(0, file.length(), file) != 0 &&
125       url.compare(0, about.length(), about) != 0) {
126     url = "http://" + url;
127   }
128   log_info("Loading URL: %s", url.c_str());
129   ewk_view_url_set(web_view_, url.c_str());
130   ui_->OnURLChanged(url.c_str());
131 }
132
133 const char* Window::GetURL() const {
134   return ewk_view_url_get(web_view_);
135 }
136
137 void Window::Activate() {
138   log_trace("%s", __PRETTY_FUNCTION__);
139   elm_win_activate(window_);
140 }
141
142 void Window::Close() {
143   log_trace("%s", __PRETTY_FUNCTION__);
144   evas_object_del(window_);
145   browser_.OnWindowDestroyed(Id());
146   window_ = NULL;
147 }
148
149 void Window::Show() {
150   log_trace("%s", __PRETTY_FUNCTION__);
151   evas_object_show(window_);
152 }
153
154 void Window::Hide() {
155   log_trace("%s", __PRETTY_FUNCTION__);
156   evas_object_hide(window_);
157 }
158
159 void Window::Back() {
160   log_trace("%s", __PRETTY_FUNCTION__);
161   if (is_fullscreen_) {
162     is_fullscreen_ = false;
163     ewk_view_fullscreen_exit(web_view_);
164     return;
165   }
166   ewk_view_back(web_view_);
167 }
168
169 void Window::Forward() {
170   log_trace("%s", __PRETTY_FUNCTION__);
171   ewk_view_forward(web_view_);
172 }
173
174 void Window::Reload() {
175   log_trace("%s", __PRETTY_FUNCTION__);
176   ewk_view_reload(web_view_);
177 }
178
179 void Window::Stop() {
180   log_trace("%s", __PRETTY_FUNCTION__);
181   ewk_view_stop(web_view_);
182 }
183
184 void Window::SetUserAgent(const char* new_ua) {
185   log_trace("%s: %s", __PRETTY_FUNCTION__, new_ua);
186   ewk_view_user_agent_set(web_view_, new_ua);
187 }
188
189 const char* Window::GetUserAgent() const {
190   return ewk_view_user_agent_get(web_view_);
191 }
192
193 void Window::FakeRotate() {
194   log_trace("%s", __PRETTY_FUNCTION__);
195   int x, y, width, height;
196   evas_object_geometry_get(window_, &x, &y, &width, &height);
197   evas_object_move(window_, x, y);
198   evas_object_resize(window_, height, width);
199   if (width > height)
200     ewk_view_orientation_send(web_view_, 0);
201   else
202     ewk_view_orientation_send(web_view_, 90);
203 }
204
205 void Window::Resize(int width, int height) {
206   int x, y;
207   log_trace("%s: %dx%d", __PRETTY_FUNCTION__, width, height);
208   evas_object_geometry_get(window_, &x, &y, 0, 0);
209   evas_object_move(window_, x, y);
210   evas_object_resize(window_, width, height);
211   ewk_view_orientation_send(web_view_, 0);
212 }
213
214 void Window::EnableTouchEvents(bool enable) {
215   log_trace("%s: %d", __PRETTY_FUNCTION__, enable);
216   ewk_view_touch_events_enabled_set(web_view_, enable);
217 }
218
219 void Window::EnableMouseEvents(bool enable) {
220   log_trace("%s: %d", __PRETTY_FUNCTION__, enable);
221   ewk_view_mouse_events_enabled_set(web_view_, enable);
222 }
223
224 bool Window::AreTouchEventsEnabled() const {
225   log_trace("%s", __PRETTY_FUNCTION__);
226   return ewk_view_touch_events_enabled_get(web_view_);
227 }
228
229 bool Window::IsRememberFormDataEnabled() const {
230   log_trace("%s", __PRETTY_FUNCTION__);
231   Ewk_Settings* settings = GetEwkSettings();
232   return ewk_settings_form_candidate_data_enabled_get(settings);
233 }
234
235 bool Window::IsRememberPasswordEnabled() const {
236   log_trace("%s", __PRETTY_FUNCTION__);
237   Ewk_Settings* settings = GetEwkSettings();
238   return ewk_settings_autofill_password_form_enabled_get(settings);
239 }
240
241 bool Window::IsFormProfileEnabled() const {
242   log_trace("%s", __PRETTY_FUNCTION__);
243   Ewk_Settings* settings = GetEwkSettings();
244   return ewk_settings_form_profile_data_enabled_get(settings);
245 }
246
247 double Window::GetScale() const {
248   log_trace("%s", __PRETTY_FUNCTION__);
249   return ewk_view_scale_get(web_view_);
250 }
251
252 void Window::GetScaleRange(double* minScale, double* maxScale) const {
253   log_trace("%s", __PRETTY_FUNCTION__);
254   ewk_view_scale_range_get(web_view_, minScale, maxScale);
255 }
256
257 void Window::SetScale(double scale) {
258   log_trace("%s", __PRETTY_FUNCTION__);
259   ewk_view_scale_set(web_view_, scale, 0, 0);
260 }
261
262 Window::IdType Window::Id() const {
263   return window_;
264 }
265
266 void Window::OnEnterFullScreenRequest(void* data, Evas_Object*,
267                                       void* event_info) {
268   log_trace("%s", __PRETTY_FUNCTION__);
269   Window* thiz = static_cast<Window*>(data);
270   thiz->is_fullscreen_ = true;
271 }
272
273 void Window::OnExitFullScreenRequest(void* data, Evas_Object*,
274                                      void* event_info) {
275   log_trace("%s", __PRETTY_FUNCTION__);
276   Window* thiz = static_cast<Window*>(data);
277   thiz->is_fullscreen_ = false;
278 }
279
280 #if defined(OS_TIZEN_TV_PRODUCT)
281 void Window::CreateMouseCursor() {
282   log_trace("%s", __PRETTY_FUNCTION__);
283 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
284   Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
285   struct wl_display* display = ecore_wl2_display_get(wl2_display);
286   Eina_Iterator* globals = ecore_wl2_display_globals_get(wl2_display);
287   struct wl_registry* registry = ecore_wl2_display_registry_get(wl2_display);
288   struct wl_seat* seat =
289       ecore_wl2_input_seat_get(ecore_wl2_input_default_input_get(wl2_display));
290
291   Ecore_Wl2_Global* global;
292   EINA_ITERATOR_FOREACH(globals, global) {
293     if (!strcmp(global->interface, "tizen_cursor"))
294       if (!CursorModule_Initialize(display, registry, seat, global->id))
295         log_error("CursorModule_Initialize() Failed!\n");
296   }
297   eina_iterator_free(globals);
298
299   struct wl_surface* const surface =
300       ecore_wl2_window_surface_get(ecore_evas_wayland2_window_get(
301           ecore_evas_ecore_evas_get(evas_object_evas_get(window_))));
302   ecore_wl2_sync();
303
304   if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL))
305     log_error("Cursor_Set_Config() Failed!\n");
306   CursorModule_Finalize();
307 #else
308   Ecore_Wl_Global* global_data = NULL;
309   unsigned int cursormgr_id = 0;
310
311   EINA_INLIST_FOREACH(ecore_wl_globals_get(), global_data) {
312     if (0 == strcmp(global_data->interface, "tizen_cursor")) {
313       cursormgr_id = global_data->id;  // to get the id of cursormgr object
314       break;
315     }
316   }
317
318   wl_surface* surface =
319       ecore_wl_window_surface_get(elm_win_wl_window_get(window_));
320   ecore_wl_sync();
321
322   int ret_cursormod = CursorModule_Initialize(
323       ecore_wl_display_get(), ecore_wl_registry_get(),
324       ecore_wl_input_seat_get(ecore_wl_input_get()), cursormgr_id);
325   if (ret_cursormod) {
326     Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL);
327   }
328   CursorModule_Finalize();
329 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
330 }
331 #endif
332
333 void Window::OnUserMediaPermissionRequest(void* data, Evas_Object*,
334                                           void* event_info) {
335   log_trace("%s", __PRETTY_FUNCTION__);
336   Window* thiz = static_cast<Window*>(data);
337
338   Ewk_User_Media_Permission_Request* permissionRequest =
339       (Ewk_User_Media_Permission_Request*)event_info;
340
341   ewk_user_media_permission_request_suspend(permissionRequest);
342
343   thiz->ui_->ShowPermissionPopup(
344       "Media permission request",
345       "Do you want to allow this page to access Media Resources?",
346       OnUserMediaPermissionDecisionTaken,
347       permissionRequest);
348 }
349
350 void Window::OnUserMediaPermissionDecisionTaken(bool decision,
351                                                 void* data) {
352   log_trace("%s", __PRETTY_FUNCTION__);
353
354   Ewk_User_Media_Permission_Request* permissionRequest =
355       (Ewk_User_Media_Permission_Request*)data;
356
357   ewk_user_media_permission_request_set(permissionRequest, decision);
358 }
359
360 void Window::OnWindowDelRequest(void* data, Evas_Object*, void*) {
361   Window* thiz = static_cast<Window*>(data);
362   thiz->browser_.OnWindowDestroyed(thiz->Id());
363 }
364
365 void Window::OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
366   log_trace("%s", __PRETTY_FUNCTION__);
367   Window* thiz = static_cast<Window*>(data);
368   Window& new_window = thiz->browser_.CreateWindow();
369   *static_cast<Evas_Object**>(out_view) = new_window.web_view_;
370 }
371
372 void Window::OnTitleChanged(void *data, Evas_Object *obj, void *arg) {
373   Window* thiz = static_cast<Window*>(data);
374   elm_win_title_set(thiz->window_, static_cast<char*>(arg));
375   log_trace("%s: %s", __PRETTY_FUNCTION__, static_cast<char*>(arg));
376   thiz->browser_.OnWindowTitleChanged(thiz->Id(), static_cast<char *>(arg));
377 }
378
379 void Window::OnURLChanged(void *data, Evas_Object *obj, void *arg) {
380   Window* thiz = static_cast<Window*>(data);
381   log_trace("%s: %s", __PRETTY_FUNCTION__, static_cast<char*>(arg));
382   elm_win_title_set(thiz->window_, static_cast<char*>(arg));
383   thiz->ui_->OnURLChanged(static_cast<char*>(arg));
384 }
385
386 void Window::OnLoadStarted(void* data, Evas_Object*, void*) {
387   Window* thiz = static_cast<Window*>(data);
388   log_trace("%s", __PRETTY_FUNCTION__);
389   thiz->browser_.OnWindowLoadStarted(thiz->Id());
390   thiz->ui_->OnLoadingStarted();
391 }
392
393 void Window::OnLoadFinished(void* data, Evas_Object*, void*) {
394   Window* thiz = static_cast<Window*>(data);
395   log_trace("%s", __PRETTY_FUNCTION__);
396   thiz->browser_.OnWindowLoadFinished(thiz->Id());
397   thiz->ui_->OnLoadingFinished();
398 }
399
400 void Window::OnConsoleMessage(void*, Evas_Object*, void* event_info) {
401   Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
402
403   MESSAGE_TYPE type;
404   switch (ewk_console_message_level_get(msg)) {
405   case EWK_CONSOLE_MESSAGE_LEVEL_ERROR:
406     type = ERROR;
407     break;
408   case EWK_CONSOLE_MESSAGE_LEVEL_WARNING:
409     type = WARNING;
410     break;
411   case EWK_CONSOLE_MESSAGE_LEVEL_DEBUG:
412     type = DEBUG;
413     break;
414   default:
415     type = INFO;
416   }
417
418   log_message(type, true, "[JS Console] [%s:%d] %s",
419               ewk_console_message_source_get(msg),
420               ewk_console_message_line_get(msg),
421               ewk_console_message_text_get(msg));
422 }
423
424 void Window::OnOrientationChanged(void* data, Evas_Object *obj, void* event) {
425   Window* thiz = static_cast<Window*>(data);
426   log_trace("%s", __PRETTY_FUNCTION__);
427
428   int rotation = elm_win_rotation_get(thiz->window_);
429   // ewk_view_orientation_send expects angles: 0, 90, -90, 180.
430   if (rotation == 270)
431     rotation = -90;
432   ewk_view_orientation_send(thiz->web_view_, rotation);
433 }
434
435 void Window::OnNewWindowPolicyDecide(void*, Evas_Object*, void* policy) {
436   log_trace("%s", __PRETTY_FUNCTION__);
437   Ewk_Policy_Decision *policy_decision = static_cast<Ewk_Policy_Decision*>(policy);
438   const char* url = ewk_policy_decision_url_get(policy_decision);
439   log_info("Allowing new window for: %s", url);
440   ewk_policy_decision_use(policy_decision);
441 }
442
443 void Window::OnBackForwardListChanged(void* data, Evas_Object*, void* policy) {
444   log_trace("%s", __PRETTY_FUNCTION__);
445   Window* thiz = static_cast<Window*>(data);
446   thiz->ui_->EnableBackButton(ewk_view_back_possible(thiz->web_view_));
447   thiz->ui_->EnableForwardButton(ewk_view_forward_possible(thiz->web_view_));
448 }
449
450 void Window::OnQuotaPermissionRequest(Evas_Object*, const Ewk_Quota_Permission_Request* request, void*) {
451   log_trace("%s", __PRETTY_FUNCTION__);
452   ewk_view_quota_permission_request_reply(request, true);
453 }
454
455 void Window::Exit() const {
456   browser_.Exit();
457 }