+++ /dev/null
-/*\r
- * @file e_mod_keyrouter_combination.c\r
- * @brief Implementation of e_mod_keyrouter_combination.c\r
- * @author Shubham Shrivastav shubham.sh@samsung.com\r
- * @date 25th Feb 2016\r
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#define E_COMP_WL\r
-#include "e_mod_main_wl.h"\r
-#include <dbus/dbus-glib.h>\r
-#include <dbus/dbus.h>\r
-#include "ini.h"\r
-\r
-#define MAX_LEN 64\r
-#define DBUS_PATH "/com/burtonini/dbus/ping"\r
-#define DBUS_IFACE "keyrouter.dbus.Signal"\r
-#define DBUS_MSG_NAME "KEY_COMBINATION"\r
-#define COMBINATION_TIME_OUT 4000\r
-#define MAX_SUPPORTED_COMBINATION 255\r
-#define DBUS_CONN_RETRY_TIMEOUT 0.2\r
-#define DBUS_CONN_MAX_RETRY_COUNT 20\r
-#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0\r
-\r
-typedef unsigned long Time;\r
-typedef struct _DbusConf\r
-{\r
- char path[MAX_LEN];\r
- char interface[MAX_LEN];\r
- char msg[MAX_LEN];\r
-} DbusConf;\r
-typedef struct _KeyCombination\r
-{\r
- DBusConnection * keyrouter_dbus_conn;\r
- DbusConf dbusconf;\r
- DBusError DBus_error;\r
- char combinationFilePath[MAX_LEN];\r
- GArray* _master_combinations;\r
- GArray* _current_matched_combinations;\r
- Time combination_timeout;\r
-} KeyCombination;\r
-\r
-static int keyCombinationInitialize = 0;\r
-static int dbus_connection_init_retry_count = 0;\r
-static Ecore_Timer *dbus_conn_timer = NULL;\r
-KeyCombination g_key_combination;\r
-\r
-static Eina_Bool _e_keyrouter_dbus_connection_init();\r
-static int _e_keyrouter_search_key_combination(int keycode, Time timestamp);\r
-static int _e_keyrouter_send_dbus_message(DBusConnection *bus, int Input);\r
-static char * _e_keyrouter_substring(char *string, int position);\r
-static int _e_keyrouter_parse_ini_config(void* user, const char* section, const char* name, const char* value);\r
-\r
-static Eina_Bool\r
-_e_keyrouter_dbus_connection_init()\r
-{\r
- DBusError dBus_error;\r
-\r
- KLINF("_e_keyrouter_dbus_connection_init()");\r
-\r
- dbus_error_init(&dBus_error);\r
- g_key_combination.keyrouter_dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dBus_error);\r
- if (!g_key_combination.keyrouter_dbus_conn)\r
- {\r
- KLWRN("[DBUS-CONNECTION-FAIL] DBUS connection is failed");\r
- if (dbus_error_is_set(&dBus_error))\r
- {\r
- KLWRN("[DBUS-ERROR] %s",dBus_error.message);\r
- dbus_error_free(&dBus_error);\r
- }\r
- return EINA_FALSE;\r
- }\r
- return EINA_TRUE;\r
-}\r
-\r
-static Eina_Bool\r
-dbus_connection_init_retry_timercb()\r
-{\r
- if (_e_keyrouter_dbus_connection_init())\r
- {\r
- keyCombinationInitialize = 1;\r
- dbus_conn_timer = NULL;\r
- return ECORE_CALLBACK_CANCEL;\r
- }\r
- else\r
- {\r
- if (dbus_connection_init_retry_count < DBUS_CONN_MAX_RETRY_COUNT)\r
- {\r
- dbus_connection_init_retry_count++;\r
- KLWRN("Failed to init dbus conn trying again, try count %d",dbus_connection_init_retry_count);\r
- return ECORE_CALLBACK_RENEW;\r
- }\r
- else\r
- {\r
- KLERR("Failed to init dbus connection for key combination after multiple tries");\r
- dbus_conn_timer = NULL;\r
- return ECORE_CALLBACK_CANCEL;\r
- }\r
- }\r
-}\r
-\r
-void\r
-e_keyrouter_key_combination_init()\r
-{\r
- memset(&g_key_combination, 0, sizeof(g_key_combination));\r
- g_key_combination.keyrouter_dbus_conn = NULL;\r
- dbus_conn_timer = NULL;\r
- snprintf(g_key_combination.dbusconf.path, strlen(DBUS_PATH)+1, DBUS_PATH);\r
- snprintf(g_key_combination.dbusconf.interface, strlen(DBUS_IFACE)+1, DBUS_IFACE);\r
- snprintf(g_key_combination.dbusconf.msg, strlen(DBUS_MSG_NAME)+1, DBUS_MSG_NAME);\r
- snprintf(g_key_combination.combinationFilePath, strlen(COMBINATION_FILE_PATH)+1, COMBINATION_FILE_PATH);\r
-\r
- g_key_combination._master_combinations = g_array_new(FALSE, FALSE, sizeof(GArray*));\r
- if (ini_parse((const char *) g_key_combination.combinationFilePath, _e_keyrouter_parse_ini_config, g_key_combination._master_combinations) < 0)\r
- {\r
- KLWRN("Can't load %s file", g_key_combination.combinationFilePath);\r
- }\r
-\r
- g_key_combination.combination_timeout = COMBINATION_TIME_OUT;\r
- if (_e_keyrouter_dbus_connection_init())\r
- {\r
- keyCombinationInitialize = 1;\r
- }\r
- else\r
- {\r
- dbus_conn_timer = ecore_timer_add(DBUS_CONN_RETRY_TIMEOUT, dbus_connection_init_retry_timercb, NULL);\r
- if (dbus_conn_timer != NULL)\r
- {\r
- KLWRN("Ecore Timer added for dbus init retry ");\r
- }\r
- else\r
- {\r
- KLERR("dbus connection init failed and unable to add ecore timer callback for init retry");\r
- }\r
- }\r
-}\r
-\r
-static char *\r
-_e_keyrouter_substring(char *string, int position)\r
-{\r
- char *pointer;\r
- int c;\r
-\r
- if (!string) return NULL;\r
-\r
- for (c = 0; c < position - 1; c++)\r
- string++;\r
-\r
- pointer = malloc(strlen(string) + 1);\r
- if (pointer == NULL)\r
- {\r
- KLWRN("Unable to allocate memory.");\r
- return NULL;\r
- }\r
-\r
- for (c = 0; *string != '\0'; c++)\r
- {\r
- *(pointer + c) = *string;\r
- string++;\r
- }\r
- *(pointer + c) = '\0';\r
-\r
- return pointer;\r
-}\r
-\r
-static int\r
-_e_keyrouter_parse_ini_config(void* user, const char* section, const char* name, const char* value)\r
-{\r
- int section_number, val;\r
- size_t needed;\r
- char *local_section, *c_num, *dup = NULL;\r
- GArray *masterArray, *childArray;\r
-\r
- if (!section) return -1;\r
-\r
- dup = strdup(section);\r
- c_num = _e_keyrouter_substring(dup, 12/*"Combination"*/);\r
- if (c_num == NULL)\r
- {\r
- KLWRN(" Unable to read config. substring is null.");\r
- return -1;\r
- }\r
-\r
- section_number = atoi(c_num);\r
- free(c_num);\r
- free(dup);\r
- if (section_number <= 0 || section_number > MAX_SUPPORTED_COMBINATION)\r
- {\r
- KLWRN("^[[36m Unable to read config. section_number is invalid. ^[[0m");\r
- return -1;\r
- }\r
- section_number--;\r
-\r
- masterArray = (GArray*) user;\r
- if (masterArray->len <= (unsigned int) section_number)\r
- {\r
- childArray = g_array_new(FALSE, FALSE, sizeof(int));\r
- g_array_insert_val(masterArray, section_number, childArray);\r
- }\r
-\r
- needed = snprintf(NULL, 0, "%s%d", "Combination", section_number + 1);\r
- local_section = malloc(needed + 1);\r
- if (local_section == NULL)\r
- {\r
- KLWRN("^[[36m Failed to allocate memory for local_section ^[[0m");\r
- return -1;\r
- }\r
- snprintf(local_section, needed + 1, "%s%d", "Combination", section_number + 1);\r
-\r
- if (MATCH(local_section, "1"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 0, val);\r
- }\r
- else if (MATCH(local_section, "2"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 1, val);\r
- }\r
- else if (MATCH(local_section, "3"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 2, val);\r
- }\r
- else if (MATCH(local_section, "4"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 3, val);\r
- }\r
- else if (MATCH(local_section, "5"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 4, val);\r
- }\r
- else if (MATCH(local_section, "6"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 5, val);\r
- }\r
- else if (MATCH(local_section, "7"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 6, val);\r
- }\r
- else if (MATCH(local_section, "8"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 7, val);\r
- }\r
- else if (MATCH(local_section, "9"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 8, val);\r
- }\r
- else if (MATCH(local_section, "10"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 9, val);\r
- }\r
- else if (MATCH(local_section, "11"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 10, val);\r
- }\r
- else if (MATCH(local_section, "12"))\r
- {\r
- val = atoi(value);\r
- childArray = g_array_index(masterArray,GArray*,section_number);\r
- g_array_insert_val(childArray, 11, val);\r
- }\r
- else\r
- {\r
- free(local_section);\r
- return 0; /* unknown section/name, error */\r
- }\r
- free(local_section);\r
- return 1;\r
-}\r
-\r
-void\r
-e_keyrouter_process_key_combination(Time cur_time, int keycode, int state)\r
-{\r
- int ret;\r
-\r
- if (!keyCombinationInitialize)\r
- {\r
- KLWRN("KeyCombinatioin support is not initiazlied yet");\r
- return ;\r
- }\r
- if (g_key_combination._master_combinations == NULL)\r
- {\r
- KLDBG(" Not searching key combination as Master combination is NULL");\r
- }\r
- if (state == ECORE_EVENT_KEY_UP)\r
- {\r
- ret = _e_keyrouter_search_key_combination(keycode, cur_time);\r
-\r
- if(ret > 0)\r
- {\r
- _e_keyrouter_send_dbus_message(g_key_combination.keyrouter_dbus_conn, ret);\r
- }\r
- }\r
-}\r
-\r
-static int\r
-_e_keyrouter_send_dbus_message(DBusConnection *bus, int Input)\r
-{\r
- DBusMessage *message = NULL;\r
-\r
- message = dbus_message_new_signal(g_key_combination.dbusconf.path, g_key_combination.dbusconf.interface, g_key_combination.dbusconf.msg);\r
- dbus_message_append_args(message, DBUS_TYPE_INT32, &Input, DBUS_TYPE_INVALID);\r
-\r
- if (!dbus_connection_send(bus, message, NULL))\r
- KLWRN( "DBUS sending MSG FAILED!!");\r
-\r
- dbus_message_unref(message);\r
- return 1;\r
-}\r
-\r
-static int\r
-_e_keyrouter_search_key_combination(int keycode, Time timestamp)\r
-{\r
- static Time t = 0;\r
- unsigned int i, j = 0;\r
- int matchedIdx = 0, foundAt = 0;\r
- static int keyIdx = 0;\r
- static GArray *_source_Search_Array = NULL;\r
- GArray *childArray, *matched;\r
-\r
- if (timestamp - t >= g_key_combination.combination_timeout && keyIdx != 0)\r
- {\r
- t = timestamp;\r
- keyIdx = 0;\r
- g_array_free(_source_Search_Array, FALSE);\r
-\r
- {\r
- g_key_combination._current_matched_combinations = g_array_new(FALSE, FALSE, sizeof(GArray*));\r
- _source_Search_Array = g_key_combination._master_combinations;/*now update _current_matched_combinations assuming last key that invalidated as first key*/\r
- matchedIdx = 0;\r
- for (i = 0; i < _source_Search_Array->len; i++)\r
- {\r
- GArray * childArray = g_array_index(_source_Search_Array,GArray*,i);\r
- if (keycode == g_array_index(childArray,int,0))\r
- {\r
- g_array_insert_val(g_key_combination._current_matched_combinations, matchedIdx, childArray);\r
- matchedIdx++;\r
- }\r
- }\r
-\r
- if (g_key_combination._current_matched_combinations->len > 0)\r
- {\r
- keyIdx = 1;/*assumed that first key is the last key that invalidated the combinaton.*/\r
- _source_Search_Array = g_key_combination._current_matched_combinations;/*start next key combination matching from this assumed _current_matched_combinations*/\r
- t = timestamp;\r
- }\r
- else /* the key that invalidated is unavailable in any master_combinations as first element*/\r
- {\r
- keyIdx = 0;\r
- t = timestamp;\r
- g_array_free(g_key_combination._current_matched_combinations, FALSE);\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
- g_key_combination._current_matched_combinations = g_array_new(FALSE, FALSE, sizeof(GArray*));\r
- if (keyIdx == 0) _source_Search_Array = g_key_combination._master_combinations;\r
-\r
- for (i = 0; i < _source_Search_Array->len; i++)\r
- {\r
- childArray = g_array_index(_source_Search_Array,GArray*,i);\r
- if (keycode == g_array_index(childArray,int,keyIdx))\r
- {\r
- g_array_insert_val(g_key_combination._current_matched_combinations, matchedIdx, childArray);\r
- matchedIdx++;\r
- }\r
- }\r
-\r
- if (keyIdx > 0)/* this needs to be freed for count > 0 as for keyIdx== 0 it will point to master_combinations!*/\r
- {\r
- g_array_free(_source_Search_Array, FALSE);/* this actually frees "last" current_matched_combinations*/\r
- }\r
- if (g_key_combination._current_matched_combinations->len < 1)/* the incoming key has invalidated the combination sequence*/\r
- {\r
- _source_Search_Array = g_key_combination._master_combinations;/*now update _current_matched_combinations assuming last key that invalidated as first key*/\r
- matchedIdx = 0;\r
-\r
- for (i = 0; i < _source_Search_Array->len; i++)\r
- {\r
- childArray = g_array_index(_source_Search_Array,GArray*,i);\r
- if (keycode == g_array_index(childArray,int,0))\r
- {\r
- g_array_insert_val(g_key_combination._current_matched_combinations, matchedIdx, childArray);\r
- matchedIdx++;\r
- }\r
- }\r
-\r
- if (g_key_combination._current_matched_combinations->len > 0)\r
- {\r
- keyIdx = 1;/*assumed that first key is the last key that invalidated the combinaton.*/\r
- _source_Search_Array = g_key_combination._current_matched_combinations;/*start next key combination matching from this assumed _current_matched_combinations*/\r
- t = timestamp;\r
- }\r
- else/* the key that invalidated is unavailable in any master_combinations as first element*/\r
- {\r
- keyIdx = 0;\r
- t = timestamp;\r
- g_array_free(g_key_combination._current_matched_combinations, FALSE);\r
- }\r
- }\r
- else\r
- {\r
- if (g_key_combination._current_matched_combinations->len == 1 && (unsigned int)(keyIdx+1) == g_array_index(g_key_combination._current_matched_combinations,GArray*,0)->len)\r
- {\r
- keyIdx = 0;\r
- t = timestamp;\r
- matched = g_array_index(g_key_combination._current_matched_combinations,GArray*,0);\r
-\r
- for (i = 0; i < matched->len; i++)\r
- KLDBG("[32m Matched Combination:|%d| [0m", g_array_index(matched,int,i));\r
- foundAt = 0;\r
-\r
- for (i = 0; i < g_key_combination._master_combinations->len; i++)\r
- {\r
- childArray=g_array_index(g_key_combination._master_combinations,GArray*,i);\r
- for (j = 0; j < childArray->len; j++)\r
- {\r
- if (childArray->len == matched->len && g_array_index(childArray,int,j) == g_array_index(matched,int,j))\r
- {\r
- foundAt = i + 1;\r
- }\r
- else\r
- {\r
- foundAt = FALSE;\r
- break;\r
- }\r
- }\r
- if (foundAt)\r
- {\r
- KLDBG("[32m COMBINATION FOUND AT : %d [0m", foundAt);\r
- break;\r
- }\r
- }\r
- g_array_free(g_key_combination._current_matched_combinations, FALSE);/* we free this as combination is found and we need to start fresh for next key.*/\r
- return foundAt;\r
- }\r
- else/*continue search for next key*/\r
- {\r
- t = timestamp;\r
- keyIdx++;\r
- _source_Search_Array = g_key_combination._current_matched_combinations;\r
- }\r
- }\r
-\r
- return -1;\r
-}\r