* X Selection stuff, for cutting and pasting text to other windows.
*/
-static Boolean clip_x11_convert_selection_cb(Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *);
-static void clip_x11_lose_ownership_cb(Widget, Atom *);
+static Boolean clip_x11_convert_selection_cb(Widget w, Atom *sel_atom, Atom *target, Atom *type, XtPointer *value, long_u *length, int *format);
+static void clip_x11_lose_ownership_cb(Widget w, Atom *sel_atom);
+static void clip_x11_notify_cb(Widget w, Atom *sel_atom, Atom *target);
static void clip_x11_timestamp_cb(Widget w, XtPointer n, XEvent *event, Boolean *cont);
-static void clip_x11_request_selection_cb(Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *);
+static void clip_x11_request_selection_cb(Widget w, XtPointer success, Atom *sel_atom, Atom *type, XtPointer value, long_u *length, int *format);
/*
* Property callback to get a timestamp for XtOwnSelection.
/* Get the selection, using the event timestamp. */
if (XtOwnSelection(w, xproperty->atom, xproperty->time,
clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
- NULL) == OK)
+ clip_x11_notify_cb) == OK)
{
/* Set the "owned" flag now, there may have been a call to
* lose_ownership_cb in between. */
start_time = time(NULL);
while (success == MAYBE)
{
- if (XCheckTypedEvent(dpy, SelectionNotify, &event)
- || XCheckTypedEvent(dpy, SelectionRequest, &event)
- || XCheckTypedEvent(dpy, PropertyNotify, &event))
+ if (XCheckTypedEvent(dpy, PropertyNotify, &event)
+ || XCheckTypedEvent(dpy, SelectionNotify, &event)
+ || XCheckTypedEvent(dpy, SelectionRequest, &event))
{
/* This is where clip_x11_request_selection_cb() should be
* called. It may actually happen a bit later, so we loop
long_u *length,
int *format)
{
- char_u *string;
- char_u *result;
- int motion_type;
- VimClipboard *cbd;
- int i;
+ static char_u *save_result = NULL;
+ static long_u save_length = 0;
+ char_u *string;
+ int motion_type;
+ VimClipboard *cbd;
+ int i;
if (*sel_atom == clip_plus.sel_atom)
cbd = &clip_plus;
/* requestor wants to know what target types we support */
if (*target == targets_atom)
{
- Atom *array;
+ static Atom array[7];
- if ((array = (Atom *)XtMalloc((unsigned)(sizeof(Atom) * 7))) == NULL)
- return False;
*value = (XtPointer)array;
i = 0;
array[i++] = targets_atom;
*length += STRLEN(p_enc) + 2;
#endif
- *value = XtMalloc((Cardinal)*length);
- result = (char_u *)*value;
- if (result == NULL)
+ if (save_length < *length || save_length / 2 >= *length)
+ *value = XtRealloc((char *)save_result, (Cardinal)*length + 1);
+ else
+ *value = save_result;
+ if (*value == NULL)
{
vim_free(string);
return False;
}
+ save_result = (char_u *)*value;
+ save_length = *length;
if (*target == XA_STRING
#ifdef FEAT_MBYTE
#endif
)
{
- mch_memmove(result, string, (size_t)(*length));
+ mch_memmove(save_result, string, (size_t)(*length));
*type = *target;
}
else if (*target == compound_text_atom || *target == text_atom)
{
XTextProperty text_prop;
- char *string_nt = (char *)alloc((unsigned)*length + 1);
+ char *string_nt = (char *)save_result;
int conv_result;
/* create NUL terminated string which XmbTextListToTextProperty wants */
string_nt[*length] = NUL;
conv_result = XmbTextListToTextProperty(X_DISPLAY, (char **)&string_nt,
1, XCompoundTextStyle, &text_prop);
- vim_free(string_nt);
- XtFree(*value); /* replace with COMPOUND text */
if (conv_result != Success)
{
vim_free(string);
*value = (XtPointer)(text_prop.value); /* from plain text */
*length = text_prop.nitems;
*type = compound_text_atom;
+ XtFree((char *)save_result);
+ save_result = (char_u *)*value;
+ save_length = *length;
}
-
#ifdef FEAT_MBYTE
else if (*target == vimenc_atom)
{
int l = STRLEN(p_enc);
- result[0] = motion_type;
- STRCPY(result + 1, p_enc);
- mch_memmove(result + l + 2, string, (size_t)(*length - l - 2));
+ save_result[0] = motion_type;
+ STRCPY(save_result + 1, p_enc);
+ mch_memmove(save_result + l + 2, string, (size_t)(*length - l - 2));
*type = vimenc_atom;
}
#endif
-
else
{
- result[0] = motion_type;
- mch_memmove(result + 1, string, (size_t)(*length - 1));
+ save_result[0] = motion_type;
+ mch_memmove(save_result + 1, string, (size_t)(*length - 1));
*type = vim_atom;
}
*format = 8; /* 8 bits per char */
XtLastTimestampProcessed(XtDisplay(myShell)));
}
+ static void
+clip_x11_notify_cb(Widget w UNUSED, Atom *sel_atom UNUSED, Atom *target UNUSED)
+{
+ /* To prevent automatically freeing the selection value. */
+}
+
int
clip_x11_own_selection(Widget myShell, VimClipboard *cbd)
{
if (XtOwnSelection(myShell, cbd->sel_atom,
XtLastTimestampProcessed(XtDisplay(myShell)),
clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
- NULL) == False)
+ clip_x11_notify_cb) == False)
return FAIL;
}
else