1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <limits.h>
32 #include <Xm/XmosP.h>
33 #include <X11/Xatom.h>
34 #include <X11/ShellP.h>
35 #include <X11/VendorP.h>
36 #include <X11/keysym.h>
37 #include <X11/Xresource.h>
38 #include "XmI.h"
39 #include <Xm/AtomMgr.h>
40 #include <Xm/CutPaste.h>
41 #include <Xm/DragC.h>
42 #include <Xm/DragIcon.h>
43 #include <Xm/DropSMgr.h>
44 #include <Xm/DropTrans.h>
45 #include <Xm/Display.h>
46 #include <Xm/ManagerP.h>
47 #include <Xm/ScreenP.h>
48 #include <Xm/DragIconP.h>
49 #include <Xm/TransltnsP.h>
50 #include <Xm/DrawP.h>
51 
52 #include <Xm/Ext.h>
53 #include <Xm/DataFSelP.h>
54 #include <Xm/DataFP.h>
55 
56 #include <Xm/TraitP.h>
57 #include <Xm/AccTextT.h>
58 #include <Xm/TransferT.h>
59 #include <Xm/SpecRenderT.h>
60 #include <Xm/VaSimpleP.h>
61 
62 #include "TextFI.h"
63 #include "TextFSelI.h"
64 #include "XmStringI.h"
65 #include "ImageCachI.h"
66 
67 #ifdef USE_XFT
68 #include <X11/Xft/Xft.h>
69 #include "XmRenderTI.h"
70 #endif
71 
72 
73 #include "MessagesI.h"
74 
75 #define FIX_1531
76 /*
77  * Stuff from various internal motif headers that we need to declare
78  */
79 
80 #ifndef MAX
81 #define MAX(x,y)	((x) > (y) ? (x) : (y))
82 #endif
83 
84 #define TEXT_MAX_INSERT_SIZE 64    /* Size of buffer for XLookupString. */
85 /*
86  * Various DataField messages macro
87  */
88 #define MSG1	        _XmMMsgDataF_0000
89 #define MSG2	        _XmMMsgDataF_0001
90 #define MSG3	        _XmMMsgDataF_0002
91 #define MSG4	        _XmMMsgDataF_0003
92 #define MSG5	        _XmMMsgDataF_0004
93 #define MSG6	        _XmMMsgDataF_0005
94 #define MSG7	        _XmMMsgDataF_0006
95 #define WC_MSG1	        _XmMMsgDataFWcs_0000
96 #define WC_MSG2	        _XmMMsgDataFWcs_0001
97 #define GRABKBDERROR	_XmMMsgRowColText_0024
98 
99 #ifdef _XmConst
100        #undef _XmConst
101        #define _XmConst
102 #else
103        #define _XmConst
104 #endif
105 
106 #ifdef _NO_PROTO
107 extern Boolean _XmParentProcess();
108 extern Boolean _XmMgrTraversal();
109 extern unsigned char _XmGetFocusPolicy();
110 extern void _XmPrimitiveFocusIn();
111 extern void _XmPrimitiveEnter();
112 extern void _XmPrimitiveLeave();
113 extern Boolean _XmGetImage();
114 extern Boolean _XmGetIconControlInfo();
115 extern unsigned char _XmGetAudibleWarning();
116 extern void _XmSetDestination();
117 #else
118 extern Boolean _XmParentProcess(Widget, XmParentProcessData);
119 extern Boolean _XmMgrTraversal(Widget, XmTraversalDirection);
120 extern unsigned char _XmGetFocusPolicy(Widget);
121 extern void _XmPrimitiveFocusIn(Widget, XEvent *, String *, Cardinal *);
122 extern void _XmPrimitiveEnter(Widget, XEvent *, String *, Cardinal *);
123 extern void _XmPrimitiveLeave(Widget, XEvent *, String *, Cardinal *);
124 extern Boolean _XmGetImage(Screen *, char *, XImage **);
125 extern Boolean _XmGetIconControlInfo(
126                         Screen *screen,
127                         Boolean *useMaskRtn,
128                         Boolean *useMultiColorIconsRtn,
129                         Boolean *useIconFileCacheRtn) ;
130 extern unsigned char _XmGetAudibleWarning(Widget);
131 extern void _XmSetDestination(Display *, Widget);
132 #endif
133 
134 /*
135  * Back to the original XmTextField code
136  */
137 #define TEXT_INCREMENT 32
138 #define PRIM_SCROLL_INTERVAL 100
139 #define SEC_SCROLL_INTERVAL 200
140 #define XmDYNAMIC_BOOL 255
141 
142 #define EventBindings1  _XmDataF_EventBindings1
143 #define EventBindings2  _XmDataF_EventBindings2
144 #define EventBindings3  _XmDataF_EventBindings3
145 #define EventBindings4  _XmDataF_EventBindings4
146 
147 typedef struct {
148     Boolean has_destination;
149     XmTextPosition position;
150     int replace_length;
151     Boolean quick_key;
152 } TextFDestDataRec, *TextFDestData;
153 
154 typedef struct {
155     XmDataFieldWidget tf;
156 } TextFGCDataRec, *TextFGCData;
157 
158 
159 /********    Static Function Declarations    ********/
160 #ifdef _NO_PROTO
161 
162 static void df_ValidateAndMove() ;
163 static int _XmDataFieldCountCharacters() ;
164 static void df_MakeCopy() ;
165 static void df_WcsMakeCopy() ;
166 static void df_FreeContextData() ;
167 static TextFDestData df_GetTextFDestData() ;
168 static void df_SetDropContext() ;
169 static void df_DeleteDropContext() ;
170 static TextFGCData df_GetTextFGCData() ;
171 static _XmHighlightRec * df_FindHighlight() ;
172 static void df_InsertHighlight() ;
173 static void DataFieldSetHighlight() ;
174 static Boolean df_GetXYFromPos() ;
175 static Boolean df_CurrentCursorState() ;
176 static void df_PaintCursor() ;
177 static int _XmGetImage();
178 static void df_BlinkInsertionPoint() ;
179 static void df_HandleTimer() ;
180 static void df_ChangeBlinkBehavior() ;
181 static void df_GetRect() ;
182 static void df_CheckHasRect() ;
183 static void df_XmSetFullGC() ;
184 static void df_XmSetMarginGC() ;
185 static void df_XmResetSaveGC() ;
186 static void df_XmSetNormGC() ;
187 #ifdef FIX_1381
188 static void df_XmSetShadowGC() ;
189 #endif
190 static void df_XmSetInvGC() ;
191 static void df_DrawText() ;
192 static int df_FindPixelLength() ;
193 static void df_DrawTextSegment() ;
194 static void df_RedisplayText() ;
195 static void df_ComputeSize() ;
196 static XtGeometryResult df_TryResize() ;
197 static Boolean df_AdjustText() ;
198 static void df_AdjustSize() ;
199 static Boolean df_ModifyVerify() ;
200 static void df_ResetClipOrigin() ;
201 static void df_InvertImageGC() ;
202 static void df_ResetImageGC() ;
203 static void df_SetCursorPosition() ;
204 static void df_VerifyBounds() ;
205 static XmTextPosition df_GetPosFromX() ;
206 static XmTextPosition RightAlignedGetPosFromX() ;
207 static Boolean df_SetDestination() ;
208 static Boolean df_VerifyLeave() ;
209 static Boolean _XmDataFieldIsWordBoundary() ;
210 static int _XmGetImage(Screen *, char *, XImage **);
211 static Boolean _XmDataFieldIsWSpace() ;
212 static void df_FindWord() ;
213 static void df_FindPrevWord() ;
214 static void df_FindNextWord() ;
215 static void df_CheckDisjointSelection() ;
216 static Boolean df_NeedsPendingDelete() ;
217 static Boolean df_NeedsPendingDeleteDisjoint() ;
218 static Time df_GetServerTime() ;
219 static void df_InsertChar() ;
220 static void df_InsertString() ;
221 static void df_DeletePrevChar() ;
222 static void df_DeleteNextChar() ;
223 static void df_DeletePrevWord() ;
224 static void df_DeleteNextWord() ;
225 static void df_DeleteToEndOfLine() ;
226 static void df_DeleteToStartOfLine() ;
227 static void df_ProcessCancel() ;
228 static void df_Activate() ;
229 static void df_SetAnchorBalancing() ;
230 static void df_SetNavigationAnchor() ;
231 static void df_CompleteNavigation() ;
232 static void df_SimpleMovement() ;
233 static void df_BackwardChar() ;
234 static void df_ForwardChar() ;
235 static void df_BackwardWord() ;
236 static void df_ForwardWord() ;
237 static void df_EndOfLine() ;
238 static void df_BeginningOfLine() ;
239 static void df_SetSelection() ;
240 static void df_ProcessHorizontalParams() ;
241 static void df_ProcessSelectParams() ;
242 static void df_KeySelection() ;
243 static void df_TextFocusIn() ;
244 static void df_TextFocusOut() ;
245 static void df_SetScanIndex() ;
246 static void df_ExtendScanSelection() ;
247 static void df_SetScanSelection() ;
248 static void df_StartPrimary() ;
249 static void df_MoveDestination() ;
250 static void df_ExtendPrimary() ;
251 static void df_ExtendEnd() ;
252 static void df_DoExtendedSelection() ;
253 static void df_DoSecondaryExtend() ;
254 static void df_BrowseScroll() ;
255 static Boolean df_CheckTimerScrolling() ;
256 static void df_RestorePrimaryHighlight() ;
257 static void df_StartDrag() ;
258 static void df_StartSecondary() ;
259 static void df_ProcessBDrag() ;
260 static void df_ExtendSecondary() ;
261 static void df_DoStuff() ;
262 static void df_Stuff() ;
263 static void df_HandleSelectionReplies() ;
264 static void df_SecondaryNotify() ;
265 static void df_HandleTargets() ;
266 static void df_ProcessBDragRelease() ;
267 static void df_ProcessCopy() ;
268 static void df_ProcessMove() ;
269 static void df_DeleteSelection() ;
270 static void df_ClearSelection() ;
271 static void df_PageRight() ;
272 static void df_PageLeft() ;
273 static void df_CopyPrimary() ;
274 static void df_CutPrimary() ;
275 static void df_SetAnchor() ;
276 static void df_ToggleOverstrike() ;
277 static void df_ToggleAddMode() ;
278 static void df_SelectAll() ;
279 static void df_DeselectAll() ;
280 static void df_VoidAction() ;
281 static void df_CutClipboard() ;
282 static void df_CopyClipboard() ;
283 static void df_PasteClipboard() ;
284 static void df_TraverseDown() ;
285 static void df_TraverseUp() ;
286 static void df_TraverseHome() ;
287 static void df_TraverseNextTabGroup() ;
288 static void df_TraversePrevTabGroup() ;
289 static void df_TextEnter() ;
290 static void df_TextLeave() ;
291 static void df_ClassPartInitialize() ;
292 static void df_Validates() ;
293 static Boolean df_LoadFontMetrics() ;
294 static void df_ValidateString() ;
295 static void df_InitializeTextStruct() ;
296 static Pixmap df_GetClipMask() ;
297 static void df_LoadGCs() ;
298 static void df_MakeIBeamOffArea() ;
299 static void df_MakeIBeamStencil() ;
300 static void df_MakeAddModeCursor() ;
301 static void df_MakeCursors() ;
302 static void df_DropDestroyCB() ;
303 static void df_DropTransferCallback() ;
304 static void df_HandleDrop() ;
305 static void df_DragProcCallback() ;
306 static void df_DropProcCallback() ;
307 static void df_RegisterDropSite() ;
308 static void df_Initialize() ;
309 static void df_Realize() ;
310 static void df_Destroy() ;
311 static void df_Resize() ;
312 static XtGeometryResult df_QueryGeometry() ;
313 static void DataFieldExpose() ;
314 static Boolean df_SetValues() ;
315 static Boolean DataFieldGetBaselines() ;
316 static Boolean DataFieldGetDisplayRect() ;
317 static void DataFieldMarginsProc() ;
318 static Boolean DataFieldRemove();
319 static void PictureVerifyCallback();
320 static void ClassInit();
321 static void XmDataFieldSetStringWcs();
322 #else
323 static void df_ValidateAndMove(
324 			       Widget w,
325 			       XEvent *ev,
326 			       String *args,
327 			       Cardinal *nargs) ;
328 static int _XmDataFieldCountCharacters(
329                         XmDataFieldWidget tf,
330                         char *ptr,
331                         int n_bytes) ;
332 static void df_MakeCopy(
333                         Widget w,
334                         int n,
335                         XtArgVal *value) ;
336 static void df_WcsMakeCopy(
337                         Widget w,
338                         int n,
339                         XtArgVal *value) ;
340 static void df_FreeContextData(
341                         Widget w,
342                         XtPointer clientData,
343                         XtPointer callData) ;
344 static TextFDestData df_GetTextFDestData(
345                         Widget w) ;
346 static void df_SetDropContext(
347                         Widget w) ;
348 static void df_DeleteDropContext(
349                         Widget w) ;
350 static TextFGCData df_GetTextFGCData(
351                         Widget w) ;
352 static _XmHighlightRec * df_FindHighlight(
353                         XmDataFieldWidget w,
354                         XmTextPosition position) ;
355 static void df_InsertHighlight(
356                         XmDataFieldWidget w,
357                         XmTextPosition position,
358                         XmHighlightMode mode) ;
359 static void DataFieldSetHighlight(
360                         XmDataFieldWidget tf,
361                         XmTextPosition left,
362                         XmTextPosition right,
363                         XmHighlightMode mode) ;
364 static Boolean df_GetXYFromPos(
365                         XmDataFieldWidget tf,
366                         XmTextPosition position,
367                         Position *x,
368                         Position *y) ;
369 static Boolean df_CurrentCursorState(
370                         XmDataFieldWidget tf) ;
371 static void df_PaintCursor(
372                         XmDataFieldWidget tf) ;
373 static void df_BlinkInsertionPoint(
374                         XmDataFieldWidget tf) ;
375 static void df_HandleTimer(
376                         XtPointer closure,
377                         XtIntervalId *id) ;
378 
379 static void df_ChangeBlinkBehavior(
380                         XmDataFieldWidget tf,
381 #if NeedWidePrototypes
382                         int turn_on) ;
383 #else
384                         Boolean turn_on) ;
385 #endif /* NeedWidePrototypes */
386 
387 static void df_GetRect(
388                         XmDataFieldWidget tf,
389                         XRectangle *rect) ;
390 static void df_CheckHasRect(
391                         XmDataFieldWidget tf) ;
392 static void df_XmSetFullGC(
393                         XmDataFieldWidget tf,
394                         GC gc) ;
395 static void df_XmSetMarginGC(
396                         XmDataFieldWidget tf,
397                         GC gc) ;
398 static void df_XmResetSaveGC(
399                         XmDataFieldWidget tf,
400                         GC gc) ;
401 static void df_XmSetNormGC(
402                         XmDataFieldWidget tf,
403                         GC gc,
404 #if NeedWidePrototypes
405                         int change_stipple,
406                         int stipple) ;
407 #else
408                         Boolean change_stipple,
409                         Boolean stipple) ;
410 #endif /* NeedWidePrototypes */
411 
412 #ifdef FIX_1381
413 static void df_XmSetShadowGC(
414                         XmDataFieldWidget tf,
415                         GC gc);
416 #endif
417 
418 static void df_XmSetInvGC(
419                         XmDataFieldWidget tf,
420                         GC gc) ;
421 static void df_DrawText(
422                         XmDataFieldWidget tf,
423                         GC gc,
424                         int x,
425                         int y,
426                         char *string,
427                         int length) ;
428 static int df_FindPixelLength(
429                         XmDataFieldWidget tf,
430                         char *string,
431                         int length) ;
432 
433 static void df_DrawTextSegment(
434                         XmDataFieldWidget tf,
435                         XmHighlightMode mode,
436                         XmTextPosition prev_seg_start,
437                         XmTextPosition seg_start,
438                         XmTextPosition seg_end,
439                         XmTextPosition next_seg,
440 #if NeedWidePrototypes
441                         int stipple,
442 #else
443                         Boolean stipple,
444 #endif /* NeedWidePrototypes */
445                         int y,
446                         int *x) ;
447 
448 static void df_RedisplayText(
449                         XmDataFieldWidget tf,
450                         XmTextPosition start,
451                         XmTextPosition end) ;
452 static void df_ComputeSize(
453                         XmDataFieldWidget tf,
454                         Dimension *width,
455                         Dimension *height) ;
456 
457 static XtGeometryResult df_TryResize(
458                         XmDataFieldWidget tf,
459 #if NeedWidePrototypes
460                         int width,
461                         int height) ;
462 #else
463                         Dimension width,
464                         Dimension height) ;
465 #endif /* NeedWidePrototypes */
466 
467 static Boolean df_AdjustText(
468                         XmDataFieldWidget tf,
469                         XmTextPosition position,
470 #if NeedWidePrototypes
471                         int flag) ;
472 #else
473                         Boolean flag) ;
474 #endif /* NeedWidePrototypes */
475 
476 static void df_AdjustSize(
477                         XmDataFieldWidget tf) ;
478 static Boolean df_ModifyVerify(
479                         XmDataFieldWidget tf,
480                         XEvent *event,
481                         XmTextPosition *replace_prev,
482                         XmTextPosition *replace_next,
483                         char **insert,
484                         int *insert_length,
485 			XmTextPosition *newInsert,
486 			int *free_insert) ;
487 
488 static void df_ResetClipOrigin(
489                         XmDataFieldWidget tf,
490 #if NeedWidePrototypes
491                         int clip_mask_reset) ;
492 #else
493                         Boolean clip_mask_reset) ;
494 #endif /* NeedWidePrototypes */
495 
496 static void df_InvertImageGC(
497                         XmDataFieldWidget tf) ;
498 static void df_ResetImageGC(
499                         XmDataFieldWidget tf) ;
500 static void df_SetCursorPosition(
501                         XmDataFieldWidget tf,
502                         XEvent *event,
503                         XmTextPosition position,
504 #if NeedWidePrototypes
505                         int adjust_flag,
506                         int call_cb,
507 			int set_dest) ;
508 #else
509                         Boolean adjust_flag,
510                         Boolean call_cb,
511                         Boolean set_dest) ;
512 #endif /* NeedWidePrototypes */
513 
514 static void df_VerifyBounds(
515                         XmDataFieldWidget tf,
516                         XmTextPosition *from,
517                         XmTextPosition *to) ;
518 static XmTextPosition df_GetPosFromX(
519                         XmDataFieldWidget tf,
520 #if NeedWidePrototypes
521                         int x) ;
522 #else
523                         Position x) ;
524 #endif /* NeedWidePrototypes */
525 
526 static XmTextPosition RightAlignedGetPosFromX(
527                         XmDataFieldWidget tf,
528 #if NeedWidePrototypes
529                         int x) ;
530 #else
531                         Position x) ;
532 #endif /* NeedWidePrototypes */
533 
534 static Boolean df_SetDestination(
535                         Widget w,
536                         XmTextPosition position,
537 
538 #if NeedWidePrototypes
539                         int disown,
540 #else
541                         Boolean disown,
542 #endif /* NeedWidePrototypes */
543                         Time set_time) ;
544 
545 static Boolean df_VerifyLeave(
546                         XmDataFieldWidget tf,
547                         XEvent *event) ;
548 static Boolean _XmDataFieldIsWordBoundary(
549                         XmDataFieldWidget tf,
550                         XmTextPosition pos1,
551                         XmTextPosition pos2) ;
552 static Boolean _XmDataFieldIsWSpace(
553                         wchar_t wide_char,
554                         wchar_t *white_space,
555                         int num_entries) ;
556 static void df_FindWord(
557                         XmDataFieldWidget tf,
558                         XmTextPosition begin,
559                         XmTextPosition *left,
560                         XmTextPosition *right) ;
561 static void df_FindPrevWord(
562                         XmDataFieldWidget tf,
563                         XmTextPosition *left,
564                         XmTextPosition *right) ;
565 static void df_FindNextWord(
566                         XmDataFieldWidget tf,
567                         XmTextPosition *left,
568                         XmTextPosition *right) ;
569 static void df_CheckDisjointSelection(
570                         Widget w,
571                         XmTextPosition position,
572                         Time sel_time) ;
573 static Boolean df_NeedsPendingDelete(
574                         XmDataFieldWidget tf) ;
575 static Boolean df_NeedsPendingDeleteDisjoint(
576                         XmDataFieldWidget tf) ;
577 static Time df_GetServerTime(
578                         Widget w) ;
579 static void df_InsertChar(
580                         Widget w,
581                         XEvent *event,
582                         char **params,
583                         Cardinal *num_params) ;
584 static void df_InsertString(
585                         Widget w,
586                         XEvent *event,
587                         char **params,
588                         Cardinal *num_params) ;
589 static void df_DeletePrevChar(
590                         Widget w,
591                         XEvent *event,
592                         char **params,
593                         Cardinal *num_params) ;
594 static void df_DeleteNextChar(
595                         Widget w,
596                         XEvent *event,
597                         char **params,
598                         Cardinal *num_params) ;
599 static void df_DeletePrevWord(
600                         Widget w,
601                         XEvent *event,
602                         char **params,
603                         Cardinal *num_params) ;
604 static void df_DeleteNextWord(
605                         Widget w,
606                         XEvent *event,
607                         char **params,
608                         Cardinal *num_params) ;
609 static void df_DeleteToEndOfLine(
610                         Widget w,
611                         XEvent *event,
612                         char **params,
613                         Cardinal *num_params) ;
614 static void df_DeleteToStartOfLine(
615                         Widget w,
616                         XEvent *event,
617                         char **params,
618                         Cardinal *num_params) ;
619 static void df_ProcessCancel(
620                         Widget w,
621                         XEvent *event,
622                         char **params,
623                         Cardinal *num_params) ;
624 static void df_Activate(
625                         Widget w,
626                         XEvent *event,
627                         char **params,
628                         Cardinal *num_params) ;
629 static void df_SetAnchorBalancing(
630                         XmDataFieldWidget tf,
631                         XmTextPosition position) ;
632 
633 static void df_SetNavigationAnchor(
634                         XmDataFieldWidget tf,
635                         XmTextPosition position,
636 #if NeedWidePrototypes
637                         int extend) ;
638 #else
639                         Boolean extend) ;
640 #endif /* NeedWidePrototypes */
641 
642 static void df_CompleteNavigation(
643                         XmDataFieldWidget tf,
644                         XEvent *event,
645                         XmTextPosition position,
646                         Time time,
647 #if NeedWidePrototypes
648                         int extend) ;
649 #else
650                         Boolean extend) ;
651 #endif /* NeedWidePrototypes */
652 
653 static void df_SimpleMovement(
654                         Widget w,
655                         XEvent *event,
656                         String *params,
657                         Cardinal *num_params,
658                         XmTextPosition cursorPos,
659                         XmTextPosition position) ;
660 static void df_BackwardChar(
661                         Widget w,
662                         XEvent *event,
663                         char **params,
664                         Cardinal *num_params) ;
665 static void df_ForwardChar(
666                         Widget w,
667                         XEvent *event,
668                         char **params,
669                         Cardinal *num_params) ;
670 static void df_BackwardWord(
671                         Widget w,
672                         XEvent *event,
673                         char **params,
674                         Cardinal *num_params) ;
675 static void df_ForwardWord(
676                         Widget w,
677                         XEvent *event,
678                         char **params,
679                         Cardinal *num_params) ;
680 static void df_EndOfLine(
681                         Widget w,
682                         XEvent *event,
683                         char **params,
684                         Cardinal *num_params) ;
685 static void df_BeginningOfLine(
686                         Widget w,
687                         XEvent *event,
688                         char **params,
689                         Cardinal *num_params) ;
690 
691 static void df_SetSelection(
692                         XmDataFieldWidget tf,
693                         XmTextPosition left,
694                         XmTextPosition right,
695 #if NeedWidePrototypes
696                         int redisplay) ;
697 #else
698                         Boolean redisplay) ;
699 #endif /* NeedWidePrototypes */
700 
701 static void df_ProcessHorizontalParams(
702                         Widget w,
703                         XEvent *event,
704                         char **params,
705                         Cardinal *num_params,
706                         XmTextPosition *left,
707                         XmTextPosition *right,
708                         XmTextPosition *position) ;
709 static void df_ProcessSelectParams(
710                         Widget w,
711                         XEvent *event,
712                         XmTextPosition *left,
713                         XmTextPosition *right,
714                         XmTextPosition *position) ;
715 static void df_KeySelection(
716                         Widget w,
717                         XEvent *event,
718                         char **params,
719                         Cardinal *num_params) ;
720 static void df_TextFocusIn(
721                         Widget w,
722                         XEvent *event,
723                         char **params,
724                         Cardinal *num_params) ;
725 static void df_TextFocusOut(
726                         Widget w,
727                         XEvent *event,
728                         char **params,
729                         Cardinal *num_params) ;
730 static void df_SetScanIndex(
731                         XmDataFieldWidget tf,
732                         XEvent *event) ;
733 static void df_ExtendScanSelection(
734                         XmDataFieldWidget tf,
735                         XEvent *event) ;
736 static void df_SetScanSelection(
737                         XmDataFieldWidget tf,
738                         XEvent *event) ;
739 static void df_StartPrimary(
740                         Widget w,
741                         XEvent *event,
742                         char **params,
743                         Cardinal *num_params) ;
744 static void df_MoveDestination(
745                         Widget w,
746                         XEvent *event,
747                         char **params,
748                         Cardinal *num_params) ;
749 static void df_ExtendPrimary(
750                         Widget w,
751                         XEvent *event,
752                         char **params,
753                         Cardinal *num_params) ;
754 static void df_ExtendEnd(
755                         Widget w,
756                         XEvent *event,
757                         char **params,
758                         Cardinal *num_params) ;
759 static void df_DoExtendedSelection(
760                         Widget w,
761                         Time time) ;
762 static void df_DoSecondaryExtend(
763                         Widget w,
764                         Time ev_time) ;
765 static void df_BrowseScroll(
766                         XtPointer closure,
767                         XtIntervalId *id) ;
768 static Boolean df_CheckTimerScrolling(
769                         Widget w,
770                         XEvent *event) ;
771 static void df_RestorePrimaryHighlight(
772                         XmDataFieldWidget tf,
773                         XmTextPosition prim_left,
774                         XmTextPosition prim_right) ;
775 static void df_StartDrag(
776                         Widget w,
777                         XEvent *event,
778                         String *params,
779                         Cardinal *num_params) ;
780 static void df_StartSecondary(
781                         Widget w,
782                         XEvent *event,
783                         char **params,
784                         Cardinal *num_params) ;
785 static void df_ProcessBDrag(
786                         Widget w,
787                         XEvent *event,
788                         char **params,
789                         Cardinal *num_params) ;
790 static void df_ExtendSecondary(
791                         Widget w,
792                         XEvent *event,
793                         char **params,
794                         Cardinal *num_params) ;
795 static void df_DoStuff(
796                         Widget w,
797                         XtPointer closure,
798                         Atom *seltype,
799                         Atom *type,
800                         XtPointer value,
801                         unsigned long *length,
802                         int *format) ;
803 static void df_Stuff(
804                         Widget w,
805                         XEvent *event,
806                         char **params,
807                         Cardinal *num_params) ;
808 static void df_HandleSelectionReplies(
809                         Widget w,
810                         XtPointer closure,
811                         XEvent *event,
812                         Boolean *cont) ;
813 static void df_SecondaryNotify(
814                         Widget w,
815                         XEvent *event,
816                         char **params,
817                         Cardinal *num_params) ;
818 static void df_HandleTargets(
819                         Widget w,
820                         XtPointer closure,
821                         Atom *seltype,
822                         Atom *type,
823                         XtPointer value,
824                         unsigned long *length,
825                         int *format) ;
826 static void df_ProcessBDragRelease(
827                         Widget w,
828                         XEvent *event,
829                         String *params,
830                         Cardinal *num_params) ;
831 static void df_ProcessCopy(
832                         Widget w,
833                         XEvent *event,
834                         char **params,
835                         Cardinal *num_params) ;
836 static void df_ProcessMove(
837                         Widget w,
838                         XEvent *event,
839                         char **params,
840                         Cardinal *num_params) ;
841 static void df_DeleteSelection(
842                         Widget w,
843                         XEvent *event,
844                         char **params,
845                         Cardinal *num_params) ;
846 static void df_ClearSelection(
847                         Widget w,
848                         XEvent *event,
849                         char **params,
850                         Cardinal *num_params) ;
851 static void df_PageRight(
852                         Widget w,
853                         XEvent *event,
854                         char **params,
855                         Cardinal *num_params) ;
856 static void df_PageLeft(
857                         Widget w,
858                         XEvent *event,
859                         char **params,
860                         Cardinal *num_params) ;
861 static void df_CopyPrimary(
862                         Widget w,
863                         XEvent *event,
864                         char **params,
865                         Cardinal *num_params) ;
866 static void df_CutPrimary(
867                         Widget w,
868                         XEvent *event,
869                         char **params,
870                         Cardinal *num_params) ;
871 static void df_SetAnchor(
872                         Widget w,
873                         XEvent *event,
874                         char **params,
875                         Cardinal *num_params) ;
876 static void df_ToggleOverstrike(
877                         Widget w,
878                         XEvent *event,
879                         char **params,
880                         Cardinal *num_params) ;
881 static void df_ToggleAddMode(
882                         Widget w,
883                         XEvent *event,
884                         char **params,
885                         Cardinal *num_params) ;
886 static void df_SelectAll(
887                         Widget w,
888                         XEvent *event,
889                         char **params,
890                         Cardinal *num_params) ;
891 static void df_DeselectAll(
892                         Widget w,
893                         XEvent *event,
894                         char **params,
895                         Cardinal *num_params) ;
896 static void df_VoidAction(
897                         Widget w,
898                         XEvent *event,
899                         char **params,
900                         Cardinal *num_params) ;
901 static void df_CutClipboard(
902                         Widget w,
903                         XEvent *event,
904                         char **params,
905                         Cardinal *num_params) ;
906 static void df_CopyClipboard(
907                         Widget w,
908                         XEvent *event,
909                         char **params,
910                         Cardinal *num_params) ;
911 static void df_PasteClipboard(
912                         Widget w,
913                         XEvent *event,
914                         char **params,
915                         Cardinal *num_params) ;
916 static void df_TraverseDown(
917                         Widget w,
918                         XEvent *event,
919                         char **params,
920                         Cardinal *num_params) ;
921 static void df_TraverseUp(
922                         Widget w,
923                         XEvent *event,
924                         char **params,
925                         Cardinal *num_params) ;
926 static void df_TraverseHome(
927                         Widget w,
928                         XEvent *event,
929                         char **params,
930                         Cardinal *num_params) ;
931 static void df_TraverseNextTabGroup(
932                         Widget w,
933                         XEvent *event,
934                         char **params,
935                         Cardinal *num_params) ;
936 static void df_TraversePrevTabGroup(
937                         Widget w,
938                         XEvent *event,
939                         char **params,
940                         Cardinal *num_params) ;
941 static void df_TextEnter(
942                         Widget w,
943                         XEvent *event,
944                         String *params,
945                         Cardinal *num_params) ;
946 static void df_TextLeave(
947                         Widget w,
948                         XEvent *event,
949                         String *params,
950                         Cardinal *num_params) ;
951 static void df_ClassPartInitialize(
952                         WidgetClass w_class) ;
953 static void df_Validates(
954                         XmDataFieldWidget tf) ;
955 static Boolean df_LoadFontMetrics(
956                         XmDataFieldWidget tf) ;
957 
958 static void df_ValidateString(
959                         XmDataFieldWidget tf,
960                         char *value,
961 #if NeedWidePrototypes
962                         int is_wchar) ;
963 #else
964                         Boolean is_wchar) ;
965 #endif /* NeedWidePrototypes */
966 
967 static void df_InitializeTextStruct(
968                         XmDataFieldWidget tf) ;
969 static Pixmap df_GetClipMask(
970                         XmDataFieldWidget tf,
971                         char *pixmap_name) ;
972 static void df_LoadGCs(
973                         XmDataFieldWidget tf,
974                         Pixel background,
975                         Pixel foreground) ;
976 
977 static void df_MakeIBeamOffArea(
978                         XmDataFieldWidget tf,
979 #if NeedWidePrototypes
980                         int width,
981                         int height) ;
982 #else
983                         Dimension width,
984                         Dimension height) ;
985 #endif /* NeedWidePrototypes */
986 
987 static void df_MakeIBeamStencil(
988                         XmDataFieldWidget tf,
989                         int line_width) ;
990 static void df_MakeAddModeCursor(
991                         XmDataFieldWidget tf,
992                         int line_width) ;
993 static void df_MakeCursors(
994                         XmDataFieldWidget tf) ;
995 static void df_DropDestroyCB(
996                         Widget w,
997                         XtPointer clientData,
998                         XtPointer callData) ;
999 static void df_DropTransferCallback(
1000                         Widget w,
1001                         XtPointer closure,
1002                         Atom *seltype,
1003                         Atom *type,
1004                         XtPointer value,
1005                         unsigned long *length,
1006                         int *format) ;
1007 static void df_HandleDrop(
1008                         Widget w,
1009                         XmDropProcCallbackStruct *cb) ;
1010 static void df_DragProcCallback(
1011                         Widget w,
1012                         XtPointer client,
1013                         XtPointer call) ;
1014 static void df_DropProcCallback(
1015                         Widget w,
1016                         XtPointer client,
1017                         XtPointer call) ;
1018 static void df_RegisterDropSite(
1019                         Widget w) ;
1020 static void df_Initialize(
1021                         Widget request,
1022                         Widget new_w,
1023                         ArgList args,
1024                         Cardinal *num_args) ;
1025 static void df_Realize(
1026                         Widget w,
1027                         XtValueMask *valueMask,
1028                         XSetWindowAttributes *attributes) ;
1029 static void df_Destroy(
1030                         Widget wid) ;
1031 static void df_Resize(
1032                         Widget w) ;
1033 static XtGeometryResult df_QueryGeometry(
1034                         Widget w,
1035                         XtWidgetGeometry *intended,
1036                         XtWidgetGeometry *reply) ;
1037 static void DataFieldExpose(
1038                         Widget w,
1039                         XEvent *event,
1040                         Region region) ;
1041 static Boolean df_SetValues(
1042                         Widget old,
1043                         Widget request,
1044                         Widget new_w,
1045                         ArgList args,
1046                         Cardinal *num_args) ;
1047 static Boolean DataFieldGetBaselines(
1048                         Widget w,
1049                         Dimension **baselines,
1050                         int *line_count) ;
1051 static Boolean DataFieldGetDisplayRect(
1052                         Widget w,
1053                         XRectangle *display_rect) ;
1054 static void DataFieldMarginsProc(
1055                         Widget w,
1056                         XmBaselineMargins *margins_rec) ;
1057 static XtPointer DataFieldGetValue(Widget w,
1058 				   int format);
1059 
1060 static void DataFieldSetValue(Widget w,
1061 			      XtPointer s,
1062 			      int format);
1063 
1064 static int DataFieldPreferredValue(Widget w);
1065 
1066 static void CheckSetRenderTable(Widget wid,
1067 				int offset,
1068 				XrmValue *value);
1069 
1070 static Boolean DataFieldRemove(Widget w,
1071 			       XEvent *event);
1072 static void PictureVerifyCallback(Widget w,
1073     XtPointer call_d, XtPointer client_d);
1074 static void ClassInit(void);
1075 
1076 
1077 static void XmDataFieldSetStringWcs(Widget w, wchar_t *wc_value);
1078 
1079 #endif /* _NO_PROTO */
1080 
1081 /***************** End Static Function Declarations  ************/
1082 
1083 static XmTextScanType df_sarray[] = {
1084     XmSELECT_POSITION, XmSELECT_WORD, XmSELECT_LINE
1085 };
1086 
1087 static int df_sarraysize = XtNumber(df_sarray);
1088 
1089 static XContext _XmDataFDestContext = 0;
1090 static XContext _XmDataFGCContext = 0;
1091 static XContext _XmDataFDNDContext = 0;
1092 
1093 
1094 /* default translations and action recs */
1095 
1096 static XtActionsRec data_actions[] = {
1097 /* ICS DataField actions */
1098   {"ValidateAndMove",           df_ValidateAndMove},
1099 /* Text Replacing Bindings */
1100   {"self-insert",		df_InsertChar},
1101   {"insert-string",		df_InsertString},
1102   {"delete-previous-character",	df_DeletePrevChar},
1103   {"delete-next-character",	df_DeleteNextChar},
1104   {"delete-previous-word",	df_DeletePrevWord},
1105   {"delete-next-word",		df_DeleteNextWord},
1106   {"delete-to-end-of-line",	df_DeleteToEndOfLine},
1107   {"delete-to-start-of-line",	df_DeleteToStartOfLine},
1108 /* Miscellaneous Bindings */
1109   {"activate",			df_Activate},
1110   {"process-cancel",		df_ProcessCancel},
1111   {"process-bdrag",		df_ProcessBDrag},
1112 /* Motion Bindings */
1113   {"backward-character",	df_BackwardChar},
1114   {"forward-character",		df_ForwardChar},
1115   {"backward-word",		df_BackwardWord},
1116   {"forward-word",		df_ForwardWord},
1117   {"end-of-line",		df_EndOfLine},
1118   {"beginning-of-line",		df_BeginningOfLine},
1119   {"page-left",			df_PageLeft},
1120   {"page-right",		df_PageRight},
1121 /* Selection Bindings */
1122   {"key-select",		df_KeySelection},
1123   {"grab-focus",		df_StartPrimary},
1124   {"move-destination",		df_MoveDestination},
1125   {"extend-start",		df_ExtendPrimary},
1126   {"extend-adjust",		df_ExtendPrimary},
1127   {"extend-end",		df_ExtendEnd},
1128   {"delete-selection",		df_DeleteSelection},
1129   {"clear-selection",		df_ClearSelection},
1130   {"cut-primary",		df_CutPrimary},
1131   {"copy-primary",		df_CopyPrimary},
1132   {"set-anchor",		df_SetAnchor},
1133   {"toggle-overstrike",		df_ToggleOverstrike},
1134   {"toggle-add-mode",		df_ToggleAddMode},
1135   {"select-all",		df_SelectAll},
1136   {"deselect-all",		df_DeselectAll},
1137 /* Quick Cut and Paste Bindings */
1138   {"secondary-start",		df_StartSecondary},
1139   {"secondary-adjust",		df_ExtendSecondary},
1140   {"copy-to",			df_ProcessCopy},
1141   {"move-to",			df_ProcessMove},
1142   {"quick-cut-set",		df_VoidAction},
1143   {"quick-copy-set",		df_VoidAction},
1144   {"do-quick-action",		df_VoidAction},
1145 /* Clipboard Bindings */
1146   {"cut-clipboard",		df_CutClipboard},
1147   {"copy-clipboard",		df_CopyClipboard},
1148   {"paste-clipboard",		df_PasteClipboard},
1149 /* Traversal */
1150   {"traverse-next",		df_TraverseDown},
1151   {"traverse-prev",		df_TraverseUp},
1152   {"traverse-home",		df_TraverseHome},
1153   {"next-tab-group",		df_TraverseNextTabGroup},
1154   {"prev-tab-group",		df_TraversePrevTabGroup},
1155 /* Focus */
1156   {"focusIn",			df_TextFocusIn},
1157   {"focusOut",			df_TextFocusOut},
1158   {"enter",			df_TextEnter},
1159   {"leave",			df_TextLeave},
1160 };
1161 
1162 static XtResource resources[] =
1163 {
1164     {
1165       XmNpicture, XmCPicture, XmRString, sizeof(String),
1166       XtOffsetOf(XmDataFieldRec, data.picture_source),
1167       XmRImmediate, (XtPointer) NULL
1168     },
1169     {
1170       XmNautoFill, XmCAutoFill, XmRBoolean, sizeof(Boolean),
1171       XtOffsetOf(XmDataFieldRec, data.auto_fill),
1172       XmRImmediate, (XtPointer) True
1173     },
1174     {
1175       XmNalignment, XmCAlignment, XmRAlignment, sizeof(unsigned char),
1176       XtOffsetOf(XmDataFieldRec, data.alignment), XmRImmediate,
1177       (XtPointer) XmALIGNMENT_BEGINNING
1178     },
1179     {
1180       XmNpictureErrorCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1181       XtOffsetOf(XmDataFieldRec, data.picture_error_cb), XmRCallback,
1182       (XtPointer) NULL
1183     },
1184     {
1185       XmNvalidateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1186       XtOffsetOf(XmDataFieldRec, data.validate_cb),
1187       XmRCallback, (XtPointer) NULL
1188     },
1189 
1190 	/* the following are undocumented overrides of XmTextField resources */
1191     {
1192       XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1193       XtOffsetOf(XmDataFieldRec, text.activate_callback),
1194       XmRCallback, NULL
1195     },
1196     {
1197       XmNlosingFocusCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1198       XtOffsetOf(XmDataFieldRec, text.losing_focus_callback),
1199       XmRCallback, NULL
1200     },
1201     {
1202       XmNfocusCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1203       XtOffsetOf(XmDataFieldRec, text.focus_callback),
1204       XmRCallback, NULL
1205     },
1206     {
1207       XmNmodifyVerifyCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1208       XtOffsetOf(XmDataFieldRec, text.modify_verify_callback),
1209       XmRCallback, NULL
1210     },
1211     {
1212       XmNmodifyVerifyCallbackWcs, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1213       XtOffsetOf(XmDataFieldRec, text.wcs_modify_verify_callback),
1214       XmRCallback, NULL
1215     },
1216     {
1217       XmNmotionVerifyCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1218       XtOffsetOf(XmDataFieldRec, text.motion_verify_callback),
1219       XmRCallback, NULL
1220     },
1221     {
1222       XmNgainPrimaryCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1223       XtOffsetOf(XmDataFieldRec, text.gain_primary_callback),
1224       XmRCallback, NULL
1225     },
1226     {
1227       XmNlosePrimaryCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1228       XtOffsetOf(XmDataFieldRec, text.lose_primary_callback),
1229       XmRCallback, NULL
1230     },
1231     {
1232       XmNvalueChangedCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
1233       XtOffsetOf(XmDataFieldRec, text.value_changed_callback),
1234       XmRCallback, NULL
1235     },
1236     {
1237       XmNvalue, XmCValue, XmRString, sizeof(String),
1238       XtOffsetOf(XmDataFieldRec, text.value),
1239       XmRString, ""
1240     },
1241     {
1242       XmNvalueWcs, XmCValueWcs, XmRValueWcs, sizeof(wchar_t*),
1243       XtOffsetOf(XmDataFieldRec, text.wc_value),
1244       XmRString, NULL
1245     },
1246     {
1247       XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension),
1248       XtOffsetOf(XmDataFieldRec, text.margin_height),
1249       XmRImmediate, (XtPointer) 5
1250     },
1251     {
1252       XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension),
1253       XtOffsetOf(XmDataFieldRec, text.margin_width),
1254       XmRImmediate, (XtPointer) 5
1255     },
1256     {
1257       XmNcursorPosition, XmCCursorPosition, XmRTextPosition, sizeof (XmTextPosition),
1258       XtOffsetOf(XmDataFieldRec, text.cursor_position),
1259       XmRImmediate, (XtPointer) 0
1260     },
1261     {
1262       XmNcolumns, XmCColumns, XmRShort, sizeof(short),
1263       XtOffsetOf(XmDataFieldRec, text.columns),
1264       XmRImmediate, (XtPointer) 20
1265     },
1266     {
1267       XmNmaxLength, XmCMaxLength, XmRInt, sizeof(int),
1268       XtOffsetOf(XmDataFieldRec, text.max_length),
1269       XmRImmediate, (XtPointer) INT_MAX
1270     },
1271     {
1272       XmNblinkRate, XmCBlinkRate, XmRInt, sizeof(int),
1273       XtOffsetOf(XmDataFieldRec, text.blink_rate),
1274       XmRImmediate, (XtPointer) 500
1275     },
1276     {
1277       "pri.vate", "Pri.vate", XmRBoolean, sizeof(Boolean),
1278       XtOffsetOf(XmDataFieldRec, text.check_set_render_table),
1279       XmRImmediate, (XtPointer) False
1280     },
1281     {
1282      XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList),
1283      XtOffsetOf(XmDataFieldRec, text.font_list),
1284      XmRCallProc, (XtPointer)CheckSetRenderTable
1285     },
1286     {
1287      XmNrenderTable, XmCRenderTable, XmRRenderTable, sizeof(XmRenderTable),
1288      XtOffsetOf(XmDataFieldRec, text.font_list),
1289      XmRCallProc, (XtPointer)CheckSetRenderTable
1290     },
1291     {
1292       XmNselectionArray, XmCSelectionArray, XmRPointer,
1293       sizeof(XtPointer),
1294       XtOffsetOf(XmDataFieldRec, text.selection_array),
1295       XmRImmediate, (XtPointer) df_sarray
1296     },
1297     {
1298       XmNselectionArrayCount, XmCSelectionArrayCount, XmRInt, sizeof(int),
1299       XtOffsetOf(XmDataFieldRec, text.selection_array_count),
1300       XmRInt, (XtPointer) &df_sarraysize
1301     },
1302     {
1303       XmNresizeWidth, XmCResizeWidth, XmRBoolean, sizeof(Boolean),
1304       XtOffsetOf(XmDataFieldRec, text.resize_width),
1305       XmRImmediate, (XtPointer) False
1306     },
1307     {
1308       XmNpendingDelete, XmCPendingDelete, XmRBoolean, sizeof(Boolean),
1309       XtOffsetOf(XmDataFieldRec, text.pending_delete),
1310       XmRImmediate, (XtPointer) True
1311     },
1312     {
1313       XmNeditable, XmCEditable, XmRBoolean, sizeof(Boolean),
1314       XtOffsetOf(XmDataFieldRec, text.editable),
1315       XmRImmediate, (XtPointer) True
1316     },
1317     {
1318       XmNcursorPositionVisible, XmCCursorPositionVisible, XmRBoolean,
1319       sizeof(Boolean),
1320       XtOffsetOf(XmDataFieldRec, text.cursor_position_visible),
1321       XmRImmediate, (XtPointer) True
1322     },
1323    {
1324      XmNverifyBell, XmCVerifyBell, XmRBoolean, sizeof(Boolean),
1325      XtOffsetOf(XmDataFieldRec, text.verify_bell),
1326      XmRImmediate, (XtPointer) XmDYNAMIC_BOOL
1327    },
1328    {
1329      XmNselectThreshold, XmCSelectThreshold, XmRInt, sizeof(int),
1330      XtOffsetOf(XmDataFieldRec, text.threshold),
1331      XmRImmediate, (XtPointer) 5
1332    },
1333    {
1334      XmNnavigationType, XmCNavigationType, XmRNavigationType,
1335      sizeof (unsigned char),
1336      XtOffsetOf(XmDataFieldRec, primitive.navigation_type),
1337      XmRImmediate, (XtPointer) XmTAB_GROUP
1338    },
1339 };
1340 
1341 /* Definition for resources that need special processing in get values */
1342 static XmSyntheticResource syn_resources[] =
1343 {
1344    {
1345      XmNmarginWidth,
1346      sizeof(Dimension),
1347      XtOffsetOf(XmDataFieldRec, text.margin_width),
1348      XmeFromHorizontalPixels,
1349      XmeToHorizontalPixels
1350    },
1351 
1352    {
1353      XmNmarginHeight,
1354      sizeof(Dimension),
1355      XtOffsetOf(XmDataFieldRec, text.margin_height),
1356      XmeFromVerticalPixels,
1357      XmeToVerticalPixels
1358    },
1359 
1360    {
1361      XmNvalue,
1362      sizeof(char *),
1363      XtOffsetOf(XmDataFieldRec, text.value),
1364      df_MakeCopy,
1365      NULL
1366    },
1367 
1368    {
1369      XmNvalueWcs,
1370      sizeof(wchar_t *),
1371      XtOffsetOf(XmDataFieldRec, text.wc_value),
1372      df_WcsMakeCopy,
1373      NULL
1374    },
1375 
1376 };
1377 
1378 XmPrimitiveClassExtRec _XmDataFPrimClassExtRec = {
1379     NULL,
1380     NULLQUARK,
1381     XmPrimitiveClassExtVersion,
1382     sizeof(XmPrimitiveClassExtRec),
1383     DataFieldGetBaselines,		/* widget_baseline        */
1384     DataFieldGetDisplayRect,		/* widget_display_rect    */
1385     DataFieldMarginsProc,		/* get/set widget margins */
1386 };
1387 
1388 
1389 externaldef(xmdatafieldclassrec) XmDataFieldClassRec xmDataFieldClassRec =
1390 {
1391    {
1392       (WidgetClass) &xmPrimitiveClassRec,       /* superclass         */
1393       "XmDataField",				/* class_name         */
1394       sizeof(XmDataFieldRec),			/* widget_size        */
1395       ClassInit,		                /* class_initialize   */
1396       df_ClassPartInitialize,			/* class_part_initiali*/
1397       FALSE,					/* class_inited       */
1398       df_Initialize,				/* initialize         */
1399       (XtArgsProc)NULL,				/* initialize_hook    */
1400       df_Realize,				/* realize            */
1401       data_actions,				/* actions            */
1402       XtNumber(data_actions),			/* num_actions        */
1403       resources,				/* resources          */
1404       XtNumber(resources),			/* num_resources      */
1405       NULLQUARK,				/* xrm_class          */
1406       TRUE,					/* compress_motion    */
1407       XtExposeCompressMaximal,			/* compress_exposure  */
1408       TRUE,					/* compress_enterleave*/
1409       FALSE,					/* visible_interest   */
1410       df_Destroy,				/* destroy            */
1411       df_Resize,				/* resize             */
1412       DataFieldExpose,				/* expose             */
1413       df_SetValues,				/* set_values         */
1414 
1415 #ifdef sco    /* ICS -pwc 7/28/93 */
1416       NULL,					/* set_values_hook    */
1417 #else
1418       (XtArgsFunc)NULL,				/* set_values_hook    */
1419 #endif        /* sco */
1420 
1421       XtInheritSetValuesAlmost,			/* set_values_almost  */
1422       (XtArgsProc)NULL,				/* get_values_hook    */
1423 
1424 #ifdef sco		/* ICS - pwc 7/28/93 */
1425       NULL,					/* accept_focus       */
1426 #else
1427       (XtAcceptFocusProc)NULL,			/* accept_focus       */
1428 #endif /* sco */
1429 
1430       XtVersion,			/* version            */
1431       NULL,					/* callback_private   */
1432       NULL,					/* tm_table           */
1433       df_QueryGeometry,				/* query_geometry     */
1434       (XtStringProc)NULL,			/* display accel      */
1435       NULL,					/* extension          */
1436    },
1437 
1438    {  	                          		/* Xmprimitive        */
1439       XmInheritBorderHighlight,        		/* border_highlight   */
1440       XmInheritBorderUnhighlight,              	/* border_unhighlight */
1441       NULL,					/* translations	      */
1442       (XtActionProc)NULL,             		/* arm_and_activate   */
1443       syn_resources,            		/* syn resources      */
1444       XtNumber(syn_resources),  		/* num syn_resources  */
1445       (XtPointer) &_XmDataFPrimClassExtRec,	/* extension          */
1446    },
1447    {                            		/* text classs        */
1448       NULL,                     		/* extension          */
1449    }
1450 };
1451 
1452 externaldef(xmdatafieldwidgetclass) WidgetClass xmDataFieldWidgetClass =
1453 					 (WidgetClass) &xmDataFieldClassRec;
1454 
1455 /* AccessXmString Trait record for DataField */
1456 static XmConst XmAccessTextualTraitRec dataFieldCS = {
1457   0,  				  /* version */
1458   DataFieldGetValue,
1459   DataFieldSetValue,
1460   DataFieldPreferredValue,
1461 };
1462 
1463 static void
1464 #ifdef _NO_PROTO
ClassInit()1465 ClassInit()
1466 #else
1467 ClassInit(void)
1468 #endif
1469 {
1470     XmDataFieldClassRec* wc = &xmDataFieldClassRec;
1471     XmTransferTrait tt;
1472 
1473     /* set TextField's transfer trait */
1474     tt = XmeTraitGet((XtPointer)xmTextFieldWidgetClass, XmQTtransfer);
1475     XmeTraitSet((XtPointer)xmDataFieldWidgetClass,
1476     		XmQTtransfer,
1477 		(XtPointer) &tt);
1478 
1479     XmeTraitSet((XtPointer)xmDataFieldWidgetClass,
1480 		XmQTaccessTextual,
1481 		(XtPointer) &dataFieldCS);
1482 }
1483 
1484 /* ARGSUSED */
1485 static void
1486 #ifdef _NO_PROTO
df_ValidateAndMove(w,ev,args,nargs)1487 df_ValidateAndMove(w, ev, args, nargs)
1488      Widget w;
1489      XEvent *ev;
1490      String *args;
1491      Cardinal *nargs;
1492 #else
1493 df_ValidateAndMove(
1494     Widget w,
1495     XEvent *ev,
1496     String *args,
1497     Cardinal *nargs)
1498 #endif
1499 {
1500     XmDataFieldCallbackStruct cbs;
1501 
1502     /*
1503      * We are guaranteed that the picture will have accepted the string, so
1504      * just call the verify callbacks.
1505      */
1506     cbs.w      = w;
1507     cbs.text   = XmDataFieldGetString(w);
1508     cbs.accept = True;
1509     XtCallCallbackList(w, XmDataField_validate_cb(w), (XtPointer)&cbs);
1510     XtFree(cbs.text);
1511 
1512     /*
1513      * Make sure we accepted it
1514      */
1515     if(cbs.accept == False)
1516     {
1517 	XBell(XtDisplay(w), 0);
1518 	return;
1519     }
1520 
1521     /*
1522      * Otherwise just give up the focus and process the traversal as
1523      * normal
1524      */
1525     if(*nargs > 0 && strncasecmp(args[0], "prev", 4) == 0) {
1526 	(void) XmProcessTraversal(w, XmTRAVERSE_PREV_TAB_GROUP);
1527     } else {
1528 	(void) XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP);
1529     }
1530 }
1531 
1532 
1533 
1534 /* ARGSUSED */
1535 static void
1536 #ifdef _NO_PROTO
PictureVerifyCallback(w,client_d,call_d)1537 PictureVerifyCallback(w, client_d, call_d)
1538     Widget w;
1539     XtPointer client_d;
1540     XtPointer call_d;
1541 #else
1542 PictureVerifyCallback(
1543     Widget w,
1544     XtPointer client_d,
1545     XtPointer call_d )
1546 #endif /* _NO_PROTO */
1547 {
1548     XmTextVerifyCallbackStruct *cbs =
1549 	(XmTextVerifyCallbackStruct*) call_d;
1550     char *curr, *newptr, *changed = NULL;
1551     int src, dst, i;
1552     XmPictureState ps;
1553     Boolean done = False;
1554 
1555     /*
1556      * If we're just backspacing, allow the change irregarless
1557      */
1558     if(cbs->startPos < cbs->currInsert || cbs->text->length == 0)
1559 	return;
1560 
1561     /*
1562      * Get the current string, and splice in the intended changes
1563      */
1564     curr = XmDataFieldGetString(w);
1565 
1566     newptr = XtMalloc((cbs->text->length + strlen(curr) + 2) *
1567 		      sizeof(char *));
1568 
1569     dst = 0;
1570 
1571     /* Copy in the stuff before the modification */
1572     for(src=0; src<cbs->startPos; src++, dst++)
1573  	newptr[dst] = curr[src];
1574 
1575     /* Then the modification text */
1576     if(cbs->text->ptr) {
1577 	for(src=0; src<cbs->text->length; src++, dst++)
1578 	    newptr[dst] = cbs->text->ptr[src];
1579     }
1580     /* Then the last bit */
1581     if(cbs->endPos > cbs->startPos) {
1582 	for(dst = cbs->endPos + cbs->text->length;
1583 	    src<cbs->endPos;
1584 	    src++, dst++)
1585 	    newptr[dst] = curr[src];
1586     }
1587     /* And stick a null in for good measure and sanity in debugging */
1588     newptr[dst] = '\0';
1589 
1590     /*
1591      * Run it through the picture, and bail if it isn't accepted
1592      */
1593     ps = XmGetNewPictureState(XmDataField_picture(w));
1594 
1595     for(i=0; i<strlen(newptr); i++) {
1596 	changed = XmPictureProcessCharacter(ps, newptr[i], &done);
1597 	if(changed == NULL || done) break;
1598     }
1599 
1600     if(changed == NULL) {
1601 	cbs->doit = False;
1602 	XtCallCallbackList(w, XmDataField_picture_error_cb(w), NULL);
1603 	return;
1604     }
1605 
1606 
1607     /*
1608      * And now try autofilling
1609      */
1610     if(XmDataField_auto_fill(w)) {
1611 	changed = XmPictureDoAutoFill(ps);
1612     } else {
1613 	changed = XmPictureGetCurrentString(ps);
1614     }
1615 
1616     /*
1617      * Now the hard part:  we may have been auto-filled, so we have to
1618      * massage the callback struct to reflect what's happened
1619      */
1620 
1621     cbs->startPos = 0;
1622     /* CR03686 cbs->endPos = strlen(newptr); */
1623     cbs->text->ptr = XtNewString(changed);
1624     cbs->text->length = strlen(changed);
1625 
1626     XtFree(newptr);
1627     XmPictureDeleteState(ps);
1628 }
1629 
1630 
1631 /* USE ITERATIONS OF mblen TO COUNT THE NUMBER OF CHARACTERS REPRESENTED
1632  * BY n_bytes BYTES POINTED TO BY ptr, a pointer to char*.
1633  * n_bytes does not include NULL terminator (if any), nor does return.
1634  */
1635 
1636 /* ARGSUSED */
1637 static int
1638 #ifdef _NO_PROTO
_XmDataFieldCountCharacters(tf,ptr,n_bytes)1639 _XmDataFieldCountCharacters( tf, ptr, n_bytes )
1640         XmDataFieldWidget tf ;
1641         char *ptr ;
1642         int n_bytes ;
1643 #else
1644 _XmDataFieldCountCharacters(
1645         XmDataFieldWidget tf,
1646         char *ptr,
1647         int n_bytes )
1648 #endif /* _NO_PROTO */
1649 {
1650    char * bptr;
1651    int count = 0;
1652    int char_size = 0;
1653 
1654    if (n_bytes <= 0 || ptr == NULL || *ptr == '\0')
1655       return 0;
1656 
1657    if (XmTextF_max_char_size(tf) == 1)
1658       return n_bytes;
1659 
1660    bptr = ptr;
1661 
1662    for (bptr = ptr; n_bytes > 0; count++, bptr+= char_size){
1663       char_size = mblen(bptr, XmTextF_max_char_size(tf));
1664       if (char_size < 0) break; /* error */
1665       n_bytes -= char_size;
1666    }
1667    return count;
1668 }
1669 
1670 /* USE ITERATIONS OF wctomb TO COUNT THE NUMBER OF BYTES REQUIRED FOR THE
1671  * MULTI-BYTE REPRESENTION OF num_chars WIDE CHARACTERS IN wc_value.
1672  * COUNT TERMINATED IF NULL ENCOUNTERED IN THE STRING.
1673  * NUMBER OF BYTES IS RETURNED.
1674  */
1675 
1676 /* ARGSUSED */
1677 int
1678 #ifdef _NO_PROTO
_XmDataFieldCountBytes(tf,wc_value,num_chars)1679 _XmDataFieldCountBytes( tf, wc_value, num_chars )
1680 	XmDataFieldWidget tf;
1681 	wchar_t * wc_value;
1682 	int num_chars;
1683 #else /* _NO_PROTO */
1684 _XmDataFieldCountBytes(
1685 	XmDataFieldWidget tf,
1686 	wchar_t * wc_value,
1687 	int num_chars)
1688 #endif /* _NO_PROTO */
1689 {
1690    wchar_t 	* wc_ptr;
1691    char 	tmp[MB_LEN_MAX];  /* defined in limits.h: max in any locale */
1692    int 		n_bytes = 0;
1693 
1694    if (num_chars <= 0 || wc_value == NULL || *wc_value == (wchar_t)0L)
1695       return 0;
1696 
1697    if (XmTextF_max_char_size(tf) == 1)
1698       return num_chars;
1699 
1700    wc_ptr = wc_value;
1701    while ((num_chars > 0) && (*wc_ptr != (wchar_t)0L)){
1702       n_bytes += wctomb(tmp, *wc_ptr);
1703       num_chars--;
1704       wc_ptr++;
1705    }
1706    return n_bytes;
1707 }
1708 
1709 /*ARGSUSED*/
1710 static void
1711 #ifdef _NO_PROTO
df_MakeCopy(w,n,value)1712 df_MakeCopy( w, n, value )
1713         Widget w ;
1714 	int n;
1715         XtArgVal *value ;
1716 #else
1717 df_MakeCopy(
1718         Widget w,
1719 	int n,
1720         XtArgVal *value )
1721 #endif /* _NO_PROTO */
1722 {
1723     (*value) = (XtArgVal) XmDataFieldGetString (w);
1724 }
1725 
1726 /*ARGSUSED*/
1727 static void
1728 #ifdef _NO_PROTO
df_WcsMakeCopy(w,n,value)1729 df_WcsMakeCopy( w, n, value )
1730         Widget w ;
1731 	int n;
1732         XtArgVal *value ;
1733 #else
1734 df_WcsMakeCopy(
1735         Widget w,
1736 	int n,
1737         XtArgVal *value )
1738 #endif /* _NO_PROTO */
1739 {
1740     (*value) = (XtArgVal) XmDataFieldGetStringWcs (w);
1741 }
1742 
1743 /* ARGSUSED */
1744 static void
1745 #ifdef _NO_PROTO
df_FreeContextData(w,clientData,callData)1746 df_FreeContextData(w, clientData, callData)
1747     Widget w;
1748     XtPointer clientData;
1749     XtPointer callData;
1750 #else
1751 df_FreeContextData(
1752 	Widget w,
1753 	XtPointer clientData,
1754 	XtPointer callData )
1755 #endif /* _NO_PROTO */
1756 {
1757     XmTextContextData ctx_data = (XmTextContextData) clientData;
1758     Display *display = DisplayOfScreen(ctx_data->screen);
1759     XtPointer data_ptr;
1760 
1761     if (XFindContext(display, (Window) ctx_data->screen,
1762                      ctx_data->context, (char **) &data_ptr)) {
1763 
1764        if (ctx_data->type == _XM_IS_PIXMAP_CTX) {
1765           XFreePixmap(display, (Pixmap) data_ptr);
1766        } else if (ctx_data->type != '\0') {
1767           if (data_ptr)
1768              XtFree((char *) data_ptr);
1769        }
1770 
1771        XDeleteContext (display, (Window) ctx_data->screen, ctx_data->context);
1772     }
1773 
1774     XtFree ((char *) ctx_data);
1775 }
1776 
1777 static TextFDestData
1778 #ifdef _NO_PROTO
df_GetTextFDestData(w)1779 df_GetTextFDestData( w )
1780         Widget w ;
1781 #else
1782 df_GetTextFDestData(
1783         Widget w )
1784 #endif /* _NO_PROTO */
1785 {
1786    static TextFDestData dest_data;
1787    Display *display = XtDisplay(w);
1788    Screen *screen = XtScreen(w);
1789 
1790    if (_XmDataFDestContext == 0)
1791       _XmDataFDestContext = XUniqueContext();
1792 
1793    if (XFindContext(display, (Window) screen,
1794                     _XmDataFDestContext, (char **) &dest_data)) {
1795        XmTextContextData ctx_data;
1796        Widget xm_display = (Widget) XmGetXmDisplay(display);
1797 
1798        ctx_data = (XmTextContextData) XtMalloc(sizeof(XmTextContextDataRec));
1799 
1800        ctx_data->screen = screen;
1801        ctx_data->context = _XmDataFDestContext;
1802        ctx_data->type = _XM_IS_DEST_CTX;
1803 
1804        dest_data = (TextFDestData) XtCalloc(1, sizeof(TextFDestDataRec));
1805 
1806        XtAddCallback(xm_display, XmNdestroyCallback,
1807                      (XtCallbackProc) df_FreeContextData, (XtPointer) ctx_data);
1808 
1809        XSaveContext(XtDisplay(w), (Window) screen,
1810                     _XmDataFDestContext, (XPointer)dest_data);
1811    }
1812 
1813    return dest_data;
1814 }
1815 
1816 static void
1817 #ifdef _NO_PROTO
df_SetDropContext(w)1818 df_SetDropContext( w )
1819         Widget w ;
1820 #else
1821 df_SetDropContext(
1822         Widget w )
1823 #endif /* _NO_PROTO */
1824 {
1825    Display *display = XtDisplay(w);
1826    Screen *screen = XtScreen(w);
1827 
1828    if (_XmDataFDNDContext == 0)
1829       _XmDataFDNDContext = XUniqueContext();
1830 
1831    XSaveContext(display, (Window)screen,
1832                 _XmDataFDNDContext, (XPointer)w);
1833 }
1834 
1835 
1836 static void
1837 #ifdef _NO_PROTO
df_DeleteDropContext(w)1838 df_DeleteDropContext( w )
1839         Widget w ;
1840 #else
1841 df_DeleteDropContext(
1842         Widget w )
1843 #endif /* _NO_PROTO */
1844 {
1845    Display *display = XtDisplay(w);
1846    Screen *screen = XtScreen(w);
1847 
1848    XDeleteContext(display, (Window)screen, _XmDataFDNDContext);
1849 }
1850 
1851 
1852 Widget
1853 #ifdef _NO_PROTO
_XmDataFieldGetDropReciever(w)1854 _XmDataFieldGetDropReciever( w )
1855         Widget w ;
1856 #else
1857 _XmDataFieldGetDropReciever(
1858         Widget w )
1859 #endif /* _NO_PROTO */
1860 {
1861    Widget widget;
1862 
1863    if (_XmDataFDNDContext == 0) return NULL;
1864 
1865    if (!XFindContext(XtDisplay(w), (Window) XtScreen(w),
1866                      _XmDataFDNDContext, (char **) &widget)) {
1867       return widget;
1868    }
1869 
1870    return NULL;
1871 }
1872 
1873 
1874 
1875 static TextFGCData
1876 #ifdef _NO_PROTO
df_GetTextFGCData(w)1877 df_GetTextFGCData( w )
1878         Widget w ;
1879 #else
1880 df_GetTextFGCData(
1881         Widget w )
1882 #endif /* _NO_PROTO */
1883 {
1884    static TextFGCData gc_data;
1885    Display *display = XtDisplay(w);
1886    Screen *screen = XtScreen(w);
1887 
1888    if (_XmDataFGCContext == 0)
1889       _XmDataFGCContext = XUniqueContext();
1890 
1891    if (XFindContext(display, (Window)screen,
1892                     _XmDataFGCContext, (char **)&gc_data)) {
1893        XmTextContextData ctx_data;
1894        Widget xm_display = (Widget) XmGetXmDisplay(display);
1895 
1896        ctx_data = (XmTextContextData) XtMalloc(sizeof(XmTextContextDataRec));
1897 
1898        ctx_data->screen = screen;
1899        ctx_data->context = _XmDataFGCContext;
1900        ctx_data->type = _XM_IS_GC_DATA_CTX;
1901 
1902        gc_data = (TextFGCData) XtCalloc(1, sizeof(TextFGCDataRec));
1903 
1904        XtAddCallback(xm_display, XmNdestroyCallback,
1905                      (XtCallbackProc) df_FreeContextData, (XtPointer) ctx_data);
1906 
1907        XSaveContext(display, (Window)screen, _XmDataFGCContext,
1908 		    (XPointer)gc_data);
1909        gc_data->tf = (XmDataFieldWidget) w;
1910    }
1911 
1912    if (gc_data->tf == NULL) gc_data->tf = (XmDataFieldWidget) w;
1913 
1914    return gc_data;
1915 }
1916 
1917 void
1918 #ifdef _NO_PROTO
_XmDataFToggleCursorGC(widget)1919 _XmDataFToggleCursorGC( widget )
1920         Widget widget;
1921 #else
1922 _XmDataFToggleCursorGC(
1923         Widget widget )
1924 #endif /* _NO_PROTO */
1925 {
1926     XmDataFieldWidget tf = (XmDataFieldWidget) widget;
1927     XGCValues values;
1928     unsigned long valuemask = GCFillStyle|GCFunction|GCForeground|GCBackground;
1929 
1930     if (!XtIsRealized(widget)) return;
1931 
1932     if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
1933 
1934 #ifdef FIX_1501
1935     if (!XtIsSensitive(widget)) {
1936       valuemask = GCForeground|GCBackground|GCFillStyle|GCStipple|GCFunction;
1937       values.foreground = _XmAssignInsensitiveColor((Widget)tf);
1938       values.background = tf->core.background_pixel;
1939       values.fill_style = FillStippled;
1940 
1941       if (XmTextF_overstrike(tf)) {
1942         if (XmTextF_stipple_tile(tf) == XmUNSPECIFIED_PIXMAP) return;
1943         values.stipple = XmTextF_stipple_tile(tf);
1944         values.function = GXxor;
1945       } else {
1946         if (XmTextF_cursor(tf) == XmUNSPECIFIED_PIXMAP) return;
1947         values.stipple = XmTextF_cursor(tf);
1948         values.function = GXcopy;
1949       }
1950     } else {
1951 #endif
1952     if (XmTextF_overstrike(tf)) {
1953       if (!XmTextF_add_mode(tf) && XtIsSensitive(widget) &&
1954 	  (XmTextF_has_focus(tf) || XmTextF_has_destination(tf))) {
1955 	values.fill_style = FillSolid;
1956       } else {
1957 	values.fill_style = FillTiled;
1958       }
1959       values.foreground = values.background =
1960 	tf->primitive.foreground ^ tf->core.background_pixel;
1961       values.function = GXxor;
1962     } else {
1963       if (XtIsSensitive(widget) && !XmTextF_add_mode(tf) &&
1964 	  (XmTextF_has_focus(tf) || XmTextF_has_destination(tf))) {
1965 	if (XmTextF_cursor(tf) == XmUNSPECIFIED_PIXMAP) return;
1966 	values.stipple = XmTextF_cursor(tf);
1967       } else {
1968 	if (XmTextF_add_mode_cursor(tf) == XmUNSPECIFIED_PIXMAP) return;
1969 	values.stipple = XmTextF_add_mode_cursor(tf);
1970       }
1971       values.fill_style = FillStippled;
1972       values.function = GXcopy;
1973       if (XmTextF_have_inverted_image_gc(tf)){
1974 	values.background = tf->primitive.foreground;
1975 	values.foreground = tf->core.background_pixel;
1976       } else {
1977 	values.foreground = tf->primitive.foreground;
1978 	values.background = tf->core.background_pixel;
1979       }
1980       valuemask |= GCStipple;
1981     }
1982 #ifdef FIX_1501
1983     }
1984 #endif
1985     XChangeGC(XtDisplay(widget), XmTextF_image_gc(tf), valuemask, &values);
1986 }
1987 
1988 /*
1989  * Find the highlight record corresponding to the given position.  Returns a
1990  * pointer to the record.  The third argument indicates whether we are probing
1991  * the left or right edge of a highlighting range.
1992  */
1993 static _XmHighlightRec *
1994 #ifdef _NO_PROTO
df_FindHighlight(w,position)1995 df_FindHighlight( w, position )
1996         XmDataFieldWidget w ;
1997         XmTextPosition position ;
1998 #else
1999 df_FindHighlight(
2000         XmDataFieldWidget w,
2001         XmTextPosition position )
2002 #endif /* _NO_PROTO */
2003 {
2004     _XmHighlightRec *l = XmTextF_highlight(w).list;
2005     int i;
2006 
2007     for (i=XmTextF_highlight(w).number - 1 ; i>=0 ; i--)
2008         if (position >= l[i].position) {
2009             l = l + i;
2010             break;
2011         }
2012 
2013     return(l);
2014 }
2015 
2016 static void
2017 #ifdef _NO_PROTO
df_InsertHighlight(w,position,mode)2018 df_InsertHighlight( w, position, mode )
2019         XmDataFieldWidget w ;
2020         XmTextPosition position ;
2021         XmHighlightMode mode ;
2022 #else
2023 df_InsertHighlight(
2024         XmDataFieldWidget w,
2025         XmTextPosition position,
2026         XmHighlightMode mode )
2027 #endif /* _NO_PROTO */
2028 {
2029     _XmHighlightRec *l1;
2030     _XmHighlightRec *l = XmTextF_highlight(w).list;
2031     int i, j;
2032 
2033     l1 = df_FindHighlight(w, position);
2034     if (l1->position == position)
2035        l1->mode = mode;
2036     else {
2037        i = (l1 - l) + 1;
2038        XmTextF_highlight(w).number++;
2039        if (XmTextF_highlight(w).number > XmTextF_highlight(w).maximum) {
2040           XmTextF_highlight(w).maximum = XmTextF_highlight(w).number;
2041           l = XmTextF_highlight(w).list = (_XmHighlightRec *)XtRealloc((char *) l,
2042               (unsigned)(XmTextF_highlight(w).maximum * sizeof(_XmHighlightRec)));
2043        }
2044        for (j=XmTextF_highlight(w).number-1 ; j>i ; j--)
2045            l[j] = l[j-1];
2046        l[i].position = position;
2047        l[i].mode = mode;
2048     }
2049 }
2050 
2051 static void
2052 #ifdef _NO_PROTO
DataFieldSetHighlight(tf,left,right,mode)2053 DataFieldSetHighlight( tf, left, right, mode )
2054         XmDataFieldWidget tf ;
2055         XmTextPosition left ;
2056         XmTextPosition right ;
2057         XmHighlightMode mode ;
2058 #else
2059 DataFieldSetHighlight(
2060         XmDataFieldWidget tf,
2061         XmTextPosition left,
2062         XmTextPosition right,
2063         XmHighlightMode mode )
2064 #endif /* _NO_PROTO */
2065 {
2066     _XmHighlightRec *l;
2067     XmHighlightMode endmode;
2068     int i, j;
2069 
2070     if (left >= right || right <= 0) return;
2071 
2072     _XmDataFieldDrawInsertionPoint(tf, False);
2073     endmode = df_FindHighlight(tf, right)->mode;
2074     df_InsertHighlight(tf, left, mode);
2075     df_InsertHighlight(tf, right, endmode);
2076     l = XmTextF_highlight(tf).list;
2077     i = 1;
2078     while (i < XmTextF_highlight(tf).number) {
2079         if (l[i].position >= left && l[i].position < right)
2080             l[i].mode = mode;
2081         if (l[i].mode == l[i-1].mode) {
2082             XmTextF_highlight(tf).number--;
2083             for (j=i ; j<XmTextF_highlight(tf).number ; j++)
2084                 l[j] = l[j+1];
2085         } else i++;
2086     }
2087     if (XmTextF_cursor_position(tf) > left && XmTextF_cursor_position(tf) < right){
2088        if (mode == XmHIGHLIGHT_SELECTED){
2089           df_InvertImageGC(tf);
2090        } else if (mode != XmHIGHLIGHT_SELECTED){
2091           df_ResetImageGC(tf);
2092        }
2093     }
2094     XmTextF_refresh_ibeam_off(tf) = True;
2095     _XmDataFieldDrawInsertionPoint(tf, True);
2096 }
2097 
2098 /*
2099  * Get x and y based on position.
2100  */
2101 static Boolean
2102 #ifdef _NO_PROTO
df_GetXYFromPos(tf,position,x,y)2103 df_GetXYFromPos( tf, position, x, y )
2104         XmDataFieldWidget tf ;
2105         XmTextPosition position ;
2106         Position *x ;
2107         Position *y ;
2108 #else
2109 df_GetXYFromPos(
2110         XmDataFieldWidget tf,
2111         XmTextPosition position,
2112         Position *x,
2113         Position *y )
2114 #endif /* _NO_PROTO */
2115 {
2116     int	x1, x2;
2117 
2118     /* initialize the x and y positions to zero */
2119     if (XmDataField_alignment(tf) == XmALIGNMENT_BEGINNING)
2120     {
2121 	*x = 0;
2122 	*y = 0;
2123 
2124 	if (position > XmTextF_string_length(tf)) return False;
2125 
2126 	if (XmTextF_max_char_size(tf) != 1) {
2127 	    x1 = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf), (int)position);
2128 	} else {
2129 	    x1 = df_FindPixelLength(tf, XmTextF_value(tf), (int)position);
2130 	}
2131     }
2132     else
2133     {
2134 	int	length;
2135 
2136 	*x = tf->core.width - (XmTextF_margin_width(tf) +
2137 			       tf->primitive.highlight_thickness +
2138 			       tf->primitive.shadow_thickness);
2139 	*y = 0;
2140 
2141 	length = XmTextF_string_length(tf) - position;
2142 
2143 	if (length < 0) return False;
2144 
2145 	if (XmTextF_max_char_size(tf) != 1) {
2146 	    x1 = df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + position),
2147 				 length);
2148 	} else {
2149 	    x1 = df_FindPixelLength(tf, XmTextF_value(tf) + position, length);
2150 	}
2151     }
2152 
2153     *y += tf->primitive.highlight_thickness + tf->primitive.shadow_thickness
2154 	  + XmTextF_margin_top(tf) + XmTextF_font_ascent(tf);
2155     x2 = (Position) XmTextF_h_offset(tf);
2156 
2157     if (XmDataField_alignment(tf) == XmALIGNMENT_BEGINNING)
2158     {
2159 	*x += x1 + x2;
2160     }
2161     else
2162     {
2163 	*x -= (x1 - x2);
2164     }
2165 
2166     return True;
2167 }
2168 
2169 static Boolean
2170 #ifdef _NO_PROTO
df_CurrentCursorState(tf)2171 df_CurrentCursorState( tf )
2172         XmDataFieldWidget tf ;
2173 #else
2174 df_CurrentCursorState(
2175         XmDataFieldWidget tf )
2176 #endif /* _NO_PROTO */
2177 {
2178     if (XmTextF_cursor_on(tf) < 0) return False;
2179     if (XmTextF_blink_on(tf) || !XtIsSensitive((Widget)tf))
2180         return True;
2181     return False;
2182 }
2183 
2184 /*
2185  * Paint insert cursor
2186  */
2187 static void
2188 #ifdef _NO_PROTO
df_PaintCursor(tf)2189 df_PaintCursor( tf )
2190         XmDataFieldWidget tf ;
2191 #else
2192 df_PaintCursor(
2193         XmDataFieldWidget tf )
2194 #endif /* _NO_PROTO */
2195 {
2196     Position x, y;
2197     XmTextPosition position;
2198 
2199     if (!XmTextF_cursor_position_visible(tf)) return;
2200 
2201     if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
2202 
2203     position = XmTextF_cursor_position(tf);
2204     (void) df_GetXYFromPos(tf, position, &x, &y);
2205 
2206     if (!XmTextF_overstrike(tf))
2207       x -=(XmTextF_cursor_width(tf) >> 1) + 1; /* "+1" for 1 pixel left of char */
2208     else {
2209       int pxlen;
2210       if (XmTextF_max_char_size(tf) != 1)
2211 	pxlen = df_FindPixelLength(tf, (char*)&(XmTextF_wc_value(tf)[position]), 1);
2212       else
2213 	pxlen = df_FindPixelLength(tf, &(XmTextF_value(tf)[position]), 1);
2214       if (pxlen > XmTextF_cursor_width(tf))
2215 	x += (pxlen - XmTextF_cursor_width(tf)) >> 1;
2216     }
2217     y = (y + (Position) XmTextF_font_descent(tf)) -
2218 	 (Position) XmTextF_cursor_height(tf);
2219 
2220 /* If time to paint the I Beam... first capture the IBeamOffArea, then draw
2221  * the IBeam */
2222 
2223     if (XmTextF_refresh_ibeam_off(tf) == True){ /* get area under IBeam first */
2224       /* Fill is needed to realign clip rectangle with gc */
2225        XFillRectangle(XtDisplay((Widget)tf), XtWindow((Widget)tf),
2226                          XmTextF_save_gc(tf), 0, 0, 0, 0);
2227 
2228        XCopyArea(XtDisplay(tf), XtWindow(tf), XmTextF_ibeam_off(tf),
2229 		 XmTextF_save_gc(tf), x, y, XmTextF_cursor_width(tf),
2230 		 XmTextF_cursor_height(tf), 0, 0);
2231        XmTextF_refresh_ibeam_off(tf) = False;
2232     }
2233 
2234     if ((XmTextF_cursor_on(tf) >= 0) && XmTextF_blink_on(tf)) {
2235 #ifdef FIX_1501
2236        if (!XtIsSensitive((Widget) tf)) {
2237           df_XmSetShadowGC(tf, XmTextF_image_gc(tf));
2238           XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_image_gc(tf), x + 1, y + 1,
2239                          XmTextF_cursor_width(tf), XmTextF_cursor_height(tf));
2240        }
2241        _XmDataFToggleCursorGC((Widget) tf);
2242 #endif
2243        XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_image_gc(tf), x, y,
2244 		      XmTextF_cursor_width(tf), XmTextF_cursor_height(tf));
2245     } else {
2246        XCopyArea(XtDisplay(tf), XmTextF_ibeam_off(tf), XtWindow(tf),
2247 		 XmTextF_save_gc(tf), 0, 0, XmTextF_cursor_width(tf),
2248 		 XmTextF_cursor_height(tf), x, y);
2249     }
2250 }
2251 
2252 void
2253 #ifdef _NO_PROTO
_XmDataFieldDrawInsertionPoint(tf,turn_on)2254 _XmDataFieldDrawInsertionPoint( tf, turn_on )
2255         XmDataFieldWidget tf ;
2256         Boolean turn_on ;
2257 #else
2258 _XmDataFieldDrawInsertionPoint(
2259         XmDataFieldWidget tf,
2260         Boolean turn_on )
2261 #endif /* _NO_PROTO */
2262 {
2263 
2264     if (turn_on == True) {
2265        XmTextF_cursor_on(tf) += 1;
2266        if (XmTextF_blink_rate(tf) == 0 || !XmTextF_has_focus(tf))
2267 	  XmTextF_blink_on(tf) = True;
2268     } else {
2269        if (XmTextF_blink_on(tf) && (XmTextF_cursor_on(tf) == 0))
2270 	  if (XmTextF_blink_on(tf) == df_CurrentCursorState(tf) &&
2271 	      XtIsRealized((Widget)tf)){
2272 	     XmTextF_blink_on(tf) = !XmTextF_blink_on(tf);
2273              df_PaintCursor(tf);
2274        }
2275        XmTextF_cursor_on(tf) -= 1;
2276     }
2277 
2278     if (XmTextF_cursor_on(tf) < 0 || !XtIsRealized((Widget) tf))
2279         return;
2280 
2281     df_PaintCursor(tf);
2282 }
2283 
2284 static void
2285 #ifdef _NO_PROTO
df_BlinkInsertionPoint(tf)2286 df_BlinkInsertionPoint( tf )
2287         XmDataFieldWidget tf ;
2288 #else
2289 df_BlinkInsertionPoint(
2290         XmDataFieldWidget tf )
2291 #endif /* _NO_PROTO */
2292 {
2293     if ((XmTextF_cursor_on(tf) >= 0) &&
2294 	XmTextF_blink_on(tf) == df_CurrentCursorState(tf) &&
2295 	XtIsRealized((Widget)tf)) {
2296        XmTextF_blink_on(tf) = !XmTextF_blink_on(tf);
2297        df_PaintCursor(tf);
2298     }
2299 }
2300 
2301 
2302 
2303 /*
2304  * Handle blink on and off
2305  */
2306 /* ARGSUSED */
2307 static void
2308 #ifdef _NO_PROTO
df_HandleTimer(closure,id)2309 df_HandleTimer( closure, id )
2310         XtPointer closure ;
2311         XtIntervalId *id ;
2312 #else
2313 df_HandleTimer(
2314         XtPointer closure,
2315         XtIntervalId *id )
2316 #endif /* _NO_PROTO */
2317 {
2318     XmDataFieldWidget tf = (XmDataFieldWidget) closure;
2319 
2320     if (XmTextF_blink_rate(tf) != 0)
2321         XmTextF_timer_id(tf) =
2322 		 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tf),
2323 				 (unsigned long)XmTextF_blink_rate(tf),
2324                                  df_HandleTimer,
2325                                  (XtPointer) closure);
2326     if (XmTextF_has_focus(tf) && XtIsSensitive((Widget)tf))
2327 	df_BlinkInsertionPoint(tf);
2328 }
2329 
2330 
2331 /*
2332  * Change state of blinking insert cursor on and off
2333  */
2334 static void
2335 #ifdef _NO_PROTO
df_ChangeBlinkBehavior(tf,turn_on)2336 df_ChangeBlinkBehavior( tf, turn_on )
2337         XmDataFieldWidget tf ;
2338         Boolean turn_on ;
2339 #else
2340 df_ChangeBlinkBehavior(
2341         XmDataFieldWidget tf,
2342 #if NeedWidePrototypes
2343         int turn_on )
2344 #else
2345         Boolean turn_on )
2346 #endif /* NeedWidePrototypes */
2347 #endif /* _NO_PROTO */
2348 {
2349 
2350     if (turn_on) {
2351         if (XmTextF_blink_rate(tf) != 0 && XmTextF_timer_id(tf) == (XtIntervalId)0)
2352             XmTextF_timer_id(tf) =
2353                 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tf),
2354 			        (unsigned long)XmTextF_blink_rate(tf),
2355                                 df_HandleTimer,
2356                                 (XtPointer) tf);
2357         XmTextF_blink_on(tf) = True;
2358     } else {
2359         if (XmTextF_timer_id(tf))
2360             XtRemoveTimeOut(XmTextF_timer_id(tf));
2361         XmTextF_timer_id(tf) = (XtIntervalId)0;
2362     }
2363 }
2364 
2365 static void
2366 #ifdef _NO_PROTO
df_GetRect(tf,rect)2367 df_GetRect( tf, rect )
2368         XmDataFieldWidget tf ;
2369         XRectangle *rect ;
2370 #else
2371 df_GetRect(
2372         XmDataFieldWidget tf,
2373         XRectangle *rect )
2374 #endif /* _NO_PROTO */
2375 {
2376   Dimension margin_width = XmTextF_margin_width(tf) +
2377 	                   tf->primitive.shadow_thickness +
2378 			   tf->primitive.highlight_thickness;
2379   Dimension margin_top = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
2380 			 tf->primitive.highlight_thickness;
2381   Dimension margin_bottom = XmTextF_margin_bottom(tf) +
2382 			    tf->primitive.shadow_thickness +
2383 			    tf->primitive.highlight_thickness;
2384 
2385   if (margin_width < tf->core.width)
2386      rect->x = margin_width;
2387   else
2388      rect->x = tf->core.width;
2389 
2390   if (margin_top  < tf->core.height)
2391      rect->y = margin_top;
2392   else
2393      rect->y = tf->core.height;
2394 
2395   if ((int)(2 * margin_width) < (int)tf->core.width)
2396      rect->width = (int) tf->core.width - (2 * margin_width);
2397   else
2398      rect->width = 0;
2399 
2400   if ((int)(margin_top + margin_bottom) < (int)tf->core.height)
2401      rect->height = (int) tf->core.height - (margin_top + margin_bottom);
2402   else
2403      rect->height = 0;
2404 }
2405 
2406 static void
2407 #ifdef _NO_PROTO
df_CheckHasRect(tf)2408 df_CheckHasRect( tf )
2409         XmDataFieldWidget tf ;
2410 #else
2411 df_CheckHasRect(
2412         XmDataFieldWidget tf )
2413 #endif /* _NO_PROTO */
2414 {
2415  /*
2416   * Make sure the cached GC has the clipping rectangle
2417   * set to the current widget.
2418   */
2419   if (!XmTextF_has_rect(tf)) {
2420      TextFGCData gc_data = df_GetTextFGCData((Widget)tf);
2421      XmTextF_has_rect(gc_data->tf) = False;
2422      gc_data->tf = tf;
2423      XmTextF_has_rect(tf) = True;
2424   }
2425 }
2426 
2427 static void
2428 #ifdef _NO_PROTO
df_XmSetFullGC(tf,gc)2429 df_XmSetFullGC( tf, gc )
2430         XmDataFieldWidget tf ;
2431         GC gc ;
2432 #else
2433 df_XmSetFullGC(
2434         XmDataFieldWidget tf,
2435         GC gc )
2436 #endif /* _NO_PROTO */
2437 {
2438   XRectangle ClipRect;
2439 
2440  /* adjust clip rectangle to allow the cursor to paint into the margins */
2441   ClipRect.x = tf->primitive.shadow_thickness +
2442                tf->primitive.highlight_thickness;
2443   ClipRect.y = tf->primitive.shadow_thickness +
2444                tf->primitive.highlight_thickness;
2445   ClipRect.width = tf->core.width - (2 * (tf->primitive.shadow_thickness +
2446                                           tf->primitive.highlight_thickness));
2447   ClipRect.height = tf->core.height - (2 * (tf->primitive.shadow_thickness +
2448                                            tf->primitive.highlight_thickness));
2449 
2450   XSetClipRectangles(XtDisplay(tf), gc, 0, 0, &ClipRect, 1,
2451                      Unsorted);
2452 }
2453 
2454 static void
2455 #ifdef _NO_PROTO
df_XmSetMarginGC(tf,gc)2456 df_XmSetMarginGC( tf, gc )
2457         XmDataFieldWidget tf ;
2458         GC gc ;
2459 #else
2460 df_XmSetMarginGC(
2461         XmDataFieldWidget tf,
2462         GC gc )
2463 #endif /* _NO_PROTO */
2464 {
2465   XRectangle ClipRect;
2466 
2467   df_GetRect(tf, &ClipRect);
2468 #ifdef USE_XFT
2469   if (XmTextF_use_xft(tf))
2470     _XmXftSetClipRectangles(XtDisplay(tf), XtWindow(tf), 0, 0, &ClipRect, 1);
2471 #endif
2472   XSetClipRectangles(XtDisplay(tf), gc, 0, 0, &ClipRect, 1,
2473                      Unsorted);
2474 }
2475 
2476 
2477 static void
2478 #ifdef _NO_PROTO
df_XmResetSaveGC(tf,gc)2479 df_XmResetSaveGC( tf, gc )
2480         XmDataFieldWidget tf ;
2481         GC gc ;
2482 #else
2483 df_XmResetSaveGC(
2484         XmDataFieldWidget tf,
2485         GC gc )
2486 #endif /* _NO_PROTO */
2487 {
2488   XSetClipMask(XtDisplay(tf), gc, None);
2489 }
2490 
2491 /*
2492  * Set new clipping rectangle for text field.  This is
2493  * done on each focus in event since the text field widgets
2494  * share the same GC.
2495  */
2496 void
2497 #ifdef _NO_PROTO
_XmDataFieldSetClipRect(tf)2498 _XmDataFieldSetClipRect( tf )
2499         XmDataFieldWidget tf ;
2500 #else
2501 _XmDataFieldSetClipRect(
2502         XmDataFieldWidget tf )
2503 #endif /* _NO_PROTO */
2504 {
2505   XGCValues values;
2506   unsigned long valuemask = (unsigned long) 0;
2507 
2508 
2509  /*
2510   * Make sure the cached GC has the clipping rectangle
2511   * set to the current widget.
2512   */
2513   df_CheckHasRect(tf);
2514 
2515   df_XmSetMarginGC(tf, XmTextF_gc(tf));
2516   df_XmSetFullGC(tf, XmTextF_image_gc(tf));
2517 
2518   df_ResetClipOrigin(tf, False);
2519 
2520 
2521  /* Restore cached save gc to state correct for this instantiation */
2522   if (XmTextF_save_gc(tf)){
2523      valuemask = (GCFunction | GCBackground | GCForeground);
2524      values.function = GXcopy;
2525      values.foreground = tf->primitive.foreground ;
2526      values.background = tf->core.background_pixel;
2527      XChangeGC(XtDisplay(tf), XmTextF_save_gc(tf), valuemask, &values);
2528   }
2529 
2530  /* Restore cached text gc to state correct for this instantiation */
2531 
2532   if (XmTextF_gc(tf)){
2533 #if USE_XFT
2534      if (!XmTextF_have_fontset(tf) && !XmTextF_use_xft(tf)
2535          && (XmTextF_font(tf) != NULL)) {
2536 #else
2537      if (!XmTextF_have_fontset(tf) && (XmTextF_font(tf) != NULL)){
2538 #endif
2539         valuemask |= GCFont;
2540         values.font = XmTextF_font(tf)->fid;
2541      }
2542      valuemask |= GCGraphicsExposures;
2543      values.graphics_exposures = (Bool) True;
2544      values.foreground = tf->primitive.foreground ^ tf->core.background_pixel;
2545      values.background = 0;
2546      XChangeGC(XtDisplay(tf), XmTextF_gc(tf), valuemask, &values);
2547   }
2548 
2549  /* Restore cached image gc to state correct for this instantiation */
2550   if (XmTextF_image_gc(tf)){
2551      valuemask = (GCForeground | GCBackground);
2552      if (XmTextF_overstrike(tf)) {
2553        values.background = values.foreground =
2554 	 tf->core.background_pixel ^ tf->primitive.foreground;
2555      } else if (XmTextF_have_inverted_image_gc(tf)){
2556        values.background = tf->primitive.foreground;
2557        values.foreground = tf->core.background_pixel;
2558      } else {
2559        values.foreground = tf->primitive.foreground;
2560        values.background = tf->core.background_pixel;
2561      }
2562      XChangeGC(XtDisplay(tf), XmTextF_image_gc(tf), valuemask, &values);
2563   }
2564 
2565   _XmDataFToggleCursorGC((Widget)tf);
2566 }
2567 
2568 static void
2569 #ifdef _NO_PROTO
df_XmSetNormGC(tf,gc,change_stipple,stipple)2570 df_XmSetNormGC( tf, gc, change_stipple, stipple )
2571         XmDataFieldWidget tf ;
2572         GC gc ;
2573 	Boolean change_stipple;
2574 	Boolean stipple;
2575 #else
2576 df_XmSetNormGC(
2577         XmDataFieldWidget tf,
2578         GC gc,
2579 #if NeedWidePrototypes
2580 	int change_stipple,
2581         int stipple)
2582 #else
2583 	Boolean change_stipple,
2584         Boolean stipple)
2585 #endif /* NeedWidePrototypes */
2586 #endif /* _NO_PROTO */
2587 {
2588     unsigned long valueMask = (GCForeground | GCBackground);
2589     XGCValues values;
2590 
2591     if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
2592     values.foreground = tf->primitive.foreground;
2593     values.background = tf->core.background_pixel;
2594     if (change_stipple) {
2595 #ifdef FIX_1381
2596        valueMask |= GCFillStyle;
2597        if (stipple) {
2598           /*generally gray insensitive foreground (instead stipple)*/
2599           values.foreground = _XmAssignInsensitiveColor((Widget)tf);
2600           values.fill_style = FillSolid;
2601        } else values.fill_style = FillSolid;
2602 #else
2603        valueMask |= GCTile | GCFillStyle;
2604        values.tile = XmTextF_stipple_tile(tf);
2605        if (stipple) values.fill_style = FillTiled;
2606        else values.fill_style = FillSolid;
2607 #endif
2608     }
2609 
2610     XChangeGC(XtDisplay(tf), gc, valueMask, &values);
2611 }
2612 
2613 #ifdef FIX_1381
2614 static void
2615 #ifdef _NO_PROTO
df_XmSetShadowGC(tf,gc)2616 df_XmSetShadowGC( tf, gc )
2617         XmDataFieldWidget tf ;
2618         GC gc ;
2619 #else
2620 df_XmSetShadowGC(
2621         XmDataFieldWidget tf,
2622         GC gc )
2623 #endif /* _NO_PROTO */
2624 {
2625     unsigned long valueMask = (GCForeground | GCBackground);
2626     XGCValues values;
2627 
2628     values.foreground = tf->primitive.top_shadow_color;
2629     values.background = tf->core.background_pixel;
2630 
2631     XChangeGC(XtDisplay(tf), gc, valueMask, &values);
2632 }
2633 #endif
2634 
2635 static void
2636 #ifdef _NO_PROTO
df_XmSetInvGC(tf,gc)2637 df_XmSetInvGC( tf, gc )
2638         XmDataFieldWidget tf ;
2639         GC gc ;
2640 #else
2641 df_XmSetInvGC(
2642         XmDataFieldWidget tf,
2643         GC gc )
2644 #endif /* _NO_PROTO */
2645 {
2646     unsigned long valueMask = (GCForeground | GCBackground);
2647     XGCValues values;
2648 
2649     if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
2650     values.foreground = tf->core.background_pixel;
2651     values.background = tf->primitive.foreground;
2652 
2653     XChangeGC(XtDisplay(tf), gc, valueMask, &values);
2654 }
2655 
2656 static void
2657 #ifdef _NO_PROTO
df_DrawText(tf,gc,x,y,string,length)2658 df_DrawText( tf, gc, x, y, string, length )
2659         XmDataFieldWidget tf ;
2660         GC gc ;
2661         int x ;
2662         int y ;
2663         char * string ;
2664         int length ;
2665 #else
2666 df_DrawText(
2667         XmDataFieldWidget tf,
2668         GC  gc,
2669         int x,
2670         int y,
2671         char * string,
2672         int length )
2673 #endif /* _NO_PROTO */
2674 {
2675    if (XmTextF_have_fontset(tf)){
2676       if (XmTextF_max_char_size(tf) != 1)
2677          XwcDrawString (XtDisplay(tf), XtWindow(tf), (XFontSet)XmTextF_font(tf),
2678 			gc, x, y, (wchar_t*) string, length);
2679 
2680       else  /* one byte chars */
2681          XmbDrawString (XtDisplay(tf), XtWindow(tf), (XFontSet)XmTextF_font(tf),
2682 			gc, x, y, string, length);
2683 
2684 #ifdef USE_XFT
2685   } else if (XmTextF_use_xft(tf)) {
2686     if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t*  */
2687       char stack_cache[400], *tmp;
2688       wchar_t tmp_wc;
2689       wchar_t *wc_string = (wchar_t*)string;
2690       int num_bytes = 0;
2691       /* ptr = tmp = XtMalloc((int)(length + 1)*sizeof(wchar_t)); */
2692       tmp = (char *)XmStackAlloc((Cardinal) ((length + 1)*sizeof(wchar_t)),
2693 				 stack_cache);
2694       tmp_wc = wc_string[length];
2695       wc_string[length] = 0L;
2696       num_bytes = wcstombs(tmp, wc_string,
2697 			   (int)((length + 1) * sizeof(wchar_t)));
2698       wc_string[length] = tmp_wc;
2699       if (num_bytes >= 0)
2700         _XmXftDrawString2(XtDisplay(tf), XtWindow(tf), gc, XmTextF_xft_font(tf),
2701 			1, x, y, tmp, num_bytes);
2702       XmStackFree(tmp, stack_cache);
2703     } else /* one byte chars */
2704         _XmXftDrawString2(XtDisplay(tf), XtWindow(tf), gc, XmTextF_xft_font(tf),
2705 			1, x, y, string, length);
2706 #endif
2707    } else { /* have a font struct, not a font set */
2708       if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t*  */
2709 	 char stack_cache[400], *tmp;
2710 	 wchar_t tmp_wc;
2711 	 wchar_t *wc_string = (wchar_t*)string;
2712 	 int num_bytes = 0;
2713 	 /* ptr = tmp = XtMalloc((int)(length + 1)*sizeof(wchar_t)); */
2714 	 tmp = (char *)XmStackAlloc((Cardinal) ((length + 1)*sizeof(wchar_t)),
2715 				    stack_cache);
2716 	 tmp_wc = wc_string[length];
2717 	 wc_string[length] = 0L;
2718 	 num_bytes = wcstombs(tmp, wc_string,
2719 			      (int)((length + 1) * sizeof(wchar_t)));
2720 	 wc_string[length] = tmp_wc;
2721 	 if (num_bytes >= 0) {
2722 	   if (_XmIsISO10646(XtDisplay(tf), XmTextF_font(tf))) {
2723              size_t str_len = 0;
2724 	     XChar2b *str = _XmUtf8ToUcs2(tmp, num_bytes, &str_len);
2725 	     XDrawString16(XtDisplay(tf), XtWindow(tf), gc, x, y,
2726 			     str, str_len);
2727 	     XFree(str);
2728 	   } else
2729              XDrawString(XtDisplay(tf), XtWindow(tf), gc, x, y,
2730 			     tmp, num_bytes);
2731 	 }
2732 	 XmStackFree((char *)tmp, stack_cache);
2733       } else /* one byte chars */
2734          XDrawString (XtDisplay(tf), XtWindow(tf), gc, x, y, string, length);
2735    }
2736 }
2737 
2738 static int
2739 #ifdef _NO_PROTO
df_FindPixelLength(tf,string,length)2740 df_FindPixelLength( tf, string, length)
2741         XmDataFieldWidget tf ;
2742         char * string ;
2743         int length ;
2744 #else
2745 df_FindPixelLength(
2746         XmDataFieldWidget tf,
2747         char * string,
2748         int length )
2749 #endif /* _NO_PROTO */
2750 {
2751    if (XmTextF_have_fontset(tf)) {
2752       if (XmTextF_max_char_size(tf) != 1)
2753          return (XwcTextEscapement((XFontSet)XmTextF_font(tf),
2754                                    (wchar_t *) string, length));
2755       else /* one byte chars */
2756          return (XmbTextEscapement((XFontSet)XmTextF_font(tf), string, length));
2757 #ifdef USE_XFT
2758   } else if (XmTextF_use_xft(tf)) {
2759     XGlyphInfo	ext;
2760     if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t*  */
2761       wchar_t *wc_string = (wchar_t*)string;
2762       wchar_t wc_tmp = wc_string[length];
2763       char stack_cache[400], *tmp;
2764       int num_bytes;
2765 
2766       wc_string[length] = 0L;
2767       tmp = (char*)XmStackAlloc((Cardinal)((length + 1) * sizeof(wchar_t)),
2768 				stack_cache);
2769       num_bytes = wcstombs(tmp, wc_string,
2770 			   (int)((length + 1)*sizeof(wchar_t)));
2771       wc_string[length] = wc_tmp;
2772       XftTextExtentsUtf8(XtDisplay(tf), XmTextF_xft_font(tf),
2773           (FcChar8*)tmp, num_bytes, &ext);
2774       XmStackFree(tmp, stack_cache);
2775     } else /* one byte chars */
2776       XftTextExtentsUtf8(XtDisplay(tf), XmTextF_xft_font(tf),
2777           (FcChar8*)string, length, &ext);
2778 
2779     return ext.xOff;
2780 #endif
2781    } else { /* have font struct, not a font set */
2782       if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t*  */
2783 	 wchar_t *wc_string = (wchar_t*)string;
2784 	 wchar_t wc_tmp = wc_string[length];
2785 	 char stack_cache[400], *tmp;
2786 	 int num_bytes, ret_len = 0;
2787 
2788 	 wc_string[length] = 0L;
2789          tmp = (char*)XmStackAlloc((Cardinal)((length + 1) * sizeof(wchar_t)),
2790 				   stack_cache);
2791          num_bytes = wcstombs(tmp, wc_string,
2792 			      (int)((length + 1)*sizeof(wchar_t)));
2793 	 wc_string[length] = wc_tmp;
2794 	 if (num_bytes >= 0) {
2795 	   if (_XmIsISO10646(XtDisplay(tf), XmTextF_font(tf))) {
2796 	     size_t str_len = 0;
2797 	     XChar2b *str = _XmUtf8ToUcs2(tmp, num_bytes, &str_len);
2798 	     ret_len = XTextWidth16(XmTextF_font(tf), str, str_len);
2799 	     XFree(str);
2800 	   } else
2801             ret_len = XTextWidth(XmTextF_font(tf), tmp, num_bytes);
2802 	 }
2803          XmStackFree((char *)tmp, stack_cache);
2804 	 return (ret_len);
2805       } else /* one byte chars */
2806          return (XTextWidth(XmTextF_font(tf), string, length));
2807    }
2808 }
2809 
2810 static void
2811 #ifdef _NO_PROTO
df_DrawTextSegment(tf,mode,prev_seg_start,seg_start,seg_end,next_seg,stipple,y,x)2812 df_DrawTextSegment( tf, mode, prev_seg_start, seg_start, seg_end, next_seg,
2813 		 stipple, y, x)
2814         XmDataFieldWidget tf ;
2815         XmHighlightMode mode;
2816 	XmTextPosition prev_seg_start;
2817 	XmTextPosition seg_start;
2818 	XmTextPosition seg_end;
2819 	XmTextPosition next_seg;
2820 	Boolean stipple;
2821         int y ;
2822         int *x ;
2823 #else
2824 df_DrawTextSegment(
2825         XmDataFieldWidget tf,
2826         XmHighlightMode mode,
2827 	XmTextPosition prev_seg_start,
2828 	XmTextPosition seg_start,
2829 	XmTextPosition seg_end,
2830 	XmTextPosition next_seg,
2831 #if NeedWidePrototypes
2832         int stipple,
2833 #else
2834         Boolean stipple,
2835 #endif /* NeedWidePrototypes */
2836         int y,
2837         int *x)
2838 #endif /* _NO_PROTO */
2839 {
2840     int x_seg_len;
2841 
2842 #if PWC_DEBUG
2843     {
2844 	char seg[256];
2845 
2846 	memset((char *)seg, 256, 0);
2847 	strncpy(seg, (char *)(XmTextF_value(tf) + seg_start),
2848 		seg_end - seg_start);
2849 
2850 	seg[seg_end] = '\0';
2851 
2852 	printf("df_DrawText(\"%s\" - %s) :: [start(%d), end(%d), x(%d), offset(%d)]\n",
2853 	       seg, (mode == XmHIGHLIGHT_NORMAL ? "NORMAL" : "HIGHLIGHT"),
2854 	       seg_start, seg_end, *x, XmTextF_h_offset(tf));
2855     }
2856 #endif
2857 
2858     /* update x position up to start position */
2859     if (XmTextF_max_char_size(tf) != 1) {
2860        *x += df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + prev_seg_start),
2861                                  (int)(seg_start - prev_seg_start));
2862        x_seg_len = df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + seg_start),
2863                                            (int)seg_end - (int)seg_start);
2864     } else {
2865        *x += df_FindPixelLength(tf, XmTextF_value(tf) + prev_seg_start,
2866                                  (int)(seg_start - prev_seg_start));
2867        x_seg_len = df_FindPixelLength(tf, XmTextF_value(tf) + seg_start,
2868                                            (int)seg_end - (int)seg_start);
2869     }
2870     if (mode == XmHIGHLIGHT_SELECTED) {
2871       /* Draw the selected text using an inverse gc */
2872        df_XmSetNormGC(tf, XmTextF_gc(tf), False, False);
2873        XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), *x,
2874 		      y - XmTextF_font_ascent(tf), x_seg_len,
2875 		      XmTextF_font_ascent(tf) + XmTextF_font_descent(tf));
2876        df_XmSetInvGC(tf, XmTextF_gc(tf));
2877     } else {
2878        df_XmSetInvGC(tf, XmTextF_gc(tf));
2879        XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), *x,
2880 		      y - XmTextF_font_ascent(tf), x_seg_len,
2881 		      XmTextF_font_ascent(tf) + XmTextF_font_descent(tf));
2882        df_XmSetNormGC(tf, XmTextF_gc(tf), True, stipple);
2883     }
2884 
2885 #ifdef FIX_1381
2886     if (stipple) {
2887        /*Draw shadow for insensitive text*/
2888        df_XmSetShadowGC(tf, XmTextF_gc(tf));
2889        if (tf->text.max_char_size != 1) {
2890           df_DrawText(tf, XmTextF_gc(tf), *x + 1, y + 1, (char*) (XmTextF_wc_value(tf) + seg_start),
2891                                               (int)seg_end - (int)seg_start);
2892        } else {
2893            df_DrawText(tf, XmTextF_gc(tf), *x + 1, y + 1, XmTextF_value(tf) + seg_start,
2894                                               (int)seg_end - (int)seg_start);
2895        }
2896        df_XmSetNormGC(tf, XmTextF_gc(tf), True, stipple);
2897     }
2898 #endif
2899 
2900     if (XmTextF_max_char_size(tf) != 1) {
2901        df_DrawText(tf, XmTextF_gc(tf), *x, y, (char*) (XmTextF_wc_value(tf) + seg_start),
2902                                            (int)seg_end - (int)seg_start);
2903     } else {
2904        df_DrawText(tf, XmTextF_gc(tf), *x, y, XmTextF_value(tf) + seg_start,
2905                                            (int)seg_end - (int)seg_start);
2906     }
2907     if (stipple) df_XmSetNormGC(tf, XmTextF_gc(tf), True, !stipple);
2908 
2909     if (mode == XmHIGHLIGHT_SECONDARY_SELECTED)
2910        XDrawLine(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), *x, y,
2911                               *x + x_seg_len - 1, y);
2912 
2913    /* update x position up to the next highlight position */
2914     if (XmTextF_max_char_size(tf) != 1)
2915        *x += df_FindPixelLength(tf, (char*) (XmTextF_wc_value(tf) + seg_start),
2916 				    (int)(next_seg - (int)seg_start));
2917     else
2918        *x += df_FindPixelLength(tf, XmTextF_value(tf) + seg_start,
2919 				    (int)(next_seg - (int)seg_start));
2920 }
2921 
2922 
2923 /*
2924  * Redisplay the new adjustments that have been made the the text
2925  * field widget.
2926  */
2927 static void
2928 #ifdef _NO_PROTO
df_RedisplayText(tf,start,end)2929 df_RedisplayText( tf, start, end )
2930         XmDataFieldWidget tf ;
2931         XmTextPosition start ;
2932         XmTextPosition end ;
2933 #else
2934 df_RedisplayText(
2935         XmDataFieldWidget tf,
2936         XmTextPosition start,
2937         XmTextPosition end )
2938 #endif /* _NO_PROTO */
2939 {
2940   _XmHighlightRec *l = XmTextF_highlight(tf).list;
2941   XRectangle rect;
2942   int x, y, i, startx = 0;
2943   Dimension margin_width = XmTextF_margin_width(tf) +
2944 	                   tf->primitive.shadow_thickness +
2945 			   tf->primitive.highlight_thickness;
2946   Dimension margin_top = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
2947 			 tf->primitive.highlight_thickness;
2948   Dimension margin_bottom = XmTextF_margin_bottom(tf) +
2949 	                    tf->primitive.shadow_thickness +
2950 			    tf->primitive.highlight_thickness;
2951   Boolean stipple = False;
2952 
2953   if (!XtIsRealized((Widget)tf)) return;
2954 
2955   if (XmTextF_in_setvalues(tf)) {
2956      XmTextF_redisplay(tf) = True;
2957      return;
2958   }
2959 
2960   if ((int)tf->core.width - (int)(2 * margin_width) <= 0)
2961     return;
2962   if ((int)tf->core.height - (int)(margin_top + margin_bottom) <= 0)
2963     return;
2964 
2965  /*
2966   * Make sure the cached GC has the clipping rectangle
2967   * set to the current widget.
2968   */
2969   if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
2970 
2971   _XmDataFieldDrawInsertionPoint(tf, False);
2972 
2973  /* Get the current rectangle.
2974   */
2975   df_GetRect(tf, &rect);
2976 
2977   y = margin_top + XmTextF_font_ascent(tf);
2978 
2979   if (XmDataField_alignment(tf) == XmALIGNMENT_END)
2980   {
2981       x = tf->core.width - margin_width + XmTextF_h_offset(tf);
2982 
2983       if (XmTextF_max_char_size(tf) != 1)
2984 	  x -= df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + l[0].position),
2985 			       XmTextF_string_length(tf) - l[0].position);
2986       else
2987 	  x -= df_FindPixelLength(tf, XmTextF_value(tf) + l[0].position,
2988 			       XmTextF_string_length(tf) - l[0].position);
2989 
2990       /* PWC - alignment requires we draw all characters to the left of end */
2991       start = 0;
2992       startx = x;
2993   }
2994   else
2995       x = (int) XmTextF_h_offset(tf);
2996 
2997   if (!XtIsSensitive((Widget)tf)) stipple = True;
2998 
2999   /* search through the highlight array and draw the text */
3000   for (i = 0; i + 1 < XmTextF_highlight(tf).number; i++) {
3001 #if PWC_DEBUG
3002       printf("XmTextF_value(\"%s\")::Highlight #%d = pos(%d), start(%d), end(%d)\n",
3003 	     (char *)XmTextF_value(tf), i, l[i].position, start, end);
3004 #endif
3005      /* make sure start is within current highlight */
3006       if (l[i].position <= start && start < l[i+1].position &&
3007           l[i].position < end) {
3008 
3009          if (end > l[i+1].position) {
3010 
3011 	    df_DrawTextSegment(tf, l[i].mode, l[i].position, start,
3012 			    l[i+1].position, l[i+1].position, stipple, y, &x);
3013 
3014            /* update start position to the next highlight position */
3015             start = l[i+1].position;
3016 
3017          } else {
3018 
3019 	    df_DrawTextSegment(tf, l[i].mode, l[i].position, start,
3020 			    end, l[i+1].position, stipple, y, &x);
3021             start = end;
3022          }
3023       }
3024       else
3025       { /* start not within current record */
3026 	  if (XmTextF_max_char_size(tf) != 1)
3027 	  {
3028 	      x += df_FindPixelLength(tf, (char *) (XmTextF_wc_value(tf)
3029 						 + l[i].position),
3030 				   (int)(l[i+1].position - l[i].position));
3031 	  }
3032 	  else
3033 	  {
3034 	      x += df_FindPixelLength(tf, XmTextF_value(tf) + l[i].position,
3035 				   (int)(l[i+1].position - l[i].position));
3036 	  }
3037      }
3038   }  /* end for loop */
3039 
3040   if (l[i].position < end)
3041   {
3042       /* complete the drawing of the text to the end of the line */
3043       df_DrawTextSegment(tf, l[i].mode, l[i].position, start, end,
3044 		      XmTextF_string_length(tf), stipple, y, &x);
3045   } else {
3046       if (XmTextF_max_char_size(tf) != 1)
3047 	 x += df_FindPixelLength(tf, (char*) (XmTextF_wc_value(tf) + l[i].position),
3048 			      XmTextF_string_length(tf) - (int)l[i].position);
3049      else
3050 	 x += df_FindPixelLength(tf, XmTextF_value(tf) + l[i].position,
3051 			      XmTextF_string_length(tf) - (int)l[i].position);
3052   }
3053 
3054   if (x < (int)(rect.x + rect.width)
3055       && XmDataField_alignment(tf) == XmALIGNMENT_BEGINNING) {
3056     df_XmSetInvGC(tf, XmTextF_gc(tf));
3057     XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), x, rect.y,
3058                     rect.x + rect.width - x, rect.height);
3059   } else if (XmTextF_h_offset(tf) < startx
3060         && XmDataField_alignment(tf) == XmALIGNMENT_END) {
3061     df_XmSetInvGC(tf, XmTextF_gc(tf));
3062     XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), XmTextF_h_offset(tf), rect.y,
3063                     startx - XmTextF_h_offset(tf), rect.height);
3064   }
3065 
3066   XmTextF_refresh_ibeam_off(tf) = True;
3067   _XmDataFieldDrawInsertionPoint(tf, True);
3068 }
3069 
3070 
3071 /*
3072  * Use the font along with the resources that have been set
3073  * to determine the height and width of the text field widget.
3074  */
3075 static void
3076 #ifdef _NO_PROTO
df_ComputeSize(tf,width,height)3077 df_ComputeSize( tf, width, height )
3078         XmDataFieldWidget tf ;
3079         Dimension *width ;
3080         Dimension *height ;
3081 #else
3082 df_ComputeSize(
3083         XmDataFieldWidget tf,
3084         Dimension *width,
3085         Dimension *height )
3086 #endif /* _NO_PROTO */
3087 {
3088     Dimension tmp = 0;
3089 
3090     if (XmTextF_resize_width(tf) &&
3091 	XmTextF_columns(tf) < XmTextF_string_length(tf)){
3092 
3093        if (XmTextF_max_char_size(tf) != 1)
3094           tmp = df_FindPixelLength(tf, (char *)XmTextF_wc_value(tf),
3095 	                        XmTextF_string_length(tf));
3096        else
3097           tmp = df_FindPixelLength(tf, XmTextF_value(tf), XmTextF_string_length(tf));
3098 
3099 
3100        *width = tmp + (2 * (XmTextF_margin_width(tf) +
3101 			    tf->primitive.shadow_thickness +
3102 			    tf->primitive.highlight_thickness));
3103     } else {
3104 	*width = XmTextF_columns(tf) * XmTextF_average_char_width(tf) +
3105 	    2 * (XmTextF_margin_width(tf) + tf->primitive.shadow_thickness +
3106 		 tf->primitive.highlight_thickness);
3107     }
3108 
3109     if (height != NULL)
3110 	*height = XmTextF_font_descent(tf) + XmTextF_font_ascent(tf) +
3111 	    2 * (XmTextF_margin_height(tf) + tf->primitive.shadow_thickness +
3112 		 tf->primitive.highlight_thickness);
3113 }
3114 
3115 
3116 /*
3117  * df_TryResize - Attempts to resize the width of the text field widget.
3118  * If the attempt fails or is ineffective, return GeometryNo.
3119  */
3120 static XtGeometryResult
3121 #ifdef _NO_PROTO
df_TryResize(tf,width,height)3122 df_TryResize( tf, width, height )
3123         XmDataFieldWidget tf ;
3124         Dimension width ;
3125         Dimension height ;
3126 #else
3127 df_TryResize(
3128         XmDataFieldWidget tf,
3129 #if NeedWidePrototypes
3130         int width,
3131         int height )
3132 #else
3133         Dimension width,
3134         Dimension height )
3135 #endif /* NeedWidePrototypes */
3136 #endif /* _NO_PROTO */
3137 {
3138     Dimension reswidth, resheight;
3139     Dimension origwidth = tf->core.width;
3140     XtGeometryResult result;
3141 
3142     result = XtMakeResizeRequest((Widget)tf, width, height,
3143                                  &reswidth, &resheight);
3144 
3145     if (result == XtGeometryAlmost) {
3146         result = XtMakeResizeRequest((Widget)tf, reswidth, resheight,
3147 				     &reswidth, &resheight);
3148 
3149         if (reswidth == origwidth)
3150            result = XtGeometryNo;
3151         return result;
3152     }
3153 
3154    /*
3155     * Caution: Some geometry managers return XtGeometryYes
3156     *	        and don't change the widget's size.
3157     */
3158     if (tf->core.width != width && tf->core.height != height)
3159         result = XtGeometryNo;
3160 
3161     return result;
3162 }
3163 
3164 
3165 /*
3166  * Function df_AdjustText
3167  *
3168  * df_AdjustText ensures that the character at the given position is entirely
3169  * visible in the Text Field widget.  If the character is not already entirely
3170  * visible, df_AdjustText changes the Widget's h_offsetring appropriately.  If
3171  * the text must be redrawn, df_AdjustText calls df_RedisplayText.
3172  *
3173  */
3174 static Boolean
3175 #ifdef _NO_PROTO
df_AdjustText(tf,position,flag)3176 df_AdjustText( tf, position, flag )
3177         XmDataFieldWidget tf ;
3178         XmTextPosition position ;
3179         Boolean flag ;
3180 #else
3181 df_AdjustText(
3182         XmDataFieldWidget tf,
3183         XmTextPosition position,
3184 #if NeedWidePrototypes
3185         int flag )
3186 #else
3187         Boolean flag )
3188 #endif /* NeedWidePrototypes */
3189 #endif /* _NO_PROTO */
3190 {
3191   int left_edge = 0;
3192   int diff;
3193   Dimension margin_width = XmTextF_margin_width(tf) +
3194 			      tf->primitive.shadow_thickness +
3195                               tf->primitive.highlight_thickness;
3196   Dimension thickness    = 2 * (tf->primitive.shadow_thickness +
3197                               tf->primitive.highlight_thickness);
3198   Dimension temp;
3199 
3200   if (XmDataField_alignment(tf) == XmALIGNMENT_END)
3201   {
3202     if (XmTextF_max_char_size(tf) != 1)
3203     {
3204       left_edge = tf->core.width - margin_width + XmTextF_h_offset(tf) -
3205                   df_FindPixelLength(tf, (char *)(XmTextF_wc_value(tf) + position),
3206                                   XmTextF_string_length(tf) - (int) position);
3207     }
3208     else
3209     {
3210       left_edge = tf->core.width - margin_width + XmTextF_h_offset(tf) -
3211                   df_FindPixelLength(tf, XmTextF_value(tf) + position,
3212                                   XmTextF_string_length(tf) - (int) position);
3213     }
3214   }
3215   else
3216   {
3217     if (XmTextF_max_char_size(tf) != 1)
3218     {
3219       left_edge = df_FindPixelLength(tf, (char *) XmTextF_wc_value(tf),
3220                                   (int)position) + (int) XmTextF_h_offset(tf);
3221     }
3222     else
3223     {
3224       left_edge = df_FindPixelLength(tf, XmTextF_value(tf), (int)position) +
3225 		                  (int) XmTextF_h_offset(tf);
3226     }
3227   }
3228 
3229  /*
3230   * Make sure the cached GC has the clipping rectangle
3231   * set to the current widget.
3232   */
3233   if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
3234 
3235   if ((diff = left_edge - margin_width) < 0) {
3236     /* We need to scroll the string to the right. */
3237      if (!XtIsRealized((Widget)tf)) {
3238        XmTextF_h_offset(tf) -= diff;
3239        return True;
3240      }
3241      _XmDataFieldDrawInsertionPoint(tf, False);
3242      XmTextF_h_offset(tf) -= diff;
3243      df_XmSetInvGC(tf, XmTextF_gc(tf));
3244      df_XmSetFullGC(tf, XmTextF_gc(tf));
3245      if (tf->core.height <= thickness)
3246        temp = 0;
3247      else
3248        temp = tf->core.height - thickness;
3249      XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf),
3250 		    tf->primitive.shadow_thickness +
3251                     tf->primitive.highlight_thickness,
3252 		    tf->primitive.shadow_thickness +
3253                     tf->primitive.highlight_thickness,
3254                     XmTextF_margin_width(tf),
3255                     temp);
3256      df_XmSetMarginGC(tf, XmTextF_gc(tf));
3257      df_RedisplayText(tf, 0, XmTextF_string_length(tf));
3258      _XmDataFieldDrawInsertionPoint(tf, True);
3259      return True;
3260    } else if ((diff = ( left_edge -
3261 		       (int)(tf->core.width - margin_width))) > 0) {
3262            /* We need to scroll the string to the left. */
3263             if (!XtIsRealized((Widget)tf)) {
3264               XmTextF_h_offset(tf) -= diff;
3265               return True;
3266             }
3267             _XmDataFieldDrawInsertionPoint(tf, False);
3268             XmTextF_h_offset(tf) -= diff;
3269             df_XmSetInvGC(tf, XmTextF_gc(tf));
3270             df_XmSetFullGC(tf, XmTextF_gc(tf));
3271 	    if (tf->core.width <= thickness)
3272 	      temp = 0;
3273 	    else
3274 	      temp = tf->core.width - thickness;
3275             XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf),
3276                            tf->core.width - margin_width,
3277 		           tf->primitive.shadow_thickness +
3278                            tf->primitive.highlight_thickness,
3279                            XmTextF_margin_width(tf),
3280 			   temp);
3281              df_XmSetMarginGC(tf, XmTextF_gc(tf));
3282              df_RedisplayText(tf, 0, XmTextF_string_length(tf));
3283              _XmDataFieldDrawInsertionPoint(tf, True);
3284              return True;
3285   }
3286 
3287   if (flag) df_RedisplayText(tf, position, XmTextF_string_length(tf));
3288 
3289   return False;
3290 }
3291 
3292 /*
3293  * df_AdjustSize
3294  *
3295  * Adjust size will resize the text to ensure that all the text is visible.
3296  * It will also adjust text that is shrunk.  Shrinkage is limited to the
3297  * size determined by the XmNcolumns resource.
3298  */
3299 static void
3300 #ifdef _NO_PROTO
df_AdjustSize(tf)3301 df_AdjustSize( tf )
3302         XmDataFieldWidget tf ;
3303 #else
3304 df_AdjustSize(
3305         XmDataFieldWidget tf )
3306 #endif /* _NO_PROTO */
3307 {
3308   XtGeometryResult result = XtGeometryYes;
3309   int left_edge = 0;
3310   int diff;
3311   Boolean redisplay = False;
3312   Dimension margin_width = XmTextF_margin_width(tf) +
3313 			      tf->primitive.shadow_thickness +
3314                               tf->primitive.highlight_thickness;
3315 
3316   if (XmTextF_max_char_size(tf) != 1) {
3317       left_edge = df_FindPixelLength(tf, (char *) XmTextF_wc_value(tf),
3318 				  XmTextF_string_length(tf)) + margin_width;
3319   } else {
3320       left_edge = df_FindPixelLength(tf, XmTextF_value(tf),
3321 				  XmTextF_string_length(tf)) + margin_width;
3322   }
3323 
3324   if ((diff = (left_edge - (tf->core.width - (margin_width)))) > 0) {
3325      if (XmTextF_in_setvalues(tf)) {
3326 	tf->core.width += diff;
3327 	if (XmDataField_alignment(tf) == XmALIGNMENT_END)
3328 	    XmTextF_new_h_offset(tf) = diff;
3329 	else
3330 	    XmTextF_new_h_offset(tf) = margin_width - diff;
3331 	return;
3332      }
3333     /* Attempt to resize.  If it doesn't succeed, do scrolling.  */
3334      result = df_TryResize(tf, tf->core.width + diff, tf->core.height);
3335      if (result == XtGeometryYes)
3336      {
3337         XtWidgetProc resize;
3338 
3339         _XmProcessLock();
3340         resize = tf->core.widget_class->core_class.resize;
3341         _XmProcessUnlock();
3342 
3343         (*resize)((Widget)tf);
3344         return;
3345      } else
3346 	 /* We need to scroll the string to the left. */
3347 	 if (XmDataField_alignment(tf) == XmALIGNMENT_END)
3348 	     XmTextF_h_offset(tf) = diff;
3349 	 else
3350 	     XmTextF_h_offset(tf) = margin_width - diff;
3351   } else {
3352      Dimension width;
3353 
3354     /* If the new size is smaller than core size, we need
3355      * to shrink.  Note: new size will never be less than the
3356      * width determined by the columns resource.
3357      */
3358      df_ComputeSize(tf, &width, NULL);
3359      if (width < tf->core.width) {
3360         if (XmTextF_in_setvalues(tf)) {
3361 	   tf->core.width = width;
3362 	   return;
3363         }
3364         result = df_TryResize(tf, width, tf->core.height);
3365         if (result == XtGeometryYes)
3366         {
3367            XtWidgetProc resize;
3368 
3369            _XmProcessLock();
3370            resize = tf->core.widget_class->core_class.resize;
3371            _XmProcessUnlock();
3372 
3373            (*resize)((Widget)tf);
3374            return;
3375         }
3376      }
3377   }
3378 
3379   redisplay = df_AdjustText(tf, XmTextF_cursor_position(tf), False);
3380 
3381   if (!redisplay)
3382      df_RedisplayText(tf, 0, XmTextF_string_length(tf));
3383 }
3384 
3385 /* If MB_CUR_MAX == 1, insert is a char* pointer; else, it is a wchar_t *
3386  * pointer and must be appropriately cast.  In all cases, insert_length
3387  * is the number of characters, not the number of bytes pointed to by
3388  * insert
3389  */
3390 static Boolean
3391 #ifdef _NO_PROTO
df_ModifyVerify(tf,event,replace_prev,replace_next,insert,insert_length,newInsert,free_insert)3392 df_ModifyVerify( tf, event, replace_prev, replace_next,
3393 	      insert, insert_length, newInsert, free_insert )
3394         XmDataFieldWidget tf ;
3395         XEvent *event ;
3396         XmTextPosition *replace_prev ;
3397         XmTextPosition *replace_next ;
3398         char **insert ;
3399         int *insert_length ;
3400         XmTextPosition *newInsert ;
3401         int *free_insert ;
3402 #else
3403 df_ModifyVerify(
3404         XmDataFieldWidget tf,
3405         XEvent *event,
3406         XmTextPosition *replace_prev,
3407         XmTextPosition *replace_next,
3408         char **insert,
3409         int *insert_length,
3410         XmTextPosition *newInsert,
3411 	int *free_insert )
3412 #endif /* _NO_PROTO */
3413 {
3414      XmTextVerifyCallbackStruct vcb;
3415      XmTextVerifyCallbackStructWcs wcs_vcb;
3416      XmTextBlockRec newblock;
3417      XmTextBlockRecWcs wcs_newblock;
3418      Boolean do_free = False;
3419      Boolean wcs_do_free = False;
3420      int count;
3421      wchar_t *wptr;
3422 
3423      *newInsert = XmTextF_cursor_position(tf);
3424      *free_insert = (int)False;
3425 
3426     /* if there are no callbacks, don't waste any time... just return  True */
3427      if (!XmTextF_modify_verify_callback(tf) && !XmTextF_wcs_modify_verify_callback(tf))
3428 	return(True);
3429 
3430      newblock.format = XmFMT_8_BIT;
3431      newblock.length = *insert_length * XmTextF_max_char_size(tf);
3432 
3433      if (*insert_length) {
3434 	 if (XmTextF_modify_verify_callback(tf)){
3435             newblock.ptr = (char *) XtMalloc((unsigned) newblock.length +
3436 					     XmTextF_max_char_size(tf));
3437 	    if (XmTextF_max_char_size(tf) == 1) {
3438               (void)memcpy((void*)newblock.ptr, (void*)*insert,
3439 			   newblock.length);
3440 	      newblock.ptr[newblock.length]='\0';
3441 	    } else {
3442 	       count = (int) wcstombs(newblock.ptr, (wchar_t*)*insert,
3443 				                newblock.length);
3444 	       if (count < 0) { /* bad wchar; don't pass anything */
3445 		  newblock.ptr[0] = '\0';
3446 		  newblock.length = 0;
3447 	       } else if (count == newblock.length) {
3448 		  newblock.ptr[newblock.length] = '\0';
3449 	       } else {
3450 		  newblock.ptr[count] = '\0';
3451 		  newblock.length = count;
3452 	       }
3453 	    }
3454             do_free = True;
3455 	 } else
3456             newblock.ptr = NULL;
3457      } else
3458 	newblock.ptr = NULL;
3459 
3460     /* Fill in the appropriate structs */
3461      vcb.reason = XmCR_MODIFYING_TEXT_VALUE;
3462      vcb.event = (XEvent *) event;
3463      vcb.doit = True;
3464      vcb.currInsert = XmTextF_cursor_position(tf);
3465      vcb.newInsert = XmTextF_cursor_position(tf);
3466      vcb.text = &newblock;
3467      vcb.startPos = *replace_prev;
3468      vcb.endPos = *replace_next;
3469 
3470      /* Call the modify verify callbacks. */
3471      if (XmTextF_modify_verify_callback(tf))
3472         XtCallCallbackList((Widget) tf, XmTextF_modify_verify_callback(tf),
3473 			   (XtPointer) &vcb);
3474 
3475      if (XmTextF_wcs_modify_verify_callback(tf) && vcb.doit){
3476 	if (do_free){ /* there is a char* modify verify callback; the data we
3477 		       * want is in vcb struct */
3478 	   wcs_newblock.wcsptr = (wchar_t *) XtMalloc((unsigned)
3479 				      (vcb.text->length + 1) * sizeof(wchar_t));
3480 	   wcs_newblock.length = mbstowcs(wcs_newblock.wcsptr, vcb.text->ptr,
3481 				          vcb.text->length);
3482 	   if (wcs_newblock.length < 0) { /* bad value; don't pass anything */
3483 	      wcs_newblock.wcsptr[0] = 0L;
3484 	      wcs_newblock.length = 0;
3485            } else
3486 	      wcs_newblock.wcsptr[wcs_newblock.length] = 0L;
3487 	} else { /* there was no char* modify verify callback; use data
3488 		  * passed in from caller instead of that in vcb struct. */
3489 	  wcs_newblock.wcsptr = (wchar_t *) XtMalloc((unsigned)
3490 				       (*insert_length + 1) * sizeof(wchar_t));
3491 	  if (XmTextF_max_char_size(tf) == 1)
3492 	    wcs_newblock.length = mbstowcs(wcs_newblock.wcsptr, *insert,
3493 				          *insert_length);
3494 	  else {
3495 	    wcs_newblock.length = *insert_length;
3496 	    (void)memcpy((void*)wcs_newblock.wcsptr, (void*)*insert,
3497 			 *insert_length * sizeof(wchar_t));
3498 	  }
3499 	  if (wcs_newblock.length < 0) { /* bad value; don't pass anything */
3500 	    wcs_newblock.wcsptr[0] = 0L;
3501 	    wcs_newblock.length = 0;
3502 	  } else
3503 	    wcs_newblock.wcsptr[wcs_newblock.length] = 0L;
3504 
3505 	}
3506 	wcs_do_free = True;
3507 	wcs_vcb.reason = XmCR_MODIFYING_TEXT_VALUE;
3508 	wcs_vcb.event = (XEvent *) event;
3509 	wcs_vcb.doit = True;
3510 	wcs_vcb.currInsert = vcb.currInsert;
3511 	wcs_vcb.newInsert = vcb.newInsert;
3512 	wcs_vcb.text = &wcs_newblock;
3513 	wcs_vcb.startPos = vcb.startPos;
3514 	wcs_vcb.endPos = vcb.endPos;
3515 
3516         XtCallCallbackList((Widget) tf, XmTextF_wcs_modify_verify_callback(tf),
3517 			   (XtPointer) &wcs_vcb);
3518 
3519      }
3520 
3521      /*
3522       * copy the newblock.ptr, length, start, and
3523       * end to the pointers passed
3524       */
3525 
3526      if (XmTextF_wcs_modify_verify_callback(tf))
3527      { /* use wcs_vcb data */
3528 	 *insert_length = wcs_vcb.text->length; /* length is char count*/
3529 	 if (wcs_vcb.doit)
3530 	 {
3531 	     if (XmTextF_max_char_size(tf) == 1)
3532 	     { /* caller expects char */
3533 		 wcs_vcb.text->wcsptr[wcs_vcb.text->length] = 0L;
3534 		 if (*insert_length > 0)
3535 		 {
3536 		     *insert = XtMalloc((unsigned) (*insert_length + 1) \
3537 					* sizeof(wchar_t));
3538 		     *free_insert = (int)True;
3539 		     count = wcstombs(*insert, wcs_vcb.text->wcsptr,
3540 				      *insert_length + 1);
3541 		     if (count < 0)
3542 		     {
3543 			 (*insert)[0] = 0;
3544 			 *insert_length = 0;
3545 		     }
3546 		 }
3547 	     }
3548 	     else
3549 	     {  /* callback struct has wchar*; caller expects wchar* */
3550 		 if (*insert_length > 0)
3551 		 {
3552 		     *insert = XtMalloc((unsigned)(*insert_length + 1) \
3553 					* sizeof(wchar_t));
3554 		     *free_insert = (int)True;
3555 		     (void)memcpy((void*)*insert, (void*)wcs_vcb.text->wcsptr,
3556 				  *insert_length * sizeof(wchar_t));
3557 		     wptr = (wchar_t*) *insert;
3558 		     wptr[*insert_length] = 0L;
3559 		 }
3560 	     }
3561 
3562 	     *replace_prev = wcs_vcb.startPos;
3563 	     *replace_next = wcs_vcb.endPos;
3564 	     *newInsert = wcs_vcb.newInsert;
3565 	 }
3566      }
3567      else
3568      { /* use vcb data */
3569 	 if (vcb.doit)
3570 	 {
3571 	     if (XmTextF_max_char_size(tf) == 1)
3572 	     {  /* caller expects char* */
3573 		 *insert_length =  vcb.text->length;
3574 		 if (*insert_length > 0)
3575 		 {
3576 		     *insert = XtMalloc((unsigned) *insert_length + 1);
3577 		     *free_insert = (int)True;
3578 		     (void)memcpy((void*)*insert, (void*)vcb.text->ptr,
3579 				  *insert_length);
3580 		     (*insert)[*insert_length] = 0;
3581 		 }
3582 	     }
3583 	     else
3584 	     {	/* caller expects wchar_t* back */
3585 		 *insert_length =
3586 		     _XmDataFieldCountCharacters(tf, vcb.text->ptr,
3587 						 vcb.text->length);
3588 		 if (*insert_length > 0)
3589 		 {
3590 		     *insert =
3591 			 XtMalloc((unsigned)(*insert_length + 1) *
3592 				  sizeof(wchar_t));
3593 		     *free_insert = (int)True;
3594 		     count = mbstowcs((wchar_t*)*insert, vcb.text->ptr,
3595 				      *insert_length);
3596 		     wptr = (wchar_t*) *insert;
3597 		     if (count < 0) {
3598 			 wptr[0] = 0L;
3599 			 *insert_length = 0;
3600 		     }
3601 		     else
3602 		     {
3603 			 wptr[count] = 0L;
3604 		     }
3605 		 }
3606 	     }
3607 	     *replace_prev = vcb.startPos;
3608 	     *replace_next = vcb.endPos;
3609 	     *newInsert = vcb.newInsert;
3610 	 }
3611      }
3612 
3613      if (do_free) {
3614 	 XtFree(newblock.ptr);
3615      }
3616      if (wcs_do_free) {
3617 	 XtFree((char*)wcs_newblock.wcsptr);
3618      }
3619 
3620      /* If doit becomes False, then don't allow the change. */
3621      if (XmTextF_wcs_modify_verify_callback(tf))
3622         return wcs_vcb.doit;
3623      else
3624         return vcb.doit;
3625 }
3626 
3627 static void
3628 #ifdef _NO_PROTO
df_ResetClipOrigin(tf,clip_mask_reset)3629 df_ResetClipOrigin(tf, clip_mask_reset)
3630 	XmDataFieldWidget tf;
3631 	Boolean clip_mask_reset;
3632 #else /* _NO_PROTO */
3633 df_ResetClipOrigin(
3634 	XmDataFieldWidget tf,
3635 #if NeedWidePrototypes
3636         int clip_mask_reset)
3637 #else
3638         Boolean clip_mask_reset)
3639 #endif /* NeedWidePrototypes */
3640 #endif /* _NO_PROTO */
3641 {
3642    unsigned long valuemask = (GCTileStipXOrigin | GCTileStipYOrigin |
3643 			     GCClipXOrigin | GCClipYOrigin);
3644    XGCValues values;
3645    int x, y, clip_mask_x, clip_mask_y;
3646    Position x_pos, y_pos;
3647    (void) df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &x_pos, &y_pos);
3648 
3649    if (!XtIsRealized((Widget)tf)) return;
3650 
3651    if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
3652    x = (int) x_pos; y = (int) y_pos;
3653 
3654    x -=(XmTextF_cursor_width(tf) >> 1) + 1;
3655 
3656    clip_mask_y = y = (y + XmTextF_font_descent(tf)) - XmTextF_cursor_height(tf);
3657 
3658    if (x < (int)(tf->primitive.highlight_thickness +
3659        tf->primitive.shadow_thickness + XmTextF_margin_width(tf))){
3660 	  clip_mask_x = tf->primitive.highlight_thickness +
3661           tf->primitive.shadow_thickness + (int)(XmTextF_margin_width(tf));
3662    } else
3663      clip_mask_x = x;
3664 
3665    if (clip_mask_reset) {
3666       values.ts_x_origin = x;
3667       values.ts_y_origin = y;
3668       values.clip_x_origin = clip_mask_x;
3669       values.clip_y_origin = clip_mask_y;
3670       XChangeGC(XtDisplay(tf), XmTextF_image_gc(tf), valuemask, &values);
3671    }
3672    else
3673       XSetTSOrigin(XtDisplay(tf), XmTextF_image_gc(tf), x, y);
3674 }
3675 
3676 static void
3677 #ifdef _NO_PROTO
df_InvertImageGC(tf)3678 df_InvertImageGC (tf)
3679 	XmDataFieldWidget tf ;
3680 #else
3681 df_InvertImageGC (
3682 	XmDataFieldWidget tf )
3683 #endif /* _NO_PROTO */
3684 {
3685    unsigned long valuemask = (GCForeground | GCBackground);
3686    XGCValues values;
3687    Display *dpy = XtDisplay(tf);
3688 
3689    if (XmTextF_have_inverted_image_gc(tf)) return;
3690 
3691    if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
3692 
3693    if (!XmTextF_overstrike(tf)) {
3694      values.background = tf->primitive.foreground;
3695      values.foreground = tf->core.background_pixel;
3696 
3697      XChangeGC(dpy, XmTextF_image_gc(tf), valuemask, &values);
3698    }
3699 
3700    XmTextF_have_inverted_image_gc(tf) = True;
3701 }
3702 
3703 static void
3704 #ifdef _NO_PROTO
df_ResetImageGC(tf)3705 df_ResetImageGC (tf)
3706         XmDataFieldWidget tf ;
3707 #else
3708 df_ResetImageGC (
3709         XmDataFieldWidget tf )
3710 #endif /* _NO_PROTO */
3711 {
3712    unsigned long valuemask = (GCForeground | GCBackground);
3713    XGCValues values;
3714    Display *dpy = XtDisplay(tf);
3715 
3716    if (!XmTextF_have_inverted_image_gc(tf)) return;
3717 
3718    if (!XmTextF_has_rect(tf))
3719    {
3720        _XmDataFieldSetClipRect(tf);
3721    }
3722 
3723    if (!XmTextF_overstrike(tf))
3724    {
3725        values.foreground = tf->primitive.foreground;
3726        values.background = tf->core.background_pixel;
3727 
3728        XChangeGC(dpy, XmTextF_image_gc(tf), valuemask, &values);
3729    }
3730 
3731    XmTextF_have_inverted_image_gc(tf) = False;
3732 }
3733 
3734 /*
3735  * Calls the motion verify callback.  If the doit flag is true,
3736  * then reset the cursor_position and call df_AdjustText() to
3737  * move the text if need be.
3738  */
3739 
3740 void
3741 #ifdef _NO_PROTO
_XmDataFielddf_SetCursorPosition(tf,event,position,adjust_flag,call_cb)3742 _XmDataFielddf_SetCursorPosition( tf, event, position,
3743 			      adjust_flag, call_cb)
3744         XmDataFieldWidget tf ;
3745         XEvent *event ;
3746         XmTextPosition position ;
3747         Boolean adjust_flag ;
3748         Boolean call_cb ;
3749 #else
3750 _XmDataFielddf_SetCursorPosition(
3751         XmDataFieldWidget tf,
3752         XEvent *event,
3753         XmTextPosition position,
3754 #if NeedWidePrototypes
3755         int adjust_flag,
3756         int call_cb)
3757 #else
3758         Boolean adjust_flag,
3759         Boolean call_cb)
3760 #endif /* NeedWidePrototypes */
3761 #endif /* _NO_PROTO */
3762 {
3763   df_SetCursorPosition(tf, event, position, adjust_flag, call_cb, True);
3764 }
3765 
3766 static void
3767 #ifdef _NO_PROTO
df_SetCursorPosition(tf,event,position,adjust_flag,call_cb,set_dest)3768 df_SetCursorPosition( tf, event, position,
3769 		  adjust_flag, call_cb, set_dest)
3770         XmDataFieldWidget tf ;
3771         XEvent *event ;
3772         XmTextPosition position ;
3773         Boolean adjust_flag ;
3774         Boolean call_cb ;
3775         Boolean set_dest;
3776 #else
3777 df_SetCursorPosition(
3778         XmDataFieldWidget tf,
3779         XEvent *event,
3780         XmTextPosition position,
3781 #if NeedWidePrototypes
3782         int adjust_flag,
3783         int call_cb,
3784 	int set_dest)
3785 #else
3786         Boolean adjust_flag,
3787         Boolean call_cb,
3788         Boolean set_dest)
3789 #endif /* NeedWidePrototypes */
3790 #endif /* _NO_PROTO */
3791 {
3792     XmTextVerifyCallbackStruct cb;
3793     Boolean flag = False;
3794     XPoint xmim_point;
3795     _XmHighlightRec *hl_list = XmTextF_highlight(tf).list;
3796     int i;
3797 
3798     if (position < 0) position = 0;
3799 
3800     if (position > XmTextF_string_length(tf))
3801        position = XmTextF_string_length(tf);
3802 
3803     if (XmTextF_cursor_position(tf) != position && call_cb) {
3804       /* Call Motion Verify Callback before Cursor Changes Positon */
3805        cb.reason = XmCR_MOVING_INSERT_CURSOR;
3806        cb.event  = event;
3807        cb.currInsert = XmTextF_cursor_position(tf);
3808        cb.newInsert = position;
3809        cb.doit = True;
3810        XtCallCallbackList((Widget) tf, XmTextF_motion_verify_callback(tf),
3811 			  (XtPointer) &cb);
3812 
3813        if (!cb.doit) {
3814           if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
3815 	  return;
3816        }
3817     }
3818     _XmDataFieldDrawInsertionPoint(tf, False);
3819 
3820     XmTextF_cursor_position(tf) = position;
3821 
3822     if (!XmTextF_add_mode(tf) && XmTextF_pending_off(tf) && XmTextF_has_primary(tf)) {
3823        df_SetSelection(tf, position, position, True);
3824        flag = True;
3825     }
3826 
3827    /* Deterimine if we need an inverted image GC or not.  Get the highlight
3828     * record for the cursor position.  If position is on a boundary of
3829     * a highlight, then we always display cursor in normal mode (i.e. set
3830     * normal image GC).  If position is within a selected highlight rec,
3831     * then make sure the image GC is inverted.  If we've moved out of a
3832     * selected highlight region, restore the normal image GC. */
3833 
3834     for (i = XmTextF_highlight(tf).number - 1; i >= 0; i--){
3835        if (position >= hl_list[i].position || i == 0)
3836 	  break;
3837     }
3838 
3839     if (position == hl_list[i].position)
3840        df_ResetImageGC(tf);
3841     else if (hl_list[i].mode != XmHIGHLIGHT_SELECTED)
3842        df_ResetImageGC(tf);
3843     else
3844        df_InvertImageGC(tf);
3845 
3846     if (adjust_flag) (void) df_AdjustText(tf, position, flag);
3847 
3848     df_ResetClipOrigin(tf, False);
3849 
3850     XmTextF_refresh_ibeam_off(tf) = True;
3851     _XmDataFieldDrawInsertionPoint(tf, True);
3852 
3853     (void) df_GetXYFromPos(tf, XmTextF_cursor_position(tf),
3854 			&xmim_point.x, &xmim_point.y);
3855     XmImVaSetValues((Widget)tf, XmNspotLocation, &xmim_point, NULL);
3856 
3857     if (set_dest)
3858       (void) df_SetDestination((Widget) tf, XmTextF_cursor_position(tf), False,
3859 			    XtLastTimestampProcessed(XtDisplay((Widget)tf)));
3860 }
3861 
3862 
3863 /*
3864  * This routine is used to verify that the positions are within the bounds
3865  * of the current DataField widgets value.  Also, it ensures that left is
3866  * less than right.
3867  */
3868 static void
3869 #ifdef _NO_PROTO
df_VerifyBounds(tf,from,to)3870 df_VerifyBounds( tf, from, to )
3871         XmDataFieldWidget tf ;
3872         XmTextPosition *from ;
3873         XmTextPosition *to ;
3874 #else
3875 df_VerifyBounds(
3876         XmDataFieldWidget tf,
3877         XmTextPosition *from,
3878         XmTextPosition *to )
3879 #endif /* _NO_PROTO */
3880 {
3881   XmTextPosition tmp;
3882 
3883     if (*from < 0)
3884        *from = 0;
3885     else if (*from > XmTextF_string_length(tf)) {
3886        *from = XmTextF_string_length(tf);
3887     }
3888     if (*to < 0 )
3889        *to = 0;
3890     else if (*to > XmTextF_string_length(tf)) {
3891        *to = XmTextF_string_length(tf);
3892     }
3893     if (*from > *to) {
3894        tmp = *to;
3895        *to = *from;
3896        *from = tmp;
3897     }
3898 }
3899 
3900 /*
3901  * Function _XmDataFieldReplaceText
3902  *
3903  * _XmDataFieldReplaceText is a utility function for the text-modifying
3904  * action procedures below (df_InsertChar, df_DeletePrevChar, and so on).
3905  * _XmDataFieldReplaceText does the real work of editing the string,
3906  * including:
3907  *
3908  *   (1) invoking the modify verify callbacks,
3909  *   (2) allocating more memory for the string if necessary,
3910  *   (3) doing the string manipulation,
3911  *   (4) moving the selection (the insertion point), and
3912  *   (5) redrawing the text.
3913  *
3914  * Though the procedure claims to take a char* argument, MB_CUR_MAX determines
3915  * what the different routines will actually pass to it.  If MB_CUR_MAX is
3916  * greater than 1, then "insert" points to wchar_t data and we must set up
3917  * the appropriate cast.  In all cases, insert_length is the number of
3918  * characters (not bytes) to be inserted.
3919  */
3920 Boolean
3921 #ifdef _NO_PROTO
_XmDataFieldReplaceText(tf,event,replace_prev,replace_next,insert,insert_length,move_cursor)3922 _XmDataFieldReplaceText( tf, event, replace_prev, replace_next,
3923 		         insert, insert_length, move_cursor )
3924         XmDataFieldWidget tf ;
3925         XEvent *event ;
3926         XmTextPosition replace_prev ;
3927         XmTextPosition replace_next ;
3928         char *insert ;
3929         int insert_length ;
3930 	Boolean move_cursor ;
3931 #else
3932 _XmDataFieldReplaceText(
3933         XmDataFieldWidget tf,
3934         XEvent *event,
3935         XmTextPosition replace_prev,
3936         XmTextPosition replace_next,
3937         char *insert,
3938         int insert_length,
3939 	Boolean move_cursor )
3940 #endif /* _NO_PROTO */
3941 {
3942   int replace_length, i;
3943   char *src, *dst;
3944   wchar_t *wc_src, *wc_dst;
3945   int delta = 0;
3946   XmTextPosition cursorPos, newInsert;
3947   XmTextPosition old_pos = replace_prev;
3948   int free_insert = (int)False;
3949   Position	x1, y1, x2, y2;
3950 
3951   df_VerifyBounds(tf, &replace_prev, &replace_next);
3952 
3953   if (!XmTextF_editable(tf)) {
3954      if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
3955      return False;
3956   }
3957 
3958   replace_length = (int) (replace_next - replace_prev);
3959   delta = insert_length - replace_length;
3960 
3961  /* Disallow insertions that go beyond max length boundries.
3962   */
3963   if ((delta >= 0) &&
3964       ((XmTextF_string_length(tf) + delta) - (XmTextF_max_length(tf)) > 0)) {
3965       if (XmTextF_verify_bell(tf))
3966       {
3967 	  XBell(XtDisplay(tf), 0);
3968       }
3969       return False;
3970   }
3971 
3972   if (XmDataField_alignment(tf) == XmALIGNMENT_END)
3973   {
3974       df_GetXYFromPos(tf, 0, &x1, &y1);
3975   }
3976 
3977  /* If there are modify verify callbacks, verify that we want to continue
3978   * the action.
3979   */
3980   newInsert = XmTextF_cursor_position(tf);
3981 
3982   if (XmTextF_modify_verify_callback(tf) || XmTextF_wcs_modify_verify_callback(tf)) {
3983     /* If the function df_ModifyVerify() returns false then don't
3984      * continue with the action.
3985      */
3986      if (!df_ModifyVerify(tf, event, &replace_prev, &replace_next,
3987 		       &insert, &insert_length, &newInsert, &free_insert)) {
3988         if (XmTextF_verify_bell(tf)) XBell(XtDisplay(tf), 0);
3989 	if (free_insert) XtFree(insert);
3990 	return False;
3991      } else {
3992         df_VerifyBounds(tf, &replace_prev, &replace_next);
3993         replace_length = (int) (replace_next - replace_prev);
3994         delta = insert_length - replace_length;
3995 
3996        /* Disallow insertions that go beyond max length boundries.
3997         */
3998         if ((delta >= 0) &&
3999 	    ((XmTextF_string_length(tf) + delta) - (XmTextF_max_length(tf)) > 0)) {
4000             if (XmTextF_verify_bell(tf)) XBell(XtDisplay(tf), 0);
4001 	    if (free_insert) XtFree(insert);
4002             return False;
4003         }
4004 
4005      }
4006   }
4007 
4008  /* make sure selections are turned off prior to changeing text */
4009   if (XmTextF_has_primary(tf) &&
4010       XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
4011      XmDataFieldSetHighlight((Widget)tf, XmTextF_prim_pos_left(tf),
4012 			     XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
4013 
4014   _XmDataFieldDrawInsertionPoint(tf, False);
4015 
4016   /* Allocate more space if we need it.
4017    */
4018   if (XmTextF_max_char_size(tf) == 1){
4019   if (XmTextF_string_length(tf) + insert_length - replace_length >=
4020       XmTextF_size_allocd(tf))
4021     {
4022       XmTextF_size_allocd(tf) += MAX(insert_length + TEXT_INCREMENT,
4023                                         (XmTextF_size_allocd(tf) * 2));
4024       XmTextF_value(tf) = (char *) XtRealloc((char*)XmTextF_value(tf),
4025 		              (unsigned) (XmTextF_size_allocd(tf) * sizeof(char)));
4026     }
4027   } else {
4028   if ((XmTextF_string_length(tf) + insert_length - replace_length) *
4029                                         sizeof(wchar_t) >= XmTextF_size_allocd(tf))
4030     {
4031       XmTextF_size_allocd(tf) +=
4032 			  MAX((insert_length + TEXT_INCREMENT)*sizeof(wchar_t),
4033                               (XmTextF_size_allocd(tf) * 2));
4034       XmTextF_wc_value(tf) = (wchar_t *) XtRealloc((char*)XmTextF_wc_value(tf),
4035 		           (unsigned) XmTextF_size_allocd(tf));
4036     }
4037   }
4038 
4039   if (XmTextF_has_primary(tf) && replace_prev < XmTextF_prim_pos_right(tf) &&
4040 			      replace_next > XmTextF_prim_pos_left(tf)) {
4041      if (replace_prev <= XmTextF_prim_pos_left(tf)) {
4042 	if (replace_next < XmTextF_prim_pos_right(tf)) {
4043           /* delete encompasses left half of the selection
4044 	   * so move left endpoint
4045            */
4046 	   XmTextF_prim_pos_left(tf) = replace_next;
4047 	} else {
4048           /* delete encompasses the selection so set selection to NULL */
4049 	   XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf);
4050 	}
4051      } else {
4052 	if (replace_next > XmTextF_prim_pos_right(tf)) {
4053 	  /* delete encompasses the right half of the selection
4054 	   * so move right endpoint
4055 	   */
4056 	   XmTextF_prim_pos_right(tf) = replace_next;
4057 	} else {
4058 	  /* delete is completely within the selection
4059 	   * so set selection to NULL
4060 	   */
4061 	   XmTextF_prim_pos_right(tf) = XmTextF_prim_pos_left(tf);
4062 	}
4063      }
4064   }
4065 
4066   if (XmTextF_max_char_size(tf) == 1) {
4067      if (replace_length > insert_length)
4068        /* We need to shift the text at and after replace_next to the left. */
4069        for (src = XmTextF_value(tf) + replace_next,
4070             dst = src + (insert_length - replace_length),
4071             i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
4072             i > 0;
4073             ++src, ++dst, --i)
4074          *dst = *src;
4075      else if (replace_length < insert_length)
4076        /* We need to shift the text at and after replace_next to the right. */
4077        /* Need to add 1 to string_length to handle the NULL terminator on */
4078        /* the string. */
4079        for (src = XmTextF_value(tf) + XmTextF_string_length(tf),
4080             dst = src + (insert_length - replace_length),
4081             i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
4082             i > 0;
4083             --src, --dst, --i)
4084          *dst = *src;
4085 
4086     /* Update the string.
4087      */
4088      if (insert_length != 0) {
4089         for (src = insert,
4090              dst = XmTextF_value(tf) + replace_prev,
4091              i = insert_length;
4092              i > 0;
4093              ++src, ++dst, --i)
4094           *dst = *src;
4095      }
4096    } else {  /* have wchar_t* data */
4097      if (replace_length > insert_length)
4098        /* We need to shift the text at and after replace_next to the left. */
4099        for (wc_src = XmTextF_wc_value(tf) + replace_next,
4100             wc_dst = wc_src + (insert_length - replace_length),
4101             i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
4102             i > 0;
4103             ++wc_src, ++wc_dst, --i)
4104          *wc_dst = *wc_src;
4105      else if (replace_length < insert_length)
4106        /* We need to shift the text at and after replace_next to the right. */
4107        /* Need to add 1 to string_length to handle the NULL terminator on */
4108        /* the string. */
4109        for (wc_src = XmTextF_wc_value(tf) + XmTextF_string_length(tf),
4110             wc_dst = wc_src + (insert_length - replace_length),
4111             i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
4112             i > 0;
4113             --wc_src, --wc_dst, --i)
4114          *wc_dst = *wc_src;
4115 
4116     /* Update the string.
4117      */
4118      if (insert_length != 0) {
4119         for (wc_src = (wchar_t *)insert,
4120              wc_dst = XmTextF_wc_value(tf) + replace_prev,
4121              i = insert_length;
4122              i > 0;
4123              ++wc_src, ++wc_dst, --i)
4124           *wc_dst = *wc_src;
4125      }
4126    }
4127 
4128   if (XmTextF_has_primary(tf) &&
4129       XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
4130      if (replace_prev <= XmTextF_prim_pos_left(tf)) {
4131         XmTextF_prim_pos_left(tf) += delta;
4132         XmTextF_prim_pos_right(tf) += delta;
4133      }
4134      if (XmTextF_prim_pos_left(tf) > XmTextF_prim_pos_right(tf))
4135 	XmTextF_prim_pos_right(tf) = XmTextF_prim_pos_left(tf);
4136   }
4137 
4138  /* make sure the selection are redisplay, since
4139   * they were turned off earlier
4140   */
4141   if (XmTextF_has_primary(tf) &&
4142       XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
4143   {
4144      XmDataFieldSetHighlight((Widget)tf, XmTextF_prim_pos_left(tf),
4145 			     XmTextF_prim_pos_right(tf),
4146 			     XmHIGHLIGHT_SELECTED);
4147   }
4148   XmTextF_string_length(tf) += insert_length - replace_length;
4149 
4150   if (move_cursor) {
4151      if (XmTextF_cursor_position(tf) != newInsert) {
4152         if (newInsert > XmTextF_string_length(tf)) {
4153 	   cursorPos = XmTextF_string_length(tf);
4154 	} else if (newInsert < 0) {
4155            cursorPos = 0;
4156         } else {
4157            cursorPos = newInsert;
4158         }
4159      } else
4160        cursorPos = replace_next + (insert_length - replace_length);
4161      if (event != NULL) {
4162         (void)df_SetDestination((Widget)tf, cursorPos, False, event->xkey.time);
4163      } else {
4164         (void) df_SetDestination((Widget)tf, cursorPos, False,
4165 			      XtLastTimestampProcessed(XtDisplay((Widget)tf)));
4166      }
4167      _XmDataFielddf_SetCursorPosition(tf, event, cursorPos, False, True);
4168   }
4169 
4170   if (XmDataField_alignment(tf) == XmALIGNMENT_END)
4171   {
4172       df_GetXYFromPos(tf, 0, &x2, &y2);
4173 
4174       y2 -= XmTextF_font_ascent(tf);
4175 
4176       if ((x2 > 0) && (x1 < x2) && (y2 < y1))
4177       {
4178           if (x1 < 0) x1 = 0;
4179 
4180           /* PWC - Erase leading space (delta of old & new first position) */
4181           df_XmSetInvGC(tf, XmTextF_gc(tf));
4182           XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf),
4183 	                 x1, y2, x2, y1);
4184 #if PWC_DEBUG
4185           printf("Fill Rectangle :: x1(%d), y1(%d) - x2(%d), y2(%d)\n",
4186                  x1, y2, x2, y1);
4187 #endif
4188       }
4189   }
4190 
4191   if (XmTextF_resize_width(tf) && XmTextF_do_resize(tf))
4192   {
4193      df_AdjustSize(tf);
4194   } else {
4195      df_AdjustText(tf, XmTextF_cursor_position(tf), False);
4196      df_RedisplayText(tf, old_pos, XmTextF_string_length(tf));
4197   }
4198 
4199   _XmDataFieldDrawInsertionPoint(tf, True);
4200   if (free_insert) {
4201       XtFree(insert);
4202   }
4203 
4204   return True;
4205 }
4206 
4207 
4208 /*
4209  * Reset selection flag and selection positions and then display
4210  * the new settings.
4211  */
4212 void
4213 #ifdef _NO_PROTO
_XmDataFieldDeselectSelection(w,disown,sel_time)4214 _XmDataFieldDeselectSelection( w, disown, sel_time )
4215         Widget w ;
4216         Boolean disown ;
4217         Time sel_time ;
4218 #else
4219 _XmDataFieldDeselectSelection(
4220         Widget w,
4221 #if NeedWidePrototypes
4222         int disown,
4223 #else
4224         Boolean disown,
4225 #endif /* NeedWidePrototypes */
4226         Time sel_time )
4227 #endif /* _NO_PROTO */
4228 {
4229   XmDataFieldWidget tf = (XmDataFieldWidget) w;
4230 
4231   if (disown)
4232   {
4233     /*
4234      * Disown the primary selection (This function is a no-op if
4235      * this widget doesn't own the primary selection)
4236      */
4237      XtDisownSelection(w, XA_PRIMARY, sel_time);
4238   }
4239   if (tf != NULL) {
4240      _XmDataFieldDrawInsertionPoint(tf, False);
4241      XmTextF_has_primary(tf) = False;
4242      DataFieldSetHighlight(tf, XmTextF_prim_pos_left(tf),
4243 			   XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
4244      XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf) =
4245 	       XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
4246 
4247      if (!XmTextF_has_focus(tf))
4248      {
4249 	 XmDataFieldSetAddMode(w, False);
4250      }
4251      df_RedisplayText(tf, 0, XmTextF_string_length(tf));
4252 
4253      _XmDataFieldDrawInsertionPoint(tf, True);
4254   }
4255 }
4256 
4257 /*
4258  * Finds the cursor position from the given X value.
4259  */
4260 static XmTextPosition
4261 #ifdef _NO_PROTO
df_GetPosFromX(tf,x)4262 df_GetPosFromX( tf, x )
4263         XmDataFieldWidget tf ;
4264         Position x ;
4265 #else
4266 df_GetPosFromX(
4267         XmDataFieldWidget tf,
4268 #if NeedWidePrototypes
4269         int x )
4270 #else
4271         Position x )
4272 #endif /* NeedWidePrototypes */
4273 #endif /* _NO_PROTO */
4274 {
4275     XmTextPosition position;
4276     int temp_x = 0;
4277     int next_char_width = 0;
4278 
4279     if (XmDataField_alignment(tf) == XmALIGNMENT_END)
4280         return RightAlignedGetPosFromX(tf, x);
4281 
4282    /* Decompose the x to equal the length of the text string */
4283     temp_x += (int) XmTextF_h_offset(tf);
4284 
4285    /* Next width is an offset allowing button presses on the left side
4286     * of a character to select that character, while button presses
4287     * on the rigth side of the character select the  NEXT character.
4288     */
4289 
4290     if (XmTextF_string_length(tf) > 0) {
4291 
4292        if (XmTextF_max_char_size(tf) != 1) {
4293           next_char_width = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf), 1);
4294        } else {
4295           next_char_width = df_FindPixelLength(tf, XmTextF_value(tf), 1);
4296        }
4297     }
4298 
4299     for (position = 0; temp_x + next_char_width/2 < (int) x &&
4300 	               position < XmTextF_string_length(tf); position++){
4301 
4302        temp_x+=next_char_width;    /*
4303 				    * We still haven't reached the x pos.
4304 				    * Add the width and find the next chars
4305 				    * width.
4306 				    */
4307 
4308 	/*
4309 	 * If there is a next position, find its width.  Otherwise, use the
4310 	 * current "next" width.
4311 	 */
4312 
4313        if (XmTextF_string_length(tf) > position + 1) {
4314           if (XmTextF_max_char_size(tf) != 1) {
4315              next_char_width = df_FindPixelLength(tf,
4316 				  (char*)(XmTextF_wc_value(tf) + position + 1), 1);
4317 	  } else {
4318              next_char_width = df_FindPixelLength(tf,
4319 				           XmTextF_value(tf) + position + 1, 1);
4320 	  }
4321        }
4322     } /* for */
4323 
4324     return position;
4325 }
4326 
4327 /*
4328  * Finds the cursor position from the given X value.
4329  */
4330 static XmTextPosition
4331 #ifdef _NO_PROTO
RightAlignedGetPosFromX(tf,x)4332 RightAlignedGetPosFromX( tf, x )
4333     XmDataFieldWidget tf ;
4334     Position x ;
4335 #else
4336 RightAlignedGetPosFromX( XmDataFieldWidget tf,
4337 #if NeedWidePrototypes
4338     int x )
4339 #else
4340     Position x )
4341 #endif /* NeedWidePrototypes */
4342 #endif /* _NO_PROTO */
4343 {
4344     XmTextPosition position;
4345     int margin_width = XmTextF_margin_width(tf) +
4346                         tf->primitive.highlight_thickness +
4347                         tf->primitive.shadow_thickness;
4348     int temp_x;
4349     int next_char_width = 0;
4350 
4351     position = XmTextF_string_length(tf);
4352 
4353     temp_x = tf->core.width - margin_width + XmTextF_h_offset(tf);
4354 
4355     if (XmTextF_string_length(tf) > 0) {
4356 
4357        if (XmTextF_max_char_size(tf) != 1) {
4358           next_char_width = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf) +
4359 					    position - 1, 1);
4360        } else {
4361           next_char_width = df_FindPixelLength(tf, XmTextF_value(tf) +
4362 					    position - 1, 1);
4363        }
4364     }
4365 
4366     for (; x < (temp_x - next_char_width / 2) && (position > 0); position--)
4367     {
4368         temp_x -= next_char_width; /*
4369 				    * We still haven't reached the x pos.
4370 				    * Add the width and find the next chars
4371 				    * width.
4372 				    */
4373 
4374 	/*
4375 	 * If there is a next position, find its width.  Otherwise, use the
4376 	 * current "next" width.
4377 	 */
4378         if (position > 1)
4379         {
4380             if (XmTextF_max_char_size(tf) != 1) {
4381                 next_char_width = df_FindPixelLength(tf,
4382 		    (char*)(XmTextF_wc_value(tf) + position - 2), 1);
4383 	    } else {
4384                 next_char_width = df_FindPixelLength(tf,
4385 		    XmTextF_value(tf) + position - 2 , 1);
4386             }
4387         }
4388     } /* for */
4389 
4390 #if PWC_DEBUG
4391     printf("CursorPos(%d), x(%d)\n", position, x);
4392 #endif
4393 
4394     return position;
4395 }
4396 
4397 /* ARGSUSED */
4398 static Boolean
4399 #ifdef _NO_PROTO
df_SetDestination(w,position,disown,set_time)4400 df_SetDestination( w, position, disown, set_time )
4401         Widget w ;
4402         XmTextPosition position ;
4403         Boolean disown ;
4404         Time set_time ;
4405 #else
4406 df_SetDestination(
4407         Widget w,
4408         XmTextPosition position,
4409 #if NeedWidePrototypes
4410         int disown,
4411 #else
4412         Boolean disown,
4413 #endif /* NeedWidePrototypes */
4414         Time set_time )
4415 #endif /* _NO_PROTO */
4416 {
4417     XmDataFieldWidget tf = (XmDataFieldWidget) w;
4418     Boolean result = TRUE;
4419     Atom MOTIF_DESTINATION = XmInternAtom(XtDisplay(w),
4420                                         "MOTIF_DESTINATION", False);
4421 
4422     if (!XtIsRealized(w)) return False;
4423 
4424     _XmDataFieldDrawInsertionPoint(tf, False);
4425 
4426     if (!disown) {
4427         if (!XmTextF_has_destination(tf)) {
4428 	    if (!set_time) set_time = df_GetServerTime(w);
4429             result = XtOwnSelection(w, MOTIF_DESTINATION, set_time,
4430                                     _XmDataFieldConvert,
4431 				    _XmDataFieldLoseSelection,
4432                                     (XtSelectionDoneProc) NULL);
4433             XmTextF_dest_time(tf) = set_time;
4434             XmTextF_has_destination(tf) = result;
4435 
4436             if (result) _XmSetDestination(XtDisplay(w), w);
4437       	    _XmDataFToggleCursorGC(w);
4438         }
4439     } else {
4440         if (XmTextF_has_destination(tf))
4441 	   if (!set_time) set_time = df_GetServerTime(w);
4442            XtDisownSelection(w, MOTIF_DESTINATION, set_time);
4443 
4444           /* Call XmGetDestination(dpy) to get widget that last had
4445              destination cursor. */
4446            if (w == XmGetDestination(XtDisplay(w)))
4447               _XmSetDestination(XtDisplay(w), (Widget)NULL);
4448 
4449            XmTextF_has_destination(tf) = False;
4450       	   _XmDataFToggleCursorGC(w);
4451     }
4452 
4453     _XmDataFieldDrawInsertionPoint(tf, True);
4454 
4455     return result;
4456 }
4457 
4458 Boolean
4459 #ifdef _NO_PROTO
_XmDataFielddf_SetDestination(w,position,set_time)4460 _XmDataFielddf_SetDestination( w, position, set_time )
4461         Widget w ;
4462         XmTextPosition position ;
4463         Time set_time ;
4464 #else
4465 _XmDataFielddf_SetDestination(
4466         Widget w,
4467         XmTextPosition position,
4468         Time set_time )
4469 #endif /* _NO_PROTO */
4470 {
4471    Boolean result;
4472 
4473    result = df_SetDestination(w, position, False, set_time);
4474 
4475    return result;
4476 }
4477 
4478 
4479 /*
4480  * Calls the losing focus verify callback to verify that the application
4481  * want to traverse out of the text field widget.  Returns the result.
4482  */
4483 static Boolean
4484 #ifdef _NO_PROTO
df_VerifyLeave(tf,event)4485 df_VerifyLeave( tf, event )
4486         XmDataFieldWidget tf ;
4487         XEvent *event ;
4488 #else
4489 df_VerifyLeave(
4490         XmDataFieldWidget tf,
4491         XEvent *event )
4492 #endif /* _NO_PROTO */
4493 {
4494     XmTextVerifyCallbackStruct  cbdata;
4495 
4496     cbdata.reason = XmCR_LOSING_FOCUS;
4497     cbdata.event = event;
4498     cbdata.doit = True;
4499     cbdata.currInsert = XmTextF_cursor_position(tf);
4500     cbdata.newInsert = XmTextF_cursor_position(tf);
4501     cbdata.startPos = XmTextF_cursor_position(tf);
4502     cbdata.endPos = XmTextF_cursor_position(tf);
4503     cbdata.text = NULL;
4504     XtCallCallbackList((Widget) tf, XmTextF_losing_focus_callback(tf),
4505 		       (XtPointer) &cbdata);
4506     return(cbdata.doit);
4507 }
4508 
4509 /* This routine is used to determine if two adjacent wchar_t characters
4510  * constitute a word boundary */
4511 /* ARGSUSED */
4512 static Boolean
4513 #ifdef _NO_PROTO
_XmDataFieldIsWordBoundary(tf,pos1,pos2)4514 _XmDataFieldIsWordBoundary( tf, pos1, pos2 )
4515 	XmDataFieldWidget tf ;
4516 	XmTextPosition pos1 ;
4517 	XmTextPosition pos2 ;
4518 #else
4519 _XmDataFieldIsWordBoundary(
4520 	XmDataFieldWidget tf,
4521 	XmTextPosition pos1 ,
4522 	XmTextPosition pos2 )
4523 #endif /* _NO_PROTO */
4524 {
4525    int size_pos1 = 0;
4526    int size_pos2 = 0;
4527    char s1[MB_LEN_MAX];
4528    char s2[MB_LEN_MAX];
4529 
4530 /* if positions aren't adjacent, return False */
4531    if(pos1 < pos2 && ((pos2 - pos1) != 1))
4532       return False;
4533    else if(pos2 < pos1 && ((pos1 - pos2) != 1))
4534       return False;
4535 
4536    if (XmTextF_max_char_size(tf) == 1) { /* data is char* and one-byte per char */
4537       if (isspace((int)(unsigned char)XmTextF_value(tf)[pos1]) ||
4538 	  isspace((int)(unsigned char)XmTextF_value(tf)[pos2])) return True;
4539    } else {
4540       size_pos1 = wctomb(s1, XmTextF_wc_value(tf)[pos1]);
4541       size_pos2 = wctomb(s2, XmTextF_wc_value(tf)[pos2]);
4542       if (size_pos1 == 1 && (size_pos2 != 1 ||
4543 			     isspace((int)(unsigned char)*s1)))
4544 	return True;
4545       if (size_pos2 == 1 && (size_pos1 != 1 ||
4546 			     isspace((int)(unsigned char)*s2)))
4547 	return True;
4548    }
4549    return False;
4550 }
4551 
4552 /* This routine accepts an array of wchar_t's containing wchar encodings
4553  * of whitespace characters (and the number of array elements), comparing
4554  * the wide character passed to each element of the array.  If a match
4555  * is found, we got a white space.  This routine exists only because
4556  * iswspace(3c) is not yet standard.  If a system has isw* available,
4557  * calls to this routine should be changed to iswspace(3c) (and callers
4558  * should delete initialization of the array), and this routine should
4559  * be deleted.  Its a stop gap measure to avoid allocating an instance
4560  * variable for the white_space array and/or declaring a widget wide
4561  * global for the data and using a macro.  Its ugly, but it works and
4562  * in the long run will be replaced by standard functionality. */
4563 
4564 /* ARGSUSED */
4565 static Boolean
4566 #ifdef _NO_PROTO
_XmDataFieldIsWSpace(wide_char,white_space,num_entries)4567 _XmDataFieldIsWSpace( wide_char, white_space, num_entries )
4568 	wchar_t wide_char ;
4569 	wchar_t * white_space ;
4570 	int num_entries ;
4571 #else
4572 _XmDataFieldIsWSpace(
4573 	wchar_t wide_char,
4574 	wchar_t * white_space ,
4575 	int num_entries )
4576 #endif /* _NO_PROTO */
4577 {
4578    int i;
4579 
4580    for (i=num_entries; i > 0; i--){
4581       if (wide_char == white_space[i]) return True;
4582    }
4583    return False;
4584 }
4585 
4586 static void
4587 #ifdef _NO_PROTO
df_FindWord(tf,begin,left,right)4588 df_FindWord( tf, begin, left, right )
4589         XmDataFieldWidget tf ;
4590         XmTextPosition begin ;
4591         XmTextPosition *left ;
4592         XmTextPosition *right ;
4593 #else
4594 df_FindWord(
4595         XmDataFieldWidget tf,
4596         XmTextPosition begin,
4597         XmTextPosition *left,
4598         XmTextPosition *right )
4599 #endif /* _NO_PROTO */
4600 {
4601     XmTextPosition start, end;
4602     wchar_t white_space[3];
4603 
4604     if (XmTextF_max_char_size(tf) == 1) {
4605        for (start = begin; start > 0; start--) {
4606           if (isspace((int)(unsigned char)XmTextF_value(tf)[start - 1])) {
4607 	     break;
4608           }
4609        }
4610        *left = start;
4611 
4612        for (end = begin; end <= XmTextF_string_length(tf); end++) {
4613           if (isspace((int)(unsigned char)XmTextF_value(tf)[end])) {
4614              end++;
4615              break;
4616           }
4617        }
4618        *right = end - 1;
4619     } else { /* check for iswspace and iswordboundary in each direction */
4620        (void)mbtowc(&white_space[0], " ", 1);
4621        (void)mbtowc(&white_space[1], "\n", 1);
4622        (void)mbtowc(&white_space[2], "\t", 1);
4623        for (start = begin; start > 0; start --) {
4624           if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[start-1],white_space, 3)
4625 	      || _XmDataFieldIsWordBoundary(tf, (XmTextPosition) start - 1,
4626 					    start)) {
4627 		 break;
4628 	  }
4629        }
4630        *left = start;
4631 
4632        for (end = begin; end <= XmTextF_string_length(tf); end++) {
4633 	   if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[end], white_space, 3)){
4634 	      end++;
4635 	      break;
4636 	   } else if (end < XmTextF_string_length(tf)) {
4637 	      if (_XmDataFieldIsWordBoundary(tf, end, (XmTextPosition)end + 1)){
4638 	         end += 2; /* want to return position of next word; end + 1 */
4639 		 break;    /* is that position && *right = end - 1... */
4640               }
4641            }
4642        }
4643        *right = end - 1;
4644    }
4645 }
4646 
4647 static void
4648 #ifdef _NO_PROTO
df_FindPrevWord(tf,left,right)4649 df_FindPrevWord( tf, left, right )
4650         XmDataFieldWidget tf ;
4651         XmTextPosition *left ;
4652         XmTextPosition *right ;
4653 #else
4654 df_FindPrevWord(
4655         XmDataFieldWidget tf,
4656         XmTextPosition *left,
4657         XmTextPosition *right )
4658 #endif /* _NO_PROTO */
4659 {
4660 
4661     XmTextPosition start = XmTextF_cursor_position(tf);
4662     wchar_t white_space[3];
4663 
4664     if (XmTextF_max_char_size(tf) != 1) {
4665        (void)mbtowc(&white_space[0], " ", 1);
4666        (void)mbtowc(&white_space[1], "\n", 1);
4667        (void)mbtowc(&white_space[2], "\t", 1);
4668     }
4669 
4670 
4671     if (XmTextF_max_char_size(tf) == 1) {
4672        if ((start > 0) &&
4673 	   (isspace((int)(unsigned char)XmTextF_value(tf)[start - 1]))) {
4674            for (; start > 0; start--) {
4675                if (!isspace((int)(unsigned char)XmTextF_value(tf)[start - 1])) {
4676                   start--;
4677                   break;
4678                }
4679            }
4680        }
4681        df_FindWord(tf, start, left, right);
4682     } else {
4683        if ((start > 0) && (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[start - 1],
4684 						white_space, 3))) {
4685           for (; start > 0; start--) {
4686 	     if (!_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[start -1],
4687 				       white_space, 3)){
4688 		start--;
4689 		break;
4690              }
4691           }
4692        } else if ((start > 0) &&
4693 		  _XmDataFieldIsWordBoundary(tf, (XmTextPosition) start - 1,
4694 					     start)){
4695           start--;
4696        }
4697        df_FindWord(tf, start, left, right);
4698     }
4699 }
4700 
4701 static void
4702 #ifdef _NO_PROTO
df_FindNextWord(tf,left,right)4703 df_FindNextWord( tf, left, right )
4704         XmDataFieldWidget tf ;
4705         XmTextPosition *left ;
4706         XmTextPosition *right ;
4707 #else
4708 df_FindNextWord(
4709         XmDataFieldWidget tf,
4710         XmTextPosition *left,
4711         XmTextPosition *right )
4712 #endif /* _NO_PROTO */
4713 {
4714 
4715     XmTextPosition end = XmTextF_cursor_position(tf);
4716     wchar_t white_space[3];
4717 
4718     if (XmTextF_max_char_size(tf) != 1) {
4719        (void)mbtowc(&white_space[0], " ", 1);
4720        (void)mbtowc(&white_space[1], "\n", 1);
4721        (void)mbtowc(&white_space[2], "\t", 1);
4722     }
4723 
4724 
4725     if(XmTextF_max_char_size(tf) == 1) {
4726        if (isspace((int)(unsigned char)XmTextF_value(tf)[end])) {
4727            for (end = XmTextF_cursor_position(tf);
4728                 end < XmTextF_string_length(tf); end++) {
4729                if (!isspace((int)(unsigned char)XmTextF_value(tf)[end])) {
4730                   break;
4731                }
4732            }
4733        }
4734        df_FindWord(tf, end, left, right);
4735       /*
4736        * Set right to the last whitespace following the end of the
4737        * current word.
4738        */
4739        while (*right < XmTextF_string_length(tf) &&
4740               isspace((int)(unsigned char)XmTextF_value(tf)[(int)*right]))
4741              *right = *right + 1;
4742        if (*right < XmTextF_string_length(tf))
4743           *right = *right - 1;
4744    } else {
4745       if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[end], white_space, 3)) {
4746 	 for ( ; end < XmTextF_string_length(tf); end ++) {
4747 	   if (!_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[end], white_space, 3)) {
4748 	       break;
4749            }
4750          }
4751       } else { /* if for other reasons at word boundry, advance to next word */
4752 	 if ((end < XmTextF_string_length(tf)) &&
4753 	      _XmDataFieldIsWordBoundary(tf, end, (XmTextPosition) end + 1))
4754 	      end++;
4755       }
4756       df_FindWord(tf, end, left, right);
4757       /*
4758        * If word boundary caused by whitespace, set right to the last
4759        * whitespace following the end of the current word.
4760        */
4761       if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[(int)*right], white_space, 3))      {
4762          while (*right < XmTextF_string_length(tf) &&
4763                _XmDataFieldIsWSpace(XmTextF_wc_value(tf)[(int)*right],
4764 				    white_space, 3)) {
4765             *right = *right + 1;
4766 	 }
4767 	 if (*right < XmTextF_string_length(tf))
4768             *right = *right - 1;
4769       }
4770    }
4771 }
4772 
4773 static void
4774 #ifdef _NO_PROTO
df_CheckDisjointSelection(w,position,sel_time)4775 df_CheckDisjointSelection( w, position, sel_time )
4776         Widget w ;
4777         XmTextPosition position ;
4778         Time sel_time ;
4779 #else
4780 df_CheckDisjointSelection(
4781         Widget w,
4782         XmTextPosition position,
4783         Time sel_time )
4784 #endif /* _NO_PROTO */
4785 {
4786     XmDataFieldWidget tf = (XmDataFieldWidget) w;
4787     XmTextPosition left = 0, right = 0;
4788 
4789     if (XmTextF_add_mode(tf) ||
4790         (XmDataFieldGetSelectionPosition(w, &left, &right) && left != right &&
4791          position >= left && position <= right))
4792        XmTextF_pending_off(tf) = FALSE;
4793     else
4794        XmTextF_pending_off(tf) = TRUE;
4795 
4796     if (left == right) {
4797        (void) df_SetDestination(w, position, False, sel_time);
4798        XmTextF_prim_anchor(tf) = position;
4799     } else {
4800        (void) df_SetDestination(w, position, False, sel_time);
4801        if (!XmTextF_add_mode(tf)) XmTextF_prim_anchor(tf) = position;
4802     }
4803 }
4804 
4805 static Boolean
4806 #ifdef _NO_PROTO
df_NeedsPendingDelete(tf)4807 df_NeedsPendingDelete( tf )
4808         XmDataFieldWidget tf ;
4809 #else
4810 df_NeedsPendingDelete(
4811         XmDataFieldWidget tf )
4812 #endif /* _NO_PROTO */
4813 {
4814    return (XmTextF_add_mode(tf) ?
4815 	   (XmTextF_pending_delete(tf) &&
4816 	    XmTextF_has_primary(tf) &&
4817 	    XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf) &&
4818 	    XmTextF_prim_pos_left(tf) <= XmTextF_cursor_position(tf) &&
4819 	    XmTextF_prim_pos_right(tf) >= XmTextF_cursor_position(tf)) :
4820 	   (XmTextF_has_primary(tf) &&
4821 	    XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)));
4822 }
4823 
4824 static Boolean
4825 #ifdef _NO_PROTO
df_NeedsPendingDeleteDisjoint(tf)4826 df_NeedsPendingDeleteDisjoint( tf )
4827         XmDataFieldWidget tf ;
4828 #else
4829 df_NeedsPendingDeleteDisjoint(
4830         XmDataFieldWidget tf )
4831 #endif /* _NO_PROTO */
4832 {
4833   return (XmTextF_pending_delete(tf) &&
4834 	  XmTextF_has_primary(tf) &&
4835 	  XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf) &&
4836 	  XmTextF_prim_pos_left(tf) <= XmTextF_cursor_position(tf) &&
4837 	  XmTextF_prim_pos_right(tf) >= XmTextF_cursor_position(tf));
4838 }
4839 
4840 static Time
4841 #ifdef _NO_PROTO
df_GetServerTime(w)4842 df_GetServerTime( w )
4843         Widget w ;
4844 #else
4845 df_GetServerTime(
4846         Widget w )
4847 #endif /* _NO_PROTO */
4848 {
4849   XEvent event;
4850   EventMask shellMask;
4851 
4852   while(!XtIsShell(w)) w = XtParent(w);
4853 
4854   shellMask =  XtBuildEventMask(w);
4855 
4856   if (!(shellMask & PropertyChangeMask))
4857      XSelectInput(XtDisplay(w), XtWindow(w),
4858                   (long)(shellMask | PropertyChangeMask));
4859 
4860   XChangeProperty(XtDisplay(w), XtWindow(w), XA_WM_HINTS, XA_WM_HINTS,
4861                   32, PropModeAppend, (unsigned char *)NULL, 0);
4862 
4863 
4864   XWindowEvent(XtDisplay(w), XtWindow(w), PropertyChangeMask, &event);
4865 
4866   if (!(shellMask & PropertyChangeMask))
4867      XSelectInput(XtDisplay(w), XtWindow(w), (long)shellMask);
4868 
4869   return (event.xproperty.time);
4870 }
4871 
4872 static Boolean
PrintableString(XmDataFieldWidget tf,char * str,int n,Boolean use_wchar)4873 PrintableString(XmDataFieldWidget tf,
4874 		char* str,
4875 		int n,
4876 		Boolean use_wchar) /* sometimes unused */
4877 {
4878 #ifdef SUPPORT_ZERO_WIDTH
4879   /* some locales (such as Thai) have characters that are
4880    * printable but non-spacing. These should be inserted,
4881    * even if they have zero width.
4882    */
4883   if (tf->text.max_char_size == 1) {
4884     int i;
4885     if (!use_wchar) {
4886       for (i = 0; i < n; i++) {
4887 	if (!isprint((unsigned char)str[i])) {
4888 	  return False;
4889 	}
4890       }
4891     } else {
4892       char scratch[8];
4893       wchar_t *ws = (wchar_t *) str;
4894       for (i = 0; i < n; i++) {
4895 	if (wctomb(scratch, ws[i]) <= 0)
4896 	  return False;
4897 	if (!isprint((unsigned char)scratch[0])) {
4898 	  return False;
4899 	}
4900       }
4901     }
4902     return True;
4903   } else {
4904     /* tf->text.max_char_size > 1 */
4905 #ifdef HAS_WIDECHAR_FUNCTIONS
4906     if (use_wchar) {
4907       int i;
4908       wchar_t *ws = (wchar_t *) str;
4909       for (i = 0; i < n; i++) {
4910 	if (!iswprint(ws[i])) {
4911 	  return False;
4912 	}
4913       }
4914       return True;
4915     } else {
4916       int i, csize;
4917       wchar_t wc;
4918 #ifndef NO_MULTIBYTE
4919       for (i = 0, csize = mblen(str, tf->text.max_char_size);
4920 	   i < n;
4921 	   i += csize, csize=mblen(&(str[i]), tf->text.max_char_size))
4922 #else
4923       for (i = 0, csize = *str ? 1 : 0; i < n;
4924 	   i += csize, csize = str[i] ? 1 : 0)
4925 #endif
4926 	{
4927 	  if (csize < 0)
4928 	    return False;
4929 	  if (mbtowc(&wc, &(str[i]), tf->text.max_char_size) <= 0)
4930 	    return False;
4931 	  if (!iswprint(wc)) {
4932 	    return False;
4933 	  }
4934 	}
4935     }
4936 #else /* HAS_WIDECHAR_FUNCTIONS */
4937     /*
4938      * This will only check if any single-byte characters are non-
4939      * printable. Better than nothing...
4940      */
4941     int i, csize;
4942     if (!use_wchar) {
4943 #ifndef NO_MULTIBYTE
4944       for (i = 0, csize = mblen(str, tf->text.max_char_size);
4945 	   i < n;
4946 	   i += csize, csize=mblen(&(str[i]), tf->text.max_char_size))
4947 #else
4948       for (i = 0, csize = *str ? 1 : 0; i < n;
4949 	   i += csize, csize = str[i] ? 1 : 0)
4950 #endif
4951 	{
4952 	  if (csize < 0)
4953 	    return False;
4954 	  if (csize == 1 && !isprint((unsigned char)str[i])) {
4955 	    return False;
4956 	  }
4957 	}
4958     } else {
4959       char scratch[8];
4960       wchar_t *ws = (wchar_t *) str;
4961       for (i = 0; i < n; i++) {
4962 	if ((csize = wctomb(scratch, ws[i])) <= 0)
4963 	  return False;
4964 	if (csize == 1 && !isprint((unsigned char)scratch[0])) {
4965 	  return False;
4966 	}
4967       }
4968     }
4969 #endif /* HAS_WIDECHAR_FUNCTIONS */
4970     return True;
4971   }
4972 #else /* SUPPORT_ZERO_WIDTH */
4973   if (TextF_UseFontSet(tf)) {
4974       if(use_wchar)
4975 	  return (XwcTextEscapement((XFontSet)TextF_Font(tf), (wchar_t *)str, n) != 0);
4976       else
4977 	  return (XmbTextEscapement((XFontSet)TextF_Font(tf), str, n) != 0);
4978 #ifdef USE_XFT
4979   } else if (TextF_UseXft(tf)) {
4980     XGlyphInfo	ext;
4981 
4982     XftTextExtentsUtf8(XtDisplay(tf), TextF_XftFont(tf),
4983             (FcChar8*)str, n, &ext);
4984 
4985     return ext.xOff != 0;
4986 #endif
4987   }
4988   else {
4989     if (use_wchar) {
4990       char cache[100];
4991       char *tmp, *cache_ptr;
4992       wchar_t *tmp_str;
4993       int ret_val, buf_size, count;
4994       Boolean is_printable;
4995       buf_size = (n * MB_CUR_MAX) + 1;
4996       cache_ptr = tmp = XmStackAlloc(buf_size, cache);
4997 
4998       tmp_str = (wchar_t *)str;
4999       // Fixed MZ BZ#1257: by Brad Despres <brad@sd.aonix.com>
5000       count = 0;
5001       do {
5002 	ret_val = wctomb(tmp, *tmp_str);
5003 	count += 1;
5004 	tmp += ret_val;
5005 	buf_size -= ret_val;
5006 	tmp_str++;
5007       } while ( (ret_val > 0)&& (buf_size >= MB_CUR_MAX) && (count < n) ) ;
5008       if (ret_val == -1)    /* bad character */
5009 	return (False);
5010       is_printable = XTextWidth(TextF_Font(tf), cache_ptr, tmp - cache_ptr);
5011       XmStackFree(cache_ptr, cache);
5012       return (is_printable);
5013     }
5014     else {
5015       return (XTextWidth(TextF_Font(tf), str, n) != 0);
5016     }
5017   }
5018 #endif /* SUPPORT_ZERO_WIDTH */
5019 }
5020 
5021 /****************************************************************
5022  *
5023  * Input functions defined in the action table.
5024  *
5025  ****************************************************************/
5026 
5027 /* ARGSUSED */
5028 static void
5029 #ifdef _NO_PROTO
df_InsertChar(w,event,params,num_params)5030 df_InsertChar( w, event, params, num_params )
5031         Widget w ;
5032         XEvent *event ;
5033         char **params ;
5034         Cardinal *num_params ;
5035 #else
5036 df_InsertChar(
5037         Widget w,
5038         XEvent *event,
5039         char **params,
5040         Cardinal *num_params )
5041 #endif /* _NO_PROTO */
5042 {
5043   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5044   char insert_string[TEXT_MAX_INSERT_SIZE];
5045   XmTextPosition cursorPos, nextPos;
5046   wchar_t * wc_insert_string;
5047   int insert_length, i;
5048   int num_chars;
5049   Boolean replace_res;
5050   Boolean pending_delete = False;
5051   Status status_return;
5052   XmAnyCallbackStruct cb;
5053 
5054   /* Determine what was pressed.
5055   */
5056   insert_length = XmImMbLookupString(w, (XKeyEvent *) event, insert_string,
5057 		                     TEXT_MAX_INSERT_SIZE, (KeySym *) NULL,
5058 				     &status_return);
5059 
5060   if (insert_length > 0 && !XmTextF_editable(tf)) {
5061      if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
5062      return;
5063   }
5064 
5065  /* If there is more data than we can handle, bail out */
5066   if (status_return == XBufferOverflow || insert_length > TEXT_MAX_INSERT_SIZE)
5067   {
5068      return;
5069   }
5070 
5071  /* *LookupString in some cases can return the NULL as a character, such
5072   * as when the user types <Ctrl><back_quote> or <Ctrl><@>.  Text widget
5073   * can't handle the NULL as a character, so we dump it here.
5074   */
5075 
5076   for (i=0; i < insert_length; i++)
5077      if (insert_string[i] == 0) insert_length = 0; /* toss out input string */
5078 
5079   if (insert_length > 0) {
5080     /* do not insert non-printing characters */
5081     if (!PrintableString(tf, insert_string, insert_length, False))
5082       return;
5083 
5084     _XmDataFieldDrawInsertionPoint(tf, False);
5085     if (df_NeedsPendingDeleteDisjoint(tf)){
5086        if (!XmDataFieldGetSelectionPosition(w, &cursorPos, &nextPos) ||
5087             cursorPos == nextPos) {
5088           XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
5089        }
5090        pending_delete = True;
5091 
5092        XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
5093 
5094     } else {
5095        cursorPos = nextPos = XmTextF_cursor_position(tf);
5096     }
5097 
5098 
5099     if (XmTextF_max_char_size(tf) == 1) {
5100        if (XmTextF_overstrike(tf)) nextPos += insert_length;
5101        if (nextPos > XmTextF_string_length(tf)) nextPos = XmTextF_string_length(tf);
5102        replace_res = _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
5103 					     nextPos, insert_string,
5104 					     insert_length, True);
5105     } else {
5106        char stack_cache[100];
5107        insert_string[insert_length] = '\0'; /* NULL terminate for mbstowcs */
5108        wc_insert_string = (wchar_t*)XmStackAlloc((Cardinal)(insert_length+1) *						     sizeof(wchar_t), stack_cache);
5109        num_chars = mbstowcs( wc_insert_string, insert_string, insert_length+1);
5110        if (XmTextF_overstrike(tf)) nextPos += num_chars;
5111        if (nextPos > XmTextF_string_length(tf)) nextPos = XmTextF_string_length(tf);
5112        replace_res = _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
5113 					     nextPos, (char*) wc_insert_string,
5114 					     num_chars, True);
5115        XmStackFree((char *)wc_insert_string, stack_cache);
5116     }
5117 
5118     if (replace_res) {
5119         if (pending_delete) {
5120            XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
5121                                XmTextF_cursor_position(tf), event->xkey.time);
5122         }
5123         df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5124 			       event->xkey.time);
5125         _XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
5126 				      False, True);
5127         cb.reason = XmCR_VALUE_CHANGED;
5128         cb.event = event;
5129         XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5130 		           (XtPointer) &cb);
5131     }
5132     _XmDataFieldDrawInsertionPoint(tf, True);
5133   }
5134 }
5135 
5136 /* ARGSUSED */
5137 static void
5138 #ifdef _NO_PROTO
df_InsertString(w,event,params,num_params)5139 df_InsertString( w, event, params, num_params )
5140         Widget w ;
5141         XEvent *event ;
5142         char **params ;
5143         Cardinal *num_params ;
5144 #else
5145 df_InsertString(
5146         Widget w,
5147         XEvent *event,
5148         char **params,
5149         Cardinal *num_params )
5150 #endif /* _NO_PROTO */
5151 {
5152   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5153   char insert_string[TEXT_MAX_INSERT_SIZE];
5154   XmTextPosition cursorPos, nextPos;
5155   wchar_t * wc_insert_string;
5156   int insert_length;
5157   int num_chars;
5158   Boolean replace_res;
5159   Boolean pending_delete = False;
5160   register int i;
5161 
5162   if (!XmTextF_editable(tf)) {
5163      if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
5164   }
5165 
5166   for (i = 0; i < *num_params; i++)  {
5167       strcpy(insert_string, params[i]);
5168       insert_length = strlen(insert_string);
5169 
5170       if (insert_length > 0) {
5171 	  /* do not insert non-printing characters */
5172 	  if (XmTextF_have_fontset(tf)){
5173 	      if (!XmbTextEscapement((XFontSet)XmTextF_font(tf), insert_string,
5174 				     insert_length))
5175 		  return;
5176 	  } else {
5177 	      if (!XTextWidth(XmTextF_font(tf), insert_string, insert_length))
5178 		  return;
5179 	  }
5180 
5181 	  _XmDataFieldDrawInsertionPoint(tf, False);
5182 	  if (df_NeedsPendingDeleteDisjoint(tf)){
5183 	      if (!XmDataFieldGetSelectionPosition(w, &cursorPos, &nextPos) ||
5184 		  cursorPos == nextPos) {
5185 		  XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
5186 	      }
5187 	      pending_delete = True;
5188 
5189 	      XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
5190 
5191 	  } else {
5192 	      cursorPos = nextPos = XmTextF_cursor_position(tf);
5193 	  }
5194 
5195 
5196 	  if (XmTextF_overstrike(tf)) {
5197 	      if (nextPos != XmTextF_string_length(tf)) nextPos++;
5198 	  }
5199 	  if (XmTextF_max_char_size(tf) == 1) {
5200 	      replace_res =
5201 		  _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
5202 					  nextPos, insert_string,insert_length,
5203 					  True);
5204 	  } else {
5205 	      insert_string[insert_length] = '\0'; /* NULL terminate for mbstowcs */
5206 	      wc_insert_string = (wchar_t*)XtMalloc((unsigned)(insert_length+1) *						     sizeof(wchar_t));
5207 	      num_chars = mbstowcs( wc_insert_string, insert_string, insert_length+1);
5208 	      replace_res = _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
5209 						    nextPos, (char*) wc_insert_string,
5210 						    num_chars, True);
5211 	      XtFree((char *)wc_insert_string);
5212 	  }
5213 
5214 	  if (replace_res) {
5215 	      if (pending_delete) {
5216 		  XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
5217 					  XmTextF_cursor_position(tf), event->xkey.time);
5218 	      }
5219 	      df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5220 				     event->xkey.time);
5221 	      _XmDataFielddf_SetCursorPosition(tf, event,
5222 					    XmTextF_cursor_position(tf), False, True);
5223 	  }
5224 	  _XmDataFieldDrawInsertionPoint(tf, True);
5225       }
5226   }
5227 }
5228 
5229 /* ARGSUSED */
5230 static void
5231 #ifdef _NO_PROTO
df_DeletePrevChar(w,event,params,num_params)5232 df_DeletePrevChar( w, event, params, num_params )
5233         Widget w ;
5234         XEvent *event ;
5235         char **params ;
5236         Cardinal *num_params ;
5237 #else
5238 df_DeletePrevChar(
5239         Widget w,
5240         XEvent *event,
5241         char **params,
5242         Cardinal *num_params )
5243 #endif /* _NO_PROTO */
5244 {
5245   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5246   XmAnyCallbackStruct cb;
5247 
5248   /* if pending delete is on and there is a selection */
5249   _XmDataFieldDrawInsertionPoint(tf, False);
5250   if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
5251   else {
5252      if (XmTextF_has_primary(tf) &&
5253          XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
5254         if (XmTextF_cursor_position(tf) - 1 >= 0)
5255            if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf) - 1,
5256                                      XmTextF_cursor_position(tf), NULL, 0, True)) {
5257               df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5258 	               event->xkey.time);
5259               _XmDataFielddf_SetCursorPosition(tf, event,
5260 					    XmTextF_cursor_position(tf),
5261 					    False, True);
5262               cb.reason = XmCR_VALUE_CHANGED;
5263               cb.event = event;
5264               XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5265 		                 (XtPointer) &cb);
5266            }
5267       } else if (XmTextF_cursor_position(tf) - 1 >= 0) {
5268         if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf) - 1,
5269                                     XmTextF_cursor_position(tf), NULL, 0, True)) {
5270             df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5271 	             event->xkey.time);
5272             _XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
5273 					  False, True);
5274             cb.reason = XmCR_VALUE_CHANGED;
5275             cb.event = event;
5276             XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5277 		               (XtPointer) &cb);
5278         }
5279       }
5280   }
5281   _XmDataFieldDrawInsertionPoint(tf, True);
5282 }
5283 
5284 /* ARGSUSED */
5285 static void
5286 #ifdef _NO_PROTO
df_DeleteNextChar(w,event,params,num_params)5287 df_DeleteNextChar( w, event, params, num_params )
5288         Widget w ;
5289         XEvent *event ;
5290         char **params ;
5291         Cardinal *num_params ;
5292 #else
5293 df_DeleteNextChar(
5294         Widget w,
5295         XEvent *event,
5296         char **params,
5297         Cardinal *num_params )
5298 #endif /* _NO_PROTO */
5299 {
5300   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5301   XmAnyCallbackStruct cb;
5302 
5303  /* if pending delete is on and there is a selection */
5304   _XmDataFieldDrawInsertionPoint(tf, False);
5305   if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
5306   else {
5307       if (XmTextF_has_primary(tf) &&
5308            XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
5309           if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf))
5310              if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
5311                                  XmTextF_cursor_position(tf) + 1, NULL, 0, True)) {
5312                  df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5313 			                event->xkey.time);
5314                  _XmDataFielddf_SetCursorPosition(tf, event,
5315 					       XmTextF_cursor_position(tf),
5316 					       False, True);
5317                  cb.reason = XmCR_VALUE_CHANGED;
5318                  cb.event = event;
5319                  XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5320 		                    (XtPointer) &cb);
5321              }
5322        } else if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf))
5323           if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
5324 				      XmTextF_cursor_position(tf) + 1,
5325 				      NULL, 0, True))
5326 	  {
5327               df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5328 					event->xkey.time);
5329               _XmDataFielddf_SetCursorPosition(tf, event,
5330 					    XmTextF_cursor_position(tf),
5331 					    False, True);
5332               cb.reason = XmCR_VALUE_CHANGED;
5333               cb.event = event;
5334               XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5335 		                 (XtPointer) &cb);
5336           }
5337   }
5338   _XmDataFieldDrawInsertionPoint(tf, True);
5339 }
5340 
5341 /* ARGSUSED */
5342 static void
5343 #ifdef _NO_PROTO
df_DeletePrevWord(w,event,params,num_params)5344 df_DeletePrevWord( w, event, params, num_params )
5345         Widget w ;
5346         XEvent *event ;
5347         char **params ;
5348         Cardinal *num_params ;
5349 #else
5350 df_DeletePrevWord(
5351         Widget w,
5352         XEvent *event,
5353         char **params,
5354         Cardinal *num_params )
5355 #endif /* _NO_PROTO */
5356 {
5357   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5358   XmTextPosition left, right;
5359   XmAnyCallbackStruct cb;
5360 
5361  /* if pending delete is on and there is a selection */
5362   _XmDataFieldDrawInsertionPoint(tf, False);
5363   if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
5364   else {
5365        df_FindPrevWord(tf, &left, &right);
5366        if (XmTextF_has_primary(tf) &&
5367            XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
5368        {
5369 	   if (_XmDataFieldReplaceText(tf, event,
5370 				       left, XmTextF_cursor_position(tf),
5371 				       NULL, 0, True))
5372 	   {
5373 	       df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5374 					 event->xkey.time);
5375 	       _XmDataFielddf_SetCursorPosition(tf, event,
5376 						XmTextF_cursor_position(tf),
5377 						False, True);
5378 	       cb.reason = XmCR_VALUE_CHANGED;
5379 	       cb.event = event;
5380 	       XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5381 				  (XtPointer) &cb);
5382 	   }
5383        } else if (XmTextF_cursor_position(tf) - 1 >= 0)
5384           if (_XmDataFieldReplaceText(tf, event, left, XmTextF_cursor_position(tf),
5385 				      NULL, 0, True)) {
5386               df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5387 			             event->xkey.time);
5388               _XmDataFielddf_SetCursorPosition(tf, event,
5389 					    XmTextF_cursor_position(tf),
5390 					    False, True);
5391               cb.reason = XmCR_VALUE_CHANGED;
5392               cb.event = event;
5393               XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5394 		                 (XtPointer) &cb);
5395           }
5396   }
5397   _XmDataFieldDrawInsertionPoint(tf, True);
5398 }
5399 
5400 /* ARGSUSED */
5401 static void
5402 #ifdef _NO_PROTO
df_DeleteNextWord(w,event,params,num_params)5403 df_DeleteNextWord( w, event, params, num_params )
5404         Widget w ;
5405         XEvent *event ;
5406         char **params ;
5407         Cardinal *num_params ;
5408 #else
5409 df_DeleteNextWord(
5410         Widget w,
5411         XEvent *event,
5412         char **params,
5413         Cardinal *num_params )
5414 #endif /* _NO_PROTO */
5415 {
5416   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5417   XmTextPosition left, right;
5418   XmAnyCallbackStruct cb;
5419 
5420  /* if pending delete is on and there is a selection */
5421   _XmDataFieldDrawInsertionPoint(tf, False);
5422   if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
5423   else {
5424        df_FindNextWord(tf, &left, &right);
5425        if (XmTextF_has_primary(tf) &&
5426            XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
5427           if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
5428 				      right, NULL, 0, True)){
5429              df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5430 				    event->xkey.time);
5431              _XmDataFielddf_SetCursorPosition(tf, event,
5432 					   XmTextF_cursor_position(tf),
5433 					   False, True);
5434              cb.reason = XmCR_VALUE_CHANGED;
5435              cb.event = event;
5436              XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5437 		                (XtPointer) &cb);
5438           }
5439        } else if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf))
5440           if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
5441 				      right, NULL, 0, True)){
5442               df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5443 			             event->xkey.time);
5444               _XmDataFielddf_SetCursorPosition(tf, event,
5445 					    XmTextF_cursor_position(tf),
5446 					    False, True);
5447               cb.reason = XmCR_VALUE_CHANGED;
5448               cb.event = event;
5449               XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5450 		                 (XtPointer) &cb);
5451           }
5452   }
5453   _XmDataFieldDrawInsertionPoint(tf, True);
5454 }
5455 
5456 
5457 /* ARGSUSED */
5458 static void
5459 #ifdef _NO_PROTO
df_DeleteToEndOfLine(w,event,params,num_params)5460 df_DeleteToEndOfLine( w, event, params, num_params )
5461         Widget w ;
5462         XEvent *event ;
5463         char **params ;
5464         Cardinal *num_params ;
5465 #else
5466 df_DeleteToEndOfLine(
5467         Widget w,
5468         XEvent *event,
5469         char **params,
5470         Cardinal *num_params )
5471 #endif /* _NO_PROTO */
5472 {
5473   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5474   XmAnyCallbackStruct cb;
5475 
5476  /* if pending delete is on and there is a selection */
5477   _XmDataFieldDrawInsertionPoint(tf, False);
5478   if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
5479   else if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf)) {
5480      if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
5481                                  XmTextF_string_length(tf), NULL, 0, True)) {
5482          df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5483 			        event->xkey.time);
5484          _XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
5485 				       False, True);
5486          cb.reason = XmCR_VALUE_CHANGED;
5487          cb.event = event;
5488          XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5489 		            (XtPointer) &cb);
5490        }
5491   }
5492   _XmDataFieldDrawInsertionPoint(tf, True);
5493 }
5494 
5495 
5496 /* ARGSUSED */
5497 static void
5498 #ifdef _NO_PROTO
df_DeleteToStartOfLine(w,event,params,num_params)5499 df_DeleteToStartOfLine( w, event, params, num_params )
5500         Widget w ;
5501         XEvent *event ;
5502         char **params ;
5503         Cardinal *num_params ;
5504 #else
5505 df_DeleteToStartOfLine(
5506         Widget w,
5507         XEvent *event,
5508         char **params,
5509         Cardinal *num_params )
5510 #endif /* _NO_PROTO */
5511 {
5512   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5513   XmAnyCallbackStruct cb;
5514 
5515  /* if pending delete is on and there is a selection */
5516   _XmDataFieldDrawInsertionPoint(tf, False);
5517   if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
5518   else if (XmTextF_cursor_position(tf) - 1 >= 0) {
5519     if (_XmDataFieldReplaceText(tf, event, 0,
5520 			        XmTextF_cursor_position(tf), NULL, 0, True)) {
5521         df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
5522 			       event->xkey.time);
5523         _XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
5524 				      False, True);
5525         cb.reason = XmCR_VALUE_CHANGED;
5526         cb.event = event;
5527         XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
5528 		           (XtPointer) &cb);
5529        }
5530   }
5531   _XmDataFieldDrawInsertionPoint(tf, True);
5532 }
5533 
5534 /* ARGSUSED */
5535 static void
5536 #ifdef _NO_PROTO
df_ProcessCancel(w,event,params,num_params)5537 df_ProcessCancel( w, event, params, num_params )
5538         Widget w ;
5539         XEvent *event ;
5540         char **params ;
5541         Cardinal *num_params ;
5542 #else
5543 df_ProcessCancel(
5544         Widget w,
5545         XEvent *event,
5546         char **params,
5547         Cardinal *num_params )
5548 #endif /* _NO_PROTO */
5549 {
5550     XmDataFieldWidget tf = (XmDataFieldWidget) w;
5551 
5552     XmParentInputActionRec  p_event ;
5553 
5554     p_event.process_type = XmINPUT_ACTION ;
5555     p_event.action = XmPARENT_CANCEL ;
5556     p_event.event = event ;/* Pointer to XEvent. */
5557     p_event.params = params ; /* Or use what you have if   */
5558     p_event.num_params = num_params ;/* input is from translation.*/
5559 
5560     _XmDataFieldDrawInsertionPoint(tf, False);
5561     if (XmTextF_has_secondary(tf)) {
5562        XmTextF_cancel(tf) = True;
5563        _XmDataFieldSetSel2(w, 0, 0, False, event->xkey.time);
5564        XmTextF_has_secondary(tf) = False;
5565        XtUngrabKeyboard(w, CurrentTime);
5566     }
5567 
5568     if (XmTextF_has_primary(tf) && XmTextF_extending(tf)) {
5569        XmTextF_cancel(tf) = True;
5570       /* reset orig_left and orig_right */
5571        XmDataFieldSetSelection(w, XmTextF_orig_left(tf),
5572 			       XmTextF_orig_right(tf), event->xkey.time);
5573     }
5574 
5575     if (!XmTextF_cancel(tf))
5576        (void) _XmParentProcess(XtParent(tf), (XmParentProcessData) &p_event);
5577 
5578     if (XmTextF_select_id(tf)) {
5579        XtRemoveTimeOut(XmTextF_select_id(tf));
5580        XmTextF_select_id(tf) = 0;
5581     }
5582     _XmDataFieldDrawInsertionPoint(tf, True);
5583 
5584 }
5585 
5586 /* ARGSUSED */
5587 static void
5588 #ifdef _NO_PROTO
df_Activate(w,event,params,num_params)5589 df_Activate( w, event, params, num_params )
5590         Widget w ;
5591         XEvent *event ;
5592         char **params ;
5593         Cardinal *num_params ;
5594 #else
5595 df_Activate(
5596         Widget w,
5597         XEvent *event,
5598         char **params,
5599         Cardinal *num_params )
5600 #endif /* _NO_PROTO */
5601 {
5602     XmAnyCallbackStruct cb;
5603     XmDataFieldWidget tf = (XmDataFieldWidget) w;
5604     XmParentInputActionRec  p_event ;
5605 
5606     p_event.process_type = XmINPUT_ACTION ;
5607     p_event.action = XmPARENT_ACTIVATE ;
5608     p_event.event = event ;/* Pointer to XEvent. */
5609     p_event.params = params ; /* Or use what you have if   */
5610     p_event.num_params = num_params ;/* input is from translation.*/
5611 
5612     cb.reason = XmCR_ACTIVATE;
5613     cb.event  = event;
5614     XtCallCallbackList(w, XmTextF_activate_callback(tf), (XtPointer) &cb);
5615 
5616     (void) _XmParentProcess(XtParent(w), (XmParentProcessData) &p_event);
5617 }
5618 
5619 static void
5620 #ifdef _NO_PROTO
df_SetAnchorBalancing(tf,position)5621 df_SetAnchorBalancing(tf, position)
5622 XmDataFieldWidget tf;
5623 XmTextPosition position;
5624 #else
5625 df_SetAnchorBalancing(
5626         XmDataFieldWidget tf,
5627         XmTextPosition position)
5628 #endif /* _NO_PROTO */
5629 {
5630     XmTextPosition left, right;
5631     float bal_point;
5632 
5633     if (!XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) ||
5634 	left == right) {
5635           XmTextF_prim_anchor(tf) = position;
5636     } else {
5637           bal_point = (float)(((float)(right - left) / 2.0) + (float)left);
5638 
5639          /* shift anchor and direction to opposite end of the selection */
5640           if ((float)position < bal_point) {
5641              XmTextF_prim_anchor(tf) = XmTextF_orig_right(tf);
5642           } else if ((float)position > bal_point) {
5643              XmTextF_prim_anchor(tf) = XmTextF_orig_left(tf);
5644           }
5645     }
5646 }
5647 
5648 static void
5649 #ifdef _NO_PROTO
df_SetNavigationAnchor(tf,position,extend)5650 df_SetNavigationAnchor(tf, position, extend)
5651 XmDataFieldWidget tf;
5652 XmTextPosition position;
5653 Boolean extend;
5654 #else
5655 df_SetNavigationAnchor(
5656         XmDataFieldWidget tf,
5657         XmTextPosition position,
5658 #if NeedWidePrototypes
5659         int extend )
5660 #else
5661         Boolean extend )
5662 #endif /* NeedWidePrototypes */
5663 #endif /* _NO_PROTO */
5664 {
5665     XmTextPosition left, right;
5666 
5667     if (!XmTextF_add_mode(tf)) {
5668        if (extend) {
5669           df_SetAnchorBalancing(tf, position);
5670        } else {
5671          if (XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) &&
5672             left != right) {
5673            df_SetSelection(tf, position, position, True);
5674            XmTextF_prim_anchor(tf) = position;
5675          }
5676        }
5677     } else if (extend) {
5678        df_SetAnchorBalancing(tf, position);
5679     }
5680 }
5681 
5682 static void
5683 #ifdef _NO_PROTO
df_CompleteNavigation(tf,event,position,time,extend)5684 df_CompleteNavigation(tf, event, position, time, extend)
5685 XmDataFieldWidget tf;
5686 XEvent *event;
5687 XmTextPosition position;
5688 Time time;
5689 Boolean extend;
5690 #else
5691 df_CompleteNavigation(
5692         XmDataFieldWidget tf,
5693 	XEvent *event,
5694         XmTextPosition position,
5695         Time time,
5696 #if NeedWidePrototypes
5697         int extend )
5698 #else
5699         Boolean extend )
5700 #endif /* NeedWidePrototypes */
5701 #endif /* _NO_PROTO */
5702 {
5703     XmTextPosition left, right;
5704     Boolean     backward = False;
5705 
5706     if ((XmTextF_add_mode(tf) &&
5707 	 XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) &&
5708          position >= left && position <= right) || extend)
5709        XmTextF_pending_off(tf) = FALSE;
5710     else
5711        XmTextF_pending_off(tf) = TRUE;
5712 
5713     _XmDataFielddf_SetCursorPosition(tf, event, position, True, True);
5714 
5715     if (extend) {
5716        if (XmTextF_prim_anchor(tf) > position) {
5717           left = position;
5718           right = XmTextF_prim_anchor(tf);
5719           backward = True;
5720        } else {
5721           left = XmTextF_prim_anchor(tf);
5722           right = position;
5723        }
5724        XmDataFieldSetSelection((Widget)tf, left, right, time);
5725 
5726     /*  Begin fix for CR 5994 */
5727     if ( backward )
5728       _XmDataFielddf_SetCursorPosition(tf, event, position, False, False);
5729     /*  End fix for CR 5994 */
5730 
5731        XmTextF_orig_left(tf) = left;
5732        XmTextF_orig_right(tf) = right;
5733     }
5734 }
5735 
5736 /* ARGSUSED */
5737 static void
5738 #ifdef _NO_PROTO
df_SimpleMovement(w,event,params,num_params,cursorPos,position)5739 df_SimpleMovement( w, event, params, num_params, cursorPos, position )
5740         Widget w ;
5741         XEvent *event ;
5742         String *params ;
5743         Cardinal *num_params ;
5744         XmTextPosition cursorPos ;
5745         XmTextPosition position ;
5746 #else
5747 df_SimpleMovement(
5748         Widget w,
5749         XEvent *event,
5750         String *params,
5751         Cardinal *num_params,
5752         XmTextPosition cursorPos,
5753         XmTextPosition position )
5754 #endif /* _NO_PROTO */
5755 {
5756   XmDataFieldWidget tf = (XmDataFieldWidget) w;
5757   Boolean extend = False;
5758 
5759   if (*num_params > 0 && !strcmp(*params, "extend")) extend = True;
5760 
5761   _XmDataFieldDrawInsertionPoint(tf, False);
5762   df_SetNavigationAnchor(tf, cursorPos, extend);
5763   df_CompleteNavigation(tf, event, position, event->xkey.time, extend);
5764   _XmDataFieldDrawInsertionPoint(tf, True);
5765 }
5766 
5767 /* ARGSUSED */
5768 static void
5769 #ifdef _NO_PROTO
df_BackwardChar(w,event,params,num_params)5770 df_BackwardChar( w, event, params, num_params )
5771         Widget w ;
5772         XEvent *event ;
5773         char **params ;
5774         Cardinal *num_params ;
5775 #else
5776 df_BackwardChar(
5777         Widget w,
5778         XEvent *event,
5779         char **params,
5780         Cardinal *num_params )
5781 #endif /* _NO_PROTO */
5782 {
5783     XmDataFieldWidget tf = (XmDataFieldWidget) w;
5784     XmTextPosition cursorPos, position;
5785 
5786     cursorPos = XmTextF_cursor_position(tf);
5787 
5788     if (cursorPos > 0) {
5789        _XmDataFieldDrawInsertionPoint(tf, False);
5790        position = cursorPos - 1;
5791        df_SimpleMovement((Widget) tf, event, params, num_params,
5792 		      cursorPos, position);
5793        _XmDataFieldDrawInsertionPoint(tf, True);
5794     }
5795 }
5796 
5797 /* ARGSUSED */
5798 static void
5799 #ifdef _NO_PROTO
df_ForwardChar(w,event,params,num_params)5800 df_ForwardChar( w, event, params, num_params )
5801         Widget w ;
5802         XEvent *event ;
5803         char **params ;
5804         Cardinal *num_params ;
5805 #else
5806 df_ForwardChar(
5807         Widget w,
5808         XEvent *event,
5809         char **params,
5810         Cardinal *num_params )
5811 #endif /* _NO_PROTO */
5812 {
5813     XmDataFieldWidget tf = (XmDataFieldWidget) w;
5814     XmTextPosition cursorPos, position;
5815 
5816     cursorPos = XmTextF_cursor_position(tf);
5817 
5818     if (cursorPos < XmTextF_string_length(tf)) {
5819        _XmDataFieldDrawInsertionPoint(tf, False);
5820        position = cursorPos + 1;
5821        df_SimpleMovement((Widget) tf, event, params, num_params,
5822 		      cursorPos, position);
5823        _XmDataFieldDrawInsertionPoint(tf, True);
5824     }
5825 }
5826 
5827 /* ARGSUSED */
5828 static void
5829 #ifdef _NO_PROTO
df_BackwardWord(w,event,params,num_params)5830 df_BackwardWord( w, event, params, num_params )
5831         Widget w ;
5832         XEvent *event ;
5833         char **params ;
5834         Cardinal *num_params ;
5835 #else
5836 df_BackwardWord(
5837         Widget w,
5838         XEvent *event,
5839         char **params,
5840         Cardinal *num_params )
5841 #endif /* _NO_PROTO */
5842 {
5843    XmDataFieldWidget tf = (XmDataFieldWidget) w;
5844    XmTextPosition cursorPos, position, dummy;
5845 
5846    cursorPos = XmTextF_cursor_position(tf);
5847 
5848    if (cursorPos > 0) {
5849       _XmDataFieldDrawInsertionPoint(tf, False);
5850       df_FindPrevWord(tf, &position, &dummy);
5851       df_SimpleMovement((Widget) tf, event, params, num_params,
5852 		     cursorPos, position);
5853       _XmDataFieldDrawInsertionPoint(tf, True);
5854    }
5855 }
5856 
5857 /* ARGSUSED */
5858 static void
5859 #ifdef _NO_PROTO
df_ForwardWord(w,event,params,num_params)5860 df_ForwardWord( w, event, params, num_params )
5861         Widget w ;
5862         XEvent *event ;
5863         char **params ;
5864         Cardinal *num_params ;
5865 #else
5866 df_ForwardWord(
5867         Widget w,
5868         XEvent *event,
5869         char **params,
5870         Cardinal *num_params )
5871 #endif /* _NO_PROTO */
5872 {
5873     XmDataFieldWidget tf = (XmDataFieldWidget) w;
5874     XmTextPosition cursorPos, position, dummy;
5875     wchar_t white_space[3];
5876 
5877     if (XmTextF_max_char_size(tf) != 1) {
5878        (void)mbtowc(&white_space[0], " ", 1);
5879        (void)mbtowc(&white_space[1], "\n", 1);
5880        (void)mbtowc(&white_space[2], "\t", 1);
5881     }
5882 
5883     cursorPos = XmTextF_cursor_position(tf);
5884 
5885     _XmDataFieldDrawInsertionPoint(tf, False);
5886     if (cursorPos < XmTextF_string_length(tf)) {
5887        if (XmTextF_max_char_size(tf) == 1) {
5888          if (isspace((int)(unsigned char)XmTextF_value(tf)[cursorPos]))
5889 	    df_FindWord(tf, cursorPos, &dummy, &position);
5890          else
5891             df_FindNextWord(tf, &dummy, &position);
5892           if(isspace((int)(unsigned char)XmTextF_value(tf)[position])){
5893 	     for (;position < XmTextF_string_length(tf); position++){
5894 	        if (!isspace((int)(unsigned char)XmTextF_value(tf)[position]))
5895 	   	break;
5896              }
5897           }
5898        } else {
5899 	  if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[cursorPos],
5900 				   white_space, 3))
5901 	     df_FindWord(tf, cursorPos, &dummy, &position);
5902 	  else
5903 	     df_FindNextWord(tf, &dummy, &position);
5904           if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[position],
5905 				   white_space, 3)){
5906 	     for (; position < XmTextF_string_length(tf); position++) {
5907 		if (!_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[position],
5908 					  white_space, 3))
5909 		   break;
5910 	     }
5911 	  }
5912        }
5913        df_SimpleMovement((Widget) tf, event, params, num_params,
5914 		      cursorPos, position);
5915     }
5916     _XmDataFieldDrawInsertionPoint(tf, True);
5917 }
5918 
5919 
5920 /* ARGSUSED */
5921 static void
5922 #ifdef _NO_PROTO
df_EndOfLine(w,event,params,num_params)5923 df_EndOfLine( w, event, params, num_params )
5924         Widget w ;
5925         XEvent *event ;
5926         char **params ;
5927         Cardinal *num_params ;
5928 #else
5929 df_EndOfLine(
5930         Widget w,
5931         XEvent *event,
5932         char **params,
5933         Cardinal *num_params )
5934 #endif /* _NO_PROTO */
5935 {
5936    XmDataFieldWidget tf = (XmDataFieldWidget) w;
5937    XmTextPosition cursorPos, position;
5938 
5939    cursorPos = XmTextF_cursor_position(tf);
5940 
5941    if (cursorPos < XmTextF_string_length(tf)) {
5942       _XmDataFieldDrawInsertionPoint(tf, False);
5943       position = XmTextF_string_length(tf);
5944       df_SimpleMovement((Widget) tf, event, params, num_params,
5945 		     cursorPos, position);
5946       _XmDataFieldDrawInsertionPoint(tf, True);
5947    }
5948 }
5949 
5950 
5951 /* ARGSUSED */
5952 static void
5953 #ifdef _NO_PROTO
df_BeginningOfLine(w,event,params,num_params)5954 df_BeginningOfLine( w, event, params, num_params )
5955         Widget w ;
5956         XEvent *event ;
5957         char **params ;
5958         Cardinal *num_params ;
5959 #else
5960 df_BeginningOfLine(
5961         Widget w,
5962         XEvent *event,
5963         char **params,
5964         Cardinal *num_params )
5965 #endif /* _NO_PROTO */
5966 {
5967    XmDataFieldWidget tf = (XmDataFieldWidget) w;
5968    XmTextPosition cursorPos, position;
5969 
5970    cursorPos = XmTextF_cursor_position(tf);
5971 
5972    if (cursorPos > 0) {
5973       position = 0;
5974       _XmDataFieldDrawInsertionPoint(tf, False);
5975       df_SimpleMovement((Widget) tf, event, params, num_params,
5976 		     cursorPos, position);
5977       _XmDataFieldDrawInsertionPoint(tf, True);
5978    }
5979 }
5980 
5981 static void
5982 #ifdef _NO_PROTO
df_SetSelection(tf,left,right,redisplay)5983 df_SetSelection( tf, left, right, redisplay )
5984         XmDataFieldWidget tf ;
5985         XmTextPosition left ;
5986         XmTextPosition right ;
5987         Boolean redisplay ;
5988 #else
5989 df_SetSelection(
5990         XmDataFieldWidget tf,
5991         XmTextPosition left,
5992         XmTextPosition right,
5993 #if NeedWidePrototypes
5994         int redisplay )
5995 #else
5996         Boolean redisplay )
5997 #endif /* NeedWidePrototypes */
5998 #endif /* _NO_PROTO */
5999 {
6000    XmTextPosition display_left, display_right;
6001    XmTextPosition old_prim_left, old_prim_right;
6002 
6003    if (left < 0) left = 0;
6004    if (right < 0) right = 0;
6005 
6006    if (left > XmTextF_string_length(tf))
6007       left = XmTextF_string_length(tf);
6008    if (right > XmTextF_string_length(tf))
6009       right = XmTextF_string_length(tf);
6010 
6011    if (left == right && XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
6012       XmDataFieldSetAddMode((Widget)tf, False);
6013    if (left == XmTextF_prim_pos_left(tf) && right == XmTextF_prim_pos_right(tf))
6014       return;
6015 
6016    DataFieldSetHighlight(tf, XmTextF_prim_pos_left(tf),
6017 		         XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
6018 
6019    old_prim_left = XmTextF_prim_pos_left(tf);
6020    old_prim_right = XmTextF_prim_pos_right(tf);
6021 
6022    if (left > right) {
6023       XmTextF_prim_pos_left(tf) = right;
6024       XmTextF_prim_pos_right(tf) = left;
6025    } else {
6026       XmTextF_prim_pos_left(tf) = left;
6027       XmTextF_prim_pos_right(tf) = right;
6028    }
6029 
6030    DataFieldSetHighlight(tf, XmTextF_prim_pos_left(tf),
6031 	                    XmTextF_prim_pos_right(tf), XmHIGHLIGHT_SELECTED);
6032 
6033    if (redisplay) {
6034       if (old_prim_left > XmTextF_prim_pos_left(tf)) {
6035          display_left = XmTextF_prim_pos_left(tf);
6036       } else if (old_prim_left < XmTextF_prim_pos_left(tf)) {
6037          display_left = old_prim_left;
6038       } else
6039          display_left = (old_prim_right > XmTextF_prim_pos_right(tf)) ?
6040 		        XmTextF_prim_pos_right(tf) : old_prim_right;
6041 
6042       if (old_prim_right < XmTextF_prim_pos_right(tf)) {
6043          display_right = XmTextF_prim_pos_right(tf);
6044       } else if (old_prim_right > XmTextF_prim_pos_right(tf)) {
6045          display_right = old_prim_right;
6046       } else
6047          display_right = (old_prim_left < XmTextF_prim_pos_left(tf)) ?
6048 		         XmTextF_prim_pos_left(tf) : old_prim_left;
6049 
6050       df_RedisplayText(tf, display_left, display_right);
6051    }
6052    XmTextF_refresh_ibeam_off(tf) = True;
6053 }
6054 
6055 
6056 /*
6057  * Begin the selection by gaining ownership of the selection
6058  * and setting the selection parameters.
6059  */
6060 void
6061 #ifdef _NO_PROTO
_XmDataFieldStartSelection(tf,left,right,sel_time)6062 _XmDataFieldStartSelection( tf, left, right, sel_time )
6063         XmDataFieldWidget tf ;
6064         XmTextPosition left ;
6065         XmTextPosition right ;
6066         Time sel_time ;
6067 #else
6068 _XmDataFieldStartSelection(
6069         XmDataFieldWidget tf,
6070         XmTextPosition left,
6071         XmTextPosition right,
6072         Time sel_time )
6073 #endif /* _NO_PROTO */
6074 {
6075   if (!XtIsRealized((Widget)tf)) return;
6076 
6077   /* if we don't already own the selection */
6078   if (!XmTextF_has_primary(tf)) {
6079     /*
6080      * Try to gain ownership. This function identifies the
6081      * XtConvertSelectionProc and the XtLoseSelectionProc.
6082      */
6083      if (XtOwnSelection((Widget)tf, XA_PRIMARY, sel_time, _XmDataFieldConvert,
6084 		      _XmDataFieldLoseSelection, (XtSelectionDoneProc) NULL)) {
6085        XmAnyCallbackStruct cb;
6086 
6087        XmTextF_prim_time(tf) = sel_time;
6088        _XmDataFieldDrawInsertionPoint(tf, False);
6089        XmTextF_has_primary(tf) = True;
6090        XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf) =
6091 			   XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
6092       /*
6093        * Set the selection boundries for highlighting the text,
6094        * and marking the selection.
6095        */
6096        df_SetSelection(tf, left, right, True);
6097 
6098        _XmDataFieldDrawInsertionPoint(tf, True);
6099 
6100       /* Call the gain selection callback */
6101        cb.reason = XmCR_GAIN_PRIMARY;
6102        cb.event = NULL;
6103        XtCallCallbackList((Widget) tf, XmTextF_gain_primary_callback(tf),
6104 			  (XtPointer) &cb);
6105 
6106     } else
6107      /*
6108       * Failed to gain ownership of the selection so make sure
6109       * the text does not think it owns the selection.
6110       * (this might be overkill)
6111       */
6112        _XmDataFieldDeselectSelection((Widget)tf, True, sel_time);
6113   } else {
6114        _XmDataFieldDrawInsertionPoint(tf, False);
6115        XmDataFieldSetHighlight((Widget)tf, XmTextF_prim_pos_left(tf),
6116 		          XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
6117        XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf) =
6118 			   XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
6119       /*
6120        * Set the new selection boundries for highlighting the text,
6121        * and marking the selection.
6122        */
6123        df_SetSelection(tf, left, right, True);
6124 
6125        _XmDataFieldDrawInsertionPoint(tf, True);
6126   }
6127 }
6128 
6129 /* ARGSUSED */
6130 static void
6131 #ifdef _NO_PROTO
df_ProcessHorizontalParams(w,event,params,num_params,left,right,position)6132 df_ProcessHorizontalParams( w, event, params, num_params, left, right, position )
6133         Widget w ;
6134         XEvent *event ;
6135         char **params ;
6136 	Cardinal *num_params;
6137 	XmTextPosition *left ;
6138 	XmTextPosition *right ;
6139 	XmTextPosition *position ;
6140 #else
6141 df_ProcessHorizontalParams(
6142         Widget w,
6143         XEvent *event,
6144         char **params,
6145 	Cardinal *num_params,
6146 	XmTextPosition *left,
6147 	XmTextPosition *right,
6148         XmTextPosition *position )
6149 #endif /* _NO_PROTO */
6150 {
6151     XmDataFieldWidget tf = (XmDataFieldWidget) w;
6152     XmTextPosition old_cursorPos = XmTextF_cursor_position(tf);
6153 
6154     *position = XmTextF_cursor_position(tf);
6155 
6156     if (!XmDataFieldGetSelectionPosition(w, left, right) || *left == *right) {
6157         XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_prim_anchor(tf);
6158         *left = *right = old_cursorPos;
6159     }
6160 
6161     if (*num_params > 0 && !strcmp(*params, "right")) {
6162        if (*position >= XmTextF_string_length(tf)) return;
6163        (*position)++;
6164     } else if (*num_params > 0 && !strcmp(*params, "left")) {
6165        if (*position <= 0) return;
6166        (*position)--;
6167     }
6168 }
6169 
6170 
6171 /* ARGSUSED */
6172 static void
6173 #ifdef _NO_PROTO
df_ProcessSelectParams(w,event,left,right,position)6174 df_ProcessSelectParams( w, event, left, right, position )
6175         Widget w ;
6176         XEvent *event ;
6177         XmTextPosition *left ;
6178         XmTextPosition *right ;
6179         XmTextPosition *position ;
6180 #else
6181 df_ProcessSelectParams(
6182         Widget w,
6183         XEvent *event,
6184         XmTextPosition *left,
6185         XmTextPosition *right,
6186         XmTextPosition *position )
6187 #endif /* _NO_PROTO */
6188 {
6189    XmDataFieldWidget tf = (XmDataFieldWidget) w;
6190 
6191    *position = XmTextF_cursor_position(tf);
6192 
6193    if (!XmDataFieldGetSelectionPosition(w, left, right) || *left == *right) {
6194       if (*position > XmTextF_prim_anchor(tf)) {
6195         *left = XmTextF_prim_anchor(tf);
6196         *right = *position;
6197       } else {
6198         *left = *position;
6199         *right = XmTextF_prim_anchor(tf);
6200       }
6201    }
6202 }
6203 
6204 
6205 /* ARGSUSED */
6206 static void
6207 #ifdef _NO_PROTO
df_KeySelection(w,event,params,num_params)6208 df_KeySelection( w, event, params, num_params )
6209         Widget w ;
6210         XEvent *event ;
6211         char **params ;
6212         Cardinal *num_params ;
6213 #else
6214 df_KeySelection(
6215         Widget w,
6216         XEvent *event,
6217         char **params,
6218         Cardinal *num_params )
6219 #endif /* _NO_PROTO */
6220 {
6221   XmTextPosition position = 0, left, right;
6222   XmDataFieldWidget tf = (XmDataFieldWidget) w;
6223   XmTextPosition cursorPos;
6224 
6225   _XmDataFieldDrawInsertionPoint(tf,False); /* Turn off I beam blink
6226 					       during selection */
6227 
6228   XmTextF_orig_left(tf) = XmTextF_prim_pos_left(tf);
6229   XmTextF_orig_right(tf) = XmTextF_prim_pos_right(tf);
6230 
6231   cursorPos = XmTextF_cursor_position(tf);
6232   if (*num_params > 0 && (!strcmp(*params,"right") || !strcmp(*params, "left")))
6233      df_SetAnchorBalancing(tf, cursorPos);
6234 
6235   XmTextF_extending(tf) = True;
6236 
6237   if (*num_params == 0) {
6238      position = cursorPos;
6239      df_ProcessSelectParams(w, event, &left, &right, &position);
6240   } else if (*num_params > 0 && (!strcmp(*params, "right") ||
6241 				 !strcmp(*params, "left"))) {
6242      df_ProcessHorizontalParams(w, event, params, num_params, &left,
6243 			     &right, &position);
6244   }
6245 
6246   cursorPos = position;
6247 
6248   if (position < 0 || position > XmTextF_string_length(tf)) {
6249      _XmDataFieldDrawInsertionPoint(tf,True); /* Turn on I beam now
6250 						 that we are done */
6251      return;
6252   }
6253 
6254  /* shift anchor and direction to opposite end of the selection */
6255   if (position > XmTextF_prim_anchor(tf)) {
6256      right = cursorPos = position;
6257      left = XmTextF_prim_anchor(tf);
6258   } else {
6259      left = cursorPos = position;
6260      right = XmTextF_prim_anchor(tf);
6261   }
6262 
6263   if (left > right) {
6264      XmTextPosition tempIndex = left;
6265      left = right;
6266      right = tempIndex;
6267   }
6268 
6269   if (XmTextF_has_primary(tf))
6270      df_SetSelection(tf, left, right, True);
6271   else
6272      _XmDataFieldStartSelection(tf, left, right, event->xbutton.time);
6273 
6274   XmTextF_pending_off(tf) = False;
6275 
6276   _XmDataFielddf_SetCursorPosition(tf, event, cursorPos, True, True);
6277   (void) df_SetDestination(w, cursorPos, False, event->xkey.time);
6278 
6279   XmTextF_orig_left(tf) = XmTextF_prim_pos_left(tf);
6280   XmTextF_orig_right(tf) = XmTextF_prim_pos_right(tf);
6281 
6282   _XmDataFieldDrawInsertionPoint(tf,True); /* Turn on I beam now
6283 					      that we are done */
6284 
6285 }
6286 
6287 /* ARGSUSED */
6288 static void
6289 #ifdef _NO_PROTO
df_TextFocusIn(w,event,params,num_params)6290 df_TextFocusIn( w, event, params, num_params )
6291         Widget w ;
6292         XEvent *event ;
6293         char **params ;
6294         Cardinal *num_params ;
6295 #else
6296 df_TextFocusIn(
6297         Widget w,
6298         XEvent *event,
6299         char **params,
6300         Cardinal *num_params )
6301 #endif /* _NO_PROTO */
6302 {
6303    XmDataFieldWidget tf = (XmDataFieldWidget) w;
6304    XmAnyCallbackStruct cb;
6305    XPoint xmim_point;
6306    XtWidgetProc bhl;
6307 
6308    if (event->xfocus.send_event && !(XmTextF_has_focus(tf))) {
6309       if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
6310       XmTextF_has_focus(tf) = True;
6311       if (XtIsSensitive(w)) _XmDataFToggleCursorGC(w);
6312       _XmDataFieldDrawInsertionPoint(tf, False);
6313       XmTextF_blink_on(tf) = False;
6314 
6315       XmTextF_refresh_ibeam_off(tf) = True;
6316 
6317       if (_XmGetFocusPolicy(w) == XmEXPLICIT)
6318       {
6319          _XmProcessLock();
6320          bhl = ((XmDataFieldWidgetClass)XtClass(w))->primitive_class.border_highlight;
6321          _XmProcessUnlock();
6322 
6323          if (bhl)
6324          {
6325             (*bhl)(w);
6326          }
6327 
6328          if (!XmTextF_has_destination(tf))
6329          {
6330             (void) df_SetDestination(w, XmTextF_cursor_position(tf), False, XtLastTimestampProcessed(XtDisplay(w)));
6331          }
6332       }
6333 
6334       if (tf->core.sensitive) df_ChangeBlinkBehavior(tf, True);
6335       _XmDataFieldDrawInsertionPoint(tf, True);
6336       (void) df_GetXYFromPos(tf, XmTextF_cursor_position(tf),
6337 			  &xmim_point.x, &xmim_point.y);
6338       XmImVaSetFocusValues(w, XmNspotLocation, &xmim_point, NULL);
6339 
6340       cb.reason = XmCR_FOCUS;
6341       cb.event = event;
6342       XtCallCallbackList (w, XmTextF_focus_callback(tf), (XtPointer) &cb);
6343    }
6344 
6345    _XmPrimitiveFocusIn(w, event, params, num_params);
6346 }
6347 
6348 
6349 /* ARGSUSED */
6350 static void
6351 #ifdef _NO_PROTO
df_TextFocusOut(w,event,params,num_params)6352 df_TextFocusOut( w, event, params, num_params )
6353         Widget w ;
6354         XEvent *event ;
6355         char **params ;
6356         Cardinal *num_params ;
6357 #else
6358 df_TextFocusOut(
6359         Widget w,
6360         XEvent *event,
6361         char **params,
6362         Cardinal *num_params )
6363 #endif /* _NO_PROTO */
6364 {
6365    XmDataFieldWidget tf = (XmDataFieldWidget) w;
6366    XtWidgetProc buhl;
6367 
6368    if (event->xfocus.send_event && XmTextF_has_focus(tf)) {
6369       XmTextF_has_focus(tf) = False;
6370       df_ChangeBlinkBehavior(tf, False);
6371       _XmDataFieldDrawInsertionPoint(tf, False);
6372       _XmDataFToggleCursorGC(w);
6373       XmTextF_blink_on(tf) = True;
6374       _XmDataFieldDrawInsertionPoint(tf, True);
6375 
6376       _XmProcessLock();
6377       buhl = ((XmDataFieldWidgetClass) XtClass(tf))->primitive_class.border_unhighlight;
6378       _XmProcessUnlock();
6379 
6380       if(buhl)
6381       {
6382           (*buhl)( (Widget) tf) ;
6383       }
6384       XmImUnsetFocus(w);
6385    }
6386 
6387    /* If traversal is on, then the leave verification callback is called in
6388       the traversal event handler */
6389    if (event->xfocus.send_event && !XmTextF_traversed(tf) &&
6390        _XmGetFocusPolicy(w) == XmEXPLICIT) {
6391         if (!df_VerifyLeave(tf, event)) {
6392            if (XmTextF_verify_bell(tf)) XBell(XtDisplay(w), 0);
6393            return;
6394         }
6395    } else
6396         if (XmTextF_traversed(tf)) {
6397 	   XmTextF_traversed(tf) = False;
6398         }
6399 }
6400 
6401 static void
6402 #ifdef _NO_PROTO
df_SetScanIndex(tf,event)6403 df_SetScanIndex( tf, event )
6404         XmDataFieldWidget tf ;
6405         XEvent *event ;
6406 #else
6407 df_SetScanIndex(
6408         XmDataFieldWidget tf,
6409         XEvent *event )
6410 #endif /* _NO_PROTO */
6411 {
6412    Time sel_time;
6413 
6414    if (event->type == ButtonPress) sel_time = event->xbutton.time;
6415    else sel_time = event->xkey.time;
6416 
6417 
6418    if (sel_time > XmTextF_last_time(tf) &&
6419 	sel_time - XmTextF_last_time(tf) < XtGetMultiClickTime(XtDisplay(tf))) {
6420 /*
6421  * Fix for HaL DTS 9841 - Increment the sarray_index first, then check to
6422  *			  see if it is greater that the count.  Otherwise,
6423  *			  an error will occur.
6424  */
6425        XmTextF_sarray_index(tf)++;
6426        if (XmTextF_sarray_index(tf) >= XmTextF_selection_array_count(tf)) {
6427 	  XmTextF_sarray_index(tf) = 0;
6428        }
6429 /*
6430  * End fix for HaL DTS 9841
6431  */
6432     } else
6433        XmTextF_sarray_index(tf) = 0;
6434 
6435     XmTextF_last_time(tf) = sel_time;
6436 }
6437 
6438 static void
6439 #ifdef _NO_PROTO
df_ExtendScanSelection(tf,event)6440 df_ExtendScanSelection( tf, event )
6441         XmDataFieldWidget tf ;
6442         XEvent *event ;
6443 #else
6444 df_ExtendScanSelection(
6445         XmDataFieldWidget tf,
6446         XEvent *event )
6447 #endif /* _NO_PROTO */
6448 {
6449    XmTextPosition pivot_left, pivot_right;
6450    XmTextPosition left, right;
6451    XmTextPosition new_position = df_GetPosFromX(tf, (Position) event->xbutton.x);
6452    XmTextPosition cursorPos = XmTextF_cursor_position(tf);
6453    Boolean pivot_modify = False;
6454    float bal_point;
6455 
6456    if (!XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) ||
6457        left == right) {
6458        XmTextF_orig_left(tf) = XmTextF_orig_right(tf) =
6459 	   XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
6460        bal_point = (float)XmTextF_orig_left(tf);
6461    } else
6462         bal_point = (float)(((float)(right - left) / 2.0) + (float)left);
6463 
6464    if (!XmTextF_extending(tf))
6465    {
6466       if ((float)new_position < bal_point) {
6467          XmTextF_prim_anchor(tf) = XmTextF_orig_right(tf);
6468       } else if ((float)new_position > bal_point) {
6469          XmTextF_prim_anchor(tf) = XmTextF_orig_left(tf);
6470       }
6471   }
6472 
6473    XmTextF_extending(tf) = True;
6474 
6475    switch (XmTextF_selection_array(tf)[XmTextF_sarray_index(tf)]) {
6476        case XmSELECT_POSITION:
6477       	   if (XmTextF_has_primary(tf))
6478 	      df_SetSelection(tf, XmTextF_prim_anchor(tf), new_position, True);
6479            else if (new_position != XmTextF_prim_anchor(tf))
6480      	      _XmDataFieldStartSelection(tf, XmTextF_prim_anchor(tf),
6481 			     new_position, event->xbutton.time);
6482            XmTextF_pending_off(tf) = False;
6483            cursorPos = new_position;
6484            break;
6485        case XmSELECT_WHITESPACE:
6486        case XmSELECT_WORD:
6487 	   df_FindWord(tf, new_position, &left, &right);
6488            df_FindWord(tf, XmTextF_prim_anchor(tf),
6489 		    &pivot_left, &pivot_right);
6490            XmTextF_pending_off(tf) = False;
6491            if (left != pivot_left || right != pivot_right) {
6492               if (left > pivot_left)
6493                  left = pivot_left;
6494               if (right < pivot_right)
6495                  right = pivot_right;
6496               pivot_modify = True;
6497            }
6498       	   if (XmTextF_has_primary(tf))
6499               df_SetSelection(tf, left, right, True);
6500       	   else
6501      	      _XmDataFieldStartSelection(tf, left, right, event->xbutton.time);
6502 
6503            if (pivot_modify) {
6504               if ((((right - left) / 2) + left) <= new_position) {
6505                  cursorPos = right;
6506               } else
6507                  cursorPos = left;
6508            } else {
6509 	      if (left >= XmTextF_cursor_position(tf))
6510                  cursorPos = left;
6511               else
6512                  cursorPos = right;
6513            }
6514            break;
6515        default:
6516 	   break;
6517    }
6518    if (cursorPos != XmTextF_cursor_position(tf)) {
6519       (void) df_SetDestination((Widget)tf, cursorPos, False, event->xkey.time);
6520       _XmDataFielddf_SetCursorPosition(tf, event, cursorPos, True, True);
6521    }
6522 }
6523 
6524 static void
6525 #ifdef _NO_PROTO
df_SetScanSelection(tf,event)6526 df_SetScanSelection( tf, event )
6527         XmDataFieldWidget tf ;
6528         XEvent *event ;
6529 #else
6530 df_SetScanSelection(
6531         XmDataFieldWidget tf,
6532         XEvent *event )
6533 #endif /* _NO_PROTO */
6534 {
6535    XmTextPosition left, right;
6536    XmTextPosition new_position = 0;
6537    XmTextPosition cursorPos = XmTextF_cursor_position(tf);
6538    Position dummy = 0;
6539    Boolean update_position = False;
6540 
6541    df_SetScanIndex(tf, event);
6542 
6543    if (event->type == ButtonPress)
6544        new_position = df_GetPosFromX(tf, (Position) event->xbutton.x);
6545    else
6546        new_position = XmTextF_cursor_position(tf);
6547 
6548    _XmDataFieldDrawInsertionPoint(tf,False); /* Turn off I beam
6549 						blink during selection */
6550 
6551    switch (XmTextF_selection_array(tf)[XmTextF_sarray_index(tf)]) {
6552        case XmSELECT_POSITION:
6553            XmTextF_prim_anchor(tf) = new_position;
6554       	   if (XmTextF_has_primary(tf)) {
6555               df_SetSelection(tf, new_position, new_position, True);
6556               XmTextF_pending_off(tf) = False;
6557            }
6558            cursorPos = new_position;
6559 	   update_position = True;
6560            break;
6561        case XmSELECT_WHITESPACE:
6562        case XmSELECT_WORD:
6563 	   df_FindWord(tf, XmTextF_cursor_position(tf), &left, &right);
6564       	   if (XmTextF_has_primary(tf))
6565               df_SetSelection(tf, left, right, True);
6566       	   else
6567      	      _XmDataFieldStartSelection(tf, left, right, event->xbutton.time);
6568            XmTextF_pending_off(tf) = False;
6569            if ((((right - left) / 2) + left) <= new_position)
6570               cursorPos = right;
6571            else
6572               cursorPos = left;
6573            break;
6574        case XmSELECT_LINE:
6575        case XmSELECT_OUT_LINE:
6576        case XmSELECT_PARAGRAPH:
6577        case XmSELECT_ALL:
6578       	   if (XmTextF_has_primary(tf))
6579               df_SetSelection(tf, 0, XmTextF_string_length(tf), True);
6580       	   else
6581               _XmDataFieldStartSelection(tf, 0, XmTextF_string_length(tf),
6582 			     event->xbutton.time);
6583            XmTextF_pending_off(tf) = False;
6584    	   if (event->type == ButtonPress)
6585            {
6586               if ((XmTextF_string_length(tf)) / 2 <= new_position)
6587                  cursorPos = XmTextF_string_length(tf);
6588               else
6589                  cursorPos = 0;
6590           }
6591            break;
6592    }
6593 
6594    (void) df_SetDestination((Widget)tf, cursorPos, False, event->xkey.time);
6595    if (cursorPos != XmTextF_cursor_position(tf) || update_position) {
6596       _XmDataFielddf_SetCursorPosition(tf, event, cursorPos, True, True);
6597    }
6598    df_GetXYFromPos(tf, cursorPos, &(XmTextF_select_pos_x(tf)),
6599                 &dummy);
6600    _XmDataFieldDrawInsertionPoint(tf,True);
6601 }
6602 
6603 
6604 /* ARGSUSED */
6605 static void
6606 #ifdef _NO_PROTO
df_StartPrimary(w,event,params,num_params)6607 df_StartPrimary( w, event, params, num_params )
6608         Widget w ;
6609         XEvent *event ;
6610         char **params ;
6611         Cardinal *num_params ;
6612 #else
6613 df_StartPrimary(
6614         Widget w,
6615         XEvent *event,
6616         char **params,
6617         Cardinal *num_params )
6618 #endif /* _NO_PROTO */
6619 {
6620   XmDataFieldWidget tf = (XmDataFieldWidget) w;
6621 
6622   if (!XmTextF_has_focus(tf) && _XmGetFocusPolicy(w) == XmEXPLICIT)
6623      (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
6624 
6625   _XmDataFieldDrawInsertionPoint(tf,False);
6626   df_SetScanSelection(tf, event); /* use scan type to set the selection */
6627   _XmDataFieldDrawInsertionPoint(tf,True);
6628 }
6629 
6630 
6631 /* ARGSUSED */
6632 static void
6633 #ifdef _NO_PROTO
df_MoveDestination(w,event,params,num_params)6634 df_MoveDestination( w, event, params, num_params )
6635         Widget w ;
6636         XEvent *event ;
6637         char **params ;
6638         Cardinal *num_params ;
6639 #else
6640 df_MoveDestination(
6641         Widget w,
6642         XEvent *event,
6643         char **params,
6644         Cardinal *num_params )
6645 #endif /* _NO_PROTO */
6646 {
6647   XmDataFieldWidget tf = (XmDataFieldWidget) w;
6648   XmTextPosition left, right;
6649   XmTextPosition new_position;
6650   Boolean old_has_focus = XmTextF_has_focus(tf);
6651   Boolean reset_cursor = False;
6652 
6653   new_position = df_GetPosFromX(tf, (Position) event->xbutton.x);
6654 
6655   _XmDataFieldDrawInsertionPoint(tf, False);
6656   if (XmDataFieldGetSelectionPosition(w, &left, &right) && (right != left))
6657      (void) df_SetDestination(w, new_position, False, event->xbutton.time);
6658 
6659   XmTextF_pending_off(tf) = False;
6660 
6661   if (!XmTextF_has_focus(tf) && _XmGetFocusPolicy(w) == XmEXPLICIT)
6662      (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
6663 
6664   /* Doing the the df_MoveDestination caused a traversal into my, causing
6665    * me to gain focus... Cursor is now on when it shouldn't be. */
6666   if ((reset_cursor = !old_has_focus && XmTextF_has_focus(tf)) != False)
6667      _XmDataFieldDrawInsertionPoint(tf, False);
6668 
6669   _XmDataFielddf_SetCursorPosition(tf, event, new_position,
6670 				True, True);
6671   if (new_position < left && new_position > right)
6672      XmTextF_pending_off(tf) = True;
6673 
6674   /*
6675    * if cursor was turned off as a result of the focus state changing
6676    * then we need to undo the decrement to the cursor_on variable
6677    * by redrawing the insertion point.
6678    */
6679   if (reset_cursor)
6680      _XmDataFieldDrawInsertionPoint(tf, True);
6681   _XmDataFieldDrawInsertionPoint(tf, True);
6682 }
6683 
6684 /* ARGSUSED */
6685 static void
6686 #ifdef _NO_PROTO
df_ExtendPrimary(w,event,params,num_params)6687 df_ExtendPrimary( w, event, params, num_params )
6688         Widget w ;
6689         XEvent *event ;
6690         char **params ;
6691         Cardinal *num_params ;
6692 #else
6693 df_ExtendPrimary(
6694         Widget w,
6695         XEvent *event,
6696         char **params,
6697         Cardinal *num_params )
6698 #endif /* _NO_PROTO */
6699 {
6700   XmDataFieldWidget tf = (XmDataFieldWidget) w;
6701 
6702   if (XmTextF_cancel(tf)) return;
6703 
6704   _XmDataFieldDrawInsertionPoint(tf, False);
6705   XmTextF_do_drop(tf) = False;
6706 
6707   if (!df_CheckTimerScrolling(w, event)){
6708      if (event->type == ButtonPress)
6709         df_DoExtendedSelection(w, event->xbutton.time);
6710      else
6711         df_DoExtendedSelection(w, event->xkey.time);
6712   } else
6713      df_ExtendScanSelection(tf, event); /* use scan type to set the selection */
6714 
6715   _XmDataFieldDrawInsertionPoint(tf, True);
6716 }
6717 
6718 
6719 /* ARGSUSED */
6720 static void
6721 #ifdef _NO_PROTO
df_ExtendEnd(w,event,params,num_params)6722 df_ExtendEnd( w, event, params, num_params )
6723         Widget w ;
6724         XEvent *event ;
6725         char **params ;
6726         Cardinal *num_params ;
6727 #else
6728 df_ExtendEnd(
6729         Widget w,
6730         XEvent *event,
6731         char **params,
6732         Cardinal *num_params )
6733 #endif /* _NO_PROTO */
6734 {
6735   XmDataFieldWidget tf = (XmDataFieldWidget) w;
6736 
6737 
6738   if (XmTextF_prim_pos_left(tf) == 0 && XmTextF_prim_pos_right(tf) == 0)
6739      XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_cursor_position(tf);
6740   else {
6741      XmTextF_orig_left(tf) = XmTextF_prim_pos_left(tf);
6742      XmTextF_orig_right(tf) = XmTextF_prim_pos_right(tf);
6743      XmTextF_cancel(tf) = False;
6744   }
6745 
6746   if (XmTextF_select_id(tf)) {
6747      XtRemoveTimeOut(XmTextF_select_id(tf));
6748      XmTextF_select_id(tf) = 0;
6749   }
6750     XmTextF_select_pos_x(tf) = 0;
6751     XmTextF_extending(tf) = False;
6752 }
6753 
6754 /* ARGSUSED */
6755 static void
6756 #ifdef _NO_PROTO
df_DoExtendedSelection(w,time)6757 df_DoExtendedSelection(w, time)
6758         Widget w;
6759         Time time;
6760 #else
6761 df_DoExtendedSelection(
6762         Widget w,
6763         Time time )
6764 #endif /* _NO_PROTO */
6765 {
6766     XmDataFieldWidget tf = (XmDataFieldWidget) w;
6767     XmTextPosition position, left, right, cursorPos;
6768     XmTextPosition pivot_left, pivot_right;
6769     Boolean pivot_modify = False;
6770     float bal_point;
6771 
6772     if (XmTextF_cancel(tf)) {
6773           if (XmTextF_select_id(tf)) XtRemoveTimeOut(XmTextF_select_id(tf));
6774           XmTextF_select_id(tf) = 0;
6775           return;
6776     }
6777 
6778     cursorPos = XmTextF_cursor_position(tf);
6779     _XmDataFieldDrawInsertionPoint(tf, False);
6780     if (!(XmDataFieldGetSelectionPosition(w, &left, &right)) || left == right) {
6781         XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
6782         left = right = XmTextF_cursor_position(tf);
6783         XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_prim_anchor(tf);
6784         bal_point = (float)XmTextF_prim_anchor(tf);
6785     } else
6786         bal_point = (float)(((float)(XmTextF_orig_right(tf) - XmTextF_orig_left(tf))
6787                                      / 2.0) + (float)XmTextF_orig_left(tf));
6788 
6789     position = XmDataFieldXYToPos(w, XmTextF_select_pos_x(tf), 0);
6790 
6791    if (!XmTextF_extending(tf))
6792    {
6793       if ((float)position < bal_point) {
6794          XmTextF_prim_anchor(tf) = XmTextF_orig_right(tf);
6795       } else if ((float)position > bal_point) {
6796          XmTextF_prim_anchor(tf) = XmTextF_orig_left(tf);
6797       }
6798   }
6799    XmTextF_extending(tf) = True;
6800 
6801     /* Extend selection in same way as ExtendScan would do */
6802 
6803    switch (XmTextF_selection_array(tf)[XmTextF_sarray_index(tf)]) {
6804        case XmSELECT_POSITION:
6805            if (XmTextF_has_primary(tf))
6806               df_SetSelection(tf, XmTextF_prim_anchor(tf), position, True);
6807            else if (position != XmTextF_prim_anchor(tf))
6808               _XmDataFieldStartSelection(tf, XmTextF_prim_anchor(tf),
6809                              position, time);
6810            XmTextF_pending_off(tf) = False;
6811            cursorPos = position;
6812            break;
6813        case XmSELECT_WHITESPACE:
6814        case XmSELECT_WORD:
6815            df_FindWord(tf, position, &left, &right);
6816            df_FindWord(tf, XmTextF_prim_anchor(tf),
6817                     &pivot_left, &pivot_right);
6818            XmTextF_pending_off(tf) = False;
6819            if (left != pivot_left || right != pivot_right) {
6820               if (left > pivot_left)
6821                  left = pivot_left;
6822               if (right < pivot_right)
6823                  right = pivot_right;
6824               pivot_modify = True;
6825            }
6826            if (XmTextF_has_primary(tf))
6827               df_SetSelection(tf, left, right, True);
6828            else
6829               _XmDataFieldStartSelection(tf, left, right, time);
6830 
6831            if (pivot_modify) {
6832               if ((((right - left) / 2) + left) <= position) {
6833                  cursorPos = right;
6834               } else
6835                  cursorPos = left;
6836            } else {
6837               if (left >= XmTextF_cursor_position(tf))
6838                  cursorPos = left;
6839               else
6840                  cursorPos = right;
6841            }
6842            break;
6843        default:
6844            break;
6845    }
6846    if (cursorPos != XmTextF_cursor_position(tf)) {
6847       (void) df_SetDestination((Widget)tf, cursorPos, False, time);
6848       _XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos, True, True);
6849    }
6850     _XmDataFieldDrawInsertionPoint(tf, True);
6851 }
6852 
6853 /* ARGSUSED */
6854 static void
6855 #ifdef _NO_PROTO
df_DoSecondaryExtend(w,ev_time)6856 df_DoSecondaryExtend(w, ev_time)
6857         Widget w;
6858         Time ev_time;
6859 #else
6860 df_DoSecondaryExtend(
6861         Widget w,
6862         Time ev_time )
6863 #endif /* _NO_PROTO */
6864 {
6865     XmDataFieldWidget tf = (XmDataFieldWidget) w;
6866 
6867     XmTextPosition position = XmDataFieldXYToPos(w, XmTextF_select_pos_x(tf), 0);
6868 
6869     if (XmTextF_cancel(tf)) return;
6870 
6871     if (position < XmTextF_sec_anchor(tf)) {
6872        if (XmTextF_sec_pos_left(tf) > 0)
6873           _XmDataFieldSetSel2(w, position, XmTextF_sec_anchor(tf), False, ev_time);
6874        XmDataFieldShowPosition(w, XmTextF_sec_pos_left(tf));
6875     } else if (position > XmTextF_sec_anchor(tf)) {
6876        if (XmTextF_sec_pos_right(tf) < XmTextF_string_length(tf))
6877        _XmDataFieldSetSel2(w, XmTextF_sec_anchor(tf), position, False, ev_time);
6878        XmDataFieldShowPosition(w, XmTextF_sec_pos_right(tf));
6879     } else {
6880        _XmDataFieldSetSel2(w, position, position, False, ev_time);
6881        XmDataFieldShowPosition(w, position);
6882     }
6883     df_ResetClipOrigin(tf, False);
6884 
6885     XmTextF_sec_extending(tf) = True;
6886 }
6887 
6888 
6889 
6890 /************************************************************************
6891  *                                                                      *
6892  * df_BrowseScroll - timer proc that scrolls the list if the user has left *
6893  *              the window with the button down. If the button has been *
6894  *              released, call the standard click stuff.                *
6895  *                                                                      *
6896  ************************************************************************/
6897 /* ARGSUSED */
6898 static void
6899 #ifdef _NO_PROTO
df_BrowseScroll(closure,id)6900 df_BrowseScroll( closure, id )
6901         XtPointer closure ;
6902         XtIntervalId *id ;
6903 #else
6904 df_BrowseScroll(
6905         XtPointer closure,
6906         XtIntervalId *id )
6907 #endif /* _NO_PROTO */
6908 {
6909     Widget w = (Widget) closure ;
6910     XmDataFieldWidget tf = (XmDataFieldWidget) w;
6911 
6912     if (XmTextF_cancel(tf)) {
6913        XmTextF_select_id(tf) = 0;
6914        return;
6915     }
6916 
6917     if (!XmTextF_select_id(tf)) return;
6918 
6919     _XmDataFieldDrawInsertionPoint(tf, False);
6920     if (XmTextF_sec_extending(tf))
6921       df_DoSecondaryExtend(w, XtLastTimestampProcessed(XtDisplay(w)));
6922     else if (XmTextF_extending(tf))
6923       df_DoExtendedSelection(w, XtLastTimestampProcessed(XtDisplay(w)));
6924 
6925     XSync (XtDisplay(w), False);
6926 
6927     _XmDataFieldDrawInsertionPoint(tf, True);
6928 
6929     XmTextF_select_id(tf) = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
6930                                  (unsigned long) PRIM_SCROLL_INTERVAL,
6931                                  df_BrowseScroll, (XtPointer) w);
6932 }
6933 
6934 
6935 /* ARGSUSED */
6936 static Boolean
6937 #ifdef _NO_PROTO
df_CheckTimerScrolling(w,event)6938 df_CheckTimerScrolling( w, event )
6939         Widget w ;
6940         XEvent *event ;
6941 #else
6942 df_CheckTimerScrolling(
6943         Widget w,
6944         XEvent *event )
6945 #endif /* _NO_PROTO */
6946 {
6947     XmDataFieldWidget tf = (XmDataFieldWidget) w;
6948     Dimension margin_size = XmTextF_margin_width(tf) +
6949                                tf->primitive.shadow_thickness +
6950                                tf->primitive.highlight_thickness;
6951     Dimension top_margin = XmTextF_margin_height(tf) +
6952                             tf->primitive.shadow_thickness +
6953                             tf->primitive.highlight_thickness;
6954 
6955     XmTextF_select_pos_x(tf) = event->xmotion.x;
6956 
6957     if ((event->xmotion.x > (int) margin_size) &&
6958       (event->xmotion.x < (int) (tf->core.width - margin_size))  &&
6959       (event->xmotion.y > (int) top_margin) &&
6960         (event->xmotion.y < (int) (top_margin + XmTextF_font_ascent(tf) +
6961                                  XmTextF_font_descent(tf)))) {
6962 
6963        if (XmTextF_select_id(tf)) {
6964           XtRemoveTimeOut(XmTextF_select_id(tf));
6965           XmTextF_select_id(tf) = 0;
6966        }
6967     } else {
6968        /* to the left of the text */
6969         if (event->xmotion.x <= (int) margin_size)
6970            XmTextF_select_pos_x(tf) = (Position) (margin_size -
6971                                           (XmTextF_average_char_width(tf) + 1));
6972        /* to the right of the text */
6973       else if (event->xmotion.x >= (int) (tf->core.width - margin_size))
6974            XmTextF_select_pos_x(tf) = (Position) ((tf->core.width - margin_size) +
6975                                            XmTextF_average_char_width(tf) + 1);
6976        if (!XmTextF_select_id(tf))
6977           XmTextF_select_id(tf) = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
6978                                        (unsigned long) SEC_SCROLL_INTERVAL,
6979                                        df_BrowseScroll, (XtPointer) w);
6980        return True;
6981     }
6982     return False;
6983 }
6984 
6985 static void
6986 #ifdef _NO_PROTO
df_RestorePrimaryHighlight(tf,prim_left,prim_right)6987 df_RestorePrimaryHighlight( tf, prim_left, prim_right )
6988         XmDataFieldWidget tf ;
6989         XmTextPosition prim_left ;
6990         XmTextPosition prim_right ;
6991 #else
6992 df_RestorePrimaryHighlight(
6993         XmDataFieldWidget tf,
6994         XmTextPosition prim_left,
6995         XmTextPosition prim_right )
6996 #endif /* _NO_PROTO */
6997 {
6998    if (XmTextF_sec_pos_right(tf) >= prim_left &&
6999        XmTextF_sec_pos_right(tf) <= prim_right) {
7000      /* secondary selection is totally inside primary selection */
7001       if (XmTextF_sec_pos_left(tf) >= prim_left) {
7002          DataFieldSetHighlight(tf, prim_left, XmTextF_sec_pos_left(tf),
7003                             XmHIGHLIGHT_SELECTED);
7004          DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf),
7005                                XmTextF_sec_pos_right(tf),
7006                                XmHIGHLIGHT_NORMAL);
7007          DataFieldSetHighlight(tf, XmTextF_sec_pos_right(tf), prim_right,
7008                                XmHIGHLIGHT_SELECTED);
7009      /* right side of secondary selection is inside primary selection */
7010       } else {
7011          DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf), prim_left,
7012                                XmHIGHLIGHT_NORMAL);
7013          DataFieldSetHighlight(tf, prim_left, XmTextF_sec_pos_right(tf),
7014                                XmHIGHLIGHT_SELECTED);
7015       }
7016    } else {
7017      /* left side of secondary selection is inside primary selection */
7018       if (XmTextF_sec_pos_left(tf) <= prim_right &&
7019 	  XmTextF_sec_pos_left(tf) >= prim_left) {
7020          DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf), prim_right,
7021                                XmHIGHLIGHT_SELECTED);
7022          DataFieldSetHighlight(tf, prim_right, XmTextF_sec_pos_right(tf),
7023                                XmHIGHLIGHT_NORMAL);
7024       } else  {
7025        /* secondary selection encompasses the primary selection */
7026         if (XmTextF_sec_pos_left(tf) <= prim_left &&
7027             XmTextF_sec_pos_right(tf) >= prim_right){
7028            DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf), prim_left,
7029                                  XmHIGHLIGHT_NORMAL);
7030            DataFieldSetHighlight(tf, prim_left, prim_right,
7031                                  XmHIGHLIGHT_SELECTED);
7032            DataFieldSetHighlight(tf, prim_right, XmTextF_sec_pos_right(tf),
7033                                  XmHIGHLIGHT_NORMAL);
7034      /* secondary selection is outside primary selection */
7035         } else {
7036            DataFieldSetHighlight(tf, prim_left, prim_right,
7037                                  XmHIGHLIGHT_SELECTED);
7038            DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf),
7039                                  XmTextF_sec_pos_right(tf),
7040                                  XmHIGHLIGHT_NORMAL);
7041         }
7042       }
7043    }
7044 }
7045 
7046 void
7047 #ifdef _NO_PROTO
_XmDataFieldSetSel2(w,left,right,disown,sel_time)7048 _XmDataFieldSetSel2( w, left, right, disown, sel_time )
7049         Widget w ;
7050         XmTextPosition left ;
7051         XmTextPosition right ;
7052         Boolean disown ;
7053         Time sel_time ;
7054 #else
7055 _XmDataFieldSetSel2(
7056         Widget w,
7057         XmTextPosition left,
7058         XmTextPosition right,
7059         Boolean disown,
7060         Time sel_time )
7061 #endif /* _NO_PROTO */
7062 {
7063     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7064     Boolean result;
7065 
7066     if (XmTextF_has_secondary(tf)) {
7067        XmTextPosition prim_left, prim_right;
7068 
7069        if (left == XmTextF_sec_pos_left(tf) && right == XmTextF_sec_pos_right(tf))
7070           return;
7071 
7072       /* If the widget has the primary selection, make sure the selection
7073        * highlight is restored appropriately.
7074        */
7075        if (XmDataFieldGetSelectionPosition(w, &prim_left, &prim_right))
7076           df_RestorePrimaryHighlight(tf, prim_left, prim_right);
7077        else
7078           DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf),
7079 		                  XmTextF_sec_pos_right(tf), XmHIGHLIGHT_NORMAL);
7080     }
7081 
7082     if (left < right) {
7083        if (!XmTextF_has_secondary(tf)) {
7084           result = XtOwnSelection(w, XA_SECONDARY, sel_time,
7085 				  _XmDataFieldConvert,
7086 			          _XmDataFieldLoseSelection,
7087 				  (XtSelectionDoneProc) NULL);
7088           XmTextF_sec_time(tf) = sel_time;
7089           XmTextF_has_secondary(tf) = result;
7090           if (result) {
7091              XmTextF_sec_pos_left(tf) = left;
7092              XmTextF_sec_pos_right(tf) = right;
7093           }
7094        } else {
7095           XmTextF_sec_pos_left(tf) = left;
7096           XmTextF_sec_pos_right(tf) = right;
7097        }
7098        XmTextF_sec_drag(tf) = True;
7099    } else {
7100        XmTextF_sec_pos_left(tf) = XmTextF_sec_pos_right(tf) = left;
7101        if (disown) {
7102           XtDisownSelection(w, XA_SECONDARY, sel_time);
7103           XmTextF_has_secondary(tf) = False;
7104        }
7105    }
7106 
7107    DataFieldSetHighlight((XmDataFieldWidget) w, XmTextF_sec_pos_left(tf),
7108 		      XmTextF_sec_pos_right(tf), XmHIGHLIGHT_SECONDARY_SELECTED);
7109 
7110   /* This can be optimized for performance enhancement */
7111 
7112     df_RedisplayText(tf, 0, XmTextF_string_length(tf));
7113 }
7114 
7115 /* ARGSUSED */
7116 static void
7117 #ifdef _NO_PROTO
df_StartDrag(w,event,params,num_params)7118 df_StartDrag( w, event, params, num_params )
7119         Widget w ;
7120         XEvent *event ;
7121         String *params ;
7122         Cardinal *num_params ;
7123 #else
7124 df_StartDrag(
7125         Widget w,
7126         XEvent *event,
7127         String *params,
7128         Cardinal *num_params )
7129 #endif /* _NO_PROTO */
7130 {
7131     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7132     Atom targets[5];
7133     char * tmp_string = "ABC";  /* these are characters in XPCS, so... safe */
7134     XTextProperty tmp_prop;
7135     int status = 0;
7136     Cardinal num_targets = 0;
7137     Widget drag_icon;
7138     Arg args[10];
7139     int n;
7140 
7141     tmp_prop.value = NULL;
7142     status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
7143                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
7144     if (status == Success)
7145        targets[num_targets++] = tmp_prop.encoding;
7146     else
7147        targets[num_targets++] = 99999; /* XmbTextList...  should never fail
7148                                         * for XPCS characters.  But just in
7149                                         * case someones Xlib is broken,
7150                                         * this prevents a core dump.
7151                                         */
7152     if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
7153 
7154 #ifdef UTF8_SUPPORTED
7155     targets[num_targets++] = XmInternAtom(XtDisplay(w), "UTF8_STRING", False);
7156 #endif
7157     targets[num_targets++] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
7158     targets[num_targets++] = XA_STRING;
7159     targets[num_targets++] = XmInternAtom(XtDisplay(w), "TEXT", False);
7160 
7161     drag_icon = XmeGetTextualDragIcon(w);
7162 
7163     n = 0;
7164     XtSetArg(args[n], XmNcursorBackground, tf->core.background_pixel);  n++;
7165     XtSetArg(args[n], XmNcursorForeground, tf->primitive.foreground);  n++;
7166     XtSetArg(args[n], XmNsourceCursorIcon, drag_icon);  n++;
7167     XtSetArg(args[n], XmNexportTargets, targets);  n++;
7168     XtSetArg(args[n], XmNnumExportTargets, num_targets);  n++;
7169     XtSetArg(args[n], XmNconvertProc, _XmDataFieldConvert);  n++;
7170     XtSetArg(args[n], XmNclientData, w);  n++;
7171     if (XmTextF_editable(tf)) {
7172        XtSetArg(args[n], XmNdragOperations, (XmDROP_MOVE | XmDROP_COPY)); n++;
7173     } else {
7174        XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
7175     }
7176     (void) XmDragStart(w, event, args, n);
7177 }
7178 
7179 /* ARGSUSED */
7180 static void
7181 #ifdef _NO_PROTO
df_StartSecondary(w,event,params,num_params)7182 df_StartSecondary( w, event, params, num_params )
7183         Widget w ;
7184         XEvent *event ;
7185         char **params ;
7186         Cardinal *num_params ;
7187 #else
7188 df_StartSecondary(
7189         Widget w,
7190         XEvent *event,
7191         char **params,
7192         Cardinal *num_params )
7193 #endif /* _NO_PROTO */
7194 {
7195   XmDataFieldWidget tf = (XmDataFieldWidget) w;
7196   XmTextPosition position = df_GetPosFromX(tf, (Position) event->xbutton.x);
7197   int status;
7198 
7199   XmTextF_sec_anchor(tf) = position;
7200   XmTextF_selection_move(tf) = FALSE;
7201 
7202   status = XtGrabKeyboard(w, False, GrabModeAsync, GrabModeAsync,
7203 			  event->xbutton.time);
7204 
7205   if (status != GrabSuccess)
7206      XmeWarning(w, GRABKBDERROR);
7207 }
7208 
7209 
7210 /* ARGSUSED */
7211 static void
7212 #ifdef _NO_PROTO
df_ProcessBDrag(w,event,params,num_params)7213 df_ProcessBDrag( w, event, params, num_params )
7214         Widget w ;
7215         XEvent *event ;
7216         char **params ;
7217         Cardinal *num_params ;
7218 #else
7219 df_ProcessBDrag(
7220         Widget w,
7221         XEvent *event,
7222         char **params,
7223         Cardinal *num_params )
7224 #endif /* _NO_PROTO */
7225 {
7226     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7227     XmTextPosition position, left, right;
7228     Position left_x, right_x, dummy;
7229 
7230     position = df_GetPosFromX(tf, (Position) event->xbutton.x);
7231 
7232     XmTextF_sec_pos_left(tf) = position;
7233 
7234     _XmDataFieldDrawInsertionPoint(tf, False);
7235     if (XmDataFieldGetSelectionPosition(w, &left, &right) &&
7236 	left != right) {
7237         if ((position > left && position < right) ||
7238 	  /* Take care of border conditions */
7239 	   (position == left &&
7240             df_GetXYFromPos(tf, left, &left_x, &dummy) &&
7241 	    event->xbutton.x > left_x) ||
7242 	   (position == right &&
7243             df_GetXYFromPos(tf, right, &right_x, &dummy) &&
7244 	    event->xbutton.x < right_x)) {
7245            XmTextF_sel_start(tf) = False;
7246            df_StartDrag(w, event, params, num_params);
7247 	} else {
7248 	   XmTextF_sel_start(tf) = True;
7249 	   XAllowEvents(XtDisplay(w), AsyncBoth, event->xbutton.time);
7250 	   df_StartSecondary(w, event, params, num_params);
7251 	}
7252     } else {
7253        XmTextF_sel_start(tf) = True;
7254        XAllowEvents(XtDisplay(w), AsyncBoth, event->xbutton.time);
7255        df_StartSecondary(w, event, params, num_params);
7256     }
7257     _XmDataFieldDrawInsertionPoint(tf, True);
7258 }
7259 
7260 /* ARGSUSED */
7261 static void
7262 #ifdef _NO_PROTO
df_ExtendSecondary(w,event,params,num_params)7263 df_ExtendSecondary( w, event, params, num_params )
7264         Widget w ;
7265         XEvent *event ;
7266         char **params ;
7267         Cardinal *num_params ;
7268 #else
7269 df_ExtendSecondary(
7270         Widget w,
7271         XEvent *event,
7272         char **params,
7273         Cardinal *num_params )
7274 #endif /* _NO_PROTO */
7275 {
7276   XmDataFieldWidget tf = (XmDataFieldWidget) w;
7277   XmTextPosition position = df_GetPosFromX(tf, (Position) event->xbutton.x);
7278 
7279   if (XmTextF_cancel(tf)) return;
7280 
7281   _XmDataFieldDrawInsertionPoint(tf, False);
7282   if (position < XmTextF_sec_anchor(tf)) {
7283      _XmDataFieldSetSel2(w, position, XmTextF_sec_anchor(tf),
7284 			 False, event->xbutton.time);
7285   } else if (position > XmTextF_sec_anchor(tf)) {
7286      _XmDataFieldSetSel2(w, XmTextF_sec_anchor(tf), position,
7287 			 False, event->xbutton.time);
7288   } else {
7289      _XmDataFieldSetSel2(w, position, position, False, event->xbutton.time);
7290   }
7291 
7292   XmTextF_sec_extending(tf) = True;
7293 
7294   if (!df_CheckTimerScrolling(w, event))
7295      df_DoSecondaryExtend(w, event->xmotion.time);
7296 
7297   _XmDataFieldDrawInsertionPoint(tf, True);
7298 }
7299 
7300 
7301 /* ARGSUSED */
7302 static void
7303 #ifdef _NO_PROTO
df_DoStuff(w,closure,seltype,type,value,length,format)7304 df_DoStuff( w, closure, seltype, type, value, length, format )
7305         Widget w ;
7306         XtPointer closure ;
7307         Atom *seltype ;
7308         Atom *type ;
7309         XtPointer value ;
7310         unsigned long *length ;
7311         int *format ;
7312 #else
7313 df_DoStuff(
7314         Widget w,
7315         XtPointer closure,
7316         Atom *seltype,
7317         Atom *type,
7318         XtPointer value,
7319         unsigned long *length,
7320         int *format )
7321 #endif /* _NO_PROTO */
7322 {
7323     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7324     _XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
7325     Atom NULL_ATOM = XmInternAtom(XtDisplay(w), "NULL", False);
7326     XmTextPosition right, left;
7327     int prim_char_length = 0;
7328     Boolean replace_res = False;
7329     XTextProperty tmp_prop;
7330     int i, status;
7331     int malloc_size;
7332     int num_vals;
7333     char **tmp_value;
7334     XmAnyCallbackStruct cb;
7335 
7336     if (!XmTextF_has_focus(tf) && _XmGetFocusPolicy(w) == XmEXPLICIT)
7337        (void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
7338 
7339     if (!(*length) && *type != NULL_ATOM ) {
7340       /* Backwards compatibility for 1.0 Selections */
7341        if (prim_select->target == XmInternAtom(XtDisplay(w), "TEXT", False)) {
7342           prim_select->target = XA_STRING;
7343           XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, df_DoStuff,
7344                            (XtPointer)prim_select, prim_select->time);
7345        }
7346        XtFree((char *)value);
7347        value = NULL;
7348        return;
7349     }
7350 
7351    /* if length == 0 and *type is the NULL atom we are assuming
7352     * that a DELETE target is requested.
7353     */
7354     if (*type == NULL_ATOM ) {
7355        if (prim_select->num_chars > 0 && XmTextF_selection_move(tf)) {
7356           prim_char_length = prim_select->num_chars;
7357           XmDataFieldSetSelection(w, prim_select->position,
7358 				  prim_select->position + prim_char_length,
7359 				  prim_select->time);
7360           XmTextF_prim_anchor(tf) = prim_select->position;
7361           (void) df_SetDestination(w, XmTextF_cursor_position(tf),
7362 				False, prim_select->time);
7363        }
7364     } else {
7365        int max_length = 0;
7366        Boolean local = XmTextF_has_primary(tf);
7367 
7368        if (XmTextF_selection_move(tf) && local) {
7369           max_length = XmTextF_max_length(tf);
7370           XmTextF_max_length(tf) = INT_MAX;
7371        }
7372 
7373        if (*type == XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False) ||
7374 #ifdef UTF8_SUPPORTED
7375            *type == XmInternAtom(XtDisplay(w), "UTF8_STRING", False) ||
7376 #endif
7377            *type == XA_STRING) {
7378 	  tmp_prop.value = (unsigned char *) value;
7379 	  tmp_prop.encoding = *type;
7380 	  tmp_prop.format = *format;
7381 	  tmp_prop.nitems = *length;
7382 	  num_vals = 0;
7383 	  status = XmbTextPropertyToTextList(XtDisplay(w), &tmp_prop,
7384 					     &tmp_value, &num_vals);
7385 	 /* if no conversion, num_vals is not changed */
7386 	 /* status will be >0 if some characters could not be converted */
7387 	  if (num_vals && (status == Success || status > 0)) {
7388 	     if (XmTextF_max_char_size(tf) == 1){
7389 		char * total_tmp_value;
7390 
7391 		for (i = 0, malloc_size = 1; i < num_vals ; i++)
7392 		   malloc_size += strlen(tmp_value[i]);
7393 		prim_select->num_chars = malloc_size - 1;
7394 		total_tmp_value = XtMalloc ((unsigned) malloc_size);
7395 		total_tmp_value[0] = '\0';
7396 		for (i = 0; i < num_vals ; i++)
7397 		   strcat(total_tmp_value, tmp_value[i]);
7398 		replace_res = _XmDataFieldReplaceText(tf, NULL,
7399 						      prim_select->position,
7400 						      prim_select->position,
7401 						      total_tmp_value,
7402 						      strlen(total_tmp_value),
7403 						      False);
7404 		XFreeStringList(tmp_value);
7405 		XtFree(total_tmp_value);
7406 	     } else {
7407 		wchar_t * wc_value;
7408 
7409 		prim_select->num_chars = 0;
7410 		for (i = 0, malloc_size = sizeof(wchar_t); i < num_vals ; i++)
7411 		   malloc_size += strlen(tmp_value[i]) * sizeof(wchar_t);
7412 		wc_value = (wchar_t*)XtMalloc ((unsigned) malloc_size);
7413 		for (i = 0; i < num_vals ; i++)
7414 		   prim_select->num_chars +=
7415 		                    mbstowcs(wc_value + prim_select->num_chars,
7416 				             tmp_value[i],
7417 				             (size_t)malloc_size -
7418 					     prim_select->num_chars);
7419 		replace_res = _XmDataFieldReplaceText(tf, NULL,
7420 						      prim_select->position,
7421 						      prim_select->position,
7422 						      (char*)wc_value,
7423 						      prim_select->num_chars,
7424 						      False);
7425 		XtFree((char*)wc_value);
7426 	     }
7427 	  } else { /* initialize prim_select values for possible delete oper */
7428 	     prim_select->num_chars = 0;
7429 	  }
7430        } else {
7431 	     if (XmTextF_max_char_size(tf) == 1){
7432                /* Note: *length may be truncated during cast to int */
7433 		prim_select->num_chars = (int) *length;
7434 		replace_res = _XmDataFieldReplaceText(tf, NULL,
7435 						      prim_select->position,
7436 						      prim_select->position,
7437 						      (char *) value,
7438 						      prim_select->num_chars,
7439 						      False);
7440 	     } else {
7441 		wchar_t * wc_value;
7442 
7443 		wc_value = (wchar_t*)XtMalloc ((unsigned)
7444                                                (*length * sizeof(wchar_t)));
7445 		prim_select->num_chars = mbstowcs(wc_value, (char *) value,
7446 					 (size_t) *length);
7447 		replace_res = _XmDataFieldReplaceText(tf, NULL,
7448 						      prim_select->position,
7449 						      prim_select->position,
7450 						      (char*)wc_value,
7451 						      prim_select->num_chars,
7452 						      False);
7453 		XtFree((char*)wc_value);
7454 	     }
7455        }
7456 
7457        if (replace_res) {
7458           XmTextPosition cursorPos;
7459 
7460           XmTextF_pending_off(tf) = FALSE;
7461           cursorPos = prim_select->position + prim_select->num_chars;
7462 	  if (prim_select->num_chars > 0 && !XmTextF_selection_move(tf)){
7463 		(void) df_SetDestination(w, cursorPos, False, prim_select->time);
7464 		_XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos,
7465 					      True, True);
7466 	  }
7467 	  if (XmDataFieldGetSelectionPosition(w, &left, &right)) {
7468              if (XmTextF_selection_move(tf) && left < prim_select->position)
7469                 prim_select->position -= prim_select->num_chars;
7470              if (left <= cursorPos && right >= cursorPos)
7471                 XmTextF_pending_off(tf) = TRUE;
7472           } else {
7473              if (!XmTextF_selection_move(tf) && !XmTextF_add_mode(tf) &&
7474                  prim_select->num_chars != 0)
7475                 XmTextF_prim_anchor(tf) = prim_select->position;
7476           }
7477 	  if (XmTextF_selection_move(tf)) {
7478               prim_select->ref_count++;
7479               XtGetSelectionValue(w, XA_PRIMARY,
7480                                   XmInternAtom(XtDisplay(w), "DELETE", False),
7481                                   df_DoStuff, (XtPointer)prim_select,
7482                                   prim_select->time);
7483            }
7484            cb.reason = XmCR_VALUE_CHANGED;
7485            cb.event = (XEvent *)NULL;
7486            XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
7487 		              (XtPointer) &cb);
7488        }
7489 
7490        if (XmTextF_selection_move(tf) && local) {
7491           XmTextF_max_length(tf) = max_length;
7492        }
7493     }
7494 
7495     XtFree((char *)value);
7496     value = NULL;
7497     if (--prim_select->ref_count == 0)
7498        XtFree((char*)prim_select);
7499 }
7500 
7501 
7502 
7503 /* ARGSUSED */
7504 static void
7505 #ifdef _NO_PROTO
df_Stuff(w,event,params,num_params)7506 df_Stuff( w, event, params, num_params )
7507         Widget w ;
7508         XEvent *event ;
7509         char **params ;
7510         Cardinal *num_params ;
7511 #else
7512 df_Stuff(
7513         Widget w,
7514         XEvent *event,
7515         char **params,
7516         Cardinal *num_params )
7517 #endif /* _NO_PROTO */
7518 {
7519   _XmTextActionRec *tmp = (_XmTextActionRec*)XtMalloc(sizeof(_XmTextActionRec));
7520 
7521 /* Request targets from the selection owner so you can decide what to
7522  * request.  The decision process and request for the selection is
7523  * taken care of in df_HandleTargets().
7524  */
7525 
7526   tmp->event = (XEvent *) XtMalloc(sizeof(XEvent));
7527   memcpy((void *)tmp->event, (void *)event, sizeof(XEvent));
7528 
7529   tmp->params = params;
7530   tmp->num_params = num_params;
7531 
7532   XtGetSelectionValue(w, XA_PRIMARY,
7533 		      XmInternAtom(XtDisplay(w), "TARGETS", False),
7534 		      df_HandleTargets,
7535 		      (XtPointer)tmp, event->xbutton.time);
7536 }
7537 
7538 
7539 /* ARGSUSED */
7540 static void
7541 #ifdef _NO_PROTO
df_HandleSelectionReplies(w,closure,event,cont)7542 df_HandleSelectionReplies( w, closure, event, cont )
7543         Widget w ;
7544         XtPointer closure ;
7545         XEvent *event ;
7546         Boolean *cont ;
7547 #else
7548 df_HandleSelectionReplies(
7549         Widget w,
7550         XtPointer closure,
7551         XEvent *event,
7552         Boolean *cont )
7553 #endif /* _NO_PROTO */
7554 {
7555    XmDataFieldWidget tf = (XmDataFieldWidget) w;
7556    Atom property = (Atom) closure;
7557    TextFDestData dest_data;
7558    XmTextPosition left, right;
7559    int adjustment = 0;
7560    XmAnyCallbackStruct cb;
7561 
7562    if (event->type != SelectionNotify) return;
7563 
7564    XtRemoveEventHandler(w, (EventMask) NULL, TRUE,
7565                         df_HandleSelectionReplies,
7566 		       (XtPointer) XmInternAtom(XtDisplay(w),
7567 						"_XM_TEXT_I_S_PROP", False));
7568 
7569    dest_data = df_GetTextFDestData(w);
7570 
7571    if (event->xselection.property == None) {
7572       (void) _XmDataFieldSetSel2(w, 0, 0, False, event->xselection.time);
7573       XmTextF_selection_move(tf) = False;
7574    } else {
7575       if (dest_data->has_destination) {
7576          adjustment = (int) (XmTextF_sec_pos_right(tf) - XmTextF_sec_pos_left(tf));
7577 
7578          XmDataFieldSetHighlight(w, XmTextF_sec_pos_left(tf),
7579 		                 XmTextF_sec_pos_right(tf), XmHIGHLIGHT_NORMAL);
7580          if (dest_data->position <= XmTextF_sec_pos_left(tf)) {
7581             XmTextF_sec_pos_left(tf) += adjustment - dest_data->replace_length;
7582             XmTextF_sec_pos_right(tf) += adjustment - dest_data->replace_length;
7583          } else if (dest_data->position > XmTextF_sec_pos_left(tf) &&
7584                     dest_data->position < XmTextF_sec_pos_right(tf)) {
7585             XmTextF_sec_pos_left(tf) -= dest_data->replace_length;
7586             XmTextF_sec_pos_right(tf) += adjustment - dest_data->replace_length;
7587          }
7588       }
7589 
7590       left = XmTextF_sec_pos_left(tf);
7591       right = XmTextF_sec_pos_right(tf);
7592 
7593       (void) _XmDataFieldSetSel2(w, 0, 0, False, event->xselection.time);
7594       XmTextF_has_secondary(tf) = False;
7595 
7596       if (XmTextF_selection_move(tf)) {
7597          if (_XmDataFieldReplaceText(tf, event, left, right, NULL, 0, False)) {
7598            if (dest_data->has_destination && XmTextF_cursor_position(tf) > right){
7599               XmTextPosition cursorPos;
7600               cursorPos = XmTextF_cursor_position(tf) - (right - left);
7601               if (!dest_data->quick_key)
7602                 _XmDataFielddf_SetCursorPosition(tf, event, cursorPos,
7603 					      True, True);
7604               (void) df_SetDestination((Widget) tf, cursorPos, False,
7605                                                        event->xselection.time);
7606            }
7607            if (!dest_data->has_destination) {
7608                XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
7609                XmDataFieldSetAddMode(w, False);
7610            }
7611            cb.reason = XmCR_VALUE_CHANGED;
7612            cb.event = event;
7613            XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
7614 		              (XtPointer) &cb);
7615          }
7616          XmTextF_selection_move(tf) = False;
7617       }
7618    }
7619 
7620    XDeleteProperty(XtDisplay(w), event->xselection.requestor, property);
7621 }
7622 
7623 
7624 /*
7625  * Notify the primary selection that the secondary selection
7626  * wants to insert it's selection data into the primary selection.
7627  */
7628    /* REQUEST TARGETS FROM SELECTION RECEIVER; THEN CALL HANDLETARGETS
7629     * WHICH LOOKS AT THE TARGET LIST AND DETERMINE WHAT TARGET TO PLACE
7630     * IN THE PAIR.  IT WILL THEN DO ANY NECESSARY CONVERSIONS BEFORE
7631     * TELLING THE RECEIVER WHAT TO REQUEST AS THE SELECTION VALUE.
7632     * THIS WILL GUARANTEE THE BEST CHANCE AT A SUCCESSFUL EXCHANGE.
7633     */
7634 /* ARGSUSED */
7635 static void
7636 #ifdef _NO_PROTO
df_SecondaryNotify(w,event,params,num_params)7637 df_SecondaryNotify( w, event, params, num_params )
7638         Widget w ;
7639         XEvent *event ;
7640         char **params ;
7641         Cardinal *num_params ;
7642 #else
7643 df_SecondaryNotify(
7644         Widget w,
7645         XEvent *event,
7646         char **params,
7647         Cardinal *num_params )
7648 #endif /* _NO_PROTO */
7649 {
7650     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7651     Atom XM_TEXT_PROP = XmInternAtom(XtDisplay(w), "_XM_TEXT_I_S_PROP", False);
7652     Atom CS_OF_LOCALE; /* to be initialized by XmbTextListToTextProperty */
7653     char * tmp_string = "ABC";  /* these are characters in XPCS, so... safe */
7654     TextFDestData dest_data;
7655     XTextProperty tmp_prop;
7656     _XmTextInsertPair tmp_pair[1];
7657     _XmTextInsertPair *pair = tmp_pair;
7658     XmTextPosition left, right;
7659     int status = 0;
7660 
7661     if (XmTextF_selection_move(tf) == TRUE && XmTextF_has_destination(tf) &&
7662         XmTextF_cursor_position(tf) >= XmTextF_sec_pos_left(tf) &&
7663         XmTextF_cursor_position(tf) <= XmTextF_sec_pos_right(tf)) {
7664        (void) _XmDataFieldSetSel2(w, 0, 0, False, event->xbutton.time);
7665        return;
7666     }
7667 
7668     status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
7669                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
7670     if (status == Success)
7671        CS_OF_LOCALE = tmp_prop.encoding;
7672     else
7673        CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
7674                                  * characters.  But just in case someones
7675                                  * Xlib is broken, this prevents a core dump.
7676                                  */
7677     if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
7678 
7679    /*
7680     * Determine what the reciever supports so you can tell 'em what to
7681     * request.
7682     */
7683 
7684    /* fill in atom pair */
7685     pair->selection = XA_SECONDARY;
7686     pair->target = CS_OF_LOCALE;
7687 
7688    /* add the insert selection property on the text field widget's window */
7689     XChangeProperty(XtDisplay(w), XtWindow(w), XM_TEXT_PROP,
7690     		    XmInternAtom(XtDisplay(w), "ATOM_PAIR", False),
7691 		    32, PropModeReplace, (unsigned char *)pair, 2);
7692 
7693     dest_data = df_GetTextFDestData(w);
7694 
7695     dest_data->has_destination = XmTextF_has_destination(tf);
7696     dest_data->position = XmTextF_cursor_position(tf);
7697     dest_data->replace_length = 0;
7698 
7699     if (*(num_params) == 1) dest_data->quick_key = True;
7700     else dest_data->quick_key = False;
7701 
7702     if (XmDataFieldGetSelectionPosition(w, &left, &right) && left != right) {
7703        if (dest_data->position >= left && dest_data->position <= right)
7704           dest_data->replace_length = (int) (right - left);
7705     }
7706 
7707    /* add an event handler to handle selection notify events */
7708     XtAddEventHandler(w, (EventMask) NULL, TRUE,
7709 		      df_HandleSelectionReplies, (XtPointer)XM_TEXT_PROP);
7710 
7711    /*
7712     * Make a request for the primary selection to convert to
7713     * type INSERT_SELECTION as per ICCCM.
7714     */
7715     XConvertSelection(XtDisplay(w),
7716     		      XmInternAtom(XtDisplay(w), "MOTIF_DESTINATION", False),
7717     		      XmInternAtom(XtDisplay(w), "INSERT_SELECTION", False),
7718                       XM_TEXT_PROP, XtWindow(w), event->xbutton.time);
7719 }
7720 
7721    /*
7722     * LOOKS AT THE TARGET LIST AND DETERMINE WHAT TARGET TO PLACE
7723     * IN THE PAIR.  IT WILL THEN DO ANY NECESSARY CONVERSIONS BEFORE
7724     * TELLING THE RECEIVER WHAT TO REQUEST AS THE SELECTION VALUE.
7725     * THIS WILL GUARANTEE THE BEST CHANCE AT A SUCCESSFUL EXCHANGE.
7726     */
7727 
7728 /* ARGSUSED */
7729 static void
7730 #ifdef _NO_PROTO
df_HandleTargets(w,closure,seltype,type,value,length,format)7731 df_HandleTargets( w, closure, seltype, type, value, length, format )
7732         Widget w ;
7733         XtPointer closure ;
7734         Atom *seltype ;
7735         Atom *type ;
7736         XtPointer value ;
7737         unsigned long *length ;
7738         int *format ;
7739 #else
7740 df_HandleTargets(
7741         Widget w,
7742         XtPointer closure,
7743         Atom *seltype,
7744         Atom *type,
7745         XtPointer value,
7746         unsigned long *length,
7747         int *format )
7748 #endif /* _NO_PROTO */
7749 {
7750     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7751     Atom CS_OF_LOCALE; /* to be initialized by XmbTextListToTextProperty */
7752     Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w),"COMPOUND_TEXT", False);
7753 #ifdef UTF8_SUPPORTED
7754     Atom UTF8_STRING = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
7755 #endif
7756     XmTextPosition left, right;
7757     Boolean supports_locale_data = False;
7758     Boolean supports_CT = False;
7759     Boolean supports_utf8_string = False;
7760     Atom *atom_ptr;
7761     _XmTextActionRec *tmp_action = (_XmTextActionRec *) closure;
7762     _XmTextPrimSelect *prim_select;
7763     char * tmp_string = "ABC";  /* these are characters in XPCS, so... safe */
7764     XTextProperty tmp_prop;
7765     int status = 0;
7766     Atom targets[2];
7767     XmTextPosition select_pos;
7768     int i;
7769 
7770     if (!length) {
7771        XtFree((char *)value);
7772        value = NULL;
7773        XtFree((char *)tmp_action->event);
7774        XtFree((char *)tmp_action);
7775        return; /* Supports no targets, so don't bother sending anything */
7776     }
7777 
7778     atom_ptr = (Atom *)value;
7779 
7780     status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
7781                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
7782     if (status == Success)
7783        CS_OF_LOCALE = tmp_prop.encoding;
7784     else
7785        CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
7786                                  * characters.  But just in case someones
7787                                  * Xlib is broken, this prevents a core dump.
7788                                  */
7789 
7790     if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
7791 
7792     for (i = 0; i < *length; i++, atom_ptr++) {
7793       if (*atom_ptr == CS_OF_LOCALE) {
7794          supports_locale_data = True;
7795 	 break;
7796       }
7797       if (*atom_ptr == COMPOUND_TEXT)
7798          supports_CT = True;
7799 #ifdef UTF8_SUPPORTED
7800       if (*atom_ptr == UTF8_STRING)
7801          supports_utf8_string = True;
7802 #endif
7803     }
7804 
7805 
7806   /*
7807    * Set stuff position to the x and y position of
7808    * the button pressed event for primary pastes.
7809    */
7810    if (tmp_action->event->type == ButtonRelease) {
7811       select_pos =  df_GetPosFromX(tf, (Position)tmp_action->event->xbutton.x);
7812    } else {
7813       select_pos = XmTextF_cursor_position(tf);
7814    }
7815 
7816    if (XmDataFieldGetSelectionPosition(w, &left, &right) &&
7817        left != right && select_pos > left && select_pos < right) {
7818       XtFree((char *)value);
7819       value = NULL;
7820       XtFree((char *)tmp_action->event);
7821       XtFree((char *)tmp_action);
7822       return;
7823    }
7824 
7825    prim_select = (_XmTextPrimSelect *)
7826 		  XtMalloc((unsigned) sizeof(_XmTextPrimSelect));
7827 
7828    prim_select->position = select_pos;
7829 
7830    if (tmp_action->event->type == ButtonRelease) {
7831       prim_select->time = tmp_action->event->xbutton.time;
7832    } else {
7833       prim_select->time = tmp_action->event->xkey.time;
7834    }
7835 
7836    prim_select->num_chars = 0;
7837 
7838    if (supports_locale_data)
7839       prim_select->target = targets[0] = XmInternAtom(XtDisplay(w), "TEXT",
7840 						      False);
7841 #ifdef UTF8_SUPPORTED
7842    else if (supports_utf8_string)
7843        prim_select->target = targets[0] = UTF8_STRING;
7844 #endif
7845    else if (supports_CT)
7846       prim_select->target = targets[0] = COMPOUND_TEXT;
7847    else
7848       prim_select->target = targets[0] = XA_STRING;
7849 
7850    prim_select->ref_count = 1;
7851    /* Make request to call df_DoStuff() with the primary selection. */
7852    XtGetSelectionValue(w, XA_PRIMARY, targets[0], df_DoStuff,
7853                           (XtPointer)prim_select,
7854 			  tmp_action->event->xbutton.time);
7855 
7856    XtFree((char *)value);
7857    value = NULL;
7858    XtFree((char *)tmp_action->event);
7859    XtFree((char *)tmp_action);
7860 }
7861 
7862 static void
7863 #ifdef _NO_PROTO
df_ProcessBDragRelease(w,event,params,num_params)7864 df_ProcessBDragRelease( w, event, params, num_params )
7865         Widget w ;
7866         XEvent *event ;
7867         String *params ;
7868         Cardinal *num_params ;
7869 #else
7870 df_ProcessBDragRelease(
7871         Widget w,
7872         XEvent *event,
7873         String *params,
7874         Cardinal *num_params )
7875 #endif /* _NO_PROTO */
7876 {
7877     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7878     XButtonEvent      *ev = (XButtonEvent *) event;
7879     XmTextPosition position;
7880 
7881    /* Work around for intrinsic bug.  Remove once bug is fixed. */
7882     XtUngrabPointer(w, ev->time);
7883 
7884     _XmDataFieldDrawInsertionPoint(tf, False);
7885     if (!XmTextF_cancel(tf)) XtUngrabKeyboard(w, CurrentTime);
7886 
7887     position = df_GetPosFromX(tf, (Position) event->xbutton.x);
7888 
7889     if (XmTextF_sel_start(tf)) {
7890        if (XmTextF_has_secondary(tf) &&
7891 	       XmTextF_sec_pos_left(tf) != XmTextF_sec_pos_right(tf)) {
7892           if (ev->x > (int)tf->core.width || ev->x < 0 ||
7893 	      ev->y > (int)tf->core.height || ev->y < 0) {
7894              _XmDataFieldSetSel2(w, 0, 0, False, event->xkey.time);
7895              XmTextF_has_secondary(tf) = False;
7896           } else {
7897 	     df_SecondaryNotify(w, event, params, num_params);
7898           }
7899        } else if (!XmTextF_sec_drag(tf) && !XmTextF_cancel(tf) &&
7900 		  XmTextF_sec_pos_left(tf) == position) {
7901 	  XmTextF_stuff_pos(tf) =  df_GetPosFromX(tf, (Position) event->xbutton.x);
7902 	/*
7903 	 * Copy contents of primary selection to the stuff position found above.
7904 	 */
7905 	  df_Stuff(w, event, params, num_params);
7906        }
7907     }
7908 
7909     if (XmTextF_select_id(tf)) {
7910        XtRemoveTimeOut(XmTextF_select_id(tf));
7911        XmTextF_select_id(tf) = 0;
7912     }
7913 
7914     XmTextF_sec_extending(tf) = False;
7915 
7916     XmTextF_sec_drag(tf) = False;
7917     XmTextF_sel_start(tf) = False;
7918     XmTextF_cancel(tf) = False;
7919     _XmDataFieldDrawInsertionPoint(tf, True);
7920 }
7921 
7922 static void
7923 #ifdef _NO_PROTO
df_ProcessCopy(w,event,params,num_params)7924 df_ProcessCopy( w, event, params, num_params )
7925         Widget w ;
7926         XEvent *event ;
7927         char **params ;
7928         Cardinal *num_params ;
7929 #else
7930 df_ProcessCopy(
7931         Widget w,
7932         XEvent *event,
7933         char **params,
7934         Cardinal *num_params )
7935 #endif /* _NO_PROTO */
7936 {
7937     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7938 
7939     _XmDataFieldDrawInsertionPoint(tf, False);
7940     XmTextF_selection_move(tf) = FALSE;
7941     df_ProcessBDragRelease(w, event, params, num_params);
7942     _XmDataFieldDrawInsertionPoint(tf, True);
7943 }
7944 
7945 static void
7946 #ifdef _NO_PROTO
df_ProcessMove(w,event,params,num_params)7947 df_ProcessMove( w, event, params, num_params )
7948         Widget w ;
7949         XEvent *event ;
7950         char **params ;
7951         Cardinal *num_params ;
7952 #else
7953 df_ProcessMove(
7954         Widget w,
7955         XEvent *event,
7956         char **params,
7957         Cardinal *num_params )
7958 #endif /* _NO_PROTO */
7959 {
7960     XmDataFieldWidget tf = (XmDataFieldWidget) w;
7961 
7962     _XmDataFieldDrawInsertionPoint(tf, False);
7963     XmTextF_selection_move(tf) = TRUE;
7964     df_ProcessBDragRelease(w, event, params, num_params);
7965     _XmDataFieldDrawInsertionPoint(tf, True);
7966 }
7967 
7968 
7969 /* ARGSUSED */
7970 static void
7971 #ifdef _NO_PROTO
df_DeleteSelection(w,event,params,num_params)7972 df_DeleteSelection( w, event, params, num_params )
7973         Widget w ;
7974         XEvent *event ;
7975         char **params ;
7976         Cardinal *num_params ;
7977 #else
7978 df_DeleteSelection(
7979         Widget w,
7980         XEvent *event,
7981         char **params,
7982         Cardinal *num_params )
7983 #endif /* _NO_PROTO */
7984 {
7985     (void) DataFieldRemove(w, event);
7986 }
7987 
7988 /* ARGSUSED */
7989 static void
7990 #ifdef _NO_PROTO
df_ClearSelection(w,event,params,num_params)7991 df_ClearSelection( w, event, params, num_params )
7992         Widget w ;
7993         XEvent *event ;
7994         char **params ;
7995         Cardinal *num_params ;
7996 #else
7997 df_ClearSelection(
7998         Widget w,
7999         XEvent *event,
8000         char **params,
8001         Cardinal *num_params )
8002 #endif /* _NO_PROTO */
8003 {
8004     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8005     XmTextPosition left = XmTextF_prim_pos_left(tf);
8006     XmTextPosition right = XmTextF_prim_pos_right(tf);
8007     int num_spaces = 0;
8008     XmAnyCallbackStruct cb;
8009     Boolean rep_result = False;
8010 
8011     if (left < right)
8012        num_spaces = (int)(right - left);
8013     else
8014        num_spaces = (int)(left - right);
8015 
8016     if (num_spaces) {
8017        _XmDataFieldDrawInsertionPoint(tf, False);
8018        if (XmTextF_max_char_size(tf) == 1){
8019           char spaces_cache[100];
8020           Cardinal spaces_size;
8021           char *spaces;
8022           int i;
8023 
8024           spaces_size = num_spaces + 1;
8025 
8026           spaces = (char *)XmStackAlloc(spaces_size, spaces_cache);
8027 
8028           for (i = 0; i < num_spaces; i++) spaces[i] = ' ';
8029           spaces[num_spaces] = 0;
8030 
8031 	  rep_result = _XmDataFieldReplaceText(tf, (XEvent *)event, left, right,
8032 				               spaces, num_spaces, False);
8033           if (XmTextF_cursor_position(tf) > left)
8034 	     df_ResetClipOrigin(tf, False);
8035           XmStackFree((char *)spaces, spaces_cache);
8036        } else {
8037           wchar_t *wc_spaces;
8038           int i;
8039 
8040           wc_spaces = (wchar_t *)XtMalloc((unsigned)
8041                                           (num_spaces + 1) * sizeof(wchar_t));
8042 
8043           for (i = 0; i < num_spaces; i++){
8044              (void)mbtowc(&wc_spaces[i], " ", 1);
8045           }
8046 
8047 	  rep_result = _XmDataFieldReplaceText(tf, (XEvent *)event, left, right,
8048 					       (char*)wc_spaces, num_spaces,
8049 					       False);
8050           if (XmTextF_cursor_position(tf) > left)
8051 	     df_ResetClipOrigin(tf, False);
8052 
8053           XtFree((char*)wc_spaces);
8054        }
8055        if (rep_result) {
8056           cb.reason = XmCR_VALUE_CHANGED;
8057           cb.event = event;
8058           XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
8059 		             (XtPointer) &cb);
8060        }
8061        _XmDataFieldDrawInsertionPoint(tf, True);
8062     }
8063 }
8064 
8065 /* ARGSUSED */
8066 static void
8067 #ifdef _NO_PROTO
df_PageRight(w,event,params,num_params)8068 df_PageRight( w, event, params, num_params )
8069         Widget w ;
8070         XEvent *event ;
8071         char **params ;
8072         Cardinal *num_params ;
8073 #else
8074 df_PageRight(
8075         Widget w,
8076         XEvent *event,
8077         char **params,
8078         Cardinal *num_params )
8079 #endif /* _NO_PROTO */
8080 {
8081     Position x, y;
8082     int length = 0;
8083     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8084     Dimension margin_width = XmTextF_margin_width(tf) +
8085 	                     tf->primitive.shadow_thickness +
8086 			     tf->primitive.highlight_thickness;
8087 
8088     if (XmTextF_max_char_size(tf) != 1){
8089        length = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf),
8090 				XmTextF_string_length(tf));
8091     } else {
8092        length = df_FindPixelLength(tf, XmTextF_value(tf), XmTextF_string_length(tf));
8093     }
8094 
8095     _XmDataFieldDrawInsertionPoint(tf, False);
8096 
8097     if (*num_params > 0 && !strcmp(*params, "extend"))
8098        df_SetAnchorBalancing(tf, XmTextF_cursor_position(tf));
8099 
8100     df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &x, &y);
8101 
8102     if (length - ((int)(tf->core.width - (2 * margin_width)) -
8103 	 XmTextF_h_offset(tf)) > (int)(tf->core.width - (2 * margin_width)))
8104        XmTextF_h_offset(tf) -= tf->core.width - (2 * margin_width);
8105     else
8106        XmTextF_h_offset(tf) = -(length - (tf->core.width - (2 * margin_width)));
8107 
8108     df_RedisplayText(tf, 0, XmTextF_string_length(tf));
8109     _XmDataFielddf_SetCursorPosition(tf, event, df_GetPosFromX(tf, x),
8110 				  True, True);
8111 
8112     if (*num_params > 0 && !strcmp(*params, "extend"))
8113        df_KeySelection(w, event, params, num_params);
8114 
8115     _XmDataFieldDrawInsertionPoint(tf, True);
8116 }
8117 
8118 /* ARGSUSED */
8119 static void
8120 #ifdef _NO_PROTO
df_PageLeft(w,event,params,num_params)8121 df_PageLeft( w, event, params, num_params )
8122         Widget w ;
8123         XEvent *event ;
8124         char **params ;
8125         Cardinal *num_params ;
8126 #else
8127 df_PageLeft(
8128         Widget w,
8129         XEvent *event,
8130         char **params,
8131         Cardinal *num_params )
8132 #endif /* _NO_PROTO */
8133 {
8134     Position x, y;
8135     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8136     int margin_width = (int)XmTextF_margin_width(tf) +
8137 	                     tf->primitive.shadow_thickness +
8138 			     tf->primitive.highlight_thickness;
8139 
8140     _XmDataFieldDrawInsertionPoint(tf, False);
8141 
8142     if (*num_params > 0 && !strcmp(*params, "extend"))
8143        df_SetAnchorBalancing(tf, XmTextF_cursor_position(tf));
8144 
8145     df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &x, &y);
8146     if (margin_width  <= XmTextF_h_offset(tf) +
8147 			    ((int)tf->core.width - (2 * margin_width)))
8148        XmTextF_h_offset(tf) = margin_width;
8149     else
8150        XmTextF_h_offset(tf) += tf->core.width - (2 * margin_width);
8151 
8152     df_RedisplayText(tf, 0, XmTextF_string_length(tf));
8153     _XmDataFielddf_SetCursorPosition(tf, event, df_GetPosFromX(tf, x),
8154 				  True, True);
8155 
8156     if (*num_params > 0 && !strcmp(*params, "extend"))
8157        df_KeySelection(w, event, params, num_params);
8158 
8159     _XmDataFieldDrawInsertionPoint(tf, True);
8160 }
8161 
8162 static void
8163 #ifdef _NO_PROTO
df_CopyPrimary(w,event,params,num_params)8164 df_CopyPrimary( w, event, params, num_params )
8165         Widget w ;
8166         XEvent *event ;
8167         char **params ;
8168         Cardinal *num_params ;
8169 #else
8170 df_CopyPrimary(
8171         Widget w,
8172         XEvent *event,
8173         char **params,
8174         Cardinal *num_params )
8175 #endif /* _NO_PROTO */
8176 {
8177     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8178 
8179     _XmDataFieldDrawInsertionPoint(tf, False);
8180     XmTextF_selection_move(tf) = False;
8181 
8182    /* perform the primary paste action */
8183     df_Stuff(w, event, params, num_params);
8184     _XmDataFieldDrawInsertionPoint(tf, True);
8185 }
8186 
8187 static void
8188 #ifdef _NO_PROTO
df_CutPrimary(w,event,params,num_params)8189 df_CutPrimary( w, event, params, num_params )
8190         Widget w ;
8191         XEvent *event ;
8192         char **params ;
8193         Cardinal *num_params ;
8194 #else
8195 df_CutPrimary(
8196         Widget w,
8197         XEvent *event,
8198         char **params,
8199         Cardinal *num_params )
8200 #endif /* _NO_PROTO */
8201 {
8202     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8203 
8204     _XmDataFieldDrawInsertionPoint(tf, False);
8205     XmTextF_selection_move(tf) = True;
8206     df_Stuff(w, event, params, num_params);
8207     _XmDataFieldDrawInsertionPoint(tf, True);
8208 }
8209 
8210 /* ARGSUSED */
8211 static void
8212 #ifdef _NO_PROTO
df_SetAnchor(w,event,params,num_params)8213 df_SetAnchor( w, event, params, num_params )
8214         Widget w ;
8215         XEvent *event ;
8216         char **params ;
8217         Cardinal *num_params ;
8218 #else
8219 df_SetAnchor(
8220         Widget w,
8221         XEvent *event,
8222         char **params,
8223         Cardinal *num_params )
8224 #endif /* _NO_PROTO */
8225 {
8226     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8227     XmTextPosition left, right;
8228 
8229     XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
8230     (void) df_SetDestination(w, XmTextF_prim_anchor(tf), False, event->xkey.time);
8231     if (XmDataFieldGetSelectionPosition(w, &left, &right)) {
8232        _XmDataFieldStartSelection(tf, XmTextF_prim_anchor(tf),
8233                                   XmTextF_prim_anchor(tf), event->xkey.time);
8234        XmDataFieldSetAddMode(w, False);
8235     }
8236 }
8237 
8238 /* ARGSUSED */
8239 static void
8240 #ifdef _NO_PROTO
df_ToggleOverstrike(w,event,params,num_params)8241 df_ToggleOverstrike( w, event, params, num_params )
8242         Widget w ;
8243         XEvent *event ;
8244         char **params ;
8245         Cardinal *num_params ;
8246 #else
8247 df_ToggleOverstrike(
8248         Widget w,
8249         XEvent *event,
8250         char **params,
8251         Cardinal *num_params )
8252 #endif /* _NO_PROTO */
8253 {
8254     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8255 
8256     _XmDataFieldDrawInsertionPoint(tf, False);
8257     XmTextF_overstrike(tf) = !XmTextF_overstrike(tf);
8258     XmTextF_refresh_ibeam_off(tf) = True;
8259     if (XmTextF_overstrike(tf))
8260       XmTextF_cursor_width(tf) = XmTextF_cursor_height(tf) >> 1;
8261     else {
8262       XmTextF_cursor_width(tf) = 5;
8263       if (XmTextF_cursor_height(tf) > 19)
8264 	XmTextF_cursor_width(tf)++;
8265       df_ResetClipOrigin(tf, False);
8266     }
8267     _XmDataFToggleCursorGC(w);
8268     _XmDataFieldDrawInsertionPoint(tf, True);
8269 }
8270 
8271 /* ARGSUSED */
8272 static void
8273 #ifdef _NO_PROTO
df_ToggleAddMode(w,event,params,num_params)8274 df_ToggleAddMode( w, event, params, num_params )
8275         Widget w ;
8276         XEvent *event ;
8277         char **params ;
8278         Cardinal *num_params ;
8279 #else
8280 df_ToggleAddMode(
8281         Widget w,
8282         XEvent *event,
8283         char **params,
8284         Cardinal *num_params )
8285 #endif /* _NO_PROTO */
8286 {
8287     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8288     XmTextPosition left, right;
8289 
8290     _XmDataFieldDrawInsertionPoint(tf, False);
8291 
8292     XmDataFieldSetAddMode(w, !XmTextF_add_mode(tf));
8293     if (XmTextF_add_mode(tf) &&
8294         (!(XmDataFieldGetSelectionPosition(w, &left, &right)) ||
8295 	 left == right))
8296        XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
8297 
8298     _XmDataFieldDrawInsertionPoint(tf, True);
8299 }
8300 
8301 /* ARGSUSED */
8302 static void
8303 #ifdef _NO_PROTO
df_SelectAll(w,event,params,num_params)8304 df_SelectAll( w, event, params, num_params )
8305         Widget w ;
8306         XEvent *event ;
8307         char **params ;
8308         Cardinal *num_params ;
8309 #else
8310 df_SelectAll(
8311         Widget w,
8312         XEvent *event,
8313         char **params,
8314         Cardinal *num_params )
8315 #endif /* _NO_PROTO */
8316 {
8317     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8318 
8319     _XmDataFieldDrawInsertionPoint(tf, False);
8320     if (XmTextF_has_primary(tf))
8321        df_SetSelection(tf, 0, XmTextF_string_length(tf), True);
8322     else
8323        _XmDataFieldStartSelection(tf, 0, XmTextF_string_length(tf),
8324            	      		  event->xbutton.time);
8325 
8326     /* Call _XmDataFielddf_SetCursorPosition to force image gc to be updated
8327      * in case the i-beam is contained within the selection */
8328 
8329     XmTextF_pending_off(tf) = False;
8330 
8331     _XmDataFielddf_SetCursorPosition(tf, NULL, XmTextF_cursor_position(tf),
8332 				  False, False);
8333     XmTextF_prim_anchor(tf) = 0;
8334 
8335     (void) df_SetDestination(w, XmTextF_cursor_position(tf),
8336 			  False, event->xkey.time);
8337     _XmDataFieldDrawInsertionPoint(tf, True);
8338 }
8339 
8340 /* ARGSUSED */
8341 static void
8342 #ifdef _NO_PROTO
df_DeselectAll(w,event,params,num_params)8343 df_DeselectAll( w, event, params, num_params )
8344         Widget w ;
8345         XEvent *event ;
8346         char **params ;
8347         Cardinal *num_params ;
8348 #else
8349 df_DeselectAll(
8350         Widget w,
8351         XEvent *event,
8352         char **params,
8353         Cardinal *num_params )
8354 #endif /* _NO_PROTO */
8355 {
8356     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8357 
8358     _XmDataFieldDrawInsertionPoint(tf, False);
8359     df_SetSelection(tf, XmTextF_cursor_position(tf), XmTextF_cursor_position(tf), True);
8360     XmTextF_pending_off(tf) = True;
8361     _XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
8362 				  True, True);
8363     XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
8364     (void) df_SetDestination(w, XmTextF_cursor_position(tf),
8365 			  False, event->xkey.time);
8366     _XmDataFieldDrawInsertionPoint(tf, True);
8367 }
8368 
8369 /* ARGSUSED */
8370 static void
8371 #ifdef _NO_PROTO
df_VoidAction(w,event,params,num_params)8372 df_VoidAction( w, event, params, num_params )
8373         Widget w ;
8374         XEvent *event ;
8375         char **params ;
8376         Cardinal *num_params ;
8377 #else
8378 df_VoidAction(
8379         Widget w,
8380         XEvent *event,
8381         char **params,
8382         Cardinal *num_params )
8383 #endif /* _NO_PROTO */
8384 {
8385   /* Do Nothing */
8386 }
8387 
8388 /* ARGSUSED */
8389 static void
8390 #ifdef _NO_PROTO
df_CutClipboard(w,event,params,num_params)8391 df_CutClipboard( w, event, params, num_params )
8392         Widget w ;
8393         XEvent *event ;
8394         char **params ;
8395         Cardinal *num_params ;
8396 #else
8397 df_CutClipboard(
8398         Widget w,
8399         XEvent *event,
8400         char **params,
8401         Cardinal *num_params )
8402 #endif /* _NO_PROTO */
8403 {
8404     _XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, False);
8405     (void) XmDataFieldCut(w, event->xkey.time);
8406     _XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, True);
8407 }
8408 
8409 /* ARGSUSED */
8410 static void
8411 #ifdef _NO_PROTO
df_CopyClipboard(w,event,params,num_params)8412 df_CopyClipboard( w, event, params, num_params )
8413         Widget w ;
8414         XEvent *event ;
8415         char **params ;
8416         Cardinal *num_params ;
8417 #else
8418 df_CopyClipboard(
8419         Widget w,
8420         XEvent *event,
8421         char **params,
8422         Cardinal *num_params )
8423 #endif /* _NO_PROTO */
8424 {
8425     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8426 
8427     _XmDataFieldDrawInsertionPoint(tf, False);
8428     (void) XmDataFieldCopy(w, event->xkey.time);
8429     (void) df_SetDestination(w, XmTextF_cursor_position(tf), False, event->xkey.time);
8430     _XmDataFieldDrawInsertionPoint(tf, True);
8431 }
8432 
8433 /* ARGSUSED */
8434 static void
8435 #ifdef _NO_PROTO
df_PasteClipboard(w,event,params,num_params)8436 df_PasteClipboard( w, event, params, num_params )
8437         Widget w ;
8438         XEvent *event ;
8439         char **params ;
8440         Cardinal *num_params ;
8441 #else
8442 df_PasteClipboard(
8443         Widget w,
8444         XEvent *event,
8445         char **params,
8446         Cardinal *num_params )
8447 #endif /* _NO_PROTO */
8448 {
8449     _XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, False);
8450     (void) XmDataFieldPaste(w);
8451     _XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, True);
8452 }
8453 
8454 /* ARGSUSED */
8455 static void
8456 #ifdef _NO_PROTO
df_TraverseDown(w,event,params,num_params)8457 df_TraverseDown( w, event, params, num_params )
8458         Widget w ;
8459         XEvent *event ;
8460         char **params ;
8461         Cardinal *num_params ;
8462 #else
8463 df_TraverseDown(
8464         Widget w,
8465         XEvent *event,
8466         char **params,
8467         Cardinal *num_params )
8468 #endif /* _NO_PROTO */
8469 {
8470     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8471 
8472     if (tf->primitive.navigation_type == XmNONE && df_VerifyLeave(tf, event)) {
8473        XmTextF_traversed(tf) = True;
8474        if (!_XmMgrTraversal(w, XmTRAVERSE_DOWN))
8475           XmTextF_traversed(tf) = False;
8476     }
8477 }
8478 
8479 
8480 /* ARGSUSED */
8481 static void
8482 #ifdef _NO_PROTO
df_TraverseUp(w,event,params,num_params)8483 df_TraverseUp( w, event, params, num_params )
8484         Widget w ;
8485         XEvent *event ;
8486         char **params ;
8487         Cardinal *num_params ;
8488 #else
8489 df_TraverseUp(
8490         Widget w,
8491         XEvent *event,
8492         char **params,
8493         Cardinal *num_params )
8494 #endif /* _NO_PROTO */
8495 {
8496     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8497 
8498     if (tf->primitive.navigation_type == XmNONE && df_VerifyLeave(tf, event)) {
8499        XmTextF_traversed(tf) = True;
8500        if (!_XmMgrTraversal(w, XmTRAVERSE_UP))
8501           XmTextF_traversed(tf) = False;
8502     }
8503 }
8504 
8505 /* ARGSUSED */
8506 static void
8507 #ifdef _NO_PROTO
df_TraverseHome(w,event,params,num_params)8508 df_TraverseHome( w, event, params, num_params )
8509         Widget w ;
8510         XEvent *event ;
8511         char **params ;
8512         Cardinal *num_params ;
8513 #else
8514 df_TraverseHome(
8515         Widget w,
8516         XEvent *event,
8517         char **params,
8518         Cardinal *num_params )
8519 #endif /* _NO_PROTO */
8520 {
8521     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8522 
8523    /* Allow the verification routine to control the traversal */
8524     if (tf->primitive.navigation_type == XmNONE && df_VerifyLeave(tf, event)) {
8525        XmTextF_traversed(tf) = True;
8526        if (!_XmMgrTraversal(w, XmTRAVERSE_HOME))
8527           XmTextF_traversed(tf) = False;
8528     }
8529 }
8530 
8531 
8532 /* ARGSUSED */
8533 static void
8534 #ifdef _NO_PROTO
df_TraverseNextTabGroup(w,event,params,num_params)8535 df_TraverseNextTabGroup( w, event, params, num_params )
8536         Widget w ;
8537         XEvent *event ;
8538         char **params ;
8539         Cardinal *num_params ;
8540 #else
8541 df_TraverseNextTabGroup(
8542         Widget w,
8543         XEvent *event,
8544         char **params,
8545         Cardinal *num_params )
8546 #endif /* _NO_PROTO */
8547 {
8548     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8549 
8550    /* Allow the verification routine to control the traversal */
8551     if (df_VerifyLeave(tf, event)) {
8552        XmTextF_traversed(tf) = True;
8553        if (!_XmMgrTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP))
8554           XmTextF_traversed(tf) = False;
8555     }
8556 }
8557 
8558 
8559 /* ARGSUSED */
8560 static void
8561 #ifdef _NO_PROTO
df_TraversePrevTabGroup(w,event,params,num_params)8562 df_TraversePrevTabGroup( w, event, params, num_params )
8563         Widget w ;
8564         XEvent *event ;
8565         char **params ;
8566         Cardinal *num_params ;
8567 #else
8568 df_TraversePrevTabGroup(
8569         Widget w,
8570         XEvent *event,
8571         char **params,
8572         Cardinal *num_params )
8573 #endif /* _NO_PROTO */
8574 {
8575     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8576 
8577    /* Allow the verification routine to control the traversal */
8578     if (df_VerifyLeave(tf, event)) {
8579        XmTextF_traversed(tf) = True;
8580        if (!_XmMgrTraversal(w, XmTRAVERSE_PREV_TAB_GROUP))
8581           XmTextF_traversed(tf) = False;
8582     }
8583 }
8584 
8585 
8586 /* ARGSUSED */
8587 static void
8588 #ifdef _NO_PROTO
df_TextEnter(w,event,params,num_params)8589 df_TextEnter( w, event, params, num_params )
8590         Widget w ;
8591         XEvent *event ;
8592         String *params ;
8593         Cardinal *num_params ;
8594 #else
8595 df_TextEnter(
8596         Widget w,
8597         XEvent *event,
8598         String *params,
8599         Cardinal *num_params )
8600 #endif /* _NO_PROTO */
8601 {
8602     XmDataFieldWidget tf = (XmDataFieldWidget) w;
8603     XmAnyCallbackStruct cb;
8604     XPoint xmim_point;
8605 
8606     /* Use != NotifyInferior along with event->xcrossing.focus to avoid
8607      * sending input method info if reason for the event is pointer moving
8608      * from TextF widget to over-the-spot window (case when over-the-spot
8609      * is child of TextF widget). */
8610     if (_XmGetFocusPolicy(w) != XmEXPLICIT && !(XmTextF_has_focus(tf)) &&
8611 	event->xcrossing.focus &&
8612         (event->xcrossing.detail != NotifyInferior)) {
8613        if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
8614        _XmDataFieldDrawInsertionPoint(tf, False);
8615        XmTextF_blink_on(tf) = False;
8616        XmTextF_has_focus(tf) = True;
8617        _XmDataFToggleCursorGC(w);
8618        if (XtIsSensitive(w)) df_ChangeBlinkBehavior(tf, True);
8619        _XmDataFieldDrawInsertionPoint(tf, True);
8620        df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &xmim_point.x,
8621 		    &xmim_point.y);
8622        XmImVaSetFocusValues(w, XmNspotLocation, &xmim_point, NULL);
8623        cb.reason = XmCR_FOCUS;
8624        cb.event = event;
8625        XtCallCallbackList (w, XmTextF_focus_callback(tf), (XtPointer) &cb);
8626     }
8627 
8628     _XmPrimitiveEnter(w, event, params, num_params);
8629 }
8630 
8631 
8632 /* ARGSUSED */
8633 static void
8634 #ifdef _NO_PROTO
df_TextLeave(w,event,params,num_params)8635 df_TextLeave( w, event, params, num_params )
8636         Widget w ;
8637         XEvent *event ;
8638         String *params ;
8639         Cardinal *num_params ;
8640 #else
8641 df_TextLeave(
8642         Widget w,
8643         XEvent *event,
8644         String *params,
8645         Cardinal *num_params )
8646 #endif /* _NO_PROTO */
8647 {
8648    XmDataFieldWidget tf = (XmDataFieldWidget) w;
8649 
8650    /* use detail!= NotifyInferior to handle focus change due to pointer
8651     * wandering into over-the-spot input window - we don't want to change
8652     * IM's focus state in this case. */
8653    if (_XmGetFocusPolicy(w) != XmEXPLICIT && XmTextF_has_focus(tf) &&
8654        event->xcrossing.focus &&
8655        (event->xcrossing.detail != NotifyInferior)) {
8656       if (tf->core.sensitive) df_ChangeBlinkBehavior(tf, False);
8657       _XmDataFieldDrawInsertionPoint(tf, False);
8658       XmTextF_has_focus(tf) = False;
8659       _XmDataFToggleCursorGC(w);
8660       XmTextF_blink_on(tf) = True;
8661       _XmDataFieldDrawInsertionPoint(tf, True);
8662       (void) df_VerifyLeave(tf, event);
8663       XmImUnsetFocus(w);
8664    }
8665 
8666    _XmPrimitiveLeave(w, event, params, num_params);
8667 }
8668 
8669 /****************************************************************
8670  *
8671  * Private definitions.
8672  *
8673  ****************************************************************/
8674 
8675 /*
8676  * df_ClassPartInitialize sets up the fast subclassing for the widget.i
8677  * It also merges translation tables.
8678  */
8679 static void
8680 #ifdef _NO_PROTO
df_ClassPartInitialize(w_class)8681 df_ClassPartInitialize( w_class )
8682         WidgetClass w_class ;
8683 #else
8684 df_ClassPartInitialize(
8685         WidgetClass w_class )
8686 #endif /* _NO_PROTO */
8687 {
8688     char *event_bindings;
8689 
8690     _XmFastSubclassInit (w_class, XmDATAFIELD_BIT);
8691 
8692   /* Install traits */
8693   XmeTraitSet((XtPointer) w_class, XmQTaccessTextual, (XtPointer) &dataFieldCS);
8694 
8695     event_bindings = (char *)XtMalloc((unsigned) (strlen(EventBindings1) +
8696                                       strlen(EventBindings2) +
8697                                       strlen(EventBindings3) + strlen("\n") +
8698 				      strlen(EventBindings4) + 1));
8699 
8700     strcpy(event_bindings, EventBindings4);
8701     strcat(event_bindings, "\n");
8702     strcat(event_bindings, EventBindings1);
8703     strcat(event_bindings, EventBindings2);
8704     strcat(event_bindings, EventBindings3);
8705 
8706     _XmProcessLock();
8707     w_class->core_class.tm_table = (String) XtParseTranslationTable(event_bindings);
8708     _XmProcessUnlock();
8709 
8710     XtFree(event_bindings);
8711 }
8712 
8713 /****************************************************************
8714  *
8715  * Private functions used in df_Initialize.
8716  *
8717  ****************************************************************/
8718 
8719 /*
8720  * Verify that the resource settings are valid.  Print a warning
8721  * message and reset the s if the are invalid.
8722  */
8723 static void
8724 #ifdef _NO_PROTO
df_Validates(tf)8725 df_Validates( tf )
8726         XmDataFieldWidget tf ;
8727 #else
8728 df_Validates(
8729         XmDataFieldWidget tf )
8730 #endif /* _NO_PROTO */
8731 {
8732     XtPointer temp_ptr;
8733 
8734     if (XmTextF_cursor_position(tf) < 0) {
8735 	  XmeWarning ((Widget)tf, MSG1);
8736           XmTextF_cursor_position(tf) = 0;
8737     }
8738 
8739     if (XmTextF_columns(tf) <= 0) {
8740 	  XmeWarning ((Widget)tf, MSG2);
8741 	  XmTextF_columns(tf) = 20;
8742     }
8743 
8744     if (XmTextF_selection_array(tf) == NULL)
8745        XmTextF_selection_array(tf) = (XmTextScanType *) df_sarray;
8746 
8747     if (XmTextF_selection_array_count(tf) <= 0)
8748        XmTextF_selection_array_count(tf) = XtNumber(df_sarray);
8749 
8750 /*
8751  * Fix for HaL DTS 9841 - copy the selectionArray into dedicated memory.
8752  */
8753     temp_ptr = (XtPointer)XmTextF_selection_array(tf);
8754     XmTextF_selection_array(tf) = NULL;
8755 
8756     XmTextF_selection_array(tf) = (XmTextScanType *)XtMalloc (
8757 		 XmTextF_selection_array_count(tf) * sizeof(XmTextScanType));
8758     memcpy((void *)XmTextF_selection_array(tf), (void *)temp_ptr,
8759 	   (XmTextF_selection_array_count(tf) * sizeof(XmTextScanType)));
8760 /*
8761  * End fix for HaL DTS 9841
8762  */
8763 }
8764 
8765 static Boolean
8766 #ifdef _NO_PROTO
df_LoadFontMetrics(tf)8767 df_LoadFontMetrics( tf )
8768         XmDataFieldWidget tf ;
8769 #else
8770 df_LoadFontMetrics(
8771         XmDataFieldWidget tf )
8772 #endif /* _NO_PROTO */
8773 {
8774     XmFontContext context;
8775     XmFontListEntry next_entry;
8776     XmFontType type_return = XmFONT_IS_FONT;
8777     XtPointer tmp_font;
8778     Boolean have_font_struct = False;
8779     Boolean have_font_set = False;
8780 #ifdef USE_XFT
8781     Boolean have_xft_font = False;
8782 #endif
8783     XFontSetExtents *fs_extents;
8784     XFontStruct *font;
8785     unsigned long charwidth = 0;
8786     char* font_tag = NULL;
8787     Boolean return_val = 1; /* non-zero == success */
8788 
8789     if (!XmFontListInitFontContext(&context, XmTextF_font_list(tf)))
8790        XmeWarning ((Widget)tf, MSG3);
8791 
8792     do {
8793        next_entry = XmFontListNextEntry(context);
8794        if (next_entry) {
8795           tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
8796           if (type_return == XmFONT_IS_FONTSET) {
8797 	     font_tag = XmFontListEntryGetTag(next_entry);
8798 	     if (!have_font_set){ /* this saves the first fontset found, just in
8799                                    * case we don't find a default tag set.
8800                                    */
8801 	        XmTextF_have_fontset(tf) = True;
8802 #ifdef USE_XFT
8803 	        XmTextF_use_xft(tf) = False;
8804 #endif
8805 	        tf->text.font = (XFontStruct *)tmp_font;
8806 	        have_font_struct = True; /* we have a font set, so no need to
8807                                           * consider future font structs */
8808 	        have_font_set = True;    /* we have a font set. */
8809 
8810 	        if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag))
8811 	           break; /* Break out!  We've found the one we want. */
8812 
8813 	     } else if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag)){
8814                 tf->text.font = (XFontStruct *)tmp_font;
8815 	        have_font_set = True;    /* we have a font set. */
8816 	        break; /* Break out!  We've found the one we want. */
8817 	     }
8818           } else if (type_return == XmFONT_IS_FONT && !have_font_struct) {
8819 	     /* return_type must be XmFONT_IS_FONT */
8820 	     XmTextF_have_fontset(tf) = False;
8821 #ifdef USE_XFT
8822 	     XmTextF_use_xft(tf) = False;
8823 #endif
8824 	     tf->text.font=(XFontStruct*)tmp_font; /* save the first font
8825                                                      * struct in case no font
8826                                                      * set is found */
8827 	     have_font_struct = True;
8828 #ifdef USE_XFT
8829           } else if (type_return == XmFONT_IS_XFT && !have_xft_font) {
8830 	     XmTextF_have_fontset(tf) = False;
8831              XmTextF_use_xft(tf) = True;
8832 	     have_xft_font = True;
8833 	     tf->text.font = tmp_font;
8834 #endif
8835           }
8836        }
8837     } while(next_entry != NULL);
8838 
8839 #if USE_XFT
8840     if (!have_font_struct && !have_font_set && !have_xft_font) {
8841 #else
8842     if (!have_font_struct && !have_font_set) {
8843 #endif
8844           XmeWarning ((Widget)tf, MSG4);
8845     }
8846 
8847     if (XmTextF_max_char_size(tf) > 1 && !have_font_set){
8848      /*XmeWarning((Widget)tf, MSGnnn); */
8849      /* printf ("You've got the wrong font baby, Uh-Huh!\n"); */
8850      /* Must have a font set, as text will be rendered only with new R5 calls
8851       * If df_LoadFontMetrics is called from df_SetValues and set
8852       * values will retain use of old fontlist (which is presumed correct
8853       * for the current locale). */
8854 
8855        return_val = 0; /* tell caller that this font won't work for MB_CUR_MAX*/
8856     }
8857     XmFontListFreeFontContext(context);
8858 
8859     if(XmTextF_have_fontset(tf)){
8860        fs_extents = XExtentsOfFontSet((XFontSet)XmTextF_font(tf));
8861 	charwidth = (unsigned long)fs_extents->max_ink_extent.width;
8862        /* max_ink_extent.y is number of pixels from origin to top of
8863         * rectangle (i.e. y is negative) */
8864        XmTextF_font_ascent(tf) = -fs_extents->max_ink_extent.y;
8865        XmTextF_font_descent(tf) = fs_extents->max_ink_extent.height +
8866                                fs_extents->max_ink_extent.y;
8867 #ifdef USE_XFT
8868     } else if (XmTextF_use_xft(tf)) {
8869 #ifdef FIX_1415
8870 	  _XmXftFontAverageWidth((Widget) tf, TextF_XftFont(tf), (int *)&charwidth);
8871 #else
8872         charwidth = XmTextF_xft_font(tf)->max_advance_width;
8873 #endif
8874 #ifdef FIX_1531
8875         XmTextF_font_ascent(tf) = TextF_XftFont(tf)->ascent;
8876         XmTextF_font_descent(tf) = TextF_XftFont(tf)->descent;
8877 #endif /* FIX_1531 */
8878 #endif
8879     } else {
8880        font = XmTextF_font(tf);
8881        if ((!XGetFontProperty(font, XA_QUAD_WIDTH, &charwidth)) ||
8882             charwidth == 0) {
8883           if (font->per_char && font->min_char_or_byte2 <= '0' &&
8884                                 font->max_char_or_byte2 >= '0')
8885               charwidth = font->per_char['0' - font->min_char_or_byte2].width;
8886           else
8887               charwidth = font->max_bounds.width;
8888        }
8889        XmTextF_font_ascent(tf) = font->max_bounds.ascent;
8890        XmTextF_font_descent(tf) = font->max_bounds.descent;
8891     }
8892     XmTextF_average_char_width(tf) = (Dimension) charwidth;
8893     return (return_val);
8894 }
8895 
8896 
8897 /* df_ValidateString makes the following assumption:  if MB_CUR_MAX == 1, value
8898  * is a char*, otherwise value is a wchar_t*.  The Boolean "is_wchar" indicates
8899  * if value points to char* or wchar_t* data.
8900  *
8901  * It is df_ValidateString's task to verify that "value" contains only printing
8902  * characters; all others are discarded.  df_ValidateString then mallocs data
8903  * to store the value and assignes it to XmTextF_value(tf) (if MB_CUR_MAX == 1)
8904  * or to XmTextF_wc_value(tf) (if MB_CUR_MAX != 1), setting the opposite
8905  * pointer to NULL.  It is the callers responsibility to free data before
8906  * calling df_ValidateString.
8907  */
8908 static void
8909 #ifdef _NO_PROTO
df_ValidateString(tf,value,is_wchar)8910 df_ValidateString( tf, value, is_wchar )
8911         XmDataFieldWidget tf ;
8912         char *value ;
8913 	Boolean is_wchar;
8914 #else
8915 df_ValidateString(
8916         XmDataFieldWidget tf,
8917         char *value,
8918 #if NeedWidePrototypes
8919 	int is_wchar)
8920 #else
8921 	Boolean is_wchar)
8922 #endif /* NeedWidePrototypes */
8923 #endif /* _NO_PROTO */
8924 {
8925    /* if value is wchar_t *, must count the characters; else use strlen */
8926 
8927    int str_len = 0;
8928    int i, j;
8929    char stack_cache[400];
8930 
8931    if (!is_wchar) {
8932       char *temp_str, *curr_str, *start_temp;
8933 
8934       str_len = strlen(value);
8935       temp_str = (char*)XmStackAlloc((Cardinal)str_len + 1, stack_cache);
8936       start_temp = temp_str;
8937       curr_str = value;
8938 
8939       for (i = 0; i < str_len;) {
8940          if (XmTextF_max_char_size(tf) == 1){
8941             if (df_FindPixelLength(tf, curr_str, 1)) {
8942                *temp_str = *curr_str;
8943                temp_str++;
8944             } else {
8945                char warn_str[52];
8946                sprintf(warn_str, MSG5, *curr_str);
8947                XmeWarning ((Widget)tf, warn_str);
8948             }
8949 	    curr_str++;
8950 	    i++;
8951 	 } else {
8952 	    wchar_t tmp[XmTextF_max_char_size(tf)+1];
8953 	    int num_conv;
8954 	    num_conv = mbtowc(tmp, curr_str, XmTextF_max_char_size(tf));
8955             if (num_conv >= 0 && df_FindPixelLength(tf, (char*) &tmp, 1)) {
8956 	       for (j = 0; j < num_conv; j++) {
8957                   *temp_str = *curr_str;
8958                   temp_str++;
8959 		  curr_str++;
8960 		  i++;
8961 		}
8962             } else {
8963                char warn_str[52];
8964                sprintf(warn_str, MSG5, *curr_str);
8965                XmeWarning ((Widget)tf, warn_str);
8966 	       curr_str++;
8967 	       i++;
8968             }
8969 	 }
8970       }
8971       *temp_str = '\0';
8972 
8973       /* value contains validated string; now stuff it into the proper
8974        * instance pointer. */
8975       if (XmTextF_max_char_size(tf) == 1) {
8976          XmTextF_string_length(tf) = strlen(start_temp);
8977         /* malloc the space for the text value */
8978          XmTextF_value(tf) = (char *) memcpy(
8979 			     XtMalloc((unsigned)(XmTextF_string_length(tf) + 30)),
8980 			       (void *)start_temp, XmTextF_string_length(tf) + 1);
8981          XmTextF_size_allocd(tf) = XmTextF_string_length(tf) + 30;
8982          XmTextF_wc_value(tf) = NULL;
8983       } else { /* Need wchar_t* data to set as the widget's value */
8984          /* count number of wchar's */
8985          str_len = strlen(start_temp);
8986          XmTextF_string_length(tf) = str_len;
8987 
8988          XmTextF_size_allocd(tf) = (XmTextF_string_length(tf) + 30)*sizeof(wchar_t);
8989          XmTextF_wc_value(tf) = (wchar_t*)XtMalloc((unsigned)XmTextF_size_allocd(tf));
8990          XmTextF_string_length(tf) = mbstowcs(XmTextF_wc_value(tf), start_temp,
8991                                            XmTextF_string_length(tf) + 30);
8992          XmTextF_value(tf) = NULL;
8993       }
8994       XmStackFree((char *)start_temp, stack_cache);
8995    } else {  /* pointer passed points to wchar_t* data */
8996       wchar_t *wc_value, *wcs_temp_str, *wcs_start_temp, *wcs_curr_str;
8997       char scratch[8];
8998       int new_len = 0;
8999       int csize = 1;
9000 
9001       wc_value = (wchar_t *) value;
9002       for (str_len = 0, i = 0; *wc_value != (wchar_t)0L; str_len++)
9003           wc_value++; /* count number of wchars */
9004       wcs_temp_str=(wchar_t *)XmStackAlloc((Cardinal)
9005 					   ((str_len+1) * sizeof(wchar_t)),
9006 					   stack_cache);
9007       wcs_start_temp = wcs_temp_str;
9008       wcs_curr_str = (wchar_t *) value;
9009 
9010       for (i = 0; i < str_len; i++, wcs_curr_str++) {
9011 	 if (XmTextF_max_char_size(tf) == 1){
9012 	    csize = wctomb(scratch, *wcs_curr_str);
9013 	    if (csize >= 0 && df_FindPixelLength(tf, scratch, csize)) {
9014 	       *wcs_temp_str = *wcs_curr_str;
9015 	       wcs_temp_str++;
9016 	       new_len++;
9017 	    } else {
9018 	       char warn_str[52];
9019 	       scratch[csize]= '\0';
9020 	       sprintf(warn_str, WC_MSG1, scratch);
9021 	       XmeWarning ((Widget)tf, warn_str);
9022 	    }
9023 	 } else {
9024 	    if (df_FindPixelLength(tf, (char*)wcs_curr_str, 1)) {
9025 	       *wcs_temp_str = *wcs_curr_str;
9026 	       wcs_temp_str++;
9027 	       new_len++;
9028 	    } else {
9029                char warn_str[52];
9030                csize = wctomb(scratch, *wcs_curr_str);
9031 	       if (csize >= 0)
9032                   scratch[csize]= '\0';
9033 	       else
9034 		  scratch[0] = '\0';
9035                sprintf(warn_str, WC_MSG1, scratch);
9036                XmeWarning ((Widget)tf, warn_str);
9037 	    }
9038 	 }
9039       }
9040       str_len = new_len;
9041 
9042       *wcs_temp_str = (wchar_t)0L; /* terminate with a wchar_t NULL */
9043 
9044       XmTextF_string_length(tf) = str_len; /* This is *wrong* if MB_CUR_MAX > 2
9045 					 * with no font set... but what can
9046 					 * ya do? Spec says let it dump core. */
9047 
9048       XmTextF_size_allocd(tf) = (str_len + 30) * sizeof(wchar_t);
9049       if (XmTextF_max_char_size(tf) == 1) { /* Need to store data as char* */
9050          XmTextF_value(tf) = XtMalloc((unsigned)XmTextF_size_allocd(tf));
9051          (void)wcstombs(XmTextF_value(tf), wcs_start_temp, XmTextF_size_allocd(tf));
9052          XmTextF_wc_value(tf) = NULL;
9053       } else { /* Need to store data as wchar_t* */
9054          XmTextF_wc_value(tf) = (wchar_t*)memcpy(XtMalloc((unsigned)
9055 						       XmTextF_size_allocd(tf)),
9056                                               	       (void*)wcs_start_temp,
9057                                                        (1 + str_len) *
9058 						       sizeof(wchar_t));
9059          XmTextF_value(tf) = NULL;
9060       }
9061       XmStackFree((char *)wcs_start_temp, stack_cache);
9062    }
9063 }
9064 
9065 /* The following is a hack to overcome the buggy Motif from SGI on IM */
9066 #if defined(__sgi)
9067 static void /* CR03685 */
9068 #ifdef _NO_PROTO
SGI_hack_XmImRegister(w)9069 SGI_hack_XmImRegister(w)
9070   Widget w;
9071 #else
9072 SGI_hack_XmImRegister(
9073   Widget w )
9074 #endif /* _NO_PROTO */
9075 {
9076   _XmProcessLock();
9077   w->core.widget_class = xmTextFieldWidgetClass;
9078   _XmProcessUnlock();
9079 
9080   XmImRegister(w, NULL);
9081 
9082   _XmProcessLock();
9083   w->core.widget_class = xmDataFieldWidgetClass;
9084   _XmProcessUnlock();
9085 }
9086 #endif
9087 /*
9088  * df_Initialize the s in the text fields instance record.
9089  */
9090 static void
9091 #ifdef _NO_PROTO
df_InitializeTextStruct(tf)9092 df_InitializeTextStruct( tf )
9093         XmDataFieldWidget tf ;
9094 #else
9095 df_InitializeTextStruct(
9096         XmDataFieldWidget tf )
9097 #endif /* _NO_PROTO */
9098 {
9099    /* Flag used in losing focus verification to indicate that a traversal
9100     * key was pressed.  Must be initialized to False.
9101     */
9102     Arg args[6];  /* To set initial values to input method */
9103     Cardinal n = 0;
9104     XPoint xmim_point;
9105 
9106     XmTextF_traversed(tf) = False;
9107 
9108     XmTextF_add_mode(tf) = False;
9109     XmTextF_has_focus(tf) = False;
9110     XmTextF_blink_on(tf) = True;
9111     XmTextF_cursor_on(tf) = 0;
9112     XmTextF_has_rect(tf) = False;
9113     XmTextF_has_primary(tf) = False;
9114     XmTextF_has_secondary(tf) = False;
9115     XmTextF_has_destination(tf) = False;
9116     XmTextF_overstrike(tf) = False;
9117     XmTextF_selection_move(tf) = False;
9118     XmTextF_sel_start(tf) = False;
9119     XmTextF_pending_off(tf) = True;
9120     XmTextF_fontlist_created(tf) = False;
9121     XmTextF_cancel(tf) = False;
9122     XmTextF_extending(tf) = False;
9123     XmTextF_prim_time(tf) = 0;
9124     XmTextF_dest_time(tf) = 0;
9125     XmTextF_select_id(tf) = 0;
9126     XmTextF_select_pos_x(tf) = 0;
9127     XmTextF_sec_extending(tf) = False;
9128     XmTextF_sec_drag(tf) = False;
9129     XmTextF_changed_visible(tf) = False;
9130     XmTextF_refresh_ibeam_off(tf) = True;
9131     XmTextF_in_setvalues(tf) = False;
9132     XmTextF_do_resize(tf) = True;
9133     XmTextF_have_inverted_image_gc(tf) = False;
9134     XmTextF_margin_top(tf) = XmTextF_margin_height(tf);
9135     XmTextF_margin_bottom(tf) = XmTextF_margin_height(tf);
9136 
9137     /* copy over the font list */
9138     if (XmTextF_font_list(tf) == NULL) {
9139        XmTextF_font_list(tf) = XmeGetDefaultRenderTable((Widget)tf,
9140 				              (unsigned char) XmTEXT_FONTLIST);
9141        XmTextF_fontlist_created(tf) = True;
9142     }
9143 
9144     XmTextF_font_list(tf) = (XmFontList)XmFontListCopy(XmTextF_font_list(tf));
9145 
9146     XmTextF_max_char_size(tf) = MB_CUR_MAX;
9147 
9148     (void)df_LoadFontMetrics(tf);
9149 
9150     XmTextF_gc(tf) = NULL;
9151     XmTextF_image_gc(tf) = NULL;
9152     XmTextF_save_gc(tf) = NULL;
9153 
9154     if (XmDataField_alignment(tf) == XmALIGNMENT_END)
9155 	XmTextF_new_h_offset(tf) = XmTextF_h_offset(tf) = 0;
9156     else
9157 	XmTextF_new_h_offset(tf) = XmTextF_h_offset(tf) = XmTextF_margin_width(tf) +
9158 	    tf->primitive.shadow_thickness + tf->primitive.highlight_thickness;
9159 
9160     /* df_ValidateString will verify value contents, convert to appropriate
9161      * storage form (i.e. char* or wchar_t*), place in the appropriate
9162      * location (text.value or text.wc_value), and null out opposite
9163      * pointer.  */
9164 
9165     if (XmTextF_wc_value(tf) != NULL) { /* XmNvalueWcs was set - it rules */
9166        XmTextF_value(tf) = NULL;
9167        df_ValidateString(tf, (char*)XmTextF_wc_value(tf), True);
9168     } else if (XmTextF_value(tf) != NULL)
9169        df_ValidateString(tf, XmTextF_value(tf), False);
9170     else /* XmTextF_value(tf) is null pointer */
9171        df_ValidateString(tf, "", False);
9172 
9173     if (XmTextF_cursor_position(tf) > XmTextF_string_length(tf))
9174        XmTextF_cursor_position(tf) = XmTextF_string_length(tf);
9175 
9176     XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_prim_pos_left(tf) =
9177      XmTextF_prim_pos_right(tf) = XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
9178 
9179     XmTextF_sec_pos_left(tf) = XmTextF_sec_pos_right(tf) =
9180      	XmTextF_sec_anchor(tf) = XmTextF_cursor_position(tf);
9181 
9182     XmTextF_stuff_pos(tf) = XmTextF_cursor_position(tf);
9183 
9184     XmTextF_cursor_height(tf) = XmTextF_cursor_width(tf) = 0;
9185     XmTextF_stipple_tile(tf) = None;
9186     XmTextF_add_mode_cursor(tf) = XmUNSPECIFIED_PIXMAP;
9187     XmTextF_cursor(tf) = XmUNSPECIFIED_PIXMAP;
9188     XmTextF_ibeam_off(tf) = XmUNSPECIFIED_PIXMAP;
9189     XmTextF_image_clip(tf) = XmUNSPECIFIED_PIXMAP;
9190 
9191     XmTextF_last_time(tf) = 0;
9192 
9193     XmTextF_sarray_index(tf) = 0;
9194 
9195    /* df_Initialize highlight elements */
9196     XmTextF_highlight(tf).number = XmTextF_highlight(tf).maximum = 1;
9197     XmTextF_highlight(tf).list = (_XmHighlightRec *)XtMalloc((unsigned)
9198 						 sizeof(_XmHighlightRec));
9199     XmTextF_highlight(tf).list[0].position = 0;
9200     XmTextF_highlight(tf).list[0].mode = XmHIGHLIGHT_NORMAL;
9201 
9202     XmTextF_timer_id(tf) = (XtIntervalId)0;
9203 
9204     if(XmDataField_picture_source(tf)) {
9205 	XmDataField_picture_source(tf) = XtNewString(XmDataField_picture_source(tf));
9206 	XmDataField_picture(tf) = XmParsePicture(XmDataField_picture_source(tf));
9207         XtAddCallback((Widget)tf, XmNmodifyVerifyCallback,
9208 			  PictureVerifyCallback, NULL);
9209     } else {
9210 	/* No picture specified */
9211 	XmDataField_picture(tf) = NULL;
9212     }
9213 
9214     XmDataFieldSetEditable((Widget)tf, XmTextF_editable(tf));
9215 
9216     if (XmTextF_editable(tf)){
9217 #if defined(__sgi)
9218       /* CR03685 */
9219       SGI_hack_XmImRegister((Widget)tf);
9220 #else
9221       XmImRegister((Widget)tf, (unsigned int) NULL);
9222 #endif
9223       df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &xmim_point.x, &xmim_point.y);
9224       n = 0;
9225       XtSetArg(args[n], XmNfontList, XmTextF_font_list(tf)); n++;
9226       XtSetArg(args[n], XmNbackground, tf->core.background_pixel); n++;
9227       XtSetArg(args[n], XmNforeground, tf->primitive.foreground); n++;
9228       XtSetArg(args[n], XmNbackgroundPixmap,tf->core.background_pixmap);n++;
9229       XtSetArg(args[n], XmNspotLocation, &xmim_point); n++;
9230       XtSetArg(args[n], XmNlineSpace,
9231                XmTextF_font_ascent(tf)+ XmTextF_font_descent(tf)); n++;
9232       XmImSetValues((Widget)tf, args, n);
9233     }
9234 }
9235 
9236 static Pixmap
9237 #ifdef _NO_PROTO
df_GetClipMask(tf,pixmap_name)9238 df_GetClipMask( tf, pixmap_name)
9239         XmDataFieldWidget tf ;
9240         char *pixmap_name ;
9241 #else
9242 df_GetClipMask(
9243         XmDataFieldWidget tf,
9244         char *pixmap_name)
9245 #endif /* _NO_PROTO */
9246 {
9247    Display *dpy = XtDisplay(tf);
9248    Screen *screen = XtScreen(tf);
9249    XGCValues values;
9250    GC fillGC;
9251    Pixmap clip_mask;
9252 
9253    clip_mask = XCreatePixmap(dpy, RootWindowOfScreen(screen),
9254 			     XmTextF_cursor_width(tf), XmTextF_cursor_height(tf), 1);
9255 
9256    values.foreground = 1;
9257    values.background = 0;
9258    fillGC = XCreateGC(dpy, clip_mask, GCForeground | GCBackground, &values);
9259 
9260    XFillRectangle(dpy, clip_mask, fillGC, 0, 0, XmTextF_cursor_width(tf),
9261 		  XmTextF_cursor_height(tf));
9262 
9263   /* Install the clipmask for pixmap caching */
9264    (void) _XmCachePixmap(clip_mask, screen, pixmap_name, 1, 0, 0, 0, 0);
9265 
9266    XFreeGC(XtDisplay(tf), fillGC);
9267 
9268    return(clip_mask);
9269 }
9270 
9271 /*
9272  * Get the graphics context for filling the background, and for drawing
9273  * and inverting text.  Used a unique pixmap so all text field widgets
9274  * share common GCs.
9275  */
9276 static void
9277 #ifdef _NO_PROTO
df_LoadGCs(tf,background,foreground)9278 df_LoadGCs( tf, background, foreground )
9279         XmDataFieldWidget tf ;
9280         Pixel background ;
9281         Pixel foreground ;
9282 #else
9283 df_LoadGCs(
9284         XmDataFieldWidget tf,
9285         Pixel background,
9286         Pixel foreground )
9287 #endif /* _NO_PROTO */
9288 {
9289    Display *display = XtDisplay((Widget)tf);
9290    Screen *screen = XtScreen((Widget)tf);
9291    XGCValues values;
9292    static XContext context = 0;
9293    static Pixmap tf_cache_pixmap;
9294    unsigned long value_mask = (GCFunction | GCForeground | GCBackground |
9295 			      GCClipMask | GCArcMode);
9296    unsigned long dynamic_mask;
9297 
9298    if (XmTextF_stipple_tile(tf) != None)
9299        XmDestroyPixmap(XtScreen(tf), XmTextF_stipple_tile(tf));
9300 
9301    XmTextF_stipple_tile(tf) = (Pixmap)
9302        XmGetPixmapByDepth(XtScreen(tf),"50_foreground",
9303 			  tf->primitive.foreground, tf->core.background_pixel,
9304 			  tf->core.depth);
9305 
9306    if (context == 0)
9307       context = XUniqueContext();
9308 
9309    if (XFindContext(display, (Window)screen,
9310 		    context, (char **) &tf_cache_pixmap)){
9311      XmTextContextData ctx_data;
9312      Widget xm_display = (Widget) XmGetXmDisplay(display);
9313 
9314      ctx_data = (XmTextContextData) XtMalloc(sizeof(XmTextContextDataRec));
9315 
9316      ctx_data->screen = screen;
9317      ctx_data->context = context;
9318      ctx_data->type = _XM_IS_PIXMAP_CTX;
9319 
9320     /* Get the Pixmap identifier that the X Toolkit uses to cache our */
9321     /* GC's.  We never actually use this Pixmap; just so long as it's */
9322     /* a unique identifier. */
9323      tf_cache_pixmap =  XCreatePixmap(display,
9324 				     (Drawable) RootWindowOfScreen(screen),
9325 				     (unsigned int) 1, (unsigned int) 1,
9326 				     (unsigned int) 1);
9327 
9328      XtAddCallback(xm_display, XmNdestroyCallback,
9329                    (XtCallbackProc) df_FreeContextData, (XtPointer) ctx_data);
9330 
9331      XSaveContext(display, (Window)screen, context, (XPointer) tf_cache_pixmap);
9332    }
9333 
9334    /* Used to be: values.clip_mask = tf_cache_pixmap; */
9335    values.clip_mask = 0;    /* use in caching Text Field gc's */
9336    values.arc_mode = ArcPieSlice; /* Used in differentiating from Text
9337 				     widget GC caching */
9338 
9339    if (XmTextF_has_rect(tf)) {
9340       TextFGCData gc_data = df_GetTextFGCData((Widget)tf);
9341       XmTextF_has_rect(gc_data->tf) = False;
9342       gc_data->tf = NULL;
9343    }
9344 
9345   /*
9346    * Get GC for saving area under the cursor.
9347    */
9348    values.function = GXcopy;
9349    values.foreground = tf->primitive.foreground ;
9350    values.background = tf->core.background_pixel;
9351    if (XmTextF_save_gc(tf) != NULL)
9352        XtReleaseGC((Widget)tf, XmTextF_save_gc(tf));
9353    dynamic_mask = (GCClipMask);
9354    XmTextF_save_gc(tf) = XtAllocateGC((Widget) tf,
9355 	tf->core.depth, value_mask,
9356 	&values, dynamic_mask, 0);
9357 
9358    df_XmResetSaveGC(tf, XmTextF_save_gc(tf));
9359   /*
9360    * Get GC for drawing text.
9361    */
9362 
9363 #if USE_XFT
9364    if (!XmTextF_have_fontset(tf) && !XmTextF_use_xft(tf)) {
9365 #else
9366    if (!XmTextF_have_fontset(tf)) {
9367 #endif
9368       value_mask |= GCFont | GCGraphicsExposures;
9369       values.font = XmTextF_font(tf)->fid;
9370    } else {
9371       value_mask |= GCGraphicsExposures;
9372    }
9373    values.graphics_exposures = (Bool) TRUE;
9374    values.foreground = foreground ^ background;
9375    values.background = 0;
9376    if (XmTextF_gc(tf) != NULL)
9377    	XtReleaseGC((Widget)tf, XmTextF_gc(tf));
9378    dynamic_mask |=  GCForeground | GCBackground | GCFillStyle | GCTile;
9379    XmTextF_gc(tf) = XtAllocateGC((Widget) tf,
9380 	tf->core.depth, value_mask,
9381 	&values, dynamic_mask, 0);
9382 
9383    /* Create a temporary GC - change it later in make IBEAM */
9384    value_mask |= GCTile;
9385    values.tile = XmTextF_stipple_tile(tf);
9386    if (XmTextF_image_gc(tf) != NULL)
9387    	XtReleaseGC((Widget)tf, XmTextF_image_gc(tf));
9388    dynamic_mask = (GCForeground | GCBackground | GCStipple | GCFillStyle |
9389                    GCTileStipXOrigin | GCTileStipYOrigin | GCFunction |
9390                    GCClipMask | GCClipXOrigin | GCClipYOrigin);
9391    XmTextF_image_gc(tf) = XtAllocateGC((Widget) tf,
9392 	                   tf->core.depth, value_mask,
9393                            &values, dynamic_mask, 0);
9394 
9395 }
9396 
9397 static void
9398 #ifdef _NO_PROTO
df_MakeIBeamOffArea(tf,width,height)9399 df_MakeIBeamOffArea( tf, width, height )
9400         XmDataFieldWidget tf ;
9401         Dimension width ;
9402         Dimension height ;
9403 #else
9404 df_MakeIBeamOffArea(
9405         XmDataFieldWidget tf,
9406 #if NeedWidePrototypes
9407         int width,
9408         int height)
9409 #else
9410         Dimension width,
9411         Dimension height)
9412 #endif /* NeedWidePrototypes */
9413 #endif /* _NO_PROTO */
9414 {
9415    Display *dpy = XtDisplay(tf);
9416    Screen  *screen = XtScreen(tf);
9417    GC fillGC;
9418 
9419   /* Create a pixmap for storing the screen data where the I-Beam will
9420    * be painted */
9421 
9422    XmTextF_ibeam_off(tf) = XCreatePixmap(dpy, RootWindowOfScreen(screen), width,
9423 				      height, tf->core.depth);
9424 
9425   /* Create a GC for drawing 0's into the pixmap */
9426    fillGC = XCreateGC(dpy, XmTextF_ibeam_off(tf), 0, (XGCValues *) NULL);
9427 
9428   /* df_Initialize the pixmap to 0's */
9429    XFillRectangle(dpy, XmTextF_ibeam_off(tf), fillGC, 0, 0, width, height);
9430 
9431   /* Free the GC */
9432    XFreeGC(XtDisplay(tf), fillGC);
9433 }
9434 
9435 static void
9436 #ifdef _NO_PROTO
df_MakeIBeamStencil(tf,line_width)9437 df_MakeIBeamStencil( tf, line_width )
9438         XmDataFieldWidget tf ;
9439         int line_width ;
9440 #else
9441 df_MakeIBeamStencil(
9442         XmDataFieldWidget tf,
9443         int line_width )
9444 #endif /* _NO_PROTO */
9445 {
9446    Screen *screen = XtScreen(tf);
9447    char pixmap_name[17];
9448    XGCValues values;
9449    unsigned long valuemask;
9450 
9451    if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
9452    sprintf(pixmap_name, "_XmDataF_%d_%d", XmTextF_cursor_height(tf), line_width);
9453    XmTextF_cursor(tf) = (Pixmap) XmGetPixmapByDepth(screen, pixmap_name, 1, 0, 1);
9454 
9455    if (XmTextF_cursor(tf) == XmUNSPECIFIED_PIXMAP) {
9456       Display *dpy = XtDisplay(tf);
9457       GC fillGC;
9458       XSegment segments[3];
9459       XRectangle ClipRect;
9460 
9461      /* Create a pixmap for the I-Beam stencil */
9462       XmTextF_cursor(tf) = XCreatePixmap(dpy, XtWindow(tf), XmTextF_cursor_width(tf),
9463 				      XmTextF_cursor_height(tf), 1);
9464 
9465      /* Create a GC for "cutting out" the I-Beam shape from the pixmap in
9466       * order to create the stencil.
9467       */
9468       fillGC = XCreateGC(dpy, XmTextF_cursor(tf), 0, (XGCValues *)NULL);
9469 
9470      /* Fill in the stencil with a solid in preparation
9471       * to "cut out" the I-Beam
9472       */
9473       XFillRectangle(dpy, XmTextF_cursor(tf), fillGC, 0, 0, XmTextF_cursor_width(tf),
9474 		     XmTextF_cursor_height(tf));
9475 
9476      /* Change the GC for use in "cutting out" the I-Beam shape */
9477       values.foreground = 1;
9478       values.line_width = line_width;
9479       XChangeGC(dpy, fillGC, GCForeground | GCLineWidth, &values);
9480 
9481      /* Draw the segments of the I-Beam */
9482      /* 1st segment is the top horizontal line of the 'I' */
9483       segments[0].x1 = 0;
9484       segments[0].y1 = line_width - 1;
9485       segments[0].x2 = XmTextF_cursor_width(tf);
9486       segments[0].y2 = line_width - 1;
9487 
9488      /* 2nd segment is the bottom horizontal line of the 'I' */
9489       segments[1].x1 = 0;
9490       segments[1].y1 = XmTextF_cursor_height(tf) - 1;
9491       segments[1].x2 = XmTextF_cursor_width(tf);
9492       segments[1].y2 = XmTextF_cursor_height(tf) - 1;
9493 
9494      /* 3rd segment is the vertical line of the 'I' */
9495       segments[2].x1 = XmTextF_cursor_width(tf) >> 1;
9496       segments[2].y1 = line_width;
9497       segments[2].x2 = XmTextF_cursor_width(tf) >> 1;
9498       segments[2].y2 = XmTextF_cursor_height(tf) - 1;
9499 
9500      /* Set the clipping rectangle of the image GC from drawing */
9501       ClipRect.width = XmTextF_cursor_width(tf);
9502       ClipRect.height = XmTextF_cursor_height(tf);
9503       ClipRect.x = 0;
9504       ClipRect.y = 0;
9505 
9506       XSetClipRectangles(XtDisplay(tf), fillGC, 0, 0, &ClipRect, 1, Unsorted);
9507 
9508      /* Draw the segments onto the cursor */
9509       XDrawSegments(dpy, XmTextF_cursor(tf), fillGC, segments, 3);
9510 
9511     /* Install the cursor for pixmap caching */
9512       (void) _XmCachePixmap(XmTextF_cursor(tf), XtScreen(tf), pixmap_name, 1, 0, 0, 0, 0);
9513 
9514      /* Free the fill GC */
9515       XFreeGC(XtDisplay(tf), fillGC);
9516    }
9517 
9518   /* Get/create the image_gc used to paint the I-Beam */
9519 
9520     sprintf(pixmap_name, "_XmText_CM_%d", XmTextF_cursor_height(tf));
9521     XmTextF_image_clip(tf) = XmGetPixmapByDepth(XtScreen(tf), pixmap_name,
9522 					     1, 0, 1);
9523     if (XmTextF_image_clip(tf) == XmUNSPECIFIED_PIXMAP)
9524        XmTextF_image_clip(tf) = df_GetClipMask(tf, pixmap_name);
9525 
9526     valuemask = (GCClipMask | GCStipple | GCForeground | GCBackground |
9527 		 GCFillStyle);
9528     if (!XmTextF_overstrike(tf)) {
9529       values.foreground = tf->primitive.foreground;
9530       values.background = tf->core.background_pixel;
9531     } else
9532       values.background = values.foreground =
9533 	tf->core.background_pixel ^ tf->primitive.foreground;
9534     values.clip_mask = XmTextF_image_clip(tf);
9535     values.stipple = XmTextF_cursor(tf);
9536     values.fill_style = FillStippled;
9537     XChangeGC(XtDisplay(tf), XmTextF_image_gc(tf), valuemask, &values);
9538 
9539 }
9540 
9541 
9542 /* The IBeam Stencil must have already been created before this routine
9543  * is called.
9544  */
9545 
9546 static void
9547 #ifdef _NO_PROTO
df_MakeAddModeCursor(tf,line_width)9548 df_MakeAddModeCursor( tf, line_width )
9549         XmDataFieldWidget tf ;
9550         int line_width ;
9551 #else
9552 df_MakeAddModeCursor(
9553         XmDataFieldWidget tf,
9554         int line_width )
9555 #endif /* _NO_PROTO */
9556 {
9557    Screen *screen = XtScreen(tf);
9558    char pixmap_name[25];
9559 
9560    if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
9561    sprintf(pixmap_name, "_XmDataF_AddMode_%d_%d",
9562 	   XmTextF_cursor_height(tf), line_width);
9563 
9564    XmTextF_add_mode_cursor(tf) = (Pixmap) XmGetPixmapByDepth(screen, pixmap_name,
9565 							  1, 0, 1);
9566 
9567    if (XmTextF_add_mode_cursor(tf) == XmUNSPECIFIED_PIXMAP) {
9568       GC fillGC;
9569       XtGCMask  valueMask;
9570       XGCValues values;
9571       unsigned int pix_width, pix_height, unused;
9572       Display *dpy = XtDisplay(tf);
9573       Pixmap stipple;
9574       XImage *image;
9575       Pixmap pixmap;
9576       int unused_origin;
9577       Window	root;
9578 
9579       pixmap =  XmGetPixmapByDepth(screen, "50_foreground",
9580 				   1, 0, 1);
9581 
9582       if (pixmap != XmUNSPECIFIED_PIXMAP) {
9583       	XGetGeometry(XtDisplay(tf), pixmap, &root, &unused_origin,
9584 		     &unused_origin, &pix_width, &pix_height,
9585 		     &unused, &unused);
9586       	image = XGetImage(XtDisplay(tf), (Drawable)pixmap, 0, 0,
9587 			  pix_width, pix_height, AllPlanes,
9588 			  XYPixmap);
9589 
9590 
9591       	stipple = XCreatePixmap(dpy, XtWindow(tf),
9592 				image->width, image->height,1);
9593 
9594         XmTextF_add_mode_cursor(tf) =  XCreatePixmap(dpy, XtWindow(tf),
9595 						     XmTextF_cursor_width(tf),
9596 			                             XmTextF_cursor_height(tf),
9597 						     1);
9598 
9599         fillGC = XCreateGC(dpy, XmTextF_add_mode_cursor(tf), 0,
9600 			   (XGCValues *)NULL);
9601 
9602         XPutImage(dpy, stipple, fillGC, image, 0, 0, 0, 0, image->width,
9603 	   	  image->height);
9604 
9605         XCopyArea(dpy, XmTextF_cursor(tf), XmTextF_add_mode_cursor(tf),
9606 	          fillGC, 0, 0, XmTextF_cursor_width(tf),
9607                   XmTextF_cursor_height(tf), 0, 0);
9608 
9609         valueMask = (GCTile | GCFillStyle | GCForeground |
9610 		     GCBackground | GCFunction);
9611         values.function = GXand;
9612         values.tile = stipple;
9613         values.fill_style = FillTiled;
9614         values.foreground = tf->primitive.foreground;
9615         values.background = tf->core.background_pixel;
9616 
9617         XChangeGC(XtDisplay(tf), fillGC, valueMask, &values);
9618 
9619         XFillRectangle(dpy, XmTextF_add_mode_cursor(tf), fillGC,
9620 		       0, 0, XmTextF_cursor_width(tf),
9621                        XmTextF_cursor_height(tf));
9622 
9623         /* Install the pixmap for pixmap caching */
9624         _XmCachePixmap(XmTextF_add_mode_cursor(tf),
9625 		         XtScreen(tf), pixmap_name, 1, 0, 0, 0, 0);
9626 
9627         XFreePixmap(dpy, stipple);
9628         XFreeGC(dpy, fillGC);
9629         XDestroyImage(image);
9630      }
9631   }
9632 }
9633 
9634 static void
9635 #ifdef _NO_PROTO
df_MakeCursors(tf)9636 df_MakeCursors( tf )
9637         XmDataFieldWidget tf ;
9638 #else
9639 df_MakeCursors(
9640         XmDataFieldWidget tf )
9641 #endif /* _NO_PROTO */
9642 {
9643    Screen *screen = XtScreen(tf);
9644    int line_width = 1;
9645 
9646    if (!XtIsRealized((Widget) tf)) return;
9647 
9648    XmTextF_cursor_width(tf) = 5;
9649    XmTextF_cursor_height(tf) = XmTextF_font_ascent(tf) + XmTextF_font_descent(tf);
9650 
9651   /* setup parameters to make a thicker I-Beam */
9652    if (XmTextF_cursor_height(tf) > 19) {
9653       XmTextF_cursor_width(tf)++;
9654       line_width = 2;
9655    }
9656 
9657   /* Remove old ibeam off area */
9658    if (XmTextF_ibeam_off(tf) != XmUNSPECIFIED_PIXMAP)
9659       XFreePixmap(XtDisplay((Widget)tf), XmTextF_ibeam_off(tf));
9660 
9661   /* Remove old insert cursor */
9662    if (XmTextF_cursor(tf) != XmUNSPECIFIED_PIXMAP) {
9663        (void) XmDestroyPixmap(screen, XmTextF_cursor(tf));
9664        XmTextF_cursor(tf) = XmUNSPECIFIED_PIXMAP;
9665    }
9666 
9667   /* Remove old add mode cursor */
9668    if (XmTextF_add_mode_cursor(tf) != XmUNSPECIFIED_PIXMAP) {
9669        (void) XmDestroyPixmap(screen, XmTextF_add_mode_cursor(tf));
9670        XmTextF_add_mode_cursor(tf) = XmUNSPECIFIED_PIXMAP;
9671    }
9672 
9673   /* Remove old image_clip pixmap */
9674    if (XmTextF_image_clip(tf) != XmUNSPECIFIED_PIXMAP) {
9675        (void) XmDestroyPixmap(screen, XmTextF_image_clip(tf));
9676        XmTextF_image_clip(tf) = XmUNSPECIFIED_PIXMAP;
9677    }
9678 
9679   /* Create area in which to save text located underneath I beam */
9680    df_MakeIBeamOffArea(tf, MAX(XmTextF_cursor_height(tf)>>1, XmTextF_cursor_height(tf)),
9681 		    XmTextF_cursor_height(tf));
9682 
9683   /* Create a new i-beam cursor */
9684    df_MakeIBeamStencil(tf, line_width);
9685 
9686   /* Create a new add_mode cursor */
9687    df_MakeAddModeCursor(tf, line_width);
9688 
9689    df_ResetClipOrigin(tf, False);
9690 
9691    if (XmTextF_overstrike(tf))
9692      XmTextF_cursor_width(tf) = XmTextF_cursor_height(tf) >> 1;
9693 }
9694 
9695 /* ARGSUSED */
9696 static void
9697 #ifdef _NO_PROTO
df_DropDestroyCB(w,clientData,callData)9698 df_DropDestroyCB(w, clientData, callData)
9699     Widget      w;
9700     XtPointer   clientData;
9701     XtPointer   callData;
9702 #else
9703 df_DropDestroyCB(
9704     Widget      w,
9705     XtPointer   clientData,
9706     XtPointer   callData )
9707 #endif /* NO_PROTO */
9708 {
9709     df_DeleteDropContext(w);
9710     XtFree((char *)clientData);
9711 }
9712 
9713 
9714 /* ARGSUSED */
9715 static void
9716 #ifdef _NO_PROTO
df_DropTransferCallback(w,closure,seltype,type,value,length,format)9717 df_DropTransferCallback( w, closure, seltype, type, value, length, format )
9718         Widget w ;
9719         XtPointer closure ;
9720         Atom *seltype ;
9721         Atom *type ;
9722         XtPointer value ;
9723         unsigned long *length ;
9724         int *format ;
9725 #else
9726 df_DropTransferCallback(
9727         Widget w,
9728         XtPointer closure,
9729         Atom *seltype,
9730         Atom *type,
9731         XtPointer value,
9732         unsigned long *length,
9733         int *format )
9734 #endif /* _NO_PROTO */
9735 {
9736     _XmTextDropTransferRec *transfer_rec = (_XmTextDropTransferRec *) closure;
9737     XmDataFieldWidget tf = (XmDataFieldWidget) transfer_rec->widget;
9738     Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
9739 #ifdef UTF8_SUPPORTED
9740     Atom UTF8_STRING = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
9741 #endif
9742     Atom CS_OF_LOCALE;
9743     XmTextPosition insertPosLeft, insertPosRight, left, right, cursorPos;
9744     int max_length = 0;
9745     Boolean local = XmTextF_has_primary(tf);
9746     char * total_tmp_value;
9747     wchar_t * wc_total_tmp_value;
9748     char ** tmp_value;
9749     int malloc_size = 0;
9750     int num_vals, status;
9751     Arg args[8];
9752     Cardinal n, i;
9753     unsigned long total_length = 0;
9754     char * tmp_string = "ABC";  /* these are characters in XPCS, so... safe */
9755     XTextProperty tmp_prop;
9756     Boolean replace = False;
9757     XmAnyCallbackStruct cb;
9758 
9759    /* When type = NULL, we are assuming a DELETE request has been requested */
9760     if (*type == XmInternAtom(XtDisplay(transfer_rec->widget), "NULL", False)) {
9761        if (transfer_rec->num_chars > 0 && transfer_rec->move) {
9762           XmTextF_prim_anchor(tf) = transfer_rec->insert_pos;
9763           cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
9764           _XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos,
9765 					False, True);
9766           (void) df_SetDestination((Widget)tf, XmTextF_cursor_position(tf),
9767                                 False, transfer_rec->timestamp);
9768           XmDataFieldSetSelection((Widget)tf, XmTextF_prim_anchor(tf),
9769 				  XmTextF_cursor_position(tf),
9770                                   transfer_rec->timestamp);
9771        }
9772        if (value) {
9773 	  XtFree((char *)value);
9774           value = NULL;
9775        }
9776        return;
9777     }
9778 
9779     status = XmbTextListToTextProperty(XtDisplay(transfer_rec->widget),
9780 				      &tmp_string, 1,
9781                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
9782     if (status == Success)
9783        CS_OF_LOCALE = tmp_prop.encoding;
9784     else
9785        CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
9786                               * characters.  But just in case someones
9787                               * Xlib is broken, this prevents a core dump.
9788                               */
9789 
9790     if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
9791 
9792     if (!value || (*type != CS_OF_LOCALE && *type != COMPOUND_TEXT
9793 #ifdef UTF8_SUPPORTED
9794                    && *type != XA_STRING && *type != UTF8_STRING
9795 #endif
9796     )) {
9797         n = 0;
9798         XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
9799         XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
9800         XtSetValues(w, args, n);
9801         if (value) {
9802 	   XtFree((char *)value);
9803 	   value = NULL;
9804         }
9805         return;
9806     }
9807 
9808     insertPosLeft = insertPosRight = transfer_rec->insert_pos;
9809 
9810     if (*type == XA_STRING || *type == COMPOUND_TEXT
9811 #ifdef UTF8_SUPPORTED
9812             || *type == UTF8_STRING
9813 #endif
9814     ) {
9815        /* value NEEDS TO BE FREED */
9816        tmp_prop.value = (unsigned char *) value;
9817        tmp_prop.encoding = *type;
9818        tmp_prop.format = 8;
9819        tmp_prop.nitems = *length;
9820        status = 0;
9821 
9822        status = XmbTextPropertyToTextList(XtDisplay(transfer_rec->widget),
9823 					  &tmp_prop, &tmp_value, &num_vals);
9824 
9825       /* if no conversion, num_vals is not changed */
9826        if (num_vals && (status == Success || status > 0)) {
9827           for (i = 0; i < num_vals ; i++)
9828               malloc_size += strlen(tmp_value[i]);
9829 
9830           total_tmp_value = XtMalloc ((unsigned) malloc_size + 1);
9831           total_tmp_value[0] = '\0';
9832           for (i = 0; i < num_vals ; i++)
9833              strcat(total_tmp_value, tmp_value[i]);
9834           total_length = strlen(total_tmp_value);
9835 	  XFreeStringList(tmp_value);
9836        } else  {
9837           if (value) {
9838 	     XtFree((char *)value);
9839 	     value = NULL;
9840           }
9841           return;
9842        }
9843     } else {
9844        total_tmp_value = (char *)value;
9845        total_length = *length;
9846     }
9847 
9848     if (XmTextF_pending_delete(tf) && XmTextF_has_primary(tf) &&
9849        XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf) &&
9850        insertPosLeft > XmTextF_prim_pos_left(tf) &&
9851        insertPosRight < XmTextF_prim_pos_right(tf)) {
9852       insertPosLeft = XmTextF_prim_pos_left(tf);
9853       insertPosRight = XmTextF_prim_pos_right(tf);
9854     }
9855 
9856     transfer_rec->num_chars = _XmDataFieldCountCharacters(tf, total_tmp_value,
9857 							  (int)total_length);
9858 
9859     _XmDataFieldDrawInsertionPoint(tf, False);
9860 
9861     if (transfer_rec->move && local) {
9862        max_length = XmTextF_max_length(tf);
9863        XmTextF_max_length(tf) = INT_MAX;
9864     }
9865 
9866     if (XmTextF_max_char_size(tf) == 1) {
9867        if (_XmDataFieldReplaceText(tf, NULL, insertPosLeft, insertPosRight,
9868 				   (char *) total_tmp_value,
9869 				   (int)total_length, False))
9870 	  replace = True;
9871     } else {
9872        wc_total_tmp_value = (wchar_t*)XtMalloc((unsigned)
9873 					       total_length * sizeof(wchar_t));
9874       /* Note: casting total_length to an int may result in a truncation. */
9875        total_length = mbstowcs(wc_total_tmp_value, total_tmp_value,
9876 			       (int)total_length);
9877        if (_XmDataFieldReplaceText(tf, NULL, insertPosLeft, insertPosRight,
9878 				   (char *) wc_total_tmp_value,
9879 				   (int)total_length, False))
9880 	  replace = True;
9881        XtFree((char*)wc_total_tmp_value);
9882     }
9883 
9884     if (replace) {
9885        XmTextF_pending_off(tf) = FALSE;
9886        if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
9887           cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
9888           _XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos,
9889 					False, True);
9890           df_SetDestination((Widget)tf, XmTextF_cursor_position(tf), False,
9891 			 transfer_rec->timestamp);
9892        }
9893        if (XmDataFieldGetSelectionPosition((Widget)tf, &left, &right)) {
9894           if (transfer_rec->move && left < transfer_rec->insert_pos)
9895 	     transfer_rec->insert_pos -= transfer_rec->num_chars;
9896           if (XmTextF_cursor_position(tf) < left ||
9897 	      XmTextF_cursor_position(tf) > right)
9898 	     XmTextF_pending_off(tf) = TRUE;
9899        } else {
9900           if (!transfer_rec->move && !XmTextF_add_mode(tf) &&
9901               transfer_rec->num_chars != 0)
9902 	     XmTextF_prim_anchor(tf) = insertPosLeft;
9903        }
9904        if (transfer_rec->move) {
9905           XmDropTransferEntryRec transferEntries[1];
9906 
9907           transferEntries[0].client_data = (XtPointer) transfer_rec;
9908           transferEntries[0].target = XmInternAtom(XtDisplay(w),"DELETE",False);
9909           XmDropTransferAdd(w, transferEntries, 1);
9910        }
9911        cb.reason = XmCR_VALUE_CHANGED;
9912        cb.event = (XEvent *)NULL;
9913        XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
9914 		          (XtPointer) &cb);
9915     }
9916 
9917     if (transfer_rec->move && local) {
9918        XmTextF_max_length(tf) = max_length;
9919     }
9920 
9921     XtFree(total_tmp_value);
9922     _XmDataFieldDrawInsertionPoint(tf, True);
9923 }
9924 
9925 
9926 static void
9927 #ifdef _NO_PROTO
df_HandleDrop(w,cb)9928 df_HandleDrop(w, cb)
9929         Widget w;
9930         XmDropProcCallbackStruct *cb;
9931 #else
9932 df_HandleDrop(
9933         Widget w,
9934         XmDropProcCallbackStruct *cb )
9935 #endif /* _NO_PROTO */
9936 {
9937     static XtCallbackRec dropdf_DestroyCB[] = { {df_DropDestroyCB, NULL},
9938                                              {(XtCallbackProc)NULL, NULL} };
9939     Widget drag_cont, initiator;
9940     Cardinal numExportTargets, n;
9941     Atom *exportTargets;
9942     Arg args[10];
9943     XmTextPosition insert_pos, left, right;
9944     Display *display = XtDisplay(w);
9945 
9946     drag_cont = cb->dragContext;
9947 
9948     n = 0;
9949     XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
9950     XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
9951     XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
9952     XtGetValues((Widget) drag_cont, args, n);
9953 
9954     insert_pos = df_GetPosFromX((XmDataFieldWidget) w, cb->x);
9955 
9956     if (cb->operation & XmDROP_MOVE && w == initiator &&
9957         XmDataFieldGetSelectionPosition(w, &left, &right) &&
9958         left != right && insert_pos >= left && insert_pos <= right) {
9959        XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
9960        XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
9961     } else {
9962        XmDropTransferEntryRec transferEntries[2];
9963        XmDropTransferEntryRec *transferList = NULL;
9964        Atom TEXT = XmInternAtom(display, "TEXT", False);
9965        Atom COMPOUND_TEXT = XmInternAtom(display, "COMPOUND_TEXT", False);
9966 #ifdef UTF8_SUPPORTED
9967        Atom UTF8_STRING = XmInternAtom(display, "UTF8_STRING", False);
9968 #endif
9969        Atom CS_OF_LOCALE;
9970        char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
9971        XTextProperty tmp_prop;
9972        _XmTextDropTransferRec *transfer_rec;
9973        Cardinal numTransfers = 0;
9974        Boolean locale_found = False;
9975        Boolean c_text_found = False;
9976        Boolean utf8_string_found = False;
9977        Boolean string_found = False;
9978        Boolean text_found = False;
9979        int status;
9980 
9981        status = XmbTextListToTextProperty(display, &tmp_string, 1,
9982                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
9983        if (status == Success)
9984 	  CS_OF_LOCALE = tmp_prop.encoding;
9985        else
9986 	  CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
9987 				 * characters.  But just in case someones
9988 				 * Xlib is broken, this prevents a core dump.
9989 				 */
9990        if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
9991 
9992 
9993       /* intialize data to send to drop transfer callback */
9994        transfer_rec = (_XmTextDropTransferRec *)
9995 		       XtMalloc(sizeof(_XmTextDropTransferRec));
9996        transfer_rec->widget = w;
9997        transfer_rec->insert_pos = insert_pos;
9998        transfer_rec->num_chars = 0;
9999        transfer_rec->timestamp = cb->timeStamp;
10000        transfer_rec->move = False;
10001 
10002        if (cb->operation & XmDROP_MOVE) {
10003           transfer_rec->move = True;
10004        } else {
10005           transfer_rec->move = False;
10006        }
10007 
10008        transferEntries[0].client_data = (XtPointer) transfer_rec;
10009        transferList = transferEntries;
10010        numTransfers = 1;
10011 
10012        for (n = 0; n < numExportTargets; n++) {
10013 	 if (exportTargets[n] == CS_OF_LOCALE) {
10014 	   transferEntries[0].target = CS_OF_LOCALE;
10015 	   locale_found = True;
10016 	   break;
10017 	 }
10018 	 if (exportTargets[n] == COMPOUND_TEXT) c_text_found = True;
10019 #ifdef UTF8_SUPPORTED
10020 	 if (exportTargets[n] == UTF8_STRING) utf8_string_found = True;
10021 #endif
10022 	 if (exportTargets[n] == XA_STRING) string_found = True;
10023 	 if (exportTargets[n] == TEXT) text_found = True;
10024        }
10025 
10026        n = 0;
10027        if (locale_found || c_text_found || string_found || text_found) {
10028 	 if (!locale_found) {
10029 #ifdef UTF8_SUPPORTED
10030            if (utf8_string_found)
10031 	     transferEntries[0].target = UTF8_STRING;
10032 	   else
10033 #endif
10034 	   if (c_text_found)
10035 	     transferEntries[0].target = COMPOUND_TEXT;
10036 	   else if (string_found)
10037 	     transferEntries[0].target = XA_STRING;
10038 	   else
10039 	     transferEntries[0].target = TEXT;
10040 	 }
10041 
10042 	 if (cb->operation & XmDROP_MOVE || cb->operation & XmDROP_COPY) {
10043 		XtSetArg(args[n], XmNdropTransfers, transferList); n++;
10044 		XtSetArg(args[n], XmNnumDropTransfers, numTransfers); n++;
10045 	 } else {
10046 		XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
10047 		XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
10048 	 }
10049 
10050        } else {
10051 	 XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
10052 	 XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
10053        }
10054 
10055        dropdf_DestroyCB[0].closure = (XtPointer) transfer_rec;
10056        XtSetArg(args[n], XmNdestroyCallback, dropdf_DestroyCB); n++;
10057        XtSetArg(args[n], XmNtransferProc, df_DropTransferCallback); n++;
10058     }
10059     df_SetDropContext(w);
10060     XmDropTransferStart(drag_cont, args, n);
10061 }
10062 
10063 
10064 /* ARGSUSED */
10065 static void
10066 #ifdef _NO_PROTO
df_DragProcCallback(w,client,call)10067 df_DragProcCallback(w, client, call)
10068         Widget w;
10069         XtPointer client;
10070         XtPointer call;
10071 #else
10072 df_DragProcCallback(
10073         Widget w,
10074         XtPointer client,
10075         XtPointer call )
10076 #endif /* _NO_PROTO */
10077 {
10078     XmDragProcCallbackStruct *cb = (XmDragProcCallbackStruct *)call;
10079     Widget drag_cont;
10080     Atom targets[5];
10081     char * tmp_string = "ABC";  /* these are characters in XPCS, so... safe */
10082     XTextProperty tmp_prop;
10083     Arg args[10];
10084     Atom *exp_targets;
10085     Cardinal num_exp_targets, n;
10086     int status = 0;
10087 
10088     status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
10089                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
10090     if (status == Success)
10091        targets[0] = tmp_prop.encoding;
10092     else
10093        targets[0] = 99999; /* XmbTextList... should never fail for XPCS
10094                             * characters.  But just in case someones
10095                             * Xlib is broken, this prevents a core dump.
10096                             */
10097     if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
10098 
10099     targets[1] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
10100     targets[2] = XA_STRING;
10101     targets[3] = XmInternAtom(XtDisplay(w), "TEXT", False);
10102 #ifdef UTF8_SUPPORTED
10103     targets[4] = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
10104 #endif
10105 
10106     drag_cont = cb->dragContext;
10107 
10108     n = 0;
10109     XtSetArg(args[n], XmNexportTargets, &exp_targets); n++;
10110     XtSetArg(args[n], XmNnumExportTargets, &num_exp_targets); n++;
10111     XtGetValues(drag_cont, args, n);
10112 
10113     switch(cb->reason) {
10114       case XmCR_DROP_SITE_ENTER_MESSAGE:
10115 	  if (XmTargetsAreCompatible(XtDisplay(drag_cont), exp_targets,
10116 #ifdef UTF8_SUPPORTED
10117 			      	     num_exp_targets, targets, 4))
10118 #else
10119 			      	     num_exp_targets, targets, 3))
10120 #endif
10121              cb->dropSiteStatus = XmVALID_DROP_SITE;
10122           else
10123              cb->dropSiteStatus = XmINVALID_DROP_SITE;
10124           break;
10125       case XmCR_DROP_SITE_LEAVE_MESSAGE:
10126       case XmCR_DROP_SITE_MOTION_MESSAGE:
10127       case XmCR_OPERATION_CHANGED:
10128          /* we currently don't care about these messages */
10129 	  break;
10130       default:
10131 	/* other messages we consider invalid */
10132           cb->dropSiteStatus = XmINVALID_DROP_SITE;
10133 	  break;
10134     }
10135 }
10136 
10137 
10138 /* ARGSUSED */
10139 static void
10140 #ifdef _NO_PROTO
df_DropProcCallback(w,client,call)10141 df_DropProcCallback(w, client, call)
10142         Widget w;
10143         XtPointer client;
10144         XtPointer call;
10145 #else
10146 df_DropProcCallback(
10147         Widget w,
10148         XtPointer client,
10149         XtPointer call )
10150 #endif /* _NO_PROTO */
10151 {
10152     XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *) call;
10153 
10154     if (cb->dropAction != XmDROP_HELP) {
10155        df_HandleDrop(w, cb);
10156     } else {
10157        Arg args[2];
10158 
10159        XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
10160        XtSetArg(args[1], XmNnumDropTransfers, 0);
10161        XmDropTransferStart(cb->dragContext, args, 2);
10162     }
10163 }
10164 
10165 static void
10166 #ifdef _NO_PROTO
df_RegisterDropSite(w)10167 df_RegisterDropSite(w)
10168         Widget w ;
10169 #else
10170 df_RegisterDropSite(
10171         Widget w )
10172 #endif /* _NO_PROTO */
10173 {
10174     Atom targets[5];
10175     Arg args[10];
10176     int n;
10177     char * tmp_string = "ABC";  /* these are characters in XPCS, so... safe */
10178     XTextProperty tmp_prop;
10179     int status = 0;
10180 
10181     status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
10182                                       (XICCEncodingStyle)XTextStyle, &tmp_prop);
10183     if (status == Success)
10184        targets[0] = tmp_prop.encoding;
10185     else
10186        targets[0] = 99999; /* XmbTextList... should never fail for XPCS
10187                             * characters.  But just in case someones
10188                             * Xlib is broken, this prevents a core dump.
10189                             */
10190     if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
10191 
10192     targets[1] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
10193     targets[2] = XA_STRING;
10194     targets[3] = XmInternAtom(XtDisplay(w), "TEXT", False);
10195 #ifdef UTF8_SUPPORTED
10196     targets[4] = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
10197 #endif
10198 
10199     n = 0;
10200     XtSetArg(args[n], XmNimportTargets, targets); n++;
10201 #ifdef UTF8_SUPPORTED
10202     XtSetArg(args[n], XmNnumImportTargets, 4); n++;
10203 #else
10204     XtSetArg(args[n], XmNnumImportTargets, 3); n++;
10205 #endif
10206     XtSetArg(args[n], XmNdropProc, df_DragProcCallback); n++;
10207     XtSetArg(args[n], XmNdropProc, df_DropProcCallback); n++;
10208     XmDropSiteRegister(w, args, n);
10209 }
10210 
10211 /*
10212  * df_Initialize
10213  *    Intializes the text data and ensures that the data in new
10214  * is valid.
10215  */
10216 /* ARGSUSED */
10217 static void
10218 #ifdef _NO_PROTO
df_Initialize(request,new_w,args,num_args)10219 df_Initialize( request, new_w, args, num_args )
10220         Widget request ;
10221         Widget new_w ;
10222         ArgList args ;
10223         Cardinal *num_args ;
10224 #else
10225 df_Initialize(
10226         Widget request,
10227         Widget new_w,
10228         ArgList args,
10229         Cardinal *num_args )
10230 #endif /* _NO_PROTO */
10231 {
10232     XmDataFieldWidget req_tf = (XmDataFieldWidget) request;
10233     XmDataFieldWidget new_tf = (XmDataFieldWidget) new_w;
10234     Dimension width, height;
10235 
10236     df_Validates(new_tf);
10237 
10238     df_InitializeTextStruct(new_tf);
10239 
10240     df_LoadGCs(new_tf, new_tf->core.background_pixel,
10241 	    new_tf->primitive.foreground );
10242 
10243     df_ComputeSize(new_tf, &width, &height);
10244 
10245     if (req_tf->core.width == 0)
10246        new_tf->core.width = width;
10247     if (req_tf->core.height == 0)
10248        new_tf->core.height = height;
10249 
10250     df_RegisterDropSite(new_w);
10251 
10252     if (XmTextF_verify_bell(new_tf) == (Boolean) XmDYNAMIC_BOOL)
10253     {
10254       if (_XmGetAudibleWarning(new_w) == XmBELL)
10255 	XmTextF_verify_bell(new_tf) = True;
10256       else
10257 	XmTextF_verify_bell(new_tf) = False;
10258     }
10259 }
10260 
10261 static void
10262 #ifdef _NO_PROTO
df_Realize(w,valueMask,attributes)10263 df_Realize( w, valueMask, attributes )
10264         Widget w ;
10265         XtValueMask *valueMask ;
10266         XSetWindowAttributes *attributes ;
10267 #else
10268 df_Realize(
10269         Widget w,
10270         XtValueMask *valueMask,
10271         XSetWindowAttributes *attributes )
10272 #endif /* _NO_PROTO */
10273 {
10274    XmDataFieldWidget tf = (XmDataFieldWidget) w;
10275 
10276    XtCreateWindow(w, (unsigned int) InputOutput,
10277                    (Visual *) CopyFromParent, *valueMask, attributes);
10278    df_MakeCursors(tf);
10279    _XmDataFieldSetClipRect(tf);
10280 }
10281 
10282 static void
10283 #ifdef _NO_PROTO
df_Destroy(wid)10284 df_Destroy( wid )
10285         Widget wid ;
10286 #else
10287 df_Destroy(
10288         Widget wid )
10289 #endif /* _NO_PROTO */
10290 {
10291     XmDataFieldWidget tf = (XmDataFieldWidget) wid ;
10292     Widget dest = XmGetDestination(XtDisplay(wid));
10293 
10294     if (dest == wid)
10295        _XmSetDestination(XtDisplay(wid), NULL);
10296 
10297     if (XmTextF_timer_id(tf))
10298 	XtRemoveTimeOut(XmTextF_timer_id(tf));
10299 
10300     if (XmTextF_has_rect(tf)) {
10301        TextFGCData gc_data = df_GetTextFGCData(wid);
10302        gc_data->tf = NULL;
10303     }
10304 
10305     if (XmTextF_max_char_size(tf) == 1)
10306        XtFree(XmTextF_value(tf));
10307     else
10308        XtFree((char *)XmTextF_wc_value(tf));
10309 
10310     XmDestroyPixmap(XtScreen(tf), XmTextF_stipple_tile(tf));
10311 
10312     XtReleaseGC(wid, XmTextF_gc(tf));
10313     XtReleaseGC(wid, XmTextF_image_gc(tf));
10314     XtReleaseGC(wid, XmTextF_save_gc(tf));
10315 
10316     XtFree((char *)XmTextF_highlight(tf).list);
10317 
10318     if (XmTextF_fontlist_created(tf))
10319        XmFontListFree((XmFontList)XmTextF_font_list(tf));
10320 
10321     if (XmTextF_add_mode_cursor(tf) != XmUNSPECIFIED_PIXMAP)
10322        (void) XmDestroyPixmap(XtScreen(tf), XmTextF_add_mode_cursor(tf));
10323 
10324     if (XmTextF_cursor(tf) != XmUNSPECIFIED_PIXMAP)
10325        (void) XmDestroyPixmap(XtScreen(tf), XmTextF_cursor(tf));
10326 
10327     if (XmTextF_ibeam_off(tf) != XmUNSPECIFIED_PIXMAP)
10328        XFreePixmap(XtDisplay((Widget)tf), XmTextF_ibeam_off(tf));
10329 
10330     if (XmTextF_image_clip(tf) != XmUNSPECIFIED_PIXMAP)
10331        XmDestroyPixmap(XtScreen(tf), XmTextF_image_clip(tf));
10332 
10333 /*
10334  * Fix for HaL DTS 9841 - release the data for the selectionArray.
10335  */
10336     XtFree((char *)XmTextF_selection_array(tf));
10337 
10338     XtRemoveAllCallbacks(wid, XmNactivateCallback);
10339     XtRemoveAllCallbacks(wid, XmNlosingFocusCallback);
10340     XtRemoveAllCallbacks(wid, XmNfocusCallback);
10341     XtRemoveAllCallbacks(wid, XmNmodifyVerifyCallback);
10342     XtRemoveAllCallbacks(wid, XmNmotionVerifyCallback);
10343     XtRemoveAllCallbacks(wid, XmNvalueChangedCallback);
10344     XtRemoveAllCallbacks(wid, XmNgainPrimaryCallback);
10345     XtRemoveAllCallbacks(wid, XmNlosePrimaryCallback);
10346 
10347     XmImUnregister(wid);
10348 
10349     XtFree((char*)XmDataField_picture_source(tf));
10350     if(XmDataField_picture(tf))
10351 	    XmPictureDelete(XmDataField_picture(tf));
10352 }
10353 
10354 static void
10355 #ifdef _NO_PROTO
df_Resize(w)10356 df_Resize( w )
10357         Widget w ;
10358 #else
10359 df_Resize(
10360         Widget w )
10361 #endif /* _NO_PROTO */
10362 {
10363   XmDataFieldWidget tf = (XmDataFieldWidget) w;
10364 
10365   XmTextF_do_resize(tf) = False;
10366 
10367   _XmDataFieldSetClipRect(tf);
10368 
10369   if (XmDataField_alignment(tf) == XmALIGNMENT_END)
10370       XmTextF_h_offset(tf) = 0;
10371   else
10372       XmTextF_h_offset(tf) = XmTextF_margin_width(tf) +
10373 	  tf->primitive.shadow_thickness + tf->primitive.highlight_thickness;
10374 
10375   XmTextF_refresh_ibeam_off(tf) = True;
10376 
10377   (void) df_AdjustText(tf, XmTextF_cursor_position(tf), True);
10378 
10379   XmTextF_do_resize(tf) = True;
10380 }
10381 
10382 
10383 /************************************************************************
10384  *
10385  *  df_QueryGeometry
10386  *
10387  ************************************************************************/
10388 static XtGeometryResult
10389 #ifdef _NO_PROTO
df_QueryGeometry(widget,intended,desired)10390 df_QueryGeometry( widget, intended, desired )
10391         Widget widget ;
10392         XtWidgetGeometry *intended ;
10393         XtWidgetGeometry *desired ;
10394 #else
10395 df_QueryGeometry(
10396         Widget widget,
10397         XtWidgetGeometry *intended,
10398         XtWidgetGeometry *desired )
10399 #endif /* _NO_PROTO */
10400 {
10401     /* this function deals with resizeWidth False */
10402     df_ComputeSize((XmDataFieldWidget) widget,
10403 		&desired->width, &desired->height);
10404 
10405     return XmeReplyToQueryGeometry(widget, intended, desired) ;
10406 }
10407 
10408 
10409 /*
10410  * Redisplay will redraw shadows, borders, and text.
10411  */
10412 /* ARGSUSED */
10413 static void
10414 #ifdef _NO_PROTO
DataFieldExpose(w,event,region)10415 DataFieldExpose( w, event, region )
10416         Widget w ;
10417         XEvent *event ;
10418         Region region ;
10419 #else
10420 DataFieldExpose(
10421         Widget w,
10422         XEvent *event,
10423         Region region )
10424 #endif /* _NO_PROTO */
10425 {
10426   XmDataFieldWidget tf = (XmDataFieldWidget) w;
10427   XGCValues values;
10428 
10429 
10430   if (event->xany.type != Expose) return;
10431 
10432   XmTextF_do_resize(tf) = False;
10433 
10434   if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
10435 
10436   /* I can get here even though the widget isn't visible (i.e. my parent is
10437    * sized so that I have nothing visible.  In this case, capturing the putback
10438    * area yields garbage...  And if this area is not in an area where text
10439    * will be drawn (i.e. forcing something new/valid to be there next time I
10440    * go to capture it) the garbage persists.  To prevent this, initialize the
10441    * putback area and then update it to a solid background color.
10442    */
10443 
10444   XmTextF_refresh_ibeam_off(tf) = False;
10445   values.foreground = tf->core.background_pixel;
10446   XChangeGC(XtDisplay(w), XmTextF_save_gc(tf), GCForeground, &values);
10447   XFillRectangle(XtDisplay(w), XmTextF_ibeam_off(tf), XmTextF_save_gc(tf), 0, 0,
10448 		    XmTextF_cursor_width(tf), XmTextF_cursor_height(tf));
10449   values.foreground = tf->primitive.foreground;
10450   XChangeGC(XtDisplay(w), XmTextF_save_gc(tf), GCForeground, &values);
10451 
10452   _XmDataFieldDrawInsertionPoint(tf, False);
10453 
10454   if (XtIsRealized((Widget)tf)) {
10455      if (tf->primitive.shadow_thickness > 0)
10456        XmeDrawShadows(XtDisplay(tf), XtWindow(tf),
10457              tf->primitive.bottom_shadow_GC,
10458              tf->primitive.top_shadow_GC,
10459              (int) tf->primitive.highlight_thickness,
10460              (int) tf->primitive.highlight_thickness,
10461              (int) (tf->core.width - (2 * tf->primitive.highlight_thickness)),
10462              (int) (tf->core.height - (2 * tf->primitive.highlight_thickness)),
10463              (int) tf->primitive.shadow_thickness,
10464              XmSHADOW_OUT);
10465 
10466 
10467      if (tf->primitive.highlighted)
10468      {
10469          XtWidgetProc bhl;
10470 
10471          _XmProcessLock();
10472          bhl = ((XmDataFieldWidgetClass) XtClass(tf))->primitive_class.border_highlight;
10473          _XmProcessUnlock();
10474 
10475          if(bhl)
10476          {
10477              (*bhl)( (Widget) tf) ;
10478          }
10479      }
10480      else
10481      {
10482          XtWidgetProc buhl;
10483 
10484          _XmProcessLock();
10485          buhl = ((XmDataFieldWidgetClass) XtClass(tf))->primitive_class.border_unhighlight;
10486          _XmProcessUnlock();
10487 
10488          if(buhl)
10489          {
10490             (*buhl)( (Widget) tf) ;
10491          }
10492      }
10493 
10494      df_RedisplayText(tf, 0, XmTextF_string_length(tf));
10495   }
10496 
10497   XmTextF_refresh_ibeam_off(tf) = True;
10498 
10499   _XmDataFieldDrawInsertionPoint(tf, True);
10500 
10501   XmTextF_do_resize(tf) = True;
10502 }
10503 
10504 /*
10505  *
10506  * df_SetValues
10507  *
10508  *    Checks the new text data and ensures that the data is valid.
10509  * Invalid values will be rejected and changed back to the old
10510  * values.
10511  *
10512  */
10513 /* ARGSUSED */
10514 static Boolean
10515 #ifdef _NO_PROTO
df_SetValues(old,request,new_w,args,num_args)10516 df_SetValues( old, request, new_w, args, num_args )
10517         Widget old ;
10518         Widget request ;
10519         Widget new_w ;
10520         ArgList args ;
10521         Cardinal *num_args ;
10522 #else
10523 df_SetValues(
10524         Widget old,
10525         Widget request,
10526         Widget new_w,
10527         ArgList args,
10528         Cardinal *num_args )
10529 #endif /* _NO_PROTO */
10530 {
10531     XmDataFieldWidget new_tf = (XmDataFieldWidget) new_w;
10532     XmDataFieldWidget old_tf = (XmDataFieldWidget) old;
10533     Boolean cursor_pos_set = False;
10534     Boolean new_size = False;
10535     Boolean redisplay = False;
10536     Boolean redisplay_text = False;
10537     Boolean new_font = False;
10538     Boolean mod_ver_ret = False;
10539     Boolean diff_values = False;
10540     Dimension new_width = new_tf->core.width;
10541     Dimension new_height = new_tf->core.height;
10542     Arg im_args[6];
10543     XPoint xmim_point;
10544     XmTextPosition new_position = 0;
10545     XmTextPosition newInsert;
10546     int n = 0;
10547 
10548     if (new_w->core.being_destroyed) return False;
10549 
10550     XmTextF_in_setvalues(new_tf) = True;
10551     XmTextF_redisplay(new_tf) = False;
10552 
10553      /************************************
10554      * ICS DataField specific stuff here *
10555      ************************************/
10556 
10557     /*
10558      * This is a patch-around to a bug we seem to have exposed.
10559      * The special redisplay handling has been broken somehow with the
10560      * end result that the DataField doesn't redisplay itself
10561      * correctly when its XmNvalue is set.  This just hacks around the
10562      * problem.
10563      */
10564     if(XmTextF_value(old_tf) != XmTextF_value(new_tf)) {
10565 	redisplay = True;
10566     }
10567 
10568     if (XmDataField_picture_source(old_tf) != XmDataField_picture_source(new_tf))
10569     {
10570 	/*
10571 	 * Delete what's there
10572 	 */
10573 	XtFree((char*)XmDataField_picture_source(old_tf));
10574 	XmDataField_picture_source(new_tf) = XtNewString(XmDataField_picture_source(new_tf));
10575 	if(XmDataField_picture(new_tf)) {
10576 	    XmPictureDelete(XmDataField_picture(new_tf));
10577 	    XmDataField_picture(new_tf) = NULL;
10578 	}
10579 
10580 	/*
10581 	 * And make a new one if we have to
10582 	 */
10583 	if(XmDataField_picture_source(new_tf)) {
10584 	    XmDataField_picture(new_tf) = XmParsePicture(XmDataField_picture_source(new_tf));
10585 	}
10586 
10587 	/*
10588 	 * Finally register (or remove) the callback
10589 	 */
10590 	if(XmDataField_picture(new_tf)) {
10591 	    XtAddCallback((Widget)new_tf, XmNmodifyVerifyCallback,
10592 			  PictureVerifyCallback, NULL);
10593 	} else {
10594 	    XtRemoveCallback((Widget)new_tf, XmNmodifyVerifyCallback,
10595 			     PictureVerifyCallback, NULL);
10596 	}
10597 
10598 
10599     }
10600 
10601     if (XmDataField_alignment(old_tf) != XmDataField_alignment(new_tf))
10602     {
10603 	if (XmDataField_alignment(new_tf) == XmALIGNMENT_END)
10604 	    XmTextF_h_offset(new_tf) = XmTextF_new_h_offset(new_tf) = 0;
10605 	else
10606 	    XmTextF_h_offset(new_tf) = XmTextF_new_h_offset(new_tf) =
10607 		XmTextF_margin_width(new_tf) +
10608 		new_tf->primitive.shadow_thickness +
10609 		new_tf->primitive.highlight_thickness;
10610 
10611 	redisplay = True;
10612     }
10613 
10614    /* If new cursor position, copy the old cursor pos to the new widget
10615     * so that when we turn off the i-beam, the current location (old
10616     * widget) is used, but the new i-beam parameters (on/off, state, ...)
10617     * are utilized.  Then move the cursor.  Otherwise, just turn off
10618     * the i-beam. */
10619 
10620     if (XmTextF_cursor_position(new_tf) != XmTextF_cursor_position(old_tf)) {
10621        new_position = XmTextF_cursor_position(new_tf) ;
10622        XmTextF_cursor_position(new_tf) = XmTextF_cursor_position(old_tf);
10623        _XmDataFieldDrawInsertionPoint(old_tf, False);
10624        XmTextF_blink_on(new_tf) = XmTextF_blink_on(old_tf);
10625        XmTextF_cursor_on(new_tf) = XmTextF_cursor_on(old_tf);
10626        _XmDataFielddf_SetCursorPosition(new_tf, NULL, new_position,
10627 				     True, True);
10628        (void) df_SetDestination(new_w, XmTextF_cursor_position(new_tf), False,
10629 			     XtLastTimestampProcessed(XtDisplay(new_w)));
10630        cursor_pos_set = True;
10631     } else {
10632       int ix;
10633 
10634       for (ix = 0; ix < *num_args; ix++)
10635 	if (strcmp(args[ix].name, XmNcursorPosition) == 0) {
10636 	  cursor_pos_set = True;
10637 	  new_position = XmTextF_cursor_position(new_tf);
10638 	  break;
10639 	}
10640 
10641       _XmDataFieldDrawInsertionPoint(old_tf, False);
10642       XmTextF_blink_on(new_tf) = XmTextF_blink_on(old_tf);
10643       XmTextF_cursor_on(new_tf) = XmTextF_cursor_on(old_tf);
10644     }
10645 
10646     if (new_w->core.sensitive == False &&
10647         XmTextF_has_destination(new_tf)) {
10648        (void) df_SetDestination(new_w, XmTextF_cursor_position(new_tf),
10649 			     True, XtLastTimestampProcessed(XtDisplay(new_w)));
10650     }
10651 
10652     if (XmTextF_selection_array(new_tf) == NULL)
10653        XmTextF_selection_array(new_tf) = XmTextF_selection_array(old_tf);
10654 
10655     if (XmTextF_selection_array_count(new_tf) <= 0)
10656        XmTextF_selection_array_count(new_tf) = XmTextF_selection_array_count(old_tf);
10657 
10658 /*
10659  * Fix for HaL DTS 9841 - If the new and old selectionArrays do not match,
10660  *			  free the old array and then copy the new array.
10661  */
10662     if (XmTextF_selection_array(new_tf) != XmTextF_selection_array(old_tf))
10663     {
10664       XtPointer temp_ptr;
10665 
10666       XtFree((char *)XmTextF_selection_array(old_tf));
10667       temp_ptr = (XtPointer)XmTextF_selection_array(new_tf);
10668       XmTextF_selection_array(new_tf) = (XmTextScanType *)XtMalloc (
10669                  XmTextF_selection_array_count(new_tf) * sizeof(XmTextScanType));
10670       memcpy((void *)XmTextF_selection_array(new_tf), (void *)temp_ptr,
10671              (XmTextF_selection_array_count(new_tf) * sizeof(XmTextScanType)));
10672     }
10673 /*
10674  * End fix for HaL DTS 9841
10675  */
10676 
10677 
10678    /* Make sure the new_tf cursor position is a valid value.
10679     */
10680     if (XmTextF_cursor_position(new_tf) < 0) {
10681        XmeWarning (new_w, MSG1);
10682        XmTextF_cursor_position(new_tf) = XmTextF_cursor_position(old_tf);
10683        cursor_pos_set = False;
10684     }
10685 
10686     if (XmTextF_font_list(new_tf)!= XmTextF_font_list(old_tf)) {
10687        new_font = True;
10688        if (XmTextF_font_list(new_tf) == NULL)
10689           XmTextF_font_list(new_tf) = XmeGetDefaultRenderTable(new_w, XmTEXT_FONTLIST);
10690        XmTextF_font_list(new_tf) =
10691 			    (XmFontList)XmFontListCopy(XmTextF_font_list(new_tf));
10692        if (!df_LoadFontMetrics(new_tf)){ /* Fails if font set required but not
10693                                        * available. */
10694           XmFontListFree((XmFontList)XmTextF_font_list(new_tf));
10695           XmTextF_font_list(new_tf) = XmTextF_font_list(old_tf);
10696           (void)df_LoadFontMetrics(new_tf); /* it *was* correct, so re-use it */
10697           new_font = False;
10698        } else {
10699           XtSetArg(im_args[n], XmNfontList, XmTextF_font_list(new_tf)); n++;
10700           redisplay = True;
10701        }
10702     }
10703 
10704     /* Four cases to handle for value:
10705      *   1. user set both XmNvalue and XmNwcValue.
10706      *   2. user set the opposite resource (i.e. value is a char*
10707      *      and user set XmNwcValue, or vice versa).
10708      *   3. user set the corresponding resource (i.e. value is a char*
10709      *      and user set XmNValue, or vice versa).
10710      *   4. user set neither XmNValue nor XmNwcValue
10711      */
10712 
10713     /* OSF says:  if XmNvalueWcs set, it overrides all else */
10714 
10715      if (XmTextF_max_char_size(new_tf) == 1) {
10716        /* wc_value on new will be NULL unless XmNvalueWcs was set.   */
10717         if (XmTextF_wc_value(new_tf) != NULL){ /* must be new if MB_CUR... == 1 */
10718            df_ValidateString(new_tf, (char*) XmTextF_wc_value(new_tf), True);
10719            diff_values = True;
10720         } else if (XmTextF_value(new_tf) != XmTextF_value(old_tf)) {
10721            diff_values = True;
10722            if (XmTextF_value(new_tf) == NULL) {
10723               df_ValidateString(new_tf, "", False);
10724            } else
10725               df_ValidateString(new_tf, XmTextF_value(new_tf), False);
10726         } /* else, no change so don't do anything */
10727      } else {
10728         if (XmTextF_wc_value(new_tf) != XmTextF_wc_value(old_tf)) {
10729            diff_values = True;
10730            if (XmTextF_wc_value(new_tf) == NULL) {
10731               XmTextF_wc_value(new_tf) = (wchar_t*) XtMalloc(sizeof(wchar_t));
10732               *XmTextF_wc_value(new_tf) = (wchar_t)NULL;
10733            }
10734            df_ValidateString(new_tf, (char*)XmTextF_wc_value(new_tf), True);
10735         } else if (XmTextF_value(new_tf) != XmTextF_value(old_tf)) {
10736            /* Someone set XmNvalue */
10737            diff_values = True;
10738            if (XmTextF_value(new_tf) == NULL)
10739               df_ValidateString(new_tf, "", True);
10740            else
10741               df_ValidateString(new_tf, XmTextF_value(new_tf), False);
10742 
10743         } /* else, no change so don't do anything */
10744      }
10745 
10746     if (diff_values) { /* old value != new value */
10747        Boolean do_it = True;
10748       /* If there are modify verify callbacks, verify that we want to continue
10749        * the action.
10750        */
10751        if (XmTextF_modify_verify_callback(new_tf) ||
10752 	   XmTextF_wcs_modify_verify_callback(new_tf)) {
10753          /* If the function df_ModifyVerify() returns false then don't
10754           * continue with the action.
10755           */
10756 	  char *temp, *old;
10757 	  int free_insert;
10758           XmTextPosition fromPos = 0, toPos;
10759           toPos = XmTextF_string_length(old_tf);
10760 	  if (XmTextF_max_char_size(new_tf) == 1) {
10761 	     temp = XmTextF_value(new_tf);
10762 	     mod_ver_ret = df_ModifyVerify(new_tf, NULL, &fromPos, &toPos,
10763 					&temp, &XmTextF_string_length(new_tf),
10764 					&newInsert, &free_insert);
10765 	  } else {
10766 	     old = temp = XtMalloc((unsigned)((XmTextF_string_length(new_tf) + 1) *
10767 					      XmTextF_max_char_size(new_tf)));
10768 	     (void)wcstombs(temp, XmTextF_wc_value(new_tf),
10769 	         (XmTextF_string_length(new_tf) + 1) * XmTextF_max_char_size(new_tf));
10770 	     mod_ver_ret = df_ModifyVerify(new_tf, NULL, &fromPos, &toPos, &temp,
10771 					&XmTextF_string_length(new_tf), &newInsert,
10772 					&free_insert);
10773 	     if (old != temp) XtFree (old);
10774           }
10775 	  if (free_insert) XtFree(temp);
10776           if (!mod_ver_ret) {
10777              if (XmTextF_verify_bell(new_tf)) XBell(XtDisplay(new_w), 0);
10778 	     if (XmTextF_max_char_size(new_tf) == 1) {
10779                 XmTextF_value(new_tf) = (char *) memcpy(
10780 					   XtRealloc(XmTextF_value(new_tf),
10781                                            (unsigned)XmTextF_size_allocd(old_tf)),
10782                                            (void*)XmTextF_value(old_tf),
10783 					   XmTextF_string_length(old_tf) + 1);
10784                 XmTextF_string_length(new_tf) = XmTextF_string_length(old_tf);
10785                 XmTextF_size_allocd(new_tf) = XmTextF_size_allocd(old_tf);
10786                 XtFree(XmTextF_value(old_tf));
10787              } else {
10788 		/* realloc to old size, cast to wchar_t*, and copy the data */
10789 		XmTextF_wc_value(new_tf) = (wchar_t*)memcpy(
10790 		       XtRealloc((char *)XmTextF_wc_value(new_tf),
10791                        (unsigned)XmTextF_size_allocd(old_tf)),
10792                        (void*)XmTextF_wc_value(old_tf),
10793 		       (unsigned) XmTextF_size_allocd(old_tf));
10794 
10795                 XmTextF_string_length(new_tf) = XmTextF_string_length(old_tf);
10796                 XmTextF_size_allocd(new_tf) = XmTextF_size_allocd(old_tf);
10797                 XtFree((char *)XmTextF_wc_value(old_tf));
10798 	     }
10799              do_it = False;
10800           }
10801        }
10802 
10803 
10804        if (do_it) {
10805           XmAnyCallbackStruct cb;
10806 
10807 	  if (XmTextF_max_char_size(new_tf) == 1)
10808              XtFree(XmTextF_value(old_tf));
10809 	  else
10810              XtFree((char *)XmTextF_wc_value(old_tf));
10811 
10812           XmDataFieldSetHighlight(new_w, XmTextF_prim_pos_left(new_tf),
10813 			          XmTextF_prim_pos_right(new_tf),
10814 				  XmHIGHLIGHT_NORMAL);
10815 
10816           XmTextF_pending_off(new_tf) = True;
10817 
10818 	  /* if new_position was > XmTextF_string_length(old_tf), last time
10819 	   * the df_SetCursorPosition didn't take.
10820 	   */
10821           if (!cursor_pos_set || new_position > XmTextF_string_length(old_tf)){
10822              _XmDataFielddf_SetCursorPosition(new_tf, NULL, new_position,
10823 					   True, False);
10824              if (XmTextF_has_destination(new_tf))
10825                 (void) df_SetDestination(new_w, XmTextF_cursor_position(new_tf),
10826 			     False, XtLastTimestampProcessed(XtDisplay(new_w)));
10827 	  }
10828 
10829           if (XmTextF_resize_width(new_tf) && XmTextF_do_resize(new_tf))
10830              df_AdjustSize(new_tf);
10831           else {
10832 	      if (XmDataField_alignment(new_tf) == XmALIGNMENT_END)
10833 		  XmTextF_h_offset(new_tf) = 0;
10834 	      else
10835 		  XmTextF_h_offset(new_tf) = XmTextF_margin_width(new_tf) +
10836 		      new_tf->primitive.shadow_thickness +
10837 		      new_tf->primitive.highlight_thickness;
10838 
10839              if (!df_AdjustText(new_tf, XmTextF_cursor_position(new_tf), False))
10840                 redisplay_text = True;
10841           }
10842 
10843           cb.reason = XmCR_VALUE_CHANGED;
10844           cb.event = NULL;
10845           XtCallCallbackList(new_w, XmTextF_value_changed_callback(new_tf),
10846 			     (XtPointer) &cb);
10847 
10848        }
10849     }
10850 
10851     if (new_tf->primitive.foreground != old_tf->primitive.foreground ||
10852         XmTextF_font_list(new_tf)!= XmTextF_font_list(old_tf) ||
10853         new_tf->core.background_pixel != old_tf->core.background_pixel) {
10854        df_LoadGCs(new_tf, new_tf->primitive.foreground,
10855 			 new_tf->core.background_pixel);
10856        df_MakeCursors(new_tf);
10857        _XmDataFieldSetClipRect(new_tf);
10858        if (XmTextF_have_inverted_image_gc(new_tf)){
10859 	  XmTextF_have_inverted_image_gc(new_tf) = False;
10860           df_InvertImageGC(new_tf);
10861        }
10862        redisplay = True;
10863        XtSetArg(im_args[n], XmNbackground, new_tf->core.background_pixel); n++;
10864        XtSetArg(im_args[n], XmNforeground, new_tf->primitive.foreground); n++;
10865     }
10866 
10867     if (XmTextF_has_focus(new_tf) && XtIsSensitive((Widget)new_tf) &&
10868         XmTextF_blink_rate(new_tf) != XmTextF_blink_rate(old_tf)) {
10869 
10870         if (XmTextF_blink_rate(new_tf) == 0) {
10871             XmTextF_blink_on(new_tf) = True;
10872             if (XmTextF_timer_id(new_tf)) {
10873                 XtRemoveTimeOut(XmTextF_timer_id(new_tf));
10874                 XmTextF_timer_id(new_tf) = (XtIntervalId)0;
10875             }
10876         } else if (XmTextF_timer_id(new_tf) == (XtIntervalId)0) {
10877            XmTextF_timer_id(new_tf) =
10878 		 XtAppAddTimeOut(XtWidgetToApplicationContext(new_w),
10879 				 (unsigned long)XmTextF_blink_rate(new_tf),
10880                                  df_HandleTimer,
10881                                  (XtPointer) new_tf);
10882         }
10883         df_BlinkInsertionPoint(new_tf);
10884     }
10885 
10886     if (XmTextF_margin_height(new_tf) != XmTextF_margin_height(old_tf)) {
10887        XmTextF_margin_top(new_tf) = XmTextF_margin_height(new_tf);
10888        XmTextF_margin_bottom(new_tf) = XmTextF_margin_height(new_tf);
10889     }
10890 
10891     new_size = XmTextF_margin_width(new_tf) != XmTextF_margin_width(old_tf) ||
10892                XmTextF_margin_height(new_tf) != XmTextF_margin_height(old_tf) ||
10893                XmTextF_font_list(new_tf) != XmTextF_font_list(old_tf) ||
10894 	       new_tf->primitive.highlight_thickness !=
10895 		 old_tf->primitive.highlight_thickness ||
10896 	       new_tf->primitive.shadow_thickness !=
10897 		 old_tf->primitive.shadow_thickness;
10898 
10899 
10900     if (XmTextF_columns(new_tf) < 0) {
10901        XmeWarning (new_w, MSG7);
10902        XmTextF_columns(new_tf) = XmTextF_columns(old_tf);
10903     }
10904 
10905     if (!(new_width != old_tf->core.width &&
10906 	  new_height != old_tf->core.height)) {
10907        if (XmTextF_columns(new_tf) != XmTextF_columns(old_tf) || new_size) {
10908 	  Dimension width, height;
10909 
10910 	  df_ComputeSize(new_tf, &width, &height);
10911 	  df_AdjustText(new_tf, 0, False);
10912 
10913 	  if (new_width == old_tf->core.width)
10914 	     new_w->core.width = width;
10915 	  if (new_height == old_tf->core.height)
10916 	     new_w->core.height = height;
10917 
10918 	  if (XmDataField_alignment(new_tf) == XmALIGNMENT_END)
10919 	      XmTextF_h_offset(new_tf) = 0;
10920 	  else
10921 	      XmTextF_h_offset(new_tf) = XmTextF_margin_width(new_tf) +
10922 		  new_tf->primitive.shadow_thickness +
10923 		  new_tf->primitive.highlight_thickness;
10924 
10925 	  redisplay = True;
10926        }
10927     } else {
10928        if (new_width != new_tf->core.width)
10929           new_tf->core.width = new_width;
10930        if (new_height != new_tf->core.height)
10931           new_tf->core.height = new_height;
10932     }
10933 
10934     XmTextF_refresh_ibeam_off(new_tf) = 1; /* force update of putback area */
10935 
10936     _XmDataFieldDrawInsertionPoint(new_tf, True);
10937 
10938     if (XtIsSensitive((Widget)new_tf) != XtIsSensitive((Widget)old_tf)) {
10939        if (XtIsSensitive(new_w)) {
10940           _XmDataFieldDrawInsertionPoint(new_tf, False);
10941           XmTextF_blink_on(new_tf) = False;
10942           _XmDataFToggleCursorGC(new_w);
10943          _XmDataFieldDrawInsertionPoint(new_tf, True);
10944        } else {
10945           if (XmTextF_has_focus(new_tf)) {
10946              XmTextF_has_focus(new_tf) = False;
10947              df_ChangeBlinkBehavior(new_tf, False);
10948              _XmDataFieldDrawInsertionPoint(new_tf, False);
10949              _XmDataFToggleCursorGC(new_w);
10950              XmTextF_blink_on(new_tf) = True;
10951              _XmDataFieldDrawInsertionPoint(new_tf, True);
10952           }
10953        }
10954        if (XmTextF_string_length(new_tf) > 0) redisplay = True;
10955     }
10956 
10957     df_GetXYFromPos(new_tf, XmTextF_cursor_position(new_tf), &xmim_point.x,
10958 		 &xmim_point.y);
10959 
10960     if (XmTextF_editable(old_tf) != XmTextF_editable(new_tf)) {
10961        Boolean editable = XmTextF_editable(new_tf);
10962        XmTextF_editable(new_tf) = XmTextF_editable(old_tf);
10963        XmDataFieldSetEditable(new_w, editable);
10964     }
10965 
10966     XtSetArg(im_args[n], XmNbackgroundPixmap,
10967 	     new_tf->core.background_pixmap); n++;
10968     XtSetArg(im_args[n], XmNspotLocation, &xmim_point); n++;
10969     XtSetArg(im_args[n], XmNlineSpace,
10970 	     XmTextF_font_ascent(new_tf) + XmTextF_font_descent(new_tf)); n++;
10971     XmImSetValues((Widget)new_tf, im_args, n);
10972 
10973     if (new_font) XmFontListFree((XmFontList)XmTextF_font_list(old_tf));
10974 
10975     if (!redisplay) redisplay = XmTextF_redisplay(new_tf);
10976 
10977     /* If I'm forced to redisplay, then actual widget won't be updated
10978      * until the expose proc.  Force the ibeam putback to be refreshed
10979      * at expose time so that it reflects true visual state of the
10980      * widget.  */
10981 
10982     if (redisplay) XmTextF_refresh_ibeam_off(new_tf) = True;
10983 
10984     XmTextF_in_setvalues(new_tf) = False;
10985 
10986     /*
10987      * Force new clip rectangles to be computed during redisplay,
10988      * *after* XtSetValues decides on final geometry.
10989      */
10990     if (redisplay) XmTextF_has_rect(new_tf) = False;
10991 
10992     if ((!XmTextF_editable(new_tf) || !XtIsSensitive(new_w)) &&
10993         XmTextF_has_destination(new_tf))
10994        (void) df_SetDestination(new_w, 0, False, (Time)0);
10995 
10996     /* don't shrink to nothing */
10997     if (new_tf->core.width == 0) new_tf->core.width = old_tf->core.width;
10998     if (new_tf->core.height == 0) new_tf->core.height = old_tf->core.height;
10999 
11000     if (!redisplay && redisplay_text)
11001       df_RedisplayText(new_tf, 0, XmTextF_string_length(new_tf));
11002 
11003     return redisplay;
11004 }
11005 
11006 static Boolean
11007 #ifdef _NO_PROTO
DataFieldRemove(w,event)11008 DataFieldRemove( w, event)
11009         Widget w ;
11010         XEvent *event ;
11011 #else
11012 DataFieldRemove(
11013         Widget w,
11014 	XEvent *event)
11015 #endif /* _NO_PROTO */
11016 {
11017    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11018    XmTextPosition left, right;
11019    XmAnyCallbackStruct cb;
11020 
11021    if (XmTextF_editable(tf) == False)
11022       return False;
11023 
11024    if (!XmDataFieldGetSelectionPosition(w, &left, &right) || left == right) {
11025       XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
11026       return False;
11027    }
11028 
11029    if (_XmDataFieldReplaceText(tf, event, left, right, NULL, 0, True)){
11030       XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
11031                               XmTextF_cursor_position(tf),
11032 			      XtLastTimestampProcessed(XtDisplay(w)));
11033       cb.reason = XmCR_VALUE_CHANGED;
11034       cb.event = event;
11035       XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
11036 		         (XtPointer) &cb);
11037    }
11038    XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
11039 
11040    return True;
11041 }
11042 
11043 /********************************************
11044  * AccessTextual trait method implementation
11045  ********************************************/
11046 
11047 static XtPointer
DataFieldGetValue(Widget w,int format)11048 DataFieldGetValue(Widget w, int format)
11049 {
11050   char *str;
11051   XmString tmp;
11052 
11053   switch(format) {
11054   case XmFORMAT_XmSTRING:
11055     str = XmDataFieldGetString(w);
11056     tmp = XmStringCreateLocalized(str);
11057     if (str != NULL) XtFree(str);
11058     return((XtPointer) tmp);
11059   case XmFORMAT_MBYTE:
11060     return((XtPointer) XmDataFieldGetString(w));
11061   case XmFORMAT_WCS:
11062     return((XtPointer) XmDataFieldGetStringWcs(w));
11063   }
11064 
11065   return(NULL);
11066 }
11067 
11068 static void
DataFieldSetValue(Widget w,XtPointer s,int format)11069 DataFieldSetValue(Widget w, XtPointer s, int format)
11070 {
11071   char *str;
11072 
11073   switch(format)
11074     {
11075     case XmFORMAT_XmSTRING:
11076       str = _XmStringGetTextConcat((XmString) s);
11077       XmDataFieldSetString(w, str);
11078       if (str != NULL) XtFree(str);
11079       break;
11080     case XmFORMAT_MBYTE:
11081       XmDataFieldSetString(w, (char*) s);
11082       break;
11083     case XmFORMAT_WCS:
11084       XmDataFieldSetStringWcs(w, (wchar_t *) s);
11085     }
11086 }
11087 
11088 /*ARGSUSED*/
11089 static int
DataFieldPreferredValue(Widget w)11090 DataFieldPreferredValue(Widget w) /* unused */
11091 {
11092   return(XmFORMAT_MBYTE);
11093 }
11094 
11095 /*
11096  * XmRCallProc routine for checking data.font_list before setting it to NULL
11097  * if no value is specified for both XmNrenderTable and XmNfontList.
11098  * If "check_set_render_table" == True, then function has been called twice
11099  * on same widget, thus resource needs to be set NULL, otherwise leave it
11100  * alone.
11101  */
11102 /* ARGSUSED */
11103 static void
CheckSetRenderTable(Widget wid,int offset,XrmValue * value)11104 CheckSetRenderTable(Widget wid, int offset, XrmValue *value)
11105 {
11106   XmDataFieldWidget df = (XmDataFieldWidget)wid;
11107 
11108   if (XmTextF_check_set_render_table(df))
11109 	value->addr = NULL;
11110   else {
11111 	XmTextF_check_set_render_table(df) = True;
11112 	value->addr = (char*)&(XmTextF_font_list(df));
11113   }
11114 }
11115 /***********************************<->***************************************
11116 
11117  *                              Public Functions                             *
11118  ***********************************<->***************************************/
11119 
11120 char *
11121 #ifdef _NO_PROTO
XmDataFieldGetString(w)11122 XmDataFieldGetString( w )
11123         Widget w ;
11124 #else
11125 XmDataFieldGetString(
11126         Widget w )
11127 #endif /* _NO_PROTO */
11128 {
11129     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11130     char *temp_str;
11131     int ret_val = 0;
11132 
11133     _XmWidgetToAppContext(w);
11134     _XmAppLock(app);
11135 
11136     if (XmTextF_string_length(tf) > 0)
11137     {
11138 	if (XmTextF_max_char_size(tf) == 1)
11139 	{
11140 	    temp_str = XtNewString(XmTextF_value(tf));
11141 	    _XmAppUnlock(app);
11142 	    return(temp_str);
11143 	}
11144 	else
11145 	{
11146 	    temp_str = (char *) XtMalloc((unsigned) XmTextF_max_char_size(tf) *
11147 					 (XmTextF_string_length(tf) + 1));
11148 	    ret_val = wcstombs(temp_str, XmTextF_wc_value(tf),
11149 			       (XmTextF_string_length(tf) + 1) *
11150 			       XmTextF_max_char_size(tf));
11151 	    if (ret_val < 0)
11152 	    {
11153 		temp_str[0] = '\0';
11154 	    }
11155 
11156 	    _XmAppUnlock(app);
11157 	    return temp_str;
11158 	}
11159     } else
11160     {
11161       _XmAppUnlock(app);
11162       return(XtNewString(""));
11163     }
11164 }
11165 
11166 int
11167 #ifdef _NO_PROTO
XmDataFieldGetSubstring(widget,start,num_chars,buf_size,buffer)11168 XmDataFieldGetSubstring( widget, start, num_chars, buf_size, buffer )
11169         Widget widget;
11170         XmTextPosition start;
11171         int num_chars;
11172         int buf_size;
11173         char *buffer;
11174 #else
11175 XmDataFieldGetSubstring(
11176 	Widget widget,
11177         XmTextPosition start,
11178         int num_chars,
11179         int buf_size,
11180         char *buffer )
11181 #endif /* _NO_PROTO */
11182 {
11183     XmDataFieldWidget tf = (XmDataFieldWidget) widget;
11184     int ret_value = XmCOPY_SUCCEEDED;
11185     int n_bytes = 0;
11186     int wcs_ret = 0;
11187 
11188     _XmWidgetToAppContext(widget);
11189     _XmAppLock(app);
11190 
11191     if (XmTextF_max_char_size(tf) != 1)
11192     {
11193 	n_bytes = _XmDataFieldCountBytes(tf, XmTextF_wc_value(tf)+start, num_chars);
11194     }
11195     else
11196     {
11197 	n_bytes = num_chars;
11198     }
11199 
11200     if (buf_size < n_bytes + 1 )
11201     {
11202       _XmAppUnlock(app);
11203       return XmCOPY_FAILED;
11204     }
11205 
11206     if (start + num_chars > XmTextF_string_length(tf))
11207     {
11208 	num_chars = (int) (XmTextF_string_length(tf) - start);
11209 	if (XmTextF_max_char_size(tf) != 1)
11210 	{
11211 	    n_bytes = _XmDataFieldCountBytes(tf, XmTextF_wc_value(tf)+start,
11212 					     num_chars);
11213 	}
11214 	else
11215 	{
11216 	    n_bytes = num_chars;
11217 	}
11218 	ret_value = XmCOPY_TRUNCATED;
11219     }
11220 
11221     if (num_chars > 0) {
11222 	if (XmTextF_max_char_size(tf) == 1)
11223 	{
11224 	    (void)memcpy((void*)buffer, (void*)&XmTextF_value(tf)[start], num_chars);
11225 	}
11226 	else
11227 	{
11228 	    wcs_ret = wcstombs(buffer, &XmTextF_wc_value(tf)[start],
11229 			       n_bytes);
11230 	    if (wcs_ret < 0) n_bytes = 0;
11231 	}
11232 	buffer[n_bytes] = '\0';
11233     }
11234     else
11235     {
11236 	ret_value = XmCOPY_FAILED;
11237     }
11238 
11239     _XmAppUnlock(app);
11240     return (ret_value);
11241 }
11242 
11243 
11244 wchar_t *
11245 #ifdef _NO_PROTO
XmDataFieldGetStringWcs(w)11246 XmDataFieldGetStringWcs( w )
11247         Widget w ;
11248 #else
11249 XmDataFieldGetStringWcs(
11250         Widget w )
11251 #endif /* _NO_PROTO */
11252 {
11253     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11254     wchar_t *temp_wcs;
11255     int num_wcs = 0;
11256 
11257     _XmWidgetToAppContext(w);
11258     _XmAppLock(app);
11259 
11260     if (XmTextF_string_length(tf) > 0)
11261     {
11262 	temp_wcs = (wchar_t*) XtMalloc((unsigned) sizeof(wchar_t) *
11263 				       (XmTextF_string_length(tf) + 1));
11264 	if (XmTextF_max_char_size(tf) != 1)
11265 	{
11266 	    (void)memcpy((void*)temp_wcs, (void*)XmTextF_wc_value(tf),
11267 			 sizeof(wchar_t) * (XmTextF_string_length(tf) + 1));
11268 	}
11269 	else
11270 	{
11271 	    num_wcs = mbstowcs(temp_wcs, XmTextF_value(tf),
11272 			       XmTextF_string_length(tf) + 1);
11273 	}
11274 
11275 	_XmAppUnlock(app);
11276 	return temp_wcs;
11277     }
11278     else
11279       {
11280 	temp_wcs = (wchar_t*) XtMalloc((unsigned) sizeof(wchar_t));
11281 	temp_wcs[0] = (wchar_t)0L; /* put a wchar_t NULL in position 0 */
11282 
11283 	_XmAppUnlock(app);
11284 	return temp_wcs;
11285       }
11286 }
11287 
11288 int
11289 #ifdef _NO_PROTO
XmDataFieldGetSubstringWcs(widget,start,num_chars,buf_size,buffer)11290 XmDataFieldGetSubstringWcs( widget, start, num_chars, buf_size, buffer )
11291         Widget widget;
11292         XmTextPosition start;
11293         int num_chars;
11294         int buf_size;
11295         wchar_t *buffer;
11296 #else
11297 XmDataFieldGetSubstringWcs(
11298 	Widget widget,
11299         XmTextPosition start,
11300         int num_chars,
11301         int buf_size,
11302         wchar_t *buffer )
11303 #endif /* _NO_PROTO */
11304 {
11305     XmDataFieldWidget tf = (XmDataFieldWidget) widget;
11306     int ret_value = XmCOPY_SUCCEEDED;
11307     int num_wcs = 0;
11308 
11309     _XmWidgetToAppContext(widget);
11310     _XmAppLock(app);
11311 
11312     if (start + num_chars > XmTextF_string_length(tf))
11313     {
11314 	num_chars = (int) (XmTextF_string_length(tf) - start);
11315 	ret_value = XmCOPY_TRUNCATED;
11316     }
11317 
11318     if (buf_size < num_chars + 1 )
11319     {
11320       _XmAppUnlock(app);
11321       return XmCOPY_FAILED;
11322     }
11323 
11324     if (num_chars > 0)
11325     {
11326 	if (XmTextF_max_char_size(tf) == 1)
11327 	{
11328 	    num_wcs = mbstowcs(buffer, &XmTextF_value(tf)[start], num_chars);
11329 	    if (num_wcs < 0) num_chars = 0;
11330 	}
11331 	else
11332 	{
11333 	    (void)memcpy((void*)buffer, (void*)&XmTextF_wc_value(tf)[start],
11334 			 (size_t) num_chars * sizeof(wchar_t));
11335 	}
11336 	buffer[num_chars] = '\0';
11337     } else if (num_chars == 0) {
11338 	buffer[num_chars] = '\0';
11339     }
11340     else
11341     {
11342       ret_value = XmCOPY_FAILED;
11343     }
11344 
11345     _XmAppUnlock(app);
11346     return (ret_value);
11347 }
11348 
11349 
11350 XmTextPosition
11351 #ifdef _NO_PROTO
XmDataFieldGetLastPosition(w)11352 XmDataFieldGetLastPosition( w )
11353         Widget w ;
11354 #else
11355 XmDataFieldGetLastPosition(
11356         Widget w )
11357 #endif /* _NO_PROTO */
11358 {
11359     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11360     XmTextPosition ret_val;
11361 
11362     _XmWidgetToAppContext(w);
11363     _XmAppLock(app);
11364 
11365     ret_val = XmTextF_string_length(tf);
11366 
11367     _XmAppUnlock(app);
11368     return(ret_val);
11369 }
11370 
11371 void
11372 #ifdef _NO_PROTO
XmDataFieldSetString(w,value)11373 XmDataFieldSetString( w, value )
11374         Widget w ;
11375         char *value ;
11376 #else
11377 XmDataFieldSetString(
11378         Widget w,
11379         char *value )
11380 #endif /* _NO_PROTO */
11381 {
11382     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11383     XmAnyCallbackStruct cb;
11384     XmTextPosition fromPos, toPos, newInsert;
11385     int length;
11386     int free_insert = False;
11387     int ret_val = 0;
11388     char * tmp_ptr;
11389     char * mod_value = NULL;
11390 
11391     _XmWidgetToAppContext(w);
11392     _XmAppLock(app);
11393 
11394     fromPos = 0;
11395 
11396     if (value == NULL) value = "";
11397     toPos = XmTextF_string_length(tf);
11398 
11399     if (XmTextF_max_char_size(tf) == 1)
11400     {
11401 	length = strlen(value);
11402     }
11403     else
11404     {
11405 	length = mbstowcs(NULL, value, 0);
11406     }
11407 
11408     if (tf->core.sensitive && XmTextF_has_focus(tf))
11409     {
11410         df_ChangeBlinkBehavior(tf, False);
11411     }
11412     _XmDataFieldDrawInsertionPoint(tf, False);
11413 
11414     if (XmTextF_modify_verify_callback(tf) ||
11415 	XmTextF_wcs_modify_verify_callback(tf))
11416     {
11417 	/*
11418 	 * If the function df_ModifyVerify() returns
11419 	 * false then don't continue with the action.
11420 	 */
11421 	if (!df_ModifyVerify(tf, NULL, &fromPos, &toPos,
11422 			     &value, &length, &newInsert, &free_insert))
11423 	{
11424 	    if (XmTextF_verify_bell(tf)) XBell(XtDisplay(w), 0);
11425 	    if (free_insert) XtFree(value);
11426 	    _XmAppUnlock(app);
11427 	    return;
11428 	}
11429     }
11430 
11431     XmDataFieldSetHighlight(w, 0, XmTextF_string_length(tf),
11432 			    XmHIGHLIGHT_NORMAL);
11433 
11434     if (XmTextF_max_char_size(tf) == 1)
11435     {
11436 	XtFree(XmTextF_value(tf));
11437     }
11438     else   /* convert to wchar_t before calling df_ValidateString */
11439     {
11440 	XtFree((char *)XmTextF_wc_value(tf));
11441     }
11442 
11443     df_ValidateString(tf, value, False);
11444     XmTextF_pending_off(tf) = True;
11445 
11446     df_SetCursorPosition(tf, NULL, 0, True, True, False);
11447 
11448     if (XmTextF_resize_width(tf) && XmTextF_do_resize(tf))
11449     {
11450 	df_AdjustSize(tf);
11451     }
11452     else
11453     {
11454 	if (XmDataField_alignment(tf) == XmALIGNMENT_END)
11455 	{
11456 	    XmTextF_h_offset(tf) = 0;
11457 	}
11458 	else
11459 	{
11460 	    XmTextF_h_offset(tf) = XmTextF_margin_width(tf) +
11461 		tf->primitive.shadow_thickness +
11462 		tf->primitive.highlight_thickness;
11463 	}
11464 	if (!df_AdjustText(tf, XmTextF_cursor_position(tf), False))
11465 	{
11466 	    df_RedisplayText(tf, 0, XmTextF_string_length(tf));
11467 	}
11468     }
11469 
11470     cb.reason = XmCR_VALUE_CHANGED;
11471     cb.event = NULL;
11472     XtCallCallbackList(w, XmTextF_value_changed_callback(tf), (XtPointer) &cb);
11473 
11474     XmTextF_refresh_ibeam_off(tf) = True;
11475 
11476     if (tf->core.sensitive && XmTextF_has_focus(tf))
11477     {
11478         df_ChangeBlinkBehavior(tf, True);
11479     }
11480 
11481     _XmDataFieldDrawInsertionPoint(tf, True);
11482     if (free_insert) XtFree(value);
11483 
11484     _XmAppUnlock(app);
11485 }
11486 
11487 static void
11488 #ifdef _NO_PROTO
XmDataFieldSetStringWcs(w,wc_value)11489 XmDataFieldSetStringWcs( w, wc_value )
11490         Widget w;
11491         wchar_t *wc_value;
11492 #else
11493 XmDataFieldSetStringWcs(
11494         Widget w,
11495         wchar_t *wc_value )
11496 #endif /* _NO_PROTO */
11497 {
11498 
11499    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11500    char * tmp;
11501    wchar_t *tmp_wc;
11502    int num_chars = 0;
11503    int result;
11504 
11505    _XmWidgetToAppContext(w);
11506    _XmAppLock(app);
11507 
11508     for (num_chars = 0, tmp_wc = wc_value; *tmp_wc != (wchar_t)0L; num_chars++)
11509         tmp_wc++;  /* count number of wchar_t's */
11510 
11511    tmp = XtMalloc((unsigned) (num_chars + 1) * XmTextF_max_char_size(tf));
11512    result = wcstombs(tmp, wc_value, (num_chars + 1) * XmTextF_max_char_size(tf));
11513 
11514    if (result == (size_t) -1) /* if wcstombs fails, it returns (size_t) -1 */
11515        tmp = "";               /* if invalid data, pass in the empty string */
11516 
11517    XmDataFieldSetString(w, tmp);
11518 
11519    XtFree(tmp);
11520    _XmAppUnlock(app);
11521 }
11522 
11523 
11524 void
11525 #ifdef _NO_PROTO
XmDataFieldReplace(w,from_pos,to_pos,value)11526 XmDataFieldReplace( w, from_pos, to_pos, value )
11527         Widget w ;
11528         XmTextPosition from_pos ;
11529         XmTextPosition to_pos ;
11530         char *value ;
11531 #else
11532 XmDataFieldReplace(
11533         Widget w,
11534         XmTextPosition from_pos,
11535         XmTextPosition to_pos,
11536         char *value )
11537 #endif /* _NO_PROTO */
11538 {
11539     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11540 
11541     int save_maxlength = XmTextF_max_length(tf);
11542     Boolean save_editable = XmTextF_editable(tf);
11543     Boolean deselected = False;
11544     Boolean rep_result = False;
11545     wchar_t *wc_value;
11546     int length = 0;
11547     XmAnyCallbackStruct cb;
11548 
11549     _XmWidgetToAppContext(w);
11550     _XmAppLock(app);
11551 
11552     if (value == NULL) value = "";
11553 
11554     df_VerifyBounds(tf, &from_pos, &to_pos);
11555 
11556     if (XmTextF_has_primary(tf)) {
11557        if ((XmTextF_prim_pos_left(tf) > from_pos &&
11558 	    XmTextF_prim_pos_left(tf) < to_pos) ||
11559            (XmTextF_prim_pos_right(tf) >from_pos &&
11560 	    XmTextF_prim_pos_right(tf) < to_pos) ||
11561            (XmTextF_prim_pos_left(tf) <= from_pos &&
11562 	    XmTextF_prim_pos_right(tf) >= to_pos)) {
11563 	 _XmDataFieldDeselectSelection(w, False,
11564 				       XtLastTimestampProcessed(XtDisplay(w)));
11565 	 deselected = True;
11566        }
11567     }
11568 
11569     XmTextF_editable(tf) = True;
11570     XmTextF_max_length(tf) = INT_MAX;
11571     if (XmTextF_max_char_size(tf) == 1) {
11572        length = strlen(value);
11573        rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos,
11574 				            to_pos, value, length, False);
11575     } else { /* need to convert to wchar_t* before calling Replace */
11576        wc_value = (wchar_t *) XtMalloc((unsigned) sizeof(wchar_t) *
11577 				       (1 + strlen(value)));
11578        length = mbstowcs(wc_value, value, (unsigned) (strlen(value) + 1));
11579        rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos, to_pos,
11580 				      (char*)wc_value, length, False);
11581        XtFree((char *)wc_value);
11582     }
11583     if (from_pos <= XmTextF_cursor_position(tf)) {
11584       XmTextPosition cursorPos;
11585       /* Replace will not move us, we still want this to happen */
11586       if (XmTextF_cursor_position(tf) < to_pos) {
11587 	if (XmTextF_cursor_position(tf) - from_pos <= length)
11588 	  cursorPos = XmTextF_cursor_position(tf);
11589 	else
11590 	  cursorPos = from_pos + length;
11591       } else {
11592 	cursorPos = XmTextF_cursor_position(tf) - (to_pos - from_pos) + length;
11593       }
11594       XmDataFieldSetInsertionPosition((Widget)tf, cursorPos);
11595     }
11596     XmTextF_editable(tf) = save_editable;
11597     XmTextF_max_length(tf) = save_maxlength;
11598 
11599     /*
11600      * Replace Text utilizes an optimization in deciding which text to redraw;
11601      * in the case that the selection has been changed (as above), this can
11602      * cause part/all of the replaced text to NOT be redrawn.  The following
11603      * df_AdjustText call ensures that it IS drawn in this case.
11604      */
11605 
11606     if (deselected)
11607        df_AdjustText(tf, from_pos, True);
11608 
11609     (void) df_SetDestination(w, XmTextF_cursor_position(tf), False,
11610 			  XtLastTimestampProcessed(XtDisplay(w)));
11611     if (rep_result) {
11612        cb.reason = XmCR_VALUE_CHANGED;
11613        cb.event = (XEvent *)NULL;
11614        XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
11615 		          (XtPointer) &cb);
11616     }
11617 
11618     _XmAppUnlock(app);
11619 }
11620 
11621 /* TOM - XmDataFieldReplaceWcs not converted */
11622 void
11623 #ifdef _NO_PROTO
XmDataFieldReplaceWcs(w,from_pos,to_pos,wc_value)11624 XmDataFieldReplaceWcs( w, from_pos, to_pos, wc_value )
11625         Widget w ;
11626         XmTextPosition from_pos ;
11627         XmTextPosition to_pos ;
11628         wchar_t *wc_value ;
11629 #else
11630 XmDataFieldReplaceWcs(
11631         Widget w,
11632         XmTextPosition from_pos,
11633         XmTextPosition to_pos,
11634         wchar_t *wc_value )
11635 #endif /* _NO_PROTO */
11636 {
11637     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11638     int save_maxlength = XmTextF_max_length(tf);
11639     Boolean save_editable = XmTextF_editable(tf);
11640     Boolean deselected = False;
11641     Boolean rep_result = False;
11642     wchar_t *tmp_wc;
11643     char *tmp;
11644     int wc_length = 0;
11645     XmAnyCallbackStruct cb;
11646 
11647    _XmWidgetToAppContext(w);
11648    _XmAppLock(app);
11649 
11650     if (wc_value == NULL) wc_value = (wchar_t*)"";
11651 
11652     df_VerifyBounds(tf, &from_pos, &to_pos);
11653 
11654     if (XmTextF_has_primary(tf)) {
11655        if ((XmTextF_prim_pos_left(tf) > from_pos &&
11656               XmTextF_prim_pos_left(tf) < to_pos) ||
11657            (XmTextF_prim_pos_right(tf) >from_pos &&
11658               XmTextF_prim_pos_right(tf) < to_pos) ||
11659            (XmTextF_prim_pos_left(tf) <= from_pos &&
11660               XmTextF_prim_pos_right(tf) >= to_pos)) {
11661                 _XmDataFieldDeselectSelection(w, False,
11662 			                XtLastTimestampProcessed(XtDisplay(w)));
11663                 deselected = True;
11664        }
11665     }
11666 
11667    /* Count the number of wide chars in the array */
11668     for (wc_length = 0, tmp_wc = wc_value; *tmp_wc != (wchar_t)0L; wc_length++)
11669 	tmp_wc++;  /* count number of wchar_t's */
11670 
11671     XmTextF_editable(tf) = True;
11672     XmTextF_max_length(tf) = INT_MAX;
11673 
11674     if (XmTextF_max_char_size(tf) != 1)
11675     {
11676 	rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos, to_pos,
11677 					     (char*)wc_value, wc_length, False);
11678     }
11679     else
11680     {     /* need to convert to char* before calling Replace */
11681 	tmp = XtMalloc((unsigned) (wc_length + 1) * XmTextF_max_char_size(tf));
11682 	wc_length = wcstombs(tmp, wc_value,
11683 			     (wc_length + 1) * XmTextF_max_char_size(tf));
11684 
11685        if (wc_length == (size_t) -1){ /* if wcstombs fails, it returns -1 */
11686           tmp = "";                   /* if invalid data, pass in the empty
11687                                        * string */
11688           wc_length = 0;
11689        }
11690        rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos, to_pos,
11691                                             (char*)tmp, wc_length, False);
11692        XtFree(tmp);
11693     }
11694     if (from_pos <= XmTextF_cursor_position(tf)) {
11695       XmTextPosition cursorPos;
11696       /* Replace will not move us, we still want this to happen */
11697       if (XmTextF_cursor_position(tf) < to_pos) {
11698 	if (XmTextF_cursor_position(tf) - from_pos <= wc_length)
11699 	  cursorPos = XmTextF_cursor_position(tf);
11700 	else
11701 	  cursorPos = from_pos + wc_length;
11702       } else {
11703 	cursorPos = XmTextF_cursor_position(tf) - (to_pos - from_pos) + wc_length;
11704       }
11705       XmDataFieldSetInsertionPosition((Widget)tf, cursorPos);
11706     }
11707     XmTextF_editable(tf) = save_editable;
11708     XmTextF_max_length(tf) = save_maxlength;
11709 
11710     /*
11711      * Replace Text utilizes an optimization in deciding which text to redraw;
11712      * in the case that the selection has been changed (as above), this can
11713      * cause part/all of the replaced text to NOT be redrawn.  The following
11714      * df_AdjustText call ensures that it IS drawn in this case.
11715      */
11716 
11717     if (deselected)
11718        df_AdjustText(tf, from_pos, True);
11719 
11720     (void) df_SetDestination(w, XmTextF_cursor_position(tf), False,
11721 			  XtLastTimestampProcessed(XtDisplay(w)));
11722     if (rep_result) {
11723        cb.reason = XmCR_VALUE_CHANGED;
11724        cb.event = (XEvent *)NULL;
11725        XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
11726 		          (XtPointer) &cb);
11727     }
11728 
11729     _XmAppUnlock(app);
11730 }
11731 
11732 
11733 void
11734 #ifdef _NO_PROTO
XmDataFieldInsert(w,position,value)11735 XmDataFieldInsert( w, position, value )
11736         Widget w ;
11737         XmTextPosition position ;
11738         char *value ;
11739 #else
11740 XmDataFieldInsert(
11741         Widget w,
11742         XmTextPosition position,
11743         char *value )
11744 #endif /* _NO_PROTO */
11745 {
11746   _XmWidgetToAppContext(w);
11747   _XmAppLock(app);
11748 
11749   /* XmDataFieldReplace takes care of converting to wchar_t* if needed */
11750   XmDataFieldReplace(w, position, position, value);
11751 
11752   _XmAppUnlock(app);
11753 }
11754 
11755 void
11756 #ifdef _NO_PROTO
XmDataFieldInsertWcs(w,position,wcstring)11757 XmDataFieldInsertWcs( w, position, wcstring )
11758         Widget w ;
11759         XmTextPosition position ;
11760         wchar_t *wcstring ;
11761 #else
11762 XmDataFieldInsertWcs(
11763         Widget w,
11764         XmTextPosition position,
11765         wchar_t *wcstring )
11766 #endif /* _NO_PROTO */
11767 {
11768   _XmWidgetToAppContext(w);
11769   _XmAppLock(app);
11770 
11771   /* XmDataFieldReplaceWcs takes care of converting to wchar_t* if needed */
11772   XmDataFieldReplaceWcs(w, position, position, wcstring);
11773 
11774   _XmAppUnlock(app);
11775 }
11776 
11777 void
11778 #ifdef _NO_PROTO
XmDataFieldSetAddMode(w,state)11779 XmDataFieldSetAddMode( w, state )
11780         Widget w ;
11781         Boolean state ;
11782 #else
11783 XmDataFieldSetAddMode(
11784         Widget w,
11785         Boolean state )
11786 #endif /* _NO_PROTO */
11787 {
11788    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11789 
11790   _XmWidgetToAppContext(w);
11791   _XmAppLock(app);
11792 
11793    if (XmTextF_add_mode(tf) == state)
11794    {
11795      _XmAppUnlock(app);
11796      return;
11797    }
11798 
11799    _XmDataFieldDrawInsertionPoint(tf, False);
11800    XmTextF_add_mode(tf) = state;
11801    _XmDataFToggleCursorGC(w);
11802    _XmDataFieldDrawInsertionPoint(tf, True);
11803 
11804    _XmAppUnlock(app);
11805 }
11806 
11807 Boolean
11808 #ifdef _NO_PROTO
XmDataFieldGetAddMode(w)11809 XmDataFieldGetAddMode( w )
11810         Widget w ;
11811 #else
11812 XmDataFieldGetAddMode(
11813         Widget w )
11814 #endif /* _NO_PROTO */
11815 {
11816    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11817    Boolean ret_val;
11818 
11819    _XmWidgetToAppContext(w);
11820    _XmAppLock(app);
11821 
11822    ret_val = XmTextF_add_mode(tf);
11823 
11824    _XmAppUnlock(app);
11825    return (ret_val);
11826 }
11827 
11828 Boolean
11829 #ifdef _NO_PROTO
XmDataFieldGetEditable(w)11830 XmDataFieldGetEditable( w )
11831         Widget w ;
11832 #else
11833 XmDataFieldGetEditable(
11834         Widget w )
11835 #endif /* _NO_PROTO */
11836 {
11837    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11838    Boolean ret_val;
11839 
11840    _XmWidgetToAppContext(w);
11841    _XmAppLock(app);
11842 
11843    ret_val = XmTextF_editable(tf);
11844 
11845    _XmAppUnlock(app);
11846    return ret_val;
11847 }
11848 
11849 void
11850 #ifdef _NO_PROTO
XmDataFieldSetEditable(w,editable)11851 XmDataFieldSetEditable( w, editable )
11852         Widget w ;
11853         Boolean editable ;
11854 #else
11855 XmDataFieldSetEditable(
11856         Widget w,
11857         Boolean editable )
11858 #endif /* _NO_PROTO */
11859 {
11860     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11861     XPoint xmim_point;
11862     Arg args[6];  /* To set initial values to input method */
11863     Cardinal n = 0;
11864 
11865    _XmWidgetToAppContext(w);
11866    _XmAppLock(app);
11867 
11868    /* if widget previously wasn't editable, no input method has yet been */
11869    /* registered.  So, if we're making it editable now, register the IM  */
11870    /* give the IM the relevent values.                                   */
11871 
11872    if (!XmTextF_editable(tf) && editable)
11873      {
11874 #if defined(__sgi)
11875        /* CR03685 */
11876        SGI_hack_XmImRegister((Widget)tf);
11877 #else
11878        XmImRegister((Widget)tf, (unsigned int) NULL);
11879 #endif
11880        df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &xmim_point.x,
11881 		       &xmim_point.y);
11882        n = 0;
11883        XtSetArg(args[n], XmNfontList, XmTextF_font_list(tf)); n++;
11884        XtSetArg(args[n], XmNbackground, tf->core.background_pixel); n++;
11885        XtSetArg(args[n], XmNforeground, tf->primitive.foreground); n++;
11886        XtSetArg(args[n], XmNbackgroundPixmap,tf->core.background_pixmap);n++;
11887        XtSetArg(args[n], XmNspotLocation, &xmim_point); n++;
11888        XtSetArg(args[n], XmNlineSpace,
11889 		 XmTextF_font_ascent(tf)+ XmTextF_font_descent(tf)); n++;
11890 	XmImSetValues((Widget)tf, args, n);
11891      } else if (XmTextF_editable(tf) && !editable){
11892        XmImUnregister(w);
11893     }
11894 
11895     XmTextF_editable(tf) = editable;
11896 
11897     n = 0;
11898     if (editable) {
11899 	XtSetArg(args[n], XmNdropSiteActivity, XmDROP_SITE_ACTIVE); n++;
11900     } else {
11901 	XtSetArg(args[n], XmNdropSiteActivity, XmDROP_SITE_INACTIVE); n++;
11902     }
11903 
11904     XmDropSiteUpdate((Widget)tf, args, n);
11905     _XmAppUnlock(app);
11906 }
11907 
11908 int
11909 #ifdef _NO_PROTO
XmDataFieldGetMaxLength(w)11910 XmDataFieldGetMaxLength( w )
11911         Widget w ;
11912 #else
11913 XmDataFieldGetMaxLength(
11914         Widget w )
11915 #endif /* _NO_PROTO */
11916 {
11917     XmDataFieldWidget tf = (XmDataFieldWidget) w;
11918     int ret_val;
11919 
11920     _XmWidgetToAppContext(w);
11921     _XmAppLock(app);
11922 
11923     ret_val = XmTextF_max_length(tf);
11924 
11925     _XmAppUnlock(app);
11926     return ret_val;
11927 }
11928 
11929 void
11930 #ifdef _NO_PROTO
XmDataFieldSetMaxLength(w,max_length)11931 XmDataFieldSetMaxLength( w, max_length )
11932         Widget w ;
11933         int max_length ;
11934 #else
11935 XmDataFieldSetMaxLength(
11936         Widget w,
11937         int max_length )
11938 #endif /* _NO_PROTO */
11939 {
11940    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11941 
11942    _XmWidgetToAppContext(w);
11943    _XmAppLock(app);
11944 
11945    XmTextF_max_length(tf) = max_length;
11946 
11947    _XmAppUnlock(app);
11948 }
11949 
11950 XmTextPosition
11951 #ifdef _NO_PROTO
XmDataFieldGetCursorPosition(w)11952 XmDataFieldGetCursorPosition( w )
11953         Widget w ;
11954 #else
11955 XmDataFieldGetCursorPosition(
11956         Widget w )
11957 #endif /* _NO_PROTO */
11958 {
11959    XmDataFieldWidget tf = (XmDataFieldWidget) w;
11960    XmTextPosition ret_val;
11961 
11962    _XmWidgetToAppContext(w);
11963    _XmAppLock(app);
11964 
11965    ret_val = XmTextF_cursor_position(tf);
11966 
11967    _XmAppUnlock(app);
11968    return ret_val;
11969 }
11970 
11971 XmTextPosition
11972 #ifdef _NO_PROTO
XmDataFieldGetInsertionPosition(w)11973 XmDataFieldGetInsertionPosition( w )
11974         Widget w ;
11975 #else
11976 XmDataFieldGetInsertionPosition(
11977         Widget w )
11978 #endif /* _NO_PROTO */
11979 {
11980     XmTextPosition ret_val;
11981 
11982    _XmWidgetToAppContext(w);
11983    _XmAppLock(app);
11984 
11985     ret_val = XmDataFieldGetCursorPosition(w);
11986 
11987     _XmAppUnlock(app);
11988     return ret_val;
11989 }
11990 
11991 /* Obsolete - shouldn't be here ! */
11992 void
11993 #ifdef _NO_PROTO
XmDataFielddf_SetCursorPosition(w,position)11994 XmDataFielddf_SetCursorPosition( w, position )
11995         Widget w ;
11996         XmTextPosition position ;
11997 #else
11998 XmDataFielddf_SetCursorPosition(
11999         Widget w,
12000         XmTextPosition position )
12001 #endif /* _NO_PROTO */
12002 {
12003     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12004 
12005    _XmWidgetToAppContext(w);
12006    _XmAppLock(app);
12007 
12008     df_SetCursorPosition(tf, NULL, position, True, False, False);
12009     _XmAppUnlock(app);
12010 }
12011 
12012 void
12013 #ifdef _NO_PROTO
XmDataFieldSetInsertionPosition(w,position)12014 XmDataFieldSetInsertionPosition( w, position )
12015         Widget w ;
12016         XmTextPosition position ;
12017 #else
12018 XmDataFieldSetInsertionPosition(
12019         Widget w,
12020         XmTextPosition position )
12021 #endif /* _NO_PROTO */
12022 {
12023    XmDataFieldWidget tf = (XmDataFieldWidget) w;
12024 
12025    _XmWidgetToAppContext(w);
12026    _XmAppLock(app);
12027 
12028    df_SetCursorPosition(tf, NULL, position, True, True, False);
12029 
12030    _XmAppUnlock(app);
12031 }
12032 
12033 Boolean
12034 #ifdef _NO_PROTO
XmDataFieldGetSelectionPosition(w,left,right)12035 XmDataFieldGetSelectionPosition( w, left, right )
12036         Widget w ;
12037         XmTextPosition *left ;
12038         XmTextPosition *right ;
12039 #else
12040 XmDataFieldGetSelectionPosition(
12041         Widget w,
12042         XmTextPosition *left,
12043         XmTextPosition *right )
12044 #endif /* _NO_PROTO */
12045 {
12046    XmDataFieldWidget tf = (XmDataFieldWidget) w;
12047 
12048    _XmWidgetToAppContext(w);
12049    _XmAppLock(app);
12050 
12051    if (!XmTextF_has_primary(tf)) {
12052      _XmAppUnlock(app);
12053        return False;
12054    }
12055 
12056    *left = XmTextF_prim_pos_left(tf);
12057    *right = XmTextF_prim_pos_right(tf);
12058 
12059    _XmAppUnlock(app);
12060    return True;
12061 }
12062 
12063 char *
12064 #ifdef _NO_PROTO
XmDataFieldGetSelection(w)12065 XmDataFieldGetSelection( w )
12066         Widget w ;
12067 #else
12068 XmDataFieldGetSelection(
12069         Widget w )
12070 #endif /* _NO_PROTO */
12071 {
12072    XmDataFieldWidget tf = (XmDataFieldWidget) w;
12073    size_t length, num_chars;
12074    char *value;
12075 
12076    _XmWidgetToAppContext(w);
12077    _XmAppLock(app);
12078 
12079     if (XmTextF_prim_pos_left(tf) == XmTextF_prim_pos_right(tf))
12080     {
12081       _XmAppUnlock(app);
12082       return NULL;
12083     }
12084 
12085     num_chars = (size_t) (XmTextF_prim_pos_right(tf) \
12086 			  - XmTextF_prim_pos_left(tf));
12087     length = num_chars;
12088 
12089     if (XmTextF_max_char_size(tf) == 1)
12090     {
12091 	value = XtMalloc((unsigned) num_chars + 1);
12092 	(void) memcpy((void*)value,
12093 		      (void*)(XmTextF_value(tf) +
12094 			      XmTextF_prim_pos_left(tf)), num_chars);
12095     }
12096     else
12097     {
12098 	value = XtMalloc((unsigned) ((num_chars + 1) * XmTextF_max_char_size(tf)));
12099 	length = wcstombs(value, XmTextF_wc_value(tf) + XmTextF_prim_pos_left(tf),
12100 			  (num_chars + 1) * XmTextF_max_char_size(tf));
12101 	if (length == (size_t) -1)
12102 	{
12103 	    length = 0;
12104 	}
12105 	else
12106 	{
12107 	    for (length = 0;num_chars > 0; num_chars--)
12108 	    {
12109 		length += mblen(&value[length], XmTextF_max_char_size(tf));
12110 	    }
12111 	}
12112     }
12113     value[length] = (char)'\0';
12114 
12115     _XmAppUnlock(app);
12116     return value;
12117 }
12118 
12119 wchar_t *
12120 #ifdef _NO_PROTO
XmDataFieldGetSelectionWcs(w)12121 XmDataFieldGetSelectionWcs( w )
12122         Widget w ;
12123 #else
12124 XmDataFieldGetSelectionWcs(
12125         Widget w )
12126 #endif /* _NO_PROTO */
12127 {
12128    XmDataFieldWidget tf = (XmDataFieldWidget) w;
12129    size_t length;
12130    wchar_t *wc_value;
12131    int return_val;
12132 
12133    _XmWidgetToAppContext(w);
12134    _XmAppLock(app);
12135 
12136    if (XmTextF_prim_pos_left(tf) == XmTextF_prim_pos_right(tf))
12137    {
12138      _XmAppUnlock(app);
12139      return NULL;
12140    }
12141 
12142    length = (size_t)(XmTextF_prim_pos_right(tf) -
12143 		     XmTextF_prim_pos_left(tf));
12144 
12145    wc_value = (wchar_t*)XtMalloc((unsigned) (length + 1) * sizeof(wchar_t));
12146 
12147    if (XmTextF_max_char_size(tf) == 1)
12148    {
12149        return_val = mbstowcs(wc_value, XmTextF_value(tf) +
12150 			     XmTextF_prim_pos_left(tf), length);
12151        if (return_val < 0) length = 0;
12152    }
12153    else
12154    {
12155       (void)memcpy((void*)wc_value,
12156 		   (void*)(XmTextF_wc_value(tf) + XmTextF_prim_pos_left(tf)),
12157 		   length * sizeof(wchar_t));
12158    }
12159    wc_value[length] = (wchar_t)0L;
12160 
12161    _XmAppUnlock(app);
12162    return (wc_value);
12163 }
12164 
12165 
12166 Boolean
12167 #ifdef _NO_PROTO
XmDataFieldRemove(w)12168 XmDataFieldRemove( w )
12169         Widget w ;
12170 #else
12171 XmDataFieldRemove(
12172         Widget w )
12173 #endif /* _NO_PROTO */
12174 {
12175     Boolean ret_val;
12176 
12177    _XmWidgetToAppContext(w);
12178    _XmAppLock(app);
12179 
12180     ret_val = DataFieldRemove(w, NULL);
12181 
12182     _XmAppUnlock(app);
12183     return ret_val;
12184 }
12185 
12186 Boolean
12187 #ifdef _NO_PROTO
XmDataFieldCopy(w,clip_time)12188 XmDataFieldCopy( w, clip_time )
12189         Widget w ;
12190         Time clip_time ;
12191 #else
12192 XmDataFieldCopy(
12193         Widget w,
12194         Time clip_time )
12195 #endif /* _NO_PROTO */
12196 {
12197     /* XmDataFieldGetSelection gets char* rep of data, so no special handling
12198      * needed
12199      */
12200     char * selected_string = XmDataFieldGetSelection(w); /* text selection */
12201     long item_id = 0L;                      /* clipboard item id */
12202     long data_id = 0;                        /* clipboard data id */
12203     int status = 0;                         /* clipboard status  */
12204     XmString clip_label;
12205     XTextProperty tmp_prop;
12206     Display *display = XtDisplay(w);
12207     Window window = XtWindow(w);
12208     char *atom_name;
12209 
12210    _XmWidgetToAppContext(w);
12211    _XmAppLock(app);
12212 
12213     /* using the clipboard facilities, copy the selected text to the clipboard */
12214     if (selected_string != NULL)
12215     {
12216 	clip_label = XmStringCreateLtoR ("XM_TEXT_FIELD",
12217 					 XmFONTLIST_DEFAULT_TAG);
12218 
12219 	/* start copy to clipboard */
12220 	status = XmClipboardStartCopy(display, window, clip_label, clip_time,
12221 				      w, (XmCutPasteProc)NULL, &item_id);
12222 
12223 	if (status != ClipboardSuccess)
12224 	{
12225 	    XtFree(selected_string);
12226 	    XmStringFree(clip_label);
12227 	    _XmAppUnlock(app);
12228 	    return False;
12229 	}
12230 
12231 	status = XmbTextListToTextProperty(display, &selected_string, 1,
12232 					   (XICCEncodingStyle)XStdICCTextStyle,
12233 					   &tmp_prop);
12234 
12235 	if (status != Success && status <= 0)
12236 	{
12237 	    XmClipboardCancelCopy(display, window, item_id);
12238 	    XtFree(selected_string);
12239 	    XmStringFree(clip_label);
12240 	    _XmAppUnlock(app);
12241 	    return False;
12242 	}
12243 
12244 	atom_name = XGetAtomName(display, tmp_prop.encoding);
12245 
12246 	/* move the data to the clipboard */
12247 	status = XmClipboardCopy(display, window, item_id, atom_name,
12248 				 (XtPointer)tmp_prop.value, tmp_prop.nitems,
12249 				 0, &data_id);
12250 
12251 	XtFree(atom_name);
12252 
12253 	if (status != ClipboardSuccess)
12254 	{
12255 	    XmClipboardCancelCopy(XtDisplay(w), XtWindow(w), item_id);
12256 	    XtFree(selected_string);
12257 	    XmStringFree(clip_label);
12258 	    _XmAppUnlock(app);
12259 	    return False;
12260 	}
12261 
12262 	/* end the copy to the clipboard */
12263 	status = XmClipboardEndCopy(display, window, item_id);
12264 
12265 	XtFree((char*)tmp_prop.value);
12266 	XmStringFree(clip_label);
12267 
12268 	if (status != ClipboardSuccess)
12269 	{
12270 	    XtFree (selected_string);
12271 	    _XmAppUnlock(app);
12272 	    return False;
12273 	}
12274 
12275     }
12276     else
12277       {
12278 	_XmAppUnlock(app);
12279 	return False;
12280       }
12281 
12282     if (selected_string != NULL)
12283     {
12284 	XtFree (selected_string);
12285     }
12286 
12287     _XmAppUnlock(app);
12288     return True;
12289 }
12290 
12291 Boolean
12292 #ifdef _NO_PROTO
XmDataFieldCut(w,clip_time)12293 XmDataFieldCut( w, clip_time )
12294         Widget w ;
12295         Time clip_time ;
12296 #else
12297 XmDataFieldCut(
12298         Widget w,
12299         Time clip_time )
12300 #endif /* _NO_PROTO */
12301 {
12302     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12303     Boolean success = False;
12304 
12305    _XmWidgetToAppContext(w);
12306    _XmAppLock(app);
12307 
12308     if (XmTextF_editable(tf) == False)
12309     {
12310       _XmAppUnlock(app);
12311       return False;
12312     }
12313 
12314     if (XmDataFieldCopy(w, clip_time))
12315     {
12316 	if (XmDataFieldRemove(w))
12317 	{
12318 	    success = True;
12319 	}
12320     }
12321 
12322     _XmAppUnlock(app);
12323     return success;
12324 }
12325 
12326 
12327 /*
12328  * Retrieves the current data from the clipboard
12329  * and paste it at the current cursor position
12330  */
12331 Boolean
12332 #ifdef _NO_PROTO
XmDataFieldPaste(w)12333 XmDataFieldPaste( w )
12334         Widget w ;
12335 #else
12336 XmDataFieldPaste(
12337         Widget w )
12338 #endif /* _NO_PROTO */
12339 {
12340     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12341     XmTextPosition sel_left = 0;
12342     XmTextPosition sel_right = 0;
12343     XmTextPosition paste_pos_left, paste_pos_right;
12344     int status = 0;                            /* clipboard status        */
12345     char* buffer;                              /* temporary text buffer   */
12346     unsigned long length;                      /* length of buffer        */
12347     unsigned long outlength = 0L;              /* length of bytes copied  */
12348     long private_id = 0;                       /* id of item on clipboard */
12349     Boolean dest_disjoint = True;
12350     Boolean rep_status = False;                /* did Replace succeed? */
12351     Display *display = XtDisplay(w);
12352     Window window = XtWindow(w);
12353     Boolean get_ct = False;
12354     Boolean get_us = False;
12355     XTextProperty tmp_prop;
12356     int malloc_size = 0;
12357     int num_vals;
12358     char **tmp_value;
12359     int i;
12360     XmAnyCallbackStruct cb;
12361 
12362    _XmWidgetToAppContext(w);
12363    _XmAppLock(app);
12364 
12365     if (XmTextF_editable(tf) == False)
12366     {
12367       _XmAppUnlock(app);
12368       return False;
12369     }
12370 
12371     paste_pos_left = paste_pos_right = XmTextF_cursor_position(tf);
12372 
12373     status = XmClipboardInquireLength(display, window, "STRING", &length);
12374 
12375     if (status == ClipboardNoData || length == 0)
12376     {
12377 	status = XmClipboardInquireLength(display,
12378 					  window, "COMPOUND_TEXT",
12379 					  &length);
12380 	if (status == ClipboardNoData || length == 0)
12381 	{
12382 #ifdef UTF8_SUPPORTED
12383           status = XmClipboardInquireLength(display, window,
12384                                             XmSUTF8_STRING, &length);
12385 #endif
12386           if (status == ClipboardNoData || length == 0)
12387           {
12388             _XmAppUnlock(app);
12389             return False;
12390           }
12391           get_us = True;
12392 	} else {
12393 	  get_ct = True;
12394         }
12395    }
12396 
12397    /* malloc length of clipboard data */
12398    buffer = XtMalloc((unsigned) length);
12399 
12400    if (!get_ct && !get_us)
12401    {
12402        status = XmClipboardRetrieve(display, window, "STRING", buffer,
12403 				    length, &outlength, &private_id);
12404    }
12405 #ifdef UTF8_SUPPORTED
12406    else if (!get_ct && get_us) {
12407        status = XmClipboardRetrieve(display, window, XmSUTF8_STRING, buffer,
12408 				    length, &outlength, &private_id);
12409    }
12410 #endif
12411    else
12412    {
12413        status = XmClipboardRetrieve(display, window, "COMPOUND_TEXT", buffer,
12414 				    length, &outlength, &private_id);
12415    }
12416 
12417    if (status != ClipboardSuccess)
12418    {
12419        XmClipboardEndRetrieve(display, window);
12420        XtFree(buffer);
12421        _XmAppUnlock(app);
12422        return False;
12423    }
12424 
12425    if (XmDataFieldGetSelectionPosition(w, &sel_left, &sel_right))
12426    {
12427        if (XmTextF_pending_delete(tf) &&
12428 	   paste_pos_left >= sel_left && paste_pos_right <= sel_right)
12429        {
12430 	   paste_pos_left = sel_left;
12431 	   paste_pos_right = sel_right;
12432 	   dest_disjoint = False;
12433        }
12434    }
12435 
12436    tmp_prop.value = (unsigned char *) buffer;
12437 
12438    if (!get_ct)
12439    {
12440        tmp_prop.encoding = XA_STRING;
12441    }
12442    else
12443    {
12444        tmp_prop.encoding = XmInternAtom(display, "COMPOUND_TEXT", False);
12445    }
12446 
12447    tmp_prop.format = 8;
12448    tmp_prop.nitems = outlength;
12449    num_vals = 0;
12450 
12451    status = XmbTextPropertyToTextList(display, &tmp_prop, &tmp_value,
12452 				      &num_vals);
12453 
12454   /* add new text */
12455    if (num_vals && (status == Success || status > 0))
12456    {
12457        if (XmTextF_max_char_size(tf) == 1)
12458        {
12459 	   char * total_tmp_value;
12460 
12461 	   for (i = 0, malloc_size = 1; i < num_vals ; i++)
12462 	   {
12463 	       malloc_size += strlen(tmp_value[i]);
12464 	   }
12465 	   total_tmp_value = XtMalloc ((unsigned) malloc_size);
12466 	   total_tmp_value[0] = '\0';
12467 	   for (i = 0; i < num_vals ; i++)
12468 	   {
12469 	       strcat(total_tmp_value, tmp_value[i]);
12470 	   }
12471 	   rep_status = _XmDataFieldReplaceText(tf, NULL, paste_pos_left,
12472 						paste_pos_right,
12473 						total_tmp_value,
12474 						strlen(total_tmp_value), True);
12475 	   XFreeStringList(tmp_value);
12476 	   if (malloc_size) XtFree(total_tmp_value);
12477        } else {
12478 	 wchar_t * wc_value;
12479          int num_chars = 0;
12480 
12481 	 for (i = 0, malloc_size = sizeof(wchar_t); i < num_vals ; i++)
12482 	 {
12483 	     malloc_size += strlen(tmp_value[i]);
12484 	 }
12485 	 wc_value = (wchar_t*)XtMalloc((unsigned)malloc_size * sizeof(wchar_t));
12486 	 /* change malloc_size to the number of wchars available in wc_value */
12487 	 for (i = 0; i < num_vals ; i++)
12488 	     num_chars +=
12489 		 mbstowcs(wc_value + num_chars, tmp_value[i],
12490 			  (size_t)malloc_size - num_chars);
12491 	 rep_status = _XmDataFieldReplaceText(tf, NULL, paste_pos_left,
12492 					      paste_pos_right,
12493 					      (char*)wc_value,
12494 					      num_chars, True);
12495 	 if (malloc_size) XtFree((char*)wc_value);
12496        }
12497    }
12498 
12499    if (rep_status) {
12500        XmTextF_prim_anchor(tf) = sel_left;
12501        (void) df_SetDestination(w, XmTextF_cursor_position(tf), False,
12502 				XtLastTimestampProcessed(display));
12503        if (sel_left != sel_right)
12504        {
12505            if (!dest_disjoint || !XmTextF_add_mode(tf))
12506 	   {
12507 	       XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
12508 				       XmTextF_cursor_position(tf),
12509 				       XtLastTimestampProcessed(display));
12510            }
12511        }
12512        cb.reason = XmCR_VALUE_CHANGED;
12513        cb.event = (XEvent *)NULL;
12514        XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
12515      		          (XtPointer) &cb);
12516    }
12517    XtFree(buffer);
12518 
12519    _XmAppUnlock(app);
12520    return True;
12521 }
12522 
12523 void
12524 #ifdef _NO_PROTO
XmDataFielddf_ClearSelection(w,sel_time)12525 XmDataFielddf_ClearSelection( w, sel_time )
12526         Widget w ;
12527         Time sel_time ;
12528 #else
12529 XmDataFielddf_ClearSelection(
12530         Widget w,
12531         Time sel_time )
12532 #endif /* _NO_PROTO */
12533 {
12534   _XmWidgetToAppContext(w);
12535   _XmAppLock(app);
12536 
12537   _XmDataFieldDeselectSelection(w, False, sel_time);
12538 
12539   _XmAppUnlock(app);
12540 }
12541 
12542 void
12543 #ifdef _NO_PROTO
XmDataFieldSetSelection(w,first,last,sel_time)12544 XmDataFieldSetSelection( w, first, last, sel_time )
12545         Widget w ;
12546         XmTextPosition first ;
12547         XmTextPosition last ;
12548         Time sel_time ;
12549 #else
12550 XmDataFieldSetSelection(
12551         Widget w,
12552         XmTextPosition first,
12553         XmTextPosition last,
12554         Time sel_time )
12555 #endif /* _NO_PROTO */
12556 {
12557   XmDataFieldWidget tf = (XmDataFieldWidget) w;
12558 
12559   _XmWidgetToAppContext(w);
12560   _XmAppLock(app);
12561 
12562   _XmDataFieldStartSelection(tf, first, last, sel_time);
12563   XmTextF_pending_off(tf) = False;
12564   df_SetCursorPosition(tf, NULL, last, True, True, False);
12565 
12566   _XmAppUnlock(app);
12567 }
12568 
12569 /* ARGSUSED */
12570 XmTextPosition
12571 #ifdef _NO_PROTO
XmDataFieldXYToPos(w,x,y)12572 XmDataFieldXYToPos( w, x, y )
12573         Widget w ;
12574         Position x ;
12575         Position y ;
12576 #else
12577 XmDataFieldXYToPos(
12578         Widget w,
12579         Position x,
12580         Position y )
12581 #endif /* _NO_PROTO */
12582 {
12583     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12584     XmTextPosition ret_val;
12585 
12586   _XmWidgetToAppContext(w);
12587   _XmAppLock(app);
12588 
12589     ret_val = df_GetPosFromX(tf, x);
12590 
12591     _XmAppUnlock(app);
12592     return(ret_val);
12593 }
12594 
12595 Boolean
12596 #ifdef _NO_PROTO
XmDataFieldPosToXY(w,position,x,y)12597 XmDataFieldPosToXY( w, position, x, y )
12598      Widget w ;
12599      XmTextPosition position ;
12600      Position *x ;
12601      Position *y ;
12602 #else
12603 XmDataFieldPosToXY(
12604 		   Widget w,
12605 		   XmTextPosition position,
12606 		   Position *x,
12607 		   Position *y )
12608 #endif /* _NO_PROTO */
12609 {
12610   XmDataFieldWidget tf = (XmDataFieldWidget) w;
12611   Boolean ret_val;
12612 
12613   _XmWidgetToAppContext(w);
12614   _XmAppLock(app);
12615 
12616   ret_val = df_GetXYFromPos(tf, position, x, y);
12617 
12618   _XmAppUnlock(app);
12619   return(ret_val);
12620 }
12621 
12622 /*
12623  * Force the given position to be displayed.  If position < 0, then don't force
12624  * any position to be displayed.
12625  */
12626 void
12627 #ifdef _NO_PROTO
XmDataFieldShowPosition(w,position)12628 XmDataFieldShowPosition( w, position )
12629         Widget w ;
12630         XmTextPosition position ;
12631 #else
12632 XmDataFieldShowPosition(
12633         Widget w,
12634         XmTextPosition position )
12635 #endif /* _NO_PROTO */
12636 {
12637   XmDataFieldWidget tf = (XmDataFieldWidget) w;
12638 
12639   _XmWidgetToAppContext(w);
12640   _XmAppLock(app);
12641 
12642   if (position < 0) {
12643     _XmAppUnlock(app);
12644     return;
12645   }
12646 
12647   df_AdjustText(tf, position, True);
12648 
12649   _XmAppUnlock(app);
12650 }
12651 
12652 /* ARGSUSED */
12653 void
12654 #ifdef _NO_PROTO
XmDataFieldSetHighlight(w,left,right,mode)12655 XmDataFieldSetHighlight( w, left, right, mode )
12656         Widget w ;
12657         XmTextPosition left ;
12658         XmTextPosition right ;
12659         XmHighlightMode mode ;
12660 #else
12661 XmDataFieldSetHighlight(
12662         Widget w,
12663         XmTextPosition left,
12664         XmTextPosition right,
12665         XmHighlightMode mode )
12666 #endif /* _NO_PROTO */
12667 {
12668     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12669 
12670     _XmWidgetToAppContext(w);
12671     _XmAppLock(app);
12672 
12673     if (left >= right || right <= 0) {
12674       _XmAppUnlock(app);
12675       return;
12676     }
12677 
12678     if (left < 0) left = 0;
12679 
12680     if (right > XmTextF_string_length(tf))
12681     {
12682 	right = XmTextF_string_length(tf);
12683     }
12684 
12685     DataFieldSetHighlight(tf, left, right, mode);
12686 
12687     df_RedisplayText(tf, left, right);
12688     _XmAppUnlock(app);
12689 }
12690 
12691 /* ARGSUSED */
12692 static Boolean
12693 #ifdef _NO_PROTO
DataFieldGetBaselines(w,baselines,line_count)12694 DataFieldGetBaselines( w, baselines, line_count )
12695         Widget w ;
12696         Dimension ** baselines;
12697         int *line_count;
12698 #else
12699 DataFieldGetBaselines(
12700         Widget w,
12701         Dimension ** baselines,
12702         int *line_count )
12703 #endif /* _NO_PROTO */
12704 {
12705     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12706     Dimension *base_array;
12707 
12708     _XmWidgetToAppContext(w);
12709     _XmAppLock(app);
12710 
12711     *line_count = 1;
12712     base_array = (Dimension *) XtMalloc(sizeof(Dimension));
12713     base_array[0] = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
12714 	tf->primitive.highlight_thickness + XmTextF_font_ascent(tf);
12715 
12716     *baselines = base_array;
12717 
12718     _XmAppUnlock(app);
12719     return (TRUE);
12720 }
12721 
12722 int
12723 #ifdef _NO_PROTO
XmDataFieldGetBaseline(w)12724 XmDataFieldGetBaseline( w )
12725         Widget w ;
12726 #else
12727 XmDataFieldGetBaseline(
12728         Widget w )
12729 #endif /* _NO_PROTO */
12730 {
12731     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12732     Dimension margin_top;
12733     int ret_val;
12734 
12735     _XmWidgetToAppContext(w);
12736     _XmAppLock(app);
12737 
12738     margin_top = XmTextF_margin_top(tf) +
12739 	tf->primitive.shadow_thickness +
12740 	tf->primitive.highlight_thickness;
12741 
12742     ret_val = (int) margin_top + (int) XmTextF_font_ascent(tf);
12743 
12744     _XmAppUnlock(app);
12745     return(ret_val);
12746 }
12747 
12748 static Boolean
12749 #ifdef _NO_PROTO
DataFieldGetDisplayRect(w,display_rect)12750 DataFieldGetDisplayRect( w, display_rect )
12751         Widget w;
12752         XRectangle * display_rect;
12753 #else
12754 DataFieldGetDisplayRect(
12755         Widget w,
12756         XRectangle * display_rect )
12757 #endif /* _NO_PROTO */
12758 {
12759    XmDataFieldWidget tf = (XmDataFieldWidget) w;
12760 
12761    Position margin_width = XmTextF_margin_width(tf) +
12762 	               	   tf->primitive.shadow_thickness +
12763 		       	   tf->primitive.highlight_thickness;
12764    Position margin_top = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
12765                        	 tf->primitive.highlight_thickness;
12766    Position margin_bottom = XmTextF_margin_bottom(tf) +
12767 			    tf->primitive.shadow_thickness +
12768                        	    tf->primitive.highlight_thickness;
12769    (*display_rect).x = margin_width;
12770    (*display_rect).y = margin_top;
12771    (*display_rect).width = tf->core.width - (2 * margin_width);
12772    (*display_rect).height = tf->core.height - (margin_top + margin_bottom);
12773 
12774    return(TRUE);
12775 }
12776 
12777 
12778 /* ARGSUSED */
12779 static void
12780 #ifdef _NO_PROTO
DataFieldMarginsProc(w,margins_rec)12781 DataFieldMarginsProc( w, margins_rec )
12782         Widget w ;
12783         XmBaselineMargins *margins_rec;
12784 #else
12785 DataFieldMarginsProc(
12786         Widget w,
12787         XmBaselineMargins *margins_rec )
12788 #endif /* _NO_PROTO */
12789 {
12790     XmDataFieldWidget tf = (XmDataFieldWidget) w;
12791 
12792     if (margins_rec->get_or_set == XmBASELINE_SET) {
12793        XmTextF_margin_top(tf) = margins_rec->margin_top;
12794        XmTextF_margin_bottom(tf) = margins_rec->margin_bottom;
12795     } else {
12796        margins_rec->margin_top = XmTextF_margin_top(tf);
12797        margins_rec->margin_bottom = XmTextF_margin_bottom(tf);
12798        margins_rec->text_height = XmTextF_font_ascent(tf) + XmTextF_font_descent(tf);
12799        margins_rec->shadow = tf->primitive.shadow_thickness;
12800        margins_rec->highlight = tf->primitive.highlight_thickness;
12801     }
12802 }
12803 
12804 /*
12805  * Text Field w creation convienence routine.
12806  */
12807 
12808 Widget
12809 #ifdef _NO_PROTO
XmCreateDataField(parent,name,arglist,argcount)12810 XmCreateDataField( parent, name, arglist, argcount )
12811         Widget parent ;
12812         char *name ;
12813         ArgList arglist ;
12814         Cardinal argcount ;
12815 #else
12816 XmCreateDataField(
12817         Widget parent,
12818         char *name,
12819         ArgList arglist,
12820         Cardinal argcount )
12821 #endif /* _NO_PROTO */
12822 {
12823     return (XtCreateWidget(name, xmDataFieldWidgetClass,
12824                            parent, arglist, argcount));
12825 }
12826 
12827 Widget
XmVaCreateDataField(Widget parent,char * name,...)12828 XmVaCreateDataField(
12829         Widget parent,
12830         char *name,
12831         ...)
12832 {
12833     register Widget w;
12834     va_list var;
12835     int count;
12836 
12837     Va_start(var,name);
12838     count = XmeCountVaListSimple(var);
12839     va_end(var);
12840 
12841 
12842     Va_start(var, name);
12843     w = XmeVLCreateWidget(name,
12844                          xmDataFieldWidgetClass,
12845                          parent, False,
12846                          var, count);
12847     va_end(var);
12848     return w;
12849 }
12850 
12851 Widget
XmVaCreateManagedDataField(Widget parent,char * name,...)12852 XmVaCreateManagedDataField(
12853         Widget parent,
12854         char *name,
12855         ...)
12856 {
12857     Widget w = NULL;
12858     va_list var;
12859     int count;
12860 
12861     Va_start(var, name);
12862     count = XmeCountVaListSimple(var);
12863     va_end(var);
12864 
12865     Va_start(var, name);
12866     w = XmeVLCreateWidget(name,
12867                          xmDataFieldWidgetClass,
12868                          parent, True,
12869                          var, count);
12870     va_end(var);
12871     return w;
12872 }
12873