diff --git a/configure.ac b/configure.ac index 0c9411d08..9050294d8 100644 --- a/configure.ac +++ b/configure.ac @@ -855,6 +855,17 @@ define([CHECK_MODULE_WL_TEXT_INPUT], ]) AM_CONDITIONAL([HAVE_WL_TEXT_INPUT], [test "x${WL_TEXT_INPUT}" = "xtrue"]) +WL_WEEKEYBOARD=false +define([CHECK_MODULE_WL_WEEKEYBOARD], +[ + if test "x${have_wayland}" = "xyes" ; then + AC_E_CHECK_PKG(WL_WEEKEYBOARD, [ eina >= 1.8.0 evas >= 1.8.0 ecore >= 1.8.0 ecore-evas >= 1.8.0 ecore-wayland >= 1.8.0 edje >= 1.8.0 ], [WL_WEEKEYBOARD=true], [WL_WEEKEYBOARD=false]) + else + WL_WEEKEYBOARD=false + fi +]) +AM_CONDITIONAL([HAVE_WL_WEEKEYBOARD], [test "x${WL_WEEKEYBOARD}" = "xtrue"]) + AC_E_OPTIONAL_MODULE([ibar], true) AC_E_OPTIONAL_MODULE([clock], true) AC_E_OPTIONAL_MODULE([pager], true) @@ -910,6 +921,7 @@ AC_E_OPTIONAL_MODULE([wl_wl], $have_wayland, [CHECK_MODULE_WL_WL]) #AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB]) AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM]) AC_E_OPTIONAL_MODULE([wl_text_input], $have_wayland, [CHECK_MODULE_WL_TEXT_INPUT]) +AC_E_OPTIONAL_MODULE([wl_weekeyboard], $have_wayland, [CHECK_MODULE_WL_WEEKEYBOARD]) AC_E_OPTIONAL_MODULE([policy_mobile], true) AC_E_OPTIONAL_MODULE([geolocation], true) AC_E_OPTIONAL_MODULE([xwayland], $have_wayland, [CHECK_MODULE_XWAYLAND]) diff --git a/src/modules/Makefile.mk b/src/modules/Makefile.mk index ed334b236..0ddee4937 100644 --- a/src/modules/Makefile.mk +++ b/src/modules/Makefile.mk @@ -123,6 +123,8 @@ include src/modules/Makefile_xwayland.mk include src/modules/Makefile_wl_text_input.mk +include src/modules/Makefile_wl_weekeyboard.mk + include src/modules/Makefile_policy_mobile.mk include src/modules/Makefile_geolocation.mk diff --git a/src/modules/Makefile_wl_weekeyboard.mk b/src/modules/Makefile_wl_weekeyboard.mk new file mode 100644 index 000000000..ca6adfc5e --- /dev/null +++ b/src/modules/Makefile_wl_weekeyboard.mk @@ -0,0 +1,84 @@ +DEFAULT_FILES = \ + src/modules/wl_weekeyboard/themes/default/default.edc \ + src/modules/wl_weekeyboard/themes/default/ignorekeys.txt \ + src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Regular.ttf \ + src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Semibold.ttf \ + src/modules/wl_weekeyboard/themes/default/images/key-hint-bg.png \ + src/modules/wl_weekeyboard/themes/default/images/icon-language.png \ + src/modules/wl_weekeyboard/themes/default/images/icon-backspace.png \ + src/modules/wl_weekeyboard/themes/default/images/key-special.png \ + src/modules/wl_weekeyboard/themes/default/images/icon-space.png \ + src/modules/wl_weekeyboard/themes/default/images/key-hint.png \ + src/modules/wl_weekeyboard/themes/default/images/icon-shift.png \ + src/modules/wl_weekeyboard/themes/default/images/icon-shift-active.png \ + src/modules/wl_weekeyboard/themes/default/images/icon-enter.png \ + src/modules/wl_weekeyboard/themes/default/images/key-special-pressed.png \ + src/modules/wl_weekeyboard/themes/default/images/key-default.png \ + src/modules/wl_weekeyboard/themes/default/images/key-default-pressed.png + +EXTRA_DIST += \ + $(DEFAULT_FILES) \ + src/modules/wl_weekeyboard/themes/default/default_600.edc \ + src/modules/wl_weekeyboard/themes/default/default_720.edj \ + src/modules/wl_weekeyboard/themes/default/default_1080.edj + +if USE_MODULE_WL_WEEKEYBOARD +wl_weekeyboarddir = $(MDIR)/wl_weekeyboard +wl_weekeyboard_DATA = \ + src/modules/wl_weekeyboard/themes/default/default_600.edj \ + src/modules/wl_weekeyboard/themes/default/default_720.edj \ + src/modules/wl_weekeyboard/themes/default/default_1080.edj + +CLEANFILES += \ + src/modules/wl_weekeyboard/themes/default/default_600.edj \ + src/modules/wl_weekeyboard/themes/default/default_720.edj \ + src/modules/wl_weekeyboard/themes/default/default_1080.edj + +src/modules/wl_weekeyboard/themes/default/default_600.edj: src/modules/wl_weekeyboard/themes/default/default_600.edc $(DEFAULT_FILES) Makefile + $(EDJE_CC) $(EDJE_FLAGS) \ + -dd $(top_srcdir)/src/modules/wl_weekeyboard/themes/default \ + -id $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/images \ + -fd $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/fonts \ + $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/default_600.edc \ + $(top_builddir)/src/modules/wl_weekeyboard/themes/default/default_600.edj + +src/modules/wl_weekeyboard/themes/default/default_720.edj: src/modules/wl_weekeyboard/themes/default/default_720.edc $(DEFAULT_FILES) Makefile + $(EDJE_CC) $(EDJE_FLAGS) \ + -dd $(top_srcdir)/src/modules/wl_weekeyboard/themes/default \ + -id $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/images \ + -fd $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/fonts \ + $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/default_720.edc \ + $(top_builddir)/src/modules/wl_weekeyboard/themes/default/default_720.edj + +src/modules/wl_weekeyboard/themes/default/default_1080.edj: src/modules/wl_weekeyboard/themes/default/default_1080.edc $(DEFAULT_FILES) Makefile + $(EDJE_CC) $(EDJE_FLAGS) \ + -dd $(top_srcdir)/src/modules/wl_weekeyboard/themes/default \ + -id $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/images \ + -fd $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/fonts \ + $(top_srcdir)/src/modules/wl_weekeyboard/themes/default/default_1080.edc \ + $(top_builddir)/src/modules/wl_weekeyboard/themes/default/default_1080.edj + +wl_weekeyboardpkgdir = $(MDIR)/wl_weekeyboard/$(MODULE_ARCH) +wl_weekeyboardpkg_LTLIBRARIES = src/modules/wl_weekeyboard/module.la + +src_modules_wl_weekeyboard_module_la_DEPENDENCIES = $(MDEPENDENCIES) +src_modules_wl_weekeyboard_module_la_CPPFLAGS = \ + $(MOD_CPPFLAGS) \ + @WL_WEEKEYBOARD_CFLAGS@ \ + @WAYLAND_CFLAGS@ \ + -DPKGDATADIR='"$pkgdatadir)"' +src_modules_wl_weekeyboard_module_la_LIBADD = $(LIBS) @WL_WEEKEYBOARD_LIBS@ @WAYLAND_LIBS@ +src_modules_wl_weekeyboard_module_la_LDFLAGS = $(MOD_LDFLAGS) +src_modules_wl_weekeyboard_module_la_SOURCES = \ + src/modules/wl_weekeyboard/e_mod_main.c \ + src/modules/wl_weekeyboard/wkb-log.h \ + src/modules/wl_weekeyboard/wkb-log.c \ + src/modules/wl_weekeyboard/input-method-protocol.c \ + src/modules/wl_weekeyboard/input-method-client-protocol.h \ + src/modules/wl_weekeyboard/text-protocol.c \ + src/modules/wl_weekeyboard/text-client-protocol.h + +PHONIES += wl_weekeyboard install-wl_weekeyboard +wl_weekeyboard: $(wl_weekeyboardpkg_LTLIBRARIES) $(wl_weekeyboard_DATA) +install-wl_weekeyboard: install-wl_weekeyboardpkgLTLIBRARIES +endif diff --git a/src/modules/wl_weekeyboard/e_mod_main.c b/src/modules/wl_weekeyboard/e_mod_main.c new file mode 100644 index 000000000..bb5cbe714 --- /dev/null +++ b/src/modules/wl_weekeyboard/e_mod_main.c @@ -0,0 +1,651 @@ +#include "e.h" + +#include "wkb-log.h" + +#include "input-method-client-protocol.h" +#include "text-client-protocol.h" + +struct weekeyboard +{ + E_Module *module; + Ecore_Evas *ee; + Ecore_Wl_Window *win; + Evas_Object *edje_obj; + const char *ee_engine; + char **ignore_keys; + + struct wl_surface *surface; + struct wl_input_panel *ip; + struct wl_input_method *im; + struct wl_output *output; + struct wl_input_method_context *im_ctx; + + char *surrounding_text; + char *preedit_str; + char *language; + char *theme; + + uint32_t text_direction; + uint32_t preedit_style; + uint32_t content_hint; + uint32_t content_purpose; + uint32_t serial; + uint32_t surrounding_cursor; + + Eina_Bool context_changed; +}; + +static char * +_wkb_insert_text(const char *text, uint32_t offset, const char *insert) +{ + char *new_text = malloc(strlen(text) + strlen(insert) + 1); + uint32_t text_len = 0; + + if ((!text) || (!insert)) + return NULL; + + text_len = strlen(text); + if (offset > text_len) + offset = text_len; + + new_text = malloc(text_len + strlen(insert) + 1); + if (!new_text) + { + ERR("out of memory"); + return NULL; + } + + strncpy(new_text, text, offset); + new_text[offset] = '\0'; + strcat(new_text, insert); + strcat(new_text, text + offset); + + return new_text; +} + +static void +_wkb_commit_preedit_str(struct weekeyboard *wkb) +{ + char *surrounding_text; + + if ((!wkb->preedit_str) || (strlen(wkb->preedit_str) == 0)) + return; + + wl_input_method_context_cursor_position(wkb->im_ctx, 0, 0); + wl_input_method_context_commit_string(wkb->im_ctx, wkb->serial, wkb->preedit_str); + + if (wkb->surrounding_text) + { + surrounding_text = _wkb_insert_text(wkb->surrounding_text, wkb->surrounding_cursor, wkb->preedit_str); + free(wkb->surrounding_text); + wkb->surrounding_text = surrounding_text; + wkb->surrounding_cursor += strlen(wkb->preedit_str); + } + else + { + wkb->surrounding_text = strdup(wkb->preedit_str); + wkb->surrounding_cursor = strlen(wkb->preedit_str); + } + + free(wkb->preedit_str); + wkb->preedit_str = strdup(""); +} + +static void +_wkb_send_preedit_str(struct weekeyboard *wkb, int cursor) +{ + unsigned int index = strlen(wkb->preedit_str); + + if (wkb->preedit_style) + wl_input_method_context_preedit_styling(wkb->im_ctx, 0, strlen(wkb->preedit_str), wkb->preedit_style); + + if (cursor > 0) + index = cursor; + + wl_input_method_context_preedit_cursor(wkb->im_ctx, index); + wl_input_method_context_preedit_string(wkb->im_ctx, wkb->serial, wkb->preedit_str, wkb->preedit_str); +} + +static void +_wkb_update_preedit_str(struct weekeyboard *wkb, const char *key) +{ + char *tmp; + + if (!wkb->preedit_str) + wkb->preedit_str = strdup(""); + + tmp = _wkb_insert_text(wkb->preedit_str, strlen(wkb->preedit_str), key); + free(wkb->preedit_str); + wkb->preedit_str = tmp; + + if (eina_streq(key, " ")) + _wkb_commit_preedit_str(wkb); + else + _wkb_send_preedit_str(wkb, -1); +} + +static Eina_Bool +_wkb_ignore_key(struct weekeyboard *wkb, const char *key) +{ + int i; + + if (!wkb->ignore_keys) + return EINA_FALSE; + + for (i = 0; wkb->ignore_keys[i] != NULL; i++) + if (eina_streq(key, wkb->ignore_keys[i])) + return EINA_TRUE; + + return EINA_FALSE; +} + +static void +_cb_wkb_on_key_down(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source) +{ + struct weekeyboard *wkb = data; + char *src; + const char *key; + + EINA_SAFETY_ON_FALSE_RETURN(wkb); + EINA_SAFETY_ON_FALSE_RETURN(source); + + src = strdup(source); + if (!src) + { + ERR("out of memory"); + return; + } + + key = strtok(src, ":"); + key = strtok(NULL, ":"); + if (key == NULL) + key = ":"; + + if (_wkb_ignore_key(wkb, key)) + { + DBG("Ignoring key: '%s'", key); + goto end; + } + else if (eina_streq(key, "backspace")) + { + if (strlen(wkb->preedit_str) == 0) + { + wl_input_method_context_delete_surrounding_text(wkb->im_ctx, -1, 1); + wl_input_method_context_commit_string(wkb->im_ctx, wkb->serial, ""); + } + else + { + wkb->preedit_str[strlen(wkb->preedit_str) -1] = '\0'; + _wkb_send_preedit_str(wkb, -1); + } + + goto end; + } + else if (eina_streq(key, "enter")) + { + _wkb_commit_preedit_str(wkb); + wl_input_method_context_keysym(wkb->im_ctx, wkb->serial, 0, + XKB_KEY_Return, WL_KEYBOARD_KEY_STATE_PRESSED, 0); + goto end; + } + else if (eina_streq(key, "space")) + { + key = " "; + } + + DBG("Key pressed: '%s'", key); + + _wkb_update_preedit_str(wkb, key); + +end: + free(src); +} + +static Eina_Bool +_wkb_ui_setup(struct weekeyboard *wkb) +{ + char path[PATH_MAX]; + int w = 1080, h; + char *ignore_keys; + const char *theme; + + /* First run */ + if (!wkb->edje_obj) + { + Evas *evas; + ecore_evas_alpha_set(wkb->ee, EINA_TRUE); + ecore_evas_title_set(wkb->ee, "Weekeyboard"); + + evas = ecore_evas_get(wkb->ee); + wkb->edje_obj = edje_object_add(evas); + edje_object_signal_callback_add(wkb->edje_obj, "key_down", "*", _cb_wkb_on_key_down, wkb); + } + + // hard coded + theme = "default"; + + if ((wkb->theme) && (eina_streq(theme, wkb->theme))) + return EINA_TRUE; + + free(wkb->theme); + wkb->theme = strdup(theme); + + if (eina_streq(wkb->theme, "default")) + { + ecore_wl_screen_size_get(&w, &h); + DBG("Screen size: w=%d, h=%d", w, h); + if (w >= 1080) + w = 1080; + else if (w >= 720) + w = 720; + else + w = 600; + + DBG("Using default_%d theme", w); + } + + snprintf(path, PATH_MAX, "%s/%s_%d.edj", e_module_dir_get(wkb->module), wkb->theme, w); + INF("Loading edje file: '%s'", path); + + if (!edje_object_file_set(wkb->edje_obj, path, "main")) + { + int err = edje_object_load_error_get(wkb->edje_obj); + ERR("Unable to load the edje file: '%s'", edje_load_error_str(err)); + return EINA_FALSE; + } + + edje_object_size_min_get(wkb->edje_obj, &w, &h); + DBG("edje_object_size_min_get - w: %d h: %d", w, h); + if ((w == 0) || (h == 0)) + { + edje_object_size_min_restricted_calc(wkb->edje_obj, &w, &h, w, h); + DBG("edje_object_size_min_restricted_calc - w: %d h: %d", w, h); + if ((w == 0) || (h == 0)) + { + edje_object_parts_extends_calc(wkb->edje_obj, NULL, NULL, &w, &h); + DBG("edje_object_parts_extends_calc - w: %d h: %d", w, h); + } + } + + ecore_evas_move_resize(wkb->ee, 0, 0, w, h); + evas_object_move(wkb->edje_obj, 0, 0); + evas_object_resize(wkb->edje_obj, w, h); + evas_object_size_hint_min_set(wkb->edje_obj, w, h); + evas_object_size_hint_max_set(wkb->edje_obj, w, h); + + if (wkb->win) + { + int rx, ry, rw, rh; + + edje_object_part_geometry_get(wkb->edje_obj, "background", &rx, &ry, &rw, &rh); + ecore_wl_window_input_region_set(wkb->win, rx, ry, rw, rh); + } + + ignore_keys = edje_file_data_get(path, "ignore-keys"); + if (!ignore_keys) + { + ERR("Special keys file not found in: '%s'", path); + goto end; + } + + DBG("Got ignore keys: '%s'", ignore_keys); + wkb->ignore_keys = eina_str_split(ignore_keys, "\n", 0); + free(ignore_keys); + +end: + ecore_evas_show(wkb->ee); + return EINA_TRUE; +} + +static void +_wkb_im_ctx_surrounding_text(void *data, struct wl_input_method_context *im_ctx, const char *text, uint32_t cursor, uint32_t anchor) +{ + struct weekeyboard *wkb = data; + + EINA_SAFETY_ON_NULL_RETURN(text); + + DBG("im_context = %p text = '%s' cursor = %d anchor = %d", im_ctx, text, cursor, anchor); + + free(wkb->surrounding_text); + + wkb->surrounding_text = strdup(text); + if (!wkb->surrounding_text) + { + ERR("out of memory"); + return; + } + + wkb->surrounding_cursor = cursor; +} + +static void +_wkb_im_ctx_reset(void *data, struct wl_input_method_context *im_ctx) +{ + struct weekeyboard *wkb = data; + + DBG("im_context = %p", im_ctx); + + if (strlen(wkb->preedit_str)) + { + free(wkb->preedit_str); + wkb->preedit_str = strdup(""); + } +} + +static void +_wkb_im_ctx_content_type(void *data, struct wl_input_method_context *im_ctx, uint32_t hint, uint32_t purpose) +{ + struct weekeyboard *wkb = data; + + DBG("im_context = %p hint = %d purpose = %d", im_ctx, hint, purpose); + + if (!wkb->context_changed) + return; + + switch (purpose) + { + case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS: + case WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER: + { + if (wkb->edje_obj) + edje_object_signal_emit(wkb->edje_obj, "show,numeric", ""); + break; + } + default: + { + if (wkb->edje_obj) + edje_object_signal_emit(wkb->edje_obj, "show,alphanumeric", ""); + break; + } + } + + wkb->content_hint = hint; + wkb->content_purpose = purpose; + wkb->context_changed = EINA_FALSE; +} + +static void +_wkb_im_ctx_invoke_action(void *data, struct wl_input_method_context *im_ctx, uint32_t button, uint32_t index) +{ + struct weekeyboard *wkb = data; + + DBG("im_context = %p button = %d, index = %d", im_ctx, button, index); + + if (button != BTN_LEFT) + return; + + _wkb_send_preedit_str(wkb, index); +} + +static void +_wkb_im_ctx_commit_state(void *data, struct wl_input_method_context *im_ctx, uint32_t serial) +{ + struct weekeyboard *wkb = data; + + DBG("im_context = %p serial = %d", im_ctx, serial); + + if (wkb->surrounding_text) + INF("Surrounding text updated: %s", wkb->surrounding_text); + + wkb->serial = serial; + + wl_input_method_context_language(im_ctx, wkb->serial, "en"); + wl_input_method_context_text_direction(im_ctx, wkb->serial, WL_TEXT_INPUT_TEXT_DIRECTION_LTR); +} + +static void +_wkb_im_ctx_preferred_language(void *data, struct wl_input_method_context *im_ctx, const char *language) +{ + struct weekeyboard *wkb = data; + + DBG("im_context = %p language = %s", im_ctx, language ? language : "null"); + + if ((language) && (wkb->language) && (eina_streq(language, wkb->language))) + return; + + E_FREE_FUNC(wkb->language, free); + + if (language) + { + wkb->language = strdup(language); + INF("Language changed, new: '%s'", language); + } +} + +static const struct wl_input_method_context_listener wkb_im_context_listener = { + _wkb_im_ctx_surrounding_text, + _wkb_im_ctx_reset, + _wkb_im_ctx_content_type, + _wkb_im_ctx_invoke_action, + _wkb_im_ctx_commit_state, + _wkb_im_ctx_preferred_language, +}; + +static void +_wkb_im_activate(void *data, struct wl_input_method *input_method EINA_UNUSED, struct wl_input_method_context *im_ctx) +{ + struct weekeyboard *wkb = data; + + DBG("Activate"); + + // check if the UI is valid and draw it if not + _wkb_ui_setup(wkb); + + E_FREE_FUNC(wkb->im_ctx, wl_input_method_context_destroy); + + free(wkb->preedit_str); + wkb->preedit_str = strdup(""); + wkb->content_hint = WL_TEXT_INPUT_CONTENT_HINT_NONE; + wkb->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL; + + free(wkb->language); + wkb->language = NULL; + + free(wkb->surrounding_text); + wkb->surrounding_text = NULL; + + wkb->serial = 0; + + wkb->im_ctx = im_ctx; + wl_input_method_context_add_listener(im_ctx, &wkb_im_context_listener, wkb); + + /* hard coded */ + wl_input_method_context_language(im_ctx, wkb->serial, "en"); + wl_input_method_context_text_direction(im_ctx, wkb->serial, WL_TEXT_INPUT_TEXT_DIRECTION_LTR); + + wkb->context_changed = EINA_TRUE; + evas_object_show(wkb->edje_obj); +} + +static void +_wkb_im_deactivate(void *data, struct wl_input_method *input_method EINA_UNUSED, struct wl_input_method_context *im_ctx EINA_UNUSED) +{ + struct weekeyboard *wkb = data; + + DBG("Deactivate"); + + E_FREE_FUNC(wkb->im_ctx, wl_input_method_context_destroy); + + if (wkb->edje_obj) + evas_object_hide(wkb->edje_obj); +} + +static const struct wl_input_method_listener wkb_im_listener = { + _wkb_im_activate, + _wkb_im_deactivate +}; + +static Eina_Bool +_wkb_setup(struct weekeyboard *wkb) +{ + Eina_Inlist *globals; + struct wl_registry *registry; + Ecore_Wl_Global *global; + struct wl_input_panel_surface *ips; + + globals = ecore_wl_globals_get(); + registry = ecore_wl_registry_get(); + EINA_INLIST_FOREACH(globals, global) + { + DBG("interface: <%s>", global->interface); + if (eina_streq(global->interface, "wl_input_panel")) + { + wkb->ip = wl_registry_bind(registry, global->id, &wl_input_panel_interface, 1); + DBG("binding wl_input_panel"); + } + else if (eina_streq(global->interface, "wl_input_method")) + { + wkb->im = wl_registry_bind(registry, global->id, &wl_input_method_interface, 1); + DBG("binding wl_input_method, id = %d", global->id); + } + else if (eina_streq(global->interface, "wl_output")) + { + wkb->output = wl_registry_bind(registry, global->id, &wl_output_interface, 1); + DBG("binding wl_output"); + } + } + + if ((!wkb->ip) || (!wkb->im) || (!wkb->output)) + return EINA_FALSE; + + /* invalidate the UI so it is drawn when invoked */ + wkb->theme = NULL; + + /* Set input panel surface */ + DBG("Setting up input panel"); + wkb->win = ecore_evas_wayland_window_get(wkb->ee); + ecore_wl_window_type_set(wkb->win, ECORE_WL_WINDOW_TYPE_NONE); + wkb->surface = ecore_wl_window_surface_create(wkb->win); + ips = wl_input_panel_get_input_panel_surface(wkb->ip, wkb->surface); + wl_input_panel_surface_set_toplevel(ips, wkb->output, WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM); + + /* Input method listener */ + DBG("Adding wl_input_method listener"); + wl_input_method_add_listener(wkb->im, &wkb_im_listener, wkb); + + wkb->edje_obj = NULL; + + return EINA_TRUE; +} + +static Eina_Bool +_wkb_check_evas_engine(struct weekeyboard *wkb) +{ + const char *env = getenv("ECORE_EVAS_ENGINE"); + + if (!env) + { + if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_SHM)) + env = "wayland_shm"; + else if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL)) + env = "wayland_egl"; + else + { + ERR("Ecore_Evas must be compiled with support for Wayland engines"); + return EINA_FALSE; + } + } + else if ((!eina_streq(env, "wayland_shm")) && + (!eina_streq(env, "wayland_egl"))) + { + ERR("ECORE_EVAS_ENGINE must be set to either 'wayland_shm' or 'wayland_egl'"); + return EINA_FALSE; + } + + wkb->ee_engine = env; + + return EINA_TRUE; +} + +static void +_wkb_free(struct weekeyboard *wkb) +{ + E_FREE_FUNC(wkb->im_ctx, wl_input_method_context_destroy); + E_FREE_FUNC(wkb->edje_obj, evas_object_del); + + if (wkb->ignore_keys) + { + free(*wkb->ignore_keys); + free(wkb->ignore_keys); + } + + free(wkb->preedit_str); + free(wkb->surrounding_text); + free(wkb->theme); + free(wkb); +} + +E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Weekeyboard" }; + +E_API void * +e_modapi_init(E_Module *m) +{ + struct weekeyboard *wkb; + + EINA_LOG_DBG("LOAD 'weekeyboard' module\n"); + + wkb = E_NEW(struct weekeyboard, 1); + if (!wkb) + { + EINA_LOG_ERR("out of memory"); + goto err; + } + + if (!wkb_log_init("weekeyboard")) + { + EINA_LOG_ERR("failed to init log"); + goto log_err; + } + + if (!_wkb_check_evas_engine(wkb)) + { + ERR("Unable to find available ee engine"); + goto engine_err; + } + + DBG("Selected engine: '%s'", wkb->ee_engine); + wkb->ee = ecore_evas_new(wkb->ee_engine, 0, 0, 1, 1, "frame=0"); + if (!wkb->ee) + { + ERR("Unable to create Ecore_Evas object"); + goto engine_err; + } + + if (!_wkb_setup(wkb)) + { + ERR("Unable to setup weekeyboard"); + goto setup_err; + } + + wkb->module = m; + + m->data = wkb; + + return m; + +setup_err: + ecore_evas_free(wkb->ee); + +engine_err: + wkb_log_shutdown(); + +log_err: + free(wkb); + +err: + return NULL; +} + +E_API int +e_modapi_shutdown(E_Module *m) +{ + struct weekeyboard *wkb = m->data; + + wkb_log_shutdown(); + + _wkb_free(wkb); + + m->data = NULL; + + return 1; +} diff --git a/src/modules/wl_weekeyboard/input-method-client-protocol.h b/src/modules/wl_weekeyboard/input-method-client-protocol.h new file mode 100644 index 000000000..64773b5e3 --- /dev/null +++ b/src/modules/wl_weekeyboard/input-method-client-protocol.h @@ -0,0 +1,439 @@ +/* + * Copyright © 2012, 2013 Intel Corporation + * + * 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 INPUT_METHOD_CLIENT_PROTOCOL_H +#define INPUT_METHOD_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct wl_input_method; +struct wl_input_method_context; +struct wl_input_panel; +struct wl_input_panel_surface; +struct wl_keyboard; +struct wl_output; +struct wl_surface; + +extern const struct wl_interface wl_input_method_context_interface; +extern const struct wl_interface wl_input_method_interface; +extern const struct wl_interface wl_input_panel_interface; +extern const struct wl_interface wl_input_panel_surface_interface; + +/** + * wl_input_method_context - input method context + * @surrounding_text: surrounding text event + * @reset: (none) + * @content_type: (none) + * @invoke_action: (none) + * @commit_state: (none) + * @preferred_language: (none) + * + * Corresponds to a text model on input method side. An input method + * context is created on text mode activation on the input method side. It + * allows to receive information about the text model from the application + * via events. Input method contexts do not keep state after deactivation + * and should be destroyed after deactivation is handled. + * + * Text is generally UTF-8 encoded, indices and lengths are in bytes. + * + * Serials are used to synchronize the state between the text input and an + * input method. New serials are sent by the text input in the commit_state + * request and are used by the input method to indicate the known text + * input state in events like preedit_string, commit_string, and keysym. + * The text input can then ignore events from the input method which are + * based on an outdated state (for example after a reset). + */ +struct wl_input_method_context_listener { + /** + * surrounding_text - surrounding text event + * @text: (none) + * @cursor: (none) + * @anchor: (none) + * + * The plain surrounding text around the input position. Cursor + * is the position in bytes within the surrounding text relative to + * the beginning of the text. Anchor is the position in bytes of + * the selection anchor within the surrounding text relative to the + * beginning of the text. If there is no selected text anchor is + * the same as cursor. + */ + void (*surrounding_text)(void *data, + struct wl_input_method_context *wl_input_method_context, + const char *text, + uint32_t cursor, + uint32_t anchor); + /** + * reset - (none) + */ + void (*reset)(void *data, + struct wl_input_method_context *wl_input_method_context); + /** + * content_type - (none) + * @hint: (none) + * @purpose: (none) + */ + void (*content_type)(void *data, + struct wl_input_method_context *wl_input_method_context, + uint32_t hint, + uint32_t purpose); + /** + * invoke_action - (none) + * @button: (none) + * @index: (none) + */ + void (*invoke_action)(void *data, + struct wl_input_method_context *wl_input_method_context, + uint32_t button, + uint32_t index); + /** + * commit_state - (none) + * @serial: serial of text input state + */ + void (*commit_state)(void *data, + struct wl_input_method_context *wl_input_method_context, + uint32_t serial); + /** + * preferred_language - (none) + * @language: (none) + */ + void (*preferred_language)(void *data, + struct wl_input_method_context *wl_input_method_context, + const char *language); +}; + +static inline int +wl_input_method_context_add_listener(struct wl_input_method_context *wl_input_method_context, + const struct wl_input_method_context_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_input_method_context, + (void (**)(void)) listener, data); +} + +#define WL_INPUT_METHOD_CONTEXT_DESTROY 0 +#define WL_INPUT_METHOD_CONTEXT_COMMIT_STRING 1 +#define WL_INPUT_METHOD_CONTEXT_PREEDIT_STRING 2 +#define WL_INPUT_METHOD_CONTEXT_PREEDIT_STYLING 3 +#define WL_INPUT_METHOD_CONTEXT_PREEDIT_CURSOR 4 +#define WL_INPUT_METHOD_CONTEXT_DELETE_SURROUNDING_TEXT 5 +#define WL_INPUT_METHOD_CONTEXT_CURSOR_POSITION 6 +#define WL_INPUT_METHOD_CONTEXT_MODIFIERS_MAP 7 +#define WL_INPUT_METHOD_CONTEXT_KEYSYM 8 +#define WL_INPUT_METHOD_CONTEXT_GRAB_KEYBOARD 9 +#define WL_INPUT_METHOD_CONTEXT_KEY 10 +#define WL_INPUT_METHOD_CONTEXT_MODIFIERS 11 +#define WL_INPUT_METHOD_CONTEXT_LANGUAGE 12 +#define WL_INPUT_METHOD_CONTEXT_TEXT_DIRECTION 13 + +static inline void +wl_input_method_context_set_user_data(struct wl_input_method_context *wl_input_method_context, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_input_method_context, user_data); +} + +static inline void * +wl_input_method_context_get_user_data(struct wl_input_method_context *wl_input_method_context) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_input_method_context); +} + +static inline void +wl_input_method_context_destroy(struct wl_input_method_context *wl_input_method_context) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_DESTROY); + + wl_proxy_destroy((struct wl_proxy *) wl_input_method_context); +} + +static inline void +wl_input_method_context_commit_string(struct wl_input_method_context *wl_input_method_context, uint32_t serial, const char *text) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_COMMIT_STRING, serial, text); +} + +static inline void +wl_input_method_context_preedit_string(struct wl_input_method_context *wl_input_method_context, uint32_t serial, const char *text, const char *commit) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_PREEDIT_STRING, serial, text, commit); +} + +static inline void +wl_input_method_context_preedit_styling(struct wl_input_method_context *wl_input_method_context, uint32_t index, uint32_t length, uint32_t style) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_PREEDIT_STYLING, index, length, style); +} + +static inline void +wl_input_method_context_preedit_cursor(struct wl_input_method_context *wl_input_method_context, int32_t index) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_PREEDIT_CURSOR, index); +} + +static inline void +wl_input_method_context_delete_surrounding_text(struct wl_input_method_context *wl_input_method_context, int32_t index, uint32_t length) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_DELETE_SURROUNDING_TEXT, index, length); +} + +static inline void +wl_input_method_context_cursor_position(struct wl_input_method_context *wl_input_method_context, int32_t index, int32_t anchor) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_CURSOR_POSITION, index, anchor); +} + +static inline void +wl_input_method_context_modifiers_map(struct wl_input_method_context *wl_input_method_context, struct wl_array *map) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_MODIFIERS_MAP, map); +} + +static inline void +wl_input_method_context_keysym(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_KEYSYM, serial, time, sym, state, modifiers); +} + +static inline struct wl_keyboard * +wl_input_method_context_grab_keyboard(struct wl_input_method_context *wl_input_method_context) +{ + struct wl_proxy *keyboard; + + keyboard = wl_proxy_marshal_constructor((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_GRAB_KEYBOARD, &wl_keyboard_interface, NULL); + + return (struct wl_keyboard *) keyboard; +} + +static inline void +wl_input_method_context_key(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_KEY, serial, time, key, state); +} + +static inline void +wl_input_method_context_modifiers(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_MODIFIERS, serial, mods_depressed, mods_latched, mods_locked, group); +} + +static inline void +wl_input_method_context_language(struct wl_input_method_context *wl_input_method_context, uint32_t serial, const char *language) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_LANGUAGE, serial, language); +} + +static inline void +wl_input_method_context_text_direction(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t direction) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_method_context, + WL_INPUT_METHOD_CONTEXT_TEXT_DIRECTION, serial, direction); +} + +/** + * wl_input_method - input method + * @activate: activate event + * @deactivate: activate event + * + * An input method object is responsible to compose text in response to + * input from hardware or virtual keyboards. There is one input method + * object per seat. On activate there is a new input method context object + * created which allows the input method to communicate with the text + * model. + */ +struct wl_input_method_listener { + /** + * activate - activate event + * @id: (none) + * + * A text model was activated. Creates an input method context + * object which allows communication with the text model. + */ + void (*activate)(void *data, + struct wl_input_method *wl_input_method, + struct wl_input_method_context *id); + /** + * deactivate - activate event + * @context: (none) + * + * The text model corresponding to the context argument was + * deactivated. The input method context should be destroyed after + * deactivation is handled. + */ + void (*deactivate)(void *data, + struct wl_input_method *wl_input_method, + struct wl_input_method_context *context); +}; + +static inline int +wl_input_method_add_listener(struct wl_input_method *wl_input_method, + const struct wl_input_method_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_input_method, + (void (**)(void)) listener, data); +} + +static inline void +wl_input_method_set_user_data(struct wl_input_method *wl_input_method, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_input_method, user_data); +} + +static inline void * +wl_input_method_get_user_data(struct wl_input_method *wl_input_method) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_input_method); +} + +static inline void +wl_input_method_destroy(struct wl_input_method *wl_input_method) +{ + wl_proxy_destroy((struct wl_proxy *) wl_input_method); +} + +#define WL_INPUT_PANEL_GET_INPUT_PANEL_SURFACE 0 + +static inline void +wl_input_panel_set_user_data(struct wl_input_panel *wl_input_panel, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_input_panel, user_data); +} + +static inline void * +wl_input_panel_get_user_data(struct wl_input_panel *wl_input_panel) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_input_panel); +} + +static inline void +wl_input_panel_destroy(struct wl_input_panel *wl_input_panel) +{ + wl_proxy_destroy((struct wl_proxy *) wl_input_panel); +} + +static inline struct wl_input_panel_surface * +wl_input_panel_get_input_panel_surface(struct wl_input_panel *wl_input_panel, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor((struct wl_proxy *) wl_input_panel, + WL_INPUT_PANEL_GET_INPUT_PANEL_SURFACE, &wl_input_panel_surface_interface, NULL, surface); + + return (struct wl_input_panel_surface *) id; +} + +#ifndef WL_INPUT_PANEL_SURFACE_POSITION_ENUM +#define WL_INPUT_PANEL_SURFACE_POSITION_ENUM +enum wl_input_panel_surface_position { + WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM = 0, +}; +#endif /* WL_INPUT_PANEL_SURFACE_POSITION_ENUM */ + +struct wl_input_panel_surface_listener { + /** + * cursor_rectangle - cursor rectangle + * @x: (none) + * @y: (none) + * @width: (none) + * @height: (none) + * + * Notify when the cursor rectangle relative to the input panel + * surface change. + */ + void (*cursor_rectangle)(void *data, + struct wl_input_panel_surface *wl_input_panel_surface, + int32_t x, + int32_t y, + int32_t width, + int32_t height); +}; + +static inline int +wl_input_panel_surface_add_listener(struct wl_input_panel_surface *wl_input_panel_surface, + const struct wl_input_panel_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_input_panel_surface, + (void (**)(void)) listener, data); +} + +#define WL_INPUT_PANEL_SURFACE_SET_TOPLEVEL 0 +#define WL_INPUT_PANEL_SURFACE_SET_OVERLAY_PANEL 1 + +static inline void +wl_input_panel_surface_set_user_data(struct wl_input_panel_surface *wl_input_panel_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_input_panel_surface, user_data); +} + +static inline void * +wl_input_panel_surface_get_user_data(struct wl_input_panel_surface *wl_input_panel_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_input_panel_surface); +} + +static inline void +wl_input_panel_surface_destroy(struct wl_input_panel_surface *wl_input_panel_surface) +{ + wl_proxy_destroy((struct wl_proxy *) wl_input_panel_surface); +} + +static inline void +wl_input_panel_surface_set_toplevel(struct wl_input_panel_surface *wl_input_panel_surface, struct wl_output *output, uint32_t position) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_panel_surface, + WL_INPUT_PANEL_SURFACE_SET_TOPLEVEL, output, position); +} + +static inline void +wl_input_panel_surface_set_overlay_panel(struct wl_input_panel_surface *wl_input_panel_surface) +{ + wl_proxy_marshal((struct wl_proxy *) wl_input_panel_surface, + WL_INPUT_PANEL_SURFACE_SET_OVERLAY_PANEL); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/modules/wl_weekeyboard/input-method-protocol.c b/src/modules/wl_weekeyboard/input-method-protocol.c new file mode 100644 index 000000000..72d84cf77 --- /dev/null +++ b/src/modules/wl_weekeyboard/input-method-protocol.c @@ -0,0 +1,118 @@ +/* + * Copyright © 2012, 2013 Intel Corporation + * + * 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. + */ + +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface wl_input_method_context_interface; +extern const struct wl_interface wl_input_panel_surface_interface; +extern const struct wl_interface wl_keyboard_interface; +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface wl_surface_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + &wl_keyboard_interface, + &wl_input_method_context_interface, + &wl_input_method_context_interface, + &wl_input_panel_surface_interface, + &wl_surface_interface, + &wl_output_interface, + NULL, +}; + +static const struct wl_message wl_input_method_context_requests[] = { + { "destroy", "", types + 0 }, + { "commit_string", "us", types + 0 }, + { "preedit_string", "uss", types + 0 }, + { "preedit_styling", "uuu", types + 0 }, + { "preedit_cursor", "i", types + 0 }, + { "delete_surrounding_text", "iu", types + 0 }, + { "cursor_position", "ii", types + 0 }, + { "modifiers_map", "a", types + 0 }, + { "keysym", "uuuuu", types + 0 }, + { "grab_keyboard", "n", types + 5 }, + { "key", "uuuu", types + 0 }, + { "modifiers", "uuuuu", types + 0 }, + { "language", "us", types + 0 }, + { "text_direction", "uu", types + 0 }, +}; + +static const struct wl_message wl_input_method_context_events[] = { + { "surrounding_text", "suu", types + 0 }, + { "reset", "", types + 0 }, + { "content_type", "uu", types + 0 }, + { "invoke_action", "uu", types + 0 }, + { "commit_state", "u", types + 0 }, + { "preferred_language", "s", types + 0 }, +}; + +WL_EXPORT const struct wl_interface wl_input_method_context_interface = { + "wl_input_method_context", 1, + 14, wl_input_method_context_requests, + 6, wl_input_method_context_events, +}; + +static const struct wl_message wl_input_method_events[] = { + { "activate", "n", types + 6 }, + { "deactivate", "o", types + 7 }, +}; + +WL_EXPORT const struct wl_interface wl_input_method_interface = { + "wl_input_method", 1, + 0, NULL, + 2, wl_input_method_events, +}; + +static const struct wl_message wl_input_panel_requests[] = { + { "get_input_panel_surface", "no", types + 8 }, +}; + +WL_EXPORT const struct wl_interface wl_input_panel_interface = { + "wl_input_panel", 1, + 1, wl_input_panel_requests, + 0, NULL, +}; + +static const struct wl_message wl_input_panel_surface_requests[] = { + { "set_toplevel", "ou", types + 10 }, + { "set_overlay_panel", "", types + 0 }, +}; + +static const struct wl_message wl_input_panel_surface_events[] = { + { "cursor_rectangle", "iiii", types + 0 }, +}; + +WL_EXPORT const struct wl_interface wl_input_panel_surface_interface = { + "wl_input_panel_surface", 1, + 2, wl_input_panel_surface_requests, + 1, wl_input_panel_surface_events, +}; + diff --git a/src/modules/wl_weekeyboard/text-client-protocol.h b/src/modules/wl_weekeyboard/text-client-protocol.h new file mode 100644 index 000000000..f9288b159 --- /dev/null +++ b/src/modules/wl_weekeyboard/text-client-protocol.h @@ -0,0 +1,540 @@ +/* + * Copyright © 2012, 2013 Intel Corporation + * + * 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 TEXT_CLIENT_PROTOCOL_H +#define TEXT_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct wl_seat; +struct wl_surface; +struct wl_text_input; +struct wl_text_input_manager; + +extern const struct wl_interface wl_text_input_interface; +extern const struct wl_interface wl_text_input_manager_interface; + +#ifndef WL_TEXT_INPUT_CONTENT_HINT_ENUM +#define WL_TEXT_INPUT_CONTENT_HINT_ENUM +/** + * wl_text_input_content_hint - content hint + * @WL_TEXT_INPUT_CONTENT_HINT_NONE: no special behaviour + * @WL_TEXT_INPUT_CONTENT_HINT_DEFAULT: auto completion, correction and + * capitalization + * @WL_TEXT_INPUT_CONTENT_HINT_PASSWORD: hidden and sensitive text + * @WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION: suggest word completions + * @WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION: suggest word corrections + * @WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION: switch to uppercase + * letters at the start of a sentence + * @WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE: prefer lowercase letters + * @WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE: prefer uppercase letters + * @WL_TEXT_INPUT_CONTENT_HINT_TITLECASE: prefer casing for titles and + * headings (can be language dependent) + * @WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT: characters should be hidden + * @WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA: typed text should not be + * stored + * @WL_TEXT_INPUT_CONTENT_HINT_LATIN: just latin characters should be + * entered + * @WL_TEXT_INPUT_CONTENT_HINT_MULTILINE: the text input is multiline + * + * Content hint is a bitmask to allow to modify the behavior of the text + * input. + */ +enum wl_text_input_content_hint { + WL_TEXT_INPUT_CONTENT_HINT_NONE = 0x0, + WL_TEXT_INPUT_CONTENT_HINT_DEFAULT = 0x7, + WL_TEXT_INPUT_CONTENT_HINT_PASSWORD = 0xc0, + WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION = 0x1, + WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION = 0x2, + WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 0x4, + WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE = 0x8, + WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE = 0x10, + WL_TEXT_INPUT_CONTENT_HINT_TITLECASE = 0x20, + WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT = 0x40, + WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA = 0x80, + WL_TEXT_INPUT_CONTENT_HINT_LATIN = 0x100, + WL_TEXT_INPUT_CONTENT_HINT_MULTILINE = 0x200, +}; +#endif /* WL_TEXT_INPUT_CONTENT_HINT_ENUM */ + +#ifndef WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM +#define WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM +/** + * wl_text_input_content_purpose - content purpose + * @WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL: default input, allowing all + * characters + * @WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA: allow only alphabetic characters + * @WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS: allow only digits + * @WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER: input a number (including + * decimal separator and sign) + * @WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE: input a phone number + * @WL_TEXT_INPUT_CONTENT_PURPOSE_URL: input an URL + * @WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL: input an email address + * @WL_TEXT_INPUT_CONTENT_PURPOSE_NAME: input a name of a person + * @WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD: input a password (combine + * with password or sensitive_data hint) + * @WL_TEXT_INPUT_CONTENT_PURPOSE_DATE: input a date + * @WL_TEXT_INPUT_CONTENT_PURPOSE_TIME: input a time + * @WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME: input a date and time + * @WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL: input for a terminal + * + * The content purpose allows to specify the primary purpose of a text + * input. + * + * This allows an input method to show special purpose input panels with + * extra characters or to disallow some characters. + */ +enum wl_text_input_content_purpose { + WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL = 0, + WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA = 1, + WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS = 2, + WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER = 3, + WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE = 4, + WL_TEXT_INPUT_CONTENT_PURPOSE_URL = 5, + WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL = 6, + WL_TEXT_INPUT_CONTENT_PURPOSE_NAME = 7, + WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD = 8, + WL_TEXT_INPUT_CONTENT_PURPOSE_DATE = 9, + WL_TEXT_INPUT_CONTENT_PURPOSE_TIME = 10, + WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME = 11, + WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL = 12, +}; +#endif /* WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM */ + +#ifndef WL_TEXT_INPUT_PREEDIT_STYLE_ENUM +#define WL_TEXT_INPUT_PREEDIT_STYLE_ENUM +enum wl_text_input_preedit_style { + WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT = 0, + WL_TEXT_INPUT_PREEDIT_STYLE_NONE = 1, + WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE = 2, + WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE = 3, + WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT = 4, + WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE = 5, + WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION = 6, + WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT = 7, +}; +#endif /* WL_TEXT_INPUT_PREEDIT_STYLE_ENUM */ + +#ifndef WL_TEXT_INPUT_TEXT_DIRECTION_ENUM +#define WL_TEXT_INPUT_TEXT_DIRECTION_ENUM +enum wl_text_input_text_direction { + WL_TEXT_INPUT_TEXT_DIRECTION_AUTO = 0, + WL_TEXT_INPUT_TEXT_DIRECTION_LTR = 1, + WL_TEXT_INPUT_TEXT_DIRECTION_RTL = 2, +}; +#endif /* WL_TEXT_INPUT_TEXT_DIRECTION_ENUM */ + +/** + * wl_text_input - text input + * @enter: enter event + * @leave: leave event + * @modifiers_map: modifiers map + * @input_panel_state: state of the input panel + * @preedit_string: pre-edit + * @preedit_styling: pre-edit styling + * @preedit_cursor: pre-edit cursor + * @commit_string: commit + * @cursor_position: set cursor to new position + * @delete_surrounding_text: delete surrounding text + * @keysym: keysym + * @language: language + * @text_direction: text direction + * + * An object used for text input. Adds support for text input and input + * methods to applications. A text-input object is created from a + * wl_text_input_manager and corresponds typically to a text entry in an + * application. Requests are used to activate/deactivate the text-input + * object and set state information like surrounding and selected text or + * the content type. The information about entered text is sent to the + * text-input object via the pre-edit and commit events. Using this + * interface removes the need for applications to directly process hardware + * key events and compose text out of them. + * + * Text is generally UTF-8 encoded, indices and lengths are in bytes. + * + * Serials are used to synchronize the state between the text input and an + * input method. New serials are sent by the text input in the commit_state + * request and are used by the input method to indicate the known text + * input state in events like preedit_string, commit_string, and keysym. + * The text input can then ignore events from the input method which are + * based on an outdated state (for example after a reset). + */ +struct wl_text_input_listener { + /** + * enter - enter event + * @surface: (none) + * + * Notify the text-input object when it received focus. Typically + * in response to an activate request. + */ + void (*enter)(void *data, + struct wl_text_input *wl_text_input, + struct wl_surface *surface); + /** + * leave - leave event + * + * Notify the text-input object when it lost focus. Either in + * response to a deactivate request or when the assigned surface + * lost focus or was destroyed. + */ + void (*leave)(void *data, + struct wl_text_input *wl_text_input); + /** + * modifiers_map - modifiers map + * @map: (none) + * + * Transfer an array of 0-terminated modifiers names. The + * position in the array is the index of the modifier as used in + * the modifiers bitmask in the keysym event. + */ + void (*modifiers_map)(void *data, + struct wl_text_input *wl_text_input, + struct wl_array *map); + /** + * input_panel_state - state of the input panel + * @state: (none) + * + * Notify when the visibility state of the input panel changed. + */ + void (*input_panel_state)(void *data, + struct wl_text_input *wl_text_input, + uint32_t state); + /** + * preedit_string - pre-edit + * @serial: serial of the latest known text input state + * @text: (none) + * @commit: (none) + * + * Notify when a new composing text (pre-edit) should be set + * around the current cursor position. Any previously set composing + * text should be removed. + * + * The commit text can be used to replace the preedit text on reset + * (for example on unfocus). + * + * The text input should also handle all preedit_style and + * preedit_cursor events occuring directly before preedit_string. + */ + void (*preedit_string)(void *data, + struct wl_text_input *wl_text_input, + uint32_t serial, + const char *text, + const char *commit); + /** + * preedit_styling - pre-edit styling + * @index: (none) + * @length: (none) + * @style: (none) + * + * Sets styling information on composing text. The style is + * applied for length bytes from index relative to the beginning of + * the composing text (as byte offset). Multiple styles can be + * applied to a composing text by sending multiple preedit_styling + * events. + * + * This event is handled as part of a following preedit_string + * event. + */ + void (*preedit_styling)(void *data, + struct wl_text_input *wl_text_input, + uint32_t index, + uint32_t length, + uint32_t style); + /** + * preedit_cursor - pre-edit cursor + * @index: (none) + * + * Sets the cursor position inside the composing text (as byte + * offset) relative to the start of the composing text. When index + * is a negative number no cursor is shown. + * + * This event is handled as part of a following preedit_string + * event. + */ + void (*preedit_cursor)(void *data, + struct wl_text_input *wl_text_input, + int32_t index); + /** + * commit_string - commit + * @serial: serial of the latest known text input state + * @text: (none) + * + * Notify when text should be inserted into the editor widget. + * The text to commit could be either just a single character after + * a key press or the result of some composing (pre-edit). It could + * be also an empty text when some text should be removed (see + * delete_surrounding_text) or when the input cursor should be + * moved (see cursor_position). + * + * Any previously set composing text should be removed. + */ + void (*commit_string)(void *data, + struct wl_text_input *wl_text_input, + uint32_t serial, + const char *text); + /** + * cursor_position - set cursor to new position + * @index: (none) + * @anchor: (none) + * + * Notify when the cursor or anchor position should be modified. + * + * This event should be handled as part of a following + * commit_string event. + */ + void (*cursor_position)(void *data, + struct wl_text_input *wl_text_input, + int32_t index, + int32_t anchor); + /** + * delete_surrounding_text - delete surrounding text + * @index: (none) + * @length: (none) + * + * Notify when the text around the current cursor position should + * be deleted. + * + * Index is relative to the current cursor (in bytes). Length is + * the length of deleted text (in bytes). + * + * This event should be handled as part of a following + * commit_string event. + */ + void (*delete_surrounding_text)(void *data, + struct wl_text_input *wl_text_input, + int32_t index, + uint32_t length); + /** + * keysym - keysym + * @serial: serial of the latest known text input state + * @time: (none) + * @sym: (none) + * @state: (none) + * @modifiers: (none) + * + * Notify when a key event was sent. Key events should not be + * used for normal text input operations, which should be done with + * commit_string, delete_surrounding_text, etc. The key event + * follows the wl_keyboard key event convention. Sym is a XKB + * keysym, state a wl_keyboard key_state. Modifiers are a mask for + * effective modifiers (where the modifier indices are set by the + * modifiers_map event) + */ + void (*keysym)(void *data, + struct wl_text_input *wl_text_input, + uint32_t serial, + uint32_t time, + uint32_t sym, + uint32_t state, + uint32_t modifiers); + /** + * language - language + * @serial: serial of the latest known text input state + * @language: (none) + * + * Sets the language of the input text. The "language" argument + * is a RFC-3066 format language tag. + */ + void (*language)(void *data, + struct wl_text_input *wl_text_input, + uint32_t serial, + const char *language); + /** + * text_direction - text direction + * @serial: serial of the latest known text input state + * @direction: (none) + * + * Sets the text direction of input text. + * + * It is mainly needed for showing input cursor on correct side of + * the editor when there is no input yet done and making sure + * neutral direction text is laid out properly. + */ + void (*text_direction)(void *data, + struct wl_text_input *wl_text_input, + uint32_t serial, + uint32_t direction); +}; + +static inline int +wl_text_input_add_listener(struct wl_text_input *wl_text_input, + const struct wl_text_input_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_text_input, + (void (**)(void)) listener, data); +} + +#define WL_TEXT_INPUT_ACTIVATE 0 +#define WL_TEXT_INPUT_DEACTIVATE 1 +#define WL_TEXT_INPUT_SHOW_INPUT_PANEL 2 +#define WL_TEXT_INPUT_HIDE_INPUT_PANEL 3 +#define WL_TEXT_INPUT_RESET 4 +#define WL_TEXT_INPUT_SET_SURROUNDING_TEXT 5 +#define WL_TEXT_INPUT_SET_CONTENT_TYPE 6 +#define WL_TEXT_INPUT_SET_CURSOR_RECTANGLE 7 +#define WL_TEXT_INPUT_SET_PREFERRED_LANGUAGE 8 +#define WL_TEXT_INPUT_COMMIT_STATE 9 +#define WL_TEXT_INPUT_INVOKE_ACTION 10 + +static inline void +wl_text_input_set_user_data(struct wl_text_input *wl_text_input, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_text_input, user_data); +} + +static inline void * +wl_text_input_get_user_data(struct wl_text_input *wl_text_input) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_text_input); +} + +static inline void +wl_text_input_destroy(struct wl_text_input *wl_text_input) +{ + wl_proxy_destroy((struct wl_proxy *) wl_text_input); +} + +static inline void +wl_text_input_activate(struct wl_text_input *wl_text_input, struct wl_seat *seat, struct wl_surface *surface) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_ACTIVATE, seat, surface); +} + +static inline void +wl_text_input_deactivate(struct wl_text_input *wl_text_input, struct wl_seat *seat) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_DEACTIVATE, seat); +} + +static inline void +wl_text_input_show_input_panel(struct wl_text_input *wl_text_input) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_SHOW_INPUT_PANEL); +} + +static inline void +wl_text_input_hide_input_panel(struct wl_text_input *wl_text_input) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_HIDE_INPUT_PANEL); +} + +static inline void +wl_text_input_reset(struct wl_text_input *wl_text_input) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_RESET); +} + +static inline void +wl_text_input_set_surrounding_text(struct wl_text_input *wl_text_input, const char *text, uint32_t cursor, uint32_t anchor) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_SET_SURROUNDING_TEXT, text, cursor, anchor); +} + +static inline void +wl_text_input_set_content_type(struct wl_text_input *wl_text_input, uint32_t hint, uint32_t purpose) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_SET_CONTENT_TYPE, hint, purpose); +} + +static inline void +wl_text_input_set_cursor_rectangle(struct wl_text_input *wl_text_input, int32_t x, int32_t y, int32_t width, int32_t height) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_SET_CURSOR_RECTANGLE, x, y, width, height); +} + +static inline void +wl_text_input_set_preferred_language(struct wl_text_input *wl_text_input, const char *language) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_SET_PREFERRED_LANGUAGE, language); +} + +static inline void +wl_text_input_commit_state(struct wl_text_input *wl_text_input, uint32_t serial) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_COMMIT_STATE, serial); +} + +static inline void +wl_text_input_invoke_action(struct wl_text_input *wl_text_input, uint32_t button, uint32_t index) +{ + wl_proxy_marshal((struct wl_proxy *) wl_text_input, + WL_TEXT_INPUT_INVOKE_ACTION, button, index); +} + +#define WL_TEXT_INPUT_MANAGER_CREATE_TEXT_INPUT 0 + +static inline void +wl_text_input_manager_set_user_data(struct wl_text_input_manager *wl_text_input_manager, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_text_input_manager, user_data); +} + +static inline void * +wl_text_input_manager_get_user_data(struct wl_text_input_manager *wl_text_input_manager) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_text_input_manager); +} + +static inline void +wl_text_input_manager_destroy(struct wl_text_input_manager *wl_text_input_manager) +{ + wl_proxy_destroy((struct wl_proxy *) wl_text_input_manager); +} + +static inline struct wl_text_input * +wl_text_input_manager_create_text_input(struct wl_text_input_manager *wl_text_input_manager) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor((struct wl_proxy *) wl_text_input_manager, + WL_TEXT_INPUT_MANAGER_CREATE_TEXT_INPUT, &wl_text_input_interface, NULL); + + return (struct wl_text_input *) id; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/modules/wl_weekeyboard/text-protocol.c b/src/modules/wl_weekeyboard/text-protocol.c new file mode 100644 index 000000000..c5b3f07e8 --- /dev/null +++ b/src/modules/wl_weekeyboard/text-protocol.c @@ -0,0 +1,92 @@ +/* + * Copyright © 2012, 2013 Intel Corporation + * + * 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. + */ + +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface wl_text_input_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + &wl_seat_interface, + &wl_surface_interface, + &wl_seat_interface, + &wl_surface_interface, + &wl_text_input_interface, +}; + +static const struct wl_message wl_text_input_requests[] = { + { "activate", "oo", types + 5 }, + { "deactivate", "o", types + 7 }, + { "show_input_panel", "", types + 0 }, + { "hide_input_panel", "", types + 0 }, + { "reset", "", types + 0 }, + { "set_surrounding_text", "suu", types + 0 }, + { "set_content_type", "uu", types + 0 }, + { "set_cursor_rectangle", "iiii", types + 0 }, + { "set_preferred_language", "s", types + 0 }, + { "commit_state", "u", types + 0 }, + { "invoke_action", "uu", types + 0 }, +}; + +static const struct wl_message wl_text_input_events[] = { + { "enter", "o", types + 8 }, + { "leave", "", types + 0 }, + { "modifiers_map", "a", types + 0 }, + { "input_panel_state", "u", types + 0 }, + { "preedit_string", "uss", types + 0 }, + { "preedit_styling", "uuu", types + 0 }, + { "preedit_cursor", "i", types + 0 }, + { "commit_string", "us", types + 0 }, + { "cursor_position", "ii", types + 0 }, + { "delete_surrounding_text", "iu", types + 0 }, + { "keysym", "uuuuu", types + 0 }, + { "language", "us", types + 0 }, + { "text_direction", "uu", types + 0 }, +}; + +WL_EXPORT const struct wl_interface wl_text_input_interface = { + "wl_text_input", 1, + 11, wl_text_input_requests, + 13, wl_text_input_events, +}; + +static const struct wl_message wl_text_input_manager_requests[] = { + { "create_text_input", "n", types + 9 }, +}; + +WL_EXPORT const struct wl_interface wl_text_input_manager_interface = { + "wl_text_input_manager", 1, + 1, wl_text_input_manager_requests, + 0, NULL, +}; + diff --git a/src/modules/wl_weekeyboard/themes/default/default.edc b/src/modules/wl_weekeyboard/themes/default/default.edc new file mode 100644 index 000000000..8b976e994 --- /dev/null +++ b/src/modules/wl_weekeyboard/themes/default/default.edc @@ -0,0 +1,1118 @@ +/* + * Copyright © 2013 Intel Corporation + * Copyright © 2014 Jaguar Landrover + * + * 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. + */ + +images { + image: "icon-backspace.png" COMP; + image: "icon-enter.png" COMP; + image: "icon-language.png" COMP; + image: "icon-shift-active.png" COMP; + image: "icon-shift.png" COMP; + image: "icon-space.png" COMP; + + image: "key-default.png" COMP; + image: "key-default-pressed.png" COMP; + image: "key-hint.png" COMP; + image: "key-hint-bg.png" COMP; + image: "key-special.png" COMP; + image: "key-special-pressed.png" COMP; +} + +fonts { + font: "SourceSansPro-Regular.ttf" "Regular"; + font: "SourceSansPro-Semibold.ttf" "Semibold"; +} + +data { + file: "ignore-keys" "ignorekeys.txt"; +} + +collections { + group { + name: "main"; + + min: MIN_WIDTH MIN_HEIGHT; + max: MAX_WIDTH MAX_HEIGHT; + + parts { + part { + name: "rect_bg"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 0; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + relative: 1.0 1.0; + offset: -1 -1; + } + } + } + + part { + name: "background"; + mouse_events: 1; + pointer_mode: NOGRAB; + type: RECT; + description { + state: "default" 0.0; + color: 214 215 218 255; + rel1 { + relative: 0.0 0.0; + offset: 0 (150*SCALE); + } + rel2 { + relative: 1.0 1.0; + offset: -1 -1; + } + } + } + } + +#define KEY_GROUP(_name) \ + parts { \ + part { \ + name: _name"_clip"; \ + type: RECT; \ + description { \ + state: "default" 0.0; \ + rel1 { \ + relative: 0.0 0.0; \ + offset: 0 0; \ + } \ + rel2 { \ + relative: 1.0 1.0; \ + offset: -1 -1; \ + } \ + } \ + description { \ + state: "hidden" 0.0; \ + inherit: "default" 0.0; \ + visible: 0; \ + } \ + } \ + part { \ + name: _name; \ + type: GROUP; \ + source: _name; \ + clip_to: _name"_clip"; \ + description { \ + state: "default" 0.0; \ + rel1 { \ + to: "background"; \ + relative: 0.0 0.0; \ + offset: (5*SCALE) (10*SCALE); \ + } \ + rel2 { \ + to: "background"; \ + relative: 1.0 1.0; \ + offset: -1 -1; \ + } \ + } \ + } \ + } \ + programs { \ + program { \ + name: "show-"_name; \ + action: STATE_SET "default" 0.0; \ + target: _name"_clip"; \ + } \ + program { \ + name: "hide-"_name; \ + action: STATE_SET "hidden" 0.0; \ + target: _name"_clip"; \ + } \ + } + + KEY_GROUP("alphanum") + KEY_GROUP("numeric") + KEY_GROUP("special-1") + KEY_GROUP("special-2") + KEY_GROUP("fixed") + + programs { + program { + name: "alphanum_show"; + signal: "show,alphanumeric"; + after: "show-alphanum"; + after: "hide-numeric"; + after: "hide-special-1"; + after: "hide-special-2"; + after: "show-fixed"; + } + + program { + name: "numeric_show"; + signal: "show,numeric"; + after: "show-numeric"; + after: "hide-alphanum"; + after: "hide-special-1"; + after: "hide-special-2"; + after: "hide-fixed"; + } + + program { + name: "special-1_show"; + signal: "show,special,1"; + after: "show-special-1"; + after: "hide-numeric"; + after: "hide-alphanum"; + after: "hide-special-2"; + after: "show-fixed"; + } + + program { + name: "special-2_show"; + signal: "show,special,2"; + after: "show-special-2"; + after: "hide-numeric"; + after: "hide-alphanum"; + after: "hide-special-1"; + after: "show-fixed"; + } + + program { + name: "?123_clicked"; + signal: "key_down"; + source: "alphanum:?123"; + after: "special-1_show"; + } + program { + name: "special-1_abc_clicked"; + signal: "key_down"; + source: "special-1:abc"; + after: "alphanum_show"; + } + program { + name: "special-2_abc_clicked"; + signal: "key_down"; + source: "special-2:abc"; + after: "alphanum_show"; + } + program { + name: "1/2_clicked"; + signal: "key_down"; + source: "special-1:1/2"; + after: "special-2_show"; + } + program { + name: "2/2_clicked"; + signal: "key_down"; + source: "special-2:2/2"; + after: "special-1_show"; + } + program { + name: "init"; + signal: "show"; + after: "alphanum_show"; + } + } + } + + group { + name: "alphanum"; + +#define MOUSE_DOWN_UP_SCRIPTS \ + public shift_pressed = 0; \ + public mouse_down = 0; \ + public long_press_timer = 0; \ + public long_press = 0; \ + public pressed_key; \ + \ + public _set_long_press(val) { \ + new _cur[20]; \ + new _timer; \ + _timer = get_int(long_press_timer); \ + if (_timer) { \ + cancel_timer(_timer); \ + set_int(long_press_timer, 0); \ + } \ + set_int(long_press, val); \ + if (!val) \ + return; \ + get_str(pressed_key, _cur, 20); \ + if (strlen(_cur) > 0) { \ + emit("long_press", _cur); \ + } \ + } \ + \ + _set_key_pressed(_key[]) { \ + new _cur[20]; \ + new _prg[30]; \ + new _timer; \ + get_str(pressed_key, _cur, 20); \ + if (strlen(_cur) > 0) { \ + _set_key_released(_cur); \ + } \ + set_str(pressed_key, _key); \ + _timer = timer(0.5, "_set_long_press", 1); \ + set_int(long_press_timer, _timer); \ + snprintf(_prg, 30, "key-press-%s", _key); \ + run_program(get_program_id(_prg)); \ + } \ + \ + _set_key_released(_key[]) { \ + new _prg[30]; \ + _set_long_press(0); \ + set_str(pressed_key, ""); \ + snprintf(_prg, 30, "key-release-%s", _key); \ + run_program(get_program_id(_prg)); \ + } \ + +#define MOUSE_DOWN_UP_PROGRAMS \ + program { \ + name: "mouse-down"; \ + signal: "mouse,down,1"; \ + source: "*"; \ + script { \ + set_int(mouse_down, 1); \ + } \ + } \ + program { \ + name: "mouse-up"; \ + signal: "mouse,up,1"; \ + source: "*"; \ + script { \ + set_int(mouse_down, 0); \ + } \ + } + + script { + MOUSE_DOWN_UP_SCRIPTS + } + programs { + MOUSE_DOWN_UP_PROGRAMS + } + parts { +#undef INIT_HSPACE +#define INIT_HSPACE 5 +#define KEY_WIDTH (65*SCALE) +#define KEY_HEIGHT (90*SCALE) +#define COL_SPACE 5 +#define KEY_OFFSET(index) ((COL_SPACE+KEY_WIDTH)*index)+INIT_HSPACE + +#define FIRST_ROW 0 +#define ROW_SPACE (20*SCALE) + +#define SKEY_FULL(key_low, key_up, key_name, key_alt, x, y) \ + part { \ + name: "key-img-"key_name; \ + type: IMAGE; \ + mouse_events: 0; \ + description { \ + state: "default" 0.0; \ + min: KEY_WIDTH KEY_HEIGHT; \ + max: KEY_WIDTH KEY_HEIGHT; \ + fixed: 1 1; \ + rel1 { \ + relative: 0.0 0.0; \ + offset: (x) (y); \ + } \ + rel2 { \ + relative: 0.0 0.0; \ + offset: (x+KEY_WIDTH-1) (y+KEY_HEIGHT-1); \ + } \ + image { \ + normal: "key-default.png"; \ + border: 8 8 10 10; \ + } \ + } \ + description { \ + state: "down" 0.0; \ + inherit: "default" 0.0; \ + rel1.offset: (x+1) (y+1); \ + rel2.offset: (x+1+KEY_WIDTH-1) (y+1+KEY_HEIGHT-1); \ + image.normal: "key-default-pressed.png"; \ + } \ + } \ + part { \ + name: "key-bg-"key_name; \ + type: RECT; \ + pointer_mode: NOGRAB; \ + description { \ + state: "default" 0.0; \ + color: 0 0 0 0; \ + rel1 { \ + to: "key-img-"key_name; \ + relative: 0.0 0.0; \ + offset: 3 2; \ + } \ + rel2 { \ + to: "key-img-"key_name; \ + relative: 1.0 1.0; \ + offset: -4 -6; \ + } \ + } \ + } \ + part { \ + name: "key-lbl-"key_name; \ + type: TEXT; \ + mouse_events: 0; \ + effect: SHADOW BOTTOM; \ + description { \ + state: "default" 0.0; \ + color: 63 67 72 255; \ + color2: 240 240 240 255; \ + color3: 240 240 240 255; \ + rel1 { \ + to: "key-bg-"key_name; \ + relative: 0.0 0.4; \ + } \ + rel2 { \ + to: "key-bg-"key_name; \ + relative: 1.0 0.9; \ + } \ + text { \ + font: "Regular"; \ + size: (44*SCALE); \ + text: key_low; \ + } \ + } \ + } \ + part { \ + name: "key-lbl-alt-"key_name; \ + type: TEXT; \ + mouse_events: 0; \ + effect: SHADOW BOTTOM; \ + description { \ + state: "default" 0.0; \ + color: 63 67 72 255; \ + color2: 240 240 240 255; \ + color3: 240 240 240 255; \ + rel1 { \ + to: "key-bg-"key_name; \ + relative: 0.0 0.1; \ + } \ + rel2 { \ + to: "key-bg-"key_name; \ + relative: 1.0 0.4; \ + } \ + text { \ + font: "Regular"; \ + size: (22*SCALE); \ + align: 0.8 0.0; \ + text: key_alt; \ + } \ + } \ + } \ + part { \ + name: "key-img-hint-"key_name; \ + type: IMAGE; \ + mouse_events: 0; \ + description { \ + state: "default" 0.0; \ + min: KEY_WIDTH KEY_HEIGHT; \ + max: KEY_WIDTH KEY_HEIGHT; \ + fixed: 1 1; \ + rel1 { \ + to: "key-img-"key_name; \ + relative: 0.0 0.0; \ + offset: 0 ((-20*SCALE)-KEY_HEIGHT); \ + } \ + rel2 { \ + to: "key-img-"key_name; \ + relative: 1.0 0.0; \ + offset: 0 (-20*SCALE); \ + } \ + image { \ + normal: "key-hint.png"; \ + border: 8 8 10 10; \ + } \ + visible: 0; \ + } \ + description { \ + state: "down" 0.0; \ + inherit: "default" 0.0; \ + visible: 1; \ + } \ + } \ + part { \ + name: "key-lbl-hint-"key_name; \ + type: TEXT; \ + mouse_events: 0; \ + effect: SHADOW BOTTOM; \ + description { \ + state: "default" 0.0; \ + color: 63 67 72 255; \ + color2: 240 240 240 255; \ + color3: 240 240 240 255; \ + rel1 { \ + to: "key-img-hint-"key_name; \ + relative: 0.0 0.0; \ + } \ + rel2 { \ + to: "key-img-hint-"key_name; \ + relative: 1.0 1.0; \ + } \ + text { \ + font: "Regular"; \ + size: (48*SCALE); \ + text: key_low; \ + } \ + visible: 0; \ + } \ + description { \ + state: "down" 0.0; \ + inherit: "default" 0.0; \ + visible: 1; \ + } \ + } \ + programs { \ + program { \ + name: "key-mouse-in-"key_name; \ + signal: "mouse,in"; \ + source: "key-bg-"key_name; \ + script { \ + if (get_int(mouse_down) == 0) \ + return; \ + _set_key_pressed(key_name); \ + } \ + } \ + program { \ + name: "key-mouse-out-"key_name; \ + signal: "mouse,out"; \ + source: "key-bg-"key_name; \ + script { \ + if (get_int(mouse_down) == 0) \ + return; \ + _set_key_released(key_name); \ + } \ + } \ + program { \ + name: "key-mouse-down-"key_name; \ + signal: "mouse,down,1"; \ + source: "key-bg-"key_name; \ + script { \ + _set_key_pressed(key_name); \ + } \ + } \ + program { \ + name: "key-mouse-up-"key_name; \ + signal: "mouse,up,1"; \ + source: "key-bg-"key_name; \ + script { \ + if (get_int(long_press) == 0) { \ + if (get_int(shift_pressed) == 0) \ + emit("key_down", key_low); \ + else \ + emit("key_down", key_up); \ + } else { \ + if (strcmp(key_alt, " ")) \ + emit("key_down", key_alt); \ + else if (get_int(shift_pressed) == 0) \ + emit("key_down", key_low); \ + else \ + emit("key_down", key_up); \ + } \ + _set_key_released(key_name); \ + } \ + } \ + program { \ + name: "key-press-"key_name; \ + action: STATE_SET "down" 0.0; \ + target: "key-img-"key_name; \ + target: "key-img-hint-"key_name; \ + target: "key-lbl-hint-"key_name; \ + } \ + program { \ + name: "key-release-"key_name; \ + action: STATE_SET "default" 0.0; \ + transition: LINEAR 0.2; \ + target: "key-img-"key_name; \ + target: "key-img-hint-"key_name; \ + target: "key-lbl-hint-"key_name; \ + after: "shift-pressed-"key_name; \ + } \ + program { \ + name: "long-press-"key_name; \ + signal: "long_press"; \ + source: key_name; \ + script { \ + if (strcmp(key_alt, " ")) \ + set_text(PART:"key-lbl-hint-"key_name, key_alt); \ + } \ + } \ + program { \ + name: "shift-pressed-"key_name; \ + signal: "key_down"; \ + source: "shift"; \ + script { \ + if (get_int(shift_pressed) == 0) { \ + set_text(PART:"key-lbl-"key_name, key_low); \ + set_text(PART:"key-lbl-hint-"key_name, key_low); \ + } else { \ + set_text(PART:"key-lbl-"key_name, key_up); \ + set_text(PART:"key-lbl-hint-"key_name, key_up); \ + } \ + } \ + } \ + } +#define KEY_FULL(low, up, alt, x, y) SKEY_FULL(low, up, low, alt, x, y) +#define SKEY(name, text, alt, x, y) SKEY_FULL(name, name, text, alt, x, y) +#define KEY(v, alt, x, y) SKEY(v, v, alt, x, y) + + KEY_FULL("q", "Q", "1", KEY_OFFSET(0), FIRST_ROW) + KEY_FULL("w", "W", "2", KEY_OFFSET(1), FIRST_ROW) + KEY_FULL("e", "E", "3", KEY_OFFSET(2), FIRST_ROW) + KEY_FULL("r", "R", "4", KEY_OFFSET(3), FIRST_ROW) + KEY_FULL("t", "T", "5", KEY_OFFSET(4), FIRST_ROW) + KEY_FULL("y", "Y", "6", KEY_OFFSET(5), FIRST_ROW) + KEY_FULL("u", "U", "7", KEY_OFFSET(6), FIRST_ROW) + KEY_FULL("i", "I", "8", KEY_OFFSET(7), FIRST_ROW) + KEY_FULL("o", "O", "9", KEY_OFFSET(8), FIRST_ROW) + KEY_FULL("p", "P", "0", KEY_OFFSET(9), FIRST_ROW) + +#undef INIT_HSPACE +#define INIT_HSPACE (45*SCALE) +#define SECOND_ROW FIRST_ROW+KEY_HEIGHT+ROW_SPACE + + KEY_FULL("a", "A", "-", KEY_OFFSET(0), SECOND_ROW) + KEY_FULL("s", "S", "@", KEY_OFFSET(1), SECOND_ROW) + KEY_FULL("d", "D", "*", KEY_OFFSET(2), SECOND_ROW) + KEY_FULL("f", "F", "^", KEY_OFFSET(3), SECOND_ROW) + KEY_FULL("g", "G", ":", KEY_OFFSET(4), SECOND_ROW) + KEY_FULL("h", "H", ";", KEY_OFFSET(5), SECOND_ROW) + KEY_FULL("j", "J", "(", KEY_OFFSET(6), SECOND_ROW) + KEY_FULL("k", "K", ")", KEY_OFFSET(7), SECOND_ROW) + KEY_FULL("l", "L", "~", KEY_OFFSET(8), SECOND_ROW) + +#undef INIT_HSPACE +#define INIT_HSPACE (110*SCALE) +#define THIRD_ROW SECOND_ROW+KEY_HEIGHT+ROW_SPACE + + KEY_FULL("z", "Z", "/", KEY_OFFSET(0), THIRD_ROW) + KEY_FULL("x", "X", "'", KEY_OFFSET(1), THIRD_ROW) + KEY_FULL("c", "C", "\"", KEY_OFFSET(2), THIRD_ROW) + KEY_FULL("v", "V", ".", KEY_OFFSET(3), THIRD_ROW) + KEY_FULL("b", "B", ",", KEY_OFFSET(4), THIRD_ROW) + KEY_FULL("n", "N", "?", KEY_OFFSET(5), THIRD_ROW) + KEY_FULL("m", "M", "!", KEY_OFFSET(6), THIRD_ROW) + +#define KEY_SPECIAL(val, x, y, w) \ + part { \ + name: "key-img-"val; \ + type: IMAGE; \ + mouse_events: 0; \ + description { \ + state: "default" 0.0; \ + min: w KEY_HEIGHT; \ + max: w KEY_HEIGHT; \ + fixed: 1 1; \ + rel1 { \ + relative: 0.0 0.0; \ + offset: (x) (y); \ + } \ + rel2 { \ + relative: 0.0 0.0; \ + offset: (x+w-1) (y+KEY_HEIGHT-1); \ + } \ + image { \ + normal: "key-special.png"; \ + border: 8 8 10 10; \ + } \ + } \ + description { \ + state: "down" 0.0; \ + inherit: "default" 0.0; \ + rel1.offset: (x+1) (y+1); \ + rel2.offset: (x+1+w-1) (y+1+KEY_HEIGHT-1); \ + image.normal: "key-special-pressed.png"; \ + } \ + } \ + part { \ + name: "key-bg-"val; \ + type: RECT; \ + pointer_mode: NOGRAB; \ + description { \ + state: "default" 0.0; \ + rel1 { \ + to: "key-img-"val; \ + relative: 0.0 0.0; \ + offset: 3 2; \ + } \ + rel2 { \ + to: "key-img-"val; \ + relative: 1.0 1.0; \ + offset: -4 -6; \ + } \ + color: 0 0 0 0; \ + } \ + } \ + programs { \ + program { \ + name: "key-mouse-up-"val; \ + signal: "mouse,up,1"; \ + source: "key-bg-"val; \ + script { \ + emit("key_down", val); \ + _set_key_released(val); \ + emit("key_up", val); \ + } \ + } \ + program { \ + name: "key-mouse-in-"val; \ + signal: "mouse,in"; \ + source: "key-bg-"val; \ + script { \ + if (get_int(mouse_down) == 0) \ + return; \ + _set_key_pressed(val); \ + } \ + } \ + program { \ + name: "key-mouse-out-"val; \ + signal: "mouse,out"; \ + source: "key-bg-"val; \ + script { \ + if (get_int(mouse_down) == 0) \ + return; \ + _set_key_released(val); \ + emit("key_up", val); \ + } \ + } \ + program { \ + name: "key-mouse-down-"val; \ + signal: "mouse,down,1"; \ + source: "key-bg-"val; \ + script { \ + _set_key_pressed(val); \ + } \ + } \ + program { \ + name: "key-press-"val; \ + action: STATE_SET "down" 0.0; \ + target: "key-img-"val; \ + target: "key-lbl-"val; \ + } \ + program { \ + name: "key-release-"val; \ + action: STATE_SET "default" 0.0; \ + transition: LINEAR 0.2; \ + target: "key-img-"val; \ + target: "key-lbl-"val; \ + } \ + } + +#define KEY_SPECIAL_TEXT(val, x, y, w) \ + KEY_SPECIAL(val, x, y, w) \ + part { \ + name: "key-lbl-"val; \ + type: TEXT; \ + mouse_events: 0; \ + effect: SHADOW BOTTOM; \ + description { \ + state: "default" 0.0; \ + color: 63 67 72 255; \ + color2: 240 240 240 255; \ + color3: 240 240 240 255; \ + rel1 { \ + to: "key-bg-"val; \ + relative: 0.0 0.4; \ + } \ + rel2 { \ + to: "key-bg-"val; \ + relative: 1.0 1.0; \ + } \ + text { \ + font: "Semibold"; \ + size: (34*SCALE); \ + text: val; \ + } \ + } \ + } + +#define KEY_SPECIAL_ICON(val, x, y, w, icon_size) \ + KEY_SPECIAL(val, x, y, w) \ + part { \ + name: "key-lbl-"val; \ + type: IMAGE; \ + mouse_events: 0; \ + description { \ + state: "default" 0.0; \ + min: icon_size icon_size; \ + max: icon_size icon_size; \ + fixed: 1 1; \ + rel1 { \ + to: "key-bg-"val; \ + relative: 0.5 0.4; \ + } \ + rel2 { \ + to: "key-bg-"val; \ + relative: 0.5 0.8; \ + } \ + image.normal: "icon-"val".png"; \ + } \ + } \ + +#define FOURTH_ROW THIRD_ROW+KEY_HEIGHT+ROW_SPACE + KEY_SPECIAL_TEXT("?123", (5*SCALE), FOURTH_ROW, (95*SCALE)) + + part { + name: "key-img-shift"; + type: IMAGE; + mouse_events: 0; + description { + state: "default" 0.0; + min: (85*SCALE) KEY_HEIGHT; + max: (85*SCALE) KEY_HEIGHT; + fixed: 1 1; + rel1 { + relative: 0.0 0.0; + offset: (5*SCALE) (THIRD_ROW); + } + rel2 { + relative: 0.0 0.0; + offset: (((5+85)*SCALE)-1) (THIRD_ROW+KEY_HEIGHT-1); + } + image { + normal: "key-special.png"; + border: 8 8 10 10; + } + } + description { + state: "down" 0.0; + inherit: "default" 0.0; + rel1.offset: ((5*SCALE)+2) (THIRD_ROW+2); + rel2.offset: ((((5+85)*SCALE)+2)-1) (THIRD_ROW+2+KEY_HEIGHT-1); + image.normal: "key-special-pressed.png"; + } + } + part { + name: "key-bg-shift"; + type: RECT; + pointer_mode: NOGRAB; + description { + state: "default" 0.0; + rel1 { + to: "key-img-shift"; + relative: 0.0 0.0; + offset: 3 2; + } + rel2 { + to: "key-img-shift"; + relative: 1.0 1.0; + offset: -4 -6; + } + color: 0 0 0 0; + } + } + part { + name: "key-lbl-shift"; + type: IMAGE; + mouse_events: 0; + description { + state: "default" 0.0; + max: (50*SCALE) (50*SCALE); + min: (50*SCALE) (50*SCALE); + fixed: 1 1; + rel1 { + to: "key-bg-shift"; + relative: 0.5 0.4; + } + rel2 { + to: "key-bg-shift"; + relative: 0.5 0.8; + } + image.normal: "icon-shift.png"; + } + description { + state: "down" 0.0; + inherit: "default" 0.0; + image.normal: "icon-shift-active.png"; + } + } + programs { + program { + name: "key-press-shift"; + signal: "mouse,down,1"; + source: "key-bg-shift"; + action: STATE_SET "down" 0.0; + target: "key-img-shift"; + target: "key-lbl-shift"; + } + program { + name: "key-release-shift"; + action: STATE_SET "default" 0.0; + transition: LINEAR 0.2; + target: "key-img-shift"; + target: "key-lbl-shift"; + } + program { + name: "key-mouse-in-shift"; + signal: "mouse,in"; + source: "key-bg-shift"; + script { + if (get_int(mouse_down) == 0) + return; + run_program(PROGRAM:"key-press-shift"); + } + } + program { + name: "key-mouse-out-shift"; + signal: "mouse,out"; + source: "key-bg-shift"; + script { + if (get_int(mouse_down) == 0) + return; + run_program(PROGRAM:"key-release-shift"); + } + } + program { + name: "key-down-shift"; + signal: "mouse,up,1"; + source: "key-bg-shift"; + script { + emit("key_down", "shift"); + if (get_int(shift_pressed) == 0) { + run_program(PROGRAM:"key-press-shift"); + set_int(shift_pressed, 1); + } else { + run_program(PROGRAM:"key-release-shift"); + set_int(shift_pressed, 0); + } + } + } + } + } + } + + group { + name: "special-1"; + + script { + MOUSE_DOWN_UP_SCRIPTS + } + programs { + MOUSE_DOWN_UP_PROGRAMS + } + parts { +#undef INIT_HSPACE +#define INIT_HSPACE 5 + + KEY("1", "#", KEY_OFFSET(0), FIRST_ROW) + KEY("2", "&", KEY_OFFSET(1), FIRST_ROW) + KEY("3", "%", KEY_OFFSET(2), FIRST_ROW) + KEY("4", "+", KEY_OFFSET(3), FIRST_ROW) + KEY("5", "=", KEY_OFFSET(4), FIRST_ROW) + KEY("6", "_", KEY_OFFSET(5), FIRST_ROW) + KEY("7", "\\", KEY_OFFSET(6), FIRST_ROW) + KEY("8", "|", KEY_OFFSET(7), FIRST_ROW) + KEY("9", "<", KEY_OFFSET(8), FIRST_ROW) + KEY("0", ">", KEY_OFFSET(9), FIRST_ROW) + +#undef INIT_HSPACE +#define INIT_HSPACE (45*SCALE) + + SKEY("-", "dash", "{", KEY_OFFSET(0), SECOND_ROW) + SKEY("@", "at", "}", KEY_OFFSET(1), SECOND_ROW) + SKEY("*", "star", "[", KEY_OFFSET(2), SECOND_ROW) + SKEY("^", "circumflex", "]", KEY_OFFSET(3), SECOND_ROW) + SKEY(":", "colon", "$", KEY_OFFSET(4), SECOND_ROW) + SKEY(";", "semi_colon", "£", KEY_OFFSET(5), SECOND_ROW) + SKEY("(", "open_par", "¥", KEY_OFFSET(6), SECOND_ROW) + SKEY(")", "close_par", "€", KEY_OFFSET(7), SECOND_ROW) + SKEY("~", "tilde", "₩", KEY_OFFSET(8), SECOND_ROW) + +#undef INIT_HSPACE +#define INIT_HSPACE (110*SCALE) + + SKEY("/", "slash", "¢", KEY_OFFSET(0), THIRD_ROW) + SKEY("'", "single_quote", "`", KEY_OFFSET(1), THIRD_ROW) + SKEY("\"", "double_quote", "°", KEY_OFFSET(2), THIRD_ROW) + SKEY(".", "dot", "˙", KEY_OFFSET(3), THIRD_ROW) + SKEY(",", "comma", "®", KEY_OFFSET(4), THIRD_ROW) + SKEY("?", "question", "©", KEY_OFFSET(5), THIRD_ROW) + SKEY("!", "exclamation", "¿", KEY_OFFSET(6), THIRD_ROW) + + KEY_SPECIAL_TEXT("1/2", (5*SCALE), THIRD_ROW, (85*SCALE)) + KEY_SPECIAL_TEXT("abc", (5*SCALE), FOURTH_ROW, (95*SCALE)) + } + } + + group { + name: "special-2"; + + script { + MOUSE_DOWN_UP_SCRIPTS + } + programs { + MOUSE_DOWN_UP_PROGRAMS + } + parts { +#undef INIT_HSPACE +#define INIT_HSPACE 5 + + SKEY("#", "hash", "1", KEY_OFFSET(0), FIRST_ROW) + SKEY("&", "amp", "2", KEY_OFFSET(1), FIRST_ROW) + SKEY("%", "percent", "3", KEY_OFFSET(2), FIRST_ROW) + SKEY("+", "plus", "4", KEY_OFFSET(3), FIRST_ROW) + SKEY("=", "equal", "5", KEY_OFFSET(4), FIRST_ROW) + SKEY("_", "underline", "6", KEY_OFFSET(5), FIRST_ROW) + SKEY("\\", "backslash", "7", KEY_OFFSET(6), FIRST_ROW) + SKEY("|", "vert_bar", "8", KEY_OFFSET(7), FIRST_ROW) + SKEY("<", "less", "9", KEY_OFFSET(8), FIRST_ROW) + SKEY(">", "greater", "0", KEY_OFFSET(9), FIRST_ROW) + +#undef INIT_HSPACE +#define INIT_HSPACE (45*SCALE) + + SKEY("{", "open_brace", "-", KEY_OFFSET(0), SECOND_ROW) + SKEY("}", "close_brace", "@", KEY_OFFSET(1), SECOND_ROW) + SKEY("[", "open_bracket", "*", KEY_OFFSET(2), SECOND_ROW) + SKEY("]", "close_bracket", "^", KEY_OFFSET(3), SECOND_ROW) + SKEY("$", "dollar", ":", KEY_OFFSET(4), SECOND_ROW) + SKEY("£", "sterling", ";", KEY_OFFSET(5), SECOND_ROW) + SKEY("¥", "yen", "(", KEY_OFFSET(6), SECOND_ROW) + SKEY("€", "euro", ")", KEY_OFFSET(7), SECOND_ROW) + SKEY("₩", "won", "~", KEY_OFFSET(8), SECOND_ROW) + +#undef INIT_HSPACE +#define INIT_HSPACE (110*SCALE) + + SKEY("¢", "cent" , "/", KEY_OFFSET(0), THIRD_ROW) + SKEY("`", "back_quote", "'", KEY_OFFSET(1), THIRD_ROW) + SKEY("°", "ring", "\"", KEY_OFFSET(2), THIRD_ROW) + SKEY("˙", "dot", ".", KEY_OFFSET(3), THIRD_ROW) + SKEY("®", "registered", ",", KEY_OFFSET(4), THIRD_ROW) + SKEY("©", "copyright", "?", KEY_OFFSET(5), THIRD_ROW) + SKEY("¿", "inv_question", "!", KEY_OFFSET(6), THIRD_ROW) + + KEY_SPECIAL_TEXT("2/2", (5*SCALE), THIRD_ROW, (85*SCALE)) + KEY_SPECIAL_TEXT("abc", (5*SCALE), FOURTH_ROW, (95*SCALE)) + } + } + + group { + name: "fixed"; + +#define REPEAT_KEY_SCRIPTS \ + public repeat_timer; \ + public repeat_key; \ + \ + public _repeat_key(val) { \ + new _cur[20]; \ + new _timer; \ + get_str(repeat_key, _cur, 20); \ + emit("key_down", _cur); \ + _timer = get_int(repeat_timer); \ + if (_timer) { \ + cancel_timer(_timer); \ + } \ + _timer = timer(0.1, "_repeat_key", 1); \ + set_int(repeat_timer, _timer); \ + } \ + \ + public _repeat_key_pressed(_key[]) { \ + new _cur[20]; \ + get_str(repeat_key, _cur, 20); \ + if (strlen(_cur) > 0) { \ + _repeat_key_released(_cur); \ + } \ + set_str(repeat_key, _key); \ + _repeat_key(1); \ + } \ + \ + public _repeat_key_released(_key[]) { \ + new _timer; \ + set_str(repeat_key, ""); \ + _timer = get_int(repeat_timer); \ + if (_timer) { \ + cancel_timer(_timer); \ + set_int(repeat_timer, 0); \ + } \ + } + + script { + MOUSE_DOWN_UP_SCRIPTS + REPEAT_KEY_SCRIPTS + } + programs { + MOUSE_DOWN_UP_PROGRAMS + } + +#define KEY_SPECIAL_ICON_REPEAT(val, x, y, w, icon_size) \ + KEY_SPECIAL_ICON(val, x, y, w, icon_size) \ + programs { \ + program { \ + name: "long-press-"val; \ + signal: "long_press"; \ + source: val; \ + script { \ + _repeat_key_pressed(val); \ + } \ + } \ + program { \ + name: "key-up-"val; \ + signal: "key_up"; \ + source: val; \ + script { \ + _repeat_key_released(val); \ + } \ + } \ + } + + parts { + KEY_SPECIAL_ICON_REPEAT("backspace", (620*SCALE), THIRD_ROW, (85*SCALE), (60*SCALE)) + KEY_SPECIAL_ICON("enter", (610*SCALE), FOURTH_ROW, (95*SCALE), (60*SCALE)) + +#undef INIT_HSPACE +#define INIT_HSPACE (120*SCALE) + KEY_SPECIAL_ICON_REPEAT("space", KEY_OFFSET(0), FOURTH_ROW, KEY_OFFSET(5), (64*SCALE)); + } + } + + group { + name: "numeric"; + script { + MOUSE_DOWN_UP_SCRIPTS + REPEAT_KEY_SCRIPTS + } + programs { + MOUSE_DOWN_UP_PROGRAMS + } + parts { +#undef KEY_WIDTH +#define KEY_WIDTH (200*SCALE) +#undef KEY_HEIGHT +#define KEY_HEIGHT NUMERIC_KEY_HEIGHT +#undef INIT_HSPACE +#define INIT_HSPACE (45*SCALE) +#undef ROW_SPACE +#define ROW_SPACE (10*SCALE) +#undef COL_SPACE +#define COL_SPACE (10*SCALE) + KEY("1", " ", KEY_OFFSET(0), FIRST_ROW) + KEY("2", " ", KEY_OFFSET(1), FIRST_ROW) + KEY("3", " ", KEY_OFFSET(2), FIRST_ROW) + + KEY("4", " ", KEY_OFFSET(0), SECOND_ROW) + KEY("5", " ", KEY_OFFSET(1), SECOND_ROW) + KEY("6", " ", KEY_OFFSET(2), SECOND_ROW) + + KEY("7", " ", KEY_OFFSET(0), THIRD_ROW) + KEY("8", " ", KEY_OFFSET(1), THIRD_ROW) + KEY("9", " ", KEY_OFFSET(2), THIRD_ROW) + + KEY_SPECIAL_ICON_REPEAT("backspace", KEY_OFFSET(0), FOURTH_ROW, KEY_WIDTH, (50*SCALE)) + KEY("0", " ", KEY_OFFSET(1), FOURTH_ROW) + KEY_SPECIAL_ICON("enter", KEY_OFFSET(2), FOURTH_ROW, KEY_WIDTH, (60*SCALE)) + } + } +} diff --git a/src/modules/wl_weekeyboard/themes/default/default_1080.edc b/src/modules/wl_weekeyboard/themes/default/default_1080.edc new file mode 100644 index 000000000..d5f23d6ff --- /dev/null +++ b/src/modules/wl_weekeyboard/themes/default/default_1080.edc @@ -0,0 +1,26 @@ +/* + * Copyright © 2014 Jaguar Landrover + * + * 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. + */ + +#define SCALE 1.5 + +#define MIN_WIDTH 1080 +#define MAX_WIDTH 1280 +#define MIN_HEIGHT 900 +#define MAX_HEIGHT 900 + +#define NUMERIC_KEY_HEIGHT 150 + +#include "default.edc" diff --git a/src/modules/wl_weekeyboard/themes/default/default_600.edc b/src/modules/wl_weekeyboard/themes/default/default_600.edc new file mode 100644 index 000000000..b5ef5e49a --- /dev/null +++ b/src/modules/wl_weekeyboard/themes/default/default_600.edc @@ -0,0 +1,26 @@ +/* + * Copyright © 2013 Intel Corporation + * + * 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. + */ + +#define SCALE 0.83 + +#define MIN_WIDTH 600 +#define MAX_WIDTH 1024 +#define MIN_HEIGHT 480 +#define MAX_HEIGHT 480 + +#define NUMERIC_KEY_HEIGHT 80 + +#include "default.edc" diff --git a/src/modules/wl_weekeyboard/themes/default/default_720.edc b/src/modules/wl_weekeyboard/themes/default/default_720.edc new file mode 100644 index 000000000..476f40556 --- /dev/null +++ b/src/modules/wl_weekeyboard/themes/default/default_720.edc @@ -0,0 +1,26 @@ +/* + * Copyright © 2013 Intel Corporation + * + * 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. + */ + +#define SCALE 1.0 + +#define MIN_WIDTH 720 +#define MAX_WIDTH 1280 +#define MIN_HEIGHT 600 +#define MAX_HEIGHT 600 + +#define NUMERIC_KEY_HEIGHT 100 + +#include "default.edc" diff --git a/src/modules/wl_weekeyboard/themes/default/fonts/LICENSE.txt b/src/modules/wl_weekeyboard/themes/default/fonts/LICENSE.txt new file mode 100644 index 000000000..df187637e --- /dev/null +++ b/src/modules/wl_weekeyboard/themes/default/fonts/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Regular.ttf b/src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Regular.ttf new file mode 100644 index 000000000..a011dff93 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Regular.ttf differ diff --git a/src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Semibold.ttf b/src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Semibold.ttf new file mode 100644 index 000000000..dbf946a50 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/fonts/SourceSansPro-Semibold.ttf differ diff --git a/src/modules/wl_weekeyboard/themes/default/ignorekeys.txt b/src/modules/wl_weekeyboard/themes/default/ignorekeys.txt new file mode 100644 index 000000000..de27cff6f --- /dev/null +++ b/src/modules/wl_weekeyboard/themes/default/ignorekeys.txt @@ -0,0 +1,4 @@ +abc +?123 +1/2 +2/2 diff --git a/src/modules/wl_weekeyboard/themes/default/images/icon-backspace.png b/src/modules/wl_weekeyboard/themes/default/images/icon-backspace.png new file mode 100644 index 000000000..32a1c3f13 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/icon-backspace.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/icon-enter.png b/src/modules/wl_weekeyboard/themes/default/images/icon-enter.png new file mode 100644 index 000000000..66b2d4d26 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/icon-enter.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/icon-language.png b/src/modules/wl_weekeyboard/themes/default/images/icon-language.png new file mode 100644 index 000000000..d3d754b0f Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/icon-language.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/icon-shift-active.png b/src/modules/wl_weekeyboard/themes/default/images/icon-shift-active.png new file mode 100644 index 000000000..17a91c4e3 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/icon-shift-active.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/icon-shift.png b/src/modules/wl_weekeyboard/themes/default/images/icon-shift.png new file mode 100644 index 000000000..b59d6a2d5 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/icon-shift.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/icon-space.png b/src/modules/wl_weekeyboard/themes/default/images/icon-space.png new file mode 100644 index 000000000..b1b5bd3cd Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/icon-space.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/key-default-pressed.png b/src/modules/wl_weekeyboard/themes/default/images/key-default-pressed.png new file mode 100644 index 000000000..bcc0f7dee Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/key-default-pressed.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/key-default.png b/src/modules/wl_weekeyboard/themes/default/images/key-default.png new file mode 100644 index 000000000..a4f5ba24f Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/key-default.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/key-hint-bg.png b/src/modules/wl_weekeyboard/themes/default/images/key-hint-bg.png new file mode 100644 index 000000000..b72b876a1 Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/key-hint-bg.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/key-hint.png b/src/modules/wl_weekeyboard/themes/default/images/key-hint.png new file mode 100644 index 000000000..d051c98bd Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/key-hint.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/key-special-pressed.png b/src/modules/wl_weekeyboard/themes/default/images/key-special-pressed.png new file mode 100644 index 000000000..ae0a76c4b Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/key-special-pressed.png differ diff --git a/src/modules/wl_weekeyboard/themes/default/images/key-special.png b/src/modules/wl_weekeyboard/themes/default/images/key-special.png new file mode 100644 index 000000000..1cf53fe6b Binary files /dev/null and b/src/modules/wl_weekeyboard/themes/default/images/key-special.png differ diff --git a/src/modules/wl_weekeyboard/wkb-log.c b/src/modules/wl_weekeyboard/wkb-log.c new file mode 100644 index 000000000..543bb530d --- /dev/null +++ b/src/modules/wl_weekeyboard/wkb-log.c @@ -0,0 +1,55 @@ +/* + * Copyright © 2013 Intel Corporation + * + * 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. + */ + +#include "wkb-log.h" + +int _wkb_log_domain = -1; +static int _init_count = 0; + +int +wkb_log_init(const char *domain) +{ + if (_init_count) + goto end; + + if (!eina_init()) + { + fprintf(stderr, "%s:%d - %s() Error initializing Eina\n", __FILE__, __LINE__, __FUNCTION__); + return 0; + } + + _wkb_log_domain = eina_log_domain_register(domain, EINA_COLOR_LIGHTCYAN); + + if (_wkb_log_domain < 0) + { + EINA_LOG_ERR("Unable to register '%s' log domain", domain); + eina_shutdown(); + return 0; + } + +end: + return ++_init_count; +} + +void +wkb_log_shutdown(void) +{ + if (_init_count <= 0 || --_init_count > 0) + return; + + eina_log_domain_unregister(_wkb_log_domain); + eina_shutdown(); +} diff --git a/src/modules/wl_weekeyboard/wkb-log.h b/src/modules/wl_weekeyboard/wkb-log.h new file mode 100644 index 000000000..810b36599 --- /dev/null +++ b/src/modules/wl_weekeyboard/wkb-log.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2013 Intel Corporation + * + * 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. + */ + +#ifndef _WKB_LOG_H_ +#define _WKB_LOG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DBG +#undef DBG +#endif +#ifdef INF +#undef INF +#endif +#ifdef WRN +#undef WRN +#endif +#ifdef ERR +#undef ERR +#endif +#ifdef CRITICAL +#undef CRITICAL +#endif + +extern int _wkb_log_domain; +#define DBG(...) EINA_LOG_DOM_DBG(_wkb_log_domain, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_wkb_log_domain, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_wkb_log_domain, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_wkb_log_domain, __VA_ARGS__) +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_wkb_log_domain, __VA_ARGS__) + +int wkb_log_init(const char *domain); +void wkb_log_shutdown(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _WKB_LOG_H_ */