Add ime_event_set_process_key_event_cb() function. 31/40931/1
authorSungmin Kwak <sungmin.kwak@samsung.com>
Thu, 5 Mar 2015 08:42:32 +0000 (17:42 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Wed, 10 Jun 2015 09:12:39 +0000 (18:12 +0900)
Change-Id: I9dcb30d1c5ced19cc2ee98f52f9fdd0cbcce6a83

include/inputmethod.h
include/inputmethod_keydef.h
src/inputmethod.cpp

index 6fa8f0a..7477052 100644 (file)
@@ -264,7 +264,7 @@ typedef void (*ime_language_requested_cb)(void *user_data, char **lang_code);
  *
  * @since_tizen 2.4
  *
- * @param[in] language The preferred language that the client wants
+ * @param[in] language The preferred language that the client application wants
  * @param[in] user_data User data to be passed from the callback registration function
  *
  * @pre The callback can be registered using ime_event_set_language_set_cb().
@@ -368,6 +368,21 @@ typedef void (*ime_return_key_state_set_cb)(bool disabled, void *user_data);
 typedef void (*ime_geometry_requested_cb)(void *user_data, int *x, int *y, int *w, int *h);
 
 /**
+ * @brief Called when the key event is received from the external keyboard devices or ime_send_key_event() function.
+ *
+ * @details This function processes the key event before an associated text input UI control deos.
+ *
+ * @param[in] keycode The key code to be sent
+ * @param[in] keymask The modifier key mask
+ * @param[in] user_data User data to be passed from the callback registration function
+ *
+ * @return @c true if the event is processed, otherwise the event is not processed and is forwarded to the client application.
+ *
+ * @see ime_event_set_process_key_event_cb, ime_send_key_event, ime_commit_string, ime_show_preedit_string, ime_hide_preedit_string, ime_update_preedit_string
+ */
+typedef bool (*ime_process_key_event_cb)(ime_key_code_e keycode, ime_key_mask_e keymask, void *user_data);
+
+/**
  * @brief Called when the system display language is changed.
  *
  * @since_tizen 2.4
@@ -824,6 +839,72 @@ EXPORT_API int ime_event_set_return_key_state_set_cb(ime_return_key_state_set_cb
 EXPORT_API int ime_event_set_geometry_requested_cb(ime_geometry_requested_cb callback_func, void *user_data);
 
 /**
+ * @brief Sets @c process_key_event event callback function.
+ *
+ * @remarks The ime_process_key_event_cb() callback function is called when the key event
+ * is received from the external keyboard devices or ime_send_key_event() function.
+ *
+ * @since_tizen 2.4
+ *
+ * @param[in] callback_func @c process_key_event event callback function
+ * @param[in] user_data User data to be passed to the callback function
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #IME_ERROR_NONE No error
+ * @retval #IME_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #IME_ERROR_OPERATION_FAILED Operation failed
+ *
+ * @post The ime_run() function should be called to start to run IME application's main loop.
+ *
+ * @see ime_process_key_event_cb, ime_run
+ *
+ * @code
+ static void inputmethod_create_cb(void *user_data);
+ static void inputmethod_terminate_cb(void *user_data);
+ static void inputmethod_show_cb(int context_id, ime_context_h context, void *user_data);
+ static void inputmethod_hide_cb(int context_id, void *user_data);
+
+ static bool inputmethod_process_key_event_cb(ime_key_code_e keycode, ime_key_mask_e keymask, void *user_data);
+ {
+     if (keymask & IME_KEY_MASK_CONTROL) {
+         return false; // e.g., Cotrol+C key event would be forwarded to UI control of the client application
+     }
+     if (keymask & IME_KEY_MASK_ALT) {
+         return false;
+     }
+
+     if (!(keymask & IME_KEY_MASK_RELEASED)) { // The key is pressed
+         if (keycode == IME_KEY_1) {
+             ime_update_preedit_string("1"); // Show "1" preedit string
+             return true;
+         }
+         else if (keycode == IME_KEY_2) {
+             ime_commit_string("12"); // Input "12" string
+             return true;
+         }
+     }
+
+     return false;
+ }
+
+ void ime_app_main(int argc, char **argv)
+ {
+     ime_callback_s basic_callback = {
+         inputmethod_create_cb,
+         inputmethod_terminate_cb,
+         inputmethod_show_cb,
+         inputmethod_hide_cb,
+     };
+
+     ime_event_set_process_key_event_cb(inputmethod_process_key_event_cb, NULL);
+
+     ime_run(&basic_callback, NULL);
+ }
+ * @endcode
+ */
+EXPORT_API int ime_event_set_process_key_event_cb(ime_process_key_event_cb callback_func, void *user_data);
+
+/**
  * @brief Sets @c display_language_changed event callback function.
  *
  * @remarks The ime_display_language_changed_cb() callback function is called when the system
@@ -932,20 +1013,27 @@ EXPORT_API int ime_event_set_option_window_created_cb(ime_option_window_created_
 EXPORT_API int ime_event_set_option_window_destroyed_cb(ime_option_window_destroyed_cb callback_func, void *user_data);
 
 /**
- * @brief Sends a key event directly to the associated text input UI control.
+ * @brief Sends a key event to the associated text input UI control.
+ *
+ * @details This function sends key down or up event with key mask to the client application.
+ * If @a forward_key is @c true, this key event goes to the edit filed directly. And if @a forward_key
+ * is @c false, the ime_process_key_event_cb() callback function receives the key event before the edit field.
  *
  * @since_tizen 2.4
  *
  * @param[in] keycode The key code to be sent
  * @param[in] keymask The modifier key mask
+ * @param[in] forward_key The flag to send the key event directly to the edit field
  *
  * @return 0 on success, otherwise a negative error value
  * @retval #IME_ERROR_NONE No error
  * @retval #IME_ERROR_NOT_RUNNING IME main loop isn't started yet
  *
- * @see ime_key_code_e, ime_key_mask_e
+ * @post If @a forward_key is @c false, the ime_process_key_event_cb() callback function can compose the text with the key events.
+ *
+ * @see ime_key_code_e, ime_key_mask_e, ime_process_key_event_cb
  */
-EXPORT_API int ime_send_key_event(ime_key_code_e keycode, ime_key_mask_e keymask);
+EXPORT_API int ime_send_key_event(ime_key_code_e keycode, ime_key_mask_e keymask, bool forward_key);
 
 /**
  * @brief Sends the text to the associated text input UI control.
@@ -1391,4 +1479,3 @@ EXPORT_API int ime_context_get_language(ime_context_h context, Ecore_IMF_Input_P
 
 #endif // __TIZEN_UIX_INPUTMETHOD_H__
 
-\0
index 800dbe9..cd32bb1 100644 (file)
@@ -30,6 +30,9 @@
 /**
  * @brief Enumeration of the key codes.
  *
+ * If keycode & 0xff000000 == 0x01000000 then this key code is directly encoded 24-bit UCS character.
+ * The UCS value is keycode & 0x00ffffff.
+ *
  * @details Defines the list of keys supported by the system.
  * Note that certain keys may not be available on all devices.
  *
@@ -203,7 +206,7 @@ typedef enum
     IME_KEY_equal                              = 0x03d,    /**< The equal key */
     IME_KEY_greater                            = 0x03e,    /**< The greater key */
     IME_KEY_question                           = 0x03f,    /**< The question key */
-    IME_KEY_at                                 = 0x040,    /**< The  key */
+    IME_KEY_at                                 = 0x040,    /**< The at key */
     IME_KEY_A                                  = 0x041,    /**< The A key */
     IME_KEY_B                                  = 0x042,    /**< The B key */
     IME_KEY_C                                  = 0x043,    /**< The C key */
@@ -271,16 +274,23 @@ typedef enum
 /**
  * @brief Enumeration of the key masks.
  *
+ * The key masks indicate which modifier keys is pressed down during the keyboard hit.
+ * The special IME_KEY_MASK_RELEASED indicates the key release event.
+ *
  * @since_tizen 2.4
  */
 typedef enum
 {
-    IME_KEY_MASK_PRESSED = 0,       /**< The key is pressed */
-    IME_KEY_MASK_SHIFT = (1<<0),    /**< The Shift key is pressed */
-    IME_KEY_MASK_CONTROL = (1<<2),  /**< The Control key is pressed */
-    IME_KEY_MASK_ALT = (1<<3),      /**< The Alt key is pressed */
-    IME_KEY_MASK_WIN = (1<<5),      /**< The Win (between Control and Alt) is pressed */
-    IME_KEY_MASK_RELEASED = (1<<15) /**< The key is released */
+    IME_KEY_MASK_PRESSED = 0,       /**< Key press event without modifier key */
+    IME_KEY_MASK_SHIFT = (1<<0),    /**< The Shift key is pressed down */
+    IME_KEY_MASK_CAPSLOCK = (1<<1), /**< The CapsLock key is pressed down */
+    IME_KEY_MASK_CONTROL = (1<<2),  /**< The Control key is pressed down */
+    IME_KEY_MASK_ALT = (1<<3),      /**< The Alt key is pressed down */
+    IME_KEY_MASK_META = (1<<4),     /**< The Meta key is pressed down */
+    IME_KEY_MASK_WIN = (1<<5),      /**< The Win (between Control and Alt) is pressed down */
+    IME_KEY_MASK_HYPER = (1<<6),    /**< The Hyper key is pressed down */
+    IME_KEY_MASK_NUMLOCK = (1<<7),  /**< The NumLock key is pressed down */
+    IME_KEY_MASK_RELEASED = (1<<15) /**< Key release event */
 } ime_key_mask_e;
 
 /**
index 4d5cb99..9f0b377 100644 (file)
@@ -48,6 +48,7 @@ class CCoreEventCallback : public ISCLCoreEventCallback
     void on_set_return_key_disable(bool disabled);
     void on_set_layout(Ecore_IMF_Input_Panel_Layout layout);
     void on_reset_input_context(sclint ic, const sclchar *uuid);
+    void on_process_key_event(scim::KeyEvent &key, sclu32 *ret);
     void on_set_display_language(const sclchar *language);
     void on_set_rotation_degree(sclint degree);
     void on_set_accessibility_state(sclboolean state);
@@ -67,8 +68,9 @@ typedef struct
     ime_imdata_set_cb imdata_set;       /**< Called to set the application specific data to deliver to the input panel */
     ime_layout_set_cb layout_set;       /**< Called when an edit field requests the input panel to set its layout */
     ime_return_key_type_set_cb return_key_type_set;     /**< Called when an edit field requests the input panel to set the "return" key label */
-    ime_return_key_state_set_cb return_key_state_set;   /**< Called when an edit field requests the input panel to enable or disable the "return" key state. */
+    ime_return_key_state_set_cb return_key_state_set;   /**< Called when an edit field requests the input panel to enable or disable the "return" key state */
     ime_geometry_requested_cb geometry_requested;       /**< Called when an edit field requests for the position and size of the input panel */
+    ime_process_key_event_cb process_key_event;         /**< Called when the key event is received from the external keyboard devices */
     ime_display_language_changed_cb display_language_changed;   /**< Called when the system display language is changed */
     ime_rotation_degree_changed_cb rotation_degree_changed;     /**< Called when the device is rotated */
     ime_accessibility_state_changed_cb accessibility_state_changed; /**< Called when Accessibility in Settings application is on or off */
@@ -86,6 +88,7 @@ typedef struct
     void *return_key_type_set_user_data;
     void *return_key_state_set_user_data;
     void *geometry_requested_user_data;
+    void *process_key_event_user_data;
     void *display_language_changed_user_data;
     void *rotation_degree_changed_user_data;
     void *accessibility_state_changed_user_data;
@@ -258,6 +261,26 @@ void CCoreEventCallback::on_reset_input_context(sclint ic, const sclchar *uuid)
     }
 }
 
