~ubuntu-branches/ubuntu/quantal/openmotif/quantal

« back to all changes in this revision

Viewing changes to lib/Xm/TextSel.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bauer
  • Date: 2010-06-23 12:12:31 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100623121231-u89gxdp51sg9wjj2
Tags: 2.3.0-1
* New Maintainer (Closes: #379258) 
* Acknowledge NMU changes
* New upstream release (Closes: #494375)
* Get rid of security patches as they are already part of new upstream
  release (00-xpmvuln.openmotif.patch, 342092-CVE-2005-3964.patch)
* Bump Standards to 3.8.4
* Added {misc:Depends} to make the package lintian cleaner
* Fix weak-library-dev-dependency by adding ${binary:Version}) for the
  -dev Package of openmotif
* Let package depend on autotools-dev to use newer autotools-helper-files
* Work around an autoconf-bug (Gentoo-Bug #1475)
* Added Client-side anti-aliased fonts support via XFT
* Added UTF-8 and UTF8_STRING atom support
* Ability to show text and pixmaps in Label, LabelGadget and all
  derived widgets
* Support of PNG/JPEG image formats in the same way as XPM is supported
* Increase FILE_OFFSET_BITS to 64 to show files >2GB in file-selector
  Idea taken from Magne Oestlyngen (Closes: #288537)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 *  @OPENGROUP_COPYRIGHT@
 
3
 *  COPYRIGHT NOTICE
 
4
 *  Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
 
5
 *  Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
 
6
 *  ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
 
7
 *  the full copyright text.
 
8
 *  
 
9
 *  This software is subject to an open license. It may only be
 
10
 *  used on, with or for operating systems which are themselves open
 
11
 *  source systems. You must contact The Open Group for a license
 
12
 *  allowing distribution and sublicensing of this software on, with,
 
13
 *  or for operating systems which are not Open Source programs.
 
14
 *  
 
15
 *  See http://www.opengroup.org/openmotif/license for full
 
16
 *  details of the license agreement. Any use, reproduction, or
 
17
 *  distribution of the program constitutes recipient's acceptance of
 
18
 *  this agreement.
 
19
 *  
 
20
 *  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
 
21
 *  PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
22
 *  KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 
23
 *  WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
 
24
 *  OR FITNESS FOR A PARTICULAR PURPOSE
 
25
 *  
 
26
 *  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
 
27
 *  NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
 
28
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
29
 *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
 
30
 *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
31
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
32
 *  ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
 
33
 *  EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
 
34
 *  POSSIBILITY OF SUCH DAMAGES.
 
35
*/ 
 
36
/* 
 
37
 * HISTORY
 
38
*/ 
 
39
#ifdef HAVE_CONFIG_H
 
40
#include <config.h>
 
41
#endif
 
42
 
 
43
 
 
44
#ifdef REV_INFO
 
45
#ifndef lint
 
46
static char rcsid[] = "$TOG: TextSel.c /main/24 1998/12/07 11:12:08 mgreess $"
 
47
#endif
 
48
#endif
 
49
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
 
50
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
 
51
 
 
52
#include <X11/Xatom.h>
 
53
#include <Xm/AtomMgr.h>
 
54
#include <Xm/DragC.h>
 
55
#include <Xm/DropTrans.h>
 
56
#include <Xm/TraitP.h>          /* for XmeTraitSet() */
 
57
#include <Xm/TransferT.h>
 
58
#include <Xm/XmosP.h>
 
59
#include "TextI.h"
 
60
#include "TextInI.h"
 
61
#include "TextSelI.h"
 
62
#include "TextStrSoI.h"
 
63
#include "TransferI.h"          /* for _XmConvertComplete() */
 
64
#include "TraversalI.h"
 
65
#include "XmI.h"
 
66
 
 
67
 
 
68
/********    Static Function Declarations    ********/
 
69
 
 
70
static void InsertSelection( 
 
71
                        Widget w,
 
72
                        XtPointer closure,
 
73
                        Atom *seltype,
 
74
                        Atom *type,
 
75
                        XtPointer value,
 
76
                        unsigned long *length,
 
77
                        int *format, 
 
78
                        XtPointer tid) ;
 
79
static void HandleInsertTargets( 
 
80
                        Widget w,
 
81
                        XtPointer closure,
 
82
                        Atom *seltype,
 
83
                        Atom *type,
 
84
                        XtPointer value,
 
85
                        unsigned long *length,
 
86
                        int *format,
 
87
                        XtPointer tid) ;
 
88
 
 
89
static void HandleDrop(Widget w,
 
90
                       XmDropProcCallbackStruct *cb,
 
91
                       XmDestinationCallbackStruct *ds);
 
92
 
 
93
static void HandleTargets(Widget w, 
 
94
                          XtPointer ignore, 
 
95
                          XmSelectionCallbackStruct *ds);
 
96
 
 
97
static void DoStuff(Widget w, 
 
98
                    XtPointer closure, 
 
99
                    XmSelectionCallbackStruct *ds);
 
100
 
 
101
static void DropDestroyCB(Widget w,
 
102
                          XtPointer clientData,
 
103
                          XtPointer callData);
 
104
 
 
105
static void DropTransferProc(Widget w, XtPointer ignore, 
 
106
                             XmSelectionCallbackStruct *ds);
 
107
 
 
108
static void SetDropContext(Widget w);
 
109
 
 
110
static void DeleteDropContext(Widget w);
 
111
static void TextSecondaryWrapper(Widget, XtPointer, 
 
112
                                 XmSelectionCallbackStruct *);
 
113
static void TextConvertCallback(Widget, XtPointer, 
 
114
                                XmConvertCallbackStruct*);
 
115
static void TextDestinationCallback(Widget, XtPointer,
 
116
                                    XmDestinationCallbackStruct*);
 
117
 
 
118
/********    End Static Function Declarations    ********/
 
119
 
 
120
/* Transfer Trait record for Text */
 
121
 
 
122
static XmConst XmTransferTraitRec TextTransfer = {
 
123
  0,                            /* version */
 
124
  (XmConvertCallbackProc)       TextConvertCallback,
 
125
  (XmDestinationCallbackProc)   TextDestinationCallback,
 
126
  (XmDestinationCallbackProc)   NULL,
 
127
};
 
128
 
 
129
static XContext _XmTextDNDContext = 0;
 
130
static _XmTextPrimSelect *prim_select;
 
131
static _XmInsertSelect insert_select;
 
132
 
 
133
/*ARGSUSED*/
 
134
static void
 
135
SetPrimarySelection(Widget w, 
 
136
                    XtEnum op,  /* unused */
 
137
                    XmTransferDoneCallbackStruct *ts) /* unused */
 
138
{
 
139
  XmTextWidget tw = (XmTextWidget) w;
 
140
  InputData data = tw->text.input->data;
 
141
  XmTextPosition cursorPos = tw->text.cursor_position;
 
142
 
 
143
  _XmProcessLock();
 
144
  if (!prim_select) {
 
145
    _XmProcessUnlock();
 
146
    return;
 
147
  }
 
148
 
 
149
  if (prim_select->num_chars > 0) {
 
150
    data->anchor = prim_select->position;
 
151
    cursorPos = prim_select->position + prim_select->num_chars;
 
152
    _XmTextSetCursorPosition(w, cursorPos);
 
153
    _XmTextSetDestinationSelection(w, tw->text.cursor_position,
 
154
                                   False, prim_select->time);
 
155
    (*tw->text.source->SetSelection)(tw->text.source, data->anchor,
 
156
                                     tw->text.cursor_position,
 
157
                                     prim_select->time);
 
158
  }
 
159
  if (--prim_select->ref_count == 0) {
 
160
    XtFree((char *)prim_select);
 
161
    prim_select = NULL;
 
162
  }
 
163
  _XmProcessUnlock();
 
164
}
 
165
 
 
166
 
 
167
/*ARGSUSED*/
 
168
static void
 
169
CleanPrimarySelection(Widget w, 
 
170
                    XtEnum op,  /* unused */
 
171
                    XmTransferDoneCallbackStruct *ts) /* unused */
 
172
{
 
173
  _XmProcessLock();
 
174
  if (!prim_select) {
 
175
    _XmProcessUnlock();
 
176
    return;
 
177
  }
 
178
 
 
179
  if (--prim_select->ref_count == 0) {
 
180
    XtFree((char *)prim_select);
 
181
    prim_select = NULL;
 
182
  }
 
183
  _XmProcessUnlock();
 
184
}
 
185
 
 
186
 
 
187
static void 
 
188
TextSecondaryWrapper(Widget w, XtPointer closure,
 
189
                        XmSelectionCallbackStruct *ds)
 
190
{
 
191
  Atom XA_TARGETS = XInternAtom(XtDisplay(w), XmSTARGETS, False);
 
192
 
 
193
  if (ds -> target == XA_TARGETS)
 
194
    HandleInsertTargets(w, closure, &(ds -> selection), &(ds -> type),
 
195
                        ds -> value, &(ds -> length), &(ds -> format),
 
196
                        ds -> transfer_id);
 
197
  else
 
198
    InsertSelection(w, closure, &(ds -> selection), &(ds -> type),
 
199
                    ds -> value, &(ds -> length), &(ds -> format),
 
200
                    ds -> transfer_id);
 
201
}
 
202
 
 
203
/* ARGSUSED */
 
204
static void
 
205
InsertSelection(
 
206
        Widget w,
 
207
        XtPointer closure,
 
208
        Atom *seltype,
 
209
        Atom *type,
 
210
        XtPointer value,
 
211
        unsigned long *length,
 
212
        int *format, 
 
213
        XtPointer tid)
 
214
{
 
215
  _XmInsertSelect *insert_select = (_XmInsertSelect *)closure;
 
216
  XmTextWidget tw = (XmTextWidget) w;
 
217
  XmTextPosition left = 0;
 
218
  XmTextPosition right = 0;
 
219
  Boolean dest_disjoint = False;
 
220
  Atom COMPOUND_TEXT = XInternAtom(XtDisplay(w), XmSCOMPOUND_TEXT, False);
 
221
#ifdef UTF8_SUPPORTED
 
222
  Atom UTF8_STRING = XInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
 
223
#endif
 
224
  char * total_value = NULL;
 
225
  XmTextBlockRec block, newblock;
 
226
  XmTextPosition cursorPos;
 
227
  Boolean freeBlock;
 
228
  
 
229
  if (!value) {
 
230
    insert_select->done_status = True;
 
231
    return;
 
232
  }
 
233
  
 
234
  /* Don't do replace if there is no text to add */
 
235
  if (*(char *)value == '\0' || *length == 0){
 
236
    XtFree((char*)value);
 
237
    value = NULL;
 
238
    insert_select->done_status = True;
 
239
    return;
 
240
  }
 
241
  
 
242
  if (insert_select->select_type == XmPRIM_SELECT) {
 
243
    if (!(*tw->text.source->GetSelection)(tw->text.source, &left, &right) ||
 
244
        left == right) {
 
245
      XBell(XtDisplay(w), 0);
 
246
      XtFree((char*)value);
 
247
      value = NULL;
 
248
      insert_select->done_status = True;
 
249
      insert_select->success_status = False;
 
250
      return;
 
251
    }
 
252
  } else if (insert_select->select_type == XmDEST_SELECT) {
 
253
    if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) && 
 
254
        left != right) {
 
255
      if (tw->text.cursor_position < left ||
 
256
          tw->text.cursor_position > right ||
 
257
          !tw->text.input->data->pendingdelete) {
 
258
        left = right = tw->text.cursor_position; 
 
259
        dest_disjoint = True;
 
260
      }
 
261
    } else
 
262
      left = right = tw->text.cursor_position;
 
263
  }
 
264
  
 
265
  (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
 
266
  
 
267
  block.format = XmFMT_8_BIT;
 
268
  
 
269
  if (*type == COMPOUND_TEXT || *type == XA_STRING
 
270
#ifdef UTF8_SUPPORTED
 
271
      || *type == UTF8_STRING
 
272
#endif
 
273
  ) {
 
274
    if ((total_value =
 
275
         _XmTextToLocaleText(w, value, *type, *format, 
 
276
                             *length, NULL)) != NULL) {
 
277
      block.ptr = total_value;
 
278
      block.length = strlen(block.ptr);
 
279
    } else {
 
280
      insert_select->done_status = True;
 
281
      insert_select->success_status = False;
 
282
      (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
 
283
      return;
 
284
    }
 
285
  } else {  /* it must be either CS_OF_ENCODING or TEXT */
 
286
    block.ptr = (char*)value;
 
287
    /* NOTE: casting *length could result in a truncated long. */
 
288
    block.length = (unsigned) *length;
 
289
    block.format = XmFMT_8_BIT;
 
290
  }
 
291
  
 
292
  if (_XmTextModifyVerify(tw, (XEvent *)insert_select->event, &left, &right,
 
293
                          &cursorPos, &block, &newblock, &freeBlock)) {
 
294
    if ((*tw->text.source->Replace)(tw, (XEvent *)insert_select->event, 
 
295
                                    &left, &right,
 
296
                                    &newblock, False) != EditDone) {
 
297
      if (tw->text.verify_bell) XBell(XtDisplay(w), 0);
 
298
      insert_select->success_status = False;
 
299
    } else {
 
300
      insert_select->success_status = True;
 
301
      
 
302
      if (!tw->text.add_mode) tw->text.input->data->anchor = left;
 
303
      
 
304
      if (tw->text.add_mode && cursorPos >= left && cursorPos <= right)
 
305
        tw->text.pendingoff = FALSE;
 
306
      else
 
307
        tw->text.pendingoff = TRUE;
 
308
      
 
309
      _XmTextSetCursorPosition(w, cursorPos);
 
310
      _XmTextSetDestinationSelection(w, tw->text.cursor_position, False,
 
311
                                     insert_select->event->time);
 
312
      
 
313
      if (insert_select->select_type == XmDEST_SELECT) {
 
314
        if (left != right) {
 
315
          if (!dest_disjoint || !tw->text.add_mode) {
 
316
            (*tw->text.source->SetSelection)(tw->text.source,
 
317
                                             tw->text.cursor_position,
 
318
                                             tw->text.cursor_position,
 
319
                                             insert_select->event->time);
 
320
          } 
 
321
        }
 
322
      }
 
323
      _XmTextValueChanged(tw, (XEvent *)insert_select->event);
 
324
    }
 
325
    if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
 
326
  }
 
327
  
 
328
  (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
 
329
  if (total_value) XtFree(total_value);
 
330
  XtFree((char*)value);
 
331
  value = NULL;
 
332
  insert_select->done_status = True;
 
333
}
 
334
 
 
335
/* ARGSUSED */
 
336
static void
 
337
HandleInsertTargets(
 
338
        Widget w,
 
339
        XtPointer closure,
 
340
        Atom *seltype,
 
341
        Atom *type,
 
342
        XtPointer value,
 
343
        unsigned long *length,
 
344
        int *format,
 
345
        XtPointer tid )
 
346
{
 
347
  enum { XmATEXT, XmACOMPOUND_TEXT,
 
348
#ifdef UTF8_SUPPORTED
 
349
      XmAUTF8_STRING,
 
350
#endif
 
351
      NUM_ATOMS };
 
352
  static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT,
 
353
#ifdef UTF8_SUPPORTED
 
354
      XmSUTF8_STRING
 
355
#endif
 
356
      };
 
357
 
 
358
  _XmInsertSelect *insert_select = (_XmInsertSelect *) closure;
 
359
  Atom atoms[XtNumber(atom_names)];
 
360
  Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
361
  Atom target;
 
362
  Atom *atom_ptr;
 
363
  Boolean supports_encoding_data = False;
 
364
  Boolean supports_CT = False;
 
365
  Boolean supports_text = False;
 
366
  Boolean supports_utf8_string = False;
 
367
  int i;
 
368
  
 
369
  if (0 == *length) {
 
370
    XtFree((char *)value);
 
371
    insert_select->done_status = True;
 
372
    return; /* Supports no targets, so don't bother sending anything */
 
373
  }
 
374
  
 
375
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
376
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
377
 
 
378
  atom_ptr = (Atom *)value;
 
379
  
 
380
  for (i = 0; i < *length; i++, atom_ptr++) {
 
381
    if (*atom_ptr == atoms[XmATEXT])
 
382
      supports_text = True;
 
383
    
 
384
    if (*atom_ptr == CS_OF_ENCODING) 
 
385
      supports_encoding_data = True;
 
386
    
 
387
    if (*atom_ptr == atoms[XmACOMPOUND_TEXT]) 
 
388
      supports_CT = True;
 
389
 
 
390
#ifdef UTF8_SUPPORTED
 
391
    if (*atom_ptr == atoms[XmAUTF8_STRING]) 
 
392
      supports_utf8_string = True;
 
393
#endif
 
394
  }
 
395
 
 
396
  if (supports_text && supports_encoding_data)
 
397
    target = atoms[XmATEXT];
 
398
#ifdef UTF8_SUPPORTED
 
399
  else if (supports_utf8_string)
 
400
    target = atoms[XmAUTF8_STRING];
 
401
#endif
 
402
  else if (supports_CT)
 
403
    target = atoms[XmACOMPOUND_TEXT];
 
404
  else if (supports_encoding_data)
 
405
    target = CS_OF_ENCODING;
 
406
  else
 
407
    target = XA_STRING;
 
408
 
 
409
  XmTransferValue(tid, target,
 
410
                  (XtCallbackProc) TextSecondaryWrapper,
 
411
                  closure, insert_select -> event -> time);
 
412
}
 
413
 
 
414
/* ARGSUSED */
 
415
Boolean
 
416
_XmTextConvert(
 
417
        Widget w,
 
418
        Atom *selection,
 
419
        Atom *target,
 
420
        Atom *type,
 
421
        XtPointer *value,
 
422
        unsigned long *length,
 
423
        int *format,
 
424
        Widget drag_context,
 
425
        XEvent *event )
 
426
{
 
427
  enum { XmA_MOTIF_DESTINATION, XmAINSERT_SELECTION, XmADELETE,
 
428
         XmATARGETS, XmATEXT, XmACOMPOUND_TEXT, XmATIMESTAMP,
 
429
         XmA_MOTIF_DROP, XmACLIPBOARD, XmANULL,
 
430
#ifdef UTF8_SUPPORTED
 
431
         XmAUTF8_STRING,
 
432
#endif
 
433
         NUM_ATOMS };
 
434
  static char *atom_names[] = {
 
435
    XmS_MOTIF_DESTINATION, XmSINSERT_SELECTION, XmSDELETE,
 
436
    XmSTARGETS, XmSTEXT, XmSCOMPOUND_TEXT, XmSTIMESTAMP,
 
437
    XmS_MOTIF_DROP, XmSCLIPBOARD, XmSNULL,
 
438
#ifdef UTF8_SUPPORTED
 
439
    XmSUTF8_STRING
 
440
#endif
 
441
    };
 
442
 
 
443
  XmTextWidget tw = (XmTextWidget) w;
 
444
  XmTextSource source;
 
445
  Atom atoms[XtNumber(atom_names)];
 
446
  Atom CS_OF_ENCODING;
 
447
  XSelectionRequestEvent * req_event = (XSelectionRequestEvent *) event;
 
448
  Boolean has_selection = False;
 
449
  XmTextPosition left = 0;
 
450
  XmTextPosition right = 0;
 
451
  Boolean is_primary;
 
452
  Boolean is_secondary;
 
453
  Boolean is_destination;
 
454
  Boolean is_drop;
 
455
  int target_count = 0;
 
456
  XTextProperty tmp_prop;
 
457
  int status = 0;
 
458
  char * tmp_value;
 
459
  Time _time;
 
460
  
 
461
  if (w == NULL) return False;
 
462
  
 
463
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
464
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
465
  CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
466
 
 
467
  if (req_event == NULL) 
 
468
    _time = XtLastTimestampProcessed(XtDisplay(w));
 
469
  else
 
470
    _time = req_event -> time;
 
471
  
 
472
  source = tw->text.source;
 
473
  
 
474
  if (*selection == XA_PRIMARY || *selection == atoms[XmACLIPBOARD]) {
 
475
    has_selection = (*tw->text.source->GetSelection)(source, &left, &right);
 
476
    is_primary = True;
 
477
    is_secondary = is_destination = is_drop = False;
 
478
  } else if (*selection == atoms[XmA_MOTIF_DESTINATION]) {
 
479
    has_selection = tw->text.input->data->has_destination;
 
480
    is_destination = True;
 
481
    is_secondary = is_primary = is_drop = False;
 
482
  } else if (*selection == XA_SECONDARY) {
 
483
    has_selection = _XmTextGetSel2(tw, &left, &right);
 
484
    is_secondary = True;
 
485
    is_destination = is_primary = is_drop = False;
 
486
  } else if (*selection == atoms[XmA_MOTIF_DROP]) {
 
487
    has_selection = (*tw->text.source->GetSelection)(source, &left, &right);
 
488
    is_drop = True;
 
489
    is_destination = is_primary = is_secondary = False;
 
490
  } else
 
491
    return False;
 
492
  
 
493
  
 
494
  /*
 
495
   * TARGETS identifies what targets the text widget can
 
496
   * provide data for.
 
497
   */
 
498
  if (*target == atoms[XmATARGETS]) {
 
499
    Atom *targs = XmeStandardTargets(w, 10, &target_count);
 
500
    
 
501
    *value = (XtPointer) targs;
 
502
    if (XA_STRING != CS_OF_ENCODING) {
 
503
      targs[target_count] = CS_OF_ENCODING;  target_count++;
 
504
    }
 
505
    if (is_primary || is_destination) {
 
506
      targs[target_count] = atoms[XmAINSERT_SELECTION];  target_count++;
 
507
    }
 
508
    if (is_primary || is_secondary || is_drop) {
 
509
      targs[target_count] = atoms[XmACOMPOUND_TEXT];  target_count++;
 
510
      targs[target_count] = atoms[XmATEXT];  target_count++;
 
511
      targs[target_count] = XA_STRING;  target_count++;
 
512
#ifdef UTF8_SUPPORTED
 
513
      targs[target_count] = atoms[XmAUTF8_STRING];  target_count++;
 
514
#endif
 
515
    }
 
516
    if (is_primary || is_drop) {
 
517
      targs[target_count] = atoms[XmADELETE]; target_count++;
 
518
    }
 
519
    *type = XA_ATOM;
 
520
    *length = target_count;
 
521
    *format = 32;
 
522
  } else if (*target == atoms[XmATIMESTAMP]) {
 
523
    Time *timestamp;
 
524
    timestamp = (Time *) XtMalloc(sizeof(Time));
 
525
    if (is_primary)
 
526
      *timestamp = source->data->prim_time;
 
527
    else if (is_destination)
 
528
      *timestamp = tw->text.input->data->dest_time;
 
529
    else if (is_secondary)
 
530
      *timestamp = tw->text.input->data->sec_time;
 
531
    else if (is_drop)
 
532
      *timestamp = tw->text.input->data->sec_time;
 
533
    *value = (XtPointer) timestamp;
 
534
    *type = XA_INTEGER;
 
535
    *length = sizeof(Time) / 4;
 
536
    *format = 32;
 
537
  } else if (*target == XA_STRING) {
 
538
    /* Provide data for XA_STRING requests */
 
539
    *type = (Atom) XA_STRING;
 
540
    *format = 8;
 
541
    if (is_destination || !has_selection) return False;
 
542
    tmp_prop.value = NULL;
 
543
    tmp_value = _XmStringSourceGetString(tw, left, right, False);
 
544
    status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
 
545
                                       (XICCEncodingStyle)XStringStyle, 
 
546
                                       &tmp_prop);
 
547
    XtFree(tmp_value);
 
548
    if (status == Success || status > 0){
 
549
      /* NOTE: casting tmp_prop.nitems could result in a truncated long. */
 
550
      if (0 >= tmp_prop.nitems)
 
551
        *value = (XtPointer) XtMalloc(1);
 
552
      else
 
553
        *value = (XtPointer) XtMalloc((unsigned)tmp_prop.nitems);
 
554
      memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
 
555
      if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
 
556
      *length = tmp_prop.nitems;
 
557
    } else {
 
558
      *value = NULL;
 
559
      *length = 0;
 
560
      return False;
 
561
    }
 
562
    
 
563
  } else if (*target == atoms[XmATEXT] || *target == CS_OF_ENCODING) {
 
564
    *type = CS_OF_ENCODING;
 
565
    *format = 8;
 
566
    if (is_destination || !has_selection) return False;
 
567
    *value = (XtPointer)_XmStringSourceGetString(tw, left, right, False);
 
568
    *length = strlen((char*) *value);
 
569
  } else if (*target == atoms[XmACOMPOUND_TEXT]) {
 
570
    *type = atoms[XmACOMPOUND_TEXT];
 
571
    *format = 8;
 
572
    if (is_destination || !has_selection) return False;
 
573
    tmp_prop.value = NULL;
 
574
    tmp_value =_XmStringSourceGetString(tw, left, right, False);
 
575
    status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
 
576
                                       (XICCEncodingStyle)XCompoundTextStyle,
 
577
                                       &tmp_prop);
 
578
    XtFree(tmp_value);
 
579
    if (status == Success || status > 0) {
 
580
      /* NOTE: casting tmp_prop.nitems could result in a truncated long. */
 
581
      *value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
 
582
      memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
 
583
      if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
 
584
      *length = tmp_prop.nitems;
 
585
    } else {
 
586
      *value =  NULL;
 
587
      *length = 0;
 
588
      return False;
 
589
    }
 
590
#ifdef UTF8_SUPPORTED
 
591
  } else if (*target == atoms[XmAUTF8_STRING]) {
 
592
    *type = atoms[XmAUTF8_STRING];
 
593
    *format = 8;
 
594
    if (is_destination || !has_selection) return False;
 
595
    tmp_prop.value = NULL;
 
596
    tmp_value =_XmStringSourceGetString(tw, left, right, False);
 
597
    status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
 
598
                                       (XICCEncodingStyle)XUTF8StringStyle,
 
599
                                       &tmp_prop);
 
600
    XtFree(tmp_value);
 
601
    if (status == Success || status > 0) {
 
602
      /* NOTE: casting tmp_prop.nitems could result in a truncated long. */
 
603
      *value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
 
604
      memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
 
605
      if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
 
606
      *length = tmp_prop.nitems;
 
607
    } else {
 
608
      *value =  NULL;
 
609
      *length = 0;
 
610
      return False;
 
611
    }
 
612
#endif
 
613
  } else if (*target == atoms[XmAINSERT_SELECTION]) {
 
614
    if (is_secondary) 
 
615
      return False;
 
616
    else
 
617
      return True;
 
618
    /* Delete the selection */
 
619
  } else if (*target == atoms[XmADELETE]) {
 
620
    XmTextBlockRec block, newblock;
 
621
    XmTextPosition cursorPos;
 
622
    Boolean freeBlock;
 
623
    
 
624
    if (!(is_primary || is_drop)) return False;
 
625
    
 
626
    /* The on_or_off flag is set to prevent unecessary
 
627
       cursor shifting during the Replace operation */
 
628
    tw->text.on_or_off = off;
 
629
    
 
630
    block.ptr = "";
 
631
    block.length = 0;
 
632
    block.format = XmFMT_8_BIT;
 
633
    
 
634
    if (_XmTextModifyVerify(tw, event, &left, &right,
 
635
                            &cursorPos, &block, &newblock, &freeBlock)) {
 
636
      if ((*tw->text.source->Replace)(tw, event, &left, &right, 
 
637
                                      &newblock, False) != EditDone) {
 
638
        if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
 
639
        return False;
 
640
      } else {
 
641
        if (is_drop) {
 
642
          if (_XmTextGetDropReciever((Widget)tw) != (Widget) tw)
 
643
            _XmTextSetCursorPosition((Widget)tw, cursorPos);
 
644
        } else {
 
645
          if ((*selection == atoms[XmACLIPBOARD]) || 
 
646
              (req_event != NULL &&
 
647
              req_event->requestor != XtWindow((Widget) tw)))
 
648
            _XmTextSetCursorPosition(w, cursorPos);
 
649
        }
 
650
        _XmTextValueChanged(tw, (XEvent *) req_event);
 
651
      }
 
652
      if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
 
653
    } 
 
654
    if (!tw->text.input->data->has_destination)
 
655
      tw->text.input->data->anchor = tw->text.cursor_position;
 
656
    
 
657
    (*tw->text.source->SetSelection)(tw->text.source,
 
658
                                     tw->text.cursor_position,
 
659
                                     tw->text.cursor_position,
 
660
                                     _time);
 
661
    
 
662
    *type = atoms[XmANULL];
 
663
    *value = NULL;
 
664
    *length = 0;
 
665
    *format = 8;
 
666
    
 
667
    tw->text.on_or_off = on;
 
668
    
 
669
    /* unknown selection type */
 
670
  } else
 
671
    return FALSE;
 
672
  return TRUE;
 
673
}
 
