aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/winclipboard
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/winclipboard')
-rwxr-xr-x[-rw-r--r--]xorg-server/hw/xwin/winclipboard/internal.h66
-rw-r--r--xorg-server/hw/xwin/winclipboard/makefile18
-rwxr-xr-x[-rw-r--r--]xorg-server/hw/xwin/winclipboard/thread.c314
-rw-r--r--xorg-server/hw/xwin/winclipboard/winclipboard.h6
-rwxr-xr-x[-rw-r--r--]xorg-server/hw/xwin/winclipboard/wndproc.c323
-rwxr-xr-x[-rw-r--r--]xorg-server/hw/xwin/winclipboard/xevents.c285
6 files changed, 466 insertions, 546 deletions
diff --git a/xorg-server/hw/xwin/winclipboard/internal.h b/xorg-server/hw/xwin/winclipboard/internal.h
index 94956f80d..55c7771af 100644..100755
--- a/xorg-server/hw/xwin/winclipboard/internal.h
+++ b/xorg-server/hw/xwin/winclipboard/internal.h
@@ -1,4 +1,3 @@
-
/*
*Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
*
@@ -32,24 +31,54 @@
#ifndef WINCLIPBOARD_INTERNAL_H
#define WINCLIPBOARD_INTERNAL_H
+/* Standard library headers */
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#ifdef __CYGWIN__
+#include <sys/select.h>
+#else
+#include <X11/Xwinsock.h>
+#endif
+#include <fcntl.h>
+#include <setjmp.h>
+#ifdef _MSC_VER
+typedef int pid_t;
+#endif
+#include <pthread.h>
+
/* X headers */
-#include <X11/Xlib.h>
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
/* Windows headers */
#include <X11/Xwindows.h>
+#include "winmsg.h"
+
#define WIN_XEVENTS_SUCCESS 0
#define WIN_XEVENTS_CONVERT 2
#define WIN_XEVENTS_NOTIFY 3
+#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER"
-#define WM_WM_REINIT (WM_USER + 1)
+#define WM_WM_REINIT (WM_USER + 200)
/*
* References to external symbols
*/
-extern void winDebug(const char *format, ...);
-extern void ErrorF(const char *format, ...);
+extern char *display;
+/*
+ * winclipboardinit.c
+ */
+
+Bool
+ winInitClipboard(void);
/*
* winclipboardtextconv.c
@@ -66,15 +95,6 @@ void
*/
-typedef struct
-{
- Atom atomClipboard;
- Atom atomLocalProperty;
- Atom atomUTF8String;
- Atom atomCompoundText;
- Atom atomTargets;
-} ClipboardAtoms;
-
/*
* winclipboardwndproc.c
*/
@@ -84,26 +104,12 @@ Bool winClipboardFlushWindowsMessageQueue(HWND hwnd);
LRESULT CALLBACK
winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
-typedef struct
-{
- Display *pClipboardDisplay;
- Window iClipboardWindow;
- ClipboardAtoms *atoms;
-} ClipboardWindowCreationParams;
-
/*
* winclipboardxevents.c
*/
int
-winClipboardFlushXEvents(HWND hwnd,
- Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom);
-
-
-Atom
-winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms);
-
-void
-winClipboardInitMonitoredSelections(void);
+winClipboardFlushXEvents(HWND hwnd,
+ int iWindow, Display * pDisplay, Bool fUnicodeSupport, Bool ClipboardOpened);
#endif
diff --git a/xorg-server/hw/xwin/winclipboard/makefile b/xorg-server/hw/xwin/winclipboard/makefile
new file mode 100644
index 000000000..f49117b3e
--- /dev/null
+++ b/xorg-server/hw/xwin/winclipboard/makefile
@@ -0,0 +1,18 @@
+LIBRARY = libXWinclipboard
+
+CSRCS = \
+ textconv.c \
+ thread.c \
+ wndproc.c \
+ xevents.c
+
+INCLUDES += ..
+
+DEFINES += HAVE_XWIN_CONFIG_H
+DEFINES += XWIN_CLIPBOARD
+DEFINES += XWIN_MULTIWINDOW
+DEFINES += XWIN_GLX_WINDOWS
+DEFINES += XWIN_RANDR
+DEFINES += RELOCATE_PROJECTROOT
+DEFINES += PTW32_STATIC_LIB
+
diff --git a/xorg-server/hw/xwin/winclipboard/thread.c b/xorg-server/hw/xwin/winclipboard/thread.c
index c179e3f83..5dee3040e 100644..100755
--- a/xorg-server/hw/xwin/winclipboard/thread.c
+++ b/xorg-server/hw/xwin/winclipboard/thread.c
@@ -35,61 +35,62 @@
#else
#define HAS_WINSOCK 1
#endif
-
-/*
- * Including any server header might define the macro _XSERVER64 on 64 bit machines.
- * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
- * So let's undef that macro if necessary.
- */
-#ifdef _XSERVER64
-#undef _XSERVER64
-#endif
-
-#include <assert.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <setjmp.h>
+#include <sys/types.h>
+#include <signal.h>
#include <pthread.h>
-#include <sys/param.h> // for MAX() macro
-
-#ifdef HAS_WINSOCK
-#include <X11/Xwinsock.h>
-#else
+#include "winclipboard.h"
+#include "windisplay.h"
+#ifdef __CYGWIN__
#include <errno.h>
#endif
-
-#include <X11/Xatom.h>
-#include <X11/extensions/Xfixes.h>
-#include "winclipboard.h"
+#include "misc.h"
+#include "winmsg.h"
#include "internal.h"
+/* Clipboard module constants */
#define WIN_CONNECT_RETRIES 40
#define WIN_CONNECT_DELAY 4
+#define WIN_JMP_OKAY 0
+#define WIN_JMP_ERROR_IO 2
#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip"
#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip"
#ifdef HAS_DEVWINDOWS
-#define WIN_MSG_QUEUE_FNAME "/dev/windows"
+#define WIN_MSG_QUEUE_FNAME "/dev/windows"
+#endif
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
#endif
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUnicodeClipboard;
+extern Bool g_fClipboard;
+extern Bool g_fClipboardStarted;
+extern Bool g_fClipboardLaunched;
+extern HWND g_hwndClipboard;
+extern void *g_pClipboardDisplay;
+extern Window g_iClipboardWindow;
+extern Bool g_fClipboardPrimary;
/*
* Global variables
*/
-static HWND g_hwndClipboard = NULL;
static jmp_buf g_jmpEntry;
static XIOErrorHandler g_winClipboardOldIOErrorHandler;
static pthread_t g_winClipboardProcThread;
-int xfixes_event_base;
-int xfixes_error_base;
+Bool g_fUseUnicode = FALSE;
/*
* Local function prototypes
*/
static HWND
-winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms);
+winClipboardCreateMessagingWindow(void);
static int
winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr);
@@ -97,19 +98,20 @@ static int
static int
winClipboardIOErrorHandler(Display * pDisplay);
+static void
+winClipboardThreadExit(void *arg);
/*
- * Create X11 and Win32 messaging windows, and run message processing loop
- *
- * returns TRUE if shutdown was signalled to loop, FALSE if some error occurred
+ * Main thread function
*/
Bool
winClipboardProc(Bool fUseUnicode, char *szDisplay)
{
- ClipboardAtoms atoms;
+ Atom atomClipboard;
int iReturn;
HWND hwnd = NULL;
int iConnectionNumber = 0;
+ Bool bShutDown = TRUE;
#ifdef HAS_DEVWINDOWS
int fdMessageQueue = 0;
@@ -121,74 +123,80 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
Display *pDisplay = NULL;
Window iWindow = None;
int iSelectError;
- Bool fShutdown = FALSE;
- static Bool fErrorHandlerSet = FALSE;
- winDebug("winClipboardProc - Hello\n");
+ pthread_cleanup_push(&winClipboardThreadExit, NULL);
- /* Allow multiple threads to access Xlib */
- if (XInitThreads() == 0) {
- ErrorF("winClipboardProc - XInitThreads failed.\n");
- goto winClipboardProc_Exit;
- }
+ winDebug ("winClipboardProc - Hello\n");
- /* See if X supports the current locale */
- if (XSupportsLocale() == False) {
- ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
- }
+ /* Save the Unicode support flag in a global */
+ g_fUseUnicode = fUseUnicode;
+
+ /* Create Windows messaging window */
+ hwnd = winClipboardCreateMessagingWindow ();
+
+ /* Save copy of HWND in screen privates */
+ g_hwndClipboard = hwnd;
g_winClipboardProcThread = pthread_self();
/* Set error handler */
- if (!fErrorHandlerSet) {
- XSetErrorHandler(winClipboardErrorHandler);
- g_winClipboardOldIOErrorHandler =
- XSetIOErrorHandler(winClipboardIOErrorHandler);
- fErrorHandlerSet = TRUE;
- }
+ XSetErrorHandler(winClipboardErrorHandler);
+ g_winClipboardOldIOErrorHandler =
+ XSetIOErrorHandler(winClipboardIOErrorHandler);
/* Set jump point for Error exits */
- if (setjmp(g_jmpEntry)) {
+ iReturn = setjmp(g_jmpEntry);
+
+ /* Check if we should continue operations */
+ if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) {
+ /* setjmp returned an unknown value, exit */
+ ErrorF("winClipboardProc - setjmp returned: %d exiting\n", iReturn);
+ goto thread_errorexit;
+ }
+ else if (iReturn == WIN_JMP_ERROR_IO) {
+ /* TODO: Cleanup the Win32 window and free any allocated memory */
ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n");
- goto winClipboardProc_Done;
}
/* Make sure that the display opened */
pDisplay = XOpenDisplay(szDisplay);
if (pDisplay == NULL) {
ErrorF("winClipboardProc - Failed opening the display, giving up\n");
- goto winClipboardProc_Done;
+ bShutDown = FALSE;
+ goto thread_errorexit;
}
- ErrorF("winClipboardProc - XOpenDisplay () returned and "
+ /* Save the display in the screen privates */
+ g_pClipboardDisplay = pDisplay;
+
+ winDebug ("winClipboardProc - XOpenDisplay () returned and "
"successfully opened the display.\n");
/* Get our connection number */
iConnectionNumber = ConnectionNumber(pDisplay);
+ winDebug("Clipboard is using socket %d\n",iConnectionNumber);
+
#ifdef HAS_DEVWINDOWS
/* Open a file descriptor for the windows message queue */
- fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY);
+ fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, _O_RDONLY);
if (fdMessageQueue == -1) {
ErrorF("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
- goto winClipboardProc_Done;
+ goto thread_errorexit;
}
/* Find max of our file descriptors */
- iMaxDescriptor = MAX(fdMessageQueue, iConnectionNumber) + 1;
+ iMaxDescriptor = max(fdMessageQueue, iConnectionNumber) + 1;
#else
iMaxDescriptor = iConnectionNumber + 1;
#endif
- if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base))
- ErrorF ("winClipboardProc - XFixes extension not present\n");
-
- /* Create atoms */
- atoms.atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
- atoms.atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False);
- atoms.atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
- atoms.atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
- atoms.atomTargets = XInternAtom (pDisplay, "TARGETS", False);
+ /* Create atom */
+ atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
+ XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
+ XInternAtom (pDisplay, "UTF8_STRING", False);
+ XInternAtom (pDisplay, "COMPOUND_TEXT", False);
+ XInternAtom (pDisplay, "TARGETS", False);
/* Create a messaging window */
iWindow = XCreateSimpleWindow(pDisplay,
@@ -200,7 +208,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
BlackPixel(pDisplay, 0));
if (iWindow == 0) {
ErrorF("winClipboardProc - Could not create an X window.\n");
- goto winClipboardProc_Done;
+ goto thread_errorexit;
}
XStoreName(pDisplay, iWindow, "xwinclip");
@@ -210,47 +218,33 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
ErrorF("winClipboardProc - XSelectInput generated BadWindow "
"on messaging window\n");
- XFixesSelectSelectionInput (pDisplay,
- iWindow,
- XA_PRIMARY,
- XFixesSetSelectionOwnerNotifyMask |
- XFixesSelectionWindowDestroyNotifyMask |
- XFixesSelectionClientCloseNotifyMask);
-
- XFixesSelectSelectionInput (pDisplay,
- iWindow,
- atoms.atomClipboard,
- XFixesSetSelectionOwnerNotifyMask |
- XFixesSelectionWindowDestroyNotifyMask |
- XFixesSelectionClientCloseNotifyMask);
-
-
- /* Initialize monitored selection state */
- winClipboardInitMonitoredSelections();
- /* Create Windows messaging window */
- hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow, &atoms);
-
- /* Save copy of HWND */
- g_hwndClipboard = hwnd;
+ /* Save the window in the screen privates */
+ g_iClipboardWindow = iWindow;
/* Assert ownership of selections if Win32 clipboard is owned */
if (NULL != GetClipboardOwner()) {
- /* PRIMARY */
- iReturn = XSetSelectionOwner(pDisplay, XA_PRIMARY,
- iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
- ErrorF("winClipboardProc - Could not set PRIMARY owner\n");
- goto winClipboardProc_Done;
+ if (g_fClipboardPrimary)
+ {
+ /* PRIMARY */
+ winDebug("winClipboardProc - asserted ownership.\n");
+ iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/)
+ {
+ ErrorF ("winClipboardProc - Could not set PRIMARY owner\n");
+ goto thread_errorexit;
+ }
}
/* CLIPBOARD */
- iReturn = XSetSelectionOwner(pDisplay, atoms.atomClipboard,
+ iReturn = XSetSelectionOwner(pDisplay, atomClipboard,
iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) {
- ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n");
- goto winClipboardProc_Done;
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/)
+ {
+ ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
+ goto thread_errorexit;
}
}
@@ -260,13 +254,20 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
* because there may be events in local data structures
* already.
*/
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
+ //winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);
/* Pre-flush Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
- ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
+ winDebug ("Start flushing \n");
+ if (!winClipboardFlushWindowsMessageQueue(hwnd))
+ {
+ ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n");
+ goto thread_errorexit;
}
+ winDebug ("winClipboardProc - Started\n");
+ /* Signal that the clipboard client has started */
+ g_fClipboardStarted = TRUE;
+
/* Loop for X events */
while (1) {
/* Setup the file descriptor set */
@@ -316,10 +317,12 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
/* Branch on which descriptor became active */
- if (FD_ISSET(iConnectionNumber, &fdsRead)) {
+// if (FD_ISSET (iConnectionNumber, &fdsRead)) {
+// Also do it when no read since winClipboardFlushXEvents
+// is sending the output.
/* Process X events */
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
- }
+ winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, FALSE);
+// }
#ifdef HAS_DEVWINDOWS
/* Check for Windows event ready */
@@ -338,23 +341,15 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
}
- winClipboardProc_Exit:
- /* broke out of while loop on a shutdown message */
- fShutdown = TRUE;
-
- winClipboardProc_Done:
- /* Close our Windows window */
- if (g_hwndClipboard) {
- winClipboardWindowDestroy();
- }
-
/* Close our X window */
if (pDisplay && iWindow) {
iReturn = XDestroyWindow(pDisplay, iWindow);
if (iReturn == BadWindow)
ErrorF("winClipboardProc - XDestroyWindow returned BadWindow.\n");
+#ifdef WINDBG
else
- ErrorF("winClipboardProc - XDestroyWindow succeeded.\n");
+ winDebug("winClipboardProc - XDestroyWindow succeeded.\n");
+#endif
}
#ifdef HAS_DEVWINDOWS
@@ -365,11 +360,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
#if 0
/*
- * FIXME: XCloseDisplay hangs if we call it
- *
- * XCloseDisplay() calls XSync(), so any outstanding errors are reported.
- * If we are built into the server, this can deadlock if the server is
- * in the process of exiting and waiting for this thread to exit.
+ * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The
+ * XSync and XSelectInput calls did not help.
*/
/* Discard any remaining events */
@@ -384,21 +376,40 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
#endif
- /* global clipboard variable reset */
- g_hwndClipboard = NULL;
+ goto commonexit;
- return fShutdown;
+thread_errorexit:
+ if (g_pClipboardDisplay && g_iClipboardWindow)
+ {
+ iReturn = XDestroyWindow (g_pClipboardDisplay, g_iClipboardWindow);
+ if (iReturn == BadWindow)
+ ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n");
+#ifdef WINDBG
+ else
+ winDebug ("winClipboardProc - XDestroyWindow succeeded.\n");
+#endif
+ }
+ winDebug ("Clipboard thread died.\n");
+
+commonexit:
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+
+ pthread_cleanup_pop(0);
+
+ return bShutDown;
}
/*
* Create the Windows window that we use to receive Windows messages
*/
-static HWND
-winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms)
+HWND
+winClipboardCreateMessagingWindow(void)
{
WNDCLASSEX wc;
- ClipboardWindowCreationParams cwcp;
HWND hwnd;
/* Setup our window class */
@@ -416,11 +427,6 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAt
wc.hIconSm = 0;
RegisterClassEx(&wc);
- /* Information to be passed to WM_CREATE */
- cwcp.pClipboardDisplay = pDisplay;
- cwcp.iClipboardWindow = iWindow;
- cwcp.atoms = atoms;
-
/* Create the window */
hwnd = CreateWindowExA(0, /* Extended styles */
WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */
@@ -433,7 +439,7 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAt
(HWND) NULL, /* No parent or owner window */
(HMENU) NULL, /* No menu */
GetModuleHandle(NULL), /* Instance handle */
- &cwcp); /* Creation data */
+ NULL); /* Creation data */
assert(hwnd != NULL);
/* I'm not sure, but we may need to call this to start message processing */
@@ -456,8 +462,17 @@ winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr)
XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
ErrorF("winClipboardErrorHandler - ERROR: \n\t%s\n"
- "\tSerial: %lu, Request Code: %d, Minor Code: %d\n",
- pszErrorMsg, pErr->serial, pErr->request_code, pErr->minor_code);
+ " errorCode %d\n"
+ " serial %lu\n"
+ " resourceID 0x%x\n"
+ " majorCode %d\n"
+ " minorCode %d\n"
+ , pszErrorMsg
+ , pErr->error_code
+ , pErr->serial
+ , pErr->resourceid
+ , pErr->request_code
+ , pErr->minor_code);
return 0;
}
@@ -472,7 +487,7 @@ winClipboardIOErrorHandler(Display * pDisplay)
if (pthread_equal(pthread_self(), g_winClipboardProcThread)) {
/* Restart at the main entry point */
- longjmp(g_jmpEntry, 2);
+ longjmp(g_jmpEntry, WIN_JMP_ERROR_IO);
}
if (g_winClipboardOldIOErrorHandler)
@@ -481,18 +496,23 @@ winClipboardIOErrorHandler(Display * pDisplay)
return 0;
}
-void
-winClipboardWindowDestroy(void)
+/*
+ * winClipboardThreadExit - Thread exit handler
+ */
+
+static void
+winClipboardThreadExit(void *arg)
{
- if (g_hwndClipboard) {
- SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
- }
+ /* clipboard thread has exited, stop server as well */
+ AbortDDX(EXIT_ERR_ABORT);
+ TerminateProcess(GetCurrentProcess(),1);
}
+
void
-winFixClipboardChain(void)
+winFixClipboardChain(int Removed)
{
- if (g_hwndClipboard) {
- PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0);
- }
+ if (g_fClipboard && g_hwndClipboard) {
+ PostMessage (g_hwndClipboard, WM_WM_REINIT, Removed, 0);
+ }
}
diff --git a/xorg-server/hw/xwin/winclipboard/winclipboard.h b/xorg-server/hw/xwin/winclipboard/winclipboard.h
index 52481301b..7b172739a 100644
--- a/xorg-server/hw/xwin/winclipboard/winclipboard.h
+++ b/xorg-server/hw/xwin/winclipboard/winclipboard.h
@@ -27,10 +27,6 @@
#ifndef WINCLIPBOARD_H
#define WINCLIPBOARD_H
-Bool winClipboardProc(Bool fUseUnicode, char *szDisplay);
-
-void winFixClipboardChain(void);
-
-void winClipboardWindowDestroy(void);
+void winFixClipboardChain (int Removed);
#endif
diff --git a/xorg-server/hw/xwin/winclipboard/wndproc.c b/xorg-server/hw/xwin/winclipboard/wndproc.c
index 165ff558a..f5f931f74 100644..100755
--- a/xorg-server/hw/xwin/winclipboard/wndproc.c
+++ b/xorg-server/hw/xwin/winclipboard/wndproc.c
@@ -26,7 +26,7 @@
*the sale, use or other dealings in this Software without prior written
*authorization from the copyright holder(s) and author(s).
*
- * Authors: Harold L Hunt II
+ * Authors: Harold L Hunt II
* Colin Harrison
*/
@@ -45,34 +45,55 @@
#include <sys/types.h>
#include <sys/time.h>
-
-#include <X11/Xatom.h>
-
-#include "internal.h"
#include "winclipboard.h"
+#include "misc.h"
+#include "winmsg.h"
+#include "objbase.h"
+#include "ddraw.h"
+#include "winwindow.h"
+#include "internal.h"
/*
* Constants
*/
-#define WIN_POLL_TIMEOUT 1
+#define WIN_POLL_TIMEOUT 1
+/*
+ * References to external symbols
+ */
+
+extern void *g_pClipboardDisplay;
+extern Window g_iClipboardWindow;
+extern Atom g_atomLastOwnedSelection;
+extern Bool g_fClipboardStarted;
+extern HWND g_hwndClipboard;
+extern Bool g_fClipboardPrimary;
/*
* Process X events up to specified timeout
*/
static int
-winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
- Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec)
+winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
+ Bool fUseUnicode, int iTimeoutSec)
{
int iConnNumber;
struct timeval tv;
int iReturn;
DWORD dwStopTime = GetTickCount() + iTimeoutSec * 1000;
- winDebug("winProcessXEventsTimeout () - pumping X events for %d seconds\n",
- iTimeoutSec);
+ /* Make sure the output messages are sent before waiting on a response. */
+ iReturn = winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode,
+ TRUE);
+ if (WIN_XEVENTS_NOTIFY == iReturn)
+ {
+ /* Bail out if notify processed */
+ return iReturn;
+ }
/* Get our connection number */
iConnNumber = ConnectionNumber(pDisplay);
@@ -82,9 +103,6 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
fd_set fdsRead;
long remainingTime;
- /* We need to ensure that all pending events are processed */
- XSync(pDisplay, FALSE);
-
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
FD_SET(iConnNumber, &fdsRead);
@@ -107,8 +125,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
NULL, /* No exception mask */
&tv); /* Timeout */
if (iReturn < 0) {
- ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. "
- "Bailing.\n", iReturn);
+ ErrorF("winProcessXEventsTimeout - Call to select () failed: %d (%x). "
+ "Bailing.\n", iReturn, WSAGetLastError());
break;
}
@@ -117,7 +135,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
/* Process X events */
/* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, fUseUnicode, atoms);
+ iWindow, pDisplay, fUseUnicode, TRUE);
winDebug
("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
@@ -144,10 +162,6 @@ LRESULT CALLBACK
winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND s_hwndNextViewer;
- static Bool s_fCBCInitialized;
- static Display *pDisplay;
- static Window iWindow;
- static ClipboardAtoms *atoms;
/* Branch on message type */
switch (message) {
@@ -159,7 +173,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ChangeClipboardChain(hwnd, s_hwndNextViewer);
s_hwndNextViewer = NULL;
-
+ g_hwndClipboard = NULL;
PostQuitMessage(0);
}
return 0;
@@ -168,24 +182,19 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND first, next;
DWORD error_code = 0;
- ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams;
winDebug("winClipboardWindowProc - WM_CREATE\n");
- pDisplay = cwcp->pClipboardDisplay;
- iWindow = cwcp->iClipboardWindow;
- atoms = cwcp->atoms;
-
- first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
- if (first == hwnd)
- return 0; /* Make sure it's not us! */
/* Add ourselves to the clipboard viewer chain */
- next = SetClipboardViewer(hwnd);
- error_code = GetLastError();
- if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */
- s_hwndNextViewer = next; /* it returned must have been the first window in the chain */
- else
- s_fCBCInitialized = FALSE;
+ s_hwndNextViewer = SetClipboardViewer (hwnd);
+ #ifdef _DEBUG
+ if (s_hwndNextViewer== hwnd)
+ {
+ ErrorF("WM_CREATE: SetClipboardViewer returned own window. This causes an endless loop, so reset s_hwndNextViewer. ");
+ s_hwndNextViewer=NULL;
+ }
+ #endif
+
}
return 0;
@@ -198,9 +207,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if ((HWND) wParam == s_hwndNextViewer) {
s_hwndNextViewer = (HWND) lParam;
if (s_hwndNextViewer == hwnd) {
- s_hwndNextViewer = NULL;
- ErrorF("winClipboardWindowProc - WM_CHANGECBCHAIN: "
- "attempted to set next window to ourselves.");
+ winDebug("WM_CHANGECBCHAIN: trying to set s_hwndNextViewer to own window. Resetting it back to NULL. ");
+ s_hwndNextViewer=NULL; /* This would cause an endless loop, so break it by ending the loop here. I have seen this happening, why??? */
}
}
else if (s_hwndNextViewer)
@@ -227,38 +235,52 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
HWND first, next;
DWORD error_code = 0;
-
+ if (!g_hwndClipboard)
+ return 0;
winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
- if (first == hwnd)
- return 0; /* Make sure it's not us! */
- winDebug(" WM_WM_REINIT: Replacing us(%x) with %x at head "
- "of chain\n", hwnd, s_hwndNextViewer);
- s_fCBCInitialized = FALSE;
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
- s_hwndNextViewer = NULL;
- s_fCBCInitialized = FALSE;
- winDebug(" WM_WM_REINIT: Putting us back at head of chain.\n");
- first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
- if (first == hwnd)
- return 0; /* Make sure it's not us! */
- next = SetClipboardViewer(hwnd);
- error_code = GetLastError();
- if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */
- s_hwndNextViewer = next; /* it returned must have been the first window in the chain */
- else
- s_fCBCInitialized = FALSE;
+ if (first != hwnd)
+ {
+ winDebug (" WM_WM_REINIT: Replacing us(%x) with %x at head "
+ "of chain\n", hwnd, s_hwndNextViewer);
+ if (!wParam) ChangeClipboardChain (hwnd, s_hwndNextViewer); /* When wParam is set, the window was already removed from the chain */
+ winDebug (" WM_WM_REINIT: Putting us back at head of chain.\n");
+ s_hwndNextViewer = SetClipboardViewer (hwnd);
+ #ifdef _DEBUG
+ if (s_hwndNextViewer== hwnd)
+ {
+ ErrorF("WM_WM_REINIT: SetClipboardViewer returned own window. This causes an endless loop, so reset s_hwndNextViewer. ");
+ s_hwndNextViewer=NULL;
+ }
+ #endif
+ }
+ winDebug ("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
}
- winDebug("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
return 0;
case WM_DRAWCLIPBOARD:
{
+ static Atom atomClipboard;
+ static int generation;
static Bool s_fProcessingDrawClipboard = FALSE;
+ Display *pDisplay = g_pClipboardDisplay;
+ Window iWindow = g_iClipboardWindow;
int iReturn;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD 0x%x 0x%x 0x%x: Enter\n",hwnd,wParam,lParam);
+
+ if (!g_fClipboardStarted) {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit with no processing\n");
+ if (s_hwndNextViewer)
+ SendMessage (s_hwndNextViewer, message, wParam, lParam);
+ return 0;
+ }
+
+ if (generation != serverGeneration) {
+ generation = serverGeneration;
+ atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
+ }
/*
* We've occasionally seen a loop in the clipboard chain.
@@ -269,41 +291,12 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
else {
/* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
- s_fCBCInitialized = FALSE;
ChangeClipboardChain(hwnd, s_hwndNextViewer);
- winFixClipboardChain();
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Nested calls detected. Re-initing.\n");
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- s_fProcessingDrawClipboard = FALSE;
- return 0;
- }
-
- /* Bail on first message */
- if (!s_fCBCInitialized) {
- s_fCBCInitialized = TRUE;
- s_fProcessingDrawClipboard = FALSE;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- return 0;
- }
-
- /*
- * NOTE: We cannot bail out when NULL == GetClipboardOwner ()
- * because some applications deal with the clipboard in a manner
- * that causes the clipboard owner to be NULL when they are in
- * fact taking ownership. One example of this is the Win32
- * native compile of emacs.
- */
-
- /* Bail when we still own the clipboard */
- if (hwnd == GetClipboardOwner()) {
-
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "We own the clipboard, returning.\n");
+ winFixClipboardChain(1);
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Nested calls detected. Re-initing.\n");
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
s_fProcessingDrawClipboard = FALSE;
- if (s_hwndNextViewer)
- SendMessage(s_hwndNextViewer, message, wParam, lParam);
return 0;
}
@@ -325,31 +318,31 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
*/
XSync(pDisplay, FALSE);
- winDebug("winClipboardWindowProc - XSync done.\n");
-
- /* Release PRIMARY selection if owned */
- iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
- if (iReturn == iWindow) {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "PRIMARY selection is owned by us.\n");
- XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
+ if (g_fClipboardPrimary)
+ {
+ /* Release PRIMARY selection if owned */
+ iReturn = XGetSelectionOwner (pDisplay, XA_PRIMARY);
+ if (iReturn == g_iClipboardWindow) {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "PRIMARY selection is owned by us.\n");
+ XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
+ }
+ else if (BadWindow == iReturn || BadAtom == iReturn)
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "XGetSelection failed for PRIMARY: %d\n",
+ iReturn);
}
- else if (BadWindow == iReturn || BadAtom == iReturn)
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelectionOwner failed for PRIMARY: %d\n",
- iReturn);
-
/* Release CLIPBOARD selection if owned */
- iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard);
- if (iReturn == iWindow) {
+ iReturn = XGetSelectionOwner(pDisplay, atomClipboard);
+ if (iReturn == g_iClipboardWindow) {
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "CLIPBOARD selection is owned by us, releasing\n");
- XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime);
+ "CLIPBOARD selection is owned by us.\n");
+ XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime);
}
else if (BadWindow == iReturn || BadAtom == iReturn)
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelectionOwner failed for CLIPBOARD: %d\n",
- iReturn);
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "XGetSelection failed for CLIPBOARD: %d\n",
+ iReturn);
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
s_fProcessingDrawClipboard = FALSE;
@@ -357,45 +350,48 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
SendMessage(s_hwndNextViewer, message, wParam, lParam);
return 0;
}
-
- /* Reassert ownership of PRIMARY */
- iReturn = XSetSelectionOwner(pDisplay,
- XA_PRIMARY, iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Could not reassert ownership of PRIMARY\n");
- }
- else {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Reasserted ownership of PRIMARY\n");
- }
-
- /* Reassert ownership of the CLIPBOARD */
- iReturn = XSetSelectionOwner(pDisplay,
- atoms->atomClipboard, iWindow, CurrentTime);
-
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) {
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Could not reassert ownership of CLIPBOARD\n");
- }
- else {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Reasserted ownership of CLIPBOARD\n");
+ /* Only reassert ownership when we did not change the clipboard ourselves */
+ if (hwnd!=(HWND)wParam) {
+ if (g_fClipboardPrimary) {
+ /* Reassert ownership of PRIMARY */
+ iReturn = XSetSelectionOwner (pDisplay,
+ XA_PRIMARY, iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow ||
+ XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow) {
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Could not reassert ownership of PRIMARY\n");
+ }
+ else {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Reasserted ownership of PRIMARY\n");
+ }
+ }
+ /* Reassert ownership of the CLIPBOARD */
+ iReturn = XSetSelectionOwner (pDisplay,
+ atomClipboard, iWindow, CurrentTime);
+
+ if (iReturn == BadAtom || iReturn == BadWindow ||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) {
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Could not reassert ownership of CLIPBOARD\n");
+ }
+ else {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Reasserted ownership of CLIPBOARD\n");
+ }
+
+ /* Flush the pending SetSelectionOwner event now */
+ XFlush (pDisplay);
}
- /* Flush the pending SetSelectionOwner event now */
- XFlush(pDisplay);
-
s_fProcessingDrawClipboard = FALSE;
- }
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
/* Pass the message on the next window in the clipboard viewer chain */
if (s_hwndNextViewer)
SendMessage(s_hwndNextViewer, message, wParam, lParam);
return 0;
+ }
case WM_DESTROYCLIPBOARD:
/*
* NOTE: Intentionally do nothing.
@@ -414,6 +410,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_RENDERALLFORMATS:
{
int iReturn;
+ Display *pDisplay = g_pClipboardDisplay;
+ Window iWindow = g_iClipboardWindow;
Bool fConvertToUnicode;
winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
@@ -426,36 +424,33 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* Request the selection contents */
iReturn = XConvertSelection(pDisplay,
- winClipboardGetLastOwnedSelectionAtom(atoms),
- atoms->atomCompoundText,
- atoms->atomLocalProperty,
+ g_atomLastOwnedSelection,
+ XInternAtom(pDisplay,
+ "COMPOUND_TEXT", False),
+ XInternAtom(pDisplay,
+ WIN_LOCAL_PROPERTY, False),
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - "
- "XConvertSelection () failed\n");
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMAT - "
+ "XConvertSelection () failed\n");
break;
}
/* Special handling for WM_RENDERALLFORMATS */
if (message == WM_RENDERALLFORMATS) {
/* We must open and empty the clipboard */
-
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow() == hwnd) {
- CloseClipboard();
- }
-
if (!OpenClipboard(hwnd)) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
- "OpenClipboard () failed: %08x\n",
- GetLastError());
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
+ "OpenClipboard () failed: %08x\n",
+ GetLastError());
break;
}
if (!EmptyClipboard()) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
- "EmptyClipboard () failed: %08x\n",
- GetLastError());
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
+ "EmptyClipboard () failed: %08x\n",
+ GetLastError());
+ CloseClipboard ();
break;
}
}
@@ -464,9 +459,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
pDisplay,
- fConvertToUnicode,
- atoms,
- WIN_POLL_TIMEOUT);
+ fConvertToUnicode, WIN_POLL_TIMEOUT);
/*
* The last call to winProcessXEventsTimeout
@@ -476,6 +469,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
* satisfy the requirement that we write something to it.
*/
if (WIN_XEVENTS_NOTIFY != iReturn) {
+ ErrorF("winClipboardWindowProc - winProcessXEventsTimeout should have returned WIN_XEVENTS_NOTIFY was %d\n",iReturn);
/* Paste no data, to satisfy required call to SetClipboardData */
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
@@ -489,9 +483,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* We must close the clipboard */
if (!CloseClipboard()) {
- ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
- "CloseClipboard () failed: %08x\n",
- GetLastError());
+ ErrorF (
+ "winClipboardWindowProc - WM_RENDERALLFORMATS - "
+ "CloseClipboard () failed: %08x\n",
+ GetLastError());
break;
}
}
diff --git a/xorg-server/hw/xwin/winclipboard/xevents.c b/xorg-server/hw/xwin/winclipboard/xevents.c
index d0077b846..cfbf0121e 100644..100755
--- a/xorg-server/hw/xwin/winclipboard/xevents.c
+++ b/xorg-server/hw/xwin/winclipboard/xevents.c
@@ -33,104 +33,13 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
-
-/*
- * Including any server header might define the macro _XSERVER64 on 64 bit machines.
- * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
- * So let's undef that macro if necessary.
- */
-#ifdef _XSERVER64
-#undef _XSERVER64
-#endif
-
+#include "winclipboard.h"
+#include "misc.h"
+#include "winmsg.h"
#include "internal.h"
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xfixes.h>
-
-/*
- * Constants
- */
-
-#define CLIP_NUM_SELECTIONS 2
-#define CLIP_OWN_NONE -1
-#define CLIP_OWN_PRIMARY 0
-#define CLIP_OWN_CLIPBOARD 1
-
-/*
- * Global variables
- */
+#include <unistd.h>
-extern int xfixes_event_base;
-
-/*
- * Local variables
- */
-
-static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None, None };
-static const char *szSelectionNames[CLIP_NUM_SELECTIONS] =
- { "PRIMARY", "CLIPBOARD" };
-
-static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE;
-
-static void
-MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i)
-{
- /* Look for owned -> not owned transition */
- if (None == e->owner && None != s_iOwners[i]) {
- unsigned int other_index;
-
- winDebug("MonitorSelection - %s - Going from owned to not owned.\n",
- szSelectionNames[i]);
-
- /* If this selection is not owned, the other monitored selection must be the most
- recently owned, if it is owned at all */
- if (i == CLIP_OWN_PRIMARY)
- other_index = CLIP_OWN_CLIPBOARD;
- if (i == CLIP_OWN_CLIPBOARD)
- other_index = CLIP_OWN_PRIMARY;
- if (None != s_iOwners[other_index])
- lastOwnedSelectionIndex = other_index;
- else
- lastOwnedSelectionIndex = CLIP_OWN_NONE;
- }
-
- /* Save last owned selection */
- if (None != e->owner) {
- lastOwnedSelectionIndex = i;
- }
-
- /* Save new selection owner or None */
- s_iOwners[i] = e->owner;
- winDebug("MonitorSelection - %s - Now owned by XID %x\n",
- szSelectionNames[i], e->owner);
-}
-
-Atom
-winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms)
-{
- if (lastOwnedSelectionIndex == CLIP_OWN_NONE)
- return None;
-
- if (lastOwnedSelectionIndex == CLIP_OWN_PRIMARY)
- return XA_PRIMARY;
-
- if (lastOwnedSelectionIndex == CLIP_OWN_CLIPBOARD)
- return atoms->atomClipboard;
-
- return None;
-}
-
-
-void
-winClipboardInitMonitoredSelections(void)
-{
- /* Initialize static variables */
- for (int i = 0; i < CLIP_NUM_SELECTIONS; ++i)
- s_iOwners[i] = None;
-
- lastOwnedSelectionIndex = CLIP_OWN_NONE;
-}
+extern Bool g_fClipboardPrimary;
/*
* Process any pending X events
@@ -138,13 +47,21 @@ winClipboardInitMonitoredSelections(void)
int
winClipboardFlushXEvents(HWND hwnd,
- Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms)
+ int iWindow, Display * pDisplay, Bool fUseUnicode, Bool ClipboardOpened)
{
- Atom atomClipboard = atoms->atomClipboard;
- Atom atomLocalProperty = atoms->atomLocalProperty;
- Atom atomUTF8String = atoms->atomUTF8String;
- Atom atomCompoundText = atoms->atomCompoundText;
- Atom atomTargets = atoms->atomTargets;
+ static Atom atomLocalProperty;
+ static Atom atomCompoundText;
+ static Atom atomUTF8String;
+ static Atom atomTargets;
+ static int generation;
+
+ if (generation != serverGeneration) {
+ generation = serverGeneration;
+ atomLocalProperty = XInternAtom(pDisplay, WIN_LOCAL_PROPERTY, False);
+ atomUTF8String = XInternAtom(pDisplay, "UTF8_STRING", False);
+ atomCompoundText = XInternAtom(pDisplay, "COMPOUND_TEXT", False);
+ atomTargets = XInternAtom(pDisplay, "TARGETS", False);
+ }
/* Process all pending events */
while (XPending(pDisplay)) {
@@ -165,6 +82,7 @@ winClipboardFlushXEvents(HWND hwnd,
wchar_t *pwszUnicodeStr = NULL;
int iUnicodeLen = 0;
int iReturnDataLen = 0;
+ int i;
Bool fAbort = FALSE;
Bool fCloseClipboard = FALSE;
Bool fSetClipboardData = TRUE;
@@ -172,6 +90,8 @@ winClipboardFlushXEvents(HWND hwnd,
/* Get the next event - will not block because one is ready */
XNextEvent(pDisplay, &event);
+ winDebug ("Received event type %d\n",event.type);
+
/* Branch on the event type */
switch (event.type) {
/*
@@ -179,6 +99,7 @@ winClipboardFlushXEvents(HWND hwnd,
*/
case SelectionRequest:
+#ifdef _DEBUG
{
char *pszAtomName = NULL;
@@ -190,7 +111,10 @@ winClipboardFlushXEvents(HWND hwnd,
winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
XFree(pszAtomName);
pszAtomName = NULL;
+ winDebug ("SelectionRequest - owner %d\n", event.xselectionrequest.owner);
+ winDebug ("SelectionRequest - requestor %d\n", event.xselectionrequest.requestor);
}
+#endif
/* Abort if invalid target type */
if (event.xselectionrequest.target != XA_STRING
@@ -252,24 +176,24 @@ winClipboardFlushXEvents(HWND hwnd,
break;
}
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow() == hwnd) {
- CloseClipboard();
- }
-
- /* Access the clipboard */
- if (!OpenClipboard(hwnd)) {
- ErrorF("winClipboardFlushXEvents - SelectionRequest - "
- "OpenClipboard () failed: %08lx\n", GetLastError());
+ /* Access the clipboard */
+ if (!ClipboardOpened)
+ {
+ if (!OpenClipboard (hwnd))
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "OpenClipboard () failed: %08lx\n",
+ GetLastError ());
/* Abort */
fAbort = TRUE;
goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Indicate that clipboard was opened */
+ fCloseClipboard = TRUE;
}
- /* Indicate that clipboard was opened */
- fCloseClipboard = TRUE;
-
/* Check that clipboard format is available */
if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
static int count; /* Hack to stop acroread spamming the log */
@@ -319,7 +243,16 @@ winClipboardFlushXEvents(HWND hwnd,
hGlobal = GetClipboardData(CF_TEXT);
}
if (!hGlobal) {
- ErrorF("winClipboardFlushXEvents - SelectionRequest - "
+ if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && ClipboardOpened)
+ {
+ ErrorF("We should not have received a SelectionRequest????\n"
+ "The owner is the clipboard, but in reality it was"
+ "an X window\n");
+ /* Set the owner to None */
+ if (g_fClipboardPrimary) XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
+ XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime);
+ }
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"GetClipboardData () failed: %08lx\n", GetLastError());
/* Abort */
@@ -407,9 +340,11 @@ winClipboardFlushXEvents(HWND hwnd,
/* Release the clipboard data */
GlobalUnlock(hGlobal);
pszGlobalData = NULL;
- fCloseClipboard = FALSE;
- CloseClipboard();
-
+ if (fCloseClipboard)
+ {
+ fCloseClipboard = FALSE;
+ CloseClipboard ();
+ }
/* Clean up */
XFree(xtpText.value);
xtpText.value = NULL;
@@ -488,9 +423,8 @@ winClipboardFlushXEvents(HWND hwnd,
/*
* SelectionNotify
*/
-
case SelectionNotify:
-
+#ifdef _DEBUG
winDebug("winClipboardFlushXEvents - SelectionNotify\n");
{
char *pszAtomName;
@@ -501,8 +435,11 @@ winClipboardFlushXEvents(HWND hwnd,
winDebug
("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
pszAtomName);
+ winDebug ("SelectionNotify - requestor %d\n", event.xselectionrequest.requestor);
XFree(pszAtomName);
}
+#endif
+
/*
* Request conversion of UTF8 and CompoundText targets.
@@ -585,6 +522,7 @@ winClipboardFlushXEvents(HWND hwnd,
break;
}
+#ifdef WINDBG
{
char *pszAtomName = NULL;
@@ -595,6 +533,7 @@ winClipboardFlushXEvents(HWND hwnd,
XFree(pszAtomName);
pszAtomName = NULL;
}
+#endif
if (fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
@@ -612,13 +551,11 @@ winClipboardFlushXEvents(HWND hwnd,
if (iReturn == Success || iReturn > 0) {
/* Conversion succeeded or some unconvertible characters */
if (ppszTextList != NULL) {
- int i;
-
iReturnDataLen = 0;
for (i = 0; i < iCount; i++) {
iReturnDataLen += strlen(ppszTextList[i]);
}
- pszReturnData = malloc(iReturnDataLen + 1);
+ pszReturnData = (char *) malloc(iReturnDataLen + 1);
pszReturnData[0] = '\0';
for (i = 0; i < iCount; i++) {
strcat(pszReturnData, ppszTextList[i]);
@@ -627,7 +564,7 @@ winClipboardFlushXEvents(HWND hwnd,
else {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"X*TextPropertyToTextList list_return is NULL.\n");
- pszReturnData = malloc(1);
+ pszReturnData = (char *) malloc(1);
pszReturnData[0] = '\0';
}
}
@@ -648,7 +585,7 @@ winClipboardFlushXEvents(HWND hwnd,
ErrorF("%d\n", iReturn);
break;
}
- pszReturnData = malloc(1);
+ pszReturnData = (char *) malloc(1);
pszReturnData[0] = '\0';
}
@@ -661,7 +598,7 @@ winClipboardFlushXEvents(HWND hwnd,
xtpText.nitems = 0;
/* Convert the X clipboard string to DOS format */
- winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
+ winClipboardUNIXtoDOS((unsigned char **)&pszReturnData, strlen(pszReturnData));
if (fUseUnicode) {
/* Find out how much space needed to convert MBCS to Unicode */
@@ -771,89 +708,37 @@ winClipboardFlushXEvents(HWND hwnd,
}
return WIN_XEVENTS_NOTIFY;
- case SelectionClear:
+ /*
+ * SelectionClear
+ */
+ case SelectionClear:
+#ifdef _DEBUG
winDebug("SelectionClear - doing nothing\n");
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+
+ winDebug ("SelectionClear - ATOM: %s\n",
+ pszAtomName);
+ winDebug ("SelectionClear - owner %d\n", event.xselectionrequest.owner);
+
+ XFree (pszAtomName);
+ }
+#endif
break;
case PropertyNotify:
break;
-
+
case MappingNotify:
+ XRefreshKeyboardMapping((XMappingEvent *)&event);
break;
default:
- if (event.type == XFixesSetSelectionOwnerNotify + xfixes_event_base) {
- XFixesSelectionNotifyEvent *e =
- (XFixesSelectionNotifyEvent *) & event;
-
- winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n");
-
- /* Save selection owners for monitored selections, ignore other selections */
- if (e->selection == XA_PRIMARY) {
- MonitorSelection(e, CLIP_OWN_PRIMARY);
- }
- else if (e->selection == atomClipboard) {
- MonitorSelection(e, CLIP_OWN_CLIPBOARD);
- }
- else
- break;
-
- /* Selection is being disowned */
- if (e->owner == None) {
- winDebug
- ("winClipboardFlushXEvents - No window, returning.\n");
- break;
- }
-
- /*
- XXX: there are all kinds of wacky edge cases we might need here:
- - we own windows clipboard, but neither PRIMARY nor CLIPBOARD have an owner, so we should disown it?
- - root window is taking ownership?
- */
-
- /* If we are the owner of the most recently owned selection, don't go all recursive :) */
- if ((lastOwnedSelectionIndex != CLIP_OWN_NONE) &&
- (s_iOwners[lastOwnedSelectionIndex] == iWindow)) {
- winDebug("winClipboardFlushXEvents - Ownership changed to us, aborting.\n");
- break;
- }
-
- /* Close clipboard if we have it open already (possible? correct??) */
- if (GetOpenClipboardWindow() == hwnd) {
- CloseClipboard();
- }
-
- /* Access the Windows clipboard */
- if (!OpenClipboard(hwnd)) {
- ErrorF("winClipboardFlushXEvents - OpenClipboard () failed: %08x\n",
- (int) GetLastError());
- break;
- }
-
- /* Take ownership of the Windows clipboard */
- if (!EmptyClipboard()) {
- ErrorF("winClipboardFlushXEvents - EmptyClipboard () failed: %08x\n",
- (int) GetLastError());
- break;
- }
-
- /* Advertise regular text and unicode */
- SetClipboardData(CF_UNICODETEXT, NULL);
- SetClipboardData(CF_TEXT, NULL);
-
- /* Release the clipboard */
- if (!CloseClipboard()) {
- ErrorF("winClipboardFlushXEvents - CloseClipboard () failed: %08x\n",
- (int) GetLastError());
- break;
- }
- }
- /* XFixesSelectionWindowDestroyNotifyMask */
- /* XFixesSelectionClientCloseNotifyMask */
- else {
- ErrorF("winClipboardFlushXEvents - unexpected event type %d\n",
- event.type);
- }
+ ErrorF("winClipboardFlushXEvents - unexpected event type %d\n",
+ event.type);
break;
}
}