Add XKB interface for x11

This commit is contained in:
James Grogan 2022-11-17 11:28:18 +00:00
parent 7ad237edc1
commit cf9bace272
15 changed files with 232 additions and 31 deletions

View file

@ -4,8 +4,14 @@
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h> /* for XGetXCBConnection, link with libX11-xcb */
#include <xkbcommon/xkbcommon-x11.h>
#include <xcb/xcb.h>
// Header is c-like, uses explicit as a var
#define explicit explicit_
#include <xcb/xkb.h>
#undef explicit
#include "PaintEvent.h"
#include "ResizeEvent.h"
#include "Screen.h"
@ -14,17 +20,35 @@
#include "UiEvent.h"
#include "XcbKeyboard.h"
#include "XcbWindow.h"
#include "XcbEventInterface.h"
#include "XcbGlInterface.h"
#include "XcbExtensionInterface.h"
#include "FileLogger.h"
#include "FontsManager.h"
#include <iostream>
namespace {
typedef union {
struct {
uint8_t response_type;
uint8_t xkbType;
uint16_t sequence;
xcb_timestamp_t time;
uint8_t deviceID;
} any;
xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
xcb_xkb_map_notify_event_t map_notify;
xcb_xkb_state_notify_event_t state_notify;
} _xkb_event;
}
XcbInterface::XcbInterface(DesktopManager* desktopManager, std::unique_ptr<FontsManager> fontsManager, bool useHardware)
: AbstractUIInterface(desktopManager, std::move(fontsManager), useHardware),
mEventInterface(XcbEventInterface::Create())
mEventInterface(XcbEventInterface::Create()),
mExtensionInterface(std::make_unique<XcbExtensionInterface>())
{
}
@ -43,7 +67,9 @@ void XcbInterface::initialize()
{
initializeHardwareRendering();
}
mDesktopManager->setKeyboard(XcbKeyboard::Create());
mExtensionInterface->initialize(mConnection);
mDesktopManager->setKeyboard(XcbKeyboard::Create(mConnection));
const auto num_windows = mDesktopManager->getWindowManager()->getNumWindows();
for(std::size_t idx=0; idx< num_windows; idx++)
@ -178,6 +204,7 @@ void XcbInterface::loop()
xcb_generic_event_t *event;
while ((event = xcb_wait_for_event(mConnection)))
{
auto handled = true;
switch (event->response_type & ~0x80)
{
case XCB_EXPOSE:{
@ -235,9 +262,23 @@ void XcbInterface::loop()
break;
}
default:
/* Unknown event type, ignore it */
handled = false;
break;
}
if (!handled)
{
if (mExtensionInterface->isXkBEvent(event->response_type))
{
auto xkb_event = reinterpret_cast<_xkb_event *>(event);
if (xkb_event->any.xkbType == XCB_XKB_STATE_NOTIFY)
{
dynamic_cast<XcbKeyboard*>(mDesktopManager->getKeyboard())->updateState(&xkb_event->state_notify);
}
}
}
free(event);
mDesktopManager->onLoopIteration();
}