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