Remove compile warning messages
[platform/core/appfw/app-core.git] / src / appcore-rotation.c
1 /*
2  *  app-core
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26
27 #include <sensor_internal.h>
28 #include <vconf.h>
29 #include <Ecore.h>
30 #include "appcore-internal.h"
31
32 #ifdef X11
33 #include <Ecore_X.h>
34 #include <X11/Xlib.h>
35
36 /* Fixme: to be added for wayland works */
37 #define _MAKE_ATOM(a, s)                                \
38         do {                                            \
39                 a = ecore_x_atom_get(s);                \
40                 if (!a)                                 \
41                         _ERR("##s creation failed.\n"); \
42         } while (0)
43
44 #define STR_ATOM_ROTATION_LOCK "_E_ROTATION_LOCK"
45
46 static Ecore_X_Atom ATOM_ROTATION_LOCK = 0;
47 static Ecore_X_Window root;
48 #endif
49
50 struct rot_s {
51         int handle;
52         int (*callback) (void *event_info, enum appcore_rm, void *);
53         enum appcore_rm mode;
54         int lock;
55         void *cbdata;
56         int cb_set;
57         int sf_started;
58
59         struct ui_wm_rotate* wm_rotate;
60 };
61 static struct rot_s rot;
62
63 struct rot_evt {
64         enum accelerometer_rotate_state re;
65         enum appcore_rm rm;
66 };
67
68 static struct rot_evt re_to_rm[] = {
69         {
70          ROTATION_EVENT_0,
71           APPCORE_RM_PORTRAIT_NORMAL,
72         },
73         {
74          ROTATION_EVENT_90,
75          APPCORE_RM_LANDSCAPE_NORMAL,
76         },
77         {
78          ROTATION_EVENT_180,
79          APPCORE_RM_PORTRAIT_REVERSE,
80         },
81         {
82          ROTATION_EVENT_270,
83          APPCORE_RM_LANDSCAPE_REVERSE,
84         },
85 };
86
87 static enum appcore_rm __get_mode(int event_data)
88 {
89         int i;
90         enum appcore_rm m;
91
92         m = APPCORE_RM_UNKNOWN;
93
94         for (i = 0; i < sizeof(re_to_rm) / sizeof(re_to_rm[0]); i++) {
95                 if (re_to_rm[i].re == event_data) {
96                         m = re_to_rm[i].rm;
97                         break;
98                 }
99         }
100
101         return m;
102 }
103
104 static void __changed_cb(unsigned int event_type, sensor_event_data_t *event,
105                        void *data)
106 {
107         int *cb_event_data;
108         enum appcore_rm m;
109
110         if (rot.lock)
111                 return;
112
113         if (event_type != ACCELEROMETER_EVENT_ROTATION_CHECK) {
114                 errno = EINVAL;
115                 return;
116         }
117
118         cb_event_data = (int *)(event->event_data);
119
120         m = __get_mode(*cb_event_data);
121
122         _DBG("[APP %d] Rotation: %d -> %d", getpid(), rot.mode, m);
123
124         if (rot.callback) {
125                 if (rot.cb_set && rot.mode != m) {
126                         _DBG("[APP %d] Rotation: %d -> %d", getpid(), rot.mode, m);
127                         rot.callback((void *)&m, m, data);
128                         rot.mode = m;
129                 }
130         }
131 }
132
133 static void __lock_cb(keynode_t *node, void *data)
134 {
135         int r;
136         enum appcore_rm m;
137
138         rot.lock = !vconf_keynode_get_bool(node);
139
140         if (rot.lock) {
141                 m = APPCORE_RM_PORTRAIT_NORMAL;
142                 if (rot.mode != m) {
143                         rot.callback((void *)&m, m, data);
144                         rot.mode = m;
145                 }
146                 _DBG("[APP %d] Rotation locked", getpid());
147                 return;
148         }
149
150         _DBG("[APP %d] Rotation unlocked", getpid());
151         if (rot.callback) {
152                 if (rot.cb_set) {
153                         r = appcore_get_rotation_state(&m);
154                         _DBG("[APP %d] Rotmode prev %d -> curr %d", getpid(),
155                              rot.mode, m);
156                         if (!r && rot.mode != m) {
157                                 rot.callback((void *)&m, m, data);
158                                 rot.mode = m;
159                         }
160                 }
161         }
162 }
163
164 static void __add_rotlock(void *data)
165 {
166         int r;
167         int lock;
168
169         lock = 0;
170         r = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
171         if (r)
172                 _DBG("[APP %d] Rotation vconf get bool failed", getpid());
173
174         rot.lock = !lock;
175
176         vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb,
177                                  data);
178 }
179
180 static void __del_rotlock(void)
181 {
182         vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb);
183         rot.lock = 0;
184 }
185
186 EXPORT_API int appcore_set_rotation_cb(int (*cb) (void *evnet_info, enum appcore_rm, void *),
187                                        void *data)
188 {
189         if (rot.wm_rotate)
190                 return rot.wm_rotate->set_rotation_cb(cb, data);
191         else {
192                 int r;
193                 int handle;
194
195                 if (cb == NULL) {
196                         errno = EINVAL;
197                         return -1;
198                 }
199
200                 if (rot.callback != NULL) {
201                         errno = EALREADY;
202                         return -1;
203                 }
204
205                 handle = sf_connect(ACCELEROMETER_SENSOR);
206                 if (handle < 0) {
207                         _ERR("sf_connect failed: %d", handle);
208                         return -1;
209                 }
210
211                 r = sf_register_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK,
212                                       NULL, __changed_cb, data);
213                 if (r < 0) {
214                         _ERR("sf_register_event failed: %d", r);
215                         sf_disconnect(handle);
216                         return -1;
217                 }
218
219                 rot.cb_set = 1;
220                 rot.callback = cb;
221                 rot.cbdata = data;
222
223                 r = sf_start(handle, 0);
224                 if (r < 0) {
225                         _ERR("sf_start failed: %d", r);
226                         r = sf_unregister_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK);
227                         if (r < 0)
228                                 _ERR("sf_unregister_event failed: %d", r);
229
230                         rot.callback = NULL;
231                         rot.cbdata = NULL;
232                         rot.cb_set = 0;
233                         rot.sf_started = 0;
234                         sf_disconnect(handle);
235                         return -1;
236                 }
237                 rot.sf_started = 1;
238
239                 rot.handle = handle;
240                 __add_rotlock(data);
241
242 #ifdef X11
243                 _MAKE_ATOM(ATOM_ROTATION_LOCK, STR_ATOM_ROTATION_LOCK);
244                 root =  ecore_x_window_root_first_get();
245                 XSelectInput(ecore_x_display_get(), root, PropertyChangeMask);
246 #endif
247         }
248         return 0;
249 }
250
251 EXPORT_API int appcore_unset_rotation_cb(void)
252 {
253         if (rot.wm_rotate)
254                 return rot.wm_rotate->unset_rotation_cb();
255         else {
256                 int r;
257
258                 _retv_if(rot.callback == NULL, 0);
259
260                 __del_rotlock();
261
262                 if (rot.cb_set) {
263                         r = sf_unregister_event(rot.handle,
264                                                 ACCELEROMETER_EVENT_ROTATION_CHECK);
265                         if (r < 0) {
266                                 _ERR("sf_unregister_event failed: %d", r);
267                                 return -1;
268                         }
269                         rot.cb_set = 0;
270                 }
271                 rot.callback = NULL;
272                 rot.cbdata = NULL;
273
274                 if (rot.sf_started == 1) {
275                         r = sf_stop(rot.handle);
276                         if (r < 0) {
277                                 _ERR("sf_stop failed: %d", r);
278                                 return -1;
279                         }
280                         rot.sf_started = 0;
281                 }
282
283                 r = sf_disconnect(rot.handle);
284                 if (r < 0) {
285                         _ERR("sf_disconnect failed: %d", r);
286                         return -1;
287                 }
288                 rot.handle = -1;
289         }
290         return 0;
291 }
292
293 EXPORT_API int appcore_get_rotation_state(enum appcore_rm *curr)
294 {
295         if (rot.wm_rotate)
296                 return rot.wm_rotate->get_rotation_state(curr);
297         else {
298                 int r;
299                 unsigned long event;
300
301                 if (curr == NULL) {
302                         errno = EINVAL;
303                         return -1;
304                 }
305
306                 r = sf_check_rotation(&event);
307                 if (r < 0) {
308                         _ERR("sf_check_rotation failed: %d", r);
309                         *curr = APPCORE_RM_UNKNOWN;
310                         return -1;
311                 }
312
313                 *curr = __get_mode(event);
314         }
315         return 0;
316 }
317
318 EXPORT_API int appcore_pause_rotation_cb(void)
319 {
320         if (rot.wm_rotate)
321                 return rot.wm_rotate->pause_rotation_cb();
322         else {
323                 int r;
324
325                 _retv_if(rot.callback == NULL, 0);
326                 _DBG("[APP %d] appcore_pause_rotation_cb is called", getpid());
327
328                 __del_rotlock();
329
330                 if (rot.cb_set) {
331                         r = sf_unregister_event(rot.handle,
332                                                 ACCELEROMETER_EVENT_ROTATION_CHECK);
333                         if (r < 0) {
334                                 _ERR("sf_unregister_event in appcore_internal_sf_stop failed: %d", r);
335                                 return -1;
336                         }
337                         rot.cb_set = 0;
338                 }
339
340                 if (rot.sf_started == 1) {
341                         r = sf_stop(rot.handle);
342                         if (r < 0) {
343                                 _ERR("sf_stop in appcore_internal_sf_stop failed: %d",
344                                      r);
345                                 return -1;
346                         }
347                         rot.sf_started = 0;
348                 }
349         }
350
351         return 0;
352 }
353
354 EXPORT_API int appcore_resume_rotation_cb(void)
355 {
356         if (rot.wm_rotate)
357                 return rot.wm_rotate->resume_rotation_cb();
358         else {
359                 int r;
360                 int ret;
361                 enum appcore_rm m;
362
363                 _retv_if(rot.callback == NULL, 0);
364                 _DBG("[APP %d] appcore_resume_rotation_cb is called", getpid());
365
366                 if (rot.cb_set == 0) {
367                         r = sf_register_event(rot.handle,
368                                               ACCELEROMETER_EVENT_ROTATION_CHECK, NULL,
369                                               __changed_cb, rot.cbdata);
370                         if (r < 0) {
371                                 _ERR("sf_register_event in appcore_internal_sf_start failed: %d", r);
372                                 return -1;
373                         }
374                         rot.cb_set = 1;
375                 }
376
377                 if (rot.sf_started == 0) {
378                         r = sf_start(rot.handle, 0);
379                         if (r < 0) {
380                                 _ERR("sf_start in appcore_internal_sf_start failed: %d",
381                                      r);
382                                 ret = sf_unregister_event(rot.handle,
383                                                     ACCELEROMETER_EVENT_ROTATION_CHECK);
384                                 if (ret < 0)
385                                         _ERR("sf_unregister_event failed: %d", ret);
386                                 rot.cb_set = 0;
387                                 return -1;
388                         }
389                         rot.sf_started = 1;
390                 }
391
392                 __add_rotlock(rot.cbdata);
393
394                 r = appcore_get_rotation_state(&m);
395                 _DBG("[APP %d] Rotmode prev %d -> curr %d", getpid(), rot.mode, m);
396                 if (!r && rot.mode != m && rot.lock == 0) {
397                         rot.callback((void *)&m, m, rot.cbdata);
398                         rot.mode = m;
399                 }
400         }
401         return 0;
402 }
403
404 EXPORT_API int appcore_set_wm_rotation(struct ui_wm_rotate* wm_rotate)
405 {
406         if (!wm_rotate) return -1;
407
408         if (rot.callback) {
409                 wm_rotate->set_rotation_cb(rot.callback, rot.cbdata);
410                 appcore_unset_rotation_cb();
411         }
412         rot.wm_rotate = wm_rotate;
413         _DBG("[APP %d] Support wm rotate:%p", getpid(), wm_rotate);
414         return 0;
415 }