bool
NativeKeyBindings::Execute(const WidgetKeyboardEvent& aEvent,
                           DoCommandCallback aCallback,
                           void* aCallbackData)
{
  // If the native key event is set, it must be synthesized for tests.
  // We just ignore such events because this behavior depends on system
  // settings.
  if (!aEvent.mNativeKeyEvent) {
    // It must be synthesized event or dispatched DOM event from chrome.
    return false;
  }

  guint keyval;

  if (aEvent.mCharCode) {
    keyval = gdk_unicode_to_keyval(aEvent.mCharCode);
  } else {
    keyval =
      static_cast<GdkEventKey*>(aEvent.mNativeKeyEvent)->keyval;
  }

  if (ExecuteInternal(aEvent, aCallback, aCallbackData, keyval)) {
    return true;
  }

  for (uint32_t i = 0; i < aEvent.mAlternativeCharCodes.Length(); ++i) {
    uint32_t ch = aEvent.IsShift() ?
      aEvent.mAlternativeCharCodes[i].mShiftedCharCode :
      aEvent.mAlternativeCharCodes[i].mUnshiftedCharCode;
    if (ch && ch != aEvent.mCharCode) {
      keyval = gdk_unicode_to_keyval(ch);
      if (ExecuteInternal(aEvent, aCallback, aCallbackData, keyval)) {
        return true;
      }
    }
  }

/*
gtk_bindings_activate_event is preferable, but it has unresolved bug:
http://bugzilla.gnome.org/show_bug.cgi?id=162726
The bug was already marked as FIXED.  However, somebody reports that the
bug still exists.
Also gtk_bindings_activate may work with some non-shortcuts operations
(todo: check it). See bug 411005 and bug 406407.

Code, which should be used after fixing GNOME bug 162726:

  gtk_bindings_activate_event(GTK_OBJECT(mNativeTarget),
    static_cast<GdkEventKey*>(aEvent.mNativeKeyEvent));
*/

  return false;
}
Esempio n. 2
0
static void load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
{
    KeyEventFixture* fixture = (KeyEventFixture*)data;
    WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
    if (status == WEBKIT_LOAD_FINISHED) {
        gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                                 gdk_unicode_to_keyval('a'), 0);
    }

}
static void test_blocking_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
{
    KeyEventFixture* fixture = (KeyEventFixture*)data;
    WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
    if (status != WEBKIT_LOAD_FINISHED)
        return;

    // The first keypress event should not modify the field.
    fixture->info->text = g_strdup("bc");
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                                 gdk_unicode_to_keyval('a'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                                  gdk_unicode_to_keyval('b'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                                  gdk_unicode_to_keyval('c'), 0))
        g_assert_not_reached();

    g_idle_add(verify_contents, fixture);
}
static void test_keypress_events_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
{
    KeyEventFixture* fixture = (KeyEventFixture*)data;
    WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
    if (status == WEBKIT_LOAD_FINISHED) {
        g_signal_connect(fixture->webView, "key-press-event",
                         G_CALLBACK(key_press_event_cb), fixture);
        g_signal_connect(fixture->webView, "key-release-event",
                         G_CALLBACK(key_release_event_cb), fixture);
        if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                                      gdk_unicode_to_keyval('a'), 0))
            g_assert_not_reached();
    }

}
/* A key was pressed in locationbar */
static gboolean _interface_tweaks_on_key_press_event(GSignalInvocationHint *inHint,
														guint inNumberParams,
														const GValue *inParams,
														gpointer inUserData)
{
	g_return_val_if_fail(GTK_IS_ENTRY(inUserData), FALSE);

	GtkEntry				*entry=GTK_ENTRY(inUserData);
	GtkWidget				*target;
	GdkEventKey				*event;
	guint					changedSignalID;
	GSList					*handlers;

	/* Get target of this event and check if it is for locationbar entry */
	target=GTK_WIDGET(g_value_get_object(inParams));
	if(target==GTK_WIDGET(entry))
	{
		/* Get key-event data */
		inParams++;
		event=(GdkEventKey*)g_value_get_boxed(inParams);

		/* Check if key-event would _not_ add any characters */
		if(!(gdk_keyval_is_upper(event->keyval)==gdk_keyval_is_lower(event->keyval) &&
				gdk_unicode_to_keyval(gdk_keyval_to_unicode(event->keyval))!=event->keyval))
		{
			/* Get "changed" signal ID */
			changedSignalID=g_signal_lookup("changed", GTK_TYPE_ENTRY);

			/* Block all unblocked signal handlers for "changed" signal, remove selected
			 * text region from entry text and unblock these signal handlers again.
			 * This way we keep Midori's auto-completion working. Otherwise it fetches the
			 * complete entry text with the text portion in selected text region and adds
			 * the pressed key to it which results in a completely wrong text for auto-completion.
			 */
			handlers=_interface_tweaks_block_all_handlers(G_OBJECT(entry), changedSignalID);

			gtk_editable_delete_selection(GTK_EDITABLE(entry));

			_interface_tweaks_unblock_handlers(G_OBJECT(entry), handlers);
			g_slist_free(handlers);
		}
	}

	return(TRUE);
}
Esempio n. 6
0
void gtksendkey(sPlayerInterface* player_interf,int keycode)
{
	TRACEINFO;
	GdkEvent *KeyEvent;
	
	fprintf(stderr, "\x1b[%i;3%imKeyCode\x1b[0m: %d\n",1, 4,keycode);
	
	KeyEvent = gdk_event_new (GDK_KEY_PRESS);
	/* Key Value */
	KeyEvent->key.keyval = gdk_unicode_to_keyval(keycode);	
	/* GDK_BUTTON1_MASK refers to left mouse button */
	KeyEvent->key.state = GDK_BUTTON1_MASK;
	/* Send the key event to Web Window */
	
	KeyEvent->key.window = player_interf->ui->pWebWindow->window;
	gtk_main_do_event (KeyEvent);
	//gdk_event_free(KeyEvent);
}
Esempio n. 7
0
static JSValueRef runPasteTestCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    gtk_widget_grab_focus(GTK_WIDGET(currentFixture->webView));

    // Simulate a paste keyboard sequence.
    GdkEvent* event = gdk_event_new(GDK_KEY_PRESS);
    event->key.keyval = gdk_unicode_to_keyval('v');
    event->key.state = GDK_CONTROL_MASK;
    event->key.window = gtk_widget_get_window(GTK_WIDGET(currentFixture->webView));
    g_object_ref(event->key.window);
