Example #1
0
gint
KeymapWrapper::GetFirstLatinGroup()
{
    GdkKeymapKey *keys;
    gint count;
    gint minGroup = -1;
    if (gdk_keymap_get_entries_for_keyval(mGdkKeymap, GDK_a, &keys, &count)) {
        // find the minimum number group for latin inputtable layout
        for (gint i = 0; i < count && minGroup != 0; ++i) {
            if (keys[i].level != 0 && keys[i].level != 1) {
                continue;
            }
            if (minGroup >= 0 && keys[i].group > minGroup) {
                continue;
            }
            minGroup = keys[i].group;
        }
        g_free(keys);
    }
    return minGroup;
}
void EventSenderProxy::keyDown(WKStringRef keyRef, WKEventModifiers wkModifiers, unsigned location)
{
    guint modifiers = webkitModifiersToGDKModifiers(wkModifiers);
    int gdkKeySym = getGDKKeySymForKeyRef(keyRef, location, &modifiers);

    GdkEvent* pressEvent = gdk_event_new(GDK_KEY_PRESS);
    pressEvent->key.keyval = gdkKeySym;
    pressEvent->key.state = modifiers;
    pressEvent->key.window = gtk_widget_get_window(GTK_WIDGET(m_testController->mainWebView()->platformWindow()));
    g_object_ref(pressEvent->key.window);
    gdk_event_set_device(pressEvent, gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_window_get_display(pressEvent->key.window))));

    GOwnPtr<GdkKeymapKey> keys;
    gint nKeys;
    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys.outPtr(), &nKeys))
        pressEvent->key.hardware_keycode = keys.get()[0].keycode;

    GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
    dispatchEvent(pressEvent);
    releaseEvent->key.type = GDK_KEY_RELEASE;
    dispatchEvent(releaseEvent);
}
Example #3
0
/* Return true if keyval is defined in keyboard group
 */
