Atom *selection;
Atom *type;
XtPointer value;
unsigned long *length;
int *format;
The widget parameter is the widget that requested the data, and client_data is the data specified in the
client_data field of the XmDropTransferEntryRec that is being processed. The type, value, length,
and format arguments contain the data that was converted by the drag source in its XmN-convertProc.
The TransferProc() routine in the source code checks the type to determine what needs to be done with the
data. If the data is FILE_CONTENTS data, the text in value is placed in the Text widget with
XmTextSetString(). Otherwise, the text is used to create a new value for XmN-labelString for the file
status area. Since the file status area requests both target data types, both formats are processed by
TransferProc().
The HandleDropText() routine for the ScrolledText object is very similar to HandleDropLabel(). The main
difference is that the routine for the text area checks the XmN-exportTargets resource of the DragContext object
to determine whether or not the drag source provides file data. If it does, HandleDropText() initiates the data
transfer just as in HandleDropLabel(). Otherwise, the text routine calls the XmN-dropProc that we retrieved
from the Text widget when we modified the drop site. By calling the original drop routine, we allow the Text widget
to process textual data as it would by default. As a result, the user can drop a file object in the text entry area, as well
as manipulate textual data in the widget using drag and drop.
Once a data transfer is in progress, additional targets for the DropTransfer object can be specified using
XmDropTransferAdd(). The primary use of this routine is for move operations. In this case, the drop site receives
a copy of the data from the drag source and then requests that the source delete the data. Once the drop site has stored
the data, it can call XmDropTransferAdd() to specify the DELETE target, which indicates to the initiating
application that it should delete the data.
19.5.4 Providing Help
Since it is not always obvious what will happen when data is dropped on a particular drop site, the user can request
help on a drop site by pressing the HELP or F1 key when the drag icon is over the drop site. An application should
provide help information for its drop sites to assist users in understanding the drag and drop capabilities of the
application. When the user requests help, the drop site should respond by posting an InformationDialog that explains
what would happen and allows the user to proceed with the drop or cancel it.
When the user presses HELP while the drag icon is over a drop site, the XmN-dropProc for the drop site is called
with the dropAction field in the callback structure set to to XmDROP_HELP. the source code shows a new
HandleDropLabel() routine for the editor_dnd.c application that provides help for the file status drop site. The
example also shows the HandleDropOK() and HandleDropCancel() callback routines for the help dialog.
/* HandleDropLabel() −− start the data transfer when data is dropped in
* the filename status area.
*/
void
HandleDropLabel(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
Display *dpy;
19 Drag and Drop 19.5.4 Providing Help
556
Atom FILE_CONTENTS, FILE_NAME;
XmDropProcCallback DropData;
XmDropTransferEntryRec transferEntries[2];
XmDropTransferEntry transferList;
Arg args[10];
int n, i;
Widget dc;
Cardinal numExportTargets;
Atom *exportTargets;
Boolean file_name = False;
static XmDropProcCallbackStruct client;
static Widget dialog = NULL;
XmString message;
void HandleDropOK(), HandleDropCancel();
void TransferProc();
/* intern the Atoms for data targets */
dpy = XtDisplay (toplevel);
FILE_CONTENTS = XmInternAtom (dpy, "FILE_CONTENTS", False);
FILE_NAME = XmInternAtom (dpy, "FILE_NAME", False);
DropData = (XmDropProcCallback) call_data;
dc = DropData−>dragContext;
/* retrieve the data targets and search for FILE_NAME */
n = 0;
XtSetArg (args[n], XmNexportTargets, &exportTargets); n++;
XtSetArg (args[n], XmNnumExportTargets, &numExportTargets); n++;
XtGetValues (dc, args, n);
for (i = 0; i < numExportTargets; i++) {
if (exportTargets[i] == FILE_NAME) {
file_name = True;
break;
}
}
/* if one of the targets is not FILE_NAME, transfer fails */
if (!file_name) {
n = 0;
XtSetArg (args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg (args[n], XmNnumDropTransfers, 0); n++;
}
/* check if the user has requested help */
else if (DropData−>dropAction == XmDROP_HELP) {
/* create a dialog if it doesn't already exist */
if (!dialog) {
n = 0;
message = XmStringCreateLtoR (help_str, XmFONTLIST_DEFAULT_TAG);
XtSetArg (args[n], XmNdialogStyle,
XmDIALOG_FULL_APPLICATION_MODAL); n++;
XtSetArg (args[n], XmNtitle, "Drop Help"); n++;
XtSetArg (args[n], XmNmessageString, message); n++;
dialog = XmCreateInformationDialog (toplevel, "help", args, n);
XmStringFree (message);
XtUnmanageChild (XmMessageBoxGetChild
(dialog, XmDIALOG_HELP_BUTTON));
XtAddCallback (dialog, XmNokCallback, HandleDropOK,
(XtPointer) &client);
19 Drag and Drop 19.5.4 Providing Help
557
XtAddCallback (dialog, XmNcancelCallback, HandleDropCancel,
(XtPointer) &client);
}
/* set up the callback structure for when the user proceeds
* with the drop and pass it as client data to the callbacks
* for the buttons.
*/
client.dragContext = dc;
client.x = DropData−>x;
client.y = DropData−>y;
client.dropSiteStatus = DropData−>dropSiteStatus;
client.operation = DropData−>operation;
client.operations = DropData−>operations;
XtManageChild (dialog);
return;
}
else if (DropData−>operation != XmDROP_COPY) {
/* if the operation is not a copy, the transfer fails */
n = 0;
XtSetArg (args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg (args[n], XmNnumDropTransfers, 0); n++;
}
else {
/* set up transfer requests since this is a normal drop */
n = 0;
transferEntries[0].target = FILE_CONTENTS;
transferEntries[0].client_data = (XtPointer) text_edit;
transferEntries[1].target = FILE_NAME;
transferEntries[1].client_data = (XtPointer) file_label;
transferList = transferEntries;
XtSetArg (args[n], XmNdropTransfers, transferEntries); n++;
XtSetArg (args[n], XmNnumDropTransfers,
XtNumber (transferEntries)); n++;
XtSetArg (args[n], XmNtransferProc, TransferProc); n++;
}
XmDropTransferStart (dc, args, n);
}
/* HandleDropOK() −− callback routine for OK button in drop site help
* dialog that processes the drop as normal.
*/
void
HandleDropOK(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
Display *dpy;
Atom FILE_CONTENTS, FILE_NAME;
XmDropProcCallbackStruct *DropData;
XmDropTransferEntryRec transferEntries[2];
XmDropTransferEntry transferList;
Arg args[10];
int n;
Widget dc;
void TransferProc();
/* intern the Atoms for data targets */
dpy = XtDisplay (toplevel);
19 Drag and Drop 19.5.4 Providing Help
558
FILE_CONTENTS = XmInternAtom (dpy, "FILE_CONTENTS", False);
FILE_NAME = XmInternAtom (dpy, "FILE_NAME", False);
/* get the callback structure passed via client data */
DropData = (XmDropProcCallbackStruct *) client_data;
dc = DropData−>dragContext;
n = 0;
/* if operation is not a copy, the transfer fails */
if (DropData−>operation != XmDROP_COPY) {
XtSetArg (args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg (args[n], XmNnumDropTransfers, 0); n++;
}
else {
/* set up transfer requests to process data transfer */
transferEntries[0].target = FILE_CONTENTS;
transferEntries[0].client_data = (XtPointer) text_edit;
transferEntries[1].target = FILE_NAME;
transferEntries[1].client_data = (XtPointer) file_label;
transferList = transferEntries;
XtSetArg (args[n], XmNdropTransfers, transferEntries); n++;
XtSetArg (args[n], XmNnumDropTransfers,
XtNumber (transferEntries)); n++;
XtSetArg (args[n], XmNtransferProc, TransferProc); n++;
}
XmDropTransferStart (dc, args, n);
}
/* HandleDropCancel() −− callback routine for Cancel button in drop site
* help dialog that cancels the transfer.
*/
void
HandleDropCancel(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
XmDropProcCallbackStruct *DropData;
Arg args[10];
int n;
Widget dc;
/* get the callback structures passed via client data */
DropData = (XmDropProcCallbackStruct *) client_data;
dc = DropData−>dragContext;
/* user has canceled the transfer, so it fails */
n = 0;
XtSetArg (args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg (args[n], XmNnumDropTransfers, 0); n++;
XmDropTransferStart (dc, args, n);
}
When the user requests help on the file status drop site, the application displays a help dialog, as shown in the figure.
19 Drag and Drop 19.5.4 Providing Help
559

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.