aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/winclipboardthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardthread.c')
-rw-r--r--xorg-server/hw/xwin/winclipboardthread.c166
1 files changed, 117 insertions, 49 deletions
diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c
index 34a963ce8..6df6ff380 100644
--- a/xorg-server/hw/xwin/winclipboardthread.c
+++ b/xorg-server/hw/xwin/winclipboardthread.c
@@ -39,7 +39,11 @@
#include <errno.h>
#endif
#include "misc.h"
+#include "winmsg.h"
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
/*
* References to external symbols
@@ -47,6 +51,7 @@
extern Bool g_fUnicodeClipboard;
extern unsigned long serverGeneration;
+extern Bool g_fClipboardLaunched;
extern Bool g_fClipboardStarted;
extern HWND g_hwndClipboard;
extern void *g_pClipboardDisplay;
@@ -58,6 +63,9 @@ extern Window g_iClipboardWindow;
*/
static jmp_buf g_jmpEntry;
+static XIOErrorHandler g_winClipboardOldIOErrorHandler;
+static pthread_t g_winClipboardProcThread;
+
Bool g_fUnicodeSupport = FALSE;
Bool g_fUseUnicode = FALSE;
@@ -72,6 +80,8 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
static int
winClipboardIOErrorHandler (Display *pDisplay);
+static void
+winClipboardThreadExit(void *arg);
/*
* Main thread function
@@ -98,7 +108,9 @@ winClipboardProc (void *pvNotUsed)
char szDisplay[512];
int iSelectError;
- ErrorF ("winClipboardProc - Hello\n");
+ pthread_cleanup_push(&winClipboardThreadExit, NULL);
+
+ winDebug ("winClipboardProc - Hello\n");
/* Do we have Unicode support? */
g_fUnicodeSupport = winClipboardDetectUnicodeSupport ();
@@ -109,19 +121,23 @@ winClipboardProc (void *pvNotUsed)
/* Save the Unicode support flag in a global */
g_fUseUnicode = fUseUnicode;
- /* Allow multiple threads to access Xlib */
- if (XInitThreads () == 0)
- {
- ErrorF ("winClipboardProc - XInitThreads failed.\n");
- pthread_exit (NULL);
- }
-
/* See if X supports the current locale */
if (XSupportsLocale () == False)
{
ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n");
}
+ /* Create Windows messaging window */
+ hwnd = winClipboardCreateMessagingWindow ();
+
+ /* Save copy of HWND in screen privates */
+ g_hwndClipboard = hwnd;
+
+ /* Set error handler */
+ XSetErrorHandler (winClipboardErrorHandler);
+ g_winClipboardProcThread = pthread_self();
+ g_winClipboardOldIOErrorHandler = XSetIOErrorHandler (winClipboardIOErrorHandler);
+
/* Set jump point for Error exits */
iReturn = setjmp (g_jmpEntry);
@@ -132,22 +148,18 @@ winClipboardProc (void *pvNotUsed)
/* setjmp returned an unknown value, exit */
ErrorF ("winClipboardProc - setjmp returned: %d exiting\n",
iReturn);
- pthread_exit (NULL);
+ 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");
- pthread_exit (NULL);
+ //goto thread_errorexit;
}
/* Use our generated cookie for authentication */
winSetAuthorization();
- /* Set error handler */
- XSetErrorHandler (winClipboardErrorHandler);
- XSetIOErrorHandler (winClipboardIOErrorHandler);
-
/* Initialize retry count */
iRetries = 0;
@@ -165,7 +177,7 @@ winClipboardProc (void *pvNotUsed)
display);
/* Print the display connection string */
- ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay);
+ winDebug ("winClipboardProc - DISPLAY=%s\n", szDisplay);
/* Open the X display */
do
@@ -189,25 +201,27 @@ winClipboardProc (void *pvNotUsed)
if (pDisplay == NULL)
{
ErrorF ("winClipboardProc - Failed opening the display, giving up\n");
- pthread_exit (NULL);
+ goto thread_errorexit;
}
/* Save the display in the screen privates */
g_pClipboardDisplay = pDisplay;
- ErrorF ("winClipboardProc - XOpenDisplay () returned and "
+ 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);
- pthread_exit (NULL);
+ goto thread_errorexit;
}
/* Find max of our file descriptors */
@@ -219,6 +233,10 @@ winClipboardProc (void *pvNotUsed)
/* Create atoms */
atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False);
atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", 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,
@@ -231,9 +249,11 @@ winClipboardProc (void *pvNotUsed)
if (iWindow == 0)
{
ErrorF ("winClipboardProc - Could not create an X window.\n");
- pthread_exit (NULL);
+ goto thread_errorexit;
}
+ XStoreName(pDisplay, iWindow, "xwinclip");
+
/* Select event types to watch */
if (XSelectInput (pDisplay,
iWindow,
@@ -244,33 +264,28 @@ winClipboardProc (void *pvNotUsed)
/* Save the window in the screen privates */
g_iClipboardWindow = iWindow;
- /* Create Windows messaging window */
- hwnd = winClipboardCreateMessagingWindow ();
-
- /* Save copy of HWND in screen privates */
- g_hwndClipboard = hwnd;
-
/* Assert ownership of selections if Win32 clipboard is owned */
if (NULL != GetClipboardOwner ())
{
/* PRIMARY */
+ winDebug("winClipboardProc - asserted ownership.\n");
iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow)
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/)
{
ErrorF ("winClipboardProc - Could not set PRIMARY owner\n");
- pthread_exit (NULL);
+ goto thread_errorexit;
}
/* CLIPBOARD */
iReturn = XSetSelectionOwner (pDisplay, atomClipboard,
iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner (pDisplay, atomClipboard) != iWindow)
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/)
{
ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
- pthread_exit (NULL);
+ goto thread_errorexit;
}
}
@@ -280,15 +295,20 @@ winClipboardProc (void *pvNotUsed)
* because there may be events in local data structures
* already.
*/
- winClipboardFlushXEvents (hwnd,
+ /*winClipboardFlushXEvents (hwnd,
iWindow,
pDisplay,
fUseUnicode);
-
+ */
/* Pre-flush Windows messages */
+ winDebug ("Start flushing \n");
if (!winClipboardFlushWindowsMessageQueue (hwnd))
- return 0;
+ {
+ ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n");
+ goto thread_errorexit;
+ }
+ winDebug ("winClipboardProc - Started\n");
/* Signal that the clipboard client has started */
g_fClipboardStarted = TRUE;
@@ -343,21 +363,24 @@ winClipboardProc (void *pvNotUsed)
}
/* 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 */
/* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents (hwnd,
iWindow,
pDisplay,
- fUseUnicode);
+ fUseUnicode,
+ FALSE
+ );
if (WIN_XEVENTS_SHUTDOWN == iReturn)
{
ErrorF ("winClipboardProc - winClipboardFlushXEvents "
"trapped shutdown event, exiting main loop.\n");
break;
}
- }
+// }
#ifdef HAS_DEVWINDOWS
/* Check for Windows event ready */
@@ -383,8 +406,10 @@ winClipboardProc (void *pvNotUsed)
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
}
@@ -415,9 +440,28 @@ winClipboardProc (void *pvNotUsed)
}
#endif
+ goto commonexit;
+
+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_hwndClipboard = NULL;
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+
+ pthread_cleanup_pop(0);
return NULL;
}
@@ -437,11 +481,17 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr)
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;
}
@@ -455,8 +505,26 @@ winClipboardIOErrorHandler (Display *pDisplay)
{
ErrorF ("winClipboardIOErrorHandler!\n\n");
- /* Restart at the main entry point */
- longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
-
+ if (pthread_equal(pthread_self(),g_winClipboardProcThread))
+ {
+ /* Restart at the main entry point */
+ longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
+ }
+
+ if (g_winClipboardOldIOErrorHandler)
+ g_winClipboardOldIOErrorHandler(pDisplay);
+
return 0;
}
+
+/*
+ * winClipboardThreadExit - Thread exit handler
+ */
+
+static void
+winClipboardThreadExit(void *arg)
+{
+ /* clipboard thread has exited, stop server as well */
+ AbortDDX();
+ TerminateProcess(GetCurrentProcess(),1);
+}