mirror of
https://github.com/AxioDL/boo.git
synced 2025-05-15 11:51:27 +00:00
Added XInput event registration to XCB
This commit is contained in:
parent
a66469b991
commit
d0db7b080f
@ -77,7 +77,7 @@ public:
|
||||
{(void)coord;(void)button;(void)mods;}
|
||||
virtual void mouseMove(const SWindowCoord& coord)
|
||||
{(void)coord;}
|
||||
virtual void scroll(const SScrollDelta& scroll)
|
||||
virtual void scroll(const SWindowCoord& coord, const SScrollDelta& scroll)
|
||||
{(void)scroll;}
|
||||
|
||||
virtual void touchDown(const SWindowCoord& coord, uintptr_t tid)
|
||||
|
@ -1,9 +1,13 @@
|
||||
CONFIG -= Qt
|
||||
CONFIG += console
|
||||
QT =
|
||||
LIBS -= -lQtGui -lQtCore
|
||||
#CONFIG += console
|
||||
#QMAKE_CXXFLAGS -= -std=c++0x
|
||||
#CONFIG += c++11
|
||||
unix:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++
|
||||
unix:LIBS += -std=c++11 -stdlib=libc++ -lc++abi -lxcb -lxcb-glx -lxcb-xkb -lxcb-keysyms -lxkbcommon -lxkbcommon-x11
|
||||
unix:LIBS += -std=c++11 -stdlib=libc++ -lc++abi -lxcb \
|
||||
-lxcb-glx -lxcb-xkb -lxcb-xinput -lxcb-keysyms \
|
||||
-lxkbcommon -lxkbcommon-x11
|
||||
|
||||
win32:LIBS += Setupapi.lib winusb.lib User32.lib /SUBSYSTEM:Windows
|
||||
|
||||
|
@ -9,15 +9,25 @@
|
||||
#include <xcb/xcb_event.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
#include <xcb/xkb.h>
|
||||
#include <xcb/xinput.h>
|
||||
#undef explicit
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
||||
|
||||
int XINPUT_OPCODE = 0;
|
||||
|
||||
static xcb_window_t getWindowOfEvent(xcb_generic_event_t* event, bool& windowEvent)
|
||||
{
|
||||
switch (XCB_EVENT_RESPONSE_TYPE(event))
|
||||
{
|
||||
case XCB_CLIENT_MESSAGE:
|
||||
{
|
||||
xcb_client_message_event_t* ev = (xcb_client_message_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->window;
|
||||
}
|
||||
case XCB_EXPOSE:
|
||||
{
|
||||
xcb_expose_event_t* ev = (xcb_expose_event_t*)event;
|
||||
@ -34,31 +44,56 @@ static xcb_window_t getWindowOfEvent(xcb_generic_event_t* event, bool& windowEve
|
||||
{
|
||||
xcb_key_press_event_t* ev = (xcb_key_press_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->root;
|
||||
return ev->event;
|
||||
}
|
||||
case XCB_KEY_RELEASE:
|
||||
{
|
||||
xcb_key_release_event_t* ev = (xcb_key_release_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->root;
|
||||
return ev->event;
|
||||
}
|
||||
case XCB_BUTTON_PRESS:
|
||||
{
|
||||
xcb_button_press_event_t* ev = (xcb_button_press_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->root;
|
||||
return ev->event;
|
||||
}
|
||||
case XCB_BUTTON_RELEASE:
|
||||
{
|
||||
xcb_button_release_event_t* ev = (xcb_button_release_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->root;
|
||||
return ev->event;
|
||||
}
|
||||
case XCB_MOTION_NOTIFY:
|
||||
{
|
||||
xcb_motion_notify_event_t* ev = (xcb_motion_notify_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->root;
|
||||
return ev->event;
|
||||
}
|
||||
case XCB_GE_GENERIC:
|
||||
{
|
||||
xcb_ge_event_t* gev = (xcb_ge_event_t*)event;
|
||||
if (gev->pad0 == XINPUT_OPCODE)
|
||||
{
|
||||
fprintf(stderr, "INPUTEVENT\n");
|
||||
return 0;
|
||||
switch (XCB_EVENT_RESPONSE_TYPE(gev))
|
||||
{
|
||||
case XCB_INPUT_DEVICE_CHANGED:
|
||||
{
|
||||
xcb_input_device_changed_event_t* ev = (xcb_input_device_changed_event_t*)event;
|
||||
return 0;
|
||||
}
|
||||
case XCB_INPUT_DEVICE_MOTION_NOTIFY:
|
||||
{
|
||||
xcb_input_device_motion_notify_event_t* ev = (xcb_input_device_motion_notify_event_t*)event;
|
||||
windowEvent = true;
|
||||
return ev->event;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
windowEvent = false;
|
||||
@ -108,6 +143,10 @@ public:
|
||||
xcb_xkb_per_client_flags(m_xcbConn, XCB_XKB_ID_USE_CORE_KBD,
|
||||
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
|
||||
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, 0, 0, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
~CApplicationXCB()
|
||||
@ -125,6 +164,7 @@ public:
|
||||
xcb_generic_event_t* event;
|
||||
m_running = true;
|
||||
m_callback.appLaunched(this);
|
||||
xcb_flush(m_xcbConn);
|
||||
while (m_running && (event = xcb_wait_for_event(m_xcbConn)))
|
||||
{
|
||||
bool windowEvent;
|
||||
@ -132,9 +172,9 @@ public:
|
||||
fprintf(stderr, "EVENT %d\n", XCB_EVENT_RESPONSE_TYPE(event));
|
||||
if (windowEvent)
|
||||
{
|
||||
IWindow* window = m_windows[evWindow];
|
||||
if (window)
|
||||
window->_incomingEvent(event);
|
||||
auto window = m_windows.find(evWindow);
|
||||
if (window != m_windows.end())
|
||||
window->second->_incomingEvent(event);
|
||||
}
|
||||
free(event);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "inputdev/CDeviceFinder.hpp"
|
||||
#include <libudev.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <thread>
|
||||
|
||||
namespace boo
|
||||
@ -165,6 +166,8 @@ public:
|
||||
~CHIDListenerUdev()
|
||||
{
|
||||
m_udevRunning = false;
|
||||
//raise(SIGINT);
|
||||
pthread_kill(m_udevThread->native_handle(), SIGINT);
|
||||
m_udevThread->join();
|
||||
delete m_udevThread;
|
||||
udev_monitor_unref(m_udevMon);
|
||||
|
@ -7,8 +7,10 @@
|
||||
#include <xcb/xproto.h>
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <xcb/xinput.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define XK_MISCELLANY
|
||||
@ -77,46 +79,50 @@ static int translateModifiers(unsigned state)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int translateButton(unsigned state)
|
||||
static int translateButton(unsigned detail)
|
||||
{
|
||||
int retval = 0;
|
||||
if (state & XCB_BUTTON_MASK_1)
|
||||
if (detail == 1)
|
||||
retval = IWindowCallback::BUTTON_PRIMARY;
|
||||
else if (state & XCB_BUTTON_MASK_2)
|
||||
else if (detail == 3)
|
||||
retval = IWindowCallback::BUTTON_SECONDARY;
|
||||
else if (state & XCB_BUTTON_MASK_3)
|
||||
else if (detail == 2)
|
||||
retval = IWindowCallback::BUTTON_MIDDLE;
|
||||
else if (state & XCB_BUTTON_MASK_4)
|
||||
else if (detail == 8)
|
||||
retval = IWindowCallback::BUTTON_AUX1;
|
||||
else if (state & XCB_BUTTON_MASK_5)
|
||||
retval = IWindowCallback::BUTTON_AUX2;
|
||||
else if (detail == 9)
|
||||
retval =
|
||||
IWindowCallback::BUTTON_AUX2;
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define INTERN_ATOM(var, conn, name) \
|
||||
#define INTERN_ATOM(var, conn, name, if_exists) \
|
||||
do {\
|
||||
xcb_intern_atom_cookie_t cookie = \
|
||||
xcb_intern_atom(conn, 0, sizeof(#name), #name); \
|
||||
xcb_intern_atom(conn, if_exists, sizeof(#name), #name); \
|
||||
xcb_intern_atom_reply_t* reply = \
|
||||
xcb_intern_atom_reply(conn, cookie, NULL); \
|
||||
var = reply->atom; \
|
||||
free(reply); \
|
||||
/*free(reply);*/ \
|
||||
} while(0)
|
||||
|
||||
struct SXCBAtoms
|
||||
{
|
||||
xcb_atom_t m_wmProtocols = 0;
|
||||
xcb_atom_t m_wmDeleteWindow = 0;
|
||||
xcb_atom_t m_netwmState = 0;
|
||||
xcb_atom_t m_netwmStateFullscreen = 0;
|
||||
xcb_atom_t m_netwmStateAdd = 0;
|
||||
xcb_atom_t m_netwmStateRemove = 0;
|
||||
xcb_atom_t m_
|
||||
xcb_key_symbols_t* m_keySyms = NULL;
|
||||
SXCBAtoms(xcb_connection_t* conn)
|
||||
{
|
||||
INTERN_ATOM(m_netwmState, conn, _NET_WM_STATE);
|
||||
INTERN_ATOM(m_netwmStateFullscreen, conn, _NET_WM_STATE_FULLSCREEN);
|
||||
INTERN_ATOM(m_netwmStateAdd, conn, _NET_WM_STATE_ADD);
|
||||
INTERN_ATOM(m_netwmStateRemove, conn, _NET_WM_STATE_REMOVE);
|
||||
INTERN_ATOM(m_wmProtocols, conn, WM_PROTOCOLS, 1);
|
||||
INTERN_ATOM(m_wmDeleteWindow, conn, WM_DELETE_WINDOW, 1);
|
||||
INTERN_ATOM(m_netwmState, conn, _NET_WM_STATE, 0);
|
||||
INTERN_ATOM(m_netwmStateFullscreen, conn, _NET_WM_STATE_FULLSCREEN, 0);
|
||||
INTERN_ATOM(m_netwmStateAdd, conn, _NET_WM_STATE_ADD, 0);
|
||||
INTERN_ATOM(m_netwmStateRemove, conn, _NET_WM_STATE_REMOVE, 0);
|
||||
m_keySyms = xcb_key_symbols_alloc(conn);
|
||||
}
|
||||
};
|
||||
@ -138,7 +144,6 @@ IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
||||
|
||||
class CWindowXCB final : public IWindow
|
||||
{
|
||||
|
||||
xcb_connection_t* m_xcbConn;
|
||||
xcb_window_t m_windowId;
|
||||
IGraphicsContext* m_gfxCtx;
|
||||
@ -164,7 +169,6 @@ public:
|
||||
uint32_t visualId;
|
||||
m_gfxCtx = _CGraphicsContextXCBNew(IGraphicsContext::API_OPENGL_3_3, this, m_xcbConn, visualId);
|
||||
|
||||
|
||||
/* Create colormap */
|
||||
xcb_colormap_t colormap = xcb_generate_id(m_xcbConn);
|
||||
xcb_create_colormap(m_xcbConn, XCB_COLORMAP_ALLOC_NONE,
|
||||
@ -179,7 +183,7 @@ public:
|
||||
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
||||
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY | 0xFFFFFF,
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
|
||||
colormap,
|
||||
XCB_NONE
|
||||
};
|
||||
@ -190,6 +194,27 @@ public:
|
||||
XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
|
||||
valueMasks);
|
||||
|
||||
/* The XInput extension enables per-pixel smooth scrolling trackpads */
|
||||
struct
|
||||
{
|
||||
xcb_input_event_mask_t mask;
|
||||
uint32_t maskVal;
|
||||
} masks =
|
||||
{
|
||||
{XCB_INPUT_DEVICE_ALL_MASTER, 1},
|
||||
XCB_INPUT_XI_EVENT_MASK_MOTION
|
||||
};
|
||||
xcb_input_xi_select_events(m_xcbConn, m_windowId, 1, &masks.mask);
|
||||
|
||||
xcb_change_property(m_xcbConn, XCB_PROP_MODE_REPLACE, m_windowId, S_ATOMS->m_wmProtocols,
|
||||
XCB_ATOM_ATOM, 32, 1, &S_ATOMS->m_wmDeleteWindow);
|
||||
const xcb_atom_t wm_protocols[1] = {
|
||||
S_ATOMS->m_wmDeleteWindow,
|
||||
};
|
||||
xcb_change_property(m_xcbConn, XCB_PROP_MODE_REPLACE, m_windowId,
|
||||
S_ATOMS->m_wmProtocols, 4,
|
||||
32, 1, wm_protocols);
|
||||
|
||||
/* Set the title of the window */
|
||||
const char* c_title = title.c_str();
|
||||
xcb_change_property(m_xcbConn, XCB_PROP_MODE_REPLACE, m_windowId,
|
||||
@ -203,8 +228,9 @@ public:
|
||||
|
||||
/* Initialize context */
|
||||
xcb_map_window(m_xcbConn, m_windowId);
|
||||
m_gfxCtx->initializeContext();
|
||||
xcb_flush(m_xcbConn);
|
||||
|
||||
m_gfxCtx->initializeContext();
|
||||
}
|
||||
|
||||
~CWindowXCB()
|
||||
@ -323,7 +349,6 @@ public:
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
||||
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
|
||||
(const char*)&fsEvent);
|
||||
|
||||
}
|
||||
|
||||
uintptr_t getPlatformHandle() const
|
||||
@ -336,6 +361,14 @@ public:
|
||||
xcb_generic_event_t* event = (xcb_generic_event_t*)e;
|
||||
switch (XCB_EVENT_RESPONSE_TYPE(event))
|
||||
{
|
||||
case XCB_CLIENT_MESSAGE:
|
||||
{
|
||||
xcb_client_message_event_t* ev = (xcb_client_message_event_t*)event;
|
||||
if (ev->data.data32[0] == S_ATOMS->m_wmDeleteWindow)
|
||||
{
|
||||
fprintf(stderr, "CLOSED\n");
|
||||
}
|
||||
}
|
||||
case XCB_EXPOSE:
|
||||
{
|
||||
xcb_expose_event_t* ev = (xcb_expose_event_t*)event;
|
||||
@ -347,10 +380,13 @@ public:
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
{
|
||||
xcb_configure_notify_event_t* ev = (xcb_configure_notify_event_t*)event;
|
||||
m_wx = ev->x;
|
||||
m_wy = ev->y;
|
||||
m_ww = ev->width;
|
||||
m_wh = ev->height;
|
||||
if (ev->width && ev->height)
|
||||
{
|
||||
m_wx = ev->x;
|
||||
m_wy = ev->y;
|
||||
m_ww = ev->width;
|
||||
m_wh = ev->height;
|
||||
}
|
||||
}
|
||||
case XCB_KEY_PRESS:
|
||||
{
|
||||
@ -395,15 +431,15 @@ public:
|
||||
case XCB_BUTTON_PRESS:
|
||||
{
|
||||
xcb_button_press_event_t* ev = (xcb_button_press_event_t*)event;
|
||||
int button = translateButton(ev->state);
|
||||
int button = translateButton(ev->detail);
|
||||
if (m_callback && button)
|
||||
{
|
||||
int modifierMask = translateModifiers(ev->state);
|
||||
IWindowCallback::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)ev->root_x, (unsigned)ev->root_y},
|
||||
{(unsigned)(ev->root_x / m_pixelFactor), (unsigned)(ev->root_y / m_pixelFactor)},
|
||||
{ev->root_x / (float)m_ww, ev->root_y / (float)m_wh}
|
||||
{(unsigned)ev->event_x, (unsigned)ev->event_y},
|
||||
{(unsigned)(ev->event_x / m_pixelFactor), (unsigned)(ev->event_y / m_pixelFactor)},
|
||||
{ev->event_x / (float)m_ww, ev->event_y / (float)m_wh}
|
||||
};
|
||||
m_callback->mouseDown(coord, (IWindowCallback::EMouseButton)button,
|
||||
(IWindowCallback::EModifierKey)modifierMask);
|
||||
@ -412,15 +448,15 @@ public:
|
||||
case XCB_BUTTON_RELEASE:
|
||||
{
|
||||
xcb_button_release_event_t* ev = (xcb_button_release_event_t*)event;
|
||||
int button = translateButton(ev->state);
|
||||
int button = translateButton(ev->detail);
|
||||
if (m_callback && button)
|
||||
{
|
||||
int modifierMask = translateModifiers(ev->state);
|
||||
IWindowCallback::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)ev->root_x, (unsigned)ev->root_y},
|
||||
{(unsigned)(ev->root_x / m_pixelFactor), (unsigned)(ev->root_y / m_pixelFactor)},
|
||||
{ev->root_x / (float)m_ww, ev->root_y / (float)m_wh}
|
||||
{(unsigned)ev->event_x, (unsigned)ev->event_y},
|
||||
{(unsigned)(ev->event_x / m_pixelFactor), (unsigned)(ev->event_y / m_pixelFactor)},
|
||||
{ev->event_x / (float)m_ww, ev->event_y / (float)m_wh}
|
||||
};
|
||||
m_callback->mouseUp(coord, (IWindowCallback::EMouseButton)button,
|
||||
(IWindowCallback::EModifierKey)modifierMask);
|
||||
@ -433,9 +469,9 @@ public:
|
||||
{
|
||||
IWindowCallback::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)ev->root_x, (unsigned)ev->root_y},
|
||||
{(unsigned)(ev->root_x / m_pixelFactor), (unsigned)(ev->root_y / m_pixelFactor)},
|
||||
{ev->root_x / (float)m_ww, ev->root_y / (float)m_wh}
|
||||
{(unsigned)ev->event_x, (unsigned)ev->event_y},
|
||||
{(unsigned)(ev->event_x / m_pixelFactor), (unsigned)(ev->event_y / m_pixelFactor)},
|
||||
{ev->event_x / (float)m_ww, ev->event_y / (float)m_wh}
|
||||
};
|
||||
m_callback->mouseMove(coord);
|
||||
}
|
||||
|
@ -46,13 +46,76 @@ public:
|
||||
};
|
||||
|
||||
|
||||
struct CTestWindowCallback : public IWindowCallback
|
||||
{
|
||||
|
||||
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
|
||||
{
|
||||
fprintf(stderr, "Mouse Down %d (%f,%f)\n", button, coord.norm[0], coord.norm[1]);
|
||||
}
|
||||
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
|
||||
{
|
||||
fprintf(stderr, "Mouse Up %d (%f,%f)\n", button, coord.norm[0], coord.norm[1]);
|
||||
}
|
||||
void mouseMove(const SWindowCoord& coord)
|
||||
{
|
||||
//fprintf(stderr, "Mouse Move (%f,%f)\n", coord.norm[0], coord.norm[1]);
|
||||
}
|
||||
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll)
|
||||
{
|
||||
fprintf(stderr, "Mouse Move (%f,%f)\n", coord.norm[0], coord.norm[1]);
|
||||
}
|
||||
|
||||
void touchDown(const SWindowCoord& coord, uintptr_t tid)
|
||||
{
|
||||
|
||||
}
|
||||
void touchUp(const SWindowCoord& coord, uintptr_t tid)
|
||||
{
|
||||
|
||||
}
|
||||
void touchMove(const SWindowCoord& coord, uintptr_t tid)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat)
|
||||
{
|
||||
|
||||
}
|
||||
void charKeyUp(unsigned long charCode, EModifierKey mods)
|
||||
{
|
||||
|
||||
}
|
||||
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat)
|
||||
{
|
||||
|
||||
}
|
||||
void specialKeyUp(ESpecialKey key, EModifierKey mods)
|
||||
{
|
||||
|
||||
}
|
||||
void modKeyDown(EModifierKey mod, bool isRepeat)
|
||||
{
|
||||
|
||||
}
|
||||
void modKeyUp(EModifierKey mod)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct CTestApplicationCallback : public IApplicationCallback
|
||||
{
|
||||
IWindow* mainWindow = NULL;
|
||||
boo::CTestDeviceFinder devFinder;
|
||||
CTestWindowCallback windowCallback;
|
||||
void appLaunched(IApplication* app)
|
||||
{
|
||||
mainWindow = app->newWindow("YAY!");
|
||||
mainWindow->setCallback(&windowCallback);
|
||||
mainWindow->showWindow();
|
||||
devFinder.startScanning();
|
||||
}
|
||||
@ -75,6 +138,7 @@ int main(int argc, char** argv)
|
||||
boo::IApplication* app = IApplicationBootstrap(boo::IApplication::PLAT_AUTO, appCb, "RWK", argc, argv);
|
||||
app->run();
|
||||
delete app;
|
||||
printf("IM DYING!!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user