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:
parent
3354831a4e
commit
8353259b40
77
xclip.c
77
xclip.c
@ -36,6 +36,51 @@ static Atom targets[NUM_TARGETS];
|
|||||||
static int have_primary = 0;
|
static int have_primary = 0;
|
||||||
static int rdesktop_is_selection_owner = 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
|
static void
|
||||||
xclip_provide_selection(XSelectionRequestEvent * req, Atom type, unsigned int format, uint8 * data,
|
xclip_provide_selection(XSelectionRequestEvent * req, Atom type, unsigned int format, uint8 * data,
|
||||||
uint32 length)
|
uint32 length)
|
||||||
@ -86,6 +131,7 @@ xclip_handle_SelectionNotify(XSelectionEvent * event)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Negotiate target format */
|
||||||
if (event->target == targets_atom)
|
if (event->target == targets_atom)
|
||||||
{
|
{
|
||||||
/* FIXME: We should choose format here based on what the server wanted */
|
/* 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"));
|
DEBUG_CLIPBOARD(("Other party supports TEXT, choosing that as best_target\n"));
|
||||||
best_target = text_target;
|
best_target = text_target;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(data);
|
XFree(data);
|
||||||
@ -118,7 +165,22 @@ xclip_handle_SelectionNotify(XSelectionEvent * event)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
cliprdr_send_data(data, nitems + 1);
|
||||||
|
}
|
||||||
XFree(data);
|
XFree(data);
|
||||||
|
|
||||||
if (!rdesktop_is_selection_owner)
|
if (!rdesktop_is_selection_owner)
|
||||||
@ -240,6 +302,21 @@ ui_clip_format_announce(uint8 * data, uint32 length)
|
|||||||
void
|
void
|
||||||
ui_clip_handle_data(uint8 * data, uint32 length)
|
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);
|
xclip_provide_selection(&selection_request, XA_STRING, 8, data, length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user