/* functional parameters */
int reading; /* read instead of writing? */
int convert_to_ctext = True; /* Xmb convert to compound text? */
+int verbose;
const char usagemsg[] =
"usage: xcopy [ -r ] [ -u | -c ] [ -C ]\n"
" -T get the time stamp of the selection contents\n"
" -a atom get an arbitrary form of the selection data\n"
" -F do not fork in write mode\n"
+ " -v proceed verbosely when reading selection\n"
" also: xcopy --version report version number\n"
" xcopy --help display this help text\n"
" xcopy --licence display the (MIT) licence text\n"
}
const char licencemsg[] =
- "xcopy is copyright 2001-2004 Simon Tatham.\n"
+ "xcopy is copyright 2001-2004,2008 Simon Tatham.\n"
"\n"
"Permission is hereby granted, free of charge, to any person\n"
"obtaining a copy of this software and associated documentation files\n"
mode = CUSTOM;
} else if (!strcmp(p, "-F")) {
fork_when_writing = False;
+ } else if (!strcmp(p, "-v")) {
+ verbose = True;
} else if (!strcmp(p, "--help")) {
usage();
return 0;
Atom expected_type = (Atom)None;
int expected_format = 8;
+static const char *translate_atom(Display *disp, Atom atom)
+{
+ if (atom == None)
+ return "None";
+ else
+ return XGetAtomName(disp, atom);
+}
+
/*
* Returns TRUE if we need to enter an event loop, FALSE otherwise.
*/
*/
if (XGetSelectionOwner(disp, sel_atom) == None) {
/* No primary selection, so use the cut buffer. */
+ if (verbose)
+ fprintf(stderr, "no selection owner: trying cut buffer\n");
if (strtype == XA_STRING)
do_paste(DefaultRootWindow(disp), XA_CUT_BUFFER0, False);
return False;
} else {
Atom sel_property = XInternAtom(disp, "VT_SELECTION", False);
+ if (verbose)
+ fprintf(stderr, "calling XConvertSelection: selection=%s"
+ " target=%s property=%s requestor=%08lx\n",
+ translate_atom(disp, sel_atom),
+ translate_atom(disp, strtype),
+ translate_atom(disp, sel_property),
+ ourwin);
XConvertSelection(disp, sel_atom, strtype,
sel_property, ourwin, CurrentTime);
return True;
*/
XSetSelectionOwner (disp, sel_atom, ourwin, CurrentTime);
if (XGetSelectionOwner (disp, sel_atom) != ourwin)
- error ("unable to obtain primary X selection\n");
+ error ("unable to obtain primary X selection");
compound_text_atom = XInternAtom(disp, "COMPOUND_TEXT", False);
if (strtype == XA_STRING) {
/*
unsigned char *data;
Atom *adata;
+ if (property == (Atom)None)
+ return None; /* ICCCM says this isn't allowed */
+
/*
* Fetch the requestor's window property giving a list of
* selection requests.
adata = (Atom *)data;
for (i = 0; i+1 < nitems; i += 2) {
- adata[i+1] = convert_sel_inner(requestor, adata[i], adata[i+1]);
+ if (adata[i+1] != (Atom)None) /* ICCCM says this isn't allowed */
+ adata[i+1] = convert_sel_inner(requestor, adata[i],
+ adata[i+1]);
}
XChangeProperty (disp, requestor, property,
return property;
} else {
+ if (property == (Atom)None)
+ property = target; /* ICCCM says this is a sensible default */
return convert_sel_inner(requestor, target, property);
}
}
if (reading) {
switch (ev.type) {
case SelectionNotify:
+ if (verbose)
+ fprintf(stderr, "got SelectionNotify: requestor=%08lx "
+ "selection=%s target=%s property=%s\n",
+ ev.xselection.requestor,
+ translate_atom(disp, ev.xselection.selection),
+ translate_atom(disp, ev.xselection.target),
+ translate_atom(disp, ev.xselection.property));
+
if (ev.xselection.property != None)
do_paste(ev.xselection.requestor,
ev.xselection.property, True);
Delete, AnyPropertyType, &actual_type,
&actual_format, &nitems, &bytes_after,
(unsigned char **) &data) == Success) {
+ if (verbose)
+ fprintf(stderr, "got %ld items of %d-byte data, type=%s;"
+ " %ld to go\n", nitems, actual_format,
+ translate_atom(disp, actual_type), bytes_after);
+
if (nitems > 0) {
/*
* We expect all returned chunks of data to be
*/
if ((nread & 3) != 0) {
error("unexpected data size: %d read (not a multiple"
- " of 4), but more to come\n", nread);
+ " of 4), but more to come", nread);
}
if (expected_type != (Atom)None && actual_type != expected_type) {
- char *expout = XGetAtomName(disp, expected_type);
- char *gotout = (actual_type == (Atom)None ? "None" :
- XGetAtomName(disp, actual_type));
- error("unexpected data type: expected %s, got %s\n",
+ const char *expout = translate_atom(disp, expected_type);
+ const char *gotout = translate_atom(disp, actual_type);
+ error("unexpected data type: expected %s, got %s",
expout, gotout);
}
if (expected_format && expected_format != actual_format) {
- error("unexpected data format: expected %d-bit, got %d-bit\n",
+ error("unexpected data format: expected %d-bit, got %d-bit",
expected_format, actual_format);
}
}
int i;
for (i = 0; i < nitems; i++) {
Atom x = ((Atom *)data)[i];
- printf("%s\n", XGetAtomName(disp, x));
+ printf("%s\n", translate_atom(disp, x));
}
} else if (mode == TIMESTAMP) {
assert(actual_format == 32);