674
 
 
675
/* ARGSUSED */
 
676
void
 
677
_XmTextLoseSelection(
 
678
        Widget w,
 
679
        Atom *selection )
 
680
{
 
681
  XmTextWidget tw = (XmTextWidget) w;
 
682
  XmTextSource source = tw->text.source;
 
683
  Atom MOTIF_DESTINATION = XInternAtom(XtDisplay(w),
 
684
                                       XmS_MOTIF_DESTINATION, False);
 
685
  /* Losing Primary Selection */
 
686
  if (*selection == XA_PRIMARY && _XmStringSourceHasSelection(source)) {
 
687
    XmAnyCallbackStruct cb;
 
688
    (*source->SetSelection)(source, 1, -999,
 
689
                            XtLastTimestampProcessed(XtDisplay(w)));
 
690
    cb.reason = XmCR_LOSE_PRIMARY;
 
691
    cb.event = NULL;
 
692
    XtCallCallbackList(w, tw->text.lose_primary_callback, (XtPointer) &cb);
 
693
    /* Losing Destination Selection */
 
694
  } else if (*selection == MOTIF_DESTINATION) {
 
695
    tw->text.input->data->has_destination = False;
 
696
    (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
 
697
    tw->text.output->data->blinkstate = on;
 
698
    (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
 
699
    /* Losing Secondary Selection */
 
700
  } else if (*selection == XA_SECONDARY && tw->text.input->data->hasSel2){
 
701
    _XmTextSetSel2(tw, 1, -999, XtLastTimestampProcessed(XtDisplay(w)));
 
702
  }
 
703
}
 
704
 
 
705
 
 
706
static void
 
707
HandleDrop(Widget w,
 
708
           XmDropProcCallbackStruct *cb,
 
709
           XmDestinationCallbackStruct *ds)
 
710
{
 
711
  Widget drag_cont, initiator;
 
712
  XmTextWidget tw = (XmTextWidget) w;
 
713
  Cardinal numExportTargets, n;
 
714
  Atom *exportTargets;
 
715
  Atom desiredTarget = None;
 
716
  Arg args[10];
 
717
  XmTextPosition insert_pos, left, right;
 
718
  Boolean doTransfer = False;
 
719
  XtPointer tid = ds->transfer_id;
 
720
  _XmTextDropTransferRec *transfer_rec = NULL;
 
721
  
 
722
  drag_cont = cb->dragContext;
 
723
  
 
724
  n = 0;
 
725
  XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
 
726
  XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
 
727
  XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
 
728
  XtGetValues((Widget) drag_cont, args, n);
 
729
  
 
730
  insert_pos = (*tw->text.output->XYToPos)(tw, cb->x, cb->y);
 
731
  
 
732
  if (cb->operation & XmDROP_MOVE && w == initiator &&
 
733
      ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
 
734
       left != right && insert_pos >= left && insert_pos <= right)) {
 
735
    XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
 
736
  } else {
 
737
    enum { XmATEXT, XmACOMPOUND_TEXT,
 
738
#ifdef UTF8_SUPPORTED
 
739
        XmAUTF8_STRING,
 
740
#endif
 
741
        NUM_ATOMS };
 
742
    static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT,
 
743
#ifdef UTF8_SUPPORTED
 
744
        XmSUTF8_STRING
 
745
#endif
 
746
        };
 
747
    Atom atoms[XtNumber(atom_names)];
 
748
    Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
749
    Boolean encoding_found = False;
 
750
    Boolean c_text_found = False;
 
751
    Boolean string_found = False;
 
752
    Boolean text_found = False;
 
753
    Boolean utf8_string_found = False;
 
754
    
 
755
    assert(XtNumber(atom_names) == NUM_ATOMS);
 
756
    XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
757
 
 
758
    /* intialize data to send to drop transfer callback */
 
759
    transfer_rec = (_XmTextDropTransferRec *)
 
760
      XtMalloc(sizeof(_XmTextDropTransferRec));
 
761
    transfer_rec->widget = w;
 
762
    transfer_rec->insert_pos = insert_pos;
 
763
    transfer_rec->num_chars = 0;
 
764
    transfer_rec->timestamp = cb->timeStamp;
 
765
    
 
766
    if (cb->operation & XmDROP_MOVE) {
 
767
      transfer_rec->move = True;
 
768
    } else {
 
769
      transfer_rec->move = False;
 
770
    }
 
771
    
 
772
    for (n = 0; n < numExportTargets; n++) {
 
773
      if (exportTargets[n] == CS_OF_ENCODING) {
 
774
        desiredTarget = CS_OF_ENCODING;
 
775
        encoding_found = True;
 
776
        break;
 
777
      }
 
778
#ifdef UTF8_SUPPORTED
 
779
      if (exportTargets[n] == atoms[XmAUTF8_STRING]) utf8_string_found = True;
 
780
#endif
 
781
      if (exportTargets[n] == atoms[XmACOMPOUND_TEXT]) c_text_found = True;
 
782
      if (exportTargets[n] == XA_STRING) string_found = True;
 
783
      if (exportTargets[n] == atoms[XmATEXT]) text_found = True;
 
784
    }
 
785
    
 
786
    n = 0;
 
787
    if (encoding_found || c_text_found || string_found || text_found
 
788
        || utf8_string_found) {
 
789
      if (!encoding_found) {
 
790
        if (c_text_found)
 
791
          desiredTarget = atoms[XmACOMPOUND_TEXT];
 
792
#ifdef UTF8_SUPPORTED
 
793
        else if (utf8_string_found)
 
794
          desiredTarget = atoms[XmAUTF8_STRING];
 
795
#endif
 
796
        else if (string_found)
 
797
          desiredTarget = XA_STRING;
 
798
        else
 
799
          desiredTarget = atoms[XmATEXT];
 
800
      }
 
801
      
 
802
      if (cb->operation & XmDROP_MOVE || cb->operation & XmDROP_COPY) {
 
803
        doTransfer = True;
 
804
      } else {
 
805
        XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
 
806
      }
 
807
    } else {
 
808
      XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
 
809
    }
 
810
  }
 
811
  SetDropContext(w);
 
812
  
 
813
  if (doTransfer) {
 
814
    XmeTransferAddDoneProc(tid, (XmSelectionFinishedProc) DropDestroyCB);
 
815
    XmTransferValue(tid, desiredTarget,
 
816
                    (XtCallbackProc) DropTransferProc,
 
817
                    (XtPointer) transfer_rec, 0);
 
818
  }
 
819
}
 
