From 85696121239c4e7bff3f7611e1acf46b365403ac Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Tue, 11 Aug 2020 21:52:03 +0900 Subject: [PATCH] DSWaylandKeyboard: implements event send functions for wl_keyboard Change-Id: I624efe06267cb4f07d07598f265ff42548411f5a Signed-off-by: Sung-Jin Park --- src/DSWaylandServer/DSWaylandKeyboard.cpp | 182 ++++++++++++++++++++++++- src/DSWaylandServer/DSWaylandKeyboard.h | 3 + src/DSWaylandServer/DSWaylandKeyboardPrivate.h | 39 ++++-- 3 files changed, 210 insertions(+), 14 deletions(-) diff --git a/src/DSWaylandServer/DSWaylandKeyboard.cpp b/src/DSWaylandServer/DSWaylandKeyboard.cpp index 3dc8880..2bed2ca 100644 --- a/src/DSWaylandServer/DSWaylandKeyboard.cpp +++ b/src/DSWaylandServer/DSWaylandKeyboard.cpp @@ -1,6 +1,12 @@ #include "DSWaylandKeyboard.h" #include "DSWaylandKeyboardPrivate.h" #include "DSWaylandClient.h" +#include "DSWaylandSeat.h" +#include "DSWaylandSurface.h" +#include "DSWaylandCompositor.h" +#include "DSXkb.h" + +#include namespace display_server { @@ -10,20 +16,54 @@ DSWaylandKeyboardPrivate::DSWaylandKeyboardPrivate(DSWaylandSeat *seat, DSWaylan : DSObjectPrivate(keyboard), __p_ptr(keyboard), __seat(seat), - __waylandSurface(nullptr), + __xkb(seat->getXkb()), + __compositor(seat->getCompositor()), + __focusSurface(nullptr), + __focusClient(nullptr), __repeatRate(0), __repeatDelay(0) { + if (__xkb) + { + __fdKeymap = __xkb->getKeymapFd(); + __fdKeymapSize = __xkb->getKeymapSize(); + __formatKeymap = WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1; + __depressed = __xkb->getModifierDepressed(); + __latched = __xkb->getModifierLatched(); + __locked = __xkb->getModifierLocked(); + __group = __xkb->getModifierGroup(); + } + else + { + /* open fd of null keymap */ + __fdKeymap = open("/dev/null", O_RDONLY); + __fdKeymapSize = 0; + __formatKeymap = WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP; + __depressed = 0; + __latched = 0; + __locked = 0; + __group = 0; + } + + DSLOG_INF("DSWaylandKeyboardPrivate", "__fdKeymap=%d, __fdKeymapSize=%d, __formatKeymap=%d", + __fdKeymap, __fdKeymapSize, __formatKeymap); + wl_keyboard(); + __keys.clear(); } DSWaylandKeyboardPrivate::~DSWaylandKeyboardPrivate() { + if (__fdKeymap >= 0) + close(__fdKeymap); } void DSWaylandKeyboardPrivate::keyboard_bind_resource(Resource *resource) { DSLOG_INF("DSWaylandKeyboardPrivate",""); + + sendKeymap(resource); + sendRepeatInfo(resource); } void DSWaylandKeyboardPrivate::keyboard_destroy_resource(Resource *resource) @@ -37,6 +77,109 @@ void DSWaylandKeyboardPrivate::keyboard_release(Resource *resource) wl_resource_destroy(resource->handle); } +void DSWaylandKeyboardPrivate::sendKeymap(Resource *resource) +{ + send_keymap(resource->handle, __formatKeymap, __fdKeymap, __fdKeymapSize); +} + +void DSWaylandKeyboardPrivate::sendRepeatInfo(Resource *resource) +{ + if (WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION > resource->version()) + return; + + send_repeat_info(resource->handle, __repeatRate, __repeatDelay); +} + +void DSWaylandKeyboardPrivate::sendEnter(struct ::wl_resource *surface) +{ + auto client = wl_resource_get_client(surface); + auto resMap = resourceMap(); + auto func = [&](std::pair res) + { + if (res.first == client) + { + send_enter(res.second->handle, __compositor->nextSerial(), surface, __keys); + } + }; + + std::for_each(resMap.begin(), resMap.end(), func); + + //TODO : send key press event(s) of the pressed key(s) to current focus window +} + +void DSWaylandKeyboardPrivate::sendLeave(struct ::wl_resource *surface) +{ + auto client = wl_resource_get_client(surface); + auto resMap = resourceMap(); + auto func = [&](std::pair res) + { + if (res.first == client) + { + send_leave(res.second->handle, __compositor->nextSerial(), surface); + } + }; + + //TODO : send key release events of the pressed keys to current focus window + + std::for_each(resMap.begin(), resMap.end(), func); +} + +void DSWaylandKeyboardPrivate::sendModifiers(struct ::wl_resource *surface) +{ + bool need_send = false; + uint32_t mod = 0; + + if (!__xkb) + return; + + mod = __xkb->getModifierDepressed(); + need_send |= (__depressed != mod); + __depressed = mod; + + mod = __xkb->getModifierLatched(); + need_send |= (__latched != mod); + __latched = mod; + + mod = __xkb->getModifierLocked(); + need_send |= (__locked != mod); + __locked = mod; + + mod = __xkb->getModifierGroup(); + need_send |= (__group != mod); + __group = mod; + + if (!need_send) + return; + + auto client = wl_resource_get_client(surface); + auto resMap = resourceMap(); + auto func = [&](std::pair res) + { + if (res.first == client) + { + send_modifiers(res.second->handle, __compositor->nextSerial(), __depressed, __latched, __locked, __group); + } + }; + std::for_each(resMap.begin(), resMap.end(), func); +} + +void DSWaylandKeyboardPrivate::sendKey(uint32_t key, uint32_t state) +{ + if (!__focusSurface) + { + DSLOG_INF("DSWaylandKeyboardPrivate", "No focusSurface !"); + return; + } + + auto resMap = resourceMap(); + auto func = [&](std::pair res) + { + if (res.first == __focusClient) + send_key(res.second->handle, __compositor->nextSerial(), __seat->getCurrentEventTime(), key, state); + }; + std::for_each(resMap.begin(), resMap.end(), func); +} + /* Begin Public Class Implementation */ DSWaylandKeyboard::DSWaylandKeyboard(DSWaylandSeat *seat) : DSObject(), _d_ptr(std::make_unique(seat, this)) @@ -96,13 +239,46 @@ void DSWaylandKeyboard::addClient(DSWaylandClient *client, uint32_t id, int vers void DSWaylandKeyboard::setFocus(DSWaylandSurface *waylandSurface) { DS_GET_PRIV(DSWaylandKeyboard); - priv->__waylandSurface = waylandSurface; + + if (priv->__focusSurface != waylandSurface) + { + if (priv->__focusSurface) + { + struct ::wl_resource *surfaceToLeave = priv->__focusSurface->getWlResource(); + priv->sendModifiers(surfaceToLeave); + priv->sendLeave(surfaceToLeave); + } + + struct ::wl_resource *surfaceToEnter = waylandSurface->getWlResource(); + priv->sendEnter(surfaceToEnter); + + priv->__focusSurface = waylandSurface; + priv->__focusClient = wl_resource_get_client(waylandSurface->getWlResource()); + } } DSWaylandSurface *DSWaylandKeyboard::getFocus() { DS_GET_PRIV(DSWaylandKeyboard); - return priv->__waylandSurface; + return priv->__focusSurface; +} + +void DSWaylandKeyboard::sendKeyDown(uint32_t keycode) +{ + DS_GET_PRIV(DSWaylandKeyboard); + priv->sendKey(keycode, WL_KEYBOARD_KEY_STATE_PRESSED); + + if (priv->__focusSurface) + priv->sendModifiers(priv->__focusSurface->getWlResource()); +} + +void DSWaylandKeyboard::sendKeyUp(uint32_t keycode) +{ + DS_GET_PRIV(DSWaylandKeyboard); + priv->sendKey(keycode, WL_KEYBOARD_KEY_STATE_RELEASED); + + if (priv->__focusSurface) + priv->sendModifiers(priv->__focusSurface->getWlResource()); } } diff --git a/src/DSWaylandServer/DSWaylandKeyboard.h b/src/DSWaylandServer/DSWaylandKeyboard.h index c927100..040a600 100644 --- a/src/DSWaylandServer/DSWaylandKeyboard.h +++ b/src/DSWaylandServer/DSWaylandKeyboard.h @@ -30,6 +30,9 @@ public: void setFocus(DSWaylandSurface *waylandSurface); DSWaylandSurface *getFocus(); + void sendKeyDown(uint32_t keycode); + void sendKeyUp(uint32_t keycode); + protected: private: diff --git a/src/DSWaylandServer/DSWaylandKeyboardPrivate.h b/src/DSWaylandServer/DSWaylandKeyboardPrivate.h index 1946d7f..a23abb0 100644 --- a/src/DSWaylandServer/DSWaylandKeyboardPrivate.h +++ b/src/DSWaylandServer/DSWaylandKeyboardPrivate.h @@ -1,16 +1,21 @@ #ifndef __DS_WAYLAND_KEYBOARD_PRIVATE_H__ #define __DS_WAYLAND_KEYBOARD_PRIVATE_H__ -#include "dswayland-server-wayland.h" - #include "DSCore.h" #include "DSObjectPrivate.h" +#include "dswayland-server-wayland.h" +#include "wayland-util.h" + +struct wl_client; +struct wl_array; namespace display_server { +class DSXkb; class DSWaylandSeat; class DSWaylandSurface; +class DSWaylandCompositor; class DS_DECL_EXPORT DSWaylandKeyboardPrivate : public DSObjectPrivate, public DSWaylandServer::wl_keyboard { @@ -28,21 +33,33 @@ protected: virtual void keyboard_release(Resource *resource); /* APIs must be provided */ - /* - void sendKeymap(struct ::wl_client *client, uint32_t format, int32_t fd, uint32_t size); - void sendEnter(struct ::wl_client *client, uint32_t serial, struct ::wl_resource *surface, const std::string &keys); - void sendLeave(struct ::wl_client *client, uint32_t serial, struct ::wl_resource *surface); - void sendKey(struct ::wl_client *client, uint32_t serial, uint32_t time, uint32_t key, uint32_t state); - void sendModifiers(struct ::wl_client *client, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group); - void sendRepeat_info(struct ::wl_client *client, int32_t rate, int32_t delay); - */ + void sendKey(uint32_t key, uint32_t state); + void sendKeymap(Resource *resource); + void sendRepeatInfo(Resource *resource); + void sendEnter(struct ::wl_resource *surface); + void sendLeave(struct ::wl_resource *surface); + void sendModifiers(struct ::wl_resource *surface); private: DSWaylandSeat *__seat; - DSWaylandSurface *__waylandSurface; + DSXkb *__xkb; + DSWaylandCompositor *__compositor; + DSWaylandSurface *__focusSurface; + struct ::wl_client *__focusClient; uint32_t __repeatRate; uint32_t __repeatDelay; + std::string __keys; + + int __fdKeymap; + uint32_t __fdKeymapSize; + uint32_t __formatKeymap; + + /* modifiers status */ + uint32_t __depressed; + uint32_t __latched; + uint32_t __locked; + uint32_t __group; }; } -- 2.7.4