Merge remote-tracking branch 'jturney/xwin-clipboard-refactoring'
This commit is contained in:
		
						commit
						78c27d12e1
					
				| 
						 | 
				
			
			@ -2142,7 +2142,7 @@ if test "x$XWIN" = xyes; then
 | 
			
		|||
	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
 | 
			
		||||
	AC_CHECK_TOOL(WINDRES, windres)
 | 
			
		||||
 | 
			
		||||
	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau])
 | 
			
		||||
	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes])
 | 
			
		||||
 | 
			
		||||
	if test "x$WINDOWSWM" = xauto; then
 | 
			
		||||
		PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
 | 
			
		||||
| 
						 | 
				
			
			@ -2600,6 +2600,7 @@ hw/xnest/man/Makefile
 | 
			
		|||
hw/xwin/Makefile
 | 
			
		||||
hw/xwin/glx/Makefile
 | 
			
		||||
hw/xwin/man/Makefile
 | 
			
		||||
hw/xwin/winclipboard/Makefile
 | 
			
		||||
hw/xquartz/Makefile
 | 
			
		||||
hw/xquartz/GL/Makefile
 | 
			
		||||
hw/xquartz/bundle/Makefile
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,6 @@
 | 
			
		|||
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
int winProcEstablishConnection(ClientPtr /* client */ );
 | 
			
		||||
int winProcSetSelectionOwner(ClientPtr /* client */ );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,24 +66,11 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
 | 
			
		|||
/*
 | 
			
		||||
 * References to external symbols
 | 
			
		||||
 */
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
extern Bool g_fUnicodeClipboard;
 | 
			
		||||
extern Bool g_fClipboardLaunched;
 | 
			
		||||
extern Bool g_fClipboardStarted;
 | 
			
		||||
extern pthread_t g_ptClipboardProc;
 | 
			
		||||
extern HWND g_hwndClipboard;
 | 
			
		||||
