From defc88f78b3d4e512952afa45ced2b0619932554 Mon Sep 17 00:00:00 2001 From: Jaeho Lee Date: Tue, 19 Feb 2013 17:47:00 +0900 Subject: [PATCH] changed rotation code Signed-off-by: Jaeho Lee --- include/appcore-internal.h | 8 ++ src/appcore-efl.c | 204 ++++++++++++++++++++++++++++++- src/appcore-rotation.c | 296 +++++++++++++++++++++++++-------------------- src/appcore.c | 23 +++- 4 files changed, 395 insertions(+), 136 deletions(-) diff --git a/include/appcore-internal.h b/include/appcore-internal.h index dd3f890..038e2dc 100755 --- a/include/appcore-internal.h +++ b/include/appcore-internal.h @@ -169,6 +169,14 @@ extern int x_raise_win(pid_t pid); int appcore_pause_rotation_cb(void); int appcore_resume_rotation_cb(void); +struct ui_wm_rotate { + int (*set_rotation_cb) (int (*cb) (enum appcore_rm, void *), void *data); + int (*unset_rotation_cb) (void); + int (*get_rotation_state) (enum appcore_rm *curr); + int (*pause_rotation_cb) (void); + int (*resume_rotation_cb) (void); +}; +int appcore_set_wm_rotation(struct ui_wm_rotate* wm_rotate); #define ENV_START "APP_START_TIME" diff --git a/src/appcore-efl.c b/src/appcore-efl.c index a66ade5..dfc1735 100755 --- a/src/appcore-efl.c +++ b/src/appcore-efl.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -46,11 +49,19 @@ struct ui_priv { Ecore_Event_Handler *hshow; Ecore_Event_Handler *hhide; Ecore_Event_Handler *hvchange; + Ecore_Event_Handler *hcmsg; /* WM_ROTATE */ Ecore_Timer *mftimer; /* Ecore Timer for memory flushing */ struct appcore_ops *ops; void (*mfcb) (void); /* Memory Flushing Callback */ + + /* WM_ROTATE */ + int wm_rot_supported; + int rot_started; + int (*rot_cb) (enum appcore_rm, void *); + void *rot_cb_data; + enum appcore_rm rot_mode; }; static struct ui_priv priv; @@ -80,6 +91,8 @@ struct win_node { bool bfobscured; }; +static struct ui_wm_rotate wm_rotate; + static int WIN_COMP(gconstpointer data1, gconstpointer data2) { struct win_node *a = (struct win_node *)data1; @@ -87,7 +100,7 @@ static int WIN_COMP(gconstpointer data1, gconstpointer data2) return (int)((a->win)-(b->win)); } -GSList *g_winnode_list; +GSList *g_winnode_list = NULL; #if defined(MEMORY_FLUSH_ACTIVATE) static Eina_Bool __appcore_memory_flush_cb(void *data) @@ -349,6 +362,64 @@ static bool __update_win(unsigned int win, bool bfobscured) } +/* WM_ROTATE */ +static Ecore_X_Atom _WM_WINDOW_ROTATION_SUPPORTED = 0; +static Ecore_X_Atom _WM_WINDOW_ROTATION_CHANGE_REQUEST = 0; + +static int __check_wm_rotation_support(void) +{ + Ecore_X_Window root, win, win2; + int ret; + + if (!_WM_WINDOW_ROTATION_SUPPORTED) { + _WM_WINDOW_ROTATION_SUPPORTED = + ecore_x_atom_get("_E_WINDOW_ROTATION_SUPPORTED"); + } + + if (!_WM_WINDOW_ROTATION_CHANGE_REQUEST) { + _WM_WINDOW_ROTATION_CHANGE_REQUEST = + ecore_x_atom_get("_E_WINDOW_ROTATION_CHANGE_REQUEST"); + } + + root = ecore_x_window_root_first_get(); + ret = ecore_x_window_prop_xid_get(root, + _WM_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win, 1); + if ((ret == 1) && (win)) + { + ret = ecore_x_window_prop_xid_get(win, + _WM_WINDOW_ROTATION_SUPPORTED, + ECORE_X_ATOM_WINDOW, + &win2, 1); + if ((ret == 1) && (win2 == win)) + return 0; + } + + return -1; +} + +static void __set_wm_rotation_support(unsigned int win, unsigned int set) +{ + GSList *iter = NULL; + struct win_node *entry = NULL; + + if (0 == win) { + for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) { + entry = iter->data; + if (entry->win) { + ecore_x_window_prop_card32_set(entry->win, + _WM_WINDOW_ROTATION_SUPPORTED, + &set, 1); + } + } + } else { + ecore_x_window_prop_card32_set(win, + _WM_WINDOW_ROTATION_SUPPORTED, + &set, 1); + } +} + Ecore_X_Atom atom_parent; static Eina_Bool __show_cb(void *data, int type, void *event) @@ -368,8 +439,13 @@ static Eina_Bool __show_cb(void *data, int type, void *event) _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x\n", ev->win); - if (!__exist_win((unsigned int)ev->win)) + if (!__exist_win((unsigned int)ev->win)) { + /* WM_ROTATE */ + if ((priv.wm_rot_supported) && (1 == priv.rot_started)) { + __set_wm_rotation_support(ev->win, 1); + } __add_win((unsigned int)ev->win); + } else __update_win((unsigned int)ev->win, FALSE); @@ -425,6 +501,41 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) } +/* WM_ROTATE */ +static Eina_Bool __cmsg_cb(void *data, int type, void *event) +{ + struct ui_priv *ui = (struct ui_priv *)data; + Ecore_X_Event_Client_Message *e = event; + + if (!ui) return ECORE_CALLBACK_PASS_ON; + if (e->format != 32) return ECORE_CALLBACK_PASS_ON; + if (e->message_type == _WM_WINDOW_ROTATION_CHANGE_REQUEST) { + if ((0 == ui->wm_rot_supported) || + (0 == ui->rot_started) || + (NULL == ui->rot_cb)) { + return ECORE_CALLBACK_PASS_ON; + } + + enum appcore_rm rm; + switch (e->data.l[1]) + { + case 0: rm = APPCORE_RM_PORTRAIT_NORMAL; break; + case 90: rm = APPCORE_RM_LANDSCAPE_REVERSE; break; + case 180: rm = APPCORE_RM_PORTRAIT_REVERSE; break; + case 270: rm = APPCORE_RM_LANDSCAPE_NORMAL; break; + default: rm = APPCORE_RM_UNKNOWN; break; + } + + ui->rot_mode = rm; + + if (APPCORE_RM_UNKNOWN != rm) { + ui->rot_cb(rm, ui->rot_cb_data); + } + } + + return ECORE_CALLBACK_PASS_ON; +} + static void __add_climsg_cb(struct ui_priv *ui) { _ret_if(ui == NULL); @@ -443,6 +554,14 @@ static void __add_climsg_cb(struct ui_priv *ui) ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, ui); + /* Add client message callback for WM_ROTATE */ + if(!__check_wm_rotation_support()) + { + ui->hcmsg = + ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, __cmsg_cb, ui); + ui->wm_rot_supported = 1; + appcore_set_wm_rotation(&wm_rotate); + } } static int __before_loop(struct ui_priv *ui, int *argc, char ***argv) @@ -545,6 +664,13 @@ static int __set_data(struct ui_priv *ui, const char *name, _pid = getpid(); + /* WM_ROTATE */ + ui->wm_rot_supported = 0; + ui->rot_started = 0; + ui->rot_cb = NULL; + ui->rot_cb_data = NULL; + ui->rot_mode = APPCORE_RM_UNKNOWN; + return 0; } @@ -556,6 +682,80 @@ static void __unset_data(struct ui_priv *ui) memset(ui, 0, sizeof(struct ui_priv)); } +/* WM_ROTATE */ +static int __wm_set_rotation_cb(int (*cb) (enum appcore_rm, void *), void *data) +{ + if (cb == NULL) { + errno = EINVAL; + return -1; + } + + if ((priv.wm_rot_supported) && (0 == priv.rot_started)) { + __set_wm_rotation_support(0, 1); + } + + priv.rot_cb = cb; + priv.rot_cb_data = data; + priv.rot_started = 1; + + return 0; +} + +static int __wm_unset_rotation_cb(void) +{ + if ((priv.wm_rot_supported) && (1 == priv.rot_started)) { + __set_wm_rotation_support(0, 0); + } + + priv.rot_cb = NULL; + priv.rot_cb_data = NULL; + priv.rot_started = 0; + + return 0; +} + +static int __wm_get_rotation_state(enum appcore_rm *curr) +{ + if (curr == NULL) { + errno = EINVAL; + return -1; + } + + *curr = priv.rot_mode; + + return 0; +} + +static int __wm_pause_rotation_cb(void) +{ + if ((1 == priv.rot_started) && (priv.wm_rot_supported)) { + __set_wm_rotation_support(0, 0); + } + + priv.rot_started = 0; + + return 0; +} + +static int __wm_resume_rotation_cb(void) +{ + if ((0 == priv.rot_started) && (priv.wm_rot_supported)) { + __set_wm_rotation_support(0, 1); + } + + priv.rot_started = 1; + + return 0; +} + +static struct ui_wm_rotate wm_rotate = { + __wm_set_rotation_cb, + __wm_unset_rotation_cb, + __wm_get_rotation_state, + __wm_pause_rotation_cb, + __wm_resume_rotation_cb +}; + EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv, struct appcore_ops *ops) { diff --git a/src/appcore-rotation.c b/src/appcore-rotation.c index c6657db..27c747a 100755 --- a/src/appcore-rotation.c +++ b/src/appcore-rotation.c @@ -52,6 +52,8 @@ struct rot_s { void *cbdata; int cb_set; int sf_started; + + struct ui_wm_rotate* wm_rotate; }; static struct rot_s rot; @@ -184,148 +186,165 @@ static void __del_rotlock(void) EXPORT_API int appcore_set_rotation_cb(int (*cb) (enum appcore_rm, void *), void *data) { - int r; - int handle; - - if (cb == NULL) { - errno = EINVAL; - return -1; + if (rot.wm_rotate) { + return rot.wm_rotate->set_rotation_cb(cb, data); } + else { + int r; + int handle; - if (rot.callback != NULL) { - errno = EALREADY; - return -1; - } + if (cb == NULL) { + errno = EINVAL; + return -1; + } - handle = sf_connect(ACCELEROMETER_SENSOR); - if (handle < 0) { - _ERR("sf_connect failed: %d", handle); - return -1; - } + if (rot.callback != NULL) { + errno = EALREADY; + return -1; + } - r = sf_register_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK, - NULL, __changed_cb, data); - if (r < 0) { - _ERR("sf_register_event failed: %d", r); - sf_disconnect(handle); - return -1; - } + handle = sf_connect(ACCELEROMETER_SENSOR); + if (handle < 0) { + _ERR("sf_connect failed: %d", handle); + return -1; + } - rot.cb_set = 1; - rot.callback = cb; - rot.cbdata = data; + r = sf_register_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK, + NULL, __changed_cb, data); + if (r < 0) { + _ERR("sf_register_event failed: %d", r); + sf_disconnect(handle); + return -1; + } - r = sf_start(handle, 0); - if (r < 0) { - _ERR("sf_start failed: %d", r); - sf_unregister_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK); - rot.callback = NULL; - rot.cbdata = NULL; - rot.cb_set = 0; - rot.sf_started = 0; - sf_disconnect(handle); - return -1; - } - rot.sf_started = 1; + rot.cb_set = 1; + rot.callback = cb; + rot.cbdata = data; - rot.handle = handle; - __add_rotlock(data); + r = sf_start(handle, 0); + if (r < 0) { + _ERR("sf_start failed: %d", r); + sf_unregister_event(handle, ACCELEROMETER_EVENT_ROTATION_CHECK); + rot.callback = NULL; + rot.cbdata = NULL; + rot.cb_set = 0; + rot.sf_started = 0; + sf_disconnect(handle); + return -1; + } + rot.sf_started = 1; - _MAKE_ATOM(ATOM_ROTATION_LOCK, STR_ATOM_ROTATION_LOCK ); - root = ecore_x_window_root_first_get(); - XSelectInput(ecore_x_display_get(), root, PropertyChangeMask); + rot.handle = handle; + __add_rotlock(data); + _MAKE_ATOM(ATOM_ROTATION_LOCK, STR_ATOM_ROTATION_LOCK ); + root = ecore_x_window_root_first_get(); + XSelectInput(ecore_x_display_get(), root, PropertyChangeMask); + } return 0; } EXPORT_API int appcore_unset_rotation_cb(void) { - int r; + if (rot.wm_rotate) { + return rot.wm_rotate->unset_rotation_cb(); + } + else { + int r; - _retv_if(rot.callback == NULL, 0); + _retv_if(rot.callback == NULL, 0); - __del_rotlock(); + __del_rotlock(); - if (rot.cb_set) { - r = sf_unregister_event(rot.handle, - ACCELEROMETER_EVENT_ROTATION_CHECK); - if (r < 0) { - _ERR("sf_unregister_event failed: %d", r); - return -1; + if (rot.cb_set) { + r = sf_unregister_event(rot.handle, + ACCELEROMETER_EVENT_ROTATION_CHECK); + if (r < 0) { + _ERR("sf_unregister_event failed: %d", r); + return -1; + } + rot.cb_set = 0; + } + rot.callback = NULL; + rot.cbdata = NULL; + + if (rot.sf_started == 1) { + r = sf_stop(rot.handle); + if (r < 0) { + _ERR("sf_stop failed: %d", r); + return -1; + } + rot.sf_started = 0; } - rot.cb_set = 0; - } - rot.callback = NULL; - rot.cbdata = NULL; - if (rot.sf_started == 1) { - r = sf_stop(rot.handle); + r = sf_disconnect(rot.handle); if (r < 0) { - _ERR("sf_stop failed: %d", r); + _ERR("sf_disconnect failed: %d", r); return -1; } - rot.sf_started = 0; + rot.handle = -1; } - - r = sf_disconnect(rot.handle); - if (r < 0) { - _ERR("sf_disconnect failed: %d", r); - return -1; - } - rot.handle = -1; - return 0; } EXPORT_API int appcore_get_rotation_state(enum appcore_rm *curr) { - int r; - unsigned long event; - - if (curr == NULL) { - errno = EINVAL; - return -1; + if (rot.wm_rotate) { + return rot.wm_rotate->get_rotation_state(curr); } + else { + int r; + unsigned long event; - r = sf_check_rotation(&event); - if (r < 0) { - _ERR("sf_check_rotation failed: %d", r); - *curr = APPCORE_RM_UNKNOWN; - return -1; - } + if (curr == NULL) { + errno = EINVAL; + return -1; + } - *curr = __get_mode(event); + r = sf_check_rotation(&event); + if (r < 0) { + _ERR("sf_check_rotation failed: %d", r); + *curr = APPCORE_RM_UNKNOWN; + return -1; + } + *curr = __get_mode(event); + } return 0; } EXPORT_API int appcore_pause_rotation_cb(void) { - int r; + if (rot.wm_rotate) { + return rot.wm_rotate->pause_rotation_cb(); + } + else { + int r; - _retv_if(rot.callback == NULL, 0); - _DBG("[APP %d] appcore_pause_rotation_cb is called", getpid()); + _retv_if(rot.callback == NULL, 0); + _DBG("[APP %d] appcore_pause_rotation_cb is called", getpid()); - __del_rotlock(); + __del_rotlock(); - if (rot.cb_set) { - r = sf_unregister_event(rot.handle, - ACCELEROMETER_EVENT_ROTATION_CHECK); - if (r < 0) { - _ERR("sf_unregister_event in appcore_internal_sf_stop failed: %d", r); - return -1; + if (rot.cb_set) { + r = sf_unregister_event(rot.handle, + ACCELEROMETER_EVENT_ROTATION_CHECK); + if (r < 0) { + _ERR("sf_unregister_event in appcore_internal_sf_stop failed: %d", r); + return -1; + } + rot.cb_set = 0; } - rot.cb_set = 0; - } - if (rot.sf_started == 1) { - r = sf_stop(rot.handle); - if (r < 0) { - _ERR("sf_stop in appcore_internal_sf_stop failed: %d", - r); - return -1; + if (rot.sf_started == 1) { + r = sf_stop(rot.handle); + if (r < 0) { + _ERR("sf_stop in appcore_internal_sf_stop failed: %d", + r); + return -1; + } + rot.sf_started = 0; } - rot.sf_started = 0; } return 0; @@ -333,44 +352,61 @@ EXPORT_API int appcore_pause_rotation_cb(void) EXPORT_API int appcore_resume_rotation_cb(void) { - int r; - enum appcore_rm m; - - _retv_if(rot.callback == NULL, 0); - _DBG("[APP %d] appcore_resume_rotation_cb is called", getpid()); + if (rot.wm_rotate) { + return rot.wm_rotate->resume_rotation_cb(); + } + else { + int r; + enum appcore_rm m; + + _retv_if(rot.callback == NULL, 0); + _DBG("[APP %d] appcore_resume_rotation_cb is called", getpid()); + + if (rot.cb_set == 0) { + r = sf_register_event(rot.handle, + ACCELEROMETER_EVENT_ROTATION_CHECK, NULL, + __changed_cb, rot.cbdata); + if (r < 0) { + _ERR("sf_register_event in appcore_internal_sf_start failed: %d", r); + return -1; + } + rot.cb_set = 1; + } - if (rot.cb_set == 0) { - r = sf_register_event(rot.handle, - ACCELEROMETER_EVENT_ROTATION_CHECK, NULL, - __changed_cb, rot.cbdata); - if (r < 0) { - _ERR("sf_register_event in appcore_internal_sf_start failed: %d", r); - return -1; + if (rot.sf_started == 0) { + r = sf_start(rot.handle, 0); + if (r < 0) { + _ERR("sf_start in appcore_internal_sf_start failed: %d", + r); + sf_unregister_event(rot.handle, + ACCELEROMETER_EVENT_ROTATION_CHECK); + rot.cb_set = 0; + return -1; + } + rot.sf_started = 1; } - rot.cb_set = 1; - } - if (rot.sf_started == 0) { - r = sf_start(rot.handle, 0); - if (r < 0) { - _ERR("sf_start in appcore_internal_sf_start failed: %d", - r); - sf_unregister_event(rot.handle, - ACCELEROMETER_EVENT_ROTATION_CHECK); - rot.cb_set = 0; - return -1; + __add_rotlock(rot.cbdata); + + r = appcore_get_rotation_state(&m); + _DBG("[APP %d] Rotmode prev %d -> curr %d", getpid(), rot.mode, m); + if (!r && rot.mode != m && rot.lock == 0) { + rot.callback(m, rot.cbdata); + rot.mode = m; } - rot.sf_started = 1; } + return 0; +} - __add_rotlock(rot.cbdata); +EXPORT_API int appcore_set_wm_rotation(struct ui_wm_rotate* wm_rotate) +{ + if (!wm_rotate) return -1; - r = appcore_get_rotation_state(&m); - _DBG("[APP %d] Rotmode prev %d -> curr %d", getpid(), rot.mode, m); - if (!r && rot.mode != m && rot.lock == 0) { - rot.callback(m, rot.cbdata); - rot.mode = m; + if (rot.callback) { + wm_rotate->set_rotation_cb(rot.callback, rot.cbdata); + appcore_unset_rotation_cb(); } - + rot.wm_rotate = wm_rotate; + _DBG("[APP %d] Support wm rotate:%p", getpid(), wm_rotate); return 0; } diff --git a/src/appcore.c b/src/appcore.c index ace9e89..da03942 100755 --- a/src/appcore.c +++ b/src/appcore.c @@ -232,18 +232,33 @@ static int __sys_do(struct appcore *ac, enum sys_event event) static int __sys_lowmem_post(void *data, void *evt) { + keynode_t *key = evt; + int val; + + val = vconf_keynode_get_int(key); + + if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) { #if defined(MEMORY_FLUSH_ACTIVATE) - struct appcore *ac = data; - ac->ops->cb_app(AE_LOWMEM_POST, ac->ops->data, NULL); + struct appcore *ac = data; + ac->ops->cb_app(AE_LOWMEM_POST, ac->ops->data, NULL); #else - malloc_trim(0); + malloc_trim(0); #endif + } return 0; } static int __sys_lowmem(void *data, void *evt) { - return __sys_do(data, SE_LOWMEM); + keynode_t *key = evt; + int val; + + val = vconf_keynode_get_int(key); + + if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) + return __sys_do(data, SE_LOWMEM); + + return 0; } static int __sys_lowbatt(void *data, void *evt) -- 2.7.4