static gboolean 
keyval_in_group (GdkKeymap  *keymap,
                 guint      keyval,
                 gint       group)
{                 
  GtkKeyHashEntry entry;
  gint i;

  gdk_keymap_get_entries_for_keyval (keymap,
				     keyval,
				     &entry.keys, &entry.n_keys);

  for (i = 0; i < entry.n_keys; i++)
    {
      if (entry.keys[i].group == group)
        {
          g_free (entry.keys);
          return TRUE;
        }
    }

  g_free (entry.keys);
  return FALSE;
}
Example #4
0
static VALUE
rg_get_entries_for_keyval(VALUE self, VALUE keyval)
{
  GdkKeymapKey* keys;
  gint n_keys;
  gboolean ret;
  ret = gdk_keymap_get_entries_for_keyval(_SELF(self),
                                          NUM2UINT(keyval), &keys, &n_keys);

  if (ret){
    VALUE key;
    VALUE ary = rb_ary_new();
    gint i;
    for (i = 0; i < n_keys; i++){
      key = rb_ary_new3(3, UINT2NUM(keys[i].keycode), INT2NUM(keys[i].group), 
                        INT2NUM(keys[i].level));
      rb_ary_push(ary, key);
    }
    g_free(keys);
    return ary;
  } else {
    return Qnil;
  }
}
Example #5
0
static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");

    webkit_web_frame_layout(mainFrame);

    // handle modifier keys.
    int state = 0;
    if (argumentCount > 1) {
        JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception);
        if (modifiersArray) {
            for (int i = 0; i < JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); ++i) {
                JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
                JSStringRef string = JSValueToStringCopy(context, value, 0);
                if (JSStringIsEqualToUTF8CString(string, "ctrlKey"))
                    state |= GDK_CONTROL_MASK;
                else if (JSStringIsEqualToUTF8CString(string, "shiftKey"))
                    state |= GDK_SHIFT_MASK;
                else if (JSStringIsEqualToUTF8CString(string, "altKey"))
                    state |= GDK_MOD1_MASK;

                JSStringRelease(string);
            }
        }
    }

    // handle location argument.
    int location = DOM_KEY_LOCATION_STANDARD;
    if (argumentCount > 2)
        location = (int)JSValueToNumber(context, arguments[2], exception);

    JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
    int gdkKeySym = GDK_VoidSymbol;
    if (location == DOM_KEY_LOCATION_NUMPAD) {
        if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
            gdkKeySym = GDK_KP_Left;
        else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
            gdkKeySym = GDK_KP_Right;
        else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
            gdkKeySym = GDK_KP_Up;
        else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
            gdkKeySym = GDK_KP_Down;
        else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
            gdkKeySym = GDK_KP_Page_Up;
        else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
            gdkKeySym = GDK_KP_Page_Down;
        else if (JSStringIsEqualToUTF8CString(character, "home"))
            gdkKeySym = GDK_KP_Home;
        else if (JSStringIsEqualToUTF8CString(character, "end"))
            gdkKeySym = GDK_KP_End;
        else
            // Assume we only get arrow/pgUp/pgDn/home/end keys with
            // location=NUMPAD for now.
            g_assert_not_reached();
    } else {
        if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
            gdkKeySym = GDK_Left;
        else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
            gdkKeySym = GDK_Right;
        else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
            gdkKeySym = GDK_Up;
        else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
            gdkKeySym = GDK_Down;
        else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
            gdkKeySym = GDK_Page_Up;
        else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
            gdkKeySym = GDK_Page_Down;
        else if (JSStringIsEqualToUTF8CString(character, "home"))
            gdkKeySym = GDK_Home;
        else if (JSStringIsEqualToUTF8CString(character, "end"))
            gdkKeySym = GDK_End;
        else if (JSStringIsEqualToUTF8CString(character, "delete"))
            gdkKeySym = GDK_BackSpace;
        else if (JSStringIsEqualToUTF8CString(character, "F1"))
            gdkKeySym = GDK_F1;
        else if (JSStringIsEqualToUTF8CString(character, "F2"))
            gdkKeySym = GDK_F2;
        else if (JSStringIsEqualToUTF8CString(character, "F3"))
            gdkKeySym = GDK_F3;
        else if (JSStringIsEqualToUTF8CString(character, "F4"))
            gdkKeySym = GDK_F4;
        else if (JSStringIsEqualToUTF8CString(character, "F5"))
            gdkKeySym = GDK_F5;
        else if (JSStringIsEqualToUTF8CString(character, "F6"))
            gdkKeySym = GDK_F6;
        else if (JSStringIsEqualToUTF8CString(character, "F7"))
            gdkKeySym = GDK_F7;
        else if (JSStringIsEqualToUTF8CString(character, "F8"))
            gdkKeySym = GDK_F8;
        else if (JSStringIsEqualToUTF8CString(character, "F9"))
            gdkKeySym = GDK_F9;
        else if (JSStringIsEqualToUTF8CString(character, "F10"))
            gdkKeySym = GDK_F10;
        else if (JSStringIsEqualToUTF8CString(character, "F11"))
            gdkKeySym = GDK_F11;
        else if (JSStringIsEqualToUTF8CString(character, "F12"))
            gdkKeySym = GDK_F12;
        else {
            int charCode = JSStringGetCharactersPtr(character)[0];
            if (charCode == '\n' || charCode == '\r')
                gdkKeySym = GDK_Return;
            else if (charCode == '\t')
                gdkKeySym = GDK_Tab;
            else if (charCode == '\x8')
                gdkKeySym = GDK_BackSpace;
            else {
                gdkKeySym = gdk_unicode_to_keyval(charCode);
                if (WTF::isASCIIUpper(charCode))
                    state |= GDK_SHIFT_MASK;
            }
        }
    }
    JSStringRelease(character);

    WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
    if (!view)
        return JSValueMakeUndefined(context);

    // create and send the event
    GdkEvent event;
    memset(&event, 0, sizeof(event));
    event.key.keyval = gdkKeySym;
    event.key.state = state;
    event.key.window = GTK_WIDGET(view)->window;

    // When synthesizing an event, an invalid hardware_keycode value
    // can cause it to be badly processed by Gtk+.
    GdkKeymapKey* keys;
    gint n_keys;
    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys, &n_keys)) {
        event.key.hardware_keycode = keys[0].keycode;
        g_free(keys);
    }

    gboolean return_val;
    event.key.type = GDK_KEY_PRESS;

    g_signal_emit_by_name(view, "key-press-event", &event.key, &return_val);

    event.key.type = GDK_KEY_RELEASE;
    g_signal_emit_by_name(view, "key-release-event", &event.key, &return_val);

    return JSValueMakeUndefined(context);
}
Example #6
0
static GdkNativeWindow
select_window_x11 (GdkScreen *screen)
{
  Display      *x_dpy       = GDK_SCREEN_XDISPLAY (screen);
  gint          x_scr       = GDK_SCREEN_XNUMBER (screen);
  Window        x_root      = RootWindow (x_dpy, x_scr);
  Window        x_win       = None;
  GC            x_gc          = None;
  Cursor        x_cursor    = XCreateFontCursor (x_dpy, GDK_CROSSHAIR);
  GdkKeymapKey *keys        = NULL;
  gint          status;
  gint          i, num_keys;
  gint          buttons     = 0;
  gint          mask        = ButtonPressMask | ButtonReleaseMask;
  gboolean      cancel      = FALSE;

  if (shootvals.shoot_type == SHOOT_REGION)
    mask |= PointerMotionMask;

  status = XGrabPointer (x_dpy, x_root, False,
                         mask, GrabModeSync, GrabModeAsync,
                         x_root, x_cursor, CurrentTime);

  if (status != GrabSuccess)
    {
      gint  x, y;
      guint xmask;

      /* if we can't grab the pointer, return the window under the pointer */
      XQueryPointer (x_dpy, x_root, &x_root, &x_win, &x, &y, &x, &y, &xmask);

      if (x_win == None || x_win == x_root)
        g_message (_("Error selecting the window"));
    }

  if (shootvals.shoot_type == SHOOT_REGION)
    {
      XGCValues gc_values;

      gc_values.function           = GXxor;
      gc_values.plane_mask         = AllPlanes;
      gc_values.foreground         = WhitePixel (x_dpy, x_scr);
      gc_values.background         = BlackPixel (x_dpy, x_scr);
      gc_values.line_width         = 0;
      gc_values.line_style         = LineSolid;
      gc_values.fill_style         = FillSolid;
      gc_values.cap_style          = CapButt;
      gc_values.join_style         = JoinMiter;
      gc_values.graphics_exposures = FALSE;
      gc_values.clip_x_origin      = 0;
      gc_values.clip_y_origin      = 0;
      gc_values.clip_mask          = None;
      gc_values.subwindow_mode     = IncludeInferiors;

      x_gc = XCreateGC (x_dpy, x_root,
                        GCFunction | GCPlaneMask | GCForeground | GCLineWidth |
                        GCLineStyle | GCCapStyle | GCJoinStyle |
                        GCGraphicsExposures | GCBackground | GCFillStyle |
                        GCClipXOrigin | GCClipYOrigin | GCClipMask |
                        GCSubwindowMode,
                        &gc_values);
    }

  if (gdk_keymap_get_entries_for_keyval (NULL, GDK_Escape, &keys, &num_keys))
    {
      gdk_error_trap_push ();

#define X_GRAB_KEY(index, modifiers) \
      XGrabKey (x_dpy, keys[index].keycode, modifiers, x_root, False, \
                GrabModeAsync, GrabModeAsync)

      for (i = 0; i < num_keys; i++)
        {
          X_GRAB_KEY (i, 0);
          X_GRAB_KEY (i, LockMask);            /* CapsLock              */
          X_GRAB_KEY (i, Mod2Mask);            /* NumLock               */
          X_GRAB_KEY (i, Mod5Mask);            /* ScrollLock            */
          X_GRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock    */
          X_GRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */
          X_GRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock  + ScrollLock */
          X_GRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all        */
        }

#undef X_GRAB_KEY

      gdk_flush ();
      gdk_error_trap_pop ();
    }

  while (! cancel && ((x_win == None) || (buttons != 0)))
    {
      XEvent x_event;
      gint   x, y, w, h;

      XAllowEvents (x_dpy, SyncPointer, CurrentTime);
      XWindowEvent (x_dpy, x_root, mask | KeyPressMask, &x_event);

      switch (x_event.type)
        {
        case ButtonPress:
          if (x_win == None)
            {
              x_win = x_event.xbutton.subwindow;

              if (x_win == None)
                x_win = x_root;
#ifdef HAVE_X11_XMU_WINUTIL_H
              else if (! shootvals.decorate)
                x_win = XmuClientWindow (x_dpy, x_win);
#endif

              shootvals.x2 = shootvals.x1 = x_event.xbutton.x_root;
              shootvals.y2 = shootvals.y1 = x_event.xbutton.y_root;
            }

          buttons++;
          break;

        case ButtonRelease:
          if (buttons > 0)
            buttons--;

          if (! buttons && shootvals.shoot_type == SHOOT_REGION)
            {
              x = MIN (shootvals.x1, shootvals.x2);
              y = MIN (shootvals.y1, shootvals.y2);
              w = ABS (shootvals.x2 - shootvals.x1);
              h = ABS (shootvals.y2 - shootvals.y1);

              if (w > 0 && h > 0)
                XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);

              shootvals.x2 = x_event.xbutton.x_root;
              shootvals.y2 = x_event.xbutton.y_root;
            }
          break;

        case MotionNotify:
          if (buttons > 0)
            {
              x = MIN (shootvals.x1, shootvals.x2);
              y = MIN (shootvals.y1, shootvals.y2);
              w = ABS (shootvals.x2 - shootvals.x1);
              h = ABS (shootvals.y2 - shootvals.y1);

              if (w > 0 && h > 0)
                XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);

              shootvals.x2 = x_event.xmotion.x_root;
              shootvals.y2 = x_event.xmotion.y_root;

              x = MIN (shootvals.x1, shootvals.x2);
              y = MIN (shootvals.y1, shootvals.y2);
              w = ABS (shootvals.x2 - shootvals.x1);
              h = ABS (shootvals.y2 - shootvals.y1);

              if (w > 0 && h > 0)
                XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);
            }
          break;

        case KeyPress:
          {
            guint *keyvals;
            gint   n;

            if (gdk_keymap_get_entries_for_keycode (NULL, x_event.xkey.keycode,
                                                    NULL, &keyvals, &n))
              {
                gint i;

                for (i = 0; i < n && ! cancel; i++)
                  if (keyvals[i] == GDK_Escape)
                    cancel = TRUE;

                g_free (keyvals);
              }
          }
          break;

        default:
          break;
        }
    }

  if (keys)
    {
#define X_UNGRAB_KEY(index, modifiers) \
      XUngrabKey (x_dpy, keys[index].keycode, modifiers, x_root)

      for (i = 0; i < num_keys; i++)
        {
          X_UNGRAB_KEY (i, 0);
          X_UNGRAB_KEY (i, LockMask);            /* CapsLock              */
          X_UNGRAB_KEY (i, Mod2Mask);            /* NumLock               */
          X_UNGRAB_KEY (i, Mod5Mask);            /* ScrollLock            */
          X_UNGRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock    */
          X_UNGRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */
          X_UNGRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock  + ScrollLock */
          X_UNGRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all        */
        }
#undef X_UNGRAB_KEY

      g_free (keys);
    }

  if (status == GrabSuccess)
    XUngrabPointer (x_dpy, CurrentTime);

  XFreeCursor (x_dpy, x_cursor);

  if (x_gc != None)
    XFreeGC (x_dpy, x_gc);

  return x_win;
}
Example #7
0
GdkEventKey *
ide_gdk_synthesize_event_key (GdkWindow *window,
                              gunichar   ch)
{
  GdkDisplay *display;
  GdkDeviceManager *device_manager;
  GdkDevice *client_pointer;
  GdkEvent *ev;
  GdkKeymapKey *keys = NULL;
  gint n_keys = 0;
  gchar str[8] = { 0 };

  g_assert (window != NULL);
  g_assert (GDK_IS_WINDOW (window));

  g_unichar_to_utf8 (ch, str);

  ev = gdk_event_new (GDK_KEY_PRESS);
  ev->key.window = g_object_ref (window);
  ev->key.send_event = TRUE;
  ev->key.time = gtk_get_current_event_time ();
  ev->key.state = 0;
  ev->key.hardware_keycode = 0;
  ev->key.group = 0;
  ev->key.is_modifier = 0;

  switch (ch)
    {
    case '\n':
      ev->key.keyval = GDK_KEY_Return;
      ev->key.string = g_strdup ("\n");
      ev->key.length = 1;
      break;

    case '\e':
      ev->key.keyval = GDK_KEY_Escape;
      ev->key.string = g_strdup ("");
      ev->key.length = 0;
      break;

    default:
      ev->key.keyval = gdk_unicode_to_keyval (ch);
      ev->key.length = strlen (str);
      ev->key.string = g_strdup (str);
      break;
    }

  gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
                                     ev->key.keyval,
                                     &keys,
                                     &n_keys);

  if (n_keys > 0)
    {
      ev->key.hardware_keycode = keys [0].keycode;
      ev->key.group = keys [0].group;
      if (keys [0].level == 1)
        ev->key.state |= GDK_SHIFT_MASK;
      g_free (keys);
    }

  display = gdk_window_get_display (ev->any.window);
  device_manager = gdk_display_get_device_manager (display);
  client_pointer = gdk_device_manager_get_client_pointer (device_manager);
  gdk_event_set_device (ev, gdk_device_get_associated_device (client_pointer));

  return &ev->key;
}
/*
 * Translate a Java KeyEvent object into a GdkEventKey event, then
 * pass it to the GTK main loop for processing.
 */
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetDispatchKeyEvent
  (JNIEnv *env, jobject obj, jint id, jlong when, jint mods,
   jint keyCode, jint keyLocation)
{
  void *ptr;
  GdkEvent *event = NULL;
  GdkKeymapKey *keymap_keys = NULL;
  gint n_keys = 0;
  guint lookup_keyval = 0;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  if (id == AWT_KEY_PRESSED)
    event = gdk_event_new (GDK_KEY_PRESS);
  else if (id == AWT_KEY_RELEASED)
    event = gdk_event_new (GDK_KEY_RELEASE);
  else
    {
      gdk_threads_leave ();
      /* Don't send AWT KEY_TYPED events to GTK. */
      return;
    }

  if (GTK_IS_BUTTON (ptr))
    event->key.window = GTK_BUTTON (get_widget(GTK_WIDGET (ptr)))->event_window;
  else if (GTK_IS_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr))))
    event->key.window = GTK_WIDGET (GTK_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr)))->container.child)->window;
  else
    event->key.window = get_widget(GTK_WIDGET (ptr))->window;

  event->key.send_event = 0;
  event->key.time = (guint32) when;

  if (mods & AWT_SHIFT_DOWN_MASK)
    event->key.state |= GDK_SHIFT_MASK;
  if (mods & AWT_CTRL_DOWN_MASK)
    event->key.state |= GDK_CONTROL_MASK;
  if (mods & AWT_ALT_DOWN_MASK)
    event->key.state |= GDK_MOD1_MASK;

  /* This hack is needed because the AWT has no notion of num lock.
     It infers numlock state from the only Java virtual keys that are
     affected by it. */
  if (keyCode == VK_NUMPAD9
      || keyCode == VK_NUMPAD8
      || keyCode == VK_NUMPAD7
      || keyCode == VK_NUMPAD6
      || keyCode == VK_NUMPAD5
      || keyCode == VK_NUMPAD4
      || keyCode == VK_NUMPAD3
      || keyCode == VK_NUMPAD2
      || keyCode == VK_NUMPAD1
      || keyCode == VK_NUMPAD0
      || keyCode == VK_DECIMAL)
    event->key.state |= GDK_MOD2_MASK;

  /* These values don't need to be filled in since GTK doesn't use
     them. */
  event->key.length = 0;
  event->key.string = NULL;

  lookup_keyval = cp_gtk_awt_keycode_to_keysym (keyCode, keyLocation);

  if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
                                          lookup_keyval,
                                          &keymap_keys,
                                          &n_keys))
    {
      /* No matching keymap entry was found. */
      g_printerr ("No matching keymap entries were found\n");
      gdk_threads_leave ();
      return;
    }

  /* Note: if n_keys > 1 then there are multiple hardware keycodes
     that translate to lookup_keyval.  We arbitrarily choose the first
     hardware keycode from the list returned by
     gdk_keymap_get_entries_for_keyval. */

  event->key.hardware_keycode = keymap_keys[0].keycode;
  event->key.group =  keymap_keys[0].group;

  g_free (keymap_keys);

  if (!gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
                                            event->key.hardware_keycode,
                                            event->key.state,
                                            event->key.group,
                                            &event->key.keyval,
                                            NULL, NULL, NULL))
    {
      /* No matching keyval was found. */
      g_printerr ("No matching keyval was found\n");
      gdk_threads_leave ();
      return;
    }

  /*  keyevent = (GdkEventKey *) event; */
  /*  g_printerr ("generated event: sent: %d  time: %d  state: %d  keyval: %d  length: %d  string: %s  hardware_keycode: %d  group: %d\n", keyevent->send_event, keyevent->time, keyevent->state, keyevent->keyval, keyevent->length, keyevent->string, keyevent->hardware_keycode, keyevent->group); */

  /* We already received the original key event on the window itself,
     so we don't want to resend it. */
  if (!GTK_IS_WINDOW (ptr))
    {
      if (GTK_IS_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr))))
        gtk_widget_event (GTK_WIDGET (GTK_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr)))->container.child), event);
      else
        gtk_widget_event (get_widget(GTK_WIDGET (ptr)), event);
    }

  gdk_threads_leave ();
}
Example #9
0
static void
carbon_menu_item_update_accelerator (CarbonMenuItem *carbon_item,
				     GtkWidget      *widget)
{
  GtkWidget *label;

  get_menu_label_text (widget, &label);

  if (GTK_IS_ACCEL_LABEL (label))
    {
      GClosure      *closure;

      g_object_get (label, "accel-closure", &closure, NULL);

      if (closure)
	{
	  GtkAccelGroup *group;
	  GtkAccelKey   *key;

	  group = gtk_accel_group_from_accel_closure (closure);
	  key = gtk_accel_group_find (group, accel_find_func, closure);

	  g_closure_unref (closure);

	  if (key            &&
	      key->accel_key &&
	      key->accel_flags & GTK_ACCEL_VISIBLE)
	    {
	      GdkDisplay      *display = gtk_widget_get_display (widget);
	      GdkKeymap       *keymap  = gdk_keymap_get_for_display (display);
	      GdkKeymapKey    *keys;
	      gint             n_keys;

	      if (gdk_keymap_get_entries_for_keyval (keymap, key->accel_key,
						     &keys, &n_keys))
		{
		  UInt8 modifiers = 0;

		  SetMenuItemCommandKey (carbon_item->menu, carbon_item->index,
					 true, keys[0].keycode);

		  g_free (keys);

		  if (key->accel_mods)
		    {
		      if (key->accel_mods & GDK_SHIFT_MASK)
			modifiers |= kMenuShiftModifier;

		      if (key->accel_mods & GDK_MOD1_MASK)
			modifiers |= kMenuOptionModifier;
		    }

		  if (!(key->accel_mods & GDK_META_MASK))
		    {
		      modifiers |= kMenuNoCommandModifier;
		    }

		  SetMenuItemModifiers (carbon_item->menu, carbon_item->index,
					modifiers);

		  return;
		}
	    }
	}
    }

  /*  otherwise, clear the menu shortcut  */
  SetMenuItemModifiers (carbon_item->menu, carbon_item->index,
			kMenuNoModifiers | kMenuNoCommandModifier);
  ChangeMenuItemAttributes (carbon_item->menu, carbon_item->index,
			    0, kMenuItemAttrUseVirtualKey);
  SetMenuItemCommandKey (carbon_item->menu, carbon_item->index,
			 false, 0);
}
Example #10
0
void keyPress(char * key, int type)
{
    printf("%s %s\n", __func__, key);
    gboolean rtv;
/*
  GdkEventType type;
  GdkWindow *window;
  gint8 send_event;
  guint32 time;
  guint state;
  guint keyval;
  gint length;
  gchar *string;
  guint16 hardware_keycode;
  guint8 group;
  guint is_modifier : 1;
*/

    //GdkEventKey * event = (GdkEventKey*)malloc(sizeof(GdkEventKey));
    GdkEvent* event = gdk_event_new(GDK_KEY_PRESS); 


    if(type == KEY_TYPE_PRESS)
        ((GdkEventKey*)event)->type = GDK_KEY_PRESS; 
    else if(type == KEY_TYPE_RELEASE)    
        ((GdkEventKey*)event)->type = GDK_KEY_RELEASE;
    else
        return;
    
    ((GdkEventKey*)event)->window = g_window->window;  

    ((GdkEventKey*)event)->send_event = 1;
    ((GdkEventKey*)event)->time = GDK_CURRENT_TIME;
    ((GdkEventKey*)event)->state = 0;
    
    ((GdkEventKey*)event)->keyval = 0;
    //((GdkEventKey*)event)->length = 1;
    
    if     (!strcmp(key, "red"))
        ((GdkEventKey*)event)->keyval = GDK_F5; //'t';
    else if(!strcmp(key, "green"))
        ((GdkEventKey*)event)->keyval = GDK_F6; //'u';
    else if(!strcmp(key, "yellow"))
        ((GdkEventKey*)event)->keyval = GDK_F7; //'v';
    else if(!strcmp(key, "blue"))
        ((GdkEventKey*)event)->keyval = GDK_F8; //'w';

    else if(!strcmp(key, "up"))
        ((GdkEventKey*)event)->keyval = GDK_Up;
    else if(!strcmp(key, "down"))
        ((GdkEventKey*)event)->keyval = GDK_Down;
    else if(!strcmp(key, "left"))
        ((GdkEventKey*)event)->keyval = GDK_Left;
    else if(!strcmp(key, "right"))
        ((GdkEventKey*)event)->keyval = GDK_Right;
    
    else if(!strcmp(key, "ok"))
        ((GdkEventKey*)event)->keyval = GDK_Return;
    else if(!strcmp(key, "play"))
        ((GdkEventKey*)event)->keyval = 'P';
    else if(!strcmp(key, "pause"))
        ((GdkEventKey*)event)->keyval = 'P'; // PAUSE IS Q but it seems that P is Toggle PlayPause
    else if(!strcmp(key, "stop"))
        ((GdkEventKey*)event)->keyval = 'S';
    else if(!strcmp(key, "rewind"))
        ((GdkEventKey*)event)->keyval = 'R';
    else if(!strcmp(key, "fastforward"))
        ((GdkEventKey*)event)->keyval = 'F';


    else {
        GdkKeymapKey* keys; 
        gint n_keys; 
        gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), ((GdkEventKey*)event)->keyval, &keys, &n_keys); 

        ((GdkEventKey*)event)->hardware_keycode = keys[0].keycode; 
    }

    ((GdkEventKey*)event)->group = 0;
    ((GdkEventKey*)event)->is_modifier = 0;
    
  
    if(((GdkEventKey*)event)->keyval != 0) {
        //if(type == KEY_TYPE_PRESS) {
            //gtk_signal_emit_by_name(GTK_OBJECT (g_window), "key-press-event", event, &rtv);
            gdk_event_put(event); 
        //}
        //else if(type == KEY_TYPE_RELEASE)   
        //    gtk_signal_emit_by_name(GTK_OBJECT (g_window), "key-release-event", event, &rtv);
        return;
    }

    //event->state |= GDK_MOD1_MASK;
    return;
}
Example #11
0
static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");

    webkit_web_frame_layout(mainFrame);

    // handle modifier keys.
    int state = 0;
    if (argumentCount > 1) {
        JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception);
        if (modifiersArray) {
            for (int i = 0; i < JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); ++i) {
                JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
                JSStringRef string = JSValueToStringCopy(context, value, 0);
                if (JSStringIsEqualToUTF8CString(string, "ctrlKey"))
                    state |= GDK_CONTROL_MASK;
                else if (JSStringIsEqualToUTF8CString(string, "shiftKey"))
                    state |= GDK_SHIFT_MASK;
                else if (JSStringIsEqualToUTF8CString(string, "altKey"))
                    state |= GDK_MOD1_MASK;

                JSStringRelease(string);
            }
        }
    }

    // handle location argument.
    int location = DOM_KEY_LOCATION_STANDARD;
    if (argumentCount > 2)
        location = (int)JSValueToNumber(context, arguments[2], exception);

    JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
    int gdkKeySym = GDK_VoidSymbol;
    if (location == DOM_KEY_LOCATION_NUMPAD) {
        if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
            gdkKeySym = GDK_KP_Left;
        else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
            gdkKeySym = GDK_KP_Right;
        else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
            gdkKeySym = GDK_KP_Up;
        else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
            gdkKeySym = GDK_KP_Down;
        else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
            gdkKeySym = GDK_KP_Page_Up;
        else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
            gdkKeySym = GDK_KP_Page_Down;
        else if (JSStringIsEqualToUTF8CString(character, "home"))
            gdkKeySym = GDK_KP_Home;
        else if (JSStringIsEqualToUTF8CString(character, "end"))
            gdkKeySym = GDK_KP_End;
        else if (JSStringIsEqualToUTF8CString(character, "insert"))
            gdkKeySym = GDK_KP_Insert;
        else if (JSStringIsEqualToUTF8CString(character, "delete"))
            gdkKeySym = GDK_KP_Delete;
        else
            // If we get some other key specified with the numpad location,
            // crash here, so we add it sooner rather than later.
            g_assert_not_reached();
    } else {
        if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
            gdkKeySym = GDK_Left;
        else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
            gdkKeySym = GDK_Right;
        else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
            gdkKeySym = GDK_Up;
        else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
            gdkKeySym = GDK_Down;
        else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
            gdkKeySym = GDK_Page_Up;
        else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
            gdkKeySym = GDK_Page_Down;
        else if (JSStringIsEqualToUTF8CString(character, "home"))
            gdkKeySym = GDK_Home;
        else if (JSStringIsEqualToUTF8CString(character, "end"))
            gdkKeySym = GDK_End;
        else if (JSStringIsEqualToUTF8CString(character, "insert"))
            gdkKeySym = GDK_Insert;
        else if (JSStringIsEqualToUTF8CString(character, "delete"))
            gdkKeySym = GDK_Delete;
        else if (JSStringIsEqualToUTF8CString(character, "printScreen"))
            gdkKeySym = GDK_Print;
        else if (JSStringIsEqualToUTF8CString(character, "F1"))
            gdkKeySym = GDK_F1;
        else if (JSStringIsEqualToUTF8CString(character, "F2"))
            gdkKeySym = GDK_F2;
        else if (JSStringIsEqualToUTF8CString(character, "F3"))
            gdkKeySym = GDK_F3;
        else if (JSStringIsEqualToUTF8CString(character, "F4"))
            gdkKeySym = GDK_F4;
        else if (JSStringIsEqualToUTF8CString(character, "F5"))
            gdkKeySym = GDK_F5;
        else if (JSStringIsEqualToUTF8CString(character, "F6"))
            gdkKeySym = GDK_F6;
        else if (JSStringIsEqualToUTF8CString(character, "F7"))
            gdkKeySym = GDK_F7;
        else if (JSStringIsEqualToUTF8CString(character, "F8"))
            gdkKeySym = GDK_F8;
        else if (JSStringIsEqualToUTF8CString(character, "F9"))
            gdkKeySym = GDK_F9;
        else if (JSStringIsEqualToUTF8CString(character, "F10"))
            gdkKeySym = GDK_F10;
        else if (JSStringIsEqualToUTF8CString(character, "F11"))
            gdkKeySym = GDK_F11;
        else if (JSStringIsEqualToUTF8CString(character, "F12"))
            gdkKeySym = GDK_F12;
        else {
            int charCode = JSStringGetCharactersPtr(character)[0];
            if (charCode == '\n' || charCode == '\r')
                gdkKeySym = GDK_Return;
            else if (charCode == '\t')
                gdkKeySym = GDK_Tab;
            else if (charCode == '\x8')
                gdkKeySym = GDK_BackSpace;
            else {
                gdkKeySym = gdk_unicode_to_keyval(charCode);
                if (WTF::isASCIIUpper(charCode))
                    state |= GDK_SHIFT_MASK;
            }
        }
    }
    JSStringRelease(character);

    WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
    if (!view)
        return JSValueMakeUndefined(context);

    // create and send the event
    GdkEvent* pressEvent = gdk_event_new(GDK_KEY_PRESS);
    pressEvent->key.keyval = gdkKeySym;
    pressEvent->key.state = state;
    pressEvent->key.window = gtk_widget_get_window(GTK_WIDGET(view));
    g_object_ref(pressEvent->key.window);
