summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--generic/tk.h18
-rw-r--r--library/console.tcl5
-rw-r--r--tests/winClipboard.test7
-rw-r--r--win/tkWinClipboard.c240
5 files changed, 236 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index f874388..257d937 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+1999-05-20 <redman@scriptics.com>
+
+ * library/console.tcl: Changed copyright string to read 1999
+ Scriptics Corp. in wish console about box.
+
+1999-05-19 <redman@scriptics.com>
+
+ * generic/tk.h: Add extern "C" block around entire header file for
+ C++ compilers to fix linkage issues. Submitted by Don Porter and
+ Paul Duffin.
+
+1999-05-18 <stanton@scriptics.com>
+
+ * tests/winClipboard.test:
+ * win/tkWinClipboard.c: Fixed clipboard code so it handles Unicode
+ data properly on Windows NT and 95. [Bug: 1791]
+
1999-05-07 <stanton@scriptics.com>
* library/menu.tcl: Fixed bug where tk_popup fails when called too
diff --git a/generic/tk.h b/generic/tk.h
index c5ea528..45ef472 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -12,13 +12,21 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tk.h,v 1.24 1999/04/30 23:40:44 stanton Exp $
+ * RCS: @(#) $Id: tk.h,v 1.25 1999/05/22 01:59:21 stanton Exp $
*/
#ifndef _TK
#define _TK
/*
+ * For C++ compilers, use extern "C"
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
* When version numbers change here, you must also go into the following files
* and update the version numbers:
*
@@ -1210,4 +1218,12 @@ typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData,
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
+/*
+ * end block for C++
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _TK */
diff --git a/library/console.tcl b/library/console.tcl
index 602f32d..0ea7716 100644
--- a/library/console.tcl
+++ b/library/console.tcl
@@ -4,8 +4,9 @@
# can be used by non-unix systems that do not have built-in support
# for shells.
#
-# RCS: @(#) $Id: console.tcl,v 1.4 1999/04/16 01:51:26 stanton Exp $
+# RCS: @(#) $Id: console.tcl,v 1.5 1999/05/22 01:59:21 stanton Exp $
#
+# Copyright (c) 1998-1999 Scriptics Corp.
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
@@ -470,7 +471,7 @@ proc tkConsoleExit {} {
proc tkConsoleAbout {} {
global tk_patchLevel
tk_messageBox -type ok -message "Tcl for Windows
-Copyright \251 1996 Sun Microsystems, Inc.
+Copyright \251 1999 Scriptics Corporation
Tcl [info patchlevel]
Tk $tk_patchLevel"
diff --git a/tests/winClipboard.test b/tests/winClipboard.test
index 446dbd1..492ced9 100644
--- a/tests/winClipboard.test
+++ b/tests/winClipboard.test
@@ -10,7 +10,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: winClipboard.test,v 1.4 1999/04/16 01:51:43 stanton Exp $
+# RCS: @(#) $Id: winClipboard.test,v 1.5 1999/05/22 01:59:22 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -39,6 +39,11 @@ test winClipboard-1.4 {TkSelGetSelection & TkWinClipboardRender} {pcOnly} {
clipboard append "line 1\nline 2"
list [selection get -selection CLIPBOARD] [testclipboard]
} [list "line 1\nline 2" "line 1\r\nline 2"]
+test winClipboard-1.5 {TkSelGetSelection & TkWinClipboardRender} {pcOnly} {
+ clipboard clear
+ clipboard append "line 1\u00c7\nline 2"
+ list [selection get -selection CLIPBOARD] [testclipboard]
+} [list "line 1\u00c7\nline 2" [bytestring "line 1\u00c7\r\nline 2"]]
# cleanup
::tcltest::cleanupTests
diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c
index de0b40c..cb7d1a8 100644
--- a/win/tkWinClipboard.c
+++ b/win/tkWinClipboard.c
@@ -8,12 +8,13 @@
* 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.3 1999/04/16 01:51:49 stanton Exp $
+ * RCS: @(#) $Id: tkWinClipboard.c,v 1.4 1999/05/22 01:59:22 stanton Exp $
*/
#include "tkWinInt.h"
#include "tkSelect.h"
+static void UpdateClipboard _ANSI_ARGS_((HWND hwnd));
/*
*----------------------------------------------------------------------
@@ -49,43 +50,123 @@ TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
* selection, once it has been retrieved. */
ClientData clientData; /* Arbitrary value to pass to proc. */
{
- char *data, *buffer, *destPtr;
+ char *data, *destPtr;
Tcl_DString ds;
HGLOBAL handle;
- int result, length;
-
- if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD"))
- && (target == XA_STRING)) {
- if (OpenClipboard(NULL)) {
- handle = GetClipboardData(CF_TEXT);
- if (handle != NULL) {
- data = GlobalLock(handle);
- length = strlen(data);
- buffer = ckalloc(length+1);
- destPtr = buffer;
- while (*data != '\0') {
- if (*data != '\r') {
- *destPtr = *data;
- destPtr++;
- }
- data++;
- }
- *destPtr = '\0';
- GlobalUnlock(handle);
- CloseClipboard();
- Tcl_ExternalToUtfDString(NULL, buffer, -1, &ds);
- ckfree(buffer);
- result = (*proc)(clientData, interp, Tcl_DStringValue(&ds));
- Tcl_DStringFree(&ds);
- return result;
- }
+ Tcl_Encoding encoding;
+ int result, locale;
+
+ if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
+ || (target != XA_STRING)
+ || !OpenClipboard(NULL)) {
+ goto error;
+ }
+
+ /*
+ * Attempt to get the data in Unicode form if available as this is
+ * less work that CF_TEXT.
+ */
+
+ result = TCL_ERROR;
+ if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ handle = GetClipboardData(CF_UNICODETEXT);
+ if (!handle) {
CloseClipboard();
+ goto error;
+ }
+ data = GlobalLock(handle);
+ Tcl_DStringInit(&ds);
+ Tcl_UniCharToUtfDString((Tcl_UniChar *)data,
+ Tcl_UniCharLen((Tcl_UniChar *)data), &ds);
+ GlobalUnlock(handle);
+ } else if (IsClipboardFormatAvailable(CF_TEXT)
+ && IsClipboardFormatAvailable(CF_LOCALE)) {
+ /*
+ * Determine the encoding to use to convert this text.
+ */
+
+ handle = GetClipboardData(CF_LOCALE);
+ if (!handle) {
+ CloseClipboard();
+ goto error;
+ }
+
+ /*
+ * Get the locale identifier, determine the proper code page to use,
+ * and find the corresponding encoding.
+ */
+
+ Tcl_DStringInit(&ds);
+ Tcl_DStringAppend(&ds, "cp######", -1);
+ data = GlobalLock(handle);
+
+
+ /*
+ * Even though the documentation claims that GetLocaleInfo expects an
+ * LCID, on Windows 9x it really seems to expect a LanguageID.
+ */
+
+ locale = LANGIDFROMLCID(*((int*)data));
+ GetLocaleInfo(locale, LOCALE_IDEFAULTANSICODEPAGE,
+ Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2);
+ GlobalUnlock(handle);
+
+ encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds));
+ Tcl_DStringFree(&ds);
+
+ if (!encoding) {
+ CloseClipboard();
+ goto error;
+ }
+
+ /*
+ * Fetch the text and convert it to UTF.
+ */
+
+ handle = GetClipboardData(CF_TEXT);
+ if (!handle) {
+ Tcl_FreeEncoding(encoding);
+ CloseClipboard();
+ goto error;
+ }
+ data = GlobalLock(handle);
+ Tcl_ExternalToUtfDString(encoding, data, -1, &ds);
+ GlobalUnlock(handle);
+ Tcl_FreeEncoding(encoding);
+
+ } else {
+ CloseClipboard();
+ goto error;
+ }
+
+ /*
+ * Translate CR/LF to LF.
+ */
+
+ data = destPtr = Tcl_DStringValue(&ds);
+ while (*data) {
+ if (data[0] == '\r' && data[1] == '\n') {
+ data++;
+ } else {
+ *destPtr++ = *data++;
}
}
+ *destPtr = '\0';
+
+ /*
+ * Pass the data off to the selection procedure.
+ */
+ result = (*proc)(clientData, interp, Tcl_DStringValue(&ds));
+ Tcl_DStringFree(&ds);
+ CloseClipboard();
+ return result;
+
+error:
Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
- " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target),
- "\" not defined", (char *) NULL);
+ " selection doesn't exist or form \"",
+ Tk_GetAtomName(tkwin, target),
+ "\" not defined", (char *) NULL);
return TCL_ERROR;
}
@@ -132,10 +213,7 @@ XSetSelectionOwner(display, selection, owner, time)
*/
if (GetClipboardOwner() != hwnd) {
- OpenClipboard(hwnd);
- EmptyClipboard();
- SetClipboardData(CF_TEXT, NULL);
- CloseClipboard();
+ UpdateClipboard(hwnd);
}
}
}
@@ -174,6 +252,12 @@ TkWinClipboardRender(dispPtr, format)
if (targetPtr->type == XA_STRING)
break;
}
+
+ /*
+ * Count the number of newlines so we can add space for them in
+ * the resulting string.
+ */
+
length = 0;
if (targetPtr != NULL) {
for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
@@ -187,6 +271,11 @@ TkWinClipboardRender(dispPtr, format)
}
}
}
+
+ /*
+ * Copy the data and change EOL characters.
+ */
+
buffer = rawText = ckalloc(length + 1);
if (targetPtr != NULL) {
for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
@@ -201,19 +290,43 @@ TkWinClipboardRender(dispPtr, format)
}
}
*buffer = '\0';
- Tcl_UtfToExternalDString(NULL, rawText, -1, &ds);
- ckfree(rawText);
- handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
- Tcl_DStringLength(&ds)+1);
- if (!handle) {
+
+ /*
+ * Depending on the platform, turn the data into Unicode or the
+ * system encoding before placing it on the clipboard.
+ */
+
+ if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
+ Tcl_DStringInit(&ds);
+ Tcl_UtfToUniCharDString(rawText, -1, &ds);
+ ckfree(rawText);
+ handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
+ Tcl_DStringLength(&ds)+2);
+ if (!handle) {
+ Tcl_DStringFree(&ds);
+ return;
+ }
+ buffer = GlobalLock(handle);
+ memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 2);
+ GlobalUnlock(handle);
Tcl_DStringFree(&ds);
- return;
+ SetClipboardData(CF_UNICODETEXT, handle);
+ } else {
+ Tcl_UtfToExternalDString(NULL, rawText, -1, &ds);
+ ckfree(rawText);
+ handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
+ Tcl_DStringLength(&ds)+1);
+ if (!handle) {
+ Tcl_DStringFree(&ds);
+ return;
+ }
+ buffer = GlobalLock(handle);
+ memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 1);
+ GlobalUnlock(handle);
+ Tcl_DStringFree(&ds);
+ SetClipboardData(CF_TEXT, handle);
}
- buffer = GlobalLock(handle);
- memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 1);
- GlobalUnlock(handle);
- Tcl_DStringFree(&ds);
- SetClipboardData(CF_TEXT, handle);
+
return;
}
@@ -240,10 +353,43 @@ TkSelUpdateClipboard(winPtr, targetPtr)
TkClipboardTarget *targetPtr;
{
HWND hwnd = TkWinGetHWND(winPtr->window);
+ UpdateClipboard(hwnd);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateClipboard --
+ *
+ * Take ownership of the clipboard, clear it, and indicate to the
+ * system the supported formats.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+UpdateClipboard(hwnd)
+ HWND hwnd;
+{
OpenClipboard(hwnd);
EmptyClipboard();
- SetClipboardData(CF_TEXT, NULL);
+
+ /*
+ * CF_UNICODETEXT is only supported on NT, but it it is preffered
+ * when possible.
+ */
+
+ if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
+ SetClipboardData(CF_UNICODETEXT, NULL);
+ } else {
+ SetClipboardData(CF_TEXT, NULL);
+ }
CloseClipboard();
}