2000-12-14 23:14:18 +00:00
|
|
|
/* 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/>.
|
2000-12-14 23:14:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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/.
|
|
|
|
*/
|
2013-05-30 08:07:31 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2021-09-24 19:01:13 +00:00
|
|
|
#include "gdkwin32keys.h"
|
2000-12-14 23:14:18 +00:00
|
|
|
|
|
|
|
#include "gdk.h"
|
|
|
|
|
|
|
|
#include "gdkprivate-win32.h"
|
2021-09-24 19:01:13 +00:00
|
|
|
#include "gdkdebug.h"
|
|
|
|
#include "gdkdisplayprivate.h"
|
2000-12-14 23:14:18 +00:00
|
|
|
#include "gdkkeysyms.h"
|
2011-01-02 10:51:25 +00:00
|
|
|
#include "gdkkeysprivate.h"
|
2022-01-05 14:44:49 +00:00
|
|
|
#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>
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2020-04-06 19:13:00 +00:00
|
|
|
#define GDK_MOD2_MASK (1 << 4)
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* GdkWin32Keymap */
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
struct _GdkWin32KeymapClass
|
|
|
|
{
|
|
|
|
GdkKeymapClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _GdkWin32Keymap
|
|
|
|
{
|
|
|
|
GdkKeymap parent_instance;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Array of HKL */
|
2016-07-13 11:41:35 +00:00
|
|
|
GArray *layout_handles;
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Array of GdkWin32KeymapLayoutInfo */
|
|
|
|
GArray *layout_infos;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
|
|
|
/* 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;
|
2022-01-05 14:44:49 +00:00
|
|
|
|
|
|
|
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;
|
2016-07-13 11:41:35 +00:00
|
|
|
};
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
G_DEFINE_TYPE (GdkWin32Keymap, gdk_win32_keymap, GDK_TYPE_KEYMAP)
|
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
guint _gdk_keymap_serial = 0;
|
|
|
|
static GdkKeymap *default_keymap = NULL;
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static void update_keymap (GdkWin32Keymap *gdk_keymap);
|
|
|
|
static void clear_keyboard_layout_info (gpointer data);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
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
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
keymap->layout_handles = g_array_new (FALSE, FALSE,
|
|
|
|
sizeof (GdkWin32KeymapLayoutInfo));
|
2016-07-13 11:41:35 +00:00
|
|
|
keymap->active_layout = 0;
|
2022-01-05 14:44:49 +00:00
|
|
|
|
|
|
|
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);
|
2011-01-02 10:51:25 +00:00
|
|
|
}
|
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
static void
|
|
|
|
gdk_win32_keymap_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
GdkWin32Keymap *keymap = GDK_WIN32_KEYMAP (object);
|
2001-06-22 14:08:51 +00:00
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
g_clear_pointer (&keymap->layout_handles, g_array_unref);
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
G_OBJECT_CLASS (gdk_win32_keymap_parent_class)->finalize (object);
|
|
|
|
}
|
2014-08-13 18:43:51 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Convenience wrapper functions */
|
2005-02-01 11:26:05 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static gboolean
|
|
|
|
load_layout_dll (GdkWin32Keymap *keymap,
|
|
|
|
const char *dll,
|
|
|
|
GdkWin32KeymapLayoutInfo *info)
|
2005-02-01 11:26:05 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
return keymap->gdkwin32_keymap_impl->load_layout_dll (dll, info);
|
2005-02-01 11:26:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-01-05 14:44:49 +00:00
|
|
|
init_vk_lookup_table (GdkWin32Keymap *keymap,
|
|
|
|
GdkWin32KeymapLayoutInfo *info)
|
2005-02-01 11:26:05 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
keymap->gdkwin32_keymap_impl->init_vk_lookup_table (info);
|
2005-02-01 11:26:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static BYTE
|
|
|
|
keystate_to_modbits (GdkWin32Keymap *keymap,
|
|
|
|
GdkWin32KeymapLayoutInfo *info,
|
|
|
|
const BYTE keystate[256])
|
2005-02-01 11:26:05 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
return keymap->gdkwin32_keymap_impl->keystate_to_modbits (info, keystate);
|
2005-02-01 11:26:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static BYTE
|
|
|
|
modbits_to_level (GdkWin32Keymap *keymap,
|
|
|
|
GdkWin32KeymapLayoutInfo *info,
|
|
|
|
BYTE modbits)
|
2005-02-01 11:26:05 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
return keymap->gdkwin32_keymap_impl->modbits_to_level (info, modbits);
|
2005-02-01 11:26:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static WCHAR
|
|
|
|
vk_to_char_fuzzy (GdkWin32Keymap *keymap,
|
|
|
|
GdkWin32KeymapLayoutInfo *info,
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
BYTE mod_bits,
|
|
|
|
BYTE lock_bits,
|
2022-01-05 14:44:49 +00:00
|
|
|
BYTE *consumed_mod_bits,
|
|
|
|
gboolean *is_dead,
|
|
|
|
BYTE vk)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
return keymap->gdkwin32_keymap_impl->vk_to_char_fuzzy (info, mod_bits, lock_bits,
|
2022-01-05 14:44:49 +00:00
|
|
|
consumed_mod_bits, is_dead, vk);
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
|
|
|
|
2022-01-12 20:41:02 +00:00
|
|
|
/*
|
|
|
|
* Return the keyboard layout according to the user's keyboard layout
|
|
|
|
* substitution preferences.
|
|
|
|
*
|
|
|
|
* The result is heap-allocated and should be freed with g_free().
|
|
|
|
*/
|
|
|
|
static char*
|
|
|
|
get_keyboard_layout_substituted_name (const char *layout_name)
|
|
|
|
{
|
|
|
|
HKEY hkey = 0;
|
|
|
|
DWORD var_type = REG_SZ;
|
|
|
|
char *result = NULL;
|
|
|
|
DWORD buf_len = 0;
|
|
|
|
LSTATUS status;
|
|
|
|
|
|
|
|
static const char *substitute_path = "Keyboard Layout\\Substitutes";
|
|
|
|
|
|
|
|
status = RegOpenKeyExA (HKEY_CURRENT_USER, substitute_path, 0,
|
|
|
|
KEY_QUERY_VALUE, &hkey);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
/* No substitute set for this value, not sure if this is a normal case */
|
|
|
|
g_warning("Could not open registry key '%s'. Error code: %d",
|
|
|
|
substitute_path, (int)status);
|
|
|
|
|
|
|
|
goto fail1;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = RegQueryValueExA (hkey, layout_name, 0, &var_type, 0, &buf_len);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
g_debug("Could not query registry key '%s\\%s'. Error code: %d",
|
|
|
|
substitute_path, layout_name, (int)status);
|
|
|
|
goto fail2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate buffer */
|
|
|
|
result = (char*) g_malloc (buf_len);
|
|
|
|
|
|
|
|
/* Retrieve substitute name */
|
|
|
|
status = RegQueryValueExA (hkey, layout_name, 0, &var_type,
|
|
|
|
(LPBYTE) result, &buf_len);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
g_warning("Could not obtain registry value at key '%s\\%s'. "
|
|
|
|
"Error code: %d",
|
|
|
|
substitute_path, layout_name, (int)status);
|
|
|
|
goto fail3;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hkey);
|
|
|
|
return result;
|
|
|
|
|
|
|
|
fail3:
|
|
|
|
g_free (result);
|
|
|
|
fail2:
|
|
|
|
RegCloseKey (hkey);
|
|
|
|
fail1:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static char*
|
2022-02-27 15:32:59 +00:00
|
|
|
_get_keyboard_layout_file (const char *layout_name)
|
2016-02-26 17:21:26 +00:00
|
|
|
{
|
2022-01-12 20:41:02 +00:00
|
|
|
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;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static const char prefix[] = "SYSTEM\\CurrentControlSet\\Control\\"
|
|
|
|
"Keyboard Layouts\\";
|
|
|
|
char kbdKeyPath[sizeof (prefix) + KL_NAMELENGTH];
|
2016-02-26 17:21:26 +00:00
|
|
|
|
2022-02-27 15:32:59 +00:00
|
|
|
g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s",
|
|
|
|
prefix, layout_name);
|
2022-01-12 20:31:21 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2016-02-26 17:21:26 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Get sizes */
|
2022-01-12 20:31:21 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
dir_len = GetSystemDirectoryA (0, 0); /* includes \0 */
|
|
|
|
if (dir_len == 0)
|
2022-01-12 20:31:21 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Allocate buffer */
|
|
|
|
buf_len = dir_len + (int) strlen ("\\") + file_name_len;
|
|
|
|
result = (char*) g_malloc (buf_len);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* 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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Append file name */
|
2022-01-12 20:31:21 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
}
|
|
|
|
|
2022-02-27 15:32:59 +00:00
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
|
|
|
char *result = _get_keyboard_layout_file (layout_name);
|
|
|
|
|
|
|
|
/* If we could not retrieve a path, it may be that we need to perform layout
|
|
|
|
* substitution
|
|
|
|
*/
|
|
|
|
if (result == NULL)
|
|
|
|
{
|
|
|
|
char *substituted = get_keyboard_layout_substituted_name (layout_name);
|
|
|
|
result = _get_keyboard_layout_file (substituted);
|
|
|
|
g_free (substituted);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
static void
|
2022-01-05 14:44:49 +00:00
|
|
|
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) \
|
2022-01-12 20:19:10 +00:00
|
|
|
map (VK_RMENU, GDK_KEY_Alt_R) \
|
|
|
|
map (VK_CAPITAL, GDK_KEY_Caps_Lock)
|
2022-01-05 14:44:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
#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
|
|
|
|
2005-05-18 14:53:00 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static guint
|
|
|
|
vk_and_mod_bits_to_gdk_keysym (GdkWin32Keymap *keymap,
|
|
|
|
GdkWin32KeymapLayoutInfo *info,
|
|
|
|
guint vk,
|
|
|
|
BYTE mod_bits,
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
BYTE lock_bits,
|
2022-01-05 14:44:49 +00:00
|
|
|
BYTE *consumed_mod_bits)
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
{
|
|
|
|
gboolean is_dead = FALSE;
|
|
|
|
gunichar c;
|
|
|
|
guint sym;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (consumed_mod_bits)
|
|
|
|
*consumed_mod_bits = 0;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* 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;
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Handle other special keys */
|
|
|
|
switch (vk)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
#define MAP(a_vk, a_gdk) case a_vk: return a_gdk;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
DEFINE_SPECIAL (MAP)
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* 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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
#undef MAP
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Handle regular keys (including dead keys) */
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
c = vk_to_char_fuzzy (keymap, info, mod_bits, lock_bits,
|
2022-01-05 14:44:49 +00:00
|
|
|
consumed_mod_bits, &is_dead, vk);
|
2005-02-01 11:26:05 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (c == WCH_NONE)
|
|
|
|
return GDK_KEY_VoidSymbol;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
sym = gdk_unicode_to_keyval (c);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (is_dead)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
switch (sym)
|
|
|
|
{
|
|
|
|
#define MAP(a_nondead, a_dead) case a_nondead: return a_dead;
|
|
|
|
DEFINE_DEAD (MAP)
|
|
|
|
#undef MAP
|
|
|
|
}
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
return sym;
|
|
|
|
}
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
static int
|
|
|
|
gdk_keysym_to_key_entry_index (GdkWin32KeymapLayoutInfo *info,
|
|
|
|
guint sym)
|
|
|
|
{
|
|
|
|
gunichar c;
|
|
|
|
gintptr index;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-12 20:31:21 +00:00
|
|
|
if (info->reverse_lookup_table == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Special cases */
|
|
|
|
if (sym == GDK_KEY_Tab)
|
|
|
|
return VK_TAB;
|
|
|
|
if (sym == GDK_KEY_ISO_Left_Tab)
|
|
|
|
return 256;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Generic non-printable keys */
|
|
|
|
switch (sym)
|
|
|
|
{
|
|
|
|
#define MAP(a_vk, a_gdk) case a_gdk: return a_vk;
|
|
|
|
DEFINE_SPECIAL (MAP)
|
|
|
|
#undef MAP
|
|
|
|
}
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Fix up dead keys */
|
|
|
|
#define MAP(a_nondead, a_dead) \
|
|
|
|
if (sym == a_dead) \
|
|
|
|
sym = a_nondead;
|
|
|
|
DEFINE_DEAD (MAP)
|
|
|
|
#undef MAP
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Try converting to Unicode and back */
|
|
|
|
c = gdk_keyval_to_unicode (sym);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
}
|
2022-01-05 14:44:49 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
}
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-12 20:31:21 +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
|
|
|
{
|
2022-01-05 14:44:49 +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
|
|
|
}
|
2022-01-12 20:31:21 +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
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
}
|
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
guint8
|
|
|
|
_gdk_win32_keymap_get_rshift_scancode (GdkWin32Keymap *keymap)
|
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
return MapVirtualKey (VK_RSHIFT, MAPVK_VK_TO_VSC);
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
|
|
|
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;
|
2015-04-29 07:31:08 +00:00
|
|
|
}
|
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
|
|
|
|
2001-06-22 14:08:51 +00:00
|
|
|
GdkKeymap*
|
2011-01-02 10:51:25 +00:00
|
|
|
_gdk_win32_display_get_keymap (GdkDisplay *display)
|
2001-06-22 14:08:51 +00:00
|
|
|
{
|
2002-06-20 23:59:27 +00:00
|
|
|
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
|
|
|
|
2001-06-22 14:08:51 +00:00
|
|
|
if (default_keymap == NULL)
|
2011-01-02 10:51:25 +00:00
|
|
|
default_keymap = g_object_new (gdk_win32_keymap_get_type (), NULL);
|
2001-06-22 14:08:51 +00:00
|
|
|
|
|
|
|
return default_keymap;
|
|
|
|
}
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static PangoDirection
|
2016-07-13 11:41:35 +00:00
|
|
|
get_hkl_direction (HKL hkl)
|
2001-06-22 14:08:51 +00:00
|
|
|
{
|
2016-07-13 11:41:35 +00:00
|
|
|
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:
|
2002-02-27 16:37:04 +00:00
|
|
|
#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:
|
2002-02-27 16:37:04 +00:00
|
|
|
#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;
|
|
|
|
}
|
2001-06-22 14:08:51 +00:00
|
|
|
}
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
static PangoDirection
|
|
|
|
gdk_win32_keymap_get_direction (GdkKeymap *gdk_keymap)
|
|
|
|
{
|
|
|
|
GdkWin32Keymap *keymap;
|
2022-01-05 14:44:49 +00:00
|
|
|
HKL active_hkl;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), PANGO_DIRECTION_LTR);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
update_keymap (keymap);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
|
|
|
if (keymap->layout_handles->len <= 0)
|
|
|
|
active_hkl = GetKeyboardLayout (0);
|
|
|
|
else
|
2022-01-05 14:44:49 +00:00
|
|
|
active_hkl = g_array_index (keymap->layout_handles, HKL,
|
|
|
|
keymap->active_layout);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
|
|
|
return get_hkl_direction (active_hkl);
|
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static gboolean
|
2016-07-13 11:41:35 +00:00
|
|
|
gdk_win32_keymap_have_bidi_layouts (GdkKeymap *gdk_keymap)
|
2007-07-03 16:53:17 +00:00
|
|
|
{
|
2016-07-13 11:41:35 +00:00
|
|
|
GdkWin32Keymap *keymap;
|
|
|
|
gboolean have_rtl = FALSE;
|
|
|
|
gboolean have_ltr = FALSE;
|
2020-07-24 13:54:49 +00:00
|
|
|
int group;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
|
|
|
|
|
|
|
|
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
update_keymap (keymap);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
|
|
|
for (group = 0; group < keymap->layout_handles->len; group++)
|
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
if (get_hkl_direction (g_array_index (keymap->layout_handles, HKL,
|
|
|
|
group)) == PANGO_DIRECTION_RTL)
|
2016-07-13 11:41:35 +00:00
|
|
|
have_rtl = TRUE;
|
|
|
|
else
|
|
|
|
have_ltr = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return have_ltr && have_rtl;
|
2007-07-03 16:53:17 +00:00
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static gboolean
|
|
|
|
gdk_win32_keymap_get_caps_lock_state (GdkKeymap *keymap)
|
2008-10-01 11:02:22 +00:00
|
|
|
{
|
2016-07-13 11:41:35 +00:00
|
|
|
(void) keymap;
|
|
|
|
|
2008-10-01 11:02:22 +00:00
|
|
|
return ((GetKeyState (VK_CAPITAL) & 1) != 0);
|
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static gboolean
|
|
|
|
gdk_win32_keymap_get_num_lock_state (GdkKeymap *keymap)
|
2010-07-01 22:45:06 +00:00
|
|
|
{
|
2016-07-13 11:41:35 +00:00
|
|
|
(void) keymap;
|
|
|
|
|
2010-07-01 22:45:06 +00:00
|
|
|
return ((GetKeyState (VK_NUMLOCK) & 1) != 0);
|
|
|
|
}
|
|
|
|
|
2015-04-14 11:25:38 +00:00
|
|
|
static gboolean
|
|
|
|
gdk_win32_keymap_get_scroll_lock_state (GdkKeymap *keymap)
|
|
|
|
{
|
2016-07-13 11:41:35 +00:00
|
|
|
(void) keymap;
|
|
|
|
|
2015-04-14 11:25:38 +00:00
|
|
|
return ((GetKeyState (VK_SCROLL) & 1) != 0);
|
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static gboolean
|
2016-07-13 11:41:35 +00:00
|
|
|
gdk_win32_keymap_get_entries_for_keyval (GdkKeymap *gdk_keymap,
|
|
|
|
guint keyval,
|
2020-04-30 04:33:06 +00:00
|
|
|
GArray *retval)
|
2000-12-14 23:14:18 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
GdkWin32Keymap *keymap;
|
|
|
|
int group;
|
|
|
|
guint len = retval->len;
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
|
2000-12-14 23:14:18 +00:00
|
|
|
g_return_val_if_fail (keyval != 0, FALSE);
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
update_keymap (keymap);
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
while (entry_index >= 0)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
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)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
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,
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
modbits, 0, NULL);
|
2022-01-05 14:44:49 +00:00
|
|
|
if (sym == keyval || sym == GDK_KEY_VoidSymbol)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
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);
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
|
|
|
}
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
entry_index = entry->next;
|
2016-07-13 11:41:35 +00:00
|
|
|
}
|
2022-01-05 14:44:49 +00:00
|
|
|
}
|
Remove the event_mask, it is now in GdkWindowObject.
2002-03-01 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.h (struct _GdkWindowImplWin32): Remove
the event_mask, it is now in GdkWindowObject.
* gdk/win32/gdkwindow-win32.c: Change accordingly. Set the
GDK_STRUCTURE_MASK in gdk_window_set_events(), as it is always set
in gdk_window_new(), too. (Bug#72921)
* gdk/win32/gdkevents-win32.c: Change accordingly here, too.
(vk_from_char): New function, calculates the virtual keycode
corresponding to the char in a WM_CHAR message.
(build_keypress_event, build_keyrelease_event): Use it.
(build_keypress_event): Call ImmReleaseContext() after using the
input context. This might plug a memory or resource leak.
(build_key_event_state): Remove #if 0 code.
(gdk_event_translate): Actually, it would be preferrable to always
handle just the WM_KEYDOWN and WM_KEYUP messages, not WM_CHAR at
all, and thus drop the contorted logic with ignore_wm_char etc.
* gdk/win32/gdkkeys-win32.c: (gdk_keymap_get_entries_for_keyval):
Debugging output.
(gdk_keymap_translate_keyboard_state): Return correct value. (But
_gtk_key_hash_lookup() doesn't check the return value...)
2002-02-28 23:38:55 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
return retval->len > len;
|
2000-12-14 23:14:18 +00:00
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static gboolean
|
2016-07-13 11:41:35 +00:00
|
|
|
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)
|
2000-12-14 23:14:18 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
GdkWin32Keymap *keymap;
|
2016-07-13 11:41:35 +00:00
|
|
|
GArray *key_array;
|
|
|
|
GArray *keyval_array;
|
2020-07-24 13:54:49 +00:00
|
|
|
int group;
|
2022-01-05 14:44:49 +00:00
|
|
|
BYTE vk;
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
|
2000-12-14 23:14:18 +00:00
|
|
|
g_return_val_if_fail (n_entries != NULL, FALSE);
|
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
*n_entries = 0;
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (keys != NULL)
|
2000-12-14 23:14:18 +00:00
|
|
|
key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
|
|
|
else
|
|
|
|
key_array = NULL;
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (keyvals != NULL)
|
2000-12-14 23:14:18 +00:00
|
|
|
keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
|
|
|
|
else
|
|
|
|
keyval_array = NULL;
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2016-07-13 11:41:35 +00:00
|
|
|
for (group = 0; group < keymap->layout_handles->len; group++)
|
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
for (level = 0; level <= info->max_level; ++level)
|
2016-07-13 11:41:35 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
BYTE modbits = info->level_to_modbits[level];
|
|
|
|
BYTE consumed_modbits = 0;
|
|
|
|
GdkKeymapKey key = {0};
|
|
|
|
guint keyval;
|
2015-04-29 07:31:08 +00:00
|
|
|
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (keyval == GDK_KEY_VoidSymbol || consumed_modbits != modbits)
|
|
|
|
continue;
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
key.keycode = vk;
|
|
|
|
key.group = group;
|
|
|
|
key.level = level;
|
2016-07-13 11:41:35 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (key_array)
|
|
|
|
g_array_append_val (key_array, key);
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (keyval_array)
|
|
|
|
g_array_append_val (keyval_array, keyval);
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
++(*n_entries);
|
|
|
|
}
|
2000-12-14 23:14:18 +00:00
|
|
|
}
|
2022-01-05 14:44:49 +00:00
|
|
|
|
|
|
|
if (keys != NULL)
|
|
|
|
*keys = (GdkKeymapKey*) g_array_free (key_array, FALSE);
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
if (keyvals != NULL)
|
|
|
|
*keyvals = (guint*) g_array_free (keyval_array, FALSE);
|
2000-12-14 23:14:18 +00:00
|
|
|
|
|
|
|
return *n_entries > 0;
|
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static guint
|
2016-07-13 11:41:35 +00:00
|
|
|
gdk_win32_keymap_lookup_key (GdkKeymap *gdk_keymap,
|
|
|
|
const GdkKeymapKey *key)
|
2000-12-14 23:14:18 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
BYTE modbits;
|
|
|
|
guint sym;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), 0);
|
2000-12-14 23:14:18 +00:00
|
|
|
g_return_val_if_fail (key != NULL, 0);
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
|
|
|
|
update_keymap (keymap);
|
2000-12-14 23:14:18 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
info = &g_array_index (keymap->layout_infos, GdkWin32KeymapLayoutInfo, key->group);
|
2015-04-29 07:31:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
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;
|
2022-01-05 14:44:49 +00:00
|
|
|
if (key->level < 0 || key->level > info->max_level)
|
|
|
|
return 0;
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
modbits = info->level_to_modbits[key->level];
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
sym = vk_and_mod_bits_to_gdk_keysym (keymap, info, key->keycode, modbits, 0, NULL);
|
2015-04-29 07:31:08 +00:00
|
|
|
|
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;
|
2000-12-14 23:14:18 +00:00
|
|
|
}
|
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
static gboolean
|
2016-07-13 11:41:35 +00:00
|
|
|
gdk_win32_keymap_translate_keyboard_state (GdkKeymap *gdk_keymap,
|
|
|
|
guint hardware_keycode,
|
|
|
|
GdkModifierType state,
|
2020-07-24 13:54:49 +00:00
|
|
|
int group,
|
2016-07-13 11:41:35 +00:00
|
|
|
guint *keyval,
|
2020-07-24 13:54:49 +00:00
|
|
|
int *effective_group,
|
|
|
|
int *level,
|
2016-07-13 11:41:35 +00:00
|
|
|
GdkModifierType *consumed_modifiers)
|
2000-12-14 23:14:18 +00:00
|
|
|
{
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
GdkWin32KeymapLayoutInfo *layout_info;
|
|
|
|
guint vk;
|
|
|
|
BYTE mod_bits;
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +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
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
g_return_val_if_fail (group >= 0 && group < keymap->layout_infos->len, FALSE);
|
2004-04-10 08:43:36 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
layout_info = &g_array_index (keymap->layout_infos, GdkWin32KeymapLayoutInfo,
|
|
|
|
group);
|
2004-04-10 08:43:36 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
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
|
|
|
|
2022-01-05 14:44:49 +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;
|
2002-03-06 00:36:08 +00:00
|
|
|
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +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;
|
2002-03-06 00:36:08 +00:00
|
|
|
|
gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.
However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).
So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).
[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 20:17:28 +00:00
|
|
|
tmp_keyval = vk_and_mod_bits_to_gdk_keysym (keymap, layout_info, vk, mod_bits,
|
|
|
|
lock_bits, &consumed_mod_bits);
|
2022-01-05 14:44:49 +00:00
|
|
|
tmp_effective_group = group;
|
|
|
|
tmp_level = modbits_to_level (keymap, layout_info, consumed_mod_bits);
|
2002-03-06 00:36:08 +00:00
|
|
|
|
2022-01-05 14:44:49 +00:00
|
|
|
/* Determine consumed modifiers */
|
|
|
|
|
2005-01-19 22:48:30 +00:00
|
|
|
if (keyval)
|
|
|
|
*keyval = tmp_keyval;
|
|
|
|
if (effective_group)
|
2022-01-05 14:44:49 +00:00
|
|
|
*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)
|
2022-01-05 14:44:49 +00:00
|
|
|
*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)
|
2022-01-05 14:44:49 +00:00
|
|
|
*consumed_modifiers = mod_bits_to_gdk_mod_mask (consumed_mod_bits);
|
2002-03-06 00:36:08 +00:00
|
|
|
|
2022-01-12 20:31:21 +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;
|
2000-12-14 23:14:18 +00:00
|
|
|
}
|
2009-12-21 20:42:55 +00:00
|
|
|
|
2011-01-02 10:51:25 +00:00
|
|
|
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;
|
2015-04-14 11:25:38 +00:00
|
|
|
keymap_class->get_scroll_lock_state = gdk_win32_keymap_get_scroll_lock_state;
|
2011-01-02 10:51:25 +00:00
|
|
|
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;
|
|
|
|
}
|