#define LOG_DEBUG(...) vncLogDebug(LOG_NAME, __VA_ARGS__)
static Atom xaPRIMARY, xaCLIPBOARD;
-static Atom xaTARGETS, xaTIMESTAMP, xaSTRING, xaTEXT;
+static Atom xaTARGETS, xaTIMESTAMP, xaSTRING, xaTEXT, xaUTF8_STRING;
static WindowPtr pWindow;
static Window wid;
xaTIMESTAMP = MakeAtom("TIMESTAMP", 9, TRUE);
xaSTRING = MakeAtom("STRING", 6, TRUE);
xaTEXT = MakeAtom("TEXT", 4, TRUE);
+ xaUTF8_STRING = MakeAtom("UTF8_STRING", 11, TRUE);
/* There are no hooks for when these are internal windows, so
* override the relevant handlers. */
/* FIXME: MULTIPLE target */
if (target == xaTARGETS) {
- Atom targets[] = { xaTARGETS, xaTIMESTAMP, xaSTRING, xaTEXT };
+ Atom targets[] = { xaTARGETS, xaTIMESTAMP,
+ xaSTRING, xaTEXT, xaUTF8_STRING };
rc = ChangeWindowProperty(pWin, realProperty, XA_ATOM, 32,
PropModeReplace,
clientCutText, TRUE);
if (rc != Success)
return rc;
+ } else if (target == xaUTF8_STRING) {
+ unsigned char* buffer;
+ unsigned char* out;
+ size_t len;
+
+ const unsigned char* in;
+ size_t in_len;
+
+ buffer = malloc(clientCutTextLen*2);
+ if (buffer == NULL)
+ return BadAlloc;
+
+ out = buffer;
+ len = 0;
+ in = clientCutText;
+ in_len = clientCutTextLen;
+ while (in_len > 0) {
+ if (*in & 0x80) {
+ *out++ = 0xc0 | (*in >> 6);
+ *out++ = 0x80 | (*in & 0x3f);
+ len += 2;
+ in++;
+ in_len--;
+ } else {
+ *out++ = *in++;
+ len++;
+ in_len--;
+ }
+ }
+
+ rc = ChangeWindowProperty(pWin, realProperty, xaUTF8_STRING, 8,
+ PropModeReplace, len, buffer, TRUE);
+ free(buffer);
+ if (rc != Success)
+ return rc;
} else {
return BadMatch;
}
if (vncHasAtom(xaSTRING, (const Atom*)prop->data, prop->size))
vncSelectionRequest(selection, xaSTRING);
+ else if (vncHasAtom(xaUTF8_STRING, (const Atom*)prop->data, prop->size))
+ vncSelectionRequest(selection, xaUTF8_STRING);
} else if (target == xaSTRING) {
if (prop->format != 8)
return;
return;
vncServerCutText(prop->data, prop->size);
+ } else if (target == xaUTF8_STRING) {
+ unsigned char* buffer;
+ unsigned char* out;
+ size_t len;
+
+ const unsigned char* in;
+ size_t in_len;
+
+ if (prop->format != 8)
+ return;
+ if (prop->type != xaUTF8_STRING)
+ return;
+
+ buffer = malloc(prop->size);
+ if (buffer == NULL)
+ return;
+
+ out = buffer;
+ len = 0;
+ in = prop->data;
+ in_len = prop->size;
+ while (in_len > 0) {
+ if ((*in & 0x80) == 0x00) {
+ *out++ = *in++;
+ len++;
+ in_len--;
+ } else if ((*in & 0xe0) == 0xc0) {
+ unsigned ucs;
+ ucs = (*in++ & 0x1f) << 6;
+ in_len--;
+ if (in_len > 0) {
+ ucs |= (*in++ & 0x3f);
+ in_len--;
+ }
+ if (ucs <= 0xff)
+ *out++ = ucs;
+ else
+ *out++ = '?';
+ len++;
+ } else {
+ *out++ = '?';
+ len++;
+ do {
+ in++;
+ in_len--;
+ } while ((in_len > 0) && ((*in & 0xc0) == 0x80));
+ }
+ }
+
+ vncServerCutText((const char*)buffer, len);
+
+ free(buffer);
}
}