#ifndef GTK_API_VERSION_2
    gdk_event_set_device(pressEvent, getDefaultGDKPointerDevice(pressEvent->key.window));
#endif

    // When synthesizing an event, an invalid hardware_keycode value
    // can cause it to be badly processed by Gtk+.
    GdkKeymapKey* keys;
    gint n_keys;
    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys, &n_keys)) {
        pressEvent->key.hardware_keycode = keys[0].keycode;
        g_free(keys);
    }

    GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
    dispatchEvent(pressEvent);
    releaseEvent->key.type = GDK_KEY_RELEASE;
    dispatchEvent(releaseEvent);

    return JSValueMakeUndefined(context);
}
Example #12
0
/* Grab or ungrab then keyval and modifiers combination, grabbing all key
 * combinations yielding the same key values.
 * Includes ignorable modifiers using grab_ungrab_with_ignorable_modifiers.
 */
static gboolean
grab_ungrab (GdkWindow *rootwin,
             uint       keyval,
             uint       modifiers,
             gboolean   grab)
{
	int k;
	GdkKeymap *map;
	GdkKeymapKey *keys;
	gint n_keys;
	GdkModifierType add_modifiers;
	XkbDescPtr xmap;
	gboolean success = FALSE;

	xmap = XkbGetMap(GDK_WINDOW_XDISPLAY(rootwin),
	                 XkbAllClientInfoMask,
	                 XkbUseCoreKbd);

	map = gdk_keymap_get_default();
	gdk_keymap_get_entries_for_keyval(map, keyval, &keys, &n_keys);

	if (n_keys == 0)
		return FALSE;

	for (k = 0; k < n_keys; k++) {
		/* NOTE: We only bind for the first group,
		 * so regardless of current keyboard layout, it will
		 * grab the key from the default Layout.
		 */
		if (keys[k].group != WE_ONLY_USE_ONE_GROUP) {
			continue;
		}

		add_modifiers = FinallyGetModifiersForKeycode(xmap,
		                                              keys[k].keycode,
		                                              keys[k].group,
		                                              keys[k].level);

		if (add_modifiers == MODIFIERS_ERROR) {
			continue;
		}
		TRACE (g_print("grab/ungrab keycode: %d, lev: %d, grp: %d, ",
			keys[k].keycode, keys[k].level, keys[k].group));
		TRACE (g_print("modifiers: 0x%x (consumed: 0x%x)\n",
		               add_modifiers | modifiers, add_modifiers));
		if (grab_ungrab_with_ignorable_modifiers(rootwin,
		                                         keys[k].keycode,
		                                         add_modifiers | modifiers,
		                                         grab)) {

			success = TRUE;
		} else {
			/* When grabbing, break on error */
			if (grab && !success) {
				break;
			}
		}

	}
	g_free(keys);
	XkbFreeClientMap(xmap, 0, TRUE);

	return success;
}
Example #13
0
void
compzillaWindow::SendKeyEvent (int eventType, nsIDOMKeyEvent *keyEv)
{
    DOMTimeStamp timestamp;
    PRBool ctrl, shift, alt, meta;
    int state = 0;

    keyEv->GetTimeStamp (&timestamp);
    if (!timestamp) {
        timestamp = gtk_get_current_event_time (); // CurrentTime;
    }

    keyEv->GetAltKey (&alt);
    keyEv->GetCtrlKey (&ctrl);
    keyEv->GetShiftKey (&shift);
    keyEv->GetMetaKey (&meta);

    if (ctrl) {
        state |= ControlMask;
    }
    if (shift) {
        state |= ShiftMask;
    }
    if (alt) {
        state |= Mod1Mask;
    }
    if (meta) {
        state |= Mod2Mask;
    }

    PRUint32 keycode;
    keyEv->GetKeyCode (&keycode);

    unsigned int xkeysym = DOMKeyCodeToKeySym (keycode);

#ifdef USE_GDK_KEYMAP
    // FIXME: There's probably some annoying reason, like XKB, we need to use 
    //        the GDK version.  But for now I'm in denial.
    GdkKeymapKey *keys = NULL;
    int n_keys = 0;
    if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_for_display (gdk_display_get_default ()),
                                            xkeysym,
                                            &keys,
                                            &n_keys)) {
        ERROR ("Unknown keyval '%d' ignored.\n", xkeysym);
        return;
    }

    unsigned int xkeycode = 0;
    for (int i = 0; i < n_keys; i++) {
        if (keys [i].keycode) {
            xkeycode = keys [i].keycode;
            break;
        }
    }
    g_free (keys);

    SPEW_EVENT ("SendKeyEvent: gdk_keymap_get_entries_for_keyval keysym=%p, "
                "keycode=%p\n", xkeysym, xkeycode);
