static void LoseSelection(Widget w, Atom *selection) { Display *d = XtDisplay(w); XtGetSelectionValue(w, *selection, XA_UTF8_STRING(d), InsertClipboard, (XtPointer)(XA_UTF8_STRING(d)), CurrentTime); }
XCTRL_API uchar* get_selection(Display* dpy, char kind, Bool utf8) { uchar *sel_buf=NULL; /* buffer for selection data */ ulong sel_len = 0; /* length of sel_buf */ XEvent evt; /* X Event Structures */ uint context = XCLIB_XCOUT_NONE; Window win = make_selection_window(dpy); Atom seltype = selarg_to_seltype(dpy,kind); Atom target = utf8 ? XA_UTF8_STRING(dpy) : XA_STRING; if (seltype == XA_STRING) { sel_buf = (uchar*) XFetchBuffer(dpy, (int *) &sel_len, 0); } else { while (1) { if (context != XCLIB_XCOUT_NONE) { XNextEvent(dpy, &evt); } xcout(dpy, win, evt, seltype, target, &sel_buf, &sel_len, &context); if (context == XCLIB_XCOUT_FALLBACK) { context = XCLIB_XCOUT_NONE; target = XA_STRING; continue; } if (context == XCLIB_XCOUT_NONE) { break; } } } if (sel_len) { if (seltype == XA_STRING) { uchar*tmp=(uchar*)calloc(sel_len+1,1); strncpy((char*)tmp, (char*)sel_buf, sel_len); XFree(sel_buf); sel_buf=tmp; } sel_buf[sel_len]='\0'; } XDestroyWindow(dpy,win); return sel_buf; }
XCTRL_API void set_selection(Display*dpy, char kind, char *sel_buf, Bool utf8) { Atom seltype=selarg_to_seltype(dpy,kind); long sel_len=strlen(sel_buf); if (seltype == XA_STRING) { XStoreBuffer(dpy, (char*)sel_buf, (int)sel_len, 0); } else { XEvent evt; Window win = make_selection_window(dpy); Atom target = utf8 ? XA_UTF8_STRING(dpy) : XA_STRING; /* FIXME: Should not use CurrentTime per ICCCM section 2.1 */ XSetSelectionOwner(dpy, seltype, win, CurrentTime); while (1) { /* wait for a SelectionRequest event */ static uint clear = 0; static uint context = XCLIB_XCIN_NONE; static ulong sel_pos = 0; static Window cwin; static Atom pty; int finished; XNextEvent(dpy, &evt); finished = xcin(dpy, &cwin, evt, &pty, target, (uchar*)sel_buf, sel_len, &sel_pos, &context); if (evt.type == SelectionClear) { clear = 1; } if ((context == XCLIB_XCIN_NONE) && clear) { break; } if (finished) { break; } } XDestroyWindow(dpy,win); } }
static int doOut(Window win) { Atom sel_type = None; unsigned char *sel_buf; /* buffer for selection data */ unsigned long sel_len = 0; /* length of sel_buf */ XEvent evt; /* X Event Structures */ unsigned int context = XCLIB_XCOUT_NONE; if (sseln == XA_STRING) sel_buf = (unsigned char *) XFetchBuffer(dpy, (int *) &sel_len, 0); else { while (1) { /* only get an event if xcout() is doing something */ if (context != XCLIB_XCOUT_NONE) XNextEvent(dpy, &evt); /* fetch the selection, or part of it */ xcout(dpy, win, evt, sseln, target, &sel_type, &sel_buf, &sel_len, &context); if (context == XCLIB_XCOUT_BAD_TARGET) { if (target == XA_UTF8_STRING(dpy)) { /* fallback is needed. set XA_STRING to target and restart the loop. */ context = XCLIB_XCOUT_NONE; target = XA_STRING; continue; } else { /* no fallback available, exit with failure */ char *atom_name = XGetAtomName(dpy, target); fprintf(stderr, "Error: target %s not available\n", atom_name); XFree(atom_name); return EXIT_FAILURE; } } /* only continue if xcout() is doing something */ if (context == XCLIB_XCOUT_NONE) break; } } if (sel_len) { /* only print the buffer out, and free it, if it's not * empty */ printSelBuf(stdout, sel_type, sel_buf, sel_len); if (sseln == XA_STRING) XFree(sel_buf); else free(sel_buf); } return EXIT_SUCCESS; }
const char * visibleSelectionTarget(Display * d, Atom a) { const char *result = "?"; if (a == XA_STRING) { result = "XA_STRING"; } else if (a == XA_TEXT(d)) { result = "XA_TEXT()"; } else if (a == XA_COMPOUND_TEXT(d)) { result = "XA_COMPOUND_TEXT()"; } else if (a == XA_UTF8_STRING(d)) { result = "XA_UTF8_STRING()"; } else if (a == XA_TARGETS(d)) { result = "XA_TARGETS()"; } return result; }
/* process noutf8 and target command line options */ static void doOptTarget(void) { /* check for -noutf8 */ if (XrmGetResource(opt_db, "xclip.noutf8", "Xclip.noutf8", &rec_typ, &rec_val) ) { if (fverb == OVERBOSE) /* print in verbose mode only */ fprintf(stderr, "Using old UNICODE instead of UTF8.\n"); } else if (XrmGetResource(opt_db, "xclip.target", "Xclip.Target", &rec_typ, &rec_val) ) { target = XInternAtom(dpy, rec_val.addr, False); if (fverb == OVERBOSE) /* print in verbose mode only */ fprintf(stderr, "Using %s.\n", rec_val.addr); } else { target = XA_UTF8_STRING(dpy); if (fverb == OVERBOSE) /* print in verbose mode only */ fprintf(stderr, "Using UTF8_STRING.\n"); } }
static Boolean ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, XtPointer *value, unsigned long *length, int *format) { Display* d = XtDisplay(w); XSelectionRequestEvent* req = XtGetSelectionRequest(w, *selection, (XtRequestId)NULL); if (*target == XA_TARGETS(d)) { Atom* targetP; Atom* std_targets; unsigned long std_length; XmuConvertStandardSelection(w, req->time, selection, target, type, (XPointer*)&std_targets, &std_length, format); *value = XtMalloc(sizeof(Atom)*(std_length + 7)); targetP = *(Atom**)value; *targetP++ = XA_STRING; *targetP++ = XA_TEXT(d); *targetP++ = XA_UTF8_STRING(d); *targetP++ = XA_COMPOUND_TEXT(d); *targetP++ = XA_LENGTH(d); *targetP++ = XA_LIST_LENGTH(d); *targetP++ = XA_CHARACTER_POSITION(d); *length = std_length + (targetP - (*(Atom **) value)); memmove( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length); XtFree((char*)std_targets); *type = XA_ATOM; *format = 32; return True; } if (*target == XA_LIST_LENGTH(d) || *target == XA_LENGTH(d)) { long * temp; temp = (long *) XtMalloc(sizeof(long)); if (*target == XA_LIST_LENGTH(d)) *temp = 1L; else /* *target == XA_LENGTH(d) */ *temp = (long) TextLength (text); *value = (XPointer) temp; *type = XA_INTEGER; *length = 1L; *format = 32; return True; } if (*target == XA_CHARACTER_POSITION(d)) { long * temp; temp = (long *) XtMalloc(2 * sizeof(long)); temp[0] = (long) 0; temp[1] = TextLength (text); *value = (XPointer) temp; *type = XA_SPAN(d); *length = 2L; *format = 32; return True; } if (*target == XA_STRING || *target == XA_TEXT(d) || *target == XA_UTF8_STRING(d) || *target == XA_COMPOUND_TEXT(d)) { Arg args[1]; Widget source; XTextProperty prop; int ret, style = XStdICCTextStyle; /* a safe default for TEXT */ char *data; source = XawTextGetSource (text); XtSetArg (args[0], XtNstring, &data); XtGetValues (source, args, 1); if (*target == XA_UTF8_STRING(d)) style = XUTF8StringStyle; else if (*target == XA_COMPOUND_TEXT(d)) style = XCompoundTextStyle; else if (*target == XA_STRING) style = XStringStyle; ret = XmbTextListToTextProperty (d, &data, 1, style, &prop); if (ret >= Success) { *length = prop.nitems; *value = prop.value; *type = prop.encoding; *format = prop.format; return True; } else return False; } if (XmuConvertStandardSelection(w, req->time, selection, target, type, (XPointer *) value, length, format)) return True; return False; }
/*ARGSUSED*/ static void InsertClipboard(Widget w, XtPointer client_data, Atom *selection, Atom *type, XtPointer value, unsigned long *length, int *format) { Display *d = XtDisplay(w); Atom target = (Atom)client_data; Boolean convert_failed = (*type == XT_CONVERT_FAIL); if (!convert_failed) { char **list; int i, ret, count; XTextProperty prop; prop.value = value; prop.nitems = *length; prop.format = *format; prop.encoding = *type; ret = XmbTextPropertyToTextList(d, &prop, &list, &count); if (ret >= Success) { /* manuals say something about multiple strings in a disjoint text selection (?), it should be harmless to get them all */ for (i = 0; i < count; i++) NewCurrentClipContents(list[i], strlen(list[i])); XFreeStringList(list); } else convert_failed = True; XFree(value); } if (convert_failed) { /* if UTF8_STRING failed try COMPOUND_TEXT */ if (target == XA_UTF8_STRING(d)) { XtGetSelectionValue(w, *selection, XA_COMPOUND_TEXT(d), InsertClipboard, (XtPointer)(XA_COMPOUND_TEXT(d)), CurrentTime); return; } /* if COMPOUND_TEXT failed try STRING */ else if (target == XA_COMPOUND_TEXT(d)) { XtGetSelectionValue(w, *selection, XA_STRING, InsertClipboard, NULL, CurrentTime); return; } /* all conversions failed */ else { Arg arg; XtSetArg (arg, XtNlabel, "CLIPBOARD selection conversion failed"); XtSetValues (failDialog, &arg, 1); CenterWidgetOnWidget (failDialogShell, text); XtPopup (failDialogShell, XtGrabNone); #ifdef XKB XkbStdBell (d, XtWindow(w), 0, XkbBI_MinorError); #else XBell (d, 0); #endif } } XtOwnSelection(top, ClipboardAtom, CurrentTime, ConvertSelection, LoseSelection, NULL); }