+void CCoreEventCallback::on_process_key_event(scim::KeyEvent &key, sclu32 *ret)
+{
+    if (g_event_callback.process_key_event) {
+        bool processed = g_event_callback.process_key_event(static_cast<ime_key_code_e>(key.code), static_cast<ime_key_mask_e>(key.mask),
+            g_event_callback.process_key_event_user_data);
+
+        if (ret) {
+            if (processed)
+                *ret = 1;
+            else
+                *ret = 0;
+        }
+    }
+    else {
+        if (ret) {
+            *ret = 0;
+        }
+    }
+}
+
 void CCoreEventCallback::on_set_display_language(const sclchar *language)
 {
     if (g_event_callback.display_language_changed) {
@@ -496,6 +519,20 @@ int ime_event_set_geometry_requested_cb(ime_geometry_requested_cb callback_func,
     return IME_ERROR_NONE;
 }
 
+int ime_event_set_process_key_event_cb(ime_process_key_event_cb callback_func, void *user_data)
+{
+    if (!callback_func)
+        return IME_ERROR_INVALID_PARAMETER;
+
+    if (g_running)
+        return IME_ERROR_OPERATION_FAILED;
+
+    g_event_callback.process_key_event = callback_func;
+    g_event_callback.process_key_event_user_data = user_data;
+
+    return IME_ERROR_NONE;
+}
+
 int ime_event_set_display_language_changed_cb(ime_display_language_changed_cb callback_func, void *user_data)
 {
     if (!callback_func)
@@ -566,12 +603,15 @@ int ime_event_set_option_window_destroyed_cb(ime_option_window_destroyed_cb call
     return IME_ERROR_NONE;
 }
 
-int ime_send_key_event(ime_key_code_e keycode, ime_key_mask_e keymask)
+int ime_send_key_event(ime_key_code_e keycode, ime_key_mask_e keymask, bool forward_key)
 {
     if (!g_running)
         return IME_ERROR_NOT_RUNNING;
 
-    g_core.forward_key_event(-1, NULL, (sclu32)keycode, (sclu16)keymask);
+    if (forward_key)
+        g_core.forward_key_event(-1, NULL, (sclu32)keycode, (sclu16)keymask);
+    else
+        g_core.send_key_event(-1, NULL, (sclu32)keycode, (sclu16)keymask);
 
     return IME_ERROR_NONE;
 }