xwin: Use WM_CLIPBOARDUPDATE clipboard API
Windows Vista and later have a saner clipboard API where the clipboard viewer linked list is no longer maintained by applications. Use it where available. Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk> Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
This commit is contained in:
parent
de7f1fd6f8
commit
008efebda8
|
@ -77,6 +77,14 @@ typedef struct
|
|||
Atom atomTargets;
|
||||
} ClipboardAtoms;
|
||||
|
||||
/* Modern clipboard API functions */
|
||||
typedef wBOOL WINAPI (*ADDCLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
|
||||
typedef wBOOL WINAPI (*REMOVECLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
|
||||
|
||||
extern Bool g_fHasModernClipboardApi;
|
||||
extern ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
|
||||
extern REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
|
||||
|
||||
/*
|
||||
* winclipboardwndproc.c
|
||||
*/
|
||||
|
|
|
@ -84,6 +84,10 @@ static pthread_t g_winClipboardProcThread;
|
|||
int xfixes_event_base;
|
||||
int xfixes_error_base;
|
||||
|
||||
Bool g_fHasModernClipboardApi = FALSE;
|
||||
ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
|
||||
REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
|
||||
|
||||
/*
|
||||
* Local function prototypes
|
||||
*/
|
||||
|
@ -138,6 +142,11 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
|
|||
ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
|
||||
}
|
||||
|
||||
g_fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener");
|
||||
g_fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener");
|
||||
g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener;
|
||||
ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no");
|
||||
|
||||
g_winClipboardProcThread = pthread_self();
|
||||
|
||||
/* Set error handler */
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
|
||||
#define WIN_POLL_TIMEOUT 1
|
||||
|
||||
#ifndef WM_CLIPBOARDUPDATE
|
||||
#define WM_CLIPBOARDUPDATE 0x031D
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Process X events up to specified timeout
|
||||
|
@ -151,8 +154,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
winDebug("winClipboardWindowProc - WM_DESTROY\n");
|
||||
|
||||
if (g_fHasModernClipboardApi)
|
||||
{
|
||||
/* Remove clipboard listener */
|
||||
g_fpRemoveClipboardFormatListener(hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove ourselves from the clipboard chain */
|
||||
ChangeClipboardChain(hwnd, s_hwndNextViewer);
|
||||
}
|
||||
|
||||
s_hwndNextViewer = NULL;
|
||||
}
|
||||
|
@ -168,8 +179,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
case WM_CREATE:
|
||||
{
|
||||
HWND first, next;
|
||||
DWORD error_code = 0;
|
||||
ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams;
|
||||
|
||||
winDebug("winClipboardWindowProc - WM_CREATE\n");
|
||||
|
@ -179,6 +188,15 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
atoms = cwcp->atoms;
|
||||
fRunning = TRUE;
|
||||
|
||||
if (g_fHasModernClipboardApi)
|
||||
{
|
||||
g_fpAddClipboardFormatListener(hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HWND first, next;
|
||||
DWORD error_code = 0;
|
||||
|
||||
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
|
||||
if (first == hwnd)
|
||||
return 0; /* Make sure it's not us! */
|
||||
|
@ -190,6 +208,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
else
|
||||
s_fCBCInitialized = FALSE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_CHANGECBCHAIN:
|
||||
|
@ -233,6 +252,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
|
||||
|
||||
if (g_fHasModernClipboardApi)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
|
||||
if (first == hwnd)
|
||||
return 0; /* Make sure it's not us! */
|
||||
|
@ -257,12 +281,18 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
|
||||
case WM_DRAWCLIPBOARD:
|
||||
case WM_CLIPBOARDUPDATE:
|
||||
{
|
||||
static Bool s_fProcessingDrawClipboard = FALSE;
|
||||
int iReturn;
|
||||
|
||||
if (message == WM_DRAWCLIPBOARD)
|
||||
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
|
||||
else
|
||||
winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
|
||||
|
||||
if (!g_fHasModernClipboardApi)
|
||||
{
|
||||
/*
|
||||
* We've occasionally seen a loop in the clipboard chain.
|
||||
* Try and fix it on the first hint of recursion.
|
||||
|
@ -289,6 +319,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: We cannot bail out when NULL == GetClipboardOwner ()
|
||||
|
|
Loading…
Reference in New Issue
Block a user