Remove focus button
[platform/framework/web/crosswalk-tizen.git] / runtime / browser / native_window.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "runtime/browser/native_window.h"
18
19 #if defined(HAVE_X11)
20 #include <Ecore_X.h>
21 #elif defined(HAVE_WAYLAND)
22 #include <Ecore_Wayland.h>
23 #endif
24
25 #include <cstdint>
26
27 #include "common/logger.h"
28
29 namespace runtime {
30
31 namespace {
32   const char* kEdjePath = "/usr/share/edje/xwalk/xwalk_tizen.edj";
33   const char* kWinowRotationEventKey = "wm,rotation,changed";
34 }  // namespace
35
36
37 NativeWindow::NativeWindow()
38     : initialized_(false),
39       window_(NULL),
40       layout_(NULL),
41       content_(NULL),
42       rotation_(0),
43       handler_id_(0) {
44 }
45
46 NativeWindow::~NativeWindow() {
47 }
48
49 void NativeWindow::Initialize() {
50   // window
51   window_ = CreateWindowInternal();
52   elm_win_conformant_set(window_, EINA_TRUE);
53   int w, h;
54 #if defined(HAVE_X11)
55   uint16_t pid = getpid();
56   ecore_x_window_prop_property_set(
57     elm_win_xwindow_get(window_),
58     ECORE_X_ATOM_NET_WM_PID,
59     ECORE_X_ATOM_CARDINAL, 32, &pid, 1);
60   ecore_x_vsync_animator_tick_source_set(elm_win_xwindow_get(window_));
61   ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
62 #elif defined(HAVE_WAYLAND)
63   ecore_wl_screen_size_get(&w, &h);
64 #endif
65   evas_object_resize(window_, w, h);
66   elm_win_autodel_set(window_, EINA_TRUE);
67   evas_object_smart_callback_add(window_, "delete,request",
68                                  DidDeleteRequested, this);
69   evas_object_smart_callback_add(window_, "profile,changed",
70                                  DidProfileChanged, this);
71
72   #define EVAS_SIZE_EXPAND_FILL(obj) \
73     evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); \
74     evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
75
76   // background
77   Evas_Object* bg = evas_object_rectangle_add(evas_object_evas_get(window_));
78   evas_object_color_set(bg, 0, 0, 0, 255);
79   EVAS_SIZE_EXPAND_FILL(bg);
80   elm_win_resize_object_add(window_, bg);
81   evas_object_render_op_set(bg, EVAS_RENDER_BLEND);
82   evas_object_show(bg);
83
84   // conformant
85   Evas_Object* conformant = elm_conformant_add(window_);
86   EVAS_SIZE_EXPAND_FILL(conformant);
87   elm_win_resize_object_add(window_, conformant);
88   evas_object_show(conformant);
89
90   // top layout
91   Evas_Object* top_layout = elm_layout_add(conformant);
92   elm_layout_file_set(top_layout, kEdjePath, "web-application");
93   EVAS_SIZE_EXPAND_FILL(top_layout);
94   elm_object_content_set(conformant, top_layout);
95   evas_object_show(top_layout);
96   layout_ = top_layout;
97
98   // Rotation
99   auto rotation_callback = [](void* user_data,
100                               Evas_Object* obj,
101                               void*) -> void {
102       NativeWindow* window = static_cast<NativeWindow*>(user_data);
103       int degree = elm_win_rotation_get(obj);
104       window->DidRotation(degree);
105   };
106   evas_object_smart_callback_add(window_,
107                                  kWinowRotationEventKey,
108                                  rotation_callback,
109                                  this);
110
111   if (w > h) {
112     natural_orientation_ = ScreenOrientation::LANDSCAPE_PRIMARY;
113   } else {
114     natural_orientation_ = ScreenOrientation::PORTRAIT_PRIMARY;
115   }
116
117   initialized_ = true;
118 }
119
120 void NativeWindow::DidDeleteRequested(void* /*data*/,
121     Evas_Object* /*obj*/, void* /*event_info*/) {
122   LOGGER(DEBUG) << "didDeleteRequested";
123   elm_exit();
124 }
125
126 void NativeWindow::DidProfileChanged(void* /*data*/,
127     Evas_Object* /*obj*/, void* /*event_info*/) {
128   LOGGER(DEBUG) << "didProfileChanged";
129 }
130
131 Evas_Object* NativeWindow::evas_object() const {
132   return window_;
133 }
134
135 void NativeWindow::SetContent(Evas_Object* content) {
136   // Remarks
137   // If any object was already set as a content object in the same part,
138   // the previous object will be deleted automatically with this call.
139   // If the content is NULL, this call will just delete the previous object.
140   // If the If you wish to preserve it,
141   // issue elm_object_part_content_unset() on it first.
142
143   evas_object_show(content);
144   elm_object_part_content_unset(layout_, "elm.swallow.content");
145   elm_object_part_content_set(layout_, "elm.swallow.content", content);
146   content_ = content;
147
148   // attached webview was resized by evas_norender API
149   evas_norender(evas_object_evas_get(window_));
150 }
151
152 void NativeWindow::DidRotation(int degree) {
153   rotation_ = degree;
154   auto it = handler_table_.begin();
155   for ( ; it != handler_table_.end(); ++it) {
156     it->second(degree);
157   }
158 }
159
160 int NativeWindow::AddRotationHandler(RotationHandler handler) {
161   int id = handler_id_++;
162   handler_table_[id] = handler;
163   return id;
164 }
165
166 void NativeWindow::RemoveRotationHandler(int id) {
167   handler_table_.erase(id);
168 }
169
170 void NativeWindow::SetRotationLock(int degree) {
171   if (degree != -1)
172     rotation_ = degree % 360;
173   elm_win_wm_rotation_preferred_rotation_set(window_, rotation_);
174 }
175
176 void NativeWindow::SetRotationLock(ScreenOrientation orientation) {
177   int portrait_natural_angle[] = {
178     0,  // PORTRAIT_PRIMARY
179     180,  // PORTRAIT_SECONDARY
180     270,  // LANDSCAPE_PRIMARY
181     90,  // LANDSCAPE_SECONDARY
182     0,  // NATURAL
183     -1  // ANY
184   };
185   int landscape_natural_angle[] = {
186     270,  // PORTRAIT_PRIMARY
187     90,  // PORTRAIT_SECONDARY
188     0,  // LANDSCAPE_PRIMARY
189     180,  // LANDSCAPE_SECONDARY
190     0,  // NATURAL
191     -1,  // ANY
192   };
193   auto& convert_table =
194       natural_orientation_ == ScreenOrientation::PORTRAIT_PRIMARY ?
195           portrait_natural_angle :
196           landscape_natural_angle;
197   SetRotationLock(convert_table[static_cast<int>(orientation)]);
198 }
199
200
201 void NativeWindow::SetAutoRotation() {
202   elm_win_wm_rotation_preferred_rotation_set(window_, -1);
203   if (elm_win_wm_rotation_supported_get(window_)) {
204     const int rotation[4] = {0, 90, 180, 270};
205     elm_win_wm_rotation_available_rotations_set(window_, rotation, 4);
206   }
207   rotation_ = elm_win_rotation_get(window_);
208 }
209
210 void NativeWindow::Show() {
211   evas_object_show(window_);
212 }
213
214 void NativeWindow::Active() {
215   elm_win_activate(window_);
216 }
217
218 void NativeWindow::InActive() {
219   elm_win_lower(window_);
220 }
221
222 void NativeWindow::FullScreen(bool enable) {
223   elm_win_indicator_opacity_set(window_,
224       enable ? ELM_WIN_INDICATOR_TRANSPARENT : ELM_WIN_INDICATOR_OPAQUE);
225 }
226
227 }  // namespace runtime