#ifndef GTK_API_VERSION_2
    GdkDeviceManager* manager =  gdk_display_get_device_manager(gdk_window_get_display(event->key.window));
    gdk_event_set_device(event, gdk_device_manager_get_client_pointer(manager));
#endif

    GdkKeymapKey* keys;
    gint n_keys;
    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), event->key.keyval, &keys, &n_keys)) {
        event->key.hardware_keycode = keys[0].keycode;
        g_free(keys);
    }

    gtk_main_do_event(event);
    event->key.type = GDK_KEY_RELEASE;
    gtk_main_do_event(event);
    gdk_event_free(event);

    JSStringRef scriptString = JSStringCreateWithUTF8CString("document.body.innerHTML;");
    JSValueRef value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0);
    JSStringRelease(scriptString);

    g_assert(JSValueIsString(context, value));
    JSStringRef actual = JSValueToStringCopy(context, value, exception);
    g_assert(!exception || !*exception);
    g_assert(currentFixture->info->expectedContent);
    JSStringRef expected = JSStringCreateWithUTF8CString(currentFixture->info->expectedContent);
    g_assert(JSStringIsEqual(expected, actual));

    JSStringRelease(expected);
    JSStringRelease(actual);
    g_main_loop_quit(currentFixture->loop);
    return JSValueMakeUndefined(context);
}
Esempio n. 8
0
File: tmKey.cpp Progetto: dxtravi/e
bool tmKey::uniToWxk(wxChar uniCode, int& wxk, int& mod) // static
{
#ifdef __WXMSW__
    // Convert key to scan code
    const SHORT scancode = ::VkKeyScan(uniCode);
    const unsigned char vk = LOBYTE(scancode);     // Low eight bits = virtual-key code
    const int state = HIBYTE(scancode);   // The next eight bits = shift state
    if (state & 1) mod |= wxMOD_SHIFT;
    if (state & 2) mod |= wxMOD_CONTROL;
    if (state & 4) mod |= wxMOD_ALT;

    wxk = wxCharCodeMSWToWX(vk, 0);
    if (wxk == 0) {
        // Normal ascii char
        // Note that this is set to the virtual keycode (which does not necessarily
        // correspond to the ascii value). This is needed because keydown events
        // report it in this format.
        wxk = vk;
    }
    return true;
#elif defined(__WXGTK__)
    guint keyval = gdk_unicode_to_keyval(uniCode);
    if (keyval & 0x01000000)
        return false;
    if (gdk_keyval_is_upper(keyval))
    {
        mod |= wxMOD_SHIFT;
        keyval = gdk_keyval_to_lower(keyval);
#ifdef __WXDEBUG__
    wxLogDebug(wxT("uniToWxk(%x - %c) downshifting keycode is %x"), uniCode, uniCode, keyval);
#endif //__WXDEBUG__
    }
    // FIXME not too correct - this is wxChar not wxKeyCode
    wxk = gdk_keyval_to_unicode(keyval);
#ifdef __WXDEBUG__
    wxLogDebug(wxT("uniToWxk(%x - %c) to %x - %c"), uniCode, uniCode, wxk, wxk);
#endif //__WXDEBUG__
    return true;
#else
#error Unknown platform
#endif
}
Esempio n. 9
0
File: tmKey.cpp Progetto: joeri/e
bool tmKey::wxkToUni(int wxk, bool shifted, wxChar& uniCode) // static
{
    if (!wxIsprint(wxk))
        return false;

#ifdef __WXMSW__
    // Convert key to scan code
    const SHORT scancode = ::VkKeyScan(wxk);
    const unsigned char vk = LOBYTE(scancode);     // Low eight bits = virtual-key code

    // Get the char on the key for this keycode
    unsigned char key_state[256];
    memset (key_state, 0, sizeof (key_state));
    const int BUFFER_SIZE = 10;
    if (shifted)
        key_state[VK_SHIFT] = 0x80;
    TCHAR buf[BUFFER_SIZE] = { 0 };
    if (::ToUnicode(vk, 0, key_state, buf, BUFFER_SIZE, 0) != 1)
        return false;

    uniCode = buf[0];
    return true;
#elif defined(__WXGTK__)
    // FIXME not too correct - this is wxKeyCode not wxChar
    guint keyval = gdk_unicode_to_keyval(wxk);
    if (keyval & 0x01000000)
        return false;
    keyval = shifted ? gdk_keyval_to_upper(keyval) : gdk_keyval_to_lower(keyval);
    uniCode = gdk_keyval_to_unicode(keyval);

#ifdef __WXDEBUG__
    wxLogDebug(wxT("wxkToUni(%x- %c,%d) to %x - %c"), wxk, wxk, shifted, uniCode, uniCode);
#endif //__WXDEBUG__
    return true;
#else
#error Unknown platform
#endif
}
static void test_xim_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
{
    KeyEventFixture* fixture = (KeyEventFixture*)data;
    WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
    if (status != WEBKIT_LOAD_FINISHED)
        return;

    GtkIMContext* imContext = 0;
    g_object_get(webView, "im-context", &imContext, NULL);
    g_assert(imContext);

    gchar* originalId = g_strdup(gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(imContext)));
    gtk_im_multicontext_set_context_id(GTK_IM_MULTICONTEXT(imContext), "xim");

    // Test that commits that happen outside of key events
    // change the text field immediately. This closely replicates
    // the behavior of SCIM.
    fixture->info->text = g_strdup("debian");
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                                 gdk_unicode_to_keyval('d'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                             gdk_unicode_to_keyval('e'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                             gdk_unicode_to_keyval('b'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                             gdk_unicode_to_keyval('i'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                             gdk_unicode_to_keyval('a'), 0))
        g_assert_not_reached();
    if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
                             gdk_unicode_to_keyval('n'), 0))
        g_assert_not_reached();

    gtk_im_multicontext_set_context_id(GTK_IM_MULTICONTEXT(imContext), originalId);
    g_free(originalId);
    g_object_unref(imContext);

    g_idle_add(verify_contents, fixture);
}
Esempio n. 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
            // 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);
}
Esempio n. 12
0
File: gdkkeys.c Progetto: GNOME/gtk
/**
 * gdk_keyval_convert_case:
 * @symbol: a keyval
 * @lower: (out): return location for lowercase version of @symbol
 * @upper: (out): return location for uppercase version of @symbol
 *
 * Obtains the upper- and lower-case versions of the keyval @symbol.
 * Examples of keyvals are #GDK_KEY_a, #GDK_KEY_Enter, #GDK_KEY_F1, etc.
 */
