















        Chapter 15.  DDrraagg aanndd DDrroopp








             Drag and drop allows the user to "pick up" objects on
             the screen, "drag" them around the display, and "drop"
             them at a new location, possibly in another
             application.

             With drag and drop the user can:

                +o Move text or other information between windows.

                +o Cause application-specific actions to occur.

                +o Obtain Help information about drop sites.

             This chapter first provides an overview of the drag and
             drop process and concepts from both the user's and the
             application developer's perspectives, then explains the
             actions of both initiator and receiver clients during
             the drag and at the drop, giving code samples.



        15.1  UUsseerr OOvveerrvviieeww ooff DDrraagg aanndd DDrroopp



             This section describes what the user does and sees
             during a drag and drop transaction.







        May 9, 1992                                             15-1








        OSF/Motif Programmer's Guide


        15.1.1  OOvveerrvviieeww ooff UUsseerr IInntteerraaccttiioonn



             A drag and drop transaction consists of the following
             actions:

               1.  A user presses and holds BBTTrraannssffeerr, usually mouse
                   button 2, over a source object starting a drag
                   transaction. The application owning that object
                   is the initiator of the drag.  The current
                   pointer is replaced by a drag icon-a picture
                   representing the item being dragged.

               2.  The user moves the pointer.  From now until a
                   drop occurs, the drag icon replaces the mouse
                   pointer.

               3.  The user drops the object, usually by releasing
                   the mouse button.

                   The drag icon can be dropped anywhere on the
                   screen.  However, only certain widgets have
                   registered themselves as drop sites and are able
                   to process the drop.

                   Locations on the screen that can accept drops are
                   drop sites and the application owning that drop
                   site is the destination or receiver.

                   The receiver application usually performs some
                   action on the information represented by the
                   dragged icon.  The initiator application may also
                   perform some action based on the results of a
                   drag transaction.

             A drop can be between applications or within the same
             application.  An application can be both source and
             destination of a drop, source only, destination only,
             or not participate in drag and drop at all.

             The user can request help about a drop site, if
             available, by dragging to the drop site, and pressing
             KKHHeellpp (usually FF11).

             The user can cancel the drag at any time by pressing
             KKCCaanncceell, usually EEssccaappee.







        15-2                                             May 9, 1992








                                                       Drag and Drop


        15.1.2  OOvveerrvviieeww ooff DDrraagg OOvveerr EEffffeeccttss



             The drag icon consists of three parts:

                +o The source icon is a picture representing the type
                  of the source object, such as text.

                +o The state icon can be used to show whether or not
                  the object being dragged can be dropped at its
                  current location on the screen.

                +o The operation icon can be used to show what action
                  should happen when the drop takes place.

             In the following illustration, the running figure is
             the source icon, the arrow in the upper left is the
             state icon, and the rectangles with the corner folded
             over indicate a Copy is desired.
                           FFiigguurree 1155--11..  A Drag Icon








             These parts can be combined (blended) and attached to
             each other in different ways.  The default blending and
             attachment are shown in the previous illustration.

             Parts of the drag icon may change shape or color as it
             is being dragged through potential drop sites,
             providing visual feedback about possible drop sites to
             the user.  These changes are drag over effects.

             Applications can use the default drag icon effects, or
             provide more sophisticated or custom drag icons.  The
             application or user can customize these drag over
             effects in resource files.












        May 9, 1992                                             15-3








        OSF/Motif Programmer's Guide


        15.1.2.1  DDrraagg SSttaatteess



             During a drag, there are three states that describe the
             relationship of a drag icon to what is under it at the
             time:

             valid drop site if the drag icon is over a drop site on
                            which it can potentially be dropped
                            (this is only a hint; when the drop is
                            actually attempted, further processing
                            may show that the drop cannot actually
                            be done)

             invalid drop site the drag icon is over a drop site;
                            but it can't be dropped there.

             no drop site   the drag icon is not over a registered
                            drop site.

             The default state icon for all three states is the
             same: an arrow in the upper left corner of the drag
             icon.  Because the icon is the same for all three
             states, it appears not to change during the drag.  The
             application or the user can provide custom state icons
             or colors in a resource file.



        15.1.2.2  DDrraagg OOppeerraattiioonnss



             The user specifies what action is to take place when
             the drop occurs by pressing certain keys when the drag
             starts or while the drag is in process:

             Shift only  Force a move from the initiator to the
                         receiver client (Move).

             Ctrl only   Force a copy from the initiator to the
                         receiver client (Copy).

             Shift and Ctrl Force a link between the initiator and
                         receiver clients (Link).

             The operation chosen by the user must be valid for both
             the drag source and the drop site, or the drop site
             will be considered invalid.




        15-4                                             May 9, 1992








                                                       Drag and Drop


             If the user doesn't specify an operation, one is chosen
             by the toolkit. It choses an operation that is valid
             for both the drag source and drop site.  Move is the
             first choice, Copy is the second, and Link is the
             third.  If the system can not find a valid operation,
             the drop site is considered invalid.

             The operation icon reflects the operation chosen by the
             user or by the system.  If the operation is changed by
             the user during the drag, the operation icon changes
             also.

             The operation icon may change as the drag icon moves to
             different drop sites if the drop sites accept different
             operations.



        15.1.3  OOvveerrvviieeww ooff DDrraagg UUnnddeerr EEffffeeccttss



             A widget registered as a drop site may change visually
             as a drag icon passes over it.  These visual cues are
             drag under effects. The sensitive area of the widget is
             the part that responds to drag and drop.  By default it
             is the whole widget, but applications can specify that
             only parts of the widget respond to drag and drop.

             Various highlighting styles are possible:

                +o A border around the sensitive area of the drop
                  site widget. This is the default value.

                +o The sensitive area of the drop site widget looks
                  pushed out.

                +o The sensitive area of the drop site widget looks
                  pushed in.

                +o A special pixmap is displayed within the sensitive
                  area of the drop site widget, overwriting what is
                  normally there.

                +o No drag under effects are used for the drop site
                  widget.

             Applications can use the default drag under visual
             effects, or create more sophisticated or custom
             effects, such as special animation or sound effects.




        May 9, 1992                                             15-5








        OSF/Motif Programmer's Guide


        15.1.4  OOvveerrvviieeww ooff DDrroopp EEffffeeccttss



             Visual effects also take place during the drop:

                +o The drag icon appears to sit over the drop site
                  while the processing for the drop is finishing,
                  but the standard cursor is restored and can be
                  used normally.

                +o The source icon appears to melt into the drop site
                  if the drop is successful.

                +o The source icon appears to snap back to the source
                  if the drop is unsuccessful.

                +o A dialog window containing information about a
                  drop site should appear if the user has requested
                  help and the receiver client provides help,
                  otherwise nothing happens.

                +o The source icon appears to snap back to the source
                  and the previous X cursor returns if Cancel is
                  requested.  All drag under and drag over effects
                  are removed.

             These drop effects cannot be changed by the application
             or the user.



        15.2  TTeecchhnniiccaall OOvveerrvviieeww ooff DDrraagg aanndd DDrroopp



             This section explains some drag and drop concepts, and
             provides a general view of the initiator and receiver
             duties during the drag and at the drop.

             The Motif 1.2 toolkit for drag and drop consists of:

                +o widgets and widget classes that provide resources
                  containing details about the source and
                  destination of the drag

                +o functions that applications use to manage the
                  widgets and widget classes.

                +o protocols that specify how interactions between
                  source and destination clients are to take place.



        15-6                                             May 9, 1992








                                                       Drag and Drop


                +o functions that manage messages, call callbacks,
                  decide on the valid operations for a potential
                  drop, and keep the drop site status updated.

             If the initiator and receiver are in the same client,
             they share the same toolkit.  If the initiator and
             receiver are different clients, each client has a
             version of the toolkit.

             An application can allow any widget to be a drag source
             or initiator by specifying a translation for BBTTrraannssffeerr
             PPrreessss in that widget.  The corresponding action creates
             a DragContext which starts the drag and drop
             transaction. The toolkit on the initiator side in in
             charge during the drag and manages all drag messages
             and callbacks.

             An application can register any widget as a drop site.
             The drop site widget may change visually as a drag icon
             moves in and out of it, providing drag under visual
             clues to the status of the drag.  The application
             controlling the current drop site is known as the
             receiver.  The toolkit on the receiver side is in
             charge of the drop operation, and manages all drop
             messages and callbacks.

             Each drag source and drop site specifies the types of
             data it is prepared to handle and what operations it
             can perform on that data.

             The state of the drag indicates whether the drag icon
             is over a valid drop site, and invalid drop site, or no
             drop site. For a drop site to be valid, there must be
             at least one target type and one operation in common
             between the drag source and drop site.



        15.2.1  CCoommpplleexxiittyy ooff DDrraagg aanndd DDrroopp PPrrooggrraammss



             Applications can use drag and drop functionality on any
             of several levels:

                +o Text, List, Label, and Button widgets are already
                  defined as drag sources.  Text and TextField
                  widgets are registered as drop sites.  So, at the
                  simplest, an application can compile with the
                  Motif 1.2 libraries, and have those widgets
                  participate in drag and drop.  For instance, text



        May 9, 1992                                             15-7








        OSF/Motif Programmer's Guide


                  could be selected from one application and moved
                  into a text area in another application.

                +o On a slightly more advanced level, applications
                  can let the toolkit do most of the work, but
                  provide some customization.  For instance, an
                  application could register a pushbutton as a drop
                  site, but still use default visual effects.  In
                  this case, the application would register a widget
                  as a DropSite and provide code to handle drop and
                  transfer duties.  The example programs DDNNDDllaabbeell..cc
                  and DDNNDDssccrroollll..cc in Appendix B are at this level.

                +o A complex application can take much of the control
                  of the drag and drop itself.  It can provide
                  custom visuals for both drag icon and drop site.
                  It can manage overlapping drop sites.  It can have
                  complex transfers of information.  The example
                  program DDNNDDddeemmoo in Appendix B contains extensive
                  customization.



        15.2.1.1  AA SSiimmppllee DDrraagg RReecceeiivveerr



             This sample program displays a Label widget and
             registers it as a drop site.  It accepts compound text,
             and supports only the Copy operation (that is, it does
             not support Move or Link).

             When a valid drop is made on the Label widget, its
             HandleDrop routine changes the Label widget's label to
             compound text passed from the initiator.

             The appropriate #include lines, the
             DropTransferCallback routine, the HandleDrop routine,
             and a few lines in the main routine to register the
             drop site are all that is needed to customize a Label
             widget to accept a drop and change its label in
             response.  The details of this additional code are
             covered in later sections of this chapter.

          FFiigguurree 1155--22..  A Label Widget Receiver Before and After Drag









        15-8                                             May 9, 1992








                                                       Drag and Drop


             /*      file: DNDlabel.c     */

             #include <signal.h>
             #include <stdio.h>

             #include <X11/Xlib.h>
             #include <Xm/Xm.h>
             #include <Xm/BulletinB.h>
             #include <Xm/AtomMgr.h>
             #include <Xm/Label.h>

             #include <Xm/DragDrop.h>

             #include <X11/Xatom.h>

             #define MAX_ARGS        10

             /* global variables */
             Widget   myDC;
             Atom     COMPOUND_TEXT;

             /* This routine transfers information from the initiator */
             static void TransferProc(w, closure, seltype, type, value, length,
                                              format)
             Widget           w;
             XtPointer        closure;
             Atom             *seltype;
             Atom             *type;
             XtPointer        value;
             unsigned long    *length;
             int              format;
             {
                int         n;
                Arg         args[MAX_ARGS];

                /* information from the drag initiator is passed in compound
                 *text format.  Convert it to compound string and replace the
                 * Label label. */

                if (*type = COMPOUND_TEXT) {
                   n = 0;
                   XtSetArg(args[n], XmNlabelString, XmCvtCTToXmString(value));
                   n++;
                   XtSetValues(closure, args, n);
                   }
             }

             /* This routine is performed when a drop is made.  It decides what
             information it wants and uses TransferProc to transfer the data
             from the initiator */




        May 9, 1992                                             15-9








        OSF/Motif Programmer's Guide


             static void HandleDrop(w, client_data, call_data)
             Widget          w;
             XtPointer       client_data, call_data;
             {

                XmDropProcCallback      DropData;
                XmDropTransferEntryRec  transferEntries[2];
                XmDropTransferEntry     transferList;
                Arg                     args[MAX_ARGS];
                int                     n;

                DropData = (XmDropProcCallback)call_data;

                /* set the transfer resources */
                n = 0;

                /* if the action is not Drop or the operation is not Copy,
                 * cancel the drop */
                if ((DropData->dropAction != XmDROP) ||
                (DropData->operation != XmDROP_COPY))
                   XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
                else {
                   /* the drop can continue.  Establish the transfer list and
                    * start the transfer */
                   transferEntries[0].target = COMPOUND_TEXT;
                   transferEntries[0].client_data = (XtPointer)w;
                   transferList = transferEntries;
                   XtSetArg(args[n], XmNdropTransfers, transferList); n++;
                   XtSetArg(args[n], XmNnumDropTransfers, 1); n++;
                   XtSetArg(args[n], XmNtransferProc, TransferProc); n++;
                   }

                /* start the transfer or cancel */
                XmDropTransferStart(DropData->dragContext, args, n);
             }

             /* This program creates a pushbutton with a label, which is
              * registered as a drop site.  The label changes when compound
              * text is dropped on it.  */

             void main (argc, argv)
             unsigned int argc;
             char **argv;
             {

                Arg                     args[MAX_ARGS];
                int                     n;
                Widget                  topLevel, BulletinB, Label;
                XtAppContext            app_context;
                Atom                    importList[1];




        15-10                                            May 9, 1992








                                                       Drag and Drop


                /* make the supporting widget structure for the Label widget */
                topLevel = XtAppInitialize(&app_context, "XMTest", NULL, 0,
                                           &argc, argv, NULL, NULL, 0);

                n = 0;
                BulletinB = XmCreateBulletinBoard(topLevel, "BulletinB",
                                                  args, n);
                XtManageChild(BulletinB);

                COMPOUND_TEXT = XmInternAtom(XtDisplay(topLevel),
                                             "COMPOUND_TEXT", False);

                /* create a Label widget */
                n = 0;
                Label = XmCreateLabel(BulletinB, "title", args, n);
                XtManageChild(Label);

                /* register the label as a drop site */
                importList[0] = COMPOUND_TEXT;
                n = 0;
                XtSetArg(args[n], XmNimportTargets, importList); n++;
                XtSetArg(args[n], XmNnumImportTargets, 1); n++;
                XtSetArg(args[n], XmNdropSiteOperations, XmDROP_COPY);
                XtSetArg(args[n], XmNdropProc, HandleDrop); n++;
                XmDropSiteRegister(Label, args, n);

                XtRealizeWidget(topLevel);
                XtAppMainLoop(app_context);
             }



        15.2.1.2  AA SSiimmppllee DDrraagg SSoouurrccee



             This program creates a ScrollBar widget which is to be
             used as a drag source.  The normal action for Button 2
             Press has been overridden to cause call the StartDrag
             routine, which causes the drag to begin.  The program
             allows only the Copy operation, and will reply to
             requests for compound text.

             When a drag is started on the ScrollBar, the default
             drag icons are used.

             When a transfer request is received by the
             DragConvertProc routine, it returns the value of the
             scrollbar slider converted into compound text.





        May 9, 1992                                            15-11








        OSF/Motif Programmer's Guide


             The code necessary to make a normal ScrollBar widget
             into a source for drag and drop is the appropriate
             #include lines, the DragConvertProc routine, the
             StartDrag routine, and translation and action commands.
             The details of this additional code are covered in
             later sections of this chapter.

                FFiigguurree 1155--33..  A ScrollBar Widget as Drag Source










             /*      file: DNDscroll.c        */

             #include <signal.h>
             #include <stdio.h>

             #include <X11/Xlib.h>
             #include <Xm/Xm.h>
             #include <Xm/BulletinB.h>
             #include <Xm/ScrollBar.h>
             #include <Xm/AtomMgr.h>

             #include <Xm/DragDrop.h>

             #include <X11/Xatom.h>

             #define MAX_ARGS        10

             /* global variables */
             Widget                  scrollbar;
             Atom                    COMPOUND_TEXT;

             /* this routine returns the value of the scrollbar slider,
              * converted into compound text. */

             static Boolean DragConvertProc(w, selection, target, typeRtn,
                                            valueRtn, lengthRtn, formatRtn,
                                            max_lengthRtn, client_data,
                                            request_id)
             Widget              w;
             Atom                *selection;
             Atom                *target;
             Atom                *typeRtn;
             XtPointer           *valueRtn;



        15-12                                            May 9, 1992








                                                       Drag and Drop


             unsigned long       *lengthRtn;
             int                 *formatRtn;
             unsigned long       *max_lengthRtn;
             XtPointer           client_data;
             XtRequestId         *request_id;
             {

                Widget      dc;
                XmString    cstring;
                static char tmpstring[100];
                int         *value;
                int         n;
                Arg         args[MAX_ARGS];
                char             *ctext;
                char        *passtext;

                /* this routine processes only compound text */
                if (*target != COMPOUND_TEXT)
                   return(False);

                /* get the value of the scrollbar slider */
                n = 0;
                XtSetArg(args[n], XmNvalue, &value); n++;
                XtGetValues(scrollbar, args, n);

                /* convert the slider value to compound text */
                sprintf(tmpstring, "%d", value);
                cstring = XmStringCreateLocalized(tmpstring);
                ctext = XmCvtXmStringToCT(cstring);

                passtext = XtMalloc(strlen(ctext)+1);
                memcpy(passtext, ctext, strlen(ctext)+1);

                /* format the value for transfer.  convert the value from
                * compound string to compound text for the transfer */
                *typeRtn = COMPOUND_TEXT;
                *valueRtn = (XtPointer) passtext;
                *lengthRtn = strlen(passtext);
                *formatRtn = 8;
                return(True);
             }

             /* This routine is performed by the initiator when a drag starts
              * (in this case, when mouse button 2 was pressed).  It starts
              * the drag processing, and establishes a drag context */

             static void StartDrag(w, event)
             Widget  w;
             XEvent  *event;
             {
                Arg             args[MAX_ARGS];



        May 9, 1992                                            15-13








        OSF/Motif Programmer's Guide


                Cardinal        n;
                Atom            exportList[1];

                /* establish the list of valid target types */
                exportList[0] = COMPOUND_TEXT;

                n = 0;
                XtSetArg(args[n], XmNexportTargets, exportList); n++;
                XtSetArg(args[n], XmNnumExportTargets, 1); n++;
                XtSetArg(args[n], XmNdragOperations, XmDROP_COPY);
                XtSetArg(args[n], XmNconvertProc, DragConvertProc); n++;
                XmDragStart(w, event, args, n);
             }


             /* translations and actions.  Pressing mouse button 2 overrides
              * the normal scrollbar action and calls StartDrag to start a
              * drag transaction */

             static char dragTranslations[] =
                  "#override <Btn2Down>: StartDrag()";
             static XtActionsRec dragActions[] =
                  { {"StartDrag", (XtActionProc)StartDrag} };

             /* This routine creates a window with a scrollbar in it. */

             void main (argc, argv)
             unsigned int argc;
             char **argv;
             {

                Arg                     args[MAX_ARGS];
                int                     n;
                Widget                  topLevel, BulletinB;
                XtAppContext            app_context;
                Atom                    importList[1];
                XtTranslations          parsed_xlations;

                /* create widget structure for scrollbar widget */
                topLevel = XtAppInitialize(&app_context, "DNDscroll", NULL, 0,
                                           &argc, argv, NULL, NULL, 0);

                COMPOUND_TEXT = XmInternAtom(XtDisplay(topLevel),
                                             "COMPOUND_TEXT", False);

                n = 0;
                BulletinB = XmCreateBulletinBoard(topLevel, "BBoard", args, n);
                XtManageChild(BulletinB);

                /* override button two press to start a drag */
                parsed_xlations = XtParseTranslationTable(dragTranslations);



        15-14                                            May 9, 1992








                                                       Drag and Drop


                XtAppAddActions(app_context, dragActions, XtNumber(dragActions));

                /* create a scroll bar widget */
                n = 0;
                XtSetArg(args[n], XmNtranslations, parsed_xlations); n++;
                XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
                XtSetArg(args[n], XmNwidth, 150); n++;
                scrollbar = XmCreateScrollBar(BulletinB, "testscroll", args, n);
                XtManageChild(scrollbar);

                XtRealizeWidget(topLevel);
                XtAppMainLoop(app_context);
             }



        15.2.2  DDrraagg SSoouurrcceess aanndd DDrroopp SSiitteess



             Text, List, Label, and Button widgets are automatically
             drag sources.  Applications need do nothing further to
             use them. An application can allow any widget to be a
             drag source by establishing a callback when BBTTrraannssffeerr
             is pressed within that widget.  The application which
             owns the widget in which the drop was started is the
             initiator.

             A drag icon, which is a pictorial representation of the
             data being dragged, replaces the normal cursor while
             the drag is in effect.  The icon may change as it moves
             around the screen.  The actual data is not being
             dragged, only a representation of it.  The data is
             transferred to a new location only when the drop is
             made, through the drop transfer protocol.

             Any widget can be registered as a drop site.  Text and
             TextField widgets are automatically registered as drop
             sites.  If an application wants to use these as drop
             sites, it need not register them separately.

             The "drop site" is simply the place where the drag is
             terminated. The DropSite registry contains information
             about widgets that have been registered as drop sites.
             Although the drag icon can be dropped anywhere on the
             screen, only widgets that have been registered as drop
             sites can accept information from the initiator.  The
             receiver is the application controlling the current
             drop site.





        May 9, 1992                                            15-15








        OSF/Motif Programmer's Guide


             The "sensitive area" is the part of the widget that
             responds to drag and drop.  By default, the sensitive
             area is the whole widget.  However, the application can
             specify that only part of the widget is sensitive.

             Widgets that are drop sites can be stacked on each
             other, with one widget partially or completely within
             the boundary of another.   The sensitive areas of lower
             drop sites are clipped if they are covered by a higher
             widget.

             The stacking order of the widgets with drop sites can
             be changed by the application.



        15.2.3  PPrroottooccoollss



             The protocol describes how the initiator and receiver
             clients interact through the toolkit with each other.



        15.2.3.1  DDrraagg PPrroottooccoollss


             There are two types of drag protocol:

             preregister Does not require messaging.

             dynamic   Does require messaging.

             Applications can support either, both, or neither.  If
             possible, clients should support both to allow the most
             flexibility for users.  The Motif 1.2 toolkit
             automatically supports both unless a user or client
             sets resources to force the use of one or the other.

             The user can specify which drag protocol to use when
             the client is the initiator or receiver.  The
             application can specify drag protocol in an app-
             defaults file. If neither the application or the user
             specify a protocol, the preregister drag protocol is
             used.

             The toolkit uses the requested protocols and the
             protocols allowed by the initiator and receiver clients
             to arrive at the protocol actually being used.
             Therefore, the protocol can change as the drag icon



        15-16                                            May 9, 1992








                                                       Drag and Drop


             moves from window to window, depending on which
             protocols they both support.  If the initiator and
             receiver cannot agree on a protocol, no drag over or
             drag under visuals effects are shown.

             Even if there are no drag over or drag under visual
             effects, a drop can still occur using the drop
             protocol, unless a client has specified that that that
             window does not participate in drag and drop.



        15.2.3.2  DDrroopp PPrroottooccooll



             The drop protocol is based on the Xt Selection transfer
             protocol.  The transfer between either client and the
             toolkit can be incremental or non-incremental,
             regardless of how the other client is transferring.
             Each client has a procedure to process transfers:
             XXmmNNccoonnvveerrttPPrroocc for the initiator, and XXmmNNttrraannssffeerrPPrroocc
             for the receiver.  Incremental transfer is indicated by
             a resource value.

             The receiver creates a list of information and target
             types desired from the initiator, along with a
             XXmmNNttrraannssffeerrPPrroocc to handle any processing needed during
             the transfer.  It then calls XXmmDDrrooppTTrraannssffeerrSSttaarrtt to
             start the transfer process. Even if there is no
             transfer, the receiver should call this routine, so
             that the status can be updated correctly for the
             initiator.

             For each item in the transfer list, the initiator's
             XXmmNNccoonnvveerrttPPrroocc is called.  This procedure reads and
             processes the request and returns the information.

             When the transfer has finished, the toolkit on the
             receiver side updates the XXmmNNttrraannssffeerrSSttaattuuss
             DropTransfer resource to indicate if the transfer was
             successful.  The receiver's XXmmNNttrraannssffeerrPPrroocc routine can
             also update this resource.











        May 9, 1992                                            15-17








        OSF/Motif Programmer's Guide


        15.2.4  DDrraagg aanndd DDrroopp WWiiddggeett CCllaasssseess



             Motif 1.2 provides a number of Xt objects and widgets
             to encapsulate the underlying protocol, however, these
             are not mapped onto the screen.

             XXmmDDiissppllaayy        An object that contains display-
                              specific information, such as the
                              initiator and receiver protocol
                              styles.

             XXmmSSccrreeeenn         An object that describes screen-
                              specific information, such as font and
                              default drag over icons.

             XXmmDDrraaggIIccoonn       A widget that describes the pixmap,
                              mask, and attachment of an icon. The
                              source icon, state icon, operation
                              icon, and the resulting blended drag
                              icon are all Drag Icons.

             XXmmDDrraaggCCoonntteexxtt    A widget that describes the resources
                              specified by each drag initiator, such
                              as target type, custom icons, custom
                              colors, blending model, permitted
                              operations, and callback routines for
                              various situations encountered during
                              the drag and drop transaction.

             XXmmDDrrooppSSiittee       A drop site database maintains a
                              registry of the resources unique to
                              each drop site, such as animation for
                              drag-under effects, valid target types
                              and operations, and callback routines
                              for situations encountered during a
                              drag and drop transaction.  It is not
                              an Xt object, although it acts like
                              one with respect to resource fetching.

             XXmmDDrrooppTTrraannssffeerr   A widget that describes the
                              information desired from the initiator
                              client and the procedure used to
                              process the results.









        15-18                                            May 9, 1992








                                                       Drag and Drop


        15.2.5  DDrraagg aanndd DDrroopp FFuunnccttiioonnss



             Motif 1.2 provides functions to support drag and drop
             processing:

             XXmmCCrreeaatteeDDrraaggIIccoonn         Creates any of the parts of a
                                      drag icon (status icon,
                                      operation icon, or source
                                      icon) from a cursor or pixmap.
                                      This allows custom icons for
                                      all or part of the drag icon,
                                      rather than the default icons.

             XXmmDDrraaggCCaanncceell             Cancels a drag that is in
                                      progress.  This function is
                                      called when the user presses
                                      KKCCaanncceell.

             XXmmDDrraaggSSttaarrtt              This function is called in the
                                      routine that is performed when
                                      the user starts a drag.
                                      Resources describing the
                                      initiator are established.
                                      This function creates a
                                      DragContext object, which is
                                      referenced by other functions
                                      whenever information about the
                                      drag initiator is needed.

             XXmmDDrrooppSSiitteeCCoonnffiigguurreeSSttaacckkiinnggOOrrddeerr Sets the order of
                                      overlapping drop sites.  The
                                      default order is the first-
                                      registered drop site is on the
                                      bottom and the last-declared
                                      drop site is on top.

             XXmmDDrrooppSSiitteeEEnnddUUppddaattee      Causes the XXmmDDrrooppSSiitteeUUppddaattee
                                      requests made after
                                      XXmmDDrrooppSSiitteeSSttaarrttUUppddaattee to take
                                      place.

             XXmmDDrrooppSSiitteeQQuueerryySSttaacckkiinnggOOrrddeerr Provides information about
                                      the stacking order of
                                      overlapping drop sites.  The
                                      order can be changed with
                                      XXmmDDrrooppSSiitteeCCoonnffiigguurreeSSttaacckkiinnggOOrrddeerr.

             XXmmDDrrooppSSiitteeRReeggiisstteerr       Registers a drop site.
                                      Resources describing the drop



        May 9, 1992                                            15-19








        OSF/Motif Programmer's Guide


                                      site are defined.

             XXmmDDrrooppSSiitteeRReettrriieevvee       Retrieves the values of drop
                                      site resources.

             XXmmDDrrooppSSiitteeSSttaarrttUUppddaattee    Signals the toolkit to wait
                                      until XXmmDDrrooppSSiitteeEEnnddUUppddaattee is
                                      called to process drop site
                                      changes requested by
                                      XXmmDDrrooppSSiitteeUUppddaattee.  This
                                      provides a more efficient way
                                      to update several drop sites
                                      than changing them one at a
                                      time.

             XXmmDDrrooppSSiitteeUUppddaattee         Updates drop site resources
                                      for a single drop site.  If a
                                      series of XXmmDDrrooppSSiitteeUUppddaattee
                                      requests are surrounded by
                                      XXmmDDrrooppSSiitteeSSttaarrttUUppddaattee and
                                      XXmmDDrrooppSSiitteeEEnnddUUppddaattee, then the
                                      changes will be made all at
                                      once after the end update
                                      request.

             XXmmDDrrooppSSiitteeUUnnrreeggiisstteerr     Removes a drop site.  After a
                                      drop site has been
                                      unregistered, it is
                                      unavailable as a destination
                                      for a drag.

             XXmmDDrrooppTTrraannssffeerrAAdddd        Add additional transfer
                                      requests once a transfer has
                                      started.

             XXmmDDrrooppTTrraannssffeerrSSttaarrtt      Specifies what information
                                      should be requested from the
                                      drag initiator, and starts the
                                      process to get the
                                      information.

             XXmmGGeettDDrraaggCCoonntteexxtt         Returns the DragContext ID
                                      associated with a particular
                                      time stamp.

             XXmmGGeettXXmmDDiissppllaayy           Returns the ID for the
                                      specified display.

             XXmmGGeettXXmmSSccrreeeenn            Returns the ID for a specified
                                      screen.  Some resources, such
                                      as the drag icons, are



        15-20                                            May 9, 1992








                                                       Drag and Drop


                                      screen-specific.

             XXmmTTaarrggeettssAArreeCCoommppaattiibbllee   Checks if there are any
                                      matching targets between the
                                      initiator and destination to
                                      help determine the correct
                                      drag state.



        15.2.6  TTaarrggeettss



             Each drag source and drop site specifies what kinds of
             data types it can process, called targets.  These
             targets are atoms, such as XXAA__SSTTRRIINNGG.

             The DragContext resources, XXmmNNeexxppoorrttTTaarrggeettss and
             XXmmNNnnuummEExxppoorrttTTaarrggeettss provide a list and number of the
             data types provided by the drag source. These are
             export targets.

             The DropSite resources, XXmmNNiimmppoorrttTTaarrggeettss and
             XXmmNNnnuummIImmppoorrttTTaarrggeettss provide a list and number of the
             data types accepted by the drop site.  These are known
             as import targets.

             Any number of targets may be listed for each source and
             site.  A drop site is considered valid for a particular
             drag if at least one of its targets matches any of the
             source's targets and if the source and drop site
             operations are compatible.

             An application can define anything it wants as a
             target.  Be aware, however, that other applications
             might not recognize that target.



        15.2.7  OOppeerraattiioonnss



             There are three ways that the initiator and receiver
             can interact with each other:

                +o Data can be moved from the initiator to the
                  receiver (Move).





        May 9, 1992                                            15-21








        OSF/Motif Programmer's Guide


                +o Data can be copied from the initiator to the
                  receiver (Copy).

                +o Data can be linked from the receiver to the
                  initiator (Link).

             When a drag is started, the initiator provides a list
             of valid operations in the DragContext
             XXmmNNddrraaggOOppeerraattiioonnss resource.  When a drop site is
             registered, the receiver provides a list of operations
             it supports in the DropSite XXmmNNddrrooppSSiitteeOOppeerraattiioonnss
             resource.  These lists are the values XXmmDDRROOPP__MMOOVVEE,
             XXmmDDRROOPP__CCOOPPYY, or XXmmDDRROOPP__LLIINNKK, connected by the bitwise
             OR operator (|).  For instance, XXmmDDRROOPP__MMOOVVEE ||
             XXmmDDRROOPP__CCOOPPYY means that Move and Copy are valid
             operations, but Link is not.  The value XXmmDDRROOPP__NNOOOOPP
             indicates that there are no operations possible for a
             drop at the current site.

             Callback structures for both the DragContext and
             DropSite have _o_p_e_r_a_t_i_o_n and _o_p_e_r_a_t_i_o_n_s fields.  The
             _o_p_e_r_a_t_i_o_n_s field lists all valid operations if a drop
             were to occur at this point.  The _o_p_e_r_a_t_i_o_n field shows
             the operations that would happen if a drop occurred at
             this point.  As the drag icon moves over different
             potential drop sites, the values in its callback
             structures change in response to what operations the
             drop sites allow. If there are no common operations
             between a drag source and a drop site, the _o_p_e_r_a_t_i_o_n
             and _o_p_e_r_a_t_i_o_n_s fields are set to XXmmDDRROOPP__NNOOOOPP, and the
             _d_r_o_p_S_i_t_e_S_t_a_t_u_s field is set to XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

             The user can specify an operation using key
             combinations discussed earlier in this chapter.  The
             use can also change the operation at any time until the
             drop starts.

             The initiator and the receiver need to be able to
             handle all the operations their application supports.
             If the operation is Move, the receiver first gets a
             copy of the data, then tells the initiator that it can
             delete the data.  If the operation is Copy, both
             applications have the data, making two copies of it.
             If the operation is Link, there is only one copy of the
             data, and the receiver establishes a link to that copy.









        15-22                                            May 9, 1992








                                                       Drag and Drop


        15.2.7.1  DDrroopp SSiittee SSttaattuuss



             The drag and drop callbacks for both receiver and
             initiator contain a _d_r_o_p_S_i_t_e_S_t_a_t_u_s field.  This field
             is initialized and maintained by the receiver through
             the toolkit, although the receiver's drag and drop
             procedures can update it if they wish.  This field is
             used by the toolkit to determine what drag over and
             drag under visual effects to use.

             The field indicates the the relation of drag source to
             the drop site over which the drag icon is located.

             XXmmDDRROOPP__SSIITTEE__VVAALLIIDD        A drop can take place.  There
                                      is at least one matching
                                      target and operation between
                                      the drag source and the drop
                                      site.

             XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD      A drop cannot take place.
                                      Either there were no matching
                                      targets, no matching
                                      operations, or the receiver's
                                      XXmmNNddrraaggPPrroocc or XXmmNNddrrooppPPrroocc
                                      discovered some other problem
                                      that would make a drop
                                      impossible.

             XXmmNNOO__DDRROOPP__SSIITTEE           The drag icon is not over a
                                      drop site.

             If the toolkit on the receiver's side has set either
             _o_p_e_r_a_t_i_o_n or _o_p_e_r_a_t_i_o_n_s field to XXmmDDRROOPP__NNOOOOPP, it also
             sets the _d_r_o_p_S_i_t_e_S_t_a_t_u_s field to XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.



        15.2.8  OOvveerrvviieeww ooff PPrrooggrraammmmeerr RReessppoonnssiibbiilliittiieess



             This section provides an overview of the actions of the
             initiator client, and the receiver client while a drag
             and drop transaction is in progress.  The actions are
             covered in more detail later in the chapter.

             Before a drag starts:





        May 9, 1992                                            15-23








        OSF/Motif Programmer's Guide


                +o The user or client can indicate with the protocol
                  resources the type of protocol and visual effects
                  to be used for the initiator and receiver if
                  possible.

                +o The initiator client creates any special icons it
                  wants to use for drag over effects using
                  XXmmCCrreeaatteeDDrraaggIIccoonn.

                  The initiator establishes translation or event
                  handlers to react to BBTTrraannssffeerr PPrreessss.

                +o The receiver client registers widgets as potential
                  drop sites using XXmmDDrrooppSSiitteeRReeggiisstteerr, providing
                  information about:

                     - the shape of the area of the widget sensitive
                       to drag and drop, if it is not the whole
                       widget.

                     - valid targets

                     - optional drag under visual effects.

                     - an optional XXmmNNddrraaggPPrroocc to receive messages
                       during the drag.

                     - an XXmmNNddrrooppPPrroocc to be performed at the drop.

                  The receiver can check and change the stacking
                  order of overlapping drop sites with
                  XXmmDDrrooppSSiitteeQQuueerryySSttaacckkiinnggOOrrddeerr and
                  XXmmDDrrooppSSiitteeCCoonnffiigguurreeSSttaacckkiinnggOOrrddeerr.

                  The receiver can update drop site information
                  using XXmmDDrrooppSSiitteeUUppddaattee, XXmmDDrrooppSSiitteeSSttaarrttUUppddaattee, and
                  XXmmDDrrooppSSiitteeEEnnddUUppddaattee.

                  The receiver can unregister a drop site with
                  XXmmDDrrooppSSiitteeUUnnrreeggiisstteerr.

             When the drag starts (typically a BBTTrraannssffeerr PPrreessss
             event):

                +o The toolkit on the initiator's side is in charge
                  during the drag, until a drop is made.  The
                  initiator client:

                     - Receives an indication that the user has
                       started a drag.




        15-24                                            May 9, 1992








                                                       Drag and Drop


                     - Creates a DragContext using XXmmDDrraaggSSttaarrtt,
                       specifying:

                          - valid targets

                          - optional callbacks to be performed
                            during the drag.

                          - a XXmmNNccoonnvveerrttPPrroocc to process transfer
                            requests from the receiver.

                          - optional custom drag-over visuals.

                          - optional drop callbacks to be performed
                            when a drop occurs.

                +o The receiver client does nothing.

             During a drag:

                +o The user can cancel the drag or change operation.

                +o The receiver is not involved unless the pointer is
                  within one of its registered drop sites.

                  The toolkit on the receiver's side initializes the
                  _d_r_o_p_S_i_t_e_S_t_a_t_u_s, _o_p_e_r_a_t_i_o_n, and _o_p_e_r_a_t_i_o_n_s fields
                  in the callback structure

                  The receiver's XXmmNNddrraaggPPrroocc routine (if one was
                  registered) is notified of drag source actions
                  within the drop site: drop site enter, drop site
                  leave, drag icon motion, or change of operation.
                  This XXmmNNddrraaggPPrroocc routine is called only if the
                  drag protocol is dynamic.  It handles any special
                  processing and drag under visuals.

                  If the protocol is preregister, drag under visuals
                  are handled by the toolkit on the initiator side.

                +o By default, the initiator need do nothing during a
                  drag.

                  If the initiator client has registered the
                  appropriate callback routines, it is notified
                  after the receiver's XXmmNNddrraaggPPrroocc when the drag is
                  entering or leaving a top level window, entering
                  or leaving a drop site, is in motion, or the user
                  has changed the desired operation.  The values of
                  _d_r_o_p_S_i_t_e_S_t_a_t_u_s, _o_p_e_r_a_t_i_o_n, and _o_p_e_r_a_t_i_o_n_s in the
                  drag callbacks are initialized by either the



        May 9, 1992                                            15-25








        OSF/Motif Programmer's Guide


                  toolkit on the receiver side or XXmmNNddrraaggPPrroocc, or by
                  the toolkit on the initiator side if the pointer
                  is not over a registered drop site.

                  The initiator can activate custom drag over
                  effects or other special processing.

                  The initiator can cancel the drag in progress by
                  using XXmmDDrraaggCCaanncceell.

                +o Either client can check the compatibility of
                  export and import targets with
                  XXmmTTaarrggeettssAArreeCCoommppaattiibbllee.

                  Either client can obtain information about the
                  drop site that the drag icon is over (if any) with
                  XXmmDDrrooppSSiitteeRReettrriieevvee.

             When the drop occurs:

                +o The toolkit on the receiver side is in charge
                  during the drop and transfer.

                  The receiver's XXmmNNddrrooppPPrroocc routine makes any final
                  checks that a drop really is possible, and updates
                  the _d_r_o_p_S_i_t_e_S_t_a_t_u_s, _o_p_e_r_a_t_i_o_n_s, and _o_p_e_r_a_t_i_o_n
                  fields in the XXmmNNddrrooppPPrroocc callback structure for
                  the initiator to read in its XXmmNNddrrooppSSttaarrttCCaallllbbaacckk
                  callback structure.

                  If the drop was the result of the user requesting
                  help, the receiver's XXmmNNddrrooppPPrroocc displays
                  information in a dialog box, and waits for a
                  response from the user, before either continuing
                  or cancelling the drop.

                  If the drop is valid, the receiver requests
                  transfer information from the initiator.

                  Only the receiver can cancel a drop.

                +o The initiator's XXmmNNddrrooppSSttaarrttCCaallllbbaacckk callback
                  routine is called after the receiver's XXmmNNddrrooppPPrroocc
                  has finished.  The values of the _d_r_o_p_S_i_t_e_S_t_a_t_u_s,
                  _o_p_e_r_a_t_i_o_n, and _o_p_e_r_a_t_i_o_n_s fields in the callback
                  structure were set by the toolkit on the receiver
                  side or XXmmNNddrrooppPPrroocc.

             Transferring data between initiator and receiver:





        15-26                                            May 9, 1992








                                                       Drag and Drop


                +o The receiver's XXmmNNddrrooppPPrroocc establishes a list of
                  data and target formats it wants to receive, and
                  calls the XXmmDDrrooppTTrraannssffeerrSSttaarrtt function.  The list
                  can be updated with XXmmDDrrooppTTrraannssffeerrAAdddd during the
                  transfer.

                  The receiver registers a XXmmNNttrraannssffeerrPPrroocc to
                  process each transfer from the initiator.

                  The receiver can cancel the drop while the
                  transfer is in progress.

                  If there is no information to be transferred, or
                  if the drop is cancelled, the receiver must still
                  call XXmmDDrrooppTTrraannssffeerrSSttaarrtt.  The initiator is unable
                  to proceed until it is notified that a transfer
                  has ended.  Only the receiver can cancel a drop

                +o The initiator's XXmmNNccoonnvveerrttPPrroocc routine is executed
                  in response to a request from the
                  XXmmDDrrooppTTrraannssffeerrSSttaarrtt function called by the
                  receiver.  It returns the information formatted
                  according to the requested target to the
                  receiver's XXmmNNttrraannssffeerrPPrroocc.

             After the drop has finished:

                +o The initiator's XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk is called
                  when the transfer is complete.  The initiator's
                  XXmmNNddrraaggDDrrooppFFiinniisshhCCaallllbbaacckk is called after the
                  whole drag and drop transaction has finished.



        15.3  DDrraagg aanndd DDrroopp PPrroottooccoollss



             The protocols refer to how the initiator and receiver
             client use the toolkit to communicate with each other.
             There are two drag protocol styles that are available.
             The drop protocol is based on the Xt Selection
             protocol.











        May 9, 1992                                            15-27








        OSF/Motif Programmer's Guide


        15.3.1  DDrraagg PPrroottooccoollss



             The toolkit on the initiator side is in charge during
             the drag.  The protocol in effect determines how it
             will find the information about drop sites that it
             needs to manage visuals, and how extensively the
             initiator and receiver clients are involved during the
             drag.

             There are two kinds of drag protocol styles:

             preregister which stores drop site information in a
                       database when the drop site is registered.
                       The receiver is not involved in the drag
                       until a drop occurs.  All drag over and drag
                       under visual effects are managed by the
                       toolkit on the initiator side.

             dynamic   which uses messages from the toolkit to the
                       receiver to find out drop site information.
                       The toolkit on the receiver side can reply to
                       the messages, or the application can take
                       action based on these messages.  The receiver
                       manages the drag under effects.

             The code for the initiator is the same regardless of
             the protocol.  The code for the receiver applications
             is the same except that in the dynamic mode, the
             receiver's XXmmNNddrraaggPPrroocc is called.

             The drag protocol in use can change during the course
             of a drag.  When the drag icon enters or leaves a top
             level window, the source and potential drop receiver
             negotiate a mutually acceptable drag protocol, as
             described in a later section.



        15.3.1.1  TThhee PPrreerreeggiisstteerr DDrraagg PPrroottooccooll



             When a receiver supports the preregister protocol, the
             toolkit on the receiver side stores drop site
             information in a database. The toolkit on the initiator
             side manages all drag under effects based on the
             information in the drop site database.  By setting some
             drop site resources appropriately, the receiver can
             have the toolkit use different highlighting or pixmaps,



        15-28                                            May 9, 1992








                                                       Drag and Drop


             but the receiver does not participate directly in the
             drag under effects.

             With the preregister protocol:

                +o The toolkit uses pixmap source icons if provided
                  by the client.  If none are provided, it uses
                  bitmap source icons if provided by the client.  If
                  none are provided, it uses Screen icons.  The
                  Screen icons can be either the default icons, or
                  ones provided by the client or user.

                +o The server is grabbed by the drag icon.

                +o The only customization a receiver can perform is
                  providing custom values for the DropSite visual
                  resources.

                +o The drag icon can be any size supported by the
                  system on which the application is running.



        15.3.1.2  TThhee DDyynnaammiicc DDrraagg PPrroottooccooll



             With the dynamic drag protocol, the initiator and
             receiver communicate with messages through the toolkit.

             As the drag icon moves within the receiver's window,
             messages are sent from the toolkit on the initiator
             side to the toolkit on the receiver side.  Based on
             these messages, the receiver determines whether the
             drag icon is entering, within, or leaving a drop site.
             Although the toolkit on the receiver side initializes
             state and operation information, the receiver can check
             and update this information further if it registers a
             XXmmNNddrraaggPPrroocc for the drop site. The initiator receives
             the updated message in one of its drag-related
             callbacks (described later in this chapter), and can
             take action accordingly.

             The dynamic drag protocol allows the receiver to
             provide more sophisticated visual effects using the
             XXmmNNddrraaggPPrroocc than the toolkit can provide alone.

             With the dynamic drag procotol:

                +o The receiver can provide custom drag processing
                  and drag under visual effects.



        May 9, 1992                                            15-29








        OSF/Motif Programmer's Guide


                +o The drag icon must fit in the largest cursor size
                  supported by the system running the application.
                  If it is too large, it will be truncated to fit.



        15.3.2  CChhoooossiinngg tthhee PPrroottooccooll aanndd VViissuuaall SSttyyllee



             The user can specify which drag protocol to use or the
             application can specify the drag protocol in resource
             file.

             The preregister drag protocol can be  used with a
             minimum of additional coding in an application, since
             the toolkit manages the drag over visual effects using
             the default drag icons specified in the Screens object.
             Or the application can override the default Screen
             icons with custom icons, but still allow the toolkit to
             manage the effects.

             The dynamic drag protocol requires more work for the
             application program, but allows receiver application to
             provides visual effects beyond the capabilities of the
             toolkit.

             The drag protocol in use has an effect on the system
             performance as described later in this section.



        15.3.2.1  SSppeecciiffyyiinngg DDrraagg PPrroottooccoollss



             Two Display resources specify which protocol the
             toolkit should try to use when a client is an initiator
             or receiver.  These resources can be set by the client
             in resource file, or by the user.

                +o XXmmNNddrraaggIInniittiiaattoorrPPrroottooccoollSSttyyllee

                +o XXmmNNddrraaggRReecceeiivveerrPPrroottooccoollSSttyyllee

             They can take the following values (the letter in
             brackets following the value is used in the matrix that
             follows)

             XXmmDDRRAAGG__NNOONNEE [N]            does not participate in drag
                                        and drop. There are no drag



        15-30                                            May 9, 1992








                                                       Drag and Drop


                                        under effects.  The drag
                                        over effects depend on the
                                        value of
                                        XXmmNNddrraaggIInniittiiaattoorrPPrroottooccoollSSttyyllee.

             XXmmDDRRAAGG__DDRROOPP__OONNLLYY [X]       doesn't support either the
                                        preregister mode or the
                                        dynamic mode, but does data
                                        transfer after the drop
                                        occurs.  There are no drag
                                        over or drag under visual
                                        effects.

             XXmmDDRRAAGG__PPRREERREEGGIISSTTEERR [P]     supports the preregister
                                        mode only.  The visual
                                        effects are managed by the
                                        toolkit.

             XXmmDDRRAAGG__PPRREEFFEERR__PPRREERREEGGIISSTTEERR [PP] supports both protocols,
                                        but prefers the preregister
                                        protocol. This is the
                                        default for receivers.  The
                                        visual effects are
                                        determined by the protocol
                                        actually used.

             XXmmDDRRAAGG__PPRREEFFEERR__RREECCEEIIVVEERR [R] used by initiators only.
                                        Uses the protocol that the
                                        receiver specifies.  This is
                                        the default for initiators.
                                        The visual effects are
                                        determined by the protocol
                                        actually used.

             XXmmDDRRAAGG__PPRREEFFEERR__DDYYNNAAMMIICC [PD] supports both protocols, but
                                        prefers the dynamic mode.
                                        The visual effects are
                                        determined by the protocol
                                        actually used.

             XXmmDDRRAAGG__DDYYNNAAMMIICC [D]         supports the dynamic
                                        protocol only.  The drag
                                        over and drag under visual
                                        effects are managed by the
                                        clients.

             For example:

             myclient*dragInitiatorProtocolStyle: DRAG_PREFER_DYNAMIC
             myclient*dragReceiverProtocolStyle:  DRAG_PREFER_DYNAMIC




        May 9, 1992                                            15-31








        OSF/Motif Programmer's Guide


             If the initiator and receiver have specified the same
             protocol, that protocol is used.  If they specify
             different protocols, the protocol that is used is shown
             in the table below.

                                         II nn ii tt ii aa tt oo rr         RReecceeiivveerr PPrroottooccooll
                                         PP rr oo tt oo cc oo ll   |_____|_____|_____|_____|_____|____
                               |  PP  |  PPPP |  PPDD |  DD  |  XX  |  NN
                    ___________|_____|_____|_____|_____|_____|____
                    P          |  P  |  P  |  P  |  X  |  X  |  N
                    PP         |  P  |  P  |  P  |  D  |  X  |  N
                    R          |  P  |  P  |  D  |  D  |  X  |  N
                    PD         |  P  |  D  |  D  |  D  |  X  |  N
                    D          |  X  |  D  |  D  |  D  |  X  |  N
                    X          |  X  |  X  |  X  |  X  |  X  |  N
                                                                                                                                            N                                                                      |                 N            |              N          |           N        |        N      |     N    |  N

             The XXmmGGeettXXmmDDiissppllaayy function returns the Display object
             ID associated with a specific display. XXttGGeettVVaalluueess can
             be used to check the protocol style resources.

             If an XXmmNNddrraaggPPrroocc is specified for a drop site, it will
             be performed only if the protocol is dynamic.  In this
             case, the XXmmNNddrraaggRReecceeiivveerrPPrroottooccoollSSttyyllee resource should
             be set to DRAG_PREFER_DYNAMIC in the app-defaults file,
             rather than using the default value.



        15.3.2.2  PPrroottooccoollss aanndd VViissuuaallss



             When the resulting protocol is preregister, a
             preregister visual style is used.  The server is
             grabbed.  The drag-over visual may be a pixmap with an
             arbitrary size whose depth and colormap are the same as
             the widget associated with the drag source.  The pixmap
             is specified in the DragContext XXmmNNssoouurrcceePPiixxmmaappIIccoonn
             resource, additionally blended as described below.

             When the resulting protocol is dynamic, a dynamic
             visual style is always used.  The drag-over visual is
             implemented using the X cursor, which must be a bitmap,
             and often has limited size (use XXQQuueerryyBBeessttSSiizzee to find
             out the largest size available per-screen).  The cursor
             is specified using XXmmNNssoouurrcceeCCuurrssoorrIIccoonn, additionally
             blended as described below.

             Users will specify one of the preregister values for
             XXmmNNddrraaggIInniittiiaattoorrPPrroottooccoollSSttyyllee because they want good



        15-32                                            May 9, 1992








                                                       Drag and Drop


             performance when network loading or context switching
             are problems, or because they want better drag-over
             visuals rather than more sophisticated drag-under
             visuals.  For visual consistency, a preregister visual
             style is used whenever possible.

             Users will specify one of the dynamic values for
             XXmmNNddrraaggIInniittiiaattoorrPPrroottooccoollSSttyyllee because there are clients
             which use use the dynamic effects, and for visual
             consistency, they want to use a dynamic visual style
             whenever possible.

             Consequently, when the resulting protocol is
             XXmmDDRRAAGG__NNOONNEE or XXmmDDRRAAGG__DDRROOPP__OONNLLYY, the visual style
             depends upon the value of
             XXmmNNddrraaggIInniittiiaattoorrPPrroottooccoollSSttyyllee.  When it is
             XXmmDDRRAAGG__DDYYNNAAMMIICC or XXmmDDRRAAGG__PPRREEFFEERR__DDYYNNAAMMIICC, the dynamic
             visual style is used; otherwise, the preregister visual
             style is used.



        15.3.3  DDrroopp PPrroottooccooll



             When a drop is made, the receiver checks what action
             should happen:

                +o If the user requested help, the receiver should
                  display a dialog box explaining the consequences
                  of a drop on the site, and determine if the user
                  wants to continue or cancel the drop.

                +o If the user requests cancel from the help dialog
                  box, or if the user presses KKCCaanncceell, or if the
                  receiver determines that the drop cannot continue,
                  the receiver sets the number of transfers to zero
                  and the status to failed to cancel the drop.

                +o If the drop can continue normally, the receiver
                  starts a transfer.

             The drop protocol is a superset of the Xt incremental
             and non-incremental protocol, with two main
             differences:

                +o The receiver and initiator need only one
                  XXmmNNttrraannssffeerrPPrroocc and XXmmNNccoonnvveerrttPPrroocc (the Xt
                  Selection process requires separate procedures for
                  incremental and non-incremental transfer). They



        May 9, 1992                                            15-33








        OSF/Motif Programmer's Guide


                  each specify whether the transfer is incremental
                  or not from their side of the transfer with
                  DropTransfer and DragContext resources.  If the
                  initiator and receiver use the same incremental or
                  non-incremental protocol, the toolkit deals with
                  each in the requested protocol.

                +o The initiator and receiver are both notified of
                  the completion of the entire transfer, regardless
                  of how many sub-transfers were involved

             The drop protocol is handled by a DropTransfer widget
             created by XXmmDDrrooppTTrraannssffeerrSSttaarrtt in the receiver client.
             The receiver creates a list of information and target
             types desired from the initiator, along with a
             XXmmNNttrraannssffeerrPPrroocc to handle any processing needed during
             the transfer.  The toolkit processes the requests one
             at a time, until it has finished with the list.

             The receiver must call XXmmDDrrooppTTrraannssffeerrSSttaarrtt, even if the
             number of transfer requests is zero.  Otherwise, the
             initiator will keep waiting for a transfer request.

             For each transfer request, the initiator's
             XXmmNNccoonnvveerrttPPrroocc is called.  This procedure reads and
             processes the request and returns the information.



        15.4  DDrroopp RReecceeiivveerr RReessppoonnssiibbiilliittiieess ffoorr DDrraaggggiinngg



             The drop receiver responsibilities are covered first in
             this chapter, because in the dynamic protocol, motion
             messages go first to the receiver client.  The receiver
             evaluates the state of the drag and sends an updated
             message to the initiator, which then manages its drag
             over visuals based on the results.

             The drag receiver has some responsibilities before a
             drag even starts:

                +o It registers widgets as drop sites, providing
                  information about valid operations, target types
                  accepted, and drag under effects (animation
                  style).  The application can use the default
                  values for this information, or provide its own
                  values.





        15-34                                            May 9, 1992








                                                       Drag and Drop


                +o It registers a XXmmNNddrrooppPPrroocc that is called when a
                  drop occurs and which starts the transfer of
                  information from the initiator.  This XXmmNNddrrooppPPrroocc
                  also processes any Help information the
                  application provides about a drop site.

                +o It optionally registers a XXmmNNddrraaggPPrroocc for use with
                  the dynamic protocol that is called for events
                  while a drag is within the widget's boundaries.

             If the drag protocol in effect is preregister, the drop
             site information is put in the database as the drop
             sites are registered and the receiver client does
             nothing until a drop is made.  All visual effects are
             handled by the toolkit.

             If the drag protocol is dynamic, messaging begins when
             the pointer enters the window containing the drop site.
             The receiver is given the opportunity to provide
             additional processing in its XXmmNNddrraaggPPrroocc.  The
             XXmmNNddrraaggPPrroocc:

                +o Receives messages when the drag icon enters or
                  leaves the drop site, the operation changes, the
                  drag icon is in motion, or the drag is cancelled.

                +o Provides information back to the toolkit about the
                  state of the drag (valid drop site, invalid drop
                  site, no drop site) and the operation to be
                  performed when a drop is made.

                +o Manages any custom drag under visual effects.



        15.4.1  EEssttaabblliisshhiinngg aa DDrroopp SSiittee



             Text and TextField widgets register themselves as drop
             sites.  An application must register any other widgets
             it wants to use for drop sites.  A widget may be
             registered as only one drop site.

             XXmmDDrrooppSSiitteeRReeggiisstteerr registers a widget as a drop site,
             establishes callbacks to be used when a drag is made
             through the drop site or a drop is made in the drop
             site, and provides target and operation information.
             If the protocol is preregister, the information is
             stored in a database, which is read by the toolkit
             during the drag.  If the drag protocol is dynamic,



        May 9, 1992                                            15-35








        OSF/Motif Programmer's Guide


             messaging is used to check for possible drop sites
             within a widget.

             The application must register a XXmmNNddrrooppPPrroocc routine to
             establish a list of transfer requests and start the
             transfer.  The other resources can be left at their
             default values if those values are acceptable to the
             application.

             The optional XXmmNNddrraaggPPrroocc routine is executed only is
             the drag protocol is dynamic.  It is called in response
             to events during the drag, and allows the receiver to
             provide additional drag under effects or additional
             drag processing.

             The XXmmddrrooppSSiitteeOOppeerraattiioonnss resource lists all operations
             that the drop site will support, combined by the
             bitwise OR operations (|).  For instance the default
             value ...

             XmDROP_COPY | XmDROP_MOVE

             means that Copy and Move are valid operations, but Link
             is not.  During a drag, the toolkit on the receiver
             side compares this list with the DragContext's
             XXmmNNddrraaggOOppeerraattiioonnss list and the user-selected operation
             to arrive at the operation that will be performed if a
             drop occurs on this site, along with a list of all
             operations possible between the initiator and the
             current drop site.

             If an application wishes to use only one operation,
             such as Copy, then it should set the
             XXmmNNddrrooppSSiitteeOOppeerraattiioonnss field to just that operation to
             ensure the correct operation and drag icon are chosen
             by the toolkit during the drag and drop transaction.

             Drop sites that represent "copying devices", such as
             printers, or "transformation devices", such as
             compilers, should perform a Copy rather than a Move if
             both are possible.

             The XXmmNNddrrooppSSiitteeAAccttiivviittyy indicates if the drop site is
             available for use:

             XXmmDDRROOPP__SSIITTEE__AACCTTIIVVEE  The drop site is available for use.
                                 This is the default value.

             XXmmDDRROOPP__SSIITTEE__IINNAACCTTIIVVEE The drop site is not available for
                                 use.  If the drag icon is moved
                                 over the drop site, both the icon



        15-36                                            May 9, 1992








                                                       Drag and Drop


                                 and drop site act as if the icon
                                 were not over a drop site.

             The XXmmDDrrooppSSiitteeUUnnrreeggiisstteerr function removes a widget from
             the DropSite registry. Once a widget is unregistered,
             it displays no drag under visual effects and cannot
             accept a drop.

             The difference in an unregistered drop site and an
             inactive drop site, is that the inactive drop site is
             still registered, it still uses memory, but does not
             engage in any drag and drop transactions.  One use for
             inactive drop sites is to provide the correct clipping
             on overlapping drop sites. An unregistered drop site is
             no longer involved in the drag and drop system.  It is
             the same as a widget that was never registered.

             This code from the main routine in DDNNDDllaabbeell..cc in
             Appendix B generates a simple drop site on a Label
             widget.  The only target type it recognizes is compound
             text.  The only operation it will accept is Copy. The
             other resources, including drag under effects, are left
             at their default values.
                          FFiigguurree 1155--44..  A Label Widget










             Label = XmCreateLabel(BulletinB, "title", args, n);
             XtManageChild(Label);

             /* register the label as a drop site */
             importList[0] = COMPOUND_TEXT;
             n = 0;
             XtSetArg(args[n], XmNimportTargets, importList); n++;
             XtSetArg(args[n], XmNnumImportTargets, 1); n++;
             XtSetArg(args[n], XmNdropSiteOperations, XmDROP_COPY);
             XtSetArg(args[n], XmNdropProc, HandleDrop); n++;
             XmDropSiteRegister(Label, args, n);

             XtRealizeWidget(topLevel);
             XtAppMainLoop(app_context);






        May 9, 1992                                            15-37








        OSF/Motif Programmer's Guide


        15.4.1.1  CChhaannggiinngg aa DDrroopp SSiittee



             The XXmmDDrrooppSSiitteeUUppddaattee function is used to change drop
             site resources for a single drop site.  For multiple
             requests, XXmmDDrrooppSSiitteeSSttaarrttUUppddaattee signals that a series
             of XXmmDDrrooppSSiitteeUUppddaattee requests will follow, and
             XXmmDDrrooppSSiitteeEEnnddUUppddaattee ends the series and processes the
             requests at one time.

             XXmmDDrrooppSSiitteeUUppddaattee can also be used to change the
             resource values of the widgets that register themselves
             as drop sites (Text and TextField).  For instance, an
             application can change Text's XXmmNNddrrooppPPrroocc to call a
             procedure in the application.



        15.4.1.2  SSppeecciiaallllyy--SShhaappeedd DDrroopp SSiitteess



             The shape of a simple drop site can be specified as the
             union of a set of specified rectangles clipped by the
             associated widget.

             If only part of the widget is to be sensitive to a
             drop, it is defined by a list of rectangles in the
             XXmmNNddrrooppRReeccttaanngglleess resource.  If the resource is NULL,
             the drop site is the smallest enclosing widget and the
             shape of the drop site is the shape of the widget.

             The rectangles comprising the drop site need not be
             contiguous.  All the non-contiguous segments of the
             drop site act as one; they are all highlighted the same
             way at the same time.  A drop on one segment is the
             same as a drop on any of the other segments. This might
             look to the user as if there were several drop sites on
             a single widget, but the application handles nested
             drop sites differently from drop sites made of non-
             contiguous segments.  Nested drop sites, whether
             simulated or real, may have different drag under
             effects, targets, operations, or callback procedures.

             This example establishes a sensitive area shaped like a
             plus-sign on a DrawnButton widget named button 2.  Even
             if the drag icon is within the button 2 widget, no drag
             under effects are shown until the drag icon is within
             the sensitive area.  The area is visible only when a
             drag icon enters it and highlighting occurs.  The



        15-38                                            May 9, 1992








                                                       Drag and Drop


             sensitive area is the only part of the widget that
             accepts a drop.  This code is not in one of the three
             example programs included in Appendix B.
                     FFiigguurree 1155--55..  Special Shaped Drop Site



















             XRectangle plus[] = {
                 {30, 0, 30, 30},
                 {0, 30, 90, 30},
                 {30, 60, 30, 30},
                 };
                  .
                  .
                  .
             n = 0;
             XtSetArg(args[n], XmNimportTargets, importList); n++;
             XtSetArg(args[n], XmNnumImportTargets, 1); n++;
             XtSetArg(args[n], XmNdropProc, HandleDrop); n++;
             XtSetArg(args[n], XmNdropRectangles, plus); n++;
             XtSetArg(args[n], XmNnumDropRectangles, 3); n++;
             XmDropSiteRegister(Button2, args, n);



        15.4.1.3  NNeesstteedd DDrroopp SSiitteess



             A widget can be registered as only one drop site.
             However, widgets which are registered as drop sites can
             be nested within each other, providing nested drop
             sites.





        May 9, 1992                                            15-39








        OSF/Motif Programmer's Guide


             The XXmmNNddrrooppSSiitteeTTyyppee indicates the complexity of the
             drop site:

             XXmmDDRROOPP__SSIITTEE__SSIIMMPPLLEE    The drop site contains no other
                                   drop sites.

             XXmmDDRROOPP__SSIITTEE__CCOOMMPPOOSSIITTEE The drop site contains other drop
                                   sites.  This value is generally
                                   associated with a Manager.

             A composite drop site must be registered before any of
             its children are registered.  If a composite drop site
             is inactive, so are all of its children.

             The composite and children drop sites do not need to
             have the same operations or targets.

             A manager which contains a number of widgets with their
             associated drop sites need not be a composite drop site
             unless it is possible to drop in the background of the
             manager.

             It is possible for an application to simulate nested
             drop sites on a single widget, for example a
             DrawingArea.  The process is described as part of the
             discussion of the duties of the optional XXmmNNddrraaggPPrroocc
             routine later in this chapter.



        15.4.1.4  OOvveerrllaappppiinngg DDrroopp SSiitteess



             Drop sites may overlap.  Their stacking order is
             assumed to correspond to the order in which they are
             registered with the first-registered one on top. The
             stacking order is checked by calling
             XXmmDDrrooppSSiitteeQQuueerryySSttaacckkiinnggOOrrddeerr.  The stacking order is
             changed by calling XXmmDDrrooppSSiitteeCCoonnffiigguurreeSSttaacckkiinnggOOrrddeerr.

             When a drop site is overlapped by another drop site,
             the drag under effects of the drop site underneath are
             clipped as appropriate by the obscuring drop site.

             A widget or gadget which is not a drop site may overlap
             and partially obscure a drop site.  To ensure that the
             drop-site's drag under visuals are appropriately
             clipped by the obscuring widget, such sibling widgets
             should be registered as inactive drop sites. Parent
             widgets, whether drop sites or not, will clip their



        15-40                                            May 9, 1992








                                                       Drag and Drop


             children's drop site visuals. If a parent has some
             active and some inactive drop site children, it should
             be registered as an active drop site.



        15.4.1.5  DDrraagg UUnnddeerr VViissuuaall EEffffeeccttss



             Drag under visual effects are displayed only when the
             pointer is within the sensitive area of the drop site
             widget.  Various drag under styles can be chosen in the
             XXmmNNaanniimmaattiioonnSSttyyllee DropSite resource:

             XXmmDDRRAAGG__UUNNDDEERR__HHIIGGHHLLIIGGHHTT        A solid border around the
                                           sensitive are of the drop
                                           site is used to show the
                                           drop site is valid.  This
                                           is the default value.

             XXmmDDRRAAGG__UUNNDDEERR__SSHHAADDOOWW__OOUUTT       The sensitive area of the
                                           drop site looks pushed
                                           out when it is valid.

             XXmmDDRRAAGG__UUNNDDEERR__SSHHAADDOOWW__IINN        The sensitive are of the
                                           drop site look pushed in
                                           when it is valid.

             XXmmDDRRAAGG__UUNNDDEERR__PPIIXXMMAAPP           A custom pixmap is used
                                           to indicate the drop site
                                           is valid.  The pixmap is
                                           specified in
                                           XXmmNNaanniimmaattiioonnPPiixxmmaapp.

             XXmmDDRRAAGG__UUNNDDEERR__NNOONNEE             No indication is given
                                           that the drop site is
                                           valid.

             The following illustration shows the default drag under














        May 9, 1992                                            15-41








        OSF/Motif Programmer's Guide


             animation around the Label widget drop site.
                   FFiigguurree 1155--66..  Default Drag Under Animation













             If the value of XXmmNNaanniimmaattiioonnSSttyyllee is
             XXmmDDRRAAGG__UUNNDDEERR__PPIIXXMMAAPP, the XXmmNNaanniimmaattiioonnPPiixxmmaapp,
             XXmmNNaanniimmaattiioonnMMaasskk, and XXmmNNaanniimmaattiioonnPPiixxmmaappDDeepptthh resources
             are used to provide more information about the pixmap.
             If the depth does not match the depth of the window
             controlling the drop site widget, no animation occurs.
             Except for XXmmDDRRAAGG__UUNNDDEERR__PPIIXXMMAAPP, the colors used for the
             visual effects are based on the colors of the widget
             associated with the drop site.

             The dynamic protocol provides the most control over the
             drop site animation.  It is the only way to get visual
             effects that don't remain the same for the duration of
             the drag icon's stay in the drop site, for instance a
             background that flashes.



        15.4.2  XXmmNNddrraaggPPrroocc



             The procedure registered in the DropSite's XXmmNNddrraaggPPrroocc
             resource is called only when the dynamic protocol is in
             effect.  This procedure is optional.  Applications that
             need to provide special drag under effects or other
             special processing during a drag can do so with this
             procedure.

             The XXmmNNddrraaggPPrroocc is called in response to messages from
             the toolkit, before the initiator's equivalent drag
             callback. Fields in the callback structure provide
             information to the receiver about the drag.

             The _r_e_a_s_o_n field in the callback structure indicates
             why the procedure was called.



        15-42                                            May 9, 1992








                                                       Drag and Drop


             XXmmCCRR__DDRROOPP__SSIITTEE__EENNTTEERR__MMEESSSSAAGGEE       The drag icon hot
                                                spot has entered the
                                                drop site.

             XXmmCCRR__DDRROOPP__SSIITTEE__LLEEAAVVEE__MMEESSSSAAGGEE       The drag icon hot
                                                spot has left the
                                                drop site.

             XXmmCCRR__DDRRAAGG__MMOOTTIIOONN__MMEESSSSAAGGEE           The drag icon hot
                                                spot has moved.

             XXmmCCRR__OOPPEERRAATTIIOONN__CCHHAANNGGEEDD__MMEESSSSAAGGEE     The operation has
                                                changed.

             The _o_p_e_r_a_t_i_o_n_s field lists all the operations that are
             valid for drop site with the current drag source. The
             _o_p_e_r_a_t_i_o_n_s field is initialized by the toolkit as
             follows:

                +o If the user has selected an operation, the value
                  of _o_p_e_r_a_t_i_o_n_s is initialized to that operation if
                  it is in the DragContext's XXmmNNddrraaggOOppeerraattiioonnss list,
                  else

                +o The _o_p_e_r_a_t_i_o_n_s field is initialized to the list in
                  the DragContext's XXmmNNddrraaggOOppeerraattiioonnss list.

             The _o_p_e_r_a_t_i_o_n field indicates the type of action a
             successful drop will perform.  The _o_p_e_r_a_t_i_o_n field is
             initialized by the toolkit as follows:

                +o _o_p_e_r_a_t_i_o_n is initialized to XXmmDDRROOPP__MMOOVVEE if Move is
                  a valid operation (in both the _o_p_e_r_a_t_i_o_n_s field
                  and the DropSite's XXmmNNddrrooppSSiitteeOOppeerraattiioonnss list),
                  otherwise it is initialized to XXmmDDRROOPP__CCOOPPYY if Copy
                  is a valid operation, otherwise it is initialized
                  to XXmmDDRROOPP__LLIINNKK if Link is a valid operation,
                  otherwise it is initialized to XXmmDDRROOPP__NNOOOOPP.

             The _d_r_o_p_S_i_t_e_S_t_a_t_u_s field provides an indication of
             whether a transfer between the initiator and this drop
             site could occur.  The value that the toolkit selects
             for the _d_r_o_p_S_i_t_e_S_t_a_t_u_s field depends on the reason the
             XXmmNNddrraaggPPrroocc was entered.

                +o If the reason is motion or drop site leave, and
                  the drop site is the same as in the last call to
                  XXmmNNddrraaggPPrroocc, the _d_r_o_p_S_i_t_e_S_t_a_t_u_s is the same as at
                  the end of the previous call.





        May 9, 1992                                            15-43








        OSF/Motif Programmer's Guide


                +o Otherwise, if there is at least one target in
                  common and at least one operation in common, the
                  value is initialized to XXmmDDRROOPP__SSIITTEE__VVAALLIIDD.  If
                  not, the value is initialized to
                  XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

                +o If the _o_p_e_r_a_t_i_o_n field is XXmmDDRROOPP__NNOOOOPP, the
                  _d_r_o_p_S_i_t_e_S_t_a_t_u_s field is initialized to
                  XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

             The XXmmNNddrraaggPPrroocc can update _o_p_e_r_a_t_i_o_n, _o_p_e_r_a_t_i_o_n_s, or
             _d_r_o_p_S_i_t_e_S_t_a_t_u_s further during its execution. The final
             values for these fields are available to the initiator
             in its drag callback structures.  If the receiver's
             XXmmNNddrraaggPPrroocc is called more than once while the drag
             icon is within the drop site (for instance because of
             motion events), the values used by the toolkit when it
             initializes the drag callback _o_p_e_r_a_t_i_o_n_s, _o_p_e_r_a_t_i_o_n,
             and _d_r_o_p_S_i_t_e_S_t_a_t_u_s fields are ones at the end of the
             previous call to XXmmNNddrraaggPPrroocc.

             The _a_n_i_m_a_t_e field tells the toolkit who should provide
             the drag under visual effects.  It is initially set to
             True, but the XXmmNNddrraaggPPrroocc can set it to False.

             TRUE      The toolkit provides the drag under visuals
                       as if the protocol were preregister.

             FALSE     The receiver provides the drag under visuals.
                       The application can provide special visual
                       effects, such as a blinking background, that
                       are not possible with the toolkit.

             The DDrraaggPPrrooccCCaallllbbaacckk routine in the DDNNDDDDeemmoo..cc program
             in Appendix B is an example of a DDrraaggPPrroocc routine.  It
             can process every drag message, changes the _o_p_e_r_a_t_i_o_n_s,
             _o_p_e_r_a_t_i_o_n, and _d_r_o_p_S_i_t_e_S_t_a_t_u_s as necessary, and sets
             the _a_n_i_m_a_t_e field to TTRRUUEE, allowing the toolkit to
             manage the drag under effects.  The DDrraaggPPrrooccCCaallllbbaacckk
             routine is shown in the next section of this chapter.



        15.4.2.1  SSiimmuullaattiinngg NNeesstteedd DDrroopp SSiitteess



             A widget can be registered as only a single drop site.
             However, if the application needs one or more drop
             sites entirely enclosed within another drop site, there
             are two ways to accomplish this:



        15-44                                            May 9, 1992








                                                       Drag and Drop


                +o Widgets that contain other widgets that are drop
                  sites should be registered as composite drop sites
                  as described earlier in this chapter.

                  This method allows the toolkit to manage drop site
                  messages and drag under effects for each nested
                  drop site.

                +o An application can simulate a multiple drop sites
                  on a single widget in the XXmmNNddrraaggPPrroocc and
                  XXmmNNddrrooppPPrroocc routines.  Since the XXmmNNddrraaggPPrroocc
                  routine is executed only in the dynamic drag
                  protocol mode, this method would not work if the
                  drag procotol chosen is preregister.

                  This method requires that the application manage
                  all drag under effects, since the toolkit is not
                  aware of the simulated nesting.

             To simulate nested drop sites on a single widget:

               1.  Register the widget as a single active drop site.
                   Set XXmmNNddrrooppSSiitteeOOppeerraattiioonnss to all the operations
                   possible for any of the nested drop sites.  Set
                   XXmmNNiimmppoorrttTTaarrggeettss to all the targets possible for
                   any of the nested drop sites.  Register a
                   XXmmNNddrraaggPPrroocc to provide any special drag under
                   effects for the simulated drop sites.

                   The _o_p_e_r_a_t_i_o_n_s, _o_p_e_r_a_t_i_o_n, and _d_r_o_p_S_i_t_e_S_t_a_t_u_s
                   fields are initialized by the toolkit only when
                   this outer drop site is entered or left.  The
                   simulated drop sites must be managed by the
                   application.

               2.  When either XXmmNNddrraaggPPrroocc or XXmmNNddrrooppPPrroocc is called,
                   check the _x and _y fields in the callback
                   structure to determine which of the nested drop
                   sites contains the pointer.

               3.  If the pointer is within a simulated nested drop
                   site, update the callback fields as follows:

                      +o When the pointer enters the simulated nested
                        drop site, save the value of the _o_p_e_r_a_t_i_o_n_s
                        and _o_p_e_r_a_t_i_o_n fields.

                      +o Remove any operations from the _o_p_e_r_a_t_i_o_n_s
                        field which do not apply to the simulated
                        drop site.




        May 9, 1992                                            15-45








        OSF/Motif Programmer's Guide


                      +o Set _o_p_e_r_a_t_i_o_n to the valid operation
                        preferred by the simulated drop site, or to
                        XXmmDDRROOPP__NNOOOOPP if the _o_p_e_r_a_t_i_o_n_s list does not
                        contain the preferred operation.

                      +o The _d_r_o_p_S_i_t_e_S_t_a_t_u_s field must reflect the
                        status of the simulated drop site, so that
                        the initiator can manage drag over effects
                        correctly.

                        Set the _d_r_o_p_S_i_t_e_S_t_a_t_u_s to XXmmDDRROOPP__SSIITTEE__VVAALLIIDD
                        if the _o_p_e_r_a_t_i_o_n is allowed in the simulated
                        drop site and if there is at least one
                        target in common between the simulated drop
                        site and the initiator.  (Use the
                        XXmmTTaarrggeettssAArreeCCoommppaattiibbllee routine to check the
                        targets.)

                        Set the _d_r_o_p_S_i_t_e_S_t_a_t_u_s to
                        XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD if the _o_p_e_r_a_t_i_o_n is not
                        allowed in the simulated drop site, if there
                        are no targets in common, or if the
                        _o_p_e_r_a_t_i_o_n is XXmmDDRROOPP__NNOOOOPP.

                      +o Display appropriate drag under visual
                        effects.

                      +o When the pointer leaves the simulated drop
                        site, restore the original values of
                        _o_p_e_r_a_t_i_o_n_s and _o_p_e_r_a_t_i_o_n that apply to the
                        outer drop site.

               4.  If the pointer is not within a simulated drop
                   site, but drops are allowed in the outer drop
                   site, update the fields as described above.

               5.  If the pointer is not within a simulated drop
                   site, and drops are not allowed in the outer drop
                   site, set the _d_r_o_p_S_i_t_e_S_t_a_t_u_s field to
                   XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

             If the preregister protocol is in effect, the simulated
             drop sites cannot be managed during the move, since
             XXmmNNddrraaggPPrroocc is not performed; but they can be managed
             at the drop with XXmmNNddrrooppPPrroocc.

             In the following example, only the top level window,
             DDNNDDDDeemmoo, is registered as a drop site.  The user can
             create rectangles within the window that then act like
             drop sites themselves. The user can drag and drop
             colors from one of the six buttons in the lower part of



        15-46                                            May 9, 1992








                                                       Drag and Drop


             the window onto the rectangles to change the color of
             the rectangle.  However, these rectangles are not
             registered drop sites, they are simulated.

             The user can also drag these rectangles to new
             locations.

                       FFiigguurree 1155--77..  Simulated Drop Sites































             The RReeggiisstteerrDDrrooppSSiittee routine registers the DrawingArea
             widget as a drop site.  The list of operations and
             targets may not be valid for each simulated drop site,
             but are valid for other simulated drop sites.

             RegisterDropSite(w)
             Widget w;
             {

                 Display *display = XtDisplay(w);
                 Atom    targets[3];
                 Arg     args[5];



        May 9, 1992                                            15-47








        OSF/Motif Programmer's Guide


                 int     n = 0;

                 /* Only accept moves or copies */
                 XtSetArg(args[n], XmNdragOperations, XmDROP_COPY | XmDROP_MOVE);
                 n++;

                 /* set all possible targets for any of the nested drop sites */
                 targets[0] = XmInternAtom(display, "_MY_RECTANGLE", False);
                 targets[1] = XmInternAtom(display, "BACKGROUND", False);
                 targets[2] = XmInternAtom(display, "PIXMAP", False);
                 XtSetArg(args[n], XmNimportTargets, targets); n++;
                 XtSetArg(args[n], XmNnumImportTargets, 3); n++;

                 /* register a dragProc - necessary for simulating nested drop
                  * sites
                  */
                 XtSetArg(args[n], XmNdragProc, DragProcCallback); n++;

                 /* register a dropProc */
                 XtSetArg(args[n], XmNdropProc, DropProcCallback); n++;
                 XmDropSiteRegister(w, args, n);

             }

             The XXmmNNddrraaggPPrroocc routine, DDrraaggPPrrooccCCaallllbbaacckk, is called
             whenever a drag icon enters the registered drop site
             (the top level window). The RReeccttFFiinndd routine from
             DDNNDDDDrraaww..cc in Appendix B determines if the pointer is in
             a simulated drop site. The CChheecckkTTaarrggeettss routine
             determines if the object being dragged is one of the
             six colors (bbggFFoouunndd) or one of the created rectangles
             (rreeccttFFoouunndd).  (The value ppiixxFFoouunndd to represent a pixmap
             being dragged is coded in this routine, but not in the
             rest of the program.)

             The only drag under visual is displayed when a color is
             dragged to a rectangle.  The outline of the rectangle
             is highlighted.

             The entire DDrraaggPPrrooccCCaallllbbaacckk routine is too long to be
             listed in its entirety here.  The section dealing with
             the drop site enter message is used as an example.

             static void DragProcCallback(w, client, call)
             Widget w;
             XtPointer client;
             XtPointer call;
             {

                 XmDragProcCallbackStruct *cb = (XmDragProcCallbackStruct *) call;
                 Display                     *display = XtDisplay(w);



        15-48                                            May 9, 1992








                                                       Drag and Drop


                 Boolean                     rectFound, bgFound, pixFound;
                 static unsigned char        initial_operations;
                 static unsigned char        initial_operation;
                 RectPtr                     rect;

                 CheckTargets(cb->dragContext, display, &rectFound, &bgFound,
                      &pixFound);

                 switch(cb->reason) {

                     case XmCR_DROP_SITE_ENTER_MESSAGE:

                         /* save the value of the operations and operation
                          * fields */
                         initial_operations = cb->operations;
                         initial_operation = cb->operation;

                         rect = RectFind(cb->x, cb->y);

                         /* Remove any operations for the operations field
                          * which do not apply to the simulated drop site.
                          */
                         if (rect) {

                             if (bgFound || pixFound) {
                                 cb->operations = XmDROP_COPY;
                                 RectHighlight(w, rect);
                             }
                             else if (rectFound) {
                                 cb->operations = cb->operations &
                                                  (XmDROP_COPY | XmDROP_MOVE);
                                 RectUnhighlight(w);
                             }

                         }
                         else {
                             cb->operations = initial_operations &
                                              (XmDROP_COPY | XmDROP_MOVE);
                             RectUnhighlight(w);
                         }

                         /* Set operation to the valid operation preferred by the
                          * simulated drop site or to XmDROP_NOOP if the
                          * operations list does not contain the preferred
                          * operation.
                          */
                         if (rect) {

                             if (bgFound || pixFound) {

                                 if (cb->operations & XmDROP_COPY)



        May 9, 1992                                            15-49








        OSF/Motif Programmer's Guide


                                     cb->operation = XmDROP_COPY;
                                 else
                                     cb->operation = XmDROP_NOOP;

                             }
                             else if (rectFound) {

                                 if (cb->operations & XmDROP_MOVE)
                                     cb->operation = XmDROP_MOVE;
                                 else if (cb->operations & XmDROP_COPY)
                                     cb->operation = XmDROP_COPY;
                                 else
                                     cb->operation = XmDROP_NOOP;

                             }

                         }
                         else {

                             if (rectFound) {

                                 if (cb->operations & XmDROP_MOVE)
                                     cb->operation = XmDROP_MOVE;
                                 else if (cb->operations & XmDROP_COPY)
                                     cb->operation = XmDROP_COPY;
                                 else
                                     cb->operation = XmDROP_NOOP;

                             }
                             else
                                 cb->operation = initial_operation;

                         }

                         /*
                          * Set dropSiteStatus to XmDROP_SITE_INVALID if the
                          * operation field is XmDROP_NOOP, or if there are no
                          * common targets between the source and the nested
                          * drop site.  Otherwise, set dropSiteStatus to
                          * XmDROP_SITE_VALID.
                          */
                         if (cb->operation == XmDROP_NOOP ||
                             (rect && (!rectFound && !bgFound && !pixFound)) ||
                             (!rect && !rectFound))
                             cb->dropSiteStatus = XmINVALID_DROP_SITE;
                         else
                             cb->dropSiteStatus = XmVALID_DROP_SITE;

                         /*
                          * Display appropriate drag under visuals.  Only
                          * highlight the rectangle if we are changing



        15-50                                            May 9, 1992








                                                       Drag and Drop


                          * rectangle attributes.
                          */
                         if (rect && bgFound || pixFound &&
                             cb->dropSiteStatus == XmVALID_DROP_SITE)
                             RectHighlight(w, rect);
                         break;

                     case XmCR_DROP_SITE_LEAVE_MESSAGE:
                         .
                         .
                         .



        15.5  DDrraagg IInniittiiaattoorr RReessppoonnssiibbiilliittiieess ffoorr DDrraaggggiinngg


             The application within whose window the user initiated
             the drag is considered the drag initiator.

             The drag initiator:

                +o Recognizes the start of a drag (BBTTrraannssffeerr PPrreessss)
                  within a widget controlled by the application.

                +o Establishes a DragContext for the widget,
                  providing information about operations, targets,
                  and drag over visuals, using the XXmmDDrraaggSSttaarrtt
                  function.

                +o Optionally provides special drag over effects.

             These steps are covered in the following sections.



        15.5.1  RReeccooggnniizziinngg aa DDrraagg HHaass SSttaarrtteedd



             The initiator client must be able to recognize the
             BBTTrraannssffeerr PPrreessss event within a widget it allows to be a
             drag source.  It may have to override an already-
             assigned translation for the widget.

             This example from the main routine ofDDNNDDssccrroollll..cc in
             Appendix B overrides the existing mouse button 2
             translation for the ScrollBar widget, and maps it to
             the StartDrag routine which will start the drag
             transaction.




        May 9, 1992                                            15-51








        OSF/Motif Programmer's Guide


             static char dragTranslations[] =
                  "#override <Btn2Down>: StartDrag()";
             static XtActionsRec dragActions[] =
                  { {"StartDrag", (XtActionProc)StartDrag}, };
                  .
                  .
             XtTranslations parsed_xlations;
                  .
                  .
             /* override button two press to start a drag */
             parsed_xlations = XtParseTranslationTable(dragTranslations);
             XtAppAddActions(app_context, dragActions, XtNumber(dragActions));

             /* create a scroll bar widget */
             n = 0;
             XtSetArg(args[n], XmNtranslations, parsed_xlations); n++;
             scrollbar = XmCreateScrollBar(BulletinB, "testscroll", args, n);
             XtManageChild(scrollbar);

             Translation may be more complicated in some editable
             widgets, in which BBTTrraannssffeerr CClliicckk is used for primary
             transfer, and BBTTrraannssffeerr MMoottiioonn is used for drag and
             drop.



        15.5.2  SSttaarrttiinngg aa DDrraagg WWiitthh XXmmDDrraaggSSttaarrtt



             Not every widget in an application can be a drag
             source.  Text, Label, Button, and List widgets are
             automatically defined as drag sources.  Other widgets
             must have a translation for BBTTrraannssffeerr assigned to them,
             establish DragContext resources for the widget, and
             call the XXmmDDrraaggSSttaarrtt routine to become drag sources.
             If the user tries to drag objects from a widget that
             isn't recognized as a drag source by either the toolkit
             or the source application, nothing happens.

             The XXmmDDrraaggSSttaarrtt function initiates a drag and creates a
             DragContext widget. At a minimum, the XXmmNNccoonnvveerrttPPrroocc
             DragContext resource, must be specified.  Other
             resources are optional, for instance those specifying
             drag-over visual effects.

             The XXmmNNddrraaggOOppeerraattiioonnss resource lists all the operations
             that the initiator will support for this drag source,
             combined by the bitwise OR operation (|).  During a
             drag, the toolkit compares this list with the
             receiver's XXmmNNddrrooppSSiitteeOOppeerraattiioonnss list and the user-



        15-52                                            May 9, 1992








                                                       Drag and Drop


             selected operation to arrive at the operation that will
             be performed if a drop occurs on this site.

             If an application wishes to use only one operation, it
             should set the XXmmNNddrraaggOOppeerraattiioonnss resource to just that
             operation to ensure that the correct operation and drag
             icon are chosen by the toolkit during the drag and drop
             transaction.

             This example from DDNNDDssccrroollll..cc in Appendix B establishes
             a target type of compound text and an operation of
             Copy, then establishes a DragContext for this
             transaction with XXmmDDrraaggSSttaarrtt.  This drag source does
             not have any custom drag icons or any drag callbacks.

             static void StartDrag(w, event)
             Widget  w;
             XEvent  *event;
             {
                Arg             args[MAX_ARGS];
                Cardinal        n;
                Atom            exportList[1];

                /* establish the list of valid target types */
                exportList[0] = COMPOUND_TEXT;

                n = 0;
                XtSetArg(args[n], XmNexportTargets, exportList); n++;
                XtSetArg(args[n], XmNnumExportTargets, 1); n++;
                XtSetArg(args[n], XmNdragOperations, XmDROP_COPY);
                XtSetArg(args[n], XmNconvertProc, DragConvertProc); n++;
                XmDragStart(w, event, args, n);
             }

             If drag or drop callbacks are desired, they are added
             to the DragContext's callback resources.  For example,
             a callback procedure named EnterCallBack that is
             performed when the pointer enters an active drop site
             could be added as follows:

             Widget         dc;
                .
                .
                .
                dc = XmDragStart(w, event, args, n);
                XtAddCallback(dc, XmNdropSiteEnterCallback, EnterCallBack, NULL);








        May 9, 1992                                            15-53








        OSF/Motif Programmer's Guide


        15.5.3  OOvveerrrriiddiinngg EExxiissttiinngg DDrraagg SSoouurrcceess



             XXttGGeettVVaalluueess is used to check the values of widgets
             resources established as drag sources earlier in the
             application, and XXttSSeettVVaalluueess is used to update these
             values.  The widget ID used is the DragContext, not the
             source widget ID, so that the change applies only to
             the widget during the drag.

             If the widget is a pre-defined drag source (Text,
             Label, Button, or List), overriding the default
             behavior becomes more complex.  The widget calls
             XXmmDDrraaggSSttaarrtt when the drag starts, and the application
             cannot call XXmmDDrraaggSSttaarrtt again for the widget. It must
             update the existing DragContext.  First it must find
             the DragContext for the widget, then establish the new
             behavior.  One possible means to accomplish this is as
             follows:

                +o Override the existing Btn2Down translation with a
                  new translation that calls the widget's action and
                  also an action supplied by the application.  For
                  the Text widget, this new translation might look
                  as follows:

                  <Btn2Down> : process-bdrag() my-drag-start()

                +o Register the new action, using XXttAAppppAAddddAAccttiioonnss.

                +o In the new action procedure, call XXmmGGeettDDrraaggCCoonntteexxtt
                  to get the DragContext, and then call XXttSSeettVVaalluueess
                  to change resource values.  The timestamp argument
                  to XXmmGGeettDDrraaggCCoonntteexxtt can be the timestamp from the
                  event passed to the action routine.

             For instance, Text allows the Copy and Move operations.
             If an application can support only Copy, it must update
             the DragContext's XXmmNNddrraaggOOppeerraattiioonnss resource.



        15.5.4  DDrraagg--oovveerr VViissuuaall EEffffeeccttss



             When the user moves the mouse, a drag icon representing
             the object being dragged moves around the screen
             instead of the usual pointer.  As the icon is dragged
             over portions of the screen, the icon may change to



        15-54                                            May 9, 1992








                                                       Drag and Drop


             show the status of a possible drop.  These drag-over
             visual effects help the user know how to proceed with
             the drag.

             There are four ways to provide drag-over visual
             effects:

                +o Use the default drag-over visuals, specified in
                  the Screen object.  The toolkit manages all the
                  drag over effects.

                +o Put custom icons and pixmaps in the Screen's
                  visual resources to be used as default icons for
                  all drag and drop transactions running on that
                  Screen. The toolkit manages all the drag over
                  effects using these new icons.  These resources
                  can be modified by the application or user in a
                  resource file.

                +o Put custom icons and pixmaps in the DragContext
                  visual resources for source, state, or operation
                  icons.  The application must monitor the state of
                  the drag using the drag callbacks and update the
                  DragContext icon values as necessary. The default
                  icons specified in the Screen object are used only
                  if the value for the equivalent DragContext visual
                  resource is NULL.

                +o Manage the drag-over effects entirely in the
                  application by drawing directly to the screen.
                  The toolkit is not used, nor are the Screen and
                  DragContext visual resources.

             If the application provides custom icons and they are
             unsuitable for some reason, the toolkit defaults to the
             Screen drag over visuals.

             The drag icon consists of a source icon, combined
             optionally with a state icon and an operation icon.

             Each drag icon has a hot spot.  Since a drag icon could
             be quite large, the hot spot provides a single pixel
             that is used in providing drag over and drag under
             effects.  For instance, if the drag icon moves into the
             area of a valid drop site, neither the drag icon or the
             drop site will provide visual clues until the hot spot
             has moved into the area.  By default, the hot spot is
             the upper left corner of the state icon.

             In the following illustration, the running figure is
             the source icon, the state icon is the arrow in the



        May 9, 1992                                            15-55








        OSF/Motif Programmer's Guide


             corner, and the operation icon shows a Copy will happen
             if a drop is made.  The default blending and attachment
             values are used (these terms are described in a later
             section).
                           FFiigguurree 1155--88..  A Drag Icon










        15.5.4.1  SSoouurrccee IIccoonn



             The source icon is a picture representing the object
             being dragged.  It can be either a pixmap or cursor.
             The client can specify a custom pixmap in the
             DragContext resource XXmmNNssoouurrcceePPiixxmmaappIIccoonn or a custom
             cursor in the XXmmNNssoouurrcceeCCuurrssoorrIIccoonn resource.  If these
             resources are NULL or not usable (too large, not a
             bitmap, or created on a different screen, for example),
             the default cursor is given in the Screen resource
             XXmmNNddeeffaauullttSSoouurrcceeCCuurrssoorrIIccoonn is used.

             The pixmap icon is used with the preregister visual
             style.  The colormap is based on the source widget.
             The cursor icon is used for the dynamic visual style.

             The following illustration shows the default source
             icons for general purpose, List, Label, and Text
             widgets.
                           FFiigguurree 1155--99..  Source Icons

















        15-56                                            May 9, 1992








                                                       Drag and Drop


        15.5.4.2  SSttaattee IIccoonn



             The state icon is a cursor that indicates if the drag
             is over a valid drop site, invalid drop site, or no
             drop site.  The default state icons are in the Screen
             resources XXmmNNddeeffaauullttVVaalliiddCCuurrssoorrIIccoonn,
             XXmmNNddeeffaauullttIInnvvaalliiddCCuurrssoorrIIccoonn, and
             XXmmNNddeeffaauullttNNoonneeCCuurrssoorrIIccoonn.

             A custom state icon can be specified in the DragContext
             resource XXmmNNssttaatteeCCuurrssoorrIIccoonn.  If this resource is NULL,
             not a bitmap, or not defined on the same screen as
             XXmmSSccrreeeenn, the default Screen icons are used.  If one is
             specified here, it must be changed  appropriately as
             the state of the drag changes, using the drag callbacks
             discussed later in this section.

             The default state icon for all three states is an
             arrow, usually shown at the upper left corner of the
             operation icon.

             Three DragContext resources can be used to change the
             color of the drag icon based on the state of the drag:
             XXmmNNvvaalliiddCCuurrssoorrFFoorreeggrroouunndd, XXmmNNiinnvvaalliiddCCuurrssoorrFFoorreeggrroouunndd,
             XXmmNNnnoonneeCCuurrssoorrFFoorreeggrroouunndd.  This allows visual feedback
             about the drag to the user, without changing the icon
             shape.  For example, the following lines in a resource
             file would make the drag icon green when it was over a
             valid drop site, red when it was over an invalid drop
             site, and yellow when it was not over any drop site:

             *.validCursorIcon:          green
             *.invalidCursorIcon:        red
             *.noneCursorIcon:           yellow



        15.5.4.3  OOppeerraattiioonn IIccoonn



             The operation icon is a cursor that indicates what
             operation is to happen when the drop is made.  The
             default operation icons are in the Screen resources
             XXmmNNddeeffaauullttMMoovveeCCuurrssoorrIIccoonn, XXmmNNddeeffaauullttCCooppyyCCuurrssoorrIIccoonn, and
             XXmmNNddeeffaauullttLLiinnkkCCuurrssoorrIIccoonn.

             A custom operation icon can be specified in the
             DragContext resource XXmmNNooppeerraattiioonnCCuurrssoorrIIccoonn.  If this



        May 9, 1992                                            15-57








        OSF/Motif Programmer's Guide


             resource is NULL, not a bitmap, or not defined on the
             same screen as Screen, the default Screen icons are
             used.  If a custom icon is specified, it should be
             changed as the operation changes, using the drag
             callbacks covered later in this chapter.

             The following illustration shows the default Copy,
             Link, and Move operation icons.

                         FFiigguurree 1155--1100..  Operation Icons










             If the operation in effect is XXmmDDRROOPP__NNOOOOPP, meaning that
             no operation is possible, then the operation icon is
             left blank, as shown in the following illustration.
             This condition also sets the _d_r_o_p_S_i_t_e_S_t_a_t_u_s to
             XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

                    FFiigguurree 1155--1111..  Copy and Noop Drag Icons









        15.5.4.4  DDrraagg IIccoonn BBlleennddiinngg aanndd AAttttaacchhmmeenntt



             The client can specify which of the three icons to mix
             together to form the drag icon with the XXmmNNbblleennddMMooddeell
             DragContext resource:

             XXmmBBLLEENNDD__AALLLL              Use the source icon, state
                                      icon, and operation icon. The
                                      hot spot comes from the state
                                      icon.  This is the default
                                      value.  The order listed is
                                      also the order of the blend.




        15-58                                            May 9, 1992








                                                       Drag and Drop


             XXmmBBLLEENNDD__SSTTAATTEE__SSOOUURRCCEE     Use only the source icon and
                                      state icon.  The hot spot
                                      comes from the state icon.

             XXmmBBLLEENNDD__JJUUSSTT__SSOOUURRCCEE      Use only the source icon.  The
                                      hot spot comes from the source
                                      icon.

             XXmmBBLLEENNDD__NNOONNEE             Don't display any drag icon.
                                      The client handles all drag-
                                      over effects.

             The XXmmNNaattttaacchhmmeenntt DragIcon resource specifies where the
             state and operation icons will be placed on the source
             icon.  The default placement is both the state and
             operation icons at the attachment point of the source
             icon, with the operation icon on top.  The default
             value is XXmmAATTTTAACCHH__NNOORRTTHH__WWEESSTT.

             XXmmNNooffffsseettXX and XXmmNNooffffsseettYY are used to place the icon
             relative to the attachment point.

             If the attachment point is XXmmAATTTTAACCHH__HHOOTT, the state and
             operation icons are attached to the source icon at a
             point the same x and y distance from the upper left
             corner of the source icon as the pointer is from the
             upper left corner of the widget containing the source.
             This attachment style is particularly useful when the
             application makes a custom source icon that exactly
             reflects the source widget at the time the drag starts.

             In the following illustration, the custom source icon
             is an outline of the scrollbar. When the drag was
             started, the pointer was on the slider.  The operation
             and state icons are placed at the same location on the
             source icon.

                       FFiigguurree 1155--1122..  An Attach_Hot Icon
















        May 9, 1992                                            15-59








        OSF/Motif Programmer's Guide


             When the state or operation icon is blended with a
             source icon, a specified point of the icon's XXmmNNppiixxmmaapp
             is aligned with the upper left corner of the source
             icon. The resulting XXmmNNppiixxmmaapp is large enough to
             include both, and the resulting XXmmNNmmaasskk has 1 bits
             wherever either the source icon or source mask did.

             If a dynamic cursor style is being used, and the
             resulting blended cursor is too large for the screen,
             the blending is done with the Screen
             XXmmNNddeeffaauullttSSoouurrcceeCCuurrssoorrIIccoonn instead of the DragContext's
             XXmmNNssoouurrcceeCCuurrssoorrIIccoonn.  If it is still too large, it is
             clipped relative to the hot spot (that is, if the hot
             spot is at an edge, the other edge is clipped; if the
             hot spot is in the center, opposite edges are clipped
             equally).



        15.5.4.5  VViissuuaall SSttyyllee NNootteess



             If XXmmNNssoouurrcceePPiixxmmaappIIccoonn is used, the colormap used for
             rendering is that of the DragContext's reference
             widget.

             If the DragContext XXmmNNbblleennddMMooddeell is XXmmBBLLEENNDD__NNOONNEE, and
             the dynamic cursor style is in use, the application
             must use XXCChhaannggeeAAccttiivveePPooiinntteerrGGrraabb to change the cursor.
             If XXmmBBLLEENNDD__NNOONNEE is specified, and the preregister
             cursor style is in use, the application can render the
             cursor directly onto the screen, saving and restoring
             the image underneath.

             The cursor style can change as the pointer moves from
             window to window.  An application can tell which style
             is in use by looking at the _d_r_a_g_P_r_o_t_o_c_o_l_S_t_y_l_e field in
             the XXmmNNttooppLLeevveellEEnntteerrCCaallllbbaacckk structure, or looking at
             XXmmNNddrraaggIInniittiiaattoorrPPrroottooccoollSSttyyllee Display resource in the
             case of XXmmDDRRAAGG__NNOONNEE or XXmmDDRRAAGG__DDRROOPP__OONNLLYY.

             The resolution and best cursor size can vary from
             screen to screen.  This is why the default cursor icons
             are Screen resources.  An application that wants its
             source cursor or pixmap to be screen dependent can look
             for changes in the _s_c_r_e_e_n field in the
             XXmmNNttooppLLeevveellEEnntteerrCCaallllbbaacckk struct, and update the various
             icon DragContext resources appropriately.





        15-60                                            May 9, 1992








                                                       Drag and Drop


        15.5.4.6  CCrreeaattiinngg aa DDrraagg IIccoonn



             Any of the three parts of a drag icon can be
             customized: the source icon, the state icon, and the
             operation icon.

             Use the XXmmCCrreeaatteeDDrraaggIIccoonn function to create any of
             these parts.  The XXmmNNaattttaacchhmmeenntt resource is not used
             for the source icon.  The other resources specify
             pixmap, size, and hot spot details.  The DragContext
             XXmmNNbblleennddMMooddeell resource indicates which hot spot is used
             for the entire drag icon.

             This example from DDNNDDDDeemmoo..cc in Appendix B creates a
             source icon from a bitmap.  The source icon is the
             palette and the state icon is the paintbrush.
             (Actually, the state icon is not shown when the drag
             starts, because the blend style is XXmmBBLLEENNDD__JJUUSSTT__SSOOUURRCCEE.
             It is shown here as if the blend style were
             XXmmBBLLEENNDD__AALLLL.)

                       FFiigguurree 1155--1133..  Custom Source Icon













             The CCoolloorrRReecctt function is called when a drag starts
             from one of the color rectangles in the lower portion
             of the window.  Among its other duties, it establishes
             the drag icon from source bits from the DDNNDDDDrraaww..cc file
             in Appendix B.

                 /* If the server will handle a large icon, create one */
                 if (appInfo->maxCursorWidth >= ICON_WIDTH &&
                     appInfo->maxCursorHeight >= ICON_HEIGHT) {

                     source_bits = SOURCE_ICON_BITS;
                     source_mask = SOURCE_ICON_MASK;
                     state_bits = STATE_ICON_BITS;
                     state_mask = STATE_ICON_MASK;



        May 9, 1992                                            15-61








        OSF/Motif Programmer's Guide


                     width = ICON_WIDTH;
                     height = ICON_HEIGHT;

                 }
                 else {

                     /* If the server will handle a small icon, create one */
                     source_bits = SMALL_SOURCE_ICON_BITS;
                     source_mask = SMALL_SOURCE_ICON_MASK;
                     state_bits = SMALL_STATE_ICON_BITS;
                     state_mask = SMALL_STATE_ICON_MASK;
                     width = SMALL_ICON_WIDTH;
                     height = SMALL_ICON_HEIGHT;

                 }

                 /* Create the drag cursor icons */
                 sourceIcon = GetDragIconFromBits(w, source_bits, source_mask,
                                     width, height, background, foreground);

                 stateIcon = GetDragIconFromBits(w, state_bits, state_mask,
                                     width, height, background, foreground);

                 /* Setup the arglist for the drag context that is created at
                  * drag start */
                 n = 0;
                 .
                 .
                 .
                 XtSetArg(args[n], XmNsourceCursorIcon, sourceIcon); n++;
                 XtSetArg(args[n], XmNstateCursorIcon, stateIcon); n++;
                 .
                 .
                 .

                 /* start the drag.  This creates a drag context. */
                 myDC = XmDragStart(w, event, args, n);

             }

             The GGeettDDrraaggIIccoonnFFrroommBBiittss function turns the bits into a
             bitmap.

             static Widget GetDragIconFromBits(w, bits, mask, width, height,
                                               background, foreground)
             Widget w;
             char *bits;
             char *mask;
             Dimension width;
             Dimension height;
             Pixel background;



        15-62                                            May 9, 1992








                                                       Drag and Drop


             Pixel foreground;
             {

                 Pixmap     icon, iconMask;
                 Display    *display = XtDisplay(w);

                 icon = XCreateBitmapFromData(display, DefaultRootWindow(display),
                                 bits, width, height);

                 iconMask = XCreateBitmapFromData(display,
                                                  DefaultRootWindow(display),
                                                  mask, width, height);

                 return(GetDragIcon(w, icon, iconMask, width, height,
                                    background, foreground));

             }

             The GGeettDDrraaggIIccoonn function uses the bitmap created by the
             GGeettDDrraaggIIccoonnFFrroommBBiittss function to create a drag icon.

             static Widget GetDragIcon(w, icon, iconMask, width, height,
                                       background, foreground)
             Widget w;
             Pixmap icon;
             Pixmap iconMask;
             Dimension width;
             Dimension height;
             Pixel background;
             Pixel foreground;
             {

                 Widget  dragIcon;
                 Arg     args[10];
                 int     n = 0;

                 XtSetArg(args[n], XmNhotX, ICON_X_HOT); n++;
                 XtSetArg(args[n], XmNhotY, ICON_Y_HOT); n++;
                 XtSetArg(args[n], XmNwidth, width); n++;
                 XtSetArg(args[n], XmNheight, height); n++;
                 XtSetArg(args[n], XmNmaxWidth, appInfo->maxCursorWidth); n++;
                 XtSetArg(args[n], XmNmaxHeight, appInfo->maxCursorHeight); n++;
                 XtSetArg(args[n], XmNbackground, background); n++;
                 XtSetArg(args[n], XmNforeground, foreground); n++;
                 XtSetArg(args[n], XmNpixmap, icon); n++;
                 XtSetArg(args[n], XmNmask, iconMask); n++;
                 dragIcon = XmCreateDragIcon(w, "dragIcon", args, n);

                 return(dragIcon);

             }



        May 9, 1992                                            15-63








        OSF/Motif Programmer's Guide


        15.5.5  DDrraagg CCaallllbbaacckkss



             Callbacks notify the initiator of how the drag is
             proceeding.  The receiver's XXmmNNddrraaggPPrroocc (if any) is
             first notified of the action and given a chance to
             update the _o_p_e_r_a_t_i_o_n, _o_p_e_r_a_t_i_o_n_s, and _d_r_o_p_S_i_t_e_S_t_a_t_u_s
             fields in its callback structure.  The new values are
             available to the initiator's drag callback in the
             appropriate callback structure.

             These drag callbacks are all optional.  They provide
             the means by which the initiator can monitor the
             progress of the drag and manage its visual effects
             accordingly.  Otherwise the toolkit on the initiator
             side handles the drag over effects.

             XXmmNNddrraaggMMoottiioonnCCaallllbbaacckk    Called when the drag icon is
                                      in motion.

             XXmmNNooppeerraattiioonnCChhaannggeeddCCaallllbbaacckk Called when the user
                                      requests a different operation
                                      be performed on the drop than
                                      was previously in effect.

             XXmmNNddrrooppSSiitteeEEnntteerrCCaallllbbaacckk Called when the drag icon
                                      enters a drop site.

             XXmmNNddrrooppSSiitteeLLeeaavveeCCaallllbbaacckk Called when the drag icon
                                      leaves a drop site.

             XXmmNNttooppLLeevveellEEnntteerrCCaallllbbaacckk Called when the drag icon
                                      enters a top-level window or
                                      root window (when changing
                                      screens).

             XXmmNNttooppLLeevveellLLeeaavveeCCaallllbbaacckk Called when the drag icon
                                      leaves a top-level window or
                                      root window (when changing
                                      screens).
             Callback structures for these routines contain
             information about the drag.  The structures for
             XXmmNNddrraaggMMoottiioonnCCaallllbbaacckk, XXmmNNooppeerraattiioonnCChhaannggeeddCCaallllbbaacckk, and
             XXmmNNddrrooppSSiitteeEEnntteerrCCaallllbbaacckk contain the _o_p_e_r_a_t_i_o_n_s,
             _o_p_e_r_a_t_i_o_n, and _d_r_o_p_S_i_t_e_S_t_a_t_u_s fields (among others),
             which are initialized by the toolkit before the
             callback is called.

             The _o_p_e_r_a_t_i_o_n_s field lists all operations possible for
             a drop on the current site, whether the site is



        15-64                                            May 9, 1992








                                                       Drag and Drop


             registered as a DropSite or not.  The field is
             initialized as follows:

                +o If the receiver's XXmmNNddrraaggPPrroocc was called, the
                  value of _o_p_e_r_a_t_i_o_n_s is the list of operations
                  common to the value of the XXmmNNddrraaggPPrroocc's
                  _o_p_e_r_a_t_i_o_n_s field at the end of XXmmNNddrraaggPPrroocc and the
                  DropSite's XXmmNNddrrooppSSiitteeOOppeerraattiioonnss list.

                +o Otherwise, if the user selected an operation, then
                  _o_p_e_r_a_t_i_o_n_s is set to that operation if it is in
                  the XXmmNNddrraaggOOppeerraattiioonnss list.  If it isn't in the
                  list, _o_p_e_r_a_t_i_o_n_s is set to XXmmDDRROOPP__NNOOOOPP.

                +o Otherwise, _o_p_e_r_a_t_i_o_n_s is initialized to the list
                  in the DragContext's XXmmNNddrraaggOOppeerraattiioonnss resource.

             The _o_p_e_r_a_t_i_o_n field shows the operation that will occur
             if a drop happens at the current cursor location.  It
             is initialized as follows:

                +o If the receiver's XXmmNNddrraaggPPrroocc was called,
                  _o_p_e_r_a_t_i_o_n is initialized to the value of _o_p_e_r_a_t_i_o_n
                  at the end of the XXmmNNddrraaggPPrroocc.

                +o Otherwise, if the pointer is in or entering an
                  active drop site, _o_p_e_r_a_t_i_o_n is set to XXmmDDRROOPP__MMOOVVEE
                  if Move is in both _o_p_e_r_a_t_i_o_n_s and the DropSite's
                  XXmmNNddrrooppSSiitteeOOppeerraattiioonnss lists; otherwise to
                  XXmmDDRROOPP__CCOOPPYY if Copy is in both lists; otherwise to
                  XXmmDDRROOPP__LLIINNKK if Link is in both lists; otherwise to
                  XXmmDDRROOPP__NNOOOOPP.

                +o Otherwise, _o_p_e_r_a_t_i_o_n is set to XXmmDDRROOPP__MMOOVVEE if Move
                  is a valid operation (in the _o_p_e_r_a_t_i_o_n_s field) ;
                  otherwise to XXmmDDRROOPP__CCOOPPYY if Copy is a valid
                  operation; otherwise to XXmmDDRROOPP__LLIINNKK if Link is a
                  valid operation; otherwise to XXmmDDRROOPP__NNOOOOPP.

             The _d_r_o_p_S_i_t_e_S_t_a_t_u_s field in the callback structure
             indicates if the drag icon is over a valid drop site,
             an invalid drop site, or no drop site.  The callback
             procedure can use this information to display the
             appropriate drag over visuals.  The _d_r_o_p_S_i_t_e_S_t_a_t_u_s
             field is initialized by the toolkit in the following
             manner:

                +o If the pointer is over an active drop site:

                     - If the receiver's XXmmNNddrraaggPPrroocc was called,
                       _d_r_o_p_S_i_t_e_S_t_a_t_u_s is initialized to the value of



        May 9, 1992                                            15-65








        OSF/Motif Programmer's Guide


                       _d_r_o_p_S_i_t_e_S_t_a_t_u_s at the end of the XXmmNNddrraaggPPrroocc
                       procedure.

                     - Otherwise, _d_r_o_p_S_i_t_e_S_t_a_t_u_s is initialized to
                       XXmmDDRROOPP__SSIITTEE__VVAALLIIDD if there is at least one
                       target and one operation in common between
                       the initiator and receiver.  Otherwise, it is
                       initialized to XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

                +o If the pointer is not over an active drop site,
                  _d_r_o_p_S_i_t_e_S_t_a_t_u_s is initialized to XXmmNNOO__DDRROOPP__SSIITTEE.

                +o If the _o_p_e_r_a_t_i_o_n field is XXmmDDRROOPP__NNOOOOPP,
                  _d_r_o_p_S_i_t_e_S_t_a_t_u_s is initialized to
                  XXmmDDRROOPP__SSIITTEE__IINNVVAALLIIDD.

             If the application has not stored the DragContext ID in
             a global location, these callbacks can find the
             DragContext ID by passing the XXmmGGeettDDrraaggCCoonntteexxtt function
             the _t_i_m_e_S_t_a_m_p field from the callback structure.

             This example shows a callback that is called when a new
             drop site is entered.  It checks the validity of the
             drop site, and uses one of three custom source icons,
             depending on the status.

             static void EnterCB(w, client_data, call_data)
             Widget          w;
             XtPointer       client_data, call_data;
             {

                XmDragContext                   dc;
                XmDropSiteEnterCallback         EnterData;
                Cardinal                        n;
                Arg                             args[MAX_ARGS];

                dc = (XmDragContext)w;
                EnterData = (XmDropSiteEnterCallback )call_data;

                n = 0;

                if (EnterData->dropSiteStatus == XmVALID_DROP_SITE) {
                   XtSetArg(args[n], XmNsourceCursorIcon, GetValidIcon(w));
                   n++;
                   XtSetValues(dc, args, n);
                   }
                if (EnterData->dropSiteStatus == XmINVALID_DROP_SITE) {
                   XtSetArg(args[n], XmNsourceCursorIcon, GetInvalidIcon(w));
                   n++;
                   XtSetValues(dc, args, n);
                   }



        15-66                                            May 9, 1992








                                                       Drag and Drop


                if (EnterData->dropSiteStatus == XmNO_DROP_SITE) {
                   XtSetArg(args[n], XmNsourceCursorIcon, GetNeutralIcon(w));
                   n++;
                   XtSetValues(dc, args, n);
                   }
             }

             If a drag callback is desired, it is added to the
             DragContext's callback resources.  For instance, the
             following example adds a callback named EEnntteerrCCBB that is
             performed when the pointer enters an active drop site:

             Widget       dc;

                dc = XmDragStart(w, event, args, n);
                XtAddCallback(dc, XmNdropSiteEnterCallback, EnterCB, NULL);



        15.5.6  GGeettttiinngg DDaattaa aabboouutt tthhee CCuurrrreenntt DDrroopp SSiittee



             The initiator can find information about the current
             drop site with the XXmmDDrrooppSSiitteeRReettrriieevvee function.  It
             must pass in the DragContext, so that the toolkit knows
             what drop site the request is for.  The initiator can
             find the value of any drop site resource except the
             callback routines

             The following example gets the number and list of
             import targets for a drop site.  The example shows a
             drop site enter callback, but it could be in any of the
             initiator's drag callbacks.

             XmDropSiteEnterCallback      DragData;
                  .
                  .
                  .
             n = 0;
             XtSetArg(args[n], XmNimportTargets, &importTargets); n++;
             XtSetArg(args[n], XmNnumImportTargets, &numImportTargets); n++;
             XmDropSiteRetrieve(DragData->DragContext, args, n);











        May 9, 1992                                            15-67








        OSF/Motif Programmer's Guide


        15.5.7  CCaanncceelllliinngg tthhee DDrraagg



             The drag in progress can be cancelled in either of two
             ways.  Both ways are treated the same by the toolkit.

                +o The user can press KKCCaanncceell.

                +o The initiator can call the XXmmDDrraaggCCaanncceell function
                  if it decides the drag should not continue for
                  some reason

             The initiator is notified of the cancel by the
             XXmmNNddrrooppSSttaarrttCCaallllbbaacckk wwiitthh aa _d_r_o_p_A_c_t_i_o_n field value of
             XXmmDDRROOPP__CCAANNCCEELL.

             The receiver is notified by a XXmmCCRR__DDRROOPP__SSIITTEE__LLEEAAVVEE
             message. This message is processed by the XXmmNNddrraaggPPrroocc
             in the dynamic protocol mode.  This allows any drag
             under effects to be undone.



        15.6  DDrroopp RReecceeiivveerr RReessppoonnssiibbiilliittiieess ffoorr DDrrooppppiinngg



             When the user releases the drag to start a drop, the
             toolkit sends a message to the receiver.  The
             receiver's XXmmNNddrrooppPPrroocc routine processes it by checking
             that the proposed targets and actions are valid, and
             updates the status and operations fields accordingly.
             This information is sent back to the initiator's
             XXmmNNddrrooppSSttaarrttCCaallllbbaacckk routine.

             The application receiving a drop must:

                +o Have registered a XXmmNNddrrooppPPrroocc routine to be
                  processed when a drop is made on the site.  This
                  is done as part of registering a widget as a drop
                  site.

                +o Make a list of transfer requests.  If the drop is
                  cancelled, the number of transfer requests is set
                  to zero.

                +o Register a DropTransfer XXmmNNttrraannssffeerrPPrroocc to process
                  transfers from the initiator if the number of
                  transfers is not zero.




        15-68                                            May 9, 1992








                                                       Drag and Drop


                +o Call XXmmDDrrooppTTrraannssffeerrSSttaarrtt at least once, to either
                  cancel the drop or start the transfer process.

             The receiving application may also:

                +o Provide drop site Help information.

                +o Cancel a drop.



        15.6.1  TThhee XXmmNNddrrooppPPrroocc



             When a drop occurs (except for a Cancel), a message is
             sent from the toolkit on the initiator side to the
             receiver, and the receiver's XXmmNNddrrooppPPrroocc is called.
             Fields in its callback structure provide information
             about the drop to the receiver.

             The _o_p_e_r_a_t_i_o_n_s, _o_p_e_r_a_t_i_o_n, and _d_r_o_p_S_i_t_e_S_t_a_t_u_s fields
             are initialized by the toolkit in a similar manner to
             that described for the receiver's XXmmNNddrraaggPPrroocc earlier
             in this chapter.

             The XXmmNNddrrooppPPrroocc routine can update the _o_p_e_r_a_t_i_o_n_s,
             _o_p_e_r_a_t_i_o_n, and _d_r_o_p_S_i_t_e_S_t_a_t_u_s field further.  The final
             values are available to the initiator in its drop
             callback structures.

             The _d_r_o_p_A_c_t_i_o_n field indicates if a normal drop is
             requested, or if the user requested help.  For
             information about processing a help request, refer to
             "Providing Help" later in this chapter.

             If the receiver takes too long before ending the
             XXmmNNddrrooppPPrroocc, the toolkit will time out the drag.
             Therefore, if the receiver needs to do any processing
             before the transfer other than verifying that a
             transfer can take place, it should start a new process
             and end the XXmmNNddrrooppPPrroocc.

             Either the XXmmNNddrrooppPPrroocc or one of its subprocedures must
             start a transfer by calling XXmmDDrrooppTTrraannssffeerrSSttaarrtt.  The
             initiator is waiting for a transfer request to finish
             its part in the drop.  If a drop is not possible, the
             drop is cancelled as described below.  If a drop is
             possible, the XXmmNNddrrooppPPrroocc provides the appropriate
             details to start the transfer.




        May 9, 1992                                            15-69








        OSF/Motif Programmer's Guide


             The XXmmNNddrrooppPPrroocc creates a list of DropTransfer entries,
             containing target and client-specific information for
             each transfer desired.  There is a separate entry for
             each data-target type combination.  For instance, if
             the data is desired in both TEXT and COMPOUND_TEXT
             forms, there would be two entries on the list.  This
             list and the number of items in the list are used by
             XXmmDDrrooppTTrraannssffeerrSSttaarrtt to start the transfer.

             The receiver establishes the values of the DropTransfer
             resources before calling XXmmDDrrooppTTrraannssffeerrSSttaarrtt.  The
             DropTransfer resources are:

             XXmmNNddrrooppTTrraannssffeerrss    The list of drag transfer entries.

             XXmmNNiinnccrreemmeennttaall      Whether to use the incremental
                                 transfer mechanism.

             XXmmNNnnuummDDrrooppTTrraannssffeerrss The number of transfer entries in
                                 the list.  This number is
                                 decremented each time a transfer is
                                 made.

             XXmmNNttrraannssffeerrPPrroocc     The procedure to process
                                 transferred information.  This
                                 procedure is an
                                 XXttSSeelleeccttiioonnCCaallllbbaacckkPPrroocc procedure.
                                 For details on what that means,
                                 refer to X Toolkit documentation.

             XXmmNNttrraannssffeerrSSttaattuuss   Whether the transfer failed or not.
                                 The default value is
                                 XXmmTTRRAANNSSFFEERR__SSUUCCCCEESSSS.

             This example from DDNNDDllaabbeell..cc in Appendix B creates a
             transfer request list of one transfer entry, asking
             that the initiator send its data in compound text
             format.  Copy is the only action it accepts; the rest
             result in a cancelled drop.  The DropTransferCallback
             routine receives and processes the data from the
             initiator.

             static void HandleDrop(w, client_data, call_data)
             Widget          w;
             XtPointer       client_data, call_data;
             {
                XmDropProcCallback      DropData;
                XmDropTransferEntryRec  transferEntries[2];
                XmDropTransferEntry     transferList;
                Arg                     args[MAX_ARGS];
                int                     n;



        15-70                                            May 9, 1992








                                                       Drag and Drop


                DropData = (XmDropProcCallback)call_data;

                /* set the transfer resources */
                n = 0;

                /* if the action is Help, or the operation is not Copy,
                 *cancel the drop */
                if ((DropData->dropAction != XmDROP) ||
                (DropData->operation != XmDROP_COPY))
                   XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
                else {
                   /* the drop can continue.  Establish the transfer list and
                    * start the transfer */
                   transferEntries[0].target = COMPOUND_TEXT;
                   transferEntries[0].client_data = (XtPointer)w;
                   transferList = transferEntries;
                   XtSetArg(args[n], XmNdropTransfers, transferList); n++;
                   XtSetArg(args[n], XmNnumDropTransfers, 1); n++;
                   XtSetArg(args[n], XmNtransferProc, DropTransferCallback); n++;
                   }

                /* start the transfer or cancel */
                XmDropTransferStart(DropData->dragContext, args, n);
             }

             If the program could accept transfers in more than one
             target type, for instance text and compound text, then
             a separate transfer entry is needed for each request:

             transferEntries[0].target = COMPOUND_TEXT;
             transferEntries[1].target = TEXT;
                  .
                  .
                  .
             XtSetArg(args[n], XmNnumDropTransfers, 2); n++;



        15.6.2  XXmmDDrrooppTTrraannssffeerr



             The toolkit on the receiver side is in charge of the
             transfer procedure.  Information about the transfer is
             stored in a DropTransfer widget, which is created by
             the XXmmDDrrooppTTrraannssffeerrSSttaarrtt routine.

             Before calling XXmmDDrrooppTTrraannssffeerrSSttaarrtt, the receiver stores
             a list of DropTransfer transfer entries in the
             XXmmNNddrrooppTTrraannssffeerrss resource.  Each entry contains target
             and client-specific information for each transfer



        May 9, 1992                                            15-71








        OSF/Motif Programmer's Guide


             desired.  It also registers a procedure to receive
             transfers from the initiator in the XXmmNNttrraannssffeerrPPrroocc
             resource. These resources, along with the other
             DropTransfer resources, are used by the
             XXmmDDrrooppTTrraannssffeerrSSttaarrtt function.

             The toolkit processes the items on the list, one at a
             time, decrementing XXmmNNnnuummDDrrooppTTrraannssffeerrss each time.  When
             the XXmmNNnnuummDDrrooppTTrraannssffeerrss value is zero, the drop is
             finished.  The toolkit on the receiver side sends a
             message to the initiator, whose XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk
             is called.

             If XXmmNNiinnccrreemmeennttaall is True, the Xt Selection incremental
             transfer protocol is used between the toolkit and the
             receiver, regardless of what the initiator sent.  Refer
             to the Xt documentation for details of how to use
             incremental transfer.  If the value is False, the
             transfer between the toolkit and the receiver is made
             in one pass, regardless of how the initiator sent it.

             The XXmmNNttrraannssffeerrPPrroocc routine receives each transfer from
             the initiator. If more than one target type is
             acceptable to the receiver, this procedure needs to
             check which target type was used in this transfer, and
             process the transferred data accordingly.

             The XXmmNNttrraannssffeerrPPrroocc routine can examine and update the
             DropTransfer resources during the transfer with
             XXttGGeettVVaalluueess and XXttSSeettVVaalluueess.

             The XXmmDDrrooppTTrraannssffeerrAAdddd routine is used to add to the
             transfer list after the transfer has begun.  For
             example, this routine is used when a Move operation is
             performed, to add a new transfer entry record telling
             the initiator to delete the data.  It can be used in
             other situations where the entire transfer list is not
             known when XXmmDDrrooppTTrraannssffeerrSSttaarrtt is called.

             If there are problems with the drop, it can be
             cancelled as described later in the chapter.

             This example from DDNNDDllaabbeell..cc in Appendix B receives
             compound string data from the initiator, and uses it to
             replace the label of the Label widget.

             static void TransferProc(w, closure, seltype, type, value, length,
                                              format)
             Widget           w;
             XtPointer        closure;
             Atom             *seltype;



        15-72                                            May 9, 1992








                                                       Drag and Drop


             Atom             *type;
             XtPointer        value;
             unsigned long    *length;
             int              format;
             {
                int         n;
                Arg         args[MAX_ARGS];

                /* information from the drag initiator is passed in compound
                 * text format.  Convert it to compound string and replace the
                 * Label label. */

                if (*type = COMPOUND_TEXT) {
                   n = 0;
                   XtSetArg(args[n], XmNlabelString, XmCvtCTToXmString(value));
                   n++;
                   XtSetValues(closure, args, n);
                   }
             }

             If the program is able to handle more than one target
             type, this routine needs to check for them all.  For
             instance:

                if (*type = COMPOUND_TEXT) {
                   /* code to change the label to the compound text passed */
                   }
                else if (*type = TEXT) {
                   /* code to change the label to the text passed */
                   }



        15.6.2.1  PPrroocceessssiinngg EEaacchh OOppeerraattiioonn



             The XXmmNNttrraannssffeerrPPrroocc routine must be able to process the
             data from the initiator correctly for each operation
             listed in the DropSite XXmmNNddrrooppSSiitteeOOppeerraattiioonnss resource .

                +o If the operation is Copy, the _v_a_l_u_e field contains
                  a pointer to the data from the initiator.  It is
                  used to assign the value to some element in the
                  receiver's program.  The example above shows a
                  Copy in effect.  When the transfer is finished,
                  both the initiator and receiver have the data in
                  each of their applications.

                +o If the operation is Move, data is first copied to
                  the receiver, then deleted from the initiator.  It



        May 9, 1992                                            15-73








        OSF/Motif Programmer's Guide


                  is important that the initiator not delete the
                  data before the receiver has it.  Therefore, a
                  Move is a two-step process:

                     - The first transfer is processed by the
                       initiator like a Copy.  It returns a pointer
                       to the data in the _v_a_l_u_e field.

                     - When the XXmmNNttrraannssffeerrPPrroocc has the data, it
                       uses XXmmDDrrooppTTrraannssffeerrAAdddd to make a new transfer
                       entry for that data, setting the _t_a_r_g_e_t to
                       DDEELLEETTEE.  The initiator will not delete the
                       data until the receiver has issued this
                       second transfer request.

                  At the end of the transfer, the receiver has the
                  only copy of the data.

                +o If the operation is Link, the pointer is used to
                  link an element in the receiver to the data.  At
                  the end of the operation, there is only one copy
                  of the data, belonging to the initiator, but both
                  applications have access to it.



        15.6.3  CCaanncceelllliinngg aa DDrroopp



             A drop can be cancelled only by the receiver,  from the
             XXmmNNddrrooppPPrroocc or any subroutine it calls, such as
             XXmmNNttrraannssffeerrPPrroocc. To cancel a drop:

                +o Set the XXmmNNnnuummDDrrooppTTrraannssffeerrss DropTransfer resource
                  to zero.  This tells the toolkit that there are no
                  more transfers to make and the drop is complete.

                +o Set the XXmmNNttrraannssffeerrSSttaattuuss to XXmmTTRRAANNSSFFEERR__FFAAIILLUURREE.
                  This information is passed to the initiator in the
                  XXmmNNddrrooppFFiinniisshheeddCCaallllbbaacckk structure.

                +o Call the XXmmDDrrooppTTrraannssffeerrSSttaarrtt function if the
                  decision to cancel the drop was discovered in the
                  XXmmNNddrrooppPPrroocc routine.  Otherwise, exit the
                  subroutine.

             The transfer will be cancelled at the next transfer
             request.  The drop is over, and the initiator's
             XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk and XXmmNNddrraaggDDrrooppFFiinniisshhCCaallllbbaacckk
             routines are called.



        15-74                                            May 9, 1992








                                                       Drag and Drop


             This example is from a program's XXmmNNddrrooppPPrroocc routine.

             XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
             XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
             XmDropTransferStart(DropData->dragContext, args, n);



        15.6.4  PPrroovviiddiinngg HHeellpp



             It might not always be obvious to the user what the
             result of dropping a particular source on a drop site
             might be.  The user can request more information about
             the drop site by pressing KKHHeellpp while the drag icon is
             over the drop site.

             The receiver's XXmmNNddrrooppPPrroocc is called, with a value of
             XXmmDDRROOPP__HHEELLPP in the _d_r_o_p_A_c_t_i_o_n field of its callback
             structure.  If the receiver supports help, it should
             post a dialog box, providing information about the type
             of drop this site expects, and what it will do when a
             successful drop occurs.

             The receiver should then exit the XXmmNNddrrooppPPrroocc routine,
             not waiting for a response from the user.  When the
             XXmmNNddrrooppPPrroocc has finished, the initiator's
             XXmmNNddrrooppSSttaarrttCCaallllbbaacckk is called with a _d_r_o_p_A_c_t_i_o_n of
             XXmmDDRROOPP__HHEELLPP if the initiator has registered that
             callback.  The initiator is not expected to do anything
             at this point, but it could provide special processing
             such as changing the drag icon.

             Typically, the help dialog box allows the user the
             opportunity to continue the drop or to cancel the drop.
             If more than one operation is possible, the dialog box
             should explain the consequences of each operation and
             let the user select one.  The dialog procedure may
             change the operation based on the users selection.

                +o If the user indicates that the drop should be
                  cancelled, the receiver's help procedure should
                  cancel the drop by requesting no transfers, as
                  described in the previous section.

                +o If the user indicates that the drop should
                  continue, the help procedure should call
                  XXmmDDrrooppTTrraannssffeerrSSttaarrtt to begin the transfer of
                  information from the initiator.




        May 9, 1992                                            15-75








        OSF/Motif Programmer's Guide


             In either case, the help procedure must call
             XXmmDDrrooppTTrraannffeerrSSttaarrtt before it ends to either start the
             transfers or notify the initiator that no transfers
             will be requested.

             The receiver may want to issue help information if a
             drop is considered invalid, even if the user hasn't
             requested it.  If so, the receiver's XXmmNNddrrooppPPrroocc sets
             the _d_r_o_p_A_c_t_i_o_n field to XXmmDDRROOPP__HHEELLPP, and displays the
             help dialog box as if help had been requested.

             The following example taken from DDNNDDDDeemmoo..cc in Appendix
             B shows how the help dialog box shown in the
             illustration was created.

                         FFiigguurree 1155--1144..  Help Dialog Box































             The XXmmDDrrooppPPrroocc DDrrooppPPrrooccCCaallllbbaacckk routine checks if the
             drop is normal or if there is a request for help.

             static void DropProcCallback(w, client, call)



        15-76                                            May 9, 1992








                                                       Drag and Drop


             Widget w;
             XtPointer client;
             XtPointer call;
             {

                 XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)call;

                 if (appInfo->highlightRect != NULL)
                     RectUnhighlight(w);

                 if (cb->dropAction != XmDROP_HELP)
                     HandleDrop(w, call);
                 else
                     HandleHelp(w, call);

             }

             The HHaannddlleeHHeellpp routine displays the help dialog box.
             The text presented in the dialog box depends on the
             drop site and the operation.  Callback routines are
             registered to be performed when either of the dialog
             pushbuttons is pressed.

             static void HandleHelp(w, call)
             Widget w;
             XtPointer call;
             {

                 XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)call;
                 static XmDropProcCallbackStruct client;
                 Boolean                         rectFound, bgFound, pixFound;
                 XmString                        helpStr;
                 RectPtr                         rect;
                 Arg                             args[5];
                 XmString                        tempStr, buttonArray[2];
                 int                             n = 0;

                 /* the drop is valid until it is determined invalid */
                 cb->dropSiteStatus = XmVALID_DROP_SITE;

                 /* if we haven't created a help dialog, create one now */
                 if (helpDialog == NULL) {

                     XtSetArg(args[n], XmNdialogStyle,
                          XmDIALOG_FULL_APPLICATION_MODAL); n++;
                     XtSetArg(args[n], XmNtitle, "Drop Help"); n++;
                     helpDialog = XmCreateMessageDialog(topLevel, "Help",
                          args, n);

                     n = 0;
                     buttonArray[0] = XmStringCreateSimple("Move");



        May 9, 1992                                            15-77








        OSF/Motif Programmer's Guide


                     buttonArray[1] = XmStringCreateSimple("Copy");
                     XtSetArg(args[n], XmNbuttons, buttonArray); n++;
                     XtSetArg(args[n], XmNbuttonCount, 2); n++;
                     XtSetArg(args[n], XmNbuttonSet, 0); n++;
                     XtSetArg(args[n], XmNsimpleCallback, ChangeOperation); n++;
                     tempStr = XmStringCreateSimple("Operations:");
                     XtSetArg(args[n], XmNoptionLabel, tempStr); n++;
                     helpMenu = XmCreateSimpleOptionMenu(helpDialog, "helpMenu",
                          args, n);
                     XmStringFree(tempStr);
                     XmStringFree(buttonArray[0]);
                     XmStringFree(buttonArray[1]);

                     XtAddCallback(helpDialog, XmNokCallback,
                          (XtCallbackProc) HandleOK, (XtPointer) &client);
                     XtAddCallback(helpDialog, XmNcancelCallback,
                          (XtCallbackProc) CancelDrop, (XtPointer) &client);

                     XtUnmanageChild(XmMessageBoxGetChild(helpDialog,
                          XmDIALOG_HELP_BUTTON));

                     XtRealizeWidget(helpDialog);

                 }

                 /* pass the necessary callback information along */
                 client.dragContext = cb->dragContext;
                 client.x = cb->x;
                 client.y = cb->y;
                 client.dropSiteStatus = cb->dropSiteStatus;
                 client.operation = cb->operation;
                 client.operations = cb->operations;

                 /* find the valid targets */
                 CheckTargets(cb->dragContext, XtDisplay(w), &rectFound,
                              &bgFound, &pixFound);

                 /* determine the appropriate help message */
                 if (rectFound) {

                     if (cb->operations == XmDROP_MOVE | XmDROP_COPY) {
                         XtManageChild(helpMenu);
                         helpStr = XmStringCreateLtoR(HELP_MSG4,
                              XmFONTLIST_DEFAULT_TAG);
                         XtManageChild(XmMessageBoxGetChild(helpDialog,
                              XmDIALOG_OK_BUTTON));
                     }
                     else if (cb->operation == XmDROP_MOVE) {
                         XtUnmanageChild(helpMenu);
                         helpStr = XmStringCreateLtoR(HELP_MSG2,
                              XmFONTLIST_DEFAULT_TAG);



        15-78                                            May 9, 1992








                                                       Drag and Drop


                         XtManageChild(XmMessageBoxGetChild(helpDialog,
                              XmDIALOG_OK_BUTTON));
                     }
                     else if (cb->operation == XmDROP_COPY) {
                         XtUnmanageChild(helpMenu);
                         helpStr = XmStringCreateLtoR(HELP_MSG3,
                              XmFONTLIST_DEFAULT_TAG);
                         XtManageChild(XmMessageBoxGetChild(helpDialog,
                              XmDIALOG_OK_BUTTON));
                     }

                 }
                 else if (bgFound || pixFound && cb->operation == XmDROP_COPY) {

                     XtUnmanageChild(helpMenu);
                     rect = RectFind(cb->x, cb->y);
                     if (rect) {
                         helpStr = XmStringCreateLtoR(HELP_MSG1,
                              XmFONTLIST_DEFAULT_TAG);
                         XtManageChild(XmMessageBoxGetChild(helpDialog,
                              XmDIALOG_OK_BUTTON));
                     }
                     else {
                         helpStr = XmStringCreateLtoR(HELP_MSG5,
                              XmFONTLIST_DEFAULT_TAG);
                         XtUnmanageChild(XmMessageBoxGetChild(helpDialog,
                              XmDIALOG_OK_BUTTON));
                     }

                 }
                 else {
                     XtUnmanageChild(helpMenu);
                     helpStr = XmStringCreateLtoR(HELP_MSG5,
                          XmFONTLIST_DEFAULT_TAG);
                     XtUnmanageChild(XmMessageBoxGetChild(helpDialog,
                          XmDIALOG_OK_BUTTON));
                 }

                 /* set the help message into the dialog */
                 XtSetArg(args[0], XmNmessageString, helpStr);
                 XtSetValues(helpDialog, args, 1);

                 /* Free the XmString */
                 XmStringFree(helpStr);

                 /* map the help dialog */
                 XtManageChild(helpDialog);

             }





        May 9, 1992                                            15-79








        OSF/Motif Programmer's Guide


             The HHaannddlleeOOKK callback routine is performed when the
             user selects the OK button.  It allows the drop to
             continue normally by calling the HHaannddlleeDDrroopp routine.

             static void HandleOK(w, client, call)
             Widget w;
             XtPointer client;
             XtPointer call;
             {

                 XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)client;

                 cb->operation = appInfo->operation;
                 HandleDrop(w, (XtPointer) cb);

             }


             The CCaanncceellDDrroopp callback routine is performed when the
             user selects the Cancel button.  It cancels the drop by
             calling XXmmDDrrooppTTrraannssffeerrSSttaarrtt with indicators that the
             drop failed.

             static void CancelDrop(w, client, call)
             Widget w;
             XtPointer client;
             XtPointer call;
             {

                 XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)client;
                 Arg                         args[2];

                 /* On help, we need to cancel the drop transfer */
                 XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
                 XtSetArg(args[1], XmNnumDropTransfers, 0);

                 /* we need to start the drop transfer to cancel the transfer */
                 XmDropTransferStart(cb->dragContext, args, 2);

             }














        15-80                                            May 9, 1992








                                                       Drag and Drop


        15.7  DDrraagg IInniittiiaattoorr RReessppoonnssiibbiilliittiieess ffoorr DDrrooppppiinngg



             The drag initiator:

                +o Registers a XXmmNNccoonnvveerrttPPrroocc procedure to format
                  data and send the formatted data to the receiver.

                +o Optionally registers a XXmmNNddrrooppSSttaarrttCCaallllbbaacckk to be
                  performed at the drop.

                +o Optionally registers a XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk to be
                  performed after the drop and transfer have
                  finished.

                +o Optionally registers a XXmmNNddrraaggDDrrooppFFiinniisshhCCaallllbbaacckk
                  to be performed after the entire drag and drop
                  transaction has finished.



        15.7.1  XXmmNNddrrooppSSttaarrttCCaallllbbaacckk



             The receiver's XXmmNNddrrooppPPrroocc routine receives the drop
             message first if the drop occurred over a widget which
             was registered as a DropSite. It verifies that a drop
             is possible, and updates fields in its callback
             structure, which become available to the initiator in
             its XXmmNNddrrooppSSttaarrttCCaallllbbaacckk callback structure.  The
             initiator can perform any actions necessary prior to
             the transfer of information, for instance, providing a
             new drag icon.

             The toolkit initializes the _o_p_e_r_a_t_i_o_n, _o_p_e_r_a_t_i_o_n_s, and
             _d_r_o_p_S_i_t_e_S_t_a_t_u_s fields in a manner similar to that
             described for the initiator's drag callbacks earlier in
             this chapter with one difference:  the initialization
             for the drag callbacks uses the values at the end of
             the receiver's XXmmNNddrraaggPPrroocc, while the initialization
             for the drop callbacks uses the values at the end of
             the receiver's XXmmNNddrrooppPPrroocc.

             The _d_r_o_p_A_c_t_i_o_n field indicates the action that the
             receiver has taken.  XXmmDDRROOPP shows that a normal drop is
             in progress. XXmmDDRROOPP__CCAANNCCEELL shows that the receiver has
             cancelled the drop.  If the action is XXmmDDRROOPP__HHEELLPP, the
             initiator is not expected to do anything, although this
             callback provides the opportunity to do so if desired,



        May 9, 1992                                            15-81








        OSF/Motif Programmer's Guide


             for instance, changing the drag icon to reflect the
             Help request.

             This procedure will not know the resolution of the help
             dialog.  However, if the user chooses to continue, the
             initiator's XXmmNNccoonnvveerrttPPrroocc routine is called as part of
             the transfer process, and if the user chooses to
             cancel, the receiver's XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk is called
             with a _d_r_o_p_A_c_t_i_o_n of XXmmDDRROOPP__CCAANNCCEELL.



        15.7.2  DDeeaalliinngg wwiitthh RReeqquueessttss ffoorr TTrraannssffeerr



             The drag initiator must register a callback to process
             transfers in the XXmmNNccoonnvveerrttPPrroocc DragContext resource.
             This routine is called when the receiver client invokes
             XXmmDDrrooppTTrraannssffeerrSSttaarrtt.  Prior to calling
             XXmmDDrrooppTTrraannssffeerrSSttaarrtt, the receiver makes a list of the
             target formats it wants.

             The initiator's XXmmNNccoonnvveerrttPPrroocc callback routine
             processes transfer requests from the receiver.  The
             routine should be able to return information about each
             object being dragged in each possible target format for
             that item.

             If the DropTransfer XXmmNNiinnccrreemmeennttaall resource is True,
             information is transferred between the initiator and
             the toolkit using the Xt Selection incremental
             protocol.  If the value is False, the information is
             transferred between the initiator and the toolkit in
             one pass.  The initiator and receiver need not be using
             the same incremental or non-incremental protocol.

             This XXmmNNccoonnvveerrttPPrroocc routine is called for each target
             type desired by the receiver, a single target type for
             each request.  The XXmmNNccoonnvveerrttPPrroocc routine should be
             able to perform any of the operations listed in the
             DragContext XXmmNNddrraaggOOppeerraattiioonnss resource on data in any
             of the target types listed in the XXmmNNeexxppoorrttTTaarrggeettss
             resource.

                +o If the operation is Copy or Link, the
                  XXmmNNccoonnvveerrttPPrroocc returns a pointer to the data.  The
                  receiver will use this pointer to copy this data
                  into its own storage, or establish a link using
                  this pointer.




        15-82                                            May 9, 1992








                                                       Drag and Drop


                +o If the operation is Move, the first transfer
                  request has a normal _t_a_r_g_e_t type.  The
                  XXmmNNccoonnvveerrttPPrroocc should return a pointer to the
                  data, as it would for a Copy.

                  A second transfer request for the data has a
                  _t_a_r_g_e_t type of DDEELLEETTEE.  The receiver does not
                  issue this request until it has received the data
                  and handled it appropriately (such as storing it
                  in a file).  Only then should the initiator delete
                  the data.

             In the following example from DDNNDDssccrroollll..cc in Appendix
             B, the routine returns the value of the scrollbar
             slider in only one target type, compound text. This
             information is passed to the receiver's XXmmNNttrraannssffeerrPPrroocc
             routine.  This routine is called once for each item in
             the receiver's XXmmNNddrrooppTTrraannssffeerrss list. Copy was the only
             operation allowed by the application, so this routine
             need not process any delete requests from the receiver.

             static Boolean DragConvertProc(w, selection, target, typeRtn,
                                            valueRtn, lengthRtn, formatRtn,
                                            max_lengthRtn, client_data,
                                            request_id)
             Widget              w;
             Atom                *selection;
             Atom                *target;
             Atom                *typeRtn;
             XtPointer           *valueRtn;
             unsigned long       *lengthRtn;
             int                 *formatRtn;
             unsigned long       *max_lengthRtn;
             XtPointer           client_data;
             XtRequestId         *request_id;
             {

                XmString    cstring;
                static char tmpstring[100];
                int         *value;
                int         n;
                Arg         args[MAX_ARGS];
                char             *ctext;
                char        *passtext;

                /* this routine processes only compound text */
                if (*target != COMPOUND_TEXT)
                   return(False);

                /* get the value of the scrollbar slider */
                n = 0;



        May 9, 1992                                            15-83








        OSF/Motif Programmer's Guide


                XtSetArg(args[n], XmNvalue, &value); n++;
                XtGetValues(scrollbar, args, n);

                /* convert the slider value to compound text */
                sprintf(tmpstring, "%d", value);
                cstring = XmStringCreateLocalized(tmpstring);
                ctext = XmCvtXmStringToCT(cstring);

                passtext = XtMalloc(strlen(ctext)+1);
                memcpy(passtext, ctext, strlen(ctext)+1);

                /* format the value for transfer.  convert the value from
                * compound string to compound text for the transfer */
                *typeRtn = COMPOUND_TEXT;
                *valueRtn = (XtPointer) passtext;
                *lengthRtn = strlen(passtext);
                *formatRtn = 8;
                return(True);
             }

             If the DDNNDDssccrroollll..cc program in Appendix B processed more
             than one target, such as text and compound text, then
             this routine would have to handle both types.  For
             example:

             if (*target = COMPOUND_TEXT) {
                /* processing to convert the slider to compound string format */
                }
             else if (*target = TEXT) {
                /* processing to convert the slider to text format */
                }
             else
                return(False);



        15.7.3  XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk



             The XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk is called when the receiver's
             XXmmNNttrraannssffeerrPPrroocc routine has finished processing all the
             transfers desired by the receiver.

             The _c_o_m_p_l_e_t_i_o_n_S_t_a_t_u_s field indicates whether the entire
             drop was successful or not.

             The _o_p_e_r_a_t_i_o_n_s, _o_p_e_r_a_t_i_o_n, _d_r_o_p_S_i_t_e_S_t_a_t_u_s, and
             _d_r_o_p_A_c_t_i_o_n fields are initialized as described for the
             XXmmNNddrrooppSSttaarrttCCaallllbbaacckk procedure covered earlier in this
             chapter.



        15-84                                            May 9, 1992








                                                       Drag and Drop


             In Motif 1.2, this routine is performed once per drag.



        15.7.4  XXmmNNddrraaggDDrrooppFFiinniisshhCCaallllbbaacckk



             The XXmmddrraaggDDrrooppFFiinniisshhCCaallllbbaacckk routine is performed when
             the complete drag and drop transaction has finished.
             In Motif 1.2, this routine is called immediately after
             the initiator's XXmmNNddrrooppFFiinniisshhCCaallllbbaacckk has finished. The
             initiator frees any remaining structures it has
             allocated during the drag.

             For example, this sample code destroys any cursor icons
             that were created during the drag.

             static void DnDFinishCallback(w, client_data, call_data)
             Widget          w;
             XtPointer       client_data, call_data;
             {

                XmDragContext            dc;
                Widget                   source_icon, state_icon, op_icon;
                Arg                      args[MAX_ARGS];
                int                      n;

                dc = (XmDragContext)w;
                source_icon = state_icon = op_icon = NULL;

                n = 0;
                XtSetArg(args[n], XmNsourceCursorIcon, &source_icon); n++;
                XtSetArg(args[n], XmNstateCursorIcon, &state_icon); n++;
                XtSetArg(args[n], XmNoperationCursorIcon, &op_icon); n++;
                XtGetValues(dc, args, n);

                if (source_icon != NULL)
                   XtDestroyWidget(source_icon);
                   if (state_icon != NULL)
                      XtDestroyWidget(state_icon);
                   if (op_icon != NULL)
                      XtDestroyWidget(op_icon);
             }










        May 9, 1992                                            15-85






 s
