Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d64ea8e4
Commit
d64ea8e4
authored
Nov 21, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Nov 30, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winewayland.drv: Enumerate Xkb layouts and create matching HKL.
parent
e8c96e2e
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
356 additions
and
6 deletions
+356
-6
configure
configure
+89
-1
configure.ac
configure.ac
+4
-1
Makefile.in
dlls/winewayland.drv/Makefile.in
+2
-2
wayland_keyboard.c
dlls/winewayland.drv/wayland_keyboard.c
+257
-2
waylanddrv.h
dlls/winewayland.drv/waylanddrv.h
+1
-0
config.h.in
include/config.h.in
+3
-0
No files found.
configure
View file @
d64ea8e4
...
...
@@ -702,6 +702,8 @@ INOTIFY_LIBS
INOTIFY_CFLAGS
PCSCLITE_LIBS
PCAP_LIBS
XKBREGISTRY_LIBS
XKBREGISTRY_CFLAGS
XKBCOMMON_LIBS
XKBCOMMON_CFLAGS
WAYLAND_SCANNER
...
...
@@ -1797,6 +1799,8 @@ WAYLAND_CLIENT_CFLAGS
WAYLAND_CLIENT_LIBS
XKBCOMMON_CFLAGS
XKBCOMMON_LIBS
XKBREGISTRY_CFLAGS
XKBREGISTRY_LIBS
INOTIFY_CFLAGS
INOTIFY_LIBS
DBUS_CFLAGS
...
...
@@ -2620,6 +2624,10 @@ Some influential environment variables:
C compiler flags for xkbcommon, overriding pkg-config
XKBCOMMON_LIBS
Linker flags for xkbcommon, overriding pkg-config
XKBREGISTRY_CFLAGS
C compiler flags for xkbregistry, overriding pkg-config
XKBREGISTRY_LIBS
Linker flags for xkbregistry, overriding pkg-config
INOTIFY_CFLAGS
C compiler flags for libinotify, overriding pkg-config
INOTIFY_LIBS
...
...
@@ -15956,8 +15964,86 @@ fi
CPPFLAGS
=
$ac_save_CPPFLAGS
rm
-f
conftest.err
if
${
XKBREGISTRY_CFLAGS
:+false
}
:
then
:
if
test
${
PKG_CONFIG
+y
}
then
:
XKBREGISTRY_CFLAGS
=
`
$PKG_CONFIG
--cflags
xkbregistry 2>conftest.err
`
fi
fi
if
${
XKBREGISTRY_LIBS
:+false
}
:
then
:
if
test
${
PKG_CONFIG
+y
}
then
:
XKBREGISTRY_LIBS
=
`
$PKG_CONFIG
--libs
xkbregistry 2>/dev/null
`
fi
fi
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: xkbregistry cflags:
$XKBREGISTRY_CFLAGS
"
>
&5
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: xkbregistry libs:
$XKBREGISTRY_LIBS
"
>
&5
if
test
-s
conftest.err
;
then
printf
%s
"
$as_me
:
${
as_lineno
-
$LINENO
}
: xkbregistry errors: "
>
&5
cat
conftest.err
>
&5
fi
rm
-f
conftest.err
ac_save_CPPFLAGS
=
$CPPFLAGS
CPPFLAGS
=
"
$CPPFLAGS
$XKBREGISTRY_CFLAGS
"
ac_fn_c_check_header_compile
"
$LINENO
"
"xkbcommon/xkbregistry.h"
"ac_cv_header_xkbcommon_xkbregistry_h"
"
$ac_includes_default
"
if
test
"x
$ac_cv_header_xkbcommon_xkbregistry_h
"
=
xyes
then
:
printf
"%s
\n
"
"#define HAVE_XKBCOMMON_XKBREGISTRY_H 1"
>>
confdefs.h
fi
{
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking for rxkb_context_new in -lxkbregistry"
>
&5
printf
%s
"checking for rxkb_context_new in -lxkbregistry... "
>
&6
;
}
if
test
${
ac_cv_lib_xkbregistry_rxkb_context_new
+y
}
then
:
printf
%s
"(cached) "
>
&6
else
$as_nop
ac_check_lib_save_LIBS
=
$LIBS
LIBS
=
"-lxkbregistry
$XKBREGISTRY_LIBS
$LIBS
"
cat
confdefs.h -
<<
_ACEOF
>conftest.
$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char rxkb_context_new ();
int
main (void)
{
return rxkb_context_new ();
;
return 0;
}
_ACEOF
if
ac_fn_c_try_link
"
$LINENO
"
then
:
ac_cv_lib_xkbregistry_rxkb_context_new
=
yes
else
$as_nop
ac_cv_lib_xkbregistry_rxkb_context_new
=
no
fi
rm
-f
core conftest.err conftest.
$ac_objext
conftest.beam
\
conftest
$ac_exeext
conftest.
$ac_ext
LIBS
=
$ac_check_lib_save_LIBS
fi
{
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: result:
$ac_cv_lib_xkbregistry_rxkb_context_new
"
>
&5
printf
"%s
\n
"
"
$ac_cv_lib_xkbregistry_rxkb_context_new
"
>
&6
;
}
if
test
"x
$ac_cv_lib_xkbregistry_rxkb_context_new
"
=
xyes
then
:
:
else
$as_nop
XKBREGISTRY_LIBS
=
""
fi
CPPFLAGS
=
$ac_save_CPPFLAGS
fi
if
test
-z
"
$WAYLAND_CLIENT_LIBS
"
-o
-z
"
$WAYLAND_SCANNER
"
-o
-z
"
$XKBCOMMON_LIBS
"
-o
"
$ac_cv_header_linux_input_h
"
=
"no"
if
test
-z
"
$WAYLAND_CLIENT_LIBS
"
-o
-z
"
$WAYLAND_SCANNER
"
-o
-z
"
$XKBCOMMON_LIBS
"
-o
-z
"
$XKBREGISTRY_LIBS
"
-o
"
$ac_cv_header_linux_input_h
"
=
"no"
then
:
case
"x
$with_wayland
"
in
x
)
as_fn_append wine_notices
"|Wayland
${
notice_platform
}
development files not found, the Wayland driver won't be supported."
;;
...
...
@@ -23545,6 +23631,8 @@ WAYLAND_CLIENT_LIBS = $WAYLAND_CLIENT_LIBS
WAYLAND_SCANNER =
$WAYLAND_SCANNER
XKBCOMMON_CFLAGS =
$XKBCOMMON_CFLAGS
XKBCOMMON_LIBS =
$XKBCOMMON_LIBS
XKBREGISTRY_CFLAGS =
$XKBREGISTRY_CFLAGS
XKBREGISTRY_LIBS =
$XKBREGISTRY_LIBS
PCAP_LIBS =
$PCAP_LIBS
PCSCLITE_LIBS =
$PCSCLITE_LIBS
INOTIFY_CFLAGS =
$INOTIFY_CFLAGS
...
...
configure.ac
View file @
d64ea8e4
...
...
@@ -1380,8 +1380,11 @@ then
WINE_PACKAGE_FLAGS(XKBCOMMON,[xkbcommon],,,,
[AC_CHECK_HEADERS([xkbcommon/xkbcommon.h])
AC_CHECK_LIB(xkbcommon,xkb_context_new,[:],[XKBCOMMON_LIBS=""],[$XKBCOMMON_LIBS])])
WINE_PACKAGE_FLAGS(XKBREGISTRY,[xkbregistry],,,,
[AC_CHECK_HEADERS([xkbcommon/xkbregistry.h])
AC_CHECK_LIB(xkbregistry,rxkb_context_new,[:],[XKBREGISTRY_LIBS=""],[$XKBREGISTRY_LIBS])])
fi
WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o -z "$XKBCOMMON_LIBS" -o "$ac_cv_header_linux_input_h" = "no"],
WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o -z "$XKBCOMMON_LIBS" -o
-z "$XKBREGISTRY_LIBS" -o
"$ac_cv_header_linux_input_h" = "no"],
[Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.],
[enable_winewayland_drv])
...
...
dlls/winewayland.drv/Makefile.in
View file @
d64ea8e4
MODULE
=
winewayland.drv
UNIXLIB
=
winewayland.so
UNIX_CFLAGS
=
$(WAYLAND_CLIENT_CFLAGS)
$(XKBCOMMON_CFLAGS)
UNIX_LIBS
=
-lwin32u
$(WAYLAND_CLIENT_LIBS)
$(XKBCOMMON_LIBS)
$(PTHREAD_LIBS)
-lm
UNIX_CFLAGS
=
$(WAYLAND_CLIENT_CFLAGS)
$(XKBCOMMON_CFLAGS)
$(XKBREGISTRY_CFLAGS)
UNIX_LIBS
=
-lwin32u
$(WAYLAND_CLIENT_LIBS)
$(XKBCOMMON_LIBS)
$(
XKBREGISTRY_LIBS)
$(
PTHREAD_LIBS)
-lm
SOURCES
=
\
display.c
\
...
...
dlls/winewayland.drv/wayland_keyboard.c
View file @
d64ea8e4
...
...
@@ -24,6 +24,7 @@
#endif
#include "config.h"
#include <stdlib.h>
#include <linux/input.h>
#undef SW_MAX
/* Also defined in winuser.rh */
...
...
@@ -36,6 +37,23 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
keyboard
);
WINE_DECLARE_DEBUG_CHANNEL
(
key
);
struct
layout
{
struct
list
entry
;
char
*
xkb_layout
;
int
xkb_group
;
LANGID
lang
;
WORD
index
;
/* "Layout Id", used by NtUserGetKeyboardLayoutName / LoadKeyboardLayoutW */
WORD
layout_id
;
};
/* These are only used from the wayland event thread and don't need locking */
static
struct
list
xkb_layouts
=
LIST_INIT
(
xkb_layouts
);
static
struct
rxkb_context
*
rxkb_context
;
static
HKL
keyboard_hkl
;
/* the HKL matching the currently active xkb group */
static
WORD
key2scan
(
UINT
key
)
{
/* base keys can be mapped directly */
...
...
@@ -122,6 +140,198 @@ static WORD key2scan(UINT key)
return
0x200
|
(
key
&
0x7f
);
}
static
inline
LANGID
langid_from_xkb_layout
(
const
char
*
layout
,
size_t
layout_len
)
{
#define MAKEINDEX(c0, c1) (MAKEWORD(c0, c1) - MAKEWORD('a', 'a'))
static
const
LANGID
langids
[]
=
{
[
MAKEINDEX
(
'a'
,
'f'
)]
=
MAKELANGID
(
LANG_DARI
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'a'
,
'l'
)]
=
MAKELANGID
(
LANG_ALBANIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'a'
,
'm'
)]
=
MAKELANGID
(
LANG_ARMENIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'a'
,
't'
)]
=
MAKELANGID
(
LANG_GERMAN
,
SUBLANG_GERMAN_AUSTRIAN
),
[
MAKEINDEX
(
'a'
,
'z'
)]
=
MAKELANGID
(
LANG_AZERBAIJANI
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'a'
,
'u'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_AUS
),
[
MAKEINDEX
(
'b'
,
'a'
)]
=
MAKELANGID
(
LANG_BOSNIAN
,
SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
),
[
MAKEINDEX
(
'b'
,
'd'
)]
=
MAKELANGID
(
LANG_BANGLA
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'b'
,
'e'
)]
=
MAKELANGID
(
LANG_FRENCH
,
SUBLANG_FRENCH_BELGIAN
),
[
MAKEINDEX
(
'b'
,
'g'
)]
=
MAKELANGID
(
LANG_BULGARIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'b'
,
'r'
)]
=
MAKELANGID
(
LANG_PORTUGUESE
,
2
),
[
MAKEINDEX
(
'b'
,
't'
)]
=
MAKELANGID
(
LANG_TIBETAN
,
3
),
[
MAKEINDEX
(
'b'
,
'w'
)]
=
MAKELANGID
(
LANG_TSWANA
,
SUBLANG_TSWANA_BOTSWANA
),
[
MAKEINDEX
(
'b'
,
'y'
)]
=
MAKELANGID
(
LANG_BELARUSIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'c'
,
'a'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_CAN
),
[
MAKEINDEX
(
'c'
,
'd'
)]
=
MAKELANGID
(
LANG_FRENCH
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
'c'
,
'h'
)]
=
MAKELANGID
(
LANG_GERMAN
,
SUBLANG_GERMAN_SWISS
),
[
MAKEINDEX
(
'c'
,
'm'
)]
=
MAKELANGID
(
LANG_FRENCH
,
11
),
[
MAKEINDEX
(
'c'
,
'n'
)]
=
MAKELANGID
(
LANG_CHINESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'c'
,
'z'
)]
=
MAKELANGID
(
LANG_CZECH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'd'
,
'e'
)]
=
MAKELANGID
(
LANG_GERMAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'd'
,
'k'
)]
=
MAKELANGID
(
LANG_DANISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'd'
,
'z'
)]
=
MAKELANGID
(
LANG_TAMAZIGHT
,
SUBLANG_TAMAZIGHT_ALGERIA_LATIN
),
[
MAKEINDEX
(
'e'
,
'e'
)]
=
MAKELANGID
(
LANG_ESTONIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'e'
,
's'
)]
=
MAKELANGID
(
LANG_SPANISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'e'
,
't'
)]
=
MAKELANGID
(
LANG_AMHARIC
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'f'
,
'i'
)]
=
MAKELANGID
(
LANG_FINNISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'f'
,
'o'
)]
=
MAKELANGID
(
LANG_FAEROESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'f'
,
'r'
)]
=
MAKELANGID
(
LANG_FRENCH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'g'
,
'b'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_UK
),
[
MAKEINDEX
(
'g'
,
'e'
)]
=
MAKELANGID
(
LANG_GEORGIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'g'
,
'h'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
'g'
,
'n'
)]
=
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_CUSTOM_DEFAULT
),
[
MAKEINDEX
(
'g'
,
'r'
)]
=
MAKELANGID
(
LANG_GREEK
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'h'
,
'r'
)]
=
MAKELANGID
(
LANG_CROATIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'h'
,
'u'
)]
=
MAKELANGID
(
LANG_HUNGARIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'i'
,
'd'
)]
=
MAKELANGID
(
LANG_INDONESIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'i'
,
'e'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_EIRE
),
[
MAKEINDEX
(
'i'
,
'l'
)]
=
MAKELANGID
(
LANG_HEBREW
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'i'
,
'n'
)]
=
MAKELANGID
(
LANG_HINDI
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'i'
,
'q'
)]
=
MAKELANGID
(
LANG_ARABIC
,
SUBLANG_ARABIC_IRAQ
),
[
MAKEINDEX
(
'i'
,
'r'
)]
=
MAKELANGID
(
LANG_PERSIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'i'
,
's'
)]
=
MAKELANGID
(
LANG_ICELANDIC
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'i'
,
't'
)]
=
MAKELANGID
(
LANG_ITALIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'j'
,
'p'
)]
=
MAKELANGID
(
LANG_JAPANESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'k'
,
'e'
)]
=
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_CUSTOM_DEFAULT
),
[
MAKEINDEX
(
'k'
,
'g'
)]
=
MAKELANGID
(
LANG_KYRGYZ
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'k'
,
'h'
)]
=
MAKELANGID
(
LANG_KHMER
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'k'
,
'r'
)]
=
MAKELANGID
(
LANG_KOREAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'k'
,
'z'
)]
=
MAKELANGID
(
LANG_KAZAK
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'l'
,
'a'
)]
=
MAKELANGID
(
LANG_LAO
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'l'
,
'k'
)]
=
MAKELANGID
(
LANG_SINHALESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'l'
,
't'
)]
=
MAKELANGID
(
LANG_LITHUANIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'l'
,
'v'
)]
=
MAKELANGID
(
LANG_LATVIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'm'
,
'a'
)]
=
MAKELANGID
(
LANG_ARABIC
,
SUBLANG_ARABIC_MOROCCO
),
[
MAKEINDEX
(
'm'
,
'd'
)]
=
MAKELANGID
(
LANG_ROMANIAN
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
'm'
,
'e'
)]
=
MAKELANGID
(
LANG_SERBIAN
,
SUBLANG_SERBIAN_MONTENEGRO_LATIN
),
[
MAKEINDEX
(
'm'
,
'k'
)]
=
MAKELANGID
(
LANG_MACEDONIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'm'
,
'l'
)]
=
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_CUSTOM_DEFAULT
),
[
MAKEINDEX
(
'm'
,
'm'
)]
=
MAKELANGID
(
0x55
/*LANG_BURMESE*/
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'm'
,
'n'
)]
=
MAKELANGID
(
LANG_MONGOLIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'm'
,
't'
)]
=
MAKELANGID
(
LANG_MALTESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'm'
,
'v'
)]
=
MAKELANGID
(
LANG_DIVEHI
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'm'
,
'y'
)]
=
MAKELANGID
(
LANG_MALAY
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'n'
,
'g'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
'n'
,
'l'
)]
=
MAKELANGID
(
LANG_DUTCH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'n'
,
'o'
)]
=
MAKELANGID
(
LANG_NORWEGIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'n'
,
'p'
)]
=
MAKELANGID
(
LANG_NEPALI
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'p'
,
'h'
)]
=
MAKELANGID
(
LANG_FILIPINO
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'p'
,
'k'
)]
=
MAKELANGID
(
LANG_URDU
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'p'
,
'l'
)]
=
MAKELANGID
(
LANG_POLISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'p'
,
't'
)]
=
MAKELANGID
(
LANG_PORTUGUESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'r'
,
'o'
)]
=
MAKELANGID
(
LANG_ROMANIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'r'
,
's'
)]
=
MAKELANGID
(
LANG_SERBIAN
,
SUBLANG_SERBIAN_LATIN
),
[
MAKEINDEX
(
'r'
,
'u'
)]
=
MAKELANGID
(
LANG_RUSSIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
's'
,
'e'
)]
=
MAKELANGID
(
LANG_SWEDISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
's'
,
'i'
)]
=
MAKELANGID
(
LANG_SLOVENIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
's'
,
'k'
)]
=
MAKELANGID
(
LANG_SLOVAK
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
's'
,
'n'
)]
=
MAKELANGID
(
LANG_WOLOF
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
's'
,
'y'
)]
=
MAKELANGID
(
LANG_SYRIAC
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
't'
,
'g'
)]
=
MAKELANGID
(
LANG_FRENCH
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
't'
,
'h'
)]
=
MAKELANGID
(
LANG_THAI
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
't'
,
'j'
)]
=
MAKELANGID
(
LANG_TAJIK
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
't'
,
'm'
)]
=
MAKELANGID
(
LANG_TURKMEN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
't'
,
'r'
)]
=
MAKELANGID
(
LANG_TURKISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
't'
,
'w'
)]
=
MAKELANGID
(
LANG_CHINESE
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
't'
,
'z'
)]
=
MAKELANGID
(
LANG_SWAHILI
,
SUBLANG_CUSTOM_UNSPECIFIED
),
[
MAKEINDEX
(
'u'
,
'a'
)]
=
MAKELANGID
(
LANG_UKRAINIAN
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'u'
,
's'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'u'
,
'z'
)]
=
MAKELANGID
(
LANG_UZBEK
,
2
),
[
MAKEINDEX
(
'v'
,
'n'
)]
=
MAKELANGID
(
LANG_VIETNAMESE
,
SUBLANG_DEFAULT
),
[
MAKEINDEX
(
'z'
,
'a'
)]
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_SOUTH_AFRICA
),
};
LANGID
langid
;
if
(
layout_len
==
2
&&
(
langid
=
langids
[
MAKEINDEX
(
layout
[
0
],
layout
[
1
])]))
return
langid
;
if
(
layout_len
==
3
&&
!
memcmp
(
layout
,
"ara"
,
layout_len
))
return
MAKELANGID
(
LANG_ARABIC
,
SUBLANG_DEFAULT
);
if
(
layout_len
==
3
&&
!
memcmp
(
layout
,
"epo"
,
layout_len
))
return
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_CUSTOM_DEFAULT
);
if
(
layout_len
==
3
&&
!
memcmp
(
layout
,
"mao"
,
layout_len
))
return
MAKELANGID
(
LANG_MAORI
,
SUBLANG_DEFAULT
);
if
(
layout_len
==
4
&&
!
memcmp
(
layout
,
"brai"
,
layout_len
))
return
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_CUSTOM_DEFAULT
);
if
(
layout_len
==
5
&&
!
memcmp
(
layout
,
"latam"
,
layout_len
))
return
MAKELANGID
(
LANG_SPANISH
,
SUBLANG_CUSTOM_UNSPECIFIED
);
#undef MAKEINDEX
FIXME
(
"Unknown layout language %s
\n
"
,
debugstr_a
(
layout
));
return
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_CUSTOM_UNSPECIFIED
);
};
static
HKL
get_layout_hkl
(
struct
layout
*
layout
,
LCID
locale
)
{
if
(
!
layout
->
layout_id
)
return
(
HKL
)(
UINT_PTR
)
MAKELONG
(
locale
,
layout
->
lang
);
else
return
(
HKL
)(
UINT_PTR
)
MAKELONG
(
locale
,
0xf000
|
layout
->
layout_id
);
}
static
void
add_xkb_layout
(
const
char
*
xkb_layout
,
xkb_layout_index_t
xkb_group
,
LANGID
lang
)
{
static
WORD
next_layout_id
=
1
;
struct
layout
*
layout
;
unsigned
int
len
;
WORD
index
=
0
;
char
*
ptr
;
TRACE
(
"xkb_layout=%s xkb_group=%u lang=%04x
\n
"
,
xkb_layout
,
xkb_group
,
lang
);
LIST_FOR_EACH_ENTRY
(
layout
,
&
xkb_layouts
,
struct
layout
,
entry
)
if
(
layout
->
lang
==
lang
)
index
++
;
len
=
strlen
(
xkb_layout
)
+
1
;
if
(
!
(
layout
=
calloc
(
1
,
sizeof
(
*
layout
)
+
len
)))
{
ERR
(
"Failed to allocate memory for Xkb layout entry
\n
"
);
return
;
}
ptr
=
(
char
*
)(
layout
+
1
);
layout
->
xkb_layout
=
strcpy
(
ptr
,
xkb_layout
);
layout
->
xkb_group
=
xkb_group
;
layout
->
lang
=
lang
;
layout
->
index
=
index
;
if
(
index
)
layout
->
layout_id
=
next_layout_id
++
;
TRACE
(
"Created layout entry=%p index=%04x lang=%04x id=%04x
\n
"
,
layout
,
layout
->
index
,
layout
->
lang
,
layout
->
layout_id
);
list_add_tail
(
&
xkb_layouts
,
&
layout
->
entry
);
}
static
void
set_current_xkb_group
(
xkb_layout_index_t
xkb_group
)
{
struct
wayland_keyboard
*
keyboard
=
&
process_wayland
.
keyboard
;
LCID
locale
=
LOWORD
(
NtUserGetKeyboardLayout
(
0
));
struct
layout
*
layout
;
HKL
hkl
;
LIST_FOR_EACH_ENTRY
(
layout
,
&
xkb_layouts
,
struct
layout
,
entry
)
if
(
layout
->
xkb_group
==
xkb_group
)
break
;
if
(
&
layout
->
entry
!=
&
xkb_layouts
)
hkl
=
get_layout_hkl
(
layout
,
locale
);
else
{
ERR
(
"Failed to find Xkb Layout for group %d
\n
"
,
xkb_group
);
hkl
=
keyboard_hkl
;
}
if
(
hkl
==
keyboard_hkl
)
return
;
keyboard_hkl
=
hkl
;
TRACE
(
"Changing keyboard layout to %p
\n
"
,
hkl
);
NtUserPostMessage
(
keyboard
->
focused_hwnd
,
WM_INPUTLANGCHANGEREQUEST
,
0
/*FIXME*/
,
(
LPARAM
)
keyboard_hkl
);
}
static
BOOL
find_xkb_layout_variant
(
const
char
*
name
,
const
char
**
layout
,
const
char
**
variant
)
{
struct
rxkb_layout
*
iter
;
for
(
iter
=
rxkb_layout_first
(
rxkb_context
);
iter
;
iter
=
rxkb_layout_next
(
iter
))
{
if
(
!
strcmp
(
name
,
rxkb_layout_get_description
(
iter
)))
{
*
layout
=
rxkb_layout_get_name
(
iter
);
*
variant
=
rxkb_layout_get_variant
(
iter
);
return
TRUE
;
}
}
return
FALSE
;
}
/**********************************************************************
* Keyboard handling
*/
...
...
@@ -143,7 +353,9 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
{
struct
wayland_keyboard
*
keyboard
=
&
process_wayland
.
keyboard
;
struct
xkb_keymap
*
xkb_keymap
=
NULL
;
xkb_layout_index_t
xkb_group
;
struct
xkb_state
*
xkb_state
;
struct
layout
*
entry
,
*
next
;
char
*
keymap_str
;
TRACE
(
"format=%d fd=%d size=%d
\n
"
,
format
,
fd
,
size
);
...
...
@@ -169,12 +381,39 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
return
;
}
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
next
,
&
xkb_layouts
,
struct
layout
,
entry
)
{
list_remove
(
&
entry
->
entry
);
free
(
entry
);
}
for
(
xkb_group
=
0
;
xkb_group
<
xkb_keymap_num_layouts
(
xkb_keymap
);
xkb_group
++
)
{
const
char
*
layout_name
=
xkb_keymap_layout_get_name
(
xkb_keymap
,
xkb_group
);
const
char
*
layout
,
*
variant
=
NULL
;
int
layout_len
,
variant_len
=
0
;
char
buffer
[
1024
];
LANGID
lang
;
if
(
!
find_xkb_layout_variant
(
layout_name
,
&
layout
,
&
variant
))
layout
=
"us"
;
if
(
variant
)
variant_len
=
strlen
(
variant
);
layout_len
=
strlen
(
layout
);
TRACE
(
"Found layout %u name %s -> %s:%s
\n
"
,
xkb_group
,
layout_name
,
layout
,
variant
);
lang
=
langid_from_xkb_layout
(
layout
,
layout_len
);
snprintf
(
buffer
,
ARRAY_SIZE
(
buffer
),
"%.*s:%.*s"
,
layout_len
,
layout
,
variant_len
,
variant
);
add_xkb_layout
(
buffer
,
xkb_group
,
lang
);
}
if
((
xkb_state
=
xkb_state_new
(
xkb_keymap
)))
{
pthread_mutex_lock
(
&
keyboard
->
mutex
);
xkb_state_unref
(
keyboard
->
xkb_state
);
keyboard
->
xkb_state
=
xkb_state
;
pthread_mutex_unlock
(
&
keyboard
->
mutex
);
set_current_xkb_group
(
0
);
}
xkb_keymap_unref
(
xkb_keymap
);
...
...
@@ -198,7 +437,8 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
keyboard
->
focused_hwnd
=
hwnd
;
pthread_mutex_unlock
(
&
keyboard
->
mutex
);
/* FIXME: update foreground window as well */
NtUserPostMessage
(
keyboard
->
focused_hwnd
,
WM_INPUTLANGCHANGEREQUEST
,
0
/*FIXME*/
,
(
LPARAM
)
keyboard_hkl
);
}
static
void
keyboard_handle_leave
(
void
*
data
,
struct
wl_keyboard
*
wl_keyboard
,
...
...
@@ -236,7 +476,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
input
.
type
=
INPUT_KEYBOARD
;
input
.
ki
.
wScan
=
scan
&
0xff
;
input
.
ki
.
wVk
=
NtUserMapVirtualKeyEx
(
scan
,
MAPVK_VSC_TO_VK_EX
,
NtUserGetKeyboardLayout
(
0
)
);
input
.
ki
.
wVk
=
NtUserMapVirtualKeyEx
(
scan
,
MAPVK_VSC_TO_VK_EX
,
keyboard_hkl
);
if
(
scan
&
~
0xff
)
input
.
ki
.
dwFlags
|=
KEYEVENTF_EXTENDEDKEY
;
if
(
state
==
WL_KEYBOARD_KEY_STATE_RELEASED
)
input
.
ki
.
dwFlags
|=
KEYEVENTF_KEYUP
;
...
...
@@ -260,6 +500,8 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar
mods_locked
,
0
,
0
,
xkb_group
);
pthread_mutex_unlock
(
&
keyboard
->
mutex
);
set_current_xkb_group
(
xkb_group
);
/* FIXME: Sync wine modifier state with XKB modifier state. */
}
...
...
@@ -299,6 +541,13 @@ void wayland_keyboard_init(struct wl_keyboard *wl_keyboard)
struct
wayland_keyboard
*
keyboard
=
&
process_wayland
.
keyboard
;
struct
xkb_context
*
xkb_context
=
xkb_context_new
(
XKB_CONTEXT_NO_FLAGS
);
if
(
!
(
rxkb_context
=
rxkb_context_new
(
RXKB_CONTEXT_NO_FLAGS
))
||
!
rxkb_context_parse_default_ruleset
(
rxkb_context
))
{
ERR
(
"Failed to parse default Xkb ruleset
\n
"
);
return
;
}
if
(
!
xkb_context
)
{
ERR
(
"Failed to create XKB context
\n
"
);
...
...
@@ -337,4 +586,10 @@ void wayland_keyboard_deinit(void)
keyboard
->
xkb_state
=
NULL
;
}
pthread_mutex_unlock
(
&
keyboard
->
mutex
);
if
(
rxkb_context
)
{
rxkb_context_unref
(
rxkb_context
);
rxkb_context
=
NULL
;
}
}
dlls/winewayland.drv/waylanddrv.h
View file @
d64ea8e4
...
...
@@ -28,6 +28,7 @@
#include <pthread.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbregistry.h>
#include "viewporter-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
#include "xdg-shell-client-protocol.h"
...
...
include/config.h.in
View file @
d64ea8e4
...
...
@@ -675,6 +675,9 @@
/* Define to 1 if you have the <xkbcommon/xkbcommon.h> header file. */
#undef HAVE_XKBCOMMON_XKBCOMMON_H
/* Define to 1 if you have the <xkbcommon/xkbregistry.h> header file. */
#undef HAVE_XKBCOMMON_XKBREGISTRY_H
/* Define if Xrender has the XRenderCreateLinearGradient function */
#undef HAVE_XRENDERCREATELINEARGRADIENT
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment