/* Written by Dan Heller and Paula Ferguson.
* Copyright 1994, O'Reilly & Associates, Inc.
* Permission to use, copy, and modify this program without
* restriction is hereby granted, as long as this copyright
* notice appears in each copy of the program source code.
* This program is freely distributable without licensing fees and
* is provided without guarantee or warrantee expressed or implied.
* This program is -not- in the public domain.
*/
/* copy_by_name.c -- demonstrate clipboard copies "by-name".
* Copying by name requires that the copy *to* clipboard
* functions use the same window as the copy *from* clipboard
* functions. This is a restriction placed on the API by the
* toolkit, not by the ICCCM.
*/
#include <Xm/CutPaste.h>
#include <Xm/RowColumn.h>
#include <Xm/PushB.h>
static void to_clipbd(), from_clipbd();
Widget toplevel;
main(argc, argv)
int argc;
char *argv[];
{
Widget 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", sizeof (char *),
NULL);
XtAddCallback (button, XmNactivateCallback, to_clipbd, NULL);
/* button2 retrieves text stored in the clipboard */
button = XtVaCreateManagedWidget ("button2",
xmPushButtonWidgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString,
"Retrieve From Clipboard", sizeof (char *),
NULL);
XtAddCallback (button, XmNactivateCallback, from_clipbd, NULL);
/* manage RowColumn, realize toplevel shell and start main loop */
XtManageChild (rowcol);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
static void
copy_by_name(widget, data_id, private_id, reason)
Widget widget;
int *data_id;
int *private_id;
int *reason;
{
Display *dpy = XtDisplay (toplevel);
Window window = XtWindow (toplevel);
static int cnt;
int status;
char buf[32];
printf ("Copy by name called\n\treason: %s, private_id: %d, data_id: %d\n",
*reason == XmCR_CLIPBOARD_DATA_REQUEST? "request" : "delete",
*private_id, *data_id);
if (*reason == XmCR_CLIPBOARD_DATA_REQUEST) {
sprintf (buf, "stuff-%d", ++cnt); /* make each copy unique */
do
status = XmClipboardCopyByName (dpy, window, *data_id, buf,
strlen (buf)+1, *private_id = cnt);
while (status != ClipboardSuccess);
}
}
/* 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;
Display *dpy = XtDisplay (toplevel);
Window window = XtWindow (toplevel);
clip_label = XmStringCreateLocalized ("to_clipbd");
/* start a copy. retry till unlocked */
do
status = XmClipboardBeginCopy (dpy, window,
clip_label, widget, copy_by_name, &item_id);
while (status == ClipboardLocked);
/* copy by name by passing NULL as the "data", copy_by_name() as
* the callback and "widget" as the widget.
*/
do
status = XmClipboardCopy (dpy, window, item_id, "STRING",
NULL, 8L, 0, NULL);
while (status == ClipboardLocked);
/* end the copy */
do
status = XmClipboardEndCopy (dpy, window, item_id);
while (status == ClipboardLocked);
}
static void
from_clipbd(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
int status;
unsigned total_bytes;
unsigned long received;
char *data = NULL, buf[32];
Display *dpy = XtDisplay (toplevel);
Window window = XtWindow (toplevel);
do
status = XmClipboardStartRetrieve (dpy, window, CurrentTime);
while (status == ClipboardLocked);
/* initialize data to contain at least one byte. */
data = XtMalloc (1);
total_bytes = 1;
do {
buf[0] = 0;
/* retrieve data from clipboard -- if locked, try again */
status = XmClipboardRetrieve (dpy, window, "STRING",
buf, sizeof (buf), &received, NULL);
if (status == ClipboardNoData) {
puts ("No data on the clipboard");
break;
}
/* reallocate data to contain enough space for everything */
if (!(data = XtRealloc (data, total_bytes + received))) {
XtError ("Can't allocate space for data");
break; /* XtError may or may not return */
}
/* copy buf into data. strncpy() does not NULL terminate */
strncpy (&data[total_bytes-1], buf, received);
total_bytes += received;
} while (status == ClipboardTruncate);
data[total_bytes-1] = 0; /* NULL terminate */
if (status == ClipboardSuccess)
printf ("Retrieved \"%s\" from clipboard (%d bytes)\n",
data, total_bytes);
status = XmClipboardEndRetrieve(dpy, window);
}