Index: configure.in
===================================================================
--- configure.in	(revision 2336)
+++ configure.in	(working copy)
@@ -83,10 +83,33 @@
 
 AC_SUBST(XINPUT_LIBS)
 
+dnl Allow disabling XEViE.
+AC_ARG_ENABLE(xevie, [  --enable-xevie  Build with XEViE support [default=yes]], enable_xevie="$enableval", enable_xevie=yes)
+
+if test x$enable_xevie = xyes ; then
+	have_xevie=
+	AC_CHECK_LIB(Xext, XevieStart, have_xevie="yes")
+
+	if test "x$have_xevie" = "xyes"; then
+		XEVIE_LIBS="-lXext"
+		AC_DEFINE(HAVE_XEVIE, 1, Xevie extension client libs present)
+	else
+	   AC_CHECK_LIB(Xevie, XevieQueryVersion, have_xevie="maybe",,-lXevie -lXext)
+	   if test "x$have_xevie" = "xmaybe"; then
+	      AC_CHECK_HEADER(X11/extensions/Xevie.h, have_xevie=yes, [], [#include <X11/Xlib.h>])
+	      if test "x$have_xevie" = "xyes"; then
+	      	      XEVIE_LIBS="-lXext -lXevie"	       
+		      AC_DEFINE(HAVE_XEVIE, 1, Xevie extension client libs present)
+	      fi
+	   fi	
+	fi
+	AC_SUBST(XEVIE_LIBS)
+fi
+
 if test x$no_x = xyes ; then
   AC_MSG_ERROR([X development libraries not found])
 else
-  X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $XINPUT_LIBS"
+  X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $XINPUT_LIBS $XEVIE_LIBS"
 fi
 
 AC_SUBST(X_LIBS)
Index: gok/gok-scanner.c
===================================================================
--- gok/gok-scanner.c	(revision 2337)
+++ gok/gok-scanner.c	(working copy)
@@ -160,6 +160,8 @@
 "GetRate"
 };
 
+void gok_scanner_input_motion_xevie (gint x, gint y);
+
 static xmlChar *gok_lang = NULL;
 
 /**
@@ -2193,7 +2195,6 @@
 
 	gok_main_raise_window ();
 	gok_scanner_timer_start_dwell();
-		
 	gok_scanner_perform_effects (m_pEffectsOnKeyEnter);
 }
 
@@ -2319,8 +2320,8 @@
 {
 	m_MouseX = x;
 	m_MouseY = y;
-
 	gok_scanner_perform_effects (m_pEffectsMouseMovement);
+	gok_scanner_input_motion_xevie (x, y);
 }
 
 /**
@@ -2431,7 +2432,45 @@
 	gok_keyboard_paint_pointer (pKeyboard, pWindow, offset_x, offset_y);
 }
 
+/**
+* gok_scanner_input_motion_xevie
+* @x: Horizontal (first axis) input device motion component.
+* @y: Vertical (second axis)  input device motion component.
+*
+* Handler for input device motion events generated by an input device accessed through libusb. 
+**/
+void gok_scanner_input_motion_xevie (gint x, gint y)
+{
+	GokKey *pKey;
+	gint w, h;
+	static gint offset_x = 0, origin_x = 0;
+	static gint offset_y = 0, origin_y = 0;
+	GokKeyboard *pKeyboard = gok_main_get_current_keyboard ();
+	GtkWidget *pWindow = gok_main_get_main_window ();
+	
+	/* ignore motion events outside window */
+	gdk_drawable_get_size (pWindow->window, &w, &h);
+	gdk_window_get_position (pWindow->window, &offset_x, &offset_y);
+	gdk_window_get_root_origin (pWindow->window, &origin_x, &origin_y);
+	if (x < offset_x || x > offset_x+w ||
+	    y < offset_y || y > offset_y+h) {
+	  gok_scanner_on_key_leave (m_pContainingKey);
+	  return;
+	}
+   	pKey = gok_keyboard_find_key_at (pKeyboard, x-offset_x, y-offset_y, m_pContainingKey);
+	if (m_pContainingKey != pKey) {
+		gok_scanner_on_key_leave (m_pContainingKey);
+		if (pKey) {
+			gok_scanner_on_key_enter (pKey);
+		}
+		else if (m_pContainingKey) {
+		        gok_scanner_on_key_leave (m_pContainingKey);
+		}
+		m_pContainingKey = pKey;
+	}
+}
 
+
 /**
 * gok_scanner_on_timer1
 * @data: Pointer to the user data associated with the timer.
@@ -3621,3 +3660,9 @@
   if (m_pKeyEntered == pKey) m_pKeyEntered = NULL;
   if (m_pContainingKey == pKey) m_pContainingKey = NULL;
 }
+
+gboolean 
+gok_scanner_key_is_active (void)
+{
+  return m_pKeyEntered != NULL;
+}
Index: gok/gok-scanner.h
===================================================================
--- gok/gok-scanner.h	(revision 2336)
+++ gok/gok-scanner.h	(working copy)
@@ -262,6 +262,7 @@
 void gok_scanner_on_switch5_up (void);
 void gok_scanner_repeat_on(void);
 void gok_scanner_drop_refs (GokKey *pKey);
+gboolean gok_scanner_key_is_active (void);
 
 #ifdef __cplusplus
 }
Index: gok/gok-input.c
===================================================================
--- gok/gok-input.c	(revision 2339)
+++ gok/gok-input.c	(working copy)
@@ -98,14 +98,20 @@
 	if (xevent->type == gok_input_types[GOK_INPUT_TYPE_MOTION])
 	{
 		XDeviceMotionEvent *motion = (XDeviceMotionEvent *) xevent;
-		if (gok_input_get_current() &&
+		if (!gok_input_get_current() ||
 		    motion->deviceid != gok_input_get_current ()->device->device_id)
 		{
-			GokInput *input = gok_input_find_by_device_id (motion->deviceid, TRUE);
-			if (input) gok_input_mismatch_warn (input->info);
+		        gok_log ("motion event from unexpected device...\n");
+			GokInput *input;
+			if (gok_main_attach_new_devices ()) {
+			  input = gok_input_find_by_device_id (motion->deviceid, TRUE);
+			  if (input) gok_input_mismatch_warn (input->info);
+			}
 		}
-		gok_main_motion_listener (motion->axes_count, motion->axis_data, 
-					  motion->device_state, (long) motion->time);
+		else {
+		  gok_main_motion_listener (motion->axes_count, motion->axis_data, 
+					    motion->device_state, (long) motion->time);
+		}
 	}
 	else if ((xevent->type == gok_input_types[GOK_INPUT_TYPE_BUTTON_PRESS]) || 
 		 (xevent->type == gok_input_types[GOK_INPUT_TYPE_BUTTON_RELEASE]))
@@ -387,7 +393,7 @@
 		}	
 		device_list = device_list->next;
 	}
-	printf ("%d event types available\n", number);
+	gok_log ("%d event types available\n", number);
 	
 	gdk_window_add_filter (NULL,
 			       filter_func,
@@ -401,6 +407,7 @@
 gboolean
 gok_input_set_extension_device_by_name (char *name)
 {
+        gok_log ("SETTING INPUT DEVICE TO %s\n", name);
 	gok_gconf_set_string (gconf_client_get_default(), 
 			      GOK_GCONF_INPUT_DEVICE,
 			      name);
@@ -502,12 +509,14 @@
 	  current_input = gok_input_find_by_name (input_device_name, TRUE);
       }
   }
+  gok_log ("current input device=%x\n", current_input);
   return current_input;
 }
 
 void
 gok_input_restore (void)
 {
+        gok_log (stderr, "gok input restore\n");
 	gok_input_set_extension_device_by_name (saved_input_device);
 	gok_input_close_others (); 
 }
@@ -518,6 +527,7 @@
 	gchar *message = g_strdup_printf (_("GOK has detected activity from a new hardware device named \'%s\'.  "
 					    "Would you like to use this device instead of device \'%s\'?"),
 					  device->name, gok_input_get_extension_device_name ());
+	fprintf (stderr, "%s", message);
 	saved_input_device = gok_input_get_extension_device_name ();
 	gok_input_set_extension_device_by_name (device->name);
 	gok_main_warn (message, TRUE, gok_input_restore, gok_input_close_others, FALSE);
Index: gok/gok-utf8-word-complete.c
===================================================================
--- gok/gok-utf8-word-complete.c	(revision 2336)
+++ gok/gok-utf8-word-complete.c	(working copy)
@@ -165,7 +165,7 @@
 	/* create gunichar hash for looking up search entry points */
 	utf8_wordcomplete_create_unicode_hash (utf8_complete);
 
-	fprintf (stderr, "Word prediction dictionary contains a total of %d words\n", 
+	gok_log ("Word prediction dictionary contains a total of %d words\n", 
 		 g_list_length (utf8_complete->word_list));
 
 	return TRUE;
Index: gok/gok-spy.c
===================================================================
--- gok/gok-spy.c	(revision 2336)
+++ gok/gok-spy.c	(working copy)
@@ -2300,6 +2300,7 @@
 		return FALSE;
 	}
 	else {
+	        gboolean retval;
 		gok_log("gok_data_get_drive_corepointer() is FALSE");
 		return gok_scanner_current_state_uses_core_mouse_button(button);
 	}
@@ -2345,6 +2346,7 @@
 									     event->timestamp);
 	}
 	gok_log_leave();
