1
/* $XConsortium: TextFunc.c /main/16 1996/11/19 12:37:29 drk $ */
3
* @OPENGROUP_COPYRIGHT@
5
* Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
6
* Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
7
* ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
8
* the full copyright text.
10
* This software is subject to an open license. It may only be
11
* used on, with or for operating systems which are themselves open
12
* source systems. You must contact The Open Group for a license
13
* allowing distribution and sublicensing of this software on, with,
14
* or for operating systems which are not Open Source programs.
16
* See http://www.opengroup.org/openmotif/license for full
17
* details of the license agreement. Any use, reproduction, or
18
* distribution of the program constitutes recipient's acceptance of
21
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
22
* PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23
* KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
24
* WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
25
* OR FITNESS FOR A PARTICULAR PURPOSE
27
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
28
* NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
29
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
31
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
* ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
34
* EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
35
* POSSIBILITY OF SUCH DAMAGES.
39
* (c) Copyright 1995 FUJITSU LIMITED
40
* This is source code modified by FUJITSU LIMITED under the Joint
41
* Development Agreement for the CDEnext PST.
42
* This is unpublished proprietary source code of FUJITSU LIMITED
51
#include <Xm/TextStrSoP.h>
56
#include "TextStrSoI.h"
58
/****************************************************************
60
* Public definitions with TextField calls.
62
****************************************************************/
65
XmTextGetLastPosition(Widget widget)
67
XmTextPosition ret_val;
68
_XmWidgetToAppContext(widget);
71
if (XmIsTextField(widget)){
72
XmTextFieldWidget tf = (XmTextFieldWidget) widget;
74
ret_val = tf->text.string_length;
78
source = GetSrc(widget);
79
ret_val = (*source->Scan)(source, 0, XmSELECT_ALL, XmsdRight, 1, TRUE);
86
_XmTextReplace(Widget widget,
87
XmTextPosition frompos,
90
#if NeedWidePrototypes
94
#endif /* NeedWidePrototypes */
96
XmTextWidget tw = (XmTextWidget) widget;
98
XmTextBlockRec block, newblock;
99
Boolean editable, freeBlock;
100
Boolean need_free = False;
104
XmTextPosition selleft, selright, cursorPos;
105
char * tmp_block = NULL;
109
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
111
if ((*source->GetSelection)(tw->text.source, &selleft, &selright)) {
112
if ((selleft > frompos && selleft < topos) ||
113
(selright >frompos && selright < topos) ||
114
(selleft <= frompos && selright >= topos)) {
115
(*source->SetSelection)(tw->text.source, tw->text.cursor_position,
116
tw->text.cursor_position,
117
XtLastTimestampProcessed(XtDisplay(widget)));
118
if (tw->text.input->data->pendingdelete)
119
tw->text.pendingoff = FALSE;
123
block.format = XmFMT_8_BIT;
128
block.length = strlen(value);
130
} else { /* value is really a wchar_t ptr cast to char* */
134
for (tmp_wc = (wchar_t*)value, num_chars = 0;
135
*tmp_wc != (wchar_t)0L;
136
num_chars++) tmp_wc++;
137
tmp_block = XtMalloc((unsigned)
138
(num_chars + 1) * (int)tw->text.char_size);
139
block.ptr = tmp_block;
141
tmp_wc = (wchar_t *) value;
142
/* if successful, wcstombs returns number of bytes, else -1 */
143
block.length = wcstombs(block.ptr, tmp_wc,
144
(num_chars + 1) * (int)tw->text.char_size);
145
if (block.length == -1) {
146
block.length = 0; /* if error, don't insert anything */
147
block.ptr[0] = '\0'; /* use the empty string */
151
editable = _XmStringSourceGetEditable(source);
152
max_length = _XmStringSourceGetMaxLength(source);
154
_XmStringSourceSetEditable(source, TRUE);
155
_XmStringSourceSetMaxLength(source, INT_MAX);
156
if (_XmTextModifyVerify(tw, NULL, &frompos, &topos,
157
&cursorPos, &block, &newblock, &freeBlock)) {
158
(*source->Replace)(tw, NULL, &frompos, &topos, &newblock, False);
159
if (frompos == tw->text.cursor_position && frompos == topos) {
160
_XmTextSetCursorPosition((Widget)tw, cursorPos);
162
_XmTextValueChanged(tw, NULL);
163
if (UnderVerifyPreedit(tw))
164
if (newblock.length != block.length ||
165
strncmp(newblock.ptr, block.ptr, block.length) != 0) {
166
VerifyCommitNeeded(tw) = True;
167
PreEndTW(tw) += _XmTextCountCharacters(newblock.ptr, newblock.length)
168
- _XmTextCountCharacters(block.ptr, block.length);
171
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
174
if (UnderVerifyPreedit(tw)) {
175
VerifyCommitNeeded(tw) = True;
176
PreEndTW(tw) -= _XmTextCountCharacters(block.ptr, block.length);
181
_XmStringSourceSetEditable(source, editable);
182
_XmStringSourceSetMaxLength(source, max_length);
184
if (tw->text.input->data->has_destination)
185
_XmTextSetDestinationSelection(widget, tw->text.cursor_position,
186
False, XtLastTimestampProcessed(XtDisplay(widget)));
187
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
192
XmTextReplace(Widget widget,
193
XmTextPosition frompos,
194
XmTextPosition topos,
197
if (XmIsTextField(widget))
198
XmTextFieldReplace(widget, frompos, topos, value);
200
_XmWidgetToAppContext(widget);
203
_XmTextReplace(widget, frompos, topos, value, False);
209
XmTextReplaceWcs(Widget widget,
210
XmTextPosition frompos,
211
XmTextPosition topos,
214
if (XmIsTextField(widget))
215
XmTextFieldReplaceWcs(widget, frompos, topos, (wchar_t*) value);
217
_XmWidgetToAppContext(widget);
220
_XmTextReplace(widget, frompos, topos, (char*) value, True);
226
XmTextInsert(Widget widget,
227
XmTextPosition position,
230
XmTextReplace(widget, position, position, value);
235
XmTextInsertWcs(Widget widget,
236
XmTextPosition position,
239
XmTextReplaceWcs(widget, position, position, wc_value);
244
XmTextSetAddMode(Widget widget,
245
#if NeedWidePrototypes
249
#endif /* NeedWidePrototypes */
251
if (XmIsTextField(widget))
252
XmTextFieldSetAddMode(widget, state);
254
XmTextWidget tw = (XmTextWidget) widget;
255
_XmWidgetToAppContext(widget);
258
if (tw->text.add_mode == state) {
263
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
264
tw->text.add_mode = state;
265
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
271
XmTextGetAddMode(Widget widget)
274
_XmWidgetToAppContext(widget);
277
if (XmIsTextField(widget)){
278
XmTextFieldWidget tf = (XmTextFieldWidget) widget;
279
ret_val = tf->text.add_mode;
281
XmTextWidget tw = (XmTextWidget) widget;
282
ret_val = tw->text.add_mode;
289
XmTextGetEditable(Widget widget)
292
_XmWidgetToAppContext(widget);
295
if (XmIsTextField(widget))
296
ret_val = TextF_Editable(widget);
298
ret_val = _XmStringSourceGetEditable(GetSrc(widget));
305
XmTextSetEditable(Widget widget,
306
#if NeedWidePrototypes
310
#endif /* NeedWidePrototypes */
312
if (XmIsTextField(widget))
313
XmTextFieldSetEditable(widget, editable);
315
_XmWidgetToAppContext(widget);
318
_XmTextSetEditable(widget, editable);
324
XmTextGetMaxLength(Widget widget)
327
_XmWidgetToAppContext(widget);
330
if (XmIsTextField(widget))
331
ret_val = TextF_MaxLength(widget);
333
ret_val = _XmStringSourceGetMaxLength(GetSrc(widget));
340
XmTextSetMaxLength(Widget widget,
343
_XmWidgetToAppContext(widget);
346
if (XmIsTextField(widget))
347
TextF_MaxLength(widget) = max_length;
349
XmTextWidget tw = (XmTextWidget) widget;
351
tw->text.max_length = max_length;
352
_XmStringSourceSetMaxLength(GetSrc(tw), max_length);
359
XmTextGetInsertionPosition(Widget widget)
361
XmTextPosition ret_val;
362
_XmWidgetToAppContext(widget);
365
if (XmIsTextField(widget))
366
ret_val = TextF_CursorPosition(widget);
368
XmTextWidget tw = (XmTextWidget) widget;
370
ret_val = tw->text.cursor_position;
377
XmTextSetInsertionPosition(Widget widget,
378
XmTextPosition position)
380
XmTextWidget tw = (XmTextWidget) widget;
382
if (XmIsTextField(widget))
383
XmTextFieldSetInsertionPosition(widget, position);
385
_XmWidgetToAppContext(widget);
388
_XmTextResetIC(widget);
389
_XmTextSetCursorPosition(widget, position);
391
_XmTextSetDestinationSelection(widget, tw->text.cursor_position,
392
False, XtLastTimestampProcessed(XtDisplay(widget)));
399
XmTextRemove(Widget widget)
401
if (XmIsTextField(widget))
402
return(XmTextFieldRemove(widget));
404
XmTextWidget tw = (XmTextWidget) widget;
406
XmTextPosition left, right;
407
_XmWidgetToAppContext(widget);
410
if (tw->text.editable == False) {
415
source = tw->text.source;
416
_XmTextResetIC(widget);
417
if (!(*source->GetSelection)(source, &left, &right) ||
419
tw->text.input->data->anchor = tw->text.cursor_position;
424
XmTextReplace(widget, left, right, NULL);
426
if (tw->text.cursor_position > left)
427
_XmTextSetCursorPosition(widget, left);
429
tw->text.input->data->anchor = tw->text.cursor_position;
437
XmTextCopy(Widget widget,
440
Boolean result = False;
441
XmTextPosition left, right;
442
_XmWidgetToAppContext(widget);
445
if (XmTextGetSelectionPosition(widget, &left, &right) && right != left)
446
/* start copy to clipboard */
447
result = XmeClipboardSource(widget, XmCOPY, copy_time);
454
XmTextCopyLink(Widget widget,
457
Boolean result = False;
458
XmTextPosition left, right;
459
_XmWidgetToAppContext(widget);
462
if (XmTextGetSelectionPosition(widget, &left, &right) && right != left)
463
/* start copy to clipboard */
464
result = XmeClipboardSource(widget, XmLINK, copy_time);
471
XmTextCut(Widget widget,
474
Boolean result = False;
475
XmTextPosition left, right;
476
_XmWidgetToAppContext(widget);
479
/* can't cut if you can't edit */
480
if (XmTextGetEditable(widget) &&
481
XmTextGetSelectionPosition(widget, &left, &right) &&
483
/* start copy to clipboard */
484
result = XmeClipboardSource(widget, XmMOVE, cut_time);
492
* Retrieves the current data from the clipboard
493
* and paste it at the current cursor position
496
XmTextPaste(Widget widget)
500
_XmWidgetToAppContext(widget);
503
_XmTextResetIC(widget);
504
data = ((XmTextWidget) widget)->text.input->data;
506
data->selectionMove = FALSE;
507
data->selectionLink = FALSE;
508
status = XmeClipboardSink(widget, XmCOPY, NULL);
514
* Retrieves the current data from the clipboard
515
* and paste it at the current cursor position
518
XmTextPasteLink(Widget widget)
523
_XmWidgetToAppContext(widget);
526
data = ((XmTextWidget) widget)->text.input->data;
528
data->selectionMove = FALSE;
529
data->selectionLink = True;
530
status = XmeClipboardSink(widget, XmLINK, NULL);
536
XmTextGetSelection(Widget widget)
538
if (XmIsTextField(widget))
539
return(XmTextFieldGetSelection(widget));
542
XmTextPosition left, right;
544
_XmWidgetToAppContext(widget);
547
source = GetSrc(widget);
548
if ((!(*source->GetSelection)(source, &left, &right)) || right == left)
554
ret_val = _XmStringSourceGetString((XmTextWidget)widget, left,
562
XmTextGetSelectionWcs(Widget widget)
564
if (XmIsTextField(widget))
565
return(XmTextFieldGetSelectionWcs(widget));
568
XmTextPosition left, right;
570
_XmWidgetToAppContext(widget);
573
source = GetSrc(widget);
574
if (!(*source->GetSelection)(source, &left, &right)) {
579
ret_val = (wchar_t *)_XmStringSourceGetString((XmTextWidget)widget,
589
XmTextSetSelection(Widget widget,
590
XmTextPosition first,
594
if (XmIsTextField(widget))
595
XmTextFieldSetSelection(widget, first, last, set_time);
598
XmTextWidget tw = (XmTextWidget) widget;
599
_XmWidgetToAppContext(widget);
602
_XmTextResetIC(widget);
603
if (first < 0 || last > tw->text.last_position) {
608
source = GetSrc(widget);
609
source->data->take_selection = True;
610
(*source->SetSelection)(source, first, last, set_time);
611
tw->text.pendingoff = FALSE;
612
_XmTextSetCursorPosition(widget, last);
613
_XmTextSetDestinationSelection(widget, tw->text.cursor_position, False,
620
XmTextClearSelection(Widget widget,
623
if (XmIsTextField(widget))
624
XmTextFieldClearSelection(widget, clear_time);
626
XmTextWidget tw = (XmTextWidget) widget;
627
XmTextSource source = GetSrc(widget);
628
_XmWidgetToAppContext(widget);
631
(*source->SetSelection)(source, 1, -999, source->data->prim_time);
632
if (tw->text.input->data->pendingdelete) {
633
tw->text.pendingoff = FALSE;
640
XmTextGetSelectionPosition(Widget widget,
641
XmTextPosition *left,
642
XmTextPosition *right)
645
_XmWidgetToAppContext(widget);
648
if (XmIsTextField(widget)) {
649
XmTextFieldWidget tf = (XmTextFieldWidget) widget;
651
if (!tf->text.has_primary) {
654
*left = tf->text.prim_pos_left;
655
*right = tf->text.prim_pos_right;
659
XmTextWidget tw = (XmTextWidget) widget;
660
ret_val = (*tw->text.source->GetSelection)(tw->text.source, left, right);
668
XmTextXYToPos(Widget widget,
669
#if NeedWidePrototypes
675
#endif /* NeedWidePrototypes */
677
if (XmIsTextField(widget))
678
return(XmTextFieldXYToPos(widget, x, y));
680
XmTextWidget tw = (XmTextWidget) widget;
681
XmTextPosition ret_val;
682
_XmWidgetToAppContext(widget);
685
ret_val = (*tw->text.output->XYToPos)(tw, x, y);
692
XmTextPosToXY(Widget widget,
693
XmTextPosition position,
697
if (XmIsTextField(widget))
698
return(XmTextFieldPosToXY(widget, position, x, y));
700
XmTextWidget tw = (XmTextWidget) widget;
702
_XmWidgetToAppContext(widget);
705
ret_val = (*tw->text.output->PosToXY)(tw, position, x, y);
712
* Force the given position to be displayed. If position < 0, then don't force
713
* any position to be displayed.
717
XmTextShowPosition(Widget widget,
718
XmTextPosition position)
720
if (XmIsTextField(widget))
721
XmTextFieldShowPosition(widget, position);
723
_XmWidgetToAppContext(widget);
726
_XmTextShowPosition(widget, position);
732
XmTextGetBaseline(Widget widget)
734
_XmWidgetToAppContext(widget);
737
if (XmIsTextField(widget)) {
738
XmTextFieldWidget tf = (XmTextFieldWidget) widget;
739
Dimension margin_top;
742
if(XmDirectionMatch(XmPrim_layout_direction(tf),
743
XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
748
margin_top = tf->text.margin_top +
749
tf->primitive.shadow_thickness +
750
tf->primitive.highlight_thickness;
752
ret_val = (int) margin_top + (int) TextF_FontAscent(tf);
756
Dimension *baselines;
759
XmPrimitiveClassExt *wcePtr;
760
XmTextWidget tw = (XmTextWidget) widget;
762
if(XmDirectionMatch(XmPrim_layout_direction(tw),
763
XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
768
wcePtr = _XmGetPrimitiveClassExtPtr(XtClass(widget), NULLQUARK);
770
if (*wcePtr && (*wcePtr)->widget_baseline)
771
(void) (*(*wcePtr)->widget_baseline)(widget, &baselines, &line_count);
774
temp_bl = (int) baselines[0];
778
XtFree((char *) baselines);
785
XmTextGetCenterline(Widget widget)
787
Dimension *baselines;
790
XmPrimitiveClassExt *wcePtr;
791
XmTextWidget tw = (XmTextWidget) widget;
793
_XmWidgetToAppContext(widget);
797
if (!XmDirectionMatch(XmPrim_layout_direction(tw),
798
XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
803
wcePtr = _XmGetPrimitiveClassExtPtr(XtClass(widget), NULLQUARK);
805
if (*wcePtr && (*wcePtr)->widget_baseline)
806
(void) (*(*wcePtr)->widget_baseline)(widget, &baselines, &line_count);
809
temp_bl = (int) baselines[0];
813
XtFree((char *) baselines);
819
XmTextSetHighlight(Widget w,
821
XmTextPosition right,
822
XmHighlightMode mode)
824
if (XmIsTextField(w)) {
825
XmTextFieldSetHighlight(w, left, right, mode);
827
_XmWidgetToAppContext(w);
830
_XmTextSetHighlight(w, left, right, mode);
836
_XmTextGetSubstring(Widget widget,
837
XmTextPosition start,
841
#if NeedWidePrototypes
845
#endif /* NeedWidePrototypes */
847
XmTextWidget tw = (XmTextWidget) widget;
848
XmTextBlockRec block;
849
XmTextPosition pos, end;
850
wchar_t * wc_buffer = (wchar_t*)buffer;
853
end = start + num_chars;
855
num_chars = 0; /* We're done with the value passed in, so let's
856
* re-use it when needed for the wchar functionality
857
* instead of creating a local automatic variable.
860
for (pos = start; pos < end;) {
861
pos = (*tw->text.source->ReadSource)(tw->text.source, pos, end,
863
if (block.length == 0) {
865
buffer[destpos] = '\0';
867
wc_buffer[destpos] = (wchar_t)0L;
868
return XmCOPY_TRUNCATED;
872
if (((destpos + block.length) * sizeof(char)) >= buf_size)
873
return XmCOPY_FAILED;
874
} else { /* Need number of characters for buffer comparison */
875
num_chars = _XmTextCountCharacters(block.ptr, block.length);
876
if (((destpos + num_chars) * sizeof(char)) >= buf_size)
877
return XmCOPY_FAILED;
881
(void)memcpy((void*)&buffer[destpos], (void*)block.ptr,
883
destpos += block.length;
884
} else { /* want wchar_t* data */
885
num_chars = mbstowcs(&wc_buffer[destpos], block.ptr, num_chars);
886
if (num_chars < 0) num_chars = 0;
887
destpos += num_chars;
892
buffer[destpos] = '\0';
894
wc_buffer[destpos] = (wchar_t)0L;
896
return XmCOPY_SUCCEEDED;
900
XmTextGetSubstring(Widget widget,
901
XmTextPosition start,
906
if (XmIsTextField(widget))
907
return (XmTextFieldGetSubstring(widget, start, num_chars,
911
_XmWidgetToAppContext(widget);
914
ret_val =_XmTextGetSubstring(widget, start, num_chars, buf_size,
922
XmTextGetSubstringWcs(Widget widget,
923
XmTextPosition start,
928
if (XmIsTextField(widget))
929
return (XmTextFieldGetSubstringWcs(widget, start, num_chars,
933
_XmWidgetToAppContext(widget);
936
ret_val =_XmTextGetSubstring(widget, start, num_chars, buf_size,
937
(char*) buffer, True);