diff --git a/src/lib/barrier/ClientApp.cpp b/src/lib/barrier/ClientApp.cpp index 17de18e7..15416f60 100644 --- a/src/lib/barrier/ClientApp.cpp +++ b/src/lib/barrier/ClientApp.cpp @@ -167,6 +167,7 @@ ClientApp::createScreen() false, args().m_noHooks, args().m_stopOnDeskSwitch, m_events), m_events); #elif WINAPI_XWINDOWS return new barrier::Screen(new XWindowsScreen( + new XWindowsImpl(), args().m_display, false, args().m_disableXInitThreads, args().m_yscroll, m_events), m_events); #elif WINAPI_CARBON diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index ff98cc1e..32966bbd 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -590,6 +590,7 @@ ServerApp::createScreen() true, args().m_noHooks, args().m_stopOnDeskSwitch, m_events), m_events); #elif WINAPI_XWINDOWS return new barrier::Screen(new XWindowsScreen( + new XWindowsImpl(), args().m_display, true, args().m_disableXInitThreads, 0, m_events), m_events); #elif WINAPI_CARBON return new barrier::Screen(new OSXScreen(m_events, true), m_events); diff --git a/src/lib/platform/IXWindowsImpl.h b/src/lib/platform/IXWindowsImpl.h new file mode 100644 index 00000000..263f5a6f --- /dev/null +++ b/src/lib/platform/IXWindowsImpl.h @@ -0,0 +1,191 @@ + +#pragma once + +#include "config.h" + +#if X_DISPLAY_MISSING +# error X11 is required to build barrier +#else +# include +# include +# define XK_MISCELLANY +# define XK_XKB_KEYS +# include +# if HAVE_X11_EXTENSIONS_DPMS_H + extern "C" { +# include + } +# endif +# if HAVE_X11_EXTENSIONS_XTEST_H +# include +# else +# error The XTest extension is required to build barrier +# endif +# if HAVE_X11_EXTENSIONS_XINERAMA_H + // Xinerama.h may lack extern "C" for inclusion by C++ + extern "C" { +# include + } +# endif +# if HAVE_X11_EXTENSIONS_XRANDR_H +# include +# endif +# if HAVE_XKB_EXTENSION +# include +# endif +# ifdef HAVE_XI2 +# include +# endif +#endif + +class IXWindowsImpl { +public: + + virtual Status XInitThreads() = 0; + virtual XIOErrorHandler XSetIOErrorHandler(XIOErrorHandler handler) = 0; + virtual Window do_DefaultRootWindow(Display* display) = 0; + virtual int XCloseDisplay(Display* display) = 0; + virtual int XTestGrabControl(Display* display, Bool impervious) = 0; + virtual void XDestroyIC(XIC ic) = 0; + virtual Status XCloseIM(XIM im) = 0; + virtual int XDestroyWindow(Display* display, Window w) = 0; + virtual int XGetKeyboardControl(Display* display, + XKeyboardState* value_return) = 0; + virtual int XMoveWindow(Display* display, Window w, int x, int y) = 0; + virtual int XMapRaised(Display* display, Window w) = 0; + virtual void XUnsetICFocus(XIC ic) = 0; + virtual int XUnmapWindow(Display* display, Window w) = 0; + virtual int XSetInputFocus(Display* display, Window focus, int revert_to, + Time time) = 0; + virtual Bool DPMSQueryExtension(Display* display, int* event_base, + int* error_base) = 0; + virtual Bool DPMSCapable(Display* display) = 0; + virtual Status DPMSInfo(Display* display, CARD16* power_level, + BOOL* state) = 0; + virtual Status DPMSForceLevel(Display* display, CARD16 level) =0; + virtual int XGetInputFocus(Display* display, Window* focus_return, + int* revert_to_return) = 0; + virtual void XSetICFocus(XIC ic) = 0; + virtual Bool XQueryPointer(Display* display, Window w, Window* root_return, + Window* child_return, int* root_x_return, + int* root_y_return, int* win_x_return, + int* win_y_return, unsigned int* mask_return) =0; + virtual void XLockDisplay(Display* display) = 0; + virtual Bool XCheckMaskEvent(Display* display, long event_mask, + XEvent* event_return) = 0; + virtual XModifierKeymap* XGetModifierMapping(Display* display) = 0; + virtual int XGrabKey(Display* display, int keycode, unsigned int modifiers, + Window grab_window, int owner_events, int pointer_made, + int keyboard_mode) = 0; + virtual int XFreeModifiermap(XModifierKeymap* modmap) = 0; + virtual int XUngrabKey(Display* display, int keycode, + unsigned int modifiers, Window grab_window) = 0; + virtual int XTestFakeButtonEvent(Display* display, unsigned int button, + int is_press, unsigned long delay) = 0; + virtual int XFlush(Display* display) = 0; + virtual int XWarpPointer(Display* display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y) = 0; + virtual int XTestFakeRelativeMotionEvent(Display* display, int x, int y, + unsigned long delay) = 0; + virtual KeyCode XKeysymToKeycode(Display* display, KeySym keysym) = 0; + virtual int XTestFakeKeyEvent(Display* display, unsigned int keycode, + int is_press, unsigned long delay) = 0; + virtual Display* XOpenDisplay(_Xconst char* display_name) = 0; + virtual Bool XQueryExtension(Display* display, const char* name, + int* major_opcode_return, + int* first_event_return, + int* first_error_return) = 0; + virtual Bool XkbLibraryVersion(int* libMajorRtrn, int* libMinorRtrn) = 0; + virtual Bool XkbQueryExtension(Display* display, int* opcodeReturn, + int* eventBaseReturn, int* errorBaseReturn, + int* majorRtrn, int* minorRtrn) = 0; + virtual Bool XkbSelectEvents(Display* display, unsigned int deviceID, + unsigned int affect, unsigned int values) = 0; + virtual Bool XkbSelectEventDetails(Display* display, unsigned int deviceID, + unsigned int eventType, + unsigned long affect, + unsigned long details) = 0; + virtual Bool XRRQueryExtension(Display* display, int* event_base_return, + int* error_base_return) = 0; + virtual void XRRSelectInput(Display *display, Window window, int mask) = 0; + virtual Bool XineramaQueryExtension(Display* display, int* event_base, + int* error_base) = 0; + virtual Bool XineramaIsActive(Display* display) = 0; + virtual void* XineramaQueryScreens(Display* display, + int* number) = 0; + virtual Window XCreateWindow(Display* display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, + unsigned int klass, Visual* visual, + unsigned long valuemask, + XSetWindowAttributes* attributes) = 0; + virtual XIM XOpenIM(Display* display, _XrmHashBucketRec* rdb, + char* res_name, char* res_class) = 0; + virtual char* XGetIMValues(XIM im, const char* type, void* ptr) = 0; + virtual XIC XCreateIC(XIM im, const char* type1, unsigned long data1, + const char* type2, unsigned long data2) = 0; + virtual char* XGetICValues(XIC ic, const char* type, + unsigned long* mask) = 0; + virtual Status XGetWindowAttributes(Display* display, Window w, + XWindowAttributes* attrs) = 0; + virtual int XSelectInput(Display* display, Window w, long event_mask) = 0; + virtual Bool XCheckIfEvent(Display* display, XEvent* event, + Bool (*predicate)(Display *, XEvent *, XPointer), + XPointer arg) = 0; + virtual Bool XFilterEvent(XEvent* event, Window window) = 0; + virtual Bool XGetEventData(Display* display, + XGenericEventCookie* cookie) = 0; + virtual void XFreeEventData(Display* display, + XGenericEventCookie* cookie) = 0; + virtual int XDeleteProperty(Display* display, Window w, Atom property) = 0; + virtual int XResizeWindow(Display* display, Window w, unsigned int width, + unsigned int height) = 0; + virtual int XMaskEvent(Display* display, long event_mask, + XEvent* event_return) = 0; + virtual Status XQueryBestCursor(Display* display, Drawable d, + unsigned int width, unsigned int height, + unsigned int* width_return, + unsigned int* height_return) = 0; + virtual Pixmap XCreateBitmapFromData(Display* display, Drawable d, + const char* data, unsigned int width, + unsigned int height) = 0; + virtual Cursor XCreatePixmapCursor(Display* display, + Pixmap source, Pixmap mask, + XColor* foreground_color, + XColor* background_color, + unsigned int x, unsigned int y) = 0; + virtual int XFreePixmap(Display* display, Pixmap pixmap) = 0; + virtual Status XQueryTree(Display* display, Window w, Window* root_return, + Window* parent_return, Window** children_return, + unsigned int* nchildren_return) = 0; + virtual int XmbLookupString(XIC ic, XKeyPressedEvent* event, + char* buffer_return, int bytes_buffer, + KeySym* keysym_return, int* status_return) = 0; + virtual int XLookupString(XKeyEvent* event_struct, char* buffer_return, + int bytes_buffer, KeySym* keysym_return, + XComposeStatus* status_in_out) = 0; + + virtual Status XSendEvent(Display* display, Window w, Bool propagate, + long event_mask, XEvent* event_send) = 0; + virtual int XSync(Display* display, Bool discard) = 0; + virtual int XGetPointerMapping(Display* display, unsigned char* map_return, + int nmap) = 0; + virtual int XGrabKeyboard(Display* display, Window grab_window, + Bool owner_events, int pointer_mode, + int keyboard_mode, Time time) = 0; + virtual int XGrabPointer(Display* display, Window grab_window, + Bool owner_events, unsigned int event_mask, + int pointer_mode, int keyboard_mode, + Window confine_to, Cursor cursor, Time time) = 0; + virtual int XUngrabKeyboard(Display* display, Time time) = 0; + virtual int XPending(Display* display) = 0; + virtual int XPeekEvent(Display* display, XEvent* event_return) = 0; + virtual Status XkbRefreshKeyboardMapping(XkbMapNotifyEvent* event) = 0; + virtual int XRefreshKeyboardMapping(XMappingEvent* event_map) = 0; + virtual int XISelectEvents(Display* display, Window w, XIEventMask* masks, + int num_masks) = 0; + + +}; diff --git a/src/lib/platform/XWindowsImpl.cpp b/src/lib/platform/XWindowsImpl.cpp new file mode 100644 index 00000000..bf6bb99c --- /dev/null +++ b/src/lib/platform/XWindowsImpl.cpp @@ -0,0 +1,489 @@ + +#include "XWindowsImpl.h" + +Status XWindowsImpl::XInitThreads() +{ + return ::XInitThreads(); +} + +XIOErrorHandler XWindowsImpl::XSetIOErrorHandler(XIOErrorHandler handler) +{ + return ::XSetIOErrorHandler(handler); +} + +Window XWindowsImpl::do_DefaultRootWindow(Display* display) +{ + return DefaultRootWindow(display); +} + +int XWindowsImpl::XCloseDisplay(Display* display) +{ + return ::XCloseDisplay(display); +} + +int XWindowsImpl::XTestGrabControl(Display *display, int impervious) +{ + return ::XTestGrabControl(display, impervious); +} + +void XWindowsImpl::XDestroyIC(XIC ic) +{ + ::XDestroyIC(ic); +} + +Status XWindowsImpl::XCloseIM(XIM im) +{ + return ::XCloseIM(im); +} + +int XWindowsImpl::XDestroyWindow(Display* display, Window w) +{ + return ::XDestroyWindow(display, w); +} + +int XWindowsImpl::XGetKeyboardControl(Display* display, + XKeyboardState* value_return) +{ + return ::XGetKeyboardControl(display, value_return); +} + +int XWindowsImpl::XMoveWindow(Display* display, Window w, int x, int y) +{ + return ::XMoveWindow(display, w, x, y); +} + +int XWindowsImpl::XMapRaised(Display* display, Window w) +{ + return ::XMapRaised(display, w); +} + +void XWindowsImpl::XUnsetICFocus(XIC ic) +{ + ::XUnsetICFocus(ic); +} + +int XWindowsImpl::XUnmapWindow(Display* display, Window w) +{ + return ::XUnmapWindow(display, w); +} + +int XWindowsImpl::XSetInputFocus(Display* display, Window focus, + int revert_to, Time time) +{ + return ::XSetInputFocus(display, focus, revert_to, time); +} + +Bool XWindowsImpl::DPMSQueryExtension(Display* display, int* event_base, + int* error_base) +{ + return ::DPMSQueryExtension(display, event_base, error_base); +} + +Bool XWindowsImpl::DPMSCapable(Display* display) +{ + return ::DPMSCapable(display); +} + +Status XWindowsImpl::DPMSInfo(Display* display, CARD16* power_level, + BOOL* state) +{ + return ::DPMSInfo(display, power_level, state); +} + +Status XWindowsImpl::DPMSForceLevel(Display* display, CARD16 level) +{ + return ::DPMSForceLevel(display,level); +} + +int XWindowsImpl::XGetInputFocus(Display* display, Window* focus_return, + int* revert_to_return) +{ + return ::XGetInputFocus(display, focus_return, revert_to_return); +} + + +void XWindowsImpl::XSetICFocus(XIC ic) +{ + ::XSetICFocus(ic); +} + +Bool XWindowsImpl::XQueryPointer(Display* display, Window w, + Window* root_return, Window* child_return, + int* root_x_return, int* root_y_return, + int* win_x_return, int* win_y_return, + unsigned int* mask_return) +{ + return ::XQueryPointer(display, w, root_return, child_return, root_x_return, + root_y_return, win_x_return, win_y_return, + mask_return); +} + +void XWindowsImpl::XLockDisplay(Display* display) +{ + ::XLockDisplay(display); +} + +Bool XWindowsImpl::XCheckMaskEvent(Display* display, long event_mask, + XEvent* event_return) +{ + return ::XCheckMaskEvent(display,event_mask, event_return); +} + +XModifierKeymap* XWindowsImpl::XGetModifierMapping(Display* display) +{ + return ::XGetModifierMapping(display); +} + +int XWindowsImpl::XGrabKey(Display* display, int keycode, + unsigned int modifiers, Window grab_window, + int owner_events, int pointer_made, + int keyboard_mode) +{ + return ::XGrabKey(display, keycode, modifiers, grab_window, owner_events, + pointer_made, keyboard_mode); +} + +int XWindowsImpl::XFreeModifiermap(XModifierKeymap* modmap) +{ + return ::XFreeModifiermap(modmap); +} + +int XWindowsImpl::XUngrabKey(Display* display, int keycode, + unsigned int modifiers, Window grab_window) +{ + return ::XUngrabKey(display, keycode, modifiers, grab_window); +} + +int XWindowsImpl::XTestFakeButtonEvent(Display* display, unsigned int button, + int is_press, unsigned long delay) +{ + return ::XTestFakeButtonEvent(display, button, is_press, delay); +} + +int XWindowsImpl::XFlush(Display* display) +{ + return ::XFlush(display); +} + +int XWindowsImpl::XWarpPointer(Display* display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y) +{ + return ::XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, + src_height, dest_x, dest_y); +} + +int XWindowsImpl::XTestFakeRelativeMotionEvent(Display* display, int x, int y, + unsigned long delay) +{ + return ::XTestFakeRelativeMotionEvent(display, x, y, delay); +} + +KeyCode XWindowsImpl::XKeysymToKeycode(Display* display, KeySym keysym) +{ + return ::XKeysymToKeycode(display, keysym); +} + +int XWindowsImpl::XTestFakeKeyEvent(Display* display, unsigned int keycode, + int is_press, unsigned long delay) +{ + return ::XTestFakeKeyEvent(display, keycode, is_press, delay); +} + +Display* XWindowsImpl::XOpenDisplay(_Xconst char* display_name) +{ + return ::XOpenDisplay(display_name); +} + +Bool XWindowsImpl::XQueryExtension(Display* display, const char* name, + int* major_opcode_return, + int* first_event_return, + int* first_error_return) +{ + return ::XQueryExtension(display, name, major_opcode_return, + first_event_return, first_error_return); +} + +Bool XWindowsImpl::XkbLibraryVersion(int* libMajorRtrn, int* libMinorRtrn) +{ + return ::XkbLibraryVersion(libMajorRtrn, libMinorRtrn); +} + +Bool XWindowsImpl::XkbQueryExtension(Display* display, int* opcodeReturn, + int* eventBaseReturn, int* errorBaseReturn, + int* majorRtrn, int* minorRtrn) +{ + return ::XkbQueryExtension(display, opcodeReturn, eventBaseReturn, + errorBaseReturn, majorRtrn, minorRtrn); +} + + +Bool XWindowsImpl::XkbSelectEvents(Display* display, unsigned int deviceID, + unsigned int affect, unsigned int values) +{ + return ::XkbSelectEvents(display, deviceID, affect, values); +} + +Bool XWindowsImpl::XkbSelectEventDetails(Display* display, unsigned int deviceID, + unsigned int eventType, + unsigned long affect, + unsigned long details) +{ + return ::XkbSelectEventDetails(display, deviceID, eventType, affect, details); +} + +Bool XWindowsImpl::XRRQueryExtension(Display* display, int* event_base_return, + int* error_base_return) +{ +#if HAVE_X11_EXTENSIONS_XRANDR_H + return ::XRRQueryExtension(display, event_base_return, error_base_return); +#else + return false; +#endif +} + +void XWindowsImpl::XRRSelectInput(Display *display, Window window, int mask) +{ +#if HAVE_X11_EXTENSIONS_XRANDR_H + ::XRRSelectInput(display, window, mask); +#else + (void) display; (void) window; (void) mask; +#endif +} + +Bool XWindowsImpl::XineramaQueryExtension(Display* display, int* event_base, + int* error_base) +{ +#if HAVE_X11_EXTENSIONS_XINERAMA_H + return ::XineramaQueryExtension(display, event_base, error_base); +#else + return false; +#endif +} + +Bool XWindowsImpl::XineramaIsActive(Display* display) +{ +#if HAVE_X11_EXTENSIONS_XINERAMA_H + return ::XineramaIsActive(display); +#else + return false; +#endif +} + +void* XWindowsImpl::XineramaQueryScreens(Display* display, + int* number) +{ +#if HAVE_X11_EXTENSIONS_XINERAMA_H + return ::XineramaQueryScreens(display, number); +#else + nullptr; +#endif +} + +Window XWindowsImpl::XCreateWindow(Display* display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, + unsigned int klass, Visual* visual, + unsigned long valuemask, + XSetWindowAttributes* attributes) +{ + return ::XCreateWindow(display, parent, x, y, width, height, border_width, + depth, klass, visual, valuemask, attributes); +} + +XIM XWindowsImpl::XOpenIM(Display* display, _XrmHashBucketRec* rdb, + char* res_name, char* res_class) +{ + return ::XOpenIM(display, rdb, res_name, res_class); +} + +char* XWindowsImpl::XGetIMValues(XIM im, const char* type, void* ptr) +{ + return ::XGetIMValues(im, type, ptr, nullptr); +} + +XIC XWindowsImpl::XCreateIC(XIM im, const char* type1, unsigned long data, + const char* type2, unsigned long data2) +{ + return ::XCreateIC(im, type1, data, type2, data2, nullptr); +} + +char* XWindowsImpl::XGetICValues(XIC ic, const char* type, unsigned long* mask) +{ + return ::XGetICValues(ic, type, mask, nullptr); +} + +Status XWindowsImpl::XGetWindowAttributes(Display* display, Window w, + XWindowAttributes* attrs) +{ + return ::XGetWindowAttributes(display, w, attrs); +} + +int XWindowsImpl::XSelectInput(Display* display, Window w, long event_mask) +{ + return ::XSelectInput(display, w, event_mask); +} + +Bool XWindowsImpl::XCheckIfEvent(Display* display, XEvent* event, + Bool (*predicate)(Display *, XEvent *, XPointer), + XPointer arg) +{ + return ::XCheckIfEvent(display, event, predicate, arg); +} + +Bool XWindowsImpl::XFilterEvent(XEvent* event, Window window) +{ + return ::XFilterEvent(event, window); +} + +Bool XWindowsImpl::XGetEventData(Display* display, + XGenericEventCookie* cookie) +{ + return ::XGetEventData(display, cookie); +} + +void XWindowsImpl::XFreeEventData(Display* display, + XGenericEventCookie* cookie) +{ + ::XFreeEventData(display, cookie); +} + +int XWindowsImpl::XDeleteProperty(Display* display, Window w, Atom property) +{ + return ::XDeleteProperty(display, w, property); +} + +int XWindowsImpl::XResizeWindow(Display* display, Window w, unsigned int width, + unsigned int height) +{ + return ::XResizeWindow(display, w, width, height); +} + +int XWindowsImpl::XMaskEvent(Display* display, long event_mask, + XEvent* event_return) +{ + return ::XMaskEvent(display, event_mask, event_return); +} + +Status XWindowsImpl::XQueryBestCursor(Display* display, Drawable d, + unsigned int width, unsigned int height, + unsigned int* width_return, + unsigned int* height_return) +{ + return ::XQueryBestCursor(display, d, width, height, width_return, + height_return); +} + +Pixmap XWindowsImpl::XCreateBitmapFromData(Display* display, Drawable d, + const char* data, unsigned int width, + unsigned int height) +{ + return ::XCreateBitmapFromData(display, d, data, width, height); +} + +Cursor XWindowsImpl::XCreatePixmapCursor(Display* display, + Pixmap source, Pixmap mask, + XColor* foreground_color, + XColor* background_color, + unsigned int x, unsigned int y) +{ + return ::XCreatePixmapCursor(display, source, mask, foreground_color, + background_color, x, y); +} + +int XWindowsImpl::XFreePixmap(Display* display, Pixmap pixmap) +{ + return ::XFreePixmap(display, pixmap); +} + +Status XWindowsImpl::XQueryTree(Display* display, Window w, Window* root_return, + Window* parent_return, Window** children_return, + unsigned int* nchildren_return) +{ + return ::XQueryTree(display, w, root_return, parent_return, children_return, + nchildren_return); +} + +int XWindowsImpl::XmbLookupString(XIC ic, XKeyPressedEvent* event, + char* buffer_return, int bytes_buffer, + KeySym* keysym_return, int* status_return) +{ + return ::XmbLookupString(ic, event, buffer_return, bytes_buffer, + keysym_return, status_return); +} + +int XWindowsImpl::XLookupString(XKeyEvent* event_struct, char* buffer_return, + int bytes_buffer, KeySym* keysym_return, + XComposeStatus* status_in_out) +{ + return ::XLookupString(event_struct, buffer_return, bytes_buffer, + keysym_return, status_in_out); +} + +Status XWindowsImpl::XSendEvent(Display* display, Window w, Bool propagate, + long event_mask, XEvent* event_send) +{ + return ::XSendEvent(display, w, propagate, event_mask, event_send); +} + +int XWindowsImpl::XSync(Display* display, Bool discard) +{ + return ::XSync(display, discard); +} + +int XWindowsImpl::XGetPointerMapping(Display* display, + unsigned char* map_return, int nmap) +{ + return ::XGetPointerMapping(display, map_return, nmap); +} + +int XWindowsImpl::XGrabKeyboard(Display* display, Window grab_window, + Bool owner_events, int pointer_mode, + int keyboard_mode, Time time) +{ + return ::XGrabKeyboard(display, grab_window, owner_events, pointer_mode, + keyboard_mode, time); +} + +int XWindowsImpl::XGrabPointer(Display* display, Window grab_window, + Bool owner_events, unsigned int event_mask, + int pointer_mode, int keyboard_mode, + Window confine_to, Cursor cursor, Time time) +{ + return ::XGrabPointer(display, grab_window, owner_events, event_mask, + pointer_mode, keyboard_mode, confine_to, cursor, + time); +} + +int XWindowsImpl::XUngrabKeyboard(Display* display, Time time) +{ + return ::XUngrabKeyboard(display, time); +} + +int XWindowsImpl::XPending(Display* display) +{ + return ::XPending(display); +} + +int XWindowsImpl::XPeekEvent(Display* display, XEvent* event_return) +{ + return ::XPeekEvent(display, event_return); +} + +Status XWindowsImpl::XkbRefreshKeyboardMapping(XkbMapNotifyEvent* event) +{ + return ::XkbRefreshKeyboardMapping(event); +} + +int XWindowsImpl::XRefreshKeyboardMapping(XMappingEvent* event_map) +{ + return ::XRefreshKeyboardMapping(event_map); +} + +int XWindowsImpl::XISelectEvents(Display* display, Window w, XIEventMask* masks, + int num_masks) +{ + return ::XISelectEvents(display, w, masks, num_masks); +} + diff --git a/src/lib/platform/XWindowsImpl.h b/src/lib/platform/XWindowsImpl.h new file mode 100644 index 00000000..32131be9 --- /dev/null +++ b/src/lib/platform/XWindowsImpl.h @@ -0,0 +1,152 @@ + +#pragma once + +#include "IXWindowsImpl.h" + +class XWindowsImpl : public IXWindowsImpl { +public: + + virtual Status XInitThreads(); + virtual XIOErrorHandler XSetIOErrorHandler(XIOErrorHandler handler); + virtual Window do_DefaultRootWindow(Display* display); + virtual int XCloseDisplay(Display* display); + virtual int XTestGrabControl(Display* display, Bool impervious); + virtual void XDestroyIC(XIC ic); + virtual Status XCloseIM(XIM im); + virtual int XDestroyWindow(Display* display, Window w); + virtual int XGetKeyboardControl(Display* display, + XKeyboardState* value_return); + virtual int XMoveWindow(Display* display, Window w, int x, int y); + virtual int XMapRaised(Display* display, Window w); + virtual void XUnsetICFocus(XIC ic); + virtual int XUnmapWindow(Display* display, Window w); + virtual int XSetInputFocus(Display* display, Window focus, int revert_to, + Time time); + virtual Bool DPMSQueryExtension(Display* display, int* event_base, + int* error_base); + virtual Bool DPMSCapable(Display* display); + virtual Status DPMSInfo(Display* display, CARD16* power_level, BOOL* state); + virtual Status DPMSForceLevel(Display* display, CARD16 level); + virtual int XGetInputFocus(Display* display, Window* focus_return, + int* revert_to_return); + virtual void XSetICFocus(XIC ic); + virtual Bool XQueryPointer(Display* display, Window w, Window* root_return, + Window* child_return, int* root_x_return, + int* root_y_return, int* win_x_return, + int* win_y_return, unsigned int* mask_return); + virtual void XLockDisplay(Display* display); + virtual Bool XCheckMaskEvent(Display* display, long event_mask, + XEvent* event_return); + virtual XModifierKeymap* XGetModifierMapping(Display* display); + virtual int XGrabKey(Display* display, int keycode, unsigned int modifiers, + Window grab_window, int owner_events, int pointer_made, + int keyboard_mode); + virtual int XFreeModifiermap(XModifierKeymap* modmap); + virtual int XUngrabKey(Display* display, int keycode, + unsigned int modifiers, Window grab_window); + virtual int XTestFakeButtonEvent(Display* display, unsigned int button, + int is_press, unsigned long delay); + virtual int XFlush(Display* display); + virtual int XWarpPointer(Display* display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y); + virtual int XTestFakeRelativeMotionEvent(Display* display, int x, int y, + unsigned long delay); + virtual KeyCode XKeysymToKeycode(Display* display, KeySym keysym); + virtual int XTestFakeKeyEvent(Display* display, unsigned int keycode, + int is_press, unsigned long delay); + virtual Display* XOpenDisplay(_Xconst char* display_name); + virtual Bool XQueryExtension(Display* display, const char* name, + int* major_opcode_return, + int* first_event_return, + int* first_error_return); + virtual Bool XkbLibraryVersion(int* libMajorRtrn, int* libMinorRtrn); + virtual Bool XkbQueryExtension(Display* display, int* opcodeReturn, + int* eventBaseReturn, int* errorBaseReturn, + int* majorRtrn, int* minorRtrn); + virtual Bool XkbSelectEvents(Display* display, unsigned int deviceID, + unsigned int affect, unsigned int values); + virtual Bool XkbSelectEventDetails(Display* display, unsigned int deviceID, + unsigned int eventType, + unsigned long affect, + unsigned long details); + virtual Bool XRRQueryExtension(Display* display, int* event_base_return, + int* error_base_return); + virtual void XRRSelectInput(Display *display, Window window, int mask); + virtual Bool XineramaQueryExtension(Display* display, int* event_base, + int* error_base); + virtual Bool XineramaIsActive(Display* display); + virtual void* XineramaQueryScreens(Display* display, + int* number); + virtual Window XCreateWindow(Display* display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, + unsigned int klass, Visual* visual, + unsigned long valuemask, + XSetWindowAttributes* attributes); + virtual XIM XOpenIM(Display* display, _XrmHashBucketRec* rdb, + char* res_name, char* res_class); + virtual char* XGetIMValues(XIM im, const char* type, void* ptr); + virtual XIC XCreateIC(XIM im, const char* type1, unsigned long data1, + const char* type2, unsigned long data2); + virtual char* XGetICValues(XIC ic, const char* type, unsigned long* mask); + virtual Status XGetWindowAttributes(Display* display, Window w, + XWindowAttributes* attrs); + virtual int XSelectInput(Display* display, Window w, long event_mask); + virtual Bool XCheckIfEvent(Display* display, XEvent* event, + Bool (*predicate)(Display *, XEvent *, XPointer), + XPointer arg); + virtual Bool XFilterEvent(XEvent* event, Window window); + virtual Bool XGetEventData(Display* display, + XGenericEventCookie* cookie); + virtual void XFreeEventData(Display* display, + XGenericEventCookie* cookie); + virtual int XDeleteProperty(Display* display, Window w, Atom property); + virtual int XResizeWindow(Display* display, Window w, unsigned int width, + unsigned int height); + virtual int XMaskEvent(Display* display, long event_mask, + XEvent* event_return); + virtual Status XQueryBestCursor(Display* display, Drawable d, + unsigned int width, unsigned int height, + unsigned int* width_return, + unsigned int* height_return); + virtual Pixmap XCreateBitmapFromData(Display* display, Drawable d, + const char* data, unsigned int width, + unsigned int height); + virtual Cursor XCreatePixmapCursor(Display* display, + Pixmap source, Pixmap mask, + XColor* foreground_color, + XColor* background_color, + unsigned int x, unsigned int y); + virtual int XFreePixmap(Display* display, Pixmap pixmap); + virtual Status XQueryTree(Display* display, Window w, Window* root_return, + Window* parent_return, Window** children_return, + unsigned int* nchildren_return); + virtual int XmbLookupString(XIC ic, XKeyPressedEvent* event, + char* buffer_return, int bytes_buffer, + KeySym* keysym_return, int* status_return); + virtual int XLookupString(XKeyEvent* event_struct, char* buffer_return, + int bytes_buffer, KeySym* keysym_return, + XComposeStatus* status_in_out); + virtual Status XSendEvent(Display* display, Window w, Bool propagate, + long event_mask, XEvent* event_send); + virtual int XSync(Display* display, Bool discard); + virtual int XGetPointerMapping(Display* display, unsigned char* map_return, + int nmap); + virtual int XGrabKeyboard(Display* display, Window grab_window, + Bool owner_events, int pointer_mode, + int keyboard_mode, Time time); + virtual int XGrabPointer(Display* display, Window grab_window, + Bool owner_events, unsigned int event_mask, + int pointer_mode, int keyboard_mode, + Window confine_to, Cursor cursor, Time time); + virtual int XUngrabKeyboard(Display* display, Time time); + virtual int XPending(Display* display); + virtual int XPeekEvent(Display* display, XEvent* event_return); + virtual Status XkbRefreshKeyboardMapping(XkbMapNotifyEvent* event); + virtual int XRefreshKeyboardMapping(XMappingEvent* event_map); + virtual int XISelectEvents(Display* display, Window w, XIEventMask* masks, + int num_masks); +}; + diff --git a/src/lib/platform/XWindowsScreen.cpp b/src/lib/platform/XWindowsScreen.cpp index 28464120..9d0b7c35 100644 --- a/src/lib/platform/XWindowsScreen.cpp +++ b/src/lib/platform/XWindowsScreen.cpp @@ -37,40 +37,6 @@ #include #include #include -#if X_DISPLAY_MISSING -# error X11 is required to build barrier -#else -# include -# include -# define XK_MISCELLANY -# define XK_XKB_KEYS -# include -# if HAVE_X11_EXTENSIONS_DPMS_H - extern "C" { -# include - } -# endif -# if HAVE_X11_EXTENSIONS_XTEST_H -# include -# else -# error The XTest extension is required to build barrier -# endif -# if HAVE_X11_EXTENSIONS_XINERAMA_H - // Xinerama.h may lack extern "C" for inclusion by C++ - extern "C" { -# include - } -# endif -# if HAVE_X11_EXTENSIONS_XRANDR_H -# include -# endif -# if HAVE_XKB_EXTENSION -# include -# endif -# ifdef HAVE_XI2 -# include -# endif -#endif static int xi_opcode; @@ -92,6 +58,7 @@ static int xi_opcode; XWindowsScreen* XWindowsScreen::s_screen = NULL; XWindowsScreen::XWindowsScreen( + IXWindowsImpl* impl, const char* displayName, bool isPrimary, bool disableXInitThreads, @@ -125,6 +92,7 @@ XWindowsScreen::XWindowsScreen( m_events(events), PlatformScreen(events) { + m_impl = impl; assert(s_screen == NULL); if (mouseScrollDelta==0) m_mouseScrollDelta=120; @@ -132,18 +100,18 @@ XWindowsScreen::XWindowsScreen( if (!disableXInitThreads) { // initializes Xlib support for concurrent threads. - if (XInitThreads() == 0) + if (m_impl->XInitThreads() == 0) throw XArch("XInitThreads() returned zero"); } else { LOG((CLOG_DEBUG "skipping XInitThreads()")); } // set the X I/O error handler so we catch the display disconnecting - XSetIOErrorHandler(&XWindowsScreen::ioErrorHandler); + m_impl->XSetIOErrorHandler(&XWindowsScreen::ioErrorHandler); try { m_display = openDisplay(displayName); - m_root = DefaultRootWindow(m_display); + m_root = m_impl->do_DefaultRootWindow(m_display); saveShape(); m_window = openWindow(); m_screensaver = new XWindowsScreenSaver(m_display, @@ -154,10 +122,10 @@ XWindowsScreen::XWindowsScreen( } catch (...) { if (m_display != NULL) { - XCloseDisplay(m_display); + m_impl->XCloseDisplay(m_display); } throw; - } + } // primary/secondary screen only initialization if (m_isPrimary) { @@ -177,7 +145,7 @@ XWindowsScreen::XWindowsScreen( } else { // become impervious to server grabs - XTestGrabControl(m_display, True); + m_impl->XTestGrabControl(m_display, True); } // initialize the clipboards @@ -205,24 +173,25 @@ XWindowsScreen::~XWindowsScreen() for (ClipboardID id = 0; id < kClipboardEnd; ++id) { delete m_clipboard[id]; } - delete m_keyState; + delete m_keyState; delete m_screensaver; m_keyState = NULL; m_screensaver = NULL; if (m_display != NULL) { // FIXME -- is it safe to clean up the IC and IM without a display? if (m_ic != NULL) { - XDestroyIC(m_ic); + m_impl->XDestroyIC(m_ic); } if (m_im != NULL) { - XCloseIM(m_im); + m_impl->XCloseIM(m_im); } - XDestroyWindow(m_display, m_window); - XCloseDisplay(m_display); + m_impl->XDestroyWindow(m_display, m_window); + m_impl->XCloseDisplay(m_display); } - XSetIOErrorHandler(NULL); + m_impl->XSetIOErrorHandler(NULL); s_screen = NULL; + delete m_impl; } void @@ -231,16 +200,16 @@ XWindowsScreen::enable() if (!m_isPrimary) { // get the keyboard control state XKeyboardState keyControl; - XGetKeyboardControl(m_display, &keyControl); + m_impl->XGetKeyboardControl(m_display, &keyControl); m_autoRepeat = (keyControl.global_auto_repeat == AutoRepeatModeOn); m_keyState->setAutoRepeat(keyControl); // move hider window under the cursor center - XMoveWindow(m_display, m_window, m_xCenter, m_yCenter); + m_impl->XMoveWindow(m_display, m_window, m_xCenter, m_yCenter); // raise and show the window // FIXME -- take focus? - XMapRaised(m_display, m_window); + m_impl->XMapRaised(m_display, m_window); // warp the mouse to the cursor center fakeMouseMove(m_xCenter, m_yCenter); @@ -252,12 +221,12 @@ XWindowsScreen::disable() { // release input context focus if (m_ic != NULL) { - XUnsetICFocus(m_ic); + m_impl->XUnsetICFocus(m_ic); } // unmap the hider/grab window. this also ungrabs the mouse and // keyboard if they're grabbed. - XUnmapWindow(m_display, m_window); + m_impl->XUnmapWindow(m_display, m_window); // restore auto-repeat state if (!m_isPrimary && m_autoRepeat) { @@ -272,14 +241,14 @@ XWindowsScreen::enter() // release input context focus if (m_ic != NULL) { - XUnsetICFocus(m_ic); + m_impl->XUnsetICFocus(m_ic); } // set the input focus to what it had been when we took it if (m_lastFocus != None) { // the window may not exist anymore so ignore errors XWindowsUtil::ErrorLock lock(m_display); - XSetInputFocus(m_display, m_lastFocus, m_lastFocusRevert, CurrentTime); + m_impl->XSetInputFocus(m_display, m_lastFocus, m_lastFocusRevert, CurrentTime); } #if HAVE_X11_EXTENSIONS_DPMS_H @@ -288,18 +257,18 @@ XWindowsScreen::enter() int dummy; CARD16 powerlevel; BOOL enabled; - if (DPMSQueryExtension(m_display, &dummy, &dummy) && - DPMSCapable(m_display) && - DPMSInfo(m_display, &powerlevel, &enabled)) + if (m_impl->DPMSQueryExtension(m_display, &dummy, &dummy) && + m_impl->DPMSCapable(m_display) && + m_impl->DPMSInfo(m_display, &powerlevel, &enabled)) { if (enabled && powerlevel != DPMSModeOn) - DPMSForceLevel(m_display, DPMSModeOn); + m_impl->DPMSForceLevel(m_display, DPMSModeOn); } #endif // unmap the hider/grab window. this also ungrabs the mouse and // keyboard if they're grabbed. - XUnmapWindow(m_display, m_window); + m_impl->XUnmapWindow(m_display, m_window); /* maybe call this if entering for the screensaver // set keyboard focus to root window. the screensaver should then @@ -310,7 +279,7 @@ XWindowsScreen::enter() if (!m_isPrimary) { // get the keyboard control state XKeyboardState keyControl; - XGetKeyboardControl(m_display, &keyControl); + m_impl->XGetKeyboardControl(m_display, &keyControl); m_autoRepeat = (keyControl.global_auto_repeat == AutoRepeatModeOn); m_keyState->setAutoRepeat(keyControl); @@ -338,24 +307,24 @@ XWindowsScreen::leave() } // move hider window under the cursor center - XMoveWindow(m_display, m_window, m_xCenter, m_yCenter); + m_impl->XMoveWindow(m_display, m_window, m_xCenter, m_yCenter); } // raise and show the window - XMapRaised(m_display, m_window); + m_impl->XMapRaised(m_display, m_window); // grab the mouse and keyboard, if primary and possible if (m_isPrimary && !grabMouseAndKeyboard()) { - XUnmapWindow(m_display, m_window); + m_impl->XUnmapWindow(m_display, m_window); return false; } // save current focus - XGetInputFocus(m_display, &m_lastFocus, &m_lastFocusRevert); + m_impl->XGetInputFocus(m_display, &m_lastFocus, &m_lastFocusRevert); // take focus if (m_isPrimary || !m_preserveFocus) { - XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime); + m_impl->XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime); } // now warp the mouse. we warp after showing the window so we're @@ -371,7 +340,7 @@ XWindowsScreen::leave() // set input context focus to our window if (m_ic != NULL) { XmbResetIC(m_ic); - XSetICFocus(m_ic); + m_impl->XSetICFocus(m_ic); m_filtered.clear(); } @@ -515,7 +484,7 @@ XWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const Window root, window; int mx, my, xWindow, yWindow; unsigned int mask; - if (XQueryPointer(m_display, m_root, &root, &window, + if (m_impl->XQueryPointer(m_display, m_root, &root, &window, &mx, &my, &xWindow, &yWindow, &mask)) { x = mx; y = my; @@ -540,7 +509,7 @@ XWindowsScreen::warpCursor(SInt32 x, SInt32 y) // remove all input events before and including warp XEvent event; - while (XCheckMaskEvent(m_display, PointerMotionMask | + while (m_impl->XCheckMaskEvent(m_display, PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | KeymapStateMask, @@ -609,7 +578,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) KeyModifierSuper }; - XModifierKeymap* modKeymap = XGetModifierMapping(m_display); + XModifierKeymap* modKeymap = m_impl->XGetModifierMapping(m_display); for (size_t j = 0; j < sizeof(s_hotKeyModifiers) / sizeof(s_hotKeyModifiers[0]) && !err; ++j) { // skip modifier if not in mask @@ -672,7 +641,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) for (int k = 0; k < modKeymap->max_keypermod && !err; ++k) { KeyCode code = modifiermap[k]; if (modifiermap[k] != 0) { - XGrabKey(m_display, code, modifiers2, m_root, + m_impl->XGrabKey(m_display, code, modifiers2, m_root, False, GrabModeAsync, GrabModeAsync); if (!err) { hotKeys.push_back(std::make_pair(code, modifiers2)); @@ -681,7 +650,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) } } } - XFreeModifiermap(modKeymap); + m_impl->XFreeModifiermap(modKeymap); } // a non-modifier key must be insensitive to CapsLock, NumLock and @@ -719,7 +688,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) } // add grab - XGrabKey(m_display, *j, tmpModifiers, m_root, + m_impl->XGrabKey(m_display, *j, tmpModifiers, m_root, False, GrabModeAsync, GrabModeAsync); if (!err) { hotKeys.push_back(std::make_pair(*j, tmpModifiers)); @@ -734,7 +703,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) // if any failed then unregister any we did get for (HotKeyList::iterator j = hotKeys.begin(); j != hotKeys.end(); ++j) { - XUngrabKey(m_display, j->first, j->second, m_root); + m_impl->XUngrabKey(m_display, j->first, j->second, m_root); m_hotKeyToIDMap.erase(HotKeyItem(j->first, j->second)); } @@ -764,7 +733,7 @@ XWindowsScreen::unregisterHotKey(UInt32 id) HotKeyList& hotKeys = i->second; for (HotKeyList::iterator j = hotKeys.begin(); j != hotKeys.end(); ++j) { - XUngrabKey(m_display, j->first, j->second, m_root); + m_impl->XUngrabKey(m_display, j->first, j->second, m_root); m_hotKeyToIDMap.erase(HotKeyItem(j->first, j->second)); } } @@ -805,7 +774,7 @@ XWindowsScreen::isAnyMouseButtonDown(UInt32& buttonID) const Window root, window; int xRoot, yRoot, xWindow, yWindow; unsigned int state; - if (XQueryPointer(m_display, m_root, &root, &window, + if (m_impl->XQueryPointer(m_display, m_root, &root, &window, &xRoot, &yRoot, &xWindow, &yWindow, &state)) { return ((state & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)) != 0); @@ -826,9 +795,9 @@ XWindowsScreen::fakeMouseButton(ButtonID button, bool press) { const unsigned int xButton = mapButtonToX(button); if (xButton > 0 && xButton < 11) { - XTestFakeButtonEvent(m_display, xButton, + m_impl->XTestFakeButtonEvent(m_display, xButton, press ? True : False, CurrentTime); - XFlush(m_display); + m_impl->XFlush(m_display); } } @@ -836,13 +805,13 @@ void XWindowsScreen::fakeMouseMove(SInt32 x, SInt32 y) { if (m_xinerama && m_xtestIsXineramaUnaware) { - XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); + m_impl->XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); } else { XTestFakeMotionEvent(m_display, DefaultScreen(m_display), x, y, CurrentTime); } - XFlush(m_display); + m_impl->XFlush(m_display); } void @@ -850,12 +819,12 @@ XWindowsScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const { // FIXME -- ignore xinerama for now if (false && m_xinerama && m_xtestIsXineramaUnaware) { -// XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); +// m_impl->XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); } else { - XTestFakeRelativeMotionEvent(m_display, dx, dy, CurrentTime); + m_impl->XTestFakeRelativeMotionEvent(m_display, dx, dy, CurrentTime); } - XFlush(m_display); + m_impl->XFlush(m_display); } void @@ -877,14 +846,14 @@ XWindowsScreen::fakeMouseWheel(SInt32, SInt32 yDelta) const // Patch by Tom Chadwick. KeyCode keycode = 0; if (yDelta >= 0) { - keycode = XKeysymToKeycode(m_display, XK_Page_Up); + keycode = m_impl->XKeysymToKeycode(m_display, XK_Page_Up); } else { - keycode = XKeysymToKeycode(m_display, XK_Page_Down); + keycode = m_impl->XKeysymToKeycode(m_display, XK_Page_Down); } if (keycode != 0) { - XTestFakeKeyEvent(m_display, keycode, True, CurrentTime); - XTestFakeKeyEvent(m_display, keycode, False, CurrentTime); + m_impl->XTestFakeKeyEvent(m_display, keycode, True, CurrentTime); + m_impl->XTestFakeKeyEvent(m_display, keycode, False, CurrentTime); } return; } @@ -893,11 +862,11 @@ XWindowsScreen::fakeMouseWheel(SInt32, SInt32 yDelta) const // send as many clicks as necessary for (; numEvents > 0; numEvents--) { - XTestFakeButtonEvent(m_display, xButton, True, CurrentTime); - XTestFakeButtonEvent(m_display, xButton, False, CurrentTime); + m_impl->XTestFakeButtonEvent(m_display, xButton, True, CurrentTime); + m_impl->XTestFakeButtonEvent(m_display, xButton, False, CurrentTime); } - XFlush(m_display); + m_impl->XFlush(m_display); } Display* @@ -913,7 +882,7 @@ XWindowsScreen::openDisplay(const char* displayName) // open the display LOG((CLOG_DEBUG "XOpenDisplay(\"%s\")", displayName)); - Display* display = XOpenDisplay(displayName); + Display* display = m_impl->XOpenDisplay(displayName); if (display == NULL) { throw XScreenUnavailable(60.0); } @@ -921,10 +890,10 @@ XWindowsScreen::openDisplay(const char* displayName) // verify the availability of the XTest extension if (!m_isPrimary) { int majorOpcode, firstEvent, firstError; - if (!XQueryExtension(display, XTestExtensionName, + if (!m_impl->XQueryExtension(display, XTestExtensionName, &majorOpcode, &firstEvent, &firstError)) { LOG((CLOG_ERR "XTEST extension not available")); - XCloseDisplay(display); + m_impl->XCloseDisplay(display); throw XScreenOpenFailure(); } } @@ -933,14 +902,14 @@ XWindowsScreen::openDisplay(const char* displayName) { m_xkb = false; int major = XkbMajorVersion, minor = XkbMinorVersion; - if (XkbLibraryVersion(&major, &minor)) { + if (m_impl->XkbLibraryVersion(&major, &minor)) { int opcode, firstError; - if (XkbQueryExtension(display, &opcode, &m_xkbEventBase, + if (m_impl->XkbQueryExtension(display, &opcode, &m_xkbEventBase, &firstError, &major, &minor)) { m_xkb = true; - XkbSelectEvents(display, XkbUseCoreKbd, + m_impl->XkbSelectEvents(display, XkbUseCoreKbd, XkbMapNotifyMask, XkbMapNotifyMask); - XkbSelectEventDetails(display, XkbUseCoreKbd, + m_impl->XkbSelectEventDetails(display, XkbUseCoreKbd, XkbStateNotifyMask, XkbGroupStateMask, XkbGroupStateMask); } @@ -951,10 +920,10 @@ XWindowsScreen::openDisplay(const char* displayName) #if HAVE_X11_EXTENSIONS_XRANDR_H // query for XRandR extension int dummyError; - m_xrandr = XRRQueryExtension(display, &m_xrandrEventBase, &dummyError); + m_xrandr = m_impl->XRRQueryExtension(display, &m_xrandrEventBase, &dummyError); if (m_xrandr) { // enable XRRScreenChangeNotifyEvent - XRRSelectInput(display, DefaultRootWindow(display), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask); + m_impl->XRRSelectInput(display, DefaultRootWindow(display), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask); } #endif @@ -991,11 +960,13 @@ XWindowsScreen::saveShape() m_xinerama = false; #if HAVE_X11_EXTENSIONS_XINERAMA_H int eventBase, errorBase; - if (XineramaQueryExtension(m_display, &eventBase, &errorBase) && - XineramaIsActive(m_display)) { + if (m_impl->XineramaQueryExtension(m_display, &eventBase, &errorBase) && + m_impl->XineramaIsActive(m_display)) { int numScreens; XineramaScreenInfo* screens; - screens = XineramaQueryScreens(m_display, &numScreens); + screens = reinterpret_cast( + XineramaQueryScreens(m_display, &numScreens)); + if (screens != NULL) { if (numScreens > 1) { m_xinerama = true; @@ -1049,7 +1020,7 @@ XWindowsScreen::openWindow() const } // create and return the window - Window window = XCreateWindow(m_display, m_root, x, y, w, h, 0, 0, + Window window = m_impl->XCreateWindow(m_display, m_root, x, y, w, h, 0, 0, InputOnly, CopyFromParent, CWDontPropagate | CWEventMask | CWOverrideRedirect | CWCursor, @@ -1064,7 +1035,7 @@ void XWindowsScreen::openIM() { // open the input methods - XIM im = XOpenIM(m_display, NULL, NULL, NULL); + XIM im = m_impl->XOpenIM(m_display, NULL, NULL, NULL); if (im == NULL) { LOG((CLOG_INFO "no support for IM")); return; @@ -1073,10 +1044,10 @@ XWindowsScreen::openIM() // find the appropriate style. barrier supports XIMPreeditNothing // only at the moment. XIMStyles* styles; - if (XGetIMValues(im, XNQueryInputStyle, &styles, NULL) != NULL || + if (m_impl->XGetIMValues(im, XNQueryInputStyle, &styles) != nullptr || styles == NULL) { LOG((CLOG_WARN "cannot get IM styles")); - XCloseIM(im); + m_impl->XCloseIM(im); return; } XIMStyle style = 0; @@ -1091,24 +1062,24 @@ XWindowsScreen::openIM() XFree(styles); if (style == 0) { LOG((CLOG_INFO "no supported IM styles")); - XCloseIM(im); + m_impl->XCloseIM(im); return; } // create an input context for the style and tell it about our window - XIC ic = XCreateIC(im, XNInputStyle, style, XNClientWindow, m_window, NULL); + XIC ic = m_impl->XCreateIC(im, XNInputStyle, style, XNClientWindow, m_window); if (ic == NULL) { LOG((CLOG_WARN "cannot create IC")); - XCloseIM(im); + m_impl->XCloseIM(im); return; } // find out the events we must select for and do so unsigned long mask; - if (XGetICValues(ic, XNFilterEvents, &mask, NULL) != NULL) { + if (m_impl->XGetICValues(ic, XNFilterEvents, &mask) != NULL) { LOG((CLOG_WARN "cannot get IC filter events")); - XDestroyIC(ic); - XCloseIM(im); + m_impl->XDestroyIC(ic); + m_impl->XCloseIM(im); return; } @@ -1119,8 +1090,8 @@ XWindowsScreen::openIM() // select events on our window that IM requires XWindowAttributes attr; - XGetWindowAttributes(m_display, m_window, &attr); - XSelectInput(m_display, m_window, attr.your_event_mask | mask); + m_impl->XGetWindowAttributes(m_display, m_window, &attr); + m_impl->XSelectInput(m_display, m_window, attr.your_event_mask | mask); } void @@ -1174,7 +1145,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) filter.m_time = xevent->xkey.time; filter.m_keycode = xevent->xkey.keycode; XEvent xevent2; - isRepeat = (XCheckIfEvent(m_display, &xevent2, + isRepeat = (m_impl->XCheckIfEvent(m_display, &xevent2, &XWindowsScreen::findKeyEvent, (XPointer)&filter) == True); } @@ -1219,7 +1190,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) } // now filter the event - if (XFilterEvent(xevent, DefaultRootWindow(m_display))) { + if (m_impl->XFilterEvent(xevent, DefaultRootWindow(m_display))) { if (xevent->type == KeyPress) { // add filtered presses to the filtered list m_filtered.insert(m_lastKeycode); @@ -1246,7 +1217,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) if (m_xi2detected) { // Process RawMotion XGenericEventCookie *cookie = (XGenericEventCookie*)&xevent->xcookie; - if (XGetEventData(m_display, cookie) && + if (m_impl->XGetEventData(m_display, cookie) && cookie->type == GenericEvent && cookie->extension == xi_opcode) { if (cookie->evtype == XI_RawMotion) { @@ -1259,7 +1230,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) xmotion.window = m_window; /* xmotion's time, state and is_hint are not used */ unsigned int msk; - xmotion.same_screen = XQueryPointer( + xmotion.same_screen = m_impl->XQueryPointer( m_display, m_root, &xmotion.root, &xmotion.subwindow, &xmotion.x_root, &xmotion.y_root, @@ -1267,10 +1238,10 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) &xmotion.y, &msk); onMouseMove(xmotion); - XFreeEventData(m_display, cookie); + m_impl->XFreeEventData(m_display, cookie); return; } - XFreeEventData(m_display, cookie); + m_impl->XFreeEventData(m_display, cookie); } } #endif @@ -1291,7 +1262,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) case LeaveNotify: if (!m_isPrimary) { // mouse moved out of hider window somehow. hide the window. - XUnmapWindow(m_display, m_window); + m_impl->XUnmapWindow(m_display, m_window); } break; @@ -1315,7 +1286,7 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) // retrieval methods. we'll just delete the property // with the data (satisfying the usual ICCCM protocol). if (xevent->xselection.property != None) { - XDeleteProperty(m_display, + m_impl->XDeleteProperty(m_display, xevent->xselection.requestor, xevent->xselection.property); } @@ -1417,8 +1388,8 @@ XWindowsScreen::handleSystemEvent(const Event& event, void*) // off the server onto the client causes the pointer to warp to the // center of the server (so you can't move the pointer off the server) if (m_isPrimary) { - XMoveWindow(m_display, m_window, m_x, m_y); - XResizeWindow(m_display, m_window, m_w, m_h); + m_impl->XMoveWindow(m_display, m_window, m_x, m_y); + m_impl->XResizeWindow(m_display, m_window, m_w, m_h); } sendEvent(m_events->forIScreen().shapeChanged()); @@ -1594,7 +1565,7 @@ XWindowsScreen::onMouseMove(const XMotionEvent& xmotion) XEvent xevent; char cntr = 0; do { - XMaskEvent(m_display, PointerMotionMask, &xevent); + m_impl->XMaskEvent(m_display, PointerMotionMask, &xevent); if (cntr++ > 10) { LOG((CLOG_WARN "too many discarded events! %d", cntr)); break; @@ -1656,7 +1627,7 @@ XWindowsScreen::createBlankCursor() const // get the closet cursor size to 1x1 unsigned int w = 0, h = 0; - XQueryBestCursor(m_display, m_root, 1, 1, &w, &h); + m_impl->XQueryBestCursor(m_display, m_root, 1, 1, &w, &h); w = std::max(1u, w); h = std::max(1u, h); @@ -1668,7 +1639,7 @@ XWindowsScreen::createBlankCursor() const memset(data, 0, size); // make bitmap - Pixmap bitmap = XCreateBitmapFromData(m_display, m_root, data, w, h); + Pixmap bitmap = m_impl->XCreateBitmapFromData(m_display, m_root, data, w, h); // need an arbitrary color for the cursor XColor color; @@ -1677,12 +1648,12 @@ XWindowsScreen::createBlankCursor() const color.flags = DoRed | DoGreen | DoBlue; // make cursor from bitmap - Cursor cursor = XCreatePixmapCursor(m_display, bitmap, bitmap, + Cursor cursor = m_impl->XCreatePixmapCursor(m_display, bitmap, bitmap, &color, &color, 0, 0); // don't need bitmap or the data anymore delete[] data; - XFreePixmap(m_display, bitmap); + m_impl->XFreePixmap(m_display, bitmap); return cursor; } @@ -1794,7 +1765,7 @@ XWindowsScreen::doSelectEvents(Window w) const // it already. long mask = SubstructureNotifyMask; XWindowAttributes attr; - XGetWindowAttributes(m_display, w, &attr); + m_impl->XGetWindowAttributes(m_display, w, &attr); if ((attr.all_event_masks & PointerMotionMask) == PointerMotionMask) { mask |= PointerMotionMask; } @@ -1802,12 +1773,12 @@ XWindowsScreen::doSelectEvents(Window w) const // select events of interest. do this before querying the tree so // we'll get notifications of children created after the XQueryTree() // so we won't miss them. - XSelectInput(m_display, w, mask); + m_impl->XSelectInput(m_display, w, mask); // recurse on child windows Window rw, pw, *cw; unsigned int nc; - if (XQueryTree(m_display, w, &rw, &pw, &cw, &nc)) { + if (m_impl->XQueryTree(m_display, w, &rw, &pw, &cw, &nc)) { for (unsigned int i = 0; i < nc; ++i) { doSelectEvents(cw[i]); } @@ -1827,11 +1798,11 @@ XWindowsScreen::mapKeyFromX(XKeyEvent* event) const int n = sizeof(scratch) / sizeof(scratch[0]); char* buffer = scratch; int status; - n = XmbLookupString(m_ic, event, buffer, n, &keysym, &status); + n = m_impl->XmbLookupString(m_ic, event, buffer, n, &keysym, &status); if (status == XBufferOverflow) { // not enough space. grow buffer and try again. buffer = new char[n]; - n = XmbLookupString(m_ic, event, buffer, n, &keysym, &status); + n = m_impl->XmbLookupString(m_ic, event, buffer, n, &keysym, &status); delete[] buffer; } @@ -1852,7 +1823,7 @@ XWindowsScreen::mapKeyFromX(XKeyEvent* event) const else { // plain old lookup char dummy[1]; - XLookupString(event, dummy, 0, &keysym, NULL); + m_impl->XLookupString(event, dummy, 0, &keysym, NULL); } LOG((CLOG_DEBUG2 "mapped code=%d to keysym=0x%04x", event->keycode, keysym)); @@ -1935,14 +1906,14 @@ XWindowsScreen::warpCursorNoFlush(SInt32 x, SInt32 y) eventBefore.xmotion.is_hint = NotifyNormal; eventBefore.xmotion.same_screen = True; XEvent eventAfter = eventBefore; - XSendEvent(m_display, m_window, False, 0, &eventBefore); + m_impl->XSendEvent(m_display, m_window, False, 0, &eventBefore); // warp mouse - XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); + m_impl->XWarpPointer(m_display, None, m_root, 0, 0, 0, 0, x, y); // send an event that we can recognize after the mouse warp - XSendEvent(m_display, m_window, False, 0, &eventAfter); - XSync(m_display, False); + m_impl->XSendEvent(m_display, m_window, False, 0, &eventAfter); + m_impl->XSync(m_display, False); LOG((CLOG_DEBUG2 "warped to %d,%d", x, y)); } @@ -1951,9 +1922,9 @@ void XWindowsScreen::updateButtons() { // query the button mapping - UInt32 numButtons = XGetPointerMapping(m_display, NULL, 0); + UInt32 numButtons = m_impl->XGetPointerMapping(m_display, NULL, 0); unsigned char* tmpButtons = new unsigned char[numButtons]; - XGetPointerMapping(m_display, tmpButtons, numButtons); + m_impl->XGetPointerMapping(m_display, tmpButtons, numButtons); // find the largest logical button id unsigned char maxButton = 0; @@ -1993,7 +1964,7 @@ XWindowsScreen::grabMouseAndKeyboard() do { // keyboard first do { - result = XGrabKeyboard(m_display, m_window, True, + result = m_impl->XGrabKeyboard(m_display, m_window, True, GrabModeAsync, GrabModeAsync, CurrentTime); assert(result != GrabNotViewable); if (result != GrabSuccess) { @@ -2008,13 +1979,13 @@ XWindowsScreen::grabMouseAndKeyboard() LOG((CLOG_DEBUG2 "grabbed keyboard")); // now the mouse --- use event_mask to get EnterNotify, LeaveNotify events - result = XGrabPointer(m_display, m_window, False, event_mask, + result = m_impl->XGrabPointer(m_display, m_window, False, event_mask, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); assert(result != GrabNotViewable); if (result != GrabSuccess) { // back off to avoid grab deadlock - XUngrabKeyboard(m_display, CurrentTime); + m_impl->XUngrabKeyboard(m_display, CurrentTime); LOG((CLOG_DEBUG2 "ungrabbed keyboard, waiting to grab pointer")); ARCH->sleep(0.05); if (timer.getTime() >= s_timeout) { @@ -2031,9 +2002,9 @@ XWindowsScreen::grabMouseAndKeyboard() void XWindowsScreen::refreshKeyboard(XEvent* event) { - if (XPending(m_display) > 0) { + if (m_impl->XPending(m_display) > 0) { XEvent tmpEvent; - XPeekEvent(m_display, &tmpEvent); + m_impl->XPeekEvent(m_display, &tmpEvent); if (tmpEvent.type == MappingNotify) { // discard this event since another follows. // we tend to get a bunch of these in a row. @@ -2044,12 +2015,12 @@ XWindowsScreen::refreshKeyboard(XEvent* event) // keyboard mapping changed #if HAVE_XKB_EXTENSION if (m_xkb && event->type == m_xkbEventBase) { - XkbRefreshKeyboardMapping((XkbMapNotifyEvent*)event); + m_impl->XkbRefreshKeyboardMapping((XkbMapNotifyEvent*)event); } else #else { - XRefreshKeyboardMapping(&event->xmapping); + m_impl->XRefreshKeyboardMapping(&event->xmapping); } #endif m_keyState->updateKeyMap(); @@ -2079,7 +2050,7 @@ bool XWindowsScreen::detectXI2() { int event, error; - return XQueryExtension(m_display, + return m_impl->XQueryExtension(m_display, "XInputExtension", &xi_opcode, &event, &error); } @@ -2096,7 +2067,7 @@ XWindowsScreen::selectXIRawMotion() memset(mask.mask, 0, 2); XISetMask(mask.mask, XI_RawKeyRelease); XISetMask(mask.mask, XI_RawMotion); - XISelectEvents(m_display, DefaultRootWindow(m_display), &mask, 1); + m_impl->XISelectEvents(m_display, DefaultRootWindow(m_display), &mask, 1); free(mask.mask); } #endif diff --git a/src/lib/platform/XWindowsScreen.h b/src/lib/platform/XWindowsScreen.h index a2e3495b..71340173 100644 --- a/src/lib/platform/XWindowsScreen.h +++ b/src/lib/platform/XWindowsScreen.h @@ -22,6 +22,7 @@ #include "barrier/KeyMap.h" #include "common/stdset.h" #include "common/stdvector.h" +#include "XWindowsImpl.h" #if X_DISPLAY_MISSING # error X11 is required to build barrier @@ -36,7 +37,7 @@ class XWindowsScreenSaver; //! Implementation of IPlatformScreen for X11 class XWindowsScreen : public PlatformScreen { public: - XWindowsScreen(const char* displayName, bool isPrimary, + XWindowsScreen(IXWindowsImpl* impl, const char* displayName, bool isPrimary, bool disableXInitThreads, int mouseScrollDelta, IEventQueue* events); virtual ~XWindowsScreen(); @@ -174,6 +175,8 @@ private: typedef std::vector HotKeyIDList; typedef std::map HotKeyToIDMap; + IXWindowsImpl* m_impl; + // true if screen is being used as a primary screen, false otherwise bool m_isPrimary;