+
         return is_switch_trigger;
 }
 
Index: gok/main.c
===================================================================
--- gok/main.c	(revision 2337)
+++ gok/main.c	(working copy)
@@ -44,6 +44,9 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
+#ifdef HAVE_XEVIE
+#include <X11/extensions/Xevie.h>
+#endif
 #include "main.h"
 #include "gok.h"
 #include "gok-word-complete.h"
@@ -72,6 +75,8 @@
 
 extern int errno;
 
+static Display *xevie_dpy = NULL;
+
 #define USE_GCONF 1
 
 #define APP_STATIC_BUFF_SZ 30
@@ -170,6 +175,7 @@
 static gboolean gok_main_has_xkb_extension ();
 static gboolean gok_main_check_sticky_keys (GtkWidget *widget);
 void gok_main_mouse_button_listener (gint button, gint state, long mods, long timestamp);
+static gboolean gok_main_xevie_io (GIOChannel *source, GIOCondition condition, gpointer data);
 
 /* extern funcs */
 void       gok_input_detach_corepointer (void);
@@ -347,8 +353,9 @@
 #if ! defined ENABLE_LOGGING_NORMAL
 		if (respawn_on_segv)
 		{
-		    fprintf (stderr, "Restarting GOK.\n"); 
-		    g_spawn_command_line_async ("gok", NULL); 
+		    fprintf (stderr, "Restarting GOK.\n");
+		    g_on_error_stack_trace("gok");
+		    /* g_spawn_command_line_async ("gok", NULL); */
 		}
 #endif
 		break;