#else
    unsigned int xkeycode = XKeysymToKeycode (mDisplay, xkeysym);
#endif

    // Build up the XEvent we will send
    XEvent xev = { 0 };
    xev.xkey.type = eventType;
    xev.xkey.serial = 0;
    xev.xkey.display = mDisplay;
    xev.xkey.window = mWindow;
    xev.xkey.root = mAttr.root;
    xev.xkey.time = timestamp;
    xev.xkey.state = state;
    xev.xkey.keycode = xkeycode;
    xev.xkey.same_screen = True;

    // Figure out who to send to
    long xevMask;

    switch (eventType) {
    case _KeyPress:
	xevMask = KeyPressMask;
	break;
    case KeyRelease:
	xevMask = KeyReleaseMask;
	break;
    default:
        NS_NOTREACHED ("Unknown eventType");
        return;
    }

    SPEW_EVENT ("SendKeyEvent: %s%s win=%p, child=%p, state=%p, keycode=%u, "
                "timestamp=%d\n", 
                eventType == _KeyPress ? "PRESS" : "", 
                eventType == KeyRelease ? "RELEASE" : "", 
                mWindow, mWindow, state, xkeycode, timestamp);

    XSendEvent (mDisplay, mWindow, True, xevMask, &xev);

    keyEv->StopPropagation ();
    keyEv->PreventDefault ();
}
Example #14
0
gboolean
_gdk_x11_window_simulate_key (GdkWindow      *window,
                              gint            x,
                              gint            y,
                              guint           keyval,
                              GdkModifierType modifiers,
                              GdkEventType    key_pressrelease)
{
    GdkScreen *screen;
    GdkKeymapKey *keys = NULL;
    gboolean success;
    gint n_keys = 0;
    XKeyEvent xev = {
        0,  /* type */
        0,  /* serial */
        1,  /* send_event */
    };
    g_return_val_if_fail (key_pressrelease == GDK_KEY_PRESS || key_pressrelease == GDK_KEY_RELEASE, FALSE);
    g_return_val_if_fail (window != NULL, FALSE);
    if (!GDK_WINDOW_IS_MAPPED (window))
        return FALSE;

    screen = gdk_window_get_screen (window);

    if (x < 0 && y < 0)
    {
        x = window->width / 2;
        y = window->height / 2;
    }

    /* Convert to impl coordinates */
    x = x + window->abs_x;
    y = y + window->abs_y;

    xev.type = key_pressrelease == GDK_KEY_PRESS ? KeyPress : KeyRelease;
    xev.display = GDK_WINDOW_XDISPLAY (window);
    xev.window = GDK_WINDOW_XID (window);
    xev.root = RootWindow (xev.display, GDK_X11_SCREEN (screen)->screen_num);
    xev.subwindow = 0;
    xev.time = 0;
    xev.x = MAX (x, 0);
    xev.y = MAX (y, 0);
    xev.x_root = 0;
    xev.y_root = 0;
    xev.state = modifiers;
    xev.keycode = 0;
    success = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_for_display (gdk_window_get_display (window)), keyval, &keys, &n_keys);
    success &= n_keys > 0;
    if (success)
    {
        gint i;
        for (i = 0; i < n_keys; i++)
            if (keys[i].group == 0 && (keys[i].level == 0 || keys[i].level == 1))
            {
                xev.keycode = keys[i].keycode;
                if (keys[i].level == 1)
                {
                    /* Assume shift takes us to level 1 */
                    xev.state |= GDK_SHIFT_MASK;
                }
                break;
            }
        if (i >= n_keys) /* no match for group==0 and level==0 or 1 */
            xev.keycode = keys[0].keycode;
    }
    g_free (keys);
    if (!success)
        return FALSE;
    gdk_x11_display_error_trap_push (GDK_WINDOW_DISPLAY (window));
    xev.same_screen = XTranslateCoordinates (xev.display, xev.window, xev.root,
                      xev.x, xev.y, &xev.x_root, &xev.y_root,
                      &xev.subwindow);
    if (!xev.subwindow)
        xev.subwindow = xev.window;
    success &= xev.same_screen;
    if (x >= 0 && y >= 0)
        success &= 0 != XWarpPointer (xev.display, None, xev.window, 0, 0, 0, 0, xev.x, xev.y);
    success &= 0 != XSendEvent (xev.display, xev.window, True, key_pressrelease == GDK_KEY_PRESS ? KeyPressMask : KeyReleaseMask, (XEvent*) &xev);
    XSync (xev.display, False);
    success &= 0 == gdk_x11_display_error_trap_pop (GDK_WINDOW_DISPLAY (window));
    return success;
}
Example #15
0
/* Copy from gdk */
static GdkEventKey *
_create_gdk_event(FcitxIMContext *fcitxcontext,
                  guint keyval,
                  guint state,
                  FcitxKeyEventType type
                 )
{
    gunichar c = 0;
    gchar buf[8];

    GdkEventKey *event = (GdkEventKey *)gdk_event_new((type == FCITX_RELEASE_KEY) ? GDK_KEY_RELEASE : GDK_KEY_PRESS);

    if (fcitxcontext && fcitxcontext->client_window)
        event->window = g_object_ref(fcitxcontext->client_window);

    /* The time is copied the latest value from the previous
     * GdkKeyEvent in filter_keypress().
     *
     * We understand the best way would be to pass the all time value
     * to Fcitx functions process_key_event() and Fcitx DBus functions
     * ProcessKeyEvent() in IM clients and IM engines so that the
     * _create_gdk_event() could get the correct time values.
     * However it would causes to change many functions and the time value
     * would not provide the useful meanings for each Fcitx engines but just
     * pass the original value to ForwardKeyEvent().
     * We use the saved value at the moment.
     *
     * Another idea might be to have the time implementation in X servers
     * but some Xorg uses clock_gettime() and others use gettimeofday()
     * and the values would be different in each implementation and
     * locale/remote X server. So probably that idea would not work. */
    if (fcitxcontext) {
        event->time = fcitxcontext->time;
    } else {
        event->time = GDK_CURRENT_TIME;
    }

    event->send_event = FALSE;
    event->state = state;
    event->keyval = keyval;
    event->string = NULL;
    event->length = 0;
    event->hardware_keycode = 0;
    if (event->window) {
#ifndef NEW_GDK_WINDOW_GET_DISPLAY
        GdkDisplay      *display = gdk_display_get_default();
#else
        GdkDisplay      *display = gdk_window_get_display(event->window);
#endif
        GdkKeymap       *keymap  = gdk_keymap_get_for_display(display);
        GdkKeymapKey    *keys;
        gint             n_keys = 0;

        if (gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &n_keys)) {
            if (n_keys)
                event->hardware_keycode = keys[0].keycode;
            g_free(keys);
        }
    }

    event->group = 0;
    event->is_modifier = _key_is_modifier(keyval);

