*
* (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
*
- * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2003 Sun Microsystems Inc.,
* Copyright 2001, 2002 Ximian, Inc.
*
* This library is free software; you can redistribute it and/or
static unsigned int mouse_button_mask =
Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask;
static unsigned int key_modifier_mask =
- Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | LockMask | ControlMask;
+ Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | LockMask | ControlMask | SPI_KEYMASK_NUMLOCK;
+static unsigned int _numlock_physical_mask = Mod2Mask; /* a guess, will be reset */
static GQuark spi_dec_private_quark = 0;
DEControllerPrivateData *priv =
g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
#ifdef SPI_XKB_DEBUG
- if (priv->xkb_latch_mask) fprintf (stderr, "unlatch pending! %x\n", mask);
+ if (priv->xkb_latch_mask) fprintf (stderr, "unlatch pending! %x\n",
+ priv->xkb_latch_mask);
#endif
priv->pending_xkb_mod_relatch_mask |= priv->xkb_latch_mask;
}
+static void
+spi_dec_clear_unlatch_pending (SpiDEController *controller)
+{
+ DEControllerPrivateData *priv =
+ g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
+ priv->xkb_latch_mask = 0;
+}
+
static gboolean
spi_dec_button_update_and_emit (SpiDEController *controller,
guint mask_return)
fprintf (stderr, "MODIFIER CHANGE EVENT! %x to %x\n",
prev_mask, current_mask);
#endif
+
+ /* set bits for the virtual modifiers like NUMLOCK */
+ if (prev_mask & _numlock_physical_mask)
+ prev_mask |= SPI_KEYMASK_NUMLOCK;
+ if (current_mask & _numlock_physical_mask)
+ current_mask |= SPI_KEYMASK_NUMLOCK;
+
e.type = "keyboard:modifiers";
e.source = BONOBO_OBJREF (controller->registry->desktop);
e.detail1 = prev_mask & key_modifier_mask;
if (display)
{
- XGrabButton (display, AnyButton, AnyModifier,
+ if (XGrabButton (display, AnyButton, AnyModifier,
gdk_x11_get_default_root_xwindow (),
True, ButtonPressMask | ButtonReleaseMask,
- GrabModeSync, GrabModeAsync, None, None);
+ GrabModeSync, GrabModeAsync, None, None) != Success)
+ fprintf (stderr, "WARNING: could not grab mouse buttons!\n");
XSync (display, False);
#ifdef SPI_DEBUG
fprintf (stderr, "mouse buttons grabbed\n");
}
}
+/**
+ * Eventually we can use this to make the marshalling of mask types
+ * more sane, but for now we just use this to detect
+ * the use of 'virtual' masks such as Mumlock and convert them to
+ * system-specific mask values (i.e. ModMask).
+ *
+ **/
+static Accessibility_ControllerEventMask
+spi_dec_translate_mask (Accessibility_ControllerEventMask mask)
+{
+ DEControllerPrivateData *priv;
+
+ if (mask == SPI_KEYMASK_NUMLOCK) {
+ mask = _numlock_physical_mask;
+ }
+ return mask;
+}
+
static DEControllerKeyListener *
spi_dec_key_listener_new (CORBA_Object l,
const Accessibility_KeySet *keys,
key_listener->listener.object = bonobo_object_dup_ref (l, ev);
key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
key_listener->keys = ORBit_copy_value (keys, TC_Accessibility_KeySet);
- key_listener->mask = mask;
+ key_listener->mask = spi_dec_translate_mask (mask);
key_listener->listener.typeseq = ORBit_copy_value (typeseq, TC_Accessibility_EventTypeSeq);
if (mode)
key_listener->mode = ORBit_copy_value (mode, TC_Accessibility_EventListenerMode);
int button = xbutton_event->button;
unsigned int mouse_button_state = xbutton_event->state;
-
+
switch (button)
{
case 1:
/* if client wants to consume this event, and XKB latch state was
* unset by this button event, we reset it
*/
- if (is_consumed && (xkb_mod_unlatch_occurred))
+ if (is_consumed && xkb_mod_unlatch_occurred)
spi_dec_set_unlatch_pending (controller, mouse_mask_state);
XAllowEvents (spi_get_display (),
&= ~(XkbAX_StickyKeysFBMask);
XkbChangeControls (display, priv->xkb_desc, &changes);
}
+ /* TODO: account for lock as well as latch */
XkbLatchModifiers (display,
XkbUseCoreKbd,
priv->pending_xkb_mod_relatch_mask,
XkbSelectEvents (spi_get_display (),
XkbUseCoreKbd,
XkbStateNotifyMask, XkbStateNotifyMask);
+ _numlock_physical_mask = XkbKeysymToModifiers (spi_get_display (),
+ XK_Num_Lock);
}
gdk_window_add_filter (NULL, global_filter_fn, controller);
DEControllerKeyListener *listener,
CORBA_boolean is_system_global)
{
- if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask & 0xFFFF)) &&
+ if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask & 0xFF)) &&
spi_key_set_contains_key (listener->keys, key_event) &&
spi_eventtype_seq_contains_event (listener->listener.typeseq, key_event) &&
(is_system_global == listener->mode->global))
Accessibility_DeviceEvent key_event;
KeySym keysym;
const int cbuf_bytes = 20;
- char cbuf [cbuf_bytes];
-
- keysym = XLookupKeysym (x_key_event, 0);
+ char cbuf [cbuf_bytes+1];
+ int nbytes;
+
+ nbytes = XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL);
key_event.id = (CORBA_long)(keysym);
key_event.hw_code = (CORBA_short) x_key_event->keycode;
if (((XEvent *) x_key_event)->type == KeyPress)
{
- key_event.type = Accessibility_KEY_PRESSED;
+ key_event.type = Accessibility_KEY_PRESSED_EVENT;
}
else
{
- key_event.type = Accessibility_KEY_RELEASED;
+ key_event.type = Accessibility_KEY_RELEASED_EVENT;
}
key_event.modifiers = (CORBA_unsigned_short)(x_key_event->state);
key_event.is_text = CORBA_FALSE;
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:
key_event.event_string = CORBA_string_dup ("Right");
break;
default:
- if (XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL) > 0)
+ if (nbytes > 0)
{
+ gunichar c;
+ cbuf[nbytes] = '\0'; /* OK since length is cbuf_bytes+1 */
key_event.event_string = CORBA_string_dup (cbuf);
- if (isgraph (keysym))
+ c = g_utf8_get_char_validated (cbuf, nbytes);
+ if ((c > 0) && g_unichar_isprint (c))
{
- key_event.is_text = CORBA_TRUE; /* FIXME: incorrect for some composed chars? */
+ key_event.is_text = CORBA_TRUE;
+ /* incorrect for some composed chars? */
}
}
else
key_event.timestamp = (CORBA_unsigned_long) x_key_event->time;
#ifdef SPI_KEYEVENT_DEBUG
fprintf (stderr,
- "Key %lu pressed (%c), modifiers %d\n",
- (unsigned long) keysym,
- keysym ? (int) keysym : '*',
- (int) x_key_event->state);
+ "Key %lu pressed (%c), modifiers %d; string=%s [%x] %s\n",
+ (unsigned long) keysym,
+ keysym ? (int) keysym : '*',
+ (int) x_key_event->state,
+ key_event.event_string,
+ key_event.event_string[0],
+ (key_event.is_text == CORBA_TRUE) ? "(text)" : "(not text)");
#endif
#ifdef SPI_DEBUG
fprintf (stderr, "%s%c",
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));
SpiDEController *controller =
SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant));
long key_synth_code;
+ KeySym keysym;
#ifdef SPI_DEBUG
fprintf (stderr, "synthesizing keystroke %ld, type %d\n",
{
DBG (-1, g_warning ("Error emitting keystroke"));
}
+ if (synth_type == Accessibility_KEY_SYM) {
+ keysym = keycode;
+ }
+ else {
+ keysym = XkbKeycodeToKeysym (spi_get_display (), keycode, 0, 0);
+ }
+ if (XkbKeysymToModifiers (spi_get_display (), keysym) == 0)
+ {
+ spi_dec_clear_unlatch_pending (controller);
+ }
}
/* Accessibility::DEController::generateMouseEvent */
BONOBO_TYPE_FUNC_FULL (SpiDEController,
Accessibility_DeviceEventController,
PARENT_TYPE,
- spi_device_event_controller);
+ spi_device_event_controller)