Instead of performing keyboard layout substitution whenever we find a matching
entry in the registry, first try to load the original layout and only attempt
substitution when that fails.
See #4724
For some users, GetKeyboardLayoutNameA() returns an alias instead of the
fully resolved keyboard layout identifier. In that case, we have to
query the registry to resolve the alias before we can look up the DLL
path.
See comments under #4610
Contrary to what you can read on the internet, SGCAPS keys don't work
by having capslock toggle the KBDCTRL bit, they actually have two
consecutive table entries, the first of which is for the normal
version and the second of which is for the capslocked version.
Background: SGCAPS is short for Swiss German caps because Swiss German
was the first layout to use this feature. For keys with the SGCAPS flag,
capslock has a different effect than pressing shift. For example:
Shift + ü = è, CapsLock + ü = Ü, CapsLock + Shift + ü = È
DLL loading failures should not happen under normal circumstances, but
we should at least try not to crash and and print better diagnostic
messages if they do happen.
See #4610
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
gdk_win32_keymap_get_entries_for_keycode() did not initialize n_entries,
which led to a wrong number of items being returned in some cases.
/fixes #4610
Windows keymaps contain some bogus mappings, e.g. Ctrl+Backspace=Delete.
Previously, we correctly identified the key as Backspace, but the Ctrl
was still consumed, so the Ctrl+Backspace keybinding did not work.
gdk_win32_keymap_translate_keyboard_state erroneously used the active
group rather than the specified group, which caused shortcuts not to
work in Inkscape when using a Cyrillic layout.
This consolidates the check for the running CPU in one single location,
to make things a bit cleaner, as:
* We can make use of IsWow64Process2(), if available, to check both
whether we are running on an ARM64 CPU, and whether we are running as
a WOW64 process. This is also the function to use to properly check
whether we are running as a WOW64 process on ARM64 systems, as
IsWow64Process() does not work as we want on ARM64 systems.
* If we don't have IsWow64Process2() (which is absent from Windows prior
to Windows 10 1511, where ARM64 Windows is introduced), we can fall
back to IsWow64Process(), which will tell us whether we are running
as an WOW64 process (but clearly not on an ARM64 system).
Also clean up things a bit so that we can reduce reliance on global
variables.
The old code used repeated calls to `ToUnicodeEx` to populate
the translation table, which is slow and buggy. The new code
directly loads the layout driver DLLs from Windows.
Associated issues: #2055#1033
Merge request: !1051
GdkWin32Keymap cleanup
Conform to C89, improve comments, whitespace
It apparently worked by chance in the past, but now causes e.g.
alphanumeric characters to be interpreted as half-width katakana
when using the Japanese IME.
Instead of using some kind of flawed logic about modifying a keypress result
when CapsLock is toggled, just add a CapsLock shift level (and all derived
shift levels, i.e. Shift+CapsLock and CapsLock+AltGr and Shift+CapsLock+AltGr)
and query Windows keyboard layout API about the result of keypresses involving
CapsLock.
Keysym table is going to be (roughly) twice as large now, but CapsLock'ed
keypresses will give correct results for some keyboard layouts (such as
Czech keyboard layout, which without this change produces lowercase letters
for CapsLock->[0,2,3,4...] instead of uppercase ones).
Keymap update time also increases accordingly.
https://bugzilla.gnome.org/show_bug.cgi?id=165385
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
This changes the group/level semantic.
Previously W32 backend used "group 0/1" to denote "AltGr OFF/ON"
and "level 0/1" to denote "Shift is OFF/ON".
Now "group" means "keyboard layout" and there can be up to 255 groups,
while AltGr and Shift are combined into a single level enum that
takes values between 0 and 4.
Unlike X, W32 doesn't do effective group overriding, meaning that
it will never tell the caller that a different group was actually
used (even for universal keys, such as Enter), because key symbol
table is completely fabricated and there's no point in trying to
save a few of kilobytes of RAM by not duplicating universal key
records for all groups.
Also contains many whitespace changes (tab elimination, fixed
indentation) and cleanup (axed a few global variables, these are
now accessed via the default keymap).
https://bugzilla.gnome.org/show_bug.cgi?id=768722
1f74f12d9 rendered entry of keypad decimal mark unuseable for
several national keyboard layouts, this commit amends that, at
least for W32, and makes GTK+ behave more or less the same way
W32 behaves.
The patch works like this:
- When typing the first character at the keyboard or when switching
keyboard layouts, the decimal mark character will be cached in the
static variable "decimal_mark" within gdkkeys-win32.c
- in case of WIN32, gdk_keyval_to_unicode() asks gdkkeys-win32.c for the
current decimal_mark when converting GDK_KEY_KP_Decimal.
https://bugzilla.gnome.org/show_bug.cgi?id=756751
GdkKeymap already has support for _get_num_lock_state() and
_get_caps_lock_state(). Adding _get_scroll_lock_state() would be good
for completness and some backends (Windows?) could take advantage of
this.
Include config.h first so that _GDK_EXTERN may be defined once
and only once during the build, so that we do not get warnings/
errors for macro redefinition.
https://bugzilla.gnome.org/show_bug.cgi?id=701251
There are sure regressions but basic stuff seems to be working
again after all the API breakage done with comments like
"Win32 and Quartz need to be ported still."
It turns out that my attempt at handling Super, Hyper and Meta better
is causing problems, mostly because Alt and Meta are commonly colocated
in the modmap, and apps do a check for the Alt modifier regularly.
See e.g bug 607697.
2008-10-01 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkkeys-win32.c (gdk_keymap_get_caps_lock_state):
Implement trivially on Windows. Not sure if something more complex
is actually needed, more specifically whether the function needs
to differentiate between "Caps Lock" and "Shift Lock" semantics?
svn path=/trunk/; revision=21558
2008-08-05 Tor Lillqvist <tml@novell.com>
Bug 544684 - Win64 issue, window handles are assumed to be 32-bit
* gdk/win32/gdkcursor-win32.c
* gdk/win32/xcursors.h: Change some gchar* to guchar* and vice
versa to avoid gcc 4.4 signedness warnings.
* gdk/win32/gdkevents-win32.c: Add some guchar and char pointer
casts to get rid of gcc 4.4 signedness warnings. Print GdkAtom
values in debugging output using the %p format.
* gdk/win32/gdkkeys-win32.c
* gdk/win32/gdkfont-win32.c
* gdk/win32/gdkmain-win32.c: Add some casts to avoid gcc warnings.
* gdk/win32/gdkwindow-win32.c: Use SetWindowLongPtr() instead of
SetWindowLong().
* gdk/win32/gdkwin32id.c (gdk_handle_hash): Use all 64 bits of a
HANDLE on Win64.
svn path=/trunk/; revision=20994
2008-07-02 Cody Russell <bratsche@gnome.org>
Bug 541305 – [Win32] Scrolling was broken after GdkWindow refactoring
* gdk/win32/gdkwindow-win32.c: Reverted some logic so that scrolling
works again.
* gdk/win32/gdkgeometry-win32.c: Removed some more unnecessary checks.
* gdk/win32/gdkkeys-win32.c: Removed unused variable to fix compile-time
warnings.
svn path=/trunk/; revision=20737
2007-07-03 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkkeys-win32.c (gdk_keymap_have_bidi_layouts):
Implement. Just return FALSE for now. What should this function
actually do? Does keyboards layouts being "in use" mean that such
layouts can be switched to on the fly? If so we need to actually
check that.
svn path=/trunk/; revision=18359
2006-08-29 Tor Lillqvist <tml@novell.com>
Remove support for Windows 9x/ME. GTK+ hasn't worked on Win9x
since 2.6 or 2.8. It's pointless to keep the Win9x code in here as
it isn't being maintained anyway. If somebody is interested, it
can always be found in older GTK+ versions, and in CVS.
* gdk/win32/gdkcursor-win32.c
* gdk/win32/gdkdnd-win32.c
* gdk/win32/gdkdrawable-win32.c
* gdk/win32/gdkgc-win32.c
* gdk/win32/gdkglobals-win32.c
* gdk/win32/gdkkeys-win32.c
* gdk/win32/gdkmain-win32.c
* gdk/win32/gdkproperty-win32.c
* gdk/win32/gdkselection-win32.c: Remove the G_WIN32_IS_NT_BASED()
and G_WIN32_HAVE_WIDECHAR_API() tests and their false (Win9x)
branches, and any variables or static functions used only by the
Win9x branches.
* gdk/win32/gdkprivate-win32.h: Remove backup definitions for
constants that aren't missing from current mingw and MSVC6
headers.
* gdk/win32/gdkmain-win32.c
* gdk/win32/gdkprivate-win32.h: Remove the _gdk_win32_gdi_failed()
function. On NT-based Windows GetLastError() returns error codes
also for failed GDI calls, so we can use _gdk_win32_api_failed()
always.
2005-05-23 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkkeys-win32.c (handle_dead): If the keysym isn't one
of the special cases this function takes care of, us it as
such. This takes care of for instance the Bengali Virama, see bug
#165723.
2005-05-18 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkevents-win32.c
* gdk/win32/gdkkeys-win32.c
* gdk/win32/gdkprivate-win32.h: Check the KF_EXTENDED bit in
lParam of WM_KEY* messages to distinguish between left and right
Control and Alt keys. Unfortunately, the right Shift key doesnt
set KF_EXTENDED, so to distinguish between left and right Shift
keys, check the scan code. (#304584)
2005-03-16 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkdisplay-win32.c (_win32_on_clipboard_change): Print
debugging output only if asked for, not always.
* gdk/win32/*.c: Use the %+d%+d format for coordinate pairs in
debugging printout instead of +%d+%d. Misc other additions and
cosmetic improvements to debugging printouts. Use API_CALL() and
GDI_CALL() macros in more places.
* gdk/win32/gdkwindow-win32.c (gdk_window_move, gdk_window_resize,
gdk_window_move_resize): To detect child windows, check whether
the real parent is not the desktop window, instead of relying on
the GDK window type being GDK_WINDOW_CHILD. Foreign GtkPlug
windows have a GDK window type GDK_WINDOW_FOREIGN, but are still
de facto child windows.
2005-02-23 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkkeys-win32.c (update_keymap): Workaround for bug in
MapVirtualKey(VK_DIVIDE, 0) in some Windows versions. (#142998)
2005-02-01 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkkeys-win32.c (handle_special, set_shift_vks,
reset_after_dead, handle_dead): New functions, code blocks
refactored out of update_keymap(). No functionality change.
(update_keymap): Use ToUnicodeEx() when available (on NT-based
Windows) instead of ToAsciiEx(). Makes keyboard input work in
Unicode-only input locales that don't have any ANSI codepage, for
instance Hindi and Bengali. Use _gdk_input_codepage only on
Win9x. (#165723)
* gdk/win32/gdkevents-win32.c (gdk_event_translate): On
WM_INPUTLANGCHANGE, use GetLocaleInfo() instead of
TranslateCharsetInfo() to get the input locale's corresponding
codepage, if any.
2005-01-23 Tor Lillqvist <tml@novell.com>
* gdk/win32/gdkkeys-win32.c (update_keymap): Handle Greek tonos
dead accent key. (#164859, reported and fix verified by Daniel
Atallah.)
* gtk/gtkimcontextsimple.c (gtk_compose_seqs): Handle
GDK_Greek_accentdieresis (tonos and dialytika) combining with iota
and upsilon.