Add en/decoding routine when processing input device events 67/174067/7
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 28 Mar 2018 02:10:37 +0000 (11:10 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Wed, 28 Mar 2018 23:31:13 +0000 (23:31 +0000)
Change-Id: Ie6821736f83a004cc09a7b15e63e8fa9951080ba

ism/extras/wayland_immodule/wayland_imcontext.c
ism/src/isf_device_event.h
ism/src/scim_helper.cpp

index bc699fb..43155ac 100644 (file)
@@ -889,8 +889,14 @@ rotary_event_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(active_ctx);
     if (imcontext && imcontext->input && imcontext->text_input) {
         isf_device_type_e type = find_device_type_from_ecore_event(ECORE_EVENT_DETENT_ROTATE);
-        wl_text_input_process_input_device_event(imcontext->text_input,
-            (unsigned int)type, (char*)event, sizeof(Ecore_Event_Detent_Rotate));
+        char *buffer = NULL;
+        size_t buflen = 0;
+        if (device_buffer_encode((const char*)(event), sizeof(Ecore_Event_Detent_Rotate), &buffer, &buflen) &&
+            buffer && buflen > 0) {
+            wl_text_input_process_input_device_event(imcontext->text_input,
+                (unsigned int)type, buffer, buflen);
+            free(buffer);
+        }
     }
 
     return EINA_FALSE;
index c92f530..0ecf22d 100644 (file)
@@ -45,6 +45,16 @@ typedef struct {
     isf_device_type_e device_type;
 } isf_device_type_conv_table;
 
+/* For encoding, all the NULL(0x00) bytes will be replaced with 2-byte expression
+ * {ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX, ISF_DEVICE_BUFFER_ENCODE_NULL_POSTFIX}
+ * and ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX bytes will be replace with
+ * {ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX, ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX}.
+ * Any other bytes will be copied maintaining their original values */
+const char ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX = 0xff;
+const char ISF_DEVICE_BUFFER_ENCODE_NULL_POSTFIX = 0x01;
+
+const int ISF_DEVICE_BUFFER_ENCODE_MAX_BUFFER = (4096 / 2);
+
 static isf_device_type_conv_table g_conv_table[ISF_DEVICE_TYPE_MAX] = {
     { -1, ISF_DEVICE_TYPE_CONVENTIONAL },
     { -1, ISF_DEVICE_TYPE_UNKNOWN },
@@ -86,6 +96,86 @@ static inline int find_ecore_event_from_device_type(isf_device_type_e device_typ
     return ecore_event;
 }
 
+inline int device_buffer_encode(const char *inbuf, size_t inlen, char **outbuf, size_t *outlen)
+{
+    unsigned int loop;
+    unsigned int index;
+    if (!inbuf || !outbuf || !outlen) return 0;
+
+    (*outlen) = inlen;
+    for (loop = 0; loop < inlen; loop++) {
+        if (inbuf[loop] == 0x00 || inbuf[loop] == ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX) (*outlen)++;
+    }
+
+    if ((*outlen) > ISF_DEVICE_BUFFER_ENCODE_MAX_BUFFER) return 0;
+
+    if (!(*outbuf = (char*)malloc(sizeof(char) * (*outlen) + 1))) return 0;
+    (*outbuf)[(*outlen)] = '\0'; // Make sure to be null-terminated
+
+    index = 0;
+    for (loop = 0; loop < inlen && index < (*outlen); loop++) {
+        if (inbuf[loop] == 0x00 || inbuf[loop] == ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX) {
+            // Should have enough buffer left
+            if (index >= (*outlen) - 1) {
+                free(*outbuf);
+                (*outbuf) = NULL;
+                return 0;
+            }
+            if (inbuf[loop] == 0x00) {
+                (*outbuf)[index++] = ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX;
+                (*outbuf)[index++] = ISF_DEVICE_BUFFER_ENCODE_NULL_POSTFIX;
+            }
+            else if (inbuf[loop] == ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX) {
+                (*outbuf)[index++] = ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX;
+                (*outbuf)[index++] = ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX;
+            }
+        }
+        else {
+            (*outbuf)[index++] = inbuf[loop];
+        }
+    }
+
+    return 1;
+}
+
+inline int device_buffer_decode(const char *inbuf, size_t inlen, char *outbuf, size_t *outlen)
+{
+    unsigned int loop;
+    unsigned int index;
+    if (!inbuf || !outbuf || !outlen) return 0;
+    if (inlen > ISF_DEVICE_BUFFER_ENCODE_MAX_BUFFER) return 0;
+
+    index = 0;
+    for (loop = 0; loop < inlen; loop++) {
+        if (index >= *outlen) return 0;
+        if (inbuf[loop] == ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX) {
+            // Should have enough buffer left
+            if (loop >= inlen - 1) return 0;
+            if (inbuf[loop + 1] == ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX) {
+                outbuf[index++] = ISF_DEVICE_BUFFER_ENCODE_NULL_PREFIX;
+            }
+            else if (inbuf[loop + 1] == ISF_DEVICE_BUFFER_ENCODE_NULL_POSTFIX) {
+                outbuf[index++] = 0x00;
+            }
+            else {
+                // Invalid format
+                return 0;
+            }
+            loop++;
+        }
+        else if (inbuf[loop]) {
+            outbuf[index++] = inbuf[loop];
+        } else {
+            *outlen = index;
+            return 1;
+        }
+    }
+
+    *outlen = index;
+    return 1;
+}
+
+
 #endif  /* __ISF_DEVICE_EVENT_H */
 
 /*
index 4cdada2..5b6c876 100644 (file)
@@ -1415,8 +1415,15 @@ HelperAgent::handle_message (MessageItem *message)
             MessageItemProcessInputDeviceEvent *subclass = static_cast<MessageItemProcessInputDeviceEvent*>(message);
             uint32 ret = 0;
             unsigned int ecore_event_id = find_ecore_event_from_device_type((isf_device_type_e)(subclass->get_type_ref()));
-            m_impl->signal_process_input_device_event(this,
-                ecore_event_id, *(subclass->get_data_ptr()), subclass->get_len_ref(), ret);
+            char *decoded = (char*)malloc(subclass->get_len_ref());
+            size_t decoded_size = subclass->get_len_ref();
+            if (decoded) {
+                if(device_buffer_decode((const char*)*(subclass->get_data_ptr()),
+                    subclass->get_len_ref(), (char*)(decoded), &decoded_size)) {
+                    m_impl->signal_process_input_device_event(this, ecore_event_id, decoded, decoded_size, ret);
+                }
+                free(decoded);
+            }
             break;
         }
         case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE: