/* 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); }