#ifdef DEPRECATED_GDK_KEYSYMS
    if (keyval != GDK_VoidSymbol)
#else
    if (keyval != GDK_KEY_VoidSymbol)
#endif
        c = gdk_keyval_to_unicode(keyval);

    if (c) {
        gsize bytes_written;
        gint len;

        /* Apply the control key - Taken from Xlib
        */
        if (event->state & GDK_CONTROL_MASK) {
            if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
            else if (c == '2') {
                event->string = g_memdup("\0\0", 2);
                event->length = 1;
                buf[0] = '\0';
                goto out;
            } else if (c >= '3' && c <= '7') c -= ('3' - '\033');
            else if (c == '8') c = '\177';
            else if (c == '/') c = '_' & 0x1F;
        }

        len = g_unichar_to_utf8(c, buf);
        buf[len] = '\0';

        event->string = g_locale_from_utf8(buf, len,
                                           NULL, &bytes_written,
                                           NULL);
        if (event->string)
            event->length = bytes_written;
#ifdef DEPRECATED_GDK_KEYSYMS
    } else if (keyval == GDK_Escape) {
#else
    } else if (keyval == GDK_KEY_Escape) {
#endif
        event->length = 1;
        event->string = g_strdup("\033");
    }
#ifdef DEPRECATED_GDK_KEYSYMS
    else if (keyval == GDK_Return ||
             keyval == GDK_KP_Enter) {
#else
    else if (keyval == GDK_KEY_Return ||
             keyval == GDK_KEY_KP_Enter) {
#endif
        event->length = 1;
        event->string = g_strdup("\r");
    }

    if (!event->string) {
        event->length = 0;
        event->string = g_strdup("");
    }
out:
    return event;
}


