Skip to content

Commit

Permalink
cygwin: VT clipboard UTF16/32 interoperability (fix #640)
Browse files Browse the repository at this point in the history
  • Loading branch information
U-WIN-IMS7KJ8CV43\Administrator authored and U-WIN-IMS7KJ8CV43\Administrator committed Nov 30, 2019
1 parent d4735f4 commit 9f372f0
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 4 deletions.
41 changes: 41 additions & 0 deletions WinPort/src/Backend/TTY/TTYFar2lClipboardBackend.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <fcntl.h>
#include <utils.h>
#include <base64.h>
#include <ConvertUTF.h>
#include "TTYFar2lClipboardBackend.h"
#include "FSClipboardBackend.h"

Expand Down Expand Up @@ -147,8 +148,30 @@ void *TTYFar2lClipboardBackend::OnClipboardSetData(UINT format, void *data)

try {
StackSerializer stk_ser;

#if (__WCHAR_MAX__ <= 0xffff)
UTF32 *new_data = nullptr;
if (format == CF_UNICODETEXT && len != 0) { // UTF16 -> UTF32
int cnt = 0;
const UTF16 *src = (const UTF16 *)data;
CalcSpaceUTF16toUTF32(&cnt, &src, src + len / sizeof(UTF16), lenientConversion);
new_data = (UTF32 *)malloc((cnt + 1) * sizeof(UTF32));
if (new_data != nullptr) {
new_data[cnt] = 0;
src = (const UTF16 *)data;
UTF32 *dst = new_data;
ConvertUTF16toUTF32( &src, src + len / sizeof(UTF16), &dst, dst + cnt, lenientConversion);
len = cnt * sizeof(UTF32);
}
}
stk_ser.Push(new_data ? new_data : data, len);
stk_ser.PushPOD(len);
free(new_data);
#else
stk_ser.Push(data, len);
stk_ser.PushPOD(len);
#endif

stk_ser.PushPOD(format);
stk_ser.PushPOD('s');
Far2lInterract(stk_ser, true);
Expand Down Expand Up @@ -176,6 +199,24 @@ void *TTYFar2lClipboardBackend::OnClipboardGetData(UINT format)
data = malloc(len);
if (data) {
stk_ser.Pop(data, len);
#if (__WCHAR_MAX__ <= 0xffff)
if (format == CF_UNICODETEXT) { // UTF32 -> UTF16
int cnt = 0;
const UTF32 *src = (const UTF32 *)data;
CalcSpaceUTF32toUTF16(&cnt, &src, src + len / sizeof(UTF32), lenientConversion);
UTF16 *new_data = (UTF16 *)malloc((cnt + 1) * sizeof(UTF16));
if (new_data != nullptr) {
new_data[cnt] = 0;
src = (const UTF32 *)data;
UTF16 *dst = new_data;
ConvertUTF32toUTF16( &src, src + len / sizeof(UTF32), &dst, dst + cnt, lenientConversion);
free(data);
data = new_data;
len = cnt * sizeof(UTF16);
}
}
#endif

return data;
}
}
Expand Down
55 changes: 51 additions & 4 deletions far2l/VTFar2lExtensios.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <assert.h>
#include <base64.h>
#include <utils.h>
#include <ConvertUTF.h>
#include <fcntl.h>
#include "../WinPort/src/SavedScreen.h"

Expand Down Expand Up @@ -267,6 +268,14 @@ void VTFar2lExtensios::OnInterract_ClipboardIsFormatAvailable(StackSerializer &s
stk_ser.PushPOD(out);
}

void ClipboardData_Local2Remote(UINT fmt, void *&data, uint32_t &len)
{
}

void ClipboardData_Remote2Local(UINT fmt, void *&data, uint32_t &len)
{
}

void VTFar2lExtensios::OnInterract_ClipboardSetData(StackSerializer &stk_ser)
{
char out = -1;
Expand All @@ -280,6 +289,23 @@ void VTFar2lExtensios::OnInterract_ClipboardSetData(StackSerializer &stk_ser)
if (len) {
data = malloc(len);
stk_ser.Pop(data, len);
#if (__WCHAR_MAX__ <= 0xffff)
if (fmt == CF_UNICODETEXT) { // UTF32 -> UTF16
int cnt = 0;
const UTF32 *src = (const UTF32 *)data;
CalcSpaceUTF32toUTF16(&cnt, &src, src + len / sizeof(UTF32), lenientConversion);
UTF16 *new_data = (UTF16 *)malloc((cnt + 1) * sizeof(UTF16));
if (new_data != nullptr) {
new_data[cnt] = 0;
src = (const UTF32 *)data;
UTF16 *dst = new_data;
ConvertUTF32toUTF16( &src, src + len / sizeof(UTF32), &dst, dst + cnt, lenientConversion);
free(data);
data = new_data;
len = cnt * sizeof(UTF16);
}
}
#endif
} else
data = nullptr;

Expand All @@ -297,11 +323,32 @@ void VTFar2lExtensios::OnInterract_ClipboardGetData(StackSerializer &stk_ser)

UINT fmt;
stk_ser.PopPOD(fmt);
void *ptr = allowed ? WINPORT(GetClipboardData)(fmt) : nullptr;
void *data = allowed ? WINPORT(GetClipboardData)(fmt) : nullptr;
stk_ser.Clear();
uint32_t len = ptr ? GetMallocSize(ptr) : 0;
if (len)
stk_ser.Push(ptr, len);
uint32_t len = data ? GetMallocSize(data) : 0;
if (len) {
#if (__WCHAR_MAX__ <= 0xffff)
UTF32 *new_data = nullptr;
if (fmt == CF_UNICODETEXT) { // UTF16 -> UTF32
int cnt = 0;
const UTF16 *src = (const UTF16 *)data;
CalcSpaceUTF16toUTF32(&cnt, &src, src + len / sizeof(UTF16), lenientConversion);
new_data = (UTF32 *)malloc((cnt + 1) * sizeof(UTF32));
if (new_data != nullptr) {
new_data[cnt] = 0;
src = (const UTF16 *)data;
UTF32 *dst = new_data;
ConvertUTF16toUTF32( &src, src + len / sizeof(UTF16), &dst, dst + cnt, lenientConversion);
data = new_data;
len = cnt * sizeof(UTF32);
}
}
stk_ser.Push(data, len);
free(new_data);
#else
stk_ser.Push(data, len);
#endif
}
stk_ser.PushPOD(len);

if (allowed) { // prolong allowance
Expand Down

0 comments on commit 9f372f0

Please sign in to comment.