DSWaylandKeyboard: implements event send functions for wl_keyboard 89/241789/1
authorSung-Jin Park <sj76.park@samsung.com>
Tue, 11 Aug 2020 12:52:03 +0000 (21:52 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Thu, 20 Aug 2020 10:10:47 +0000 (19:10 +0900)
Change-Id: I624efe06267cb4f07d07598f265ff42548411f5a
Signed-off-by: Sung-Jin Park <sj76.park@samsung.com>
src/DSWaylandServer/DSWaylandKeyboard.cpp
src/DSWaylandServer/DSWaylandKeyboard.h
src/DSWaylandServer/DSWaylandKeyboardPrivate.h

index 3dc8880..2bed2ca 100644 (file)
@@ -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 <fcntl.h>
 
 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<struct ::wl_client*, Resource*> 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<struct ::wl_client*, Resource*> 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<struct ::wl_client*, Resource*> 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<struct ::wl_client*, Resource*> 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<DSWaylandKeyboardPrivate>(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());
 }
 
 }
index c927100..040a600 100644 (file)
@@ -30,6 +30,9 @@ public:
        void setFocus(DSWaylandSurface *waylandSurface);
        DSWaylandSurface *getFocus();
 
+       void sendKeyDown(uint32_t keycode);
+       void sendKeyUp(uint32_t keycode);
+
 protected:
 
 private:
index 1946d7f..a23abb0 100644 (file)
@@ -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;
 };
 
 }