@@ -468,6 +475,12 @@
 		  LOGIN_HELPER_TYPE,
 		  gok_application)
 
+static void
+gok_main_intro (void)
+{
+  
+}
+
 /**
 * main
 * @argc: ignored
@@ -545,6 +558,34 @@
 		  0, 0, 0, 0, screen_width/2, screen_height/2);
 }
 
+static void
+main_xevie_test (void)
+{
+   XEvent event;
+   XClientMessageEvent *xcme;
+   XMotionEvent *motion_ev;
+   int count=0;
+   while(1) {
+     XNextEvent(xevie_dpy, &event);
+     xcme = (XClientMessageEvent *)&event;
+     /* for readOnly users, send events back to Xserver immediately */
+     printf("(%4d)", count++);
+     switch(event.type) {
+       case KeyPress:
+            printf(" KeyPress\n");
+            break;
+       case KeyRelease: printf(" KeyRelease\n"); break;
+       case ButtonPress: printf(" ButtonPress\n"); break;
+       case ButtonRelease: printf(" ButtonRelease\n"); break;
+       case MotionNotify: 
+	 motion_ev = (XMotionEvent *)&event;
+	 printf(" MotionNotify\n"); break;
+       case ClientMessage: printf("ClientMessage: <%s>\n", &xcme->data.b[1]); break;
+       default: printf(" unknown event %x\n", event.type); break;
+     }
+   }  
+}
+
 /**
 * gok_main_open
 * @argc: ignored
@@ -582,7 +623,6 @@
 		LIBGNOMEUI_PARAM_CRASH_DIALOG, FALSE,
 		NULL);
 		
-	
 	if (!bonobo_init (&argc, argv))
 	{
 	    if (gok_args.is_login)
@@ -795,11 +835,24 @@
 	gok_spy_register_windowchangelistener ((void *)gok_main_window_change_listener);
 	gok_spy_register_mousebuttonlistener ((void *)gok_main_mouse_button_listener);	
 	gok_spy_register_objectstatelistener ((void *)gok_main_object_state_listener);
-	
+#ifdef HAVE_XEVIE
+	xevie_dpy = XOpenDisplay(NULL);
+	if (!XevieStart (xevie_dpy)) 
+	  xevie_dpy = NULL;
+	else {
+	  GIOChannel *ioc;
+	  int fd;
+	  XevieSelectInput(xevie_dpy, PointerMotionMask);
+	  gok_log ("xevie opened, PointerMotionMask selected: %d\n", (int)xevie_dpy);
+	  fd = ConnectionNumber(xevie_dpy);
+	  ioc = g_io_channel_unix_new (fd);
+	  g_io_add_watch (ioc, G_IO_IN | G_IO_HUP, gok_main_xevie_io, xevie_dpy);
+	  g_io_channel_unref (ioc);
+	}
+#endif	
 	/* initialize sound */
 	gok_sound_initialize();
 
