diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index f391992b7..d70dcda0c 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -891,6 +891,27 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) xevent->type, xevent->xany.display, xevent->xany.window); #endif +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + if (SDL_X11_HAVE_XFIXES && + xevent->type == X11_GetXFixesSelectionNotifyEvent()) { + XFixesSelectionNotifyEvent *ev = (XFixesSelectionNotifyEvent *) xevent; + + /* !!! FIXME: cache atoms */ + Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); + +#ifdef DEBUG_XEVENTS + printf("window CLIPBOARD: XFixesSelectionNotify (selection = %s)\n", + X11_XGetAtomName(display, ev->selection)); +#endif + + if (ev->selection == XA_PRIMARY || + (XA_CLIPBOARD != None && ev->selection == XA_CLIPBOARD)) { + SDL_SendClipboardUpdate(); + return; + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + if ((videodata->clipboard_window != None) && (videodata->clipboard_window == xevent->xany.window)) { X11_HandleClipboardEvent(_this, xevent); diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 0a5fe38d5..08447ebd4 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -170,6 +170,7 @@ SDL_X11_SYM(PointerBarrier, XFixesCreatePointerBarrier, (Display* a, Window b, i SDL_X11_SYM(void, XFixesDestroyPointerBarrier, (Display* a, PointerBarrier b), (a,b),) SDL_X11_SYM(int, XIBarrierReleasePointer,(Display* a, int b, PointerBarrier c, BarrierEventID d), (a,b,c,d), return) /* this is actually Xinput2 */ SDL_X11_SYM(Status, XFixesQueryVersion,(Display* a, int* b, int* c), (a,b,c), return) +SDL_X11_SYM(Status, XFixesSelectSelectionInput, (Display* a, Window b, Atom c, unsigned long d), (a,b,c,d), return) #endif #ifdef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS diff --git a/src/video/x11/SDL_x11xfixes.c b/src/video/x11/SDL_x11xfixes.c index 5c69eb140..28ea7a6ad 100644 --- a/src/video/x11/SDL_x11xfixes.c +++ b/src/video/x11/SDL_x11xfixes.c @@ -29,6 +29,7 @@ #include "../../events/SDL_touch_c.h" static int xfixes_initialized = 0; +static int xfixes_selection_notify_event = 0; static int query_xfixes_version(Display *display, int major, int minor) { @@ -50,11 +51,20 @@ void X11_InitXfixes(SDL_VideoDevice *_this) int event, error; int fixes_opcode; + Atom XA_CLIPBOARD = X11_XInternAtom(data->display, "CLIPBOARD", 0); + if (!SDL_X11_HAVE_XFIXES || !X11_XQueryExtension(data->display, "XFIXES", &fixes_opcode, &event, &error)) { return; } + /* Selection tracking is available in all versions of XFixes */ + xfixes_selection_notify_event = event + XFixesSelectionNotify; + X11_XFixesSelectSelectionInput(data->display, DefaultRootWindow(data->display), + XA_CLIPBOARD, XFixesSetSelectionOwnerNotifyMask); + X11_XFixesSelectSelectionInput(data->display, DefaultRootWindow(data->display), + XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask); + /* We need at least 5.0 for barriers. */ version = query_xfixes_version(data->display, 5, 0); if (!xfixes_version_atleast(version, 5, 0)) { @@ -69,6 +79,11 @@ int X11_XfixesIsInitialized(void) return xfixes_initialized; } +int X11_GetXFixesSelectionNotifyEvent() +{ + return xfixes_selection_notify_event; +} + void X11_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window) { if (SDL_RectEmpty(&window->mouse_rect)) { diff --git a/src/video/x11/SDL_x11xfixes.h b/src/video/x11/SDL_x11xfixes.h index 328fc5aae..2c9279450 100644 --- a/src/video/x11/SDL_x11xfixes.h +++ b/src/video/x11/SDL_x11xfixes.h @@ -33,7 +33,7 @@ extern int X11_XfixesIsInitialized(void); extern void X11_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window); extern int X11_ConfineCursorWithFlags(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rect, int flags); extern void X11_DestroyPointerBarrier(SDL_VideoDevice *_this, SDL_Window *window); - +extern int X11_GetXFixesSelectionNotifyEvent(void); #endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ #endif /* SDL_x11xfixes_h_ */