diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2012-05-09 08:47:19 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2012-05-09 08:47:19 (GMT) |
commit | 3d51560e948b0600d4f3990406bca9167099c16b (patch) | |
tree | fdad3c55760b4861ec15a6ac36cdad6e2c8eb9d2 | |
parent | a31a6d94b9e9430c76fdc460fae32a9f1290d733 (diff) | |
download | tcl-3d51560e948b0600d4f3990406bca9167099c16b.zip tcl-3d51560e948b0600d4f3990406bca9167099c16b.tar.gz tcl-3d51560e948b0600d4f3990406bca9167099c16b.tar.bz2 |
[Bug 473946]: special characters not correctly sent
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | win/tclWinDde.c | 57 |
2 files changed, 51 insertions, 10 deletions
@@ -1,3 +1,7 @@ +2012-05-09 Jan Nijtmans <nijtmans@users.sf.net> + + * win/tclWinDde.c: [Bug 473946]: special characters not correctly sent + 2012-05-02 Jan Nijtmans <nijtmans@users.sf.net> * generic/configure.in: Better detection and implementation for cpuid 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; } |