static gboolean
_key_is_modifier(guint keyval)
{
    /* See gdkkeys-x11.c:_gdk_keymap_key_is_modifier() for how this
    * really should be implemented */

    switch (keyval) {
#ifdef DEPRECATED_GDK_KEYSYMS
    case GDK_Shift_L:
    case GDK_Shift_R:
    case GDK_Control_L:
    case GDK_Control_R:
    case GDK_Caps_Lock:
    case GDK_Shift_Lock:
    case GDK_Meta_L:
    case GDK_Meta_R:
    case GDK_Alt_L:
    case GDK_Alt_R:
    case GDK_Super_L:
    case GDK_Super_R:
    case GDK_Hyper_L:
    case GDK_Hyper_R:
    case GDK_ISO_Lock:
    case GDK_ISO_Level2_Latch:
    case GDK_ISO_Level3_Shift:
    case GDK_ISO_Level3_Latch:
    case GDK_ISO_Level3_Lock:
    case GDK_ISO_Group_Shift:
    case GDK_ISO_Group_Latch:
    case GDK_ISO_Group_Lock:
        return TRUE;
#else
    case GDK_KEY_Shift_L:
    case GDK_KEY_Shift_R:
    case GDK_KEY_Control_L:
    case GDK_KEY_Control_R:
    case GDK_KEY_Caps_Lock:
    case GDK_KEY_Shift_Lock:
    case GDK_KEY_Meta_L:
    case GDK_KEY_Meta_R:
    case GDK_KEY_Alt_L:
    case GDK_KEY_Alt_R:
    case GDK_KEY_Super_L:
    case GDK_KEY_Super_R:
    case GDK_KEY_Hyper_L:
    case GDK_KEY_Hyper_R:
    case GDK_KEY_ISO_Lock:
    case GDK_KEY_ISO_Level2_Latch:
    case GDK_KEY_ISO_Level3_Shift:
    case GDK_KEY_ISO_Level3_Latch:
    case GDK_KEY_ISO_Level3_Lock:
    case GDK_KEY_ISO_Level5_Shift:
    case GDK_KEY_ISO_Level5_Latch:
    case GDK_KEY_ISO_Level5_Lock:
    case GDK_KEY_ISO_Group_Shift:
    case GDK_KEY_ISO_Group_Latch:
    case GDK_KEY_ISO_Group_Lock:
        return TRUE;
#endif
    default:
        return FALSE;
    }
}

void _fcitx_im_context_connect_cb(FcitxClient* im, void* user_data)
{
    FcitxIMContext* context =  FCITX_IM_CONTEXT(user_data);
    _fcitx_im_context_set_capacity(context, TRUE);
    /* set_cursor_location_internal() will get origin from X server,
     * it blocks UI. So delay it to idle callback. */
    g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
                    (GSourceFunc) _set_cursor_location_internal,
                    g_object_ref(context),
                    (GDestroyNotify) g_object_unref);
}