Added XInput event registration to XCB

This commit is contained in:
Jack Andersen 2015-05-11 23:38:37 -10:00
parent a66469b991
commit d0db7b080f
6 changed files with 194 additions and 47 deletions

View File

@ -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)

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -44,15 +44,78 @@ 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;
}