Blame lib/Xm/TextFSel.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: TextFSel.c /main/22 1997/10/14 15:38:30 cshi $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/* (c) Copyright 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/TraitP.h>		/* for XmeTraitSet() */
Packit b099d7
#include <Xm/TransferP.h>
Packit b099d7
#include <Xm/TransferT.h>
Packit b099d7
#include <Xm/XmosP.h>
Packit b099d7
#include "TextFI.h"
Packit b099d7
#include "TextFSelI.h"
Packit b099d7
#include "TransferI.h"		/* for _XmConvertComplete() */
Packit b099d7
#include "TraversalI.h"		/* for _XmGetFocusPolicy() */
Packit b099d7
#include "XmI.h"
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
static void HandleDrop(Widget w,
Packit b099d7
		       XmDropProcCallbackStruct *cb,
Packit b099d7
		       XmDestinationCallbackStruct *ds);
Packit b099d7
static void TextFieldConvertCallback(Widget, 
Packit b099d7
				     XtPointer, 
Packit b099d7
				     XmConvertCallbackStruct*);
Packit b099d7
Packit b099d7
static void TextFieldDestinationCallback(Widget, 
Packit b099d7
					 XtPointer, 
Packit b099d7
					 XmDestinationCallbackStruct*);
Packit b099d7
static void SetDropContext(Widget w);
Packit b099d7
Packit b099d7
static void DeleteDropContext(Widget w);
Packit b099d7
Packit b099d7
static void HandleTargets(Widget w, 
Packit b099d7
			  XtPointer ignore, 
Packit b099d7
			  XmSelectionCallbackStruct *ds);
Packit b099d7
Packit b099d7
static void HandleDrop(Widget w,
Packit b099d7
		       XmDropProcCallbackStruct *cb,
Packit b099d7
		       XmDestinationCallbackStruct *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, 
Packit b099d7
			     XtPointer ignore, 
Packit b099d7
			     XmSelectionCallbackStruct *ds);
Packit b099d7
static void DoStuff(Widget w, 
Packit b099d7
		    XtPointer ignore, 
Packit b099d7
		    XmSelectionCallbackStruct *ds);
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
/* Transfer Trait record for TextField */
Packit b099d7
Packit b099d7
static XmConst XmTransferTraitRec textFieldTT = {
Packit b099d7
  0,  				/* version */
Packit b099d7
  (XmConvertCallbackProc) 	TextFieldConvertCallback,
Packit b099d7
  (XmDestinationCallbackProc)	TextFieldDestinationCallback,
Packit b099d7
  (XmDestinationCallbackProc)	NULL,
Packit b099d7
};
Packit b099d7
Packit b099d7
static XContext _XmTextFDNDContext = 0;
Packit b099d7
static _XmInsertSelect insert_select;
Packit b099d7
static _XmTextPrimSelect *prim_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
  XmTextFieldWidget tf = (XmTextFieldWidget) w;
Packit b099d7
  XmTextPosition cursorPos = tf->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
    tf->text.prim_anchor = prim_select->position;
Packit b099d7
    cursorPos = prim_select->position + prim_select->num_chars;
Packit b099d7
    _XmTextFieldStartSelection(tf, tf->text.prim_anchor, cursorPos,
Packit b099d7
			       prim_select->time);
Packit b099d7
    tf->text.pending_off = False;