820
 
 
821
/* Request targets from selection receiver; move the rest of this
 
822
 * to a new routine (the name of which is passed during the request
 
823
 * for targets).  The new routine will look at the target list and
 
824
 * determine what target to place in the pair.  It will then do
 
825
 * any necessary conversions before "thrusting" the selection value
 
826
 * onto the receiver.  This will guarantee the best chance at a
 
827
 * successful exchange.
 
828
 */
 
829
 
 
830
static void 
 
831
HandleTargets(Widget w, 
 
832
              XtPointer closure,
 
833
              XmSelectionCallbackStruct *ds)
 
834
{
 
835
  enum { XmACOMPOUND_TEXT, XmACLIPBOARD, XmATEXT,
 
836
#ifdef UTF8_SUPPORTED
 
837
      XmAUTF8_STRING,
 
838
#endif
 
839
      NUM_ATOMS };
 
840
  static char *atom_names[] =  { XmSCOMPOUND_TEXT, XmSCLIPBOARD, XmSTEXT,
 
841
#ifdef UTF8_SUPPORTED
 
842
      XmSUTF8_STRING
 
843
#endif
 
844
      };
 
845
 
 
846
  XmTextWidget tw = (XmTextWidget) w;
 
847
  Atom CS_OF_ENCODING;
 
848
  Atom atoms[XtNumber(atom_names)];
 
849
  Boolean supports_encoding_data = False;
 
850
  Boolean supports_CT = False;
 
851
  Boolean supports_text = False;
 
852
  Boolean supports_utf8_string = False;
 
853
  Atom *atom_ptr;
 
854
  XPoint *point = (XPoint *)closure;
 
855
  Atom targets[2];
 
856
  XmTextPosition select_pos;
 
857
  XmTextPosition left, right;
 
858
  int i;
 
859
  
 
860
  if (!ds->length) {
 
861
    XtFree((char *)ds->value);
 
862
    ds->value = NULL;
 
863
    return;
 
864
  }
 
865
  
 
866
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
867
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
868
  CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
869
 
 
870
  atom_ptr = (Atom *)ds->value;
 
871
  
 
872
  for (i = 0; i < ds->length; i++, atom_ptr++) {
 
873
    if (*atom_ptr == atoms[XmATEXT])
 
874
      supports_text = True;
 
875
 
 
876
    if (*atom_ptr == CS_OF_ENCODING) 
 
877
      supports_encoding_data = True;
 
878
 
 
879
    if (*atom_ptr == atoms[XmACOMPOUND_TEXT])
 
880
      supports_CT = True;
 
881
 
 
882
#ifdef UTF8_SUPPORTED
 
883
    if (*atom_ptr == atoms[XmAUTF8_STRING])
 
884
      supports_utf8_string = True;
 
885
#endif
 
886
  }
 
887
  
 
888
  
 
889
  /*
 
890
   * Set stuff position to the x and y position of
 
891
   * the button pressed event for primary pastes.
 
892
   */
 
893
  if (ds->selection != atoms[XmACLIPBOARD] && point) {
 
894
    select_pos = 
 
895
      (*tw->text.output->XYToPos)(tw, (Position)point->x, (Position)point->y);
 
896
  } else {
 
897
    select_pos = tw->text.cursor_position;
 
898
  }
 
899
  
 
900
  if (ds->selection != atoms[XmACLIPBOARD]) {
 
901
    if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) && 
 
902
        left != right && select_pos > left && 
 
903
        select_pos < right) {
 
904
      XtFree((char *)ds->value);
 
905
      ds->value = NULL;
 
906
      return;
 
907
    }
 
