/**********************************************************************
 * DropSite functions for the "week" program
 *
 * $Author: brlewis $
 * $Source$
 * $Header$
 *
 * Copyright 1994 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 **********************************************************************/
#include <mit-copyright.h>

static char rcsid_dragdrop_c[] = "$Header$";

#include <Xm/DragDrop.h>
#include <X11/Xatom.h>

Atom COMPOUND_TEXT = (Atom)0;

/* Detailed information about Drag and Drop can be found in chapter 15 of
 * the OSF/Motif Programmer's Guide, available on Athena if you have
 * attached motif1.2 (happens automatically when you setup wcl), in the
 * file /mit/motif/doc/ch15
 * Comments in this file indicate sections in that chapter.
 */

/*                     15.3  Drag and Drop
 *                           Protocols.......................    15-27
 *                           15.3.1  Drag Protocols..........    15-27
 *                           15.3.2  Choosing the Protocol
 *                                   and Visual
 *                                   Style...................    15-30
 *                           15.3.3  Drop Protocol...........    15-33
 */


/*                     15.4  Drop Receiver Responsibilities
 *                           for Dragging....................    15-34
 */

/* This example transferProc does nothing with most of its arguments.
 * To be honest, I don't know what all of them are.
 * All it does is set the dropSite's background color according to the
 * string dragged.  It's a good idea to convert whatever information you
 * want to drag into a string or some other platform-independent
 * representation.
 */

myTransferProc(w, closure, seltype, type, value, length, format)
     Widget w;
     XtPointer closure;		/* set by the dragProc to drop site widget */
     Atom *seltype;
     Atom *type;
     XtPointer value;		/* what you're actually dragging */
     unsigned long *length;
     int format;
{
  Colormap colormap;
  XColor screen_colordef, exact_colordef;
  Status retval;

  /* get colormap of drop site widget */
  XtVaGetValues((Widget) closure,
		XtNcolormap, &colormap,
		NULL);

  /* If background color is "default", don't do anything */
  if (!strcmp(value, "default")) return;

  /* Get color from color name */
  retval = XAllocNamedColor(XtDisplay((Widget)closure), colormap, value,
		   &screen_colordef, &exact_colordef);

  if (retval == 0) return;    /* failure */

  XmChangeColor((Widget)closure, screen_colordef.pixel);
  return;
}

/*                           15.4.2  XmNdragProc.............    15-42
 */

void
HandleDropCB(w, client_data, call_data)
     Widget w;
     XtPointer client_data, call_data;
{
  XmDropProcCallback DropData;
  XmDropTransferEntryRec transferEntries[2];
  XmDropTransferEntry transferList;
  Arg args[10];
  int n;
  Atom *myTargets;

  /* figure out what targets I asked for */
  XtVaGetValues(w,
		XmNimportTargets, &myTargets,
		NULL);

  /* Cast call_data to appropriate type */
  DropData = (XmDropProcCallback)call_data;

  /* set args for transferProc */
  n=0;
  transferEntries[0].target = COMPOUND_TEXT;
  transferEntries[0].client_data = (XtPointer)w; /* becomes "closure"
						  * in transferProc */
  transferList = transferEntries;
  XtSetArg(args[n], XmNdropTransfers, transferList); n++;
  XtSetArg(args[n], XmNnumDropTransfers, 1); n++;
  XtSetArg(args[n], XmNtransferProc, myTransferProc); n++;

  /* start the transfer */
  XmDropTransferStart(DropData->dragContext, args, n);
}

/*                           15.4.1  Establishing a Drop
 *                                   Site....................    15-35
 */

void
RegisterMeAsDropSiteCB(w)
     Widget w;
{
  int n;
  Arg args[10];

  /* initialize COMPOUND_TEXT atom */
  if (COMPOUND_TEXT == (Atom)0)
    COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);

  /* Motif does not provide a way to set dropSiteOperations in resources */
  n=0;
  XtSetArg(args[n], XmNdropSiteOperations, XmDROP_COPY); n++;
  XtSetArg(args[n], XmNdropProc, HandleDropCB); n++;

  XmDropSiteRegister(w, args, n);
  return;
}
