summaryrefslogtreecommitdiffstats
path: root/win/tclWinDde.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-05-09 08:47:19 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-05-09 08:47:19 (GMT)
commit3d51560e948b0600d4f3990406bca9167099c16b (patch)
treefdad3c55760b4861ec15a6ac36cdad6e2c8eb9d2 /win/tclWinDde.c
parenta31a6d94b9e9430c76fdc460fae32a9f1290d733 (diff)
downloadtcl-3d51560e948b0600d4f3990406bca9167099c16b.zip
tcl-3d51560e948b0600d4f3990406bca9167099c16b.tar.gz
tcl-3d51560e948b0600d4f3990406bca9167099c16b.tar.bz2
[Bug 473946]: special characters not correctly sent
Diffstat (limited to 'win/tclWinDde.c')
-rw-r--r--win/tclWinDde.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/win/tclWinDde.c b/win/tclWinDde.c
index aa51689..8dc8af4 100644
--- a/win/tclWinDde.c
+++ b/win/tclWinDde.c
@@ -100,6 +100,27 @@ int Tcl_DdeObjCmd(ClientData clientData, /* Used only for deletion */
Tcl_Obj *CONST objv[]); /* The arguments */
EXTERN int Dde_Init(Tcl_Interp *interp);
+
+/*
+ * The following structures allow us to select between the Unicode and ASCII
+ * interfaces at run time based on whether Unicode APIs are available. The
+ * Unicode APIs are preferable because they will handle characters outside
+ * of the current code page.
+ */
+
+typedef struct DdeWinProcs {
+ int uFmt;
+} DdeWinProcs;
+
+static DdeWinProcs *ddeWinProcs;
+
+static DdeWinProcs asciiProcs = {
+ CF_TEXT
+};
+
+static DdeWinProcs unicodeProcs = {
+ CF_UNICODETEXT
+};
/*
*----------------------------------------------------------------------
@@ -124,6 +145,16 @@ Dde_Init(
if (!Tcl_InitStubs(interp, "8.0", 0)) {
return TCL_ERROR;
}
+ /*
+ * Determine if the unicode interfaces are available and select the
+ * appropriate dde function table.
+ */
+
+ if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
+ ddeWinProcs = &unicodeProcs;
+ } else {
+ ddeWinProcs = &asciiProcs;
+ }
Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd, NULL, NULL);
@@ -537,7 +568,7 @@ DdeServerProc (
* last execute.
*/
- if (uFmt != CF_TEXT) {
+ if ((uFmt != CF_TEXT) && (uFmt != ddeWinProcs->uFmt)) {
return (HDDEDATA) FALSE;
}
@@ -562,11 +593,14 @@ DdeServerProc (
if (stricmp(utilString, "$TCLEVAL$EXECUTE$RESULT") == 0) {
returnString =
Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len);
- Tcl_DStringInit (&dString);
- returnString =
- Tcl_UtfToExternalDString (NULL, returnString, -1, &dString);
+ if (uFmt == CF_UNICODETEXT) {
+ Tcl_DStringFree(&dString);
+ returnString =
+ Tcl_WinUtfToTChar(returnString, len, &dString);
+ len = Tcl_DStringLength(&dString) + 1;
+ }
ddeReturn = DdeCreateDataHandle(ddeInstance,
- (BYTE *)returnString, (DWORD) len+1, 0, ddeItem, CF_TEXT,
+ (BYTE *)returnString, (DWORD) len+1, 0, ddeItem, uFmt,
0);
} else {
Tcl_Obj *variableObjPtr = Tcl_GetVar2Ex(
@@ -575,12 +609,15 @@ DdeServerProc (
if (variableObjPtr != NULL) {
returnString = Tcl_GetStringFromObj(variableObjPtr,
&len);
- Tcl_DStringInit (&dString);
- returnString =
- Tcl_UtfToExternalDString (NULL, returnString, -1, &dString);
+ if (uFmt == CF_UNICODETEXT) {
+ Tcl_DStringFree(&dString);
+ returnString =
+ Tcl_WinUtfToTChar(returnString, len, &dString);
+ len = Tcl_DStringLength(&dString) + 1;
+ }
ddeReturn = DdeCreateDataHandle(ddeInstance,
- (BYTE *)returnString, (DWORD) len+1, 0, ddeItem,
- CF_TEXT, 0);
+ (BYTE *)returnString, (DWORD) len+1, 0, ddeItem,
+ uFmt, 0);
} else {
ddeReturn = NULL;
}