908
  }
 
909
  
 
910
  _XmProcessLock();
 
911
  if (prim_select) {
 
912
    prim_select->ref_count++;
 
913
  } else {
 
914
    prim_select = (_XmTextPrimSelect *)
 
915
      XtMalloc((unsigned) sizeof(_XmTextPrimSelect));
 
916
  }
 
917
  prim_select->position = select_pos;
 
918
  prim_select->time = XtLastTimestampProcessed(XtDisplay(w));
 
919
  prim_select->num_chars = 0;
 
920
  
 
921
  /* If owner supports TEXT and the current locale, ask for TEXT.  
 
922
   * If not, and if the owner supports compound text, ask for 
 
923
   * compound text. If not, and owner and I have the same encoding, 
 
924
   * ask for that encoding. If not, fall back position is to ask for 
 
925
   * STRING and try to convert it locally.
 
926
   */
 
927
  
 
928
  if (supports_text && supports_encoding_data)
 
929
    prim_select->target = targets[0] = atoms[XmATEXT];
 
930
#ifdef UTF8_SUPPORTED
 
931
  else if (supports_utf8_string)
 
932
    prim_select->target = targets[0] = atoms[XmAUTF8_STRING];
 
933
#endif
 
934
  else if (supports_CT)
 
935
    prim_select->target = targets[0] = atoms[XmACOMPOUND_TEXT];
 
