Index: gnopernicus/kbd_mouse/libke/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnopernicus/kbd_mouse/libke/Makefile.am,v
retrieving revision 1.9
diff -u -r1.9 Makefile.am
--- gnopernicus/kbd_mouse/libke/Makefile.am	6 Feb 2006 12:43:17 -0000	1.9
+++ gnopernicus/kbd_mouse/libke/Makefile.am	3 Apr 2006 13:21:14 -0000
@@ -3,20 +3,16 @@
 
 INCLUDES = -I$(top_builddir)    		\
 	   -I$(top_srcdir)/srutil 		\
-	   -I$(top_srcdir)/srconf/libsrconf 	\
 	   $(LIBKE_CFLAGS)			\
 	   -DG_LOG_DOMAIN=\"gnopernicus\"
 
 libke_la_LDFLAGS = @LT_VERSION_INFO@ $(NO_UNDEFINED)
 
-libke_la_LIBADD = ../../srutil/libsrutil.la ../../srconf/libsrconf/libsrconf.la $(LIBKE_LIBS) $(X_LIBS)
+libke_la_LIBADD = ../../srutil/libsrutil.la $(LIBKE_LIBS)  $(X_LIBS)
 
 libkeincludedir =$(includedir)/gnopernicus-1.0/libke
+libkedir=$(libdir)/gnopernicus-1.0
 
 libkeinclude_HEADERS = libke.h     
 
-libke_la_SOURCES = libke.c       \
-                   libke.h       
-
-
-
+libke_la_SOURCES = libke.c
Index: gnopernicus/kbd_mouse/libke/libke.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/kbd_mouse/libke/libke.c,v
retrieving revision 1.66
diff -u -r1.66 libke.c
--- gnopernicus/kbd_mouse/libke/libke.c	25 Jul 2005 14:21:50 -0000	1.66
+++ gnopernicus/kbd_mouse/libke/libke.c	3 Apr 2006 13:21:15 -0000
@@ -18,1776 +18,1130 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+ 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
-#include "config.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
 #include <cspi/spi.h>
-#include "libke.h"
-#include "libsrconf.h"
-#include "SRMessages.h"
-
 #define XK_MISCELLANY
-#include <X11/keysymdef.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
-#include <X11/XKBlib.h>
-
-#define  USE_ALL_WINDOWS
-
-/* Solaris specific variable types. */
-#ifdef __sun
-#define u_int8_t   uint8_t
-#define u_int16_t  uint16_t
-#define u_int32_t  uint32_t
-#define u_int64_t  uint64_t
-#endif
+#define XK_LATIN1
+#include <X11/keysymdef.h> 
+#include <gdk/gdkx.h> 
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
 
-#define KE_TIME_WAIT 			5000
-#define COUNT_OF_ITEM_IN_LAYER_KEYSET 	17
+#include <unistd.h>
+#include <ctype.h>
 
-#define MODIFIER(K,C) (K ? C : "")
-#define LINE(X)       (X != 0 ? "-" : "")
-#define STR(X)	      (X != NULL ? X : "")
-
-#define Z_CHAR_POSITION 26
-
-/**
- * Keyboard echo log flags.
- *
-**/
-enum
-{
-    KE_LOG_UNKNOWN	= 0,
-    KE_LOG_AT_SPI 	= 1,
-    KE_LOG_GNOPERNICUS  = 2  
-};
+#include "libke.h"
+#include "sru-module.h"
 
-static gint 			ke_log_flags;
+#define SRU_DEBUG_MODULE "kbd"
+/*#define SRU_DEBUG_SCOPES "keyboard:init:numpad:cursor:modifier:hit:mouse:command:grab:event:entry" */
+#include "sru-debug.h" 
+
+#define KE_LAYER_DEFAULT 	0
+#define KE_LAYER_TIMEOUT 	5000
+#define KE_LOG_AT_SPI_KEYBOARD_EVENT(scope)				\
+    sru_debug_log (scope,						\
+	    "%s of keystring=\"%s\"\tkeycode=\"%d(0x%x)\""		\
+	    "\tkeysym=\"%ld(0x%x)\" with \"%s\" modifier(s) at index: %d",\
+    	    ke_debug_return_at_spi_key_mask (key->type), key->keystring,\
+    	    (gint) key->keycode, (gint) key->keycode,			\
+	    (glong) key->keyID, (guint) key->keyID,			\
+    	    ke_debug_return_at_spi_key_flags (key->modifiers), index);
+
+typedef SPIBoolean (*KEAccessibleKeystrokeListenerCB) 
+				(const AccessibleKeystroke *key, gint index);
+typedef long KEKeyFlag;
+typedef long KECount;
+
+/* FIXME start */
+#define SPI_true TRUE
+#define SPI_false FALSE
+/* FIXME end */
 
 typedef struct
 {
-    gint    flag;
-    SREvent *evnt;
-} IdleStruct;    
-    
-/**
- *
- * Key string translation table.
- *
-**/
-typedef struct 
-{
-    gchar *key;
-    gchar *key_shifted;
-} KeyTransTable;
-
-KeyTransTable key_trans_table[]=
-{
-    {"asciitilde",	"grave"},	/* ~    */
-    {"grave",		"asciitilde"},	/* `    */
-    {"numbersign",	"3"},		/* #	*/
-    {"exclam",		"1"},		/* !	*/
-    {"asciicircum",	"6"},		/* ^	*/
-    {"period",		"greater"},	/* .	*/
-    {"quotedbl",	"apostrophe"},	/* \"	*/
-    {"dollar",		"4"},		/* $	*/
-    {"percent", 	"5"},		/* %	*/
-    {"ampersand", 	"7"},		/* &	*/
-    {"apostrophe",	"quotedbl"},	/* \'	*/
-    {"parenleft", 	"9"},		/* (	*/
-    {"parenright", 	"0"},		/* )	*/
-    {"asterisk",	"8"},		/* *	*/
-    {"plus",		"equal"},	/* +	*/
-    {"comma",		"less"},	/* ,	*/
-    {"minus",		"underscore"},	/* -	*/
-    {"slash",		"question"},	/* /	*/
-    {"colon",		"semicolon"},	/* :	*/
-    {"semicolon",	"colon"},	/* ;	*/
-    {"less",		"comma"},	/* <	*/
-    {"equal",		"plus"},	/* =	*/
-    {"greater",		"period"},	/* >	*/
-    {"question",	"slash"},	/* ?	*/
-    {"at",		"2"},		/* @	*/
-    {"bracketleft",	"braceleft"},	/* [	*/
-    {"backslash",	"bar"},		/* \\	*/
-    {"bracketright",	"braceright"},	/* ]	*/
-    {"underscore",	"minus"},	/* _	*/
-    {"braceleft",	"bracketleft"},	/* {	*/
-    {"bar",		"backslash"},	/* |	*/
-    {"braceright",	"bracketright"},/* }	*/
-    {"1",		"exclam"},	/* 1	*/
-    {"2",		"at"},		/* 2	*/
-    {"3",		"numbersign"},	/* 3	*/
-    {"4",		"dollar"},	/* 4	*/
-    {"5",		"percent"},	/* 5	*/
-    {"6",		"asciicircum"},	/* 6	*/
-    {"7",		"ampersand"},	/* 7	*/
-    {"8",		"asterisk"},	/* 8	*/
-    {"9",		"parenleft"},	/* 9	*/
-    {"0",		"parenright"}	/* 0	*/
-};    
-
-/**
- *
- * Command layer state machine states.
- *
-**/
-typedef enum
-{
-    KE_LAYER_STATE_IDLE,
-    KE_LAYER_STATE_LEVEL
-} KeyboardLayerState;
-
-/**
- *
- * Keyset item type.
- *
-**/
-typedef struct
-{
-    AccessibleKeySet *keyset;
-    unsigned long    modifier;
-    long	     keysym;
-} KeySetItem;
-
-/**
- *
- * Keyevent.
- *
-**/ 
+    KeySym keysym;
+    KEKeyModifier modifier;
+}KEKeysymKeyModifier;
+
+static gboolean    	ke_keyboard_grabbing 	= FALSE;
+static gint    		ke_crt_layer 		= KE_LAYER_DEFAULT;
+static KECount 		ke_cnt_kbd_listeners  	= 0;
+static KECount 		ke_cnt_numpad_changes 	= 0;
+static KECallbacks 	ke_callbacks;
+static GArray 		*ke_commands_array 	= NULL;
+static AccessibleKeystrokeListener	*kbd_listener		= NULL;	
+static AccessibleKeystrokeListener 	*ke_mouse_listener 	= NULL;	
+
+SRU_MODULE_FLAG_DEFS(ke_module_flag); 
+
+static SPIBoolean ke_try_report_at_spi_cursor_event
+				(const AccessibleKeystroke *key,  gint index);
+static SPIBoolean ke_try_report_at_spi_numpad_event
+				(const AccessibleKeystroke *key,  gint index);
+static SPIBoolean ke_try_report_at_spi_modifier_event
+				(const AccessibleKeystroke *key,  gint index);
+static SPIBoolean ke_try_report_at_spi_command_event
+				(const AccessibleKeystroke *key,  gint index);
+static SPIBoolean ke_try_report_at_spi_grab_event
+				(const AccessibleKeystroke *key,  gint index);
+static SPIBoolean ke_try_report_at_spi_hit_event
+				(const AccessibleKeystroke *key,  gint index);
+
 typedef struct
 {
-    glong keyID;
-    gint  keycode;
-    gchar *keystring;   
-    guint modifiers;
-}KEKeyEvent;
-
-static gboolean	ke_user_key_list_unregister_events (void);
-
-/**
- * User key.
-**/
-static AccessibleKeystrokeListener *ke_user_key_listener;
-static GSList 			   *accessible_key_set_list   = NULL;
-static GSList 			   *ke_user_key_list 	 = NULL;
-static GSList 			   *reg_list = NULL;
-
-/**
- * keyecho
-**/
-static AccessibleKeystrokeListener *ke_keyecho_listener;
-static AccessibleKeySet 	   *ke_keyecho_keyset;
-
-/**
- * layer
-**/
-static AccessibleKeystrokeListener *ke_layer_listener;
-static AccessibleKeySet 	   *ke_layer_keyset  = NULL;
-KeyboardLayerState 	 	   ke_layer_state    = KE_LAYER_STATE_IDLE;
-static gint 		 	   ke_layer_level    = 0;
-
-/**
- * keyboard_echo_cb:
- *
- * The callback function used for communication with caller, is set during
- * the init process.
- *
-**/
-static KeyboardEchoCB 		   ke_keyboard_event_sink_cb = NULL;
-
-/**
- * KEStateEnum:
- *
- * Define the state of the keyboard echo library
- *    KE_IDLE    - library not initialized
- *    KE_RUNNING - initialized and running
-**/
-typedef enum 
-{
-    KE_IDLE,
-    KE_RUNNING
-} KEStateEnum;
-
-/**
- * keyboard_echo_status
- *
- * The library status
- *
-**/
-static KEStateEnum ke_keyboard_status = KE_IDLE;
-
-IdleStruct* ke_idle_struct_new ()
-{
-    IdleStruct* ke_idle;
-    ke_idle = g_new0 (IdleStruct, 1);
-    return ke_idle;
-}
+    const AccessibleKeystrokeListener 	*listener;
+    AccessibleKeyListenerSyncType 	sync_type;
+    const AccessibleKeySet 		*acc_set;
+    AccessibleKeyEventMask 		mask;
+    KEKeyFlag 				flags;
+    KEKeyFlag 				opt_flags;
+}KERegisterInfo;
+
+#define KE_HIT_FUNCTIONS				\
+    {							\
+	ke_try_report_at_spi_command_event,		\
+	ke_try_report_at_spi_grab_event,		\
+	ke_try_report_at_spi_hit_event,			\
+	NULL						\
+    }
+
+#define KE_MODIFIER_FUNCTIONS				\
+    {							\
+	ke_try_report_at_spi_command_event,		\
+	ke_try_report_at_spi_grab_event,		\
+	ke_try_report_at_spi_modifier_event,		\
+	NULL						\
+    }
+
+#define KE_CURSOR_FUNCTIONS				\
+    {							\
+	ke_try_report_at_spi_command_event,		\
+	ke_try_report_at_spi_grab_event,		\
+	ke_try_report_at_spi_hit_event,			\
+	ke_try_report_at_spi_cursor_event,		\
+	NULL						\
+    }
+
+#define KE_NUMPAD_FUNCTIONS				\
+    {							\
+	ke_try_report_at_spi_numpad_event,		\
+	NULL						\
+    }
+
+#define KE_MAX_FUNCTIONS_NO	5 /* 5 = maximum size of defines above */
+
+struct
+{
+    KeySym 	keysym;
+    gpointer	data;
+    KEAccessibleKeystrokeListenerCB process[KE_MAX_FUNCTIONS_NO];
+}ke_keys_info[] =
+{
+    { XK_a,		N_("A"),		KE_HIT_FUNCTIONS },
+    { XK_b,		N_("B"),		KE_HIT_FUNCTIONS },					
+    { XK_c,		N_("C"),		KE_HIT_FUNCTIONS },
+    { XK_d,		N_("D"),		KE_HIT_FUNCTIONS },
+    { XK_e,		N_("E"),		KE_HIT_FUNCTIONS },
+    { XK_f,		N_("F"),		KE_HIT_FUNCTIONS },
+    { XK_g,		N_("G"),		KE_HIT_FUNCTIONS },
+    { XK_h,		N_("H"),		KE_HIT_FUNCTIONS },
+    { XK_i,		N_("I"),		KE_HIT_FUNCTIONS },
+    { XK_j,		N_("J"),		KE_HIT_FUNCTIONS },
+    { XK_k,		N_("K"),		KE_HIT_FUNCTIONS },
+    { XK_l,		N_("L"),		KE_HIT_FUNCTIONS },
+    { XK_m,		N_("M"),		KE_HIT_FUNCTIONS },
+    { XK_n,		N_("N"),		KE_HIT_FUNCTIONS },
+    { XK_o,		N_("O"),		KE_HIT_FUNCTIONS },
+    { XK_p,		N_("P"),		KE_HIT_FUNCTIONS },
+    { XK_q,		N_("Q"),		KE_HIT_FUNCTIONS },
+    { XK_r,		N_("R"),		KE_HIT_FUNCTIONS },
+    { XK_s,		N_("S"),		KE_HIT_FUNCTIONS },
+    { XK_t,		N_("T"),		KE_HIT_FUNCTIONS },
+    { XK_u,		N_("U"),		KE_HIT_FUNCTIONS },
+    { XK_v,		N_("V"),		KE_HIT_FUNCTIONS },
+    { XK_w,		N_("W"),		KE_HIT_FUNCTIONS },
+    { XK_x,		N_("X"),		KE_HIT_FUNCTIONS },
+    { XK_y,		N_("Y"),		KE_HIT_FUNCTIONS },
+    { XK_z,		N_("Z"),		KE_HIT_FUNCTIONS },
+    { XK_0,		N_("0"),		KE_HIT_FUNCTIONS },
+    { XK_1,		N_("1"),		KE_HIT_FUNCTIONS },
+    { XK_2,		N_("2"),		KE_HIT_FUNCTIONS },
+    { XK_3,		N_("3"),		KE_HIT_FUNCTIONS },
+    { XK_4,		N_("4"),		KE_HIT_FUNCTIONS },
+    { XK_5,		N_("5"),		KE_HIT_FUNCTIONS },
+    { XK_6,		N_("6"),		KE_HIT_FUNCTIONS },
+    { XK_7,		N_("7"),		KE_HIT_FUNCTIONS },
+    { XK_8,		N_("8"),		KE_HIT_FUNCTIONS },
+    { XK_9,		N_("9"),		KE_HIT_FUNCTIONS },
+    { XK_F1,		N_("F1"),		KE_HIT_FUNCTIONS },
+    { XK_F2,		N_("F2"),		KE_HIT_FUNCTIONS },
+    { XK_F3,		N_("F3"),		KE_HIT_FUNCTIONS },
+    { XK_F4,		N_("F4"),		KE_HIT_FUNCTIONS },
+    { XK_F5,		N_("F5"),		KE_HIT_FUNCTIONS },
+    { XK_F6,		N_("F6"),		KE_HIT_FUNCTIONS },		
+    { XK_F7,		N_("F7"),		KE_HIT_FUNCTIONS },
+    { XK_F8,		N_("F8"),		KE_HIT_FUNCTIONS },
+    { XK_F9,		N_("F9"),		KE_HIT_FUNCTIONS },
+    { XK_F10,		N_("F10"),		KE_HIT_FUNCTIONS },
+    { XK_F11,		N_("F11"),		KE_HIT_FUNCTIONS },
+    { XK_F12,		N_("F12"),		KE_HIT_FUNCTIONS },	
+
+    { XK_Super_L,	N_("Window Left"),	KE_MODIFIER_FUNCTIONS },	
+    { XK_Super_R,	N_("Window Right"),	KE_MODIFIER_FUNCTIONS },
+    { XK_Alt_L,		N_("Alt Left"),		KE_MODIFIER_FUNCTIONS },
+    { XK_Alt_R,		N_("Alt Right"),	KE_MODIFIER_FUNCTIONS },
+    { XK_Shift_L,	N_("Shift Left"),	KE_MODIFIER_FUNCTIONS },
+    { XK_Shift_R,	N_("Shift Right"),	KE_MODIFIER_FUNCTIONS },
+    { XK_Control_L,	N_("Control Left"),	KE_MODIFIER_FUNCTIONS },
+    { XK_Control_R,	N_("Control Right"),	KE_MODIFIER_FUNCTIONS },
+    { XK_Caps_Lock,	N_("CapsLock"),		KE_MODIFIER_FUNCTIONS },
+    { XK_Num_Lock,	N_("NumLock"),		KE_MODIFIER_FUNCTIONS },
+
+    { XK_Home, 		N_("Home"),		KE_CURSOR_FUNCTIONS },
+    { XK_End,		N_("End"),		KE_CURSOR_FUNCTIONS },
+    { XK_Left,		N_("Left"),		KE_CURSOR_FUNCTIONS },
+    { XK_Right,		N_("Right"),		KE_CURSOR_FUNCTIONS },
+    { XK_Up,		N_("Up"),		KE_CURSOR_FUNCTIONS },
+    { XK_Down,		N_("Down"),		KE_CURSOR_FUNCTIONS },
+    { XK_Page_Up,	N_("Page Up"),		KE_CURSOR_FUNCTIONS },
+    { XK_Page_Down,	N_("Page Down"),	KE_CURSOR_FUNCTIONS },
+    { XK_BackSpace,	N_("BackSpace"),	KE_CURSOR_FUNCTIONS },
+    { XK_Delete,	N_("Delete"),		KE_CURSOR_FUNCTIONS },
+    { XK_Escape,	N_("Escape"),		KE_CURSOR_FUNCTIONS },
+
+    { XK_KP_0, 		GINT_TO_POINTER (0),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_1,		GINT_TO_POINTER (1),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_2, 		GINT_TO_POINTER (2),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_3,		GINT_TO_POINTER (3),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_4,		GINT_TO_POINTER (4),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_5,		GINT_TO_POINTER (5),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_6,		GINT_TO_POINTER (6),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_7,		GINT_TO_POINTER (7),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_8,		GINT_TO_POINTER (8),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_9,		GINT_TO_POINTER (9),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Decimal,	GINT_TO_POINTER (10),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Separator,	GINT_TO_POINTER (10),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Enter,	GINT_TO_POINTER (11),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Add, 	GINT_TO_POINTER (12),	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Subtract,	GINT_TO_POINTER (13), 	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Multiply,	GINT_TO_POINTER (14), 	KE_NUMPAD_FUNCTIONS },
+    { XK_KP_Divide,	GINT_TO_POINTER (15), 	KE_NUMPAD_FUNCTIONS }
+};
 
-void ke_idle_struct_free (IdleStruct *ke_idle)
+#ifdef SR_DEBUG
+static gchar*
+ke_debug_return_key_event_from_key_action (KEKeyAction action)
 {
-    sre_release_reference (ke_idle->evnt);
-    g_free (ke_idle);
-}
+    struct
+    {
+	KEKeyAction	action;
+	gchar		*name;
+    }actions_names[] = 
+    {
+	{ KE_KEY_PRESSED,	"PRESSED"  },
+	{ KE_KEY_RELEASED,	"RELEASED" }
+    };
+    gint i;
 
