From ac2b345a5a5cc34e50269f207afe7fc5d28e6f55 Mon Sep 17 00:00:00 2001 From: taeyoon Date: Wed, 30 Dec 2015 15:11:00 +0900 Subject: [PATCH] [3.0] Add key grab/ungrab interfaces for Tizen (X11/Wayland) Modify an Yoonsang Lee's patch for latest dali Conflicts: adaptors/tizen/file.list build/tizen/configure.ac Change-Id: I58279bb29b3e552f0e0eaef3db1c6dc746e83215 --- adaptors/ecore/wayland/ecore_wl_private.h | 323 +++++++++++++++++++++ adaptors/ecore/wayland/file.list | 4 +- adaptors/ecore/wayland/key-grab-ecore-wl.cpp | 185 ++++++++++++ adaptors/ecore/wayland/keyrouter-client-protocol.h | 167 +++++++++++ .../wayland/tizen-extension-client-protocol.h | 99 +++++++ .../ecore/wayland/tizen-policy-client-protocol.h | 140 +++++++++ adaptors/ecore/wayland/window-impl-ecore-wl.cpp | 7 + .../wayland/window-render-surface-ecore-wl.cpp | 4 +- adaptors/ecore/wayland/window-render-surface.h | 3 + adaptors/tizen/file.list | 4 +- adaptors/tizen/key-grab.h | 100 +++++++ adaptors/x11/file.list | 3 +- adaptors/x11/key-grab-x.cpp | 89 ++++++ build/tizen/adaptor/Makefile.am | 10 + build/tizen/configure.ac | 1 + 15 files changed, 1134 insertions(+), 5 deletions(-) create mode 100644 adaptors/ecore/wayland/ecore_wl_private.h create mode 100644 adaptors/ecore/wayland/key-grab-ecore-wl.cpp create mode 100644 adaptors/ecore/wayland/keyrouter-client-protocol.h create mode 100644 adaptors/ecore/wayland/tizen-extension-client-protocol.h create mode 100644 adaptors/ecore/wayland/tizen-policy-client-protocol.h create mode 100644 adaptors/tizen/key-grab.h create mode 100644 adaptors/x11/key-grab-x.cpp diff --git a/adaptors/ecore/wayland/ecore_wl_private.h b/adaptors/ecore/wayland/ecore_wl_private.h new file mode 100644 index 0000000..f74aade --- /dev/null +++ b/adaptors/ecore/wayland/ecore_wl_private.h @@ -0,0 +1,323 @@ +#ifndef _ECORE_WAYLAND_PRIVATE_H +# define _ECORE_WAYLAND_PRIVATE_H + +# include +# include + +# include "Ecore.h" +# include "Ecore_Input.h" +# include "Ecore_Wayland.h" +# ifdef USE_IVI_SHELL +# include "ivi-application-client-protocol.h" +# define IVI_SURFACE_ID 6000 +# endif + +# include "tizen-policy-client-protocol.h" +# include "tizen-extension-client-protocol.h" + +# include "keyrouter-client-protocol.h" + +//# define LOGFNS 1 + +# ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) printf("-ECORE-WL: %25s: %5i - %s\n", fl, ln, fn); +# else +# define LOGFN(fl, ln, fn) +# endif + +extern int _ecore_wl_log_dom; + +# ifdef ECORE_WL_DEFAULT_LOG_COLOR +# undef ECORE_WL_DEFAULT_LOG_COLOR +# endif +# define ECORE_WL_DEFAULT_LOG_COLOR EINA_COLOR_BLUE + +# ifdef ERR +# undef ERR +# endif +# define ERR(...) EINA_LOG_DOM_ERR(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef DBG +# undef DBG +# endif +# define DBG(...) EINA_LOG_DOM_DBG(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef INF +# undef INF +# endif +# define INF(...) EINA_LOG_DOM_INFO(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef WRN +# undef WRN +# endif +# define WRN(...) EINA_LOG_DOM_WARN(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef CRI +# undef CRI +# endif +# define CRI(...) EINA_LOG_DOM_CRIT(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef ECORE_WL_DEFAULT_CURSOR_SIZE +# undef ECORE_WL_DEFAULT_CURSOR_SIZE +# endif +# define ECORE_WL_DEFAULT_CURSOR_SIZE 32 + +typedef struct _Ecore_Wl_Display Ecore_Wl_Display; + +struct _Ecore_Wl_Display +{ + struct + { + struct wl_display *display; + struct wl_registry *registry; + struct wl_compositor *compositor; + struct wl_subcompositor *subcompositor; + struct wl_shell *shell; + struct xdg_shell *xdg_shell; + struct wl_shell *desktop_shell; +# ifdef USE_IVI_SHELL + struct ivi_application *ivi_application; +# endif + struct wl_shm *shm; + struct wl_data_device_manager *data_device_manager; + struct tizen_policy *tz_policy; + struct tizen_surface_extension *tz_surf_ext; + struct wl_keyrouter *keyrouter; + } wl; + + int fd; + unsigned int mask; + unsigned int serial; + int sync_ref_count; + Ecore_Fd_Handler *fd_hdl; + Ecore_Idle_Enterer *idle_enterer; + + Eina_Inlist *inputs; + Eina_Inlist *outputs; + Eina_Inlist *globals; /** @since 1.7.6 */ + + Eina_Bool init_done; + + struct + { + struct xkb_context *context; + } xkb; + + struct wl_cursor_theme *cursor_theme; + + Ecore_Wl_Output *output; + Ecore_Wl_Input *input; + + void (*output_configure)(Ecore_Wl_Output *output, void *data); + void *data; +}; + +struct _Ecore_Wl_Window +{ + Ecore_Wl_Display *display; + Ecore_Wl_Window *parent; + + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; +# ifdef USE_IVI_SHELL + struct ivi_surface *ivi_surface; + int ivi_surface_id; +# endif + struct tizen_visibility *tz_visibility; + struct tizen_resource *tz_resource; + unsigned int resource_id; + + struct wl_region *opaque_region; + struct wl_region *input_region; + + struct xdg_surface *xdg_surface; + struct xdg_popup *xdg_popup; + Eina_Bool visible : 1; + Eina_Bool focused : 1; + Eina_Bool resizing : 1; + + Eina_Bool fullscreen : 1; + Eina_Bool maximized : 1; + Eina_Bool minimized : 1; + + struct + { + struct wl_surface *surface; + int hot_x, hot_y; + Eina_Bool set : 1; + } pointer; + + int id, surface_id; + int rotation; + + const char *title; + const char *class_name; + + Eina_Rectangle allocation; + + struct + { + int w, h; + } saved; + + struct + { + int x, y, w, h; + } opaque, input; + + /* Eina_Bool redraw_scheduled : 1; */ + /* Eina_Bool resize_scheduled : 1; */ + Eina_Bool alpha : 1; + Eina_Bool transparent : 1; + Eina_Bool has_buffer : 1; + + Ecore_Wl_Window_Type type; + Ecore_Wl_Window_Buffer_Type buffer_type; + + Ecore_Wl_Input *pointer_device; + Ecore_Wl_Input *keyboard_device; + + Eina_Bool anim_pending : 1; + struct wl_callback *anim_callback; + + const char *cursor_name; + + Ecore_Wl_Subsurf *subsurfs; + + void *data; +}; + +struct _Ecore_Wl_Input +{ + EINA_INLIST; + Ecore_Wl_Display *display; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_keyboard *keyboard; + + struct wl_touch *touch; + + const char *cursor_name; + struct wl_cursor *cursor; + struct wl_surface *cursor_surface; + struct wl_callback *cursor_frame_cb; + Ecore_Timer *cursor_timer; + unsigned int cursor_current_index; + unsigned int cursor_size; + const char *cursor_theme_name; + + struct wl_data_device *data_device; + struct wl_data_source *data_source; + struct wl_array data_types; + + Ecore_Wl_Window *pointer_focus; + Ecore_Wl_Window *keyboard_focus; + Ecore_Wl_Window *touch_focus; + + unsigned int button; + unsigned int timestamp; + unsigned int modifiers; + unsigned int pointer_enter_serial; + int sx, sy; + + Ecore_Wl_Window *grab; + unsigned int grab_button; + unsigned int grab_timestamp; + unsigned int grab_count; + + Ecore_Wl_Dnd_Source *drag_source; + Ecore_Wl_Dnd_Source *selection_source; + + struct + { + struct xkb_keymap *keymap; + struct xkb_state *state; + xkb_mod_mask_t control_mask; + xkb_mod_mask_t alt_mask; + xkb_mod_mask_t shift_mask; + xkb_mod_mask_t win_mask; + xkb_mod_mask_t scroll_mask; + xkb_mod_mask_t num_mask; + xkb_mod_mask_t caps_mask; + xkb_mod_mask_t altgr_mask; + unsigned int mods_depressed; + unsigned int mods_latched; + unsigned int mods_locked; + unsigned int mods_group; + } xkb; + + struct + { + Ecore_Timer *tmr; + unsigned int sym, key, time; + } repeat; +}; + +struct _Ecore_Wl_Output +{ + EINA_INLIST; + Ecore_Wl_Display *display; + struct wl_output *output; + Eina_Rectangle allocation; + int mw, mh; + int transform; + + void (*destroy) (Ecore_Wl_Output *output, void *data); + void *data; +}; + +struct _Ecore_Wl_Dnd +{ + Ecore_Wl_Display *ewd; + Ecore_Wl_Input *input; +}; + +struct _Ecore_Wl_Dnd_Source +{ + Ecore_Wl_Input *input; + + struct wl_data_offer *data_offer; + struct wl_array types; + + int refcount; + int fd; + int x, y; +}; + +struct _Ecore_Wl_Dnd_Target +{ + Ecore_Wl_Dnd_Source *source; +}; + +extern Ecore_Wl_Display *_ecore_wl_disp; + +void _ecore_wl_window_init(void); +void _ecore_wl_window_shutdown(void); +Eina_Hash *_ecore_wl_window_hash_get(void); + +void _ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id); +void _ecore_wl_output_del(Ecore_Wl_Output *output); + +void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id); +void _ecore_wl_input_del(Ecore_Wl_Input *input); +void _ecore_wl_input_pointer_xy_get(int *x, int *y); +void _ecore_wl_input_grab_release(Ecore_Wl_Input *input, Ecore_Wl_Window *win); + +void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, struct wl_data_offer *offer); +void _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer); +void _ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device); +void _ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y); +void _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device); +void _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); +void _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source); + +void _ecore_wl_events_init(void); +void _ecore_wl_events_shutdown(void); + +void _ecore_wl_subsurfs_del_all(Ecore_Wl_Window *win); + +struct wl_compositor *_ecore_wl_compositor_get(void); +struct wl_subcompositor *_ecore_wl_subcompositor_get(void); + +#endif diff --git a/adaptors/ecore/wayland/file.list b/adaptors/ecore/wayland/file.list index 15ca55b..ac83e4d 100644 --- a/adaptors/ecore/wayland/file.list +++ b/adaptors/ecore/wayland/file.list @@ -12,7 +12,9 @@ adaptor_ecore_wayland_tizen_internal_src_files = \ $(adaptor_ecore_wayland_dir)/render-surface-ecore-wl.cpp \ $(adaptor_ecore_wayland_dir)/virtual-keyboard-impl-ecore-wl.cpp \ $(adaptor_ecore_wayland_dir)/window-impl-ecore-wl.cpp \ - $(adaptor_ecore_wayland_dir)/window-render-surface-ecore-wl.cpp + $(adaptor_ecore_wayland_dir)/window-render-surface-ecore-wl.cpp \ + $(adaptor_ecore_wayland_dir)/key-grab-ecore-wl.cpp + adaptor_ecore_wayland_tizen_common_internal_default_profile_src_files = \ $(adaptor_ecore_wayland_dir)/render-surface-factory-ecore-wl.cpp \ diff --git a/adaptors/ecore/wayland/key-grab-ecore-wl.cpp b/adaptors/ecore/wayland/key-grab-ecore-wl.cpp new file mode 100644 index 0000000..89deb11 --- /dev/null +++ b/adaptors/ecore/wayland/key-grab-ecore-wl.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +// keycode-related code +#include "ecore_wl_private.h" + +using namespace std; + +// keycode-related code +namespace +{ + +const int KEYCODE_BUFFER_SIZE = 5; + +typedef struct _keycode_map{ + xkb_keysym_t keysym; + xkb_keycode_t *keycodes; + int nkeycodes; +}keycode_map; + +static void find_keycode( struct xkb_keymap *keymap, xkb_keycode_t key, void *data ) +{ + keycode_map *found_keycodes = (keycode_map *)data; + xkb_keysym_t keysym = found_keycodes->keysym; + int nsyms = 0; + const xkb_keysym_t *syms_out = NULL; + + nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out); + if( nsyms && syms_out ) + { + if( *syms_out == keysym ) + { + found_keycodes->nkeycodes++; + found_keycodes->keycodes = static_cast(realloc( found_keycodes->keycodes, sizeof(int)*found_keycodes->nkeycodes )); + found_keycodes->keycodes[found_keycodes->nkeycodes-1] = key; + } + } +} + +int xkb_keycode_from_keysym( struct xkb_keymap *keymap, xkb_keysym_t keysym, xkb_keycode_t **keycodes ) +{ + keycode_map found_keycodes = {0,}; + found_keycodes.keysym = keysym; + xkb_keymap_key_for_each( keymap, find_keycode, &found_keycodes ); + + *keycodes = found_keycodes.keycodes; + return found_keycodes.nkeycodes; +} + +bool keycode_from_keyname( const char* keyname, char* keycode_buffer ) +{ + xkb_keysym_t keysym = xkb_keysym_from_name( keyname, XKB_KEYSYM_NO_FLAGS ); + + int nkeycodes = 0; // num of keycodes mapping with keysym + xkb_keycode_t *keycodes = NULL; // keycodes list + nkeycodes = xkb_keycode_from_keysym( ecore_wl_input_get()->xkb.keymap, keysym, &keycodes ); + if( nkeycodes > 0) + { + snprintf( keycode_buffer, KEYCODE_BUFFER_SIZE, "%d", keycodes[0] ); + return true; + } + else + { + return false; + } + free(keycodes); +} + +} // unnamed namespace + +namespace Dali +{ + +namespace KeyGrab +{ + +bool GrabKeyTopmost( Window window, Dali::KEY daliKey ) +{ + return GrabKey( window, daliKey, TOPMOST); +} + +bool UngrabKeyTopmost( Window window, Dali::KEY daliKey ) +{ + return UngrabKey( window, daliKey ); +} + +bool GrabKey( Window window, Dali::KEY daliKey, KeyGrabMode grabMode ) +{ + Ecore_Wl_Window_Keygrab_Mode wlGrabMode; + if( grabMode == TOPMOST ) + { + wlGrabMode = ECORE_WL_WINDOW_KEYGRAB_TOPMOST; + } + else if( grabMode == SHARED ) + { + wlGrabMode = ECORE_WL_WINDOW_KEYGRAB_SHARED; + } + else if( grabMode == OVERRIDE_EXCLUSIVE ) + { + wlGrabMode = ECORE_WL_WINDOW_KEYGRAB_EXCLUSIVE; + } + else if( grabMode == EXCLUSIVE ) + { + wlGrabMode = ECORE_WL_WINDOW_KEYGRAB_OVERRIDE_EXCLUSIVE; + } + else + { + return false; + } + + // keycode-related code + char keycode[KEYCODE_BUFFER_SIZE]; + if( !keycode_from_keyname( Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ), keycode ) ) + { + DALI_LOG_WARNING( "Unable to get keycode from keyname %s.\n", Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ) ); + return false; + } + return ecore_wl_window_keygrab_set( AnyCast( window.GetNativeHandle() ), + keycode, + 0, 0, 0, wlGrabMode ); + + // Currently the 2nd parameter of ecore_wl_window_keygrab_set means keycode, but its meaning will be changed to keyname later. + // Once changed, we can remove all "keycode-related code" and just uncomment below line and + // also can remove following files: + // ecore_wl_private.h, tizen-extension-client-protocol.h, tizen-policy-client-protocol.h + + //return ecore_wl_window_keygrab_set( AnyCast( window.GetNativeHandle() ), + //Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ), + //0, 0, 0, wlGrabMode ); +} + +bool UngrabKey( Window window, Dali::KEY daliKey ) +{ + // keycode-related code + char keycode[KEYCODE_BUFFER_SIZE]; + if( !keycode_from_keyname( Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ), keycode ) ) + { + DALI_LOG_WARNING( "Unable to get keycode from keyname %s.\n", Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ) ); + return false; + } + return ecore_wl_window_keygrab_unset( AnyCast( window.GetNativeHandle() ), + keycode, + 0, 0 ); + + // Currently the 2nd parameter of ecore_wl_window_keygrab_set means keycode, but its meaning will be changed to keyname later. + // Once changed, we can remove all "keycode-related code" and just uncomment below line and + // also can remove following files: + // ecore_wl_private.h, tizen-extension-client-protocol.h, tizen-policy-client-protocol.h + + //return ecore_wl_window_keygrab_unset( AnyCast( window.GetNativeHandle() ), + //Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ), + //0, 0 ); +} + +} // namespace KeyGrab + +} // namespace Dali + + diff --git a/adaptors/ecore/wayland/keyrouter-client-protocol.h b/adaptors/ecore/wayland/keyrouter-client-protocol.h new file mode 100644 index 0000000..7181278 --- /dev/null +++ b/adaptors/ecore/wayland/keyrouter-client-protocol.h @@ -0,0 +1,167 @@ +/* + * Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + * Contact: Sung-Jin Park (sj76.park@samsung.com), + * Jeonghyun Kang (jhyuni.kang@samsung.com) + * + * Permission to use, copy, modify, distribute, and sell this + * software and its documentation for any purpose is hereby granted + * without fee, provided that the above copyright notice appear in + * all copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * the copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ + +#ifndef KEYROUTER_CLIENT_PROTOCOL_H +#define KEYROUTER_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct wl_keyrouter; + +extern const struct wl_interface wl_keyrouter_interface; + +#ifndef WL_KEYROUTER_ERROR_ENUM +#define WL_KEYROUTER_ERROR_ENUM +enum wl_keyrouter_error { + WL_KEYROUTER_ERROR_NONE = 0, + WL_KEYROUTER_ERROR_INVALID_SURFACE = 1, + WL_KEYROUTER_ERROR_INVALID_KEY = 2, + WL_KEYROUTER_ERROR_INVALID_MODE = 3, + WL_KEYROUTER_ERROR_GRABBED_ALREADY = 4, + WL_KEYROUTER_ERROR_NO_PERMISSION = 5, + WL_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES = 6, +}; +#endif /* WL_KEYROUTER_ERROR_ENUM */ + +#ifndef WL_KEYROUTER_MODE_ENUM +#define WL_KEYROUTER_MODE_ENUM +/** + * wl_keyrouter_mode - mode for a key grab + * @WL_KEYROUTER_MODE_NONE: none + * @WL_KEYROUTER_MODE_SHARED: mode to get a key grab with the other + * client surfaces when the focused client surface gets the key + * @WL_KEYROUTER_MODE_TOPMOST: mode to get a key grab when the client + * surface is the top most surface + * @WL_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: mode to get a key grab + * exclusively, overridably regardless of the order in the surface stack + * @WL_KEYROUTER_MODE_EXCLUSIVE: mode to get a key grab exclusively + * regardless of the order in surface stack + * + * This value is used to set a mode for a key grab. With this mode and + * the order of the surface between surfaces' stack, the compositor will + * determine the destination client surface. + */ +enum wl_keyrouter_mode { + WL_KEYROUTER_MODE_NONE = 0, + WL_KEYROUTER_MODE_SHARED = 1, + WL_KEYROUTER_MODE_TOPMOST = 2, + WL_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE = 3, + WL_KEYROUTER_MODE_EXCLUSIVE = 4, +}; +#endif /* WL_KEYROUTER_MODE_ENUM */ + +/** + * wl_keyrouter - an interface to set each focus for each key + * @keygrab_notify: (none) + * + * In tradition, all the keys in a keyboard and a device on which some + * keys are attached will be sent to focus surface by default. Currently + * it's possible to set up each focus for each key in a keyboard and a + * device. Therefore, by setting a key grab for a surface, the owner of the + * surface will get the key event when it has the key grab for the key. + */ +struct wl_keyrouter_listener { + /** + * keygrab_notify - (none) + * @surface: (none) + * @key: (none) + * @mode: (none) + * @error: (none) + */ + void (*keygrab_notify)(void *data, + struct wl_keyrouter *wl_keyrouter, + struct wl_surface *surface, + uint32_t key, + uint32_t mode, + uint32_t error); +}; + +static inline int +wl_keyrouter_add_listener(struct wl_keyrouter *wl_keyrouter, + const struct wl_keyrouter_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_keyrouter, + (void (**)(void)) listener, data); +} + +#define WL_KEYROUTER_SET_KEYGRAB 0 +#define WL_KEYROUTER_UNSET_KEYGRAB 1 +#define WL_KEYROUTER_GET_KEYGRAB_STATUS 2 + +static inline void +wl_keyrouter_set_user_data(struct wl_keyrouter *wl_keyrouter, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_keyrouter, user_data); +} + +static inline void * +wl_keyrouter_get_user_data(struct wl_keyrouter *wl_keyrouter) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_keyrouter); +} + +static inline void +wl_keyrouter_destroy(struct wl_keyrouter *wl_keyrouter) +{ + wl_proxy_destroy((struct wl_proxy *) wl_keyrouter); +} + +static inline void +wl_keyrouter_set_keygrab(struct wl_keyrouter *wl_keyrouter, struct wl_surface *surface, uint32_t key, uint32_t mode) +{ + wl_proxy_marshal((struct wl_proxy *) wl_keyrouter, + WL_KEYROUTER_SET_KEYGRAB, surface, key, mode); +} + +static inline void +wl_keyrouter_unset_keygrab(struct wl_keyrouter *wl_keyrouter, struct wl_surface *surface, uint32_t key) +{ + wl_proxy_marshal((struct wl_proxy *) wl_keyrouter, + WL_KEYROUTER_UNSET_KEYGRAB, surface, key); +} + +static inline void +wl_keyrouter_get_keygrab_status(struct wl_keyrouter *wl_keyrouter, struct wl_surface *surface, uint32_t key) +{ + wl_proxy_marshal((struct wl_proxy *) wl_keyrouter, + WL_KEYROUTER_GET_KEYGRAB_STATUS, surface, key); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/adaptors/ecore/wayland/tizen-extension-client-protocol.h b/adaptors/ecore/wayland/tizen-extension-client-protocol.h new file mode 100644 index 0000000..d84dc40 --- /dev/null +++ b/adaptors/ecore/wayland/tizen-extension-client-protocol.h @@ -0,0 +1,99 @@ +#ifndef TIZEN_EXTENSION_CLIENT_PROTOCOL_H +#define TIZEN_EXTENSION_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct tizen_resource; +struct tizen_surface_extension; +struct wl_surface; + +extern const struct wl_interface tizen_resource_interface; +extern const struct wl_interface tizen_surface_extension_interface; +extern const struct wl_interface wl_surface_interface; + +struct tizen_resource_listener { + /** + * resource_id - (none) + * @id: (none) + */ + void (*resource_id)(void *data, + struct tizen_resource *tizen_resource, + uint32_t id); +}; + +static inline int +tizen_resource_add_listener(struct tizen_resource *tizen_resource, + const struct tizen_resource_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) tizen_resource, + (void (**)(void)) listener, data); +} + +#define TIZEN_RESOURCE_DESTROY 0 + +static inline void +tizen_resource_set_user_data(struct tizen_resource *tizen_resource, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) tizen_resource, user_data); +} + +static inline void * +tizen_resource_get_user_data(struct tizen_resource *tizen_resource) +{ + return wl_proxy_get_user_data((struct wl_proxy *) tizen_resource); +} + +static inline void +tizen_resource_destroy(struct tizen_resource *tizen_resource) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_resource, + TIZEN_RESOURCE_DESTROY); + + wl_proxy_destroy((struct wl_proxy *) tizen_resource); +} + +#define TIZEN_SURFACE_EXTENSION_GET_TIZEN_RESOURCE 0 + +static inline void +tizen_surface_extension_set_user_data(struct tizen_surface_extension *tizen_surface_extension, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_extension, user_data); +} + +static inline void * +tizen_surface_extension_get_user_data(struct tizen_surface_extension *tizen_surface_extension) +{ + return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_extension); +} + +static inline void +tizen_surface_extension_destroy(struct tizen_surface_extension *tizen_surface_extension) +{ + wl_proxy_destroy((struct wl_proxy *) tizen_surface_extension); +} + +static inline struct tizen_resource * +tizen_surface_extension_get_tizen_resource(struct tizen_surface_extension *tizen_surface_extension, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor((struct wl_proxy *) tizen_surface_extension, + TIZEN_SURFACE_EXTENSION_GET_TIZEN_RESOURCE, &tizen_resource_interface, NULL, surface); + + return (struct tizen_resource *) id; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/adaptors/ecore/wayland/tizen-policy-client-protocol.h b/adaptors/ecore/wayland/tizen-policy-client-protocol.h new file mode 100644 index 0000000..8a4113b --- /dev/null +++ b/adaptors/ecore/wayland/tizen-policy-client-protocol.h @@ -0,0 +1,140 @@ +#ifndef TIZEN_POLICY_CLIENT_PROTOCOL_H +#define TIZEN_POLICY_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct tizen_policy; +struct tizen_visibility; +struct wl_surface; + +extern const struct wl_interface tizen_policy_interface; +extern const struct wl_interface tizen_visibility_interface; +extern const struct wl_interface wl_surface_interface; + +#define TIZEN_POLICY_GET_VISIBILITY 0 +#define TIZEN_POLICY_ACTIVATE 1 +#define TIZEN_POLICY_POSITION_SET 2 +#define TIZEN_POLICY_FOCUS_SKIP_SET 3 +#define TIZEN_POLICY_FOCUS_SKIP_UNSET 4 + +static inline void +tizen_policy_set_user_data(struct tizen_policy *tizen_policy, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) tizen_policy, user_data); +} + +static inline void * +tizen_policy_get_user_data(struct tizen_policy *tizen_policy) +{ + return wl_proxy_get_user_data((struct wl_proxy *) tizen_policy); +} + +static inline void +tizen_policy_destroy(struct tizen_policy *tizen_policy) +{ + wl_proxy_destroy((struct wl_proxy *) tizen_policy); +} + +static inline struct tizen_visibility * +tizen_policy_get_visibility(struct tizen_policy *tizen_policy, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor((struct wl_proxy *) tizen_policy, + TIZEN_POLICY_GET_VISIBILITY, &tizen_visibility_interface, NULL, surface); + + return (struct tizen_visibility *) id; +} + +static inline void +tizen_policy_activate(struct tizen_policy *tizen_policy, struct wl_surface *surface) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_policy, + TIZEN_POLICY_ACTIVATE, surface); +} + +static inline void +tizen_policy_position_set(struct tizen_policy *tizen_policy, struct wl_surface *surface, int32_t x, int32_t y) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_policy, + TIZEN_POLICY_POSITION_SET, surface, x, y); +} + +static inline void +tizen_policy_focus_skip_set(struct tizen_policy *tizen_policy, struct wl_surface *surface) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_policy, + TIZEN_POLICY_FOCUS_SKIP_SET, surface); +} + +static inline void +tizen_policy_focus_skip_unset(struct tizen_policy *tizen_policy, struct wl_surface *surface) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_policy, + TIZEN_POLICY_FOCUS_SKIP_UNSET, surface); +} + +#ifndef TIZEN_VISIBILITY_VISIBILITY_ENUM +#define TIZEN_VISIBILITY_VISIBILITY_ENUM +enum tizen_visibility_visibility { + TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED = 0, + TIZEN_VISIBILITY_VISIBILITY_PARTIALLY_OBSCURED = 1, + TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED = 2, +}; +#endif /* TIZEN_VISIBILITY_VISIBILITY_ENUM */ + +struct tizen_visibility_listener { + /** + * notify - (none) + * @visibility: (none) + */ + void (*notify)(void *data, + struct tizen_visibility *tizen_visibility, + uint32_t visibility); +}; + +static inline int +tizen_visibility_add_listener(struct tizen_visibility *tizen_visibility, + const struct tizen_visibility_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) tizen_visibility, + (void (**)(void)) listener, data); +} + +#define TIZEN_VISIBILITY_DESTROY 0 + +static inline void +tizen_visibility_set_user_data(struct tizen_visibility *tizen_visibility, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) tizen_visibility, user_data); +} + +static inline void * +tizen_visibility_get_user_data(struct tizen_visibility *tizen_visibility) +{ + return wl_proxy_get_user_data((struct wl_proxy *) tizen_visibility); +} + +static inline void +tizen_visibility_destroy(struct tizen_visibility *tizen_visibility) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_visibility, + TIZEN_VISIBILITY_DESTROY); + + wl_proxy_destroy((struct wl_proxy *) tizen_visibility); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/adaptors/ecore/wayland/window-impl-ecore-wl.cpp b/adaptors/ecore/wayland/window-impl-ecore-wl.cpp index e2ad5d6..619d516 100644 --- a/adaptors/ecore/wayland/window-impl-ecore-wl.cpp +++ b/adaptors/ecore/wayland/window-impl-ecore-wl.cpp @@ -67,6 +67,13 @@ struct Window::EventHandler mClientMessageHandler( NULL ), mEcoreWindow( 0 ) { + ECore::WindowRenderSurface* wlWindow( dynamic_cast< ECore::WindowRenderSurface* >( mWindow->mSurface ) ); + if( wlWindow ) + { + mEcoreWindow = wlWindow->GetWlWindow(); + } + + DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore wl window." ); } /** diff --git a/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp b/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp index 40cd572..2a8eeae 100644 --- a/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp +++ b/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp @@ -23,7 +23,7 @@ #include // INTERNAL INCLUDES -#include +#include #include #include #include @@ -119,7 +119,7 @@ void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf ) } // create the EGL surface - ecore_wl_window_surface_create(mWlWindow); + mWlSurface = ecore_wl_window_surface_create(mWlWindow); mEglWindow = wl_egl_window_create(ecore_wl_window_surface_get(mWlWindow), mPosition.width, mPosition.height); eglImpl.CreateSurfaceWindow( (EGLNativeWindowType)mEglWindow, mColorDepth ); // reinterpret_cast does not compile } diff --git a/adaptors/ecore/wayland/window-render-surface.h b/adaptors/ecore/wayland/window-render-surface.h index 7aea88b..53a3b12 100644 --- a/adaptors/ecore/wayland/window-render-surface.h +++ b/adaptors/ecore/wayland/window-render-surface.h @@ -81,6 +81,8 @@ public: // API */ virtual Ecore_Wl_Window* GetWlWindow(); + struct wl_surface* GetWlSurface(){ return mWlSurface; } + public: // from Dali::RenderSurface /** @@ -159,6 +161,7 @@ private: // Data Ecore_Wl_Window* mWlWindow; ///< Wayland-Window wl_egl_window* mEglWindow; + struct wl_surface* mWlSurface; bool mNeedToApproveDeiconify; ///< Whether need to send ECORE_X_ATOM_E_DEICONIFY_APPROVE event }; // class WindowRenderSurface diff --git a/adaptors/tizen/file.list b/adaptors/tizen/file.list index 03b0758..ed2d658 100644 --- a/adaptors/tizen/file.list +++ b/adaptors/tizen/file.list @@ -10,5 +10,7 @@ adaptor_tizen_internal_src_files = \ adaptor_tizen_internal_non_mobile_src_files = \ $(adaptor_tizen_dir)/accessibility-adaptor-impl-tizen.cpp - adaptor_tizen_framework_efl_src_files = $(adaptor_tizen_dir)/framework-tizen.cpp + +public_api_adaptor_tizen_header_files = \ + $(adaptor_tizen_dir)/key-grab.h diff --git a/adaptors/tizen/key-grab.h b/adaptors/tizen/key-grab.h new file mode 100644 index 0000000..dbe516e --- /dev/null +++ b/adaptors/tizen/key-grab.h @@ -0,0 +1,100 @@ +#ifndef __DALI_KEY_GRAB_H__ +#define __DALI_KEY_GRAB_H__ + +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include "key.h" + +namespace Dali +{ +class Window; + +namespace KeyGrab +{ + +/** + * @brief Grabs the key specfied by @a key for @a window only when @a window is the topmost window. + * + * This function can be used for following example scenarios: + * Mobile - Using volume up/down as zoom up/down in camera apps. + * + * @privlevel public + * @note This function is only specified by Tizen. + * @param[in] window The window to set + * @param[in] dailKey The key code to grab (defined in key.h) + * @return true if the grab succeed. + */ +DALI_IMPORT_API bool GrabKeyTopmost( Window window, Dali::KEY daliKey ); + +/** + * @brief Ungrabs the key specfied by @a key for @a window. + * + * @privlevel public + * @note This function is only specified by Tizen. + * @param[in] window The window to set + * @param[in] dailKey The key code to ungrab (defined in key.h) + * @return true if the ungrab succeed. + */ +DALI_IMPORT_API bool UngrabKeyTopmost( Window window, Dali::KEY daliKey ); + +/** + * @brief Key grab mode for platform-level APIs. + */ +enum KeyGrabMode +{ + TOPMOST = 0, ///< Grab a key only when on the top of the grabbing-window stack mode. + SHARED, ///< Grab a key together with the other client window(s) mode. + OVERRIDE_EXCLUSIVE, ///< Grab a key exclusively regardless of the grabbing-window's position on the window stack with the possibility of overriding the grab by the other client window mode. + EXCLUSIVE ///< Grab a key exclusively regardless of the grabbing-window's position on the window stack mode. +}; + +/** + * @brief Grabs the key specfied by @a key for @a window in @a grabMode. + * + * This function can be used for following example scenarios: + * TV - A user might want to change the volume or channel of the background TV contents while focusing on the foregrund app. + * Mobile - When a user presses Home key, the homescreen appears regardless of current foreground app. + * Mobile - Using volume up/down as zoom up/down in camera apps. + * + * @privlevel platform + * @note This function is only specified by Tizen. + * @param[in] window The window to set + * @param[in] dailKey The key code to grab (defined in key.h) + * @param[in] grabMode The grab mode for the key + * @return true if the grab succeed. + */ +DALI_IMPORT_API bool GrabKey( Window window, Dali::KEY daliKey, KeyGrabMode grabMode ); + +/** + * @brief Ungrabs the key specfied by @a key for @a window. + * + * @privlevel platform + * @note This function is only specified by Tizen. + * @param[in] window The window to set + * @param[in] dailKey The key code to ungrab (defined in key.h) + * @return true if the ungrab succeed. + */ +DALI_IMPORT_API bool UngrabKey( Window window, Dali::KEY daliKey ); + +} // namespace KeyGrab + +} // namespace Dali + +#endif // __DALI_KEY_GRAB_H__ diff --git a/adaptors/x11/file.list b/adaptors/x11/file.list index 75bce2e..32e9d14 100644 --- a/adaptors/x11/file.list +++ b/adaptors/x11/file.list @@ -29,7 +29,8 @@ adaptor_x11_tizen_internal_src_files = \ $(_adaptor_x11_internal_src_files) \ $(adaptor_x11_dir)/framework-x.cpp \ $(adaptor_x11_dir)/key-mapping-x.cpp \ - $(adaptor_x11_dir)/window-extensions.cpp + $(adaptor_x11_dir)/window-extensions.cpp \ + $(adaptor_x11_dir)/key-grab-x.cpp adaptor_x11_tv_internal_src_files = \ $(_adaptor_x11_internal_src_files) \ diff --git a/adaptors/x11/key-grab-x.cpp b/adaptors/x11/key-grab-x.cpp new file mode 100644 index 0000000..be0cfd9 --- /dev/null +++ b/adaptors/x11/key-grab-x.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace KeyGrab +{ + +bool GrabKeyTopmost( Window window, Dali::KEY daliKey ) +{ + return GrabKey( window, daliKey, TOPMOST); +} + +bool UngrabKeyTopmost( Window window, Dali::KEY daliKey ) +{ + return UngrabKey( window, daliKey ); +} + +bool GrabKey( Window window, Dali::KEY daliKey, KeyGrabMode grabMode ) +{ + int xGrabMode; + if( grabMode == TOPMOST ) + { + xGrabMode = TOP_POSITION_GRAB; + } + else if( grabMode == SHARED ) + { + xGrabMode = SHARED_GRAB; + } + else if( grabMode == OVERRIDE_EXCLUSIVE ) + { + xGrabMode = OR_EXCLUSIVE_GRAB; + } + else if( grabMode == EXCLUSIVE ) + { + xGrabMode = EXCLUSIVE_GRAB; + } + else + { + return false; + } + + int ret = utilx_grab_key ( static_cast( ecore_x_display_get() ), + static_cast( AnyCast( window.GetNativeHandle() ) ), + Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ), xGrabMode ); + return ret==0; +} + +bool UngrabKey( Window window, Dali::KEY daliKey ) +{ + int ret = utilx_ungrab_key ( static_cast( ecore_x_display_get() ), + static_cast( AnyCast( window.GetNativeHandle() ) ), + Dali::Internal::Adaptor::KeyLookup::GetKeyName( daliKey ) ); + return ret==0; +} + +} // namespace KeyGrab + +} // namespace Dali + + diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index f66b3cb..358aeae 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -423,6 +423,15 @@ libdali_adaptor_la_CXXFLAGS += $(HAPTIC_CFLAGS) libdali_adaptor_la_LIBADD += endif +if !UBUNTU_PROFILE +if WAYLAND +else +# X11 +libdali_adaptor_la_CXXFLAGS += $(UTILX_CFLAGS) +libdali_adaptor_la_LIBADD += $(UTILX_LIBS) +endif +endif + if UBUNTU_PROFILE libdali_adaptor_la_LIBADD += -ljpeg CFLAGS += -fPIC @@ -463,6 +472,7 @@ tizentextabstractiondevelapidir = $(tizenadaptordevelapidir)/text-abstraction tizentextabstractiondevelapi_HEADERS = $(text_abstraction_header_files) if !UBUNTU_PROFILE +tizenadaptorframeworkpublicapi_HEADERS += $(public_api_adaptor_tizen_header_files) if !WAYLAND tizenadaptorframeworkdevelapi_HEADERS += $(devel_api_adaptor_tizen_x11_header_files) diff --git a/build/tizen/configure.ac b/build/tizen/configure.ac index c4b9daf..77dc857 100644 --- a/build/tizen/configure.ac +++ b/build/tizen/configure.ac @@ -278,6 +278,7 @@ PKG_CHECK_MODULES(ECORE_X, [ecore-x], PKG_CHECK_MODULES(X11, [x11], [DALI_USE_X11=1], [DALI_USE_X11=0]) +PKG_CHECK_MODULES(UTILX, utilX) fi fi # Using Wayland API directly ( main loop agnostic, typically for running on libuv) -- 2.7.4