868718e378e9415f39fad41767eef77b6af87f83
[platform/framework/web/crosswalk-tizen.git] / src / runtime / native_window.cc
1 // Copyright 2015 Samsung Electronics Co, Ltd. 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 "runtime/native_window.h"
6
7 #if defined(HAVE_X11)
8 #include <Ecore_X.h>
9 #elif defined(HAVE_WAYLAND)
10 #include <Ecore_Wayland.h>
11 #endif
12
13 #include <cstdint>
14
15 #include "common/logger.h"
16
17 namespace wrt {
18
19 namespace {
20   const char* kWRTEdjePath = "/usr/share/edje/wrt/wrt.edj";
21   const char* kWinowRotationEventKey = "wm,rotation,changed";
22   const char* kWinowFocusedEventKey = "focused";
23   const char* kWinowUnfocusedEventKey = "unfocused";
24 }  // namespace
25
26
27 NativeWindow::NativeWindow()
28     : initialized_(false),
29       window_(NULL),
30       focus_(NULL),
31       content_(NULL),
32       rotation_(0),
33       handler_id_(0) {
34 }
35
36 NativeWindow::~NativeWindow() {
37 }
38
39 void NativeWindow::Initialize() {
40   // window
41   window_ = CreateWindowInternal();
42   elm_win_conformant_set(window_, EINA_TRUE);
43   int w, h;
44 #if defined(HAVE_X11)
45   uint16_t pid = getpid();
46   ecore_x_window_prop_property_set(
47     elm_win_xwindow_get(window_),
48     ECORE_X_ATOM_NET_WM_PID,
49     ECORE_X_ATOM_CARDINAL, 32, &pid, 1);
50   ecore_x_vsync_animator_tick_source_set(elm_win_xwindow_get(window_));
51   ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
52 #elif defined(HAVE_WAYLAND)
53   ecore_wl_screen_size_get(&w, &h);
54 #endif
55   evas_object_resize(window_, w, h);
56   elm_win_autodel_set(window_, EINA_TRUE);
57   evas_object_smart_callback_add(window_, "delete,request",
58                                  DidDeleteRequested, this);
59   evas_object_smart_callback_add(window_, "profile,changed",
60                                  DidProfileChanged, this);
61
62   #define EVAS_SIZE_EXPAND_FILL(obj) \
63     evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); \
64     evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
65
66   // background
67   Evas_Object* bg = evas_object_rectangle_add(evas_object_evas_get(window_));
68   evas_object_color_set(bg, 0, 0, 0, 255);
69   EVAS_SIZE_EXPAND_FILL(bg);
70   elm_win_resize_object_add(window_, bg);
71   evas_object_render_op_set(bg, EVAS_RENDER_BLEND);
72   evas_object_show(bg);
73
74   // conformant
75   Evas_Object* conformant = elm_conformant_add(window_);
76   EVAS_SIZE_EXPAND_FILL(conformant);
77   elm_win_resize_object_add(window_, conformant);
78   evas_object_show(conformant);
79
80   // top layout
81   Evas_Object* top_layout = elm_layout_add(conformant);
82   elm_layout_file_set(top_layout, kWRTEdjePath, "web-application");
83   EVAS_SIZE_EXPAND_FILL(top_layout);
84   elm_object_content_set(conformant, top_layout);
85   evas_object_show(top_layout);
86
87   // focus
88   Evas_Object* focus = elm_button_add(top_layout);
89   elm_theme_extension_add(NULL, kWRTEdjePath);
90   elm_object_style_set(focus, "wrt");
91   elm_object_part_content_set(top_layout, "elm.swallow.content", focus);
92   EVAS_SIZE_EXPAND_FILL(focus);
93   elm_access_object_unregister(focus);
94   evas_object_show(focus);
95   focus_ = focus;
96
97   // focus callback
98   auto focus_callback = [](void* user_data,
99                            Evas_Object*,
100                            void*) -> void {
101     NativeWindow* window = static_cast<NativeWindow*>(user_data);
102     window->DidFocusChanged(true);
103   };
104   auto unfocus_callback = [](void* user_data,
105                              Evas_Object*,
106                              void*) -> void {
107     NativeWindow* window = static_cast<NativeWindow*>(user_data);
108     window->DidFocusChanged(false);
109   };
110
111   evas_object_smart_callback_add(focus,
112                                  kWinowFocusedEventKey,
113                                  focus_callback,
114                                  this);
115   evas_object_smart_callback_add(focus,
116                                  kWinowUnfocusedEventKey,
117                                  unfocus_callback,
118                                  this);
119
120   // Rotation
121   auto rotation_callback = [](void* user_data,
122                               Evas_Object* obj,
123                               void*) -> void {
124       NativeWindow* window = static_cast<NativeWindow*>(user_data);
125       int degree = elm_win_rotation_get(obj);
126       window->DidRotation(degree);
127   };
128   evas_object_smart_callback_add(window_,
129                                  kWinowRotationEventKey,
130                                  rotation_callback,
131                                  this);
132
133   initialized_ = true;
134 }
135
136 void NativeWindow::DidDeleteRequested(void* /*data*/,
137     Evas_Object* /*obj*/, void* /*event_info*/) {
138   LOGGER(DEBUG) << "didDeleteRequested";
139   elm_exit();
140 }
141
142 void NativeWindow::DidProfileChanged(void* /*data*/,
143     Evas_Object* /*obj*/, void* /*event_info*/) {
144   LOGGER(DEBUG) << "didProfileChanged";
145 }
146
147 Evas_Object* NativeWindow::evas_object() const {
148   return window_;
149 }
150
151 void NativeWindow::SetContent(Evas_Object* content) {
152   // Remarks
153   // If any object was already set as a content object in the same part,
154   // the previous object will be deleted automatically with this call.
155   // If the content is NULL, this call will just delete the previous object.
156   // If the If you wish to preserve it,
157   // issue elm_object_part_content_unset() on it first.
158   evas_object_show(content);
159   elm_object_part_content_unset(focus_, "elm.swallow.content");
160   elm_object_part_content_set(focus_, "elm.swallow.content", content);
161   elm_object_focus_set(focus_, EINA_TRUE);
162   content_ = content;
163 }
164
165 void NativeWindow::DidRotation(int degree) {
166   rotation_ = degree;
167   auto it = handler_table_.begin();
168   for ( ; it != handler_table_.end(); ++it) {
169     it->second(degree);
170   }
171 }
172
173 void NativeWindow::DidFocusChanged(bool got) {
174   if (content_ != NULL) {
175     elm_object_focus_set(content_, got ? EINA_TRUE : EINA_FALSE);
176   }
177 }
178
179 int NativeWindow::AddRotationHandler(RotationHandler handler) {
180   int id = handler_id_++;
181   handler_table_[id] = handler;
182   return id;
183 }
184
185 void NativeWindow::RemoveRotationHandler(int id) {
186   handler_table_.erase(id);
187 }
188
189 void NativeWindow::SetRotationLock(int degree) {
190   rotation_ = degree%360;
191   elm_win_wm_rotation_preferred_rotation_set(window_, rotation_);
192 }
193
194 void NativeWindow::SetAutoRotation() {
195   elm_win_wm_rotation_preferred_rotation_set(window_, -1);
196   if (elm_win_wm_rotation_supported_get(window_)) {
197     const int rotation[4] = {0, 90, 180, 270};
198     elm_win_wm_rotation_available_rotations_set(window_, rotation, 4);
199   }
200   rotation_ = elm_win_rotation_get(window_);
201 }
202
203 void NativeWindow::Show() {
204   evas_object_show(window_);
205 }
206
207 void NativeWindow::Active() {
208   elm_win_activate(window_);
209 }
210
211 void NativeWindow::InActive() {
212   elm_win_lower(window_);
213 }
214
215 void NativeWindow::FullScreen(bool enable) {
216   elm_win_indicator_opacity_set(window_,
217       enable ? ELM_WIN_INDICATOR_TRANSPARENT : ELM_WIN_INDICATOR_OPAQUE);
218 }
219
220 }  // namespace wrt