936
  else if (supports_encoding_data)
 
937
    prim_select->target = targets[0] = CS_OF_ENCODING;
 
938
  else
 
939
    prim_select->target = targets[0] = XA_STRING;
 
940
  
 
941
  prim_select->ref_count = 1;
 
942
  /* Make request to call DoStuff() with the primary selection. */
 
943
  XmTransferValue(ds->transfer_id, targets[0], (XtCallbackProc) DoStuff, 
 
944
                  (XtPointer) prim_select, prim_select->time);
 
945
  
 
946
  _XmProcessUnlock();
 
947
  XtFree((char *)ds->value);
 
948
  ds->value = NULL;
 
949
}
 
950
 
 
951
/* Pastes the primary selection to the stuff position. */
 
952
static void
 
953
DoStuff(Widget w, 
 
954
        XtPointer closure, 
 
955
        XmSelectionCallbackStruct *ds)
 
956
{
 
957
  enum { XmANULL, XmACLIPBOARD, XmATEXT, XmACOMPOUND_TEXT,
 
958
#ifdef UTF8_SUPPORTED
 
959
      XmAUTF8_STRING,
 
960
#endif
 
961
      NUM_ATOMS };
 
962
  static char *atom_names[] =  { 
 
963
    XmSNULL, XmSCLIPBOARD, XmSTEXT, XmSCOMPOUND_TEXT,
 
964
#ifdef UTF8_SUPPORTED
 
965
    XmSUTF8_STRING
 
966
#endif
 
967
    };
 
968
 
 
969
  XmTextWidget tw = (XmTextWidget) w;
 
970
  InputData data = tw->text.input->data;
 
971
  OutputData o_data = tw->text.output->data;
 
972
  Atom atoms[XtNumber(atom_names)];
 
973
  XmTextBlockRec block, newblock;
 
974
  XmTextPosition cursorPos = tw->text.cursor_position;
 
975
  XmTextPosition right, left, replace_from, replace_to;
 
976
  _XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
 
977
  char * total_value = NULL;
 
978
  Boolean freeBlock;
 
979
 
 
980
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
981
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
982
 
 
983
  if (!o_data->hasfocus && _XmGetFocusPolicy(w) == XmEXPLICIT)
 
984
    (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
 
985
  
 
986
  if (ds->selection != atoms[XmACLIPBOARD] && 
 
987
      !(ds->length) && ds->type != atoms[XmANULL]) {
 
988
    /* Backwards compatibility for 1.0 Selections */
 
989
    _XmProcessLock();
 
990
    if (prim_select->target == atoms[XmATEXT]) {
 
991
      prim_select->target = XA_STRING;
 
992
      XmTransferValue(ds->transfer_id, XA_STRING, (XtCallbackProc) DoStuff,
 
993
                      (XtPointer) prim_select, prim_select->time);
 
994
    }
 
995
    _XmProcessUnlock();
 
996
    XtFree((char *)ds->value);
 
997
    ds->value = NULL;
 
998
    return;
 
999
  }
 
1000
  
 
1001
  /* if length == 0 and ds->type is the NULL atom we are assuming
 
1002
   * that a DELETE target is requested.
 
1003
   */
 
1004
  if (ds->type == atoms[XmANULL]) {
 
1005
    _XmProcessLock();
 
1006
    if (prim_select->num_chars > 0 && data->selectionMove) {
 
1007
      data->anchor = prim_select->position;
 
1008
      cursorPos = prim_select->position + prim_select->num_chars;
 
1009
      _XmTextSetCursorPosition(w, cursorPos);
 
1010
      _XmTextSetDestinationSelection(w, tw->text.cursor_position,
 
1011
                                     False, prim_select->time);
 
1012
      (*tw->text.source->SetSelection)(tw->text.source, data->anchor,
 
1013
                                       tw->text.cursor_position,
 
1014
                                       prim_select->time);
 
1015
    }
 
1016
    _XmProcessUnlock();
 
1017
  } else {
 
1018
    XmTextSource source = GetSrc(w);
 
1019
    int max_length = 0;
 
1020
    Boolean local = _XmStringSourceHasSelection(source);
 
1021
    Boolean *pendingoff = NULL;
 
1022
    Boolean dest_disjoint = True;
 
1023
    
 
1024
    block.format = XmFMT_8_BIT;
 
1025
    
 
1026
    if (ds->type == atoms[XmACOMPOUND_TEXT] ||
 
1027
#ifdef UTF8_SUPPORTED
 
1028
        ds->type == atoms[XmAUTF8_STRING] ||
 
1029
#endif
 
1030
        ds->type == XA_STRING) {
 
1031
      if ((total_value = 
 
1032
           _XmTextToLocaleText(w, ds->value, ds->type, ds->format,
 
1033
                               ds->length, NULL)) != NULL) {
 
1034
        block.ptr = total_value;
 
1035
        block.length = strlen(block.ptr);
 
1036
      } else {
 
1037
        block.ptr = total_value = XtMalloc((unsigned)1);
 
1038
        *(block.ptr) = '\0';
 
1039
        block.length = 0;
 
1040
      }
 
1041
    } else {
 
1042
      block.ptr = (char*)ds->value;
 
1043
      block.length = (int) ds->length; /* NOTE: this causes a truncation on
 
1044
                                          some architectures */
 
1045
    }
 
1046
    
 
1047
    if (data->selectionMove && local) {
 
1048
      max_length = _XmStringSourceGetMaxLength(source);
 
1049
      _XmStringSourceSetMaxLength(source, INT_MAX);
 
1050
    }
 
1051
    
 
1052
    replace_from = replace_to = prim_select->position;
 
1053
    pendingoff = _XmStringSourceGetPending(tw);
 
1054
 
 
1055
    if (ds->selection == atoms[XmACLIPBOARD]) {
 
1056
      if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
 
1057
        if (tw->text.input->data->pendingdelete &&
 
1058
            replace_from >= left && replace_to <= right){
 
1059
          replace_from = left;
 
1060
          replace_to = right;
 
1061
          dest_disjoint = False;
 
1062
        }
 
1063
      }
 
1064
   } else {  
 
1065
      /* The on_or_off flag is set to prevent unnecessary
 
1066
         cursor shifting during the Replace operation */
 
1067
      tw->text.on_or_off = off;
 
1068
 
 
1069
      _XmStringSourceSetPending(tw, (Boolean *)FALSE);
 
1070
    }
 
1071
    
 
1072
    if (_XmTextModifyVerify(tw, ds->event, &replace_from, &replace_to,
 
1073
                            &cursorPos, &block, &newblock, &freeBlock)) {
 
1074
      _XmProcessLock();
 
1075
      prim_select->num_chars = _XmTextCountCharacters(newblock.ptr, 
 
1076
                                                      newblock.length);
 
1077
      _XmProcessUnlock();
 
1078
      if ((*tw->text.source->Replace)(tw, ds->event, 
 
1079
                                      &replace_from, &replace_to,
 
1080
                                      &newblock, False) != EditDone) {
 
1081
        XtCallActionProc(w, "beep", NULL, (String *) NULL, (Cardinal) 0);
 
1082
        _XmProcessLock();
 
1083
        prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
 
1084
                                       anything */
 
1085
        _XmProcessUnlock();
 
1086
        _XmStringSourceSetPending(tw, pendingoff);
 
1087
      } else {
 
1088
        if ((newblock.length > 0 && !data->selectionMove) || 
 
1089
            ds->selection == atoms[XmACLIPBOARD]) {
 
1090
          _XmTextSetCursorPosition(w, cursorPos);
 
1091
          _XmTextSetDestinationSelection(w, tw->text.cursor_position,
 
1092
                                         False, prim_select->time);
 
1093
        }
 
1094
        if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
 
1095
          if (ds->selection == atoms[XmACLIPBOARD]) {
 
1096
            data->anchor = replace_from;
 
1097
            if (left != right && (!dest_disjoint || !tw->text.add_mode))
 
1098
              (*source->SetSelection)(source, tw->text.cursor_position,
 
1099
                                      tw->text.cursor_position, 
 
1100
                                      prim_select->time);
 
1101
          } else {
 
1102
            if (data->selectionMove) {
 
1103
              _XmProcessLock();
 
1104
              if (left < replace_from) {
 
1105
                prim_select->position = replace_from -
 
1106
                  prim_select->num_chars;
 
1107
              } else {
 
1108
                prim_select->position = replace_from;
 
1109
              }
 
1110
              _XmProcessUnlock();
 
1111
            }
 
1112
            if (cursorPos < left || cursorPos > right)
 
1113
              _XmStringSourceSetPending(tw, (Boolean *)TRUE);
 
1114
            else
 
1115
              _XmStringSourceSetPending(tw, pendingoff);
 
1116
          }
 
1117
        } else {
 
1118
          _XmProcessLock();
 
1119
          if (ds->selection == atoms[XmACLIPBOARD])
 
1120
            data->anchor = replace_from;
 
1121
          else if (!data->selectionMove && !tw->text.add_mode &&
 
1122
              prim_select->num_chars != 0)
 
1123
            data->anchor = prim_select->position;
 
1124
          _XmProcessUnlock();
 
1125
        }
 
1126
        _XmTextValueChanged(tw, ds->event);
 
1127
      }
 
1128
      if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
 
1129
    } else {
 
1130
      XtCallActionProc(w, "beep", NULL, (String *) NULL, (Cardinal) 0);
 
1131
      _XmProcessLock();
 
1132
      prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
 
1133
                                     anything */
 
1134
      _XmProcessUnlock();
 
1135
      _XmStringSourceSetPending(tw, pendingoff);
 
1136
    }
 
1137
    
 
1138
    if (data->selectionMove && local) {
 
1139
      _XmStringSourceSetMaxLength(source, max_length);
 
1140
    }
 
1141
    
 
1142
    if (ds->selection != atoms[XmACLIPBOARD]) 
 
1143
      tw->text.on_or_off = on;
 
1144
 
 
1145
    if (pendingoff) XtFree((char *)pendingoff);
 
1146
  }
 
