#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
{
: 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)
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))
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());
}
}
#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
{
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;
};
}