Locate ewk_view_page_close in extended main loop
[platform/framework/web/crosswalk-tizen.git] / runtime / browser / ime_runtime.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 <Elementary.h>
18 #include <inputmethod.h>
19
20 #include <memory>
21 #include <string>
22
23 #include "common/application_data.h"
24 #include "common/app_control.h"
25 #include "common/app_db.h"
26 #include "common/command_line.h"
27 #include "common/logger.h"
28 #include "common/profiler.h"
29 #include "runtime/common/constants.h"
30 #include "runtime/browser/native_ime_window.h"
31 #include "runtime/browser/preload_manager.h"
32 #include "runtime/browser/runtime.h"
33 #include "runtime/browser/ime_runtime.h"
34
35 namespace runtime {
36
37 namespace {
38
39 static NativeWindow* CreateNativeWindow() {
40   SCOPE_PROFILE();
41   NativeWindow* window = NULL;
42   auto cached = PreloadManager::GetInstance()->GetCachedNativeWindow();
43   if (cached != nullptr) {
44     delete cached;
45   }
46   window = new NativeImeWindow();
47   window->Initialize();
48
49   return window;
50 }
51
52 }  // namespace
53
54 ImeRuntime::ImeRuntime(common::ApplicationData* app_data)
55     : application_(NULL),
56       native_window_(NULL),
57       app_data_(app_data) {
58 }
59
60 ImeRuntime::~ImeRuntime() {
61   if (application_) {
62     delete application_;
63   }
64   if (native_window_) {
65     delete native_window_;
66   }
67 }
68
69 static Evas_Object *enter_key_btn = NULL;
70
71 static void set_return_key_type(Ecore_IMF_Input_Panel_Return_Key_Type type)
72 {
73   switch (type) {
74   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE:
75     elm_object_text_set(enter_key_btn, "Done");
76     break;
77   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO:
78     elm_object_text_set(enter_key_btn, "Go");
79     break;
80   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN:
81     elm_object_text_set(enter_key_btn, "Join");
82     break;
83   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN:
84     elm_object_text_set(enter_key_btn, "Login");
85     break;
86   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT:
87     elm_object_text_set(enter_key_btn, "Next");
88     break;
89   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH:
90     elm_object_text_set(enter_key_btn, "Search");
91     break;
92   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND:
93     elm_object_text_set(enter_key_btn, "Send");
94     break;
95   case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN:
96     elm_object_text_set(enter_key_btn, "Sign in");
97     break;
98   default:
99     elm_object_text_set(enter_key_btn, "Enter");
100     break;
101   }
102 }
103
104 void ImeRuntime::OnAppControl() {
105   std::unique_ptr<common::AppControl>
106       appcontrol(new common::AppControl());
107   appcontrol->set_operation("http://tizen.org/appcontrol/operation/default");
108   common::AppDB* appdb = common::AppDB::GetInstance();
109   appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeBundle,
110              appcontrol->encoded_bundle());
111   if (application_->launched()) {
112     application_->AppControl(std::move(appcontrol));
113   } else {
114     application_->Launch(std::move(appcontrol));
115   }
116 }
117
118 void ImeRuntime::OnCreate() {
119   STEP_PROFILE_END("ime_app_main -> OnCreate");
120   STEP_PROFILE_END("Start -> OnCreate");
121   STEP_PROFILE_START("OnCreate -> URL Set");
122
123   common::CommandLine* cmd = common::CommandLine::ForCurrentProcess();
124   std::string appid = cmd->GetAppIdFromCommandLine(kRuntimeExecName);
125
126   // Init AppDB for Runtime
127   common::AppDB* appdb = common::AppDB::GetInstance();
128   appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeName, "xwalk-tizen");
129   appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeAppID, appid);
130   if (app_data_->setting_info()->background_support_enabled()) {
131     appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeBackgroundSupport, "true");
132   } else {
133     appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeBackgroundSupport, "false");
134   }
135   appdb->Remove(kAppDBRuntimeSection, kAppDBRuntimeBundle);
136
137   // Init ImeApplication
138   native_window_ = CreateNativeWindow();
139   STEP_PROFILE_START("ImeApplication Create");
140   application_ = new ImeApplication(native_window_, app_data_);
141   STEP_PROFILE_END("ImeApplication Create");
142
143   setlocale(LC_ALL, "");
144   bindtextdomain(kTextDomainRuntime, kTextLocalePath);
145
146   LOGGER(DEBUG) << "ime_app_create";
147   int w, h;
148
149   Evas_Object *ime_window = native_window_->evas_object();
150   if (!ime_window) {
151     LOGGER(DEBUG) << "Can't get main window: " << get_last_result();
152     return;
153   }
154   elm_win_screen_size_get(ime_window, NULL, NULL, &w, &h);
155   LOGGER(DEBUG) << "w : " << w << ", h : " << h;
156   if (w <= 0)
157     w = 720;
158   if (h <= 0)
159     h = 1280;
160   ime_set_size(w, h*2/5, h, w*3/5);
161
162   OnAppControl();
163 }
164
165 void ImeRuntime::OnTerminate() {
166 }
167
168 void ImeRuntime::Terminate() {
169   LOGGER(DEBUG) << "ime_app_terminate";
170   ProcessClosingPage(application_);
171 }
172
173 void ImeRuntime::OnShow(int context_id, ime_context_h context) {
174   Ecore_IMF_Input_Panel_Layout layout;
175   ime_layout_variation_e layout_variation;
176   int cursor_pos;
177   Ecore_IMF_Autocapital_Type autocapital_type;
178   Ecore_IMF_Input_Panel_Return_Key_Type return_key_type;
179   bool return_key_state, prediction_mode, password_mode;
180
181   LOGGER(DEBUG) << "ime_app_show";
182
183   if (ime_context_get_layout(
184         context, &layout) == IME_ERROR_NONE)
185     LOGGER(DEBUG) << "layout: " << layout;
186   if (ime_context_get_layout_variation(
187         context, &layout_variation) == IME_ERROR_NONE)
188     LOGGER(DEBUG) << "layout variation: " << layout_variation;
189   if (ime_context_get_cursor_position(
190         context, &cursor_pos) == IME_ERROR_NONE)
191     LOGGER(DEBUG) << "cursor position: " << cursor_pos;
192   if (ime_context_get_autocapital_type(
193         context, &autocapital_type) == IME_ERROR_NONE)
194     LOGGER(DEBUG) << "autocapital_type: " << autocapital_type;
195   if (ime_context_get_return_key_type(
196         context, &return_key_type) == IME_ERROR_NONE)
197     LOGGER(DEBUG) << "return_key_type: " << return_key_type;
198   if (ime_context_get_return_key_state(
199         context, &return_key_state) == IME_ERROR_NONE)
200     LOGGER(DEBUG) << "return_key_state: " << return_key_state;
201   if (ime_context_get_prediction_mode(
202         context, &prediction_mode) == IME_ERROR_NONE)
203     LOGGER(DEBUG) << "prediction_mode: " << prediction_mode;
204   if (ime_context_get_password_mode(
205         context, &password_mode) == IME_ERROR_NONE)
206     LOGGER(DEBUG) << "password_mode: " << password_mode;
207
208   set_return_key_type(return_key_type);
209 }
210
211 void ImeRuntime::OnHide(int context_id) {
212   LOGGER(DEBUG) << "ime_app_hide";
213 }
214
215 static void ime_app_focus_in_cb(int ic, void *user_data)
216 {
217   LOGGER(DEBUG) << "focus in: " << ic;
218 }
219
220 static void ime_app_focus_out_cb(int ic, void *user_data)
221 {
222   LOGGER(DEBUG) << "focus out: " << ic;
223 }
224
225 static void ime_app_cursor_position_updated_cb(
226     int cursor_pos, void *user_data)
227 {
228   LOGGER(DEBUG) << "cursor position: " << cursor_pos;
229 }
230
231 static void ime_app_return_key_type_set_cb(
232     Ecore_IMF_Input_Panel_Return_Key_Type type, void *user_data)
233 {
234   LOGGER(DEBUG) << "Return key type: " << type;
235
236   set_return_key_type(type);
237 }
238
239 static void ime_app_return_key_state_set_cb(
240     bool disabled, void *user_data)
241 {
242   LOGGER(DEBUG) << "Return key disabled: " << disabled;
243 }
244
245 static void ime_app_layout_set_cb(
246     Ecore_IMF_Input_Panel_Layout layout, void *user_data)
247 {
248   LOGGER(DEBUG) << "layout: " << layout;
249 }
250
251 static bool ime_app_process_key_event_cb(
252     ime_key_code_e keycode, ime_key_mask_e keymask,
253     ime_device_info_h dev_info, void *user_data)
254 {
255   LOGGER(DEBUG) << "keycode = " << keycode << ", keymask = " << keymask;
256
257   if ((keymask & IME_KEY_MASK_CONTROL) || (keymask & IME_KEY_MASK_ALT) ||
258       (keymask & IME_KEY_MASK_META) || (keymask & IME_KEY_MASK_WIN) ||
259       (keymask & IME_KEY_MASK_HYPER))
260     return false;
261
262   return false;
263 }
264
265 static void ime_app_display_language_changed_cb(
266     const char *language, void *user_data)
267 {
268   LOGGER(DEBUG) << "language: " << language;
269 }
270
271 int ImeRuntime::Exec(int argc, char* argv[]) {
272   ime_callback_s ops = {NULL, NULL, NULL, NULL};
273
274   // onCreate
275   ops.create = [](void* data) -> void {
276     runtime::ImeRuntime* ime_runtime =
277         reinterpret_cast<runtime::ImeRuntime*>(data);
278     if (!ime_runtime) {
279       LOGGER(ERROR) << "Runtime has not been created.";
280       return;
281     }
282     ime_runtime->OnCreate();
283   };
284
285   // onTerminate
286   ops.terminate = [](void* data) -> void {
287     runtime::ImeRuntime* ime_runtime =
288         reinterpret_cast<runtime::ImeRuntime*>(data);
289     if (!ime_runtime) {
290       LOGGER(ERROR) << "Runtime has not been created.";
291       return;
292     }
293     ime_runtime->OnTerminate();
294   };
295
296   // onShow
297   ops.show = [](int context_id, ime_context_h context, void *data) -> void {
298     runtime::ImeRuntime* ime_runtime =
299         reinterpret_cast<runtime::ImeRuntime*>(data);
300     if (!ime_runtime) {
301       LOGGER(ERROR) << "Runtime has not been created.";
302       return;
303     }
304     ime_runtime->OnShow(context_id, context);
305   };
306
307   // onHide
308   ops.hide = [](int context_id, void *data) -> void {
309     runtime::ImeRuntime* ime_runtime =
310         reinterpret_cast<runtime::ImeRuntime*>(data);
311     if (!ime_runtime) {
312       LOGGER(ERROR) << "Runtime has not been created.";
313       return;
314     }
315     ime_runtime->OnHide(context_id);
316   };
317
318   STEP_PROFILE_START("ime_app_main -> OnCreate");
319
320   // Set the necessary callback functions
321   ime_event_set_focus_in_cb(ime_app_focus_in_cb, this);
322   ime_event_set_focus_out_cb(ime_app_focus_out_cb, this);
323   ime_event_set_cursor_position_updated_cb(
324     ime_app_cursor_position_updated_cb, this);
325   ime_event_set_layout_set_cb(
326     ime_app_layout_set_cb, this);
327   ime_event_set_return_key_type_set_cb(
328     ime_app_return_key_type_set_cb, this);
329   ime_event_set_return_key_state_set_cb(
330     ime_app_return_key_state_set_cb, this);
331   ime_event_set_process_key_event_cb(
332     ime_app_process_key_event_cb, this);
333   ime_event_set_display_language_changed_cb(
334     ime_app_display_language_changed_cb, this);
335
336   return ime_run(&ops, this);
337 }
338
339
340 // ime_app_main() function is the main entry point of IME application
341 // but in case of Web App. ime_app_main() is not a entry point.
342 // To avoid build fail, add empty function.
343 #ifdef __cplusplus
344 extern "C" {
345 #endif
346
347 __attribute__ ((visibility("default")))
348 void ime_app_main(int argc, char **argv) {
349   LOGGER(DEBUG) << "ime_app_main";
350 }
351 #ifdef __cplusplus
352 }
353 #endif
354
355
356 }  // namespace runtime