/* src-kbd.c * * Copyright 2001, 2002 Sun Microsystems, Inc., * Copyright 2001, 2002 BAUM Retec, A.G. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "libke.h" #include "src-kbd.h" #include "sru-debug.h" #include "sru-glib.h" #include "SRObject.h" #include "libsrconf.h" #include #include "srspc.h" typedef struct { gint flag; SREvent *evnt; } SRCIdle; KeyboardEchoCB src_kbd_clb = NULL; extern gboolean src_use_speech; static SRCIdle * src_kbd_srcidle_new () { return g_new0 (SRCIdle, 1); } static void src_kbd_srcidle_terminate (SRCIdle *src_idle) { g_assert (src_idle); sre_release_reference (src_idle->evnt); g_free (src_idle); } static SRHotkeyData* src_kbd_init_srhotkey_data (const gchar *key, gint modifier) { SRHotkeyData *srhotkey_data = g_new0 (SRHotkeyData, 1); g_assert (key); srhotkey_data->keystring = g_strdup (key); srhotkey_data->modifiers = modifier; return srhotkey_data; } static void src_kbd_hotkey_data_destructor (gpointer data) { SRHotkeyData *srhotkey_data = (SRHotkeyData *) data; g_assert (srhotkey_data); g_free (srhotkey_data->keystring); g_free (srhotkey_data); } static gboolean src_kbd_report_callbacks_idle (gpointer data) { SRCIdle *src_idle = (SRCIdle *) data; g_assert (data); g_assert (src_idle && src_idle->evnt); g_assert (src_kbd_clb); src_kbd_clb (src_idle->evnt, src_idle->flag); src_kbd_srcidle_terminate (src_idle); return FALSE; } static void src_kbd_report_event (SREvent *evnt, gint flags) { SRCIdle *src_idle; sre_add_reference (evnt); src_idle = src_kbd_srcidle_new (); src_idle->evnt = evnt; src_idle->flag = flags; g_idle_add (src_kbd_report_callbacks_idle, src_idle); } static void src_kbd_report_hotkey_event (const gchar *key, gint modifiers, gint flag, SREventType type) { SREvent *evnt = NULL; SRHotkeyData *hotkey = src_kbd_init_srhotkey_data (key, modifiers); evnt = sre_new (); evnt->data = hotkey; evnt->type = type; evnt->data_destructor = src_kbd_hotkey_data_destructor; src_kbd_report_event (evnt, flag); } static void src_kbd_report_layer_event (gchar *buf, gint flag, SREventType type) { SREvent *evnt = NULL; g_assert (buf && type); evnt = sre_new (); evnt->data = g_strdup (buf); evnt->type = type; evnt->data_destructor = g_free; src_kbd_report_event (evnt, flag); } static void src_kbd_grab (const gchar *key, KEKeyModifier modifier) { } static void src_kbd_hit () { if (src_use_speech) src_speech_shutup (); } static gchar* src_kbd_get_string_from_modifiers (KEKeyModifier modifier) { GString *str = g_string_new (NULL); if (modifier & KE_MODIFIER_ALT) g_string_append (str, "A"); if (modifier & KE_MODIFIER_CONTROL) g_string_append (str, "C"); if (modifier & KE_MODIFIER_SHIFT) g_string_append (str, "S"); if (str->len) return g_string_free (str, FALSE); return NULL; } static KEKeyModifier src_kbd_get_modifiers_from_string (const gchar *str) { KEKeyModifier modif = KE_MODIFIER_UNMODIFIED; gint i; for (i = 0; str[i]; i++) { if (str[i] == 'A') modif |= KE_MODIFIER_ALT; if (str[i] == 'C') modif |= KE_MODIFIER_CONTROL; if (str[i] == 'S') modif |= KE_MODIFIER_SHIFT; } return modif; } static void src_kbd_command (const gchar *key, KEKeyModifier modifier) { gchar *cmd, *mod; g_assert (key && key[0]); mod = src_kbd_get_string_from_modifiers (modifier); if (mod) cmd = g_strconcat (mod, "-", key, NULL); else cmd = g_strdup (key); src_kbd_report_layer_event (cmd, 0, SR_EVENT_COMMAND_LAYER); g_free (cmd); g_free (mod); } static void src_kbd_cursor (const gchar *cursor) { src_kbd_report_hotkey_event (cursor, 0, 0, SR_EVENT_KEY); } static void src_kbd_modifier (const gchar *modifier, KEKeyAction action) { src_kbd_report_hotkey_event (modifier, 0, 0, SR_EVENT_KEY); } static void src_kbd_layer_key (gint layer, gint key) { gchar *buf = g_strdup_printf ("L%02dK%02d", layer, key); src_kbd_report_layer_event (buf, 0, SR_EVENT_COMMAND_LAYER); g_free (buf); } static void src_kbd_layer_ch (gint layer) { gchar *buf = g_strdup_printf ("L%02d", layer); src_kbd_report_layer_event (buf, KE_LAYER_CHANGED, SR_EVENT_COMMAND_LAYER_CHANGED); g_free (buf); } static void src_kbd_layer_back (gint layer) { gchar *buf = g_strdup_printf ("L%02d", layer); src_kbd_report_layer_event (buf, KE_LAYER_TIME_OUT, SR_EVENT_COMMAND_LAYER_CHANGED); g_free (buf); } static void src_kbd_mouse_move (gint x, gint y) { SRPoint *point; SREvent *evnt = NULL; evnt = sre_new (); point = g_new0 (SRPoint, 1); point->x = x; point->y = y; evnt->data = point; evnt->type = SR_EVENT_MOUSE; evnt->data_destructor = g_free; src_kbd_report_event (evnt, 0); } static SRHotkeyData* src_kbd_get_command (gchar *str) { gchar **str_split; SRHotkeyData *hotkey; KEKeyModifier modif = KE_MODIFIER_UNMODIFIED; gchar *key = NULL; g_assert (str); str_split = g_strsplit (str, "-", -1); g_assert (str_split && str_split[0]); if (!str_split[1]) key = g_strdup (str_split [0]); else { g_assert (str_split[2] == NULL); key = g_strdup (str_split[1]); modif = src_kbd_get_modifiers_from_string (str_split[0]); } g_strfreev (str_split); hotkey = src_kbd_init_srhotkey_data (key, modif); g_free (key); return hotkey; } static void src_kbd_add_commands (gpointer data) { SRHotkeyData *hotkey = src_kbd_get_command (data); ke_command_add (hotkey->keystring, hotkey->modifiers); src_kbd_hotkey_data_destructor (hotkey); } static gboolean src_kbd_get_config_settings (GSList **list) { GSList *list_tmp = NULL; *list = NULL; if (!srconf_get_data_with_default (SRC_USER_DEF_LIST , CFGT_LIST, &list_tmp, (gpointer)NULL ,SRC_USER_DEF_SECTION)) return FALSE; if (!list_tmp) return FALSE; *list = list_tmp; return TRUE; } static void src_kbd_init_commands () { GSList *user_cmds = NULL; if (src_kbd_get_config_settings (&user_cmds)) { sru_slist_foreach (user_cmds, src_kbd_add_commands); sru_slist_terminate (user_cmds, g_free); } } gboolean src_kbd_init (KeyboardEchoCB kecb) { KECallbacks callbacks; gboolean rv; g_assert (kecb); sru_debug_init (); src_kbd_clb = kecb; callbacks.grab = src_kbd_grab; callbacks.hit = src_kbd_hit; callbacks.command = src_kbd_command; callbacks.cursor = src_kbd_cursor; callbacks.modifier = src_kbd_modifier; callbacks.layer_key = src_kbd_layer_key; callbacks.layer_ch = src_kbd_layer_ch; callbacks.layer_back = src_kbd_layer_back; callbacks.mouse_move = src_kbd_mouse_move; rv = ke_init (&callbacks); src_kbd_init_commands (); return rv; } void src_kbd_terminate () { src_kbd_clb = NULL; ke_commands_remove_all (); ke_terminate (); sru_debug_terminate (); } gboolean src_kbd_restart_cmds () { ke_commands_remove_all (); src_kbd_init_commands (); return TRUE; }