1147
 
 
1148
  if (total_value) XtFree(total_value);
 
1149
  XtFree((char *)ds->value);
 
1150
  ds->value = NULL;
 
1151
}
 
1152
 
 
1153
/* ARGSUSED */
 
1154
static void
 
1155
DropDestroyCB(Widget      w,
 
1156
              XtPointer   clientData,
 
1157
              XtPointer   callData)
 
1158
{
 
1159
  XmTransferDoneCallbackStruct *ts = (XmTransferDoneCallbackStruct *)callData;
 
1160
  
 
1161
  DeleteDropContext(w);
 
1162
  if (ts->client_data != NULL) XtFree((char*) ts->client_data);
 
1163
}
 
1164
 
 
1165
/* ARGSUSED */
 
1166
static void
 
1167
DropTransferProc(Widget w, 
 
1168
                 XtPointer closure, 
 
1169
                 XmSelectionCallbackStruct *ds)
 
1170
{
 
1171
  enum { XmACOMPOUND_TEXT, XmANULL, XmADELETE,
 
1172
#ifdef UTF8_SUPPORTED
 
1173
  XmAUTF8_STRING,
 
1174
#endif
 
1175
  NUM_ATOMS };
 
1176
  static char *atom_names[] = { XmSCOMPOUND_TEXT, XmSNULL, XmSDELETE,
 
1177
#ifdef UTF8_SUPPORTED
 
1178
      XmSUTF8_STRING
 
1179
#endif
 
1180
      };
 
1181
 
 
1182
  _XmTextDropTransferRec *transfer_rec = (_XmTextDropTransferRec *) closure;
 
1183
  XmTextWidget tw = (XmTextWidget) transfer_rec->widget;
 
1184
  InputData data = tw->text.input->data;
 
1185
  Atom atoms[XtNumber(atom_names)];
 
1186
  Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
1187
  XmTextPosition insertPosLeft, insertPosRight, left, right, cursorPos;
 
1188
  XmTextBlockRec block, newblock;
 
1189
  XmTextSource source = GetSrc((Widget)tw);
 
1190
  int max_length = 0;
 
1191
  Boolean local = _XmStringSourceHasSelection(source);
 
1192
  char * total_value = NULL;
 
1193
  Boolean pendingoff;
 
1194
  Boolean freeBlock;
 
1195
  
 
1196
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
1197
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
1198
 
 
1199
  /* When type = NULL, we are assuming a DELETE request has been requested */
 
1200
  if (ds->type == atoms[XmANULL]) {
 
1201
    if (transfer_rec->num_chars > 0 && transfer_rec->move) {
 
1202
      data->anchor = transfer_rec->insert_pos;
 
1203
      cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
 
1204
      _XmTextSetCursorPosition((Widget)tw, cursorPos);
 
1205
      _XmTextSetDestinationSelection((Widget)tw, tw->text.cursor_position,
 
1206
                                     False, 
 
1207
                                     XtLastTimestampProcessed(XtDisplay(w)));
 
1208
      (*tw->text.source->SetSelection)(tw->text.source, data->anchor,
 
1209
                                       tw->text.cursor_position,
 
1210
                                       XtLastTimestampProcessed(XtDisplay(w)));
 
1211
      if (ds->value) {
 
1212
        XtFree((char *) ds->value);
 
1213
        ds->value = NULL;
 
1214
      }
 
1215
      return;
 
1216
    }
 
1217
  }
 
1218
  
 
1219
  if (!ds->value || 
 
1220
      (ds->type != atoms[XmACOMPOUND_TEXT] && 
 
1221
#ifdef UTF8_SUPPORTED
 
1222
       ds->type != atoms[XmAUTF8_STRING] && 
 
1223
#endif
 
1224
       ds->type != CS_OF_ENCODING &&
 
1225
       ds->type != XA_STRING)) {
 
1226
    XmTransferDone(ds->transfer_id, XmTRANSFER_DONE_FAIL);
 
1227
    if (ds->value) {
 
1228
      XtFree((char*) ds->value);
 
1229
      ds->value = NULL;
 
1230
    }
 
1231
    return;
 
1232
  }
 
1233
  
 
1234
  insertPosLeft = insertPosRight = transfer_rec->insert_pos;
 
1235
  
 
1236
  if (ds->type == XA_STRING || ds->type == atoms[XmACOMPOUND_TEXT]
 
1237
#ifdef UTF8_SUPPORTED
 
1238
      || ds->type == atoms[XmAUTF8_STRING]
 
1239
#endif
 
1240
  ) {
 
1241
    if ((total_value = _XmTextToLocaleText(w, ds->value, ds->type, 
 
1242
                                           8, ds->length, NULL)) != NULL) {
 
1243
      block.ptr = total_value;
 
1244
      block.length = strlen(block.ptr);
 
1245
    } else {
 
1246
      if (ds->value) {
 
1247
        XtFree((char*) ds->value);
 
1248
        ds->value = NULL;
 
1249
      }
 
1250
      return;
 
1251
    }
 
1252
  } else {
 
1253
    block.ptr = (char *) ds->value;
 
1254
    block.length = (int) ds->length; /* NOTE: this causes a truncation on
 
1255
                                          some architectures */
 
1256
  }
 
1257
  
 
1258
  block.format = XmFMT_8_BIT;
 
1259
  
 
1260
  if (data->pendingdelete && 
 
1261
      (*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
 
1262
      (left != right)){
 
1263
    if(insertPosLeft > left && insertPosLeft < right) insertPosLeft = left;
 
1264
    if(insertPosRight < right && insertPosRight > left) insertPosRight = right;
 
1265
  }
 
1266
  
 
1267
  if (transfer_rec->move && local) {
 
1268
    max_length = _XmStringSourceGetMaxLength(source);
 
1269
    _XmStringSourceSetMaxLength(source, INT_MAX);
 
1270
  }
 
1271
  
 
1272
  /* The on_or_off flag is set to prevent unecessary
 
1273
     cursor shifting during the Replace operation */
 
1274
  tw->text.on_or_off = off;
 
1275
 
 
1276
  pendingoff = tw->text.pendingoff;
 
1277
  tw->text.pendingoff = FALSE;
 
1278
  
 
1279
  if (_XmTextModifyVerify(tw, ds->event, &insertPosLeft, &insertPosRight,
 
1280
                          &cursorPos, &block, &newblock, &freeBlock)) {
 
1281
    if ((*tw->text.source->Replace)(tw, ds->event, 
 
1282
                                    &insertPosLeft, &insertPosRight,
 
1283
                                    &newblock, False) != EditDone) {
 
1284
      if (tw->text.verify_bell) XBell(XtDisplay(tw), 0);
 
1285
      tw->text.pendingoff = pendingoff;
 
1286
    } else {
 
1287
      transfer_rec->num_chars = _XmTextCountCharacters(newblock.ptr,
 
1288
                                                       newblock.length);
 
1289
      if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
 
1290
        _XmTextSetCursorPosition((Widget)tw, cursorPos);
 
1291
        _XmTextSetDestinationSelection((Widget)tw,
 
1292
                                       tw->text.cursor_position,False,
 
1293
                                       transfer_rec->timestamp);
 
1294
      }
 
1295
      if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
 
1296
        if (transfer_rec->move && left < insertPosLeft)
 
1297
          transfer_rec->insert_pos = insertPosLeft -
 
1298
            transfer_rec->num_chars;
 
1299
        if (cursorPos < left || cursorPos > right)
 
1300
          tw->text.pendingoff = TRUE;
 
1301
      } else {
 
1302
        if (!transfer_rec->move && !tw->text.add_mode &&
 
1303
            transfer_rec->num_chars != 0)
 
1304
          data->anchor = insertPosLeft;
 
1305
      }
 
1306
      if (transfer_rec->move) {
 
1307
        XmTransferValue(ds->transfer_id, 
 
1308
                        atoms[XmADELETE],
 
1309
                        (XtCallbackProc) DropTransferProc, 
 
1310
                        (XtPointer) transfer_rec, 0);
 
1311
      }
 
1312
      
 
1313
      if (transfer_rec->move && local) {
 
1314
        _XmStringSourceSetMaxLength(source, max_length);
 
1315
      }
 
1316
 
 
1317
      _XmTextValueChanged(tw, (XEvent *) ds->event);
 
1318
    }
 
1319
    if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
 
1320
  } else {
 
1321
    if (tw->text.verify_bell) XBell(XtDisplay(tw), 0);
 
1322
    tw->text.pendingoff = pendingoff;
 
1323
  }
 
