#include <config.h>
-#undef SPI_DEBUG
+#undef SPI_DEBUG
+#undef SPI_KEYEVENT_DEBUG
#include <string.h>
#include <ctype.h>
static void spi_controller_register_with_devices (SpiDEController *controller);
static gboolean spi_controller_update_key_grabs (SpiDEController *controller,
Accessibility_DeviceEvent *recv);
-static void spi_controller_register_device_listener (SpiDEController *controller,
+static gboolean spi_controller_register_device_listener (SpiDEController *controller,
DEControllerListener *l,
CORBA_Environment *ev);
static void spi_device_event_controller_forward_key_event (SpiDEController *controller,
const XEvent *event);
+#define spi_get_display() GDK_DISPLAY()
+
/* Private methods */
static KeyCode
keycode_for_keysym (long keysym)
{
- return XKeysymToKeycode (GDK_DISPLAY (), (KeySym) keysym);
+ return XKeysymToKeycode (spi_get_display (), (KeySym) keysym);
}
static DEControllerGrabMask *
DEControllerGrabMask *cur_mask = l->data;
cur_mask->ref_count--;
- cur_mask->pending_remove = TRUE;
+ if (cur_mask->ref_count <= 0)
+ {
+ cur_mask->pending_remove = TRUE;
+ }
}
else
{
if (key_listener->keys->_length == 0) /* special case means AnyKey/AllKeys */
{
grab_mask.key_val = AnyKey;
+#ifdef SPI_DEBUG
+ fprintf (stderr, "AnyKey grab!"); */
+#endif
process_cb (controller, &grab_mask);
}
else
for (i = 0; i < key_listener->keys->_length; ++i)
{
- long int key_val = key_listener->keys->_buffer[i];
+ Accessibility_KeyDefinition keydef = key_listener->keys->_buffer[i];
+ long int key_val = keydef.keysym;
/* X Grabs require keycodes, not keysyms */
- if (key_val >= 0)
+ if (keydef.keystring && keydef.keystring[0])
+ {
+ key_val = XStringToKeysym(keydef.keystring);
+ }
+ if (key_val > 0)
+ {
+ key_val = XKeysymToKeycode (spi_get_display (), (KeySym) key_val);
+ }
+ else
{
- key_val = XKeysymToKeycode (GDK_DISPLAY (), (KeySym) key_val);
+ key_val = keydef.keycode;
}
grab_mask.key_val = key_val;
-
process_cb (controller, &grab_mask);
}
}
}
-static void
+static gboolean
spi_controller_register_global_keygrabs (SpiDEController *controller,
DEControllerKeyListener *key_listener)
{
handle_keygrab (controller, key_listener, _register_keygrab);
- spi_controller_update_key_grabs (controller, NULL);
+ return spi_controller_update_key_grabs (controller, NULL);
}
static void
spi_controller_update_key_grabs (controller, NULL);
}
-static void
+static gboolean
spi_controller_register_device_listener (SpiDEController *controller,
DEControllerListener *listener,
CORBA_Environment *ev)
key_listener);
if (key_listener->mode->global)
{
- spi_controller_register_global_keygrabs (controller, key_listener);
+ return spi_controller_register_global_keygrabs (controller, key_listener);
}
+ else
+ return TRUE;
break;
default:
break;
}
+ return FALSE;
}
static GdkFilterReturn
if (error->error_code == BadAccess)
{
g_message ("Could not complete key grab: grab already in use.\n");
+ return 0;
}
else
{
- (*x_default_error_handler) (display, error);
+ return (*x_default_error_handler) (display, error);
}
}
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
x_default_error_handler = XSetErrorHandler (_spi_controller_device_error_handler);
-
- XSelectInput (GDK_DISPLAY (),
- DefaultRootWindow (GDK_DISPLAY ()),
- KeyPressMask | KeyReleaseMask);
}
+#define SPI_KEYEVENT_DEBUG
static gboolean
spi_key_set_contains_key (Accessibility_KeySet *key_set,
const Accessibility_DeviceEvent *key_event)
for (i = 0; i < len; ++i)
{
#ifdef SPI_KEYEVENT_DEBUG
- g_print ("key_set[%d] = %d; key_event %d, code %d\n",
- i, (int) key_set->_buffer[i],
- (int) key_event->id, (int) key_event->hw_code);
+ g_print ("key_set[%d] = %d; key_event %d, code %d, string %s\n",
+ i, (int) key_set->_buffer[i].keycode,
+ (int) key_event->id, (int) key_event->hw_code,
+ key_event->event_string);
#endif
- if (key_set->_buffer[i] == (CORBA_long) key_event->id)
+ if (key_set->_buffer[i].keysym == (CORBA_long) key_event->id)
+ {
+ return TRUE;
+ }
+ if (key_set->_buffer[i].keycode == (CORBA_long) key_event->hw_code)
{
return TRUE;
}
- if (key_set->_buffer[i] == (CORBA_long) -key_event->hw_code)
+ if (key_event->event_string && key_event->event_string[0] &&
+ !strcmp (key_set->_buffer[i].keystring, key_event->event_string))
{
return TRUE;
}
#ifdef SPI_KEYEVENT_DEBUG
if (!notify)
{
- g_print ("no match for listener %d\n", i);
+ g_print ("no match for event\n");
}
#endif
}
g_slist_free (notify);
-
+
+#ifdef SPI_DEBUG
+ if (is_consumed) g_message ("consumed\n");
+#endif
return is_consumed;
}
key_event.event_string = CORBA_string_dup ("space");
break;
case XK_Tab:
+#ifdef SPI_KEYEVENT_DEBUG
+ fprintf(stderr, "Tab\n");
+#endif
key_event.event_string = CORBA_string_dup ("Tab");
break;
case XK_BackSpace:
case XK_Return:
key_event.event_string = CORBA_string_dup ("Return");
break;
+ case XK_Home:
+ key_event.event_string = CORBA_string_dup ("Home");
+ break;
+ case XK_Page_Down:
+ key_event.event_string = CORBA_string_dup ("Page_Down");
+ break;
+ case XK_Page_Up:
+ key_event.event_string = CORBA_string_dup ("Page_Up");
+ break;
+ case XK_F1:
+ key_event.event_string = CORBA_string_dup ("F1");
+ break;
+ case XK_F2:
+ key_event.event_string = CORBA_string_dup ("F2");
+ break;
+ case XK_F3:
+ key_event.event_string = CORBA_string_dup ("F3");
+ break;
+ case XK_F4:
+ key_event.event_string = CORBA_string_dup ("F4");
+ break;
+ case XK_F5:
+ key_event.event_string = CORBA_string_dup ("F5");
+ break;
+ case XK_F6:
+ key_event.event_string = CORBA_string_dup ("F6");
+ break;
+ case XK_F7:
+ key_event.event_string = CORBA_string_dup ("F7");
+ break;
+ case XK_F8:
+ key_event.event_string = CORBA_string_dup ("F8");
+ break;
+ case XK_F9:
+ key_event.event_string = CORBA_string_dup ("F9");
+ break;
+ case XK_F10:
+ key_event.event_string = CORBA_string_dup ("F10");
+ break;
+ case XK_F11:
+ key_event.event_string = CORBA_string_dup ("F11");
+ break;
+ case XK_F12:
+ key_event.event_string = CORBA_string_dup ("F12");
+ break;
+ case XK_End:
+ key_event.event_string = CORBA_string_dup ("End");
+ break;
+ case XK_Escape:
+ key_event.event_string = CORBA_string_dup ("Escape");
+ break;
+ case XK_Up:
+ key_event.event_string = CORBA_string_dup ("Up");
+ break;
+ case XK_Down:
+ key_event.event_string = CORBA_string_dup ("Down");
+ break;
+ case XK_Left:
+ key_event.event_string = CORBA_string_dup ("Left");
+ break;
+ case XK_Right:
+ key_event.event_string = CORBA_string_dup ("Right");
+ break;
default:
if (XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL) > 0)
{
next = l->next;
re_issue_grab = recv &&
+/* (recv->type == Accessibility_KEY_RELEASED) && - (?) */
(recv->modifiers & grab_mask->mod_mask) &&
(grab_mask->key_val == keycode_for_keysym (recv->id));
#ifdef SPI_DEBUG
fprintf (stderr, "ungrabbing, mask=%x\n", grab_mask->mod_mask);
#endif
- XUngrabKey (GDK_DISPLAY (),
+ XUngrabKey (spi_get_display (),
grab_mask->key_val,
grab_mask->mod_mask,
gdk_x11_get_default_root_xwindow ());
#ifdef SPI_DEBUG
fprintf (stderr, "grab with mask %x\n", grab_mask->mod_mask);
#endif
- XGrabKey (GDK_DISPLAY (),
+ XGrabKey (spi_get_display (),
grab_mask->key_val,
grab_mask->mod_mask,
gdk_x11_get_default_root_xwindow (),
fprintf(stderr, "spi_device_event_controller_object_finalize called\n");
#endif
/* disconnect any special listeners, get rid of outstanding keygrabs */
- XUngrabKey (GDK_DISPLAY (), AnyKey, AnyModifier, DefaultRootWindow (GDK_DISPLAY ()));
+ XUngrabKey (spi_get_display (), AnyKey, AnyModifier, DefaultRootWindow (spi_get_display ()));
spi_device_event_controller_parent_class->finalize (object);
}
* CORBA Accessibility::DEController::registerKeystrokeListener
* method implementation
*/
-static void
+static CORBA_boolean
impl_register_keystroke_listener (PortableServer_Servant servant,
const Accessibility_DeviceEventListener l,
const Accessibility_KeySet *keys,
(void *) l, (unsigned long) mask);
#endif
dec_listener = spi_dec_key_listener_new (l, keys, mask, type, mode, ev);
- spi_controller_register_device_listener (
- controller, (DEControllerListener *) dec_listener, ev);
+ return spi_controller_register_device_listener (
+ controller, (DEControllerListener *) dec_listener, ev);
}
switch (synth_type)
{
case Accessibility_KEY_PRESS:
- XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, True, CurrentTime);
+ XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, True, CurrentTime);
break;
case Accessibility_KEY_PRESSRELEASE:
- XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, True, CurrentTime);
+ XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, True, CurrentTime);
case Accessibility_KEY_RELEASE:
- XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, False, CurrentTime);
+ XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, False, CurrentTime);
break;
case Accessibility_KEY_SYM:
key_synth_code = keycode_for_keysym (keycode);
- XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) key_synth_code, True, CurrentTime);
- XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) key_synth_code, False, CurrentTime);
+ XTestFakeKeyEvent (spi_get_display (), (unsigned int) key_synth_code, True, CurrentTime);
+ XTestFakeKeyEvent (spi_get_display (), (unsigned int) key_synth_code, False, CurrentTime);
break;
case Accessibility_KEY_STRING:
fprintf (stderr, "Not yet implemented\n");
const CORBA_char *eventName,
CORBA_Environment *ev)
{
+ int button;
+ gboolean error = FALSE;
+ Display *display = spi_get_display ();
#ifdef SPI_DEBUG
fprintf (stderr, "generating mouse %s event at %ld, %ld\n",
eventName, (long int) x, (long int) y);
#endif
- g_warning ("not yet implemented");
+ g_message ("mouse event synthesis\n");
+ switch (eventName[0])
+ {
+ case 'b':
+ switch (eventName[1])
+ {
+ /* TODO: check number of buttons before parsing */
+ case '1':
+ button = 1;
+ break;
+ case '2':
+ button = 2;
+ break;
+ case '3':
+ button = 3;
+ break;
+ default:
+ error = TRUE;
+ }
+ if (!error)
+ {
+ if (x != -1 && y != -1)
+ {
+ XTestFakeMotionEvent (display, DefaultScreen (display),
+ x, y, 0);
+ }
+ XTestFakeButtonEvent (display, button, !(eventName[2] == 'r'), 0);
+ if (eventName[2] == 'c')
+ XTestFakeButtonEvent (display, button, FALSE, 1);
+ else if (eventName[2] == 'd')
+ {
+ XTestFakeButtonEvent (display, button, FALSE, 1);
+ XTestFakeButtonEvent (display, button, TRUE, 2);
+ XTestFakeButtonEvent (display, button, FALSE, 3);
+ }
+ }
+ break;
+ case 'r': /* relative motion */
+ XTestFakeRelativeMotionEvent (display, x, y, 0);
+ break;
+ case 'a': /* absolute motion */
+ XTestFakeMotionEvent (display, DefaultScreen (display),
+ x, y, 0);
+ break;
+ }
}
/* Accessibility::DEController::notifyListenersSync */
CORBA_exception_init (&ev);
key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
+
+ spi_controller_update_key_grabs (controller, &key_event);
+
/* relay to listeners, and decide whether to consume it or not */
is_consumed = spi_notify_keylisteners (
&controller->key_listeners, &key_event, CORBA_TRUE, &ev);
if (is_consumed)
{
- XAllowEvents (GDK_DISPLAY (), AsyncKeyboard, CurrentTime);
+ XAllowEvents (spi_get_display (), AsyncKeyboard, CurrentTime);
}
else
{
- XAllowEvents (GDK_DISPLAY (), ReplayKeyboard, CurrentTime);
+ XAllowEvents (spi_get_display (), ReplayKeyboard, CurrentTime);
}
-
- spi_controller_update_key_grabs (controller, &key_event);
}
SpiDEController *