-static gboolean
-ke_repot_layer_cmd (gpointer data)
+    for (i = 0; i < G_N_ELEMENTS (actions_names); i++)
+    	if (action == actions_names[i].action)
+	{
+	    g_assert (actions_names[i].name);
+	    return actions_names[i].name;
+	}
+
+    return "NONE"; 
+}						
+
+static G_CONST_RETURN gchar*
+ke_debug_return_at_spi_key_mask (AccessibleKeyEventMask mask)
 {
-    IdleStruct *ke_idle = (IdleStruct*)data;
+    struct
+    {
+	AccessibleKeyEventMask  mask;
+	gchar     		*name;
+    }masks_names[] = 
+    {
+	{ SPI_KEY_PRESSED,	"PRESSED"  },
+	{ SPI_KEY_RELEASED,	"RELEASED" }
+    };
+    gint i;
 
-    if (ke_keyboard_event_sink_cb != NULL) 
-	ke_keyboard_event_sink_cb (ke_idle->evnt, ke_idle->flag);
-	
-    ke_idle_struct_free (ke_idle);
-    return FALSE;
+    for (i = 0; i < G_N_ELEMENTS (masks_names); i++)
+    	if (mask == masks_names[i].mask)
+	{
+	    g_assert (masks_names[i].name);
+	    return masks_names[i].name;
+	}
+
+    return "NONE";
 }
