Task TT-75 Implement "Main page loading UI" view
[profile/tv/apps/web/browser.git] / services / PlatformInputManager / PlatformInputManager.cpp
1
2 /*
3  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "PlatformInputManager.h"
19
20 //#include <X11/Xlib.h>
21 //#include <utilX.h>
22 #include <Ecore.h>
23 #include <Ecore_Evas.h>
24 #include <Ecore_Input.h>
25 #include <unistd.h>
26
27 #include "BrowserAssert.h"
28 #include "BrowserLogger.h"
29
30 #define E_PROP_DEVICEMGR_INPUTWIN "DeviceMgr Input Window"
31 #define E_PROP_NOT_CURSOR_HIDE "E_NOT_CURSOR_HIDE"
32
33 #define MOUSE_POINTER_MOVE_DELAY 0.015f
34 #define MOUSE_POINTER_STEPS 10
35
36 namespace tizen_browser
37 {
38 namespace services
39 {
40
41 EXPORT_SERVICE(PlatformInputManager, "org.tizen.browser.platforminputmanager")
42
43 PlatformInputManager::PlatformInputManager() :
44     m_mouseMoveTimer(NULL),
45     m_moveMousePointer(false),
46     m_lastPressedKey(OTHER_KEY),
47     m_pointerModeEnabled(true)
48 {
49
50 }
51
52 void PlatformInputManager::init(Evas_Object* mainWindow)
53 {
54     M_ASSERT(mainWindow);
55     ecore_event_filter_add(NULL, __filter, NULL, this);
56     m_xWindow = elm_win_xwindow_get(mainWindow);
57
58     // This snippet is needed to show mouse pointer all the time, because by default it is hidden after few seconds
59     //m_atomDevicemgrInputWindow = ecore_x_atom_get(E_PROP_DEVICEMGR_INPUTWIN);
60     //m_atomAlwaysCursorOn = ecore_x_atom_get(E_PROP_NOT_CURSOR_HIDE);
61     //if(!ecore_x_window_prop_window_get(ecore_x_window_root_first_get(), m_atomDevicemgrInputWindow, &m_devicemgr_win, 1))
62     //    BROWSER_LOGD("Failed to get device manager input window!");
63     //ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, __handler_FOCUS_IN, this);
64 }
65
66 Eina_Bool PlatformInputManager::__filter(void *data, void */*loop_data*/, int type, void *event)
67 {
68     PlatformInputManager *self = static_cast<PlatformInputManager*>(data);
69
70     if (type == ECORE_EVENT_KEY_DOWN) {
71         M_ASSERT(event);
72         Ecore_Event_Key *ev = static_cast<Ecore_Event_Key *>(event);
73
74         if(!ev->keyname)
75             return EINA_TRUE;
76
77         BROWSER_LOGD("Pressed key: %s", ev->keyname);
78         const std::string keyName = ev->keyname;
79
80         bool wasArrow = false;
81         /**
82          * In pointer mode arrow key events cause mouse pointer to move.
83          * For that each arrow key is handled by us.
84          * Pointer movement is realized in timer to achieve smooth animation of pointer's move.
85          */
86 /*
87         if(self->m_pointerModeEnabled) {
88             wasArrow = true;
89             if (!keyName.compare("KEY_LEFT")) {
90                 self->m_currentMouseMovementParams.xMod = -1;
91                 self->m_currentMouseMovementParams.yMod = 0;
92             }
93             else if (!keyName.compare("KEY_RIGHT")) {
94                 self->m_currentMouseMovementParams.xMod = 1;
95                 self->m_currentMouseMovementParams.yMod = 0;
96             }
97             else if (!keyName.compare("KEY_UP")) {
98                 self->m_currentMouseMovementParams.xMod = 0;
99                 self->m_currentMouseMovementParams.yMod = -1;
100             }
101             else if (!keyName.compare("KEY_DOWN")) {
102                 self->m_currentMouseMovementParams.xMod = 0;
103                 self->m_currentMouseMovementParams.yMod = 1;
104             }
105             else
106                 wasArrow = false;
107 */
108             /**
109             * If last pressed key was arrow we would like to convert Return key to mouse click
110             * assuming that user was moving cursor and now want to "click" chosen element.
111             * In other cases Return key is handled normally allowing for example to accecpt typed url.
112             */
113 /*
114             if(!keyName.compare("KEY_ENTER")) {
115                 if(self->m_lastPressedKey == ARROW) {
116                     self->m_lastPressedKey = RETURN;
117                     self->mouseButtonManipulate(Button1, ButtonPress);
118                     return EINA_FALSE;
119                 }
120             }
121
122             if(wasArrow) {
123                 self->m_lastPressedKey = ARROW;
124                 if(!(self->m_mouseMoveTimer)) {
125                     self->m_currentMouseMovementParams.moveMousePointer = true;
126                     self->m_currentMouseMovementParams.counter = 0;
127                     self->m_currentMouseMovementParams.speed = 1;
128                     self->m_mouseMoveTimer = ecore_timer_add(MOUSE_POINTER_MOVE_DELAY, &PlatformInputManager::mouseMove, self);
129                 }
130                 return EINA_FALSE;
131             }
132         }
133 */
134
135         self->m_lastPressedKey= OTHER_KEY;
136
137         /**
138          * Because MENU button launches org.tizen.menu
139          * we use blue 'D' button on remote control or F4 on keyboard as substitution of MENU button
140          */
141         if(!keyName.compare("KEY_MENU") || !keyName.compare("KEY_BLUE")) {
142             self->menuPressed();
143             return EINA_FALSE;
144         }
145
146 //        if(!keyName.compare("KEY_CHANNELUP")){
147             /**
148              * Converting ChannelUp Button on remote control and Page Up key on keyboard to mouse's wheel up move.
149              * This is used to achieve same effect of scrolling web page using mouse, remote control and keyboard.
150              */
151 //            self->mouseButtonManipulate(Button4, ButtonPress); // Simulate mouse wheel up movement
152 //            self->mouseButtonManipulate(Button4, ButtonRelease);
153 //            return EINA_FALSE;
154 //        }
155
156 //        if(!keyName.compare("KEY_CHANNELDOWN")){
157             /**
158              * Same as above ChannelDown and Page Down are replaced by mouse's wheel down movement.
159              */
160 //            self->mouseButtonManipulate(Button5, ButtonPress); // Simulate mouse wheel down movement
161 //            self->mouseButtonManipulate(Button5, ButtonRelease);
162 //            return EINA_FALSE;
163 //        }
164
165         if(!keyName.compare("KEY_RETURN"))
166             self->returnPressed();
167         else if(!keyName.compare("KEY_LEFT"))
168             self->leftPressed();
169         else if(!keyName.compare("KEY_RIGHT"))
170             self->rightPressed();
171         else if(!keyName.compare("KEY_ENTER"))
172             self->enterPressed();
173             // MERGE_ME dont know if should be commented out
174         else if(!keyName.compare("BackSpace"))
175             self->backPressed();
176     } else if(type == ECORE_EVENT_KEY_UP) {
177         M_ASSERT(event);
178         Ecore_Event_Key *ev = static_cast<Ecore_Event_Key *>(event);
179
180         if(!ev->keyname)
181             return EINA_TRUE;
182
183         BROWSER_LOGD("Released key: %s", ev->keyname);
184         const std::string keyName = ev->keyname;
185
186         /**
187          * When arrow key is released thread realizing pointer movement is stopped.
188          */
189 //        if(self->m_pointerModeEnabled && (!keyName.compare("KEY_LEFT")||!keyName.compare("KEY_UP")
190 //        || !keyName.compare("KEY_RIGHT")||!keyName.compare("KEY_DOWN"))) {
191 //            if(self->m_mouseMoveTimer) {
192 //                self->m_currentMouseMovementParams.moveMousePointer = false;
193 //                ecore_timer_del(self->m_mouseMoveTimer);
194 //                self->m_mouseMoveTimer = NULL;
195 //            }
196 //            return EINA_FALSE;
197 //        }
198         /**
199          * If Return key is being released we send event that mouse button was released (in pointer mode).
200          */
201 //        if(self->m_lastPressedKey == RETURN && self->m_pointerModeEnabled && !keyName.compare("KEY_ENTER")) {
202 //            self->m_lastPressedKey = OTHER_KEY;
203 //            self->mouseButtonManipulate(Button1, ButtonRelease);
204 //            return EINA_FALSE;
205 //        }
206     }
207     return EINA_TRUE;
208 }
209 /*
210 Eina_Bool PlatformInputManager::mouseMove(void *data)
211 {
212     int x, y;
213     PlatformInputManager *self = static_cast<PlatformInputManager*>(data);
214
215     if(self->m_currentMouseMovementParams.moveMousePointer) {
216         ecore_x_pointer_xy_get(self->m_xWindow, &x, &y);
217         x += self->m_currentMouseMovementParams.xMod * self->m_currentMouseMovementParams.speed;
218         y += self->m_currentMouseMovementParams.yMod * self->m_currentMouseMovementParams.speed;
219         ecore_x_pointer_warp(self->m_xWindow, x, y);
220         ecore_x_flush();
221
222         ++(self->m_currentMouseMovementParams.counter);
223         if(self->m_currentMouseMovementParams.counter == MOUSE_POINTER_STEPS) {
224             self->m_currentMouseMovementParams.counter = 0;
225             ++(self->m_currentMouseMovementParams.speed);
226         }
227         return EINA_TRUE;
228     }
229     return EINA_FALSE;
230 }
231 */
232 //Eina_Bool PlatformInputManager::__handler_FOCUS_IN(void *data, int /*type*/, void */*event*/)
233 //{
234 //    PlatformInputManager * self = reinterpret_cast<PlatformInputManager *>(data);
235 //    ecore_x_window_prop_window_set(self->m_devicemgr_win, self->m_atomAlwaysCursorOn, &(self->m_xWindow), 1);
236 //    return EINA_TRUE;
237 //}
238 /*
239 void PlatformInputManager::mouseButtonManipulate(int button, int event_type)
240 {
241     XEvent event;
242
243     Display *display = static_cast<Display*>(ecore_x_display_get());
244
245     memset(&event, 0x00, sizeof(event));
246
247     event.type = event_type;
248
249     if (event_type == ButtonRelease)
250         event.xbutton.state = 0x100;
251
252     event.xbutton.button = button;
253     event.xbutton.same_screen = True;
254
255     XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
256
257     event.xbutton.subwindow = event.xbutton.window;
258
259     while (event.xbutton.subwindow) {
260         event.xbutton.window = event.xbutton.subwindow;
261
262         XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
263     }
264
265     XSendEvent(display, PointerWindow, True, 0xfff, &event);
266
267     XFlush(display);
268 }
269 */
270 void PlatformInputManager::setPointerModeEnabled(bool enabled)
271 {
272     m_pointerModeEnabled = enabled;
273 }
274
275 bool PlatformInputManager::getPointerModeEnabled() const
276 {
277     return m_pointerModeEnabled;
278 }
279
280 }
281 }