Add XKB interface for x11
This commit is contained in:
parent
7ad237edc1
commit
cf9bace272
15 changed files with 232 additions and 31 deletions
|
@ -33,7 +33,7 @@ sudo apt-get install libpng-dev
|
||||||
#### Window rendering
|
#### Window rendering
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install libwayland-dev wayland-protocols libx11-dev libxkbcommon-dev libx11-xcb-dev libxcb-image0-dev
|
sudo apt-get install libwayland-dev wayland-protocols libx11-dev libxkbcommon-dev libxkbcommon-x11-dev libx11-xcb-dev libxcb-image0-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
We need to generate suitable xdg shell c code for wayland:
|
We need to generate suitable xdg shell c code for wayland:
|
||||||
|
|
|
@ -23,6 +23,7 @@ void MediaTool::initializeViews()
|
||||||
{
|
{
|
||||||
auto mainWindow = mDesktopManager->getWindowManager()->getMainWindow();
|
auto mainWindow = mDesktopManager->getWindowManager()->getMainWindow();
|
||||||
mainWindow->setSize(800, 600);
|
mainWindow->setSize(800, 600);
|
||||||
|
mainWindow->setTitle("Media Tool");
|
||||||
|
|
||||||
auto tabbedPanel = TabbedPanelWidget::Create();
|
auto tabbedPanel = TabbedPanelWidget::Create();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
|
|
||||||
Keyboard::Keyboard()
|
Keyboard::Keyboard()
|
||||||
:mKeyMap()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,7 @@ class Keyboard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using KeyCode = unsigned;
|
using KeyCode = unsigned;
|
||||||
|
using KeyState = unsigned;
|
||||||
protected:
|
|
||||||
std::map<KeyCode, std::string> mKeyMap;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Keyboard();
|
Keyboard();
|
||||||
|
@ -18,7 +16,7 @@ public:
|
||||||
|
|
||||||
static std::unique_ptr<Keyboard> Create();
|
static std::unique_ptr<Keyboard> Create();
|
||||||
|
|
||||||
virtual std::string GetKeyString(KeyCode code)
|
virtual std::string getKeyString(KeyCode code)
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class PaintEvent;
|
class PaintEvent;
|
||||||
class MouseEvent;
|
class MouseEvent;
|
||||||
|
@ -61,8 +62,19 @@ public:
|
||||||
|
|
||||||
bool isDirty() const;
|
bool isDirty() const;
|
||||||
|
|
||||||
|
void setTitle(const std::string& title)
|
||||||
|
{
|
||||||
|
mTitle = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& getTitle() const
|
||||||
|
{
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WidgetPtr mWidget {nullptr};
|
WidgetPtr mWidget {nullptr};
|
||||||
|
std::string mTitle;
|
||||||
IPlatformWindowPtr mPlatformWindow {nullptr};
|
IPlatformWindowPtr mPlatformWindow {nullptr};
|
||||||
std::unique_ptr<DrawingContext> mDrawingContext;
|
std::unique_ptr<DrawingContext> mDrawingContext;
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,9 +15,10 @@ if(UNIX)
|
||||||
ui_interfaces/x11/XcbTextInterface.cpp
|
ui_interfaces/x11/XcbTextInterface.cpp
|
||||||
ui_interfaces/x11/XcbKeyboard.cpp
|
ui_interfaces/x11/XcbKeyboard.cpp
|
||||||
ui_interfaces/x11/XcbGlInterface.cpp
|
ui_interfaces/x11/XcbGlInterface.cpp
|
||||||
|
ui_interfaces/x11/XcbExtensionInterface.cpp
|
||||||
ui_interfaces/x11/XcbGlWindowInterface.cpp
|
ui_interfaces/x11/XcbGlWindowInterface.cpp
|
||||||
)
|
)
|
||||||
list(APPEND platform_LIBS ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_X11_xcb_LIB} ${X11_xkbcommon_LIB} libxcb-image.so)
|
list(APPEND platform_LIBS ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_X11_xcb_LIB} ${X11_xkbcommon_LIB} ${X11_xkbcommon_X11_LIB} libxcb-image.so)
|
||||||
list(APPEND X11_INCLUDE_DIRS ${X11_xkbcommon_INCLUDE_PATH})
|
list(APPEND X11_INCLUDE_DIRS ${X11_xkbcommon_INCLUDE_PATH})
|
||||||
else()
|
else()
|
||||||
message(STATUS "x11 development headers not found - skipping support")
|
message(STATUS "x11 development headers not found - skipping support")
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Keyboard.h"
|
||||||
|
|
||||||
#include "wayland-client.h"
|
#include "wayland-client.h"
|
||||||
|
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
class WaylandKeyboard
|
class WaylandKeyboard : public Keyboard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WaylandKeyboard(wl_keyboard* keyboard);
|
WaylandKeyboard(wl_keyboard* keyboard);
|
||||||
|
|
||||||
~WaylandKeyboard();
|
~WaylandKeyboard();
|
||||||
|
|
||||||
|
std::string getKeyString(KeyCode keyCode) override { return "";};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void keyboardKeymapEvent(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size);
|
static void keyboardKeymapEvent(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size);
|
||||||
static void keyboardEnterEvent(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys);
|
static void keyboardEnterEvent(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys);
|
||||||
|
|
|
@ -17,7 +17,7 @@ std::unique_ptr<KeyboardEvent> XcbEventInterface::ConvertKeyPress(xcb_key_press_
|
||||||
{
|
{
|
||||||
auto ui_event = KeyboardEvent::Create();
|
auto ui_event = KeyboardEvent::Create();
|
||||||
ui_event->SetAction(KeyboardEvent::Action::Pressed);
|
ui_event->SetAction(KeyboardEvent::Action::Pressed);
|
||||||
ui_event->SetKeyString(keyboard->GetKeyString(event->detail));
|
ui_event->SetKeyString(keyboard->getKeyString(event->detail));
|
||||||
return ui_event;
|
return ui_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ std::unique_ptr<KeyboardEvent> XcbEventInterface::ConvertKeyRelease(xcb_key_pres
|
||||||
{
|
{
|
||||||
auto ui_event = KeyboardEvent::Create();
|
auto ui_event = KeyboardEvent::Create();
|
||||||
ui_event->SetAction(KeyboardEvent::Action::Released);
|
ui_event->SetAction(KeyboardEvent::Action::Released);
|
||||||
ui_event->SetKeyString(keyboard->GetKeyString(event->detail));
|
ui_event->SetKeyString(keyboard->getKeyString(event->detail));
|
||||||
return ui_event;
|
return ui_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
src/windows/ui_interfaces/x11/XcbExtensionInterface.cpp
Normal file
41
src/windows/ui_interfaces/x11/XcbExtensionInterface.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include "XcbExtensionInterface.h"
|
||||||
|
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
// Header is c-like, uses explicit as a var
|
||||||
|
#define explicit explicit_
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
#undef explicit
|
||||||
|
|
||||||
|
void XcbExtensionInterface::initialize(xcb_connection_t* connection)
|
||||||
|
{
|
||||||
|
xcb_prefetch_extension_data(connection, &xcb_xkb_id);
|
||||||
|
|
||||||
|
const auto reply = xcb_get_extension_data(connection, &xcb_xkb_id);
|
||||||
|
if (!reply || !reply->present)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("XKB extension not found on server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cookie = xcb_xkb_use_extension(connection, 1, 0);
|
||||||
|
auto extension_reply = xcb_xkb_use_extension_reply(connection, cookie, nullptr);
|
||||||
|
if (!extension_reply)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("XKB extension not found on server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!extension_reply->supported)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("XKB extension version not found on server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mXkbEventFlag = reply->first_event;
|
||||||
|
mHasXkb = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XcbExtensionInterface::isXkBEvent(unsigned responseType) const
|
||||||
|
{
|
||||||
|
return mHasXkb && mXkbEventFlag == responseType;
|
||||||
|
}
|
20
src/windows/ui_interfaces/x11/XcbExtensionInterface.h
Normal file
20
src/windows/ui_interfaces/x11/XcbExtensionInterface.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
class XcbExtensionInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void initialize(xcb_connection_t* connection);
|
||||||
|
|
||||||
|
bool isXkBEvent(unsigned responseType) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mHasXkb{false};
|
||||||
|
uint8_t mXkbEventFlag{0};
|
||||||
|
//std::unordered_map<std::string, xcb_extension_t> mExtensions;
|
||||||
|
};
|
|
@ -4,8 +4,14 @@
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xlib-xcb.h> /* for XGetXCBConnection, link with libX11-xcb */
|
#include <X11/Xlib-xcb.h> /* for XGetXCBConnection, link with libX11-xcb */
|
||||||
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
#include <xcb/xcb.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 "PaintEvent.h"
|
||||||
#include "ResizeEvent.h"
|
#include "ResizeEvent.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -14,17 +20,35 @@
|
||||||
#include "UiEvent.h"
|
#include "UiEvent.h"
|
||||||
#include "XcbKeyboard.h"
|
#include "XcbKeyboard.h"
|
||||||
#include "XcbWindow.h"
|
#include "XcbWindow.h"
|
||||||
|
|
||||||
#include "XcbEventInterface.h"
|
#include "XcbEventInterface.h"
|
||||||
#include "XcbGlInterface.h"
|
#include "XcbGlInterface.h"
|
||||||
|
#include "XcbExtensionInterface.h"
|
||||||
|
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "FontsManager.h"
|
#include "FontsManager.h"
|
||||||
|
|
||||||
#include <iostream>
|
#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)
|
XcbInterface::XcbInterface(DesktopManager* desktopManager, std::unique_ptr<FontsManager> fontsManager, bool useHardware)
|
||||||
: AbstractUIInterface(desktopManager, std::move(fontsManager), 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();
|
initializeHardwareRendering();
|
||||||
}
|
}
|
||||||
mDesktopManager->setKeyboard(XcbKeyboard::Create());
|
|
||||||
|
mExtensionInterface->initialize(mConnection);
|
||||||
|
mDesktopManager->setKeyboard(XcbKeyboard::Create(mConnection));
|
||||||
|
|
||||||
const auto num_windows = mDesktopManager->getWindowManager()->getNumWindows();
|
const auto num_windows = mDesktopManager->getWindowManager()->getNumWindows();
|
||||||
for(std::size_t idx=0; idx< num_windows; idx++)
|
for(std::size_t idx=0; idx< num_windows; idx++)
|
||||||
|
@ -178,6 +204,7 @@ void XcbInterface::loop()
|
||||||
xcb_generic_event_t *event;
|
xcb_generic_event_t *event;
|
||||||
while ((event = xcb_wait_for_event(mConnection)))
|
while ((event = xcb_wait_for_event(mConnection)))
|
||||||
{
|
{
|
||||||
|
auto handled = true;
|
||||||
switch (event->response_type & ~0x80)
|
switch (event->response_type & ~0x80)
|
||||||
{
|
{
|
||||||
case XCB_EXPOSE:{
|
case XCB_EXPOSE:{
|
||||||
|
@ -235,9 +262,23 @@ void XcbInterface::loop()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* Unknown event type, ignore it */
|
handled = false;
|
||||||
break;
|
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);
|
free(event);
|
||||||
mDesktopManager->onLoopIteration();
|
mDesktopManager->onLoopIteration();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ using XcbEventInterfacePtr = std::unique_ptr<XcbEventInterface>;
|
||||||
class XcbWindowInterface;
|
class XcbWindowInterface;
|
||||||
using XcbWindowInterfacePtr = std::unique_ptr<XcbWindowInterface>;
|
using XcbWindowInterfacePtr = std::unique_ptr<XcbWindowInterface>;
|
||||||
|
|
||||||
|
class XcbExtensionInterface;
|
||||||
|
|
||||||
struct xcb_connection_t;
|
struct xcb_connection_t;
|
||||||
struct xcb_expose_event_t;
|
struct xcb_expose_event_t;
|
||||||
struct _XDisplay;
|
struct _XDisplay;
|
||||||
|
@ -55,4 +57,5 @@ private:
|
||||||
_XDisplay* mX11Display{nullptr};
|
_XDisplay* mX11Display{nullptr};
|
||||||
XcbGlInterfacePtr mGlInterface;
|
XcbGlInterfacePtr mGlInterface;
|
||||||
XcbEventInterfacePtr mEventInterface;
|
XcbEventInterfacePtr mEventInterface;
|
||||||
|
std::unique_ptr<XcbExtensionInterface> mExtensionInterface;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,25 +1,83 @@
|
||||||
#include "XcbKeyboard.h"
|
#include "XcbKeyboard.h"
|
||||||
|
|
||||||
XcbKeyboard::XcbKeyboard()
|
// Header is c-like, uses explicit as a var
|
||||||
: Keyboard()
|
#define explicit explicit_
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
#undef explicit
|
||||||
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
|
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
XcbKeyboard::XcbKeyboard(xcb_connection_t* connection)
|
||||||
|
: Keyboard(),
|
||||||
|
mConnection(connection)
|
||||||
{
|
{
|
||||||
mKeyMap = {{10, "1"}, {11, "2"}, {12, "3"}, {13, "4"}, {14, "5"}, {15, "6"},
|
mXkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
{16, "7"}, {17, "8"}, {18, "9"}, {19, "0"}, {20, "-"}, {21, "+"}, {22, "KEY_BACK"},
|
if (!mXkbContext)
|
||||||
{24, "q"}, {25, "w"}, {26, "e"}, {27, "r"}, {28, "t"}, {29, "y"},
|
{
|
||||||
{30, "u"}, {31, "i"}, {32, "o"}, {33, "p"}, {34, "["}, {35, "]"}, {36, "KEY_RETURN"},
|
MLOG_ERROR("Failed to get XKB context");
|
||||||
{38, "a"}, {39, "s"}, {40, "d"}, {41, "f"}, {42, "g"}, {43, "h"},
|
}
|
||||||
{44, "j"}, {45, "k"}, {46, "l"}, {47, ":"}, {48, "'"}, {49, "#"},
|
|
||||||
{52, "z"}, {53, "x"}, {54, "c"}, {55, "v"}, {56, "b"},
|
|
||||||
{57, "n"}, {58, "m"}, {59, ","}, {60, "."}, {61, "/"},
|
|
||||||
{65, "KEY_SPACE"}, {66, "KEY_CAPS"}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<XcbKeyboard> XcbKeyboard::Create()
|
std::unique_ptr<XcbKeyboard> XcbKeyboard::Create(xcb_connection_t* connection)
|
||||||
{
|
{
|
||||||
return std::make_unique<XcbKeyboard>();
|
return std::make_unique<XcbKeyboard>(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XcbKeyboard::GetKeyString(KeyCode keyCode)
|
void XcbKeyboard::updateState(xcb_xkb_state_notify_event_t *state)
|
||||||
{
|
{
|
||||||
return mKeyMap[keyCode];
|
xkb_state_update_mask(mXkbState, state->baseMods,
|
||||||
|
state->latchedMods,
|
||||||
|
state->lockedMods,
|
||||||
|
state->baseGroup,
|
||||||
|
state->latchedGroup,
|
||||||
|
state->lockedGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string XcbKeyboard::getKeyString(KeyCode keyCode)
|
||||||
|
{
|
||||||
|
if (!mXkbState)
|
||||||
|
{
|
||||||
|
getKeyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size = xkb_state_key_get_utf8(mXkbState, keyCode, nullptr, 0) + 1;
|
||||||
|
if (size <= 1)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[size];
|
||||||
|
xkb_state_key_get_utf8(mXkbState, keyCode, buffer, size);
|
||||||
|
|
||||||
|
std::string ret(buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XcbKeyboard::getKeyMap()
|
||||||
|
{
|
||||||
|
auto device_id = xkb_x11_get_core_keyboard_device_id(mConnection);
|
||||||
|
if (device_id == -1)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Failed to get connection for keymap");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto xkb_keymap = xkb_x11_keymap_new_from_device(mXkbContext, mConnection, device_id, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
|
struct xkb_state* xkb_state = xkb_x11_state_new_from_device(xkb_keymap, mConnection, device_id);
|
||||||
|
xkb_keymap_unref(mXkbKeymap);
|
||||||
|
xkb_state_unref(mXkbState);
|
||||||
|
mXkbKeymap = xkb_keymap;
|
||||||
|
mXkbState = xkb_state;
|
||||||
|
|
||||||
|
xcb_xkb_select_events_details_t details;
|
||||||
|
auto cookie = xcb_xkb_select_events(mConnection, XCB_XKB_ID_USE_CORE_KBD,
|
||||||
|
XCB_XKB_EVENT_TYPE_STATE_NOTIFY, 0, XCB_XKB_EVENT_TYPE_STATE_NOTIFY, 0, 0, &details);
|
||||||
|
|
||||||
|
// Check errors
|
||||||
|
auto error = xcb_request_check(mConnection, cookie);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Failed to select XKB events");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
struct xcb_xkb_state_notify_event_t;
|
||||||
|
|
||||||
class XcbKeyboard : public Keyboard
|
class XcbKeyboard : public Keyboard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XcbKeyboard();
|
XcbKeyboard(xcb_connection_t* connection);
|
||||||
|
|
||||||
static std::unique_ptr<XcbKeyboard> Create();
|
static std::unique_ptr<XcbKeyboard> Create(xcb_connection_t* connection);
|
||||||
|
|
||||||
std::string GetKeyString(KeyCode keyCode) override;
|
std::string getKeyString(KeyCode keyCode) override;
|
||||||
|
|
||||||
|
void updateState(xcb_xkb_state_notify_event_t *state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getKeyMap();
|
||||||
|
|
||||||
|
xcb_connection_t* mConnection{nullptr};
|
||||||
|
xkb_state* mXkbState{nullptr};
|
||||||
|
xkb_context* mXkbContext{nullptr};
|
||||||
|
xkb_keymap* mXkbKeymap{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
using XcbKeyboardUPtr = std::unique_ptr<XcbKeyboard>;
|
using XcbKeyboardUPtr = std::unique_ptr<XcbKeyboard>;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "FontsManager.h"
|
#include "FontsManager.h"
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_atom.h>
|
||||||
|
|
||||||
XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection, XcbGlInterface* xcbGlInterface)
|
XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection, XcbGlInterface* xcbGlInterface)
|
||||||
: IPlatformWindow(window),
|
: IPlatformWindow(window),
|
||||||
|
@ -50,6 +51,13 @@ void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen
|
||||||
xcb_screen->GetNativeScreen()->root_visual, /* visual */
|
xcb_screen->GetNativeScreen()->root_visual, /* visual */
|
||||||
mask, values ); /* masks */
|
mask, values ); /* masks */
|
||||||
|
|
||||||
|
if (!window->getTitle().empty())
|
||||||
|
{
|
||||||
|
auto title = window->getTitle();
|
||||||
|
xcb_change_property (connection, XCB_PROP_MODE_REPLACE, hwnd, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title.size(), title.c_str());
|
||||||
|
//xcb_change_property (connection, XCB_PROP_MODE_REPLACE, hwnd, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, title.size(), title.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
auto xcb_window = std::make_unique<XcbWindow>(window, hwnd, connection, xcbGlInterface);
|
auto xcb_window = std::make_unique<XcbWindow>(window, hwnd, connection, xcbGlInterface);
|
||||||
|
|
||||||
const auto drawing_mode = xcbGlInterface ? DrawingMode::GRAPH : DrawingMode::RASTER;
|
const auto drawing_mode = xcbGlInterface ? DrawingMode::GRAPH : DrawingMode::RASTER;
|
||||||
|
|
Loading…
Reference in a new issue