+		
+static G_CONST_RETURN gchar*
+ke_debug_return_at_spi_key_flags (KEKeyFlag flags)
+{
+    struct
+    {
+	KEKeyFlag flag;
+	gchar     *name;
+    }flags_names[] =
+    {
+	{ SPI_KEYMASK_ALT, 		"ALT"	   },
+	{ SPI_KEYMASK_CONTROL, 		"CTRL" 	   },
+	{ SPI_KEYMASK_SHIFT, 		"SHIFT"	   },
+	{ SPI_KEYMASK_SHIFTLOCK,	"CAPSLOCK" },
+	{ SPI_KEYMASK_NUMLOCK,		"NUMLOCK"  }
+    };
+    gint i;
+    static gchar rv[200]; /* 200 = enough space for all flags names, delimitators etc */
+    gchar *crt = rv;
+    gboolean first = TRUE;
+    KEKeyFlag shown_flags = SPI_KEYMASK_UNMODIFIED;
 
-/**
- * ke_log_at_spi
- *
- *
-**/
-static void
-ke_log_at_spi (const AccessibleKeystroke *key)
-{    
-    if (!(ke_log_flags & KE_LOG_AT_SPI))
-	return;
-	
-    fprintf (stderr, "\nAT:%xp--key event:sym %ld (%c)\tmods %x\tcode %d\ttime %ld\tkeystring \"%s\"\ttype %d (press = %d, release = %d)",
-	      (unsigned int) key,
-	      (glong) key->keyID, (gchar)key->keyID,
-	      (guint) key->modifiers,
-	      (gint) key->keycode, 
-	      (long int) key->timestamp,
-	      key->keystring,
-	      (gint) key->type, (gint)SPI_KEY_PRESSED, (gint)SPI_KEY_RELEASED );   
+    for (i = 0; i < G_N_ELEMENTS (flags_names); i++)
+	if ((flags & flags_names[i].flag) == flags_names[i].flag)
+	{
+	    g_assert (flags_names[i].name);
+	    shown_flags |=  flags_names[i].flag;
+	    if (!first)
+		crt = g_stpcpy (crt, " | ");
+	    first = FALSE;
+	    crt = g_stpcpy (crt, flags_names[i].name);
+	}
+
+    if ((flags & shown_flags) != flags)
+    {
+	if (!first)
+	    crt = g_stpcpy (crt, " | ");
+        crt = g_stpcpy (crt, "OTHERS");
+    }
+
+    if (crt == rv)
+	strcpy (rv, "NONE");
 
+    return rv;
 }
 
-/**
- * ke_log_gnopernicus
- *
- *
-**/
-static void
-ke_log_gnopernicus (const SREvent *event)
+static G_CONST_RETURN gchar*
+ke_debug_return_ke_key_modifiers (KEKeyModifier modifiers)
 {
-    SRHotkeyData *srhotkey_data = NULL;
-    
-    if (!(ke_log_flags & KE_LOG_GNOPERNICUS))
-	return;
+    struct
+    {
+	KEKeyModifier 	modifier;
+	gchar   	*name;
+    }modifiers_names[] =
+    {
+	{ KE_MODIFIER_ALT, 	"ALT"	},
+	{ KE_MODIFIER_CONTROL,	"CTRL"	},
+	{ KE_MODIFIER_SHIFT, 	"SHIFT"	}
+    };
+    gint i;
+    static gchar rv[200]; /* 200 = enough space for all modifiers names, delimitators etc */
+    gchar *crt = rv;
+    gboolean first = TRUE;
+    KEKeyModifier shown_modifiers = KE_MODIFIER_UNMODIFIED;
 
-    srhotkey_data = (SRHotkeyData *) event->data;
-	
-    fprintf (stderr, "\nGN:%xp--key event:type:%d, keyID:%ld, modifiers:%d, keystring:%s",
-		     (unsigned int)event,
-		     event->type,
-		     srhotkey_data->keyID,
-		     srhotkey_data->modifiers,
-		     srhotkey_data->keystring);
+    for (i = 0; i < G_N_ELEMENTS (modifiers_names); i++)
+    	if (modifiers & modifiers_names[i].modifier)
+	{
+	    g_assert (modifiers_names[i].name);
+	    shown_modifiers |=  modifiers_names[i].modifier;
+	    if (!first)
+		crt = g_stpcpy (crt, " | ");
+	    first = FALSE;
+	    crt = g_stpcpy (crt, modifiers_names[i].name);
+	}
+
+    if ((modifiers & shown_modifiers) != modifiers)
+    {
+	if (!first)
+	    crt = g_stpcpy (crt, " | ");
+        crt = g_stpcpy (crt, "OTHERS");
+    }
+
+    if (crt == rv)
+	strcpy (rv, "NONE");
+
+    return rv;
+}		
+#endif
+
+static KEKeyModifier
+ke_get_ke_modifiers_from_at_spi_flags (KEKeyFlag flags)
+{
+    KEKeyModifier modifiers = KE_MODIFIER_UNMODIFIED;
+
+    if (flags & SPI_KEYMASK_ALT)
+	modifiers |= KE_MODIFIER_ALT;
+    if (flags & SPI_KEYMASK_CONTROL) 
+	modifiers |= KE_MODIFIER_CONTROL;
+    if (flags & SPI_KEYMASK_SHIFT)
+	modifiers |= KE_MODIFIER_SHIFT;
+
+    return modifiers;
 }
 
-/**
- * ke_get_log_flag:
- *
- * return:
-**/
-void
-ke_get_log_flag (void)
+static KeySym
+ke_get_keysym_from_keys_info (const gchar *key)
 {
-    const  gchar *log  = NULL;
-    
-    log = g_getenv ("GNOPERNICUS_LOG");
-    
-    if (!log)
-	log = "";
+    gint i;
 	
-    ke_log_flags = KE_LOG_UNKNOWN;
-    
-    if (strstr (log, "at-spi"))
-	ke_log_flags |= KE_LOG_AT_SPI;
-    if (strstr (log, "gnopernicus"))
-	ke_log_flags |= KE_LOG_GNOPERNICUS;
+    g_assert (ke_keys_info);
+
+    for (i = 0; i < G_N_ELEMENTS (ke_keys_info); i++)
+	if (strcmp (ke_keys_info[i].data, key) == 0)
+	     return ke_keys_info[i].keysym;
 
+    return NoSymbol;
 }
 
-/**
- * ke_print_register_return_value
- *
- * Show registration status.
-**/
-static void
-ke_print_register_return_value (SPIBoolean retval,
-				const gchar *modifiers)
+static KeyCode
+ke_get_keycode_from_keysym (KeySym keysym)
 {
-    sru_debug ("Key registry(%s): result %s", modifiers, retval ? "succeeded" : "failed");
+    static Display *display;
+    KeyCode keycode = 0;
+
+    if (!display)
+    	display = GDK_DISPLAY ();
+
+    if (!display)
+	g_printerr (_("Unable to get display\n"));
+    else
+	keycode = XKeysymToKeycode (display, keysym);
+
+    sru_debug_log ("keyboard", "keysym:\"%ld\" has keycode:\"%d\"",
+					keysym, keycode);
+
+    return keycode;
 }
 
-/****************************************************************************/
+static gint 
+ke_get_key_index_for_keycode (KeyCode keycode)
+{
+    gint i, rv = -1;
+    static Display *display = NULL;
+
+    if (!display)
+	display = GDK_DISPLAY ();
 
-/**
- * ke_srhotkey_data_destructor:
- *
- * @data:
- *
- * This function will be used to destroy data allocated in SREvent's data member.
- *
-**/
-static void 
-ke_srhotkey_data_destructor(gpointer data)
-{
-    SRHotkeyData *srhotkey_data = (SRHotkeyData *) data;
-    
-    if (srhotkey_data != NULL)
+    if (!display)
+    	g_printerr (_("Unable to get display\n"));
+    else
     {
-	g_free (srhotkey_data->keystring);
-	g_free (srhotkey_data);
+	for (i = 0; i < G_N_ELEMENTS (ke_keys_info); i++)
+	    if (keycode == XKeysymToKeycode (display, ke_keys_info[i].keysym))
+	    {
+		rv = i;
+		break;
+	    }
     }
+
+    sru_debug_log ("keyboard", "keycode:\"%d\" has index:\"%d\"",
+					keycode, rv);
+
+    return rv;
 }
 
-/**
- * ke_return_keystring
- *
- * @keyID:
- *
- * Return keystring from keyID.
- *
- * return:keystring.
-**/
-static gchar*
-ke_return_keystring (gint keyID)
+static KEKeyModifier
+ke_get_ke_action_from_at_spi_type (AccessibleDeviceEventType type)
 {
-    gchar *rv = NULL;
-    
-    switch (keyID)
-    {
-        case XK_Alt_L:	rv = g_strdup("Alt_L");break;
-        case XK_Alt_R:	rv = g_strdup("Alt_R");break;
-        case XK_Shift_L:rv = g_strdup("Shift_L");break;
-        case XK_Shift_R:rv = g_strdup("Shift_R");break;
-        case XK_Control_L:rv = g_strdup("Control_L");break;
-        case XK_Control_R:rv = g_strdup("Control_R");break;
-        case XK_Caps_Lock:rv = g_strdup("Caps_Lock");break;
-        case XK_Num_Lock:rv = g_strdup("Num_Lock");break;
-        case XK_Home:	rv = g_strdup("Home");break;
-        case XK_End:	rv = g_strdup("End");break;
-        case XK_Left:	rv = g_strdup("Left");break;
-        case XK_Right:	rv = g_strdup("Right");break;
-        case XK_Up:	rv = g_strdup("Up");break;
-        case XK_Down:	rv = g_strdup("Down");break;
-        case XK_Page_Up:rv = g_strdup("Page_Up");break;
-        case XK_Page_Down:rv = g_strdup("Page_Down");break;
-	case XK_BackSpace:rv = g_strdup ("BackSpace");break;
-	case XK_Delete:rv = g_strdup ("Delete");break;
-	case XK_Escape:rv = g_strdup ("Escape");break;
-	case XK_Super_L:rv = g_strdup ("Super_L");break;
-	case XK_Super_R:rv = g_strdup ("Super_R");break;
-	case XK_Hyper_L:rv = g_strdup ("Hyper_L");break;
-	case XK_Hyper_R:rv = g_strdup ("Hyper_R");break;
-	case XK_Menu:rv = g_strdup ("Menu");break;	
-        default:
-    	    rv = NULL;
-    }
-    sru_debug ("Return keystring:%s",rv);
-    
-    return rv;
+    if (type == SPI_KEY_PRESSED)
+	return KE_KEY_PRESSED;
+    else if (type == SPI_KEY_RELEASED) 
+	return KE_KEY_RELEASED;
+    else
+	g_assert_not_reached ();
+
+    return KE_KEY_RELEASED;
 }
 
+static KECount
+ke_register_listeners (KERegisterInfo *info)
+{
+    gint i, cnt;
+    SPIBoolean retval;
+    KEKeyFlag old_opt_flags;
+    KEKeyFlag all_flags[] =
+    { 	SPI_KEYMASK_ALT,
+	SPI_KEYMASK_CONTROL,
+	SPI_KEYMASK_SHIFT,
+	SPI_KEYMASK_SHIFTLOCK,
+	SPI_KEYMASK_NUMLOCK
+    };
+
+    g_assert (info->listener);
+
+    cnt = 0;
+    retval = SPI_registerAccessibleKeystrokeListener(  
+			    (AccessibleKeystrokeListener*)info->listener,
+			    (AccessibleKeySet*)info->acc_set,
+			    info->flags, info->mask, info->sync_type);
+    if (retval)
+	cnt = 1; /*FIXME is FALSE returned if registration fails only for some keys ???*/
+/* FIXME else --- unref the listener???? */
+    sru_debug_log ("init", "\"%s\" with flags \"%s\"",
+			    retval ? "succeeded" : "failed", 
+			    ke_debug_return_at_spi_key_flags (info->flags));
 
-/**
- * ke_call_srkey_cb
- *
- * @keyID:
- * @modifiers:
- * @keystring:
- *
- * This function is used to create the SREvent structure and to send it to
- * the callback when SR_KEY event occurs.
- *
- * return:
-**/
-static void 
-ke_call_srkey_cb (gulong keyID, 
-		  guint modifiers, 
-		  const gchar *keystring)
-{
-    SREvent *evnt = NULL;
-    SRHotkeyData *srhotkey_data = NULL;
-    IdleStruct *ke_idle;
-    evnt = sre_new ();
-    sru_return_if_fail (evnt);
-    srhotkey_data = (SRHotkeyData *) g_new0 (SRHotkeyData, 1);
-	
-    if (NULL != srhotkey_data )
+    old_opt_flags = info->opt_flags;
+    for (i = 0; i < G_N_ELEMENTS (all_flags); i++) 
     {
-	srhotkey_data->keyID = keyID;
-	srhotkey_data->modifiers = modifiers;
-	
-	if ( keyID > 255 ) /* 255 max printable ASCII code */
+	if (info->opt_flags & all_flags[i])
 	{
-	    if (!keystring || strlen (keystring) == 0)
-		srhotkey_data->keystring = ke_return_keystring (keyID);
-	    else
-		srhotkey_data->keystring = g_strdup (keystring);
-	}
-	else
-	    srhotkey_data->keystring = g_strdup_printf ("%c", (gchar)keyID );
-	    
-	evnt->data = srhotkey_data;
-	evnt->type = SR_EVENT_KEY;
-	evnt->data_destructor = ke_srhotkey_data_destructor;
-	
-	ke_log_gnopernicus (evnt);
-	
-	if (ke_keyboard_event_sink_cb != NULL) 
-	{
-	    sre_add_reference (evnt);
-	    ke_idle = ke_idle_struct_new ();
-	    ke_idle->flag = 0;
-	    ke_idle->evnt = evnt;
-	    g_idle_add (ke_repot_layer_cmd, ke_idle);
+	    KEKeyFlag old_flags = info->flags;
+
+    	    g_assert ((info->opt_flags & all_flags[i]) == all_flags[i]);
+	    info->flags |= all_flags[i];
+	    info->opt_flags = info->opt_flags & ~all_flags[i];
+	    cnt += ke_register_listeners (info);
+
+    	    info->flags = old_flags;
 	}
-    }	
-    sre_release_reference (evnt);
+    }
+    g_assert (info->opt_flags == SPI_KEYMASK_UNMODIFIED);
+    info->opt_flags = old_opt_flags;
+
+    return cnt;
 }
 
+static void
+ke_report_layer_key (gint layer,
+		     gint key)
+{
+    g_assert (ke_callbacks.layer_key);
+    g_assert (0 <= layer && layer <= 15);
+    g_assert (0 <= key && key <= 15);
 
-/**
- * ke_report_key_event:
- *
- * @key: AcceesibleKeystroke structure.
- * @user_data:
- *
- * The key listener function
- *
- * return: TRUE if consume a key event.
-**/
-static SPIBoolean
-ke_report_keyecho_event (const AccessibleKeystroke *key, gpointer user_data)
+    sru_debug_log ("numpad", "layer %02d key %02d", layer, key);
+    ke_callbacks.layer_key (layer, key);
+}
+
+static void
+ke_report_layer_changed (gint layer)
 {
-    static gboolean key_busy = FALSE;    
-    static GQueue  *key_queue = NULL;
-    KEKeyEvent     *ev;
-
-    sru_debug ("(Key)Received key event:\n\tsym %ld (%c)\n\tmods %x\n\tcode %d\n\ttime %ld\n\tkeystring \"%s\"\n",
-	     (glong) key->keyID, (gchar)key->keyID,
-	     (guint) key->modifiers,
-	     (gint) key->keycode,
-	     (long int) key->timestamp,
-	     key->keystring);  
-	     
-    ke_log_at_spi (key);    
-    
-    if (key->type == SPI_KEY_RELEASED)
-    {
-	sru_debug ("keyrelease received");
-	return FALSE;
-    }
-        
-    ev = (KEKeyEvent *) g_new0 (KEKeyEvent, 1);
-    
-    sru_return_val_if_fail (ev, FALSE);
-
-    if (!key_queue)
-	key_queue = g_queue_new ();
-
-    ev->keyID     = key->keyID;
-    ev->modifiers = key->modifiers;
-    ev->keycode	  = key->keycode;
-    ev->keystring = g_strdup (key->keystring);
-    
-    g_queue_push_head (key_queue, ev);
-    
-    sru_debug ("key_busy:%d", key_busy);
-    
-    sru_return_val_if_fail (!key_busy, FALSE);
-
-    key_busy = TRUE;
-    
-    while (!g_queue_is_empty (key_queue))
-    {
-	KEKeyEvent *key1;
-	
-	key1 = (KEKeyEvent *) g_queue_pop_tail (key_queue);
-	
-	ke_call_srkey_cb (key1->keyID, 0, key1->keystring);
-	
-	g_free (key1->keystring);		
-	g_free (key1);
-    }
+    g_assert (ke_callbacks.layer_ch);
+    g_assert (0 <= layer && layer <= 15);
 
-    g_queue_free (key_queue);
-    
-    key_queue = NULL;
+    ke_crt_layer = layer;
+    sru_debug_log ("numpad", "layer changed %02d", ke_crt_layer);
+    ke_callbacks.layer_ch (ke_crt_layer);
+}
 
-    key_busy = FALSE;
-        
-    return FALSE;
+static void
+ke_report_layer_back ()
+{
+    g_assert (ke_callbacks.layer_back);
+    g_assert (0 <= ke_crt_layer && ke_crt_layer <= 15);
+
+    sru_debug_log ("numpad", "layer back %02d", ke_crt_layer);
+    ke_callbacks.layer_back (ke_crt_layer);
 }
 
+static void
+ke_report_modifier (const gchar *modifier,
+		    KEKeyAction action)
+{
+    g_assert (modifier && ke_callbacks.modifier);
+
+    sru_debug_log ("modifier", "modifier \"%s\" was %s", modifier,
+			ke_debug_return_key_event_from_key_action (action));
+    ke_callbacks.modifier (modifier, action);
+}
 
+static void
+ke_report_cursor (const gchar *cursor)
+{
+    g_assert (cursor && ke_callbacks.cursor);
 
-/**
- * ke_return_key
- *
- * @keyID: keyID for pressed numpad key.
- *
- * Return a layer code.
- *
- * return:layer code or -1 if not a numpad keys.
-**/
-static gint
-ke_return_key (glong keyID)
-{
-    gint layer_code = -1;
-    
-    switch (keyID)
-    {
-	case XK_KP_0:		layer_code = 0; break;
-	case XK_KP_1:		layer_code = 1; break;
-	case XK_KP_2:		layer_code = 2; break;
-	case XK_KP_3:		layer_code = 3; break;
-	case XK_KP_4:		layer_code = 4; break;
-	case XK_KP_5:		layer_code = 5; break;
-	case XK_KP_6:		layer_code = 6; break;
-	case XK_KP_7:		layer_code = 7; break;
-	case XK_KP_8:		layer_code = 8; break;
-	case XK_KP_9:		layer_code = 9; break;
-	case XK_KP_Decimal:	layer_code = 10; break;
-	case XK_KP_Separator:	layer_code = 10; break;
-	case XK_KP_Enter:	layer_code = 11; break;
-	case XK_KP_Add:		layer_code = 12; break;
-	case XK_KP_Subtract:	layer_code = 13; break;
-	case XK_KP_Multiply:	layer_code = 14; break;
-	case XK_KP_Divide:	layer_code = 15; break;
-#ifdef __sun
-	/*
-	 * The KeySyms returned by Solaris Xserver are incorrect.
-	 * The values below are those returned on Solaris.
-	 */
-	case XK_KP_Insert:	layer_code = 0; break;
-	case XK_F33:		layer_code = 1; break;
-	case XK_Down:		layer_code = 2; break;
-	case XK_F35:		layer_code = 3; break;
-	case XK_Left:		layer_code = 4; break;
-	case XK_F31:		layer_code = 5; break;
-	case XK_Right:		layer_code = 6; break;
-	case XK_F27:		layer_code = 7; break;
-	case XK_Up:		layer_code = 8; break;
-	case XK_F29:		layer_code = 9; break;
-	case XK_KP_Delete:	layer_code = 10; break;
-	case XK_F24:		layer_code = 13; break;
-	case XK_F26:		layer_code = 14; break;
-	case XK_F25:		layer_code = 15; break;
-#endif
-	default:
-	break;
-    }		
-    
-    return layer_code;
+    sru_debug_log ("cursor", "cursor \"%s\"", cursor);
+    ke_callbacks.cursor (cursor);
 }
 
+static void
+ke_report_keyboard_grab (const gchar *key,
+			 KEKeyModifier modifiers)
+{
+    g_assert (key && ke_callbacks.grab);
 
+    sru_debug_log ("grab", "key \"%s\" with modifiers %s",
+			    key, ke_debug_return_ke_key_modifiers (modifiers));
+    ke_callbacks.grab (key, modifiers);
+}
 
-/**
- *
- * ke_call_keyboard_layer_cb
- *
- * @buf:string whit the SREvent will be called.
- * @flag: event flag (KE_LAYER_CHANGE , KE_LAYER_TIME_OUT or 0 flag).
- * @event_type: SREventType.
- * 
- * Emit command layer change event.
- *
- * return:
-**/
-static void 
-ke_call_keyboard_layer_cb (const gchar *buf, 
-			   gint 	flag,
-			   SREventType  event_type)
-{
-    SREvent *evnt = NULL;
-    IdleStruct *ke_idle;
-    
-    sru_return_if_fail (buf);
-    sru_return_if_fail (strlen(buf) != 0);
-    
-    /* create SREvent structure */
-    evnt = sre_new ();
-    
-    sru_return_if_fail (evnt);
-
-    /* fill the event structure */
-    evnt->data = g_strdup(buf);
-    evnt->type = event_type;
-    evnt->data_destructor = g_free;
-	
-    sru_debug ("Command event:%d <%s>", event_type, buf);
-    
-    if (evnt->data)
-    {
-    	ke_log_gnopernicus (evnt);
+static void
+ke_report_keyboard_hit ()
+{
+    g_assert (ke_callbacks.hit);
 
-	/* call event sink from srcore */
-        if (ke_keyboard_event_sink_cb != NULL) 
-	{
-	    sre_add_reference (evnt);
-	    ke_idle = ke_idle_struct_new ();
-	    ke_idle->flag = flag;
-	    ke_idle->evnt = evnt;
-	    g_idle_add (ke_repot_layer_cmd, ke_idle);
-	}
-    }	
-    sre_release_reference (evnt);
+    sru_debug_log ("hit", "hit");
+    ke_callbacks.hit ();
 }
 
+static void
+ke_report_command (const gchar *key,
+		   KEKeyModifier modifiers)
+{
+    g_assert (key && ke_callbacks.command);
+
+    sru_debug_log ("command", "key \"%s\" with modifiers %s",
+			    key, ke_debug_return_ke_key_modifiers (modifiers));
+    ke_callbacks.command (key, modifiers);
+}
 
-/**
- *
- * ke_press_wait_function 
- *
- * @user_data:
- *
- * Layer change timer callback.
- *
- * return: FALSE when a timer is destroyed.
- *
-**/
-static gboolean
-ke_press_wait_function (gpointer user_data)
+static void
+ke_report_mouse_moved (gint x,
+		       gint y)
 {
-    /* check if other key is pressed then 0 */
-    if (ke_layer_state != KE_LAYER_STATE_IDLE)
-    {
-	gchar *cmd;
-	
-	ke_layer_state = KE_LAYER_STATE_IDLE;
-				
-	cmd = g_strdup_printf("L%02d", ke_layer_level);				
-
-	/* send the time out event */	
-	ke_call_keyboard_layer_cb (cmd, 
-				    KE_LAYER_TIME_OUT, 
-				    SR_EVENT_COMMAND_LAYER_CHANGED);
-	
-	sru_debug ("Command code %s TIMEOUT", cmd);				
+    g_assert (ke_callbacks.mouse_move);
 
-	g_free (cmd);
-    }
-    
-    return FALSE;
+    sru_debug_log ("mouse", "mouse moved to (%d-%d)", x, y);
+    ke_callbacks.mouse_move (x, y);
 }
 
-/**
-*
-* ke_report_layer_key  
-*
-* @key: AcceesibleKeystroke structure.
-* @user_data:
-*
-* Layer command key event callback.
-*
-* return: TRUE if consume a key event.
-**/
-static SPIBoolean 
-ke_report_layer_key_event (const AccessibleKeystroke *key, gpointer user_data)
-{
-    static gboolean layer_busy = FALSE;    
-    static GQueue  *layer_queue = NULL;
-    static gint	    layer_timeout_id = 0;
-    KEKeyEvent     *ev;
-    
-    sru_debug ("(Layer)Received key event:\n\tsym %ld (%c)\n\tmods %x\n\tcode %d\n\ttime %ld\n\tkeystring \"%s\"\n\ttype %d (press = %d, release = %d)",
-	      (glong) key->keyID, (gchar)key->keyID,
-	      (guint) key->modifiers,
-	      (gint) key->keycode, 
-	      (long int) key->timestamp,
-	      key->keystring,
-	      (gint) key->type, (gint)SPI_KEY_PRESSED, (gint)SPI_KEY_RELEASED );   
-
-    ke_log_at_spi (key);	          
-    
-    /* filter the release events */
-    if (key->type == SPI_KEY_RELEASED)
-    {
-	sru_debug ("keyrelease received");
-	return TRUE;
-    }
+static void
+ke_report_at_spi_mouse_moved (const AccessibleEvent *event,
+			      void *data)
+{
+    g_assert (event);
 
-    /* create event structure */
-    ev = (KEKeyEvent *) g_new0 (KEKeyEvent, 1);
-    
-    sru_return_val_if_fail (ev, FALSE);
-    
-    /* create the event queue */
-    if (!layer_queue)
-	layer_queue = g_queue_new ();
-
-    /* fill the event structure */
-    ev->keyID     = key->keyID;
-    ev->modifiers = key->modifiers;
-    ev->keycode	  = key->keycode;
-    ev->keystring = NULL;
-    
-    /* push event in queue */
-    g_queue_push_head (layer_queue, ev);
-
-    sru_debug ("layer_busy:%d", layer_busy);
-    
-    /* check for reentrancy */
-    sru_return_val_if_fail (!layer_busy, TRUE);
-    
-    layer_busy = TRUE;
-        
-    while (!g_queue_is_empty (layer_queue))
-    {
-	KEKeyEvent *key1;
-	gint	   level = -1;
+    ke_report_mouse_moved (event->detail1, event->detail2);
+}
+
+static SPIBoolean
+ke_report_at_spi_grab_event (const AccessibleKeystroke *key,
+			     gint index)
+{
+    g_assert (key && key->keystring);
+    g_assert (index >= 0 && index < G_N_ELEMENTS (ke_keys_info));
+    g_assert (ke_keys_info[index].data);
+
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("grab");
+
+    if (key->type == SPI_KEY_PRESSED)
+	ke_report_keyboard_grab (ke_keys_info[index].data,
+			ke_get_ke_modifiers_from_at_spi_flags (key->modifiers));
+
+    return SPI_true;
+}
+
+static SPIBoolean
+ke_try_report_at_spi_grab_event (const AccessibleKeystroke *key,
+			         gint index)
+{
+    if (ke_keyboard_grabbing)
+	return ke_report_at_spi_grab_event (key, index);
+
+    return SPI_false;
+}
+
+static SPIBoolean
+ke_report_at_spi_hit_event (const AccessibleKeystroke *key,
+			    gint index)
+{
+    g_assert (key && key->keystring);
+
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("hit");
 	
-	/* pop event from queue */
-	key1 = (KEKeyEvent *) g_queue_pop_tail (layer_queue);
-		
-	/* check if it is a valid numpad key and return the level */
-	if ((level = ke_return_key (key1->keyID)) != -1)
-	{
-	    switch (ke_layer_state)
-	    {
-		case KE_LAYER_STATE_IDLE:
-		{
-		    if (level == 0)
-		    {			    
-			sru_debug ("Layer change key pressed");
-			    
-			ke_layer_state = KE_LAYER_STATE_LEVEL;
-			    
-			/* wait to press a numpad key that to change the layer */
-			layer_timeout_id = g_timeout_add (KE_TIME_WAIT , 
-							  ke_press_wait_function , 
-							  NULL);
-		    }
-		    else
-		    {
-			gchar *cmd = NULL;
-			    
-			ke_layer_state = KE_LAYER_STATE_IDLE;
-
-			/* create a command */
-			cmd = g_strdup_printf ("L%02dK%02d", 
-						ke_layer_level, 
-						level);				
-						    
-			ke_call_keyboard_layer_cb (cmd, 0, SR_EVENT_COMMAND_LAYER);
-				    
-			sru_debug ("Command code %s",cmd);				
-			
-			g_free (cmd);
-		    }
-		    break;
-		}
-		case KE_LAYER_STATE_LEVEL:
-		{
-		    gchar *cmd = NULL;
-		    
-		    if (layer_timeout_id)
-			g_source_remove (layer_timeout_id);
-		    
-		    layer_timeout_id = 0;
-		    
-		    ke_layer_level   = level;
-			    
-		    /* create a layer change command */
-		    cmd = g_strdup_printf ("L%02d", ke_layer_level);
-					
-		    ke_call_keyboard_layer_cb ( cmd, 
-						KE_LAYER_CHANGED, 
-						SR_EVENT_COMMAND_LAYER_CHANGED);
-			     
-		    sru_debug ("Command:%s",cmd);
-			    
-		    g_free (cmd);
-			    
-		    ke_layer_state = KE_LAYER_STATE_IDLE;
-			
-		    break;
-		}
-		default:
-		    ke_layer_state = KE_LAYER_STATE_IDLE;
-		break;
-	    }
-	}
-	else
-	    ke_layer_state = KE_LAYER_STATE_IDLE;
+    if (key->type == SPI_KEY_PRESSED)
+    	ke_report_keyboard_hit ();
 
-	g_free (key1);
-    }
+    return SPI_false;
+}
 
-    g_queue_free (layer_queue);
-    layer_queue = NULL;
-    layer_busy = FALSE;
-  
-    return TRUE;
+static SPIBoolean
+ke_try_report_at_spi_hit_event (const AccessibleKeystroke *key,
+				gint index)
+{
+    return ke_report_at_spi_hit_event (key, index);
 }
 
+static SPIBoolean
+ke_report_at_spi_modifier_event (const AccessibleKeystroke *key,
+				 gint index)
+{
+    g_assert (key && key->keystring);
+    g_assert (index >= 0 && index < G_N_ELEMENTS (ke_keys_info));
+    g_assert (ke_keys_info[index].data);
 
-/**
- * ke_key_set_item_new
- *
- * Create keyset item.
- *
- * return: new keyset item.
-**/
-static KeySetItem*
-ke_key_set_item_new (void)
-{
-    KeySetItem *item = NULL;
-    
-    item = (KeySetItem *) g_new0 (KeySetItem, 1);
-    
-    return item;    
-}
-
-/**
- * ke_key_set_item_free
- *
- * @item:
- *
- * Free keyset item.
-**/
-static void
-ke_key_set_item_free (KeySetItem *item)
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("modifier");
+
+    if (key->type == SPI_KEY_PRESSED)
+	ke_report_modifier (ke_keys_info[index].data, 
+				ke_get_ke_action_from_at_spi_type (key->type));
+
+    return SPI_false;
+}
+
+static SPIBoolean
+ke_try_report_at_spi_modifier_event (const AccessibleKeystroke *key,
+				     gint index)
 {
-    sru_return_if_fail (item);
-    
-    if (item->keyset)
-        SPI_freeAccessibleKeySet (item->keyset);
-
-    g_free (item);
-}
-
-/**
- * ke_translate_key_revers
- *
- * @keystring:
- *
- * Translate from keystring to shfited key.
- *
- * return: key.
-**/
-static gchar*
-ke_translate_key_revers (const gchar *keystring,
-			gboolean shift_modifier)
+    return ke_report_at_spi_modifier_event (key, index);
+}
+
+static SPIBoolean
+ke_report_at_spi_cursor_event (const AccessibleKeystroke *key,
+			       gint index)
 {
-    gint i;
+    g_assert (key && key->keystring);
+    g_assert (index >=0 && index < G_N_ELEMENTS (ke_keys_info));
+    g_assert (ke_keys_info[index].data);
 
-    sru_return_val_if_fail (keystring, NULL);
-    
-    if (strlen (keystring) == 1 && g_ascii_isalpha (*keystring))
-    {
-	return g_ascii_strup (keystring, -1);
-    }
-    	
-    for (i = 0 ; i < G_N_ELEMENTS (key_trans_table) ; i++)
-    {
-	if (!strcmp (keystring, key_trans_table[i].key))
-	{
-	    if (!shift_modifier)
-		return g_strdup (key_trans_table[i].key);
-		
-	    return g_strdup (key_trans_table[i].key_shifted);
-	}
-    }
-    
-    return g_strdup (keystring);
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("cursor");
+
+    if (key->type == SPI_KEY_PRESSED)
+	ke_report_cursor (ke_keys_info[index].data);
+
+    return SPI_false;
 }
 
-/**
- * ke_translate_key
- *
- * Translate from keystring to key.
- *
-**/
-gchar*
-ke_translate_key (const gchar *key)
+static SPIBoolean
+ke_try_report_at_spi_cursor_event (const AccessibleKeystroke *key,
+			    	   gint index)
 {
-    gint i;
-    
-    for (i = 0 ; i < G_N_ELEMENTS (key_trans_table) ; i++)
+    return ke_report_at_spi_cursor_event (key, index);
+}
+
+static gboolean 
+ke_layer_timeout (gpointer data)
+{
+    if (ke_cnt_numpad_changes == GPOINTER_TO_INT (data)) /* is for last numpad event */
     {
-	if (!strcmp (key, key_trans_table[i].key))
-	{
-	    return g_strdup (key_trans_table[i].key_shifted);
-	}
+	ke_cnt_numpad_changes++; /* == (changing_layer = FALSE) */
+	ke_report_layer_back ();
     }
-    return g_strdup (key);
+
+    return FALSE;
 }
 
-/**
- * ke_string_to_keycode
- *
- * @string:
- *
- * Covert string to keycode.
- *
- * return: keycode.
-**/
-static gchar*
-ke_string_to_keysym (const gchar *string, gboolean modifier)
+static SPIBoolean
+ke_report_at_spi_numpad_event (const AccessibleKeystroke *key,
+			       gint index)
 {
-    gchar   *keysym  = NULL;
-    gchar   *tmp_str = NULL;
-    long     lkeysym;
+    gint position;
 
-    modifier = modifier & SPI_KEYMASK_SHIFT;
-    
-    if (g_utf8_strlen (string, -1) == 1)
-    {
-        gunichar uchar = g_utf8_get_char (string);
-	
-	/* check if shift modifier is active */
-        if (modifier)
-	{
-	    if (g_unichar_isdigit (uchar))
-		tmp_str = ke_translate_key (string);
-	    else
-		tmp_str = g_ascii_strup (string, -1);
-	}
-	else
-	{
-	    tmp_str = g_ascii_strdown (string, -1);
-	}
+    g_assert (key && key->keystring);
+    g_assert (index >=0 && index < G_N_ELEMENTS (ke_keys_info));
+
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("numpad");
+
+    if (key->type == SPI_KEY_RELEASED)
+	return SPI_true;
+
+    position = GPOINTER_TO_INT (ke_keys_info[index].data);
+    g_assert (position >= 0 && position <= 15);
+
+    if (ke_cnt_numpad_changes % 2) /* == (changing_layer == TRUE) */
+    {	
+	ke_report_layer_changed (position);
+    	ke_cnt_numpad_changes++; /* == (changing_layer = FALSE) */
+    }
+    else if (position == 0)
+    {
+	sru_debug_log ("numpad", "layer will be changed...");
+	ke_cnt_numpad_changes++; /* == (changing_layer = TRUE) */
+	g_timeout_add (KE_LAYER_TIMEOUT, ke_layer_timeout,
+				    GINT_TO_POINTER (ke_cnt_numpad_changes));
     }
     else
     {
-        if (modifier)
-    	    tmp_str = ke_translate_key (string);
-	else
-	    tmp_str = g_strdup (string);
+	ke_report_layer_key (ke_crt_layer, position);
     }
-    
-    lkeysym  = XStringToKeysym (tmp_str);
-    
-    g_free (tmp_str);
-     
-    if (g_unichar_validate ((guint32)lkeysym))
+
+    return SPI_true;
+}
+
+static SPIBoolean
+ke_try_report_at_spi_numpad_event (const AccessibleKeystroke *key,
+			    	   gint index)
+{
+    return ke_report_at_spi_numpad_event (key, index);
+}
+
+static SPIBoolean
+ke_report_at_spi_command_event (const AccessibleKeystroke *key,
+				gint index)
+{
+    g_assert (key && key->keystring); 
+    g_assert (index >=0 && index < G_N_ELEMENTS (ke_keys_info));
+    g_assert (ke_keys_info[index].data);
+
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("command");
+
+    if (key->type == SPI_KEY_PRESSED)
+	ke_report_command (ke_keys_info[index].data,
+			ke_get_ke_modifiers_from_at_spi_flags (key->modifiers));
+ 
+    return SPI_true;
+}
+
+static gboolean
+ke_at_spi_event_is_command (const AccessibleKeystroke *key)
+{
+    gint i;
+    KEKeyModifier modifiers;
+		
+    g_assert (ke_commands_array && key);
+
+    modifiers = ke_get_ke_modifiers_from_at_spi_flags (key->modifiers);
+    for (i = 0; i < ke_commands_array->len; i++)
     {
-        keysym = (gchar *) g_new0 (gchar *, 8);
-	
-	if (g_unichar_to_utf8 ((guint32)lkeysym, keysym) < 1)
-	    sru_warning ("Invalid character.");
+	KEKeysymKeyModifier info;
+	KeyCode keycode;
+
+	info = g_array_index (ke_commands_array, KEKeysymKeyModifier, i);
+	keycode = ke_get_keycode_from_keysym (info.keysym);
+	if (key->keycode == keycode && info.modifier == modifiers)
+	    return TRUE;
     }
-    
-    return  keysym;
+
+    return FALSE;
 }
 
-/**
- * ke_keysym_to_string:
- *
- * @keysym:
- * @shift_modifier: TRUE if shift modified.
- *
- * Convert keysym to string.
- *
- * return: string.
-**/
-static gchar*
-ke_keysym_to_string (glong keysym, gint modifier)
+static SPIBoolean
+ke_try_report_at_spi_command_event (const AccessibleKeystroke *key,
+				    gint index)
+{
+    if (ke_at_spi_event_is_command (key))
+	return ke_report_at_spi_command_event (key, index);
+
+    return SPI_false;
+}
+
+static SPIBoolean
+ke_report_at_spi_keyboard_event (const AccessibleKeystroke *key,
+				 void *data)
 {
-    gchar *keystring = NULL;
-    gchar *tmp = NULL;
+    gint index, i;
+    SPIBoolean rv = SPI_false;
 
-    /* if special character code [0-32] */
-    if (keysym <= Z_CHAR_POSITION)
-	return g_strdup_printf ("%c", ('A' + (gint)keysym - 1));
-	    	
-    /* return a keystring from keysym */
-    tmp = XKeysymToString (keysym);
-
-    /* translate a key */
-    keystring = ke_translate_key_revers (tmp, (modifier & SPI_KEYMASK_SHIFT));
-
-/*    g_free (tmp);*/ /*FIXME: tmp could be free or not? */
-    return keystring;
-}
-
-/**
-*
-* ke_report_user_key  
-*
-* @key: AcceesibleKeystroke structure.
-* @user_data:
-*
-* User defined key event callback.
-*
-* return: TRUE if consume a key event.
-**/
-static SPIBoolean 
-ke_report_user_key_event (const AccessibleKeystroke *key, gpointer user_data)
-{
-    static gboolean user_busy = FALSE;    
-    static GQueue  *user_queue = NULL;
-    KEKeyEvent     *ev;
-    sru_debug ("(User)Received key event:\n\tsym %ld (%c)\n\tmods %x\n\tcode %d\n\ttime %ld\n\tkeystring \"%s\"\n\ttype %d (press = %d, release = %d)",
-	      (glong) key->keyID, (gchar)key->keyID,
-	      (guint) key->modifiers,
-	      (gint) key->keycode, 
-	      (long int) key->timestamp,
-	      key->keystring,
-	      (gint) key->type, (gint)SPI_KEY_PRESSED, (gint)SPI_KEY_RELEASED );   
+    KEKeyFlag all = SPI_KEYMASK_ALT | 		SPI_KEYMASK_CONTROL |
+		    SPI_KEYMASK_SHIFT |		SPI_KEYMASK_SHIFTLOCK |
+		    SPI_KEYMASK_NUMLOCK | 	SPI_KEYMASK_UNMODIFIED;
+	
+    g_assert (key && key->keystring);
 
-    ke_log_at_spi (key); 
+    sru_debug_log ("event", "start processing event from at-spi...");
 
-    /* Reject release event */     
-    if (key->type == SPI_KEY_RELEASED)
+/* FIXME start */
+    if ((key->modifiers & (~all)))
     {
-	sru_debug ("keyrelease received");
-	return TRUE;
+	g_printerr (_("Keyboard event contains a strange modifier\n"));
+	if (key->modifiers & SPI_KEYMASK_MOD2)
+	{
+	    g_printerr (_("Keyboard \"MOD2\" modifier will be changed with \"NUMLOCK\" modifier\n"));
+	    ((AccessibleKeystroke*)key)->modifiers = 
+		(key->modifiers & (~SPI_KEYMASK_MOD2)) | SPI_KEYMASK_NUMLOCK;
+	}
     }
-    
-    /* create event struct */    
-    ev = (KEKeyEvent *) g_new0 (KEKeyEvent, 1);
-    
-    sru_return_val_if_fail (ev, FALSE);
-
-    /* create queue if not exist yet */
-    if (!user_queue)
-	user_queue = g_queue_new ();
-
-    /* fill event struct */
-    ev->keyID     = key->keyID;
-    ev->modifiers = key->modifiers;
-    ev->keycode	  = key->keycode;
-    ev->keystring = NULL;
-
-    /* push event in queue */
-    g_queue_push_head (user_queue, ev);
-
-    sru_debug ("user_busy:%d", user_busy);
-    /* check for reentrancy */
-    sru_return_val_if_fail (!user_busy, TRUE);
-
-    user_busy = TRUE;
-        
-    while (!g_queue_is_empty (user_queue))
-    {
-	KEKeyEvent *key1;
-	gboolean modif = FALSE;
-	gchar *cmd = NULL;
-	gchar *keystr = NULL;
-    
-	/* pop from queue the event */
-	key1 = (KEKeyEvent *) g_queue_pop_tail (user_queue);
-	/* get the status of modifiers */
-	if (key->modifiers & (~(SPI_KEYMASK_ALT | SPI_KEYMASK_CONTROL | SPI_KEYMASK_SHIFT)))
-	    sru_warning ("Callback invoked with an unexpected modifier.");
-	modif  = key1->modifiers & (SPI_KEYMASK_ALT | SPI_KEYMASK_CONTROL | SPI_KEYMASK_SHIFT);
-	
-	/* get the keystring */
-	keystr = ke_keysym_to_string (key1->keyID, modif);
-        /* create a command */
-	cmd = g_strconcat ( MODIFIER(modif & SPI_KEYMASK_ALT,"A"),
-		    	    MODIFIER(modif & SPI_KEYMASK_CONTROL,"C"),
-		    	    MODIFIER(modif & SPI_KEYMASK_SHIFT,"S"),
-		    	    LINE(modif),
-		    	    STR(keystr), NULL);
-	g_free (key1);
-	g_free (keystr);
-	
-	sru_debug ("(User)keyevent:%s", cmd);	  
+/* FIXME end */
+
+    index = ke_get_key_index_for_keycode (key->keycode);
 
-	/* Verify if this event is registered. */
-	/* This needed until does not fix the BUG: */
-	ke_call_keyboard_layer_cb (cmd, 0, SR_EVENT_COMMAND_LAYER);
+    KE_LOG_AT_SPI_KEYBOARD_EVENT ("event");
 
-	g_free (cmd);
+    if (index < 0)
+	rv = ke_try_report_at_spi_hit_event (key, index);
+    else
+    {
+	for (i = 0; ke_keys_info[index].process[i]; i++)
+	    if (ke_keys_info[index].process[i] (key, index))
+	    {
+		rv = SPI_true;
+		break;
+	    }
     }
 
-    g_queue_free (user_queue);
-    user_queue = NULL;
-    user_busy = FALSE;
-        
-    return TRUE;
+    sru_debug_log ("event", "end of processing event from at-spi");
+
+    return rv;
 }
 
-/**
- * ke_return_modifier_mask
- *
- * @data:
- * @modifiers:
- * @key:
- *
- * Return modifier and key from data.
- *
- * return: FALSE at failed and invalid string.
-**/
 static gboolean
-ke_return_modifier_and_key (const gchar *data,
-			    unsigned long *modifiers,
-			    gchar  **key)
-{
-    gchar *delimit;
-    gchar *iter;
-    unsigned long rv = 0;
-    
-    *modifiers = SPI_KEYMASK_UNMODIFIED;
-    *key = NULL;
-    
-    sru_return_val_if_fail (data, FALSE);
-    
-    delimit = g_strrstr (data, "-");
-
-    if (!delimit)
-    {
-	*key = g_strdup (data);
-	sru_debug ("No delimiter in key combination.");
-	return TRUE;
+ke_register_listeners_for_keyboard ()
+{
+    gboolean rv = FALSE;
+
+    g_assert (kbd_listener == NULL);
+
+    ke_cnt_kbd_listeners = 0;
+    kbd_listener = SPI_createAccessibleKeystrokeListener (
+					ke_report_at_spi_keyboard_event, NULL);
+
+    if (kbd_listener)
+    {
+	KERegisterInfo data;
+
+	data.listener = kbd_listener; 
+	data.acc_set = SPI_KEYSET_ALL_KEYS;
+	data.flags = SPI_KEYMASK_UNMODIFIED;
+	/* data->sync_type = SPI_KEYLISTENER_ALL_WINDOWS | SPI_KEYLISTENER_CANCONSUME; */
+	data.sync_type = SPI_KEYLISTENER_CANCONSUME | SPI_KEYLISTENER_NOSYNC;
+        data.mask = SPI_KEY_PRESSED | SPI_KEY_RELEASED;
+	data.opt_flags = SPI_KEYMASK_ALT   	| SPI_KEYMASK_CONTROL 	|
+			  SPI_KEYMASK_SHIFT 	| SPI_KEYMASK_SHIFTLOCK |
+			  SPI_KEYMASK_NUMLOCK 	| SPI_KEYMASK_UNMODIFIED;
+
+	sru_debug_log ("init", "start registering listeners for all keys...");
+	ke_cnt_kbd_listeners = ke_register_listeners (&data);
+	sru_debug_log ("init",
+	    "end registering listeners for all keys for %ld flags combinations",
+			    ke_cnt_kbd_listeners);
+        rv = TRUE;
     }
-    
-    iter = (gchar*)data;
-    
-    /* get the modifier */
-    while (*iter != '-')
+    else
     {
-	switch (*iter)
-	{
-	    case 'A':
-		rv = rv | SPI_KEYMASK_ALT;
-	    break;
-	    case 'C':
-		rv = rv | SPI_KEYMASK_CONTROL;
-	    break;
-	    case 'S':
-		rv = rv | SPI_KEYMASK_SHIFT;
-	    break;
-	    default:
-		return FALSE;
-	    break;
-	}
-	iter++;
+	g_printerr (_("Unable to create the listener for keyboard\n"));
+	sru_debug_log ("init", "unable to create listener");
     }
-    
-    *modifiers = rv;
-    *key       = g_strdup (delimit + 1);
-    
-    return TRUE;
-}
 
+    if (kbd_listener)
+	AccessibleKeystrokeListener_unref (kbd_listener);
 
-static gboolean
-ke_register_keysetitem (KeySetItem *ksi)
+    return rv;
+}
+
+gboolean
+ke_mouse_move (gint x, gint y)
 {
-    SPIBoolean retval = FALSE;
+    gboolean rv = FALSE;
 
-    retval = SPI_registerAccessibleKeystrokeListener (ke_user_key_listener,
-			    				(AccessibleKeySet *) ksi->keyset,
-				    			ksi->modifier,
-				    			(gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-				    			SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-    ke_print_register_return_value (retval, "");
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
 
-    return TRUE;
-}
+    sru_debug_log ("entry", "start of \"ke_mouse_move\" function");
+    sru_debug_log ("mouse", "mouse will be moved to (%d-%d)", x, y);
+    rv = SPI_generateMouseEvent (x, y, "abs") ? TRUE : FALSE;
+    sru_debug_log ("mouse", "mouse moved %s", rv ? "succeeded" : "failed");
+    sru_debug_log ("entry", "end of \"ke_mouse_move\" function");
 
+    return rv;
+}
 
-/**
- * ke_user_key_list_register_events:
- *
- * @list: user keylist.
- *
- * Register a user keylist events.
- *
-**/
-static void
-ke_user_key_list_register_events (GSList *list)
+gboolean
+ke_mouse_button_action (KEMouseButton button, KEMouseButtonAction action)
 {
-    GSList *elem = NULL;
-    elem = list;
-    
-    while (elem)
-    {
-        unsigned long modifiers;
-	gchar *key;
+    gboolean rv = FALSE;
+    gchar maction[] = "b  ";
 
-	/* return the modifiers	and the key from data */
-	if (ke_return_modifier_and_key ((gchar*)elem->data, &modifiers, &key))
-	{
-	    KeySetItem 		*ksi = NULL;
-	    AccessibleKeySet 	*keyset = NULL;
-	    gchar		*keysym = NULL;
-
-	    modifiers |= SPI_KEYMASK_NUMLOCK;
-	    /* if no key go to next step */
-	    if (!key) 
-	    {
-	    	elem = elem->next;
-		continue;
-	    }
-	    
-	    /* create key set item */
-	    ksi = ke_key_set_item_new ();
-	    
-	    if (!ksi) 
-	    {
-		g_free (key);
-		elem = elem->next;
-		continue;
-	    }
-	    
-	    sru_debug ("Modifier %s combination:%ld-%s",(gchar*)elem->data,modifiers,key);
-	    
-	    /* return a keysym values from key */
-	    keysym   = ke_string_to_keysym (key, modifiers & SPI_KEYMASK_SHIFT);
-	    
-	    /* create an AccessibleKeySet with a keysym */
-	    keyset   = SPI_createAccessibleKeySet (1, (const char*)keysym, NULL, NULL);
-	    
-	    g_free (keysym);
-	    
-	    /* fill the key set item */
-	    ksi->keyset   = keyset;
-	    ksi->modifier = modifiers;
-	    
-	    /* append keyset item in list */
-	    accessible_key_set_list = g_slist_append (accessible_key_set_list, ksi);
-	
-	    /* register key events */
-	    if (ksi->keyset)
-	    {	
-		ke_register_keysetitem (ksi);
-	    }
-	}
-	
-	g_free (key);
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
+
+    sru_debug_log ("entry", "start of \"ke_mouse_button_action\" function");
+
+    if (button == KE_MOUSE_BUTTON_LEFT)
+    	maction[1] = '1'; 
+    else if (button == KE_MOUSE_BUTTON_RIGHT) 
+	maction[1] = '2'; 
+    else if (button == KE_MOUSE_BUTTON_MIDDLE)
+	maction[1] = '3';
+    else
+	g_assert_not_reached ();
 	
-	elem = elem->next;
-    }
-}
+    if (action == KE_MOUSE_BUTTON_PRESS)
+	maction[2] = 'p';
+    else if (action == KE_MOUSE_BUTTON_RELEASE)
+	maction[2] = 'r';
+    else if (action == KE_MOUSE_BUTTON_CLICK)
+	maction[2] = 'c';
+    else if (action == KE_MOUSE_BUTTON_DOUBLECLICK)
+	maction[2] = 'd';
+    else
+	g_assert_not_reached ();
 
+    sru_debug_log ("mouse", "mouse will execute \"%s\"", maction);
+    rv = SPI_generateMouseEvent (-1, -1, maction) ? TRUE : FALSE; 
+    sru_debug_log ("mouse", "mouse execution %s", rv ? "succeeded" : "failed");
 
-static gboolean
-ke_layer_register_events (AccessibleKeystrokeListener *ke_layer_listener,
-			  AccessibleKeySet 	      *ke_layer_keyset)
-{
-    gboolean retval = TRUE;
-    /*
-	Layer key listener. Listen key event from numpad. Listen only if a numlock 
-	is active.
-    */
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif
+    sru_debug_log ("entry", "end of \"ke_mouse_button_action\" function");
 
-    ke_print_register_return_value (retval, "(NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_SHIFTLOCK|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif
-    ke_print_register_return_value (retval, "(SL|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_SHIFT|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif
-    ke_print_register_return_value (retval, "(S|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_ALT|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS				
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif
-    ke_print_register_return_value (retval, "(S|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_CONTROL|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif				      
-    ke_print_register_return_value (retval, "(C|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_ALT|SPI_KEYMASK_SHIFT|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif				      
-    ke_print_register_return_value (retval, "(A|S|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_CONTROL|SPI_KEYMASK_SHIFT|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif
-    ke_print_register_return_value (retval, "(C|S|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
-				      (AccessibleKeySet *) ke_layer_keyset,
-				      SPI_KEYMASK_CONTROL|SPI_KEYMASK_ALT|SPI_KEYMASK_NUMLOCK,
-				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-#ifdef USE_ALL_WINDOWS
-				      SPI_KEYLISTENER_ALL_WINDOWS);
-#else
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-#endif
-    ke_print_register_return_value (retval, "(C|A|NUMLOCK)");
-    
-    return retval;
+    return rv;
 }
 
 static gboolean
-ke_keyecho_register_events (AccessibleKeystrokeListener *ke_key_listener,
-			    AccessibleKeySet 	        *ke_key_keyset)
+ke_register_listener_for_mouse ()
 {
-    gboolean retval = TRUE;
-    /* will listen only to unshifted key events, only press */
-    /*
-	Key echo listener: Listen the following keys: ALT_L, ALT_R, 
-	SHIFT_L, SHIFT_R, Control_L, Control_R, Up, Down, Left, Right, 
-	PageUp, PageDown, Home, End, CapsLock, NumLock,
-    */
-    retval = SPI_registerAccessibleKeystrokeListener (ke_key_listener,
-				      (AccessibleKeySet *) ke_key_keyset,
-				      SPI_KEYMASK_UNMODIFIED,
-				      (gulong) (SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-    ke_print_register_return_value (retval, "(U)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_key_listener,
-				      (AccessibleKeySet *) ke_key_keyset,
-				      SPI_KEYMASK_NUMLOCK,
-				      (gulong) (SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-    ke_print_register_return_value (retval, "(U|NUMLOCK)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_key_listener,
-				      (AccessibleKeySet *) ke_key_keyset,
-				      SPI_KEYMASK_SHIFTLOCK,
-				      (gulong) (SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-    ke_print_register_return_value (retval, "(SL)");
-    retval = SPI_registerAccessibleKeystrokeListener (ke_key_listener,
-				      (AccessibleKeySet *) ke_key_keyset,
-				      SPI_KEYMASK_SHIFTLOCK | SPI_KEYMASK_NUMLOCK,
-				      (gulong) (SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
-				      SPI_KEYLISTENER_NOSYNC | SPI_KEYLISTENER_CANCONSUME);
-    ke_print_register_return_value (retval, "(SL|NUMLOCK)");
-    
-    return retval;
-}
-
-/**
- *
- * ke_get_keypad_keycodes
- *
- * Return a keycode array for numpad keys.
- *
- *
- * return: keycode array.
-**/
-static short*
-ke_get_keypad_keycodes (void)
-{
-    Display *display;
-    short *keycodes = (short *) g_new0 (short *, COUNT_OF_ITEM_IN_LAYER_KEYSET);	
-
-    display = GDK_DISPLAY ();
-    
-    keycodes [0] = XKeysymToKeycode (display, XK_KP_0);
-    keycodes [1] = XKeysymToKeycode (display, XK_KP_1);
-    keycodes [2] = XKeysymToKeycode (display, XK_KP_2);
-    keycodes [3] = XKeysymToKeycode (display, XK_KP_3);
-    keycodes [4] = XKeysymToKeycode (display, XK_KP_4);
-    keycodes [5] = XKeysymToKeycode (display, XK_KP_5);
-    keycodes [6] = XKeysymToKeycode (display, XK_KP_6);
-    keycodes [7] = XKeysymToKeycode (display, XK_KP_7);
-    keycodes [8] = XKeysymToKeycode (display, XK_KP_8);
-    keycodes [9] = XKeysymToKeycode (display, XK_KP_9);
-    keycodes [10] = XKeysymToKeycode (display, XK_KP_Decimal);
-    keycodes [11] = XKeysymToKeycode (display, XK_KP_Enter);
-    keycodes [12] = XKeysymToKeycode (display, XK_KP_Add);
-    keycodes [13] = XKeysymToKeycode (display, XK_KP_Subtract);
-    keycodes [14] = XKeysymToKeycode (display, XK_KP_Multiply);
-    keycodes [15] = XKeysymToKeycode (display, XK_KP_Divide);
-    /* Fix for bug #148774 - some kbds report XK_KP_Separator in numpad */
-    keycodes [16] = XKeysymToKeycode (display, XK_KP_Separator);
-    	
-    return keycodes;
-}
-
-/**
- *
- * ke_get_key_keysyms
- *
- * Return a keysym array for a specific sticky and other function keys. 
- *
- * return: keysym array
- *
-**/
-long keyecho_keysym[] = { 
-    XK_Alt_L, 
-    XK_Alt_R,
-    XK_Shift_L,
-    XK_Shift_R,
-    XK_Control_L,
-    XK_Control_R,
-    XK_Caps_Lock,
-    XK_Num_Lock,
-    XK_Home,
-    XK_End,
-    XK_Left,
-    XK_Right,
-    XK_Up,
-    XK_Down,
-    XK_Page_Up,
-    XK_Page_Down,
-    XK_BackSpace,
-    XK_Delete,
-    XK_Escape,
-    XK_Super_L,
-    XK_Super_R,    
-    XK_Hyper_L,
-    XK_Hyper_R,
-    XK_Menu
-};
+    SPIBoolean rv = FALSE;
 
-gchar*
-ke_get_keyecho_keysyms (void)
-{
-    gchar *rv = NULL;
-    gint i;
-    Display *disp;
-    disp = GDK_DISPLAY ();
-
-    for (i = 0 ; i < G_N_ELEMENTS(keyecho_keysym) ; i++)
+    ke_mouse_listener = SPI_createAccessibleEventListener (
+					ke_report_at_spi_mouse_moved, NULL); 
+    if (ke_mouse_listener)
     {
-	short key;
-	key = XKeysymToKeycode (disp, keyecho_keysym[i]);
-	if (g_unichar_validate ((guint32)key)) 
-        {
-	    gchar *keysym = NULL;
-    	    gchar *tmp = NULL;
-	
-    	    keysym = (gchar *) g_new0 (gchar *, 8);
-	
-	    g_unichar_to_utf8 ((guint32)keyecho_keysym[i], keysym);
-	
-	    if (rv)
-		tmp = g_strconcat (rv, keysym, NULL);
-	    else
-		tmp = g_strdup (keysym);
-		
-	    g_free (keysym);
-	    g_free (rv);
-	    rv = tmp;
-        }
+	rv = SPI_registerGlobalEventListener (ke_mouse_listener, "mouse:abs");
+	sru_debug_log ("mouse", "registering the listener for mouse events %s",
+				    rv ? "succeeded" : "failed");
     }
-    
+
+    if (ke_mouse_listener)
+	AccessibleEventListener_unref (ke_mouse_listener);
+
+    if (!rv)
+        g_printerr (_("Unable to create the listener for mouse events\n"));
+
     return rv;
 }
 
+gboolean
+ke_init (const KECallbacks *callbacks)
+{
+    g_assert (callbacks);
+    g_assert (sru_module_flag_check_uninitialized (ke_module_flag));
 
-/**
- * ke_get_config_settings:
- *
- * @list: Return user defined keys list.
- *
- * Used to get working parameters,
- *
- * return: FALSE at fail.
-**/
-static gboolean
-ke_get_config_settings (GSList **list)
+    SRU_DEBUG_ADD_MODULE_AND_SCOPES;
 
-{
-    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;
+    sru_debug_log ("entry", "start of \"ke_init\" function");
 
-    return TRUE;
+    ke_crt_layer 	  = KE_LAYER_DEFAULT;
+    ke_cnt_numpad_changes = 0;
+
+    kbd_listener  	  = NULL;	
+    ke_mouse_listener	  = NULL;
+    ke_keyboard_grabbing  = FALSE;
+	
+    ke_cnt_kbd_listeners  = 0;
+    ke_commands_array 	  = g_array_new (FALSE, TRUE,
+						sizeof (KEKeysymKeyModifier));
+
+    ke_callbacks = *callbacks;
+
+    ke_register_listeners_for_keyboard ();
+    ke_register_listener_for_mouse ();
+	
+    sru_module_flag_set_initialized (ke_module_flag);
+
+    sru_debug_log ("entry", "end of \"ke_init\" function");
+
+    return TRUE;	
 }
 
-/**
- * ke_user_key_list_free:
- *
- * @list: user_key_list
- *
- * Free a user key list.
- *
-**/
 static void
-ke_user_key_list_free (GSList *list)
+ke_deregister_listener (AccessibleKeystrokeListener *listener, KECount cnt)
 {
-    GSList *elem = NULL;    
+    KECount i;
 
-    if (!list)
-	return;
+    g_assert (listener && cnt >= 0);
 
-    for (elem = list ; elem ; elem = elem->next)
-	g_free (elem->data);
-    
-    g_slist_free (list);
-    
-    list = NULL;
+    for (i = 0; i < cnt; i++) 
+	AccessibleKeystrokeListener_unref (listener);
 }
 
-
-/**
- * ke_config_changed:
- *
- * Using this function the KE can be notified for configuration changes
-**/
-void 
-ke_config_changed (void)
-{
-    sru_debug ("ke_config_changed invoked.");
-    
-    ke_user_key_list_unregister_events ();  
-    
-    ke_user_key_list_free (ke_user_key_list);
-    ke_user_key_list_free (reg_list);
-    ke_user_key_list = NULL;
-    
-    if (ke_get_config_settings (&ke_user_key_list))
-    {
-	ke_user_key_list_register_events (ke_user_key_list);
-    }
+static void
+ke_deregister_listeners_for_keyboard ()
+{
+    ke_deregister_listener (kbd_listener, ke_cnt_kbd_listeners);
 }
 
+static void
+ke_deregister_listener_for_mouse ()
+{
+    g_assert (ke_mouse_listener);
 
-/**
- * ke_init:
- *
- * @kecb: the callback function used to send data to caller
- *
- * This function initialize the keyboard echo library, set the working
- * parameters, create and register key listener(s)
- *
- * return: TRUE at success.
-**/
-gboolean
-ke_init (KeyboardEchoCB kecb)
+    AccessibleEventListener_unref (ke_mouse_listener);
+}
+
+void
+ke_terminate (void)
 {
-    short  *ke_layer_keycodes = NULL;
-    gchar  *ke_keyecho_keysyms = NULL;
-  
-    sru_return_val_if_fail (ke_keyboard_status == KE_IDLE, FALSE);
-    sru_return_val_if_fail (kecb, FALSE);
-
-    /*
-	Get log flag from enviroment
-    */    
-    ke_get_log_flag ();
-    
-    sru_debug ("ke_init...");
-    
-    /*
-	Attribute keyboard event sink function from srcore.
-    */
-    ke_keyboard_event_sink_cb = kecb;
-
-    /*
-	User keys get from gconf.
-    */
-    ke_user_key_list = NULL;
-    ke_get_config_settings (&ke_user_key_list);
-      
-    /* 
-	Prepare the keyboard snoopers 
-    */
-    ke_layer_listener 	 = SPI_createAccessibleKeystrokeListener (ke_report_layer_key_event, NULL);
-    ke_user_key_listener = SPI_createAccessibleKeystrokeListener (ke_report_user_key_event, NULL);
-    ke_keyecho_listener  = SPI_createAccessibleKeystrokeListener (ke_report_keyecho_event, NULL);
-    
-    /*
-	Layer commands.
-    */
-    ke_layer_keycodes = ke_get_keypad_keycodes ();
-    ke_layer_keyset   = SPI_createAccessibleKeySet (COUNT_OF_ITEM_IN_LAYER_KEYSET, NULL, ke_layer_keycodes, NULL);
-    g_free (ke_layer_keycodes);
-
-    /*
-	Keyboard echo.
-    */
-    ke_keyecho_keysyms = ke_get_keyecho_keysyms ();
-    ke_keyecho_keyset  = SPI_createAccessibleKeySet (G_N_ELEMENTS (keyecho_keysym),ke_keyecho_keysyms, NULL, NULL);
-    g_free (ke_keyecho_keysyms);
-
-    /*
-	User key registering.
-    */  
-    if (ke_user_key_list)
-	ke_user_key_list_register_events (ke_user_key_list);
-
-    /*
-	Layer key registering.
-    */    
-    ke_layer_register_events (ke_layer_listener,
-			     (AccessibleKeySet *) ke_layer_keyset);
-    /*
-	Keyboard echo key registering.
-    */
-    ke_keyecho_register_events  (ke_keyecho_listener,
-				(AccessibleKeySet *) ke_keyecho_keyset);
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
 
-    ke_keyboard_status = KE_RUNNING;
+    sru_debug_log ("entry", "start of \"ke_terminate\" function");
 
-    sru_debug ("done.status = KE_RUNNING");
+    if (kbd_listener)
+	ke_deregister_listeners_for_keyboard ();
 
-    return TRUE;
+    if (ke_mouse_listener)
+	ke_deregister_listener_for_mouse ();
+
+    g_assert (ke_commands_array && ke_commands_array->len == 0);
+    g_array_free (ke_commands_array, TRUE);
+
+    g_assert (ke_keyboard_grabbing == FALSE);
+
+    sru_module_flag_set_uninitialized (ke_module_flag);
+
+    sru_debug_log ("entry", "end of \"ke_terminate\" function");
 }
 
-/**
- * ke_user_key_list_unregister_events:
- *
- * Unregister user keys.
- *
- * return: TRUE if success.
-**/
-static gboolean
-ke_user_key_list_unregister_events (void)
+gboolean
+ke_command_add (const gchar *key, KEKeyModifier modifier)
 {
-    GSList *elem = NULL;
+    gint i;
+    KEKeysymKeyModifier info;
+	
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
+
+    sru_debug_log ("entry", "start of \"ke_command_add\" function");
+
+    info.keysym = ke_get_keysym_from_keys_info (key);
+    g_assert (info.keysym != NoSymbol);
+    info.modifier = modifier;
+    g_assert ((info.modifier & 
+	(~(KE_MODIFIER_ALT | KE_MODIFIER_CONTROL | KE_MODIFIER_SHIFT))) == 0);
 
-    if (!accessible_key_set_list)
-	return FALSE;
-    	
-    elem = accessible_key_set_list;
-    
-    while (elem)
+#ifdef SR_DEBUG
+    for (i = 0; i < ke_commands_array->len; i++)
     {
-	KeySetItem *ksi = elem->data;
-	
-	SPI_deregisterAccessibleKeystrokeListener (ke_user_key_listener, 
-						   ksi->modifier);
+        KEKeysymKeyModifier info2;
 
-	ke_key_set_item_free (ksi);
-	
-	elem->data = NULL;
-	
-	elem = elem->next;
+	info2 = g_array_index (ke_commands_array, KEKeysymKeyModifier, i);
+	if (info.keysym == info2.keysym && info.modifier == info2.modifier)
+	{
+	    g_assert_not_reached ();
+	    return FALSE;
+	}
     }
-    
-    g_slist_free (accessible_key_set_list);
-    
-    accessible_key_set_list = NULL;
-    
+#endif
+
+    sru_debug_log ("command", "key \"%s\" with modifiers %s added as command",
+			    key, ke_debug_return_ke_key_modifiers (modifier));
+
+    g_array_append_val (ke_commands_array, info);
+
+    sru_debug_log ("entry", "end of \"ke_command_add\" function");
+
     return TRUE;
 }
 
-static void 
-ke_layer_unregister_events (void)
-{
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK | 
-					    SPI_KEYMASK_SHIFTLOCK);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK | 
-					    SPI_KEYMASK_SHIFT);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK | 
-					    SPI_KEYMASK_ALT);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK | 
-					    SPI_KEYMASK_CONTROL);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK  | 
-					    SPI_KEYMASK_SHIFT |
-					    SPI_KEYMASK_CONTROL);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK  | 
-					    SPI_KEYMASK_ALT   |
-					    SPI_KEYMASK_CONTROL);
-    SPI_deregisterAccessibleKeystrokeListener (ke_layer_listener, 
-					    SPI_KEYMASK_NUMLOCK  | 
-					    SPI_KEYMASK_SHIFT |
-					    SPI_KEYMASK_ALT);
+void
+ke_commands_remove_all ()
+{		
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
+    g_assert (ke_commands_array);
+
+    sru_debug_log ("entry", "start of \"ke_commands_remove_all\" function");
+    sru_debug_log ("command", "all commands removed");
+    g_array_set_size (ke_commands_array, 0);
+    sru_debug_log ("entry", "end of \"ke_commands_remove_all\" function");
 }
 
-static void
-ke_keyecho_unregister_events (void)
+gboolean
+ke_start_keyboard_grab ()
 {
-    /* deregister keylisteners */
-    SPI_deregisterAccessibleKeystrokeListener (ke_keyecho_listener, 
-					    SPI_KEYMASK_UNMODIFIED );
-    SPI_deregisterAccessibleKeystrokeListener (ke_keyecho_listener, 
-					    SPI_KEYMASK_NUMLOCK );
-    SPI_deregisterAccessibleKeystrokeListener (ke_keyecho_listener, 
-					    SPI_KEYMASK_SHIFTLOCK );
-    SPI_deregisterAccessibleKeystrokeListener (ke_keyecho_listener, 
-					    SPI_KEYMASK_SHIFTLOCK |
-					    SPI_KEYMASK_NUMLOCK );
-}
-
-/**
- * ke_terminate
- *
- * Deregister key listener(s)
- *
-**/
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
+    g_assert (ke_keyboard_grabbing == FALSE);
+
+    sru_debug_log ("entry", "start of \"ke_start_keyboard_grab\" function");
+
+    ke_keyboard_grabbing = TRUE;
+
+    sru_debug_log ("entry", "end of \"ke_start_keyboard_grab\" function");
+
+    return TRUE;
+}
+
 void
-ke_terminate (void)
+ke_stop_keyboard_grab ()
 {
-    sru_return_if_fail (ke_keyboard_status != KE_IDLE);
-    
-    sru_debug ("ke_terminate...");
-
-    /* unregister keyecho events */
-    ke_keyecho_unregister_events ();
-    
-    /* unregister layer events */
-    ke_layer_unregister_events ();
-    
-    /* unregister user_defined events */
-    ke_user_key_list_unregister_events ();  
-    
-    ke_user_key_list_free (ke_user_key_list);
-    ke_user_key_list_free (reg_list);
-    
-    /* unref key listeners */
-    AccessibleKeystrokeListener_unref (ke_layer_listener);
-    AccessibleKeystrokeListener_unref (ke_keyecho_listener);
-    AccessibleKeystrokeListener_unref (ke_user_key_listener);  
-  
-    SPI_freeAccessibleKeySet (ke_layer_keyset);
-    SPI_freeAccessibleKeySet (ke_keyecho_keyset);    
-	
-    ke_keyboard_status = KE_IDLE;
-    
-    sru_debug ("done.");
+    g_assert (sru_module_flag_check_initialized (ke_module_flag));
+    g_assert (ke_keyboard_grabbing == TRUE);
+
+    sru_debug_log ("entry", "start of \"ke_end_keyboard_grab\" function");
+
+    ke_keyboard_grabbing = FALSE;
+
+    sru_debug_log ("entry", "end of \"ke_end_keyboard_grab\" function");
 }
Index: gnopernicus/kbd_mouse/libke/libke.h
===================================================================
RCS file: /cvs/gnome/gnopernicus/kbd_mouse/libke/libke.h,v
retrieving revision 1.11
diff -u -r1.11 libke.h
--- gnopernicus/kbd_mouse/libke/libke.h	25 Jul 2005 14:21:50 -0000	1.11
+++ gnopernicus/kbd_mouse/libke/libke.h	3 Apr 2006 13:21:15 -0000
@@ -18,55 +18,74 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#ifndef _LIBKE_H
-#define _LIBKE_H
+
+#ifndef __LIBKE_H__
+#define __LIBKE_H__
 
 #include <glib.h>
-#include "SREvent.h"
 
+typedef enum
+{
+    KE_MODIFIER_UNMODIFIED	= 0,
+    KE_MODIFIER_ALT 		= (1 << 0),
+    KE_MODIFIER_CONTROL		= (1 << 1),
+    KE_MODIFIER_SHIFT		= (1 << 2)
+}KEKeyModifier;
 
-#define KE_LAYER_TIME_OUT 1
-#define KE_LAYER_CHANGED 0
+typedef enum
+{
+    KE_KEY_PRESSED,
+    KE_KEY_RELEASED
+}KEKeyAction;
+
+typedef void (*KeReportKeyboardGrab) 	(const gchar *key, KEKeyModifier modifier);
+typedef void (*KeReportCommand) 	(const gchar *key, KEKeyModifier modifier);
+typedef void (*KeReportKeyboardHit) 	();
+typedef void (*KeReportCursor) 		(const gchar *cursor);
+typedef void (*KeReportModifier) 	(const gchar *modifier, KEKeyAction action);
+typedef void (*KeReportLayerChanged)	(gint layer);
+typedef void (*KeReportLayerBack) 	(gint layer);
+typedef void (*KeReportLayerKey) 	(gint layer, gint key);
+typedef void (*KeReportMouseMove) 	(gint x, gint y);
+
+typedef struct
+{
+    KeReportKeyboardGrab grab;
+    KeReportKeyboardHit	 hit;
+    KeReportCommand	 command;
+    KeReportCursor 	 cursor;
+    KeReportModifier 	 modifier;
+    KeReportLayerKey 	 layer_key;
+    KeReportLayerChanged layer_ch;
+    KeReportLayerBack 	 layer_back;
+    KeReportMouseMove	 mouse_move;
+}KECallbacks;
 
-/**
- * KeyboardEchoCB:
- *
- * prototype of the function used for communication.
- * The SREvent structure is used to encapsulate the character string 
- * received. The content of this string depends on the keyboard echo 
- * mode, which can be letter, word or auto. The flags is not used yet.
- *
-**/
-#define KeyboardEchoCB SROnEventProc
-
-/**
- * SRHotkeyKeyModifiers:
- *
- * an enum used in SRHotkeyData indicating the key modifiers 
-**/
-typedef enum {
-    SRHOTKEY_ALT 	= (1 << 0),
-    SRHOTKEY_CTRL 	= (1 << 1),
-    SRHOTKEY_SHIFT	= (1 << 2)
-} SRHotkeyKeyModifiers;
-
-/**
- * SRHotkeyData:
- *
- * the structure encapsulated in SREvent
- *
-**/
-typedef struct _SRHotkeyData
+typedef enum _KEMouseButton
 {
-    unsigned long keyID;
-    unsigned int modifiers;
-    gchar *keystring; 
-} SRHotkeyData;
+    KE_MOUSE_BUTTON_LEFT,	
+    KE_MOUSE_BUTTON_RIGHT,
+    KE_MOUSE_BUTTON_MIDDLE
+}KEMouseButton;
+
+typedef enum _KEMouseButtonAction
+{
+    KE_MOUSE_BUTTON_PRESS,	
+    KE_MOUSE_BUTTON_RELEASE,
+    KE_MOUSE_BUTTON_CLICK,
+    KE_MOUSE_BUTTON_DOUBLECLICK
+}KEMouseButtonAction;
+
+gboolean     ke_init 	  	    (const KECallbacks *callbacks);
+void 	     ke_terminate 	    ();
+
+gboolean     ke_command_add 	    (const gchar *key, KEKeyModifier modifier);
+void         ke_commands_remove_all ();
 
+gboolean     ke_start_keyboard_grab ();
+void         ke_stop_keyboard_grab  ();
 
-int 	ke_init (KeyboardEchoCB kecb);
-void 	ke_terminate ();
-void 	ke_config_changed ();
-void 	ke_set_default_configuration ();
+gboolean     ke_mouse_move 	    (gint x, gint y);
+gboolean     ke_mouse_button_action (KEMouseButton button, KEMouseButtonAction action);
 
-#endif
+#endif /* __LIBKE_H__ */
Index: gnopernicus/kbd_mouse/test/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnopernicus/kbd_mouse/test/Makefile.am,v
retrieving revision 1.6
diff -u -r1.6 Makefile.am
--- gnopernicus/kbd_mouse/test/Makefile.am	11 Apr 2003 13:11:43 -0000	1.6
+++ gnopernicus/kbd_mouse/test/Makefile.am	3 Apr 2006 13:21:15 -0000
@@ -2,12 +2,11 @@
 INCLUDES = -I$(srcdir)				\
 	   -I$(srcdir)/../libke  		\
 	   -I$(top_srcdir)/srutil 		\
-	   -I$(top_srcdir)/srconf/libsrconf 	\
 	   $(LIBKE_CFLAGS)			\
 	   -DG_LOG_DOMAIN=\"gnopernicus\"
 
-noinst_PROGRAMS = ke_test
+noinst_PROGRAMS = test 
 
-ke_test_SOURCES = testlibke.c
+test_SOURCES = test.c
 
-LDADD = ../libke/libke.la ../../srutil/libsrutil.la ../../srconf/libsrconf/libsrconf.la
+LDADD = ../libke/libke.la ../../srutil/libsrutil.la
Index: gnopernicus/kbd_mouse/test/test.c
===================================================================
RCS file: gnopernicus/kbd_mouse/test/test.c
diff -N gnopernicus/kbd_mouse/test/test.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/kbd_mouse/test/test.c	3 Apr 2006 13:21:15 -0000
@@ -0,0 +1,798 @@
+/* test.c
+ *
+ * Copyright 2001 - 2005 Sun Microsystems, Inc.,
+ * Copyright 2001 - 2005 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <cspi/spi.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "sru-debug.h"
+#include "sru-test.h"
+#include "libke.h"
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+
+/*#define KET_NUMLOCK_LED_MASK 		2 */
+/*#define KET_CAPSLOCK_LED_MASK 	1 */
+#define KET_START_TEST_WAIT		5
+#define KET_NO_OF_TRIES			3
+#define KET_LINE_LENGTH 		55
+#define KET_DELAY_MIN 			100
+#define KET_DELAY_MAX 			3000
+#define KET_LAYER_BACK_TIMEOUT 		5000
+#define KET_TIME_MAX			(KET_DELAY_MAX + 		\
+					    KET_LAYER_BACK_TIMEOUT + 	\
+					    5000)
+
+typedef void (*KETProcessArray) (GPtrArray *array);
+typedef struct
+{
+    gchar *message;
+    gchar *key;
+    gint   delay;
+    KeySym keysym;
+}KETKeyMessage;
+
+static GPtrArray *ket_keys_array 	= NULL;
+static gboolean	  ket_keyboard_grabbing = FALSE;
+static gboolean	  ket_wait		= TRUE;
+static gint	  ket_index = 0;
+
+
+static KETKeyMessage ket_numpad_keys[] = 
+{
+    {"Press key \"1\" from numpad", 			"LxxK01",	1000,	XK_KP_1		},
+    {"Press key \"2\" from numpad", 			"LxxK02",	1000,	XK_KP_2		},
+    {"Press key \"3\" from numpad", 			"LxxK03",	1000,	XK_KP_3		},
+    {"Press key \"4\" from numpad",		 	"LxxK04",	1000,	XK_KP_4		},
+    {"Press key \"5\" from numpad", 			"LxxK05",	1000,	XK_KP_5		},
+    {"Press key \"6\" from numpad", 			"LxxK06",	1000,	XK_KP_6		},
+    {"Press key \"7\" from numpad", 			"LxxK07",	1000,	XK_KP_7		},
+    {"Press key \"8\" from numpad", 			"LxxK08",	1000,	XK_KP_8		},
+    {"Press key \"9\" from numpad", 			"LxxK09",	1000,	XK_KP_9		},
+    {"Press key \"Decimal/Separator\" from numpad",	"LxxK10",	1000,	XK_KP_Decimal	},
+    {"Press key \"Enter\" from numpad",			"LxxK11",	1000,	XK_KP_Enter	},
+    {"Press key \"Add\" from numpad", 			"LxxK12",	1000,	XK_KP_Add	},
+    {"Press key \"Substract\" from numpad",		"LxxK13",	1000,	XK_KP_Subtract	},
+    {"Press key \"Multiply\" from numpad", 		"LxxK14",	1000,	XK_KP_Multiply	},
+    {"Press key \"Divide\" from numpad",		"LxxK15",	1000,	XK_KP_Divide	},
+    {"Press key \"0\" (and wait more than 5 sec)", 	"Lxx",		1000 + KET_LAYER_BACK_TIMEOUT,	XK_KP_0},
+    {"Press key \"0\" then key \"1\" (don't wait more than 5 sec)", "L01",	1000,	XK_KP_1	}
+};
+
+static KETKeyMessage ket_modifiers_keys[] = 
+{
+    {"Press key \"Window Left\"",	"Window Left",		1000,	XK_Super_L	},
+    {"Press key \"Window Right\"", 	"Window Right",		1000,	XK_Super_R	},    
+    {"Press key \"Alt Left\"",		"Alt Left",		1000,	XK_Alt_L	},
+    {"Press key \"Alt Right\"", 	"Alt Right",		1000,	XK_Alt_R	},
+    {"Press key \"Control Left\"", 	"Control Left",		1000,	XK_Control_L	},
+    {"Press key \"Control Right\"",	"Control Right",	1000,	XK_Control_R	},
+    {"Press key \"Shift Left\"", 	"Shift Left",		1000,	XK_Shift_L	},
+    {"Press key \"Shift Right\"", 	"Shift Right",		1000,	XK_Shift_R	},
+    {"Press key \"CapsLock\"", 		"CapsLock",		1000,	XK_Caps_Lock	},
+    {"Press key \"Numlock\"", 		"NumLock",		1000,	XK_Num_Lock	}
+};
+
+static KETKeyMessage ket_cursors_keys[] = 
+{
+    {"Press key \"Home\"",		"Home",		1000,	XK_Home		},
+    {"Press key \"End\"",	 	"End",		1000,	XK_End		},
+    {"Press key \"Up\"", 		"Up",		1000,	XK_Up		},
+    {"Press key \"Down\"",		"Down",		1000,	XK_Down		},
+    {"Press key \"Left\"", 		"Left",		1000,	XK_Left		},
+    {"Press key \"Right\"", 		"Right",	1000,	XK_Right	},
+    {"Press key \"Page Up\"",		"Page Up",	1000,	XK_Page_Up	},
+    {"Press key \"Page Down\"",		"Page Down",	1000,	XK_Page_Down	},
+    {"Press key \"Backspace\"", 	"BackSpace",	1000,	XK_BackSpace	},
+    {"Press key \"Delete\"", 		"Delete",	1000,	XK_Delete	},
+    {"Press key \"Escape\"", 		"Escape",	1000,	XK_Escape	}
+};
+
+static KETKeyMessage ket_grab_keys[] = 
+{
+    {"Press key \"A\"",			"A",		1000,	XK_a	},
+    {"Press key \"B\"",			"B",		1000,	XK_b	},
+    {"Press key \"C\"",			"C",		1000,	XK_c	},
+    {"Press key \"D\"",			"D",		1000,	XK_d	},
+    {"Press key \"E\"",			"E",		1000,	XK_e	},
+    {"Press key \"F\"",			"F",		1000,	XK_f	},
+    {"Press key \"G\"", 		"G",		1000,	XK_g	},
+    {"Press key \"H\"",			"H",		1000,	XK_h	},
+    {"Press key \"I\"",			"I",		1000,	XK_i	},
+    {"Press key \"J\"",			"J",		1000,	XK_j	},
+    {"Press key \"K\"", 		"K",		1000,	XK_k	},
+    {"Press key \"L\"",			"L",		1000,	XK_l	},
+    {"Press key \"M\"",			"M",		1000,	XK_m	},
+    {"Press key \"N\"",			"N",		1000,	XK_n	},
+    {"Press key \"O\"",			"O",		1000,	XK_o	},
+    {"Press key \"P\"",			"P",		1000,	XK_p	},
+    {"Press key \"Q\"",			"Q",		1000,	XK_q	},
+    {"Press key \"R\"", 		"R",		1000,	XK_r	},
+    {"Press key \"S\"",			"S",		1000,	XK_s	},
+    {"Press key \"T\"",			"T",		1000,	XK_t	},
+    {"Press key \"U\"",			"U",		1000,	XK_u	},
+    {"Press key \"V\"", 		"V",		1000,	XK_v	},
+    {"Press key \"W\"",			"W",		1000,	XK_w	},
+    {"Press key \"X\"",			"X",		1000,	XK_x	},
+    {"Press key \"Y\"",			"Y",		1000,	XK_y	},
+    {"Press key \"Z\"",			"Z",		1000,	XK_z	},
+    {"Press key \"0\"",			"0",		1000,	XK_0	},
+    {"Press key \"1\"",			"1",		1000,	XK_1	},
+    {"Press key \"2\"",			"2",		1000,	XK_2	},
+    {"Press key \"3\"",			"3",		1000,	XK_3	},
+    {"Press key \"4\"",			"4",		1000,	XK_4	},
+    {"Press key \"5\"",			"5",		1000,	XK_5	},
+    {"Press key \"6\"", 		"6",		1000,	XK_6	},
+    {"Press key \"7\"",			"7",		1000,	XK_7	},
+    {"Press key \"8\"",			"8",		1000,	XK_8	},
+    {"Press key \"9\"",			"9",		1000,	XK_9	},
+    {"Press key \"F1\"",		"F1",		1000,	XK_F1	},
+    {"Press key \"F2\"",		"F2",		1000,	XK_F2	},			
+    {"Press key \"F3\"",		"F3",		1000,	XK_F3	},
+    {"Press key \"F4\"",		"F4",		1000,	XK_F4	},
+    {"Press key \"F5\"",		"F5",		1000,	XK_F5	},
+    {"Press key \"F6\"",		"F6",		1000,	XK_F6	},
+    {"Press key \"F7\"",		"F7",		1000,	XK_F7	},
+    {"Press key \"F8\"",		"F8",		1000,	XK_F8	},
+    {"Press key \"F9\"",		"F9",		1000,	XK_F9	},
+    {"Press key \"F10\"",		"F10",		1000,	XK_F10	},			
+    {"Press key \"F11\"",		"F11",		1000,	XK_F11	},
+    {"Press key \"F12\"",		"F12",		1000,	XK_F12	}			
+};
+
+
+static void 
+ket_error ()
+{
+    gdk_beep ();
+}
+
+static void
+ket_write_message_for_first (GPtrArray *array)
+{
+    KETKeyMessage *key_msg;
+    gint i, length;
+
+    g_assert (array && array->len);
+
+    key_msg = g_ptr_array_index (array, 0);
+    g_print ("\n %s  ", key_msg->message);
+
+    length = KET_LINE_LENGTH - strlen (key_msg->message);
+    for (i = 0; i < length; i++)
+	g_print (".");
+    g_print ("  ");
+}
+
+static gboolean
+ket_write_result (gboolean res,
+		  gboolean force)
+{
+    static gint tries = 0;
+    gboolean next = TRUE;
+
+    if (res)
+    {
+    	g_print ("succeeded");
+	tries = 0;
+    }
+    else if (tries == KET_NO_OF_TRIES - 1 || force)
+    {
+	ket_error ();
+	g_print ("failed");
+	tries = 0;
+    }
+    else
+    {
+	ket_error ();
+	tries++;
+	next = FALSE;
+    }
+
+    return next;
+}
+
+static gboolean ket_wait_timeout (gpointer data);
+
+static void
+ket_move_to_next (GPtrArray *array)
+{
+    g_assert (array && array->len);
+
+    ket_index++;
+    g_ptr_array_remove_index (array, 0);
+
+    if (array->len)
+    {
+    	ket_write_message_for_first (array);
+	g_timeout_add (KET_TIME_MAX, ket_wait_timeout,
+						GINT_TO_POINTER (ket_index));
+    }
+    else
+	SPI_event_quit ();
+}
+
+static void
+ket_write_result_and_move_to_next (GPtrArray *array,
+				   gboolean result)
+{
+    if (ket_write_result (result, FALSE))
+	ket_move_to_next (array);
+}
+
+static gboolean 
+ket_wait_timeout (gpointer data)
+{
+    gint index = GPOINTER_TO_INT (data);
+
+    if (ket_index == index)
+    {
+        ket_write_result (FALSE, TRUE);
+	SPI_event_quit (); /* ket_move_to_next (ket_keys_array); ????? */
+    }
+
+    return FALSE;
+}
+
+
+static void
+ket_mouse_move_nothing (gint x,
+			gint y)
+{
+
+}
+
+static void
+ket_grab_print (const gchar *key,
+		KEKeyModifier m)
+{
+    g_assert (key);
+
+    g_print ("\ngrab:\"%s\" with modifiers:%d added as command", key, m);
+    ke_command_add (key, m);
+}
+
+static void
+ket_command_print (const gchar *key,
+		   KEKeyModifier m)
+{
+    g_assert (key);
+
+    g_print ("\ncommand:\"%s\" with modifiers:%d", key, m);
+    if (key[0] == 'Q' && key[1] == '\0')
+	SPI_event_quit ();
+    if (key[0] == 'S' && key[1] == '\0' && !ket_keyboard_grabbing)
+    {
+	g_print ("Keyboard grabbing started");
+	ket_keyboard_grabbing = TRUE;
+	ke_start_keyboard_grab ();
+    }
+    if (key[0] == 'E' && key[1] == '\0' && ket_keyboard_grabbing)
+    {
+    	g_print ("Keyboard grabbing stoped");
+	ket_keyboard_grabbing = FALSE;
+	ke_stop_keyboard_grab ();
+    }
+}
+
+static void
+ket_hit_print ()
+{
+    g_print ("\nhit");
+}
+
+static void
+ket_cursor_print (const gchar *cursor)
+{
+    g_assert (cursor);
+
+    g_print ("\ncursor:\"%s\"", cursor);
+}
+
+static void
+ket_modifier_print (const gchar *modifier,
+		    KEKeyAction action)
+{
+    g_assert (modifier);
+
+    g_print ("\nmodifier:\"%s\"", modifier);
+}
+
+static void
+ket_layer_back_print (gint layer)
+{
+    g_print ("\nback to  layer:%02d", layer);
+}
+
+static void
+ket_layer_changed_print (gint layer)
+{
+    g_print ("\nchange to layer:%02d", layer);
+}
+
+static void
+ket_layer_key_print (gint layer,
+		     gint key)
+{
+    g_print ("\nlayer:%02d   key:%02d", layer, key);
+}
+
+static void
+ket_mouse_move_print (gint x,
+		      gint y)
+{
+    g_print ("\nmouse: x:%02d   y:%02d", x, y);
+}
+
+
+#define KET_CHECK_AUTO(expr)						\
+    {									\
+	KETKeyMessage *key_msg;						\
+									\
+	g_assert (ket_keys_array && ket_keys_array->len);		\
+									\
+	key_msg = g_ptr_array_index (ket_keys_array, 0);		\
+	ket_write_result_and_move_to_next (ket_keys_array, expr);	\
+    }
+
+static void
+ket_layer_back_auto (gint layer)
+{
+    KET_CHECK_AUTO (strcmp (key_msg->key, "Lxx") == 0 &&
+				strlen (key_msg->key) == 3);
+}
+
+static void
+ket_layer_changed_auto (gint layer)
+{
+    KET_CHECK_AUTO (layer == atoi (key_msg->key + 1) &&
+				strlen (key_msg->key) == 3 &&
+				strcmp (key_msg->key, "Lxx") != 0);
+}
+
+static void
+ket_layer_key_auto (gint layer,
+		    gint key)
+{
+    KET_CHECK_AUTO (key == atoi (key_msg->key + 4) &&
+				strlen (key_msg->key) == 6);
+}
+
+static void
+ket_modifier_auto (const gchar *modifier,
+		   KEKeyAction action)
+{
+    if (action != KE_KEY_PRESSED)
+	return;
+
+    g_assert (modifier);
+
+    KET_CHECK_AUTO (strcmp (modifier, key_msg->key) == 0);
+}
+
+static void
+ket_cursor_auto (const gchar *cursor)
+{
+    g_assert (cursor);
+
+    KET_CHECK_AUTO (strcmp (cursor, key_msg->key) == 0);
+}
+
+static void
+ket_grab_auto (const gchar *key,
+	       KEKeyModifier m)
+{
+    g_assert (key);
+
+    KET_CHECK_AUTO (strcmp (key, key_msg->key) == 0);
+}
+
+static void
+ket_hit_auto ()
+{
+    KET_CHECK_AUTO (FALSE);
+}
+
+
+static void
+ket_add_key_messages_to_array (GPtrArray *array,
+			       KETKeyMessage *key_messages,
+			       gint len)
+{
+    gint i;
+
+    g_assert (array && key_messages);
+
+    for (i = 0; i < len; i++)
+	g_ptr_array_add (array, &key_messages[i]);
+}
+
+static gboolean
+ket_generate_key (KeySym keysym)
+{	
+    gboolean rv = FALSE;
+    KeyCode keycode;
+    static Display *display;
+
+    if (!display)
+	display = GDK_DISPLAY ();
+    if (!display)
+    {
+    	g_printerr ("\nInvalid display!");
+	return FALSE;
+    }
+
+    keycode = XKeysymToKeycode (display, keysym);
+    if (keycode)
+	rv = SPI_generateKeyboardEvent (keycode, NULL, SPI_KEY_PRESSRELEASE) ?
+					     TRUE : FALSE;
+    else
+	g_printerr ("\nUnable to get keycode for keysym \"%ld\"", keysym);
+
+    return rv;
+}
+
+static gboolean ket_generate_first_key_from_array (gpointer data);
+
+static gboolean
+ket_generate_first_key_from_array_real (gpointer data)
+{
+    GPtrArray *garray = data;
+    KETKeyMessage *key_info;
+
+    if (data != ket_keys_array)
+	return FALSE;
+
+    g_assert (garray && garray->len);
+
+    key_info = g_ptr_array_index (garray, 0);
+    ket_generate_key (key_info->keysym);
+
+    if (garray->len)
+	g_idle_add (ket_generate_first_key_from_array, data);
+
+    return FALSE;
+}
+
+static gboolean
+ket_generate_first_key_from_array (gpointer data)
+{
+    GPtrArray *garray = data;
+    KETKeyMessage *key_info;
+
+    if (data != ket_keys_array)
+	return FALSE;
+
+    g_assert (garray && garray->len);
+
+    key_info = g_ptr_array_index (garray, 0);
+    if (strlen (key_info->key) == 3 &&
+		    strcmp (key_info->key, "Lxx") != 0) /* layer changed */
+    {
+	ket_generate_key (XK_KP_0);
+	g_usleep (10000);
+    }
+    
+    if (garray->len)
+	g_timeout_add (key_info->delay, ket_generate_first_key_from_array_real, data);
+
+    return FALSE;
+}
+
+static void
+ket_test_listen_array (GPtrArray *array)
+{
+    KECallbacks callbacks;
+
+    SPI_init ();
+
+    ket_keys_array = array;
+    ket_index++;
+
+    callbacks.grab   	 = ket_grab_auto; 
+    callbacks.hit   	 = ket_hit_auto; 
+    callbacks.cursor     = ket_cursor_auto;
+    callbacks.modifier   = ket_modifier_auto;
+    callbacks.layer_key  = ket_layer_key_auto;
+    callbacks.layer_ch   = ket_layer_changed_auto;
+    callbacks.layer_back = ket_layer_back_auto;
+    callbacks.mouse_move = ket_mouse_move_nothing;
+    ke_init (&callbacks);
+    ke_start_keyboard_grab ();
+
+    g_timeout_add (KET_TIME_MAX, ket_wait_timeout, GINT_TO_POINTER (ket_index));
+
+    ket_write_message_for_first (array);
+    SPI_event_main ();
+
+    ke_stop_keyboard_grab ();
+    ke_terminate ();
+    ket_keys_array = NULL;
+
+    SPI_exit ();
+}
+
+static void
+ket_write_test_start_message (gchar *specific)
+{
+    gint i;
+
+    g_assert (specific);
+
+    if (!ket_wait)
+	return;
+
+    g_print ("\nMove to an ACCESSIBLE window!!!!\n");
+    for (i = KET_START_TEST_WAIT; i >= 0; i--)
+    {
+	g_print ("The test of \"%s\" will start in %d seconds\r", specific, i);
+	sleep(1);
+    }
+}
+
+static void
+ket_write_test_end_message (gchar *specific)
+{
+    g_assert (specific);
+
+    if (!ket_wait)
+	return;
+
+    g_print ("\nEnd of \"%s\" testing", specific);
+}
+static void 
+ket_array_function (KETProcessArray function,
+		    KETKeyMessage *keys,
+		    gint len,
+		    gchar *specific)
+{
+    GPtrArray *array;
+
+    g_assert (function);
+
+    array = g_ptr_array_new ();
+    ket_add_key_messages_to_array (array, keys, len);
+
+    ket_write_test_start_message (specific);
+    function (array);
+    ket_write_test_end_message (specific);
+
+    g_ptr_array_free (array, TRUE);
+}
+
+
+static void 
+ket_numpad_function (KETProcessArray function)
+{
+    ket_array_function (function, ket_numpad_keys,
+		    G_N_ELEMENTS (ket_numpad_keys), "numpad");
+}
+
+static void 
+ket_modifiers_function (KETProcessArray function)
+{
+    ket_array_function (function, ket_modifiers_keys,
+		    G_N_ELEMENTS (ket_modifiers_keys), "modifiers");
+} 
+
+static void 
+ket_cursors_function (KETProcessArray function)
+{
+    ket_array_function (function, ket_cursors_keys,
+		    G_N_ELEMENTS (ket_cursors_keys), "cursors");
+}
+
+static void 
+ket_grab_function (KETProcessArray function)
+{
+    ket_array_function (function, ket_grab_keys,
+		    G_N_ELEMENTS (ket_grab_keys), "grabbing");
+}
+
+static void
+ket_all_function (KETProcessArray function)
+{
+    gchar *specific = "all";
+
+    ket_write_test_start_message (specific);
+    ket_wait = FALSE;
+    ket_numpad_function    (function);
+    ket_modifiers_function (function);
+    ket_cursors_function   (function);
+    ket_grab_function      (function);
+
+    ket_wait = TRUE;
+    ket_write_test_end_message (specific);
+};
+
+
+static void 
+ket_test_numpad_listening_auto ()
+{
+    ket_numpad_function (ket_test_listen_array);
+}
+
+static void 
+ket_test_modifiers_listening_auto ()
+{
+    ket_modifiers_function (ket_test_listen_array);
+} 
+
+static void 
+ket_test_cursors_listening_auto ()
+{
+    ket_cursors_function (ket_test_listen_array);
+}
+
+static void 
+ket_test_grab_listening_auto ()
+{
+    ket_grab_function (ket_test_listen_array);
+}
+
+static void
+ket_test_all_listening_auto ()
+{
+    ket_all_function (ket_test_listen_array);
+};
+
+static void
+ket_test_generate_and_listen_array (GPtrArray *array)
+{
+
+    g_timeout_add (1000, ket_generate_first_key_from_array, array);
+
+    ket_test_listen_array (array);
+}
+
+static void 
+ket_test_numpad_auto ()
+{
+    ket_numpad_function (ket_test_generate_and_listen_array);
+}
+
+static void 
+ket_test_modifiers_auto ()
+{
+    ket_modifiers_function (ket_test_generate_and_listen_array);
+} 
+
+static void 
+ket_test_cursors_auto ()
+{
+    ket_cursors_function (ket_test_generate_and_listen_array);
+}
+
+static void 
+ket_test_grab_auto ()
+{
+    ket_grab_function (ket_test_generate_and_listen_array);
+}
+
+static void
+ket_test_all_auto ()
+{
+    ket_all_function (ket_test_generate_and_listen_array);
+};
+
+static void 
+ket_test_user_actions ()
+{
+    KECallbacks callbacks;
+    gchar *specific = "user actions";
+
+    ket_write_test_start_message (specific);
+    g_print ("\nInitial commands are:"
+		"\n\t 'Q' - for quit"
+		"\n\t 'S' - start keyboard grabbing"
+		"\n\t 'E' - end keyboard grabbing");
+
+    SPI_init ();
+
+    callbacks.grab	 = ket_grab_print;
+    callbacks.command	 = ket_command_print;
+    callbacks.hit	 = ket_hit_print;
+    callbacks.cursor     = ket_cursor_print;
+    callbacks.modifier   = ket_modifier_print;
+    callbacks.layer_key  = ket_layer_key_print;
+    callbacks.layer_ch   = ket_layer_changed_print;
+    callbacks.layer_back = ket_layer_back_print;
+    callbacks.mouse_move = ket_mouse_move_print;
+
+    ke_init (&callbacks);
+    ke_command_add ("Q", KE_MODIFIER_UNMODIFIED);
+    ke_command_add ("S", KE_MODIFIER_UNMODIFIED);
+    ke_command_add ("E", KE_MODIFIER_UNMODIFIED);
+
+    ket_keyboard_grabbing = FALSE;
+
+    SPI_event_main ();
+
+    ket_write_test_end_message (specific);
+    ke_commands_remove_all ();
+    if (ket_keyboard_grabbing)
+	ke_stop_keyboard_grab ();
+    ke_terminate ();
+
+    SPI_exit ();
+}
+
+static void 
+ket_test_manual ()
+{
+    SRUTMenuEntry menu[] =
+    {
+	{ "Test numpad", 	'1',	ket_test_numpad_listening_auto	  },
+	{ "Test modifiers",	'2',	ket_test_modifiers_listening_auto },
+	{ "Test cursors",	'3',	ket_test_cursors_listening_auto	  },
+	{ "Test grab",		'4',	ket_test_grab_listening_auto	  },
+	{ "Test numpad, modifiers, cursors, grab",'5',ket_test_all_listening_auto	  }
+    };
+
+    srut_run_menu (menu, G_N_ELEMENTS (menu));
+}
+
+static void 
+ket_test_automatic ()
+{
+    SRUTMenuEntry menu[] =
+    {
+	{ "Test numpad", 	'1',	ket_test_numpad_auto	  	},
+	{ "Test modifiers",	'2',	ket_test_modifiers_auto   	},
+	{ "Test cursors",	'3',	ket_test_cursors_auto	  	},
+	{ "Test grab",		'4',	ket_test_grab_auto	  	},
+	{ "Test numpad, modifiers, cursors, grab",'5',ket_test_all_auto	}
+    };
+
+    srut_run_menu (menu, G_N_ELEMENTS (menu));
+}
+
+int
+main (int argc,
+      char **argv)
+{
+    SRUTMenuEntry menu[] =
+    {
+	{ "Test user actions", 		'1',	ket_test_user_actions	},
+	{ "Test all manually",		'2',	ket_test_manual		},
+	{ "Test all automaticaly",	'3',	ket_test_automatic	},
+//	{ "Test robustness",		'4',	ket_test_robustness	}
+    };
+
+    gdk_init (&argc, &argv); /* needed because we are using GDK_DISPLAY () */
+
+    sru_debug_init ();
+
+    srut_run_menu (menu, G_N_ELEMENTS (menu));
+
+    sru_debug_terminate ();
+
+    return 0;
+}
Index: gnopernicus/srcore/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnopernicus/srcore/Makefile.am,v
retrieving revision 1.32
diff -u -r1.32 Makefile.am
--- gnopernicus/srcore/Makefile.am	8 Feb 2006 10:19:17 -0000	1.32
+++ gnopernicus/srcore/Makefile.am	3 Apr 2006 13:21:15 -0000
@@ -35,7 +35,8 @@
 		 brlinp.h \
 		 srpres.h \
 		 srctrl.h \
-		 srctrl.c
+		 srctrl.c \
+		 src-kbd.c
 
 LDADD = ../speech/libsrs/libsrs.la       \
 	../srlow/libsrlow/libsrlow.la    \
Index: gnopernicus/srcore/src-kbd.c
===================================================================
RCS file: gnopernicus/srcore/src-kbd.c
diff -N gnopernicus/srcore/src-kbd.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srcore/src-kbd.c	3 Apr 2006 13:21:15 -0000
@@ -0,0 +1,396 @@
+/* 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 <string.h>
+
+typedef struct
+{
+    gint flag;
+    SREvent *evnt;
+} SRCIdle;
+
+KeyboardEchoCB 	src_kbd_clb = NULL;
+
+
+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 ()
+{
+
+} 
+
+
+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; 
+}
Index: gnopernicus/srcore/src-kbd.h
===================================================================
RCS file: gnopernicus/srcore/src-kbd.h
diff -N gnopernicus/srcore/src-kbd.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srcore/src-kbd.h	3 Apr 2006 13:21:15 -0000
@@ -0,0 +1,44 @@
+/* src-kbd.h
+ *
+ * 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.
+ */
+#ifndef __SRC_KBD_H__
+#define __SRC_KBD_H__
+
+#include <glib.h>
+#include "SREvent.h"
+#include "libke.h"
+
+#define KE_LAYER_TIME_OUT 1
+#define KE_LAYER_CHANGED 0
+
+
+#define KeyboardEchoCB SROnEventProc
+
+typedef struct _SRHotkeyData
+{
+    KEKeyModifier modifiers; 
+    gchar *keystring; 
+} SRHotkeyData;
+
+gboolean 	src_kbd_init (KeyboardEchoCB kecb);
+void 		src_kbd_terminate ();
+gboolean	src_kbd_restart_cmds ();
+
+#endif /* __SRC_KBD_H__ */
Index: gnopernicus/srcore/srctrl.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srcore/srctrl.c,v
retrieving revision 1.99
diff -u -r1.99 srctrl.c
--- gnopernicus/srcore/srctrl.c	6 Feb 2006 12:43:19 -0000	1.99
+++ gnopernicus/srcore/srctrl.c	3 Apr 2006 13:21:16 -0000
@@ -32,6 +32,7 @@
 #include "srspc.h"
 #include "srbrl.h"
 
+#include "libke.h"
 #include "srmain.h" 
 #include "srpres.h"
 #include "screen-review.h"
@@ -1633,23 +1634,22 @@
 }
 
 
-extern gboolean SPI_generateMouseEvent (long int x, long int y, gchar *name);
-
 static gboolean
-src_generateMouseEvent (long int x, long int y, gchar *name)
+src_mouse_button_action (KEMouseButton button, KEMouseButtonAction action)
 {
     if (src_xevie_present)
-	return SPI_generateMouseEvent (x, y, name);
+	return ke_mouse_button_action (button, action);
     gdk_beep ();
     return FALSE;
 }
 
+
 static gboolean
 src_mouse_left_press ()
 {
     if (src_button_left_pressed) return FALSE;
     src_button_left_pressed = !src_button_left_pressed;
-    return src_generateMouseEvent (-1, -1, "b1p");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_LEFT, KE_MOUSE_BUTTON_PRESS);
 }
 
 static gboolean
@@ -1657,21 +1657,21 @@
 {
     if (!src_button_left_pressed) return FALSE;
     src_button_left_pressed = !src_button_left_pressed;
-    return src_generateMouseEvent (-1, -1, "b1r");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_LEFT, KE_MOUSE_BUTTON_RELEASE);
 }
 
 static gboolean
 src_mouse_left_click ()
 {
     if (src_button_left_pressed) return FALSE;
-    return src_generateMouseEvent (-1, -1, "b1c");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_LEFT, KE_MOUSE_BUTTON_CLICK);
 }
 
 /*
 static gboolean
 src_mouse_left_double_click ()
 {
-    return src_generateMouseEvent (-1, -1, "b1d");
+	return src_mouse_button_action (KE_MOUSE_BUTTON_LEFT, KE_MOUSE_BUTTON_DOUBLECLICK);
 }
 */
 
@@ -1680,7 +1680,7 @@
 {
     if (src_button_middle_pressed) return FALSE;
     src_button_middle_pressed = !src_button_middle_pressed;
-    return src_generateMouseEvent (-1, -1, "b3p");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_MIDDLE, KE_MOUSE_BUTTON_PRESS);
 }
 
 static gboolean
@@ -1688,21 +1688,21 @@
 {
     if (!src_button_middle_pressed) return FALSE;
     src_button_middle_pressed = !src_button_middle_pressed;
-    return src_generateMouseEvent (-1, -1, "b3r");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_MIDDLE, KE_MOUSE_BUTTON_RELEASE);
 }
 
 static gboolean
 src_mouse_middle_click ()
 {
     if (src_button_middle_pressed) return FALSE;
-    return src_generateMouseEvent (-1, -1, "b3c");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_MIDDLE, KE_MOUSE_BUTTON_CLICK);
 }
 
 /*
 static gboolean
 src_mouse_middle_double_click ()
 {
-    return src_generateMouseEvent (-1, -1, "b3d");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_MIDDLE, KE_MOUSE_BUTTON_DOUBLECLICK);
 }
 */
 
@@ -1712,7 +1712,7 @@
 {
     if (src_button_right_pressed) return FALSE;
     src_button_right_pressed = !src_button_right_pressed;
-    return src_generateMouseEvent (-1, -1, "b2p");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_RIGHT, KE_MOUSE_BUTTON_PRESS);
 }
 
 static gboolean
@@ -1720,21 +1720,21 @@
 {
     if (!src_button_right_pressed) return FALSE;
     src_button_right_pressed = !src_button_right_pressed;
-    return src_generateMouseEvent (-1, -1, "b2r");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_RIGHT, KE_MOUSE_BUTTON_RELEASE);
 }
 
 static gboolean
 src_mouse_right_click ()
 {
     if (src_button_right_pressed) return FALSE;
-    return src_generateMouseEvent (-1, -1, "b2c");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_RIGHT, KE_MOUSE_BUTTON_CLICK);
 }
 
 /*
 static gboolean
 src_mouse_right_double_click ()
 {
-    return src_generateMouseEvent (-1, -1, "b2d");
+    return src_mouse_button_action (KE_MOUSE_BUTTON_RIGHT, KE_MOUSE_BUTTON_DOUBLECLICK);
 }
 */
 
@@ -1793,7 +1793,7 @@
     obj = src_crt_sro;
     sro_add_reference (obj);
     if (src_get_mouse_coordinates_from_sro (src_crt_sro, &x, &y, TRUE))
-	rv = SPI_generateMouseEvent (x, y, "abs");
+	rv = ke_mouse_move (x, y);
     sro_release_reference (obj);
     return rv;
 }
@@ -2656,11 +2656,8 @@
     }
 	
     line = screen_review_get_line (index, &y1, &y2);
-	
-    flat_review_y = (y1 + y2) /2;
-    SPI_generateMouseEvent (flat_review_x,
-			    flat_review_y,
-			    "abs");
+    flat_review_y = (y1 + y2) / 2;
+    ke_mouse_move (flat_review_x, flat_review_y);
     if ((!line || line->is_empty) && src_use_speech)
     {
 	if (line->is_empty == 1)
@@ -2712,7 +2709,7 @@
     }
     else if (line && (src_use_braille || src_use_braille_monitor))
 	src_present_line_to_braille_or_brlmon (line);
-	
+
     last_line = index;
 
     return TRUE;
Index: gnopernicus/srcore/srmain.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srcore/srmain.c,v
retrieving revision 1.165
diff -u -r1.165 srmain.c
--- gnopernicus/srcore/srmain.c	28 Sep 2005 11:44:43 -0000	1.165
+++ gnopernicus/srcore/srmain.c	3 Apr 2006 13:21:17 -0000
@@ -28,7 +28,7 @@
 #include "srmag.h"
 #include "libsrconf.h"
 #include "brlinp.h"
-#include "libke.h"
+#include "src-kbd.h"
 #include "SREvent.h"
 #include "srctrl.h"
 #include "SRObject.h"
@@ -1363,7 +1363,7 @@
     {
 	src_ctrl_terminate 	();
 	src_ctrl_init 		();
-	ke_config_changed	();
+	src_kbd_restart_cmds	();
     }
     /*src_update_key ();*/
 }
@@ -2440,7 +2440,7 @@
     src_srl_client = srl_add_client (&client);
 
     /* initialize keyboard */
-    ke_init ((KeyboardEchoCB)&src_event_sink);
+    src_kbd_init ((KeyboardEchoCB)&src_event_sink);
 
     src_layer = NULL;
     src_focused_sro = NULL;
@@ -2513,7 +2513,7 @@
     srl_terminate ();
 
     /* terminate Keyboard */
-    ke_terminate();
+    src_kbd_terminate ();
 
     /* terminate Magnifier */
     if (src_use_magnifier)
Index: gnopernicus/srlow/libsrlow/SRLow.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srlow/libsrlow/SRLow.c,v
retrieving revision 1.131
diff -u -r1.131 SRLow.c
--- gnopernicus/srlow/libsrlow/SRLow.c	6 Mar 2006 13:40:53 -0000	1.131
+++ gnopernicus/srlow/libsrlow/SRLow.c	3 Apr 2006 13:21:17 -0000
@@ -60,7 +60,6 @@
 #define SRL_EVENT_NAME_WINDOW_RESTORE		"window:restore"
 #define SRL_EVENT_NAME_WINDOW_ACTIVATE		"window:activate"
 #define SRL_EVENT_NAME_WINDOW_DEACTIVATE	"window:deactivate"
-#define SRL_EVENT_NAME_MOUSE_ABS		"mouse:abs"
 #define SRL_EVENT_NAME_CONTENT_CHANGED		"object:property-changed:accessible-content"
 #define SRL_EVENT_NAME_WINDOW_SWITCH		"window:switch"
 #define SRL_EVENT_NAME_TOOLTIP_SHOW		"tooltip:show"
@@ -108,7 +107,6 @@
     SRL_EVENT_WINDOW_ACTIVATE,
     SRL_EVENT_WINDOW_DEACTIVATE,
     SRL_EVENT_WINDOW_TITLELIZE,
-    SRL_EVENT_MOUSE_ABS,
     SRL_EVENT_TOOLTIP_SHOW,
     SRL_EVENT_TOOLTIP_HIDE,
     SRL_EVENT_ACTIVE_DESCENDANT_CHANGED,
@@ -124,7 +122,6 @@
 
 typedef enum _SRLEventPriority
 {
-    SRL_EVENT_PRIORITY_MOUSE,
     SRL_EVENT_PRIORITY_TOOLTIP,
     SRL_EVENT_PRIORITY_FOCUS,
     SRL_EVENT_PRIORITY_WATCHED,
@@ -160,7 +157,6 @@
 	{SRL_EVENT_WINDOW_RESTORE,		SRL_EVENT_NAME_WINDOW_RESTORE},
 	{SRL_EVENT_WINDOW_ACTIVATE,		SRL_EVENT_NAME_WINDOW_ACTIVATE},
 	{SRL_EVENT_WINDOW_DEACTIVATE,		SRL_EVENT_NAME_WINDOW_DEACTIVATE},
-	{SRL_EVENT_MOUSE_ABS,			SRL_EVENT_NAME_MOUSE_ABS},
 	{SRL_EVENT_ACTIVE_DESCENDANT_CHANGED, 	SRL_EVENT_NAME_ACTIVE_DESCENDANT_CHANGED},
 	{SRL_EVENT_NAME_CHANGED,		SRL_EVENT_NAME_NAME_CHANGED},
 	{SRL_EVENT_VISIBLE_DATA_CHANGED,	SRL_EVENT_NAME_VISIBLE_DATA_CHANGED},
@@ -400,22 +396,6 @@
     SR_freeString (type);
 }
 
-static void
-srl_log_gnopernicus_event_user_mouse (SRLEvent *event,
-				      SREvent *ev)
-{
-    SRPoint *point;
-
-    srl_assert (event && ev);
-
-    if (!srl_log_is_gnopernicus_event_logged ())
-	return;
-
-    sre_get_event_data (ev, (void**)&point);
-    fprintf (stderr, "\nGN:%xp--\"mouse:move\" "
-			"at %d, %d", SRL_PTR (event), point->x, point->y);
-}
-
 static G_CONST_RETURN Accessible* srle_get_acc (SRLEvent *event);
 static G_CONST_RETURN gchar* 	  srle_get_reason (SRLEvent *event);
 
@@ -497,7 +477,6 @@
 #else /* SRL_LOG */
 #define srl_log_at_spi_event(X)
 #define srl_log_gnopernicus_event_user_obj(X, Y)
-#define srl_log_gnopernicus_event_user_mouse(X, Y)
 #define srl_log_important_event(X)
 #define srl_log_reentrancy_event(X)
 #define srl_log_init()
@@ -1018,13 +997,6 @@
     return  event->type == SRL_EVENT_TOOLTIP_SHOW;
 }
 
-static gboolean
-srl_is_mouse_event (SRLEvent *event)
-{
-    srl_assert (event);
-    
-    return  event->type == SRL_EVENT_MOUSE_ABS;
-}
 
 static SRLEventPriority
 srle_get_priority (SRLEvent *event)
@@ -1035,8 +1007,6 @@
 	return SRL_EVENT_PRIORITY_WATCHED;
     if (srl_is_window_event (event))
 	return SRL_EVENT_PRIORITY_WINDOW;
-    if (srl_is_mouse_event (event))
-	return SRL_EVENT_PRIORITY_MOUSE;
     if (srl_is_tooltip_event (event))
 	return SRL_EVENT_PRIORITY_TOOLTIP;
     return SRL_EVENT_PRIORITY_FOCUS;
@@ -1225,30 +1195,6 @@
 }
 
 static gboolean
