Blame tests/UTM/UTMactions.c

Packit b099d7
/* $XConsortium: UTMactions.c /main/5 1995/07/15 21:12:10 drk $ */
Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * HISTORY
Packit b099d7
 */
Packit b099d7
Packit b099d7
#include <Xm/XmP.h>
Packit b099d7
#include <Xm/TransferP.h>
Packit b099d7
#include "UTMtransfer.h"
Packit b099d7
Packit b099d7
/* We assume no more than 100 targets will ever be available.  MAXT
Packit b099d7
   is this upper limit */
Packit b099d7
Packit b099d7
#define MAXT 100
Packit b099d7
#define BYTELENGTH( length, format ) \
Packit b099d7
  ((format == 8) ? length : \
Packit b099d7
   ((format == 16) ? length * sizeof(short) : \
Packit b099d7
    (length * sizeof(long))))
Packit b099d7
Packit b099d7
TransferDataRec datums[MAXT]; /* Should never be larger than this */
Packit b099d7
unsigned int num_datums = 0;
Packit b099d7
Packit b099d7
/*******************************************************************
Packit b099d7
 * UpdateList
Packit b099d7
 * 
Packit b099d7
 * This takes the transfered items and updates the displayed list
Packit b099d7
 * with the transferred target names.  Note that we call a version of
Packit b099d7
 * XGetAtomName with an installed error handler.  This prevents an
Packit b099d7
 * app. exit if the Atom id is illegal.  
Packit b099d7
 *******************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
UpdateList(Widget w, XtEnum ignore, XmTransferDoneCallbackStruct *data)
Packit b099d7
{
Packit b099d7
  int i;
Packit b099d7
Packit b099d7
  XmListDeleteAllItems(list);
Packit b099d7
Packit b099d7
  for(i = 0; i < num_datums; i++) {
Packit b099d7
    char *name;
Packit b099d7
    XmString temp;
Packit b099d7
Packit b099d7
    if (datums[i].target != 0) {
Packit b099d7
      name = GetSafeAtom(XtDisplay(w), datums[i].target);
Packit b099d7
      if (name != NULL) {
Packit b099d7
        temp = XmStringCreateLocalized(name);
Packit b099d7
        XFree(name);
Packit b099d7
      }
Packit b099d7
      else {
Packit b099d7
        temp = XmStringCreateLocalized("Illegal atom");
Packit b099d7
      }
Packit b099d7
    } 
Packit b099d7
    else {
Packit b099d7
      temp = XmStringCreateLocalized("Bad target");
Packit b099d7
      if (name != NULL) XFree(name);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmListAddItemUnselected(list, temp, 0);
Packit b099d7
    XmStringFree(temp);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/********************************************************************
Packit b099d7
 * ReceiveData
Packit b099d7
 *
Packit b099d7
 * This requests the targets passed from the request for TARGETS that
Packit b099d7
 * happed in the destination callback.  Note that you must not start
Packit b099d7
 * an infinite loop of requesting the target TARGETS.  It will normally
Packit b099d7
 * be in the list of targets received.  Also,  requesting DELETE has
Packit b099d7
 * both a side effect and no value associated.  So we do not request
Packit b099d7
 * these targets.
Packit b099d7
 ********************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ReceiveData(Widget w, XtPointer ignore, XmSelectionCallbackStruct *data)
Packit b099d7
{
Packit b099d7
  if (data -> target != XInternAtom(XtDisplay(w), XmSTARGETS, False)) {
Packit b099d7
    if (num_datums < MAXT) {
Packit b099d7
      datums[num_datums].target = data -> target;
Packit b099d7
      datums[num_datums].type = data -> type;
Packit b099d7
      datums[num_datums].length = data -> length;
Packit b099d7
      datums[num_datums].format = data -> format;
Packit b099d7
      datums[num_datums].value = data -> value;
Packit b099d7
      num_datums++;
Packit b099d7
    }
Packit b099d7
  } else {
Packit b099d7
    Atom *dlist = (Atom *) data -> value;
Packit b099d7
    Atom DELETE, TARGETS, INSERT_SELECTION, LINK_SELECTION;
Packit b099d7
    int i, count = 0;
Packit b099d7
Packit b099d7
    if (data -> length == 0) {
Packit b099d7
      XmTransferDone(data -> transfer_id, XmTRANSFER_DONE_FAIL);
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* This doneProc is performed after all transfers have completed. */
Packit b099d7
    XmeTransferAddDoneProc(data -> transfer_id, 
Packit b099d7
                           (XmSelectionFinishedProc) UpdateList);
