4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
33 #include "appcore-internal.h"
35 #define _MAKE_ATOM(a, s) \
37 a = ecore_x_atom_get(s); \
39 _ERR("##s creation failed.\n"); \
42 #define STR_ATOM_ROTATION_LOCK "_E_ROTATION_LOCK"
44 static Ecore_X_Atom ATOM_ROTATION_LOCK = 0;
45 static Ecore_X_Window root;
49 int (*callback) (enum appcore_rm, void *);
56 static struct rot_s rot;
59 enum accelerometer_rotate_state re;
63 static struct rot_evt re_to_rm[] = {
66 APPCORE_RM_PORTRAIT_NORMAL,
70 APPCORE_RM_LANDSCAPE_NORMAL,
74 APPCORE_RM_PORTRAIT_REVERSE,
78 APPCORE_RM_LANDSCAPE_REVERSE,
82 static enum appcore_rm changed_m;
83 static void *changed_data;
84 static Ecore_Event_Handler *changed_handle;
86 static enum appcore_rm __get_mode(int event_data)
91 m = APPCORE_RM_UNKNOWN;
93 for (i = 0; i < sizeof(re_to_rm) / sizeof(re_to_rm[0]); i++) {
94 if (re_to_rm[i].re == event_data) {
103 static Eina_Bool __property(void *data, int type, void *event)
105 Ecore_X_Event_Window_Property *ev = event;
108 return ECORE_CALLBACK_PASS_ON;
110 if (ev->atom == ATOM_ROTATION_LOCK) {
111 _DBG("[APP %d] Rotation: %d -> %d, cb_set : %d", getpid(), rot.mode, changed_m, rot.cb_set);
112 if (rot.cb_set && rot.mode != changed_m) {
113 rot.callback(changed_m, changed_data);
114 rot.mode = changed_m;
117 ecore_event_handler_del(changed_handle);
118 changed_handle = NULL;
121 return ECORE_CALLBACK_PASS_ON;
124 static void __changed_cb(unsigned int event_type, sensor_event_data_t *event,
135 if (event_type != ACCELEROMETER_EVENT_ROTATION_CHECK) {
140 cb_event_data = (int *)(event->event_data);
142 m = __get_mode(*cb_event_data);
144 _DBG("[APP %d] Rotation: %d -> %d", getpid(), rot.mode, m);
147 if (rot.cb_set && rot.mode != m) {
148 ret = ecore_x_window_prop_card32_get(root, ATOM_ROTATION_LOCK, &val, 1);
150 _DBG("[APP %d] Rotation: %d -> %d, val : %d, ret : %d", getpid(), rot.mode, m, val, ret);
151 if (!val || ret < 1) {
152 rot.callback(m, data);
157 ecore_event_handler_del(changed_handle);
158 changed_handle = NULL;
160 changed_handle = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, __property, NULL);
167 static void __lock_cb(keynode_t *node, void *data)
174 rot.lock = vconf_keynode_get_bool(node);
177 _DBG("[APP %d] Rotation locked", getpid());
181 _DBG("[APP %d] Rotation unlocked", getpid());
184 r = appcore_get_rotation_state(&m);
185 _DBG("[APP %d] Rotmode prev %d -> curr %d", getpid(),
187 if (!r && rot.mode != m) {
189 rot.callback(m, data);
194 ecore_event_handler_del(changed_handle);
195 changed_handle = NULL;
197 changed_handle = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, __property, NULL);
207 static void __add_rotlock(void *data)
213 r = vconf_get_bool(VCONFKEY_SETAPPL_ROTATE_LOCK_BOOL, &lock);
215 _DBG("[APP %d] Rotation vconf get bool failed", getpid());
220 vconf_notify_key_changed(VCONFKEY_SETAPPL_ROTATE_LOCK_BOOL, __lock_cb,
224 static void __del_rotlock(void)
226 vconf_ignore_key_changed(VCONFKEY_SETAPPL_ROTATE_LOCK_BOOL, __lock_cb);
230 EXPORT_API int appcore_set_rotation_cb(int (*cb) (enum appcore_rm, void *),
241 if (rot.callback != NULL) {
246 handle = sf_connect(ACCELEROMETER_SENSOR);
248 _ERR("sf_connect failed: %d", handle);
252 r = sf_register_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK,
253 NULL, __changed_cb, data);
255 _ERR("sf_register_event failed: %d", r);
256 sf_disconnect(handle);
264 r = sf_start(handle, 0);
266 _ERR("sf_start failed: %d", r);
267 sf_unregister_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK);
272 sf_disconnect(handle);
280 _MAKE_ATOM(ATOM_ROTATION_LOCK, STR_ATOM_ROTATION_LOCK );
281 root = ecore_x_window_root_first_get();
282 XSelectInput(ecore_x_display_get(), root, PropertyChangeMask);
287 EXPORT_API int appcore_unset_rotation_cb(void)
291 _retv_if(rot.callback == NULL, 0);
296 r = sf_unregister_event(rot.handle,
297 ACCELEROMETER_EVENT_ROTATION_CHECK);
299 _ERR("sf_unregister_event failed: %d", r);
307 if (rot.sf_started == 1) {
308 r = sf_stop(rot.handle);
310 _ERR("sf_stop failed: %d", r);
316 r = sf_disconnect(rot.handle);
318 _ERR("sf_disconnect failed: %d", r);
326 EXPORT_API int appcore_get_rotation_state(enum appcore_rm *curr)
336 r = sf_check_rotation(&event);
338 _ERR("sf_check_rotation failed: %d", r);
339 *curr = APPCORE_RM_UNKNOWN;
343 *curr = __get_mode(event);
348 EXPORT_API int appcore_pause_rotation_cb(void)
352 _retv_if(rot.callback == NULL, 0);
353 _DBG("[APP %d] appcore_pause_rotation_cb is called", getpid());
358 r = sf_unregister_event(rot.handle,
359 ACCELEROMETER_EVENT_ROTATION_CHECK);
361 _ERR("sf_unregister_event in appcore_internal_sf_stop failed: %d", r);
367 if (rot.sf_started == 1) {
368 r = sf_stop(rot.handle);
370 _ERR("sf_stop in appcore_internal_sf_stop failed: %d",
380 EXPORT_API int appcore_resume_rotation_cb(void)
385 _retv_if(rot.callback == NULL, 0);
386 _DBG("[APP %d] appcore_resume_rotation_cb is called", getpid());
388 if (rot.cb_set == 0) {
389 r = sf_register_event(rot.handle,
390 ACCELEROMETER_EVENT_ROTATION_CHECK, NULL,
391 __changed_cb, rot.cbdata);
393 _ERR("sf_register_event in appcore_internal_sf_start failed: %d", r);
399 if (rot.sf_started == 0) {
400 r = sf_start(rot.handle, 0);
402 _ERR("sf_start in appcore_internal_sf_start failed: %d",
404 sf_unregister_event(rot.handle,
405 ACCELEROMETER_EVENT_ROTATION_CHECK);
412 __add_rotlock(rot.cbdata);
414 r = appcore_get_rotation_state(&m);
415 _DBG("[APP %d] Rotmode prev %d -> curr %d", getpid(), rot.mode, m);
416 if (!r && rot.mode != m && rot.lock == 0) {
417 rot.callback(m, rot.cbdata);