-srl_notify_clients_mouse (SRLEvent *event,
-			  SREventType type)
-{
-    SRPoint *point;
-    SREvent *ev;
-
-    srl_assert (event);
-
-    ev = sre_new ();
-    point = g_new0 (SRPoint, 1);
-
-    ev->type = type;
-    ev->data = point;
-    point->x = event->acc_ev->detail1;
-    point->y = event->acc_ev->detail2;
-    ev->data_destructor = (SREventDataDestructor) g_free;
-    srl_log_gnopernicus_event_user_mouse (event, ev);
-    srl_notify_all_clients (ev, 0);
-    sre_release_reference (ev);
-
-    return TRUE;
-}
-
-static gboolean
 srl_report_event_from_lasts_to_clients (gint index,
 				        SREventType type,
 					SRLNotify notify)
@@ -1292,18 +1238,6 @@
     return TRUE;
 }
 
-static gboolean
-srl_report_mouse_event_to_clients (gint index,
-				   SREventType type)
-{
-    srl_assert (0 <= index && index < SRL_EVENT_PRIORITY_LAST);
-
-    srl_report_event_from_lasts_to_clients (index, type,
-						srl_notify_clients_mouse);
-
-    return TRUE;
-}
-
 
 static gboolean
 srl_report_event_to_clients (gpointer data)