-
 	/* initialize libusb if it's been selected */
 	window_realize_data->use_libusb = FALSE;
 #ifdef ENABLE_LIBUSB_INPUT
@@ -844,7 +897,7 @@
 	gok_keyboard_initialize();
 	gok_branchbackstack_initialize();
 
-	fprintf (stderr, "login mode = %s\n", gok_args.is_login ? "true" : "false");
+	gok_log ("login mode = %s\n", gok_args.is_login ? "true" : "false");
 	if (!gok_args.is_login) {
 		gok_main_initialize_wordcomplete ();
 		gok_main_initialize_commandprediction ();
@@ -871,8 +924,8 @@
 
 	if (!gok_args.is_login) {
 		gok_main_check_accessibility();
-		if (gok_args.usb_vid_pid == NULL) {
-		        /* we're not using libusb */
+		if (gok_args.usb_vid_pid == NULL && xevie_dpy == NULL) {
+		        /* we're not using libusb or xevie */
 			gok_main_warn_corepointer (FALSE, FALSE, TRUE);
 		}
 	}
@@ -1185,12 +1238,45 @@
 static gboolean gok_main_idle_input (gpointer data)
 {
     input_idle_handler = 0;
+
     if ((gok_motion_event.n_axes > 0) && (gok_motion_event.n_axes < 4)) {
 	gok_scanner_input_motion (gok_motion_event.axes, gok_motion_event.n_axes);
     }
     return FALSE;
 }
 
+static gboolean gok_main_xevie_io (GIOChannel *source,
+				   GIOCondition condition,
+				   gpointer data)
+{
+    XEvent xevie_event;
+
+    while (xevie_dpy && XPending (xevie_dpy)) {
+      XMotionEvent *motion_event;
+      gboolean has_active_key = gok_scanner_key_is_active ();
+      /* Xevie has a motion event for us to check */
+      XNextEvent (xevie_dpy, &xevie_event);
+      switch (xevie_event.type)
+	{
+	case MotionNotify:
+	  motion_event = (XMotionEvent*) &xevie_event;
+	  gok_scanner_mouse_movement (motion_event->x_root, motion_event->y_root);
+	  break;
+	default:
+	  fprintf (stderr, "that's odd, unsolicited xevie event\n");
+	}
+      if (!has_active_key)
+	XevieSendEvent (xevie_dpy, &xevie_event, XEVIE_UNMODIFIED);
+    }
+    return TRUE;
+}
+
+gboolean
+gok_main_attach_new_devices (void)
+{
+  return (xevie_dpy == NULL);
+}
+
 void
 gok_main_queue_input_event (int *motion_data, gint n_axes)
 {
@@ -1274,7 +1360,6 @@
 			       &win_x, &win_y, &mask_ret);
 		SPI_generateMouseEvent (x, y, ename);
 	}
-
 	if (gok_input_corepointer_detached() || using_libusb == TRUE)
 	{
 		gok_main_mouse_button_listener (button, state, mods, timestamp);
@@ -1360,7 +1445,7 @@
 gok_main_mouse_button_listener (gint button, gint state, long mods, long timestamp)
 {
 	gok_log_enter();
-	gok_log("mouse button[%d] state[%d] mods[%lx] timestamp[%ld]",button,state,mods,timestamp);
+	gok_log ("mouse button[%d] state[%d] mods[%lx] timestamp[%ld]",button,state,mods,timestamp);
 
 	if (state == 0)
 	{
@@ -2767,12 +2852,21 @@
 gboolean
 gok_main_window_contains_pointer (void)
 {
-	gint x, y;
+	gint x=-1, y=-1, w=0, h=0;
+	gint px, py;
 	GdkModifierType mask;
 	GtkWidget *widget = gok_main_get_main_window ();
-	if (gdk_window_get_pointer (widget->window, &x, &y, &mask) != NULL)
-		return TRUE;
-	return FALSE;
+	gok_scanner_get_pointer_location (&px, &py);
+	if (widget->window) {
+	  gdk_window_get_position (widget->window, &x, &y);
+	  x = px-x;
+	  y = py-y;
+	  gdk_window_get_size (widget->window, &w, &h);
+	}
+	if (x < 0 || y < 0 || x > w || y > h)
+	  return FALSE;
+	else
+	  return TRUE;
 }
 
 Display *
Index: gok/gok-page-actions.c
===================================================================
--- gok/gok-page-actions.c	(revision 2336)
+++ gok/gok-page-actions.c	(working copy)
@@ -101,7 +101,10 @@
 			/* TODO: persist this list so we can query it later */
 			slist = slist->next;
 		}
-	
+		if (!gok_input_get_extension_device_name() ||
+		    !strlen(gok_input_get_extension_device_name())) {
+		         items = g_list_prepend (items, "");
+		}
 		gtk_combo_set_popdown_strings (GTK_COMBO (pComboBox), items);
 		g_list_free (items);
 	}
@@ -715,11 +718,13 @@
 
 	/* get the name of the input device from the combo box */
 	pStrComboInputDeviceName = gtk_editable_get_chars (pEditControl, 0, -1);
+	fprintf (stderr, "combosez %s\n", pStrComboInputDeviceName);
 	if (pStrComboInputDeviceName && strlen (pStrComboInputDeviceName) == 0) {
 		g_free (pStrComboInputDeviceName);
 	}
-	else
+	else if (pStrComboInputDeviceName)
 	{
+	  fprintf (stderr, "devicename[%s]\n", pStrComboInputDeviceName);
 		/* find the device in our list of input devices */
 	        
 		pInput = gok_input_find_by_name (pStrComboInputDeviceName, TRUE);
Index: gok/main.h
===================================================================
--- gok/main.h	(revision 2336)
+++ gok/main.h	(working copy)
@@ -85,6 +85,7 @@
 void gok_main_display_error (gchar* ErrorString);
 void gok_main_display_gconf_error (void);
 gboolean gok_main_window_contains_pointer (void);
+gboolean gok_main_attach_new_devices (void);
 Display *gok_main_display (void);
 gchar* gok_main_get_scan_override (void);
 gchar* gok_main_get_select_override (void);
