gtk2/gdk/win32/gdkkeys-win32.c

1021 lines
31 KiB
C
Raw Normal View History

/* GDK - The GIMP Drawing Kit
* Copyright (C) 2000 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
2012-02-27 13:01:10 +00:00
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
2021-09-24 19:01:13 +00:00
#include "gdkwin32keys.h"
#include "gdk.h"
#include "gdkprivate-win32.h"
2021-09-24 19:01:13 +00:00
#include "gdkdebug.h"
#include "gdkdisplayprivate.h"
#include "gdkkeysyms.h"
#include "gdkkeysprivate.h"
#include "gdkkeys-win32.h"
2021-09-24 19:01:13 +00:00
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#define GDK_MOD2_MASK (1 << 4)
/* GdkWin32Keymap */
struct _GdkWin32KeymapClass
{
GdkKeymapClass parent_class;
};
struct _GdkWin32Keymap
{
GdkKeymap parent_instance;
/* Array of HKL */
GArray *layout_handles;
/* Array of GdkWin32KeymapLayoutInfo */
GArray *layout_infos;
/* Index of a handle in layout_handles,
* at any point it should be the same handle as GetKeyboardLayout(0) returns,
* but GDK caches it to avoid calling GetKeyboardLayout (0) every time.
*/
guint8 active_layout;
guint current_serial;
/* Pointer to the implementation to be used. See comment in gdkkeys-win32.h.
* (we will dynamically choose at runtime for 32-bit builds based on whether
* we are running under WOW64)
*/
const GdkWin32KeymapImpl *gdkwin32_keymap_impl;
};
G_DEFINE_TYPE (GdkWin32Keymap, gdk_win32_keymap, GDK_TYPE_KEYMAP)
guint _gdk_keymap_serial = 0;
static GdkKeymap *default_keymap = NULL;
static void update_keymap (GdkWin32Keymap *gdk_keymap);
static void clear_keyboard_layout_info (gpointer data);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
static void
gdk_win32_keymap_init (GdkWin32Keymap *keymap)
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
/* Regular implementation (32 bit & 64 bit) */
extern const GdkWin32KeymapImpl gdkwin32_keymap_impl;
/* Implementation for 32 bit applications running on a 64 bit host (WOW64). */
#ifndef _WIN64
extern const GdkWin32KeymapImpl gdkwin32_keymap_impl_wow64;
#endif
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
keymap->layout_infos = g_array_new (FALSE, TRUE,
sizeof (GdkWin32KeymapLayoutInfo));
g_array_set_clear_func (keymap->layout_infos,
clear_keyboard_layout_info);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
keymap->layout_handles = g_array_new (FALSE, FALSE,
sizeof (GdkWin32KeymapLayoutInfo));
keymap->active_layout = 0;
keymap->gdkwin32_keymap_impl = &gdkwin32_keymap_impl;
#ifndef _WIN64
if (_gdk_win32_check_processor (GDK_WIN32_WOW64))
keymap->gdkwin32_keymap_impl = &gdkwin32_keymap_impl_wow64;
#endif
update_keymap (keymap);
}
static void
gdk_win32_keymap_finalize (GObject *object)
{
GdkWin32Keymap *keymap = GDK_WIN32_KEYMAP (object);
g_clear_pointer (&keymap->layout_handles, g_array_unref);
g_clear_pointer (&keymap->layout_infos, g_array_unref);
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
G_OBJECT_CLASS (gdk_win32_keymap_parent_class)->finalize (object);
}
/* Convenience wrapper functions */
static gboolean
load_layout_dll (GdkWin32Keymap *keymap,
const char *dll,
GdkWin32KeymapLayoutInfo *info)
{
return keymap->gdkwin32_keymap_impl->load_layout_dll (dll, info);
}
static void
init_vk_lookup_table (GdkWin32Keymap *keymap,
GdkWin32KeymapLayoutInfo *info)
{
keymap->gdkwin32_keymap_impl->init_vk_lookup_table (info);
}
static BYTE
keystate_to_modbits (GdkWin32Keymap *keymap,
GdkWin32KeymapLayoutInfo *info,
const BYTE keystate[256])
{
return keymap->gdkwin32_keymap_impl->keystate_to_modbits (info, keystate);
}
static BYTE
modbits_to_level (GdkWin32Keymap *keymap,
GdkWin32KeymapLayoutInfo *info,
BYTE modbits)
{
return keymap->gdkwin32_keymap_impl->modbits_to_level (info, modbits);
}
static WCHAR
vk_to_char_fuzzy (GdkWin32Keymap *keymap,
GdkWin32KeymapLayoutInfo *info,
BYTE mod_bits,
BYTE lock_bits,
BYTE *consumed_mod_bits,
gboolean *is_dead,
BYTE vk)
{
return keymap->gdkwin32_keymap_impl->vk_to_char_fuzzy (info, mod_bits, lock_bits,
consumed_mod_bits, is_dead, vk);
}
/*
* Get the file path of the keyboard layout dll.
* The result is heap-allocated and should be freed with g_free().
*/
static char*
get_keyboard_layout_file (const char *layout_name)
{
HKEY hkey = 0;
DWORD var_type = REG_SZ;
char *result = NULL;
DWORD file_name_len = 0;
int dir_len = 0;
int buf_len = 0;
LSTATUS status;
static const char prefix[] = "SYSTEM\\CurrentControlSet\\Control\\"
"Keyboard Layouts\\";
char kbdKeyPath[sizeof (prefix) + KL_NAMELENGTH];
g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s", prefix,
layout_name);
status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, (LPCSTR) kbdKeyPath, 0,
KEY_QUERY_VALUE, &hkey);
if (status != ERROR_SUCCESS)
{
g_warning("Could not open registry key '%s'. Error code: %d",
kbdKeyPath, (int)status);
goto fail1;
}
/* Get sizes */
status = RegQueryValueExA (hkey, "Layout File", 0, &var_type, 0,
&file_name_len);
if (status != ERROR_SUCCESS)
{
g_warning("Could not query registry key '%s\\Layout File'. Error code: %d",
kbdKeyPath, (int)status);
goto fail2;
}
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
dir_len = GetSystemDirectoryA (0, 0); /* includes \0 */
if (dir_len == 0)
{
g_warning("GetSystemDirectoryA failed. Error: %d", (int)GetLastError());
goto fail2;
}
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
/* Allocate buffer */
buf_len = dir_len + (int) strlen ("\\") + file_name_len;
result = (char*) g_malloc (buf_len);
/* Append system directory. The -1 is because dir_len includes \0 */
if (GetSystemDirectoryA (&result[0], dir_len) != dir_len - 1)
goto fail3;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
/* Append directory separator */
result[dir_len - 1] = '\\';
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
/* Append file name */
status = RegQueryValueExA (hkey, "Layout File", 0, &var_type,
(LPBYTE) &result[dir_len], &file_name_len);
if (status != ERROR_SUCCESS)
{
goto fail3;
}
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
result[dir_len + file_name_len] = '\0';
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
RegCloseKey (hkey);
return result;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
fail3:
g_free (result);
fail2:
RegCloseKey (hkey);
fail1:
return NULL;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
static void
clear_keyboard_layout_info (gpointer data)
{
GdkWin32KeymapLayoutInfo *layout_info = (GdkWin32KeymapLayoutInfo*) data;
g_free (layout_info->file);
if (layout_info->key_entries != NULL)
g_array_unref (layout_info->key_entries);
if (layout_info->reverse_lookup_table != NULL)
g_hash_table_destroy (layout_info->reverse_lookup_table);
if (layout_info->lib != NULL)
FreeLibrary (layout_info->lib);
memset (layout_info, 0, sizeof (GdkWin32KeymapLayoutInfo));
}
#define DEFINE_SPECIAL(map) \
map (VK_CANCEL, GDK_KEY_Cancel) \
map (VK_BACK, GDK_KEY_BackSpace) \
map (VK_CLEAR, GDK_KEY_Clear) \
map (VK_RETURN, GDK_KEY_Return) \
map (VK_LSHIFT, GDK_KEY_Shift_L) \
map (VK_LCONTROL, GDK_KEY_Control_L) \
map (VK_LMENU, GDK_KEY_Alt_L) \
map (VK_PAUSE, GDK_KEY_Pause) \
map (VK_ESCAPE, GDK_KEY_Escape) \
map (VK_PRIOR, GDK_KEY_Prior) \
map (VK_NEXT, GDK_KEY_Next) \
map (VK_END, GDK_KEY_End) \
map (VK_HOME, GDK_KEY_Home) \
map (VK_LEFT, GDK_KEY_Left) \
map (VK_UP, GDK_KEY_Up) \
map (VK_RIGHT, GDK_KEY_Right) \
map (VK_DOWN, GDK_KEY_Down) \
map (VK_SELECT, GDK_KEY_Select) \
map (VK_PRINT, GDK_KEY_Print) \
map (VK_EXECUTE, GDK_KEY_Execute) \
map (VK_INSERT, GDK_KEY_Insert) \
map (VK_DELETE, GDK_KEY_Delete) \
map (VK_HELP, GDK_KEY_Help) \
map (VK_LWIN, GDK_KEY_Meta_L) \
map (VK_RWIN, GDK_KEY_Meta_R) \
map (VK_APPS, GDK_KEY_Menu) \
map (VK_DECIMAL, GDK_KEY_KP_Decimal) \
map (VK_MULTIPLY, GDK_KEY_KP_Multiply) \
map (VK_ADD, GDK_KEY_KP_Add) \
map (VK_SEPARATOR, GDK_KEY_KP_Separator) \
map (VK_SUBTRACT, GDK_KEY_KP_Subtract) \
map (VK_DIVIDE, GDK_KEY_KP_Divide) \
map (VK_NUMPAD0, GDK_KEY_KP_0) \
map (VK_NUMPAD1, GDK_KEY_KP_1) \
map (VK_NUMPAD2, GDK_KEY_KP_2) \
map (VK_NUMPAD3, GDK_KEY_KP_3) \
map (VK_NUMPAD4, GDK_KEY_KP_4) \
map (VK_NUMPAD5, GDK_KEY_KP_5) \
map (VK_NUMPAD6, GDK_KEY_KP_6) \
map (VK_NUMPAD7, GDK_KEY_KP_7) \
map (VK_NUMPAD8, GDK_KEY_KP_8) \
map (VK_NUMPAD9, GDK_KEY_KP_9) \
map (VK_F1, GDK_KEY_F1) \
map (VK_F2, GDK_KEY_F2) \
map (VK_F3, GDK_KEY_F3) \
map (VK_F4, GDK_KEY_F4) \
map (VK_F5, GDK_KEY_F5) \
map (VK_F6, GDK_KEY_F6) \
map (VK_F7, GDK_KEY_F7) \
map (VK_F8, GDK_KEY_F8) \
map (VK_F9, GDK_KEY_F9) \
map (VK_F10, GDK_KEY_F10) \
map (VK_F11, GDK_KEY_F11) \
map (VK_F12, GDK_KEY_F12) \
map (VK_F13, GDK_KEY_F13) \
map (VK_F14, GDK_KEY_F14) \
map (VK_F15, GDK_KEY_F15) \
map (VK_F16, GDK_KEY_F16) \
map (VK_F17, GDK_KEY_F17) \
map (VK_F18, GDK_KEY_F18) \
map (VK_F19, GDK_KEY_F19) \
map (VK_F20, GDK_KEY_F20) \
map (VK_F21, GDK_KEY_F21) \
map (VK_F22, GDK_KEY_F22) \
map (VK_F23, GDK_KEY_F23) \
map (VK_F24, GDK_KEY_F24) \
map (VK_NUMLOCK, GDK_KEY_Num_Lock) \
map (VK_SCROLL, GDK_KEY_Scroll_Lock) \
map (VK_RSHIFT, GDK_KEY_Shift_R) \
map (VK_RCONTROL, GDK_KEY_Control_R) \
map (VK_RMENU, GDK_KEY_Alt_R) \
map (VK_CAPITAL, GDK_KEY_Caps_Lock)
#define DEFINE_DEAD(map) \
map ('"', /* 0x022 */ GDK_KEY_dead_diaeresis) \
map ('\'', /* 0x027 */ GDK_KEY_dead_acute) \
map (GDK_KEY_asciicircum, /* 0x05e */ GDK_KEY_dead_circumflex) \
map (GDK_KEY_grave, /* 0x060 */ GDK_KEY_dead_grave) \
map (GDK_KEY_asciitilde, /* 0x07e */ GDK_KEY_dead_tilde) \
map (GDK_KEY_diaeresis, /* 0x0a8 */ GDK_KEY_dead_diaeresis) \
map (GDK_KEY_degree, /* 0x0b0 */ GDK_KEY_dead_abovering) \
map (GDK_KEY_acute, /* 0x0b4 */ GDK_KEY_dead_acute) \
map (GDK_KEY_periodcentered, /* 0x0b7 */ GDK_KEY_dead_abovedot) \
map (GDK_KEY_cedilla, /* 0x0b8 */ GDK_KEY_dead_cedilla) \
map (GDK_KEY_breve, /* 0x1a2 */ GDK_KEY_dead_breve) \
map (GDK_KEY_ogonek, /* 0x1b2 */ GDK_KEY_dead_ogonek) \
map (GDK_KEY_caron, /* 0x1b7 */ GDK_KEY_dead_caron) \
map (GDK_KEY_doubleacute, /* 0x1bd */ GDK_KEY_dead_doubleacute) \
map (GDK_KEY_abovedot, /* 0x1ff */ GDK_KEY_dead_abovedot) \
map (0x1000384, /* Greek tonos */ GDK_KEY_dead_acute) \
map (GDK_KEY_Greek_accentdieresis, /* 0x7ae */ GDK_KEY_Greek_accentdieresis)
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
static guint
vk_and_mod_bits_to_gdk_keysym (GdkWin32Keymap *keymap,
GdkWin32KeymapLayoutInfo *info,
guint vk,
BYTE mod_bits,
BYTE lock_bits,
BYTE *consumed_mod_bits)
{
gboolean is_dead = FALSE;
gunichar c;
guint sym;
if (consumed_mod_bits)
*consumed_mod_bits = 0;
/* Handle special key: Tab */
if (vk == VK_TAB)
{
if (consumed_mod_bits)
*consumed_mod_bits = mod_bits & KBDSHIFT;
return (mod_bits & KBDSHIFT) ? GDK_KEY_ISO_Left_Tab : GDK_KEY_Tab;
}
/* Handle other special keys */
switch (vk)
{
#define MAP(a_vk, a_gdk) case a_vk: return a_gdk;
DEFINE_SPECIAL (MAP)
/* Non-bijective mappings: */
MAP (VK_SHIFT, GDK_KEY_Shift_L)
MAP (VK_CONTROL, GDK_KEY_Control_L)
MAP (VK_MENU, GDK_KEY_Alt_L)
MAP (VK_SNAPSHOT, GDK_KEY_Print)
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
#undef MAP
}
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
/* Handle regular keys (including dead keys) */
c = vk_to_char_fuzzy (keymap, info, mod_bits, lock_bits,
consumed_mod_bits, &is_dead, vk);
if (c == WCH_NONE)
return GDK_KEY_VoidSymbol;
sym = gdk_unicode_to_keyval (c);
if (is_dead)
{
switch (sym)
{
#define MAP(a_nondead, a_dead) case a_nondead: return a_dead;
DEFINE_DEAD (MAP)
#undef MAP
}
}
return sym;
}
static int
gdk_keysym_to_key_entry_index (GdkWin32KeymapLayoutInfo *info,
guint sym)
{
gunichar c;
gintptr index;
if (info->reverse_lookup_table == NULL)
return -1;
/* Special cases */
if (sym == GDK_KEY_Tab)
return VK_TAB;
if (sym == GDK_KEY_ISO_Left_Tab)
return 256;
/* Generic non-printable keys */
switch (sym)
{
#define MAP(a_vk, a_gdk) case a_gdk: return a_vk;
DEFINE_SPECIAL (MAP)
#undef MAP
}
/* Fix up dead keys */
#define MAP(a_nondead, a_dead) \
if (sym == a_dead) \
sym = a_nondead;
DEFINE_DEAD (MAP)
#undef MAP
/* Try converting to Unicode and back */
c = gdk_keyval_to_unicode (sym);
index = -1;
if (g_hash_table_lookup_extended (info->reverse_lookup_table,
GINT_TO_POINTER (c),
NULL, (gpointer*) &index))
{
return index;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
}
else
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
return -1;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
}
static GdkModifierType
mod_bits_to_gdk_mod_mask (BYTE mod_bits)
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
GdkModifierType result = 0;
if (mod_bits & KBDSHIFT)
result |= GDK_SHIFT_MASK;
if (mod_bits & KBDCTRL)
result |= GDK_CONTROL_MASK;
if (mod_bits & KBDALT)
result |= GDK_ALT_MASK;
return result;
}
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
static BYTE
gdk_mod_mask_to_mod_bits (GdkModifierType mod_mask)
{
BYTE result = 0;
if (mod_mask & GDK_SHIFT_MASK)
result |= KBDSHIFT;
if (mod_mask & GDK_CONTROL_MASK)
result |= KBDCTRL;
if (mod_mask & GDK_ALT_MASK)
result |= KBDALT;
return result;
}
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
/* keypad decimal mark depends on active keyboard layout
* return current decimal mark as unicode character
*/
guint32
_gdk_win32_keymap_get_decimal_mark (GdkWin32Keymap *keymap)
{
guint32 c = MapVirtualKeyW (VK_DECIMAL, MAPVK_VK_TO_CHAR);
if (!c)
c = (guint32) '.';
return c;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
static void
update_keymap (GdkWin32Keymap *keymap)
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
HKL current_layout;
BOOL changed = FALSE;
int n_layouts;
int i;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
if (keymap->current_serial == _gdk_keymap_serial &&
keymap->layout_handles->len > 0)
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
return;
}
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
n_layouts = GetKeyboardLayoutList (0, 0);
g_array_set_size (keymap->layout_handles, n_layouts);
n_layouts = GetKeyboardLayoutList (n_layouts,
&g_array_index(keymap->layout_handles,
HKL, 0));
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
g_array_set_size (keymap->layout_infos, n_layouts);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
current_layout = GetKeyboardLayout (0);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
for (i = 0; i < n_layouts; ++i)
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
GdkWin32KeymapLayoutInfo *info = &g_array_index(keymap->layout_infos,
GdkWin32KeymapLayoutInfo, i);
HKL hkl = g_array_index(keymap->layout_handles, HKL, i);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
if (info->handle != hkl)
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
changed = TRUE;
/* Free old data */
clear_keyboard_layout_info (info);
/* Load new data */
info->handle = hkl;
ActivateKeyboardLayout (hkl, 0);
GetKeyboardLayoutNameA (info->name);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
info->file = get_keyboard_layout_file (info->name);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
if (info->file != NULL && load_layout_dll (keymap, info->file, info))
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
{
info->key_entries = g_array_new (FALSE, FALSE,
sizeof (GdkWin32KeymapKeyEntry));
info->reverse_lookup_table = g_hash_table_new (g_direct_hash,
g_direct_equal);
init_vk_lookup_table (keymap, info);
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
else
{
g_warning("Failed to load keyboard layout DLL for layout %s: %s",
info->name, info->file);
}
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
if (info->handle == current_layout)
keymap->active_layout = i;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
if (changed)
ActivateKeyboardLayout (current_layout, 0);
keymap->current_serial = _gdk_keymap_serial;
W32: Prefer the deadkey combinations that the OS uses Pick the W32 API for possible deadkey+<something> combinations and prefer these to other sources of deadkey combos. Specifically, if W32 API supports at least one combo for a particular deadkey, only use that data and do not attempt to do other, unsupported combinations, even if they make sense otherwise. This is needed to, for example, correctly support US-International keyboard layout, which produces a combined character for <' + a> combo, but not for <' + s>, for example. This is achieved by stashing all the deadkeys that we find in an array, then doing extra loop through all virtual key codes and trying to combine them with each of these deadkeys. Any combinations that produce a single character are cached for later use. In GTK Simple IM context, call a new GDK W32 function to do a lookup on that cached combination table early on, among the "special cases" (which are now partially obsolete). A limitation of this code is that combinations with more than one deadkey are not supported, except for combinations that consist entirely of 2 known deadkeys. The upshot is that lookups should be relatively fast, as deadkey array stays small and the combination tree stays shallow. Note that the use of ToUnicodeEx() seems suboptimal, as it should be possible to just load a keyboard library (KBD*.DLL) manually and obtain and use its key table directly. However, that is much more complicated and would result in a significant rewrite of gdkkeys-win32. The code from this commit, though hacky, is a direct addition to existing code and should cover vast majority of the use-cases. https://bugzilla.gnome.org/show_bug.cgi?id=569581
2016-07-16 09:23:22 +00:00
}
guint8
_gdk_win32_keymap_get_rshift_scancode (GdkWin32Keymap *keymap)
{
return MapVirtualKey (VK_RSHIFT, MAPVK_VK_TO_VSC);
}
void
_gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,
HKL hkl)
{
if (keymap != NULL &&
keymap->layout_handles->len > 0)
{
2020-07-24 13:54:49 +00:00
int group;
for (group = 0; group < keymap->layout_handles->len; group++)
if (g_array_index (keymap->layout_handles, HKL, group) == hkl)
keymap->active_layout = group;
}
}
guint8
_gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap)
{
if (keymap != NULL &&
keymap->layout_handles->len > 0)
return keymap->active_layout;
return 0;
}
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
GdkKeymap*
_gdk_win32_display_get_keymap (GdkDisplay *display)
{
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
Changes multihead reorganizing code for win32 support, mostly from a patch Wed Jun 5 18:34:47 2002 Owen Taylor <otaylor@redhat.com> Changes multihead reorganizing code for win32 support, mostly from a patch by Hans Breuer. * gdk/gdkcolor.c gdk/x11/gdkcolor-x11.c gdk/gdkcursor.c gdk/x11/gdkcursor-x11.c gdk/gdkevents.c gdk/x11/gdkevents-x11.c gdk/gdkfont.c gdk/x11/gdkfont-x11.c gdk/gdkkeys.c gdk/x11/gdkkeys-x11.c gdk/gdkimage.c gdk/x11/gdkimage-x11.c gdk/gdkscreen.c gdk/x11/gdkmain-x11.c gdk/gdkdisplay.c gdk/gdkevents-x11.c gdk/gdkpango.c gdk/x11/gdkpango-x11.c gdk/gdkselection.c gdk/x11/gdkselection-x11.c gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c gdk/gdkvisual.c gdk/x11/gdkvisual-x11.c: Move port-independent singlehead wrapper functions into port-independent part of GDK. (#80009) * gdk/win32/gdkcolor-win32.c gdk/win32/gdkcursor-win32.c gdk/win32/gdkevents-win32.c gdk/win32/gdkfont-win32.c gdk/win32/gdkimage-win32.c gdk/win32/gdkkeys-win32.c gdk/win32/gdkmain-win32.c gdk/win32/gdkproperty-win32.c gdk/win32/gdkselection-win32.c gdk/win32/gkwindow-win32.c: Turn singlehead functions into "multihead" functions that ignore their GdkDisplay or GdkScreen arguments. * gdk/win32/gdkdrawable-win32.c gdk/win32/gdkevents-win32.c gdk/win32/gdkinput-win32.c gdk/win32/gdkprivate-win32.h: Misc multihead-compatibility changes. * gtk/gtk.def gdk/gdk.def: Update for multihead functions. * gdk/gdkcolormap.h gdk/gdkvisual.h gdk/x11/gdkcolormap-x11.c gdk/x11/gdkvisual-x11.c: Remove the screen fields from the public parts of the colormap/visual structures, add accessors instead. * gdk/gdkpixbuf-render.c gdk/gdkpixmap.c gdk/gdkrgb.c gdk/x11/gdkcolormap-x11.c gdk/x11/gdkimage-x11.c gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.h gtk/gtkgc.c gtk/gtkstyle.c gtk/gtkwidget.c: Use accessors to get the screen for colormaps, visuals; move the fields into the private structures for the x11 backend. * gdk/gdkdisplay.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkscreen-x11.c: Remove virtualization of screen and display functions. (#79990, patch from Erwann Chenede) * gdk/win32/gdkdisplay-x11.c gdk/win32/gdkscreen-win32.c gdk/win32/{Makefile.am, makefile.msc, makefile.mingw}: New files containing stub implementations of Display, Screen functions. * gdk/x11/gdkscreen-x11.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkx.h: Clean up function exports and what headers they are in. (#79954) * gdk/x11/gdkx.h: Fix macro that was referring to a non-existant screen->screen_num. (In the patch for #79972, Erwann Chenede) * gdk/gdkscreen.c gdk/gdkwindow.c gdk/x11/gdkinternals.h gdk/x11/gdkscreen-x11.c: Fix gdk_screen_get_window_at_pointer() to use window hooks. (#79972, patch partly from Erwann Chenede) * gdk/x11/gdkdisplay-x11.c gdk/x11/gdkevents-x11.c: Fix some warnings.
2002-06-06 00:26:42 +00:00
if (default_keymap == NULL)
default_keymap = g_object_new (gdk_win32_keymap_get_type (), NULL);
return default_keymap;
}
GdkModifierType
_gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap)
{
GdkWin32KeymapLayoutInfo *layout_info;
BYTE keystate[256] = {0};
BYTE mod_bits;
update_keymap (keymap);
layout_info = &g_array_index (keymap->layout_infos, GdkWin32KeymapLayoutInfo,
keymap->active_layout);
GetKeyboardState (keystate);
mod_bits = keystate_to_modbits (keymap, layout_info, keystate);
return mod_bits_to_gdk_mod_mask (mod_bits);
}
static PangoDirection
get_hkl_direction (HKL hkl)
{
switch (PRIMARYLANGID (LOWORD ((DWORD) (gintptr) hkl)))
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
{
case LANG_HEBREW:
case LANG_ARABIC:
#ifdef LANG_URDU
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
case LANG_URDU:
#endif
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
case LANG_FARSI:
/* Others? */
return PANGO_DIRECTION_RTL;
default:
return PANGO_DIRECTION_LTR;
}
}
static PangoDirection
gdk_win32_keymap_get_direction (GdkKeymap *gdk_keymap)
{
GdkWin32Keymap *keymap;
HKL active_hkl;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), PANGO_DIRECTION_LTR);
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
update_keymap (keymap);
if (keymap->layout_handles->len <= 0)
active_hkl = GetKeyboardLayout (0);
else
active_hkl = g_array_index (keymap->layout_handles, HKL,
keymap->active_layout);
return get_hkl_direction (active_hkl);
}
static gboolean
gdk_win32_keymap_have_bidi_layouts (GdkKeymap *gdk_keymap)
{
GdkWin32Keymap *keymap;
gboolean have_rtl = FALSE;
gboolean have_ltr = FALSE;
2020-07-24 13:54:49 +00:00
int group;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
update_keymap (keymap);
for (group = 0; group < keymap->layout_handles->len; group++)
{
if (get_hkl_direction (g_array_index (keymap->layout_handles, HKL,
group)) == PANGO_DIRECTION_RTL)
have_rtl = TRUE;
else
have_ltr = TRUE;
}
return have_ltr && have_rtl;
}
static gboolean
gdk_win32_keymap_get_caps_lock_state (GdkKeymap *keymap)
{
(void) keymap;
return ((GetKeyState (VK_CAPITAL) & 1) != 0);
}
static gboolean
gdk_win32_keymap_get_num_lock_state (GdkKeymap *keymap)
{
(void) keymap;
return ((GetKeyState (VK_NUMLOCK) & 1) != 0);
}
static gboolean
gdk_win32_keymap_get_scroll_lock_state (GdkKeymap *keymap)
{
(void) keymap;
return ((GetKeyState (VK_SCROLL) & 1) != 0);
}
static gboolean
gdk_win32_keymap_get_entries_for_keyval (GdkKeymap *gdk_keymap,
guint keyval,
GArray *retval)
{
GdkWin32Keymap *keymap;
int group;
guint len = retval->len;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
g_return_val_if_fail (keyval != 0, FALSE);
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
update_keymap (keymap);
for (group = 0; group < keymap->layout_handles->len; group++)
{
GdkWin32KeymapLayoutInfo *info = &g_array_index (keymap->layout_infos,
GdkWin32KeymapLayoutInfo,
group);
int entry_index = gdk_keysym_to_key_entry_index (info, keyval);
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
while (entry_index >= 0)
{
GdkWin32KeymapKeyEntry *entry = &g_array_index (info->key_entries,
GdkWin32KeymapKeyEntry,
entry_index);
BYTE base_modbits = entry->mod_bits;
BYTE extra_modbits;
GdkKeymapKey gdk_key = {0};
/* Add original key combination */
gdk_key.keycode = entry->vk;
gdk_key.level = modbits_to_level (keymap, info, entry->mod_bits);
gdk_key.group = group;
g_array_append_val (retval, gdk_key);
/* Add combinations with modifiers that do not affect the translation */
for (extra_modbits = 0;
extra_modbits <= info->max_modbit_value;
++extra_modbits)
{
BYTE modbits;
guint sym;
/* We are only interested in masks which are orthogonal to the
* original mask. */
if ((extra_modbits | base_modbits) == base_modbits ||
(extra_modbits & base_modbits) != 0)
continue;
modbits = base_modbits | extra_modbits;
/* Check if the additional modifiers change the semantics.
* If they do not, add them. */
sym = vk_and_mod_bits_to_gdk_keysym (keymap, info, entry->vk,
modbits, 0, NULL);
if (sym == keyval || sym == GDK_KEY_VoidSymbol)
{
gdk_key.keycode = entry->vk;
gdk_key.level = modbits_to_level (keymap, info, modbits);
gdk_key.group = group;
g_array_append_val (retval, gdk_key);
}
}
entry_index = entry->next;
}
}
return retval->len > len;
}
static gboolean
gdk_win32_keymap_get_entries_for_keycode (GdkKeymap *gdk_keymap,
guint hardware_keycode,
GdkKeymapKey **keys,
guint **keyvals,
2020-07-24 13:54:49 +00:00
int *n_entries)
{
GdkWin32Keymap *keymap;
GArray *key_array;
GArray *keyval_array;
2020-07-24 13:54:49 +00:00
int group;
BYTE vk;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
g_return_val_if_fail (n_entries != NULL, FALSE);
*n_entries = 0;
if (keys != NULL)
key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
else
key_array = NULL;
if (keyvals != NULL)
keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
else
keyval_array = NULL;
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
update_keymap (keymap);
vk = hardware_keycode;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
for (group = 0; group < keymap->layout_handles->len; group++)
{
GdkWin32KeymapLayoutInfo *info = &g_array_index (keymap->layout_infos,
GdkWin32KeymapLayoutInfo,
group);
int level;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
for (level = 0; level <= info->max_level; ++level)
{
BYTE modbits = info->level_to_modbits[level];
BYTE consumed_modbits = 0;
GdkKeymapKey key = {0};
guint keyval;
keyval = vk_and_mod_bits_to_gdk_keysym (keymap, info, vk, modbits, 0, &consumed_modbits);
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
if (keyval == GDK_KEY_VoidSymbol || consumed_modbits != modbits)
continue;
key.keycode = vk;
key.group = group;
key.level = level;
if (key_array)
g_array_append_val (key_array, key);
if (keyval_array)
g_array_append_val (keyval_array, keyval);
++(*n_entries);
}
}
if (keys != NULL)
*keys = (GdkKeymapKey*) g_array_free (key_array, FALSE);
if (keyvals != NULL)
*keyvals = (guint*) g_array_free (keyval_array, FALSE);
return *n_entries > 0;
}
static guint
gdk_win32_keymap_lookup_key (GdkKeymap *gdk_keymap,
const GdkKeymapKey *key)
{
GdkWin32Keymap *keymap;
GdkWin32KeymapLayoutInfo *info;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
BYTE modbits;
guint sym;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), 0);
g_return_val_if_fail (key != NULL, 0);
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
update_keymap (keymap);
info = &g_array_index (keymap->layout_infos, GdkWin32KeymapLayoutInfo, key->group);
if (key->group < 0 || key->group >= keymap->layout_handles->len)
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
return 0;
if (key->level < 0 || key->level > info->max_level)
return 0;
modbits = info->level_to_modbits[key->level];
sym = vk_and_mod_bits_to_gdk_keysym (keymap, info, key->keycode, modbits, 0, NULL);
2010-09-09 11:35:20 +00:00
if (sym == GDK_KEY_VoidSymbol)
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
return 0;
else
return sym;
}
static gboolean
gdk_win32_keymap_translate_keyboard_state (GdkKeymap *gdk_keymap,
guint hardware_keycode,
GdkModifierType state,
2020-07-24 13:54:49 +00:00
int group,
guint *keyval,
2020-07-24 13:54:49 +00:00
int *effective_group,
int *level,
GdkModifierType *consumed_modifiers)
{
GdkWin32Keymap *keymap;
guint tmp_keyval;
int tmp_effective_group;
int tmp_level;
BYTE consumed_mod_bits;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
GdkWin32KeymapLayoutInfo *layout_info;
guint vk;
BYTE mod_bits;
BYTE lock_bits = 0;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
update_keymap (keymap);
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
g_return_val_if_fail (group >= 0 && group < keymap->layout_infos->len, FALSE);
layout_info = &g_array_index (keymap->layout_infos, GdkWin32KeymapLayoutInfo,
group);
vk = hardware_keycode;
mod_bits = gdk_mod_mask_to_mod_bits (state);
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
if (vk == VK_SHIFT || vk == VK_LSHIFT || vk == VK_RSHIFT)
mod_bits &= ~KBDSHIFT;
if (vk == VK_CONTROL || vk == VK_LCONTROL || vk == VK_RCONTROL)
mod_bits &= ~KBDCTRL;
if (vk == VK_MENU || vk == VK_LMENU || vk == VK_RMENU)
mod_bits &= ~KBDALT;
if (vk == VK_RMENU)
mod_bits &= ~KBDALTGR;
Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they 2002-03-06 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkevents-win32.c (gdk_pointer_grab, gdk_pointer_ungrab): Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they don't effectively do anything anyway. (build_key_event_state): Set MOD2 bit if key is in AltGr group. (gdk_event_translate): Call _gdk_windowing_window_get_offsets() each time the offsets are used, on the window they refer to, instead of once in the beginning. The window in question might change due to event propagation. (gdk_event_translate): Set key event group to 0 for non-AltGr keys. Do set the SHIFT bit in the key event state also for ISO_Left_Tab. Now backtabbing finally works again. * gdk/win32/gdkunput-win32.c: Minor debugging output change. * gdk/win32/gdkkeys-win32.c (update_keymap): Set VK_TAB mapping to Gdk_Tab and GDK_ISO_Left_Tab, like on X11. (gdk_keymap_translate_keyboard_state): Add similar code as in the non-XKB case on X11 to generate a more correct consumed_modifiers. Add debugging output. (gdk_keyval_name): Use the U+xxxx format for UCS characters encoded as keyvals. Never return NULL, but hex number representation if keyval not in table. * gdk/win32/gdkwindow-win32.c (gdk_window_focus): Call SetFocus(). Doesn't seem to have any harmful effect, and probably is close to what this function is supposed to do. But it didn't fix GtkCombo as I had hoped. (gdk_window_set_type_hint): Don't intern the _NET_WM_* atoms that weren't used and wouldn't have any meaning on Win32 anyway.
2002-03-06 00:36:08 +00:00
/* Translate lock state
*
* Right now the only locking modifier is CAPSLOCK. We don't handle KANALOK
* because GDK doesn't have an equivalent modifier mask to my knowledge (On
* X11, I believe the same effect is achieved by shifting to a different
* group. It's just a different concept, that doesn't translate to Windows).
* But since KANALOK is only used on far-eastern keyboards, which require IME
* anyway, this is probably fine. The IME input module has actually been the
* default for all languages (not just far-eastern) for a while now, which
* means that the keymap is now only used for things like accelerators and
* keybindings, where you probably don't even want KANALOK to affect the
* translation.
*/
if (state & GDK_LOCK_MASK)
lock_bits |= CAPLOK;
Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they 2002-03-06 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkevents-win32.c (gdk_pointer_grab, gdk_pointer_ungrab): Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they don't effectively do anything anyway. (build_key_event_state): Set MOD2 bit if key is in AltGr group. (gdk_event_translate): Call _gdk_windowing_window_get_offsets() each time the offsets are used, on the window they refer to, instead of once in the beginning. The window in question might change due to event propagation. (gdk_event_translate): Set key event group to 0 for non-AltGr keys. Do set the SHIFT bit in the key event state also for ISO_Left_Tab. Now backtabbing finally works again. * gdk/win32/gdkunput-win32.c: Minor debugging output change. * gdk/win32/gdkkeys-win32.c (update_keymap): Set VK_TAB mapping to Gdk_Tab and GDK_ISO_Left_Tab, like on X11. (gdk_keymap_translate_keyboard_state): Add similar code as in the non-XKB case on X11 to generate a more correct consumed_modifiers. Add debugging output. (gdk_keyval_name): Use the U+xxxx format for UCS characters encoded as keyvals. Never return NULL, but hex number representation if keyval not in table. * gdk/win32/gdkwindow-win32.c (gdk_window_focus): Call SetFocus(). Doesn't seem to have any harmful effect, and probably is close to what this function is supposed to do. But it didn't fix GtkCombo as I had hoped. (gdk_window_set_type_hint): Don't intern the _NET_WM_* atoms that weren't used and wouldn't have any meaning on Win32 anyway.
2002-03-06 00:36:08 +00:00
tmp_keyval = vk_and_mod_bits_to_gdk_keysym (keymap, layout_info, vk, mod_bits,
lock_bits, &consumed_mod_bits);
tmp_effective_group = group;
tmp_level = modbits_to_level (keymap, layout_info, consumed_mod_bits);
Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they 2002-03-06 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkevents-win32.c (gdk_pointer_grab, gdk_pointer_ungrab): Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they don't effectively do anything anyway. (build_key_event_state): Set MOD2 bit if key is in AltGr group. (gdk_event_translate): Call _gdk_windowing_window_get_offsets() each time the offsets are used, on the window they refer to, instead of once in the beginning. The window in question might change due to event propagation. (gdk_event_translate): Set key event group to 0 for non-AltGr keys. Do set the SHIFT bit in the key event state also for ISO_Left_Tab. Now backtabbing finally works again. * gdk/win32/gdkunput-win32.c: Minor debugging output change. * gdk/win32/gdkkeys-win32.c (update_keymap): Set VK_TAB mapping to Gdk_Tab and GDK_ISO_Left_Tab, like on X11. (gdk_keymap_translate_keyboard_state): Add similar code as in the non-XKB case on X11 to generate a more correct consumed_modifiers. Add debugging output. (gdk_keyval_name): Use the U+xxxx format for UCS characters encoded as keyvals. Never return NULL, but hex number representation if keyval not in table. * gdk/win32/gdkwindow-win32.c (gdk_window_focus): Call SetFocus(). Doesn't seem to have any harmful effect, and probably is close to what this function is supposed to do. But it didn't fix GtkCombo as I had hoped. (gdk_window_set_type_hint): Don't intern the _NET_WM_* atoms that weren't used and wouldn't have any meaning on Win32 anyway.
2002-03-06 00:36:08 +00:00
/* Determine consumed modifiers */
if (keyval)
*keyval = tmp_keyval;
if (effective_group)
*effective_group = tmp_effective_group;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
if (level)
*level = tmp_level;
Implement the functions that until now just were non-functional stubs. For 2002-02-26 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkkeys-win32.c: Implement the functions that until now just were non-functional stubs. For "hardware keycodes", we use Windows virtual keycodes. Not scancodes, although that at first might seem more low-level and a better match to X11 keycodes. The Windows API is really mixed up and confused with respect to scancodes and virtual keycodes. (Surprised?) Some scancodes are generated by two keys on the keyboard (!), and although the keyboard messages do have a flag to indicate which key the user pressed, other API that take a scan code as input don't let you specify which actual key you mean. (update_keymap): Function to build a X11-like representation of the keyboard. Each key has four keysyms: two levels (nonshifted and shifted) and two groups (normal and with AltGr). (gdk_keymap_get_direction): Use the codepage corresponding to the thread's input locale, not the system codepage. * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c * gdk/win32/gdkprivate-win32.h * gdk/win32/gdkwindow-win32.h * gdk/win32/gdkwindow-win32.c: Remove the input_locale and charset_info fields from GdkWindowImplWin32. Input locale is per-thread in Windows, and as GDK on Windows really only works when the GDI interaction all happens in just one thread anyway, this state can be global. Use globals _gdk_input_locale and _gdk_input_codepage instead. Set these based on the thread's input locale (keyboard layout, or which IME is active). * gdk/win32/gdkevents-win32.c: Set the group and hardware_keycode fields in GDK key events. On input locale change messages, set the global state variables, and inform update_keymap() that it has to rebuild the keymap.
2002-02-26 01:18:27 +00:00
if (consumed_modifiers)
*consumed_modifiers = mod_bits_to_gdk_mod_mask (consumed_mod_bits);
Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they 2002-03-06 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkevents-win32.c (gdk_pointer_grab, gdk_pointer_ungrab): Bypass calls to the grab/ungrab functions in gdkinput-win32.c, as they don't effectively do anything anyway. (build_key_event_state): Set MOD2 bit if key is in AltGr group. (gdk_event_translate): Call _gdk_windowing_window_get_offsets() each time the offsets are used, on the window they refer to, instead of once in the beginning. The window in question might change due to event propagation. (gdk_event_translate): Set key event group to 0 for non-AltGr keys. Do set the SHIFT bit in the key event state also for ISO_Left_Tab. Now backtabbing finally works again. * gdk/win32/gdkunput-win32.c: Minor debugging output change. * gdk/win32/gdkkeys-win32.c (update_keymap): Set VK_TAB mapping to Gdk_Tab and GDK_ISO_Left_Tab, like on X11. (gdk_keymap_translate_keyboard_state): Add similar code as in the non-XKB case on X11 to generate a more correct consumed_modifiers. Add debugging output. (gdk_keyval_name): Use the U+xxxx format for UCS characters encoded as keyvals. Never return NULL, but hex number representation if keyval not in table. * gdk/win32/gdkwindow-win32.c (gdk_window_focus): Call SetFocus(). Doesn't seem to have any harmful effect, and probably is close to what this function is supposed to do. But it didn't fix GtkCombo as I had hoped. (gdk_window_set_type_hint): Don't intern the _NET_WM_* atoms that weren't used and wouldn't have any meaning on Win32 anyway.
2002-03-06 00:36:08 +00:00
/* Just a diagnostic message to inform the user why their keypresses aren't working.
* Shouldn't happen under normal circumstances. */
if (tmp_keyval == GDK_KEY_VoidSymbol && layout_info->tables == NULL)
g_warning("Failed to translate keypress (keycode: %u) for group %d (%s) because "
"we could not load the layout.",
hardware_keycode, group, layout_info->name);
2010-09-09 11:35:20 +00:00
return tmp_keyval != GDK_KEY_VoidSymbol;
}
static void
gdk_win32_keymap_class_init (GdkWin32KeymapClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
object_class->finalize = gdk_win32_keymap_finalize;
keymap_class->get_direction = gdk_win32_keymap_get_direction;
keymap_class->have_bidi_layouts = gdk_win32_keymap_have_bidi_layouts;
keymap_class->get_caps_lock_state = gdk_win32_keymap_get_caps_lock_state;
keymap_class->get_num_lock_state = gdk_win32_keymap_get_num_lock_state;
keymap_class->get_scroll_lock_state = gdk_win32_keymap_get_scroll_lock_state;
keymap_class->get_entries_for_keyval = gdk_win32_keymap_get_entries_for_keyval;
keymap_class->get_entries_for_keycode = gdk_win32_keymap_get_entries_for_keycode;
keymap_class->lookup_key = gdk_win32_keymap_lookup_key;
keymap_class->translate_keyboard_state = gdk_win32_keymap_translate_keyboard_state;
}