1324
  tw->text.on_or_off = on;
 
1325
 
 
1326
  if (total_value) XtFree(total_value);
 
1327
  if (ds->value != NULL) XtFree((char*) ds->value);
 
1328
  ds->value = NULL;
 
1329
}
 
1330
 
 
1331
static void
 
1332
SetDropContext(Widget w)
 
1333
{
 
1334
  Display *display = XtDisplay(w);
 
1335
  Screen  *screen = XtScreen(w);
 
1336
  XContext loc_context;
 
1337
 
 
1338
  _XmProcessLock();
 
1339
  if (_XmTextDNDContext == 0)
 
1340
        _XmTextDNDContext = XUniqueContext();
 
1341
  loc_context = _XmTextDNDContext;
 
1342
  _XmProcessUnlock();
 
1343
 
 
1344
  XSaveContext(display, (Window)screen,
 
1345
               loc_context, (XPointer)w);
 
1346
}
 
1347
 
 
1348
 
 
1349
static void
 
1350
DeleteDropContext(Widget w)
 
1351
{
 
1352
  Display *display = XtDisplay(w);
 
1353
  Screen  *screen = XtScreen(w);
 
1354
 
 
1355
  _XmProcessLock();
 
1356
  XDeleteContext(display, (Window)screen, _XmTextDNDContext);
 
1357
  _XmProcessUnlock();
 
1358
}
 
1359
 
 
1360
 
 
1361
Widget
 
1362
_XmTextGetDropReciever(Widget w)
 
1363
{
 
1364
  Display *display = XtDisplay(w);
 
1365
  Screen  *screen = XtScreen(w);
 
1366
  Widget widget;
 
1367
  XContext loc_context;
 
1368
 
 
1369
  _XmProcessLock();
 
1370
  loc_context = _XmTextDNDContext;
 
1371
  _XmProcessUnlock();
 
1372
  if (loc_context == 0) return NULL;
 
1373
  
 
1374
  if (!XFindContext(display, (Window)screen,
 
1375
                    loc_context, (char **) &widget)) {
 
1376
    return widget;
 
1377
  }
 
1378
  
 
1379
  return NULL;
 
1380
}
 
1381
 
 
1382
 
 
1383
 
 
1384
/********************************************
 
1385
 * Transfer trait method implementation 
 
1386
 ********************************************/
 
1387
 
 
1388
/*ARGSUSED*/
 
1389
static void
 
1390
TextConvertCallback(Widget w, 
 
1391
                    XtPointer ignore, /* unused */
 
1392
                    XmConvertCallbackStruct *cs)
 
