cdesktopenv/cde/programs/dtprintinfo/libUI/MotifUI/DtDND.C

743 lines
22 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $TOG: DtDND.C /main/7 1998/08/03 08:58:53 mgreess $ */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "stdlib.h"
#include "DtDND.h"
#include "IconObj.h"
#include "Icon.h"
#include "Dt/Dnd.h"
#include <Xm/DragCP.h>
#include <Dt/Wsm.h>
#include <Dt/Action.h>
#include <stdio.h>
extern "C" {
extern XtPointer _XmStringUngenerate (
XmString string,
XmStringTag tag,
XmTextType tag_type,
XmTextType output_type);
}
#define DRAG_THRESHOLD 10
// Absolute value macro
#ifndef ABS
#define ABS(x) (((x) > 0) ? (x) : (-(x)))
#endif
boolean DtDND::FirstTime = true;
XtCallbackRec DtDND::transferCBRec[] =
{
{&DtDND::TransferCB, NULL}, {NULL, NULL}
};
XtCallbackRec DtDND::convertCBRec[] =
{
{&DtDND::ConvertCB, NULL}, {NULL, NULL}
};
XtCallbackRec DtDND::dragFinishCBRec[] =
{
{&DtDND::DragFinishCB, NULL}, {NULL, NULL}
};
XtCallbackRec DtDND::dropOnRootCBRec[] =
{
{&DtDND::DropOnRootCB, NULL}, {NULL, NULL}
};
XtCallbackRec DtDND::animateCBRec[] =
{
{&DtDND::AnimateCB, NULL}, {NULL, NULL}
};
boolean DtDND::DoingDrag = false;
GC DtDND::gc;
GC DtDND::gc_mask;
DtDND::DtDND(MotifUI *_obj, DNDCallback _dndCB, boolean _can_drop_on_root)
{
if (FirstTime)
{
MotifUI *tmp = (MotifUI *)_obj;
Pixmap tmp_pixmap;
BaseUI *parent = _obj;
while (parent->Parent())
parent = parent->Parent();
tmp_pixmap = XCreatePixmap(tmp->display, tmp->root, 1, 1, tmp->depth);
gc = XCreateGC(tmp->display, tmp_pixmap, 0, NULL);
tmp_pixmap = XCreatePixmap(tmp->display, tmp->root, 1, 1, 1);
gc_mask = XCreateGC(tmp->display, tmp_pixmap, 0, NULL);
if (tmp->font) {
XSetFont(tmp->display, gc, tmp->font);
}
FirstTime = false;
}
obj = _obj;
can_drop_on_root = _can_drop_on_root;
dndCB = _dndCB;
dragIcon = NULL;
sourceIcon = NULL;
// Set up Drop
transferCBRec[0].closure = (XtPointer)this;
animateCBRec[0].closure = (XtPointer)this;
if (obj->UIClass() == ICON)
{
GetRects();
XtVaSetValues(obj->BaseWidget(), XmNshadowThickness, 2, NULL);
Arg args[6];
XtSetArg(args[0], XmNdropSiteType, XmDROP_SITE_SIMPLE);
XtSetArg(args[1], XmNanimationStyle, XmDRAG_UNDER_SHADOW_IN);
XtSetArg(args[2], XmNnumDropRectangles, 2);
XtSetArg(args[3], XmNdropRectangles, &rects);
XtSetArg(args[4], DtNdropAnimateCallback, animateCBRec);
XtSetArg(args[5], DtNtextIsBuffer, True);
DtDndDropRegister(obj->BaseWidget(), DtDND_FILENAME_TRANSFER|
DtDND_BUFFER_TRANSFER,
(unsigned char)XmDROP_COPY, transferCBRec, args, 6);
// Set up Drag on Button1
XtAddEventHandler(obj->BaseWidget(), Button1MotionMask, False,
(XtEventHandler)DragMotionHandler, (XtPointer)this);
// Set up Drag on Button2 if not using it for BMenu already
if (MotifUI::bMenuButton != Button2)
{
XtAddEventHandler(obj->BaseWidget(), Button2MotionMask, False,
(XtEventHandler)DragMotionHandler, (XtPointer)this);
}
}
else
{
Arg args[2];
XtSetArg(args[0], DtNdropAnimateCallback, animateCBRec);
XtSetArg(args[1], DtNtextIsBuffer, True);
DtDndDropRegister(obj->BaseWidget(), DtDND_FILENAME_TRANSFER|
DtDND_BUFFER_TRANSFER,
(unsigned char)XmDROP_COPY, transferCBRec, args, 2);
}
pixmap = 0L;
mask = 0L;
name = NULL;
iconFile = NULL;
string = NULL;
}
DtDND::~DtDND()
{
MotifUI *icon = (MotifUI *)obj;
if (pixmap && pixmap != XmUNSPECIFIED_PIXMAP)
XFreePixmap(icon->display, pixmap);
if (mask && mask != XmUNSPECIFIED_PIXMAP)
XFreePixmap(icon->display, mask);
free(name);
delete iconFile;
XmStringFree(string);
if (sourceIcon)
{
XtDestroyWidget(sourceIcon);
sourceIcon = NULL;
}
if (dragIcon)
{
XtDestroyWidget(dragIcon);
dragIcon = NULL;
}
}
void DtDND::GetDragPixmaps()
{
IconObj *icon = (IconObj *)obj;
Pixmap tmp_pixmap, tmp_mask;
delete iconFile;
free(name);
XmStringFree(string);
if (pixmap && pixmap != XmUNSPECIFIED_PIXMAP)
XFreePixmap(icon->display, pixmap);
if (mask && mask != XmUNSPECIFIED_PIXMAP)
XFreePixmap(icon->display, mask);
mask = 0L;
pixmap = 0L;
name = strdup(icon->Name());
icon_size = icon->IconView();
selected = icon->Selected();
iconFile = new char[strlen(icon->IconFile()) + 6];
Dimension height, width;
unsigned int w, h, junk;
Window junkwin;
XtVaGetValues(icon->BaseWidget(), XmNbackground, &bg, XmNforeground, &fg,
GuiNselectColor, &selectColor, XmNalignment, &alignment,
GuiNshowSelectedPixmap, &showSelectedPixmap,
XmNstringDirection, &stringDirection,
GuiNtextSelectColor, &textSelectColor,
XmNlabelString, &string, XmNfontList, &fontList, NULL);
XmStringExtent(fontList, string, &width, &height);
if (icon_size == LARGE_ICON)
string_border_width = 1;
else
string_border_width = 0;
height += 2 * string_border_width;
width += 2 * string_border_width;
s_x = s_y = string_border_width;
p_x = p_y = 0;
s_w = width;
s_h = height;
p_w = p_h = 0;
switch (icon_size)
{
case DETAILS:
case SMALL_ICON:
sprintf(iconFile, "%s.t.pm", icon->IconFile());
icon->GetPixmaps(icon->BaseWidget(), iconFile, &tmp_pixmap, &tmp_mask);
if (tmp_pixmap && tmp_pixmap != XmUNSPECIFIED_PIXMAP)
{
XGetGeometry(icon->display, tmp_pixmap, &junkwin,
(int *) &junk, (int *) &junk, &w, &h, &junk, &junk);
p_w = w;
p_h = h;
w += 2;
s_x += w;
width += w;
if (h > height)
{
s_y = (h - height) / 2;
height = h;
}
else
p_y = (height - h) / 2;
}
break;
case LARGE_ICON:
sprintf(iconFile, "%s.m.pm", icon->IconFile());
icon->GetPixmaps(icon->BaseWidget(), iconFile, &tmp_pixmap, &tmp_mask);
if (tmp_pixmap && tmp_pixmap != XmUNSPECIFIED_PIXMAP)
{
XGetGeometry(icon->display, tmp_pixmap, (Window *) &junk,
(int *) &junk, (int *) &junk, &w, &h, &junk, &junk);
p_w = w;
p_h = h;
h += 2;
s_y += h;
height += h;
if (w > width)
width = w;
}
break;
default:
sprintf(iconFile, "%s.m.pm", icon->IconFile());
icon->GetPixmaps(icon->BaseWidget(), iconFile, &tmp_pixmap, &tmp_mask);
break;
}
// Create pixmap
pixmap = XCreatePixmap(icon->display, icon->root, width, height,
icon->depth);
if (icon_size != NAME_ONLY &&
tmp_pixmap && tmp_pixmap != XmUNSPECIFIED_PIXMAP)
{
mask = XCreatePixmap(icon->display, icon->root, width, height, 1);
// Clear mask
XSetForeground(icon->display, gc_mask, 0);
XFillRectangle(icon->display, mask, gc_mask, 0, 0, width, height);
// Set Mask Bits
XSetForeground(icon->display, gc_mask, 1);
if (icon_size == LARGE_ICON)
{
#ifndef hpux
if (tmp_mask && tmp_mask != XmUNSPECIFIED_PIXMAP)
{
XSetClipOrigin(icon->display, gc_mask, p_x, p_y);
XSetClipMask(icon->display, gc_mask, tmp_mask);
XFillRectangle(icon->display, mask, gc_mask, p_x, p_y, p_w, p_h);
XSetClipMask(icon->display, gc_mask, None);
XSetClipOrigin(icon->display, gc_mask, 0, 0);
}
else
#endif
XFillRectangle(icon->display, mask, gc_mask, p_x, p_y, p_w, p_h);
}
else
XFillRectangle(icon->display, mask, gc_mask, p_x, p_y, p_w - 1,
p_h - 1);
if (icon_size == LARGE_ICON)
XFillRectangle(icon->display, mask, gc_mask, s_x - string_border_width,
s_y - string_border_width,
s_w + 2 * string_border_width,
s_h + 2 * string_border_width);
else
XFillRectangle(icon->display, mask, gc_mask, s_x, s_y, s_w - 1,
s_h - 1);
}
// If selected use selectColor as background
if (showSelectedPixmap && selected)
bg = selectColor;
// Copy Pixmap to new pixmap
XSetClipMask(icon->display, gc, None);
XSetFillStyle(icon->display, gc, FillSolid);
XSetForeground(icon->display, gc, bg);
if (icon_size == LARGE_ICON)
XFillRectangle(icon->display, pixmap, gc, p_x, p_y, p_w, p_h);
else
XFillRectangle(icon->display, pixmap, gc, p_x, p_y, p_w - 1, p_h - 1);
XSetClipOrigin(icon->display, gc, p_x, p_y);
if (tmp_mask && tmp_mask != XmUNSPECIFIED_PIXMAP)
XSetClipMask(icon->display, gc, tmp_mask);
else
XSetClipMask(icon->display, gc, None);
if (icon_size == LARGE_ICON)
XCopyArea(icon->display, tmp_pixmap, pixmap, gc, 0, 0, p_w, p_h,
p_x, p_y);
else
XCopyArea(icon->display, tmp_pixmap, pixmap, gc, 0, 0, p_w - 1, p_h - 1,
p_x, p_y);
XSetClipMask(icon->display, gc, None);
XSetClipOrigin(icon->display, gc, 0, 0);
DrawString();
Arg args[11];
int n = 0;
w = width;
h = height;
XtSetArg(args[n], XmNwidth, w); n++;
XtSetArg(args[n], XmNheight, h); n++;
XtSetArg(args[n], XmNmaxWidth, w); n++;
XtSetArg(args[n], XmNmaxHeight, h); n++;
XtSetArg(args[n], XmNdepth, icon->depth); n++;
XtSetArg(args[n], XmNforeground, bg); n++;
XtSetArg(args[n], XmNbackground, fg); n++;
XtSetArg(args[n], XmNpixmap, pixmap); n++;
if (mask)
{
XtSetArg(args[n], XmNmask, mask);
n++;
}
dragIcon = XmCreateDragIcon(icon->BaseWidget(), "dragIcon", args, n);
n = 0;
if (icon_size == LARGE_ICON)
sprintf(iconFile, "%s.m.bm", icon->IconFile());
else
sprintf(iconFile, "%s.t.bm", icon->IconFile());
icon->GetPixmaps(icon->BaseWidget(), iconFile, &tmp_pixmap);
if (!(tmp_pixmap && tmp_pixmap != XmUNSPECIFIED_PIXMAP))
{
static Pixmap l_pixmap = (Pixmap)NULL, s_pixmap = (Pixmap)NULL;
if (icon_size == LARGE_ICON)
{
if (!l_pixmap)
{
l_pixmap = XCreatePixmap(icon->display, icon->root, p_w, p_h, 1);
XFillRectangle(icon->display, l_pixmap, gc_mask, 0, 0, p_w, p_h);
}
tmp_pixmap = l_pixmap;
}
else
{
if (icon_size == NAME_ONLY)
{
p_w = 16;
p_h = 16;
}
if (!s_pixmap)
{
s_pixmap = XCreatePixmap(icon->display, icon->root, p_w, p_h, 1);
XFillRectangle(icon->display, s_pixmap, gc_mask, 0, 0, p_w, p_h);
}
tmp_pixmap = s_pixmap;
}
}
if (icon_size == NAME_ONLY)
{
w = 16;
h = 16;
}
else
{
w = p_w;
h = p_h;
}
XtSetArg(args[n], XmNwidth, w); n++;
XtSetArg(args[n], XmNheight, h); n++;
XtSetArg(args[n], XmNmaxWidth, w); n++;
XtSetArg(args[n], XmNmaxHeight, h); n++;
XtSetArg(args[n], XmNdepth, 1); n++;
XtSetArg(args[n], XmNforeground, icon->black); n++;
XtSetArg(args[n], XmNbackground, icon->white); n++;
XtSetArg(args[n], XmNpixmap, tmp_pixmap); n++;
if (tmp_mask && tmp_mask != XmUNSPECIFIED_PIXMAP)
{
XtSetArg(args[n], XmNmask, tmp_mask);
n++;
}
sourceIcon = XmCreateDragIcon(icon->BaseWidget(), "sourceIcon", args, n);
strcpy(iconFile, icon->IconFile());
}
void DtDND::DrawString()
{
IconObj *icon = (IconObj *)obj;
// Draw String
if (selected)
XSetForeground(icon->display, gc, selectColor);
else
XSetForeground(icon->display, gc, bg);
if (icon_size == LARGE_ICON)
XFillRectangle(icon->display, pixmap, gc, s_x - string_border_width,
s_y - string_border_width, s_w + 2 * string_border_width,
s_h + 2 * string_border_width);
else
XFillRectangle(icon->display, pixmap, gc, s_x, s_y, s_w - 1, s_h - 1);
// If selected use selectColor as background
if (selected)
XSetForeground(icon->display, gc, textSelectColor);
else
XSetForeground(icon->display, gc, fg);
XmStringDraw(icon->display, pixmap, fontList, string, gc, s_x, s_y, s_w,
alignment, stringDirection, NULL);
}
void DtDND::GetRects()
{
Dimension shadow, highlight, margin;
XtVaGetValues(obj->BaseWidget(), XmNhighlightThickness, &highlight,
GuiNiconMarginThickness, &margin,
GuiNiconShadowThickness, &shadow, NULL);
margin += (shadow + highlight);
GuiIconGetRects(obj->BaseWidget(), &rects[0], &rects[1]);
rects[0].x -= margin;
rects[0].y -= margin;
rects[0].width += (2 * margin);
rects[0].height += (2 * margin);
rects[1].x -= margin;
rects[1].y -= margin;
rects[1].width += (2 * margin);
rects[1].height += (2 * margin);
}
void DtDND::UpdateActivity(boolean flag)
{
Arg args[3];
int n = 0;
if (flag)
{
XtSetArg(args[n], XmNdropSiteOperations, XmDROP_COPY | XmDROP_MOVE); n++;
XtSetArg(args[n], XmNdropSiteActivity, XmDROP_SITE_ACTIVE); n++;
if (obj->UIClass() == ICON)
XtSetArg(args[n], XmNanimationStyle, XmDRAG_UNDER_SHADOW_IN);
else
XtSetArg(args[n], XmNanimationStyle, XmDRAG_UNDER_HIGHLIGHT);
n++;
}
else
{
XtSetArg(args[n], XmNdropSiteOperations, XmDROP_NOOP); n++;
XtSetArg(args[n], XmNdropSiteActivity, XmDROP_SITE_INACTIVE); n++;
XtSetArg(args[n], XmNanimationStyle, XmDRAG_UNDER_NONE); n++;
}
XmDropSiteUpdate(obj->BaseWidget(), args, n);
if (flag)
XmDropSiteConfigureStackingOrder(obj->BaseWidget(), NULL, XmABOVE);
else
XmDropSiteConfigureStackingOrder(obj->BaseWidget(), NULL, XmBELOW);
}
void DtDND::UpdateRects()
{
Arg args[2];
GetRects();
XtSetArg(args[0], XmNnumDropRectangles, 2);
XtSetArg(args[1], XmNdropRectangles, &rects);
XmDropSiteUpdate(obj->BaseWidget(), args, 2);
}
void DtDND::AnimateCB(Widget /*widget*/, XtPointer client_data,
XtPointer call_data)
{
DtDND *obj = (DtDND *)client_data;
if (obj->dndCB)
{
DtDndDropAnimateCallbackStruct *animateInfo;
animateInfo = (DtDndDropAnimateCallbackStruct *) call_data;
int i = 0, numItems;
numItems = animateInfo->dropData->numItems;
//for (i = 0; i < numItems; i++)
{
(*obj->dndCB)(obj->obj, NULL, NULL, ANIMATE);
}
}
}
void DtDND::TransferCB(Widget /*widget*/, XtPointer client_data,
XtPointer call_data)
{
DtDndTransferCallbackStruct *transferInfo;
transferInfo = (DtDndTransferCallbackStruct *) call_data;
char *value;
int len, i, numItems;
DtDND *obj = (DtDND *)client_data;
numItems = transferInfo->dropData->numItems;
switch (transferInfo->dropData->protocol)
{
case DtDND_FILENAME_TRANSFER:
if (obj->dndCB)
{
for (i = 0; i < numItems; i++)
{
value = transferInfo->dropData->data.files[i];
len = strlen(value);
(*obj->dndCB)(obj->obj, &value, &len, FILENAME_TRANSFER);
}
}
break;
case DtDND_TEXT_TRANSFER:
if (obj->dndCB)
{
for (i = 0; i < numItems; i++)
{
value = (char *) _XmStringUngenerate(
transferInfo->dropData->data.strings[i], NULL,
XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
len = strlen(value);
(*obj->dndCB)(obj->obj, &value, &len, TEXT_TRANSFER);
if (NULL != value)
XtFree(value);
}
}
break;
case DtDND_BUFFER_TRANSFER:
if (obj->dndCB)
{
(*obj->dndCB)(obj->obj, &value, &len, BUFFER_TRANSFER);
DtActionArg *aap = new DtActionArg[numItems];
memset(aap, 0, numItems * sizeof(DtActionArg));
for (i = 0; i < numItems; i++)
{
aap[i].argClass = DtACTION_BUFFER;
aap[i].u.buffer.bp = transferInfo->dropData->data.buffers[i].bp;
aap[i].u.buffer.size = transferInfo->dropData->data.buffers[i].size;
aap[i].u.buffer.name = transferInfo->dropData->data.buffers[i].name;
}
MotifUI *tmp = (MotifUI *)obj->obj;
DtActionInvoke(tmp->topLevel, value, aap, numItems, NULL, NULL, NULL,
1, NULL, NULL);
delete aap;
delete value;
}
break;
default:
transferInfo->status = DtDND_FAILURE;
break;
}
}
void DtDND::DragMotionHandler(Widget /*widget*/, XtPointer client_data,
XEvent *event, Boolean * /*continued*/)
{
static int initialX = -1;
static int initialY = -1;
int diffX, diffY;
DtDND *obj = (DtDND *)client_data;
if (obj->DoingDrag)
return;
// If the drag is just starting, set initial button down coords
if (initialX == -1 && initialY == -1)
{
initialX = event->xmotion.x;
initialY = event->xmotion.y;
}
// Find out how far pointer has moved since button press
diffX = initialX - event->xmotion.x;
diffY = initialY - event->xmotion.y;
if ((ABS(diffX) >= DRAG_THRESHOLD) ||
(ABS(diffY) >= DRAG_THRESHOLD))
{
obj->DoingDrag = true;
obj->StartDrag(event);
initialX = -1;
initialY = -1;
}
}
void DtDND::DragFinishCB(Widget /*widget*/, XtPointer client_data,
XtPointer /*callData*/)
{
DtDND *obj = (DtDND *) client_data;
obj->DoingDrag = false;
}
void DtDND::StartDrag(XEvent *event)
{
IconObj *icon = (IconObj *)obj;
convertCBRec[0].closure = (XtPointer)this;
dragFinishCBRec[0].closure = (XtPointer)this;
dropOnRootCBRec[0].closure = (XtPointer)this;
if ((!STRCMP(name, icon->Name()) || !STRCMP(iconFile, icon->IconFile()) ||
icon_size != icon->IconView()) && dragIcon)
{
XtDestroyWidget(dragIcon);
XtDestroyWidget(sourceIcon);
dragIcon = NULL;
sourceIcon = NULL;
}
if (!dragIcon)
GetDragPixmaps();
else if (selected != icon->Selected())
{
selected = icon->Selected();
DrawString();
}
Arg arg[3];
XtSetArg(arg[0], DtNsourceIcon, (XtArgVal)dragIcon);
XtSetArg(arg[1], XmNsourceCursorIcon, (XtArgVal)sourceIcon);
XtSetArg(arg[2], DtNdropOnRootCallback, dropOnRootCBRec);
Widget dc = DtDndDragStart(obj->BaseWidget(), event, DtDND_FILENAME_TRANSFER,
1, (unsigned char)(XmDROP_COPY | XmDROP_MOVE),
convertCBRec, dragFinishCBRec, arg,
can_drop_on_root ? 3 : 2);
if (dc)
{
XmDragContext xmDragContext = (XmDragContext) dc;
XtVaSetValues((Widget)xmDragContext->drag.curDragOver,
XmNdragOverMode, XmPIXMAP, NULL);
}
else
fprintf(stderr, "DtDndDragStart returned NULL.\n");
}
void DtDND::ConvertCB(Widget /*dragContext*/, XtPointer client_data,
XtPointer call_data)
{
char *value;
DtDndConvertCallbackStruct *convertInfo;
int len, i, numFiles;
DtDND *obj = (DtDND *) client_data;
convertInfo = (DtDndConvertCallbackStruct *) call_data;
numFiles = convertInfo->dragData->numItems;
switch (convertInfo->reason)
{
case DtCR_DND_CONVERT_DATA:
if (obj->dndCB)
{
for (i = 0; i < numFiles; i++)
{
value = NULL;
(*obj->dndCB)(obj->obj, &value, &len, CONVERT_DATA);
if (value && *value)
convertInfo->dragData->data.files[i] = value;
else
{
convertInfo->status = DtDND_FAILURE;
return;
}
}
}
break;
case DtCR_DND_CONVERT_DELETE:
if (obj->dndCB)
{
for (i = 0; i < numFiles; i++)
{
value = convertInfo->dragData->data.files[i];
len = strlen(value);
(*obj->dndCB)(obj->obj, &value, &len, CONVERT_DELETE);
}
}
break;
}
}
void DtDND::DropOnRootCB(Widget /*dragContext*/, XtPointer client_data,
XtPointer call_data)
{
char *value;
int len, x, y, i, numFiles;
DtDND *obj = (DtDND *) client_data;
DtDndDropCallbackStruct *fileList = (DtDndDropCallbackStruct *)call_data;
MotifUI *tmp = (MotifUI *)obj->obj;
Atom pCurrent;
char *workspace_name = NULL;
if (DtWsmGetCurrentWorkspace(tmp->display, tmp->root, &pCurrent) ==
Success)
{
workspace_name = XGetAtomName(tmp->display, pCurrent);
}
numFiles = fileList->dropData->numItems;
fileList->completeMove = False;
x = fileList->x;
y = fileList->y;
int max_len = 0;
for(i = 0; i < numFiles; i++)
if ((len = strlen(fileList->dropData->data.files[i])) > max_len)
max_len = len;
if (workspace_name)
value = new char[max_len + strlen(workspace_name) + 30];
else
value = new char[max_len + 30];
for(i = 0; i < numFiles; i++)
{
if (workspace_name)
sprintf(value, "%d\n%d\n%s \n%s", x, y,
fileList->dropData->data.files[i], workspace_name);
else
sprintf(value, "%d\n%d\n%s", x, y, fileList->dropData->data.files[i]);
len = strlen(value);
(*obj->dndCB)(obj->obj, &value, &len, DROP_ON_ROOT);
y += 20;
x += 20;
}
delete value;
}