extern Bool g_fClipboard;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Function prototypes
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
static void
 | 
			
		||||
 winClipboardShutdown(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
 winCheckDisplayNumber(void);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,31 +112,6 @@ static PixmapFormatRec g_PixmapFormats[] = {
 | 
			
		|||
 | 
			
		||||
const int NUMFORMATS = sizeof(g_PixmapFormats) / sizeof(g_PixmapFormats[0]);
 | 
			
		||||
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
static void
 | 
			
		||||
winClipboardShutdown(void)
 | 
			
		||||
{
 | 
			
		||||
    /* Close down clipboard resources */
 | 
			
		||||
    if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) {
 | 
			
		||||
        /* Synchronously destroy the clipboard window */
 | 
			
		||||
        if (g_hwndClipboard != NULL) {
 | 
			
		||||
            SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
 | 
			
		||||
            /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        /* Wait for the clipboard thread to exit */
 | 
			
		||||
        pthread_join(g_ptClipboardProc, NULL);
 | 
			
		||||
 | 
			
		||||
        g_fClipboardLaunched = FALSE;
 | 
			
		||||
        g_fClipboardStarted = FALSE;
 | 
			
		||||
 | 
			
		||||
        winDebug("winClipboardShutdown - Clipboard thread has exited.\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static const ExtensionModule xwinExtensions[] = {
 | 
			
		||||
#ifdef GLXEXT
 | 
			
		||||
  { GlxExtensionInit, "GLX", &noGlxExtension },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,9 @@ bin_PROGRAMS = XWin
 | 
			
		|||
if XWIN_CLIPBOARD
 | 
			
		||||
SRCS_CLIPBOARD = \
 | 
			
		||||
	winclipboardinit.c \
 | 
			
		||||
	winclipboardtextconv.c \
 | 
			
		||||
	winclipboardthread.c \
 | 
			
		||||
	winclipboardwndproc.c \
 | 
			
		||||
	winclipboardwrappers.c \
 | 
			
		||||
	winclipboardxevents.c
 | 
			
		||||
	winclipboardwrappers.c
 | 
			
		||||
DEFS_CLIPBOARD = -DXWIN_CLIPBOARD
 | 
			
		||||
CLIPBOARD_LIBS = $(top_builddir)/hw/xwin/winclipboard/libXWinclipboard.la
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if XWIN_GLX_WINDOWS
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +107,6 @@ SRCS =	InitInput.c \
 | 
			
		|||
	winwindow.c \
 | 
			
		||||
	winwndproc.c \
 | 
			
		||||
	ddraw.h \
 | 
			
		||||
	winclipboard.h \
 | 
			
		||||
	winconfig.h \
 | 
			
		||||
	win.h \
 | 
			
		||||
	winglobals.h \
 | 
			
		||||
| 
						 | 
				
			
			@ -162,12 +158,15 @@ XWin_DEPENDENCIES = \
 | 
			
		|||
	$(MULTIWINDOWEXTWM_LIBS) \
 | 
			
		||||
	$(XWIN_GLX_LIBS) \
 | 
			
		||||
	$(XWIN_LIBS) \
 | 
			
		||||
	$(CLIPBOARD_LIBS) \
 | 
			
		||||
	$(XSERVER_LIBS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
XWin_LDADD = \
 | 
			
		||||
	$(MULTIWINDOWEXTWM_LIBS) \
 | 
			
		||||
	$(XWIN_GLX_LIBS) \
 | 
			
		||||
	$(XWIN_LIBS) \
 | 
			
		||||
	$(CLIPBOARD_LIBS) \
 | 
			
		||||
	$(XSERVER_LIBS) \
 | 
			
		||||
	$(XWIN_GLX_SYS_LIBS) \
 | 
			
		||||
	$(XSERVER_SYS_LIBS) \
 | 
			
		||||
| 
						 | 
				
			
			@ -210,5 +209,5 @@ EXTRA_DIST = \
 | 
			
		|||
relink:
 | 
			
		||||
	$(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT)
 | 
			
		||||
 | 
			
		||||
SUBDIRS = man $(GLX_DIR) .
 | 
			
		||||
DIST_SUBDIRS = man glx .
 | 
			
		||||
SUBDIRS = man $(GLX_DIR) winclipboard .
 | 
			
		||||
DIST_SUBDIRS = man glx winclipboard .
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -793,7 +793,7 @@ Bool
 | 
			
		|||
 winInitClipboard(void);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 winFixClipboardChain(void);
 | 
			
		||||
 winClipboardShutdown(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
noinst_LTLIBRARIES = libXWinclipboard.la
 | 
			
		||||
 | 
			
		||||
libXWinclipboard_la_SOURCES = \
 | 
			
		||||
	winclipboard.h \
 | 
			
		||||
	textconv.c \
 | 
			
		||||
	thread.c \
 | 
			
		||||
	wndproc.c \
 | 
			
		||||
	xevents.c
 | 
			
		||||
 | 
			
		||||
libXWinclipboard_la_CFLAGS = -DHAVE_XWIN_CONFIG_H \
 | 
			
		||||
			     $(DIX_CFLAGS) \
 | 
			
		||||
			     $(XWINMODULES_CFLAGS)
 | 
			
		||||
 | 
			
		||||
libXWinclipboard_la_LDFLAGS = -static -no-undefined
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS = xwinclip
 | 
			
		||||
 | 
			
		||||
xwinclip_SOURCES = xwinclip.c debug.c
 | 
			
		||||
 | 
			
		||||
xwinclip_CFLAGS = $(XWINMODULES_CFLAGS)
 | 
			
		||||
 | 
			
		||||
xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32
 | 
			
		||||
 | 
			
		||||
include $(top_srcdir)/manpages.am
 | 
			
		||||
appman_PRE = xwinclip.man
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
//
 | 
			
		||||
// Copyright © Jon TURNEY 2013
 | 
			
		||||
//
 | 
			
		||||
// This file is part of xwinclip.
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice (including the next
 | 
			
		||||
// paragraph) shall be included in all copies or substantial portions of the
 | 
			
		||||
// Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#if 1
 | 
			
		||||
int
 | 
			
		||||
winDebug(const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
  int count;
 | 
			
		||||
  va_list ap;
 | 
			
		||||
  va_start(ap, format);
 | 
			
		||||
  count = fprintf(stderr, "xwinclip: ");
 | 
			
		||||
  count += vfprintf(stderr, format, ap);
 | 
			
		||||
  va_end(ap);
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
ErrorF(const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
  int count;
 | 
			
		||||
  va_list ap;
 | 
			
		||||
  va_start(ap, format);
 | 
			
		||||
  count = vfprintf(stderr, format, ap);
 | 
			
		||||
  va_end(ap);
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,4 @@
 | 
			
		|||
#ifndef _WINCLIPBOARD_H_
 | 
			
		||||
#define _WINCLIPBOARD_H_
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -30,46 +29,18 @@
 | 
			
		|||
 * Authors:	Harold L Hunt II
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Standard library headers */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#ifdef __CYGWIN__
 | 
			
		||||
#include <sys/select.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <X11/Xwinsock.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#ifndef WINCLIPBOARD_INTERNAL_H
 | 
			
		||||
#define WINCLIPBOARD_INTERNAL_H
 | 
			
		||||
 | 
			
		||||
/* X headers */
 | 
			
		||||
#include <X11/X.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <X11/Xproto.h>
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
#include <X11/Xlocale.h>
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
 | 
			
		||||
/* Windows headers */
 | 
			
		||||
#include <X11/Xwindows.h>
 | 
			
		||||
 | 
			
		||||
/* Clipboard module constants */
 | 
			
		||||
#define WIN_CLIPBOARD_WINDOW_CLASS		"xwinclip"
 | 
			
		||||
#define WIN_CLIPBOARD_WINDOW_TITLE		"xwinclip"
 | 
			
		||||
#ifdef HAS_DEVWINDOWS
 | 
			
		||||
#define WIN_MSG_QUEUE_FNAME			"/dev/windows"
 | 
			
		||||
#endif
 | 
			
		||||
#define WIN_CONNECT_RETRIES			40
 | 
			
		||||
#define WIN_CONNECT_DELAY			4
 | 
			
		||||
#define WIN_JMP_OKAY				0
 | 
			
		||||
#define WIN_JMP_ERROR_IO			2
 | 
			
		||||
#define WIN_LOCAL_PROPERTY			"CYGX_CUT_BUFFER"
 | 
			
		||||
#define WIN_XEVENTS_SUCCESS			0
 | 
			
		||||
#define WIN_XEVENTS_CONVERT			2
 | 
			
		||||
#define WIN_XEVENTS_NOTIFY			3
 | 
			
		||||
#define WIN_CLIPBOARD_RETRIES			40
 | 
			
		||||
#define WIN_CLIPBOARD_DELAY			1
 | 
			
		||||
 | 
			
		||||
#define WM_WM_REINIT                           (WM_USER + 1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -77,18 +48,8 @@
 | 
			
		|||
 * References to external symbols
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
extern char *display;
 | 
			
		||||
extern void winDebug(const char *format, ...);
 | 
			
		||||
extern void winErrorFVerb(int verb, const char *format, ...);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * winclipboardinit.c
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
 winInitClipboard(void);
 | 
			
		||||
 | 
			
		||||
HWND winClipboardCreateMessagingWindow(void);
 | 
			
		||||
extern void ErrorF(const char *format, ...);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * winclipboardtextconv.c
 | 
			
		||||
| 
						 | 
				
			
			@ -104,23 +65,45 @@ void
 | 
			
		|||
 * winclipboardthread.c
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void *winClipboardProc(void *);
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    Atom atomClipboard;
 | 
			
		||||
    Atom atomLocalProperty;
 | 
			
		||||
    Atom atomUTF8String;
 | 
			
		||||
    Atom atomCompoundText;
 | 
			
		||||
    Atom atomTargets;
 | 
			
		||||
} ClipboardAtoms;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * winclipboardwndproc.c
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
BOOL winClipboardFlushWindowsMessageQueue(HWND hwnd);
 | 
			
		||||
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,
 | 
			
		||||
                         int iWindow, Display * pDisplay, Bool fUnicodeSupport);
 | 
			
		||||
                         Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Atom
 | 
			
		||||
winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
winClipboardInitMonitoredSelections(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -31,14 +31,18 @@
 | 
			
		|||
#ifdef HAVE_XWIN_CONFIG_H
 | 
			
		||||
#include <xwin-config.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "win.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 winClipboardDOStoUNIX(char *pszSrc, int iLength);
 | 
			
		||||
void
 | 
			
		||||
 winClipboardUNIXtoDOS(char **ppszData, int iLength);
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <stdlib.h>
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert \r\n to \n
 | 
			
		||||
| 
						 | 
				
			
			@ -35,42 +35,62 @@
 | 
			
		|||
#else
 | 
			
		||||
#define HAS_WINSOCK 1
 | 
			
		||||
#endif
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include "winclipboard.h"
 | 
			
		||||
#include "windisplay.h"
 | 
			
		||||
#ifdef __CYGWIN__
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * References to external symbols
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
extern Bool g_fUnicodeClipboard;
 | 
			
		||||
extern Bool g_fClipboardStarted;
 | 
			
		||||
extern Bool g_fClipboardLaunched;
 | 
			
		||||
extern Bool g_fClipboard;
 | 
			
		||||
extern HWND g_hwndClipboard;
 | 
			
		||||
extern void *g_pClipboardDisplay;
 | 
			
		||||
extern Window g_iClipboardWindow;
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <sys/param.h> // for MAX() macro
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_WINSOCK
 | 
			
		||||
#include <X11/Xwinsock.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <X11/extensions/Xfixes.h>
 | 
			
		||||
#include "winclipboard.h"
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
 | 
			
		||||
#define WIN_CONNECT_RETRIES			40
 | 
			
		||||
#define WIN_CONNECT_DELAY			4
 | 
			
		||||
 | 
			
		||||
#define WIN_CLIPBOARD_WINDOW_CLASS		"xwinclip"
 | 
			
		||||
#define WIN_CLIPBOARD_WINDOW_TITLE		"xwinclip"
 | 
			
		||||
#ifdef HAS_DEVWINDOWS
 | 
			
		||||
#define WIN_MSG_QUEUE_FNAME "/dev/windows"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Global variables
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static HWND g_hwndClipboard = NULL;
 | 
			
		||||
static jmp_buf g_jmpEntry;
 | 
			
		||||
static int clipboardRestarts = 0;
 | 
			
		||||
static XIOErrorHandler g_winClipboardOldIOErrorHandler;
 | 
			
		||||
static pthread_t g_winClipboardProcThread;
 | 
			
		||||
 | 
			
		||||
Bool g_fUseUnicode = FALSE;
 | 
			
		||||
int xfixes_event_base;
 | 
			
		||||
int xfixes_error_base;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local function prototypes
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static HWND
 | 
			
		||||
winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms);
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
 winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,13 +98,15 @@ static int
 | 
			
		|||
 winClipboardIOErrorHandler(Display * pDisplay);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main thread function
 | 
			
		||||
 * Create X11 and Win32 messaging windows, and run message processing loop
 | 
			
		||||
 *
 | 
			
		||||
 * returns TRUE if shutdown was signalled to loop, FALSE if some error occurred
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
winClipboardProc(void *pvNotUsed)
 | 
			
		||||
Bool
 | 
			
		||||
winClipboardProc(Bool fUseUnicode, char *szDisplay)
 | 
			
		||||
{
 | 
			
		||||
    Atom atomClipboard;
 | 
			
		||||
    ClipboardAtoms atoms;
 | 
			
		||||
    int iReturn;
 | 
			
		||||
    HWND hwnd = NULL;
 | 
			
		||||
    int iConnectionNumber = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,19 +120,11 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
    int iMaxDescriptor;
 | 
			
		||||
    Display *pDisplay = NULL;
 | 
			
		||||
    Window iWindow = None;
 | 
			
		||||
    int iRetries;
 | 
			
		||||
    Bool fUseUnicode;
 | 
			
		||||
    char szDisplay[512];
 | 
			
		||||
    int iSelectError;
 | 
			
		||||
    Bool fShutdown = FALSE;
 | 
			
		||||
    static Bool fErrorHandlerSet = FALSE;
 | 
			
		||||
 | 
			
		||||
    winDebug("winClipboardProc - Hello\n");
 | 
			
		||||
    ++clipboardRestarts;
 | 
			
		||||
 | 
			
		||||
    /* Do we use Unicode clipboard? */
 | 
			
		||||
    fUseUnicode = g_fUnicodeClipboard;
 | 
			
		||||
 | 
			
		||||
    /* Save the Unicode support flag in a global */
 | 
			
		||||
    g_fUseUnicode = fUseUnicode;
 | 
			
		||||
 | 
			
		||||
    /* Allow multiple threads to access Xlib */
 | 
			
		||||
    if (XInitThreads() == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,70 +137,29 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
        ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Set error handler */
 | 
			
		||||
    XSetErrorHandler(winClipboardErrorHandler);
 | 
			
		||||
    g_winClipboardProcThread = pthread_self();
 | 
			
		||||
    g_winClipboardOldIOErrorHandler =
 | 
			
		||||
        XSetIOErrorHandler(winClipboardIOErrorHandler);
 | 
			
		||||
 | 
			
		||||
    /* Set error handler */
 | 
			
		||||
    if (!fErrorHandlerSet) {
 | 
			
		||||
      XSetErrorHandler(winClipboardErrorHandler);
 | 
			
		||||
      g_winClipboardOldIOErrorHandler =
 | 
			
		||||
         XSetIOErrorHandler(winClipboardIOErrorHandler);
 | 
			
		||||
      fErrorHandlerSet = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Set jump point for Error exits */
 | 
			
		||||
    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 winClipboardProc_Exit;
 | 
			
		||||
    }
 | 
			
		||||
    else if (iReturn == WIN_JMP_ERROR_IO) {
 | 
			
		||||
        /* TODO: Cleanup the Win32 window and free any allocated memory */
 | 
			
		||||
    if (setjmp(g_jmpEntry)) {
 | 
			
		||||
        ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n");
 | 
			
		||||
        pthread_exit(NULL);
 | 
			
		||||
        goto winClipboardProc_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Use our generated cookie for authentication */
 | 
			
		||||
    winSetAuthorization();
 | 
			
		||||
 | 
			
		||||
    /* Initialize retry count */
 | 
			
		||||
    iRetries = 0;
 | 
			
		||||
 | 
			
		||||
    /* Setup the display connection string x */
 | 
			
		||||
    /*
 | 
			
		||||
     * NOTE: Always connect to screen 0 since we require that screen
 | 
			
		||||
     * numbers start at 0 and increase without gaps.  We only need
 | 
			
		||||
     * to connect to one screen on the display to get events
 | 
			
		||||
     * for all screens on the display.  That is why there is only
 | 
			
		||||
     * one clipboard client thread.
 | 
			
		||||
     */
 | 
			
		||||
    winGetDisplayName(szDisplay, 0);
 | 
			
		||||
 | 
			
		||||
    /* Print the display connection string */
 | 
			
		||||
    ErrorF("winClipboardProc - DISPLAY=%s\n", szDisplay);
 | 
			
		||||
 | 
			
		||||
    /* Open the X display */
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    /* Make sure that the display opened */
 | 
			
		||||
    pDisplay = XOpenDisplay(szDisplay);
 | 
			
		||||
    if (pDisplay == NULL) {
 | 
			
		||||
        ErrorF("winClipboardProc - Failed opening the display, giving up\n");
 | 
			
		||||
        goto winClipboardProc_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Save the display in the screen privates */
 | 
			
		||||
    g_pClipboardDisplay = pDisplay;
 | 
			
		||||
 | 
			
		||||
    ErrorF("winClipboardProc - XOpenDisplay () returned and "
 | 
			
		||||
           "successfully opened the display.\n");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -202,13 +175,20 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* Find max of our file descriptors */
 | 
			
		||||
    iMaxDescriptor = max(fdMessageQueue, iConnectionNumber) + 1;
 | 
			
		||||
    iMaxDescriptor = MAX(fdMessageQueue, iConnectionNumber) + 1;
 | 
			
		||||
#else
 | 
			
		||||
    iMaxDescriptor = iConnectionNumber + 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Create atom */
 | 
			
		||||
    atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
 | 
			
		||||
    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 a messaging window */
 | 
			
		||||
    iWindow = XCreateSimpleWindow(pDisplay,
 | 
			
		||||
| 
						 | 
				
			
			@ -230,13 +210,27 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
        ErrorF("winClipboardProc - XSelectInput generated BadWindow "
 | 
			
		||||
               "on messaging window\n");
 | 
			
		||||
 | 
			
		||||
    /* Save the window in the screen privates */
 | 
			
		||||
    g_iClipboardWindow = iWindow;
 | 
			
		||||
    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();
 | 
			
		||||
    hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow, &atoms);
 | 
			
		||||
 | 
			
		||||
    /* Save copy of HWND in screen privates */
 | 
			
		||||
    /* Save copy of HWND */
 | 
			
		||||
    g_hwndClipboard = hwnd;
 | 
			
		||||
 | 
			
		||||
    /* Assert ownership of selections if Win32 clipboard is owned */
 | 
			
		||||
| 
						 | 
				
			
			@ -251,10 +245,10 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        /* CLIPBOARD */
 | 
			
		||||
        iReturn = XSetSelectionOwner(pDisplay, atomClipboard,
 | 
			
		||||
        iReturn = XSetSelectionOwner(pDisplay, atoms.atomClipboard,
 | 
			
		||||
                                     iWindow, CurrentTime);
 | 
			
		||||
        if (iReturn == BadAtom || iReturn == BadWindow ||
 | 
			
		||||
            XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) {
 | 
			
		||||
            XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) {
 | 
			
		||||
            ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n");
 | 
			
		||||
            goto winClipboardProc_Done;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -266,14 +260,12 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
     *       because there may be events in local data structures
 | 
			
		||||
     *       already.
 | 
			
		||||
     */
 | 
			
		||||
    winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);
 | 
			
		||||
    winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
 | 
			
		||||
 | 
			
		||||
    /* Pre-flush Windows messages */
 | 
			
		||||
    if (!winClipboardFlushWindowsMessageQueue(hwnd))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    /* Signal that the clipboard client has started */
 | 
			
		||||
    g_fClipboardStarted = TRUE;
 | 
			
		||||
    if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
 | 
			
		||||
        ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Loop for X events */
 | 
			
		||||
    while (1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +318,7 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
        /* Branch on which descriptor became active */
 | 
			
		||||
        if (FD_ISSET(iConnectionNumber, &fdsRead)) {
 | 
			
		||||
            /* Process X events */
 | 
			
		||||
            winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);
 | 
			
		||||
            winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_DEVWINDOWS
 | 
			
		||||
| 
						 | 
				
			
			@ -347,16 +339,13 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
 winClipboardProc_Exit:
 | 
			
		||||
    /* disable the clipboard, which means the thread will die */
 | 
			
		||||
    g_fClipboard = FALSE;
 | 
			
		||||
    /* broke out of while loop on a shutdown message */
 | 
			
		||||
    fShutdown = TRUE;
 | 
			
		||||
 | 
			
		||||
 winClipboardProc_Done:
 | 
			
		||||
    /* Close our Windows window */
 | 
			
		||||
    if (g_hwndClipboard) {
 | 
			
		||||
        /* Destroy the Window window (hwnd) */
 | 
			
		||||
        winDebug("winClipboardProc - Destroy Windows window\n");
 | 
			
		||||
        PostMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
 | 
			
		||||
        winClipboardFlushWindowsMessageQueue(g_hwndClipboard);
 | 
			
		||||
        winClipboardWindowDestroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Close our X window */
 | 
			
		||||
| 
						 | 
				
			
			@ -376,8 +365,11 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
 | 
			
		||||
#if 0
 | 
			
		||||
    /*
 | 
			
		||||
     * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26.  The
 | 
			
		||||
     * XSync and XSelectInput calls did not help.
 | 
			
		||||
     * 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.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* Discard any remaining events */
 | 
			
		||||
| 
						 | 
				
			
			@ -393,42 +385,64 @@ winClipboardProc(void *pvNotUsed)
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    /* global clipboard variable reset */
 | 
			
		||||
    g_fClipboardLaunched = FALSE;
 | 
			
		||||
    g_fClipboardStarted = FALSE;
 | 
			
		||||
    g_iClipboardWindow = None;
 | 
			
		||||
    g_pClipboardDisplay = NULL;
 | 
			
		||||
    g_hwndClipboard = NULL;
 | 
			
		||||
 | 
			
		||||
    /* checking if we need to restart */
 | 
			
		||||
    if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) {
 | 
			
		||||
        /* terminates clipboard thread but the main server still lives */
 | 
			
		||||
        ErrorF
 | 
			
		||||
            ("winClipboardProc - the clipboard thread has restarted %d times and seems to be unstable, disabling clipboard integration\n",
 | 
			
		||||
             clipboardRestarts);
 | 
			
		||||
        g_fClipboard = FALSE;
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return fShutdown;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    if (g_fClipboard) {
 | 
			
		||||
        sleep(WIN_CLIPBOARD_DELAY);
 | 
			
		||||
        ErrorF("winClipboardProc - trying to restart clipboard thread \n");
 | 
			
		||||
        /* Create the clipboard client thread */
 | 
			
		||||
        if (!winInitClipboard()) {
 | 
			
		||||
            ErrorF("winClipboardProc - winClipboardInit failed.\n");
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
/*
 | 
			
		||||
 * Create the Windows window that we use to receive Windows messages
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
        winDebug("winClipboardProc - winInitClipboard returned.\n");
 | 
			
		||||
        /* Flag that clipboard client has been launched */
 | 
			
		||||
        g_fClipboardLaunched = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ErrorF("winClipboardProc - Clipboard disabled  - Exit from server \n");
 | 
			
		||||
        /* clipboard thread has exited, stop server as well */
 | 
			
		||||
        raise(SIGTERM);
 | 
			
		||||
    }
 | 
			
		||||
static HWND
 | 
			
		||||
winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms)
 | 
			
		||||
{
 | 
			
		||||
    WNDCLASSEX wc;
 | 
			
		||||
    ClipboardWindowCreationParams cwcp;
 | 
			
		||||
    HWND hwnd;
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
    /* Setup our window class */
 | 
			
		||||
    wc.cbSize = sizeof(WNDCLASSEX);
 | 
			
		||||
    wc.style = CS_HREDRAW | CS_VREDRAW;
 | 
			
		||||
    wc.lpfnWndProc = winClipboardWindowProc;
 | 
			
		||||
    wc.cbClsExtra = 0;
 | 
			
		||||
    wc.cbWndExtra = 0;
 | 
			
		||||
    wc.hInstance = GetModuleHandle(NULL);
 | 
			
		||||
    wc.hIcon = 0;
 | 
			
		||||
    wc.hCursor = 0;
 | 
			
		||||
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
 | 
			
		||||
    wc.lpszMenuName = NULL;
 | 
			
		||||
    wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS;
 | 
			
		||||
    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 */
 | 
			
		||||
                           WIN_CLIPBOARD_WINDOW_TITLE,  /* Window name */
 | 
			
		||||
                           WS_OVERLAPPED,       /* Not visible anyway */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Horizontal position */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Vertical position */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Right edge */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Bottom edge */
 | 
			
		||||
                           (HWND) NULL, /* No parent or owner window */
 | 
			
		||||
                           (HMENU) NULL,        /* No menu */
 | 
			
		||||
                           GetModuleHandle(NULL),       /* Instance handle */
 | 
			
		||||
                           &cwcp);       /* Creation data */
 | 
			
		||||
    assert(hwnd != NULL);
 | 
			
		||||
 | 
			
		||||
    /* I'm not sure, but we may need to call this to start message processing */
 | 
			
		||||
    ShowWindow(hwnd, SW_HIDE);
 | 
			
		||||
 | 
			
		||||
    /* Similarly, we may need a call to this even though we don't paint */
 | 
			
		||||
    UpdateWindow(hwnd);
 | 
			
		||||
 | 
			
		||||
    return hwnd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -458,7 +472,7 @@ winClipboardIOErrorHandler(Display * pDisplay)
 | 
			
		|||
 | 
			
		||||
    if (pthread_equal(pthread_self(), g_winClipboardProcThread)) {
 | 
			
		||||
        /* Restart at the main entry point */
 | 
			
		||||
        longjmp(g_jmpEntry, WIN_JMP_ERROR_IO);
 | 
			
		||||
        longjmp(g_jmpEntry, 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_winClipboardOldIOErrorHandler)
 | 
			
		||||
| 
						 | 
				
			
			@ -466,3 +480,19 @@ winClipboardIOErrorHandler(Display * pDisplay)
 | 
			
		|||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
winClipboardWindowDestroy(void)
 | 
			
		||||
{
 | 
			
		||||
  if (g_hwndClipboard) {
 | 
			
		||||
    SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
winFixClipboardChain(void)
 | 
			
		||||
{
 | 
			
		||||
  if (g_hwndClipboard) {
 | 
			
		||||
    PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
//
 | 
			
		||||
// Copyright © Jon TURNEY 2013
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice (including the next
 | 
			
		||||
// paragraph) shall be included in all copies or substantial portions of the
 | 
			
		||||
// Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
//
 | 
			
		||||
// File: winclipboard.h
 | 
			
		||||
// Purpose: public interface to winclipboard library
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef WINCLIPBOARD_H
 | 
			
		||||
#define WINCLIPBOARD_H
 | 
			
		||||
 | 
			
		||||
Bool winClipboardProc(Bool fUseUnicode, char *szDisplay);
 | 
			
		||||
 | 
			
		||||
void winFixClipboardChain(void);
 | 
			
		||||
 | 
			
		||||
void winClipboardWindowDestroy(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -33,10 +33,23 @@
 | 
			
		|||
#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 <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
#include "winclipboard.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Constants
 | 
			
		||||
| 
						 | 
				
			
			@ -44,21 +57,14 @@
 | 
			
		|||
 | 
			
		||||
#define WIN_POLL_TIMEOUT	1
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * References to external symbols
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
extern void *g_pClipboardDisplay;
 | 
			
		||||
extern Window g_iClipboardWindow;
 | 
			
		||||
extern Atom g_atomLastOwnedSelection;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process X events up to specified timeout
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
 | 
			
		||||
                         Bool fUseUnicode, int iTimeoutSec)
 | 
			
		||||
winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
 | 
			
		||||
                         Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec)
 | 
			
		||||
{
 | 
			
		||||
    int iConnNumber;
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +117,7 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
 | 
			
		|||
            /* Process X events */
 | 
			
		||||
            /* Exit when we see that server is shutting down */
 | 
			
		||||
            iReturn = winClipboardFlushXEvents(hwnd,
 | 
			
		||||
                                               iWindow, pDisplay, fUseUnicode);
 | 
			
		||||
                                               iWindow, pDisplay, fUseUnicode, atoms);
 | 
			
		||||
 | 
			
		||||
            winDebug
 | 
			
		||||
                ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -139,6 +145,9 @@ 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,9 +168,14 @@ 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! */
 | 
			
		||||
| 
						 | 
				
			
			@ -185,8 +199,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
            s_hwndNextViewer = (HWND) lParam;
 | 
			
		||||
            if (s_hwndNextViewer == hwnd) {
 | 
			
		||||
                s_hwndNextViewer = NULL;
 | 
			
		||||
                winErrorFVerb(1, "winClipboardWindowProc - WM_CHANGECBCHAIN: "
 | 
			
		||||
                              "attempted to set next window to ourselves.");
 | 
			
		||||
                ErrorF("winClipboardWindowProc - WM_CHANGECBCHAIN: "
 | 
			
		||||
                       "attempted to set next window to ourselves.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (s_hwndNextViewer)
 | 
			
		||||
| 
						 | 
				
			
			@ -241,20 +255,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
 | 
			
		||||
    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");
 | 
			
		||||
 | 
			
		||||
        if (generation != serverGeneration) {
 | 
			
		||||
            generation = serverGeneration;
 | 
			
		||||
            atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * We've occasionally seen a loop in the clipboard chain.
 | 
			
		||||
         * Try and fix it on the first hint of recursion.
 | 
			
		||||
| 
						 | 
				
			
			@ -267,8 +272,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
            s_fCBCInitialized = FALSE;
 | 
			
		||||
            ChangeClipboardChain(hwnd, s_hwndNextViewer);
 | 
			
		||||
            winFixClipboardChain();
 | 
			
		||||
            winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                          "Nested calls detected.  Re-initing.\n");
 | 
			
		||||
            ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                   "Nested calls detected.  Re-initing.\n");
 | 
			
		||||
            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
 | 
			
		||||
            s_fProcessingDrawClipboard = FALSE;
 | 
			
		||||
            return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -324,27 +329,27 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
 | 
			
		||||
            /* Release PRIMARY selection if owned */
 | 
			
		||||
            iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
 | 
			
		||||
            if (iReturn == g_iClipboardWindow) {
 | 
			
		||||
            if (iReturn == iWindow) {
 | 
			
		||||
                winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                         "PRIMARY selection is owned by us.\n");
 | 
			
		||||
                XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
 | 
			
		||||
            }
 | 
			
		||||
            else if (BadWindow == iReturn || BadAtom == iReturn)
 | 
			
		||||
                winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                              "XGetSelection failed for PRIMARY: %d\n",
 | 
			
		||||
                              iReturn);
 | 
			
		||||
                ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                       "XGetSelectionOwner failed for PRIMARY: %d\n",
 | 
			
		||||
                       iReturn);
 | 
			
		||||
 | 
			
		||||
            /* Release CLIPBOARD selection if owned */
 | 
			
		||||
            iReturn = XGetSelectionOwner(pDisplay, atomClipboard);
 | 
			
		||||
            if (iReturn == g_iClipboardWindow) {
 | 
			
		||||
            iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard);
 | 
			
		||||
            if (iReturn == iWindow) {
 | 
			
		||||
                winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                         "CLIPBOARD selection is owned by us.\n");
 | 
			
		||||
                XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime);
 | 
			
		||||
                         "CLIPBOARD selection is owned by us, releasing\n");
 | 
			
		||||
                XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime);
 | 
			
		||||
            }
 | 
			
		||||
            else if (BadWindow == iReturn || BadAtom == iReturn)
 | 
			
		||||
                winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                              "XGetSelection failed for CLIPBOARD: %d\n",
 | 
			
		||||
                              iReturn);
 | 
			
		||||
                ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                       "XGetSelectionOwner failed for CLIPBOARD: %d\n",
 | 
			
		||||
                       iReturn);
 | 
			
		||||
 | 
			
		||||
            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
 | 
			
		||||
            s_fProcessingDrawClipboard = FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -358,8 +363,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
                                     XA_PRIMARY, iWindow, CurrentTime);
 | 
			
		||||
        if (iReturn == BadAtom || iReturn == BadWindow ||
 | 
			
		||||
            XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
 | 
			
		||||
            winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                          "Could not reassert ownership of PRIMARY\n");
 | 
			
		||||
            ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                   "Could not reassert ownership of PRIMARY\n");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
| 
						 | 
				
			
			@ -368,12 +373,12 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
 | 
			
		||||
        /* Reassert ownership of the CLIPBOARD */
 | 
			
		||||
        iReturn = XSetSelectionOwner(pDisplay,
 | 
			
		||||
                                     atomClipboard, iWindow, CurrentTime);
 | 
			
		||||
                                     atoms->atomClipboard, iWindow, CurrentTime);
 | 
			
		||||
 | 
			
		||||
        if (iReturn == BadAtom || iReturn == BadWindow ||
 | 
			
		||||
            XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) {
 | 
			
		||||
            winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                          "Could not reassert ownership of CLIPBOARD\n");
 | 
			
		||||
            XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) {
 | 
			
		||||
            ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
                    "Could not reassert ownership of CLIPBOARD\n");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
 | 
			
		||||
| 
						 | 
				
			
			@ -409,8 +414,6 @@ 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");
 | 
			
		||||
| 
						 | 
				
			
			@ -423,15 +426,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
 | 
			
		||||
        /* Request the selection contents */
 | 
			
		||||
        iReturn = XConvertSelection(pDisplay,
 | 
			
		||||
                                    g_atomLastOwnedSelection,
 | 
			
		||||
                                    XInternAtom(pDisplay,
 | 
			
		||||
                                                "COMPOUND_TEXT", False),
 | 
			
		||||
                                    XInternAtom(pDisplay,
 | 
			
		||||
                                                "CYGX_CUT_BUFFER", False),
 | 
			
		||||
                                    winClipboardGetLastOwnedSelectionAtom(atoms),
 | 
			
		||||
                                    atoms->atomCompoundText,
 | 
			
		||||
                                    atoms->atomLocalProperty,
 | 
			
		||||
                                    iWindow, CurrentTime);
 | 
			
		||||
        if (iReturn == BadAtom || iReturn == BadWindow) {
 | 
			
		||||
            winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMAT - "
 | 
			
		||||
                          "XConvertSelection () failed\n");
 | 
			
		||||
            ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - "
 | 
			
		||||
                   "XConvertSelection () failed\n");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -445,16 +446,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            if (!OpenClipboard(hwnd)) {
 | 
			
		||||
                winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - "
 | 
			
		||||
                              "OpenClipboard () failed: %08x\n",
 | 
			
		||||
                              GetLastError());
 | 
			
		||||
                ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
 | 
			
		||||
                       "OpenClipboard () failed: %08x\n",
 | 
			
		||||
                       GetLastError());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!EmptyClipboard()) {
 | 
			
		||||
                winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - "
 | 
			
		||||
                              "EmptyClipboard () failed: %08x\n",
 | 
			
		||||
                              GetLastError());
 | 
			
		||||
                ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
 | 
			
		||||
                       "EmptyClipboard () failed: %08x\n",
 | 
			
		||||
                       GetLastError());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -463,7 +464,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
        iReturn = winProcessXEventsTimeout(hwnd,
 | 
			
		||||
                                           iWindow,
 | 
			
		||||
                                           pDisplay,
 | 
			
		||||
                                           fConvertToUnicode, WIN_POLL_TIMEOUT);
 | 
			
		||||
                                           fConvertToUnicode,
 | 
			
		||||
                                           atoms,
 | 
			
		||||
                                           WIN_POLL_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * The last call to winProcessXEventsTimeout
 | 
			
		||||
| 
						 | 
				
			
			@ -486,10 +489,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
            /* We must close the clipboard */
 | 
			
		||||
 | 
			
		||||
            if (!CloseClipboard()) {
 | 
			
		||||
                winErrorFVerb(1,
 | 
			
		||||
                              "winClipboardWindowProc - WM_RENDERALLFORMATS - "
 | 
			
		||||
                              "CloseClipboard () failed: %08x\n",
 | 
			
		||||
                              GetLastError());
 | 
			
		||||
                ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
 | 
			
		||||
                       "CloseClipboard () failed: %08x\n",
 | 
			
		||||
                       GetLastError());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +509,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
			
		|||
 * Process any pending Windows messages
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
BOOL
 | 
			
		||||
Bool
 | 
			
		||||
winClipboardFlushWindowsMessageQueue(HWND hwnd)
 | 
			
		||||
{
 | 
			
		||||
    MSG msg;
 | 
			
		||||
| 
						 | 
				
			
			@ -33,8 +33,104 @@
 | 
			
		|||
#ifdef HAVE_XWIN_CONFIG_H
 | 
			
		||||
#include <xwin-config.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "winclipboard.h"
 | 
			
		||||
#include "misc.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.
 | 
			
		||||
 * So let's undef that macro if necessary.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef _XSERVER64
 | 
			
		||||
#undef _XSERVER64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process any pending X events
 | 
			
		||||
| 
						 | 
				
			
			@ -42,21 +138,13 @@
 | 
			
		|||
 | 
			
		||||
int
 | 
			
		||||
winClipboardFlushXEvents(HWND hwnd,
 | 
			
		||||
                         int iWindow, Display * pDisplay, Bool fUseUnicode)
 | 
			
		||||
                         Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms)
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
    Atom atomClipboard = atoms->atomClipboard;
 | 
			
		||||
    Atom atomLocalProperty = atoms->atomLocalProperty;
 | 
			
		||||
    Atom atomUTF8String = atoms->atomUTF8String;
 | 
			
		||||
    Atom atomCompoundText = atoms->atomCompoundText;
 | 
			
		||||
    Atom atomTargets = atoms->atomTargets;
 | 
			
		||||
 | 
			
		||||
    /* Process all pending events */
 | 
			
		||||
    while (XPending(pDisplay)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +165,6 @@ winClipboardFlushXEvents(HWND hwnd,
 | 
			
		|||
        wchar_t *pwszUnicodeStr = NULL;
 | 
			
		||||
        int iUnicodeLen = 0;
 | 
			
		||||
        int iReturnDataLen = 0;
 | 
			
		||||
        int i;
 | 
			
		||||
        Bool fAbort = FALSE;
 | 
			
		||||
        Bool fCloseClipboard = FALSE;
 | 
			
		||||
        Bool fSetClipboardData = TRUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -525,6 +612,8 @@ 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]);
 | 
			
		||||
| 
						 | 
				
			
			@ -693,8 +782,78 @@ winClipboardFlushXEvents(HWND hwnd,
 | 
			
		|||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            ErrorF("winClipboardFlushXEvents - unexpected event type %d\n",
 | 
			
		||||
                   event.type);
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
/*
 | 
			
		||||
 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
 | 
			
		||||
 *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
 | 
			
		||||
 *Copyright (C) Colin Harrison 2005-2008
 | 
			
		||||
 *
 | 
			
		||||
 *Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
 * a copy of this software and associated documentation files (the
 | 
			
		||||
 *"Software"), to deal in the Software without restriction, including
 | 
			
		||||
 *without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
 *distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
 *permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
 *the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 *The above copyright notice and this permission notice shall be
 | 
			
		||||
 *included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 *NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 | 
			
		||||
 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | 
			
		||||
 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 *Except as contained in this notice, the name of the copyright holder(s)
 | 
			
		||||
 *and author(s) shall not be used in advertising or otherwise to promote
 | 
			
		||||
 *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
 | 
			
		||||
 *              Colin Harrison
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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 <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* X headers */
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#ifdef X_LOCALE
 | 
			
		||||
#include <X11/Xlocale.h>
 | 
			
		||||
#else /* X_LOCALE */
 | 
			
		||||
#include <locale.h>
 | 
			
		||||
#endif /* X_LOCALE */
 | 
			
		||||
 | 
			
		||||
#include "winclipboard.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Main function
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int			i;
 | 
			
		||||
  char			*pszDisplay = NULL;
 | 
			
		||||
  int			fUnicodeClipboard = 1;
 | 
			
		||||
 | 
			
		||||
  /* Parse command-line parameters */
 | 
			
		||||
  for (i = 1; i < argc; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      /* Look for -display "display_name" or --display "display_name" */
 | 
			
		||||
      if (i < argc - 1
 | 
			
		||||
	  && (!strcmp (argv[i], "-display")
 | 
			
		||||
	      || !strcmp (argv[i], "--display")))
 | 
			
		||||
	{
 | 
			
		||||
	  /* Grab a pointer to the display parameter */
 | 
			
		||||
	  pszDisplay = argv[i + 1];
 | 
			
		||||
 | 
			
		||||
	  /* Skip the display argument */
 | 
			
		||||
	  i++;
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* Look for -nounicodeclipboard */
 | 
			
		||||
      if (!strcmp (argv[i], "-nounicodeclipboard"))
 | 
			
		||||
	{
 | 
			
		||||
	  fUnicodeClipboard = 0;
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* Yack when we find a parameter that we don't know about */
 | 
			
		||||
      printf ("Unknown parameter: %s\nExiting.\n", argv[i]);
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Do we have Unicode support? */
 | 
			
		||||
  if (fUnicodeClipboard)
 | 
			
		||||
    {
 | 
			
		||||
      printf ("Unicode clipboard I/O\n");
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      printf ("Non Unicode clipboard I/O\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Apply locale specified in the LANG environment variable */
 | 
			
		||||
  if (!setlocale (LC_ALL, ""))
 | 
			
		||||
    {
 | 
			
		||||
      printf ("setlocale() error\n");
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* See if X supports the current locale */
 | 
			
		||||
  if (XSupportsLocale () == False)
 | 
			
		||||
    {
 | 
			
		||||
      printf ("Locale not supported by X, falling back to 'C' locale.\n");
 | 
			
		||||
      setlocale(LC_ALL, "C");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  winClipboardProc(fUnicodeClipboard, pszDisplay);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
.TH xwinclip 1 __xorgversion__
 | 
			
		||||
.SH NAME
 | 
			
		||||
xwinclip - An X11 and Windows clipboard integration tool
 | 
			
		||||
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.B xwinclip [OPTION]...
 | 
			
		||||
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
\fIxwinclip\fP is a tool for copying and pasting text between the Windows and X11 clipboard systems.
 | 
			
		||||
 | 
			
		||||
\fIxwinclip\fP watches for updates to either clipboard and copies data between them when either one is updated.
 | 
			
		||||
 | 
			
		||||
\fIxwinclip\fP monitors the X PRIMARY and CLIBPOARD selections for changes in ownership, and makes
 | 
			
		||||
the contents of the most recent one to change available to paste from the Windows clipboard.
 | 
			
		||||
 | 
			
		||||
It also monitors the contents of the Windows clipboard for changes, taking ownership of the PRIMARY and
 | 
			
		||||
CLIPBOARD selections, and making the contents of the Windows clipboard available in them.
 | 
			
		||||
 | 
			
		||||
.B Note well:
 | 
			
		||||
The \fIXWin(1)\fP X server has internal clipboard integration that is enabled by default.
 | 
			
		||||
Do \fINOT\fP run \fIxwinclip\fP unless \fIXWin(1)\fP has been started with the -noclipboard option.
 | 
			
		||||
 | 
			
		||||
.SH OPTIONS
 | 
			
		||||
\fIxwinclip\fP accepts the following optional command line switches:
 | 
			
		||||
 | 
			
		||||
.TP 8
 | 
			
		||||
.B \-display [display]
 | 
			
		||||
Specifies the X server display to connect to.
 | 
			
		||||
.TP 8
 | 
			
		||||
.B \-nounicodeclipboard
 | 
			
		||||
Do not use unicode text on the clipboard.
 | 
			
		||||
 | 
			
		||||
.SH "SEE ALSO"
 | 
			
		||||
XWin(1)
 | 
			
		||||
 | 
			
		||||
.SH BUGS
 | 
			
		||||
Only text clipboard contents are supported.
 | 
			
		||||
 | 
			
		||||
The INCR (Incrememntal transfer) clipboard protocol for clipboard contents larger than the maximum size of an
 | 
			
		||||
X request is not supported.
 | 
			
		||||
 | 
			
		||||
Some X clients, notably ones written in Tcl/Tk, do not re-assert ownership of the PRIMARY selection or update
 | 
			
		||||
it's timestamp when it's contents change, which currently prevents \fIxwinclip\fP from correctly noticing that
 | 
			
		||||
the PRIMARY selection's contents have changed.
 | 
			
		||||
 | 
			
		||||
Windows clipboard rendering is synchronous in the WM_RENDER*FORMAT message (that is, we must have placed the
 | 
			
		||||
contents onto the clipboard by the time we return from processing this message), but we must wait for the X
 | 
			
		||||
client which owns the selection to convert the selection to our requested format.  This is currently achieved
 | 
			
		||||
using a fixed timeout of one second.
 | 
			
		||||
 | 
			
		||||
The XWin(1) server should indicate somehow (by placing an atom on the root window?) that it is running with it's
 | 
			
		||||
internal clipboard integration enabled, and xwinclip should notice this and exit with an appropriate error.
 | 
			
		||||
 | 
			
		||||
Probably many other bugs.
 | 
			
		||||
 | 
			
		||||
.SH "CONFORMING TO"
 | 
			
		||||
ICCCM (Inter-Client Communication Conventions Manual) 2.0
 | 
			
		||||
 | 
			
		||||
.SH AUTHORS
 | 
			
		||||
Contributors to xwinclip include Benjamin Riefenstahl, Roland Cassard, Brian Genisio, Colin Harrison,
 | 
			
		||||
Harold L Hunt II, Matsuzaki Kensuke, Jon Turney, Chris Twiner and Jeremy Wilkins.
 | 
			
		||||
| 
						 | 
				
			
			@ -31,25 +31,79 @@
 | 
			
		|||
#ifdef HAVE_XWIN_CONFIG_H
 | 
			
		||||
#include <xwin-config.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "dixstruct.h"
 | 
			
		||||
#include "winclipboard.h"
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#include "win.h"
 | 
			
		||||
#include "winclipboard/winclipboard.h"
 | 
			
		||||
#include "windisplay.h"
 | 
			
		||||
 | 
			
		||||
#define WIN_CLIPBOARD_RETRIES			40
 | 
			
		||||
#define WIN_CLIPBOARD_DELAY			1
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local typedefs
 | 
			
		||||
 * Local variables
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef int (*winDispatchProcPtr) (ClientPtr);
 | 
			
		||||
 | 
			
		||||
int winProcSetSelectionOwner(ClientPtr /* client */ );
 | 
			
		||||
static pthread_t g_ptClipboardProc;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * References to external symbols
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static void *
 | 
			
		||||
winClipboardThreadProc(void *arg)
 | 
			
		||||
{
 | 
			
		||||
  char szDisplay[512];
 | 
			
		||||
  int clipboardRestarts = 0;
 | 
			
		||||
 | 
			
		||||
extern pthread_t g_ptClipboardProc;
 | 
			
		||||
extern winDispatchProcPtr winProcSetSelectionOwnerOrig;
 | 
			
		||||
extern Bool g_fClipboard;
 | 
			
		||||
extern HWND g_hwndClipboard;
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      Bool fShutdown;
 | 
			
		||||
 | 
			
		||||
      ++clipboardRestarts;
 | 
			
		||||
 | 
			
		||||
      /* Use our generated cookie for authentication */
 | 
			
		||||
      winSetAuthorization();
 | 
			
		||||
 | 
			
		||||
      /* Setup the display connection string */
 | 
			
		||||
      /*
 | 
			
		||||
       * NOTE: Always connect to screen 0 since we require that screen
 | 
			
		||||
       * numbers start at 0 and increase without gaps.  We only need
 | 
			
		||||
       * to connect to one screen on the display to get events
 | 
			
		||||
       * for all screens on the display.  That is why there is only
 | 
			
		||||
       * one clipboard client thread.
 | 
			
		||||
      */
 | 
			
		||||
      winGetDisplayName(szDisplay, 0);
 | 
			
		||||
 | 
			
		||||
      /* Print the display connection string */
 | 
			
		||||
      ErrorF("winClipboardThreadProc - DISPLAY=%s\n", szDisplay);
 | 
			
		||||
 | 
			
		||||
      /* Flag that clipboard client has been launched */
 | 
			
		||||
      g_fClipboardStarted = TRUE;
 | 
			
		||||
 | 
			
		||||
      fShutdown = winClipboardProc(g_fUnicodeClipboard, szDisplay);
 | 
			
		||||
 | 
			
		||||
      /* Flag that clipboard client has stopped */
 | 
			
		||||
      g_fClipboardStarted = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (fShutdown)
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      /* checking if we need to restart */
 | 
			
		||||
      if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) {
 | 
			
		||||
        /* terminates clipboard thread but the main server still lives */
 | 
			
		||||
        ErrorF("winClipboardProc - the clipboard thread has restarted %d times and seems to be unstable, disabling clipboard integration\n", clipboardRestarts);
 | 
			
		||||
        g_fClipboard = FALSE;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      sleep(WIN_CLIPBOARD_DELAY);
 | 
			
		||||
      ErrorF("winClipboardProc - trying to restart clipboard thread \n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Intialize the Clipboard module
 | 
			
		||||
| 
						 | 
				
			
			@ -60,14 +114,8 @@ winInitClipboard(void)
 | 
			
		|||
{
 | 
			
		||||
    winDebug("winInitClipboard ()\n");
 | 
			
		||||
 | 
			
		||||
    /* Wrap some internal server functions */
 | 
			
		||||
    if (ProcVector[X_SetSelectionOwner] != winProcSetSelectionOwner) {
 | 
			
		||||
        winProcSetSelectionOwnerOrig = ProcVector[X_SetSelectionOwner];
 | 
			
		||||
        ProcVector[X_SetSelectionOwner] = winProcSetSelectionOwner;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Spawn a thread for the Clipboard module */
 | 
			
		||||
    if (pthread_create(&g_ptClipboardProc, NULL, winClipboardProc, NULL)) {
 | 
			
		||||
    if (pthread_create(&g_ptClipboardProc, NULL, winClipboardThreadProc, NULL)) {
 | 
			
		||||
        /* Bail if thread creation failed */
 | 
			
		||||
        ErrorF("winInitClipboard - pthread_create failed.\n");
 | 
			
		||||
        return FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,59 +124,19 @@ winInitClipboard(void)
 | 
			
		|||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Create the Windows window that we use to receive Windows messages
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
HWND
 | 
			
		||||
winClipboardCreateMessagingWindow(void)
 | 
			
		||||
{
 | 
			
		||||
    WNDCLASSEX wc;
 | 
			
		||||
    HWND hwnd;
 | 
			
		||||
 | 
			
		||||
    /* Setup our window class */
 | 
			
		||||
    wc.cbSize = sizeof(WNDCLASSEX);
 | 
			
		||||
    wc.style = CS_HREDRAW | CS_VREDRAW;
 | 
			
		||||
    wc.lpfnWndProc = winClipboardWindowProc;
 | 
			
		||||
    wc.cbClsExtra = 0;
 | 
			
		||||
    wc.cbWndExtra = 0;
 | 
			
		||||
    wc.hInstance = GetModuleHandle(NULL);
 | 
			
		||||
    wc.hIcon = 0;
 | 
			
		||||
    wc.hCursor = 0;
 | 
			
		||||
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
 | 
			
		||||
    wc.lpszMenuName = NULL;
 | 
			
		||||
    wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS;
 | 
			
		||||
    wc.hIconSm = 0;
 | 
			
		||||
    RegisterClassEx(&wc);
 | 
			
		||||
 | 
			
		||||
    /* Create the window */
 | 
			
		||||
    hwnd = CreateWindowExA(0,   /* Extended styles */
 | 
			
		||||
                           WIN_CLIPBOARD_WINDOW_CLASS,  /* Class name */
 | 
			
		||||
                           WIN_CLIPBOARD_WINDOW_TITLE,  /* Window name */
 | 
			
		||||
                           WS_OVERLAPPED,       /* Not visible anyway */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Horizontal position */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Vertical position */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Right edge */
 | 
			
		||||
                           CW_USEDEFAULT,       /* Bottom edge */
 | 
			
		||||
                           (HWND) NULL, /* No parent or owner window */
 | 
			
		||||
                           (HMENU) NULL,        /* No menu */
 | 
			
		||||
                           GetModuleHandle(NULL),       /* Instance handle */
 | 
			
		||||
                           NULL);       /* Creation data */
 | 
			
		||||
    assert(hwnd != NULL);
 | 
			
		||||
 | 
			
		||||
    /* I'm not sure, but we may need to call this to start message processing */
 | 
			
		||||
    ShowWindow(hwnd, SW_HIDE);
 | 
			
		||||
 | 
			
		||||
    /* Similarly, we may need a call to this even though we don't paint */
 | 
			
		||||
    UpdateWindow(hwnd);
 | 
			
		||||
 | 
			
		||||
    return hwnd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
winFixClipboardChain(void)
 | 
			
		||||
winClipboardShutdown(void)
 | 
			
		||||
{
 | 
			
		||||
    if (g_fClipboard && g_hwndClipboard) {
 | 
			
		||||
        PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
  /* Close down clipboard resources */
 | 
			
		||||
  if (g_fClipboard && g_fClipboardStarted) {
 | 
			
		||||
    /* Synchronously destroy the clipboard window */
 | 
			
		||||
    winClipboardWindowDestroy();
 | 
			
		||||
 | 
			
		||||
    /* Wait for the clipboard thread to exit */
 | 
			
		||||
    pthread_join(g_ptClipboardProc, NULL);
 | 
			
		||||
 | 
			
		||||
    g_fClipboardStarted = FALSE;
 | 
			
		||||
 | 
			
		||||
    winDebug("winClipboardShutdown - Clipboard thread has exited.\n");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,36 +33,21 @@
 | 
			
		|||
#ifdef HAVE_XWIN_CONFIG_H
 | 
			
		||||
#include <xwin-config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "win.h"
 | 
			
		||||
#include "dixstruct.h"
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Constants
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define CLIP_NUM_SELECTIONS		2
 | 
			
		||||
#define CLIP_OWN_PRIMARY		0
 | 
			
		||||
#define CLIP_OWN_CLIPBOARD		1
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local function prototypes
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
DISPATCH_PROC(winProcEstablishConnection);
 | 
			
		||||
DISPATCH_PROC(winProcSetSelectionOwner);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * References to external symbols
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
extern Bool g_fClipboardLaunched;
 | 
			
		||||
extern Bool g_fClipboardStarted;
 | 
			
		||||
extern Bool g_fClipboard;
 | 
			
		||||
extern Window g_iClipboardWindow;
 | 
			
		||||
extern Atom g_atomLastOwnedSelection;
 | 
			
		||||
extern HWND g_hwndClipboard;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Wrapper for internal EstablishConnection function.
 | 
			
		||||
| 
						 | 
				
			
			@ -127,13 +112,6 @@ winProcEstablishConnection(ClientPtr client)
 | 
			
		|||
    /* Clear original function pointer */
 | 
			
		||||
    winProcEstablishConnectionOrig = NULL;
 | 
			
		||||
 | 
			
		||||
    /* If the clipboard client has already been started, abort */
 | 
			
		||||
    if (g_fClipboardLaunched) {
 | 
			
		||||
        ErrorF("winProcEstablishConnection - Clipboard client already "
 | 
			
		||||
               "launched, returning.\n");
 | 
			
		||||
        return iReturn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Startup the clipboard client if clipboard mode is being used */
 | 
			
		||||
    if (g_fClipboard) {
 | 
			
		||||
        /*
 | 
			
		||||
| 
						 | 
				
			
			@ -163,207 +141,5 @@ winProcEstablishConnection(ClientPtr client)
 | 
			
		|||
        ErrorF("winProcEstablishConnection - winInitClipboard returned.\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Flag that clipboard client has been launched */
 | 
			
		||||
    g_fClipboardLaunched = TRUE;
 | 
			
		||||
 | 
			
		||||
    return iReturn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Wrapper for internal SetSelectionOwner function.
 | 
			
		||||
 * Grabs ownership of Windows clipboard when X11 clipboard owner changes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
winProcSetSelectionOwner(ClientPtr client)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    DrawablePtr pDrawable;
 | 
			
		||||
    WindowPtr pWindow = None;
 | 
			
		||||
    Bool fOwnedToNotOwned = FALSE;
 | 
			
		||||
    static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None };
 | 
			
		||||
    static unsigned long s_ulServerGeneration = 0;
 | 
			
		||||
 | 
			
		||||
    REQUEST(xSetSelectionOwnerReq);
 | 
			
		||||
 | 
			
		||||
    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
 | 
			
		||||
 | 
			
		||||
    winDebug("winProcSetSelectionOwner - Hello.\n");
 | 
			
		||||
 | 
			
		||||
    /* Watch for server reset */
 | 
			
		||||
    if (s_ulServerGeneration != serverGeneration) {
 | 
			
		||||
        /* Save new generation number */
 | 
			
		||||
        s_ulServerGeneration = serverGeneration;
 | 
			
		||||
 | 
			
		||||
        /* Initialize static variables */
 | 
			
		||||
        for (i = 0; i < CLIP_NUM_SELECTIONS; ++i)
 | 
			
		||||
            s_iOwners[i] = None;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Abort if clipboard not completely initialized yet */
 | 
			
		||||
    if (!g_fClipboardStarted) {
 | 
			
		||||
        /* ErrorF ("winProcSetSelectionOwner - Clipboard not yet started, "
 | 
			
		||||
           "aborting.\n"); */
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Grab window if we have one */
 | 
			
		||||
    if (None != stuff->window) {
 | 
			
		||||
        /* Grab the Window from the request */
 | 
			
		||||
        int rc =
 | 
			
		||||
            dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess);
 | 
			
		||||
        if (rc != Success) {
 | 
			
		||||
            ErrorF("winProcSetSelectionOwner - Found BadWindow, aborting.\n");
 | 
			
		||||
            goto winProcSetSelectionOwner_Done;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Now we either have a valid window or None */
 | 
			
		||||
 | 
			
		||||
    /* Save selection owners for monitored selections, ignore other selections */
 | 
			
		||||
    if (XA_PRIMARY == stuff->selection) {
 | 
			
		||||
        /* Look for owned -> not owned transition */
 | 
			
		||||
        if (None == stuff->window && None != s_iOwners[CLIP_OWN_PRIMARY]) {
 | 
			
		||||
            fOwnedToNotOwned = TRUE;
 | 
			
		||||
 | 
			
		||||
            winDebug("winProcSetSelectionOwner - PRIMARY - Going from "
 | 
			
		||||
                     "owned to not owned.\n");
 | 
			
		||||
 | 
			
		||||
            /* Adjust last owned selection */
 | 
			
		||||
            if (None != s_iOwners[CLIP_OWN_CLIPBOARD])
 | 
			
		||||
                g_atomLastOwnedSelection = MakeAtom("CLIPBOARD", 9, TRUE);
 | 
			
		||||
            else
 | 
			
		||||
                g_atomLastOwnedSelection = None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Save new selection owner or None */
 | 
			
		||||
        s_iOwners[CLIP_OWN_PRIMARY] = stuff->window;
 | 
			
		||||
 | 
			
		||||
        winDebug("winProcSetSelectionOwner - PRIMARY - Now owned by: %d\n",
 | 
			
		||||
                 stuff->window);
 | 
			
		||||
    }
 | 
			
		||||
    else if (MakeAtom("CLIPBOARD", 9, TRUE) == stuff->selection) {
 | 
			
		||||
        /* Look for owned -> not owned transition */
 | 
			
		||||
        if (None == stuff->window && None != s_iOwners[CLIP_OWN_CLIPBOARD]) {
 | 
			
		||||
            fOwnedToNotOwned = TRUE;
 | 
			
		||||
 | 
			
		||||
            winDebug("winProcSetSelectionOwner - CLIPBOARD - Going from "
 | 
			
		||||
                     "owned to not owned.\n");
 | 
			
		||||
 | 
			
		||||
            /* Adjust last owned selection */
 | 
			
		||||
            if (None != s_iOwners[CLIP_OWN_PRIMARY])
 | 
			
		||||
                g_atomLastOwnedSelection = XA_PRIMARY;
 | 
			
		||||
            else
 | 
			
		||||
                g_atomLastOwnedSelection = None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Save new selection owner or None */
 | 
			
		||||
        s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window;
 | 
			
		||||
 | 
			
		||||
        winDebug("winProcSetSelectionOwner - CLIPBOARD - Now owned by: %d\n",
 | 
			
		||||
                 stuff->window);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * At this point, if one of the selections is still owned by the 
 | 
			
		||||
     * clipboard manager then it should be marked as unowned since
 | 
			
		||||
     * we will be taking ownership of the Win32 clipboard.
 | 
			
		||||
     */
 | 
			
		||||
    if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY])
 | 
			
		||||
        s_iOwners[CLIP_OWN_PRIMARY] = None;
 | 
			
		||||
    if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD])
 | 
			
		||||
        s_iOwners[CLIP_OWN_CLIPBOARD] = None;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Handle case when selection is being disowned,
 | 
			
		||||
     * WM_DRAWCLIPBOARD did not do the disowning,
 | 
			
		||||
     * both monitored selections are no longer owned,
 | 
			
		||||
     * an owned to not owned transition was detected,
 | 
			
		||||
     * and we currently own the Win32 clipboard.
 | 
			
		||||
     */
 | 
			
		||||
    if (stuff->window == None
 | 
			
		||||
        && s_iOwners[CLIP_OWN_PRIMARY] == None
 | 
			
		||||
        && s_iOwners[CLIP_OWN_CLIPBOARD] == None
 | 
			
		||||
        && fOwnedToNotOwned
 | 
			
		||||
        && g_hwndClipboard != NULL && g_hwndClipboard == GetClipboardOwner()) {
 | 
			
		||||
        winDebug("winProcSetSelectionOwner - We currently own the "
 | 
			
		||||
                 "clipboard and neither the PRIMARY nor the CLIPBOARD "
 | 
			
		||||
                 "selections are owned, releasing ownership of Win32 "
 | 
			
		||||
                 "clipboard.\n");
 | 
			
		||||
 | 
			
		||||
        /* Release ownership of the Windows clipboard */
 | 
			
		||||
        OpenClipboard(NULL);
 | 
			
		||||
        EmptyClipboard();
 | 
			
		||||
        CloseClipboard();
 | 
			
		||||
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Abort if no window at this point */
 | 
			
		||||
    if (None == stuff->window) {
 | 
			
		||||
        winDebug("winProcSetSelectionOwner - No window, returning.\n");
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Abort if invalid selection */
 | 
			
		||||
    if (!ValidAtom(stuff->selection)) {
 | 
			
		||||
        ErrorF("winProcSetSelectionOwner - Found BadAtom, aborting.\n");
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Cast Window to Drawable */
 | 
			
		||||
    pDrawable = (DrawablePtr) pWindow;
 | 
			
		||||
 | 
			
		||||
    /* Abort if clipboard manager is owning the selection */
 | 
			
		||||
    if (pDrawable->id == g_iClipboardWindow) {
 | 
			
		||||
        winDebug("winProcSetSelectionOwner - We changed ownership, "
 | 
			
		||||
                 "aborting.\n");
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Abort if root window is taking ownership */
 | 
			
		||||
    if (pDrawable->id == 0) {
 | 
			
		||||
        ErrorF("winProcSetSelectionOwner - Root window taking ownership, "
 | 
			
		||||
               "aborting\n");
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Close clipboard if we have it open already */
 | 
			
		||||
    if (GetOpenClipboardWindow() == g_hwndClipboard) {
 | 
			
		||||
        CloseClipboard();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Access the Windows clipboard */
 | 
			
		||||
    if (!OpenClipboard(g_hwndClipboard)) {
 | 
			
		||||
        ErrorF("winProcSetSelectionOwner - OpenClipboard () failed: %08x\n",
 | 
			
		||||
               (int) GetLastError());
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Take ownership of the Windows clipboard */
 | 
			
		||||
    if (!EmptyClipboard()) {
 | 
			
		||||
        ErrorF("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n",
 | 
			
		||||
               (int) GetLastError());
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Advertise regular text and unicode */
 | 
			
		||||
    SetClipboardData(CF_UNICODETEXT, NULL);
 | 
			
		||||
    SetClipboardData(CF_TEXT, NULL);
 | 
			
		||||
 | 
			
		||||
    /* Save handle to last owned selection */
 | 
			
		||||
    g_atomLastOwnedSelection = stuff->selection;
 | 
			
		||||
 | 
			
		||||
    /* Release the clipboard */
 | 
			
		||||
    if (!CloseClipboard()) {
 | 
			
		||||
        ErrorF("winProcSetSelectionOwner - CloseClipboard () failed: "
 | 
			
		||||
               "%08x\n", (int) GetLastError());
 | 
			
		||||
        goto winProcSetSelectionOwner_Done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 winProcSetSelectionOwner_Done:
 | 
			
		||||
    return (*winProcSetSelectionOwnerOrig) (client);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,13 +36,6 @@
 | 
			
		|||
#include <shellapi.h>
 | 
			
		||||
#include "winprefs.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * References to external globals
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
extern Bool g_fClipboardStarted;
 | 
			
		||||
#endif
 | 
			
		||||
/*
 | 
			
		||||
 * Local function prototypes
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,6 @@ pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		|||
 * Wrapped DIX functions
 | 
			
		||||
 */
 | 
			
		||||
winDispatchProcPtr winProcEstablishConnectionOrig = NULL;
 | 
			
		||||
winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clipboard variables
 | 
			
		||||
| 
						 | 
				
			
			@ -94,13 +93,7 @@ winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL;
 | 
			
		|||
 | 
			
		||||
Bool g_fUnicodeClipboard = TRUE;
 | 
			
		||||
Bool g_fClipboard = TRUE;
 | 
			
		||||
Bool g_fClipboardLaunched = FALSE;
 | 
			
		||||
Bool g_fClipboardStarted = FALSE;
 | 
			
		||||
pthread_t g_ptClipboardProc;
 | 
			
		||||
HWND g_hwndClipboard = NULL;
 | 
			
		||||
void *g_pClipboardDisplay = NULL;
 | 
			
		||||
Window g_iClipboardWindow = None;
 | 
			
		||||
Atom g_atomLastOwnedSelection = None;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -112,10 +105,4 @@ void
 | 
			
		|||
winInitializeGlobals(void)
 | 
			
		||||
{
 | 
			
		||||
    g_dwCurrentThreadID = GetCurrentThreadId();
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
    g_iClipboardWindow = None;
 | 
			
		||||
    g_pClipboardDisplay = NULL;
 | 
			
		||||
    g_atomLastOwnedSelection = None;
 | 
			
		||||
    g_hwndClipboard = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,8 +72,10 @@ typedef int (*winDispatchProcPtr) (ClientPtr);
 | 
			
		|||
 * Wrapped DIX functions
 | 
			
		||||
 */
 | 
			
		||||
extern winDispatchProcPtr winProcEstablishConnectionOrig;
 | 
			
		||||
extern winDispatchProcPtr winProcSetSelectionOwnerOrig;
 | 
			
		||||
#endif
 | 
			
		||||
extern Bool g_fUnicodeClipboard;
 | 
			
		||||
extern Bool g_fClipboard;
 | 
			
		||||
extern Bool g_fClipboardStarted;
 | 
			
		||||
 | 
			
		||||
/* The global X default icons */
 | 
			
		||||
#if defined(XWIN_MULTIWINDOW)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,9 @@
 | 
			
		|||
#include "winmsg.h"
 | 
			
		||||
#include "winmonitors.h"
 | 
			
		||||
#include "inputstr.h"
 | 
			
		||||
#ifdef XWIN_CLIPBOARD
 | 
			
		||||
#include "winclipboard/winclipboard.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Global variables
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue