Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
548
cde/lib/DtSvc/DtUtil1/DndIcon.c
Normal file
548
cde/lib/DtSvc/DtUtil1/DndIcon.c
Normal file
@@ -0,0 +1,548 @@
|
||||
/* $XConsortium: DndIcon.c /main/5 1996/06/21 17:28:34 ageorge $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndIcon.c
|
||||
*
|
||||
* Description: Implemenation of DND drag icons
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement between
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (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.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/Screen.h>
|
||||
#include <Xm/DragIcon.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DndIconI.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Component types of a drag icon (source/state/operation)
|
||||
*/
|
||||
|
||||
enum {
|
||||
DtDND_DRAG_SOURCE,
|
||||
DtDND_DRAG_STATE,
|
||||
DtDND_DRAG_OPERATION
|
||||
};
|
||||
|
||||
/*
|
||||
* The XmDragIcon widgets for the state & operation components
|
||||
* of a Drag Icon
|
||||
*/
|
||||
|
||||
typedef struct _DragIcons {
|
||||
Widget validIcon, invalidIcon, noneIcon;
|
||||
Widget moveIcon, copyIcon, linkIcon;
|
||||
} DragIcons;
|
||||
|
||||
/*
|
||||
* Collection of drag icons for text & data drags
|
||||
*/
|
||||
|
||||
typedef struct _DragCollection {
|
||||
DtDndDragSource sourceType;
|
||||
DragIcons text;
|
||||
DragIcons data;
|
||||
Widget textSource;
|
||||
Widget dataSource;
|
||||
Widget multipleSource;
|
||||
} DragCollection;
|
||||
|
||||
/*
|
||||
* The context that the DragCollection is stored against.
|
||||
* Used in getDragCollection() and destroyDragCollection().
|
||||
*/
|
||||
|
||||
static XContext dragCollectionContext;
|
||||
|
||||
/*
|
||||
* Creates an XmDragIcon for use as the source component of the drag icon.
|
||||
*/
|
||||
Widget
|
||||
DtDndCreateSourceIcon(
|
||||
Widget widget,
|
||||
Pixmap pixmap,
|
||||
Pixmap mask)
|
||||
{
|
||||
Widget dragIcon;
|
||||
Window rootWindow;
|
||||
int pixmapX, pixmapY;
|
||||
unsigned int pixmapWidth, pixmapHeight, pixmapBorder, pixmapDepth;
|
||||
Arg args[20];
|
||||
Cardinal nn = 0;
|
||||
_DtSvcWidgetToAppContext(widget);
|
||||
|
||||
_DtSvcAppLock(app);
|
||||
|
||||
while (XmIsGadget(widget)) {
|
||||
widget = XtParent(widget);
|
||||
}
|
||||
|
||||
XGetGeometry (XtDisplayOfObject(widget), pixmap, &rootWindow,
|
||||
&pixmapX, &pixmapY, &pixmapWidth, &pixmapHeight,
|
||||
&pixmapBorder, &pixmapDepth);
|
||||
|
||||
XtSetArg(args[nn], XmNwidth, pixmapWidth); nn++;
|
||||
XtSetArg(args[nn], XmNheight, pixmapHeight); nn++;
|
||||
XtSetArg(args[nn], XmNmaxWidth, pixmapWidth); nn++;
|
||||
XtSetArg(args[nn], XmNmaxHeight, pixmapHeight); nn++;
|
||||
XtSetArg(args[nn], XmNpixmap, pixmap); nn++;
|
||||
XtSetArg(args[nn], XmNmask, mask); nn++;
|
||||
XtSetArg(args[nn], XmNdepth, pixmapDepth); nn++;
|
||||
dragIcon = XmCreateDragIcon(widget, "sourceIcon", args, nn);
|
||||
|
||||
_DtSvcAppUnlock(app);
|
||||
return(dragIcon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the x,y offsets for the state cursor relative to the source
|
||||
*/
|
||||
static void
|
||||
calcStateIconOffset(
|
||||
Widget sourceIcon,
|
||||
int *stateOffsetX,
|
||||
int *stateOffsetY)
|
||||
{
|
||||
Display *dpy = XtDisplayOfObject(sourceIcon);
|
||||
Pixmap pixmap;
|
||||
Window root;
|
||||
int pixmapX, pixmapY;
|
||||
unsigned int pixmapW, pixmapH, junk;
|
||||
|
||||
XtVaGetValues(sourceIcon, XmNpixmap, &pixmap, NULL);
|
||||
|
||||
if (pixmap == None)
|
||||
return;
|
||||
|
||||
XGetGeometry(dpy, pixmap, &root,
|
||||
&pixmapX, &pixmapY, &pixmapW, &pixmapH,
|
||||
&junk, &junk);
|
||||
|
||||
if (pixmapH == 16) {
|
||||
*stateOffsetX = *stateOffsetY = 8;
|
||||
} else {
|
||||
*stateOffsetX = *stateOffsetY = 16;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects or activates the request type of source by setting
|
||||
* the default drag icon resources on the XmScreen widget.
|
||||
*/
|
||||
static void
|
||||
selectDragSource(
|
||||
DragCollection *dc,
|
||||
Widget xmScreen,
|
||||
DtDndDragSource sourceType,
|
||||
Widget sourceIcon)
|
||||
{
|
||||
Display *dpy = XtDisplayOfObject(xmScreen);
|
||||
Widget validIcon, invalidIcon, noneIcon,
|
||||
moveIcon, copyIcon, linkIcon,
|
||||
defSourceIcon;
|
||||
int hotX, hotY,
|
||||
stateOffsetX, stateOffsetY,
|
||||
offsetDeltaX, offsetDeltaY;
|
||||
Arg args[30];
|
||||
Cardinal nn = 0;
|
||||
|
||||
/*
|
||||
* Choose the state/operation/default-source drag icons based
|
||||
* on the requested drag-source-type
|
||||
*/
|
||||
switch (sourceType) {
|
||||
case DtDND_DRAG_SOURCE_TEXT:
|
||||
validIcon = dc->text.validIcon;
|
||||
invalidIcon = dc->text.invalidIcon;
|
||||
noneIcon = dc->text.noneIcon;
|
||||
moveIcon = dc->text.moveIcon;
|
||||
copyIcon = dc->text.copyIcon;
|
||||
linkIcon = dc->text.linkIcon;
|
||||
defSourceIcon = dc->textSource;
|
||||
hotX = text_x_hot;
|
||||
hotY = text_y_hot;
|
||||
stateOffsetX = text_x_offset_state;
|
||||
stateOffsetY = text_y_offset_state;
|
||||
offsetDeltaX = text_x_offset_delta;
|
||||
offsetDeltaY = text_y_offset_delta;
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_DATA:
|
||||
validIcon = dc->data.validIcon;
|
||||
invalidIcon = dc->data.invalidIcon;
|
||||
noneIcon = dc->data.noneIcon;
|
||||
moveIcon = dc->data.moveIcon;
|
||||
copyIcon = dc->data.copyIcon;
|
||||
linkIcon = dc->data.linkIcon;
|
||||
defSourceIcon = dc->dataSource;
|
||||
hotX = data_x_hot;
|
||||
hotY = data_y_hot;
|
||||
stateOffsetX = data_x_offset_state;
|
||||
stateOffsetY = data_y_offset_state;
|
||||
offsetDeltaX = data_x_offset_delta;
|
||||
offsetDeltaY = data_y_offset_delta;
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_MULTIPLE:
|
||||
validIcon = dc->data.validIcon;
|
||||
invalidIcon = dc->data.invalidIcon;
|
||||
noneIcon = dc->data.noneIcon;
|
||||
moveIcon = dc->data.moveIcon;
|
||||
copyIcon = dc->data.copyIcon;
|
||||
linkIcon = dc->data.linkIcon;
|
||||
defSourceIcon = dc->multipleSource;
|
||||
hotX = data_x_hot;
|
||||
hotY = data_y_hot;
|
||||
stateOffsetX = data_x_offset_state;
|
||||
stateOffsetY = data_y_offset_state;
|
||||
offsetDeltaX = data_x_offset_delta;
|
||||
offsetDeltaY = data_y_offset_delta;
|
||||
break;
|
||||
default:
|
||||
case DtDND_DRAG_SOURCE_DEFAULT:
|
||||
validIcon = NULL;
|
||||
invalidIcon = NULL;
|
||||
noneIcon = NULL;
|
||||
moveIcon = NULL;
|
||||
copyIcon = NULL;
|
||||
linkIcon = NULL;
|
||||
defSourceIcon = NULL;
|
||||
hotX = motif_x_hot;
|
||||
hotY = motif_y_hot;
|
||||
stateOffsetX = motif_x_offset_state;
|
||||
stateOffsetY = motif_y_offset_state;
|
||||
offsetDeltaX = motif_x_offset_delta;
|
||||
offsetDeltaY = motif_y_offset_delta;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the offsets of the state icon from the
|
||||
* DtDND_DRAG_SOURCE_DATA source icon if specified
|
||||
*/
|
||||
if (sourceIcon && sourceType == DtDND_DRAG_SOURCE_DATA) {
|
||||
calcStateIconOffset(sourceIcon, &stateOffsetX, &stateOffsetY);
|
||||
}
|
||||
|
||||
nn = 0;
|
||||
XtSetArg(args[nn], XmNhotX, hotX); nn++;
|
||||
XtSetArg(args[nn], XmNhotY, hotY); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetX, stateOffsetX); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, stateOffsetY); nn++;
|
||||
|
||||
if (validIcon)
|
||||
XtSetValues(validIcon, args, nn);
|
||||
if (invalidIcon)
|
||||
XtSetValues(invalidIcon, args, nn);
|
||||
if (noneIcon)
|
||||
XtSetValues(noneIcon, args, nn);
|
||||
|
||||
nn = 0;
|
||||
XtSetArg(args[nn], XmNoffsetX, stateOffsetX + offsetDeltaX); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, stateOffsetY + offsetDeltaY); nn++;
|
||||
|
||||
if (moveIcon)
|
||||
XtSetValues(moveIcon, args, nn);
|
||||
if (copyIcon)
|
||||
XtSetValues(copyIcon, args, nn);
|
||||
if (linkIcon)
|
||||
XtSetValues(linkIcon, args, nn);
|
||||
|
||||
/*
|
||||
* Set the default drag cursor icons for the XmScreen widget
|
||||
*/
|
||||
XtVaSetValues(xmScreen,
|
||||
XmNdefaultValidCursorIcon, validIcon,
|
||||
XmNdefaultInvalidCursorIcon, invalidIcon,
|
||||
XmNdefaultNoneCursorIcon, noneIcon,
|
||||
XmNdefaultMoveCursorIcon, moveIcon,
|
||||
XmNdefaultCopyCursorIcon, copyIcon,
|
||||
XmNdefaultLinkCursorIcon, linkIcon,
|
||||
XmNdefaultSourceCursorIcon, defSourceIcon,
|
||||
NULL);
|
||||
|
||||
dc->sourceType = sourceType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a drag icon widget from the passed bits
|
||||
*/
|
||||
static Widget
|
||||
makeDragIconFromData(
|
||||
Widget widget,
|
||||
unsigned char *bits,
|
||||
unsigned char *maskbits,
|
||||
int width,
|
||||
int height,
|
||||
int component)
|
||||
{
|
||||
Widget icon;
|
||||
Pixmap pixmap, mask;
|
||||
Display *dpy = XtDisplayOfObject(widget);
|
||||
Screen *screen = XtScreenOfObject(widget);
|
||||
Window root = RootWindowOfScreen(screen);
|
||||
String name;
|
||||
Arg args[30];
|
||||
Cardinal nn = 0;
|
||||
|
||||
pixmap = XCreatePixmapFromBitmapData(dpy, root,
|
||||
(char *)bits, width, height,
|
||||
1, 0, 1);
|
||||
|
||||
mask = XCreatePixmapFromBitmapData(dpy, root,
|
||||
(char *)maskbits, width, height,
|
||||
1, 0, 1);
|
||||
|
||||
switch (component) {
|
||||
case DtDND_DRAG_SOURCE:
|
||||
name = "sourceIcon";
|
||||
break;
|
||||
case DtDND_DRAG_STATE:
|
||||
name = "stateIcon";
|
||||
XtSetArg(args[nn], XmNattachment, XmATTACH_NORTH_WEST); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetX, -6); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, -6); nn++;
|
||||
XtSetArg(args[nn], XmNhotX, 3); nn++;
|
||||
XtSetArg(args[nn], XmNhotY, 3); nn++;
|
||||
break;
|
||||
case DtDND_DRAG_OPERATION:
|
||||
name = "operationIcon";
|
||||
XtSetArg(args[nn], XmNattachment, XmATTACH_NORTH_WEST); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetX, 1); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, 1); nn++;
|
||||
break;
|
||||
}
|
||||
|
||||
XtSetArg(args[nn], XmNwidth, width); nn++;
|
||||
XtSetArg(args[nn], XmNheight, height); nn++;
|
||||
XtSetArg(args[nn], XmNmaxWidth, width); nn++;
|
||||
XtSetArg(args[nn], XmNmaxHeight, height); nn++;
|
||||
XtSetArg(args[nn], XmNpixmap, pixmap); nn++;
|
||||
XtSetArg(args[nn], XmNmask, mask); nn++;
|
||||
XtSetArg(args[nn], XmNdepth, 1); nn++;
|
||||
|
||||
icon = XmCreateDragIcon(widget, name, args, nn);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the collection of text & data drag icons; state/operation
|
||||
* cursors and source icons.
|
||||
*/
|
||||
static DragCollection *
|
||||
makeDragCollection(
|
||||
Widget widget)
|
||||
{
|
||||
DragCollection *dc = XtNew(DragCollection);
|
||||
Display *dpy = XtDisplayOfObject(widget);
|
||||
Screen *screen = XtScreenOfObject(widget);
|
||||
Window root = RootWindowOfScreen(screen);
|
||||
Widget xmScreen = XmGetXmScreen(screen);
|
||||
|
||||
/*
|
||||
* Text & Data State Cursors
|
||||
*/
|
||||
|
||||
dc->text.invalidIcon = makeDragIconFromData(widget,
|
||||
text_invalid_bits, text_invalid_m_bits,
|
||||
text_invalid_width, text_invalid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->text.validIcon = makeDragIconFromData(widget,
|
||||
text_valid_bits, text_valid_m_bits,
|
||||
text_valid_width, text_valid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->text.noneIcon = makeDragIconFromData(widget,
|
||||
text_none_bits, text_none_m_bits,
|
||||
text_none_width, text_none_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->data.invalidIcon = makeDragIconFromData(widget,
|
||||
data_invalid_bits, data_invalid_m_bits,
|
||||
data_invalid_width, data_invalid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->data.validIcon = makeDragIconFromData(widget,
|
||||
data_valid_bits, data_valid_m_bits,
|
||||
data_valid_width, data_valid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->data.noneIcon = makeDragIconFromData(widget,
|
||||
data_none_bits, data_none_m_bits,
|
||||
data_none_width, data_none_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
/*
|
||||
* Text & Data Operation Cursors
|
||||
*/
|
||||
|
||||
dc->data.moveIcon = makeDragIconFromData(widget,
|
||||
data_move_bits, data_move_m_bits,
|
||||
data_move_width, data_move_height,
|
||||
DtDND_DRAG_OPERATION);
|
||||
|
||||
dc->data.copyIcon = makeDragIconFromData(widget,
|
||||
data_copy_bits, data_copy_m_bits,
|
||||
data_copy_width, data_copy_height,
|
||||
DtDND_DRAG_OPERATION);
|
||||
|
||||
dc->data.linkIcon = makeDragIconFromData(widget,
|
||||
data_link_bits, data_link_m_bits,
|
||||
data_link_width, data_link_height,
|
||||
DtDND_DRAG_OPERATION);
|
||||
|
||||
dc->text.moveIcon = dc->data.moveIcon;
|
||||
dc->text.copyIcon = dc->data.copyIcon;
|
||||
dc->text.linkIcon = dc->data.linkIcon;
|
||||
|
||||
/*
|
||||
* Text & Data Source Cursors
|
||||
*/
|
||||
|
||||
dc->textSource = makeDragIconFromData(widget,
|
||||
text_source_bits, text_source_m_bits,
|
||||
text_source_width, text_source_height,
|
||||
DtDND_DRAG_SOURCE);
|
||||
|
||||
dc->dataSource = makeDragIconFromData(widget,
|
||||
data_single_bits, data_single_m_bits,
|
||||
data_single_width, data_single_height,
|
||||
DtDND_DRAG_SOURCE);
|
||||
|
||||
dc->multipleSource = makeDragIconFromData(widget,
|
||||
data_multiple_bits, data_multiple_m_bits,
|
||||
data_multiple_width, data_multiple_height,
|
||||
DtDND_DRAG_SOURCE);
|
||||
|
||||
dc->sourceType = DtDND_DRAG_SOURCE_DEFAULT;
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the cached DragCollection and context for it
|
||||
*/
|
||||
static void
|
||||
destroyDragCollection(
|
||||
Widget widget,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
DragCollection *dc = (DragCollection *)clientData;
|
||||
|
||||
XtFree((char *)dc);
|
||||
|
||||
XDeleteContext(XtDisplayOfObject(widget),
|
||||
RootWindowOfScreen(XtScreenOfObject(widget)),
|
||||
dragCollectionContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the cached DragCollection; will create one if needed
|
||||
*/
|
||||
static DragCollection *
|
||||
getDragCollection(
|
||||
Widget xmScreen)
|
||||
{
|
||||
DragCollection *dc = NULL;
|
||||
Display *dpy = XtDisplayOfObject(xmScreen);
|
||||
Screen *screen = XtScreenOfObject(xmScreen);
|
||||
Window root = RootWindowOfScreen(screen);
|
||||
int status;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (dragCollectionContext == (XContext)NULL) {
|
||||
dragCollectionContext = XUniqueContext();
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
status = XFindContext(dpy, root, dragCollectionContext, (XtPointer)&dc);
|
||||
|
||||
if (status != 0) {
|
||||
dc = makeDragCollection(xmScreen);
|
||||
XSaveContext(dpy, root, dragCollectionContext, (XtPointer)dc);
|
||||
XtAddCallback(xmScreen, XmNdestroyCallback,
|
||||
destroyDragCollection, (XtPointer)dc);
|
||||
}
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module-public function to select/activate a source type drag icon
|
||||
*/
|
||||
void
|
||||
_DtDndSelectDragSource(
|
||||
Widget widget,
|
||||
DtDndDragSource sourceType,
|
||||
Widget sourceIcon)
|
||||
{
|
||||
Widget xmScreen = XmGetXmScreen(XtScreenOfObject(widget));
|
||||
DragCollection *dc = getDragCollection(xmScreen);
|
||||
|
||||
selectDragSource(dc, xmScreen, sourceType, sourceIcon);
|
||||
}
|
||||
|
||||
void
|
||||
_DtDndGetIconOffset(
|
||||
Widget dragContext,
|
||||
DtDndDragSource sourceType,
|
||||
int * offsetX,
|
||||
int * offsetY)
|
||||
{
|
||||
Widget sourceIcon;
|
||||
int stateOffsetX, stateOffsetY;
|
||||
|
||||
switch (sourceType) {
|
||||
default:
|
||||
case DtDND_DRAG_SOURCE_DEFAULT:
|
||||
*offsetX = -(motif_x_hot + motif_x_offset_state);
|
||||
*offsetY = -(motif_y_hot + motif_y_offset_state);
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_TEXT:
|
||||
*offsetX = -(text_x_hot + text_x_offset_state);
|
||||
*offsetY = -(text_y_hot + text_y_offset_state);
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_DATA:
|
||||
case DtDND_DRAG_SOURCE_MULTIPLE:
|
||||
*offsetX = -(data_x_hot + data_x_offset_state);
|
||||
*offsetY = -(data_y_hot + data_y_offset_state);
|
||||
|
||||
XtVaGetValues(dragContext,
|
||||
XmNsourcePixmapIcon, &sourceIcon,
|
||||
NULL);
|
||||
|
||||
if (sourceIcon != NULL) {
|
||||
calcStateIconOffset(sourceIcon,
|
||||
&stateOffsetX, &stateOffsetY);
|
||||
*offsetX = -(data_x_hot + stateOffsetX);
|
||||
*offsetY = -(data_y_hot + stateOffsetY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user