Blame lib/Xm/TextSel.c

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
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: TextSel.c /main/24 1998/12/07 11:12:08 mgreess $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
Packit b099d7
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
Packit b099d7
#include <X11/Xatom.h>
Packit b099d7
#include <Xm/AtomMgr.h>
Packit b099d7
#include <Xm/DragC.h>
Packit b099d7
#include <Xm/DropTrans.h>
Packit b099d7
#include <Xm/TraitP.h>		/* for XmeTraitSet() */
Packit b099d7
#include <Xm/TransferT.h>
Packit b099d7
#include <Xm/XmosP.h>
Packit b099d7
#include "TextI.h"
Packit b099d7
#include "TextInI.h"
Packit b099d7
#include "TextSelI.h"
Packit b099d7
#include "TextStrSoI.h"
Packit b099d7
#include "TransferI.h"		/* for _XmConvertComplete() */
Packit b099d7
#include "TraversalI.h"
Packit b099d7
#include "XmI.h"
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static void InsertSelection( 
Packit b099d7
                        Widget w,
Packit b099d7
                        XtPointer closure,
Packit b099d7
                        Atom *seltype,
Packit b099d7
                        Atom *type,
Packit b099d7
                        XtPointer value,
Packit b099d7
                        unsigned long *length,
Packit b099d7
                        int *format, 
Packit b099d7
			XtPointer tid) ;
Packit b099d7
static void HandleInsertTargets( 
Packit b099d7
                        Widget w,
Packit b099d7
                        XtPointer closure,
Packit b099d7
                        Atom *seltype,
Packit b099d7
                        Atom *type,
Packit b099d7
                        XtPointer value,
Packit b099d7
                        unsigned long *length,
Packit b099d7
                        int *format,
Packit b099d7
			XtPointer tid) ;
Packit b099d7
Packit b099d7
static void HandleDrop(Widget w,
Packit b099d7
		       XmDropProcCallbackStruct *cb,
Packit b099d7
		       XmDestinationCallbackStruct *ds);
Packit b099d7
Packit b099d7
static void HandleTargets(Widget w, 
Packit b099d7
			  XtPointer ignore, 
Packit b099d7
			  XmSelectionCallbackStruct *ds);
Packit b099d7
Packit b099d7
static void DoStuff(Widget w, 
Packit b099d7
		    XtPointer closure, 
Packit b099d7
		    XmSelectionCallbackStruct *ds);
Packit b099d7
Packit b099d7
static void DropDestroyCB(Widget w,
Packit b099d7
			  XtPointer clientData,
Packit b099d7
			  XtPointer callData);
Packit b099d7
Packit b099d7
static void DropTransferProc(Widget w, XtPointer ignore, 
Packit b099d7
			     XmSelectionCallbackStruct *ds);
Packit b099d7
Packit b099d7
static void SetDropContext(Widget w);
Packit b099d7
Packit b099d7
static void DeleteDropContext(Widget w);
Packit b099d7
static void TextSecondaryWrapper(Widget, XtPointer, 
Packit b099d7
				 XmSelectionCallbackStruct *);
Packit b099d7
static void TextConvertCallback(Widget, XtPointer, 
Packit b099d7
				XmConvertCallbackStruct*);
Packit b099d7
static void TextDestinationCallback(Widget, XtPointer,
Packit b099d7
				    XmDestinationCallbackStruct*);
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
/* Transfer Trait record for Text */
Packit b099d7
Packit b099d7
static XmConst XmTransferTraitRec TextTransfer = {
Packit b099d7
  0,  				/* version */
Packit b099d7
  (XmConvertCallbackProc) 	TextConvertCallback,
Packit b099d7
  (XmDestinationCallbackProc)	TextDestinationCallback,
Packit b099d7
  (XmDestinationCallbackProc)	NULL,
Packit b099d7
};
Packit b099d7
Packit b099d7
static XContext _XmTextDNDContext = 0;
Packit b099d7
static _XmTextPrimSelect *prim_select;
Packit b099d7
static _XmInsertSelect insert_select;
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SetPrimarySelection(Widget w, 
Packit b099d7
		    XtEnum op,	/* unused */
Packit b099d7
		    XmTransferDoneCallbackStruct *ts) /* unused */
Packit b099d7
{
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  InputData data = tw->text.input->data;
Packit b099d7
  XmTextPosition cursorPos = tw->text.cursor_position;
Packit b099d7
 
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (!prim_select) {
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (prim_select->num_chars > 0) {
Packit b099d7
    data->anchor = prim_select->position;
Packit b099d7
    cursorPos = prim_select->position + prim_select->num_chars;
Packit b099d7
    _XmTextSetCursorPosition(w, cursorPos);
Packit b099d7
    _XmTextSetDestinationSelection(w, tw->text.cursor_position,
Packit b099d7
				   False, prim_select->time);
Packit b099d7
    (*tw->text.source->SetSelection)(tw->text.source, data->anchor,
Packit b099d7
				     tw->text.cursor_position,
Packit b099d7
				     prim_select->time);
Packit b099d7
  }
Packit b099d7
  if (--prim_select->ref_count == 0) {
Packit b099d7
    XtFree((char *)prim_select);
Packit b099d7
    prim_select = NULL;
Packit b099d7
  }
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
CleanPrimarySelection(Widget w, 
Packit b099d7
		    XtEnum op,	/* unused */
Packit b099d7
		    XmTransferDoneCallbackStruct *ts) /* unused */
Packit b099d7
{
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (!prim_select) {
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (--prim_select->ref_count == 0) {
Packit b099d7
    XtFree((char *)prim_select);
Packit b099d7
    prim_select = NULL;
Packit b099d7
  }
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void 
Packit b099d7
TextSecondaryWrapper(Widget w, XtPointer closure,
Packit b099d7
			XmSelectionCallbackStruct *ds)
Packit b099d7
{
Packit b099d7
  Atom XA_TARGETS = XInternAtom(XtDisplay(w), XmSTARGETS, False);
Packit b099d7
Packit b099d7
  if (ds -> target == XA_TARGETS)
Packit b099d7
    HandleInsertTargets(w, closure, &(ds -> selection), &(ds -> type),
Packit b099d7
			ds -> value, &(ds -> length), &(ds -> format),
Packit b099d7
			ds -> transfer_id);
Packit b099d7
  else
Packit b099d7
    InsertSelection(w, closure, &(ds -> selection), &(ds -> type),
Packit b099d7
		    ds -> value, &(ds -> length), &(ds -> format),
Packit b099d7
		    ds -> transfer_id);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
InsertSelection(
Packit b099d7
        Widget w,
Packit b099d7
        XtPointer closure,
Packit b099d7
        Atom *seltype,
Packit b099d7
        Atom *type,
Packit b099d7
        XtPointer value,
Packit b099d7
        unsigned long *length,
Packit b099d7
        int *format, 
Packit b099d7
	XtPointer tid)
Packit b099d7
{
Packit b099d7
  _XmInsertSelect *insert_select = (_XmInsertSelect *)closure;
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  XmTextPosition left = 0;
Packit b099d7
  XmTextPosition right = 0;
Packit b099d7
  Boolean dest_disjoint = False;
Packit b099d7
  Atom COMPOUND_TEXT = XInternAtom(XtDisplay(w), XmSCOMPOUND_TEXT, False);
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
  Atom UTF8_STRING = XInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
Packit b099d7
#endif
Packit b099d7
  char * total_value = NULL;
Packit b099d7
  XmTextBlockRec block, newblock;
Packit b099d7
  XmTextPosition cursorPos;
Packit b099d7
  Boolean freeBlock;
Packit b099d7
  
Packit b099d7
  if (!value) {
Packit b099d7
    insert_select->done_status = True;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  /* Don't do replace if there is no text to add */
Packit b099d7
  if (*(char *)value == '\0' || *length == 0){
Packit b099d7
    XtFree((char*)value);
Packit b099d7
    value = NULL;
Packit b099d7
    insert_select->done_status = True;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (insert_select->select_type == XmPRIM_SELECT) {
Packit b099d7
    if (!(*tw->text.source->GetSelection)(tw->text.source, &left, &right) ||
Packit b099d7
	left == right) {
Packit b099d7
      XBell(XtDisplay(w), 0);
Packit b099d7
      XtFree((char*)value);
Packit b099d7
      value = NULL;
Packit b099d7
      insert_select->done_status = True;
Packit b099d7
      insert_select->success_status = False;
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
  } else if (insert_select->select_type == XmDEST_SELECT) {
Packit b099d7
    if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) && 
Packit b099d7
	left != right) {
Packit b099d7
      if (tw->text.cursor_position < left ||
Packit b099d7
	  tw->text.cursor_position > right ||
Packit b099d7
	  !tw->text.input->data->pendingdelete) {
Packit b099d7
	left = right = tw->text.cursor_position; 
Packit b099d7
	dest_disjoint = True;
Packit b099d7
      }
Packit b099d7
    } else
Packit b099d7
      left = right = tw->text.cursor_position;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
Packit b099d7
  
Packit b099d7
  block.format = XmFMT_8_BIT;
Packit b099d7
  
Packit b099d7
  if (*type == COMPOUND_TEXT || *type == XA_STRING
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      || *type == UTF8_STRING
Packit b099d7
#endif
Packit b099d7
  ) {
Packit b099d7
    if ((total_value =
Packit b099d7
	 _XmTextToLocaleText(w, value, *type, *format, 
Packit b099d7
			     *length, NULL)) != NULL) {
Packit b099d7
      block.ptr = total_value;
Packit b099d7
      block.length = strlen(block.ptr);
Packit b099d7
    } else {
Packit b099d7
      insert_select->done_status = True;
Packit b099d7
      insert_select->success_status = False;
Packit b099d7
      (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
  } else {  /* it must be either CS_OF_ENCODING or TEXT */
Packit b099d7
    block.ptr = (char*)value;
Packit b099d7
    /* NOTE: casting *length could result in a truncated long. */
Packit b099d7
    block.length = (unsigned) *length;
Packit b099d7
    block.format = XmFMT_8_BIT;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (_XmTextModifyVerify(tw, (XEvent *)insert_select->event, &left, &right,
Packit b099d7
			  &cursorPos, &block, &newblock, &freeBlock)) {
Packit b099d7
    if ((*tw->text.source->Replace)(tw, (XEvent *)insert_select->event, 
Packit b099d7
				    &left, &right,
Packit b099d7
				    &newblock, False) != EditDone) {
Packit b099d7
      if (tw->text.verify_bell) XBell(XtDisplay(w), 0);
Packit b099d7
      insert_select->success_status = False;
Packit b099d7
    } else {
Packit b099d7
      insert_select->success_status = True;
Packit b099d7
      
Packit b099d7
      if (!tw->text.add_mode) tw->text.input->data->anchor = left;
Packit b099d7
      
Packit b099d7
      if (tw->text.add_mode && cursorPos >= left && cursorPos <= right)
Packit b099d7
	tw->text.pendingoff = FALSE;
Packit b099d7
      else
Packit b099d7
	tw->text.pendingoff = TRUE;
Packit b099d7
      
Packit b099d7
      _XmTextSetCursorPosition(w, cursorPos);
Packit b099d7
      _XmTextSetDestinationSelection(w, tw->text.cursor_position, False,
Packit b099d7
				     insert_select->event->time);
Packit b099d7
      
Packit b099d7
      if (insert_select->select_type == XmDEST_SELECT) {
Packit b099d7
	if (left != right) {
Packit b099d7
	  if (!dest_disjoint || !tw->text.add_mode) {
Packit b099d7
	    (*tw->text.source->SetSelection)(tw->text.source,
Packit b099d7
					     tw->text.cursor_position,
Packit b099d7
					     tw->text.cursor_position,
Packit b099d7
					     insert_select->event->time);
Packit b099d7
	  } 
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
      _XmTextValueChanged(tw, (XEvent *)insert_select->event);
Packit b099d7
    }
Packit b099d7
    if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
Packit b099d7
  if (total_value) XtFree(total_value);
Packit b099d7
  XtFree((char*)value);
Packit b099d7
  value = NULL;
Packit b099d7
  insert_select->done_status = True;
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
HandleInsertTargets(
Packit b099d7
        Widget w,
Packit b099d7
        XtPointer closure,
Packit b099d7
        Atom *seltype,
Packit b099d7
        Atom *type,
Packit b099d7
        XtPointer value,
Packit b099d7
        unsigned long *length,
Packit b099d7
        int *format,
Packit b099d7
	XtPointer tid )
Packit b099d7
{
Packit b099d7
  enum { XmATEXT, XmACOMPOUND_TEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
      NUM_ATOMS };
Packit b099d7
  static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
      };
Packit b099d7
Packit b099d7
  _XmInsertSelect *insert_select = (_XmInsertSelect *) closure;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
  Atom target;
Packit b099d7
  Atom *atom_ptr;
Packit b099d7
  Boolean supports_encoding_data = False;
Packit b099d7
  Boolean supports_CT = False;
Packit b099d7
  Boolean supports_text = False;
Packit b099d7
  Boolean supports_utf8_string = False;
Packit b099d7
  int i;
Packit b099d7
  
Packit b099d7
  if (0 == *length) {
Packit b099d7
    XtFree((char *)value);
Packit b099d7
    insert_select->done_status = True;
Packit b099d7
    return; /* Supports no targets, so don't bother sending anything */
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
  atom_ptr = (Atom *)value;
Packit b099d7
  
Packit b099d7
  for (i = 0; i < *length; i++, atom_ptr++) {
Packit b099d7
    if (*atom_ptr == atoms[XmATEXT])
Packit b099d7
      supports_text = True;
Packit b099d7
    
Packit b099d7
    if (*atom_ptr == CS_OF_ENCODING) 
Packit b099d7
      supports_encoding_data = True;
Packit b099d7
    
Packit b099d7
    if (*atom_ptr == atoms[XmACOMPOUND_TEXT]) 
Packit b099d7
      supports_CT = True;
Packit b099d7
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
    if (*atom_ptr == atoms[XmAUTF8_STRING]) 
Packit b099d7
      supports_utf8_string = True;
Packit b099d7
#endif
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (supports_text && supports_encoding_data)
Packit b099d7
    target = atoms[XmATEXT];
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
  else if (supports_utf8_string)
Packit b099d7
    target = atoms[XmAUTF8_STRING];
Packit b099d7
#endif
Packit b099d7
  else if (supports_CT)
Packit b099d7
    target = atoms[XmACOMPOUND_TEXT];
Packit b099d7
  else if (supports_encoding_data)
Packit b099d7
    target = CS_OF_ENCODING;
Packit b099d7
  else
Packit b099d7
    target = XA_STRING;
Packit b099d7
Packit b099d7
  XmTransferValue(tid, target,
Packit b099d7
		  (XtCallbackProc) TextSecondaryWrapper,
Packit b099d7
		  closure, insert_select -> event -> time);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
Boolean
Packit b099d7
_XmTextConvert(
Packit b099d7
        Widget w,
Packit b099d7
        Atom *selection,
Packit b099d7
        Atom *target,
Packit b099d7
        Atom *type,
Packit b099d7
        XtPointer *value,
Packit b099d7
        unsigned long *length,
Packit b099d7
        int *format,
Packit b099d7
	Widget drag_context,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
  enum { XmA_MOTIF_DESTINATION, XmAINSERT_SELECTION, XmADELETE,
Packit b099d7
	 XmATARGETS, XmATEXT, XmACOMPOUND_TEXT, XmATIMESTAMP,
Packit b099d7
	 XmA_MOTIF_DROP, XmACLIPBOARD, XmANULL,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
	 XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
	 NUM_ATOMS };
Packit b099d7
  static char *atom_names[] = {
Packit b099d7
    XmS_MOTIF_DESTINATION, XmSINSERT_SELECTION, XmSDELETE,
Packit b099d7
    XmSTARGETS, XmSTEXT, XmSCOMPOUND_TEXT, XmSTIMESTAMP,
Packit b099d7
    XmS_MOTIF_DROP, XmSCLIPBOARD, XmSNULL,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
    XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
    };
Packit b099d7
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  XmTextSource source;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  Atom CS_OF_ENCODING;
Packit b099d7
  XSelectionRequestEvent * req_event = (XSelectionRequestEvent *) event;
Packit b099d7
  Boolean has_selection = False;
Packit b099d7
  XmTextPosition left = 0;
Packit b099d7
  XmTextPosition right = 0;
Packit b099d7
  Boolean is_primary;
Packit b099d7
  Boolean is_secondary;
Packit b099d7
  Boolean is_destination;
Packit b099d7
  Boolean is_drop;
Packit b099d7
  int target_count = 0;
Packit b099d7
  XTextProperty tmp_prop;
Packit b099d7
  int status = 0;
Packit b099d7
  char * tmp_value;
Packit b099d7
  Time _time;
Packit b099d7
  
Packit b099d7
  if (w == NULL) return False;
Packit b099d7
  
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
  CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
Packit b099d7
  if (req_event == NULL) 
Packit b099d7
    _time = XtLastTimestampProcessed(XtDisplay(w));
Packit b099d7
  else
Packit b099d7
    _time = req_event -> time;
Packit b099d7
  
Packit b099d7
  source = tw->text.source;
Packit b099d7
  
Packit b099d7
  if (*selection == XA_PRIMARY || *selection == atoms[XmACLIPBOARD]) {
Packit b099d7
    has_selection = (*tw->text.source->GetSelection)(source, &left, &right);
Packit b099d7
    is_primary = True;
Packit b099d7
    is_secondary = is_destination = is_drop = False;
Packit b099d7
  } else if (*selection == atoms[XmA_MOTIF_DESTINATION]) {
Packit b099d7
    has_selection = tw->text.input->data->has_destination;
Packit b099d7
    is_destination = True;
Packit b099d7
    is_secondary = is_primary = is_drop = False;
Packit b099d7
  } else if (*selection == XA_SECONDARY) {
Packit b099d7
    has_selection = _XmTextGetSel2(tw, &left, &right);
Packit b099d7
    is_secondary = True;
Packit b099d7
    is_destination = is_primary = is_drop = False;
Packit b099d7
  } else if (*selection == atoms[XmA_MOTIF_DROP]) {
Packit b099d7
    has_selection = (*tw->text.source->GetSelection)(source, &left, &right);
Packit b099d7
    is_drop = True;
Packit b099d7
    is_destination = is_primary = is_secondary = False;
Packit b099d7
  } else
Packit b099d7
    return False;
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * TARGETS identifies what targets the text widget can
Packit b099d7
   * provide data for.
Packit b099d7
   */
Packit b099d7
  if (*target == atoms[XmATARGETS]) {
Packit b099d7
    Atom *targs = XmeStandardTargets(w, 10, &target_count);
Packit b099d7
    
Packit b099d7
    *value = (XtPointer) targs;
Packit b099d7
    if (XA_STRING != CS_OF_ENCODING) {
Packit b099d7
      targs[target_count] = CS_OF_ENCODING;  target_count++;
Packit b099d7
    }
Packit b099d7
    if (is_primary || is_destination) {
Packit b099d7
      targs[target_count] = atoms[XmAINSERT_SELECTION];  target_count++;
Packit b099d7
    }
Packit b099d7
    if (is_primary || is_secondary || is_drop) {
Packit b099d7
      targs[target_count] = atoms[XmACOMPOUND_TEXT];  target_count++;
Packit b099d7
      targs[target_count] = atoms[XmATEXT];  target_count++;
Packit b099d7
      targs[target_count] = XA_STRING;  target_count++;
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      targs[target_count] = atoms[XmAUTF8_STRING];  target_count++;
Packit b099d7
#endif
Packit b099d7
    }
Packit b099d7
    if (is_primary || is_drop) {
Packit b099d7
      targs[target_count] = atoms[XmADELETE]; target_count++;
Packit b099d7
    }
Packit b099d7
    *type = XA_ATOM;
Packit b099d7
    *length = target_count;
Packit b099d7
    *format = 32;
Packit b099d7
  } else if (*target == atoms[XmATIMESTAMP]) {
Packit b099d7
    Time *timestamp;
Packit b099d7
    timestamp = (Time *) XtMalloc(sizeof(Time));
Packit b099d7
    if (is_primary)
Packit b099d7
      *timestamp = source->data->prim_time;
Packit b099d7
    else if (is_destination)
Packit b099d7
      *timestamp = tw->text.input->data->dest_time;
Packit b099d7
    else if (is_secondary)
Packit b099d7
      *timestamp = tw->text.input->data->sec_time;
Packit b099d7
    else if (is_drop)
Packit b099d7
      *timestamp = tw->text.input->data->sec_time;
Packit b099d7
    *value = (XtPointer) timestamp;
Packit b099d7
    *type = XA_INTEGER;
Packit b099d7
    *length = sizeof(Time) / 4;
Packit b099d7
    *format = 32;
Packit b099d7
  } else if (*target == XA_STRING) {
Packit b099d7
    /* Provide data for XA_STRING requests */
Packit b099d7
    *type = (Atom) XA_STRING;
Packit b099d7
    *format = 8;
Packit b099d7
    if (is_destination || !has_selection) return False;
Packit b099d7
    tmp_prop.value = NULL;
Packit b099d7
    tmp_value = _XmStringSourceGetString(tw, left, right, False);
Packit b099d7
    status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
Packit b099d7
				       (XICCEncodingStyle)XStringStyle, 
Packit b099d7
				       &tmp_prop);
Packit b099d7
    XtFree(tmp_value);
Packit b099d7
    if (status == Success || status > 0){
Packit b099d7
      /* NOTE: casting tmp_prop.nitems could result in a truncated long. */
Packit b099d7
      if (0 >= tmp_prop.nitems)
Packit b099d7
        *value = (XtPointer) XtMalloc(1);
Packit b099d7
      else
Packit b099d7
        *value = (XtPointer) XtMalloc((unsigned)tmp_prop.nitems);
Packit b099d7
      memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
Packit b099d7
      if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
Packit b099d7
      *length = tmp_prop.nitems;
Packit b099d7
    } else {
Packit b099d7
      *value = NULL;
Packit b099d7
      *length = 0;
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
  } else if (*target == atoms[XmATEXT] || *target == CS_OF_ENCODING) {
Packit b099d7
    *type = CS_OF_ENCODING;
Packit b099d7
    *format = 8;
Packit b099d7
    if (is_destination || !has_selection) return False;
Packit b099d7
    *value = (XtPointer)_XmStringSourceGetString(tw, left, right, False);
Packit b099d7
    *length = strlen((char*) *value);
Packit b099d7
  } else if (*target == atoms[XmACOMPOUND_TEXT]) {
Packit b099d7
    *type = atoms[XmACOMPOUND_TEXT];
Packit b099d7
    *format = 8;
Packit b099d7
    if (is_destination || !has_selection) return False;
Packit b099d7
    tmp_prop.value = NULL;
Packit b099d7
    tmp_value =_XmStringSourceGetString(tw, left, right, False);
Packit b099d7
    status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
Packit b099d7
				       (XICCEncodingStyle)XCompoundTextStyle,
Packit b099d7
				       &tmp_prop);
Packit b099d7
    XtFree(tmp_value);
Packit b099d7
    if (status == Success || status > 0) {
Packit b099d7
      /* NOTE: casting tmp_prop.nitems could result in a truncated long. */
Packit b099d7
      *value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
Packit b099d7
      memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
Packit b099d7
      if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
Packit b099d7
      *length = tmp_prop.nitems;
Packit b099d7
    } else {
Packit b099d7
      *value =  NULL;
Packit b099d7
      *length = 0;
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
  } else if (*target == atoms[XmAUTF8_STRING]) {
Packit b099d7
    *type = atoms[XmAUTF8_STRING];
Packit b099d7
    *format = 8;
Packit b099d7
    if (is_destination || !has_selection) return False;
Packit b099d7
    tmp_prop.value = NULL;
Packit b099d7
    tmp_value =_XmStringSourceGetString(tw, left, right, False);
Packit b099d7
    status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
Packit b099d7
				       (XICCEncodingStyle)XUTF8StringStyle,
Packit b099d7
				       &tmp_prop);
Packit b099d7
    XtFree(tmp_value);
Packit b099d7
    if (status == Success || status > 0) {
Packit b099d7
      /* NOTE: casting tmp_prop.nitems could result in a truncated long. */
Packit b099d7
      *value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
Packit b099d7
      memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
Packit b099d7
      if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
Packit b099d7
      *length = tmp_prop.nitems;
Packit b099d7
    } else {
Packit b099d7
      *value =  NULL;
Packit b099d7
      *length = 0;
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
#endif
Packit b099d7
  } else if (*target == atoms[XmAINSERT_SELECTION]) {
Packit b099d7
    if (is_secondary) 
Packit b099d7
      return False;
Packit b099d7
    else
Packit b099d7
      return True;
Packit b099d7
    /* Delete the selection */
Packit b099d7
  } else if (*target == atoms[XmADELETE]) {
Packit b099d7
    XmTextBlockRec block, newblock;
Packit b099d7
    XmTextPosition cursorPos;
Packit b099d7
    Boolean freeBlock;
Packit b099d7
    
Packit b099d7
    if (!(is_primary || is_drop)) return False;
Packit b099d7
    
Packit b099d7
    /* The on_or_off flag is set to prevent unecessary
Packit b099d7
       cursor shifting during the Replace operation */
Packit b099d7
    tw->text.on_or_off = off;
Packit b099d7
    
Packit b099d7
    block.ptr = "";
Packit b099d7
    block.length = 0;
Packit b099d7
    block.format = XmFMT_8_BIT;
Packit b099d7
    
Packit b099d7
    if (_XmTextModifyVerify(tw, event, &left, &right,
Packit b099d7
			    &cursorPos, &block, &newblock, &freeBlock)) {
Packit b099d7
      if ((*tw->text.source->Replace)(tw, event, &left, &right, 
Packit b099d7
				      &newblock, False) != EditDone) {
Packit b099d7
	if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
Packit b099d7
	return False;
Packit b099d7
      } else {
Packit b099d7
	if (is_drop) {
Packit b099d7
	  if (_XmTextGetDropReciever((Widget)tw) != (Widget) tw)
Packit b099d7
	    _XmTextSetCursorPosition((Widget)tw, cursorPos);
Packit b099d7
	} else {
Packit b099d7
	  if ((*selection == atoms[XmACLIPBOARD]) || 
Packit b099d7
	      (req_event != NULL &&
Packit b099d7
	      req_event->requestor != XtWindow((Widget) tw)))
Packit b099d7
	    _XmTextSetCursorPosition(w, cursorPos);
Packit b099d7
	}
Packit b099d7
	_XmTextValueChanged(tw, (XEvent *) req_event);
Packit b099d7
      }
Packit b099d7
      if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
Packit b099d7
    } 
Packit b099d7
    if (!tw->text.input->data->has_destination)
Packit b099d7
      tw->text.input->data->anchor = tw->text.cursor_position;
Packit b099d7
    
Packit b099d7
    (*tw->text.source->SetSelection)(tw->text.source,
Packit b099d7
				     tw->text.cursor_position,
Packit b099d7
				     tw->text.cursor_position,
Packit b099d7
				     _time);
Packit b099d7
    
Packit b099d7
    *type = atoms[XmANULL];
Packit b099d7
    *value = NULL;
Packit b099d7
    *length = 0;
Packit b099d7
    *format = 8;
Packit b099d7
    
Packit b099d7
    tw->text.on_or_off = on;
Packit b099d7
    
Packit b099d7
    /* unknown selection type */
Packit b099d7
  } else
Packit b099d7
    return FALSE;
Packit b099d7
  return TRUE;
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void
Packit b099d7
_XmTextLoseSelection(
Packit b099d7
        Widget w,
Packit b099d7
        Atom *selection )
Packit b099d7
{
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  XmTextSource source = tw->text.source;
Packit b099d7
  Atom MOTIF_DESTINATION = XInternAtom(XtDisplay(w),
Packit b099d7
				       XmS_MOTIF_DESTINATION, False);
Packit b099d7
  /* Losing Primary Selection */
Packit b099d7
  if (*selection == XA_PRIMARY && _XmStringSourceHasSelection(source)) {
Packit b099d7
    XmAnyCallbackStruct cb;
Packit b099d7
    (*source->SetSelection)(source, 1, -999,
Packit b099d7
			    XtLastTimestampProcessed(XtDisplay(w)));
Packit b099d7
    cb.reason = XmCR_LOSE_PRIMARY;
Packit b099d7
    cb.event = NULL;
Packit b099d7
    XtCallCallbackList(w, tw->text.lose_primary_callback, (XtPointer) &cb;;
Packit b099d7
    /* Losing Destination Selection */
Packit b099d7
  } else if (*selection == MOTIF_DESTINATION) {
Packit b099d7
    tw->text.input->data->has_destination = False;
Packit b099d7
    (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
Packit b099d7
    tw->text.output->data->blinkstate = on;
Packit b099d7
    (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
Packit b099d7
    /* Losing Secondary Selection */
Packit b099d7
  } else if (*selection == XA_SECONDARY && tw->text.input->data->hasSel2){
Packit b099d7
    _XmTextSetSel2(tw, 1, -999, XtLastTimestampProcessed(XtDisplay(w)));
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void
Packit b099d7
HandleDrop(Widget w,
Packit b099d7
	   XmDropProcCallbackStruct *cb,
Packit b099d7
	   XmDestinationCallbackStruct *ds)
Packit b099d7
{
Packit b099d7
  Widget drag_cont, initiator;
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  Cardinal numExportTargets, n;
Packit b099d7
  Atom *exportTargets;
Packit b099d7
  Atom desiredTarget = None;
Packit b099d7
  Arg args[10];
Packit b099d7
  XmTextPosition insert_pos, left, right;
Packit b099d7
  Boolean doTransfer = False;
Packit b099d7
  XtPointer tid = ds->transfer_id;
Packit b099d7
  _XmTextDropTransferRec *transfer_rec = NULL;
Packit b099d7
  
Packit b099d7
  drag_cont = cb->dragContext;
Packit b099d7
  
Packit b099d7
  n = 0;
Packit b099d7
  XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
Packit b099d7
  XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
Packit b099d7
  XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
Packit b099d7
  XtGetValues((Widget) drag_cont, args, n);
Packit b099d7
  
Packit b099d7
  insert_pos = (*tw->text.output->XYToPos)(tw, cb->x, cb->y);
Packit b099d7
  
Packit b099d7
  if (cb->operation & XmDROP_MOVE && w == initiator &&
Packit b099d7
      ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
Packit b099d7
       left != right && insert_pos >= left && insert_pos <= right)) {
Packit b099d7
    XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
Packit b099d7
  } else {
Packit b099d7
    enum { XmATEXT, XmACOMPOUND_TEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
        XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
	NUM_ATOMS };
Packit b099d7
    static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
        XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
	};
Packit b099d7
    Atom atoms[XtNumber(atom_names)];
Packit b099d7
    Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
    Boolean encoding_found = False;
Packit b099d7
    Boolean c_text_found = False;
Packit b099d7
    Boolean string_found = False;
Packit b099d7
    Boolean text_found = False;
Packit b099d7
    Boolean utf8_string_found = False;
Packit b099d7
    
Packit b099d7
    assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
    XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
    /* intialize data to send to drop transfer callback */
Packit b099d7
    transfer_rec = (_XmTextDropTransferRec *)
Packit b099d7
      XtMalloc(sizeof(_XmTextDropTransferRec));
Packit b099d7
    transfer_rec->widget = w;
Packit b099d7
    transfer_rec->insert_pos = insert_pos;
Packit b099d7
    transfer_rec->num_chars = 0;
Packit b099d7
    transfer_rec->timestamp = cb->timeStamp;
Packit b099d7
    
Packit b099d7
    if (cb->operation & XmDROP_MOVE) {
Packit b099d7
      transfer_rec->move = True;
Packit b099d7
    } else {
Packit b099d7
      transfer_rec->move = False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    for (n = 0; n < numExportTargets; n++) {
Packit b099d7
      if (exportTargets[n] == CS_OF_ENCODING) {
Packit b099d7
	desiredTarget = CS_OF_ENCODING;
Packit b099d7
	encoding_found = True;
Packit b099d7
	break;
Packit b099d7
      }
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      if (exportTargets[n] == atoms[XmAUTF8_STRING]) utf8_string_found = True;
Packit b099d7
#endif
Packit b099d7
      if (exportTargets[n] == atoms[XmACOMPOUND_TEXT]) c_text_found = True;
Packit b099d7
      if (exportTargets[n] == XA_STRING) string_found = True;
Packit b099d7
      if (exportTargets[n] == atoms[XmATEXT]) text_found = True;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    n = 0;
Packit b099d7
    if (encoding_found || c_text_found || string_found || text_found
Packit b099d7
        || utf8_string_found) {
Packit b099d7
      if (!encoding_found) {
Packit b099d7
	if (c_text_found)
Packit b099d7
	  desiredTarget = atoms[XmACOMPOUND_TEXT];
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
	else if (utf8_string_found)
Packit b099d7
	  desiredTarget = atoms[XmAUTF8_STRING];
Packit b099d7
#endif
Packit b099d7
	else if (string_found)
Packit b099d7
	  desiredTarget = XA_STRING;
Packit b099d7
	else
Packit b099d7
	  desiredTarget = atoms[XmATEXT];
Packit b099d7
      }
Packit b099d7
      
Packit b099d7
      if (cb->operation & XmDROP_MOVE || cb->operation & XmDROP_COPY) {
Packit b099d7
	doTransfer = True;
Packit b099d7
      } else {
Packit b099d7
	XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
Packit b099d7
      }
Packit b099d7
    } else {
Packit b099d7
      XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  SetDropContext(w);
Packit b099d7
  
Packit b099d7
  if (doTransfer) {
Packit b099d7
    XmeTransferAddDoneProc(tid, (XmSelectionFinishedProc) DropDestroyCB);
Packit b099d7
    XmTransferValue(tid, desiredTarget,
Packit b099d7
		    (XtCallbackProc) DropTransferProc,
Packit b099d7
		    (XtPointer) transfer_rec, 0);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* Request targets from selection receiver; move the rest of this
Packit b099d7
 * to a new routine (the name of which is passed during the request
Packit b099d7
 * for targets).  The new routine will look at the target list and
Packit b099d7
 * determine what target to place in the pair.  It will then do
Packit b099d7
 * any necessary conversions before "thrusting" the selection value
Packit b099d7
 * onto the receiver.  This will guarantee the best chance at a
Packit b099d7
 * successful exchange.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
HandleTargets(Widget w, 
Packit b099d7
	      XtPointer closure,
Packit b099d7
	      XmSelectionCallbackStruct *ds)
Packit b099d7
{
Packit b099d7
  enum { XmACOMPOUND_TEXT, XmACLIPBOARD, XmATEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
      NUM_ATOMS };
Packit b099d7
  static char *atom_names[] =  { XmSCOMPOUND_TEXT, XmSCLIPBOARD, XmSTEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
      };
Packit b099d7
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  Atom CS_OF_ENCODING;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  Boolean supports_encoding_data = False;
Packit b099d7
  Boolean supports_CT = False;
Packit b099d7
  Boolean supports_text = False;
Packit b099d7
  Boolean supports_utf8_string = False;
Packit b099d7
  Atom *atom_ptr;
Packit b099d7
  XPoint *point = (XPoint *)closure;
Packit b099d7
  Atom targets[2];
Packit b099d7
  XmTextPosition select_pos;
Packit b099d7
  XmTextPosition left, right;
Packit b099d7
  int i;
Packit b099d7
  
Packit b099d7
  if (!ds->length) {
Packit b099d7
    XtFree((char *)ds->value);
Packit b099d7
    ds->value = NULL;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
  CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
Packit b099d7
  atom_ptr = (Atom *)ds->value;
Packit b099d7
  
Packit b099d7
  for (i = 0; i < ds->length; i++, atom_ptr++) {
Packit b099d7
    if (*atom_ptr == atoms[XmATEXT])
Packit b099d7
      supports_text = True;
Packit b099d7
Packit b099d7
    if (*atom_ptr == CS_OF_ENCODING) 
Packit b099d7
      supports_encoding_data = True;
Packit b099d7
Packit b099d7
    if (*atom_ptr == atoms[XmACOMPOUND_TEXT])
Packit b099d7
      supports_CT = True;
Packit b099d7
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
    if (*atom_ptr == atoms[XmAUTF8_STRING])
Packit b099d7
      supports_utf8_string = True;
Packit b099d7
#endif
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * Set stuff position to the x and y position of
Packit b099d7
   * the button pressed event for primary pastes.
Packit b099d7
   */
Packit b099d7
  if (ds->selection != atoms[XmACLIPBOARD] && point) {
Packit b099d7
    select_pos = 
Packit b099d7
      (*tw->text.output->XYToPos)(tw, (Position)point->x, (Position)point->y);
Packit b099d7
  } else {
Packit b099d7
    select_pos = tw->text.cursor_position;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (ds->selection != atoms[XmACLIPBOARD]) {
Packit b099d7
    if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) && 
Packit b099d7
	left != right && select_pos > left && 
Packit b099d7
	select_pos < right) {
Packit b099d7
      XtFree((char *)ds->value);
Packit b099d7
      ds->value = NULL;
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (prim_select) {
Packit b099d7
    prim_select->ref_count++;
Packit b099d7
  } else {
Packit b099d7
    prim_select = (_XmTextPrimSelect *)
Packit b099d7
      XtMalloc((unsigned) sizeof(_XmTextPrimSelect));
Packit b099d7
  }
Packit b099d7
  prim_select->position = select_pos;
Packit b099d7
  prim_select->time = XtLastTimestampProcessed(XtDisplay(w));
Packit b099d7
  prim_select->num_chars = 0;
Packit b099d7
  
Packit b099d7
  /* If owner supports TEXT and the current locale, ask for TEXT.  
Packit b099d7
   * If not, and if the owner supports compound text, ask for 
Packit b099d7
   * compound text. If not, and owner and I have the same encoding, 
Packit b099d7
   * ask for that encoding. If not, fall back position is to ask for 
Packit b099d7
   * STRING and try to convert it locally.
Packit b099d7
   */
Packit b099d7
  
Packit b099d7
  if (supports_text && supports_encoding_data)
Packit b099d7
    prim_select->target = targets[0] = atoms[XmATEXT];
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
  else if (supports_utf8_string)
Packit b099d7
    prim_select->target = targets[0] = atoms[XmAUTF8_STRING];
Packit b099d7
#endif
Packit b099d7
  else if (supports_CT)
Packit b099d7
    prim_select->target = targets[0] = atoms[XmACOMPOUND_TEXT];
Packit b099d7
  else if (supports_encoding_data)
Packit b099d7
    prim_select->target = targets[0] = CS_OF_ENCODING;
Packit b099d7
  else
Packit b099d7
    prim_select->target = targets[0] = XA_STRING;
Packit b099d7
  
Packit b099d7
  prim_select->ref_count = 1;
Packit b099d7
  /* Make request to call DoStuff() with the primary selection. */
Packit b099d7
  XmTransferValue(ds->transfer_id, targets[0], (XtCallbackProc) DoStuff, 
Packit b099d7
		  (XtPointer) prim_select, prim_select->time);
Packit b099d7
  
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  XtFree((char *)ds->value);
Packit b099d7
  ds->value = NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
/* Pastes the primary selection to the stuff position. */
Packit b099d7
static void
Packit b099d7
DoStuff(Widget w, 
Packit b099d7
	XtPointer closure, 
Packit b099d7
	XmSelectionCallbackStruct *ds)
Packit b099d7
{
Packit b099d7
  enum { XmANULL, XmACLIPBOARD, XmATEXT, XmACOMPOUND_TEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
      NUM_ATOMS };
Packit b099d7
  static char *atom_names[] =  { 
Packit b099d7
    XmSNULL, XmSCLIPBOARD, XmSTEXT, XmSCOMPOUND_TEXT,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
    XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
    };
Packit b099d7
Packit b099d7
  XmTextWidget tw = (XmTextWidget) w;
Packit b099d7
  InputData data = tw->text.input->data;
Packit b099d7
  OutputData o_data = tw->text.output->data;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  XmTextBlockRec block, newblock;
Packit b099d7
  XmTextPosition cursorPos = tw->text.cursor_position;
Packit b099d7
  XmTextPosition right, left, replace_from, replace_to;
Packit b099d7
  _XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
Packit b099d7
  char * total_value = NULL;
Packit b099d7
  Boolean freeBlock;
Packit b099d7
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
  if (!o_data->hasfocus && _XmGetFocusPolicy(w) == XmEXPLICIT)
Packit b099d7
    (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
Packit b099d7
  
Packit b099d7
  if (ds->selection != atoms[XmACLIPBOARD] && 
Packit b099d7
      !(ds->length) && ds->type != atoms[XmANULL]) {
Packit b099d7
    /* Backwards compatibility for 1.0 Selections */
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (prim_select->target == atoms[XmATEXT]) {
Packit b099d7
      prim_select->target = XA_STRING;
Packit b099d7
      XmTransferValue(ds->transfer_id, XA_STRING, (XtCallbackProc) DoStuff,
Packit b099d7
		      (XtPointer) prim_select, prim_select->time);
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    XtFree((char *)ds->value);
Packit b099d7
    ds->value = NULL;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  /* if length == 0 and ds->type is the NULL atom we are assuming
Packit b099d7
   * that a DELETE target is requested.
Packit b099d7
   */
Packit b099d7
  if (ds->type == atoms[XmANULL]) {
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (prim_select->num_chars > 0 && data->selectionMove) {
Packit b099d7
      data->anchor = prim_select->position;
Packit b099d7
      cursorPos = prim_select->position + prim_select->num_chars;
Packit b099d7
      _XmTextSetCursorPosition(w, cursorPos);
Packit b099d7
      _XmTextSetDestinationSelection(w, tw->text.cursor_position,
Packit b099d7
				     False, prim_select->time);
Packit b099d7
      (*tw->text.source->SetSelection)(tw->text.source, data->anchor,
Packit b099d7
				       tw->text.cursor_position,
Packit b099d7
				       prim_select->time);
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
  } else {
Packit b099d7
    XmTextSource source = GetSrc(w);
Packit b099d7
    int max_length = 0;
Packit b099d7
    Boolean local = _XmStringSourceHasSelection(source);
Packit b099d7
    Boolean *pendingoff = NULL;
Packit b099d7
    Boolean dest_disjoint = True;
Packit b099d7
    
Packit b099d7
    block.format = XmFMT_8_BIT;
Packit b099d7
    
Packit b099d7
    if (ds->type == atoms[XmACOMPOUND_TEXT] ||
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
        ds->type == atoms[XmAUTF8_STRING] ||
Packit b099d7
#endif
Packit b099d7
	ds->type == XA_STRING) {
Packit b099d7
      if ((total_value = 
Packit b099d7
	   _XmTextToLocaleText(w, ds->value, ds->type, ds->format,
Packit b099d7
			       ds->length, NULL)) != NULL) {
Packit b099d7
	block.ptr = total_value;
Packit b099d7
	block.length = strlen(block.ptr);
Packit b099d7
      } else {
Packit b099d7
	block.ptr = total_value = XtMalloc((unsigned)1);
Packit b099d7
	*(block.ptr) = '\0';
Packit b099d7
	block.length = 0;
Packit b099d7
      }
Packit b099d7
    } else {
Packit b099d7
      block.ptr = (char*)ds->value;
Packit b099d7
      block.length = (int) ds->length; /* NOTE: this causes a truncation on
Packit b099d7
					  some architectures */
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (data->selectionMove && local) {
Packit b099d7
      max_length = _XmStringSourceGetMaxLength(source);
Packit b099d7
      _XmStringSourceSetMaxLength(source, INT_MAX);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    replace_from = replace_to = prim_select->position;
Packit b099d7
    pendingoff = _XmStringSourceGetPending(tw);
Packit b099d7
Packit b099d7
    if (ds->selection == atoms[XmACLIPBOARD]) {
Packit b099d7
      if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
Packit b099d7
	if (tw->text.input->data->pendingdelete &&
Packit b099d7
	    replace_from >= left && replace_to <= right){
Packit b099d7
	  replace_from = left;
Packit b099d7
	  replace_to = right;
Packit b099d7
	  dest_disjoint = False;
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
   } else {  
Packit b099d7
      /* The on_or_off flag is set to prevent unnecessary
Packit b099d7
	 cursor shifting during the Replace operation */
Packit b099d7
      tw->text.on_or_off = off;
Packit b099d7
Packit b099d7
      _XmStringSourceSetPending(tw, (Boolean *)FALSE);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (_XmTextModifyVerify(tw, ds->event, &replace_from, &replace_to,
Packit b099d7
			    &cursorPos, &block, &newblock, &freeBlock)) {
Packit b099d7
      _XmProcessLock();
Packit b099d7
      prim_select->num_chars = _XmTextCountCharacters(newblock.ptr, 
Packit b099d7
						      newblock.length);
Packit b099d7
      _XmProcessUnlock();
Packit b099d7
      if ((*tw->text.source->Replace)(tw, ds->event, 
Packit b099d7
				      &replace_from, &replace_to,
Packit b099d7
				      &newblock, False) != EditDone) {
Packit b099d7
	XtCallActionProc(w, "beep", NULL, (String *) NULL, (Cardinal) 0);
Packit b099d7
	_XmProcessLock();
Packit b099d7
	prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
Packit b099d7
				       anything */
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	_XmStringSourceSetPending(tw, pendingoff);
Packit b099d7
      } else {
Packit b099d7
	if ((newblock.length > 0 && !data->selectionMove) || 
Packit b099d7
	    ds->selection == atoms[XmACLIPBOARD]) {
Packit b099d7
	  _XmTextSetCursorPosition(w, cursorPos);
Packit b099d7
	  _XmTextSetDestinationSelection(w, tw->text.cursor_position,
Packit b099d7
					 False, prim_select->time);
Packit b099d7
	}
Packit b099d7
	if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
Packit b099d7
	  if (ds->selection == atoms[XmACLIPBOARD]) {
Packit b099d7
	    data->anchor = replace_from;
Packit b099d7
	    if (left != right && (!dest_disjoint || !tw->text.add_mode))
Packit b099d7
	      (*source->SetSelection)(source, tw->text.cursor_position,
Packit b099d7
				      tw->text.cursor_position, 
Packit b099d7
				      prim_select->time);
Packit b099d7
	  } else {
Packit b099d7
	    if (data->selectionMove) {
Packit b099d7
	      _XmProcessLock();
Packit b099d7
	      if (left < replace_from) {
Packit b099d7
		prim_select->position = replace_from -
Packit b099d7
		  prim_select->num_chars;
Packit b099d7
	      } else {
Packit b099d7
		prim_select->position = replace_from;
Packit b099d7
	      }
Packit b099d7
	      _XmProcessUnlock();
Packit b099d7
	    }
Packit b099d7
	    if (cursorPos < left || cursorPos > right)
Packit b099d7
	      _XmStringSourceSetPending(tw, (Boolean *)TRUE);
Packit b099d7
	    else
Packit b099d7
	      _XmStringSourceSetPending(tw, pendingoff);
Packit b099d7
	  }
Packit b099d7
	} else {
Packit b099d7
	  _XmProcessLock();
Packit b099d7
	  if (ds->selection == atoms[XmACLIPBOARD])
Packit b099d7
	    data->anchor = replace_from;
Packit b099d7
	  else if (!data->selectionMove && !tw->text.add_mode &&
Packit b099d7
	      prim_select->num_chars != 0)
Packit b099d7
	    data->anchor = prim_select->position;
Packit b099d7
	  _XmProcessUnlock();
Packit b099d7
	}
Packit b099d7
	_XmTextValueChanged(tw, ds->event);
Packit b099d7
      }
Packit b099d7
      if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
Packit b099d7
    } else {
Packit b099d7
      XtCallActionProc(w, "beep", NULL, (String *) NULL, (Cardinal) 0);
Packit b099d7
      _XmProcessLock();
Packit b099d7
      prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
Packit b099d7
				     anything */
Packit b099d7
      _XmProcessUnlock();
Packit b099d7
      _XmStringSourceSetPending(tw, pendingoff);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (data->selectionMove && local) {
Packit b099d7
      _XmStringSourceSetMaxLength(source, max_length);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (ds->selection != atoms[XmACLIPBOARD]) 
Packit b099d7
      tw->text.on_or_off = on;
Packit b099d7
Packit b099d7
    if (pendingoff) XtFree((char *)pendingoff);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (total_value) XtFree(total_value);
Packit b099d7
  XtFree((char *)ds->value);
Packit b099d7
  ds->value = NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
DropDestroyCB(Widget      w,
Packit b099d7
	      XtPointer   clientData,
Packit b099d7
	      XtPointer   callData)
Packit b099d7
{
Packit b099d7
  XmTransferDoneCallbackStruct *ts = (XmTransferDoneCallbackStruct *)callData;
Packit b099d7
  
Packit b099d7
  DeleteDropContext(w);
Packit b099d7
  if (ts->client_data != NULL) XtFree((char*) ts->client_data);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
DropTransferProc(Widget w, 
Packit b099d7
		 XtPointer closure, 
Packit b099d7
		 XmSelectionCallbackStruct *ds)
Packit b099d7
{
Packit b099d7
  enum { XmACOMPOUND_TEXT, XmANULL, XmADELETE,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
  XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
  NUM_ATOMS };
Packit b099d7
  static char *atom_names[] = { XmSCOMPOUND_TEXT, XmSNULL, XmSDELETE,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
      };
Packit b099d7
Packit b099d7
  _XmTextDropTransferRec *transfer_rec = (_XmTextDropTransferRec *) closure;
Packit b099d7
  XmTextWidget tw = (XmTextWidget) transfer_rec->widget;
Packit b099d7
  InputData data = tw->text.input->data;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
  XmTextPosition insertPosLeft, insertPosRight, left, right, cursorPos;
Packit b099d7
  XmTextBlockRec block, newblock;
Packit b099d7
  XmTextSource source = GetSrc((Widget)tw);
Packit b099d7
  int max_length = 0;
Packit b099d7
  Boolean local = _XmStringSourceHasSelection(source);
Packit b099d7
  char * total_value = NULL;
Packit b099d7
  Boolean pendingoff;
Packit b099d7
  Boolean freeBlock;
Packit b099d7
  
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
  /* When type = NULL, we are assuming a DELETE request has been requested */
Packit b099d7
  if (ds->type == atoms[XmANULL]) {
Packit b099d7
    if (transfer_rec->num_chars > 0 && transfer_rec->move) {
Packit b099d7
      data->anchor = transfer_rec->insert_pos;
Packit b099d7
      cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
Packit b099d7
      _XmTextSetCursorPosition((Widget)tw, cursorPos);
Packit b099d7
      _XmTextSetDestinationSelection((Widget)tw, tw->text.cursor_position,
Packit b099d7
				     False, 
Packit b099d7
				     XtLastTimestampProcessed(XtDisplay(w)));
Packit b099d7
      (*tw->text.source->SetSelection)(tw->text.source, data->anchor,
Packit b099d7
				       tw->text.cursor_position,
Packit b099d7
				       XtLastTimestampProcessed(XtDisplay(w)));
Packit b099d7
      if (ds->value) {
Packit b099d7
	XtFree((char *) ds->value);
Packit b099d7
	ds->value = NULL;
Packit b099d7
      }
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (!ds->value || 
Packit b099d7
      (ds->type != atoms[XmACOMPOUND_TEXT] && 
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
       ds->type != atoms[XmAUTF8_STRING] && 
Packit b099d7
#endif
Packit b099d7
       ds->type != CS_OF_ENCODING &&
Packit b099d7
       ds->type != XA_STRING)) {
Packit b099d7
    XmTransferDone(ds->transfer_id, XmTRANSFER_DONE_FAIL);
Packit b099d7
    if (ds->value) {
Packit b099d7
      XtFree((char*) ds->value);
Packit b099d7
      ds->value = NULL;
Packit b099d7
    }
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  insertPosLeft = insertPosRight = transfer_rec->insert_pos;
Packit b099d7
  
Packit b099d7
  if (ds->type == XA_STRING || ds->type == atoms[XmACOMPOUND_TEXT]
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      || ds->type == atoms[XmAUTF8_STRING]
Packit b099d7
#endif
Packit b099d7
  ) {
Packit b099d7
    if ((total_value = _XmTextToLocaleText(w, ds->value, ds->type, 
Packit b099d7
					   8, ds->length, NULL)) != NULL) {
Packit b099d7
      block.ptr = total_value;
Packit b099d7
      block.length = strlen(block.ptr);
Packit b099d7
    } else {
Packit b099d7
      if (ds->value) {
Packit b099d7
	XtFree((char*) ds->value);
Packit b099d7
	ds->value = NULL;
Packit b099d7
      }
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
  } else {
Packit b099d7
    block.ptr = (char *) ds->value;
Packit b099d7
    block.length = (int) ds->length; /* NOTE: this causes a truncation on
Packit b099d7
					  some architectures */
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  block.format = XmFMT_8_BIT;
Packit b099d7
  
Packit b099d7
  if (data->pendingdelete && 
Packit b099d7
      (*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
Packit b099d7
      (left != right)){
Packit b099d7
    if(insertPosLeft > left && insertPosLeft < right) insertPosLeft = left;
Packit b099d7
    if(insertPosRight < right && insertPosRight > left) insertPosRight = right;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (transfer_rec->move && local) {
Packit b099d7
    max_length = _XmStringSourceGetMaxLength(source);
Packit b099d7
    _XmStringSourceSetMaxLength(source, INT_MAX);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  /* The on_or_off flag is set to prevent unecessary
Packit b099d7
     cursor shifting during the Replace operation */
Packit b099d7
  tw->text.on_or_off = off;
Packit b099d7
Packit b099d7
  pendingoff = tw->text.pendingoff;
Packit b099d7
  tw->text.pendingoff = FALSE;
Packit b099d7
  
Packit b099d7
  if (_XmTextModifyVerify(tw, ds->event, &insertPosLeft, &insertPosRight,
Packit b099d7
			  &cursorPos, &block, &newblock, &freeBlock)) {
Packit b099d7
    if ((*tw->text.source->Replace)(tw, ds->event, 
Packit b099d7
				    &insertPosLeft, &insertPosRight,
Packit b099d7
				    &newblock, False) != EditDone) {
Packit b099d7
      if (tw->text.verify_bell) XBell(XtDisplay(tw), 0);
Packit b099d7
      tw->text.pendingoff = pendingoff;
Packit b099d7
    } else {
Packit b099d7
      transfer_rec->num_chars = _XmTextCountCharacters(newblock.ptr,
Packit b099d7
						       newblock.length);
Packit b099d7
      if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
Packit b099d7
	_XmTextSetCursorPosition((Widget)tw, cursorPos);
Packit b099d7
	_XmTextSetDestinationSelection((Widget)tw,
Packit b099d7
				       tw->text.cursor_position,False,
Packit b099d7
				       transfer_rec->timestamp);
Packit b099d7
      }
Packit b099d7
      if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
Packit b099d7
	if (transfer_rec->move && left < insertPosLeft)
Packit b099d7
	  transfer_rec->insert_pos = insertPosLeft -
Packit b099d7
	    transfer_rec->num_chars;
Packit b099d7
	if (cursorPos < left || cursorPos > right)
Packit b099d7
	  tw->text.pendingoff = TRUE;
Packit b099d7
      } else {
Packit b099d7
	if (!transfer_rec->move && !tw->text.add_mode &&
Packit b099d7
	    transfer_rec->num_chars != 0)
Packit b099d7
	  data->anchor = insertPosLeft;
Packit b099d7
      }
Packit b099d7
      if (transfer_rec->move) {
Packit b099d7
	XmTransferValue(ds->transfer_id, 
Packit b099d7
			atoms[XmADELETE],
Packit b099d7
			(XtCallbackProc) DropTransferProc, 
Packit b099d7
			(XtPointer) transfer_rec, 0);
Packit b099d7
      }
Packit b099d7
      
Packit b099d7
      if (transfer_rec->move && local) {
Packit b099d7
	_XmStringSourceSetMaxLength(source, max_length);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      _XmTextValueChanged(tw, (XEvent *) ds->event);
Packit b099d7
    }
Packit b099d7
    if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
Packit b099d7
  } else {
Packit b099d7
    if (tw->text.verify_bell) XBell(XtDisplay(tw), 0);
Packit b099d7
    tw->text.pendingoff = pendingoff;
Packit b099d7
  }
Packit b099d7
  tw->text.on_or_off = on;
Packit b099d7
Packit b099d7
  if (total_value) XtFree(total_value);
Packit b099d7
  if (ds->value != NULL) XtFree((char*) ds->value);
Packit b099d7
  ds->value = NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
SetDropContext(Widget w)
Packit b099d7
{
Packit b099d7
  Display *display = XtDisplay(w);
Packit b099d7
  Screen  *screen = XtScreen(w);
Packit b099d7
  XContext loc_context;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (_XmTextDNDContext == 0)
Packit b099d7
	_XmTextDNDContext = XUniqueContext();
Packit b099d7
  loc_context = _XmTextDNDContext;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
Packit b099d7
  XSaveContext(display, (Window)screen,
Packit b099d7
	       loc_context, (XPointer)w);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void
Packit b099d7
DeleteDropContext(Widget w)
Packit b099d7
{
Packit b099d7
  Display *display = XtDisplay(w);
Packit b099d7
  Screen  *screen = XtScreen(w);
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  XDeleteContext(display, (Window)screen, _XmTextDNDContext);
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Widget
Packit b099d7
_XmTextGetDropReciever(Widget w)
Packit b099d7
{
Packit b099d7
  Display *display = XtDisplay(w);
Packit b099d7
  Screen  *screen = XtScreen(w);
Packit b099d7
  Widget widget;
Packit b099d7
  XContext loc_context;
Packit b099d7
 
Packit b099d7
  _XmProcessLock();
Packit b099d7
  loc_context = _XmTextDNDContext;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  if (loc_context == 0) return NULL;
Packit b099d7
  
Packit b099d7
  if (!XFindContext(display, (Window)screen,
Packit b099d7
		    loc_context, (char **) &widget)) {
Packit b099d7
    return widget;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  return NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/********************************************
Packit b099d7
 * Transfer trait method implementation 
Packit b099d7
 ********************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
TextConvertCallback(Widget w, 
Packit b099d7
		    XtPointer ignore, /* unused */
Packit b099d7
		    XmConvertCallbackStruct *cs)
Packit b099d7
{
Packit b099d7
  enum { XmADELETE, XmA_MOTIF_LOSE_SELECTION,
Packit b099d7
	 XmA_MOTIF_EXPORT_TARGETS, XmATEXT, XmACOMPOUND_TEXT,
Packit b099d7
	 XmATARGETS, XmA_MOTIF_CLIPBOARD_TARGETS, XmACLIPBOARD,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
	 XmAUTF8_STRING,
Packit b099d7
#endif
Packit b099d7
	 NUM_ATOMS };
Packit b099d7
  static char *atom_names[] = { XmSDELETE, XmS_MOTIF_LOSE_SELECTION,
Packit b099d7
	 XmS_MOTIF_EXPORT_TARGETS, XmSTEXT, XmSCOMPOUND_TEXT,
Packit b099d7
	 XmSTARGETS, XmS_MOTIF_CLIPBOARD_TARGETS, XmSCLIPBOARD,
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
	 XmSUTF8_STRING
Packit b099d7
#endif
Packit b099d7
	 };
Packit b099d7
Packit b099d7
  Atom XA_CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
  XtPointer value;
Packit b099d7
  Atom type;
Packit b099d7
  unsigned long size;
Packit b099d7
  int format;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
  value = NULL;
Packit b099d7
Packit b099d7
  if (cs->target == atoms[XmA_MOTIF_LOSE_SELECTION]) {
Packit b099d7
    _XmTextLoseSelection(w, &(cs->selection));
Packit b099d7
    cs->status = XmCONVERT_DONE;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (cs->target == atoms[XmADELETE] &&
Packit b099d7
      cs->selection == XA_SECONDARY) {
Packit b099d7
    _XmTextHandleSecondaryFinished(w, cs->event);
Packit b099d7
    cs->status = XmCONVERT_DONE;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  /* When this is called as a result of a clipboard copy link,  we
Packit b099d7
     don't have any available targets.  Make sure to return immediately
Packit b099d7
     without modification */
Packit b099d7
  if (cs->selection == atoms[XmACLIPBOARD] &&
Packit b099d7
      cs->parm == (XtPointer) XmLINK &&
Packit b099d7
      (cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS] ||
Packit b099d7
       cs->target == atoms[XmATARGETS])) return;
Packit b099d7
  
Packit b099d7
  if (!_XmTextConvert(w, &cs->selection, &cs->target,
Packit b099d7
		      &type, &value, &size, &format,
Packit b099d7
		      (Widget) cs->source_data, cs->event)) {
Packit b099d7
    value = NULL;
Packit b099d7
    type = XA_INTEGER;
Packit b099d7
    size = 0;
Packit b099d7
    format = 8;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (cs->target == atoms[XmADELETE]) {
Packit b099d7
    cs->status = XmCONVERT_DONE;
Packit b099d7
    cs->type = type;
Packit b099d7
    cs->value = value;
Packit b099d7
    cs->length = size;
Packit b099d7
    cs->format = format;
Packit b099d7
    return;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (cs->target == atoms[XmA_MOTIF_EXPORT_TARGETS] ||
Packit b099d7
      cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS]) {
Packit b099d7
    Atom *targs = (Atom *) XtMalloc(sizeof(Atom) * 5);
Packit b099d7
    int n = 0;
Packit b099d7
    
Packit b099d7
    value = (XtPointer) targs;
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
    targs[n] = atoms[XmAUTF8_STRING]; n++;
Packit b099d7
#endif
Packit b099d7
    targs[n] = atoms[XmACOMPOUND_TEXT]; n++;
Packit b099d7
    targs[n] = atoms[XmATEXT]; n++;
Packit b099d7
    targs[n] = XA_STRING; n++;
Packit b099d7
    if (XA_CS_OF_ENCODING != XA_STRING) {
Packit b099d7
      targs[n] = XA_CS_OF_ENCODING; n++;
Packit b099d7
    }
Packit b099d7
    format = 32;
Packit b099d7
    size = n;
Packit b099d7
    type = XA_ATOM;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  _XmConvertComplete(w, value, size, format, type, cs);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************
Packit b099d7
 * Free data allocated for destination callback 
Packit b099d7
 ************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
FreeLocationData(Widget w,     /* unused */
Packit b099d7
		 XtEnum op,    /* unused */
Packit b099d7
		 XmTransferDoneCallbackStruct *ts) 
Packit b099d7
{
Packit b099d7
  XmDestinationCallbackStruct *ds;
Packit b099d7
Packit b099d7
  ds = _XmTransferGetDestinationCBStruct(ts->transfer_id);
Packit b099d7
Packit b099d7
  XtFree((char*) ds->location_data);
Packit b099d7
Packit b099d7
  ds->location_data = NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
TextDestinationCallback(Widget w, 
Packit b099d7
			XtPointer closure, /* unused */
Packit b099d7
			XmDestinationCallbackStruct *ds)
Packit b099d7
{
Packit b099d7
  enum { XmATARGETS, XmA_MOTIF_DROP, NUM_ATOMS };
Packit b099d7
  static char *atom_names[] = { XmSTARGETS, XmS_MOTIF_DROP };
Packit b099d7
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  XPoint DropPoint;
Packit b099d7
Packit b099d7
  assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   ** In case of a primary transfer operation where a location_data
Packit b099d7
   ** has been allocated, register a done proc to be called when 
Packit b099d7
   ** the data transfer is complete to free the location_data
Packit b099d7
   */
Packit b099d7
  if (ds->selection == XA_PRIMARY && ds->location_data)
Packit b099d7
      XmeTransferAddDoneProc(ds->transfer_id, FreeLocationData);
Packit b099d7
Packit b099d7
  /* If we aren't sensitive,  don't allow transfer */
Packit b099d7
  if (! w -> core.sensitive ||
Packit b099d7
      ! w -> core.ancestor_sensitive) 
Packit b099d7
    XmTransferDone(ds -> transfer_id, XmTRANSFER_DONE_FAIL);
Packit b099d7
Packit b099d7
  /* We don't handle LINKs internally */
Packit b099d7
  if (ds->operation == XmLINK) return;
Packit b099d7
  
Packit b099d7
  if (ds->selection == XA_PRIMARY && ds->operation == XmMOVE)
Packit b099d7
    XmeTransferAddDoneProc(ds->transfer_id, SetPrimarySelection);
Packit b099d7
  else
Packit b099d7
    XmeTransferAddDoneProc(ds->transfer_id, CleanPrimarySelection);
Packit b099d7
     
Packit b099d7
  if (ds->selection == atoms[XmA_MOTIF_DROP]) {
Packit b099d7
    XmDropProcCallbackStruct *cb = 
Packit b099d7
      (XmDropProcCallbackStruct *) ds->destination_data;
Packit b099d7
    
Packit b099d7
    DropPoint.x = cb->x;
Packit b099d7
    DropPoint.y = cb->y;
Packit b099d7
    
Packit b099d7
    ds->location_data = (XtPointer) &DropPoint;
Packit b099d7
    
Packit b099d7
    if (cb->dropAction != XmDROP_HELP) {
Packit b099d7
      HandleDrop(w, cb, ds);
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  else if (ds->selection == XA_SECONDARY) {
Packit b099d7
    Atom CS_OF_ENCODING;
Packit b099d7
    
Packit b099d7
    CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    insert_select.done_status = False;
Packit b099d7
    insert_select.success_status = False;
Packit b099d7
    insert_select.event = (XSelectionRequestEvent *) ds->event;
Packit b099d7
    insert_select.select_type = XmDEST_SELECT;
Packit b099d7
    
Packit b099d7
    if (((Atom) ds->location_data) != CS_OF_ENCODING) {
Packit b099d7
      /*
Packit b099d7
       * Make selection request to find out which targets
Packit b099d7
       * the selection can provide.
Packit b099d7
       */
Packit b099d7
      XmTransferValue(ds->transfer_id, atoms[XmATARGETS], 
Packit b099d7
		      (XtCallbackProc) TextSecondaryWrapper,
Packit b099d7
		      (XtPointer) &insert_select, ds->time);
Packit b099d7
    } else {
Packit b099d7
      /*
Packit b099d7
       * Make selection request to replace the selection
Packit b099d7
       * with the insert selection.
Packit b099d7
       */
Packit b099d7
      XmTransferValue(ds->transfer_id, ((Atom) ds->location_data),
Packit b099d7
		      (XtCallbackProc) TextSecondaryWrapper,
Packit b099d7
		      (XtPointer) &insert_select, ds->time);
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
  } else 
Packit b099d7
    /* CLIPBOARD or PRIMARY */
Packit b099d7
    XmTransferValue(ds->transfer_id, atoms[XmATARGETS],
Packit b099d7
		    (XtCallbackProc) HandleTargets, 
Packit b099d7
		    ds->location_data, ds->time);
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
_XmTextInstallTransferTrait(void)
Packit b099d7
{
Packit b099d7
  XmeTraitSet((XtPointer)xmTextWidgetClass, XmQTtransfer, 
Packit b099d7
	      (XtPointer) &TextTransfer);
Packit b099d7
}