Translating linebreaks when exchanging data via clipboard

git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@550 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Peter Åstrand 2003-12-05 10:36:04 +00:00
parent 3354831a4e
commit 8353259b40

79
xclip.c
View File

@ -36,6 +36,51 @@ static Atom targets[NUM_TARGETS];
static int have_primary = 0;
static int rdesktop_is_selection_owner = 0;
/* Replace CR-LF to LF (well, rather removing all CR:s) This is done
in-place. The length is updated. Handles embedded nulls */
static void
crlf2lf(uint8 * data, uint32 * length)
{
uint8 *dst, *src;
src = dst = data;
while (src < data + *length)
{
if (*src != '\x0d')
*dst++ = *src;
src++;
}
*length = dst - data;
}
/* Translate LF to CR-LF. To do this, we must allocate more memory.
The length is updated. */
static uint8 *
lf2crlf(uint8 * data, uint32 * length)
{
uint8 *result, *p, *o;
/* Worst case: Every char is LF */
result = xmalloc(*length * 2);
p = data;
o = result;
while (p < data + *length)
{
if (*p == '\x0a')
*o++ = '\x0d';
*o++ = *p++;
}
*length = o - result;
/* Convenience */
*o++ = '\0';
return result;
}
static void
xclip_provide_selection(XSelectionRequestEvent * req, Atom type, unsigned int format, uint8 * data,
uint32 length)
@ -86,6 +131,7 @@ xclip_handle_SelectionNotify(XSelectionEvent * event)
goto fail;
}
/* Negotiate target format */
if (event->target == targets_atom)
{
/* FIXME: We should choose format here based on what the server wanted */
@ -102,6 +148,7 @@ xclip_handle_SelectionNotify(XSelectionEvent * event)
{
DEBUG_CLIPBOARD(("Other party supports TEXT, choosing that as best_target\n"));
best_target = text_target;
break;
}
}
XFree(data);
@ -118,7 +165,22 @@ xclip_handle_SelectionNotify(XSelectionEvent * event)
goto fail;
}
cliprdr_send_data(data, nitems + 1);
/* Translate linebreaks, but only if not getting data from
other rdesktop instance */
if (event->target != rdesktop_clipboard_formats_atom)
{
uint8 *translated_data;
uint32 length = nitems;
DEBUG_CLIPBOARD(("Translating linebreaks before sending data\n"));
translated_data = lf2crlf(data, &length);
cliprdr_send_data(translated_data, length + 1);
xfree(translated_data); /* Not the same thing as XFree! */
}
else
{
cliprdr_send_data(data, nitems + 1);
}
XFree(data);
if (!rdesktop_is_selection_owner)
@ -240,6 +302,21 @@ ui_clip_format_announce(uint8 * data, uint32 length)
void
ui_clip_handle_data(uint8 * data, uint32 length)
{
if (selection_request.target != rdesktop_clipboard_formats_atom)
{
uint8 *firstnull;
/* translate linebreaks */
crlf2lf(data, &length);
/* Only send data up to null byte, if any */
firstnull = strchr(data, '\0');
if (firstnull)
{
length = firstnull - data + 1;
}
}
xclip_provide_selection(&selection_request, XA_STRING, 8, data, length - 1);
}