void
gdk_keyval_convert_case (guint symbol,
                         guint *lower,
                         guint *upper)
{
  guint xlower, xupper;

  xlower = symbol;
  xupper = symbol;

  /* Check for directly encoded 24-bit UCS characters: */
  if ((symbol & 0xff000000) == 0x01000000)
    {
      if (lower)
        *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff));
      if (upper)
        *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff));
      return;
    }

  switch (symbol >> 8)
    {
    case 0: /* Latin 1 */
      if ((symbol >= GDK_KEY_A) && (symbol <= GDK_KEY_Z))
        xlower += (GDK_KEY_a - GDK_KEY_A);
      else if ((symbol >= GDK_KEY_a) && (symbol <= GDK_KEY_z))
        xupper -= (GDK_KEY_a - GDK_KEY_A);
      else if ((symbol >= GDK_KEY_Agrave) && (symbol <= GDK_KEY_Odiaeresis))
        xlower += (GDK_KEY_agrave - GDK_KEY_Agrave);
      else if ((symbol >= GDK_KEY_agrave) && (symbol <= GDK_KEY_odiaeresis))
        xupper -= (GDK_KEY_agrave - GDK_KEY_Agrave);
      else if ((symbol >= GDK_KEY_Ooblique) && (symbol <= GDK_KEY_Thorn))
        xlower += (GDK_KEY_oslash - GDK_KEY_Ooblique);
      else if ((symbol >= GDK_KEY_oslash) && (symbol <= GDK_KEY_thorn))
        xupper -= (GDK_KEY_oslash - GDK_KEY_Ooblique);
      break;

    case 1: /* Latin 2 */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol == GDK_KEY_Aogonek)
        xlower = GDK_KEY_aogonek;
      else if (symbol >= GDK_KEY_Lstroke && symbol <= GDK_KEY_Sacute)
        xlower += (GDK_KEY_lstroke - GDK_KEY_Lstroke);
      else if (symbol >= GDK_KEY_Scaron && symbol <= GDK_KEY_Zacute)
        xlower += (GDK_KEY_scaron - GDK_KEY_Scaron);
      else if (symbol >= GDK_KEY_Zcaron && symbol <= GDK_KEY_Zabovedot)
        xlower += (GDK_KEY_zcaron - GDK_KEY_Zcaron);
      else if (symbol == GDK_KEY_aogonek)
        xupper = GDK_KEY_Aogonek;
      else if (symbol >= GDK_KEY_lstroke && symbol <= GDK_KEY_sacute)
        xupper -= (GDK_KEY_lstroke - GDK_KEY_Lstroke);
      else if (symbol >= GDK_KEY_scaron && symbol <= GDK_KEY_zacute)
        xupper -= (GDK_KEY_scaron - GDK_KEY_Scaron);
      else if (symbol >= GDK_KEY_zcaron && symbol <= GDK_KEY_zabovedot)
        xupper -= (GDK_KEY_zcaron - GDK_KEY_Zcaron);
      else if (symbol >= GDK_KEY_Racute && symbol <= GDK_KEY_Tcedilla)
        xlower += (GDK_KEY_racute - GDK_KEY_Racute);
      else if (symbol >= GDK_KEY_racute && symbol <= GDK_KEY_tcedilla)
        xupper -= (GDK_KEY_racute - GDK_KEY_Racute);
      break;

    case 2: /* Latin 3 */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Hstroke && symbol <= GDK_KEY_Hcircumflex)
        xlower += (GDK_KEY_hstroke - GDK_KEY_Hstroke);
      else if (symbol >= GDK_KEY_Gbreve && symbol <= GDK_KEY_Jcircumflex)
        xlower += (GDK_KEY_gbreve - GDK_KEY_Gbreve);
      else if (symbol >= GDK_KEY_hstroke && symbol <= GDK_KEY_hcircumflex)
        xupper -= (GDK_KEY_hstroke - GDK_KEY_Hstroke);
      else if (symbol >= GDK_KEY_gbreve && symbol <= GDK_KEY_jcircumflex)
        xupper -= (GDK_KEY_gbreve - GDK_KEY_Gbreve);
      else if (symbol >= GDK_KEY_Cabovedot && symbol <= GDK_KEY_Scircumflex)
        xlower += (GDK_KEY_cabovedot - GDK_KEY_Cabovedot);
      else if (symbol >= GDK_KEY_cabovedot && symbol <= GDK_KEY_scircumflex)
        xupper -= (GDK_KEY_cabovedot - GDK_KEY_Cabovedot);
      break;

    case 3: /* Latin 4 */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Rcedilla && symbol <= GDK_KEY_Tslash)
        xlower += (GDK_KEY_rcedilla - GDK_KEY_Rcedilla);
      else if (symbol >= GDK_KEY_rcedilla && symbol <= GDK_KEY_tslash)
        xupper -= (GDK_KEY_rcedilla - GDK_KEY_Rcedilla);
      else if (symbol == GDK_KEY_ENG)
        xlower = GDK_KEY_eng;
      else if (symbol == GDK_KEY_eng)
        xupper = GDK_KEY_ENG;
      else if (symbol >= GDK_KEY_Amacron && symbol <= GDK_KEY_Umacron)
        xlower += (GDK_KEY_amacron - GDK_KEY_Amacron);
      else if (symbol >= GDK_KEY_amacron && symbol <= GDK_KEY_umacron)
        xupper -= (GDK_KEY_amacron - GDK_KEY_Amacron);
      break;

    case 6: /* Cyrillic */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Serbian_DJE && symbol <= GDK_KEY_Serbian_DZE)
        xlower -= (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje);
      else if (symbol >= GDK_KEY_Serbian_dje && symbol <= GDK_KEY_Serbian_dze)
        xupper += (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje);
      else if (symbol >= GDK_KEY_Cyrillic_YU && symbol <= GDK_KEY_Cyrillic_HARDSIGN)
        xlower -= (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu);
      else if (symbol >= GDK_KEY_Cyrillic_yu && symbol <= GDK_KEY_Cyrillic_hardsign)
        xupper += (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu);
      break;

    case 7: /* Greek */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Greek_ALPHAaccent && symbol <= GDK_KEY_Greek_OMEGAaccent)
        xlower += (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent);
      else if (symbol >= GDK_KEY_Greek_alphaaccent && symbol <= GDK_KEY_Greek_omegaaccent &&
               symbol != GDK_KEY_Greek_iotaaccentdieresis &&
               symbol != GDK_KEY_Greek_upsilonaccentdieresis)
        xupper -= (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent);
      else if (symbol >= GDK_KEY_Greek_ALPHA && symbol <= GDK_KEY_Greek_OMEGA)
        xlower += (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA);
      else if (symbol >= GDK_KEY_Greek_alpha && symbol <= GDK_KEY_Greek_omega &&
               symbol != GDK_KEY_Greek_finalsmallsigma)
        xupper -= (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA);
      break;

    default:
      break;
    }

  if (lower)
    *lower = xlower;
  if (upper)
    *upper = xupper;
}
Esempio n. 13
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;
}
int getGDKKeySymForKeyRef(WKStringRef keyRef, unsigned location, guint* modifiers)
{
    if (location == DOMKeyLocationNumpad) {
        if (WKStringIsEqualToUTF8CString(keyRef, "leftArrow"))
            return GDK_KEY_KP_Left;
        if (WKStringIsEqualToUTF8CString(keyRef, "rightArror"))
            return GDK_KEY_KP_Right;
        if (WKStringIsEqualToUTF8CString(keyRef, "upArrow"))
            return GDK_KEY_KP_Up;
        if (WKStringIsEqualToUTF8CString(keyRef, "downArrow"))
            return GDK_KEY_KP_Down;
        if (WKStringIsEqualToUTF8CString(keyRef, "pageUp"))
            return GDK_KEY_KP_Page_Up;
        if (WKStringIsEqualToUTF8CString(keyRef, "pageDown"))
            return GDK_KEY_KP_Page_Down;
        if (WKStringIsEqualToUTF8CString(keyRef, "home"))
            return GDK_KEY_KP_Home;
        if (WKStringIsEqualToUTF8CString(keyRef, "end"))
            return GDK_KEY_KP_End;
        if (WKStringIsEqualToUTF8CString(keyRef, "insert"))
            return GDK_KEY_KP_Insert;
        if (WKStringIsEqualToUTF8CString(keyRef, "delete"))
            return GDK_KEY_KP_Delete;

        return GDK_KEY_VoidSymbol;
    }

    if (WKStringIsEqualToUTF8CString(keyRef, "leftArrow"))
        return GDK_KEY_Left;
    if (WKStringIsEqualToUTF8CString(keyRef, "rightArrow"))
        return GDK_KEY_Right;
    if (WKStringIsEqualToUTF8CString(keyRef, "upArrow"))
        return GDK_KEY_Up;
    if (WKStringIsEqualToUTF8CString(keyRef, "downArrow"))
        return GDK_KEY_Down;
    if (WKStringIsEqualToUTF8CString(keyRef, "pageUp"))
        return GDK_KEY_Page_Up;
    if (WKStringIsEqualToUTF8CString(keyRef, "pageDown"))
        return GDK_KEY_Page_Down;
    if (WKStringIsEqualToUTF8CString(keyRef, "home"))
        return GDK_KEY_Home;
    if (WKStringIsEqualToUTF8CString(keyRef, "end"))
        return GDK_KEY_End;
    if (WKStringIsEqualToUTF8CString(keyRef, "insert"))
        return GDK_KEY_Insert;
    if (WKStringIsEqualToUTF8CString(keyRef, "delete"))
        return GDK_KEY_Delete;
    if (WKStringIsEqualToUTF8CString(keyRef, "printScreen"))
        return GDK_KEY_Print;
    if (WKStringIsEqualToUTF8CString(keyRef, "menu"))
        return GDK_KEY_Menu;
    if (WKStringIsEqualToUTF8CString(keyRef, "F1"))
        return GDK_KEY_F1;
    if (WKStringIsEqualToUTF8CString(keyRef, "F2"))
        return GDK_KEY_F2;
    if (WKStringIsEqualToUTF8CString(keyRef, "F3"))
        return GDK_KEY_F3;
    if (WKStringIsEqualToUTF8CString(keyRef, "F4"))
        return GDK_KEY_F4;
    if (WKStringIsEqualToUTF8CString(keyRef, "F5"))
        return GDK_KEY_F5;
    if (WKStringIsEqualToUTF8CString(keyRef, "F6"))
        return GDK_KEY_F6;
    if (WKStringIsEqualToUTF8CString(keyRef, "F7"))
        return GDK_KEY_F7;
    if (WKStringIsEqualToUTF8CString(keyRef, "F8"))
        return GDK_KEY_F8;
    if (WKStringIsEqualToUTF8CString(keyRef, "F9"))
        return GDK_KEY_F9;
    if (WKStringIsEqualToUTF8CString(keyRef, "F10"))
        return GDK_KEY_F10;
    if (WKStringIsEqualToUTF8CString(keyRef, "F11"))
        return GDK_KEY_F11;
    if (WKStringIsEqualToUTF8CString(keyRef, "F12"))
        return GDK_KEY_F12;

    size_t bufferSize = WKStringGetMaximumUTF8CStringSize(keyRef);
    OwnArrayPtr<char> buffer = adoptArrayPtr(new char[bufferSize]);
    WKStringGetUTF8CString(keyRef, buffer.get(), bufferSize);
    char charCode = buffer.get()[0];

    if (charCode == '\n' || charCode == '\r')
        return GDK_KEY_Return;
    if (charCode == '\t')
        return GDK_KEY_Tab;
    if (charCode == '\x8')
        return GDK_KEY_BackSpace;

    if (WTF::isASCIIUpper(charCode))
        *modifiers |= GDK_SHIFT_MASK;

    return gdk_unicode_to_keyval(static_cast<guint32>(buffer.get()[0]));
}
Esempio n. 15
0
gboolean
gom_keyboard_evt_key_identifier_to_keyval (const char        *key_identifier, 
                                           GomKeyLocationCode key_location,
                                           guint             *keyval)
{
    static GOnce in_a_lifetime = G_ONCE_INIT;
    KeyIdentifierCodes *codes;
    GHashTable *ht;

    if (key_location < GOM_DOM_KEY_LOCATION_STANDARD || key_location > GOM_DOM_KEY_LOCATION_NUMPAD) {
        return FALSE;
    }
    
    ht = g_once (&in_a_lifetime, key_identifier_to_keyval_once, NULL);

    codes = g_hash_table_lookup (ht, key_identifier);
    if (codes) {
        switch (key_location) {
        case GOM_DOM_KEY_LOCATION_STANDARD:
            *keyval = codes->standard;
            break;
        case GOM_DOM_KEY_LOCATION_LEFT:
            *keyval = codes->left;
            break;
        case GOM_DOM_KEY_LOCATION_RIGHT:
            *keyval = codes->right;
            break;
        case GOM_DOM_KEY_LOCATION_NUMPAD:
            *keyval = codes->numpad;
            break;
        }
        if (*keyval) {
            return TRUE;
        }
    }

    if (key_identifier[0] != 'U' || key_identifier[1] != '+') {
        return FALSE;
    }

    *keyval = strtol (&key_identifier[2], NULL, 16);
    if (!*keyval) {
        return FALSE;
    }
    *keyval = gdk_unicode_to_keyval (*keyval);
        
    codes = g_new0 (KeyIdentifierCodes, 1);
    codes->id = g_strdup (key_identifier);
    
    switch (key_location) {
    case GOM_DOM_KEY_LOCATION_STANDARD:
        codes->standard = *keyval;
        break;
    case GOM_DOM_KEY_LOCATION_LEFT:
        codes->left = *keyval;
        break;
    case GOM_DOM_KEY_LOCATION_RIGHT:
        codes->right = *keyval;
        break;
    case GOM_DOM_KEY_LOCATION_NUMPAD:
        codes->numpad = *keyval;
        break;
    }

    g_hash_table_insert (ht, (gpointer)codes->id, codes);

    return TRUE;
}
Esempio n. 16
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);
}
void
uGlobalMenuItem::SyncAccelFromContent()
{
  if (!mKeyContent) {
    dbusmenu_menuitem_property_remove(mDbusMenuItem,
                                      DBUSMENU_MENUITEM_PROP_SHORTCUT);
    return;
  }

  nsAutoString modStr;
  mKeyContent->GetAttr(kNameSpaceID_None, uWidgetAtoms::modifiers, modStr);

  PRUint32 modifier = 0;

  if (!modStr.IsEmpty()) {
    char* str = ToNewUTF8String(modStr);
    char *token = strtok(str, ", \t");
    while(token) {
      if (strcmp(token, "shift") == 0) {
        modifier |= GDK_SHIFT_MASK;
      } else if (strcmp(token, "alt") == 0) {
        modifier |= GDK_MOD1_MASK;
      } else if (strcmp(token, "meta") == 0) {
        modifier |= GDK_META_MASK;
      } else if (strcmp(token, "control") == 0) {
        modifier |= GDK_CONTROL_MASK;
      } else if (strcmp(token, "accel") == 0) {
        nsIPrefBranch *prefs = uGlobalMenuService::GetPrefService();
        PRInt32 accel;
        prefs->GetIntPref("ui.key.accelKey", &accel);
        if (accel == nsIDOMKeyEvent::DOM_VK_META) {
          modifier |= GDK_META_MASK;
        } else if (accel == nsIDOMKeyEvent::DOM_VK_ALT) {
          modifier |= GDK_MOD1_MASK;
        } else {
          modifier |= GDK_CONTROL_MASK;
        }
      }

      token = strtok(nullptr, ", \t");
    }

    nsMemory::Free(str);
  }

  nsAutoString keyStr;
  guint key = 0;
  mKeyContent->GetAttr(kNameSpaceID_None, uWidgetAtoms::key, keyStr);

  nsAutoCString cKeyStr;
  CopyUTF16toUTF8(keyStr, cKeyStr);

  if (!cKeyStr.IsEmpty()) {
    key = gdk_keyval_from_name(cKeyStr.get());
  }

  if (key == 0 && !keyStr.IsEmpty()) {
    key = gdk_unicode_to_keyval(*keyStr.BeginReading());
  }

  if (key == 0) {
    mKeyContent->GetAttr(kNameSpaceID_None, uWidgetAtoms::keycode, keyStr);
    if (!keyStr.IsEmpty())
      key = MozKeyCodeToGdkKeyCode(GetKeyCode(keyStr));
  }

  if (key == 0) {
    key = GDK_VoidSymbol;
  }

  if (key != GDK_VoidSymbol) {
    dbusmenu_menuitem_property_set_shortcut(mDbusMenuItem, key,
                                       static_cast<GdkModifierType>(modifier));
  } else {
    dbusmenu_menuitem_property_remove(mDbusMenuItem,
                                      DBUSMENU_MENUITEM_PROP_SHORTCUT);
  }
}
Esempio n. 18
0
static void
update_keymap (void)
{
  static guint current_serial = 0;
  guchar key_state[256];
  guint scancode;
  guint vk;
  gboolean capslock_tested = FALSE;

  if (keysym_tab != NULL && current_serial == _gdk_keymap_serial)
    return;

  current_serial = _gdk_keymap_serial;

  if (keysym_tab == NULL)
    keysym_tab = g_new (guint, 4*256);

  memset (key_state, 0, sizeof (key_state));

  _gdk_keyboard_has_altgr = FALSE;
  gdk_shift_modifiers = GDK_SHIFT_MASK;

  for (vk = 0; vk < 256; vk++)
    {
      if ((scancode = MapVirtualKey (vk, 0)) == 0 &&
	  vk != VK_DIVIDE)
	keysym_tab[vk*4+0] =
	  keysym_tab[vk*4+1] =
	  keysym_tab[vk*4+2] =
	  keysym_tab[vk*4+3] = GDK_VoidSymbol;
      else
	{
	  gint shift;

	  if (vk == VK_RSHIFT)
	    _scancode_rshift = scancode;

	  key_state[vk] = 0x80;
	  for (shift = 0; shift < 4; shift++)
	    {
	      guint *ksymp = keysym_tab + vk*4 + shift;
	      
	      set_shift_vks (key_state, shift);

	      *ksymp = 0;

	      /* First, handle those virtual keys that we always want
	       * as special GDK_* keysyms, even if ToAsciiEx might
	       * turn some them into a ASCII character (like TAB and
	       * ESC).
	       */
	      handle_special (vk, ksymp, shift);

	      if (*ksymp == 0)
		{
		  wchar_t wcs[10];
		  gint k;

		  wcs[0] = wcs[1] = 0;
		  k = ToUnicodeEx (vk, scancode, key_state,
				   wcs, G_N_ELEMENTS (wcs),
				   0, _gdk_input_locale);
#if 0
		  g_print ("ToUnicodeEx(%#02x, %d: %d): %d, %04x %04x\n",
			   vk, scancode, shift, k,
			   wcs[0], wcs[1]);
#endif
		  if (k == 1)
		    *ksymp = gdk_unicode_to_keyval (wcs[0]);
		  else if (k == -1)
		    {
		      guint keysym = gdk_unicode_to_keyval (wcs[0]);

		      /* It is a dead key, and it's has been stored in
		       * the keyboard layout's state by
		       * ToAsciiEx()/ToUnicodeEx(). Yes, this is an
		       * incredibly silly API! Make the keyboard
		       * layout forget it by calling
		       * ToAsciiEx()/ToUnicodeEx() once more, with the
		       * virtual key code and scancode for the
		       * spacebar, without shift or AltGr. Otherwise
		       * the next call to ToAsciiEx() with a different
		       * key would try to combine with the dead key.
		       */
		      reset_after_dead (key_state);

		      /* Use dead keysyms instead of "undead" ones */
		      handle_dead (keysym, ksymp);
		    }
		  else if (k == 0)
		    {
		      /* Seems to be necessary to "reset" the keyboard layout
		       * in this case, too. Otherwise problems on NT4.
		       */
		      reset_after_dead (key_state);
		    }
		  else
		    {
#if 0
		      GDK_NOTE (EVENTS,
				g_print ("ToUnicodeEx returns %d "
					 "for vk:%02x, sc:%02x%s%s\n",
					 k, vk, scancode,
					 (shift&0x1 ? " shift" : ""),
					 (shift&0x2 ? " altgr" : "")));
#endif
		    }
		}
	      if (*ksymp == 0)
		*ksymp = GDK_VoidSymbol;
	    }
	  key_state[vk] = 0;

	  /* Check if keyboard has an AltGr key by checking if
	   * the mapping with Control+Alt is different.
	   */
	  if (!_gdk_keyboard_has_altgr)
	    if ((keysym_tab[vk*4 + 2] != GDK_VoidSymbol &&
		 keysym_tab[vk*4] != keysym_tab[vk*4 + 2]) ||
		(keysym_tab[vk*4 + 3] != GDK_VoidSymbol &&
		 keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 3]))
	      _gdk_keyboard_has_altgr = TRUE;
	  
	  if (!capslock_tested)
	    {
	      /* Can we use this virtual key to determine the CapsLock
	       * key behaviour: CapsLock or ShiftLock? If it generates
	       * keysyms for printable characters and has a shifted
	       * keysym that isn't just the upperacase of the
	       * unshifted keysym, check the behaviour of VK_CAPITAL.
	       */
	      if (g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 0])) &&
		  keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 0] &&
		  g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 1])) &&
		  keysym_tab[vk*4 + 1] != gdk_keyval_to_upper (keysym_tab[vk*4 + 0]))
		{
		  guchar chars[2];
		  
		  capslock_tested = TRUE;
		  
		  key_state[VK_SHIFT] = 0;
		  key_state[VK_CONTROL] = key_state[VK_MENU] = 0;
		  key_state[VK_CAPITAL] = 1;

		  if (ToAsciiEx (vk, scancode, key_state,
				 (LPWORD) chars, 0, _gdk_input_locale) == 1)
		    {
		      if (chars[0] >= GDK_space &&
			  chars[0] <= GDK_asciitilde &&
			  chars[0] == keysym_tab[vk*4 + 1])
			{
			  /* CapsLock acts as ShiftLock */
			  gdk_shift_modifiers |= GDK_LOCK_MASK;
			}
		    }
		  key_state[VK_CAPITAL] = 0;
		}    
	    }
	}
    }
  GDK_NOTE (EVENTS, print_keysym_tab ());
}