@@ -1316,8 +1250,6 @@
 					    SR_EVENT_SRO);
     srl_report_obj_event_to_clients (SRL_EVENT_PRIORITY_TOOLTIP,
 					    SR_EVENT_TOOLTIP);
-    srl_report_mouse_event_to_clients (SRL_EVENT_PRIORITY_MOUSE,
-					    SR_EVENT_MOUSE);
 
     srl_idle_installed = srl_idle_need;
     srl_idle_need = FALSE;
@@ -2002,8 +1934,7 @@
 	    }
 	}
     }
-    else if (srl_is_mouse_event (event)	||
-	srl_is_tooltip_event (event))
+    else if (srl_is_tooltip_event (event))
 	rv = TRUE;
     else if (srle_has_type (event, SRL_EVENT_FOCUS))
 	rv = srle_acc_has_state (event, SPI_STATE_FOCUSED) ||
@@ -2409,58 +2340,6 @@
 	
     return FALSE;
 }
-
-
-gboolean
-srl_mouse_move (gint x,
-		gint y)
-{
-    return SPI_generateMouseEvent (x, y, "abs") ? TRUE : FALSE;
-}		
-
-gboolean
-srl_mouse_click (gint button)
-{
-    gchar action[] = "b1c";
-    
-    if (button == SR_MOUSE_BUTTON_LEFT)
-	action[1] = '1';
-    else if (button == SR_MOUSE_BUTTON_RIGHT)
-	action[1] = '2';
-    else
-	srl_assert_not_reached ();
-    
-    return SPI_generateMouseEvent (-1, -1, action) ? TRUE : FALSE;
-}
-
-gboolean
-srl_mouse_button_down (gint button)
-{
-    gchar action[] = "b1p";
-    
-    if (button == SR_MOUSE_BUTTON_LEFT)
-	action[1] = '1';
-    else if (button == SR_MOUSE_BUTTON_RIGHT)
-	action[1] = '2';
-    else
-	srl_assert_not_reached ();
-    return SPI_generateMouseEvent (-1,-1 , action) ? TRUE : FALSE;
-}		
-
-gboolean
-srl_mouse_button_up (gint button)
-{
-    gchar action[] = "b1r";
-    
-    if (button == SR_MOUSE_BUTTON_LEFT)
-	action[1] = '1';
-    else if (button == SR_MOUSE_BUTTON_RIGHT)
-	action[1] = '2';
-    else
-	srl_assert_not_reached ();
-    
-    return SPI_generateMouseEvent (-1,-1 , action) ? TRUE : FALSE;
-}		
 
 
 gboolean
