home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
-
- #include <X11/Xm/Xm.h>
- #include <X11/Xm/CutPaste.h>
-
- extern char *getSelection();/* function to get the current molecule */
- Window mc_win = 0; /* the single window to use in Motif clipboard calls */
-
- char *theSelection=NULL; /* the selection - mol as text */
- char *augSelection=NULL; /* the augmented selection - mol + rotation */
- char *xferSelection; /* space for the selection when it's pasted */
-
- extern short xRot, yRot; /* x and y rotation values for keeping for c&p */
-
- int wantPersistance = 1; /* whether or not to remember data when app exits */
-
- #define EV 1000 /* Escape velocity: don't spin waiting for the
- lock too long before asking if the user wants
- to keep waiting */
-
- #define MXCHARS 30
-
- /*
- * pasteCB()
- * paste call back
- *
- * request the data as a string
- */
- void pasteCB(Widget w, caddr_t client_data, XmAnyCallbackStruct *call_data) {
-
- Display *d = XtDisplay(w);
- Window win = XtWindow(w);
- Time time_of_request = XtLastTimestampProcessed(d);
- int count, nbuflen, private;
- unsigned long numcopied, buflen;
- char *namebuf=NULL;
- char *buffer=NULL;
-
- char *cptr=NULL;
- char axRot[MXCHARS], ayRot[MXCHARS], head[MXCHARS];
- int i,j,k,length,ret,found_match;
-
- #ifdef EBUG
- win = XtWindow(XtParent(w));
- fprintf(stderr,"in Paste\n");
- #endif
- /* The application should call all the
- * Motif clipboard calls with the SAME
- * window id. It really doesn't matter
- * which one, as long as it is associated
- * with a widget. In this case, the cut/
- * copy/paste widgets each have a window
- * associated with them. In the widget
- * hierarchy, they share a parent window.
- * The programmer can either use the parent
- * window, or any of the windows, provided
- * that it is the same for any of the calls
- * to the Motif clipboard.
- */
- if (mc_win == 0)
- mc_win = win;
- else if (mc_win != win) {
- win = mc_win;
- }
-
-
- /*
- * Start the retrieve. This locks the clipboard so that
- * no other application can get any info from the clipboard.
- * Be sure that this will be followed by an EndRetrieve
- * sometime in the near future.
- *
- * The programmer may want to have some sort of 'escape'
- * count here in each of these calls (if spinning on
- * the availability of the clipboard) - to be sure not
- * to loop infinitely - and to quiz the user if the operation
- * appears to be taking a loooong time.
- * Or just bop on back if want instant gratification...
- */
- if (XmClipboardStartRetrieve(d, win, time_of_request) == ClipboardLocked) {
- fprintf(stderr,"Clipboard is locked - Try again later\n");
- XBell( XtDisplay(w), 0);
- return;
- }
-
- /*
- * Find out how many different formats (targets in 'X' land)
- * there are posted to the Motif clipboard. This routine
- * also returns the length of the longest format name in
- * nbuflen, so the programmer knows how much space to allocate.
- *
- * This call could return ClipboardLocked had we not called it
- * within the StartRetrieve, EndRetrieve pair.
- */
- if (XmClipboardInquireCount(d, win, &count, &nbuflen) == ClipboardNoData) {
- XmClipboardEndRetrieve(d, win);
- XBell( XtDisplay(w), 0);
- fprintf(stderr,"no data in the clipboard\n");
- return;
- }
- #ifdef EBUG
- fprintf(stderr,"Count is %d\n",count);
- #endif
-
-
- /*
- * Now look at all the formats -
- * this is useful if your application has a preferred format.
- *
- * Note: Motif starts counting its formats at 1.
- *
- * Be careful when getting data back from the clipboard
- * that you will interpret as a string. Not everyone is
- * careful about counting the '\0' as a character.
- *
- * This call could return ClipboardLocked had we not called it
- * within the StartRetrieve, EndRetrieve pair.
- * This call could return ClipboardNoData but we already know
- * that there's data from the above call - and we have the clipboard
- * locked.
- * This call could return ClipboardTruncate if the buffer we passed
- * it was not large enough for the format name - but we checked
- * its size above.
- */
- found_match = 0;
- namebuf = (char *)malloc(sizeof(char)*(nbuflen+1));
- for (i=1; (i<=count) && (found_match==0); i++) {
- if (XmClipboardInquireFormat(d, win, i, namebuf, nbuflen, &numcopied) ==
- ClipboardNoData) {
- XmClipboardEndRetrieve(d, win);
- XBell( XtDisplay(w), 0);
- free(namebuf);
- fprintf(stderr,"no data in the clipboard\n");
- return;
- } else {
- namebuf[numcopied] = '\0';
- /* this demo only looks for string */
- if (! strcmp(namebuf,"string") || ! strcmp(namebuf,"STRING")
- || ! strcmp(namebuf,XmRString) ) {
- found_match = i;
- }
- #ifdef EBUG
- fprintf(stderr,"namebuf is %s\n",namebuf);
- #endif
- }
- }
-
-
- /*
- * Now find out how big the data is in this format.
- *
- * This call could return ClipboardLocked had we not called it
- * within the StartRetrieve, EndRetrieve pair.
- * This call could return ClipboardNoData but we already know
- * that there's data from the above call - and we have the clipboard
- * locked.
- */
- XmClipboardInquireLength(d, win, namebuf, &buflen);
- if (buflen == 0) {
- XmClipboardEndRetrieve(d, win);
- XBell( XtDisplay(w), 0);
- fprintf(stderr,"PASTE - 0 length data!!\n");
- free(namebuf);
- return;
- }
- #ifdef EBUG
- fprintf(stderr,"buflen is %d\n",buflen);
- #endif
-
- /*
- * Get the data.
- *
- * This can be done incrementally if the programmer decides
- * to allocate a smaller buffer size. Just call XmClipboardRetrieve()
- * multiple times and be sure to add the code that deals with
- * patching the data back together or processes the data in the loop.
- *
- * This call returns the actual number of bytes copied in the transaction.
- * It also returns any private data that was stored with the data.
- * This is useful for passing secret messages.
- *
- * The clipboard is STILL locked - so no way will we be seeing the
- * ClipboardLocked or ClipboardNoData returns. And we shouldn't
- * see the ClipboardTruncate cause we've allocated enough space.
- */
- buffer = (char *)malloc(sizeof(char)*(buflen+1));
- while (( (ret = XmClipboardRetrieve(d, win, namebuf, buffer, buflen, &numcopied, &private)) != ClipboardSuccess) ) {
- #ifdef EBUG
- fprintf(stderr,"ret is %d\n",ret);
- #endif
- }
-
- buffer[buflen] = '\0';
-
-
- /*
- * Just an extra check to be sure that we really got all the data.
- */
- if (numcopied != buflen) {
- fprintf(stderr,"Didn't copy all that it should\n");
- XmClipboardEndRetrieve(d, win);
- XBell( XtDisplay(w), 0);
- free(buffer);
- free(namebuf);
- return;
- }
-
-
- /*
- * Clean up temporary space. And let go of the clipboard!
- */
- free(namebuf);
- XmClipboardEndRetrieve(d, win);
-
-
- /*
- * Now that the data is finally here,
- * do something with it in the application.
- * In this case, draw the molecule
- *
- * This is the demo's format that it
- * can understand (header):
- * _MOL
- * xrot as %d
- * yrot as %d
- *
- * followed by:
- * molecule format that the graphics portion
- * of this program knows how to render
- * basically, allowing comments, molecule
- * name, color, and positions
- */
-
- /* first play with grabbing the saved rotation values */
- cptr = buffer;
- i=0;
- while ((*(cptr+i) != '\n') && (i<MXCHARS)) {
- head[i++] = *(cptr+i);
- }
- head[i] ='\0';
- i++;
- if ( strcmp(head,"_MOL") ) {
- XBell( XtDisplay(w), 0);
- fprintf(stderr,"Paste not in _MOL format\n");
- free(buffer);
- return;
- }
-
- j = 0;
- while ((*(cptr+i) != '\n') && (j<MXCHARS)) {
- axRot[j++] = *(cptr+i);
- i++;
- }
- axRot[j] = '\0';
- i++;
-
- k = 0;
- while ((*(cptr+i) != '\n') && (k<MXCHARS)) {
- ayRot[k++] = *(cptr+i);
- i++;
- }
- ayRot[k] = '\0';
- i++;
-
- xRot = (short) atoi(axRot);
- yRot = (short) atoi(ayRot);
-
-
- length = strlen(buffer+i);
- /*
- * molecule program will free this data when this
- * molecule is replaced
- */
- xferSelection =(char *)malloc(sizeof(char)*(length+1));
- strcpy(xferSelection, (char *) (buffer+i));
- #ifdef EBUG
- fprintf(stderr,"xferSelection %s\n",xferSelection);
- #endif
- free(buffer);
-
- buildMolecule(xferSelection);
-
- drawScene();
- return ;
- }
-
-
-
- /*
- * copynameCB()
- * copy by name call back (registered from the copyCB() )
- *
- * If the data was copied to the Motif clipboard
- * by name (reference), then now is the time to
- * really copy the data there, cause someone has
- * asked for it - through paste - or if the
- * through quit. This gets called if
- * data is deleted from the clipboard as well.
- */
- void copynameCB(Widget w, int *data_id, int *private, int *reason) {
-
- Display *d = XtDisplay(w);
- Window win = XtWindow(w);
- int escape;
- #ifdef EBUG
- win = XtWindow(XtParent(w));
- #endif
-
- fprintf(stderr,"In copybynameCB\n");
-
- /* The application should call all the
- * Motif clipboard calls with the SAME
- * window id. It really doesn't matter
- * which one, as long as it is associated
- * with a widget. In this case, the cut/
- * copy/paste widgets each have a window
- * associated with them. In the widget
- * hierarchy, they share a parent window.
- * The programmer can either use the parent
- * window, or any of the windows, provided
- * that it is the same for any of the calls
- * to the Motif clipboard.
- */
- if (mc_win ==0)
- mc_win = win;
- else if (mc_win != win) {
- win = mc_win;
- }
-
- /*
- * There are two reasons this routine is called.
- * Either someone has requested the data through
- * the paste -- or the Motif clipboard has been
- * used by someone else and it's ok to remove
- * the data from the application.
- */
- escape = 0;
- if (*reason == XmCR_CLIPBOARD_DATA_REQUEST) {
- while ((escape++ < EV) &&
- XmClipboardCopyByName(d,
- win,
- *data_id,
- augSelection,
- (long) strlen(augSelection),
- *private) != ClipboardSuccess) ;
- if (escape >= EV) {
- /* Clipboard is locked and I can't get it */
- fprintf(stderr,"Clipboard is locked - Try again later\n");
- XBell( XtDisplay(w), 0);
- return;
- }
-
- } else if (*reason == XmCR_CLIPBOARD_DATA_DELETE) {
- /* ok to delete data -
- * Motif clipboard doesn't need it any longer.
- * So get rid of it if keeping it in a special place.
- */
- fprintf(stderr,"copynameCB Data delete\n");
- }
- }
-
-
- /*
- * copyCB()
- * copy call back
- *
- * copy the data as a string
- *
- * demonstrates "copy by name" to the motif clipboard
- *
- */
- void copyCB(Widget w, caddr_t client_data, XmAnyCallbackStruct *call_data) {
- int rv, incr;
- char arot[MXCHARS*3];
- Display *d = XtDisplay(w);
- Window win = XtWindow(w);
- Time time_of_request = XtLastTimestampProcessed(d);
- long item_id;
- int data_id;
- int private=0;
-
- #ifdef EBUG
- win = XtWindow(XtParent(w));
- #endif
-
- /* do some cleanup of the selection if necessary */
- if (theSelection)
- free(theSelection);
- if (augSelection)
- free(augSelection);
- theSelection = getSelection();
- if (theSelection == NULL) {
- fprintf(stderr,"Nothing selected\n");
- XBell( d, 0);
- } else {
-
- #ifdef EBUG
- fprintf(stderr,"theSelection %s\n",theSelection);
- printf("\n%s\n", theSelection);
- #endif
-
- /* The application should call all the
- * Motif clipboard calls with the SAME
- * window id. It really doesn't matter
- * which one, as long as it is associated
- * with a widget. In this case, the cut/
- * copy/paste widgets each have a window
- * associated with them. In the widget
- * hierarchy, they share a parent window.
- * The programmer can either use the parent
- * window, or any of the windows, provided
- * that it is the same for any of the calls
- * to the Motif clipboard.
- */
- if (mc_win ==0)
- mc_win = win;
- else if (mc_win != win) {
- win = mc_win;
- }
-
- sprintf(arot,"_MOL\n%d\n%d\n",xRot,yRot);
- incr = strlen(arot);
- augSelection = (char *)malloc(sizeof(char)*(strlen(theSelection)+incr+1));
- sprintf(augSelection,"%s%s",arot,theSelection);
-
-
- /*
- * Start your copy. This locks the clipboard for you.
- * Here is where you register your callback if you
- * will be using CopyByName.
- *
- */
- while (XmClipboardStartCopy(
- d,
- win,
- XmStringCreate("mol.good",XmSTRING_DEFAULT_CHARSET),
- time_of_request,
- w,
- /*
- copynameCB,
- */
- NULL,
- &item_id) != ClipboardSuccess) ;
-
- /*
- * Copy the data - either by name by passing NULL
- * or by doing the copy of the data (augSelection).
- *
- * Any format passed by name is assumed to have the length
- * passed in a call to XmClipboardCopy, even though the data
- * has not yet been transferred to the clipboard in that
- * format.
- */
- while (XmClipboardCopy(
- d,
- win,
- item_id,
- /*
- XmRString,
- */
- "STRING",
- augSelection, /* not by name */
- (long) strlen(augSelection),
- private,
- &data_id) != ClipboardSuccess) ;
-
- /*
- * Up until the EndCopy, all of the transfers are going
- * to a temporary buffer. EndCopy makes the data go
- * all the way to the clipboard.
- */
- while (XmClipboardEndCopy(d, win, item_id) != ClipboardSuccess) ;
-
- }
- }
-
-
- /*
- * cutCB()
- * cut call back
- *
- * cut the data as a string and give it to the clipboard
- *
- * This routine is just like copyCB() except that some
- * application data structures have to change and the
- * display should reflect that change.
- *
- *
- * demonstrates "direct copy" to the motif clipboard
- *
- */
- void cutCB(Widget w) {
- int rv, incr;
- char arot[MXCHARS*3];
- Display *d = XtDisplay(w);
- Window win = XtWindow(w);
- Time time_of_request = XtLastTimestampProcessed(d);
- long item_id;
- int data_id;
- int private=0;
- char *empty=NULL; /* an empty string */
-
- #ifdef EBUG
- win = XtWindow(XtParent(w));
- #endif
-
- if (theSelection)
- free(theSelection);
- if (augSelection)
- free(augSelection);
- if (empty)
- free(empty);
- theSelection = getSelection();
- if (theSelection == NULL) {
- fprintf(stderr,"Nothing selected\n");
- XBell( d, 0);
- } else {
-
- #ifdef EBUG
- fprintf(stderr,"theSelection %s\n",theSelection);
- printf("\n%s\n", theSelection);
- #endif
-
- /* The application should call all the
- * Motif clipboard calls with the SAME
- * window id. It really doesn't matter
- * which one, as long as it is associated
- * with a widget. In this case, the cut/
- * copy/paste widgets each have a window
- * associated with them. In the widget
- * hierarchy, they share a parent window.
- * The programmer can either use the parent
- * window, or any of the windows, provided
- * that it is the same for any of the calls
- * to the Motif clipboard.
- */
- if (mc_win ==0)
- mc_win = win;
- else if (mc_win != win) {
- win = mc_win;
- }
-
- /* get the selected data */
- sprintf(arot,"_MOL\n%d\n%d\n",xRot,yRot);
- incr = strlen(arot);
- augSelection = (char *)malloc(sizeof(char)*(strlen(theSelection)+incr+1));
- sprintf(augSelection,"%s%s",arot,theSelection);
-
- /*
- * Start your copy. This locks the clipboard for you.
- * Here is where you register your callback if you
- * will be using CopyByName.
- *
- */
- while (XmClipboardStartCopy(
- d,
- win,
- XmStringCreate("mol.good",XmSTRING_DEFAULT_CHARSET),
- time_of_request,
- w,
- copynameCB,
- &item_id) != ClipboardSuccess) ;
-
- /*
- * Copy the data - either by name by passing NULL
- * or by doing the copy of the data (augSelection).
- *
- * Any format passed by name is assumed to have the length
- * passed in a call to XmClipboardCopy, even though the data
- * has not yet been transferred to the clipboard in that
- * format.
- *
- * Here, we transfer it explicitly, just to show the other
- * method (as opposed to the CopyByName used in the copyCB()).
- *
- */
- while (XmClipboardCopy(
- d,
- win,
- item_id,
- /*
- XmRString,
- */
- "STRING",
- augSelection,
- (long) strlen(augSelection),
- private,
- &data_id) != ClipboardSuccess) ;
-
- while (XmClipboardEndCopy(d, win, item_id) != ClipboardSuccess) ;
- /*
- * Up until the EndCopy, all of the transfers are going
- * to a temporary buffer. EndCopy makes the data go
- * all the way to the clipboard.
- */
-
- /* now draw no molecules */
- empty = (char *)malloc(sizeof(char));
- *empty = '\0';
- buildMolecule(empty);
-
- drawScene();
- return ;
-
- }
- }
-
-
- /*
- * quitCB()
- *
- * quit call back... call on exit
- *
- * Need to clean up here - if I am the clipboard owner of something by
- * name, I must either remove the format or release the data.
- */
- quitCB(Widget w, caddr_t client_data, XmAnyCallbackStruct *call_data) {
-
- Display *d = XtDisplay(w);
- Window win = XtWindow(w);
- XmClipboardPendingList retlist;
- unsigned long count;
- int i, ret;
-
- /*
- * Use the same window id
- */
- if (mc_win ==0)
- mc_win = win;
- else if (mc_win != win) {
- win = mc_win;
- }
-
- /*
- * Check to see if there are any copy by names that have
- * never passed their data to the clipboard.
- */
- while (XmClipboardInquirePendingItems(
- d,
- win,
- /*
- XmRString,
- */
- "STRING",
- &retlist,
- &count) != ClipboardSuccess) ;
- #ifdef EBUG
- fprintf(stderr,"count is %d\n",count);
- for (i=0; i<count; i++) {
- fprintf(stderr,"data id %d | private id %d \n", (retlist+i)->DataId,
- (retlist+i)->PrivateId);
- }
- #endif
-
- if (count == 0) {
- /* then no copy by name data pending on the clipboard */
- XtFree(retlist);
- exit(0);
- } else {
-
- /*
- * Don't want the data hanging around.
- * Explicitly get rid of it.
- */
- if ( ! (wantPersistance==1)) {
-
- for (i=0; i<count; i++) {
-
- /* if do this, then data will not persist beyond app quiting */
- while (XmClipboardWithdrawFormat(
- d,
- win,
- (retlist+i)->DataId) != ClipboardSuccess);
- }
-
- } else {
-
- /*
- * Get the data onto the clipboard
- */
- for (i=0; i<count; i++) {
- while ((ret=XmClipboardCopyByName(d, win, (retlist+i)->DataId,
- augSelection, (long) strlen(augSelection), (retlist+i)->PrivateId)) != ClipboardSuccess) {
- fprintf(stderr,"ret is %d\n",ret);
- }
-
- }
- }
-
- }
-
- /* app is responsible for freeing the list memory */
- XtFree(retlist);
-
- /* be sure that the data makes it to the clipboard
- */
- XSync(d, 0);
- XtCloseDisplay(d);
- exit(0);
-
- }
-
-