+Atom convert_sel_inner(Window requestor, Atom target, Atom property) {
+ if (target == strtype) {
+ XChangeProperty (disp, requestor, property, strtype,
+ 8, PropModeReplace, seltext, sellen);
+ return property;
+ } else if (target == compound_text_atom && convert_to_ctext) {
+ XTextProperty tp;
+ XmbTextListToTextProperty (disp, &seltext, 1,
+ XCompoundTextStyle, &tp);
+ XChangeProperty (disp, requestor, property, target,
+ tp.format, PropModeReplace,
+ tp.value, tp.nitems);
+ return property;
+ } else if (target == targets_atom) {
+ Atom targets[16];
+ int len = 0;
+ targets[len++] = timestamp_atom;
+ targets[len++] = targets_atom;
+ targets[len++] = multiple_atom;
+ targets[len++] = strtype;
+ if (strtype != compound_text_atom && convert_to_ctext)
+ targets[len++] = compound_text_atom;
+ XChangeProperty (disp, requestor, property,
+ atom_atom, 32, PropModeReplace,
+ (unsigned char *)targets, len);
+ return property;
+ } else if (target == timestamp_atom) {
+ Time rettime = CurrentTime;
+ XChangeProperty (disp, requestor, property,
+ integer_atom, 32, PropModeReplace,
+ (unsigned char *)&rettime, 1);
+ return property;
+ } else {
+ return None;
+ }
+}
+
+Atom convert_sel_outer(Window requestor, Atom target, Atom property) {
+ if (target == multiple_atom) {
+ /*
+ * Support for the MULTIPLE selection type, since it's
+ * specified as required in the ICCCM. Completely
+ * untested, though, because I have no idea of what X
+ * application might implement it for me to test against.
+ */
+
+ int size = SELDELTA;
+ Atom actual_type;
+ int actual_format, i;
+ long nitems, bytes_after, nread;
+ unsigned char *data;
+ Atom *adata;
+
+ /*
+ * Fetch the requestor's window property giving a list of
+ * selection requests.
+ */
+ while (XGetWindowProperty(disp, requestor, property, 0, size,
+ False, AnyPropertyType, &actual_type,
+ &actual_format, &nitems, &bytes_after,
+ (unsigned char **) &data) == Success &&
+ nitems * (actual_format / 8) == size) {
+ XFree(data);
+ size *= 3 / 2;
+ }
+
+ if (actual_type != atom_pair_atom || actual_format != 32) {
+ XFree(data);
+ return None;
+ }
+
+ adata = (Atom *)data;
+
+ for (i = 0; i+1 < nitems; i += 2) {
+ adata[i+1] = convert_sel_inner(requestor, adata[i], adata[i+1]);
+ }
+
+ XChangeProperty (disp, requestor, property,
+ atom_pair_atom, 32, PropModeReplace,
+ data, nitems);
+
+ XFree(data);
+
+ return property;
+ } else {
+ return convert_sel_inner(requestor, target, property);
+ }
+}
+