Index: gnopernicus/srlow/libsrlow/SRLow.h
===================================================================
RCS file: /cvs/gnome/gnopernicus/srlow/libsrlow/SRLow.h,v
retrieving revision 1.18
diff -u -r1.18 SRLow.h
--- gnopernicus/srlow/libsrlow/SRLow.h	25 Jul 2005 14:21:56 -0000	1.18
+++ gnopernicus/srlow/libsrlow/SRLow.h	3 Apr 2006 13:21:17 -0000
@@ -25,10 +25,6 @@
 #include "SRObject.h"
 #include "SREvent.h"
 
-#define SR_MOUSE_BUTTON_LEFT	1
-#define SR_MOUSE_BUTTON_RIGHT	2
-
-
 /**
  * SRLClientHandle :
  *
@@ -56,10 +52,6 @@
 gboolean srl_terminate 		();
 SRLClientHandle srl_add_client 	(const SRLClient *client);
 gboolean srl_remove_client 	(SRLClientHandle client_handle);
-gboolean srl_mouse_move 	(gint x, gint y);
-gboolean srl_mouse_click 	(gint button);
-gboolean srl_mouse_button_down 	(gint button);
-gboolean srl_mouse_button_up 	(gint button);
 gboolean srl_set_watch_for_object (SRObject *obj);
 void     srl_unwatch_all_objects ();
 gboolean srl_is_object_watched (SRObject *obj);
Index: gnopernicus/srlow/test/srlow_test.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srlow/test/srlow_test.c,v
retrieving revision 1.18
diff -u -r1.18 srlow_test.c
--- gnopernicus/srlow/test/srlow_test.c	25 Jul 2005 14:21:57 -0000	1.18
+++ gnopernicus/srlow/test/srlow_test.c	3 Apr 2006 13:21:17 -0000
@@ -33,21 +33,6 @@
 
     SRObject *obj;
     SREventType type;
-    static int first_time = 1;
-    
-    if (first_time)
-    {
-	srl_mouse_move (100, 100);
-	srl_mouse_click (SR_MOUSE_BUTTON_LEFT);
-	
-	sleep (2);
-	srl_mouse_move (120, 120);
-	srl_mouse_button_down (SR_MOUSE_BUTTON_LEFT);    
-	srl_mouse_button_up (SR_MOUSE_BUTTON_LEFT);
-
-	first_time = 0;
-    }
-
 
     if (sre_get_type (event, &type))
     {
Index: gnopernicus/srutil/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnopernicus/srutil/Makefile.am,v
retrieving revision 1.14
diff -u -r1.14 Makefile.am
--- gnopernicus/srutil/Makefile.am	6 Feb 2006 12:43:20 -0000	1.14
+++ gnopernicus/srutil/Makefile.am	3 Apr 2006 13:21:17 -0000
@@ -2,27 +2,22 @@
 privlib_LTLIBRARIES = libsrutil.la
 
 INCLUDES = -I$(srcdir)				\
-	   -I$(top_srcdir)/srconf/libsrconf	\
-	   $(LIBSRUTIL_CFLAGS)			\
-	   -DG_LOG_DOMAIN=\"gnopernicus\"
+	   $(LIBSRUTIL_CFLAGS)
 
 libsrutil_la_LDFLAGS = @LT_VERSION_INFO@ $(NO_UNDEFINED)
 
-libsrutil_la_LIBADD = $(LIBSRUTIL_LIBS)  
+libsrutil_la_LIBADD = $(LIBSRUTIL_LIBS)
 
 libsrutilincludedir =$(includedir)/gnopernicus-1.0/libsrutil
+libsrutildir =$(libdir)/gnopernicus-1.0
 
-libsrutilinclude_HEADERS = SREvent.h	\
-			   SRMessages.h	\
-			   util.h	\
-			   srintl.h	\
-			   sru-debug.h
+libsrutilinclude_HEADERS = sru-debug.h	\
+			   sru-glib.h	\
+			   sru-module.h
 
-libsrutil_la_SOURCES = SREvent.c	\
-		       SREvent.h	\
+libsrutil_la_SOURCES = sru-debug.c	\
+		       sru-glib.c	\
+		       sru-test.c	\
+		       SREvent.c	\
 		       util.c		\
-		       util.h		\
-		       SRMessages.h	\
-		       SRMessages.c	\
-		       sru-debug.h	\
-		       sru-debug.c
+		       SRMessages.c
Index: gnopernicus/srutil/srintl.h
===================================================================
RCS file: /cvs/gnome/gnopernicus/srutil/srintl.h,v
retrieving revision 1.6
diff -u -r1.6 srintl.h
--- gnopernicus/srutil/srintl.h	25 Jul 2005 14:21:57 -0000	1.6
+++ gnopernicus/srutil/srintl.h	3 Apr 2006 13:21:17 -0000
@@ -29,4 +29,4 @@
 #define ngettext(x, y, z) ((z) == 1 ? (x) : (y))
 #endif
 
-#endif
+#endif /* __SRINTL_H__ */
Index: gnopernicus/srutil/sru-debug.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srutil/sru-debug.c,v
retrieving revision 1.2
diff -u -r1.2 sru-debug.c
--- gnopernicus/srutil/sru-debug.c	25 Jul 2005 14:21:57 -0000	1.2
+++ gnopernicus/srutil/sru-debug.c	3 Apr 2006 13:21:17 -0000
@@ -21,14 +21,13 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
-#endif /* HAVE_CONFIG_H */
+#endif
+
 #include <glib.h>
 #include <string.h>
 #include <stdio.h>
 #include "sru-debug.h"
 
