[ Previous | Next | Contents | Glossary | Home | Search ]
Motif 2.1 Programmer's Guide



Drag Initiator Responsibilities for Dragging

This section explains what an application can do on behalf of the widget that initiates the drag. The drag initiator can do any of the following:

  1. If a widget does not already contain drag code, an application must recognize the start of a drag (Btn2Down) within a widget controlled by the application.

  2. If an application wants a widget to act as a drag source, the application must attach an XmNconvertCallback to the widget.

  3. If a widget does not already contain drag code, an application can establish a DragContext for the widget, providing information about operations, targets, and drag-over visuals, using the XmeDragSource function. If a widget does already contain drag code, an application can customize the DragContext.

  4. Optionally, an application can provide special drag-over effects.

    These steps are described in the following sections.

    If the user tries to drag objects from a widget that is not recognized as a drag source by either the toolkit or the source application, nothing happens.

  5. Recognizing a Drag Has Started

    The initiator client must be able to recognize the Btn2Down event within a widget it allows to be a drag source. It may have to override an already-assigned translation for the widget.

    The following example from the main routine of simple_drag in Section 17.2.1.2 overrides the existing mouse button 2 translation for the ScrollBar widget, and maps it to the StartDrag routine, which will start the drag transaction.

    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 */
        ScrollBar1 = XtVaCreateManagedWidget("SB1",
            xmScrollBarWidgetClass, RC1,
            XmNorientation, XmHORIZONTAL,   /* for cosmetic reasons */
            XmNtranslations, parsed_xlations,
            NULL);

    Translation may be more complicated in some editable widgets, in which Btn2DownBtn2Up is used for primary transfer, and Btn2Motion is used for drag and drop.

    Establishing an XmNconvertCallback Procedure

    If your widget is to act as a drag initator, it must provide an XmNconvertCallback procedure that converts target requests. Your application must attach an XmNconvertCallback to the drag initiator widget; for example:

    /* Associate a convert callback with the ScrollBar. */
      XtAddCallback(ScrollBar1, XmNconvertCallback, ConvertCallback,
    NULL);

    The XmNconvertCallback procedure must be able to convert two kinds of requests:

    1. A request to convert _MOTIF_EXPORT_TARGETS. The callback procedure must respond to this request by providing a list of all the targets that the callback procedure knows how to convert. For example, in the in the simple_drag demo, the only target that the ConvertCallback procedure can convert the value to is COMPOUND_TEXT. Therefore, the list of targets that ConvertCallback returns consists solely of the COMPOUND_TEXT target.

    2. A request to convert all of the targets in the list returned by _MOTIF_EXPORT_TARGETS. For example, the ConvertCallback of simple_drag must be able to return the current ScrollBar XmNvalue in COMPOUND_TEXT format.

    3. Starting a Drag With XmeDragSource

      XmeDragSource initiates a drag and creates an XmDragContext widget. In the simple_drag demo, XmeDragSource is called as follows from the StartDrag routine:

      void
      StartDrag(Widget w,
                XEvent *event)
      {
       Arg       args[2];
       Cardinal  n=0;
       
        XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
        XmeDragSource(w, NULL, event, args, n);

      StartDrag is called when the user preses Btn2Down on the XmScrollBar.

      See the Motif Widget Writer's Guide for syntactic details about XmeDragSource. In brief, XmeDragSource is the UTM replacement for the XmDragStart call. The args passed to XmeDragSource will eventually become resources of the DragContext.

      If XmDisplay has the XmNdragStartCallback resource, the nominated procedure is called at the beginning of XmeDragSource. This allows the client to cancel the drag initiation, as well as perform any other necessary operation.

      The XmNdragOperations 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 XmNdropSiteOperations list and the user-selected operation to arrive at the operation that will be performed if a drop occurs on this site.

      If an application wants to use only one operation, it should set the XmNdragOperations 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 drag source does not have any custom drag icons or any drag callbacks.

      Overriding Existing Drag Sources

      XtGetValues is used to check the values of widgets resources established as drag sources earlier in the application, and XtSetValues 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 predefined drag source (for example, XmText), overriding the default behavior becomes more complex. The widget calls XmeDragSource when the drag starts, and the application cannot call XmeDragSource again for the widget. Instead, 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:

      1. 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()

      2. Register the new action, using XtAppAddActions.

      3. In the new action procedure, call XmGetDragContext to get the DragContext, and then call XtSetValues to change resource values. The timestamp argument to XmGetDragContext 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 XmNdragOperations resource.

      4. Drag-Over Visual Effects

        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 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:

        1. Use the default drag-over visuals, specified in the XmScreen object. The toolkit manages all the drag-over effects.

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

        3. 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 XmScreen object are used only if the value for the equivalent DragContext visual resource is NULL.

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

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

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

          Each drag icon has a hotspot. Since a drag icon could be quite large, the hotspot provides a single pixel that is used in providing drag-over and drag-under effects. For example, 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 hotspot has moved into the area. By default, the hotspot 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 corner, and the operation icon shows a Copy will happen if a drop is made. The default blending and attachment values are used.

          Figure 20. A Drag Icon.

          View figure.

        5. Source Icon

          The source icon is a picture representing the object being dragged. It can be either a pixmap or cursor. The client can create a custom pixmap through the XmNsourcePixmapIcon resource or a custom cursor through the XmNsourceCursorIcon 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 given in the XmScreen resource XmNdefaultSourceCursorIcon is used.

          For example, the following code establishes the Pixmap stored in the pixmap variable as the custom pixmap:

          /* Create a drag icon using "pixmap" as the DragIcon pixmap. */
            XtSetArg(wargs[n],XmNpixmap,pixmap); n++;
            drag_icon = XmCreateDragIcon((Widget)cw,"dragIcon",wargs,n);
           
          /* Set the XmNsourcePixmapIcon resource to the drag icon widget */
            n = 0;
            XtSetArg(wargs[n],XmNsourcePixmapIcon,drag_icon);
            n++;

          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.

          Figure 21. Source Icons.

          View figure.

          State Icon

          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 XmScreen resources XmNdefaultValidCursorIcon, XmNdefaultInvalidCursorIcon, and XmNdefaultNoneCursorIcon.

          A custom state icon can be specified in the DragContext resource XmNstateCursorIcon. This icon must be changed appropriately as the state of the drag changes, using the drag callbacks to change the CursorForeground resources outlined below. If XmNstateCursorIcon is NULL, not a bitmap, or not defined on the same screen as XmScreen, the default XmScreen icons are used.

          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: XmNvalidCursorForeground, XmNinvalidCursorForeground, XmNnoneCursorForeground. 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:

          *.validCursorForeground:          green
          *.invalidCursorForeground:        red
          *.noneCursorForeground:           yellow

          Operation Icon

          The operation icon is a cursor that indicates what operation is to happen when the drop is made. The default operation icons are the values of the XmScreen resources XmNdefaultMoveCursorIcon, XmNdefaultCopyCursorIcon, and XmNdefaultLinkCursorIcon.

          A custom operation icon can be specified in the DragContext resource XmNoperationCursorIcon. The icon should be changed as the operation changes, using the drag callbacks. If XmNoperationCursorIcon is NULL, not a bitmap, or not defined on the same screen as XmScreen, the default XmScreen icons are used.

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

          Figure 22. Operation Icons.


          View figure.

          If the operation in effect is XmDROP_NOOP, meaning that no operation is possible, then the operation icon is left blank, as shown in the following illustration. This condition also sets the dropSiteStatus to XmDROP_SITE_INVALID.

          Figure 23. Copy and Noop Drag Icons.

          View figure.

          Drag Icon Blending and Attachment

          The client can specify which of the three icons to mix together to form the drag icon with the XmNblendModel DragContext resource:

          XmBLEND_ALL

          Use the source icon, state icon, and operation icon. The hotspot comes from the state icon. This is the default value. The order listed is also the order of the blend.

          XmBLEND_STATE_SOURCE

          Use only the source icon and state icon. The hotspot comes from the state icon.

          XmBLEND_JUST_SOURCE

          Use only the source icon. The hotspot comes from the source icon.

          XmBLEND_NONE

          Do not display any drag icon. The client handles all drag-over effects.

          The XmNattachment 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 XmATTACH_NORTH_WEST.

          XmNoffsetX and XmNoffsetY are used to place the icon relative to the attachment point.

          If the attachment point is XmATTACH_HOT, 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.

          Figure 24. An Attach_Hot Icon.

          View figure.

          When the state or operation icon is blended with a source icon, a specified point of the icon's XmNpixmap is aligned with the upper left corner of the source icon. The resulting XmNpixmap is large enough to include both, and the resulting XmNmask 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 XmScreen XmNdefaultSourceCursorIcon instead of the DragContext's XmNsourceCursorIcon. If it is still too large, it is clipped relative to the hotspot (that is, if the hotspot is at an edge, the other edge is clipped; if the hotspot is in the center, opposite edges are clipped equally).

          Visual Style Notes

          If XmNsourcePixmapIcon is used, the colormap used for rendering is that of the DragContext's reference widget.

          If the DragContext XmNblendModel is XmBLEND_NONE, and the dynamic cursor style is in use, the application must use XChangeActivePointerGrab to change the cursor. If XmBLEND_NONE 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 dragProtocolStyle field in the XmNtopLevelEnterCallback structure, or looking at the XmNdragInitiatorProtocolStyle Display resource in the case of XmDRAG_NONE or XmDRAG_DROP_ONLY.

          The resolution and best cursor size can vary from screen to screen. This is why the default cursor icons are XmScreen resources. An application that wants its source cursor or pixmap to be screen dependent can look for changes in the screen field in the XmNtopLevelEnterCallback struct, and update the various icon DragContext resources appropriately.

          Creating a Drag Icon

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

          Use the XmCreateDragIcon function to create any of these parts. The XmNattachment resource is not used for the source icon. The other resources specify pixmap, size, and hotspot details. The DragContext XmNblendModel resource indicates which hotspot is used for the entire drag icon.

          The following example from DNDDemo.c 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 XmBLEND_JUST_SOURCE. It is shown here as if the blend style were XmBLEND_ALL.)

          Figure 25. Custom Source Icon.

          View figure.

          The ColorRect 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 DNDDraw.c file.

          void
          ColorRect(Widget w, XEvent *event, String *params, Cardinal *num_params)
          {
              ...
              Atom        targets[1];
              Widget      sourceIcon, stateIcon;
              Pixel       background, foreground;
              char        *source_bits, *source_mask;
              char        *state_bits, *state_mask;
              Dimension   width, height;
              Arg         args[16];
              int         n = 0;
           
              n = 0;
              XtSetArg(args[n], XmNbackground, &background); n++;
              XtSetArg(args[n], XmNforeground, &foreground); n++;
              XtGetValues(w, args, n);
           
              /* If the server will handle a large icon, create one */
              if (appInfo->maxCursorWidth >= ICON_WIDTH &&
                  appInfo->maxCursorHeight >= ICON_HEIGHT) {
           
                  source_bits = (char *)SOURCE_ICON_BITS;
                  source_mask = (char *)SOURCE_ICON_MASK;
                  state_bits = (char *)STATE_ICON_BITS;
                  state_mask = (char *)STATE_ICON_MASK;
                  width = ICON_WIDTH;
                  height = ICON_HEIGHT;
           
              }
              else {
           
                  /* If the server will handle a small icon, create one */
                  source_bits = (char *)SMALL_SOURCE_ICON_BITS;
                  source_mask = (char *)SMALL_SOURCE_ICON_MASK;
                  state_bits = (char *)SMALL_STATE_ICON_BITS;
                  state_mask = (char *)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;
              ...
              /* set args for the drag cursor icons */
              XtSetArg(args[n], XmNsourceCursorIcon, sourceIcon); n++;
              XtSetArg(args[n], XmNstateCursorIcon, stateIcon); n++;
           
              /* identify the necessary callbacks */
              ...
              /* start the drag. This creates a drag context. */
              myDC = XmeDragSource(w, NULL, event, args, n);
           
          }

          The GetDragIconFromBits function turns the bits into a bitmap.

          static Widget
          GetDragIconFromBits(Widget w, char *bits, char *mask, Dimension width,
                              Dimension height, Pixel background, 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 GetDragIcon function uses the bitmap created by the GetDragIconFromBits function to create a drag icon.

          static Widget
          GetDragIcon(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++;
              if (iconMask != XmUNSPECIFIED_PIXMAP &&
                  iconMask != None) {
                XtSetArg(args[n], XmNmask, iconMask); n++;
              }
              dragIcon = XmCreateDragIcon(w, "dragIcon", args, n);
           
              return(dragIcon);
          }

          Drag Callbacks

          Callbacks notify the initiator of how the drag is proceeding. The receiver's XmNdragProc (if any) is first notified of the action and given a chance to update the operation, operations, and dropSiteStatus 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 enable the initiator to monitor the progress of the drag and manage its visual effects accordingly. Otherwise, the toolkit on the initiator side handles the drag-over effects.

          XmNdragMotionCallback

          Called when the drag icon is in motion

          XmNoperationChangedCallback

          Called when the user requests a different operation be performed on the drop than was previously in effect

          XmNdropSiteEnterCallback

          Called when the drag icon enters a drop site

          XmNdropSiteLeaveCallback

          Called when the drag icon leaves a drop site

          XmNtopLevelEnterCallback

          Called when the drag icon enters a top-level window or root window (when changing screens)

          XmNtopLevelLeaveCallback

          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 callback structures for XmNdragMotionCallback, XmNoperationChangedCallback, and XmNdropSiteEnterCallback contain the operations, operation, and dropSiteStatus fields (among others), which are initialized by the toolkit before the callback is called.

          The operations field lists all operations possible for a drop on the current site, whether the site is registered as a DropSite or not. The toolkit initializes the operations field as follows:

          1. If the receiver's XmNdragProc was called, the value of operations is the list of operations common to the value of the XmNdragProc's operations field at the end of XmNdragProc and the DropSite's XmNdropSiteOperations list.

          2. If the XmNdragProc routine was not called but the user selected an operation, operations is set to that operation if it is in the XmNdragOperations list. If it is not in the list, operations is set to XmDROP_NOOP.

          3. Otherwise, the operations field is initialized to the list in the DragContext's XmNdragOperations resource.

            The operation field shows the operation that will occur if a drop happens at the current cursor location. It is initialized as follows:

            1. If the receiver's XmNdragProc was called, operation is initialized to the value of operation at the end of the XmNdragProc.

            2. If the XmNdragProc routine was not called but the pointer is in or entering an active drop site, the toolkit initializes operation by taking the following steps, in order of precedence from highest to lowest:

              1. If Move is in both the operations field and the DropSite's XmNdropSiteOperations list, operation is set to XmDROP_MOVE.

              2. If Copy is in both the operations field and the DropSite's XmNdropSiteOperations list, operation is set to XmDROP_COPY.

              3. If Link is in both the operations field and the DropSite's XmNdropSiteOperations list, operation is set to XmDROP_LINK.

              4. Otherwise, operation is set to XmDROP_NOOP.

              5. Otherwise, the toolkit initializes operation by taking the following steps, in order of precedence from highest to lowest:

                1. If Move is in the operations field, operation is set to XmDROP_MOVE.

                2. If Copy is in the operations field, operation is set to XmDROP_COPY.

                3. If Link is in the operations field, operation is set to XmDROP_LINK.

                4. Otherwise, operation is set to XmDROP_NOOP.

                  The dropSiteStatus 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 toolkit initializes the dropSiteStatus field as follows:

                  1. If the pointer is over an active drop site:

                    1. If the receiver's XmNdragProc was called, dropSiteStatus is initialized to the value of dropSiteStatus at the end of the XmNdragProc procedure.

                    2. If the XmNdragProc routine was not called but the initiator and receiver have at least one target and one operation in common, dropSiteStatus is initialized to XmDROP_SITE_VALID.

                    3. Otherwise, dropSiteStatus is initialized to XmDROP_SITE_INVALID.

                    4. If the pointer is not over an active drop site, dropSiteStatus is initialized to XmNO_DROP_SITE.

                    5. If the operation field is XmDROP_NOOP, dropSiteStatus is initialized to XmDROP_SITE_INVALID.

                      If the application has not stored the DragContext ID in a global location, these callbacks can find the DragContext ID by passing the timeStamp field from the callback structure to the XmGetDragContext function.

                      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);
                            }
                         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. The following example adds a callback named EnterCB that is performed when the pointer enters an active drop site:

                      Widget       dc;
                       
                         dc = XmeDragSource(w, location_data, event, args, n);
                         XtAddCallback(dc, XmNdropSiteEnterCallback, EnterCB, NULL);

                    6. Getting Data about the Current Drop Site

                      The initiator can find information about the current drop site with the XmDropSiteRetrieve 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);

                      Cancelling the Drag

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

                      1. The user can press osfCancel.

                      2. The initiator can call the XmDragCancel function if it decides the drag should not continue for some reason.

                        The initiator is notified of the cancel by the XmNdropStartCallback with a dropAction field value of XmDROP_CANCEL.

                        The receiver is notified by a XmCR_DROP_SITE_LEAVE_MESSAGE message. This message is processed by the XmNdragProc in the dynamic protocol mode. This allows any drag-under effects to be undone.


                      3. [ Previous | Next | Contents | Glossary | Home | Search ]