diff options
-rw-r--r-- | tests/winClipboard.test | 20 | ||||
-rw-r--r-- | win/Makefile.in | 7 | ||||
-rw-r--r-- | win/tkWinClipboard.c | 5 | ||||
-rw-r--r-- | win/tkWinInt.h | 19 | ||||
-rw-r--r-- | win/tkWinTest.c | 34 | ||||
-rw-r--r-- | win/tkWinX.c | 45 |
6 files changed, 105 insertions, 25 deletions
diff --git a/tests/winClipboard.test b/tests/winClipboard.test index e693c6a..fca13eb 100644 --- a/tests/winClipboard.test +++ b/tests/winClipboard.test @@ -7,10 +7,10 @@ # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 by Sun Microsystems, Inc. -# Copyright (c) 1998-1999 by Scriptics Corporation. +# Copyright (c) 1998-2000 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: winClipboard.test,v 1.6 1999/12/14 06:53:15 hobbs Exp $ +# RCS: @(#) $Id: winClipboard.test,v 1.7 2000/04/12 18:52:14 hobbs Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { source [file join [pwd] [file dirname [info script]] defs.tcl] @@ -38,6 +38,7 @@ test winClipboard-1.2 {TkSelGetSelection} {pcOnly} { test winClipboard-1.3 {TkSelGetSelection & TkWinClipboardRender} {pcOnly} { clipboard clear clipboard append abcd + update list [selection get -selection CLIPBOARD] [testclipboard] } {abcd abcd} test winClipboard-1.4 {TkSelGetSelection & TkWinClipboardRender} {pcOnly} { @@ -51,6 +52,21 @@ test winClipboard-1.5 {TkSelGetSelection & TkWinClipboardRender} {pcOnly} { list [selection get -selection CLIPBOARD] [testclipboard] } [list "line 1\u00c7\nline 2" [bytestring "line 1\u00c7\r\nline 2"]] +test winClipboard-2.1 {TkSelUpdateClipboard reentrancy problem} {pcOnly} { + clipboard clear + clipboard append -type OUR_ACTION "action data" + clipboard append "string data" + update + list [selection get -selection CLIPBOARD -type OUR_ACTION] [testclipboard] +} [list "action data" "string data"] +test winClipboard-2.2 {TkSelUpdateClipboard reentrancy problem} {pcOnly} { + clipboard clear + clipboard append -type OUR_ACTION "new data" + clipboard append "more data in string" + update + list [testclipboard] [selection get -selection CLIPBOARD -type OUR_ACTION] +} [list "more data in string" "new data"] + # cleanup ::tcltest::cleanupTests return diff --git a/win/Makefile.in b/win/Makefile.in index 1af4b34..3b91f52 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -4,7 +4,7 @@ # "autoconf" program (constructs like "@foo@" will get replaced in the # actual Makefile. # -# RCS: @(#) $Id: Makefile.in,v 1.19 2000/04/08 06:59:09 hobbs Exp $ +# RCS: @(#) $Id: Makefile.in,v 1.20 2000/04/12 18:51:11 hobbs Exp $ TCLVERSION = @TCL_VERSION@ VERSION = @TK_VERSION@ @@ -132,9 +132,10 @@ DEPARG = "$(shell cygpath $(PATHTYPE) $<)" # Setting the VPATH variable to a list of paths will cause the # makefile to look into these paths when resolving .c to .obj -# dependencies. +# dependencies. Note the ':' to avoid autoconf's habit of deleting +# all VPATH lines without an explicit ':' in it. -VPATH = $(GENERIC_DIR);$(WIN_DIR);$(UNIX_DIR);$(XLIB_DIR);$(RC_DIR) +VPATH = $(GENERIC_DIR);$(WIN_DIR);$(UNIX_DIR);$(XLIB_DIR);$(RC_DIR) # : # warning flags CFLAGS_WARNING = @CFLAGS_WARNING@ diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c index c5a6cd8..b08147a 100644 --- a/win/tkWinClipboard.c +++ b/win/tkWinClipboard.c @@ -4,11 +4,12 @@ * This file contains functions for managing the clipboard. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-2000 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinClipboard.c,v 1.6 1999/09/21 06:43:06 hobbs Exp $ + * RCS: @(#) $Id: tkWinClipboard.c,v 1.7 2000/04/12 18:51:11 hobbs Exp $ */ #include "tkWinInt.h" @@ -380,6 +381,7 @@ static void UpdateClipboard(hwnd) HWND hwnd; { + TkWinUpdatingClipboard(TRUE); OpenClipboard(hwnd); EmptyClipboard(); @@ -394,6 +396,7 @@ UpdateClipboard(hwnd) SetClipboardData(CF_TEXT, NULL); } CloseClipboard(); + TkWinUpdatingClipboard(FALSE); } /* diff --git a/win/tkWinInt.h b/win/tkWinInt.h index 339b164..710779a 100644 --- a/win/tkWinInt.h +++ b/win/tkWinInt.h @@ -6,11 +6,12 @@ * Tk. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-2000 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinInt.h,v 1.9 2000/03/31 09:24:27 hobbs Exp $ + * RCS: @(#) $Id: tkWinInt.h,v 1.10 2000/04/12 18:51:11 hobbs Exp $ */ #ifndef _TKWININT @@ -90,11 +91,11 @@ typedef union { * The following macros are used to retrieve internal values from a Drawable. */ -#define TkWinGetHWND(w) (((TkWinDrawable *) w)->window.handle) -#define TkWinGetWinPtr(w) (((TkWinDrawable*)w)->window.winPtr) -#define TkWinGetHBITMAP(w) (((TkWinDrawable*)w)->bitmap.handle) -#define TkWinGetColormap(w) (((TkWinDrawable*)w)->bitmap.colormap) -#define TkWinGetHDC(w) (((TkWinDrawable *) w)->winDC.hdc) +#define TkWinGetHWND(w) (((TkWinDrawable *) w)->window.handle) +#define TkWinGetWinPtr(w) (((TkWinDrawable *) w)->window.winPtr) +#define TkWinGetHBITMAP(w) (((TkWinDrawable *) w)->bitmap.handle) +#define TkWinGetColormap(w) (((TkWinDrawable *) w)->bitmap.colormap) +#define TkWinGetHDC(w) (((TkWinDrawable *) w)->winDC.hdc) /* * The following structure is used to encapsulate palette information. @@ -157,6 +158,12 @@ extern int tkpWinRopModes[]; EXTERN LRESULT CALLBACK TkWinChildProc _ANSI_ARGS_((HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)); +/* + * Special proc needed as tsd accessor function between + * tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard + */ +EXTERN void TkWinUpdatingClipboard(int mode); + #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT diff --git a/win/tkWinTest.c b/win/tkWinTest.c index 00553eb..6f7ee7e 100644 --- a/win/tkWinTest.c +++ b/win/tkWinTest.c @@ -5,11 +5,12 @@ * the Windows platform. * * Copyright (c) 1997 Sun Microsystems, Inc. + * Copyright (c) 2000 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinTest.c,v 1.2 1999/04/16 01:51:53 stanton Exp $ + * RCS: @(#) $Id: tkWinTest.c,v 1.3 2000/04/12 18:51:11 hobbs Exp $ */ #include "tkWinInt.h" @@ -21,8 +22,9 @@ HWND tkWinCurrentDialog; */ int TkplatformtestInit(Tcl_Interp *interp); -static int TestclipboardCmd(ClientData clientData, - Tcl_Interp *interp, int argc, char **argv); +static int TestclipboardObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); static int TestwineventCmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv); @@ -52,7 +54,7 @@ TkplatformtestInit( * Add commands for platform specific tests on MacOS here. */ - Tcl_CreateCommand(interp, "testclipboard", TestclipboardCmd, + Tcl_CreateObjCommand(interp, "testclipboard", TestclipboardObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "testwinevent", TestwineventCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); @@ -63,7 +65,7 @@ TkplatformtestInit( /* *---------------------------------------------------------------------- * - * TestclipboardCmd -- + * TestclipboardObjCmd -- * * This procedure implements the testclipboard command. It provides * a way to determine the actual contents of the Windows clipboard. @@ -78,24 +80,40 @@ TkplatformtestInit( */ static int -TestclipboardCmd(clientData, interp, argc, argv) +TestclipboardObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window for application. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { TkWindow *winPtr = (TkWindow *) clientData; HGLOBAL handle; char *data; + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, (char *) NULL); + return TCL_ERROR; + } if (OpenClipboard(NULL)) { + /* + * We could consider using CF_UNICODETEXT on NT, but then we + * would have to convert it from External. Instead we'll just + * take this and do "bytestring" at the Tcl level for Unicode + * inclusive text + */ handle = GetClipboardData(CF_TEXT); if (handle != NULL) { data = GlobalLock(handle); Tcl_AppendResult(interp, data, (char *) NULL); GlobalUnlock(handle); + } else { + Tcl_AppendResult(interp, "null clipboard handle", (char *) NULL); + return TCL_ERROR; } CloseClipboard(); + } else { + Tcl_AppendResult(interp, "couldn't open clipboard", (char *) NULL); + return TCL_ERROR; } return TCL_OK; } diff --git a/win/tkWinX.c b/win/tkWinX.c index d537a7f..0ccf07a 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -5,12 +5,12 @@ * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * Copyright (c) 1994 Software Research Associates, Inc. - * Copyright (c) 1998 by Scriptics Corporation. + * Copyright (c) 1998-2000 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinX.c,v 1.8 2000/03/31 09:24:27 hobbs Exp $ + * RCS: @(#) $Id: tkWinX.c,v 1.9 2000/04/12 18:51:11 hobbs Exp $ */ #include "tkWinInt.h" @@ -41,6 +41,7 @@ TCL_DECLARE_MUTEX(winXMutex) typedef struct ThreadSpecificData { TkDisplay *winDisplay; /* TkDisplay structure that * * represents Windows screen. */ + int updatingClipboard; /* If 1, we are updating the clipboard */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -397,13 +398,14 @@ TkpOpenDisplay(display_name) screen->white_pixel = RGB(255, 255, 255); screen->black_pixel = RGB(0, 0, 0); - display->screens = screen; - display->nscreens = 1; - display->default_screen = 0; + display->screens = screen; + display->nscreens = 1; + display->default_screen = 0; screen->cmap = XCreateColormap(display, None, screen->root_visual, AllocNone); tsdPtr->winDisplay = (TkDisplay *) ckalloc(sizeof(TkDisplay)); tsdPtr->winDisplay->display = display; + tsdPtr->updatingClipboard = FALSE; return tsdPtr->winDisplay; } @@ -682,6 +684,8 @@ GenerateXEvent(hwnd, message, wParam, lParam) { XEvent event; TkWindow *winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!winPtr || winPtr->window == None) { return; @@ -746,6 +750,13 @@ GenerateXEvent(hwnd, message, wParam, lParam) } case WM_DESTROYCLIPBOARD: + if (tsdPtr->updatingClipboard == TRUE) { + /* + * We want to avoid this event if we are the ones that caused + * this event. + */ + return; + } event.type = SelectionClear; event.xselectionclear.selection = Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD"); @@ -1149,3 +1160,27 @@ TkpGetMS() { return GetTickCount(); } + +/* + *---------------------------------------------------------------------- + * + * TkWinUpdatingClipboard -- + * + * + * Results: + * Number of milliseconds. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkWinUpdatingClipboard(int mode) +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + tsdPtr->updatingClipboard = mode; +} |