-#define SRU_DEBUG_CNT
-
 #ifdef SRU_DEBUG
 
 static GPtrArray *sru_debug_tags = NULL;
@@ -110,8 +109,7 @@
     for (i = 0; scopes_array[i]; i++)
     {
 	g_assert (scopes_array[i][0]);
-	g_ptr_array_add (sru_debug_tags, 
-			    g_strconcat (module, ":", scopes_array[i], NULL));
+	g_ptr_array_add (sru_debug_tags, g_strconcat (module, ":", scopes_array[i], NULL));
     }
     g_strfreev (scopes_array);
 }
@@ -125,36 +123,28 @@
     va_list args;
     gchar *message;
     gchar *scopes_real;
-#ifdef SRU_DEBUG_CNT
-    static long cnt = 0;
-#endif /* SRU_DEBUG_CNT */
 
     g_assert (module && module[0] && scopes && scopes[0]); 
     g_assert (sru_debug_file);
 
-    scopes_real = sru_debug_module_and_scopes_real_logged (module, scopes);
-    if (!scopes_real)
+    if (!(scopes_real = sru_debug_module_and_scopes_real_logged (module, scopes)))
 	return;
 
     va_start (args, format);
     message = g_strdup_vprintf (format, args);
-#ifdef SRU_DEBUG_CNT
-    fprintf (sru_debug_file, "\n%03ld %s\t%s\t%s", cnt++, module,
-						    scopes_real, message);
-#else /* SRU_DEBUG_CNT */
     fprintf (sru_debug_file, "\n%s\t%s\t%s", module, scopes_real, message);
-#endif /* SRU_DEBUG_CNT */
-
     g_free (message);
     g_free (scopes_real);
     va_end (args);
 }
 
-void
+gboolean
 sru_debug_init ()
 {
     sru_debug_file = stderr;
     sru_debug_tags = g_ptr_array_new ();
+
+    return TRUE;
 }
 
 void
Index: gnopernicus/srutil/sru-debug.h
===================================================================
RCS file: /cvs/gnome/gnopernicus/srutil/sru-debug.h,v
retrieving revision 1.2
diff -u -r1.2 sru-debug.h
--- gnopernicus/srutil/sru-debug.h	25 Jul 2005 14:21:57 -0000	1.2
+++ gnopernicus/srutil/sru-debug.h	3 Apr 2006 13:21:17 -0000
@@ -24,18 +24,16 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
-#endif /* HAVE_CONFIG_H */
+#endif
 #include <glib.h>
 
+
+#define SR_DEBUG /* FIXME */
+
 #if defined SR_DEBUG && ! defined SRU_DEBUG
 #  define SRU_DEBUG
 #endif /* defined SR_DEBUG && ! defined SRU_DEBUG */
 
-
-G_BEGIN_DECLS 
-
-#ifdef SRU_DEBUG
-
 #ifndef SRU_DEBUG_MODULE
 #  define SRU_DEBUG_MODULE ""
 #endif /* SRU_DEBUG_MODULE */
@@ -44,14 +42,14 @@
 #  define SRU_DEBUG_SCOPES ""
 #endif /* SRU_DEBUG_SCOPES */
 
-void sru_debug_init  			();
-void sru_debug_terminate 		();
-void sru_debug_add_module_and_scopes 	(const gchar *module,
-							const gchar *scopes);
-void sru_debug_log_all   		(const gchar *module,
-					    const gchar *scopes,
-					    const gchar *format, ...)
-					     G_GNUC_PRINTF (3, 4);
+G_BEGIN_DECLS 
+
+#ifdef SRU_DEBUG
+
+gboolean sru_debug_init  ();
+void sru_debug_terminate ();
+void sru_debug_add_module_and_scopes (const gchar *module, const gchar *scopes);
+void sru_debug_log_all   (const gchar *module, const gchar *scopes, const gchar *format, ...) G_GNUC_PRINTF (3, 4);
 
 #define SRU_DEBUG_ADD_MODULE_AND_SCOPES					\
 	    {								\
@@ -68,34 +66,19 @@
 		g_free (module);					\
 		g_free (module_dbg);					\
 	    }
+#define sru_debug_log(scopes, ...) 		sru_debug_log_all (SRU_DEBUG_MODULE, scopes, __VA_ARGS__);
 
-#define sru_debug_log(scopes, ...) 					\
-		sru_debug_log_all (SRU_DEBUG_MODULE, scopes, __VA_ARGS__);
-
-#define sru_debug_log_enter_function()					\
-		sru_debug_log ("entry", "start of \""			\
-			    G_GNUC_PRETTY_FUNCTION "\" function");
-
-#define sru_debug_log_leave_function()					\
-		sru_debug_log ("entry", "end   of \""			\
-			    G_GNUC_PRETTY_FUNCTION "\" function");
-
-#define sru_debug_log_cond(cond, scopes, ...) 				\
-	    if (cond)							\
-		sru_debug_log_all (SRU_DEBUG_MODULE, scopes, __VA_ARGS__);
 
 
 #else /* SRU_DEBUG */
 
-#define sru_debug_init()
+#define sru_debug_init()			TRUE
 #define sru_debug_terminate()
 #define sru_debug_add_module_and_scopes(module, scopes)
 #define sru_debug_log_all(module, scopes, format, ...)
-#define SRU_DEBUG_ADD_MODULE_AND_SCOPES
-#define sru_debug_log(scopes, ...)
-#define sru_debug_log_enter_function()
-#define sru_debug_log_leave_function()
-#define sru_debug_log_cond(cond, scopes, ...)
+
+#define SRU_DEBUG_ADD_MODULE_AND_SCOPES 	sru_debug_add_module_and_scopes (SRU_DEBUG_MODULE, SRU_DEBUG_SCOPES);
+#define sru_debug_log(scopes, ...) 		sru_debug_log_all (SRU_DEBUG_MODULE, scopes, __VA_ARGS__);
 
 #endif /* SRU_DEBUG */
 
Index: gnopernicus/srutil/sru-glib.c
===================================================================
RCS file: gnopernicus/srutil/sru-glib.c
diff -N gnopernicus/srutil/sru-glib.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srutil/sru-glib.c	3 Apr 2006 13:21:17 -0000
@@ -0,0 +1,48 @@
+/* sru-glib.c
+ *
+ * Copyright 2001 - 2005 Sun Microsystems, Inc.,
+ * Copyright 2001 - 2005 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+
+#include "sru-glib.h"
+
+void
+sru_slist_foreach (GSList *list, 
+		   SRUProcessFunction process)
+{
+    GSList *crt;
+
+    g_assert (list && process);
+
+    for (crt = list; crt; crt = crt->next)
+	process (crt->data);
+}
+
+void
+sru_slist_terminate (GSList *list,
+		     SRUProcessFunction terminate)
+{
+    sru_slist_foreach (list, terminate);
+    g_slist_free (list);
+}
Index: gnopernicus/srutil/sru-glib.h
===================================================================
RCS file: gnopernicus/srutil/sru-glib.h
diff -N gnopernicus/srutil/sru-glib.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srutil/sru-glib.h	3 Apr 2006 13:21:17 -0000
@@ -0,0 +1,40 @@
+/* sru-glib.h
+ *
+ * Copyright 2001 - 2005 Sun Microsystems, Inc.,
+ * Copyright 2001 - 2005 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.
+ */
+
+#ifndef __SRU_GLIB_H__
+#define __SRU_GLIB_H__
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef void (*SRUProcessFunction) (gpointer data);
+
+void sru_slist_foreach (GSList *list, SRUProcessFunction process);
+void sru_slist_terminate (GSList *list, SRUProcessFunction terminate);
+
+G_END_DECLS
+
+#endif /* __SRU_GLIB_H__ */
Index: gnopernicus/srutil/sru-module.h
===================================================================
RCS file: gnopernicus/srutil/sru-module.h
diff -N gnopernicus/srutil/sru-module.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srutil/sru-module.h	3 Apr 2006 13:21:18 -0000
@@ -0,0 +1,72 @@
+/* sru-debug.h
+ *
+ * Copyright 2001 - 2005 Sun Microsystems, Inc.,
+ * Copyright 2001 - 2005 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.
+ */
+
+#ifndef __SRU_MODULE_H__
+#define __SRU_MODULE_H__
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+
+#define SR_DEBUG /* FIXME */
+
+#if defined SR_DEBUG && ! defined SRU_MODULE
+#  define SRU_MODULE
+#endif /* defined SR_DEBUG && ! defined SRU_MODULE */
+
+G_BEGIN_DECLS
+
+typedef enum _SRUModuleFlag
+{
+    SRU_MODULE_FLAG_UNINITIALIZED,
+    SRU_MODULE_FLAG_INITIALIZED,
+}SRUModuleFlag;
+
+
+#ifdef SRU_MODULE
+
+#define SRU_MODULE_FLAG_DEFS(flag)	static SRUModuleFlag flag = SRU_MODULE_FLAG_UNINITIALIZED;
+
+#define sru_module_flag_set_initialized(flag)     (flag) = SRU_MODULE_FLAG_INITIALIZED
+#define sru_module_flag_set_uninitialized(flag)   (flag) = SRU_MODULE_FLAG_UNINITIALIZED
+
+#define sru_module_flag_check_initialized(flag)   ((flag) == SRU_MODULE_FLAG_INITIALIZED)
+#define sru_module_flag_check_uninitialized(flag) ((flag) == SRU_MODULE_FLAG_UNINITIALIZED)
+
+
+#else /* SRU_MODULE */
+
+#define SRU_MODULE_FLAG_DEFS(flag)
+
+#define sru_module_flag_set_initialized(flag)
+#define sru_module_flag_set_uninitialized(flag)
+
+#define sru_module_flag_check_initialized(flag)
+#define sru_module_flag_check_uninitialized(flag)
+
+
+#endif /* SRU_MODULE */
+
+G_END_DECLS
+
+#endif /* __SRU_MODULE_H__ */
Index: gnopernicus/srutil/sru-test.c
===================================================================
RCS file: gnopernicus/srutil/sru-test.c
diff -N gnopernicus/srutil/sru-test.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srutil/sru-test.c	3 Apr 2006 13:21:18 -0000
@@ -0,0 +1,80 @@
+/* sru-test.c
+ *
+ * Copyright 2001 - 2005 Sun Microsystems, Inc.,
+ * Copyright 2001 - 2005 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "sru-test.h"
+
+static gint
+srut_get_selection_index (gchar c,
+			  SRUTMenuEntry *entries,
+			  gint len)
+{
+    gint i;
+
+    g_assert (entries && len > 0);
+
+    for (i = 0; i < len; i++)
+    	if (entries[i].selection == c)
+	    return i;
+
+    if (c == '0')
+	return -1;
+
+    return -2;
+}
+
+void
+srut_run_menu (SRUTMenuEntry *entries,
+	       gint length)
+{
+    gint i, index;	
+
+    g_assert (entries && length > 0);
+
+    do
+    {
+	g_print ("\n\n\n");
+	for (i = 0; i < length; i++)
+    	    g_print ("\n\t%c. %s", entries[i].selection, entries[i].message);
+	g_print ("\n\t0. Exit");
+	g_print ("\n");
+
+	do
+	{
+	    gchar opt[1001];
+	    gint len;
+	    g_print ("Choose an option: ");
+	    gets (opt);
+	    len = strlen (opt);
+	    index = srut_get_selection_index (opt[len-1], entries, length);
+	}while (index == -2);
+
+	if (index >= 0)
+	    entries[index].action ();
+    }while (index != -1);
+}
Index: gnopernicus/srutil/sru-test.h
===================================================================
RCS file: gnopernicus/srutil/sru-test.h
diff -N gnopernicus/srutil/sru-test.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnopernicus/srutil/sru-test.h	3 Apr 2006 13:21:18 -0000
@@ -0,0 +1,46 @@
+/* sru-debug.h
+ *
+ * Copyright 2001 - 2005 Sun Microsystems, Inc.,
+ * Copyright 2001 - 2005 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.
+ */
+
+#ifndef __SRU_TEST_H__
+#define __SRU_TEST_H__
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef void (*SRUMenuEntryAction) ();
+
+typedef struct
+{
+    gchar 		*message;
+    gchar 		selection;
+    SRUMenuEntryAction 	action;
+}SRUTMenuEntry;
+
+void srut_run_menu (SRUTMenuEntry *entries, gint len);
+
+G_END_DECLS
+
+#endif /* __SRU_TEST_H__ */
