winewayland.drv: Basic handling of Wayland keyboard events.
Handle Wayland keyboard events and translate them to Windows events, currently using a hardcoded US key mapping.
This commit is contained in:
parent
677868a0c7
commit
f58946e3ba
8 changed files with 402 additions and 4 deletions
91
configure
vendored
91
configure
vendored
|
@ -702,6 +702,8 @@ INOTIFY_LIBS
|
|||
INOTIFY_CFLAGS
|
||||
PCSCLITE_LIBS
|
||||
PCAP_LIBS
|
||||
XKBCOMMON_LIBS
|
||||
XKBCOMMON_CFLAGS
|
||||
WAYLAND_SCANNER
|
||||
WAYLAND_CLIENT_LIBS
|
||||
WAYLAND_CLIENT_CFLAGS
|
||||
|
@ -1793,6 +1795,8 @@ XMKMF
|
|||
CPP
|
||||
WAYLAND_CLIENT_CFLAGS
|
||||
WAYLAND_CLIENT_LIBS
|
||||
XKBCOMMON_CFLAGS
|
||||
XKBCOMMON_LIBS
|
||||
INOTIFY_CFLAGS
|
||||
INOTIFY_LIBS
|
||||
DBUS_CFLAGS
|
||||
|
@ -2612,6 +2616,10 @@ Some influential environment variables:
|
|||
C compiler flags for wayland-client, overriding pkg-config
|
||||
WAYLAND_CLIENT_LIBS
|
||||
Linker flags for wayland-client, overriding pkg-config
|
||||
XKBCOMMON_CFLAGS
|
||||
C compiler flags for xkbcommon, overriding pkg-config
|
||||
XKBCOMMON_LIBS
|
||||
Linker flags for xkbcommon, overriding pkg-config
|
||||
INOTIFY_CFLAGS
|
||||
C compiler flags for libinotify, overriding pkg-config
|
||||
INOTIFY_LIBS
|
||||
|
@ -11078,6 +11086,7 @@ CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -Wmicrosoft-enum-forward-reference"
|
|||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -15825,8 +15834,86 @@ fi
|
|||
|
||||
CPPFLAGS=$ac_save_CPPFLAGS
|
||||
|
||||
rm -f conftest.err
|
||||
if ${XKBCOMMON_CFLAGS:+false} :
|
||||
then :
|
||||
if test ${PKG_CONFIG+y}
|
||||
then :
|
||||
XKBCOMMON_CFLAGS=`$PKG_CONFIG --cflags xkbcommon 2>conftest.err`
|
||||
fi
|
||||
if test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o "$ac_cv_header_linux_input_h" = "no"
|
||||
fi
|
||||
|
||||
if ${XKBCOMMON_LIBS:+false} :
|
||||
then :
|
||||
if test ${PKG_CONFIG+y}
|
||||
then :
|
||||
XKBCOMMON_LIBS=`$PKG_CONFIG --libs xkbcommon 2>/dev/null`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: xkbcommon cflags: $XKBCOMMON_CFLAGS" >&5
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: xkbcommon libs: $XKBCOMMON_LIBS" >&5
|
||||
if test -s conftest.err; then
|
||||
printf %s "$as_me:${as_lineno-$LINENO}: xkbcommon errors: " >&5
|
||||
cat conftest.err >&5
|
||||
fi
|
||||
rm -f conftest.err
|
||||
ac_save_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $XKBCOMMON_CFLAGS"
|
||||
ac_fn_c_check_header_compile "$LINENO" "xkbcommon/xkbcommon.h" "ac_cv_header_xkbcommon_xkbcommon_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_xkbcommon_xkbcommon_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_XKBCOMMON_XKBCOMMON_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xkb_context_new in -lxkbcommon" >&5
|
||||
printf %s "checking for xkb_context_new in -lxkbcommon... " >&6; }
|
||||
if test ${ac_cv_lib_xkbcommon_xkb_context_new+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lxkbcommon $XKBCOMMON_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 xkb_context_new ();
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return xkb_context_new ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_lib_xkbcommon_xkb_context_new=yes
|
||||
else $as_nop
|
||||
ac_cv_lib_xkbcommon_xkb_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_xkbcommon_xkb_context_new" >&5
|
||||
printf "%s\n" "$ac_cv_lib_xkbcommon_xkb_context_new" >&6; }
|
||||
if test "x$ac_cv_lib_xkbcommon_xkb_context_new" = xyes
|
||||
then :
|
||||
:
|
||||
else $as_nop
|
||||
XKBCOMMON_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"
|
||||
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." ;;
|
||||
|
@ -23410,6 +23497,8 @@ X_EXTRA_LIBS = $X_EXTRA_LIBS
|
|||
WAYLAND_CLIENT_CFLAGS = $WAYLAND_CLIENT_CFLAGS
|
||||
WAYLAND_CLIENT_LIBS = $WAYLAND_CLIENT_LIBS
|
||||
WAYLAND_SCANNER = $WAYLAND_SCANNER
|
||||
XKBCOMMON_CFLAGS = $XKBCOMMON_CFLAGS
|
||||
XKBCOMMON_LIBS = $XKBCOMMON_LIBS
|
||||
PCAP_LIBS = $PCAP_LIBS
|
||||
PCSCLITE_LIBS = $PCSCLITE_LIBS
|
||||
INOTIFY_CFLAGS = $INOTIFY_CFLAGS
|
||||
|
|
|
@ -1368,8 +1368,11 @@ then
|
|||
[AC_PATH_PROG(WAYLAND_SCANNER,wayland-scanner,
|
||||
[`test -n "$PKG_CONFIG" && $PKG_CONFIG --variable=wayland_scanner wayland-scanner 2>/dev/null`])],
|
||||
[WAYLAND_CLIENT_LIBS=""],[$WAYLAND_CLIENT_LIBS])])])
|
||||
WINE_PACKAGE_FLAGS(XKBCOMMON,[xkbcommon],,,,
|
||||
[AC_CHECK_HEADERS([xkbcommon/xkbcommon.h])
|
||||
AC_CHECK_LIB(xkbcommon,xkb_context_new,[:],[XKBCOMMON_LIBS=""],[$XKBCOMMON_LIBS])])
|
||||
fi
|
||||
WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -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 "$ac_cv_header_linux_input_h" = "no"],
|
||||
[Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.],
|
||||
[enable_winewayland_drv])
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
MODULE = winewayland.drv
|
||||
UNIXLIB = winewayland.so
|
||||
UNIX_CFLAGS = $(WAYLAND_CLIENT_CFLAGS)
|
||||
UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(PTHREAD_LIBS) -lm
|
||||
UNIX_CFLAGS = $(WAYLAND_CLIENT_CFLAGS) $(XKBCOMMON_CFLAGS)
|
||||
UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(XKBCOMMON_LIBS) $(PTHREAD_LIBS) -lm
|
||||
|
||||
SOURCES = \
|
||||
display.c \
|
||||
dllmain.c \
|
||||
version.rc \
|
||||
wayland.c \
|
||||
wayland_keyboard.c \
|
||||
wayland_output.c \
|
||||
wayland_pointer.c \
|
||||
wayland_surface.c \
|
||||
|
|
|
@ -35,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
|
|||
struct wayland process_wayland =
|
||||
{
|
||||
.seat.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
.keyboard.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
.pointer.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
.output_list = {&process_wayland.output_list, &process_wayland.output_list},
|
||||
.output_mutex = PTHREAD_MUTEX_INITIALIZER
|
||||
|
@ -66,6 +67,11 @@ static void wl_seat_handle_capabilities(void *data, struct wl_seat *seat,
|
|||
wayland_pointer_init(wl_seat_get_pointer(seat));
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && process_wayland.pointer.wl_pointer)
|
||||
wayland_pointer_deinit();
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !process_wayland.keyboard.wl_keyboard)
|
||||
wayland_keyboard_init(wl_seat_get_keyboard(seat));
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && process_wayland.keyboard.wl_keyboard)
|
||||
wayland_keyboard_deinit();
|
||||
}
|
||||
|
||||
static void wl_seat_handle_name(void *data, struct wl_seat *seat, const char *name)
|
||||
|
|
274
dlls/winewayland.drv/wayland_keyboard.c
Normal file
274
dlls/winewayland.drv/wayland_keyboard.c
Normal file
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* Keyboard related functions
|
||||
*
|
||||
* Copyright 2020 Alexandros Frantzis for Collabora Ltd.
|
||||
* Copyright 2023 Rémi Bernon for CodeWeavers
|
||||
*
|
||||
* 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.1 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#undef SW_MAX /* Also defined in winuser.rh */
|
||||
#include <unistd.h>
|
||||
|
||||
#include "waylanddrv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(keyboard);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(key);
|
||||
|
||||
static WORD key2scan(UINT key)
|
||||
{
|
||||
/* base keys can be mapped directly */
|
||||
if (key <= KEY_KPDOT) return key;
|
||||
|
||||
/* map keys found in KBDTABLES definitions (Txx Xxx Yxx macros) */
|
||||
switch (key)
|
||||
{
|
||||
case 84 /* ISO_Level3_Shift */: return 0x005a; /* T5A / VK_OEM_WSCTRL */
|
||||
case KEY_SYSRQ: return 0x0054; /* T54 / VK_SNAPSHOT */
|
||||
case KEY_102ND: return 0x0056; /* T56 / VK_OEM_102 */
|
||||
case KEY_F11: return 0x0057; /* T57 / VK_F11 */
|
||||
case KEY_F12: return 0x0058; /* T58 / VK_F12 */
|
||||
case KEY_LINEFEED: return 0x0059; /* T59 / VK_CLEAR */
|
||||
case KEY_EXIT: return 0x005b; /* T5B / VK_OEM_FINISH */
|
||||
case KEY_OPEN: return 0x005c; /* T5C / VK_OEM_JUMP */
|
||||
/* FIXME: map a KEY to T5D / VK_EREOF */
|
||||
/* FIXME: map a KEY to T5E / VK_OEM_BACKTAB */
|
||||
case KEY_COMPOSE: return 0x005f; /* T5F / VK_OEM_AUTO */
|
||||
case KEY_SCALE: return 0x0062; /* T62 / VK_ZOOM */
|
||||
case KEY_HELP: return 0x0063; /* T63 / VK_HELP */
|
||||
case KEY_F13: return 0x0064; /* T64 / VK_F13 */
|
||||
case KEY_F14: return 0x0065; /* T65 / VK_F14 */
|
||||
case KEY_F15: return 0x0066; /* T66 / VK_F15 */
|
||||
case KEY_F16: return 0x0067; /* T67 / VK_F16 */
|
||||
case KEY_F17: return 0x0068; /* T68 / VK_F17 */
|
||||
case KEY_F18: return 0x0069; /* T69 / VK_F18 */
|
||||
case KEY_F19: return 0x006a; /* T6A / VK_F19 */
|
||||
case KEY_F20: return 0x006b; /* T6B / VK_F20 */
|
||||
case KEY_F21: return 0x006c; /* T6C / VK_F21 */
|
||||
case KEY_F22: return 0x006d; /* T6D / VK_F22 */
|
||||
case KEY_F23: return 0x006e; /* T6E / VK_F23 */
|
||||
/* FIXME: map a KEY to T6F / VK_OEM_PA3 */
|
||||
case KEY_COMPUTER: return 0x0071; /* T71 / VK_OEM_RESET */
|
||||
/* FIXME: map a KEY to T73 / VK_ABNT_C1 */
|
||||
case KEY_F24: return 0x0076; /* T76 / VK_F24 */
|
||||
case KEY_KPPLUSMINUS: return 0x007b; /* T7B / VK_OEM_PA1 */
|
||||
/* FIXME: map a KEY to T7C / VK_TAB */
|
||||
/* FIXME: map a KEY to T7E / VK_ABNT_C2 */
|
||||
/* FIXME: map a KEY to T7F / VK_OEM_PA2 */
|
||||
case KEY_PREVIOUSSONG: return 0x0110; /* X10 / VK_MEDIA_PREV_TRACK */
|
||||
case KEY_NEXTSONG: return 0x0119; /* X19 / VK_MEDIA_NEXT_TRACK */
|
||||
case KEY_KPENTER: return 0x011c; /* X1C / VK_RETURN */
|
||||
case KEY_RIGHTCTRL: return 0x011d; /* X1D / VK_RCONTROL */
|
||||
case KEY_MUTE: return 0x0120; /* X20 / VK_VOLUME_MUTE */
|
||||
case KEY_PROG2: return 0x0121; /* X21 / VK_LAUNCH_APP2 */
|
||||
case KEY_PLAYPAUSE: return 0x0122; /* X22 / VK_MEDIA_PLAY_PAUSE */
|
||||
case KEY_STOPCD: return 0x0124; /* X24 / VK_MEDIA_STOP */
|
||||
case KEY_VOLUMEDOWN: return 0x012e; /* X2E / VK_VOLUME_DOWN */
|
||||
case KEY_VOLUMEUP: return 0x0130; /* X30 / VK_VOLUME_UP */
|
||||
case KEY_HOMEPAGE: return 0x0132; /* X32 / VK_BROWSER_HOME */
|
||||
case KEY_KPSLASH: return 0x0135; /* X35 / VK_DIVIDE */
|
||||
case KEY_PRINT: return 0x0137; /* X37 / VK_SNAPSHOT */
|
||||
case KEY_RIGHTALT: return 0x0138; /* X38 / VK_RMENU */
|
||||
case KEY_CANCEL: return 0x0146; /* X46 / VK_CANCEL */
|
||||
case KEY_HOME: return 0x0147; /* X47 / VK_HOME */
|
||||
case KEY_UP: return 0x0148; /* X48 / VK_UP */
|
||||
case KEY_PAGEUP: return 0x0149; /* X49 / VK_PRIOR */
|
||||
case KEY_LEFT: return 0x014b; /* X4B / VK_LEFT */
|
||||
case KEY_RIGHT: return 0x014d; /* X4D / VK_RIGHT */
|
||||
case KEY_END: return 0x014f; /* X4F / VK_END */
|
||||
case KEY_DOWN: return 0x0150; /* X50 / VK_DOWN */
|
||||
case KEY_PAGEDOWN: return 0x0151; /* X51 / VK_NEXT */
|
||||
case KEY_INSERT: return 0x0152; /* X52 / VK_INSERT */
|
||||
case KEY_DELETE: return 0x0153; /* X53 / VK_DELETE */
|
||||
case KEY_LEFTMETA: return 0x015b; /* X5B / VK_LWIN */
|
||||
case KEY_RIGHTMETA: return 0x015c; /* X5C / VK_RWIN */
|
||||
case KEY_MENU: return 0x015d; /* X5D / VK_APPS */
|
||||
case KEY_POWER: return 0x015e; /* X5E / VK_POWER */
|
||||
case KEY_SLEEP: return 0x015f; /* X5F / VK_SLEEP */
|
||||
case KEY_FIND: return 0x0165; /* X65 / VK_BROWSER_SEARCH */
|
||||
case KEY_BOOKMARKS: return 0x0166; /* X66 / VK_BROWSER_FAVORITES */
|
||||
case KEY_REFRESH: return 0x0167; /* X67 / VK_BROWSER_REFRESH */
|
||||
case KEY_STOP: return 0x0168; /* X68 / VK_BROWSER_STOP */
|
||||
case KEY_FORWARD: return 0x0169; /* X69 / VK_BROWSER_FORWARD */
|
||||
case KEY_BACK: return 0x016a; /* X6A / VK_BROWSER_BACK */
|
||||
case KEY_PROG1: return 0x016b; /* X6B / VK_LAUNCH_APP1 */
|
||||
case KEY_MAIL: return 0x016c; /* X6C / VK_LAUNCH_MAIL */
|
||||
case KEY_MEDIA: return 0x016d; /* X6D / VK_LAUNCH_MEDIA_SELECT */
|
||||
case KEY_PAUSE: return 0x021d; /* Y1D / VK_PAUSE */
|
||||
}
|
||||
|
||||
/* otherwise just make up some extended scancode */
|
||||
return 0x200 | (key & 0x7f);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Keyboard handling
|
||||
*/
|
||||
|
||||
static HWND wayland_keyboard_get_focused_hwnd(void)
|
||||
{
|
||||
struct wayland_keyboard *keyboard = &process_wayland.keyboard;
|
||||
HWND hwnd;
|
||||
|
||||
pthread_mutex_lock(&keyboard->mutex);
|
||||
hwnd = keyboard->focused_hwnd;
|
||||
pthread_mutex_unlock(&keyboard->mutex);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t format, int fd, uint32_t size)
|
||||
{
|
||||
FIXME("stub!\n");
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, struct wl_surface *wl_surface,
|
||||
struct wl_array *keys)
|
||||
{
|
||||
struct wayland_keyboard *keyboard = &process_wayland.keyboard;
|
||||
HWND hwnd;
|
||||
|
||||
if (!wl_surface) return;
|
||||
|
||||
/* The wl_surface user data remains valid and immutable for the whole
|
||||
* lifetime of the object, so it's safe to access without locking. */
|
||||
hwnd = wl_surface_get_user_data(wl_surface);
|
||||
TRACE("serial=%u hwnd=%p\n", serial, hwnd);
|
||||
|
||||
pthread_mutex_lock(&keyboard->mutex);
|
||||
keyboard->focused_hwnd = hwnd;
|
||||
pthread_mutex_unlock(&keyboard->mutex);
|
||||
|
||||
/* FIXME: update foreground window as well */
|
||||
}
|
||||
|
||||
static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, struct wl_surface *wl_surface)
|
||||
{
|
||||
struct wayland_keyboard *keyboard = &process_wayland.keyboard;
|
||||
HWND hwnd;
|
||||
|
||||
if (!wl_surface) return;
|
||||
|
||||
/* The wl_surface user data remains valid and immutable for the whole
|
||||
* lifetime of the object, so it's safe to access without locking. */
|
||||
hwnd = wl_surface_get_user_data(wl_surface);
|
||||
TRACE("serial=%u hwnd=%p\n", serial, hwnd);
|
||||
|
||||
pthread_mutex_lock(&keyboard->mutex);
|
||||
if (keyboard->focused_hwnd == hwnd)
|
||||
keyboard->focused_hwnd = NULL;
|
||||
pthread_mutex_unlock(&keyboard->mutex);
|
||||
|
||||
/* FIXME: update foreground window as well */
|
||||
}
|
||||
|
||||
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, uint32_t time, uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
UINT scan = key2scan(key);
|
||||
INPUT input = {0};
|
||||
HWND hwnd;
|
||||
|
||||
if (!(hwnd = wayland_keyboard_get_focused_hwnd())) return;
|
||||
|
||||
TRACE_(key)("serial=%u hwnd=%p key=%d scan=%#x state=%#x\n", serial, hwnd, key, scan, state);
|
||||
|
||||
input.type = INPUT_KEYBOARD;
|
||||
input.ki.wScan = scan & 0xff;
|
||||
input.ki.wVk = NtUserMapVirtualKeyEx(scan, MAPVK_VSC_TO_VK_EX, NtUserGetKeyboardLayout(0));
|
||||
if (scan & ~0xff) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
|
||||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_RELEASED) input.ki.dwFlags |= KEYEVENTF_KEYUP;
|
||||
__wine_send_input(hwnd, &input, NULL);
|
||||
}
|
||||
|
||||
static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, uint32_t mods_depressed,
|
||||
uint32_t mods_latched, uint32_t mods_locked,
|
||||
uint32_t xkb_group)
|
||||
{
|
||||
FIXME("serial=%u mods_depressed=%#x mods_latched=%#x mods_locked=%#x xkb_group=%d stub!\n",
|
||||
serial, mods_depressed, mods_latched, mods_locked, xkb_group);
|
||||
}
|
||||
|
||||
static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
|
||||
int rate, int delay)
|
||||
{
|
||||
FIXME("rate=%d delay=%d stub!\n", rate, delay);
|
||||
}
|
||||
|
||||
static const struct wl_keyboard_listener keyboard_listener = {
|
||||
keyboard_handle_keymap,
|
||||
keyboard_handle_enter,
|
||||
keyboard_handle_leave,
|
||||
keyboard_handle_key,
|
||||
keyboard_handle_modifiers,
|
||||
keyboard_handle_repeat_info,
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_keyboard_init
|
||||
*/
|
||||
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 (!xkb_context)
|
||||
{
|
||||
ERR("Failed to create XKB context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&keyboard->mutex);
|
||||
keyboard->wl_keyboard = wl_keyboard;
|
||||
keyboard->xkb_context = xkb_context;
|
||||
pthread_mutex_unlock(&keyboard->mutex);
|
||||
wl_keyboard_add_listener(keyboard->wl_keyboard, &keyboard_listener, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_keyboard_deinit
|
||||
*/
|
||||
void wayland_keyboard_deinit(void)
|
||||
{
|
||||
struct wayland_keyboard *keyboard = &process_wayland.keyboard;
|
||||
|
||||
pthread_mutex_lock(&keyboard->mutex);
|
||||
if (keyboard->wl_keyboard)
|
||||
{
|
||||
wl_keyboard_destroy(keyboard->wl_keyboard);
|
||||
keyboard->wl_keyboard = NULL;
|
||||
}
|
||||
if (keyboard->xkb_context)
|
||||
{
|
||||
xkb_context_unref(keyboard->xkb_context);
|
||||
keyboard->xkb_context = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&keyboard->mutex);
|
||||
}
|
|
@ -181,6 +181,11 @@ void wayland_surface_destroy(struct wayland_surface *surface)
|
|||
}
|
||||
pthread_mutex_unlock(&process_wayland.pointer.mutex);
|
||||
|
||||
pthread_mutex_lock(&process_wayland.keyboard.mutex);
|
||||
if (process_wayland.keyboard.focused_hwnd == surface->hwnd)
|
||||
process_wayland.keyboard.focused_hwnd = NULL;
|
||||
pthread_mutex_unlock(&process_wayland.keyboard.mutex);
|
||||
|
||||
pthread_mutex_lock(&surface->mutex);
|
||||
|
||||
if (surface->xdg_toplevel)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <pthread.h>
|
||||
#include <wayland-client.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
|
@ -65,6 +66,14 @@ enum wayland_surface_config_state
|
|||
WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN = (1 << 3)
|
||||
};
|
||||
|
||||
struct wayland_keyboard
|
||||
{
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct xkb_context *xkb_context;
|
||||
HWND focused_hwnd;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
struct wayland_cursor
|
||||
{
|
||||
struct wayland_shm_buffer *shm_buffer;
|
||||
|
@ -100,6 +109,7 @@ struct wayland
|
|||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct wl_shm *wl_shm;
|
||||
struct wayland_seat seat;
|
||||
struct wayland_keyboard keyboard;
|
||||
struct wayland_pointer pointer;
|
||||
struct wl_list output_list;
|
||||
/* Protects the output_list and the wayland_output.current states. */
|
||||
|
@ -223,6 +233,13 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *surfac
|
|||
struct wayland_surface *wayland_surface) DECLSPEC_HIDDEN;
|
||||
void wayland_window_flush(HWND hwnd) DECLSPEC_HIDDEN;
|
||||
|
||||
/**********************************************************************
|
||||
* Wayland Keyboard
|
||||
*/
|
||||
|
||||
void wayland_keyboard_init(struct wl_keyboard *wl_keyboard) DECLSPEC_HIDDEN;
|
||||
void wayland_keyboard_deinit(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/**********************************************************************
|
||||
* Wayland pointer
|
||||
*/
|
||||
|
|
|
@ -672,6 +672,9 @@
|
|||
/* Define to 1 if `callback' is a member of `XICCallback'. */
|
||||
#undef HAVE_XICCALLBACK_CALLBACK
|
||||
|
||||
/* Define to 1 if you have the <xkbcommon/xkbcommon.h> header file. */
|
||||
#undef HAVE_XKBCOMMON_XKBCOMMON_H
|
||||
|
||||
/* Define if Xrender has the XRenderCreateLinearGradient function */
|
||||
#undef HAVE_XRENDERCREATELINEARGRADIENT
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue