Motif Drag And Drop with Exceed Server

This forum is read only. No new submissions are accepted.

Questions about motif? Contact us

1 post / 0 new
Motif Drag And Drop with Exceed Server

Submitted by Anonymous on Thu, 02/20/2003 - 08:50.

*************************************************************************************************
Drag and Drop problem on WinNT using Exceed X Server
*************************************************************************************************

I experienced a quite large problem with X/Motif Drag And Drop functionality.
I use
Motif 2.1.0
Exceed X Server for Win32 V 7.0.0.0 (HummingBird Application for NT platforms)
Win2000 Pro

My application is written with X/Motif and it needs to perfom DAD between widgets.
The problem happens when i try to drop an object on a drop site that is the same as the drag site.
This problem doesn`t appear on any other OS like Linux, Sgi or Sun. It only appears with Windows.

It seems that at the moment i drag my object, the registered drag site doesn`t receive
any event anymore till i release the drag button (EnterLeave callback or any other callback
registered on my drag site are not called anymore).
If the pointer moves over any other dropsite (different from the dragsite), everything goes
well. Only drag site seems to be locked, unsensitive to any event.

Is there a ressource or anything i could modify to prevent this problem ???
Thanks to anyone who could help me.

Here is a part of the code i built

*********** I use this function to register my drag site *******************************
void MakeDragInitiator(Widget w, GetDragDataProc get_drag_data)
{
XtAddEventHandler(w, Button1MotionMask, False, start_drag, (XtPointer)get_drag_data);
}

********** I use this function to perform drop ****************************************
void MakeDropSite(Widget w,
XtCallbackProc drop_paste_cb,
XtCallbackProc drop_delete_cb,
Boolean allow_dynamic_link)
{
Atom targets[2];
Display *display = XtDisplay(w);
Arg args[10];

DEFAULT_TARGET = XmInternAtom(display, "DEFAULT_TARGET", False);
REGISTERS_TARGET = XmInternAtom(display, "REGISTERS_TARGET", False);
targets[0] = DEFAULT_TARGET;
targets[1] = REGISTERS_TARGET;

/* Enregistre dans la widget la m?thode de r?cup?ration des ?l?ments */
XtSetArg(args[0], XtNdropPasteCallback, drop_paste_cb);
XtSetArg(args[1], XtNdropDeleteCallback, drop_delete_cb);
XtSetValues(w, args, 2);

/* Enregistre la widget comme destination (drop site) */
if (allow_dynamic_link)
XtSetArg(args[0], XmNdropSiteOperations, XmDROP_COPY | XmDROP_MOVE
| XmDROP_LINK);
else
XtSetArg(args[0], XmNdropSiteOperations, XmDROP_COPY | XmDROP_MOVE );
XtSetArg(args[1], XmNimportTargets, targets);
XtSetArg(args[2], XmNnumImportTargets, 2);
XtSetArg(args[3], XmNdropProc, handle_drop);
XtSetArg(args[4], XmNdragOperations, XmDROP_COPY | XmDROP_MOVE | XmDROP_LINK);
XtSetArg(args[5], XmNdragProc, DummyDrop);
XmDropSiteRegister(w, args, 6);
}

************* The other DAD functions i built **********************************************
/* ARGSUSED */
static void classic_transfer_callback(Widget w,
XtPointer client_data,
Atom selection_type,
Atom *type,
XtPointer value,
unsigned long length,
int *format)
{
XtCallbackProc drop_paste_cb = NULL;
Arg args[2];
DropTarget *drop_target;

drop_target = (DropTarget *)client_data;

XtSetArg(args[0], XtNdropPasteCallback, &drop_paste_cb);

if( drop_target->drop_site !=NULL)
XtGetValues(drop_target->drop_site, args, 1);
else {
return;
}

if (value) {
DragData *drag_data = ((DragData *)value);
drop_target->nb_tuples = drag_data->nb_tuples;
drop_target->nb_registers = drag_data->nb_registers;
drop_target->tuples = drag_data->tuples;
drop_target->registers = drag_data->registers;
if (drop_paste_cb)
drop_paste_cb( drop_target->drop_site, (XtPointer) drop_target, NULL);
UtlFreeList2 ((void **) drag_data->tuples, drag_data->nb_tuples);
XtFree(drag_data);
}
}