Packit b099d7
    _XmTextFieldSetCursorPosition(tf, NULL, cursorPos, True, True);
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
  {
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
TextFieldSecondaryWrapper(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
  XmTextFieldWidget tf = (XmTextFieldWidget) w;
Packit b099d7
  XmTextPosition left = 0;
Packit b099d7
  XmTextPosition right = 0;
Packit b099d7
  Boolean replace_res = False;
Packit b099d7
  Boolean dest_disjoint = False;
Packit b099d7
  wchar_t * wc_value;
Packit b099d7
  char * temp;
Packit b099d7
  int num_chars = 0;
Packit b099d7
  Atom COMPOUND_TEXT = XInternAtom(XtDisplay(w), XmSCOMPOUND_TEXT, False);
Packit b099d7
  Atom UTF8_STRING = XInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
Packit b099d7
  char * total_value = NULL;
Packit b099d7
  XmAnyCallbackStruct cb;
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 not text to add */
Packit b099d7
  if (*(char *) value == (char)'\0' || *length == 0){
Packit b099d7
    XtFree((char *)value);
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 (!tf->text.has_primary ||
Packit b099d7
	tf->text.prim_pos_left == tf->text.prim_pos_right) {
Packit b099d7
      XBell(XtDisplay(w), 0);
Packit b099d7
      XtFree((char *)value);
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 (tf->text.has_primary &&
Packit b099d7
	(left = tf->text.prim_pos_left) != (right = tf->text.prim_pos_right)) {
Packit b099d7
      if ( TextF_CursorPosition(tf) < left ||
Packit b099d7
	  TextF_CursorPosition(tf) > right ||
Packit b099d7
	  !tf->text.pending_delete) {
Packit b099d7
	left = right = TextF_CursorPosition(tf);
Packit b099d7
	dest_disjoint = True;
Packit b099d7
      }
Packit b099d7
    } else
Packit b099d7
      left = right = TextF_CursorPosition(tf);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  if (*type == COMPOUND_TEXT || *type == XA_STRING || *type == UTF8_STRING) {
Packit b099d7
    total_value =  _XmTextToLocaleText(w, value, *type, *format, 
Packit b099d7
				       *length, NULL);
Packit b099d7
    if (total_value) {
Packit b099d7
      if (tf->text.max_char_size == 1) {
Packit b099d7
	num_chars = strlen(total_value);
Packit b099d7
	replace_res = _XmTextFieldReplaceText(tf, 
Packit b099d7
					      (XEvent *)insert_select->event,
Packit b099d7
					      left, right, total_value, 
Packit b099d7
					      num_chars, True);
Packit b099d7
      } else { /* must convert to wchar_t before passing to Replace */
Packit b099d7
	int len = strlen(total_value) + 1;
Packit b099d7
	wc_value = (wchar_t *)XtMalloc((unsigned) len * sizeof(wchar_t));
Packit b099d7
	num_chars = mbstowcs(wc_value, total_value, len);
Packit b099d7
	if (num_chars < 0) 
Packit b099d7
	  num_chars = 0;
Packit b099d7
	else
Packit b099d7
	  replace_res = _XmTextFieldReplaceText(tf,
Packit b099d7
                                                (XEvent *)insert_select->event,
Packit b099d7
                                                left, right, (char*) wc_value,
Packit b099d7
                                                num_chars, True);
Packit b099d7
	XtFree((char *)wc_value);
Packit b099d7
      }
Packit b099d7
      XtFree(total_value);
Packit b099d7
    }
Packit b099d7
  } else { /* it must be either TEXT or codeset of the locale */
Packit b099d7
    if (tf->text.max_char_size == 1) {
Packit b099d7
      /* NOTE: casting *length could result in a truncated long. */
Packit b099d7
      num_chars = *length;
Packit b099d7
      replace_res = _XmTextFieldReplaceText(tf, 
Packit b099d7
					    (XEvent *)insert_select->event,
Packit b099d7
					    left, right, (char *)value,
Packit b099d7
					    (unsigned)*length, True);
Packit b099d7
    } else {
Packit b099d7
      temp = XtMalloc((unsigned) *length + 1);
Packit b099d7
      /* NOTE: casting *length could result in a truncated long. */
Packit b099d7
      (void)memcpy((void*)temp, (void*)value, (size_t)*length);
Packit b099d7
      temp[*length] = '\0';
Packit b099d7
      wc_value = (wchar_t*)XtMalloc((unsigned)
Packit b099d7
				    (*length + 1) * sizeof(wchar_t));
Packit b099d7
      
Packit b099d7
      /* NOTE: casting *length could result in a truncated long. */
Packit b099d7
      num_chars = mbstowcs(wc_value, temp, (unsigned)*length + 1);
Packit b099d7
      if (num_chars < 0)
Packit b099d7
	num_chars = 0;
Packit b099d7
      else
Packit b099d7
	replace_res = _XmTextFieldReplaceText(tf, 
Packit b099d7
					      (XEvent *)insert_select->event,
Packit b099d7
					      left, right, (char*) wc_value,
Packit b099d7
					      num_chars, True);
Packit b099d7
      XtFree(temp);
Packit b099d7
      XtFree((char *)wc_value);
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (!replace_res) {
Packit b099d7
    insert_select->success_status = False;
Packit b099d7
  } else {
Packit b099d7
    insert_select->success_status = True;
Packit b099d7
    
Packit b099d7
    if (!tf->text.add_mode) tf->text.prim_anchor = left;
Packit b099d7
    
Packit b099d7
    tf->text.pending_off = True;
Packit b099d7
    _XmTextFieldSetCursorPosition(tf, NULL, left + num_chars, False, True);
Packit b099d7
    (void) _XmTextFieldSetDestination(w, TextF_CursorPosition(tf),
Packit b099d7
				      insert_select->event->time);
Packit b099d7
    if (insert_select->select_type == XmDEST_SELECT) {
Packit b099d7
      if (left != right) {
Packit b099d7
	if (!dest_disjoint || !tf->text.add_mode) {
Packit b099d7
	  _XmTextFieldStartSelection(tf, TextF_CursorPosition(tf),
Packit b099d7
				     TextF_CursorPosition(tf),
Packit b099d7
				     insert_select->event->time);
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
    cb.reason = XmCR_VALUE_CHANGED;
Packit b099d7
    cb.event = (XEvent *)insert_select->event;
Packit b099d7
    XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
Packit b099d7
		       (XtPointer) &cb;;
Packit b099d7
  }
Packit b099d7
  
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, XmAUTF8_STRING, NUM_ATOMS };
Packit b099d7
  static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT, XmSUTF8_STRING };
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
  else if (supports_CT)
Packit b099d7
    target = atoms[XmACOMPOUND_TEXT];
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_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) TextFieldSecondaryWrapper,
Packit b099d7
		  closure, insert_select -> event -> time);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
Boolean
Packit b099d7
_XmTextFieldConvert(
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, XmAUTF8_STRING,
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, XmSUTF8_STRING };
Packit b099d7
Packit b099d7
  XmTextFieldWidget tf;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
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
  char *tmp_value;
Packit b099d7
  int ret_status = 0;
Packit b099d7
  Time _time;
Packit b099d7
  XmAnyCallbackStruct cb;
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 (req_event == NULL) 
Packit b099d7
    _time = XtLastTimestampProcessed(XtDisplay(w));
Packit b099d7
  else
Packit b099d7
    _time = req_event -> time;
Packit b099d7
  
Packit b099d7
  tf = (XmTextFieldWidget) w;
Packit b099d7
  
Packit b099d7
  if (tf == NULL) return False;
Packit b099d7
  
Packit b099d7
  if (*selection == XA_PRIMARY || *selection == atoms[XmACLIPBOARD]) {
Packit b099d7
    has_selection = tf->text.has_primary;
Packit b099d7
    left = tf->text.prim_pos_left;
Packit b099d7
    right = tf->text.prim_pos_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 = tf->text.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 = tf->text.has_secondary;
Packit b099d7
    left = tf->text.sec_pos_left;
Packit b099d7
    right = tf->text.sec_pos_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 = tf->text.has_primary;
Packit b099d7
    left = tf->text.prim_pos_left;
Packit b099d7
    right = tf->text.prim_pos_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 textfield 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
      targs[target_count] = atoms[XmAUTF8_STRING]; target_count++;
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 = tf->text.prim_time;
Packit b099d7
    else if (is_destination)
Packit b099d7
      *timestamp = tf->text.dest_time;
Packit b099d7
    else if (is_secondary)
Packit b099d7
      *timestamp = tf->text.sec_time;
Packit b099d7
    else if (is_drop)
Packit b099d7
      *timestamp = tf->text.prim_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
    *type = (Atom) XA_STRING;
Packit b099d7
    *format = 8;
Packit b099d7
    if (is_destination || !has_selection) return False;
Packit b099d7
    
Packit b099d7
    /* put a char* value into tmp_value, then convert to 8859.1 */
Packit b099d7
    if (tf->text.max_char_size != 1) {
Packit b099d7
      int stat ;
Packit b099d7
      
Packit b099d7
      /* NOTE: casting (right - left) could result in a truncated long. */
Packit b099d7
      *length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left, 
Packit b099d7
				       (int)(right - left));
Packit b099d7
      tmp_value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      stat = wcstombs(tmp_value, TextF_WcValue(tf) + left,
Packit b099d7
		      (unsigned)*length); /* NOTE: casting *length could
Packit b099d7
					     result in a truncated long. */
Packit b099d7
      if (stat < 0) /* wcstombs will return neg value on conv failure */
Packit b099d7
	*length = 0;
Packit b099d7
      else *length = (unsigned long) stat ;
Packit b099d7
    } else {
Packit b099d7
      *length = right - left;
Packit b099d7
      tmp_value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      /* get the selection value */
Packit b099d7
      (void)memcpy((void*)tmp_value, (void*)(TextF_Value(tf) + left), 
Packit b099d7
		   (size_t)*length); /* NOTE: casting *length could result
Packit b099d7
					  in a truncated long. */
Packit b099d7
    }
Packit b099d7
    tmp_value[*length] = '\0';
Packit b099d7
    tmp_prop.value = NULL;
Packit b099d7
    /* convert tmp_value to 8859.1 */
Packit b099d7
    ret_status = XmbTextListToTextProperty(XtDisplay(w), &tmp_value, 1, 
Packit b099d7
					   (XICCEncodingStyle)XStringStyle,
Packit b099d7
					   &tmp_prop);
Packit b099d7
    XtFree(tmp_value);
Packit b099d7
    if (ret_status == Success || ret_status > 0){
Packit b099d7
      *value = (XtPointer) 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
  } 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
    if (tf->text.max_char_size != 1) {
Packit b099d7
      int stat ;
Packit b099d7
      
Packit b099d7
      /* NOTE: casting (right - left) could result in a truncated long. */
Packit b099d7
      *length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
Packit b099d7
				       (int)(right - left));
Packit b099d7
      *value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      stat = wcstombs((char *)*value, TextF_WcValue(tf) + left,
Packit b099d7
		      (unsigned)*length); /* NOTE: casting *length could
Packit b099d7
					     result in a truncated long */
Packit b099d7
      if (stat < 0) /* wcstombs return neg value on conv failure */
Packit b099d7
	*length = 0;
Packit b099d7
      else *length = (unsigned long) stat ;
Packit b099d7
    } else {
Packit b099d7
      *length = right - left;
Packit b099d7
      *value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      /* get the selection value */
Packit b099d7
      (void)memcpy((void*)*value, (void*)(TextF_Value(tf) + left),
Packit b099d7
		   (size_t)*length); /* NOTE: casting *length could result
Packit b099d7
					  in a truncated long. */
Packit b099d7
    }
Packit b099d7
    (*(char **)value)[*length]='\0';
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
    if (tf->text.max_char_size != 1) { 
Packit b099d7
      int stat ;
Packit b099d7
      
Packit b099d7
      /* convert to char* before converting to CT.  NOTE: casting
Packit b099d7
       * (right - left) could result in a truncated long.
Packit b099d7
       */
Packit b099d7
      *length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
Packit b099d7
				       (int)(right - left));
Packit b099d7
      tmp_value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      stat = wcstombs(tmp_value, TextF_WcValue(tf) + left,
Packit b099d7
		      (unsigned)*length); /* NOTE: casting *length could
Packit b099d7
					     result in a truncated long. */
Packit b099d7
      if (stat < 0) /* wcstombs will return neg value on conv failure */
Packit b099d7
	*length = 0;
Packit b099d7
      else *length = (unsigned long) stat ;
Packit b099d7
    } else { /* malloc the space and copy the data to be converted */
Packit b099d7
      *length = right - left;
Packit b099d7
      tmp_value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      /* get the selection value */
Packit b099d7
      (void)memcpy((void*)tmp_value, (void*)(TextF_Value(tf) + left), 
Packit b099d7
		   (size_t)*length); /* NOTE: casting *length could result
Packit b099d7
					  in a truncated long. */
Packit b099d7
    }
Packit b099d7
    tmp_value[*length] = '\0';
Packit b099d7
    tmp_prop.value = NULL;
Packit b099d7
    /* Convert to compound text */
Packit b099d7
    ret_status = 
Packit b099d7
      XmbTextListToTextProperty(XtDisplay(w), &tmp_value, 1,
Packit b099d7
				(XICCEncodingStyle)XCompoundTextStyle,
Packit b099d7
				&tmp_prop);
Packit b099d7
    XtFree(tmp_value);
Packit b099d7
    if (ret_status == Success || ret_status > 0){
Packit b099d7
      *length = tmp_prop.nitems;
Packit b099d7
      *value = (XtPointer)tmp_prop.value;
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
    if (tf->text.max_char_size != 1) { 
Packit b099d7
      int stat ;
Packit b099d7
      
Packit b099d7
      /* convert to char* before converting to CT.  NOTE: casting
Packit b099d7
       * (right - left) could result in a truncated long.
Packit b099d7
       */
Packit b099d7
      *length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
Packit b099d7
				       (int)(right - left));
Packit b099d7
      tmp_value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      stat = wcstombs(tmp_value, TextF_WcValue(tf) + left,
Packit b099d7
		      (unsigned)*length); /* NOTE: casting *length could
Packit b099d7
					     result in a truncated long. */
Packit b099d7
      if (stat < 0) /* wcstombs will return neg value on conv failure */
Packit b099d7
	*length = 0;
Packit b099d7
      else *length = (unsigned long) stat ;
Packit b099d7
    } else { /* malloc the space and copy the data to be converted */
Packit b099d7
      *length = right - left;
Packit b099d7
      tmp_value = XtMalloc((unsigned) *length + 1);
Packit b099d7
      /* get the selection value */
Packit b099d7
      (void)memcpy((void*)tmp_value, (void*)(TextF_Value(tf) + left), 
Packit b099d7
		   (size_t)*length); /* NOTE: casting *length could result
Packit b099d7
					  in a truncated long. */
Packit b099d7
    }
Packit b099d7
    tmp_value[*length] = '\0';
Packit b099d7
    tmp_prop.value = NULL;
Packit b099d7
    /* Convert to compound text */
Packit b099d7
    ret_status = 
Packit b099d7
      XmbTextListToTextProperty(XtDisplay(w), &tmp_value, 1,
Packit b099d7
				(XICCEncodingStyle)XUTF8StringStyle,
Packit b099d7
				&tmp_prop);
Packit b099d7
    XtFree(tmp_value);
Packit b099d7
    if (ret_status == Success || ret_status > 0){
Packit b099d7
      *length = tmp_prop.nitems;
Packit b099d7
      *value = (XtPointer)tmp_prop.value;
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
    XmTextPosition left, right;
Packit b099d7
    Boolean move_cursor = True;
Packit b099d7
    
Packit b099d7
    if (!(is_primary || is_drop)) return False;
Packit b099d7
    
Packit b099d7
    left = tf->text.prim_pos_left;
Packit b099d7
    right = tf->text.prim_pos_right;
Packit b099d7
    
Packit b099d7
      if (is_drop) {
Packit b099d7
	if (_XmTextFieldGetDropReciever((Widget)tf) == (Widget) tf)
Packit b099d7
	  move_cursor = False;
Packit b099d7
      } else {
Packit b099d7
	if (req_event != NULL &&
Packit b099d7
	    req_event->requestor == XtWindow((Widget)tf))
Packit b099d7
	  move_cursor = False;
Packit b099d7
      }
Packit b099d7
    
Packit b099d7
    if (!_XmTextFieldReplaceText(tf, (XEvent *) req_event,
Packit b099d7
				 left, right, NULL, 0, move_cursor)) {
Packit b099d7
      tf->text.has_primary = True;
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    _XmTextFieldStartSelection(tf, tf->text.prim_anchor,
Packit b099d7
			       tf->text.prim_anchor, _time);
Packit b099d7
    
Packit b099d7
    cb.reason = XmCR_VALUE_CHANGED;
Packit b099d7
    cb.event = (XEvent *) req_event;
Packit b099d7
    XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
Packit b099d7
		       (XtPointer) &cb;;
Packit b099d7
    
Packit b099d7
    tf->text.has_primary = True;
Packit b099d7
    
Packit b099d7
    if (tf->text.has_destination)
Packit b099d7
      tf->text.prim_anchor = TextF_CursorPosition(tf);
Packit b099d7
    
Packit b099d7
    *type = atoms[XmANULL];
Packit b099d7
    *value = NULL;
Packit b099d7
    *length = 0;
Packit b099d7
    *format = 8;
Packit b099d7
  } else
Packit b099d7
    /* unknown selection type */
Packit b099d7
    return FALSE;
Packit b099d7
  return TRUE;
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void
Packit b099d7
_XmTextFieldLoseSelection(
Packit b099d7
        Widget w,
Packit b099d7
        Atom *selection )
Packit b099d7
{
Packit b099d7
    XmTextFieldWidget tf = (XmTextFieldWidget) w;
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 && tf->text.has_primary) {
Packit b099d7
        XmAnyCallbackStruct cb;
Packit b099d7
        _XmTextFieldDeselectSelection(w, False, 0);
Packit b099d7
Packit b099d7
        cb.reason = XmCR_LOSE_PRIMARY;
Packit b099d7
        cb.event = NULL;
Packit b099d7
        XtCallCallbackList(w, tf->text.lose_primary_callback, (XtPointer) &cb;;
Packit b099d7
/* Losing Destination Selection */
Packit b099d7
    } else if (*selection == MOTIF_DESTINATION) {
Packit b099d7
        Boolean orig_ibeam_off = tf->text.refresh_ibeam_off;
Packit b099d7
        tf->text.has_destination = False;
Packit b099d7
       /* if we have focus, we have a valid putback area.  If we don't have
Packit b099d7
	* focus, don't want to update the putback with the destination cursor
Packit b099d7
	* image.
Packit b099d7
	*/
Packit b099d7
	tf->text.refresh_ibeam_off = False;
Packit b099d7
	_XmTextFieldDrawInsertionPoint(tf, False);
Packit b099d7
	tf->text.blink_on = True;
Packit b099d7
	_XmTextFieldDrawInsertionPoint(tf, True);
Packit b099d7
	/* Restore the state of the refresh_ibeam_off flag. */
Packit b099d7
        tf->text.refresh_ibeam_off = orig_ibeam_off;
Packit b099d7
/* Losing Secondary Selection */
Packit b099d7
    } else if (*selection == XA_SECONDARY && tf->text.has_secondary){
Packit b099d7
        _XmTextFieldSetSel2(w, 0, 0, True, 
Packit b099d7
			    XtLastTimestampProcessed(XtDisplay(w)));
Packit b099d7
    }
Packit b099d7
}
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
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (_XmTextFDNDContext == 0)
Packit b099d7
    _XmTextFDNDContext = XUniqueContext();
Packit b099d7
  loc_context = _XmTextFDNDContext;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  
Packit b099d7
  XSaveContext(display, (Window)screen,
Packit b099d7
	       loc_context, (XPointer)w);
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
  XContext loc_context;
Packit b099d7
  
Packit b099d7
  _XmProcessLock();
Packit b099d7
  loc_context = _XmTextFDNDContext;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
Packit b099d7
  XDeleteContext(display, (Window)screen, loc_context);
Packit b099d7
}
Packit b099d7
Packit b099d7
Widget
Packit b099d7
_XmTextFieldGetDropReciever(Widget w)
Packit b099d7
{
Packit b099d7
  Widget widget;
Packit b099d7
  XContext loc_context;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  loc_context = _XmTextFDNDContext;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
Packit b099d7
  if (loc_context == 0) return NULL;
Packit b099d7
  
Packit b099d7
  if (!XFindContext(XtDisplay(w), (Window) XtScreen(w),
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
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
DropDestroyCB(Widget      w,
Packit b099d7
	      XtPointer   clientData,
Packit b099d7
	      XtPointer   callData)
Packit b099d7
{
Packit b099d7
  XmTransferDoneCallbackStruct *ts = 
Packit b099d7
    (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
static void 
Packit b099d7
DropTransferProc(Widget w, 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
  XmTextFieldWidget tf = (XmTextFieldWidget) w;
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
  int max_length = 0;
Packit b099d7
  Boolean local = tf->text.has_primary;
Packit b099d7
  char * total_value = NULL;
Packit b099d7
  wchar_t * wc_total_value;
Packit b099d7
  unsigned long total_length = 0;
Packit b099d7
  int wc_total_length;
Packit b099d7
  Boolean replace = False;
Packit b099d7
  XmAnyCallbackStruct cb;
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
      tf->text.prim_anchor = transfer_rec->insert_pos;
Packit b099d7
      cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
Packit b099d7
      _XmTextFieldSetCursorPosition(tf, NULL, cursorPos,
Packit b099d7
				    False, True);
Packit b099d7
      _XmTextFieldStartSelection(tf, tf->text.prim_anchor, 
Packit b099d7
				 TextF_CursorPosition(tf),
Packit b099d7
				 XtLastTimestampProcessed(XtDisplay(w)));
Packit b099d7
      tf->text.pending_off = False;
Packit b099d7
      _XmTextFieldSetCursorPosition(tf, NULL, TextF_CursorPosition(tf),
Packit b099d7
				    True, True);
Packit b099d7
    }
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
  if (!(ds->value) || 
Packit b099d7
      (ds->type != CS_OF_ENCODING &&
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 != 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
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
      || ds->type == atoms[XmAUTF8_STRING]
Packit b099d7
#endif
Packit b099d7
      || ds->type == atoms[XmACOMPOUND_TEXT]) {
Packit b099d7
    if ((total_value = _XmTextToLocaleText(w, ds->value, ds->type, 
Packit b099d7
					   8, ds->length, NULL)) != NULL)
Packit b099d7
      total_length = strlen(total_value);
Packit b099d7
    else
Packit b099d7
      if (ds->value) {
Packit b099d7
	XtFree((char*) ds->value);
Packit b099d7
	ds->value = NULL;
Packit b099d7
      }
Packit b099d7
  } else {
Packit b099d7
    total_value = (char*) ds->value;
Packit b099d7
    total_length = ds->length;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (total_value == NULL) return;
Packit b099d7
  
Packit b099d7
  if (TextF_PendingDelete(tf) && tf->text.has_primary &&
Packit b099d7
      tf->text.prim_pos_left != tf->text.prim_pos_right) {
Packit b099d7
      if(insertPosLeft > tf->text.prim_pos_left 
Packit b099d7
		&& insertPosLeft <  tf->text.prim_pos_right)
Packit b099d7
        insertPosLeft = tf->text.prim_pos_left;
Packit b099d7
      if(insertPosRight < tf->text.prim_pos_right 
Packit b099d7
		&& insertPosRight >  tf->text.prim_pos_left)
Packit b099d7
        insertPosRight = tf->text.prim_pos_right;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  transfer_rec->num_chars = _XmTextFieldCountCharacters(tf, total_value, 
Packit b099d7
							total_length);
Packit b099d7
  
Packit b099d7
  _XmTextFieldDrawInsertionPoint(tf, False);
Packit b099d7
  
Packit b099d7
  if (transfer_rec->move && local) {
Packit b099d7
    max_length = TextF_MaxLength(tf);
Packit b099d7
    TextF_MaxLength(tf) = INT_MAX;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (tf->text.max_char_size == 1) {
Packit b099d7
    replace = _XmTextFieldReplaceText(tf, ds->event, insertPosLeft, 
Packit b099d7
				      insertPosRight, (char *) total_value,
Packit b099d7
				      (int)total_length, False);
Packit b099d7
  } else {
Packit b099d7
    wc_total_length = _XmTextFieldCountCharacters(tf, total_value,
Packit b099d7
                                                  total_length);
Packit b099d7
    wc_total_value = (wchar_t*)XtMalloc((unsigned)
Packit b099d7
					(wc_total_length+1) * sizeof(wchar_t));
Packit b099d7
    wc_total_length = mbstowcs(wc_total_value, total_value, wc_total_length+1);
Packit b099d7
    if (wc_total_length > 0)
Packit b099d7
      replace = _XmTextFieldReplaceText(tf, ds->event, insertPosLeft, 
Packit b099d7
					insertPosRight, (char *)wc_total_value,
Packit b099d7
					wc_total_length, False);
Packit b099d7
    XtFree((char*)wc_total_value);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (replace) {
Packit b099d7
    tf->text.pending_off = FALSE;
Packit b099d7
    if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
Packit b099d7
      cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
Packit b099d7
      _XmTextFieldSetCursorPosition(tf, NULL, cursorPos, 
Packit b099d7
				    True, True);
Packit b099d7
      _XmTextFieldSetDestination((Widget)tf, TextF_CursorPosition(tf),
Packit b099d7
				 transfer_rec->timestamp);
Packit b099d7
    }
Packit b099d7
    left = tf->text.prim_pos_left;
Packit b099d7
    right = tf->text.prim_pos_right;
Packit b099d7
    if (tf->text.has_primary) {
Packit b099d7
      if (transfer_rec->move && left < transfer_rec->insert_pos)
Packit b099d7
	transfer_rec->insert_pos -= transfer_rec->num_chars;
Packit b099d7
      if (TextF_CursorPosition(tf) < left ||
Packit b099d7
	  TextF_CursorPosition(tf) > right)
Packit b099d7
	tf->text.pending_off = TRUE;
Packit b099d7
    } else {
Packit b099d7
      if (!transfer_rec->move && !tf->text.add_mode &&
Packit b099d7
	  transfer_rec->num_chars != 0)
Packit b099d7
	tf->text.prim_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
    cb.reason = XmCR_VALUE_CHANGED;
Packit b099d7
    cb.event = ds->event;
Packit b099d7
    XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
Packit b099d7
		       (XtPointer) &cb;;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (transfer_rec->move && local) {
Packit b099d7
    TextF_MaxLength(tf) = max_length;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (total_value && (total_value != (char*)ds->value))
Packit b099d7
    XtFree(total_value);
Packit b099d7
  if (ds->value) {
Packit b099d7
    XtFree((char*) ds->value);
Packit b099d7
    ds->value = NULL;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  _XmTextFieldDrawInsertionPoint(tf, True);
Packit b099d7
}
Packit b099d7
Packit b099d7
#define CR1228
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
DoStuff(Widget w, 
Packit b099d7
#ifdef CR1228
Packit b099d7
	XtPointer closure,
Packit b099d7
#else
Packit b099d7
	XtPointer closure,	/* unused */
Packit b099d7
#endif
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
  XmTextFieldWidget tf = (XmTextFieldWidget) w;
Packit b099d7
  XmTextPosition right=0, left=0, replace_from, replace_to;
Packit b099d7
  int prim_char_length = 0;
Packit b099d7
  Boolean replace_res = False;
Packit b099d7
  XmAnyCallbackStruct cb;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
#ifdef CR1228
Packit b099d7
  _XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
Packit b099d7
#endif
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 (!tf->text.has_focus && _XmGetFocusPolicy(w) == XmEXPLICIT)
Packit b099d7
    (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
Packit b099d7
  
Packit b099d7
  if (ds->selection != atoms[XmACLIPBOARD] && 
Packit b099d7
      ds->length == 0 &&
Packit b099d7
      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 ds->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 && tf->text.selection_move) {
Packit b099d7
      prim_char_length = prim_select->num_chars;
Packit b099d7
      _XmTextFieldStartSelection(tf, prim_select->position,
Packit b099d7
				 prim_select->position + prim_char_length,
Packit b099d7
				 prim_select->time);
Packit b099d7
      tf->text.pending_off = False;
Packit b099d7
      _XmTextFieldSetCursorPosition(tf, NULL, 
Packit b099d7
				    prim_select->position + prim_char_length, 
Packit b099d7
				    True, True);
Packit b099d7
      tf->text.prim_anchor = prim_select->position;
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock(); /* for prim_select */
Packit b099d7
  } else {
Packit b099d7
    int max_length = 0;
Packit b099d7
    Boolean local = tf->text.has_primary;
Packit b099d7
    Boolean dest_disjoint = True;
Packit b099d7
Packit b099d7
    if (tf->text.selection_move && local) {
Packit b099d7
      max_length = TextF_MaxLength(tf);
Packit b099d7
      TextF_MaxLength(tf) = INT_MAX;
Packit b099d7
    }
Packit b099d7
    _XmProcessLock();
Packit b099d7
    replace_from = replace_to = prim_select->position;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    if (ds->selection == atoms[XmACLIPBOARD]) {
Packit b099d7
      if (tf->text.has_primary) {
Packit b099d7
	left = tf->text.prim_pos_left;
Packit b099d7
	right = tf->text.prim_pos_right;
Packit b099d7
	if (tf->text.pending_delete &&
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
    }
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
      char *total_value;
Packit b099d7
      
Packit b099d7
      if ((total_value = 
Packit b099d7
	   _XmTextToLocaleText(w, ds->value, ds->type, ds->format, ds->length, 
Packit b099d7
			       NULL))
Packit b099d7
	  != NULL) {
Packit b099d7
	if (tf->text.max_char_size == 1) {
Packit b099d7
	  _XmProcessLock();
Packit b099d7
	  prim_select->num_chars = strlen(total_value);
Packit b099d7
	  replace_res = 
Packit b099d7
	    _XmTextFieldReplaceText (tf, ds->event, 
Packit b099d7
				     replace_from,
Packit b099d7
				     replace_to, 
Packit b099d7
				     total_value,
Packit b099d7
				     prim_select->num_chars,
Packit b099d7
				     ds->selection == atoms[XmACLIPBOARD]);
Packit b099d7
	  _XmProcessUnlock();
Packit b099d7
	  XtFree(total_value);
Packit b099d7
	} else {
Packit b099d7
	  wchar_t * wc_value;
Packit b099d7
	  int tmp_len = strlen(total_value) + 1;
Packit b099d7
Packit b099d7
	  _XmProcessLock();
Packit b099d7
	  prim_select->num_chars = 0;
Packit b099d7
	  wc_value = (wchar_t*)XtMalloc ((unsigned) tmp_len * sizeof(wchar_t));
Packit b099d7
	  prim_select->num_chars = mbstowcs(wc_value, total_value, tmp_len);
Packit b099d7
	  if (prim_select->num_chars < 0) 
Packit b099d7
	    prim_select->num_chars = 0;
Packit b099d7
	  else 
Packit b099d7
	    replace_res = 
Packit b099d7
	      _XmTextFieldReplaceText(tf, ds->event, 
Packit b099d7
				      replace_from,
Packit b099d7
				      replace_to, 
Packit b099d7
				      (char*)wc_value, 
Packit b099d7
				      prim_select->num_chars,
Packit b099d7
				      ds->selection == atoms[XmACLIPBOARD]);
Packit b099d7
	  _XmProcessUnlock();
Packit b099d7
	  XtFree((char*)wc_value);
Packit b099d7
	  XtFree(total_value);
Packit b099d7
	}
Packit b099d7
      } else { /* initialize prim_select values for possible delete oper */
Packit b099d7
	_XmProcessLock();
Packit b099d7
	prim_select->num_chars = 0;
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
      }
Packit b099d7
    } else {
Packit b099d7
      if (tf->text.max_char_size == 1) {
Packit b099d7
	/* Note: length may be truncated during cast to int */
Packit b099d7
	_XmProcessLock();
Packit b099d7
	prim_select->num_chars = (int) ds->length;
Packit b099d7
	replace_res =
Packit b099d7
	  _XmTextFieldReplaceText(tf, ds->event, 
Packit b099d7
				  replace_from,
Packit b099d7
				  replace_to, 
Packit b099d7
				  (char *) ds->value, 
Packit b099d7
				  prim_select->num_chars,
Packit b099d7
				  ds->selection == atoms[XmACLIPBOARD]);
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
      } else {
Packit b099d7
	wchar_t * wc_value;
Packit b099d7
	char *temp;
Packit b099d7
Packit b099d7
	temp = XtMalloc((unsigned) ds->length + 1);
Packit b099d7
	(void)memcpy((void*)temp, (void*)ds->value, (size_t)ds->length);
Packit b099d7
	temp[(size_t)ds->length] = '\0';
Packit b099d7
	
Packit b099d7
	wc_value = (wchar_t*)XtMalloc ((unsigned)
Packit b099d7
				       ((ds->length + 1) * sizeof(wchar_t)));
Packit b099d7
	_XmProcessLock();
Packit b099d7
Packit b099d7
	prim_select->num_chars = mbstowcs(wc_value, (char *) temp,
Packit b099d7
					  (size_t) ds->length+1);
Packit b099d7
Packit b099d7
	if (prim_select->num_chars < 0) 
Packit b099d7
	  prim_select->num_chars = 0;
Packit b099d7
	else {
Packit b099d7
	  wc_value[prim_select->num_chars] = 0;
Packit b099d7
	  replace_res = 
Packit b099d7
	    _XmTextFieldReplaceText(tf, ds->event, 
Packit b099d7
				    replace_from,
Packit b099d7
				    replace_to, 
Packit b099d7
				    (char*)wc_value, 
Packit b099d7
				    prim_select->num_chars,
Packit b099d7
				    ds->selection == atoms[XmACLIPBOARD]);
Packit b099d7
	}
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	XtFree(temp);
Packit b099d7
	XtFree((char*)wc_value);
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (replace_res) {
Packit b099d7
      XmTextPosition cursorPos = 0;
Packit b099d7
      
Packit b099d7
      if (ds->selection != atoms[XmACLIPBOARD]) { 
Packit b099d7
	tf->text.pending_off = FALSE;
Packit b099d7
	_XmProcessLock();
Packit b099d7
	cursorPos = replace_from + prim_select->num_chars; 
Packit b099d7
	if (prim_select->num_chars > 0 && !tf->text.selection_move) {
Packit b099d7
	  _XmTextFieldSetCursorPosition(tf, NULL, cursorPos, 
Packit b099d7
					True, True);
Packit b099d7
	  (void) _XmTextFieldSetDestination(w, cursorPos, prim_select->time);
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	}
Packit b099d7
      } else {
Packit b099d7
	_XmProcessLock();
Packit b099d7
	(void) _XmTextFieldSetDestination(w, TextF_CursorPosition(tf), 
Packit b099d7
					  prim_select->time);
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
      }
Packit b099d7
      left = tf->text.prim_pos_left;
Packit b099d7
      right = tf->text.prim_pos_right;
Packit b099d7
      if (tf->text.has_primary) {
Packit b099d7
	if (ds->selection == atoms[XmACLIPBOARD]) {
Packit b099d7
	  if (left != right && (!dest_disjoint || !tf->text.add_mode))
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    _XmTextFieldStartSelection(tf, TextF_CursorPosition(tf),
Packit b099d7
				       TextF_CursorPosition(tf),
Packit b099d7
				       prim_select->time);
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	} else {
Packit b099d7
	  _XmProcessLock();
Packit b099d7
	  if (tf->text.selection_move && left < prim_select->position)
Packit b099d7
	    prim_select->position -= prim_select->num_chars;
Packit b099d7
	  if (left <= cursorPos && right >= cursorPos)
Packit b099d7
	    tf->text.pending_off = TRUE;
Packit b099d7
	  _XmProcessUnlock();
Packit b099d7
	}
Packit b099d7
      } else {
Packit b099d7
	_XmProcessLock();
Packit b099d7
	if (ds->selection == atoms[XmACLIPBOARD])
Packit b099d7
	  tf->text.prim_anchor = replace_from;
Packit b099d7
	else if (!tf->text.selection_move && !tf->text.add_mode &&
Packit b099d7
		 prim_select->num_chars != 0)
Packit b099d7
	  tf->text.prim_anchor = prim_select->position;
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
      }
Packit b099d7
      cb.reason = XmCR_VALUE_CHANGED;
Packit b099d7
      cb.event = ds->event;
Packit b099d7
      XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
Packit b099d7
			 (XtPointer) &cb;;
Packit b099d7
    } else {
Packit b099d7
      _XmProcessLock();
Packit b099d7
      prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
Packit b099d7
				     anything */
Packit b099d7
      _XmProcessUnlock();
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (tf->text.selection_move && local) {
Packit b099d7
      TextF_MaxLength(tf) = max_length;
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  XtFree((char *)ds->value);
Packit b099d7
  ds->value = NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
HandleTargets(Widget w, 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
  XmTextFieldWidget tf = (XmTextFieldWidget) w;
Packit b099d7
  Atom atoms[XtNumber(atom_names)];
Packit b099d7
  Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
  XmTextPosition left, right;
Packit b099d7
  Boolean supports_encoding_data = False;
Packit b099d7
  Boolean supports_CT = False;
Packit b099d7
  Boolean supports_utf8_string = False;
Packit b099d7
  Boolean supports_text = False;
Packit b099d7
  XPoint *point = (XPoint *)closure;
Packit b099d7
  Atom *atom_ptr;
Packit b099d7
  Atom targets[2];
Packit b099d7
  XmTextPosition select_pos;
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; /* 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 *)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 = XmTextFieldXYToPos((Widget)tf, (Position)point->x, 0);
Packit b099d7
  } else {
Packit b099d7
    select_pos = TextF_CursorPosition(tf);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (ds->selection != atoms[XmACLIPBOARD]) {
Packit b099d7
    left = tf->text.prim_pos_left;
Packit b099d7
    right = tf->text.prim_pos_right;
Packit b099d7
    if (tf->text.has_primary &&
Packit b099d7
	left != right && select_pos > left && 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 (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
  _XmProcessUnlock();
Packit b099d7
  XtFree((char *)ds->value);
Packit b099d7
  ds->value = NULL;
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
  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
  Display *display = XtDisplay(w);
Packit b099d7
  Boolean doTransfer = False;
Packit b099d7
  _XmTextDropTransferRec *transfer_rec;
Packit b099d7
  XtPointer tid = ds->transfer_id;
Packit b099d7
  
Packit b099d7
  drag_cont = cb->dragContext;
Packit b099d7
  transfer_rec = (_XmTextDropTransferRec *) NULL;
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 = XmTextFieldXYToPos(w, cb->x, 0);
Packit b099d7
  
Packit b099d7
  left = ((XmTextFieldWidget)w)->text.prim_pos_left;
Packit b099d7
  right = ((XmTextFieldWidget)w)->text.prim_pos_right;
Packit b099d7
  if (cb->operation & XmDROP_MOVE && w == initiator && 
Packit b099d7
      ((XmTextFieldWidget)w)->text.has_primary &&
Packit b099d7
      left != right && insert_pos >= left && insert_pos <= right) {
Packit b099d7
    /*EMPTY*/
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
Packit b099d7
    Atom atoms[XtNumber(atom_names)];
Packit b099d7
    Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
Packit b099d7
    Boolean encoding_found = False;
Packit b099d7
    Boolean utf8_string_found = False;
Packit b099d7
    Boolean c_text_found = False;
Packit b099d7
    Boolean string_found = False;
Packit b099d7
    Boolean text_found = False;
Packit b099d7
    
Packit b099d7
    assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
    XInternAtoms(display, 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
    transfer_rec->move = False;
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
      if (!encoding_found) {
Packit b099d7
#ifdef UTF8_SUPPORTED
Packit b099d7
	if (utf8_string_found)
Packit b099d7
	  desiredTarget = atoms[XmAUTF8_STRING];
Packit b099d7
	else
Packit b099d7
#endif
Packit b099d7
	if (c_text_found)
Packit b099d7
	  desiredTarget = atoms[XmACOMPOUND_TEXT];
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
      
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
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
TextFieldConvertCallback(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, XmA_MOTIF_CLIPBOARD_TARGETS,
Packit b099d7
	 XmACOMPOUND_TEXT, XmATEXT, XmATARGETS, 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, XmS_MOTIF_CLIPBOARD_TARGETS,
Packit b099d7
	 XmSCOMPOUND_TEXT, XmSTEXT, XmSTARGETS, 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
    _XmTextFieldLoseSelection(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
    _XmTextFieldHandleSecondaryFinished(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 (!_XmTextFieldConvert(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
TextFieldDestinationCallback(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
  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
  } 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) TextFieldSecondaryWrapper,
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) TextFieldSecondaryWrapper,
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
_XmTextFieldInstallTransferTrait(void)
Packit b099d7
{
Packit b099d7
  XmeTraitSet((XtPointer)xmTextFieldWidgetClass, XmQTtransfer, 
Packit b099d7
	      (XtPointer) &textFieldTT);
Packit b099d7
}