Packit b099d7
Packit b099d7
    DELETE = XInternAtom(XtDisplay(w), XmSDELETE, False);
Packit b099d7
    TARGETS = XInternAtom(XtDisplay(w), XmSTARGETS, False);
Packit b099d7
    INSERT_SELECTION = XInternAtom(XtDisplay(w), "INSERT_SELECTION", False);
Packit b099d7
    LINK_SELECTION = XInternAtom(XtDisplay(w), "LINK_SELECTION", False);
Packit b099d7
Packit b099d7
    /* first free current datums */
Packit b099d7
    for(i = 0; i < num_datums; i++) {
Packit b099d7
      XtFree(datums[num_datums].value);
Packit b099d7
      datums[num_datums].value = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    num_datums = 0;
Packit b099d7
Packit b099d7
    XmTransferStartRequest(data -> transfer_id);
Packit b099d7
Packit b099d7
    for(i = 0; i < data -> length; i++) {
Packit b099d7
      if (dlist[i] != DELETE &&
Packit b099d7
	  dlist[i] != INSERT_SELECTION &&
Packit b099d7
	  dlist[i] != LINK_SELECTION &&
Packit b099d7
          dlist[i] != TARGETS &&
Packit b099d7
	  dlist[i] != None) {
Packit b099d7
        XmTransferValue(data -> transfer_id, dlist[i], 
Packit b099d7
                        (XtCallbackProc) ReceiveData, NULL, 0);
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmTransferSendRequest(data -> transfer_id, 0);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************
Packit b099d7
 * DestinationCallback
Packit b099d7
 *
Packit b099d7
 * This just requests the list of targets.  ReceiveData does the
Packit b099d7
 * rest.
Packit b099d7
 *****************************************************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
TargetDestinationCB(Widget w, XtPointer ignore, XtPointer call_data)
Packit b099d7
{
Packit b099d7
  XmDestinationCallbackStruct *cs;
Packit b099d7
  char *selection_atom_name, *atom_name;
Packit b099d7
Packit b099d7
  cs = (XmDestinationCallbackStruct *) call_data;
Packit b099d7
Packit b099d7
  selection_atom_name = GetSafeAtom(XtDisplay(w), cs->selection);
Packit b099d7
  if (selection_atom_name == NULL)
Packit b099d7
       selection_atom_name = "Illegal atom";
Packit b099d7
Packit b099d7
  printf("Destination Callback of drawing area called with: \n");
Packit b099d7
  printf("        selection = %s\n", selection_atom_name);
Packit b099d7
  printf("        operation = %s\n\n", GetStringFrom(cs->operation));
Packit b099d7
Packit b099d7
  XmTransferValue(cs -> transfer_id, 
Packit b099d7
                  XInternAtom(XtDisplay(w), XmSTARGETS, False),
Packit b099d7
                  (XtCallbackProc) ReceiveData, NULL, 0);
Packit b099d7
}
Packit b099d7
Packit b099d7
void 
Packit b099d7
TargetConvertCB(Widget w, XtPointer ignore, XtPointer call_data)
Packit b099d7
{
Packit b099d7
  XmConvertCallbackStruct *cs;
Packit b099d7
  char *selection_atom_name, *target_atom_name;
Packit b099d7
Packit b099d7
 
Packit b099d7
  Atom TARGETS = XInternAtom(XtDisplay(w), XmSTARGETS, False);
Packit b099d7
  Atom ME_TARGETS = XInternAtom(XtDisplay(w), XmS_MOTIF_EXPORT_TARGETS, False);
Packit b099d7
  Atom MC_TARGETS = XInternAtom(XtDisplay(w), 
Packit b099d7
                                XmS_MOTIF_CLIPBOARD_TARGETS, False);
Packit b099d7
  Atom DELETE = XInternAtom(XtDisplay(w), XmSDELETE, False);
Packit b099d7
  Atom LS = XInternAtom(XtDisplay(w), XmS_MOTIF_LOSE_SELECTION, False);
Packit b099d7
  Atom MDEST = XInternAtom(XtDisplay(w), XmS_MOTIF_DESTINATION, False);
Packit b099d7
Packit b099d7
  cs = (XmConvertCallbackStruct *) call_data;
Packit b099d7
Packit b099d7
  selection_atom_name = GetSafeAtom(XtDisplay(w), cs->selection);
Packit b099d7
  if (selection_atom_name == NULL)
Packit b099d7
       selection_atom_name = "Illegal atom";
Packit b099d7
Packit b099d7
  target_atom_name = GetSafeAtom(XtDisplay(w), cs->selection);
Packit b099d7
  if (target_atom_name == NULL)
Packit b099d7
       target_atom_name = "Illegal atom";
Packit b099d7
Packit b099d7
  printf("Convert Callback of drawing area called with: \n");
Packit b099d7
  printf("        selection         = %s\n", selection_atom_name);
Packit b099d7
  printf("        conversion target = %s\n\n", target_atom_name);
Packit b099d7
  
Packit b099d7
Packit b099d7
  if (cs -> target == ME_TARGETS ||
Packit b099d7
      cs -> target == MC_TARGETS) {
Packit b099d7
    /* Create an array large enough to hold all targets */
Packit b099d7
    Atom *targs = (Atom *) XtMalloc(sizeof(Atom) * num_datums);
Packit b099d7
    int i;
Packit b099d7
    int count = 0;
Packit b099d7
Packit b099d7
    for(i = 0; i < num_datums; i++) {
Packit b099d7
      if (datums[i].target != DELETE &&
Packit b099d7
	  datums[i].target != MC_TARGETS &&
Packit b099d7
	  datums[i].target != ME_TARGETS &&
Packit b099d7
          datums[i].target != TARGETS) {
Packit b099d7
        targs[count++] = datums[i].target;
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (count > 0) {
Packit b099d7
      cs -> value = (XtPointer) targs;
Packit b099d7
      cs -> length = count;
Packit b099d7
      cs -> format = 32;
Packit b099d7
      cs -> type = XA_ATOM;
Packit b099d7
      cs -> status = XmCONVERT_DONE;
Packit b099d7
    } else {
Packit b099d7
      XtFree((char*) targs);
Packit b099d7
      cs -> status = XmCONVERT_REFUSE;
Packit b099d7
    }
Packit b099d7
  } else if (cs -> target == TARGETS) {
Packit b099d7
    /* Create an array large enough to hold all targets */
Packit b099d7
    Atom *targs = (Atom *) XtMalloc(sizeof(Atom) * num_datums);
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    for(i = 0; i < num_datums; i++) {
Packit b099d7
      targs[i] = datums[i].target;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    cs -> value = (XtPointer) targs;
Packit b099d7
    cs -> length = num_datums;
Packit b099d7
    cs -> format = 32;
Packit b099d7
    cs -> type = XA_ATOM;
Packit b099d7
    cs -> status = XmCONVERT_DONE;
Packit b099d7
  }
Packit b099d7
 else if (cs -> target == LS) {
Packit b099d7
    /* Decide which selection was lost,  remove that label */
Packit b099d7
    if (cs -> selection == XA_PRIMARY)
Packit b099d7
      XtUnmanageChild(OwnPrimLG);
Packit b099d7
    else if (cs -> selection == MDEST)
Packit b099d7
      XtUnmanageChild(OwnSecLG);
Packit b099d7
  } 
Packit b099d7
Packit b099d7
 else {
Packit b099d7
    /* Try and find the right target,  otherwise fail */
Packit b099d7
    int i = 0;
Packit b099d7
    
Packit b099d7
    while(i < num_datums &&
Packit b099d7
          datums[i].target != cs -> target) 
Packit b099d7
      i++;
Packit b099d7
Packit b099d7
    if (i >= num_datums /* Not found */ ||
Packit b099d7
        datums[i].type == (Atom) 0 /* Illegal */ )
Packit b099d7
      {
Packit b099d7
        cs -> value = NULL;
Packit b099d7
        cs -> length = 0;
Packit b099d7
        cs -> type = None;
Packit b099d7
        cs -> format = 8;
Packit b099d7
        cs -> status = XmCONVERT_REFUSE;
Packit b099d7
      }
Packit b099d7
    else
Packit b099d7
      {
Packit b099d7
	char *temp;
Packit b099d7
	int size_in_bytes;
Packit b099d7
Packit b099d7
	size_in_bytes = datums[i].length * datums[i].format / 8;
Packit b099d7
	temp = XtMalloc(size_in_bytes);
Packit b099d7
	memcpy(temp, datums[i].value, size_in_bytes);
Packit b099d7
Packit b099d7
        cs -> status = XmCONVERT_DONE;
Packit b099d7
        cs -> length = datums[i].length;
Packit b099d7
        cs -> format = datums[i].format;
Packit b099d7
        cs -> type = datums[i].type;
Packit b099d7
        cs -> value = temp;
Packit b099d7
      }
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/* Error handler for XGetAtomName */
Packit b099d7
Packit b099d7
static int SIF_ErrorFlag;
Packit b099d7
 
Packit b099d7
static int 
Packit b099d7
SIF_ErrorHandler(Display *display, XErrorEvent *event)
Packit b099d7
{
Packit b099d7
  SIF_ErrorFlag = event -> type;
Packit b099d7
Packit b099d7
  return 0;
Packit b099d7
}
Packit b099d7
Packit b099d7
char * 
Packit b099d7
GetSafeAtom(Display *display, Atom a)
Packit b099d7
{
Packit b099d7
  XErrorHandler old_Handler;
Packit b099d7
  char *returnvalue;
Packit b099d7
Packit b099d7
  /* Setup error proc and reset error flag */
Packit b099d7
  old_Handler = XSetErrorHandler((XErrorHandler) SIF_ErrorHandler);
Packit b099d7
  SIF_ErrorFlag = 0;
Packit b099d7
Packit b099d7
  returnvalue = XGetAtomName(display, a);
Packit b099d7
Packit b099d7
  XSetErrorHandler(old_Handler);
Packit b099d7
Packit b099d7
  if (SIF_ErrorFlag == 0)
Packit b099d7
    return(returnvalue);
Packit b099d7
  else
Packit b099d7
    return(NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
char *
Packit b099d7
GetStringFrom(XtEnum operation)
Packit b099d7
{
Packit b099d7
  char *returnvalue;
Packit b099d7
Packit b099d7
  switch(operation) {
Packit b099d7
        case XmMOVE:
Packit b099d7
           returnvalue = "XmMOVE";
Packit b099d7
           break;
Packit b099d7
        case XmCOPY: 
Packit b099d7
           returnvalue = "XmCOPY";
Packit b099d7
           break;
Packit b099d7
        case XmLINK:
Packit b099d7
           returnvalue = "XmLINK";
Packit b099d7
           break;
Packit b099d7
        case XmOTHER:
Packit b099d7
           returnvalue = "XmOTHER";
Packit b099d7
           break;
Packit b099d7
        default:
Packit b099d7
           returnvalue = "Bad operation";
Packit b099d7
        }
Packit b099d7
Packit b099d7
  return(returnvalue);
Packit b099d7
}