123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 |
- /*
- * 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
- */
- /* $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)0) {
- 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;
- }
- }
|