/* ARGSUSED */
static void handle_drop(Widget w,
XtPointer client_data,
XtPointer call_data)
{
XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *)call_data;
Arg args[10];
int n = 0;
XmDropTransferEntryRec transfer_entries[2];
DropTarget *drop_target;

/* On n`a pas un drop ou ce n`est pas un drop avec copie */
if (cb->dropAction != XmDROP ||
(cb->operation != XmDROP_COPY &&
cb->operation != XmDROP_MOVE &&
cb->operation != XmDROP_LINK)) {

cb->operation = XmDROP_NOOP;
cb->dropSiteStatus = XmINVALID_DROP_SITE;
XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg(args[n], XmNnumDropTransfers, 0); n++;

}

/* Le drop est ok */
else {
Atom *targets;
int num_targets;
int i;
Boolean (*verify_drop_position_cb)() = NULL;
DragConvertRec *drag_convert;
XtVaGetValues(cb->dragContext, XmNclientData, &drag_convert, NULL);
if ( drag_convert != NULL )
drag_convert->drop_site = w;

XtSetArg(args[0], XtNverifyDropPosition, &verify_drop_position_cb);
XtGetValues(w, args, 1);

if ( drag_convert == NULL || ( verify_drop_position_cb &&
!verify_drop_position_cb(w, cb, drag_convert->initiator) )) {
cb->operation = XmDROP_NOOP;
cb->dropSiteStatus = XmINVALID_DROP_SITE;
XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
XmDropTransferStart(cb->dragContext, args, n);
return;
}

XtVaGetValues(cb->dragContext, XmNexportTargets, &targets, XmNnumExportTargets,
&num_targets, NULL);

for (i = 0; i < num_targets; i++) {

drop_target = malloc( sizeof(DropTarget) );
drop_target->drag_site = drag_convert->initiator;
drop_target->drop_site = w;
drop_target->drop_point.x = cb->x;
drop_target->drop_point.y = cb->y;
drop_target->nb_tuples = 0;
drop_target->nb_registers = 0;
if ( cb->operation == XmDROP_LINK )
drop_target->dynamic = True;
else
drop_target->dynamic = False;

if (targets[i] == REGISTERS_TARGET && cb->operation == XmDROP_MOVE) {

transfer_entries[0].target = REGISTERS_TARGET;
transfer_entries[0].client_data = drop_target;

XtSetArg(args[n], XmNdropTransfers, transfer_entries); n++;
XtSetArg(args[n], XmNnumDropTransfers, 1); n++;
XtSetArg(args[n], XmNtransferProc, transfer_with_delete_callback); n++;
}
else {

transfer_entries[0].target = DEFAULT_TARGET;
transfer_entries[0].client_data = drop_target;

XtSetArg(args[n], XmNdropTransfers, transfer_entries); n++;
XtSetArg(args[n], XmNnumDropTransfers, 1); n++;
XtSetArg(args[n], XmNtransferProc, classic_transfer_callback); n++;
}

}

}

/* On demande a la source de transferrer les donnees */
XmDropTransferStart(cb->dragContext, args, n);
}

/* ARGSUSED */
static void start_drag(Widget w,
XtPointer client_data,
XEvent *event,
Boolean *continueToDispatch)
{
Arg args[100];
Atom targets[1];
GetDragDataProc get_data_proc = (GetDragDataProc)client_data;
DragData *drag_data = NULL; /* Donn?es drag-?es */
DragConvertRec *drag_convert;

/* static XtCallbackRec dragMotionCB[] = {
{drag_motion_callback, NULL},
{NULL, NULL}
}; */
static XtCallbackRec dropSiteEnterCB[] = {
{drop_site_enter_callback, NULL},
{NULL, NULL}
};
static XtCallbackRec dropSiteLeaveCB[] = {
{drop_site_leave_callback, NULL},
{NULL, NULL}
};
static XtCallbackRec operationChangedCB[] = {
{operation_changed_callback, NULL},
{NULL, NULL}
};

/* R?cup?re les donn?es dragu?es avec le processus de
r?cup?ration des donn?es transmis pour v?rifier qu`il y en a bien */
drag_data = get_data_proc(w);
if (drag_data == NULL)
return;
UtlFreeList2 ((void **) drag_data->tuples, drag_data->nb_tuples);
XtFree(drag_data);

/* Pour la creation des pixmaps */
if ( !icons_created ) {
create_drag_icons();
icons_created = True;
}

/* Remplit le drag_context */
drag_convert = XtMalloc(sizeof(DragConvertRec));
drag_convert->initiator = w;
drag_convert->drop_site = NULL;
drag_convert->get_data_proc = get_data_proc;
targets[0] = DEFAULT_TARGET;
XtSetArg(args[0], XmNconvertProc, export_object);
XtSetArg(args[1], XmNexportTargets, targets);
XtSetArg(args[2], XmNnumExportTargets, 1);
XtSetArg(args[3], XmNclientData, drag_convert);
XtSetArg(args[4], XmNdragOperations, XmDROP_COPY | XmDROP_MOVE | XmDROP_LINK);
XtSetArg(args[5], XmNsourceCursorIcon, drag_type_tuple);
XtSetArg(args[6], XmNoperationCursorIcon, drag_op_move);
XtSetArg(args[7], XmNstateCursorIcon, drag_state_valid);
XtSetArg(args[8], XmNcursorBackground, white);
XtSetArg(args[9], XmNcursorForeground, black);
XtSetArg(args[10], XmNinvalidCursorForeground, red);
XtSetArg(args[11], XmNvalidCursorForeground, black);
XtSetArg(args[12], XmNnoneCursorForeground, red);
/* initially only show the source icon */
XtSetArg(args[13], XmNblendModel, XmBLEND_ALL);
/*XtSetArg(args[15], XmNdragMotionCallback, dragMotionCB);*/
XtSetArg(args[14], XmNoperationChangedCallback, operationChangedCB);
XtSetArg(args[15], XmNdropSiteEnterCallback, dropSiteEnterCB);
XtSetArg(args[16], XmNdropSiteLeaveCallback, dropSiteLeaveCB);
(void) XmDragStart(TopLevel, event, args, 17);
}

static Boolean export_object(Widget w, /* Drag context */
Atom *selection,
Atom *target,
Atom *type,
XtPointer *value,
unsigned long *length,
int *format)
{
/* Dans le cas par d?faut, fait une copie des objets */
if (*target == DEFAULT_TARGET) {
DragConvertRec *drag_convert;
DragData *drag_data = NULL;

/* On recupere la structure drag_convert */
XtVaGetValues(w, XmNclientData, &drag_convert, NULL);

/* On recupere les donnees du drag */
drag_data = drag_convert->get_data_proc(drag_convert->initiator);
if (drag_data == NULL) {
return(False);
}

*value = drag_data;
*type = DEFAULT_TARGET;
*format = 32;
*length = 1;
return(True);
}

/* Dans le cas de registres et d`un move, d?truit les objets (cut) */
else if (*target == REGISTERS_TARGET) {
DragConvertRec *drag_convert;
DragData *drag_data = NULL;

/* On recupere la structure drag_convert */
XtVaGetValues(w, XmNclientData, &drag_convert, NULL);

/* On recupere les donnees du drag */
drag_data = drag_convert->get_data_proc(drag_convert->initiator);
if (drag_data == NULL) {
return(False);
}

*value = drag_data;
*type = REGISTERS_TARGET;
*format = 32;
*length = 1;
return(True);
}

return(False);
}