summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--XClipboard.ad126
-rw-r--r--xclipboard.c738
-rw-r--r--xclipboard.man148
-rw-r--r--xcutsel.c325
-rw-r--r--xcutsel.man105
5 files changed, 1442 insertions, 0 deletions
diff --git a/XClipboard.ad b/XClipboard.ad
new file mode 100644
index 0000000..7e3b1d2
--- /dev/null
+++ b/XClipboard.ad
@@ -0,0 +1,126 @@
+! $Xorg: XClipboard.ad,v 1.3 2000/08/17 19:54:12 cpqbld Exp $
+*Command*Font: -*-helvetica-bold-r-normal--*-120-*-*-*-*-iso8859-1
+*Label*Font: -*-helvetica-bold-r-normal--*-120-*-*-*-*-iso8859-1
+*Text*Font: -*-courier-medium-r-normal--*-120-*-*-*-*-iso8859-1
+
+*quit.label: Quit
+*quit.top: ChainTop
+*quit.bottom: ChainTop
+*quit.left: ChainLeft
+*quit.right: ChainLeft
+*quit.translations: #override \n\
+ <Btn1Down>,<Btn1Up>:Quit() unset()
+
+*delete.label: Delete
+*delete.fromHoriz: quit
+*delete.top: ChainTop
+*delete.bottom: ChainTop
+*delete.left: ChainLeft
+*delete.right: ChainLeft
+*delete.translations: #override \n\
+ <Btn1Down>,<Btn1Up>:DeleteClip() unset()
+
+*new.label: New
+*new.fromHoriz: delete
+*new.top: ChainTop
+*new.bottom: ChainTop
+*new.left: ChainLeft
+*new.right: ChainLeft
+*new.translations: #override \n\
+ <Btn1Down>,<Btn1Up>:NewClip() unset()
+
+*save.label: Save
+*save.fromHoriz: new
+*save.top: ChainTop
+*save.bottom: ChainTop
+*save.left: ChainLeft
+*save.right: ChainLeft
+*save.translations: #override \n\
+ <Btn1Down>,<Btn1Up>:Save() unset()
+
+*next.label: Next
+*next.fromHoriz: save
+*next.top: ChainTop
+*next.bottom: ChainTop
+*next.left: ChainLeft
+*next.right: ChainLeft
+*next.translations: #override \n\
+ <Btn1Down>,<Btn1Up>:NextClip() unset()
+
+*prev.label: Prev
+*prev.fromHoriz: next
+*prev.top: ChainTop
+*prev.bottom: ChainTop
+*prev.left: ChainLeft
+*prev.right: ChainLeft
+*prev.translations: #override \n\
+ <Btn1Down>,<Btn1Up>:PrevClip() unset()
+
+*index.fromHoriz: prev
+*index.top: ChainTop
+*index.bottom: ChainTop
+*index.left: ChainLeft
+*index.right: ChainLeft
+*index.resizable: true
+
+*text.scrollVertical: WhenNeeded
+*text.scrollHorizontal: WhenNeeded
+*text.autoFill: on
+
+*text.fromVert: quit
+*text.top: ChainTop
+*text.bottom: ChainBottom
+*text.left: ChainLeft
+*text.right: ChainRight
+*text.resizable: true
+*text.width: 300
+
+XClipboard.geometry: 300x200
+*ShapeStyle: oval
+XClipboard.baseTranslations: #augment\n\
+ <Message>WM_PROTOCOLS: WMProtocols()\n
+*TransientShell.baseTranslations: #augment\n\
+ <Message>WM_PROTOCOLS: WMProtocols()\n
+
+*fileDialog.label: Save to file:
+*fileDialogShell.allowShellResize: true
+*fileDialogShell.title: File Save
+
+*fileDialog*accept.label: Accept
+*fileDialog*accept.translations: #override\
+ <BtnUp>: AcceptSave() unset()
+*fileDialog*value.translations: #override\
+ <Key>Return: AcceptSave() \n\
+ Ctrl<Key>S: no-op(ring-bell) \n\
+ Ctrl<Key>R: no-op(ring-bell) \n\
+ Ctrl<Key>M: no-op(ring-bell) \n\
+ Ctrl<Key>J: no-op(ring-bell) \n\
+ Meta<Key>I: no-op(ring-bell)
+*fileDialog*value.baseTranslations: #override\
+ <Key>Return: AcceptSave() \n\
+ Ctrl<Key>S: no-op(ring-bell) \n\
+ Ctrl<Key>R: no-op(ring-bell) \n\
+ Ctrl<Key>M: no-op(ring-bell) \n\
+ Ctrl<Key>J: no-op(ring-bell) \n\
+ Meta<Key>I: no-op(ring-bell)
+
+*fileDialog*cancel.label: Cancel
+*fileDialog*cancel.translations: #override\
+ <BtnUp>:CancelSave() unset()
+
+*failDialog*Label.resizable: true
+*failDialog.label: Can't write file
+*failDialogShell.title: Error
+*failDialogShell.allowShellResize: true
+
+*failDialog*continue.label: Continue
+*failDialog*continue.translations: #override\
+ <BtnUp>:FailContinue() unset()
+
+*failDialog*value.translations: #override\
+ <Key>Return: FailContinue() \n\
+ Ctrl<Key>S: no-op(ring-bell) \n\
+ Ctrl<Key>R: no-op(ring-bell) \n\
+ Ctrl<Key>M: no-op(ring-bell) \n\
+ Ctrl<Key>J: no-op(ring-bell) \n\
+ Meta<Key>I: no-op(ring-bell)
diff --git a/xclipboard.c b/xclipboard.c
new file mode 100644
index 0000000..f9e7418
--- /dev/null
+++ b/xclipboard.c
@@ -0,0 +1,738 @@
+/*
+ * $Xorg: xclipboard.c,v 1.4 2001/02/09 02:05:38 xorgcvs Exp $
+ *
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * *
+ * Author: Ralph Swick, DEC/Project Athena
+ * Updated for R4: Chris D. Peterson, MIT X Consortium.
+ * Reauthored by: Keith Packard, MIT X Consortium.
+ */
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xatom.h>
+
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/StdSel.h>
+
+#include <X11/Shell.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Dialog.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xfuncs.h>
+
+#ifdef XKB
+#include <X11/extensions/XKBbells.h>
+#endif
+
+#define Command commandWidgetClass
+#define Label labelWidgetClass
+#define Text asciiTextWidgetClass
+
+#define INFINITY 10000000 /* pretty big, huh? */
+
+typedef struct _Clip {
+ struct _Clip *next, *prev;
+ char *clip;
+ char *filename;
+ int avail;
+} ClipRec, *ClipPtr;
+
+extern char *malloc ();
+
+static Atom wm_delete_window;
+static Atom wm_protocols;
+
+static long TextLength (w)
+ Widget w;
+{
+ return XawTextSourceScan (XawTextGetSource (w),
+ (XawTextPosition) 0,
+ XawstAll, XawsdRight, 1, TRUE);
+}
+
+SaveClip (w, clip)
+ Widget w;
+ ClipPtr clip;
+{
+ Arg args[1];
+ char *data;
+ int len;
+ Widget source;
+
+ source = XawTextGetSource (w);
+ XtSetArg (args[0], XtNstring, &data);
+ XtGetValues (source, args, 1);
+ len = strlen (data);
+ if (len >= clip->avail)
+ {
+ if (clip->clip)
+ free (clip->clip);
+ clip->clip = malloc (len + 1);
+ if (!clip->clip)
+ clip->avail = 0;
+ else
+ clip->avail = len + 1;
+ }
+ if (clip->avail)
+ {
+ strcpy (clip->clip, data);
+ }
+}
+
+RestoreClip (w, clip)
+ Widget w;
+ ClipPtr clip;
+{
+ Arg args[1];
+ Widget source;
+
+ source = XawTextGetSource (w);
+ XtSetArg (args[0], XtNstring, clip->clip);
+ XtSetValues (source, args, 1);
+}
+
+/*ARGSUSED*/
+ClipPtr
+NewClip (w, old)
+ Widget w;
+ ClipPtr old;
+{
+ ClipPtr newClip;
+
+ newClip = (ClipPtr) malloc (sizeof (ClipRec));
+ if (!newClip)
+ return newClip;
+ newClip->clip = 0;
+ newClip->avail = 0;
+ newClip->prev = old;
+ newClip->next = NULL;
+ newClip->filename = NULL;
+ if (old)
+ {
+ newClip->next = old->next;
+ old->next = newClip;
+ }
+ return newClip;
+}
+
+/*ARGSUSED*/
+DeleteClip (w, clip)
+ Widget w;
+ ClipPtr clip;
+{
+ if (clip->prev)
+ clip->prev->next = clip->next;
+ if (clip->next)
+ clip->next->prev = clip->prev;
+ if (clip->clip)
+ free (clip->clip);
+ free ((char *) clip);
+}
+
+static ClipPtr currentClip;
+static Widget top;
+static Widget text, nextButton, prevButton, indexLabel;
+static Widget fileDialog, fileDialogShell;
+static Widget failDialog, failDialogShell;
+
+static int
+IndexCurrentClip ()
+{
+ int i = 0;
+ ClipPtr clip;
+
+ for (clip = currentClip; clip; clip = clip->prev)
+ i++;
+ return i;
+}
+
+static void
+set_button_state ()
+{
+ Boolean prevvalid, nextvalid;
+ Arg arg;
+ char labelString[10];
+
+ prevvalid = currentClip->prev != NULL;
+ nextvalid = currentClip->next != NULL;
+ XtSetArg (arg, XtNsensitive, prevvalid);
+ XtSetValues (prevButton, &arg, ONE);
+ XtSetArg (arg, XtNsensitive, nextvalid);
+ XtSetValues (nextButton, &arg, ONE);
+ sprintf (labelString, "%d", IndexCurrentClip ());
+ XtSetArg (arg, XtNlabel, labelString);
+ XtSetValues (indexLabel, &arg, ONE);
+}
+
+/* ARGSUSED */
+static void
+NextCurrentClip (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ if (currentClip->next)
+ {
+ SaveClip (text, currentClip);
+ currentClip = currentClip->next;
+ RestoreClip (text, currentClip);
+ set_button_state ();
+ }
+}
+
+/* ARGSUSED */
+static void
+PrevCurrentClip (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ if (currentClip->prev)
+ {
+ SaveClip (text, currentClip);
+ currentClip = currentClip->prev;
+ RestoreClip (text, currentClip);
+ set_button_state ();
+ }
+}
+
+/* ARGSUSED */
+static void
+DeleteCurrentClip (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ ClipPtr newCurrent;
+
+ if (currentClip->prev)
+ newCurrent = currentClip->prev;
+ else
+ newCurrent = currentClip->next;
+ if (newCurrent)
+ {
+ DeleteClip (text, currentClip);
+ currentClip = newCurrent;
+ RestoreClip (text, currentClip);
+ }
+ else
+ EraseTextWidget ();
+ set_button_state ();
+}
+
+/* ARGSUSED */
+static void
+Quit (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ XtCloseDisplay (XtDisplay (text));
+ exit (0);
+}
+
+static void
+CenterWidgetAtPoint (w, x, y)
+ Widget w;
+ int x, y;
+{
+ Arg args[2];
+ Dimension width, height;
+
+ XtSetArg(args[0], XtNwidth, &width);
+ XtSetArg(args[1], XtNheight, &height);
+ XtGetValues (w, args, 2);
+ x = x - (int) width / 2;
+ y = y - (int) height / 2;
+ if (x < 0)
+ x = 0;
+ else {
+ int scr_width = WidthOfScreen (XtScreen(w));
+ if (x + (int)width > scr_width)
+ x = scr_width - width;
+ }
+ if (y < 0)
+ y = 0;
+ else {
+ int scr_height = HeightOfScreen (XtScreen(w));
+ if (y + (int)height > scr_height)
+ y = scr_height - height;
+ }
+ XtSetArg(args[0], XtNx, x);
+ XtSetArg(args[1], XtNy, y);
+ XtSetValues (w, args, 2);
+}
+
+static void
+CenterWidgetOnEvent (w, e)
+ Widget w;
+ XEvent *e;
+{
+ CenterWidgetAtPoint (w, e->xbutton.x_root, e->xbutton.y_root);
+}
+
+static void
+CenterWidgetOnWidget (w, wT)
+ Widget w, wT;
+{
+ Position rootX, rootY;
+ Dimension width, height;
+ Arg args[2];
+
+ XtSetArg (args[0], XtNwidth, &width);
+ XtSetArg (args[1], XtNheight, &height);
+ XtGetValues (wT, args, 2);
+ XtTranslateCoords (wT, (Position) width/2, (Position) height/2, &rootX, &rootY);
+ CenterWidgetAtPoint (w, (int) rootX, (int) rootY);
+}
+
+/*ARGSUSED*/
+static void
+SaveToFile (w, e, argv, argc)
+ Widget w;
+ XEvent *e;
+ String *argv;
+ Cardinal *argc;
+{
+ Arg args[1];
+ char *filename;
+
+ filename = "clipboard";
+ if (currentClip->filename)
+ filename = currentClip->filename;
+ XtSetArg(args[0], XtNvalue, filename);
+ XtSetValues (fileDialog, args, 1);
+ CenterWidgetOnEvent (fileDialogShell, e);
+ XtPopup (fileDialogShell, XtGrabNone);
+}
+
+/*ARGSUSED*/
+static void
+AcceptSaveFile (w, e, argv, argc)
+ Widget w;
+ XEvent *e;
+ String *argv;
+ Cardinal *argc;
+{
+ char *filename;
+ Boolean success;
+ Arg args[1];
+
+ filename = XawDialogGetValueString (fileDialog);
+ success = XawAsciiSaveAsFile (XawTextGetSource (text), filename);
+ XtPopdown (fileDialogShell);
+ if (!success)
+ {
+ char failMessage[1024];
+
+ sprintf (failMessage, "Can't open file \"%s\"", filename);
+ XtSetArg (args[0], XtNlabel, failMessage);
+ XtSetValues (failDialog, args, 1);
+ CenterWidgetOnEvent (failDialogShell, e);
+ XtPopup (failDialogShell, XtGrabNone);
+ }
+ else
+ {
+ if (currentClip->filename)
+ free (currentClip->filename);
+ currentClip->filename = malloc (strlen (filename) + 1);
+ if (currentClip->filename)
+ strcpy (currentClip->filename, filename);
+ }
+}
+
+/* ARGSUSED */
+static void
+CancelSaveFile (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ XtPopdown (fileDialogShell);
+}
+
+/* ARGSUSED */
+static void
+FailContinue (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ XtPopdown (failDialogShell);
+}
+
+/*ARGSUSED*/
+static void WMProtocols(w, ev, params, n)
+ Widget w;
+ XEvent *ev;
+ String *params;
+ Cardinal *n;
+{
+ if (ev->type == ClientMessage &&
+ ev->xclient.message_type == wm_protocols &&
+ ev->xclient.data.l[0] == wm_delete_window) {
+ while (w && !XtIsShell(w))
+ w = XtParent(w);
+ if (w == top)
+ Quit(w, ev, params, n);
+ else if (w == fileDialogShell)
+ CancelSaveFile(w, ev, params, n);
+ else if (w == failDialogShell)
+ FailContinue(w, ev, params, n);
+ }
+}
+
+/* ARGUSED */
+static void
+NewCurrentClip (w, ev, parms, np)
+ Widget w;
+ XEvent *ev;
+ String *parms;
+ Cardinal *np;
+{
+ NewCurrentClipContents ("", 0);
+}
+
+NewCurrentClipContents (data, len)
+ char *data;
+ int len;
+{
+ XawTextBlock textBlock;
+
+ SaveClip (text, currentClip);
+
+ /* append new clips at the end */
+ while (currentClip && currentClip->next)
+ currentClip = currentClip->next;
+ /* any trailing clips with no text get overwritten */
+ if (strlen (currentClip->clip) != 0)
+ currentClip = NewClip (text, currentClip);
+
+ textBlock.ptr = data;
+ textBlock.firstPos = 0;
+ textBlock.length = len;
+ textBlock.format = FMT8BIT;
+ if (XawTextReplace(text, 0, TextLength (text), &textBlock)) {
+#ifdef XKB
+ XkbStdBell(XtDisplay(text), XtWindow(text), 0, XkbBI_Info);
+#else
+ XBell( XtDisplay(text), 0);
+#endif
+ }
+ set_button_state ();
+}
+
+EraseTextWidget ()
+{
+ XawTextBlock block;
+
+ block.ptr = "";
+ block.length = 0;
+ block.firstPos = 0;
+ block.format = FMT8BIT;
+
+ XawTextReplace(text, 0, INFINITY, &block);
+ /* If this fails, too bad. */
+}
+
+
+XtActionsRec xclipboard_actions[] = {
+ "NewClip", NewCurrentClip,
+ "NextClip", NextCurrentClip,
+ "PrevClip", PrevCurrentClip,
+ "DeleteClip", DeleteCurrentClip,
+ "Save", SaveToFile,
+ "AcceptSave", AcceptSaveFile,
+ "CancelSave", CancelSaveFile,
+ "FailContinue", FailContinue,
+ "Quit", Quit,
+ "WMProtocols", WMProtocols
+};
+
+static XrmOptionDescRec table[] = {
+ {"-w", "wrap", XrmoptionNoArg, "on"},
+/* {"-nw", "wrap", XrmoptionNoArg, "False"} */
+};
+
+static void LoseSelection ();
+static void InsertClipboard ();
+static Boolean ConvertSelection();
+static Atom ManagerAtom, ClipboardAtom;
+
+/*ARGSUSED*/
+static void
+InsertClipboard(w, client_data, selection, type, value, length, format)
+Widget w;
+XtPointer client_data;
+Atom *selection, *type;
+XtPointer value;
+unsigned long *length;
+int *format;
+{
+ if (*type != XT_CONVERT_FAIL)
+ NewCurrentClipContents ((char *) value, *length);
+ else
+ {
+ Arg arg;
+ XtSetArg (arg, XtNlabel, "CLIPBOARD selection conversion failed");
+ XtSetValues (failDialog, &arg, 1);
+ CenterWidgetOnWidget (failDialogShell, text);
+ XtPopup (failDialogShell, XtGrabNone);
+#ifdef XKB
+ XkbStdBell( XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError );
+#else
+ XBell( XtDisplay(w), 0 );
+#endif
+ }
+
+ XtOwnSelection(top, ClipboardAtom, CurrentTime,
+ ConvertSelection, LoseSelection, NULL);
+ XFree(value);
+}
+
+static Boolean ConvertSelection(w, selection, target,
+ type, value, length, format)
+ Widget w;
+ Atom *selection, *target, *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 + 5));
+ targetP = *(Atom**)value;
+ *targetP++ = XA_STRING;
+ *targetP++ = XA_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_COMPOUND_TEXT(d))
+ {
+ extern char *_XawTextGetSTRING();
+ if (*target == XA_COMPOUND_TEXT(d))
+ *type = *target;
+ else
+ *type = XA_STRING;
+ *length = TextLength (text);
+ *value = _XawTextGetSTRING((TextWidget) text, 0, *length);
+ *format = 8;
+ return True;
+ }
+
+ if (XmuConvertStandardSelection(w, req->time, selection, target, type,
+ (XPointer *)value, length, format))
+ return True;
+
+ return False;
+}
+
+static void LoseSelection(w, selection)
+ Widget w;
+ Atom *selection;
+{
+ XtGetSelectionValue(w, *selection, XA_STRING, InsertClipboard,
+ NULL, CurrentTime);
+}
+
+/*ARGSUSED*/
+static Boolean RefuseSelection(w, selection, target,
+ type, value, length, format)
+ Widget w;
+ Atom *selection, *target, *type;
+ XtPointer *value;
+ unsigned long *length;
+ int *format;
+{
+ return False;
+}
+
+/*ARGSUSED*/
+static void LoseManager(w, selection)
+ Widget w;
+ Atom *selection;
+{
+ XtError("another clipboard has taken over control\n");
+}
+
+typedef struct {
+ Boolean wrap;
+} ResourceData, *ResourceDataPtr;
+
+static ResourceData userOptions;
+
+#define Offset(field) XtOffsetOf(ResourceData, field)
+
+XtResource resources[] = {
+ {"wrap", "Wrap", XtRBoolean, sizeof(Boolean),
+ Offset(wrap), XtRImmediate, (XtPointer)False}
+};
+
+#undef Offset
+
+void
+main(argc, argv)
+int argc;
+char **argv;
+{
+ Arg args[4];
+ Cardinal n;
+ XtAppContext xtcontext;
+ Widget parent, quit, delete, new, save;
+
+ XtSetLanguageProc(NULL, NULL, NULL);
+
+ top = XtAppInitialize( &xtcontext, "XClipboard", table, XtNumber(table),
+ &argc, argv, NULL, NULL, 0);
+
+ XtGetApplicationResources(top, (XtPointer)&userOptions, resources,
+ XtNumber(resources), NULL, 0);
+
+ XtAppAddActions (xtcontext,
+ xclipboard_actions, XtNumber (xclipboard_actions));
+ /* CLIPBOARD_MANAGER is a non-standard mechanism */
+ ManagerAtom = XInternAtom(XtDisplay(top), "CLIPBOARD_MANAGER", False);
+ ClipboardAtom = XA_CLIPBOARD(XtDisplay(top));
+ if (XGetSelectionOwner(XtDisplay(top), ManagerAtom))
+ XtError("another clipboard is already running\n");
+
+ parent = XtCreateManagedWidget("form", formWidgetClass, top, NULL, ZERO);
+ quit = XtCreateManagedWidget("quit", Command, parent, NULL, ZERO);
+ delete = XtCreateManagedWidget("delete", Command, parent, NULL, ZERO);
+ new = XtCreateManagedWidget("new", Command, parent, NULL, ZERO);
+ save = XtCreateManagedWidget("save", Command, parent, NULL, ZERO);
+ nextButton = XtCreateManagedWidget("next", Command, parent, NULL, ZERO);
+ prevButton = XtCreateManagedWidget("prev", Command, parent, NULL, ZERO);
+ indexLabel = XtCreateManagedWidget("index", Label, parent, NULL, ZERO);
+
+ n=0;
+ XtSetArg(args[n], XtNtype, XawAsciiString); n++;
+ XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
+ if (userOptions.wrap) {
+ XtSetArg(args[n], XtNwrap, XawtextWrapWord); n++;
+ XtSetArg(args[n], XtNscrollHorizontal, False); n++;
+ }
+
+ text = XtCreateManagedWidget( "text", Text, parent, args, n);
+
+ currentClip = NewClip (text, (ClipPtr) 0);
+
+ set_button_state ();
+
+ fileDialogShell = XtCreatePopupShell("fileDialogShell",
+ transientShellWidgetClass,
+ top, NULL, ZERO);
+ fileDialog = XtCreateManagedWidget ("fileDialog", dialogWidgetClass,
+ fileDialogShell, NULL, ZERO);
+ XawDialogAddButton(fileDialog, "accept", NULL, NULL);
+ XawDialogAddButton(fileDialog, "cancel", NULL, NULL);
+
+ failDialogShell = XtCreatePopupShell("failDialogShell",
+ transientShellWidgetClass,
+ top, NULL, ZERO);
+ failDialog = XtCreateManagedWidget ("failDialog", dialogWidgetClass,
+ failDialogShell, NULL, ZERO);
+ XawDialogAddButton (failDialog, "continue", NULL, NULL);
+
+ XtRealizeWidget(top);
+ XtRealizeWidget(fileDialogShell);
+ XtRealizeWidget(failDialogShell);
+ XtOwnSelection(top, ManagerAtom, CurrentTime,
+ RefuseSelection, LoseManager, NULL);
+ if (XGetSelectionOwner (XtDisplay(top), ClipboardAtom)) {
+ LoseSelection (top, &ClipboardAtom);
+ } else {
+ XtOwnSelection(top, ClipboardAtom, CurrentTime,
+ ConvertSelection, LoseSelection, NULL);
+ }
+ wm_delete_window = XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW", False);
+ wm_protocols = XInternAtom(XtDisplay(top), "WM_PROTOCOLS", False);
+ (void) XSetWMProtocols(XtDisplay(top), XtWindow(top), &wm_delete_window,1);
+ (void) XSetWMProtocols(XtDisplay(top), XtWindow(fileDialogShell),
+ &wm_delete_window,1);
+ (void) XSetWMProtocols(XtDisplay(top), XtWindow(failDialogShell),
+ &wm_delete_window,1);
+ XtAppMainLoop(xtcontext);
+}
diff --git a/xclipboard.man b/xclipboard.man
new file mode 100644
index 0000000..23f13af
--- /dev/null
+++ b/xclipboard.man
@@ -0,0 +1,148 @@
+.\" $Xorg: xclipboard.man,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $
+.\" Copyright 1988, 1994, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH XCLIPBOARD 1 "Release 6.4" "X Version 11"
+.SH NAME
+xclipboard \- X clipboard client
+.SH SYNOPSIS
+\fBxclipboard\fP [ \fI\-toolkitoption\fP ... ] [ \fB\-w\fP ]
+[ \fB\-nw\fP ]
+.SH DESCRIPTION
+The \fIxclipboard\fP program is used to collect and display text selections
+that are sent to the CLIPBOARD by other clients. It is typically used to
+save CLIPBOARD selections for later use. It stores each CLIPBOARD selection
+as a separate string, each of which can be selected. Each time CLIPBOARD
+is asserted by another application, \fIxclipboard\fP transfers the contents
+of that selection to a new buffer and displays it in the text window.
+Buffers are never automatically deleted, so you'll want to use the delete
+button to get rid of useless items.
+.PP
+Since \fIxclipboard\fP uses a Text Widget to display the contents of the
+clipboard, text sent to the CLIPBOARD may be re-selected for use in other
+applications. \fIxclipboard\fP also responds to requests for the CLIPBOARD
+selection from other clients by sending the entire contents of the currently
+displayed buffer.
+.PP
+An \fIxclipboard\fP window has the following buttons across the top:
+.TP 8
+.I quit
+When this button is pressed, \fIxclipboard\fP exits.
+.TP 8
+.I delete
+When this button is pressed, the current buffer is deleted and the
+next one displayed.
+.TP 8
+.I new
+Creates a new buffer with no contents. Useful in constructing a new
+CLIPBOARD selection by hand.
+.TP 8
+.I save
+Displays a File Save dialog box.
+Pressing the Accept button saves the currently
+displayed buffer to the file specified in the text field.
+.TP 8
+.I next
+Displays the next buffer in the list.
+.TP 8
+.I previous
+Displays the previous buffer.
+.SH OPTIONS
+The \fIxclipboard\fP program accepts all of the standard X Toolkit command
+line options as well as the following:
+.TP 8
+.B \-w
+This option indicates that lines of text that are too long to be displayed on
+one line in the clipboard should wrap around to the following lines.
+.TP 8
+.B \-nw
+This option indicates that long lines of text should not wrap around. This
+is the default behavior.
+.SH WIDGETS
+In order to specify resources, it is useful to know the hierarchy of
+the widgets which compose \fIxclipboard\fR. In the notation below,
+indentation indicates hierarchical structure. The widget class name
+is given first, followed by the widget instance name.
+.sp
+.nf
+.TA .5i 1.0i 1.5i
+.ta .5i 1.0i 1.5i
+XClipboard xclipboard
+ Form form
+ Command Quit
+ Command delete
+ Command new
+ Command Save
+ Command next
+ Command prev
+ Label index
+ Text text
+ TransientShell fileDialogShell
+ Dialog fileDialog
+ Label label
+ Command accept
+ Command cancel
+ Text value
+ TransientShell failDialogShell
+ Dialog failDialog
+ Label label
+ Command continue
+.fi
+.sp
+.SH SENDING/RETRIEVING CLIPBOARD CONTENTS
+Text is copied to the clipboard whenever a client asserts ownership of the
+\fBCLIPBOARD\fP selection. Text is copied from the clipboard whenever a
+client requests the contents of the \fBCLIPBOARD\fP selection. Examples of
+event bindings that a user may wish to include in a resource configuration
+file to use the clipboard are:
+.sp
+.nf
+.TA .5i
+.ta .5i 3.0i
+*VT100.Translations: #override \\
+ <Btn3Up>: select-end(CLIPBOARD) \\n\\
+ <Btn2Up>: insert-selection(PRIMARY,CLIPBOARD) \\n\\
+ <Btn2Down>: ignore ()
+
+.fi
+.sp
+.SH "SEE ALSO"
+X(1), xcutsel(1), xterm(1), individual client documentation for how to make a
+selection and send it to the CLIPBOARD.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH FILES
+<XRoot>/lib/X11/app-defaults/XClipboard - specifies required resources
+.SH AUTHOR
+Ralph R. Swick, DEC/MIT Project Athena
+.br
+Chris D. Peterson, MIT X Consortium
+.br
+Keith Packard, MIT X Consortium
diff --git a/xcutsel.c b/xcutsel.c
new file mode 100644
index 0000000..e12ea29
--- /dev/null
+++ b/xcutsel.c
@@ -0,0 +1,325 @@
+/*
+ * $Xorg: xcutsel.c,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $
+ *
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * *
+ * Author: Ralph Swick, DEC/Project Athena
+ */
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xatom.h>
+
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/StdSel.h>
+
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xfuncs.h>
+
+#ifdef XKB
+#include <X11/extensions/XKBbells.h>
+#endif
+
+static XrmOptionDescRec optionDesc[] = {
+ {"-selection", "selection", XrmoptionSepArg, NULL},
+ {"-select", "selection", XrmoptionSepArg, NULL},
+ {"-sel", "selection", XrmoptionSepArg, NULL},
+ {"-s", "selection", XrmoptionSepArg, NULL},
+ {"-cutbuffer", "cutBuffer", XrmoptionSepArg, NULL},
+};
+
+typedef struct {
+ String selection_name;
+ int buffer;
+ Atom selection;
+ char* value;
+ int length;
+} OptionsRec;
+
+OptionsRec options;
+
+#define Offset(field) XtOffsetOf(OptionsRec, field)
+
+static XtResource resources[] = {
+ {"selection", "Selection", XtRString, sizeof(String),
+ Offset(selection_name), XtRString, "PRIMARY"},
+ {"cutBuffer", "CutBuffer", XtRInt, sizeof(int),
+ Offset(buffer), XtRImmediate, (XtPointer)0},
+};
+
+#undef Offset
+
+typedef struct {
+ Widget button;
+ Boolean is_on;
+} ButtonState;
+
+static ButtonState state;
+
+Syntax(call)
+ char *call;
+{
+ fprintf (stderr, "usage: %s [-selection name] [-cutbuffer number]\n",
+ call);
+ exit (1);
+}
+
+
+static void StoreBuffer(w, client_data, selection, type, value, length, format)
+ Widget w;
+ XtPointer client_data;
+ Atom *selection, *type;
+ XtPointer value;
+ unsigned long *length;
+ int *format;
+{
+
+ if (*type == 0 || *type == XT_CONVERT_FAIL || *length == 0) {
+#ifdef XKB
+ XkbStdBell( XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError );
+#else
+ XBell( XtDisplay(w), 0 );
+#endif
+ return;
+ }
+
+ XStoreBuffer( XtDisplay(w), (char*)value, (int)(*length),
+ options.buffer );
+
+ XtFree(value);
+}
+
+
+static Boolean ConvertSelection(w, selection, target,
+ type, value, length, format)
+ Widget w;
+ Atom *selection, *target, *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 + 4));
+ targetP = *(Atom**)value;
+ *length = std_length + 4;
+ *targetP++ = XA_STRING;
+ *targetP++ = XA_TEXT(d);
+ *targetP++ = XA_LENGTH(d);
+ *targetP++ = XA_LIST_LENGTH(d);
+/*
+ *targetP++ = XA_CHARACTER_POSITION(d);
+*/
+ memmove( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
+ XtFree((char*)std_targets);
+ *type = XA_ATOM;
+ *format = 32;
+ return True;
+ }
+ if (*target == XA_STRING || *target == XA_TEXT(d)) {
+ *type = XA_STRING;
+ *value = XtMalloc((Cardinal) options.length);
+ memmove( (char *) *value, options.value, options.length);
+ *length = options.length;
+ *format = 8;
+ return True;
+ }
+ if (*target == XA_LIST_LENGTH(d)) {
+ long *temp = (long *) XtMalloc (sizeof(long));
+ *temp = 1L;
+ *value = (XtPointer) temp;
+ *type = XA_INTEGER;
+ *length = 1;
+ *format = 32;
+ return True;
+ }
+ if (*target == XA_LENGTH(d)) {
+ long *temp = (long *) XtMalloc (sizeof(long));
+ *temp = options.length;
+ *value = (XtPointer) temp;
+ *type = XA_INTEGER;
+ *length = 1;
+ *format = 32;
+ return True;
+ }
+#ifdef notdef
+ if (*target == XA_CHARACTER_POSITION(d)) {
+ long *temp = (long *) XtMalloc (2 * sizeof(long));
+ temp[0] = ctx->text.s.left + 1;
+ temp[1] = ctx->text.s.right;
+ *value = (XtPointer) temp;
+ *type = XA_SPAN(d);
+ *length = 2;
+ *format = 32;
+ return True;
+ }
+#endif /* notdef */
+ if (XmuConvertStandardSelection(w, req->time, selection, target, type,
+ (XPointer *)value, length, format))
+ return True;
+
+ /* else */
+ return False;
+}
+
+
+static void SetButton(state, on)
+ ButtonState *state;
+ Boolean on;
+{
+ if (state->is_on != on) {
+ Arg args[2];
+ Pixel fg, bg;
+ XtSetArg( args[0], XtNforeground, &fg );
+ XtSetArg( args[1], XtNbackground, &bg );
+ XtGetValues( state->button, args, TWO );
+ args[0].value = (XtArgVal)bg;
+ args[1].value = (XtArgVal)fg;
+ XtSetValues( state->button, args, TWO );
+ state->is_on = on;
+ }
+}
+
+
+static void LoseSelection(w, selection)
+ Widget w;
+ Atom *selection;
+{
+ if (options.value) {
+ XFree( options.value );
+ options.value = NULL;
+ }
+ SetButton(&state, False);
+}
+
+
+/* ARGSUSED */
+static void Quit(w, closure, callData)
+ Widget w;
+ XtPointer closure; /* unused */
+ XtPointer callData; /* unused */
+{
+ XtCloseDisplay( XtDisplay(w) );
+ exit(0);
+}
+
+
+/* ARGSUSED */
+static void GetSelection(w, closure, callData)
+ Widget w;
+ XtPointer closure; /* unused */
+ XtPointer callData; /* unused */
+{
+ XtGetSelectionValue(w, options.selection, XA_STRING,
+ StoreBuffer, NULL,
+ XtLastTimestampProcessed(XtDisplay(w)));
+}
+
+
+/* ARGSUSED */
+static void GetBuffer(w, closure, callData)
+ Widget w;
+ XtPointer closure;
+ XtPointer callData; /* unused */
+{
+ if (options.value) XFree( options.value );
+ options.value =
+ XFetchBuffer(XtDisplay(w), &options.length, options.buffer);
+ if (options.value != NULL) {
+ if (XtOwnSelection(w, options.selection,
+ XtLastTimestampProcessed(XtDisplay(w)),
+ ConvertSelection, LoseSelection, NULL))
+ SetButton((ButtonState*)closure, True);
+ }
+}
+
+
+void main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char label[100];
+ Widget box, button;
+ XtAppContext appcon;
+ Widget shell;
+ XrmDatabase rdb;
+
+ XtSetLanguageProc(NULL, NULL, NULL);
+
+ shell =
+ XtAppInitialize( &appcon, "XCutsel", optionDesc, XtNumber(optionDesc),
+ &argc, argv, NULL, NULL, 0 );
+ rdb = XtDatabase(XtDisplay(shell));
+
+ if (argc != 1) Syntax(argv[0]);
+
+ XtGetApplicationResources( shell, (XtPointer)&options,
+ resources, XtNumber(resources),
+ NULL, ZERO );
+
+ options.value = NULL;
+ XmuInternStrings( XtDisplay(shell), &options.selection_name, ONE,
+ &options.selection );
+
+ box = XtCreateManagedWidget("box", boxWidgetClass, shell, NULL, ZERO);
+
+ button =
+ XtCreateManagedWidget("quit", commandWidgetClass, box, NULL, ZERO);
+ XtAddCallback( button, XtNcallback, Quit, NULL );
+
+ /* %%% hack alert... */
+ sprintf(label, "*label:copy %s to %d",
+ options.selection_name,
+ options.buffer);
+ XrmPutLineResource( &rdb, label );
+
+ button =
+ XtCreateManagedWidget("sel-cut", commandWidgetClass, box, NULL, ZERO);
+ XtAddCallback( button, XtNcallback, GetSelection, NULL );
+
+ sprintf(label, "*label:copy %d to %s",
+ options.buffer,
+ options.selection_name);
+ XrmPutLineResource( &rdb, label );
+
+ button =
+ XtCreateManagedWidget("cut-sel", commandWidgetClass, box, NULL, ZERO);
+ XtAddCallback( button, XtNcallback, GetBuffer, (XtPointer)&state );
+ state.button = button;
+ state.is_on = False;
+
+ XtRealizeWidget(shell);
+ XtAppMainLoop(appcon);
+}
diff --git a/xcutsel.man b/xcutsel.man
new file mode 100644
index 0000000..992a4e4
--- /dev/null
+++ b/xcutsel.man
@@ -0,0 +1,105 @@
+.\" $Xorg: xcutsel.man,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $
+.\" Copyright 1994, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH XCUTSEL 1 "Release 6.4" "X Version 11"
+.SH NAME
+xcutsel - interchange between cut buffer and selection
+.SH SYNOPSIS
+\fBxcutsel\fP [ \fI-toolkitoption\fP ...] [-selection \fIselection\fP] [-cutbuffer \fInumber\fP]
+.SH DESCRIPTION
+The \fIxcutsel\fP program is used to copy the current selection into a
+cut buffer and to make a selection that contains the current contents of
+the cut buffer. It acts as a bridge between applications that don't support
+selections and those that do.
+.PP
+By default, \fIxcutsel\fP will use the selection named PRIMARY and the cut
+buffer CUT_BUFFER0. Either or both of these can be overridden by command
+line arguments or by resources.
+.PP
+An \fIxcutsel\fP window has the following buttons:
+.TP 8
+.I " quit"
+When this button is pressed, \fIxcutsel\fP exits. Any selections held by
+\fIxcutsel\fP are automatically released.
+.TP 8
+.I " copy PRIMARY to 0"
+When this button is pressed, \fIxcutsel\fP copies the current selection into
+the cut buffer.
+.TP 8
+.I " copy 0 to PRIMARY"
+When this button is pressed, \fIxcutsel\fP converts the current contents of
+the cut buffer into the selection.
+.PP
+The button labels reflect the selection and cutbuffer selected by
+command line options or through the resource database.
+.PP
+When the ``copy 0 to PRIMARY'' button is activated, the button will
+remain inverted as long as \fIxcutsel\fP remains the owner of the
+selection. This serves to remind you which client owns the current
+selection. Note that the value of the selection remains constant;
+if the cutbuffer is changed, you must again activate the copy button
+to retrieve the new value when desired.
+.SH OPTIONS
+.I Xcutsel
+accepts all of the standard X Toolkit command line options as well as the
+following:
+.TP 8
+.B \-selection \fIname\fP
+This option specifies the name of the selection to use. The default is
+PRIMARY. The only supported abbreviations for this option are ``-select'',
+``-sel'' and ``-s'', as the standard toolkit option ``-selectionTimeout'' has a
+similar name.
+.TP 8
+.B \-cutbuffer \fInumber\fP
+This option specifies the cut buffer to use. The default is cut buffer 0.
+.SH X DEFAULTS
+This program accepts all of the standard X Toolkit resource names and classes
+as well as:
+.TP 8
+.B "selection (\fPclass\fB Selection)"
+This resource specifies the name of the selection to use. The default is
+PRIMARY.
+.TP 8
+.B "cutBuffer (\fPclass\fB CutBuffer)"
+This resource specifies the number of the cut buffer to use. The default is 0.
+.SH WIDGET NAMES
+The following instance names may be used when user configuration of the
+labels in them is desired:
+.TP 8
+.B "sel-cut (\fPclass\fB Command)"
+This is the ``copy SELECTION to BUFFER'' button.
+.TP 8
+.B "cut-sel (\fPclass\fB Command)"
+This is the ``copy BUFFER to SELECTION'' button.
+.TP 8
+.B "quit (\fPclass\fB Command)"
+This is the ``quit'' button.
+.SH "SEE ALSO"
+X(1), xclipboard(1), xterm(1), text widget documentation, individual client
+documentation for how to make a selection.
+.SH BUGS
+There is no way to change the name of the selection or the number of the
+cut buffer while the program is running.
+.SH AUTHOR
+Ralph R. Swick, DEC/MIT Project Athena