diff --git a/include/windowsys/IWindow.hpp b/include/windowsys/IWindow.hpp index d100bec..0179f0d 100644 --- a/include/windowsys/IWindow.hpp +++ b/include/windowsys/IWindow.hpp @@ -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) diff --git a/libBoo.pro b/libBoo.pro index eaa9eb4..3107cc3 100644 --- a/libBoo.pro +++ b/libBoo.pro @@ -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 diff --git a/src/CApplicationXCB.hpp b/src/CApplicationXCB.hpp index 8c1f907..91bb205 100644 --- a/src/CApplicationXCB.hpp +++ b/src/CApplicationXCB.hpp @@ -9,15 +9,25 @@ #include #include #include +#include #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); } diff --git a/src/inputdev/CHIDListenerUdev.cpp b/src/inputdev/CHIDListenerUdev.cpp index eba7e61..5fbbffb 100644 --- a/src/inputdev/CHIDListenerUdev.cpp +++ b/src/inputdev/CHIDListenerUdev.cpp @@ -2,6 +2,7 @@ #include "inputdev/CDeviceFinder.hpp" #include #include +#include #include 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); diff --git a/src/windowsys/CWindowXCB.cpp b/src/windowsys/CWindowXCB.cpp index 6bccc60..64fce35 100644 --- a/src/windowsys/CWindowXCB.cpp +++ b/src/windowsys/CWindowXCB.cpp @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include #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); } diff --git a/test/main.cpp b/test/main.cpp index badad65..12ed06f 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -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; }