Piotr Caban : winex11: Implement clipboard changes tracking using xfixes extension.
Alexandre Julliard
julliard at winehq.org
Wed May 24 17:17:34 CDT 2017
Module: wine
Branch: master
Commit: 22a75a8f077615f892d85761b88d90eba26f43ee
URL: http://source.winehq.org/git/wine.git/?a=commit;h=22a75a8f077615f892d85761b88d90eba26f43ee
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed May 24 15:17:57 2017 +0200
winex11: Implement clipboard changes tracking using xfixes extension.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winex11.drv/clipboard.c | 87 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 83 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 3c1f3b4..3da4081 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -78,12 +78,16 @@
#include <time.h>
#include <assert.h>
-#include "windef.h"
-#include "winbase.h"
+#include "x11drv.h"
+
+#ifdef HAVE_X11_EXTENSIONS_XFIXES_H
+#include <X11/extensions/Xfixes.h>
+#endif
+
#include "shlobj.h"
#include "shellapi.h"
#include "shlwapi.h"
-#include "x11drv.h"
+#include "wine/library.h"
#include "wine/list.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@@ -196,6 +200,7 @@ static UINT rendered_formats;
static ULONG64 last_clipboard_update;
static struct clipboard_format **current_x11_formats;
static unsigned int nb_current_x11_formats;
+static BOOL use_xfixes;
Display *clipboard_display = NULL;
@@ -1866,7 +1871,8 @@ static BOOL request_selection_contents( Display *display, BOOL changed )
last_size = size;
last_clipboard_update = GetTickCount64();
CloseClipboard();
- SetTimer( clipboard_hwnd, 1, SELECTION_UPDATE_DELAY, NULL );
+ if (!use_xfixes)
+ SetTimer( clipboard_hwnd, 1, SELECTION_UPDATE_DELAY, NULL );
return TRUE;
}
@@ -1878,6 +1884,7 @@ static BOOL request_selection_contents( Display *display, BOOL changed )
*/
BOOL update_clipboard( HWND hwnd )
{
+ if (use_xfixes) return TRUE;
if (hwnd != clipboard_hwnd) return TRUE;
if (!is_clipboard_owner) return TRUE;
if (GetTickCount64() - last_clipboard_update <= SELECTION_UPDATE_DELAY) return TRUE;
@@ -1947,6 +1954,75 @@ static BOOL wait_clipboard_mutex(void)
/**************************************************************************
+ * handle_selection_notify_event
+ *
+ * Called when x11 clipboard content changes
+ */
+static BOOL selection_notify_event( HWND hwnd, XEvent *event )
+{
+#ifdef SONAME_LIBXFIXES
+ XFixesSelectionNotifyEvent *req = (XFixesSelectionNotifyEvent*)event;
+
+ if (!is_clipboard_owner) return FALSE;
+ if (req->owner == selection_window) return FALSE;
+ request_selection_contents( req->display, TRUE );
+ return FALSE;
+#endif
+}
+
+/**************************************************************************
+ * xfixes_init
+ *
+ * Initialize xfixes to receive clipboard update notifications
+ */
+static void xfixes_init(void)
+{
+#ifdef SONAME_LIBXFIXES
+ typeof(XFixesSelectSelectionInput) *pXFixesSelectSelectionInput;
+ typeof(XFixesQueryExtension) *pXFixesQueryExtension;
+ typeof(XFixesQueryVersion) *pXFixesQueryVersion;
+
+ int event_base, error_base;
+ int major = 3, minor = 0;
+ void *handle;
+
+ handle = wine_dlopen(SONAME_LIBXFIXES, RTLD_NOW, NULL, 0);
+ if (!handle) return;
+
+ pXFixesQueryExtension = wine_dlsym(handle, "XFixesQueryExtension", NULL, 0);
+ if (!pXFixesQueryExtension) return;
+ pXFixesQueryVersion = wine_dlsym(handle, "XFixesQueryVersion", NULL, 0);
+ if (!pXFixesQueryVersion) return;
+ pXFixesSelectSelectionInput = wine_dlsym(handle, "XFixesSelectSelectionInput", NULL, 0);
+ if (!pXFixesSelectSelectionInput) return;
+
+ if (!pXFixesQueryExtension(clipboard_display, &event_base, &error_base))
+ return;
+ pXFixesQueryVersion(clipboard_display, &major, &minor);
+ use_xfixes = (major >= 1);
+ if (!use_xfixes) return;
+
+ pXFixesSelectSelectionInput(clipboard_display, import_window, x11drv_atom(CLIPBOARD),
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+ if (use_primary_selection)
+ {
+ pXFixesSelectSelectionInput(clipboard_display, import_window, XA_PRIMARY,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+ }
+ X11DRV_register_event_handler(event_base + XFixesSelectionNotify,
+ selection_notify_event, "XFixesSelectionNotify");
+ TRACE("xfixes succesully initialized\n");
+#else
+ WARN("xfixes not supported\n");
+#endif
+}
+
+
+/**************************************************************************
* clipboard_thread
*
* Thread running inside the desktop process to manage the clipboard
@@ -1991,6 +2067,8 @@ static DWORD WINAPI clipboard_thread( void *arg )
register_builtin_formats();
request_selection_contents( clipboard_display, TRUE );
+ xfixes_init();
+
TRACE( "clipboard thread %04x running\n", GetCurrentThreadId() );
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
return 0;
@@ -2006,6 +2084,7 @@ void CDECL X11DRV_UpdateClipboard(void)
ULONG now;
DWORD_PTR ret;
+ if (use_xfixes) return;
if (GetCurrentThreadId() == clipboard_thread_id) return;
now = GetTickCount();
if ((int)(now - last_update) <= SELECTION_UPDATE_DELAY) return;
More information about the wine-cvs
mailing list