X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=registryd%2Fdeviceeventcontroller.c;h=609deeac759a3a41476bc5a481a911d03d77c655;hb=5e9de4f03f0c4406e3479d50a012901e87642210;hp=469616cb7e0ebbb1e448087d2e285e1b3d589995;hpb=4192ec5c3f02f9520d2905e3b6bf4f5d01f8c26c;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c index 469616c..609deea 100644 --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@ -2,7 +2,7 @@ * * (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 @@ -60,7 +60,8 @@ static unsigned int mouse_mask_state = 0; 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; @@ -186,11 +187,20 @@ spi_dec_set_unlatch_pending (SpiDEController *controller, unsigned mask) 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) @@ -390,6 +400,13 @@ spi_dec_emit_modifier_event (SpiDEController *controller, guint prev_mask, 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; @@ -446,6 +463,7 @@ spi_dec_poll_mouse_moving (gpointer data) } } +#ifdef WE_NEED_UGRAB_MOUSE static int spi_dec_ungrab_mouse (gpointer data) { @@ -457,6 +475,7 @@ spi_dec_ungrab_mouse (gpointer data) } return FALSE; } +#endif static void spi_dec_init_mouse_listener (SpiRegistry *registry) @@ -466,10 +485,11 @@ spi_dec_init_mouse_listener (SpiRegistry *registry) 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"); @@ -477,6 +497,24 @@ spi_dec_init_mouse_listener (SpiRegistry *registry) } } +/** + * 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, @@ -489,7 +527,7 @@ spi_dec_key_listener_new (CORBA_Object l, 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); @@ -809,7 +847,7 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller, int button = xbutton_event->button; unsigned int mouse_button_state = xbutton_event->state; - + switch (button) { case 1: @@ -879,7 +917,7 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller, /* 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 (), @@ -948,6 +986,7 @@ global_filter_fn (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) &= ~(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, @@ -1000,7 +1039,6 @@ spi_controller_register_with_devices (SpiDEController *controller) g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark); /* FIXME: should check for extension first! */ XTestGrabControl (spi_get_display (), True); - priv->xkb_desc = XkbGetMap (spi_get_display (), 0, XkbUseCoreKbd); /* calls to device-specific implementations and routines go here */ /* register with: keyboard hardware code handler */ @@ -1012,10 +1050,14 @@ spi_controller_register_with_devices (SpiDEController *controller) &priv->xkb_base_error_code, NULL, NULL); if (priv->have_xkb) { + priv->xkb_desc = XkbGetMap (spi_get_display (), 0, XkbUseCoreKbd); 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); gdk_window_set_events (gdk_get_default_root_window (), @@ -1112,7 +1154,7 @@ spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event, 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)) @@ -1213,18 +1255,19 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) 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; @@ -1234,9 +1277,6 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) 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: @@ -1309,12 +1349,16 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) 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 @@ -1326,10 +1370,13 @@ spi_keystroke_from_x_key_event (XKeyEvent *x_key_event) 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", @@ -1367,7 +1414,6 @@ spi_controller_update_key_grabs (SpiDEController *controller, 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)); @@ -1790,11 +1836,8 @@ impl_generate_keyboard_event (PortableServer_Servant servant, { SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant)); - DEControllerPrivateData *priv; long key_synth_code; - unsigned int slow_keys_delay; - unsigned int press_time; - unsigned int release_time; + KeySym keysym; #ifdef SPI_DEBUG fprintf (stderr, "synthesizing keystroke %ld, type %d\n", @@ -1837,6 +1880,16 @@ impl_generate_keyboard_event (PortableServer_Servant servant, { 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 */ @@ -1847,7 +1900,7 @@ impl_generate_mouse_event (PortableServer_Servant servant, const CORBA_char *eventName, CORBA_Environment *ev) { - int button; + int button = 0; gboolean error = FALSE; Display *display = spi_get_display (); #ifdef SPI_DEBUG @@ -1869,6 +1922,12 @@ impl_generate_mouse_event (PortableServer_Servant servant, case '3': button = 3; break; + case '4': + button = 4; + break; + case '5': + button = 5; + break; default: error = TRUE; } @@ -1961,13 +2020,6 @@ spi_device_event_controller_init (SpiDEController *device_event_controller) device_event_controller->mouse_listeners = NULL; device_event_controller->keygrabs_list = NULL; - /* - * TODO: fixme, this module makes the foolish assumptions that - * registryd uses the same display as the apps, and that the - * DISPLAY environment variable is set. - */ - gdk_init (NULL, NULL); - private = g_new0 (DEControllerPrivateData, 1); gettimeofday (&private->last_press_time, NULL); gettimeofday (&private->last_release_time, NULL); @@ -2012,7 +2064,6 @@ spi_device_event_controller_new (SpiRegistry *registry) { SpiDEController *retval = g_object_new ( SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL); - DEControllerPrivateData *private; retval->registry = SPI_REGISTRY (bonobo_object_ref ( BONOBO_OBJECT (registry))); @@ -2025,4 +2076,4 @@ spi_device_event_controller_new (SpiRegistry *registry) BONOBO_TYPE_FUNC_FULL (SpiDEController, Accessibility_DeviceEventController, PARENT_TYPE, - spi_device_event_controller); + spi_device_event_controller)