diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboard/thread.c')
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/thread.c | 314 |
1 files changed, 167 insertions, 147 deletions
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); + } } |