1 /* $XConsortium: TextFunc.c /main/16 1996/11/19 12:37:29 drk $ */
2 /*
3  * Motif
4  *
5  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
6  *
7  * These libraries and programs are free software; you can
8  * redistribute them and/or modify them under the terms of the GNU
9  * Lesser General Public License as published by the Free Software
10  * Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  *
13  * These libraries and programs are distributed in the hope that
14  * they will be useful, but WITHOUT ANY WARRANTY; without even the
15  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16  * PURPOSE. See the GNU Lesser General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with these librararies and programs; if not, write
21  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
22  * Floor, Boston, MA 02110-1301 USA
23  *
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 
31 #include <Xm/XmosP.h>
32 #include <Xm/TextStrSoP.h>
33 #include "XmI.h"
34 #include "TextFI.h"
35 #include "TextI.h"
36 #include "TextInI.h"
37 #include "TextStrSoI.h"
38 
39 /****************************************************************
40  *
41  * Public definitions with TextField calls.
42  *
43  ****************************************************************/
44 
45 XmTextPosition
XmTextGetLastPosition(Widget widget)46 XmTextGetLastPosition(Widget widget)
47 {
48   XmTextPosition ret_val;
49   _XmWidgetToAppContext(widget);
50 
51   _XmAppLock(app);
52   if (XmIsTextField(widget)){
53     XmTextFieldWidget tf = (XmTextFieldWidget) widget;
54 
55     ret_val = tf->text.string_length;
56   } else {
57     XmTextSource source;
58 
59     source = GetSrc(widget);
60     ret_val = (*source->Scan)(source, 0, XmSELECT_ALL, XmsdRight, 1, TRUE);
61   }
62   _XmAppUnlock(app);
63   return ret_val;
64 }
65 
66 void
_XmTextReplace(Widget widget,XmTextPosition frompos,XmTextPosition topos,char * value,int is_wchar)67 _XmTextReplace(Widget widget,
68 	       XmTextPosition frompos,
69 	       XmTextPosition topos,
70 	       char *value,
71 #if NeedWidePrototypes
72 	       int is_wchar)
73 #else
74                Boolean is_wchar)
75 #endif /* NeedWidePrototypes */
76 {
77   XmTextWidget tw = (XmTextWidget) widget;
78   XmTextSource source;
79   XmTextBlockRec block, newblock;
80   Boolean editable, freeBlock;
81   Boolean need_free = False;
82   int max_length;
83   int num_chars;
84   wchar_t * tmp_wc;
85   XmTextPosition selleft, selright, cursorPos;
86   char * tmp_block = NULL;
87 
88   source = GetSrc(tw);
89 
90   (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
91 
92   if ((*source->GetSelection)(tw->text.source, &selleft, &selright)) {
93     if ((selleft > frompos && selleft < topos)  ||
94 	(selright >frompos && selright < topos) ||
95 	(selleft <= frompos && selright >= topos)) {
96       (*source->SetSelection)(tw->text.source, tw->text.cursor_position,
97 			      tw->text.cursor_position,
98 			      XtLastTimestampProcessed(XtDisplay(widget)));
99       if (tw->text.input->data->pendingdelete)
100 	tw->text.pendingoff = FALSE;
101     }
102   }
103 
104   block.format = XmFMT_8_BIT;
105   if (!is_wchar) {
106     if (value == NULL)
107       block.length = 0;
108     else
109       block.length = strlen(value);
110     block.ptr = value;
111   } else { /* value is really a wchar_t ptr cast to char* */
112     if (value == NULL) {
113       block.length = 0;
114     } else {
115       for (tmp_wc = (wchar_t*)value, num_chars = 0;
116 	   *tmp_wc != (wchar_t)0L;
117 	   num_chars++) tmp_wc++;
118       tmp_block = XtMalloc((unsigned)
119 			   (num_chars + 1) * (int)tw->text.char_size);
120       block.ptr = tmp_block;
121       need_free = True;
122       tmp_wc = (wchar_t *) value;
123       /* if successful, wcstombs returns number of bytes, else -1 */
124       block.length = wcstombs(block.ptr, tmp_wc,
125 			      (num_chars + 1) * (int)tw->text.char_size);
126       if (block.length == -1) {
127 	block.length = 0; /* if error, don't insert anything */
128 	block.ptr[0] = '\0'; /* use the empty string */
129       }
130     }
131   }
132   editable = _XmStringSourceGetEditable(source);
133   max_length = _XmStringSourceGetMaxLength(source);
134 
135   _XmStringSourceSetEditable(source, TRUE);
136   _XmStringSourceSetMaxLength(source, INT_MAX);
137   if (_XmTextModifyVerify(tw, NULL, &frompos, &topos,
138 			  &cursorPos, &block, &newblock, &freeBlock)) {
139     (*source->Replace)(tw, NULL, &frompos, &topos, &newblock, False);
140     if (frompos == tw->text.cursor_position && frompos == topos) {
141       _XmTextSetCursorPosition((Widget)tw, cursorPos);
142     }
143     _XmTextValueChanged(tw, NULL);
144     if (UnderVerifyPreedit(tw))
145       if (newblock.length != block.length ||
146 	strncmp(newblock.ptr, block.ptr, block.length) != 0) {
147 	VerifyCommitNeeded(tw) = True;
148 	PreEndTW(tw) += _XmTextCountCharacters(newblock.ptr, newblock.length)
149 			- _XmTextCountCharacters(block.ptr, block.length);
150       }
151 
152     if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
153   }
154   else
155     if (UnderVerifyPreedit(tw)) {
156       VerifyCommitNeeded(tw) = True;
157       PreEndTW(tw) -= _XmTextCountCharacters(block.ptr, block.length);
158     }
159 
160   if (need_free)
161     XtFree(tmp_block);
162   _XmStringSourceSetEditable(source, editable);
163   _XmStringSourceSetMaxLength(source, max_length);
164 
165   if (tw->text.input->data->has_destination)
166     _XmTextSetDestinationSelection(widget, tw->text.cursor_position,
167 			   False, XtLastTimestampProcessed(XtDisplay(widget)));
168   (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
169 
170 }
171 
172 void
XmTextReplace(Widget widget,XmTextPosition frompos,XmTextPosition topos,char * value)173 XmTextReplace(Widget widget,
174 	      XmTextPosition frompos,
175 	      XmTextPosition topos,
176 	      char *value)
177 {
178   if (XmIsTextField(widget))
179     XmTextFieldReplace(widget, frompos, topos, value);
180   else {
181     _XmWidgetToAppContext(widget);
182 
183     _XmAppLock(app);
184     _XmTextReplace(widget, frompos, topos, value, False);
185     _XmAppUnlock(app);
186   }
187 }
188 
189 void
XmTextReplaceWcs(Widget widget,XmTextPosition frompos,XmTextPosition topos,wchar_t * value)190 XmTextReplaceWcs(Widget widget,
191 		 XmTextPosition frompos,
192 		 XmTextPosition topos,
193 		 wchar_t *value)
194 {
195   if (XmIsTextField(widget))
196     XmTextFieldReplaceWcs(widget, frompos, topos, (wchar_t*) value);
197   else {
198     _XmWidgetToAppContext(widget);
199 
200     _XmAppLock(app);
201     _XmTextReplace(widget, frompos, topos, (char*) value, True);
202     _XmAppUnlock(app);
203   }
204 }
205 
206 void
XmTextInsert(Widget widget,XmTextPosition position,char * value)207 XmTextInsert(Widget widget,
208 	     XmTextPosition position,
209 	     char *value)
210 {
211   XmTextReplace(widget, position, position, value);
212 }
213 
214 
215 void
XmTextInsertWcs(Widget widget,XmTextPosition position,wchar_t * wc_value)216 XmTextInsertWcs(Widget widget,
217 		XmTextPosition position,
218 		wchar_t *wc_value)
219 {
220   XmTextReplaceWcs(widget, position, position, wc_value);
221 }
222 
223 
224 void
XmTextSetAddMode(Widget widget,int state)225 XmTextSetAddMode(Widget widget,
226 #if NeedWidePrototypes
227 		 int state)
228 #else
229                  Boolean state)
230 #endif /* NeedWidePrototypes */
231 {
232   if (XmIsTextField(widget))
233     XmTextFieldSetAddMode(widget, state);
234   else {
235     XmTextWidget tw = (XmTextWidget) widget;
236     _XmWidgetToAppContext(widget);
237 
238     _XmAppLock(app);
239     if (tw->text.add_mode == state) {
240 	_XmAppUnlock(app);
241 	return;
242     }
243 
244     (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
245     tw->text.add_mode = state;
246     (*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
247     _XmAppUnlock(app);
248   }
249 }
250 
251 Boolean
XmTextGetAddMode(Widget widget)252 XmTextGetAddMode(Widget widget)
253 {
254   Boolean ret_val;
255   _XmWidgetToAppContext(widget);
256 
257   _XmAppLock(app);
258   if (XmIsTextField(widget)){
259     XmTextFieldWidget tf = (XmTextFieldWidget) widget;
260     ret_val = tf->text.add_mode;
261   } else {
262     XmTextWidget tw = (XmTextWidget) widget;
263     ret_val = tw->text.add_mode;
264   }
265   _XmAppUnlock(app);
266   return ret_val;
267 }
268 
269 Boolean
XmTextGetEditable(Widget widget)270 XmTextGetEditable(Widget widget)
271 {
272   Boolean ret_val;
273   _XmWidgetToAppContext(widget);
274 
275   _XmAppLock(app);
276   if (XmIsTextField(widget))
277     ret_val = TextF_Editable(widget);
278   else
279     ret_val = _XmStringSourceGetEditable(GetSrc(widget));
280 
281   _XmAppUnlock(app);
282   return ret_val;
283 }
284 
285 void
XmTextSetEditable(Widget widget,int editable)286 XmTextSetEditable(Widget widget,
287 #if NeedWidePrototypes
288 		  int editable)
289 #else
290                   Boolean editable)
291 #endif /* NeedWidePrototypes */
292 {
293   if (XmIsTextField(widget))
294     XmTextFieldSetEditable(widget, editable);
295   else {
296     _XmWidgetToAppContext(widget);
297 
298     _XmAppLock(app);
299     _XmTextSetEditable(widget, editable);
300     _XmAppUnlock(app);
301   }
302 }
303 
304 int
XmTextGetMaxLength(Widget widget)305 XmTextGetMaxLength(Widget widget)
306 {
307   int ret_val;
308   _XmWidgetToAppContext(widget);
309 
310   _XmAppLock(app);
311   if (XmIsTextField(widget))
312     ret_val = TextF_MaxLength(widget);
313   else
314     ret_val = _XmStringSourceGetMaxLength(GetSrc(widget));
315 
316   _XmAppUnlock(app);
317   return ret_val;
318 }
319 
320 void
XmTextSetMaxLength(Widget widget,int max_length)321 XmTextSetMaxLength(Widget widget,
322 		   int max_length)
323 {
324   _XmWidgetToAppContext(widget);
325 
326   _XmAppLock(app);
327   if (XmIsTextField(widget))
328     TextF_MaxLength(widget) = max_length;
329   else {
330     XmTextWidget tw = (XmTextWidget) widget;
331 
332     tw->text.max_length = max_length;
333     _XmStringSourceSetMaxLength(GetSrc(tw), max_length);
334   }
335   _XmAppUnlock(app);
336 }
337 
338 
339 XmTextPosition
XmTextGetInsertionPosition(Widget widget)340 XmTextGetInsertionPosition(Widget widget)
341 {
342   XmTextPosition ret_val;
343   _XmWidgetToAppContext(widget);
344 
345   _XmAppLock(app);
346   if (XmIsTextField(widget))
347     ret_val = TextF_CursorPosition(widget);
348   else {
349     XmTextWidget tw = (XmTextWidget) widget;
350 
351     ret_val = tw->text.cursor_position;
352   }
353   _XmAppUnlock(app);
354   return ret_val;
355 }
356 
357 void
XmTextSetInsertionPosition(Widget widget,XmTextPosition position)358 XmTextSetInsertionPosition(Widget widget,
359 			   XmTextPosition position)
360 {
361   XmTextWidget tw = (XmTextWidget) widget;
362 
363   if (XmIsTextField(widget))
364     XmTextFieldSetInsertionPosition(widget, position);
365   else {
366     _XmWidgetToAppContext(widget);
367 
368     _XmAppLock(app);
369     _XmTextResetIC(widget);
370     _XmTextSetCursorPosition(widget, position);
371 
372     _XmTextSetDestinationSelection(widget, tw->text.cursor_position,
373 		False, XtLastTimestampProcessed(XtDisplay(widget)));
374     _XmAppUnlock(app);
375   }
376 }
377 
378 
379 Boolean
XmTextRemove(Widget widget)380 XmTextRemove(Widget widget)
381 {
382   if (XmIsTextField(widget))
383     return(XmTextFieldRemove(widget));
384   else {
385     XmTextWidget tw = (XmTextWidget) widget;
386     XmTextSource source;
387     XmTextPosition left, right;
388     _XmWidgetToAppContext(widget);
389 
390     _XmAppLock(app);
391     if (tw->text.editable == False) {
392       _XmAppUnlock(app);
393       return False;
394     }
395 
396     source = tw->text.source;
397     _XmTextResetIC(widget);
398     if (!(*source->GetSelection)(source, &left, &right) ||
399 	left == right) {
400       tw->text.input->data->anchor = tw->text.cursor_position;
401       _XmAppUnlock(app);
402       return False;
403     }
404 
405     XmTextReplace(widget, left, right, NULL);
406 
407     if (tw->text.cursor_position > left)
408       _XmTextSetCursorPosition(widget, left);
409 
410     tw->text.input->data->anchor = tw->text.cursor_position;
411 
412     _XmAppUnlock(app);
413     return True;
414   }
415 }
416 
417 Boolean
XmTextCopy(Widget widget,Time copy_time)418 XmTextCopy(Widget widget,
419 	   Time copy_time)
420 {
421   Boolean result = False;
422   XmTextPosition left, right;
423   _XmWidgetToAppContext(widget);
424 
425   _XmAppLock(app);
426   if (XmTextGetSelectionPosition(widget, &left, &right) && right != left)
427     /* start copy to clipboard */
428     result = XmeClipboardSource(widget, XmCOPY, copy_time);
429   _XmAppUnlock(app);
430 
431   return result;
432 }
433 
434 Boolean
XmTextCopyLink(Widget widget,Time copy_time)435 XmTextCopyLink(Widget widget,
436 	       Time copy_time)
437 {
438   Boolean result = False;
439   XmTextPosition left, right;
440   _XmWidgetToAppContext(widget);
441 
442   _XmAppLock(app);
443   if (XmTextGetSelectionPosition(widget, &left, &right) && right != left)
444     /* start copy to clipboard */
445     result = XmeClipboardSource(widget, XmLINK, copy_time);
446   _XmAppUnlock(app);
447 
448   return result;
449 }
450 
451 Boolean
XmTextCut(Widget widget,Time cut_time)452 XmTextCut(Widget widget,
453 	  Time cut_time)
454 {
455   Boolean result = False;
456   XmTextPosition left, right;
457   _XmWidgetToAppContext(widget);
458 
459   _XmAppLock(app);
460   /* can't cut if you can't edit */
461   if (XmTextGetEditable(widget) &&
462       XmTextGetSelectionPosition(widget, &left, &right) &&
463       (right != left))
464     /* start copy to clipboard */
465     result = XmeClipboardSource(widget, XmMOVE, cut_time);
466   _XmAppUnlock(app);
467 
468   return result;
469 }
470 
471 
472 /*
473  * Retrieves the current data from the clipboard
474  * and paste it at the current cursor position
475  */
476 Boolean
XmTextPaste(Widget widget)477 XmTextPaste(Widget widget)
478 {
479   Boolean status;
480   InputData data;
481 
482   if (XmIsTextField(widget))
483     return XmTextFieldPaste(widget);
484 
485   _XmWidgetToAppContext(widget);
486 
487   _XmAppLock(app);
488   _XmTextResetIC(widget);
489   data = ((XmTextWidget) widget)->text.input->data;
490 
491   data->selectionMove = FALSE;
492   data->selectionLink = FALSE;
493   status = XmeClipboardSink(widget, XmCOPY, NULL);
494   _XmAppUnlock(app);
495   return(status);
496 }
497 
498 /*
499  * Retrieves the current data from the clipboard
500  * and paste it at the current cursor position
501  */
502 Boolean
XmTextPasteLink(Widget widget)503 XmTextPasteLink(Widget widget)
504 {
505   Boolean status;
506 
507   InputData data;
508   _XmWidgetToAppContext(widget);
509 
510   _XmAppLock(app);
511   data = ((XmTextWidget) widget)->text.input->data;
512 
513   data->selectionMove = FALSE;
514   data->selectionLink = True;
515   status = XmeClipboardSink(widget, XmLINK, NULL);
516   _XmAppUnlock(app);
517   return(status);
518 }
519 
520 char *
XmTextGetSelection(Widget widget)521 XmTextGetSelection(Widget widget)
522 {
523   if (XmIsTextField(widget))
524     return(XmTextFieldGetSelection(widget));
525   else {
526     XmTextSource source;
527     XmTextPosition left, right;
528     char *ret_val;
529     _XmWidgetToAppContext(widget);
530 
531     _XmAppLock(app);
532     source = GetSrc(widget);
533     if ((!(*source->GetSelection)(source, &left, &right)) || right == left)
534     {
535 	_XmAppUnlock(app);
536 	return NULL;
537     }
538 
539     ret_val = _XmStringSourceGetString((XmTextWidget)widget, left,
540 				    right, False);
541     _XmAppUnlock(app);
542     return ret_val;
543   }
544 }
545 
546 wchar_t *
XmTextGetSelectionWcs(Widget widget)547 XmTextGetSelectionWcs(Widget widget)
548 {
549   if (XmIsTextField(widget))
550     return(XmTextFieldGetSelectionWcs(widget));
551   else {
552     XmTextSource source;
553     XmTextPosition left, right;
554     wchar_t *ret_val;
555     _XmWidgetToAppContext(widget);
556 
557     _XmAppLock(app);
558     source = GetSrc(widget);
559     if (!(*source->GetSelection)(source, &left, &right)) {
560       _XmAppUnlock(app);
561       return NULL;
562     }
563 
564     ret_val = (wchar_t *)_XmStringSourceGetString((XmTextWidget)widget,
565 		left, right, True);
566     _XmAppUnlock(app);
567     return ret_val;
568   }
569 }
570 
571 
572 
573 void
XmTextSetSelection(Widget widget,XmTextPosition first,XmTextPosition last,Time set_time)574 XmTextSetSelection(Widget widget,
575 		   XmTextPosition first,
576 		   XmTextPosition last,
577 		   Time set_time)
578 {
579   if (XmIsTextField(widget))
580     XmTextFieldSetSelection(widget, first, last, set_time);
581   else {
582     XmTextSource source;
583     XmTextWidget tw = (XmTextWidget) widget;
584     _XmWidgetToAppContext(widget);
585 
586     _XmAppLock(app);
587     _XmTextResetIC(widget);
588     if (first < 0 || last > tw->text.last_position) {
589 	_XmAppUnlock(app);
590 	return;
591     }
592 
593     source = GetSrc(widget);
594     source->data->take_selection = True;
595     (*source->SetSelection)(source, first, last, set_time);
596     tw->text.pendingoff = FALSE;
597     _XmTextSetCursorPosition(widget, last);
598     _XmTextSetDestinationSelection(widget, tw->text.cursor_position, False,
599 				   set_time);
600     _XmAppUnlock(app);
601   }
602 }
603 
604 void
XmTextClearSelection(Widget widget,Time clear_time)605 XmTextClearSelection(Widget widget,
606 		     Time clear_time)
607 {
608   if (XmIsTextField(widget))
609     XmTextFieldClearSelection(widget, clear_time);
610   else {
611     XmTextWidget tw = (XmTextWidget) widget;
612     XmTextSource source = GetSrc(widget);
613     _XmWidgetToAppContext(widget);
614 
615     _XmAppLock(app);
616     (*source->SetSelection)(source, 1, -999, source->data->prim_time);
617     if (tw->text.input->data->pendingdelete) {
618       tw->text.pendingoff = FALSE;
619     }
620     _XmAppUnlock(app);
621   }
622 }
623 
624 Boolean
XmTextGetSelectionPosition(Widget widget,XmTextPosition * left,XmTextPosition * right)625 XmTextGetSelectionPosition(Widget widget,
626 			   XmTextPosition *left,
627 			   XmTextPosition *right)
628 {
629   Boolean ret_val;
630   _XmWidgetToAppContext(widget);
631 
632   _XmAppLock(app);
633   if (XmIsTextField(widget)) {
634     XmTextFieldWidget tf = (XmTextFieldWidget) widget;
635 
636     if (!tf->text.has_primary) {
637       ret_val = False;
638     } else {
639       *left = tf->text.prim_pos_left;
640       *right = tf->text.prim_pos_right;
641       ret_val = True;
642     }
643   } else {
644     XmTextWidget tw = (XmTextWidget) widget;
645     ret_val = (*tw->text.source->GetSelection)(tw->text.source, left, right);
646   }
647   _XmAppUnlock(app);
648 
649   return ret_val;
650 }
651 
652 XmTextPosition
XmTextXYToPos(Widget widget,int x,int y)653 XmTextXYToPos(Widget widget,
654 #if NeedWidePrototypes
655 	      int x,
656 	      int y)
657 #else
658               Position x,
659               Position y)
660 #endif /* NeedWidePrototypes */
661 {
662   if (XmIsTextField(widget))
663     return(XmTextFieldXYToPos(widget, x, y));
664   else {
665     XmTextWidget tw = (XmTextWidget) widget;
666     XmTextPosition ret_val;
667     _XmWidgetToAppContext(widget);
668 
669     _XmAppLock(app);
670     ret_val = (*tw->text.output->XYToPos)(tw, x, y);
671     _XmAppUnlock(app);
672     return ret_val;
673   }
674 }
675 
676 Boolean
XmTextPosToXY(Widget widget,XmTextPosition position,Position * x,Position * y)677 XmTextPosToXY(Widget widget,
678 	      XmTextPosition position,
679 	      Position *x,
680 	      Position *y)
681 {
682   if (XmIsTextField(widget))
683     return(XmTextFieldPosToXY(widget, position, x, y));
684   else {
685     XmTextWidget tw = (XmTextWidget) widget;
686     Boolean ret_val;
687     _XmWidgetToAppContext(widget);
688 
689     _XmAppLock(app);
690     ret_val = (*tw->text.output->PosToXY)(tw, position, x, y);
691     _XmAppUnlock(app);
692     return ret_val;
693   }
694 }
695 
696 /*
697  * Force the given position to be displayed.  If position < 0, then don't force
698  * any position to be displayed.
699  */
700 /* ARGSUSED */
701 void
XmTextShowPosition(Widget widget,XmTextPosition position)702 XmTextShowPosition(Widget widget,
703 		   XmTextPosition position)
704 {
705   if (XmIsTextField(widget))
706     XmTextFieldShowPosition(widget, position);
707   else {
708     _XmWidgetToAppContext(widget);
709 
710     _XmAppLock(app);
711     _XmTextShowPosition(widget, position);
712     _XmAppUnlock(app);
713   }
714 }
715 
716 int
XmTextGetBaseline(Widget widget)717 XmTextGetBaseline(Widget widget)
718 {
719   _XmWidgetToAppContext(widget);
720 
721   _XmAppLock(app);
722   if (XmIsTextField(widget)) {
723     XmTextFieldWidget tf = (XmTextFieldWidget) widget;
724     Dimension margin_top;
725     int ret_val;
726 
727     if(XmDirectionMatch(XmPrim_layout_direction(tf),
728 			XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
729       _XmAppUnlock(app);
730       return(0);
731     }
732 
733     margin_top = tf->text.margin_top +
734         tf->primitive.shadow_thickness +
735 	tf->primitive.highlight_thickness;
736 
737     ret_val = (int) margin_top + (int) TextF_FontAscent(tf);
738     _XmAppUnlock(app);
739     return ret_val;
740   } else {
741     Dimension *baselines;
742     int temp_bl;
743     int line_count;
744     XmPrimitiveClassExt           *wcePtr;
745     XmTextWidget tw = (XmTextWidget) widget;
746 
747     if(XmDirectionMatch(XmPrim_layout_direction(tw),
748 			XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
749       _XmAppUnlock(app);
750       return(0);
751     }
752 
753     wcePtr = _XmGetPrimitiveClassExtPtr(XtClass(widget), NULLQUARK);
754 
755     if (*wcePtr && (*wcePtr)->widget_baseline)
756       (void) (*(*wcePtr)->widget_baseline)(widget, &baselines, &line_count);
757 
758     if (line_count)
759       temp_bl = (int) baselines[0];
760     else
761       temp_bl = 0;
762 
763     XtFree((char *) baselines);
764     _XmAppUnlock(app);
765     return (temp_bl);
766   }
767 }
768 
769 int
XmTextGetCenterline(Widget widget)770 XmTextGetCenterline(Widget widget)
771 {
772   Dimension *baselines;
773   int temp_bl;
774   int line_count;
775   XmPrimitiveClassExt           *wcePtr;
776   XmTextWidget tw = (XmTextWidget) widget;
777 
778   _XmWidgetToAppContext(widget);
779 
780   _XmAppLock(app);
781 
782   if (!XmDirectionMatch(XmPrim_layout_direction(tw),
783 			XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
784     _XmAppUnlock(app);
785     return(0);
786   }
787 
788   wcePtr = _XmGetPrimitiveClassExtPtr(XtClass(widget), NULLQUARK);
789 
790   if (*wcePtr && (*wcePtr)->widget_baseline)
791     (void) (*(*wcePtr)->widget_baseline)(widget, &baselines, &line_count);
792 
793   if (line_count)
794     temp_bl = (int) baselines[0];
795   else
796     temp_bl = 0;
797 
798   XtFree((char *) baselines);
799   _XmAppUnlock(app);
800   return (temp_bl);
801 }
802 
803 void
XmTextSetHighlight(Widget w,XmTextPosition left,XmTextPosition right,XmHighlightMode mode)804 XmTextSetHighlight(Widget w,
805 		   XmTextPosition left,
806 		   XmTextPosition right,
807 		   XmHighlightMode mode)
808 {
809   if (XmIsTextField(w)) {
810     XmTextFieldSetHighlight(w, left, right, mode);
811   } else {
812     _XmWidgetToAppContext(w);
813 
814     _XmAppLock(app);
815     _XmTextSetHighlight(w, left, right, mode);
816     _XmAppUnlock(app);
817   }
818 }
819 
820 static int
_XmTextGetSubstring(Widget widget,XmTextPosition start,int num_chars,int buf_size,char * buffer,int want_wchar)821 _XmTextGetSubstring(Widget widget,
822 		    XmTextPosition start,
823 		    int num_chars,
824 		    int buf_size,
825 		    char *buffer,
826 #if NeedWidePrototypes
827 		    int want_wchar)
828 #else
829                     Boolean want_wchar)
830 #endif /* NeedWidePrototypes */
831 {
832   XmTextWidget tw = (XmTextWidget) widget;
833   XmTextBlockRec block;
834   XmTextPosition pos, end;
835   wchar_t * wc_buffer = (wchar_t*)buffer;
836   int destpos = 0;
837 
838   end = start + num_chars;
839 
840   num_chars = 0; /* We're done with the value passed in, so let's
841 		  * re-use it when needed for the wchar functionality
842 		  * instead of creating a local automatic variable.
843 		  */
844 
845   for (pos = start; pos < end;) {
846     pos = (*tw->text.source->ReadSource)(tw->text.source, pos, end,
847 					 &block);
848     if (block.length == 0) {
849       if (!want_wchar)
850 	buffer[destpos] = '\0';
851       else
852 	wc_buffer[destpos] = (wchar_t)0L;
853       return XmCOPY_TRUNCATED;
854     }
855 
856     if (!want_wchar) {
857       if (((destpos + block.length) * sizeof(char)) >= buf_size)
858 	return XmCOPY_FAILED;
859     } else { /* Need number of characters for buffer comparison */
860       num_chars = _XmTextCountCharacters(block.ptr, block.length);
861       if (((destpos + num_chars) * sizeof(char)) >= buf_size)
862 	return XmCOPY_FAILED;
863     }
864 
865     if (!want_wchar) {
866       (void)memcpy((void*)&buffer[destpos], (void*)block.ptr,
867 		   block.length);
868       destpos += block.length;
869     } else { /* want wchar_t* data */
870       num_chars = mbstowcs(&wc_buffer[destpos], block.ptr, num_chars);
871       if (num_chars < 0) num_chars = 0;
872       destpos += num_chars;
873     }
874   }
875 
876   if (!want_wchar)
877     buffer[destpos] = '\0';
878   else
879     wc_buffer[destpos] = (wchar_t)0L;
880 
881   return XmCOPY_SUCCEEDED;
882 }
883 
884 int
XmTextGetSubstring(Widget widget,XmTextPosition start,int num_chars,int buf_size,char * buffer)885 XmTextGetSubstring(Widget widget,
886 		   XmTextPosition start,
887 		   int num_chars,
888 		   int buf_size,
889 		   char *buffer)
890 {
891   if (XmIsTextField(widget))
892     return (XmTextFieldGetSubstring(widget, start, num_chars,
893 				    buf_size, buffer));
894   else {
895     int ret_val;
896     _XmWidgetToAppContext(widget);
897 
898     _XmAppLock(app);
899     ret_val =_XmTextGetSubstring(widget, start, num_chars, buf_size,
900 			       buffer, False);
901     _XmAppUnlock(app);
902     return ret_val;
903   }
904 }
905 
906 int
XmTextGetSubstringWcs(Widget widget,XmTextPosition start,int num_chars,int buf_size,wchar_t * buffer)907 XmTextGetSubstringWcs(Widget widget,
908 		      XmTextPosition start,
909 		      int num_chars,
910 		      int buf_size,
911 		      wchar_t *buffer)
912 {
913   if (XmIsTextField(widget))
914     return (XmTextFieldGetSubstringWcs(widget, start, num_chars,
915 				       buf_size, buffer));
916   else {
917     int ret_val;
918     _XmWidgetToAppContext(widget);
919 
920     _XmAppLock(app);
921     ret_val =_XmTextGetSubstring(widget, start, num_chars, buf_size,
922 			       (char*) buffer, True);
923     _XmAppUnlock(app);
924     return ret_val;
925   }
926 }
927