1393
{
 
1394
  enum { XmADELETE, XmA_MOTIF_LOSE_SELECTION,
 
1395
         XmA_MOTIF_EXPORT_TARGETS, XmATEXT, XmACOMPOUND_TEXT,
 
1396
         XmATARGETS, XmA_MOTIF_CLIPBOARD_TARGETS, XmACLIPBOARD,
 
1397
#ifdef UTF8_SUPPORTED
 
1398
         XmAUTF8_STRING,
 
1399
#endif
 
1400
         NUM_ATOMS };
 
1401
  static char *atom_names[] = { XmSDELETE, XmS_MOTIF_LOSE_SELECTION,
 
1402
         XmS_MOTIF_EXPORT_TARGETS, XmSTEXT, XmSCOMPOUND_TEXT,
 
1403
         XmSTARGETS, XmS_MOTIF_CLIPBOARD_TARGETS, XmSCLIPBOARD,
 
1404
#ifdef UTF8_SUPPORTED
 
1405
         XmSUTF8_STRING
 
1406
#endif
 
1407
         };
 
1408
 
 
1409
  Atom XA_CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
1410
  XtPointer value;
 
1411
  Atom type;
 
1412
  unsigned long size;
 
1413
  int format;
 
1414
  Atom atoms[XtNumber(atom_names)];
 
1415
  
 
1416
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
1417
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
1418
 
 
1419
  value = NULL;
 
1420
 
 
1421
  if (cs->target == atoms[XmA_MOTIF_LOSE_SELECTION]) {
 
1422
    _XmTextLoseSelection(w, &(cs->selection));
 
1423
    cs->status = XmCONVERT_DONE;
 
1424
    return;
 
1425
  }
 
1426
  
 
1427
  if (cs->target == atoms[XmADELETE] &&
 
1428
      cs->selection == XA_SECONDARY) {
 
1429
    _XmTextHandleSecondaryFinished(w, cs->event);
 
1430
    cs->status = XmCONVERT_DONE;
 
1431
    return;
 
1432
  }
 
1433
  
 
1434
  /* When this is called as a result of a clipboard copy link,  we
 
1435
     don't have any available targets.  Make sure to return immediately
 
1436
     without modification */
 
1437
  if (cs->selection == atoms[XmACLIPBOARD] &&
 
1438
      cs->parm == (XtPointer) XmLINK &&
 
1439
      (cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS] ||
 
1440
       cs->target == atoms[XmATARGETS])) return;
 
1441
  
 
1442
  if (!_XmTextConvert(w, &cs->selection, &cs->target,
 
1443
                      &type, &value, &size, &format,
 
1444
                      (Widget) cs->source_data, cs->event)) {
 
1445
    value = NULL;
 
1446
    type = XA_INTEGER;
 
1447
    size = 0;
 
1448
    format = 8;
 
1449
  }
 
1450
  
 
1451
  if (cs->target == atoms[XmADELETE]) {
 
1452
    cs->status = XmCONVERT_DONE;
 
1453
    cs->type = type;
 
1454
    cs->value = value;
 
1455
    cs->length = size;
 
1456
    cs->format = format;
 
1457
    return;
 
1458
  }
 
1459
  
 
1460
  if (cs->target == atoms[XmA_MOTIF_EXPORT_TARGETS] ||
 
1461
      cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS]) {
 
1462
    Atom *targs = (Atom *) XtMalloc(sizeof(Atom) * 5);
 
1463
    int n = 0;
 
1464
    
 
1465
    value = (XtPointer) targs;
 
1466
#ifdef UTF8_SUPPORTED
 
1467
    targs[n] = atoms[XmAUTF8_STRING]; n++;
 
1468
#endif
 
1469
    targs[n] = atoms[XmACOMPOUND_TEXT]; n++;
 
1470
    targs[n] = atoms[XmATEXT]; n++;
 
1471
    targs[n] = XA_STRING; n++;
 
1472
    if (XA_CS_OF_ENCODING != XA_STRING) {
 
1473
      targs[n] = XA_CS_OF_ENCODING; n++;
 
1474
    }
 
1475
    format = 32;
 
1476
    size = n;
 
1477
    type = XA_ATOM;
 
1478
  }
 
1479
  
 
1480
  _XmConvertComplete(w, value, size, format, type, cs);
 
1481
}
 
1482
 
 
1483
/************************************************
 
1484
 * Free data allocated for destination callback 
 
1485
 ************************************************/
 
1486
 
 
1487
/*ARGSUSED*/
 
1488
static void
 
1489
FreeLocationData(Widget w,     /* unused */
 
1490
                 XtEnum op,    /* unused */
 
1491
                 XmTransferDoneCallbackStruct *ts) 
 
1492
{
 
1493
  XmDestinationCallbackStruct *ds;
 
1494
 
 
1495
  ds = _XmTransferGetDestinationCBStruct(ts->transfer_id);
 
1496
 
 
1497
  XtFree((char*) ds->location_data);
 
1498
 
 
1499
  ds->location_data = NULL;
 
1500
}
 
1501
 
 
1502
/*ARGSUSED*/
 
1503
static void 
 
1504
TextDestinationCallback(Widget w, 
 
1505
                        XtPointer closure, /* unused */
 
1506
                        XmDestinationCallbackStruct *ds)
 
1507
{
 
1508
  enum { XmATARGETS, XmA_MOTIF_DROP, NUM_ATOMS };
 
1509
  static char *atom_names[] = { XmSTARGETS, XmS_MOTIF_DROP };
 
1510
 
 
1511
  Atom atoms[XtNumber(atom_names)];
 
1512
  XPoint DropPoint;
 
1513
 
 
1514
  assert(XtNumber(atom_names) == NUM_ATOMS);
 
1515
  XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
1516
 
 
1517
  /*
 
1518
   ** In case of a primary transfer operation where a location_data
 
1519
   ** has been allocated, register a done proc to be called when 
 
1520
   ** the data transfer is complete to free the location_data
 
1521
   */
 
1522
  if (ds->selection == XA_PRIMARY && ds->location_data)
 
1523
      XmeTransferAddDoneProc(ds->transfer_id, FreeLocationData);
 
1524
 
 
1525
  /* If we aren't sensitive,  don't allow transfer */
 
1526
  if (! w -> core.sensitive ||
 
1527
      ! w -> core.ancestor_sensitive) 
 
1528
    XmTransferDone(ds -> transfer_id, XmTRANSFER_DONE_FAIL);
 
1529
 
 
1530
  /* We don't handle LINKs internally */
 
1531
  if (ds->operation == XmLINK) return;
 
1532
  
 
1533
  if (ds->selection == XA_PRIMARY && ds->operation == XmMOVE)
 
1534
    XmeTransferAddDoneProc(ds->transfer_id, SetPrimarySelection);
 
1535
  else
 
1536
    XmeTransferAddDoneProc(ds->transfer_id, CleanPrimarySelection);
 
1537
     
 
1538
  if (ds->selection == atoms[XmA_MOTIF_DROP]) {
 
1539
    XmDropProcCallbackStruct *cb = 
 
1540
      (XmDropProcCallbackStruct *) ds->destination_data;
 
1541
    
 
1542
    DropPoint.x = cb->x;
 
1543
    DropPoint.y = cb->y;
 
1544
    
 
1545
    ds->location_data = (XtPointer) &DropPoint;
 
1546
    
 
1547
    if (cb->dropAction != XmDROP_HELP) {
 
1548
      HandleDrop(w, cb, ds);
 
1549
    }
 
1550
  }
 
1551
  else if (ds->selection == XA_SECONDARY) {
 
1552
    Atom CS_OF_ENCODING;
 
1553
    
 
1554
    CS_OF_ENCODING = XmeGetEncodingAtom(w);
 
1555
 
 
1556
    _XmProcessLock();
 
1557
    insert_select.done_status = False;
 
1558
    insert_select.success_status = False;
 
1559
    insert_select.event = (XSelectionRequestEvent *) ds->event;
 
1560
    insert_select.select_type = XmDEST_SELECT;
 
1561
    
 
1562
    if (((Atom) ds->location_data) != CS_OF_ENCODING) {
 
1563
      /*
 
1564
       * Make selection request to find out which targets
 
1565
       * the selection can provide.
 
1566
       */
 
1567
      XmTransferValue(ds->transfer_id, atoms[XmATARGETS], 
 
1568
                      (XtCallbackProc) TextSecondaryWrapper,
 
1569
                      (XtPointer) &insert_select, ds->time);
 
1570
    } else {
 
1571
      /*
 
1572
       * Make selection request to replace the selection
 
1573
       * with the insert selection.
 
1574
       */
 
1575
      XmTransferValue(ds->transfer_id, ((Atom) ds->location_data),
 
1576
                      (XtCallbackProc) TextSecondaryWrapper,
 
1577
                      (XtPointer) &insert_select, ds->time);
 
1578
    }
 
1579
    _XmProcessUnlock();
 
1580
  } else 
 
1581
    /* CLIPBOARD or PRIMARY */
 
1582
    XmTransferValue(ds->transfer_id, atoms[XmATARGETS],
 
1583
                    (XtCallbackProc) HandleTargets, 
 
1584
                    ds->location_data, ds->time);
 
1585
}
 
1586
 
 
1587
void
 
1588
_XmTextInstallTransferTrait(void)
 
1589
{
 
1590
  XmeTraitSet((XtPointer)xmTextWidgetClass, XmQTtransfer, 
 
1591
              (XtPointer) &TextTransfer);
 
1592
}