summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/winClipboard.test20
-rw-r--r--win/Makefile.in7
-rw-r--r--win/tkWinClipboard.c5
-rw-r--r--win/tkWinInt.h19
-rw-r--r--win/tkWinTest.c34
-rw-r--r--win/tkWinX.c45
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;
+}