There are some situations where it is impractical to place complete information on the clipboard. Some people's cargo
may be "too heavy" for the clipboard to hold indefinitely. Other people may have perishables that don't last very long.
Still others may have information that varies with the state of the world. For these cases, the person with the special
cargo may choose to leave only some information about their cargo rather than the cargo itself. This information
might include its weight, type, name and/or reference number, for example. Potential recipients may then examine the
clipboard and inquire about the cargo without having to get it or even look at it. Only in the event that someone else
wishes to obtain the cargo is the original owner called upon to provide it.
In the Motif world, this scenario describes clipboard data that is available by name. For example, if a client wishes to
place an entire file on the clipboard, it might choose to register the file by name without providing the actual contents
unless someone requests it. This may save a lot of time and resources, since it's possible that no one will request it.
Referencing data this way is very cheap and is not subject to expiration or obsolescence.
When posting messages by name, the client must provide the clipboard with a callback function that returns the actual
data. This callback function may be called by the Motif toolkit at any time, provided another client requests the data.
If the data is time−dependent or subject to other criteria (someone removed or changed the file), the callback routine
may respond accordingly.
The Motif clipboard functions are based on X's Inter−Client Communications Conventions Manual (ICCCM).
Knowledge of these conventions will aid greatly in your understanding of how these functions are implemented.
However, knowledge of the implementation is not required in order to understand the concepts involved here or to be
able to use the clipboard effectively through Motif's application interface. This chapter does not address many of the
issues involved with the ICCCM and the lower−level Xlib properties that implement them. Rather, it only addresses
the highest level of interaction provided by the Motif toolkit.
Also note that the clipboard is one of three commonly used mechanisms to support interclient communication. There
are also the primary and secondary selections, which are similar in nature, but are handled differently at the
application and user level. The Motif toolkit supports convenience routines that interact with clipboard selections
only. To use the other selection mechanisms, you must use X Toolkit Intrinsics functions that were discussed in
Volume Four, X Toolkit Intrinsics Programming Manual. Note, however, that the Text widget supports both
mechanisms.
18.1 Simple Clipboard Copy and Retrieval
To introduce the application programmer's interface (API) for the clipboard functions, we demonstrate how to handle
simple copy and retrieval of text. The cut and paste functions provided by the Text widgets handle copy and retrieval
from the clipboard in the manner we are about to describe; they also support interaction with the primary and
secondary selection mechanisms. However, as pointed out in Chapter 14, Text Widgets, these functions are usually
reserved for interactive actions taken by the user. Fortunately, Motif provides many convenience functions that
facilitate the task of dealing with the clipboard for Text widgets. This section discusses the techniques used by the
Text widget when it interacts with the clipboard.
Let's begin with the short program in the source code This program creates two PushButtons that have complementary
callback routines: to_clipbd() copies text to the clipboard and from_clipbd() retrieves text from the
clipboard. For this example, the text copied to the clipboard is arbitrary; we happen to use a string that represents the
number of times the Copy to Clipboard button is pressed. XtSetLanguageProc() is only available in X11R5;
there is no corresponding function in X11R4. XmStringCreateLocalized() is only available in Motif 1.2;
XmStringCreateSimple() is the corresponding function in Motif 1.1.
/* copy_retrieve.c −− simple copy and retrieve program. Two
* pushbuttons: the first places text in the clipboard, the other
18 The Clipboard 18.1 Simple Clipboard Copy and Retrieval
494
* receives text from the clipboard. This just demonstrates the
* API involved.
*/
#include <Xm/CutPaste.h>
#include <Xm/RowColumn.h>
#include <Xm/PushB.h>
static void to_clipbd(), from_clipbd();
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, rowcol, button;
XtAppContext app;
XtSetLanguageProc (NULL, NULL, NULL);
/* Initialize toolkit, application context and toplevel shell */
toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
/* manage two buttons in a RowColumn widget */
rowcol = XtVaCreateWidget ("rowcol", xmRowColumnWidgetClass,
toplevel, NULL);
/* button1 copies to the clipboard */
button = XtVaCreateManagedWidget ("button1",
xmPushButtonWidgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString,
"Copy To Clipboard", 18, /* strlen() + 1 */
NULL);
XtAddCallback (button, XmNactivateCallback, to_clipbd, "text");
/* button2 retrieves text stored in the clipboard */
button = XtVaCreateManagedWidget ("button2",
xmPushButtonWidgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString,
"Retrieve From Clipboard", 24, /* strlen() + 1 */
NULL);
XtAddCallback (button, XmNactivateCallback, from_clipbd, NULL);
/* manage RowColumn, realize toplevel shell and start main loop */
XtManageChild (rowcol);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* copy data to clipboard. */
static void
to_clipbd(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
unsigned long item_id = 0; /* clipboard item id */
int status;
XmString clip_label;
char buf[32];
static int cnt;
Display *dpy = XtDisplayOfObject (widget);
18 The Clipboard 18.1 Simple Clipboard Copy and Retrieval
495
Window window = XtWindowOfObject (widget);
char *data = (char *) client_data;
sprintf (buf, "%s−%d", data, ++cnt); /* make each copy unique */
clip_label = XmStringCreateLocalized ("to_clipbd");
/* start a copy −− retry till unlocked */
do
status = XmClipboardStartCopy (dpy, window,
clip_label, CurrentTime, NULL, NULL, &item_id);
while (status == ClipboardLocked);
XmStringFree (clip_label);
/* copy the data (buf) −− pass "cnt" as private id for kicks */
do
status = XmClipboardCopy (dpy, window, item_id, "STRING",
buf, (long) strlen (buf)+1, cnt, NULL);
while (status == ClipboardLocked);
/* end the copy */
do
status = XmClipboardEndCopy (dpy, window, item_id);
while (status == ClipboardLocked);
printf ("Copied
}
static void
from_clipbd(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
int status, private_id;
char buf[32];
Display *dpy = XtDisplayOfObject (widget);
Window window = XtWindowOfObject (widget);
do
status = XmClipboardRetrieve (dpy, window,
"STRING", buf, sizeof (buf), NULL, &private_id);
while (status == ClipboardLocked);
if (status == ClipboardSuccess)
printf ("Retrieved
}
The program uses the header file <Xm/CutPaste.h> to include the appropriate function declarations and various
constants. Don't let the name of the file confuse you. CutPaste.h is derived from the phrase "cut and paste," which
historically has been used to describe clipboard−type operations. The to_clipbd() callback routine uses the
following clipboard functions to copy data to the clipboard:
XmClipboardStartCopy()
XmClipboardCopy()
XmClipboardEndCopy()
Copying data to the clipboard is a three−phase process. Each of the functions locks the clipboard so that other clients
18 The Clipboard 18.1 Simple Clipboard Copy and Retrieval
496

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.