winclipboardthread.c [plain text]
#include "winclipboard.h"
extern Bool g_fCalledSetLocale;
static jmp_buf g_jmpEntry;
static Bool g_shutdown = FALSE;
static int
winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
static int
winClipboardIOErrorHandler (Display *pDisplay);
void *
winClipboardProc (void *pArg)
{
Atom atomClipboard, atomClipboardManager;
Atom atomLocalProperty, atomCompoundText;
Atom atomUTF8String, atomTargets;
int iReturn;
HWND hwnd = NULL;
int iConnectionNumber;
int fdMessageQueue;
fd_set fdsRead;
int iMaxDescriptor;
Display *pDisplay;
Window iWindow;
Atom atomDeleteWindow;
Bool fReturn;
int iRetries;
Bool fUnicodeSupport;
char szDisplay[512];
ClipboardProcArgPtr pProcArg = (ClipboardProcArgPtr) pArg;
ErrorF ("winClipboardProc - Hello\n");
if (pArg == NULL)
{
ErrorF ("winClipboardProc - pArg is NULL, bailing.\n");
pthread_exit (NULL);
}
ErrorF ("winClipboardProc - Calling pthread_mutex_lock ()\n");
iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
if (iReturn != 0)
{
ErrorF ("winClipboardProc - pthread_mutex_lock () failed: %d\n",
iReturn);
pthread_exit (NULL);
}
ErrorF ("winClipboardProc - pthread_mutex_lock () returned.\n");
fUnicodeSupport = winClipboardDetectUnicodeSupport ();
if (fUnicodeSupport && !g_fCalledSetLocale)
{
ErrorF ("winClipboardProc - Calling setlocale ()\n");
if (!setlocale (LC_ALL, ""))
{
ErrorF ("winClipboardProc - setlocale () error\n");
pthread_exit (NULL);
}
ErrorF ("winClipboardProc - setlocale () returned\n");
if (XSupportsLocale () == False)
{
ErrorF ("winClipboardProc - Locale not supported by X\n");
pthread_exit (NULL);
}
}
g_fCalledSetLocale = TRUE;
if (XInitThreads () == 0)
{
ErrorF ("winClipboardProc - XInitThreads failed.\n");
pthread_exit (NULL);
}
ErrorF ("winClipboardProc - XInitThreads () returned.\n");
pthread_mutex_unlock (pProcArg->ppmServerStarted);
ErrorF ("winClipboardProc - pthread_mutex_unlock () returned.\n");
iReturn = setjmp (g_jmpEntry);
if (iReturn != WIN_JMP_ERROR_IO
&& iReturn != WIN_JMP_OKAY)
{
ErrorF ("winClipboardProc - setjmp returned: %d exiting\n",
iReturn);
pthread_exit (NULL);
}
else if (g_shutdown)
{
ErrorF ("winClipboardProc - Detected shutdown in progress\n");
pthread_exit (NULL);
}
else if (iReturn == WIN_JMP_ERROR_IO)
{
ErrorF ("winClipboardProc - setjmp returned and hwnd: %08x\n", hwnd);
}
iRetries = 0;
snprintf (szDisplay,
512,
"127.0.0.1:%s.%d",
display,
(int) pProcArg->dwScreen);
ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay);
do
{
pDisplay = XOpenDisplay (szDisplay);
if (pDisplay == NULL)
{
ErrorF ("winClipboardProc - Could not open display, "
"try: %d, sleeping: %d\n",
iRetries + 1, WIN_CONNECT_DELAY);
++iRetries;
sleep (WIN_CONNECT_DELAY);
continue;
}
else
break;
}
while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
if (pDisplay == NULL)
{
ErrorF ("winClipboardProc - Failed opening the display, giving up\n");
pthread_exit (NULL);
}
ErrorF ("winClipboardProc - XOpenDisplay () returned and "
"successfully opened the display.\n");
hwnd = winClipboardCreateMessagingWindow ();
iConnectionNumber = ConnectionNumber (pDisplay);
fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY);
if (fdMessageQueue == -1)
{
ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
pthread_exit (NULL);
}
iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1;
if (XSelectInput (pDisplay,
DefaultRootWindow (pDisplay),
SubstructureNotifyMask |
StructureNotifyMask |
PropertyChangeMask) == BadWindow)
ErrorF ("winClipboardProc - XSelectInput generated BadWindow "
"on RootWindow\n\n");
iWindow = XCreateSimpleWindow (pDisplay,
DefaultRootWindow (pDisplay),
1, 1,
500, 500,
0,
BlackPixel (pDisplay, 0),
BlackPixel (pDisplay, 0));
if (iWindow == 0)
{
ErrorF ("winClipboardProc - Could not create a window\n");
pthread_exit (NULL);
}
atomDeleteWindow = XInternAtom (pDisplay, "WM_DELETE_WINDOW", False);
XSetWMProtocols (pDisplay, iWindow, &atomDeleteWindow, 1);
XSetErrorHandler (winClipboardErrorHandler);
XSetIOErrorHandler (winClipboardIOErrorHandler);
atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False);
if (atomClipboardManager == None)
{
ErrorF ("winClipboardProc - Could not create CLIPBOARD_MANAGER atom\n");
pthread_exit (NULL);
}
iReturn = XSetSelectionOwner (pDisplay, atomClipboardManager,
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardProc - Could not set CLIPBOARD_MANAGER owner\n");
pthread_exit (NULL);
}
atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False);
if (atomClipboard == None)
{
ErrorF ("winClipboardProc - Could not create CLIPBOARD atom\n");
pthread_exit (NULL);
}
iReturn = XSetSelectionOwner (pDisplay, atomClipboard,
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
pthread_exit (NULL);
}
iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardProc - Could not set PRIMARY owner\n");
pthread_exit (NULL);
}
atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False);
if (atomLocalProperty == None)
{
ErrorF ("winClipboardProc - Could not create CYGX_CUT_BUFFER atom\n");
pthread_exit (NULL);
}
atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
if (atomUTF8String == None)
{
ErrorF ("winClipboardProc - Could not create UTF8_STRING atom\n");
pthread_exit (NULL);
}
atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
if (atomCompoundText == None)
{
ErrorF ("winClipboardProc - Could not create COMPOUND_TEXT atom\n");
pthread_exit (NULL);
}
atomTargets = XInternAtom (pDisplay, "TARGETS", False);
if (atomTargets == None)
{
ErrorF ("winClipboardProc - Could not create TARGETS atom\n");
pthread_exit (NULL);
}
winClipboardFlushXEvents (hwnd,
atomClipboard,
atomLocalProperty,
atomUTF8String,
atomCompoundText,
atomTargets,
atomDeleteWindow,
iWindow,
pDisplay,
fUnicodeSupport);
if (!winClipboardFlushWindowsMessageQueue (hwnd))
return 0;
while (1)
{
FD_ZERO (&fdsRead);
FD_SET (fdMessageQueue, &fdsRead);
FD_SET (iConnectionNumber, &fdsRead);
iReturn = select (iMaxDescriptor,
&fdsRead,
NULL,
NULL,
NULL);
if (iReturn <= 0)
{
ErrorF ("winClipboardProc - Call to select () failed: %d. "
"Bailing.\n", iReturn);
break;
}
if (FD_ISSET (iConnectionNumber, &fdsRead))
{
#if 0
ErrorF ("winClipboardProc - X event ready\n");
#endif
fReturn = winClipboardFlushXEvents (hwnd,
atomClipboard,
atomLocalProperty,
atomUTF8String,
atomCompoundText,
atomTargets,
atomDeleteWindow,
iWindow,
pDisplay,
fUnicodeSupport);
if (!fReturn)
{
ErrorF ("winClipboardProc - Caught WM_DELETE_WINDOW - "
"shutting down\n");
break;
}
}
if (FD_ISSET (fdMessageQueue, &fdsRead))
{
#if 0
ErrorF ("winClipboardProc - Windows event ready\n");
#endif
if (!winClipboardFlushWindowsMessageQueue (hwnd))
break;
}
}
return 0;
}
static int
winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr)
{
char pszErrorMsg[100];
XGetErrorText (pDisplay,
pErr->error_code,
pszErrorMsg,
sizeof (pszErrorMsg));
ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n", pszErrorMsg);
if (pErr->error_code == BadWindow
|| pErr->error_code == BadMatch
|| pErr->error_code == BadDrawable)
{
#if 0
pthread_exit (NULL);
#endif
}
#if 0
pthread_exit (NULL);
#endif
return 0;
}
static int
winClipboardIOErrorHandler (Display *pDisplay)
{
printf ("\nwinClipboardIOErrorHandler!\n\n");
longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
return 0;
}
void
winDeinitClipboard ()
{
ErrorF ("winDeinitClipboard - Noting shutdown in progress\n");
g_shutdown = TRUE;
}