diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboard')
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/internal.h | 41 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winclipboard/makefile | 18 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/thread.c | 162 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winclipboard/winclipboard.h | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/wndproc.c | 33 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/xevents.c | 35 |
6 files changed, 225 insertions, 70 deletions
diff --git a/xorg-server/hw/xwin/winclipboard/internal.h b/xorg-server/hw/xwin/winclipboard/internal.h index c6bde84af..b1ac02b2a 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,26 +31,56 @@ #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_FAILED 1 #define WIN_XEVENTS_NOTIFY_DATA 3 #define WIN_XEVENTS_NOTIFY_TARGETS 4 +#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" -#define WM_WM_REINIT (WM_USER + 1) -#define WM_WM_QUIT (WM_USER + 2) +#define WM_WM_REINIT (WM_USER + 200) +#define WM_WM_QUIT (WM_USER + 201) /* * 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 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 50e1e8cb5..20c473dd8 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/thread.c +++ b/xorg-server/hw/xwin/winclipboard/thread.c @@ -45,38 +45,52 @@ #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 "windisplay.h" +#ifdef __CYGWIN__ #include <errno.h> #endif +#include "misc.h" +#include "winmsg.h" #include <X11/Xatom.h> #include <X11/extensions/Xfixes.h> #include "winclipboard.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; /* * Global variables */ -static HWND g_hwndClipboard = NULL; static jmp_buf g_jmpEntry; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; @@ -84,6 +98,8 @@ static pthread_t g_winClipboardProcThread; int xfixes_event_base; int xfixes_error_base; +Bool g_fUseUnicode = FALSE; + /* * Local function prototypes */ @@ -97,6 +113,9 @@ static int static int winClipboardIOErrorHandler(Display * pDisplay); +static void +winClipboardThreadExit(void *arg); + /* * Create X11 and Win32 messaging windows, and run message processing loop * @@ -121,16 +140,21 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) Display *pDisplay = NULL; Window iWindow = None; int iSelectError; - Bool fShutdown = FALSE; + Bool fShutDown = TRUE; static Bool fErrorHandlerSet = FALSE; + + pthread_cleanup_push(&winClipboardThreadExit, NULL); ClipboardConversionData data; winDebug("winClipboardProc - Hello\n"); + /* 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"); - goto winClipboardProc_Exit; + goto thread_errorexit; } /* See if X supports the current locale */ @@ -149,19 +173,31 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } /* 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; + fShutDown = 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 */ @@ -172,7 +208,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) 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 */ @@ -201,7 +237,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"); @@ -225,7 +261,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask); - + /* Save the window in the screen privates */ + g_iClipboardWindow = iWindow; /* Initialize monitored selection state */ winClipboardInitMonitoredSelections(); /* Create Windows messaging window */ @@ -242,7 +279,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) if (iReturn == BadAtom || iReturn == BadWindow || XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) { ErrorF("winClipboardProc - Could not set PRIMARY owner\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } /* CLIPBOARD */ @@ -251,11 +288,14 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) if (iReturn == BadAtom || iReturn == BadWindow || XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) { ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } } data.fUseUnicode = fUseUnicode; + winDebug ("winClipboardProc - Started\n"); + /* Signal that the clipboard client has started */ + g_fClipboardStarted = TRUE; /* Loop for events */ while (1) { @@ -344,23 +384,15 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) #endif } - winClipboardProc_Exit: - /* broke out of while loop on a shutdown message */ - fShutdown = TRUE; - - winClipboardProc_Done: - /* Close our Windows window */ - if (g_hwndClipboard) { - DestroyWindow(g_hwndClipboard); - } - /* 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 @@ -390,10 +422,30 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } #endif - /* global clipboard variable reset */ - g_hwndClipboard = NULL; + 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_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + pthread_cleanup_pop(0); - return fShutdown; + return fShutDown; } /* @@ -462,8 +514,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; } @@ -478,7 +539,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) @@ -487,18 +548,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_WM_QUIT, 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 9c5c568a7..d7d8efa15 100644 --- a/xorg-server/hw/xwin/winclipboard/winclipboard.h +++ b/xorg-server/hw/xwin/winclipboard/winclipboard.h @@ -27,11 +27,9 @@ #ifndef WINCLIPBOARD_H #define WINCLIPBOARD_H -Bool winClipboardProc(Bool fUseUnicode, char *szDisplay); +#include <x11/Xdefs.h> -void winFixClipboardChain(void); - -void winClipboardWindowDestroy(void); +void winFixClipboardChain (int Removed); extern Bool fPrimarySelection; diff --git a/xorg-server/hw/xwin/winclipboard/wndproc.c b/xorg-server/hw/xwin/winclipboard/wndproc.c index 1ea5bc6b7..c99975193 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/wndproc.c +++ b/xorg-server/hw/xwin/winclipboard/wndproc.c @@ -49,6 +49,11 @@ #include <X11/Xatom.h> +#include "misc.h" +#include "winmsg.h" +#include "objbase.h" +#include "ddraw.h" +#include "winwindow.h" #include "internal.h" #include "winclipboard.h" @@ -58,6 +63,15 @@ #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; /* * Process X events up to specified timeout @@ -118,8 +132,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; } @@ -155,6 +169,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ChangeClipboardChain(hwnd, s_hwndNextViewer); s_hwndNextViewer = NULL; + g_hwndClipboard = NULL; } return 0; @@ -230,7 +245,8 @@ 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. */ @@ -261,7 +277,14 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static Bool s_fProcessingDrawClipboard = FALSE; 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; + } /* * We've occasionally seen a loop in the clipboard chain. @@ -274,7 +297,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* 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(); + winFixClipboardChain(1); ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " "Nested calls detected. Re-initing.\n"); winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); diff --git a/xorg-server/hw/xwin/winclipboard/xevents.c b/xorg-server/hw/xwin/winclipboard/xevents.c index 835195b52..5f426322d 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/xevents.c +++ b/xorg-server/hw/xwin/winclipboard/xevents.c @@ -33,7 +33,10 @@ #ifdef HAVE_XWIN_CONFIG_H #include <xwin-config.h> #endif - +#include "winclipboard.h" +#include "winglobals.h" +#include "misc.h" +#include "winmsg.h" /* * 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. @@ -44,6 +47,7 @@ #endif #include <limits.h> +#include <unistd.h> #include <wchar.h> #include <X11/Xutil.h> #include <X11/Xatom.h> @@ -228,6 +232,7 @@ winClipboardFlushXEvents(HWND hwnd, */ case SelectionRequest: +#ifdef _DEBUG { char *pszAtomName = NULL; @@ -240,6 +245,7 @@ winClipboardFlushXEvents(HWND hwnd, XFree(pszAtomName); pszAtomName = NULL; } +#endif /* Abort if invalid target type */ if (event.xselectionrequest.target != XA_STRING @@ -368,8 +374,17 @@ winClipboardFlushXEvents(HWND hwnd, hGlobal = GetClipboardData(CF_TEXT); } if (!hGlobal) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "GetClipboardData () failed: %08lx\n", GetLastError()); + if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && g_fClipboardStarted) + { + 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 (fPrimarySelection) XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime); + XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime); + } + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "GetClipboardData () failed: %08lx\n", GetLastError()); /* Abort */ fAbort = TRUE; @@ -538,6 +553,7 @@ winClipboardFlushXEvents(HWND hwnd, */ case SelectionNotify: +#ifdef _DEBUG winDebug("winClipboardFlushXEvents - SelectionNotify\n"); { char *pszAtomName; @@ -550,6 +566,8 @@ winClipboardFlushXEvents(HWND hwnd, pszAtomName); XFree(pszAtomName); } +#endif + /* SelectionNotify with property of None indicates either: @@ -588,6 +606,7 @@ winClipboardFlushXEvents(HWND hwnd, goto winClipboardFlushXEvents_SelectionNotify_Done; } +#ifdef WINDBG { char *pszAtomName = NULL; @@ -598,6 +617,7 @@ winClipboardFlushXEvents(HWND hwnd, XFree(pszAtomName); pszAtomName = NULL; } +#endif if (data->fUseUnicode) { #ifdef X_HAVE_UTF8_STRING @@ -620,7 +640,7 @@ winClipboardFlushXEvents(HWND hwnd, 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]); @@ -629,7 +649,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'; } } @@ -650,7 +670,7 @@ winClipboardFlushXEvents(HWND hwnd, ErrorF("%d\n", iReturn); break; } - pszReturnData = malloc(1); + pszReturnData = (char *) malloc(1); pszReturnData[0] = '\0'; } @@ -663,7 +683,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 (data->fUseUnicode) { /* Find out how much space needed to convert MBCS to Unicode */ @@ -781,6 +801,7 @@ winClipboardFlushXEvents(HWND hwnd, break; case MappingNotify: + XRefreshKeyboardMapping((XMappingEvent *)&event); break; default: |