Bug Summary

File:TextAction.c
Location:line 1638, column 5
Description:Value stored to 'position' is never read

Annotated Source Code

1/*
2
3Copyright 1989, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H1
28#include <config.h>
29#endif
30#include <stdio.h>
31#include <stdlib.h>
32#include <X11/Xos.h> /* for select() and struct timeval */
33#include <ctype.h>
34#include <X11/IntrinsicP.h>
35#include <X11/StringDefs.h>
36#include <X11/Xatom.h>
37#include <X11/Xfuncs.h>
38#include <X11/Xutil.h>
39#include <X11/Xmu/Atoms.h>
40#include <X11/Xmu/Misc.h>
41#include <X11/Xmu/StdSel.h>
42#include <X11/Xaw/MultiSinkP.h>
43#include <X11/Xaw/MultiSrcP.h>
44#include <X11/Xaw/TextP.h>
45#include <X11/Xaw/TextSrcP.h>
46#include <X11/Xaw/XawImP.h>
47#include "Private.h"
48#include "XawI18n.h"
49
50#define SrcScanXawTextSourceScan XawTextSourceScan
51#define FindDistXawTextSinkFindDistance XawTextSinkFindDistance
52#define FindPosXawTextSinkFindPosition XawTextSinkFindPosition
53#define MULT(w)(w->text.mult == 0 ? 4 : w->text.mult == 32767 ? -4 : w
->text.mult)
(w->text.mult == 0 ? 4 : \
54 w->text.mult == 32767 ? -4 : w->text.mult)
55
56#define KILL_RING_APPEND2 2
57#define KILL_RING_BEGIN3 3
58#define KILL_RING_YANK100 100
59#define KILL_RING_YANK_DONE98 98
60
61#define XawTextActionMaxHexChars100 100
62
63/*
64 * Prototypes
65 */
66static void _DeleteOrKill(TextWidget, XawTextPosition, XawTextPosition, Boolint);
67static void _SelectionReceived(Widget, XtPointer, Atom*, Atom*, XtPointer,
68 unsigned long*, int*);
69static void _LoseSelection(Widget, Atom*, char**, int*);
70static void AutoFill(TextWidget);
71static Boolean ConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*,
72 unsigned long*, int*);
73static void DeleteOrKill(TextWidget, XEvent*, XawTextScanDirection,
74 XawTextScanType, Boolint, Boolint);
75static void EndAction(TextWidget);
76#ifndef OLDXAW
77static Boolint BlankLine(Widget, XawTextPosition, int*);
78static int DoFormatText(TextWidget, XawTextPosition, Boolint, int,
79 XawTextBlock*, XawTextPosition*, int, Boolint);
80static int FormatText(TextWidget, XawTextPosition, Boolint,
81 XawTextPosition*, int);
82static Boolint GetBlockBoundaries(TextWidget, XawTextPosition*, XawTextPosition*);
83#endif
84static int FormRegion(TextWidget, XawTextPosition, XawTextPosition,
85 XawTextPosition*, int);
86static void GetSelection(Widget, Time, String*, Cardinal);
87static char *IfHexConvertHexElseReturnParam(char*, int*);
88static void InsertNewCRs(TextWidget, XawTextPosition, XawTextPosition,
89 XawTextPosition*, int);
90static int InsertNewLineAndBackupInternal(TextWidget);
91static int LocalInsertNewLine(TextWidget, XEvent*);
92static void LoseSelection(Widget, Atom*);
93static void ParameterError(Widget, String);
94static Boolint MatchSelection(Atom, XawTextSelection*);
95static void ModifySelection(TextWidget, XEvent*, XawTextSelectionMode,
96 XawTextSelectionAction, String*, Cardinal*);
97static void Move(TextWidget, XEvent*, XawTextScanDirection, XawTextScanType,
98 Boolint);
99static void NotePosition(TextWidget, XEvent*);
100static void StartAction(TextWidget, XEvent*);
101static XawTextPosition StripOutOldCRs(TextWidget, XawTextPosition,
102 XawTextPosition, XawTextPosition*, int);
103#ifndef OLDXAW
104static Boolint StripSpaces(TextWidget, XawTextPosition, XawTextPosition,
105 XawTextPosition*, int, XawTextBlock*);
106static Boolint Tabify(TextWidget, XawTextPosition, XawTextPosition,
107 XawTextPosition*, int, XawTextBlock*);
108static Boolint Untabify(TextWidget, XawTextPosition, XawTextPosition,
109 XawTextPosition*, int, XawTextBlock*);
110#endif
111
112/*
113 * Actions
114 */
115static void CapitalizeWord(Widget, XEvent*, String*, Cardinal*);
116static void DisplayCaret(Widget, XEvent*, String*, Cardinal*);
117static void Delete(Widget, XEvent*, String*, Cardinal*);
118static void DeleteBackwardChar(Widget, XEvent*, String*, Cardinal*);
119static void DeleteBackwardWord(Widget, XEvent*, String*, Cardinal*);
120static void DeleteCurrentSelection(Widget, XEvent*, String*, Cardinal*);
121static void DeleteForwardChar(Widget, XEvent*, String*, Cardinal*);
122static void DeleteForwardWord(Widget, XEvent*, String*, Cardinal*);
123static void DowncaseWord(Widget, XEvent*, String*, Cardinal*);
124static void ExtendAdjust(Widget, XEvent*, String*, Cardinal*);
125static void ExtendEnd(Widget, XEvent*, String*, Cardinal*);
126static void ExtendStart(Widget, XEvent*, String*, Cardinal*);
127static void FormParagraph(Widget, XEvent*, String*, Cardinal*);
128#ifndef OLDXAW
129static void Indent(Widget, XEvent*, String*, Cardinal*);
130#endif
131static void InsertChar(Widget, XEvent*, String*, Cardinal*);
132static void InsertNewLine(Widget, XEvent*, String*, Cardinal*);
133static void InsertNewLineAndBackup(Widget, XEvent*, String*, Cardinal*);
134static void InsertNewLineAndIndent(Widget, XEvent*, String*, Cardinal*);
135static void InsertSelection(Widget, XEvent*, String*, Cardinal*);
136static void InsertString(Widget, XEvent*, String*, Cardinal*);
137#ifndef OLDXAW
138static void KeyboardReset(Widget, XEvent*, String*, Cardinal*);
139#endif
140static void KillBackwardWord(Widget, XEvent*, String*, Cardinal*);
141static void KillCurrentSelection(Widget, XEvent*, String*, Cardinal*);
142static void KillForwardWord(Widget, XEvent*, String*, Cardinal*);
143#ifndef OLDXAW
144static void KillRingYank(Widget, XEvent*, String*, Cardinal*);
145#endif
146static void KillToEndOfLine(Widget, XEvent*, String*, Cardinal*);
147static void KillToEndOfParagraph(Widget, XEvent*, String*, Cardinal*);
148static void MoveBackwardChar(Widget, XEvent*, String*, Cardinal*);
149static void MoveBackwardWord(Widget, XEvent*, String*, Cardinal*);
150static void MoveBackwardParagraph(Widget, XEvent*, String*, Cardinal*);
151static void MoveBeginningOfFile(Widget, XEvent*, String*, Cardinal*);
152static void MoveEndOfFile(Widget, XEvent*, String*, Cardinal*);
153static void MoveForwardChar(Widget, XEvent*, String*, Cardinal*);
154static void MoveForwardWord(Widget, XEvent*, String*, Cardinal*);
155static void MoveForwardParagraph(Widget, XEvent*, String*, Cardinal*);
156static void MoveNextLine(Widget, XEvent*, String*, Cardinal*);
157static void MoveNextPage(Widget, XEvent*, String*, Cardinal*);
158static void MovePage(TextWidget, XEvent*, XawTextScanDirection);
159static void MovePreviousLine(Widget, XEvent*, String*, Cardinal*);
160static void MovePreviousPage(Widget, XEvent*, String*, Cardinal*);
161static void MoveLine(TextWidget, XEvent*, XawTextScanDirection);
162static void MoveToLineEnd(Widget, XEvent*, String*, Cardinal*);
163static void MoveToLineStart(Widget, XEvent*, String*, Cardinal*);
164static void Multiply(Widget, XEvent*, String*, Cardinal*);
165static void NoOp(Widget, XEvent*, String*, Cardinal*);
166#ifndef OLDXAW
167static void Numeric(Widget, XEvent*, String*, Cardinal*);
168#endif
169static void Reconnect(Widget, XEvent*, String*, Cardinal*);
170static void RedrawDisplay(Widget, XEvent*, String*, Cardinal*);
171static void Scroll(TextWidget, XEvent*, XawTextScanDirection);
172static void ScrollOneLineDown(Widget, XEvent*, String*, Cardinal*);
173static void ScrollOneLineUp(Widget, XEvent*, String*, Cardinal*);
174static void SelectAdjust(Widget, XEvent*, String*, Cardinal*);
175static void SelectAll(Widget, XEvent*, String*, Cardinal*);
176static void SelectEnd(Widget, XEvent*, String*, Cardinal*);
177static void SelectSave(Widget, XEvent*, String*, Cardinal*);
178static void SelectStart(Widget, XEvent*, String*, Cardinal*);
179static void SelectWord(Widget, XEvent*, String*, Cardinal*);
180static void SetKeyboardFocus(Widget, XEvent*, String*, Cardinal*);
181static void TextEnterWindow(Widget, XEvent*, String*, Cardinal*);
182static void TextFocusIn(Widget, XEvent*, String*, Cardinal*);
183static void TextFocusOut(Widget, XEvent*, String*, Cardinal*);
184static void TextLeaveWindow(Widget, XEvent*, String*, Cardinal*);
185static void TransposeCharacters(Widget, XEvent*, String*, Cardinal*);
186#ifndef OLDXAW
187static void ToggleOverwrite(Widget, XEvent*, String*, Cardinal*);
188static void Undo(Widget, XEvent*, String*, Cardinal*);
189#endif
190static void UpcaseWord(Widget, XEvent*, String*, Cardinal*);
191static void DestroyFocusCallback(Widget, XtPointer, XtPointer);
192
193/*
194 * External
195 */
196void _XawTextZapSelection(TextWidget, XEvent*, Boolint);
197
198/*
199 * Defined in TextPop.c
200 */
201void _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*);
202void _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*);
203void _XawTextSearch(Widget, XEvent*, String*, Cardinal*);
204void _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*);
205void _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*);
206void _XawTextSetField(Widget, XEvent*, String*, Cardinal*);
207void _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*);
208
209/*
210 * These are defined in Text.c
211 */
212void _XawTextAlterSelection(TextWidget, XawTextSelectionMode,
213 XawTextSelectionAction, String*, Cardinal*);
214void _XawTextClearAndCenterDisplay(TextWidget);
215void _XawTextExecuteUpdate(TextWidget);
216char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
217void _XawTextPrepareToUpdate(TextWidget);
218int _XawTextReplace(TextWidget, XawTextPosition, XawTextPosition,
219 XawTextBlock*);
220Atom *_XawTextSelectionList(TextWidget, String*, Cardinal);
221void _XawTextSetSelection(TextWidget, XawTextPosition, XawTextPosition,
222 String*, Cardinal);
223void _XawTextVScroll(TextWidget, int);
224void XawTextScroll(TextWidget, int, int);
225void _XawTextSetLineAndColumnNumber(TextWidget, Boolint);
226
227#ifndef OLDXAW
228/*
229 * Defined in TextSrc.c
230 */
231Boolint _XawTextSrcUndo(TextSrcObject, XawTextPosition*);
232Boolint _XawTextSrcToggleUndo(TextSrcObject);
233void _XawSourceSetUndoErase(TextSrcObject, int);
234void _XawSourceSetUndoMerge(TextSrcObject, Boolint);
235#endif /* OLDXAW */
236
237/*
238 * Initialization
239 */
240#ifndef OLDXAW
241#define MAX_KILL_RINGS1024 1024
242XawTextKillRing *xaw_text_kill_ring;
243static XawTextKillRing kill_ring_prev, kill_ring_null = { &kill_ring_prev, };
244static unsigned num_kill_rings;
245#endif
246
247/*
248 * Implementation
249 */
250static void
251ParameterError(Widget w, String param)
252{
253 String params[2];
254 Cardinal num_params = 2;
255 params[0] = XtName(w);
256 params[1] = param;
257
258 XtAppWarningMsg(XtWidgetToApplicationContext(w),
259 "parameterError", "textAction", "XawError",
260 "Widget: %s Parameter: %s",
261 params, &num_params);
262 XBell(XtDisplay(w)(((w)->core.screen)->display), 50);
263}
264
265static void
266StartAction(TextWidget ctx, XEvent *event)
267{
268#ifndef OLDXAW
269 Cardinal i;
270 TextSrcObject src = (TextSrcObject)ctx->text.source;
271
272 for (i = 0; i < src->textSrc.num_text; i++)
273 _XawTextPrepareToUpdate((TextWidget)src->textSrc.text[i]);
274 _XawSourceSetUndoMerge(src, False0);
275#else
276 _XawTextPrepareToUpdate(ctx);
277#endif
278
279 if (event != NULL((void*)0)) {
280 switch (event->type) {
281 case ButtonPress4:
282 case ButtonRelease5:
283 ctx->text.time = event->xbutton.time;
284 break;
285 case KeyPress2:
286 case KeyRelease3:
287 ctx->text.time = event->xkey.time;
288 break;
289 case MotionNotify6:
290 ctx->text.time = event->xmotion.time;
291 break;
292 case EnterNotify7:
293 case LeaveNotify8:
294 ctx->text.time = event->xcrossing.time;
295 }
296 }
297}
298
299static void
300NotePosition(TextWidget ctx, XEvent *event)
301{
302 switch (event->type) {
303 case ButtonPress4:
304 case ButtonRelease5:
305 ctx->text.ev_x = event->xbutton.x;
306 ctx->text.ev_y = event->xbutton.y;
307 break;
308 case KeyPress2:
309 case KeyRelease3: {
310 XRectangle cursor;
311 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
312 ctx->text.ev_x = cursor.x + cursor.width / 2;
313 ctx->text.ev_y = cursor.y + cursor.height / 2;
314 } break;
315 case MotionNotify6:
316 ctx->text.ev_x = event->xmotion.x;
317 ctx->text.ev_y = event->xmotion.y;
318 break;
319 case EnterNotify7:
320 case LeaveNotify8:
321 ctx->text.ev_x = event->xcrossing.x;
322 ctx->text.ev_y = event->xcrossing.y;
323 }
324}
325
326static void
327EndAction(TextWidget ctx)
328{
329#ifndef OLDXAW
330 Cardinal i;
331 TextSrcObject src = (TextSrcObject)ctx->text.source;
332
333 for (i = 0; i < src->textSrc.num_text; i++)
334 _XawTextExecuteUpdate((TextWidget)src->textSrc.text[i]);
335
336 ctx->text.mult = 1;
337 ctx->text.numeric = False0;
338 if (ctx->text.kill_ring) {
339 if (--ctx->text.kill_ring == KILL_RING_YANK_DONE98) {
340 if (ctx->text.kill_ring_ptr) {
341 --ctx->text.kill_ring_ptr->refcount;
342 ctx->text.kill_ring_ptr = NULL((void*)0);
343 }
344 }
345 }
346#else
347 ctx->text.mult = 1;
348 _XawTextExecuteUpdate(ctx);
349#endif /* OLDXAW */
350}
351
352struct _SelectionList {
353 String* params;
354 Cardinal count;
355 Time time;
356 int asked; /* which selection currently has been asked for:
357 0 = UTF8_STRING, 1 = COMPOUND_TEXT, 2 = STRING */
358 Atom selection; /* selection atom (normally XA_PRIMARY) */
359};
360
361/*ARGSUSED*/
362static void
363_SelectionReceived(Widget w, XtPointer client_data, Atom *selection,
364 Atom *type, XtPointer value, unsigned long *length,
365 int *format)
366{
367 Display *d = XtDisplay(w)(((w)->core.screen)->display);
368 TextWidget ctx = (TextWidget)w;
369 XawTextBlock text;
370
371 if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0) {
372 struct _SelectionList* list = (struct _SelectionList*)client_data;
373
374 if (list != NULL((void*)0)) {
375 if (list->asked == 0) {
376 /* If we just asked for XA_UTF8_STRING and got no response,
377 we'll ask again, this time for XA_COMPOUND_TEXT. */
378 list->asked++;
379 XtGetSelectionValue(w, list->selection, XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT),
380 _SelectionReceived,
381 (XtPointer)list, list->time);
382 } else if (list->asked == 1) {
383 /* If we just asked for XA_COMPOUND_TEXT and got no response,
384 we'll ask again, this time for XA_STRING. */
385 list->asked++;
386 XtGetSelectionValue(w, list->selection, XA_STRING((Atom) 31),
387 _SelectionReceived,
388 (XtPointer)list, list->time);
389 } else {
390 /* We tried all possible text targets in this param.
391 Recurse on the tail of the params list. */
392 GetSelection(w, list->time, list->params, list->count);
393 XtFree(client_data);
394 }
395 }
396 return;
397 }
398
399 StartAction(ctx, NULL((void*)0));
400 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
401 XTextProperty textprop;
402 wchar_t **wlist;
403 int count;
404
405 textprop.encoding = *type;
406 textprop.value = (unsigned char *)value;
407 textprop.nitems = strlen(value);
408 textprop.format = 8;
409
410 if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count)
411 != Success0
412 || count < 1) {
413 XwcFreeStringList(wlist);
414
415 /* Notify the user on strerr and in the insertion :) */
416 fprintf(stderrstderr, "Xaw Text Widget: An attempt was made to insert "
417 "an illegal selection.\n");
418
419 textprop.value = (unsigned char *)" >> ILLEGAL SELECTION << ";
420 textprop.nitems = strlen((char *) textprop.value);
421 if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count)
422 != Success0
423 || count < 1)
424 return;
425 }
426
427 XFree(value);
428 value = (XPointer)wlist[0];
429
430 *length = wcslen(wlist[0]);
431 XtFree((XtPointer)wlist);
432 text.format = XawFmtWide;
433 }
434 text.ptr = (char*)value;
435 text.firstPos = 0;
436 text.length = *length;
437 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
438 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 0);
439 EndAction(ctx);
440 return;
441 }
442
443 ctx->text.from_left = -1;
444 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.old_insert,
445 XawstPositions, XawsdRight, text.length, True1);
446
447 EndAction(ctx);
448 XtFree(client_data);
449 XFree(value); /* the selection value should be freed with XFree */
450}
451
452static void
453GetSelection(Widget w, Time timev, String *params, Cardinal num_params)
454{
455 Display *d = XtDisplay(w)(((w)->core.screen)->display);
456 TextWidget ctx = (TextWidget)w;
457 Atom selection;
458 int buffer;
459
460 selection = XInternAtom(XtDisplay(w)(((w)->core.screen)->display), *params, False0);
461 switch (selection) {
462 case XA_CUT_BUFFER0((Atom) 9): buffer = 0; break;
463 case XA_CUT_BUFFER1((Atom) 10): buffer = 1; break;
464 case XA_CUT_BUFFER2((Atom) 11): buffer = 2; break;
465 case XA_CUT_BUFFER3((Atom) 12): buffer = 3; break;
466 case XA_CUT_BUFFER4((Atom) 13): buffer = 4; break;
467 case XA_CUT_BUFFER5((Atom) 14): buffer = 5; break;
468 case XA_CUT_BUFFER6((Atom) 15): buffer = 6; break;
469 case XA_CUT_BUFFER7((Atom) 16): buffer = 7; break;
470 default: buffer = -1;
471 }
472 if (buffer >= 0) {
473 int nbytes;
474 unsigned long length;
475 int fmt8 = 8;
476 Atom type = XA_STRING((Atom) 31);
477 char *line = XFetchBuffer(XtDisplay(w)(((w)->core.screen)->display), &nbytes, buffer);
478
479 if ((length = nbytes) != 0L)
480 _SelectionReceived(w, NULL((void*)0), &selection, &type, line, &length, &fmt8);
481 else if (num_params > 1)
482 GetSelection(w, timev, params+1, num_params-1);
483 }
484 else {
485 struct _SelectionList* list;
486
487 if (--num_params) {
488 list = XtNew(struct _SelectionList)((struct _SelectionList *) XtMalloc((unsigned) sizeof(struct _SelectionList
)))
;
489 list->params = params + 1;
490 list->count = num_params;
491 list->time = timev;
492 list->asked = 0;
493 list->selection = selection;
494 }
495 else
496 list = NULL((void*)0);
497 XtGetSelectionValue(w, selection, XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) ?
498 XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING) : XA_TEXT(d)XmuInternAtom(d, _XA_TEXT),
499 _SelectionReceived, (XtPointer)list, timev);
500 }
501}
502
503static void
504InsertSelection(Widget w, XEvent *event, String *params, Cardinal *num_params)
505{
506 StartAction((TextWidget)w, event); /* Get Time. */
507 GetSelection(w, ((TextWidget)w)->text.time, params, *num_params);
508 EndAction((TextWidget)w);
509}
510
511/*
512 * Routines for Moving Around
513 */
514static void
515Move(TextWidget ctx, XEvent *event, XawTextScanDirection dir,
516 XawTextScanType type, Boolint include)
517{
518 XawTextPosition insertPos;
519 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
520
521 if (mult < 0) {
522 mult = -mult;
523 dir = dir == XawsdLeft ? XawsdRight : XawsdLeft;
524 }
525
526 insertPos = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
527 type, dir, mult, include);
528
529 StartAction(ctx, event);
530
531 if (ctx->text.s.left != ctx->text.s.right)
532 XawTextUnsetSelection((Widget)ctx);
533
534#ifndef OLDXAW
535 ctx->text.numeric = False0;
536#endif
537 ctx->text.mult = 1;
538 ctx->text.showposition = True1;
539 ctx->text.from_left = -1;
540 ctx->text.insertPos = insertPos;
541 EndAction(ctx);
542}
543
544/*ARGSUSED*/
545static void
546MoveForwardChar(Widget w, XEvent *event, String *p, Cardinal *n)
547{
548 Move((TextWidget)w, event, XawsdRight, XawstPositions, True1);
549}
550
551/*ARGSUSED*/
552static void
553MoveBackwardChar(Widget w, XEvent *event, String *p, Cardinal *n)
554{
555 Move((TextWidget)w, event, XawsdLeft, XawstPositions, True1);
556}
557
558static void
559MoveForwardWord(Widget w, XEvent *event, String *p, Cardinal *n)
560{
561 if (*n && (p[0][0] == 'A' || p[0][0] == 'a'))
562 Move((TextWidget)w, event, XawsdRight, XawstAlphaNumeric, False0);
563 else
564 Move((TextWidget)w, event, XawsdRight, XawstWhiteSpace, False0);
565}
566
567static void
568MoveBackwardWord(Widget w, XEvent *event, String *p, Cardinal *n)
569{
570 if (*n && (p[0][0] == 'A' || p[0][0] == 'a'))
571 Move((TextWidget)w, event, XawsdLeft, XawstAlphaNumeric, False0);
572 else
573 Move((TextWidget)w, event, XawsdLeft, XawstWhiteSpace, False0);
574}
575
576static void
577MoveForwardParagraph(Widget w, XEvent *event, String *p, Cardinal *n)
578{
579 TextWidget ctx = (TextWidget)w;
580 XawTextPosition position = ctx->text.insertPos;
581 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
582
583 if (mult < 0) {
584 ctx->text.mult = -mult;
585 MoveBackwardParagraph(w, event, p, n);
586 return;
587 }
588
589 while (mult--) {
590 position = SrcScanXawTextSourceScan(ctx->text.source, position,
591 XawstEOL, XawsdRight, 1, False0) - 1;
592
593 while (position == SrcScanXawTextSourceScan(ctx->text.source, position,
594 XawstEOL, XawsdRight, 1, False0))
595 if (++position > ctx->text.lastPos) {
596 mult = 0;
597 break;
598 }
599
600 position = SrcScanXawTextSourceScan(ctx->text.source, position,
601 XawstParagraph, XawsdRight, 1, True1);
602 if (position != ctx->text.lastPos)
603 position = SrcScanXawTextSourceScan(ctx->text.source, position - 1,
604 XawstEOL, XawsdLeft, 1, False0);
605 else
606 break;
607 }
608
609 if (position != ctx->text.insertPos) {
610 XawTextUnsetSelection(w);
611 StartAction(ctx, event);
612 ctx->text.showposition = True1;
613 ctx->text.from_left = -1;
614 ctx->text.insertPos = position;
615 EndAction(ctx);
616 }
617 else
618 ctx->text.mult = 1;
619}
620
621/*ARGSUSED*/
622static void
623MoveBackwardParagraph(Widget w, XEvent *event, String *p, Cardinal *n)
624{
625 TextWidget ctx = (TextWidget)w;
626 XawTextPosition position = ctx->text.insertPos;
627 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
628
629 if (mult < 0) {
630 ctx->text.mult = -mult;
631 MoveForwardParagraph(w, event, p, n);
632 return;
633 }
634
635 while (mult--) {
636 position = SrcScanXawTextSourceScan(ctx->text.source, position,
637 XawstEOL, XawsdLeft, 1, False0) + 1;
638
639 while (position == SrcScanXawTextSourceScan(ctx->text.source, position,
640 XawstEOL, XawsdLeft, 1, False0))
641 if (--position < 0) {
642 mult = 0;
643 break;
644 }
645
646 position = SrcScanXawTextSourceScan(ctx->text.source, position,
647 XawstParagraph, XawsdLeft, 1, True1);
648 if (position > 0 && position < ctx->text.lastPos)
649 ++position;
650 else
651 break;
652 }
653
654 if (position != ctx->text.insertPos) {
655 XawTextUnsetSelection(w);
656 StartAction(ctx, event);
657 ctx->text.showposition = True1;
658 ctx->text.from_left = -1;
659 ctx->text.insertPos = position;
660 EndAction(ctx);
661 }
662 else
663 ctx->text.mult = 1;
664}
665
666/*ARGSUSED*/
667static void
668MoveToLineEnd(Widget w, XEvent *event, String *p, Cardinal *n)
669{
670 Move((TextWidget)w, event, XawsdRight, XawstEOL, False0);
671}
672
673/*ARGSUSED*/
674static void
675MoveToLineStart(Widget w, XEvent *event, String *p, Cardinal *n)
676{
677 Move((TextWidget)w, event, XawsdLeft, XawstEOL, False0);
678}
679
680static void
681MoveLine(TextWidget ctx, XEvent *event, XawTextScanDirection dir)
682{
683 XawTextPosition cnew, next_line, ltemp;
684 int itemp, from_left;
685 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
686
687 StartAction(ctx, event);
688
689 XawTextUnsetSelection((Widget)ctx);
690
691 if (dir == XawsdLeft)
692 mult = mult == 0 ? 5 : mult + 1;
693
694 cnew = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
695 XawstEOL, XawsdLeft, 1, False0);
696
697 if (ctx->text.from_left < 0)
698 FindDistXawTextSinkFindDistance(ctx->text.sink, cnew, ctx->text.left_margin, ctx->text.insertPos,
699 &ctx->text.from_left, &ltemp, &itemp);
700
701 cnew = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos, XawstEOL, dir,
702 mult, (dir == XawsdRight));
703
704 next_line = SrcScanXawTextSourceScan(ctx->text.source, cnew, XawstEOL, XawsdRight, 1, False0);
705
706 FindPosXawTextSinkFindPosition(ctx->text.sink, cnew, ctx->text.left_margin, ctx->text.from_left,
707 False0, &ctx->text.insertPos, &from_left, &itemp);
708
709 if (from_left < ctx->text.from_left) {
710 XawTextBlock block;
711
712 XawTextSourceRead(ctx->text.source, ctx->text.insertPos, &block, 1);
713 if (block.length) {
714 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
715 if (*(wchar_t *)block.ptr == _Xaw_atowc(XawTAB0x09))
716 ++ctx->text.insertPos;
717 }
718 else if (block.ptr[0] == XawTAB0x09)
719 ++ctx->text.insertPos;
720 }
721 }
722
723 if (ctx->text.insertPos > next_line)
724 ctx->text.insertPos = next_line;
725
726 EndAction(ctx);
727}
728
729static void
730MoveNextLine(Widget w, XEvent *event, String *p, Cardinal *n)
731{
732 TextWidget ctx = (TextWidget)w;
733 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
734
735 if (mult < 0) {
736 ctx->text.mult = -mult;
737 MovePreviousLine(w, event, p, n);
738 return;
739 }
740
741 if (ctx->text.insertPos < ctx->text.lastPos)
742 MoveLine(ctx, event, XawsdRight);
743 else
744 ctx->text.mult = 1;
745}
746
747static void
748MovePreviousLine(Widget w, XEvent *event, String *p, Cardinal *n)
749{
750 TextWidget ctx = (TextWidget)w;
751 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
752
753 if (mult < 0) {
754 ctx->text.mult = -mult;
755 MoveNextLine(w, event, p, n);
756 return;
757 }
758
759 if (ctx->text.lt.top != 0 || (ctx->text.lt.lines > 1 &&
760 ctx->text.insertPos >= ctx->text.lt.info[1].position))
761 MoveLine(ctx, event, XawsdLeft);
762 else
763 ctx->text.mult = 1;
764}
765
766/*ARGSUSED*/
767static void
768MoveBeginningOfFile(Widget w, XEvent *event, String *p, Cardinal *n)
769{
770 Move((TextWidget)w, event, XawsdLeft, XawstAll, True1);
771}
772
773/*ARGSUSED*/
774static void
775MoveEndOfFile(Widget w, XEvent *event, String *p, Cardinal *n)
776{
777 Move((TextWidget)w, event, XawsdRight, XawstAll, True1);
778}
779
780static void
781Scroll(TextWidget ctx, XEvent *event, XawTextScanDirection dir)
782{
783 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
784
785 if (mult < 0) {
786 mult = -mult;
787 dir = dir == XawsdLeft ? XawsdRight : XawsdLeft;
788 }
789
790 if (ctx->text.lt.lines > 1
791 && (dir == XawsdRight
792 || ctx->text.lastPos >= ctx->text.lt.info[1].position)) {
793 StartAction(ctx, event);
794
795 if (dir == XawsdLeft)
796 _XawTextVScroll(ctx, mult);
797 else
798 _XawTextVScroll(ctx, -mult);
799
800 EndAction(ctx);
801 }
802 else {
803 ctx->text.mult = 1;
804#ifndef OLDXAW
805 ctx->text.numeric = False0;
806#endif
807 }
808}
809
810/*ARGSUSED*/
811static void
812ScrollOneLineUp(Widget w, XEvent *event, String *p, Cardinal *n)
813{
814 Scroll((TextWidget)w, event, XawsdLeft);
815}
816
817/*ARGSUSED*/
818static void
819ScrollOneLineDown(Widget w, XEvent *event, String *p, Cardinal *n)
820{
821 Scroll((TextWidget)w, event, XawsdRight);
822}
823
824static void
825MovePage(TextWidget ctx, XEvent *event, XawTextScanDirection dir)
826{
827 int scroll_val = 0;
828 XawTextPosition old_pos;
829
830 ctx->text.from_left = -1;
831 switch (dir) {
832 case XawsdLeft:
833 if (ctx->text.lt.top != 0)
834 scroll_val = -Max(1, ctx->text.lt.lines - 1)(((1) > (ctx->text.lt.lines - 1)) ? (1) : (ctx->text
.lt.lines - 1))
;
835 break;
836 case XawsdRight:
837 if (!IsPositionVisible(ctx, Max(0, ctx->text.lastPos))((((0) > (ctx->text.lastPos)) ? (0) : (ctx->text.lastPos
)) >= ctx->text.lt.info[0].position && (((0) >
(ctx->text.lastPos)) ? (0) : (ctx->text.lastPos)) <
ctx->text.lt.info[ctx->text.lt.lines].position)
)
838 scroll_val = Max(1, ctx->text.lt.lines - 1)(((1) > (ctx->text.lt.lines - 1)) ? (1) : (ctx->text
.lt.lines - 1))
;
839 break;
840 }
841
842 if (scroll_val)
843 XawTextScroll(ctx, scroll_val,
844 ctx->text.left_margin - ctx->text.r_margin.left);
845
846 old_pos = ctx->text.insertPos;
847 switch (dir) {
848 case XawsdRight:
849 if (IsPositionVisible(ctx, Max(0, ctx->text.lastPos))((((0) > (ctx->text.lastPos)) ? (0) : (ctx->text.lastPos
)) >= ctx->text.lt.info[0].position && (((0) >
(ctx->text.lastPos)) ? (0) : (ctx->text.lastPos)) <
ctx->text.lt.info[ctx->text.lt.lines].position)
)
850 ctx->text.insertPos = Max(0, ctx->text.lastPos)(((0) > (ctx->text.lastPos)) ? (0) : (ctx->text.lastPos
))
;
851 else
852 ctx->text.insertPos = ctx->text.lt.top;
853 if (ctx->text.insertPos < old_pos)
854 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, old_pos,
855 XawstEOL, XawsdLeft, 1, False0);
856 break;
857 case XawsdLeft:
858 if (IsPositionVisible(ctx, 0)(0 >= ctx->text.lt.info[0].position && 0 < ctx
->text.lt.info[ctx->text.lt.lines].position)
)
859 ctx->text.insertPos = 0;
860 else if (ctx->text.lt.lines)
861 ctx->text.insertPos =
862 ctx->text.lt.info[ctx->text.lt.lines - 1].position;
863 else
864 ctx->text.insertPos = ctx->text.lt.top;
865 if (ctx->text.insertPos > old_pos)
866 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, old_pos,
867 XawstEOL, XawsdLeft, 1, False0);
868 break;
869 }
870}
871
872static void
873MoveNextPage(Widget w, XEvent *event, String *p, Cardinal *n)
874{
875 TextWidget ctx = (TextWidget)w;
876 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
877
878 if (mult < 0) {
879 ctx->text.mult = -mult;
880 MovePreviousPage(w, event, p, n);
881 return;
882 }
883
884 if (ctx->text.insertPos < ctx->text.lastPos) {
885 XawTextUnsetSelection(w);
886 StartAction(ctx, event);
887 ctx->text.clear_to_eol = True1;
888 while (mult-- && ctx->text.insertPos < ctx->text.lastPos)
889 MovePage(ctx, event, XawsdRight);
890 EndAction(ctx);
891 }
892 else
893 ctx->text.mult = 1;
894}
895
896/*ARGSUSED*/
897static void
898MovePreviousPage(Widget w, XEvent *event, String *p, Cardinal *n)
899{
900 TextWidget ctx = (TextWidget)w;
901 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
902
903 if (mult < 0) {
904 ctx->text.mult = -mult;
905 MoveNextPage(w, event, p, n);
906 return;
907 }
908
909 if (ctx->text.insertPos > 0) {
910 XawTextUnsetSelection(w);
911 StartAction(ctx, event);
912 ctx->text.clear_to_eol = True1;
913 while (mult-- && ctx->text.insertPos > 0)
914 MovePage(ctx, event, XawsdLeft);
915 EndAction(ctx);
916 }
917 else
918 ctx->text.mult = 1;
919}
920
921/*
922 * Delete Routines
923 */
924static Boolint
925MatchSelection(Atom selection, XawTextSelection *s)
926{
927 Atom *match;
928 int count;
929
930 for (count = 0, match = s->selections; count < s->atom_count;
931 match++, count++)
932 if (*match == selection)
933 return (True1);
934
935 return (False0);
936}
937
938#define SrcCvtSelXawTextSourceConvertSelection XawTextSourceConvertSelection
939
940static Boolean
941ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
942 XtPointer *value, unsigned long *length, int *format)
943{
944 Display *d = XtDisplay(w)(((w)->core.screen)->display);
945 TextWidget ctx = (TextWidget)w;
946 Widget src = ctx->text.source;
947 XawTextEditType edit_mode;
948 Arg args[1];
949 XawTextSelectionSalt *salt = NULL((void*)0);
950 XawTextSelection *s;
951
952 if (*target == XA_TARGETS(d)XmuInternAtom(d, _XA_TARGETS)) {
953 Atom *targetP, *std_targets;
954 unsigned long std_length;
955
956 if (SrcCvtSelXawTextSourceConvertSelection(src, selection, target, type, value, length, format))
957 return (True1);
958
959 XtSetArg(args[0], XtNeditType,&edit_mode)((void)( (args[0]).name = (((char*)&XtStrings[185])), (args
[0]).value = (XtArgVal)(&edit_mode) ))
;
960 XtGetValues(src, args, 1);
961
962 XmuConvertStandardSelection(w, ctx->text.time, selection,
963 target, type, (XPointer *)&std_targets,
964 &std_length, format);
965
966 *length = 7 + (edit_mode == XawtextEdit) + std_length;
967 *value = XtMalloc((unsigned)sizeof(Atom)*(*length));
968 targetP = *(Atom**)value;
969 *targetP++ = XA_STRING((Atom) 31);
970 *targetP++ = XA_TEXT(d)XmuInternAtom(d, _XA_TEXT);
971 *targetP++ = XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING);
972 *targetP++ = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
973 *targetP++ = XA_LENGTH(d)XmuInternAtom(d, _XA_LENGTH);
974 *targetP++ = XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH);
975 *targetP++ = XA_CHARACTER_POSITION(d)XmuInternAtom(d, _XA_CHARACTER_POSITION);
976 if (edit_mode == XawtextEdit) {
977 *targetP++ = XA_DELETE(d)XmuInternAtom(d, _XA_DELETE);
978 }
979 memcpy((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
980 XtFree((char*)std_targets);
981 *type = XA_ATOM((Atom) 4);
982 *format = 32;
983 return (True1);
984 }
985
986 if (SrcCvtSelXawTextSourceConvertSelection(src, selection, target, type, value, length, format))
987 return (True1);
988
989 for (salt = ctx->text.salt2; salt; salt = salt->next)
990 if (MatchSelection (*selection, &salt->s))
991 break;
992 if (!salt)
993 return (False0);
994 s = &salt->s;
995 if (*target == XA_STRING((Atom) 31)
996 || *target == XA_TEXT(d)XmuInternAtom(d, _XA_TEXT)
997 || *target == XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING)
998 || *target == XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT)) {
999 if (*target == XA_TEXT(d)XmuInternAtom(d, _XA_TEXT)) {
1000 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)))
1001 *type = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1002 else
1003 *type = XA_STRING((Atom) 31);
1004 }
1005 else
1006 *type = *target;
1007
1008 /*
1009 * If salt is True, the salt->contents stores CT string,
1010 * its length is measured in bytes.
1011 * Refer to _XawTextSaltAwaySelection()
1012 *
1013 * by Li Yuhong, Mar. 20, 1991.
1014 */
1015 if (!salt) {
1016 *value = (char *)_XawTextGetSTRING(ctx, s->left, s->right);
1017 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
1018 XTextProperty textprop;
1019 if (XwcTextListToTextProperty(d, (wchar_t**)value, 1,
1020 XCompoundTextStyle, &textprop)
1021 < Success0) {
1022 XtFree(*value);
1023 return (False0);
1024 }
1025 XtFree(*value);
1026 *value = (XtPointer)textprop.value;
1027 *length = textprop.nitems;
1028 }
1029 else
1030 *length = strlen(*value);
1031 }
1032 else {
1033 *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
1034 strcpy (*value, salt->contents);
1035 *length = salt->length;
1036 }
1037 /* Got *value,*length, now in COMPOUND_TEXT format. */
1038 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
1039 if (*type == XA_STRING((Atom) 31)) {
1040 XTextProperty textprop;
1041 wchar_t **wlist;
1042 int count;
1043
1044 textprop.encoding = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1045 textprop.value = (unsigned char *)*value;
1046 textprop.nitems = strlen(*value);
1047 textprop.format = 8;
1048 if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count)
1049 < Success0
1050 || count < 1) {
1051 XtFree(*value);
1052 return (False0);
1053 }
1054 XtFree(*value);
1055 if (XwcTextListToTextProperty(d, wlist, 1, XStringStyle, &textprop)
1056 < Success0) {
1057 XwcFreeStringList((wchar_t**)wlist);
1058 return (False0);
1059 }
1060 *value = (XtPointer)textprop.value;
1061 *length = textprop.nitems;
1062 XwcFreeStringList((wchar_t**) wlist);
1063 }
1064 else if (*type == XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING)) {
1065 XTextProperty textprop;
1066 char **list;
1067 int count;
1068
1069 textprop.encoding = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1070 textprop.value = (unsigned char *)*value;
1071 textprop.nitems = strlen(*value);
1072 textprop.format = 8;
1073 if (Xutf8TextPropertyToTextList(d, &textprop, &list, &count)
1074 < Success0
1075 || count < 1) {
1076 XtFree(*value);
1077 return (False0);
1078 }
1079 XtFree(*value);
1080 *value = *list;
1081 *length = strlen(*list);
1082 XFree(list);
1083 }
1084 }
1085 *format = 8;
1086 return (True1);
1087 }
1088
1089 if (*target == XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH) || *target == XA_LENGTH(d)XmuInternAtom(d, _XA_LENGTH)) {
1090 long *temp;
1091
1092 temp = (long *)XtMalloc(sizeof(long));
1093 if (*target == XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH))
1094 *temp = 1L;
1095 else /* *target == XA_LENGTH(d) */
1096 *temp = (long)(s->right - s->left);
1097
1098 *value = (XPointer)temp;
1099 *type = XA_INTEGER((Atom) 19);
1100 *length = 1L;
1101 *format = 32;
1102 return (True1);
1103 }
1104
1105 if (*target == XA_CHARACTER_POSITION(d)XmuInternAtom(d, _XA_CHARACTER_POSITION)) {
1106 long *temp;
1107
1108 temp = (long *) XtMalloc(2 * sizeof(long));
1109 temp[0] = (long)(s->left + 1);
1110 temp[1] = s->right;
1111 *value = (XPointer)temp;
1112 *type = XA_SPAN(d)XmuInternAtom(d, _XA_SPAN);
1113 *length = 2L;
1114 *format = 32;
1115 return (True1);
1116 }
1117
1118 if (*target == XA_DELETE(d)XmuInternAtom(d, _XA_DELETE)) {
1119 if (!salt)
1120 _XawTextZapSelection(ctx, NULL((void*)0), True1);
1121 *value = NULL((void*)0);
1122 *type = XA_NULL(d)XmuInternAtom(d, _XA_NULL);
1123 *length = 0;
1124 *format = 32;
1125 return (True1);
1126 }
1127
1128 if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
1129 (XPointer *)value, length, format))
1130 return (True1);
1131
1132 return (False0);
1133}
1134
1135static void
1136LoseSelection(Widget w, Atom *selection)
1137{
1138 _LoseSelection(w, selection, NULL((void*)0), NULL((void*)0));
1139}
1140
1141static void
1142_LoseSelection(Widget w, Atom *selection, char **contents, int *length)
1143{
1144 TextWidget ctx = (TextWidget)w;
1145 Atom *atomP;
1146 int i;
1147 XawTextSelectionSalt *salt, *prevSalt, *nextSalt;
1148
1149 prevSalt = 0;
1150 for (salt = ctx->text.salt2; salt; salt = nextSalt) {
1151 atomP = salt->s.selections;
1152 nextSalt = salt->next;
1153 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
1154 if (*selection == *atomP)
1155 *atomP = (Atom)0;
1156
1157 while (salt->s.atom_count
1158 && salt->s.selections[salt->s.atom_count-1] == 0)
1159 salt->s.atom_count--;
1160
1161 /*
1162 * Must walk the selection list in opposite order from UnsetSelection.
1163 */
1164 atomP = salt->s.selections;
1165 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
1166 if (*atomP == (Atom)0) {
1167 *atomP = salt->s.selections[--salt->s.atom_count];
1168
1169 while (salt->s.atom_count
1170 && salt->s.selections[salt->s.atom_count-1] == 0)
1171 salt->s.atom_count--;
1172 }
1173 if (salt->s.atom_count == 0) {
1174#ifndef OLDXAW
1175 if (contents == NULL((void*)0)) {
1176 XawTextKillRing *kill_ring = XtNew(XawTextKillRing)((XawTextKillRing *) XtMalloc((unsigned) sizeof(XawTextKillRing
)))
;
1177
1178 kill_ring->next = xaw_text_kill_ring;
1179 kill_ring->contents = salt->contents;
1180 kill_ring->length = salt->length;
1181 kill_ring->format = XawFmt8Bit;
1182 xaw_text_kill_ring = kill_ring;
1183 kill_ring_prev.next = xaw_text_kill_ring;
1184
1185 if (++num_kill_rings > MAX_KILL_RINGS1024) {
1186 XawTextKillRing *tail = NULL((void*)0);
1187
1188 while (kill_ring->next) {
1189 tail = kill_ring;
1190 kill_ring = kill_ring->next;
1191 }
1192 if (kill_ring->refcount == 0) {
1193 --num_kill_rings;
1194 tail->next = NULL((void*)0);
1195 XtFree(kill_ring->contents);
1196 XtFree((char*)kill_ring);
1197 }
1198 }
1199 }
1200 else {
1201 *contents = salt->contents;
1202 *length = salt->length;
1203 }
1204#endif
1205 if (prevSalt)
1206 prevSalt->next = nextSalt;
1207 else
1208 ctx->text.salt2 = nextSalt;
1209
1210 XtFree((char *)salt->s.selections);
1211 XtFree((char *)salt);
1212 }
1213 else
1214 prevSalt = salt;
1215 }
1216}
1217
1218static void
1219_DeleteOrKill(TextWidget ctx, XawTextPosition from, XawTextPosition to,
1220 Boolint kill)
1221{
1222 XawTextBlock text;
1223
1224#ifndef OLDXAW
1225 if (ctx->text.kill_ring_ptr) {
1226 --ctx->text.kill_ring_ptr->refcount;
1227 ctx->text.kill_ring_ptr = NULL((void*)0);
1228 }
1229#endif
1230 if (kill && from < to) {
1231#ifndef OLDXAW
1232 Boolint append = False0;
1233 char *ring = NULL((void*)0);
1234 XawTextPosition old_from = from;
1235#endif
1236 char *string;
1237 int size = 0, length;
1238 XawTextSelectionSalt *salt;
1239 Atom selection = XInternAtom(XtDisplay(ctx)(((ctx)->core.screen)->display), "SECONDARY", False0);
1240
1241#ifndef OLDXAW
1242 if (ctx->text.kill_ring == KILL_RING_APPEND2) {
1243 old_from = ctx->text.salt2->s.left;
1244 append = True1;
1245 }
1246 else
1247 ctx->text.kill_ring = KILL_RING_BEGIN3;
1248
1249 if (append)
1250 _LoseSelection((Widget)ctx, &selection, &ring, &size);
1251 else
1252#endif
1253 LoseSelection((Widget)ctx, &selection);
1254
1255 salt = (XawTextSelectionSalt*)XtMalloc(sizeof(XawTextSelectionSalt));
1256 salt->s.selections = (Atom *)XtMalloc(sizeof(Atom));
1257 salt->s.left = from;
1258 salt->s.right = to;
1259
1260 string = (char *)_XawTextGetSTRING(ctx, from, to);
1261
1262 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
1263 XTextProperty textprop;
1264
1265 if (XwcTextListToTextProperty(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display),
1266 (wchar_t**)(&string),
1267 1, XCompoundTextStyle,
1268 &textprop) < Success0) {
1269 XtFree(string);
1270 XtFree((char*)salt->s.selections);
1271 XtFree((char*)salt);
1272 return;
1273 }
1274 XtFree(string);
1275 string = (char *)textprop.value;
1276 length = textprop.nitems;
1277 }
1278 else
1279 length = strlen(string);
1280
1281 salt->length = length + size;
1282
1283#ifndef OLDXAW
1284 if (!append)
1285 salt->contents = string;
1286 else {
1287 salt->contents = XtMalloc(length + size + 1);
1288 if (from >= old_from) {
1289 strncpy(salt->contents, ring, size);
1290 salt->contents[size] = '\0';
1291 strncat(salt->contents, string, length);
1292 }
1293 else {
1294 strncpy(salt->contents, string, length);
1295 salt->contents[length] = '\0';
1296 strncat(salt->contents, ring, size);
1297 }
1298 salt->contents[length + size] = '\0';
1299 XtFree(ring);
1300 XtFree(string);
1301 }
1302
1303 kill_ring_prev.contents = salt->contents;
1304 kill_ring_prev.length = salt->length;
1305 kill_ring_prev.format = XawFmt8Bit;
1306#else
1307 salt->contents = string;
1308#endif
1309
1310 salt->next = ctx->text.salt2;
1311 ctx->text.salt2 = salt;
1312
1313#ifndef OLDXAW
1314 if (append)
1315 ctx->text.kill_ring = KILL_RING_BEGIN3;
1316#endif
1317
1318 salt->s.selections[0] = selection;
1319
1320 XtOwnSelection((Widget)ctx, selection, ctx->text.time,
1321 ConvertSelection, LoseSelection, NULL((void*)0));
1322 salt->s.atom_count = 1;
1323 }
1324 text.length = 0;
1325 text.firstPos = 0;
1326
1327 text.format = _XawTextFormat(ctx);
1328 text.ptr = "";
1329
1330 if (_XawTextReplace(ctx, from, to, &text)) {
1331 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 50);
1332 return;
1333 }
1334 ctx->text.from_left = -1;
1335 ctx->text.insertPos = from;
1336 ctx->text.showposition = TRUE1;
1337}
1338
1339static void
1340DeleteOrKill(TextWidget ctx, XEvent *event, XawTextScanDirection dir,
1341 XawTextScanType type, Boolint include, Boolint kill)
1342{
1343 XawTextPosition from, to;
1344 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
1345
1346 if (mult < 0) {
1347 mult = -mult;
1348 dir = dir == XawsdLeft ? XawsdRight : XawsdLeft;
1349 }
1350
1351 StartAction(ctx, event);
1352#ifndef OLDXAW
1353 if (mult == 1)
1354 _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True1);
1355#endif
1356 to = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
1357 type, dir, mult, include);
1358
1359 /*
1360 * If no movement actually happened, then bump the count and try again.
1361 * This causes the character position at the very beginning and end of
1362 * a boundary to act correctly
1363 */
1364 if (to == ctx->text.insertPos)
1365 to = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
1366 type, dir, mult + 1, include);
1367
1368 if (dir == XawsdLeft) {
1369 from = to;
1370 to = ctx->text.insertPos;
1371 }
1372 else
1373 from = ctx->text.insertPos;
1374
1375 _DeleteOrKill(ctx, from, to, kill);
1376 EndAction(ctx);
1377}
1378
1379static void
1380Delete(Widget w, XEvent *event, String *p, Cardinal *n)
1381{
1382 TextWidget ctx = (TextWidget)w;
1383
1384 if (ctx->text.s.left != ctx->text.s.right)
1385 DeleteCurrentSelection(w, event, p, n);
1386 else
1387 DeleteBackwardChar(w, event, p, n);
1388}
1389
1390static void
1391DeleteChar(Widget w, XEvent *event, XawTextScanDirection dir)
1392{
1393 TextWidget ctx = (TextWidget)w;
1394 short mul = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
1395
1396 if (mul < 0) {
1397 ctx->text.mult = mul = -mul;
1398 dir = dir == XawsdLeft ? XawsdRight : XawsdLeft;
1399 }
1400 DeleteOrKill(ctx, event, dir, XawstPositions, True1, False0);
1401#ifndef OLDXAW
1402 if (mul == 1)
1403 _XawSourceSetUndoErase((TextSrcObject)ctx->text.source,
1404 dir == XawsdLeft ? -1 : 1);
1405#endif
1406}
1407
1408/*ARGSUSED*/
1409static void
1410DeleteForwardChar(Widget w, XEvent *event, String *p, Cardinal *n)
1411{
1412 DeleteChar(w, event, XawsdRight);
1413}
1414
1415/*ARGSUSED*/
1416static void
1417DeleteBackwardChar(Widget w, XEvent *event, String *p, Cardinal *n)
1418{
1419 DeleteChar(w, event, XawsdLeft);
1420}
1421
1422static void
1423DeleteForwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
1424{
1425 XawTextScanType type;
1426
1427 if (*num_params && (*params[0] == 'A' || *params[0] == 'a'))
1428 type = XawstAlphaNumeric;
1429 else
1430 type = XawstWhiteSpace;
1431
1432 DeleteOrKill((TextWidget)w, event, XawsdRight, type, False0, False0);
1433}
1434
1435static void
1436DeleteBackwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
1437{
1438 XawTextScanType type;
1439
1440 if (*num_params && (*params[0] == 'A' || *params[0] == 'a'))
1441 type = XawstAlphaNumeric;
1442 else
1443 type = XawstWhiteSpace;
1444
1445 DeleteOrKill((TextWidget)w, event, XawsdLeft, type, False0, False0);
1446}
1447
1448static void
1449KillForwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
1450{
1451 XawTextScanType type;
1452
1453 if (*num_params && (*params[0] == 'A' || *params[0] == 'a'))
1454 type = XawstAlphaNumeric;
1455 else
1456 type = XawstWhiteSpace;
1457
1458 DeleteOrKill((TextWidget)w, event, XawsdRight, type, False0, True1);
1459}
1460
1461static void
1462KillBackwardWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
1463{
1464 XawTextScanType type;
1465
1466 if (*num_params && (*params[0] == 'A' || *params[0] == 'a'))
1467 type = XawstAlphaNumeric;
1468 else
1469 type = XawstWhiteSpace;
1470
1471 DeleteOrKill((TextWidget) w, event, XawsdLeft, type, False0, True1);
1472}
1473
1474/*ARGSUSED*/
1475static void
1476KillToEndOfLine(Widget w, XEvent *event, String *p, Cardinal *n)
1477{
1478 TextWidget ctx = (TextWidget)w;
1479 XawTextPosition end_of_line;
1480 XawTextScanDirection dir = XawsdRight;
1481 short mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
1482
1483 if (mult < 0) {
1484 dir = XawsdLeft;
1485 mult = -mult;
1486 }
1487
1488 StartAction(ctx, event);
1489 end_of_line = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
1490 dir, mult, False0);
1491 if (end_of_line == ctx->text.insertPos)
1492 end_of_line = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
1493 dir, mult, True1);
1494
1495 if (dir == XawsdRight)
1496 _DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, True1);
1497 else
1498 _DeleteOrKill(ctx, end_of_line, ctx->text.insertPos, True1);
1499 EndAction(ctx);
1500}
1501
1502/*ARGSUSED*/
1503static void
1504KillToEndOfParagraph(Widget w, XEvent *event, String *p, Cardinal *n)
1505{
1506 DeleteOrKill((TextWidget)w, event, XawsdRight, XawstParagraph, False0, True1);
1507}
1508
1509void
1510_XawTextZapSelection(TextWidget ctx, XEvent *event, Boolint kill)
1511{
1512 StartAction(ctx, event);
1513 _DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill);
1514 EndAction(ctx);
1515}
1516
1517/*ARGSUSED*/
1518static void
1519KillCurrentSelection(Widget w, XEvent *event, String *p, Cardinal *n)
1520{
1521 _XawTextZapSelection((TextWidget) w, event, True1);
1522}
1523
1524#ifndef OLDXAW
1525/*ARGSUSED*/
1526static void
1527KillRingYank(Widget w, XEvent *event, String *params, Cardinal *num_params)
1528{
1529 TextWidget ctx = (TextWidget)w;
1530 XawTextPosition insertPos = ctx->text.insertPos;
1531 Boolint first_yank = False0;
1532
1533 if (ctx->text.s.left != ctx->text.s.right)
1534 XawTextUnsetSelection((Widget)ctx);
1535
1536 StartAction(ctx, event);
1537
1538 if (ctx->text.kill_ring_ptr == NULL((void*)0)) {
1539 ctx->text.kill_ring_ptr = &kill_ring_prev;
1540 ++ctx->text.kill_ring_ptr->refcount;
1541 ctx->text.s.left = ctx->text.s.right = insertPos;
1542 first_yank = True1;
1543 }
1544 if (ctx->text.kill_ring_ptr) {
1545 int mul = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
1546 XawTextBlock text;
1547
1548 if (!first_yank) {
1549 if (mul < 0)
1550 mul = 1;
1551 --ctx->text.kill_ring_ptr->refcount;
1552 while (mul--) {
1553 if ((ctx->text.kill_ring_ptr = ctx->text.kill_ring_ptr->next) == NULL((void*)0))
1554 ctx->text.kill_ring_ptr = &kill_ring_null;
1555 }
1556 ++ctx->text.kill_ring_ptr->refcount;
1557 }
1558 text.firstPos = 0;
1559 text.length = ctx->text.kill_ring_ptr->length;
1560 text.ptr = ctx->text.kill_ring_ptr->contents;
1561 text.format = ctx->text.kill_ring_ptr->format;
1562
1563 if (_XawTextReplace(ctx, ctx->text.s.left, insertPos, &text) == XawEditDone0) {
1564 ctx->text.kill_ring = KILL_RING_YANK100;
1565 ctx->text.insertPos = ctx->text.s.left + text.length;
1566 }
1567 }
1568 else
1569 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
1570
1571 EndAction(ctx);
1572}
1573#endif /* OLDXAW */
1574
1575/*ARGSUSED*/
1576static void
1577DeleteCurrentSelection(Widget w, XEvent *event, String *p, Cardinal *n)
1578{
1579 _XawTextZapSelection((TextWidget)w, event, False0);
1580}
1581
1582#ifndef OLDXAW
1583#define CHECK_SAVE() \
1584 if (save && !save->ptr) \
1585 save->ptr = _XawTextGetText(ctx, save->firstPos, \
1586 save->firstPos + save->length)
1587static Boolint
1588StripSpaces(TextWidget ctx, XawTextPosition left, XawTextPosition right,
1589 XawTextPosition *pos, int num_pos, XawTextBlock *save)
1590{
1591 Boolint done, space;
1592 int i, cpos, count = 0;
1593 XawTextBlock block, text;
1594 XawTextPosition ipos, position = left, tmp = left;
1595
1596 text.firstPos = 0;
1597 text.format = XawFmt8Bit;
1598 text.ptr = " ";
1599 text.length = 1;
1600
1601 position = XawTextSourceRead(ctx->text.source, position,
1602 &block, right - left);
1603 done = False0;
1604 space = False0;
1605 /* convert tabs and returns to spaces */
1606 while (!done) {
1607 if (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit))) {
1608 for (i = 0; i < block.length; i++)
1609 if (block.ptr[i] == '\t' || block.ptr[i] == '\n') {
1610 space = True1;
1611 break;
1612 }
1613 }
1614 else {
1615 wchar_t *wptr = (wchar_t*)block.ptr;
1616 for (i = 0; i < block.length; i++)
1617 if (wptr[i] == _Xaw_atowc('\t') || wptr[i] == _Xaw_atowc('\n')) {
1618 space = True1;
1619 break;
1620 }
1621 }
1622 if (space) {
1623 CHECK_SAVE();
1624 if (_XawTextReplace(ctx, tmp + i, tmp + i + 1, &text))
1625 return (False0);
1626 space = False0;
1627 }
1628 tmp += i;
1629 position = XawTextSourceRead(ctx->text.source, tmp,
1630 &block, right - tmp);
1631 if (block.length == 0 || tmp == position || tmp >= right)
1632 done = True1;
1633 }
1634
1635 text.ptr = "";
1636 text.length = 0;
1637 position = tmp = left;
1638 position = XawTextSourceRead(ctx->text.source, position,
Value stored to 'position' is never read
1639 &block, right - left);
1640 ipos = ctx->text.insertPos;
1641 done = False0;
1642 while (!done) {
1643 if (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit))) {
1644 for (i = 0; i < block.length; i++)
1645 if (block.ptr[i] == ' ')
1646 ++count;
1647 else if (count == 1)
1648 count = 0;
1649 else if (count)
1650 break;
1651 }
1652 else {
1653 wchar_t *wptr = (wchar_t*)block.ptr;
1654 for (i = 0; i < block.length; i++)
1655 if (wptr[i] == _Xaw_atowc(' '))
1656 ++count;
1657 else if (count == 1)
1658 count = 0;
1659 else if (count)
1660 break;
1661 }
1662 if (--count > 0) {
1663 CHECK_SAVE();
1664 if (_XawTextReplace(ctx, tmp + i - count, tmp + i, &text))
1665 return (False0);
1666 right -= count;
1667 if (num_pos) {
1668 for (cpos = 0; cpos < num_pos; cpos++) {
1669 if (tmp + i - count < pos[cpos]) {
1670 if (tmp + i < pos[cpos])
1671 pos[cpos] -= count;
1672 else
1673 pos[cpos] = tmp + i - count;
1674 }
1675 }
1676 }
1677 else {
1678 if (tmp + i - count < ipos) {
1679 if (tmp + i < ipos)
1680 ipos -= count;
1681 else
1682 ipos = tmp + i - count;
1683 }
1684 }
1685 tmp += i - count;
1686 }
1687 else
1688 tmp += i + 1;
1689 count = 0;
1690 position = XawTextSourceRead(ctx->text.source, tmp,
1691 &block, right - tmp);
1692 if (block.length == 0 || tmp == position || tmp >= right)
1693 done = True1;
1694 }
1695 if (!num_pos)
1696 ctx->text.insertPos = ipos;
1697
1698 return (True1);
1699}
1700
1701static Boolint
1702Tabify(TextWidget ctx, XawTextPosition left, XawTextPosition right,
1703 XawTextPosition *pos, int num_pos, XawTextBlock *save)
1704{
1705 Boolint done, zero;
1706 int i, cpos, count = 0, column = 0, offset = 0;
1707 XawTextBlock text, block;
1708 XawTextPosition ipos, position = left, tmp = left;
1709 TextSinkObject sink = (TextSinkObject)ctx->text.sink;
1710 short *char_tabs = sink->text_sink.char_tabs;
1711 int tab_count = sink->text_sink.tab_count;
1712 int tab_index = 0, tab_column = 0, TAB_SIZE = DEFAULT_TAB_SIZE8;
1713
1714 text.firstPos = 0;
1715 text.ptr = "\t";
1716 text.format = XawFmt8Bit;
1717 text.length = 1;
1718
1719 position = XawTextSourceRead(ctx->text.source, position,
1720 &block, right - left);
1721 ipos = ctx->text.insertPos;
1722 done = zero = False0;
1723 if (tab_count)
1724 TAB_SIZE = *char_tabs;
1725 while (!done) {
1726 if (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit))) {
1727 for (i = 0; i < block.length; i++) {
1728 ++offset;
1729 ++column;
1730 if (tab_count) {
1731 if (column > tab_column + char_tabs[tab_index]) {
1732 TAB_SIZE = tab_index < tab_count - 1 ? char_tabs[tab_index + 1] - char_tabs[tab_index] : *char_tabs;
1733 if (++tab_index >= tab_count) {
1734 tab_column += char_tabs[tab_count - 1];
1735 tab_index = 0;
1736 }
1737 }
1738 }
1739 if (block.ptr[i] == ' ') {
1740 if (++count > TAB_SIZE)
1741 count %= TAB_SIZE;
1742 if ((tab_count && column == tab_column + char_tabs[tab_index]) ||
1743 (!tab_count && column % TAB_SIZE == 0)) {
1744 if (count % (TAB_SIZE + 1) > 1)
1745 break;
1746 else
1747 count = 0;
1748 }
1749 }
1750 else {
1751 if (block.ptr[i] == '\n') {
1752 zero = True1;
1753 break;
1754 }
1755 count = 0;
1756 }
1757 }
1758 }
1759 else {
1760 wchar_t *wptr = (wchar_t*)block.ptr;
1761 for (i = 0; i < block.length; i++) {
1762 ++offset;
1763 ++column;
1764 if (tab_count) {
1765 if (column > tab_column + char_tabs[tab_index]) {
1766 TAB_SIZE = tab_index < tab_count - 1 ? char_tabs[tab_index + 1] - char_tabs[tab_index] : *char_tabs;
1767 if (++tab_index >= tab_count) {
1768 tab_column += char_tabs[tab_count - 1];
1769 tab_index = 0;
1770 }
1771 }
1772 }
1773 if (wptr[i] == _Xaw_atowc(' ')) {
1774 if (++count > TAB_SIZE)
1775 count %= TAB_SIZE;
1776 if ((tab_count && column == tab_column + char_tabs[tab_index]) ||
1777 (!tab_count && column % TAB_SIZE == 0)) {
1778 if (count % (TAB_SIZE + 1) > 1)
1779 break;
1780 else
1781 count = 0;
1782 }
1783 }
1784 else {
1785 if (wptr[i] == _Xaw_atowc('\n')) {
1786 zero = True1;
1787 break;
1788 }
1789 count = 0;
1790 }
1791 }
1792 }
1793 count %= TAB_SIZE + 1;
1794 if (!zero && count > 1 && i < block.length) {
1795 CHECK_SAVE();
1796 if (_XawTextReplace(ctx, tmp + i - count + 1, tmp + i + 1, &text))
1797 return (False0);
1798 right -= count - 1;
1799 offset -= count - 1;
1800 if (num_pos) {
1801 for (cpos = 0; cpos < num_pos; cpos++) {
1802 if (tmp + i - count + 1 < pos[cpos]) {
1803 if (tmp + i + 1 < pos[cpos])
1804 pos[cpos] -= count;
1805 else
1806 pos[cpos] = tmp + i - count + 1;
1807 ++pos[cpos];
1808 }
1809 }
1810 }
1811 else {
1812 if (tmp + i - count + 1 < ipos) {
1813 if (tmp + i + 1 < ipos)
1814 ipos -= count;
1815 else
1816 ipos = tmp + i - count + 1;
1817 ++ipos;
1818 }
1819 }
1820 }
1821 if (count)
1822 --count;
1823 if (zero) {
1824 count = column = 0;
1825 zero = False0;
1826 if (tab_count) {
1827 tab_column = tab_index = 0;
1828 TAB_SIZE = *char_tabs;
1829 }
1830 }
1831 else if (i < block.length)
1832 count = 0;
1833 tmp = left + offset;
1834 position = XawTextSourceRead(ctx->text.source, tmp,
1835 &block, right - tmp);
1836 if (tmp == position || tmp >= right)
1837 done = True1;
1838 }
1839 if (!num_pos)
1840 ctx->text.insertPos = ipos;
1841
1842 return (True1);
1843}
1844
1845static Boolint
1846Untabify(TextWidget ctx, XawTextPosition left, XawTextPosition right,
1847 XawTextPosition *pos, int num_pos, XawTextBlock *save)
1848{
1849 Boolint done, zero;
1850 int i, cpos, count = 0, diff = 0;
1851 XawTextBlock block, text;
1852 XawTextPosition ipos, position = left, tmp = left;
1853 TextSinkObject sink = (TextSinkObject)ctx->text.sink;
1854 short *char_tabs = sink->text_sink.char_tabs;
1855 int tab_count = sink->text_sink.tab_count;
1856 int tab_index = 0, tab_column = 0, tab_base = 0;
1857 static char *tabs = " ";
1858
1859 text.firstPos = 0;
1860 text.format = XawFmt8Bit;
1861 text.ptr = tabs;
1862
1863 position = XawTextSourceRead(ctx->text.source, position,
1864 &block, right - left);
1865 ipos = ctx->text.insertPos;
1866 done = False0;
1867 zero = False0;
1868 while (!done) {
1869 if (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit)))
1870 for (i = 0; i < block.length; i++) {
1871 if (block.ptr[i] != '\t') {
1872 ++count;
1873 if (block.ptr[i] == '\n') {
1874 zero = True1;
1875 break;
1876 }
1877 }
1878 else
1879 break;
1880 }
1881 else {
1882 wchar_t *wptr = (wchar_t*)block.ptr;
1883 for (i = 0; i < block.length; i++)
1884 if (wptr[i] != _Xaw_atowc('\t')) {
1885 ++count;
1886 if (wptr[i] != _Xaw_atowc('\n')) {
1887 zero = True1;
1888 break;
1889 }
1890 }
1891 else
1892 break;
1893 }
1894 if (!zero && i < block.length) {
1895 if (tab_count) {
1896 while (tab_base + tab_column <= count) {
1897 for (; tab_index < tab_count; ++tab_index)
1898 if (tab_base + char_tabs[tab_index] > count) {
1899 tab_column = char_tabs[tab_index];
1900 break;
1901 }
1902 if (tab_index >= tab_count) {
1903 tab_base += char_tabs[tab_count - 1];
1904 tab_column = tab_index = 0;
1905 }
1906 }
1907 text.length = (tab_base + tab_column) - count;
1908 if (text.length > 8) {
1909 int j;
1910
1911 text.ptr = XtMalloc(text.length);
1912 for (j = 0; j < text.length; j++)
1913 text.ptr[j] = ' ';
1914 }
1915 else
1916 text.ptr = tabs;
1917 }
1918 else
1919 text.length = DEFAULT_TAB_SIZE8 - (count % DEFAULT_TAB_SIZE8);
1920 CHECK_SAVE();
1921 if (_XawTextReplace(ctx, tmp + i, tmp + i + 1, &text)) {
1922 if (tab_count && text.length > 8)
1923 XtFree(text.ptr);
1924 return (False0);
1925 }
1926 if (tab_count && text.length > 8)
1927 XtFree(text.ptr);
1928 count += text.length;
1929 right += text.length - 1;
1930 if (num_pos) {
1931 for (cpos = 0; cpos < num_pos; cpos++) {
1932 if (tmp + i < pos[cpos]) {
1933 if (tmp + i + 1 < pos[cpos])
1934 --pos[cpos];
1935 else
1936 pos[cpos] = tmp + i;
1937 pos[cpos] += text.length;
1938 }
1939 }
1940 }
1941 else {
1942 if (tmp + i < ipos) {
1943 if (tmp + i + 1 < ipos)
1944 --ipos;
1945 else
1946 ipos = tmp + i;
1947 ipos += text.length;
1948 }
1949 }
1950 }
1951 tmp = left + count + diff;
1952 if (zero) {
1953 diff += count;
1954 count = 0;
1955 zero = False0;
1956 if (tab_count)
1957 tab_base = tab_column = tab_index = 0;
1958 }
1959 position = XawTextSourceRead(ctx->text.source, tmp,
1960 &block, right - tmp);
1961 if (tmp == position || tmp >= right)
1962 done = True1;
1963 }
1964 if (!num_pos)
1965 ctx->text.insertPos = ipos;
1966
1967 return (True1);
1968}
1969
1970static int
1971FormatText(TextWidget ctx, XawTextPosition left, Boolint force,
1972 XawTextPosition *pos, int num_pos)
1973{
1974 char *ptr = NULL((void*)0);
1975 Boolint freepos = False0, undo, paragraph = pos != NULL((void*)0);
1976 int i, result;
1977 XawTextBlock block, *text;
1978 XawTextPosition end = ctx->text.lastPos, buf[32];
1979 TextSrcObject src = (TextSrcObject)ctx->text.source;
1980 XawTextPosition right = SrcScanXawTextSourceScan(ctx->text.source, left, XawstEOL,
1981 XawsdRight, 1, False0);
1982
1983 undo = src->textSrc.enable_undo && src->textSrc.undo_state == False0;
1984 if (undo) {
1985 if (!pos) {
1986 num_pos = src->textSrc.num_text;
1987 pos = XawStackAlloc(sizeof(XawTextPosition) * num_pos, buf)((sizeof(XawTextPosition) * num_pos) <= sizeof(buf) ? (XtPointer
)(buf) : XtMalloc((unsigned)(sizeof(XawTextPosition) * num_pos
)))
;
1988 for (i = 0; i < num_pos; i++)
1989 pos[i] = ((TextWidget)src->textSrc.text[i])->text.insertPos;
1990 freepos = True1;
1991 }
1992 else
1993 freepos = False0;
1994 src->textSrc.undo_state = True1;
1995 block.ptr = NULL((void*)0);
1996 block.firstPos = left;
1997 block.length = right - left;
1998 text = &block;
1999 }
2000 else
2001 text = NULL((void*)0);
2002
2003 result = DoFormatText(ctx, left, force, 1, text, pos, num_pos, paragraph);
2004 if (undo && result == XawEditDone0 && block.ptr) {
2005 char *lbuf, *rbuf;
2006 unsigned llen, rlen, size;
2007
2008 ptr = lbuf = block.ptr;
2009 llen = block.length;
2010 rlen = llen + (ctx->text.lastPos - end);
2011
2012 block.firstPos = 0;
2013 block.format = _XawTextFormat(ctx);
2014
2015 rbuf = _XawTextGetText(ctx, left, left + rlen);
2016
2017 size = XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) ? sizeof(wchar_t) : sizeof(char);
2018 if (llen != rlen || memcmp(lbuf, rbuf, llen * size)) {
2019 block.ptr = lbuf;
2020 block.length = llen;
2021 _XawTextReplace(ctx, left, left + rlen, &block);
2022
2023 src->textSrc.undo_state = False0;
2024 block.ptr = rbuf;
2025 block.length = rlen;
2026 _XawTextReplace(ctx, left, left + llen, &block);
2027 }
2028 else
2029 src->textSrc.undo_state = False0;
2030 XtFree(rbuf);
2031 }
2032 if (undo) {
2033 src->textSrc.undo_state = False0;
2034 if (freepos) {
2035 for (i = 0; i < num_pos; i++) {
2036 TextWidget tw = (TextWidget)src->textSrc.text[i];
2037 tw->text.insertPos = XawMin(XawMax(0, pos[i]), tw->text.lastPos)((((0) > (pos[i]) ? (0) : (pos[i]))) < (tw->text.lastPos
) ? (((0) > (pos[i]) ? (0) : (pos[i]))) : (tw->text.lastPos
))
;
2038 }
2039 XawStackFree(pos, buf)do { if ((pos) != (XtPointer)(buf)) XtFree((char *)pos); } while
(0)
;
2040 }
2041 if (ptr)
2042 XtFree(ptr);
2043 }
2044
2045 return (result);
2046}
2047
2048static int
2049DoFormatText(TextWidget ctx, XawTextPosition left, Boolint force, int level,
2050 XawTextBlock *save, XawTextPosition *pos, int num_pos,
2051 Boolint paragraph)
2052{
2053 XawTextPosition right = SrcScanXawTextSourceScan(ctx->text.source, left, XawstEOL,
2054 XawsdRight, 1, False0);
2055 XawTextPosition position, tmp, ipos;
2056 XawTextBlock block, text;
2057 char buf[128];
2058 wchar_t *wptr;
2059 int i, count, cpos;
2060 Boolint done, force2 = force, recurse = False0;
2061
2062 position = XawTextSourceRead(ctx->text.source, left, &block, right - left);
2063 if (block.length == 0 || left >= right ||
2064 (level == 1 && ((XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit)) &&
2065 block.ptr[0] != ' ' &&
2066 block.ptr[0] != '\t' &&
2067 !isalnum(*(unsigned char*)block.ptr)((*__ctype_b_loc ())[(int) ((*(unsigned char*)block.ptr))] &
(unsigned short int) _ISalnum)
) ||
2068 (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) &&
2069 _Xaw_atowc(XawSP0x20) != *(wchar_t*)block.ptr &&
2070 _Xaw_atowc(XawTAB0x09) != *(wchar_t*)block.ptr &&
2071 !iswalnum(*(wchar_t*)block.ptr)))))
2072 return (XawEditDone0);
2073
2074 if (level == 1 && !paragraph) {
2075 tmp = ctx->text.lastPos;
2076 if (Untabify(ctx, left, right, pos, num_pos, save) == False0)
2077 return (XawEditError1);
2078 right += ctx->text.lastPos - tmp;
2079 position = XawTextSourceRead(ctx->text.source, left, &block,
2080 right - left);
2081 }
2082
2083 text.firstPos = 0;
2084 text.format = XawFmt8Bit;
2085
2086 ipos = ctx->text.insertPos;
2087 count = 0;
2088 done = False0;
2089 while (!done) {
2090 if (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit))) {
2091 for (i = 0; i < block.length; i++)
2092 if (block.ptr[i] == ' ')
2093 ++count;
2094 else {
2095 done = True1;
2096 break;
2097 }
2098 }
2099 else {
2100 wptr = (wchar_t*)block.ptr;
2101 for (i = 0; i < block.length; i++)
2102 if (wptr[i] == _Xaw_atowc(' '))
2103 ++count;
2104 else {
2105 done = True1;
2106 break;
2107 }
2108 }
2109 tmp = position;
2110 position = XawTextSourceRead(ctx->text.source, position,
2111 &block, right - position);
2112 if (tmp == position)
2113 done = True1;
2114 }
2115 position = left + count;
2116 if (count < ctx->text.left_column) {
2117 int bytes = ctx->text.left_column - count;
2118
2119 text.ptr = XawStackAlloc(bytes, buf)((bytes) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned
)(bytes)))
;
2120 text.length = bytes;
2121 for (i = 0; i < bytes; i++)
2122 text.ptr[i] = ' ';
2123 CHECK_SAVE();
2124 if (_XawTextReplace(ctx, left, left, &text)) {
2125 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2126 return (XawEditError1);
2127 }
2128 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2129 right += bytes;
2130 if (num_pos) {
2131 for (cpos = 0; cpos < num_pos; cpos++)
2132 if (pos[cpos] >= left)
2133 pos[cpos] += bytes;
2134 }
2135 if (ipos >= left)
2136 ipos += bytes;
2137 count += bytes;
2138 }
2139
2140 done = False0;
2141 if (!paragraph && level == 1
2142 && ipos <= right && ipos - left > ctx->text.right_column) {
2143 XawTextPosition len = ctx->text.lastPos;
2144 int skip = ctx->text.justify == XawjustifyRight
2145 || ctx->text.justify == XawjustifyCenter ?
2146 ctx->text.left_column : count;
2147
2148 if (pos)
2149 for (i = 0; i < num_pos; i++)
2150 if (pos[i] == ipos)
2151 break;
2152
2153 StripSpaces(ctx, left + skip, right, pos, num_pos, save);
2154 right += ctx->text.lastPos - len;
2155 if (pos && i < num_pos)
2156 ipos = pos[i];
2157 else
2158 ipos = ctx->text.insertPos;
2159 done = ipos - left > ctx->text.right_column;
2160 count = skip + (count == skip + 1);
2161 }
2162 if ((paragraph || done) && right - left > ctx->text.right_column) {
2163 position = tmp = right;
2164 XawTextSourceRead(ctx->text.source, position - 1, &block, 1);
2165 if (block.length &&
2166 ((XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit)) &&
2167 block.ptr[0] == ' ') ||
2168 (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) &&
2169 _Xaw_atowc(XawSP0x20) == *(wchar_t*)block.ptr)))
2170 --position;
2171 while (position - left > ctx->text.right_column) {
2172 tmp = position;
2173 position = SrcScanXawTextSourceScan(ctx->text.source, position,
2174 XawstWhiteSpace, XawsdLeft, 1, True1);
2175 }
2176 if (position <= left + ctx->text.left_column)
2177 position = tmp;
2178 if (position > left && position - left > ctx->text.left_column
2179 && position != right) {
2180 text.ptr = "\n";
2181 text.length = 1;
2182 CHECK_SAVE();
2183 if (_XawTextReplace(ctx, position, position + 1, &text))
2184 return (XawEditError1);
2185 right = position;
2186 recurse = True1;
2187 force = True1;
2188 }
2189 }
2190
2191 if (force) {
2192 if (ctx->text.justify == XawjustifyCenter)
2193 count = ctx->text.right_column - (count - ctx->text.left_column);
2194 else
2195 count = ctx->text.right_column;
2196 if (count > right - left)
2197 count -= right - left;
2198 else
2199 count = 0;
2200 }
2201 else
2202 count = 0;
2203 if (count > 0) {
2204 switch (ctx->text.justify) {
2205 case XawjustifyLeft:
2206 break;
2207 case XawjustifyRight:
2208 case XawjustifyCenter:
2209 if (ctx->text.justify == XawjustifyCenter) {
2210 int alnum = 0;
2211
2212 if (!(count & 1)) {
2213 XawTextSourceRead(ctx->text.source, right, &block, 1);
2214 if ((XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit))
2215 && isalnum(*(unsigned char*)block.ptr)((*__ctype_b_loc ())[(int) ((*(unsigned char*)block.ptr))] &
(unsigned short int) _ISalnum)
) ||
2216 (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))
2217 && iswalnum(*(wchar_t*)block.ptr)))
2218 alnum = 1;
2219 }
2220 count = (count + alnum) >> 1;
2221 }
2222 text.ptr = XawStackAlloc(count, buf)((count) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned
)(count)))
;
2223 text.length = count;
2224 for (i = 0; i < count; i++)
2225 text.ptr[i] = ' ';
2226 CHECK_SAVE();
2227 if (_XawTextReplace(ctx, left, left, &text)) {
2228 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2229 return (XawEditError1);
2230 }
2231 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2232 position += count;
2233 right += count;
2234 if (num_pos) {
2235 for (cpos = 0; cpos < num_pos; cpos++)
2236 if (pos[cpos] > left)
2237 pos[cpos] += count;
2238 }
2239 else if (ipos > left)
2240 ipos += count;
2241 break;
2242 case XawjustifyFull:
2243 i = 0;
2244 tmp = left;
2245 /*CONSTCOND*/
2246 while (True1) {
2247 tmp = SrcScanXawTextSourceScan(ctx->text.source, tmp, XawstWhiteSpace,
2248 XawsdRight, 1, True1);
2249 if (tmp < right)
2250 ++i;
2251 else
2252 break;
2253 }
2254 if (i) {
2255 double inc, ii;
2256 int bytes, steps;
2257
2258 bytes = count;
2259 inc = ii = (count + .5) / (double)i;
2260
2261 steps = count;
2262 text.ptr = XawStackAlloc(steps, buf)((steps) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned
)(steps)))
;
2263 for (i = 0; i < steps; i++)
2264 text.ptr[i] = ' ';
2265 tmp = left;
2266 CHECK_SAVE();
2267 while (bytes) {
2268 steps = 1;
2269 while (inc + ii < 1) {
2270 ++steps;
2271 inc += ii;
2272 }
2273 tmp = SrcScanXawTextSourceScan(ctx->text.source, tmp, XawstWhiteSpace,
2274 XawsdRight, steps, True1);
2275 if (bytes > inc)
2276 text.length = (int)inc;
2277 else
2278 text.length = bytes;
2279 bytes -= text.length;
2280 if (_XawTextReplace(ctx, tmp, tmp, &text)) {
2281 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2282 return (XawEditError1);
2283 }
2284 if (num_pos) {
2285 for (cpos = 0; cpos < num_pos; cpos++)
2286 if (tmp <= pos[cpos])
2287 pos[cpos] += text.length;
2288 }
2289 else if (tmp <= ipos)
2290 ipos += text.length;
2291 inc -= (int)inc;
2292 inc += ii;
2293 }
2294 position += count;
2295 right += count;
2296 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2297 }
2298 break;
2299 }
2300 }
2301
2302 if (!num_pos)
2303 ctx->text.insertPos = XawMin(ipos, ctx->text.lastPos)((ipos) < (ctx->text.lastPos) ? (ipos) : (ctx->text.
lastPos))
;
2304
2305 return (recurse ? DoFormatText(ctx, position + 1,
2306 ctx->text.justify != XawjustifyFull
2307 && (force2 || paragraph),
2308 ++level, save, pos, num_pos, paragraph)
2309 : XawEditDone0);
2310}
2311#undef CHECK_SAVE
2312
2313/*ARGSUSED*/
2314static void
2315Indent(Widget w, XEvent *event, String *params, Cardinal *num_params)
2316{
2317 TextWidget ctx = (TextWidget)w;
2318 TextSrcObject src = (TextSrcObject)ctx->text.source;
2319 XawTextPosition from, to, tmp, end = 0, *pos, *posbuf[32];
2320 char buf[32];
2321 XawTextBlock text;
2322 int i, spaces = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
2323 char *lbuf = NULL((void*)0), *rbuf;
2324 unsigned llen = 0, rlen, size;
2325 Boolint undo = src->textSrc.enable_undo && src->textSrc.undo_state == False0;
2326 Boolint format = ctx->text.auto_fill
2327 && ctx->text.left_column < ctx->text.right_column;
2328
2329 text.firstPos = 0;
2330 text.format = XawFmt8Bit;
2331 text.ptr = "";
2332
2333 StartAction(ctx, event);
2334
2335 pos = XawStackAlloc(sizeof(XawTextPosition) * src->textSrc.num_text, posbuf)((sizeof(XawTextPosition) * src->textSrc.num_text) <= sizeof
(posbuf) ? (XtPointer)(posbuf) : XtMalloc((unsigned)(sizeof(XawTextPosition
) * src->textSrc.num_text)))
;
2336 for (i = 0; i < src->textSrc.num_text; i++)
2337 pos[i] = ((TextWidget)src->textSrc.text[i])->text.insertPos;
2338
2339 if (!GetBlockBoundaries(ctx, &from, &to)) {
2340 EndAction(ctx);
2341 XawStackFree(pos, posbuf)do { if ((pos) != (XtPointer)(posbuf)) XtFree((char *)pos); }
while (0)
;
2342 return;
2343 }
2344
2345 if (undo) {
2346 llen = to - from;
2347 end = ctx->text.lastPos;
2348 lbuf = _XawTextGetText(ctx, from, to);
2349 src->textSrc.undo_state = True1;
2350 }
2351
2352 tmp = ctx->text.lastPos;
2353 if (!Untabify(ctx, from, to, pos, src->textSrc.num_text, NULL((void*)0))) {
2354 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 0);
2355 EndAction(ctx);
2356 XawStackFree(pos, posbuf)do { if ((pos) != (XtPointer)(posbuf)) XtFree((char *)pos); }
while (0)
;
2357 if (undo) {
2358 src->textSrc.undo_state = True1;
2359 XtFree(lbuf);
2360 }
2361 return;
2362 }
2363 to += ctx->text.lastPos - tmp;
2364
2365 tmp = from;
2366
2367 if (spaces > 0) {
2368 text.ptr = XawStackAlloc(spaces, buf)((spaces) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned
)(spaces)))
;
2369 for (i = 0; i < spaces; i++)
2370 text.ptr[i] = ' ';
2371
2372 text.length = spaces;
2373 while (tmp < to) {
2374 _XawTextReplace(ctx, tmp, tmp, &text);
2375
2376 for (i = 0; i < src->textSrc.num_text; i++)
2377 if (tmp < pos[i])
2378 pos[i] += spaces;
2379
2380 to += spaces;
2381 tmp = SrcScanXawTextSourceScan(ctx->text.source, tmp, XawstEOL, XawsdRight, 1, True1);
2382 }
2383 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2384 }
2385 else {
2386 int min = 32767;
2387
2388 text.length = 0;
2389 tmp = from;
2390
2391 /* find the amount of spaces to cut */
2392 while (tmp < to) {
2393 (void)BlankLine(w, tmp, &i);
2394 if (i < min)
2395 min = i;
2396 tmp = SrcScanXawTextSourceScan(ctx->text.source, tmp, XawstEOL, XawsdRight, 1, True1);
2397 }
2398 spaces = XawMin(-spaces, min)((-spaces) < (min) ? (-spaces) : (min));
2399
2400 /* cut the spaces */
2401 tmp = from;
2402 while (tmp < to) {
2403 _XawTextReplace(ctx, tmp, tmp + spaces, &text);
2404
2405 for (i = 0; i < src->textSrc.num_text; i++)
2406 if (tmp < pos[i]) {
2407 if (tmp + spaces < pos[i])
2408 pos[i] -= spaces;
2409 else
2410 pos[i] = tmp;
2411 }
2412
2413 to -= spaces;
2414 tmp = SrcScanXawTextSourceScan(ctx->text.source, tmp, XawstEOL, XawsdRight, 1, True1);
2415 }
2416 }
2417
2418 if (!format)
2419 Tabify(ctx, from, to, pos, src->textSrc.num_text, NULL((void*)0));
2420
2421 if (undo) {
2422 rlen = llen + (ctx->text.lastPos - end);
2423 rbuf = _XawTextGetText(ctx, from, from + rlen);
2424
2425 text.format = _XawTextFormat(ctx);
2426 size = XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) ? sizeof(wchar_t) : sizeof(char);
2427 if (llen != rlen || memcmp(lbuf, rbuf, llen * size)) {
2428 text.ptr = lbuf;
2429 text.length = llen;
2430 _XawTextReplace(ctx, from, from + rlen, &text);
2431
2432 src->textSrc.undo_state = False0;
2433 text.ptr = rbuf;
2434 text.length = rlen;
2435 _XawTextReplace(ctx, from, from + llen, &text);
2436 }
2437 else
2438 src->textSrc.undo_state = False0;
2439 XtFree(lbuf);
2440 XtFree(rbuf);
2441 }
2442
2443 for (i = 0; i < src->textSrc.num_text; i++) {
2444 TextWidget tw = (TextWidget)src->textSrc.text[i];
2445
2446 tw->text.insertPos = XawMin(XawMax(0, pos[i]), tw->text.lastPos)((((0) > (pos[i]) ? (0) : (pos[i]))) < (tw->text.lastPos
) ? (((0) > (pos[i]) ? (0) : (pos[i]))) : (tw->text.lastPos
))
;
2447 }
2448 XawStackFree(pos, posbuf)do { if ((pos) != (XtPointer)(posbuf)) XtFree((char *)pos); }
while (0)
;
2449 ctx->text.showposition = True1;
2450
2451 EndAction(ctx);
2452}
2453
2454/*ARGSUSED*/
2455static void
2456ToggleOverwrite(Widget w, XEvent *event, String *params, Cardinal *num_params)
2457{
2458 TextWidget ctx = (TextWidget)w;
2459
2460 ctx->text.overwrite = !ctx->text.overwrite;
2461
2462 /* call information callback */
2463 _XawTextSetLineAndColumnNumber(ctx, True1);
2464}
2465#endif /* OLDXAW */
2466
2467/*
2468 * Insertion Routines
2469 */
2470static int
2471InsertNewLineAndBackupInternal(TextWidget ctx)
2472{
2473 int count, error = XawEditDone0, mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
2474#ifndef OLDXAW
2475 XawTextPosition position;
2476#endif
2477 XawTextBlock text;
2478 char buf[32];
2479
2480 if (mult < 0) {
2481 ctx->text.mult = 1;
2482 return (XawEditError1);
2483 }
2484
2485 text.format = _XawTextFormat(ctx);
2486 text.length = mult;
2487 text.firstPos = 0;
2488
2489 if (text.format == XawFmtWide) {
2490 wchar_t *wptr;
2491
2492 text.ptr = XawStackAlloc(sizeof(wchar_t) * mult, buf)((sizeof(wchar_t) * mult) <= sizeof(buf) ? (XtPointer)(buf
) : XtMalloc((unsigned)(sizeof(wchar_t) * mult)))
;
2493 wptr = (wchar_t *)text.ptr;
2494 for (count = 0; count < mult; count++)
2495 wptr[count] = _Xaw_atowc(XawLF0x0a);
2496 }
2497 else {
2498 text.ptr = XawStackAlloc(sizeof(char) * mult, buf)((sizeof(char) * mult) <= sizeof(buf) ? (XtPointer)(buf) :
XtMalloc((unsigned)(sizeof(char) * mult)))
;
2499 for (count = 0; count < mult; count++)
2500 text.ptr[count] = XawLF0x0a;
2501 }
2502
2503#ifndef OLDXAW
2504 position = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
2505 XawstEOL, XawsdLeft, 1, False0);
2506#endif
2507 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
2508 XBell( XtDisplay(ctx)(((ctx)->core.screen)->display), 50);
2509 error = XawEditError1;
2510 }
2511 else {
2512 ctx->text.showposition = TRUE1;
2513 ctx->text.insertPos += text.length;
2514 }
2515
2516 XawStackFree(text.ptr, buf)do { if ((text.ptr) != (XtPointer)(buf)) XtFree((char *)text.
ptr); } while (0)
;
2517
2518#ifndef OLDXAW
2519 if (ctx->text.auto_fill && error == XawEditDone0)
2520 (void)FormatText(ctx, position, ctx->text.justify != XawjustifyFull,
2521 NULL((void*)0), 0);
2522#endif
2523
2524 return (error);
2525}
2526
2527/*ARGSUSED*/
2528static void
2529InsertNewLineAndBackup(Widget w, XEvent *event, String *p, Cardinal *n)
2530{
2531 TextWidget ctx = (TextWidget)w;
2532 XawTextPosition insertPos = ctx->text.insertPos;
2533
2534 StartAction((TextWidget)w, event);
2535 (void)InsertNewLineAndBackupInternal(ctx);
2536 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, insertPos, XawstEOL,
2537 XawsdRight, 1, False0);
2538 EndAction((TextWidget)w);
2539}
2540
2541static int
2542LocalInsertNewLine(TextWidget ctx, XEvent *event)
2543{
2544 int error;
2545
2546 StartAction(ctx, event);
2547 error = InsertNewLineAndBackupInternal(ctx);
2548 ctx->text.from_left = -1;
2549 EndAction(ctx);
2550
2551 return (error);
2552}
2553
2554/*ARGSUSED*/
2555static void
2556InsertNewLine(Widget w, XEvent *event, String *p, Cardinal *n)
2557{
2558 (void)LocalInsertNewLine((TextWidget)w, event);
2559}
2560
2561/*ARGSUSED*/
2562static void
2563InsertNewLineAndIndent(Widget w, XEvent *event, String *p, Cardinal *n)
2564{
2565 XawTextBlock text;
2566 XawTextPosition pos1;
2567 int length;
2568 TextWidget ctx = (TextWidget)w;
2569 String line_to_ip;
2570
2571 StartAction(ctx, event);
2572 pos1 = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
2573 XawstEOL, XawsdLeft, 1, False0);
2574
2575 line_to_ip = _XawTextGetText(ctx, pos1, ctx->text.insertPos);
2576
2577 text.format = _XawTextFormat(ctx);
2578 text.firstPos = 0;
2579
2580 if (text.format == XawFmtWide) {
2581 wchar_t *ptr;
2582
2583 text.ptr = XtMalloc((2 + wcslen((wchar_t*)line_to_ip))
2584 * sizeof(wchar_t));
2585 ptr = (wchar_t*)text.ptr;
2586 ptr[0] = _Xaw_atowc(XawLF0x0a);
2587 wcscpy((wchar_t*)++ptr, (wchar_t*)line_to_ip);
2588
2589 length = wcslen((wchar_t*)text.ptr);
2590 while (length && (iswspace(*ptr)((((*ptr) & ~0x7f) == 0) && ((*__ctype_b_loc ())[
(int) ((((*ptr) & 0x7f)))] & (unsigned short int) _ISspace
))
|| *ptr == _Xaw_atowc(XawTAB0x09)))
2591 ptr++, length--;
2592 *ptr = (wchar_t)0;
2593 text.length = wcslen((wchar_t*)text.ptr);
2594 }
2595 else {
2596 char *ptr;
2597
2598 length = strlen(line_to_ip);
2599 text.ptr = XtMalloc((2 + length) * sizeof(char));
2600 ptr = text.ptr;
2601 ptr[0] = XawLF0x0a;
2602 strcpy(++ptr, line_to_ip);
2603
2604 length++;
2605 while (length && (isspace(*ptr)((*__ctype_b_loc ())[(int) ((*ptr))] & (unsigned short int
) _ISspace)
|| (*ptr == XawTAB0x09)))
2606 ptr++, length--;
2607 *ptr = '\0';
2608 text.length = strlen(text.ptr);
2609 }
2610 XtFree(line_to_ip);
2611
2612 if (_XawTextReplace(ctx,ctx->text.insertPos, ctx->text.insertPos, &text)) {
2613 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 50);
2614 XtFree(text.ptr);
2615 EndAction(ctx);
2616 return;
2617 }
2618
2619 XtFree(text.ptr);
2620 ctx->text.from_left = -1;
2621 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.old_insert,
2622 XawstPositions, XawsdRight, text.length, True1);
2623 EndAction(ctx);
2624}
2625
2626/*
2627 * Selection Routines
2628 */
2629static void
2630SelectWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
2631{
2632 TextWidget ctx = (TextWidget)w;
2633 XawTextPosition l, r;
2634
2635 StartAction(ctx, event);
2636 l = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
2637 XawstWhiteSpace, XawsdLeft, 1, False0);
2638 r = SrcScanXawTextSourceScan(ctx->text.source, l, XawstWhiteSpace, XawsdRight, 1, False0);
2639 _XawTextSetSelection(ctx, l, r, params, *num_params);
2640 EndAction(ctx);
2641}
2642
2643static void
2644SelectAll(Widget w, XEvent *event, String *params, Cardinal *num_params)
2645{
2646 TextWidget ctx = (TextWidget)w;
2647
2648 StartAction(ctx, event);
2649 _XawTextSetSelection(ctx,zeroPosition((XawTextPosition)0),ctx->text.lastPos,params,*num_params);
2650 EndAction(ctx);
2651}
2652
2653static void
2654ModifySelection(TextWidget ctx, XEvent *event,
2655 XawTextSelectionMode mode,
2656 XawTextSelectionAction action,
2657 String *params, Cardinal *num_params)
2658{
2659#ifndef OLDXAW
2660 int old_y = ctx->text.ev_y;
2661#endif
2662
2663 StartAction(ctx, event);
2664 NotePosition(ctx, event);
2665
2666#ifndef OLDXAW
2667 if (event->type == MotionNotify6) {
2668 if (ctx->text.ev_y <= ctx->text.margin.top) {
2669 if (old_y >= ctx->text.ev_y)
2670 XawTextScroll(ctx, -1, 0);
2671 }
2672 else if (ctx->text.ev_y >= XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - ctx->text.margin.bottom) {
2673 if (old_y <= ctx->text.ev_y
2674 && !IsPositionVisible(ctx, ctx->text.lastPos)(ctx->text.lastPos >= ctx->text.lt.info[0].position &&
ctx->text.lastPos < ctx->text.lt.info[ctx->text.
lt.lines].position)
)
2675 XawTextScroll(ctx, 1, 0);
2676 }
2677 }
2678#endif
2679 ctx->text.from_left = -1;
2680 _XawTextAlterSelection(ctx, mode, action, params, num_params);
2681
2682 EndAction(ctx);
2683}
2684
2685static void
2686SelectStart(Widget w, XEvent *event, String *params, Cardinal *num_params)
2687{
2688 TextWidget ctx = (TextWidget)w;
2689
2690#ifndef OLDXAW
2691 if (!ctx->text.selection_state) {
2692 ctx->text.selection_state = True1;
2693#endif
2694 ModifySelection(ctx, event,
2695 XawsmTextSelect, XawactionStart, params, num_params);
2696#ifndef OLDXAW
2697 }
2698#endif
2699}
2700
2701static void
2702SelectAdjust(Widget w, XEvent *event, String *params, Cardinal *num_params)
2703{
2704 TextWidget ctx = (TextWidget)w;
2705
2706#ifndef OLDXAW
2707 if (ctx->text.selection_state)
2708#endif
2709 ModifySelection(ctx, event,
2710 XawsmTextSelect, XawactionAdjust, params, num_params);
2711}
2712
2713static void
2714SelectEnd(Widget w, XEvent *event, String *params, Cardinal *num_params)
2715{
2716 TextWidget ctx = (TextWidget)w;
2717
2718#ifndef OLDXAW
2719 if (ctx->text.selection_state) {
2720 ctx->text.selection_state = False0;
2721#endif
2722 ModifySelection(ctx, event,
2723 XawsmTextSelect, XawactionEnd, params, num_params);
2724#ifndef OLDXAW
2725 }
2726#endif
2727}
2728
2729static void
2730ExtendStart(Widget w, XEvent *event, String *params, Cardinal *num_params)
2731{
2732 TextWidget ctx = (TextWidget)w;
2733
2734#ifndef OLDXAW
2735 if (!ctx->text.selection_state) {
2736 ctx->text.selection_state = True1;
2737#endif
2738 ModifySelection(ctx, event,
2739 XawsmTextExtend, XawactionStart, params, num_params);
2740#ifndef OLDXAW
2741 }
2742#endif
2743}
2744
2745static void
2746ExtendAdjust(Widget w, XEvent *event, String *params, Cardinal *num_params)
2747{
2748 TextWidget ctx = (TextWidget)w;
2749
2750#ifndef OLDXAW
2751 if (ctx->text.selection_state)
2752#endif
2753 ModifySelection(ctx, event,
2754 XawsmTextExtend, XawactionAdjust, params, num_params);
2755}
2756
2757static void
2758ExtendEnd(Widget w, XEvent *event, String *params, Cardinal *num_params)
2759{
2760 TextWidget ctx = (TextWidget)w;
2761
2762#ifndef OLDXAW
2763 if (ctx->text.selection_state) {
2764 ctx->text.selection_state = False0;
2765#endif
2766 ModifySelection(ctx, event,
2767 XawsmTextExtend, XawactionEnd, params, num_params);
2768#ifndef OLDXAW
2769 }
2770#endif
2771}
2772
2773static void
2774SelectSave(Widget w, XEvent *event, String *params, Cardinal *num_params)
2775{
2776 int num_atoms;
2777 Atom *sel;
2778 Display *dpy = XtDisplay(w)(((w)->core.screen)->display);
2779 Atom selections[256];
2780
2781 StartAction((TextWidget)w, event);
2782 num_atoms = *num_params;
2783 if (num_atoms > 256)
2784 num_atoms = 256;
2785 for (sel=selections; --num_atoms >= 0; sel++, params++)
2786 *sel = XInternAtom(dpy, *params, False0);
2787 num_atoms = *num_params;
2788 _XawTextSaltAwaySelection((TextWidget)w, selections, num_atoms);
2789 EndAction((TextWidget)w);
2790}
2791
2792/*
2793 * Misc. Routines
2794 */
2795/*ARGSUSED*/
2796static void
2797SetKeyboardFocus(Widget w, XEvent *event, String *params, Cardinal *num_params)
2798{
2799 Widget shell, parent;
2800
2801 shell = parent = w;
2802 while (parent) {
2803 if (XtIsShell(shell = parent)(((Object)(shell = parent))->object.widget_class->core_class
.class_inited & 0x20)
)
2804 break;
2805 parent = XtParent(parent)((parent)->core.parent);
2806 }
2807 XtSetKeyboardFocus(shell, w);
2808}
2809
2810/*ARGSUSED*/
2811static void
2812RedrawDisplay(Widget w, XEvent *event, String *p, Cardinal *n)
2813{
2814 StartAction((TextWidget)w, event);
2815 _XawTextClearAndCenterDisplay((TextWidget)w);
2816 EndAction((TextWidget)w);
2817}
2818
2819/* This is kind of a hack, but, only one text widget can have focus at
2820 * a time on one display. There is a problem in the implementation of the
2821 * text widget, the scrollbars can not be adressed via editres, since they
2822 * are not children of a subclass of composite.
2823 * The focus variable is required to make sure only one text window will
2824 * show a block cursor at one time.
2825 */
2826struct _focus { Display *display; Widget widget; };
2827static struct _focus *focus;
2828static Cardinal num_focus;
2829
2830/*ARGSUSED*/
2831static void
2832DestroyFocusCallback(Widget w, XtPointer user_data, XtPointer call_data)
2833{
2834 struct _focus *f = (struct _focus*)(user_data);
2835
2836 if (f->widget == w)
2837 f->widget = NULL((void*)0);
2838}
2839
2840/*ARGSUSED*/
2841static void
2842TextFocusIn(Widget w, XEvent *event, String *p, Cardinal *n)
2843{
2844 TextWidget ctx = (TextWidget)w;
2845 Boolint display_caret = ctx->text.display_caret;
2846 int i;
2847
2848 if (event->xfocus.detail == NotifyPointer5)
2849 return;
2850
2851 if (event->xfocus.send_event) {
2852 Window root, child;
2853 int rootx, rooty, x, y;
2854 unsigned int mask;
2855
2856 if (ctx->text.hasfocus)
2857 return;
2858
2859 if (XQueryPointer(XtDisplay(w)(((w)->core.screen)->display), XtWindow(w)((w)->core.window), &root, &child,
2860 &rootx, &rooty, &x, &y, &mask)) {
2861 if (child)
2862 return;
2863 }
2864 }
2865
2866 /* Let the input method know focus has arrived. */
2867 _XawImSetFocusValues(w, NULL((void*)0), 0);
2868
2869 if (display_caret)
2870 StartAction(ctx, event);
2871 ctx->text.hasfocus = TRUE1;
2872 if (display_caret)
2873 EndAction(ctx);
2874
2875 for (i = 0; i < num_focus; i++)
2876 if (focus[i].display == XtDisplay(w)(((w)->core.screen)->display))
2877 break;
2878 if (i >= num_focus) {
2879 focus = (struct _focus*)
2880 XtRealloc((XtPointer)focus, sizeof(struct _focus) * (num_focus + 1));
2881 i = num_focus;
2882 focus[i].widget = NULL((void*)0);
2883 focus[i].display = XtDisplay(w)(((w)->core.screen)->display);
2884 num_focus++;
2885 }
2886 if (focus[i].widget != w) {
2887 Widget old = focus[i].widget;
2888
2889 focus[i].widget = w;
2890 if (old != NULL((void*)0)) {
2891 TextFocusOut(old, event, p, n);
2892 /* TextFocusOut may set it to NULL */
2893 focus[i].widget = w;
2894 }
2895 XtAddCallback(w, XtNdestroyCallback((char*)&XtStrings[169]),
2896 DestroyFocusCallback, (XtPointer)&focus[i]);
2897 }
2898}
2899
2900/*ARGSUSED*/
2901static void
2902TextFocusOut(Widget w, XEvent *event, String *p, Cardinal *n)
2903{
2904 TextWidget ctx = (TextWidget)w;
2905 Boolint display_caret = ctx->text.display_caret;
2906 Widget shell;
2907 Window window;
2908 int i, revert;
2909
2910 shell = w;
2911 while (shell) {
2912 if (XtIsShell(shell)(((Object)(shell))->object.widget_class->core_class.class_inited
& 0x20)
)
2913 break;
2914 shell = XtParent(shell)((shell)->core.parent);
2915 }
2916
2917 for (i = 0; i < num_focus; i++)
2918 if (focus[i].display == XtDisplay(w)(((w)->core.screen)->display))
2919 break;
2920 XGetInputFocus(XtDisplay(w)(((w)->core.screen)->display), &window, &revert);
2921 if ((XtWindow(shell)((shell)->core.window) == window &&
2922 (i < num_focus && focus[i].widget == w))
2923 || event->xfocus.detail == NotifyPointer5)
2924 return;
2925
2926 if (i < num_focus && focus[i].widget) {
2927 XtRemoveCallback(focus[i].widget, XtNdestroyCallback((char*)&XtStrings[169]),
2928 DestroyFocusCallback, (XtPointer)&focus[i]);
2929 focus[i].widget = NULL((void*)0);
2930 }
2931
2932 /* Let the input method know focus has left.*/
2933 _XawImUnsetFocus(w);
2934
2935 if (display_caret)
2936 StartAction(ctx, event);
2937 ctx->text.hasfocus = FALSE0;
2938 if (display_caret)
2939 EndAction(ctx);
2940}
2941
2942/*ARGSUSED*/
2943static void
2944TextEnterWindow(Widget w, XEvent *event, String *params, Cardinal *num_params)
2945{
2946 TextWidget ctx = (TextWidget)w;
2947
2948 if ((event->xcrossing.detail != NotifyInferior2) && event->xcrossing.focus
2949 && !ctx->text.hasfocus)
2950 _XawImSetFocusValues(w, NULL((void*)0), 0);
2951}
2952
2953/*ARGSUSED*/
2954static void
2955TextLeaveWindow(Widget w, XEvent *event, String *params, Cardinal *num_params)
2956{
2957 TextWidget ctx = (TextWidget)w;
2958
2959 if ((event->xcrossing.detail != NotifyInferior2) && event->xcrossing.focus
2960 && !ctx->text.hasfocus)
2961 _XawImUnsetFocus(w);
2962}
2963
2964/*
2965 * Function:
2966 * AutoFill
2967 * Arguments: ctx - The text widget.
2968 *
2969 * Description:
2970 * Breaks the line at the previous word boundry when
2971 * called inside InsertChar.
2972 */
2973static void
2974AutoFill(TextWidget ctx)
2975{
2976 int width, height, x, line_num, max_width;
2977 XawTextPosition ret_pos;
2978 XawTextBlock text;
2979 XRectangle cursor;
2980 wchar_t wc_buf[2];
2981
2982 for (line_num = 0; line_num < ctx->text.lt.lines ; line_num++)
2983 if (ctx->text.lt.info[line_num].position >= ctx->text.insertPos)
2984 break;
2985 if (line_num)
2986 line_num--; /* backup a line. */
2987
2988 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
2989 max_width = Max(0, (int)XtWidth(ctx) - RHMargins(ctx) - cursor.width)(((0) > ((int)(((RectObj)ctx)->rectangle.width) - ((ctx
)->text.r_margin.left + (ctx)->text.r_margin.right) - cursor
.width)) ? (0) : ((int)(((RectObj)ctx)->rectangle.width) -
((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
) - cursor.width))
;
2990
2991 x = ctx->text.r_margin.left;
2992 XawTextSinkFindPosition(ctx->text.sink, ctx->text.lt.info[line_num].position,
2993 x, max_width, True1, &ret_pos,
2994 &width, &height);
2995
2996 if (ret_pos <= ctx->text.lt.info[line_num].position
2997 || ret_pos >= ctx->text.insertPos || ret_pos < 1)
2998 return;
2999
3000 XawTextSourceRead(ctx->text.source, ret_pos - 1, &text, 1);
3001
3002 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
3003 wc_buf[0] = *(wchar_t *)text.ptr;
3004 if (wc_buf[0] != _Xaw_atowc(XawSP0x20) && wc_buf[0] != _Xaw_atowc(XawTAB0x09))
3005 /* Only eats white spaces */
3006 return;
3007
3008 text.format = XawFmtWide;
3009 text.ptr = (char *)wc_buf;
3010 wc_buf[0] = _Xaw_atowc(XawLF0x0a);
3011 wc_buf[1] = 0;
3012 }
3013 else {
3014 if (text.ptr[0] != XawSP0x20 && text.ptr[0] != XawTAB0x09)
3015 /* Only eats white spaces */
3016 return;
3017
3018 text.format = XawFmt8Bit;
3019 text.ptr = "\n";
3020 }
3021 text.length = 1;
3022 text.firstPos = 0;
3023
3024 if (_XawTextReplace(ctx, ret_pos - 1, ret_pos, &text))
3025 XBell(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), 0);
3026
3027 if (++ctx->text.insertPos > ctx->text.lastPos)
3028 ctx->text.insertPos = ctx->text.lastPos;
3029}
3030
3031/*ARGSUSED*/
3032static void
3033InsertChar(Widget w, XEvent *event, String *p, Cardinal *n)
3034{
3035 TextWidget ctx = (TextWidget)w;
3036 char *ptr, strbuf[128], ptrbuf[512];
3037 int count, error, mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
3038 KeySym keysym;
3039 XawTextBlock text;
3040#ifndef OLDXAW
3041 Boolint format = False0;
3042#endif
3043 XawTextPosition from, to;
3044
3045 if (XtIsSubclass (ctx->text.source, (WidgetClass) multiSrcObjectClass))
3046 text.length = _XawImWcLookupString(w, &event->xkey, (wchar_t*)strbuf,
3047 sizeof(strbuf), &keysym);
3048 else
3049 text.length = _XawLookupString(w, (XKeyEvent*)event, strbuf,
3050 sizeof(strbuf), &keysym);
3051
3052 if (text.length == 0)
3053 return;
3054
3055 if (mult < 0) {
3056 ctx->text.mult = 1;
3057 return;
3058 }
3059
3060 text.format = _XawTextFormat(ctx);
3061 if (text.format == XawFmtWide) {
3062 text.ptr = ptr = XawStackAlloc(sizeof(wchar_t) * text.length((sizeof(wchar_t) * text.length * mult) <= sizeof(ptrbuf) ?
(XtPointer)(ptrbuf) : XtMalloc((unsigned)(sizeof(wchar_t) * text
.length * mult)))
3063 * mult, ptrbuf)((sizeof(wchar_t) * text.length * mult) <= sizeof(ptrbuf) ?
(XtPointer)(ptrbuf) : XtMalloc((unsigned)(sizeof(wchar_t) * text
.length * mult)))
;
3064 for (count = 0; count < mult; count++) {
3065 memcpy((char*)ptr, (char *)strbuf, sizeof(wchar_t) * text.length);
3066 ptr += sizeof(wchar_t) * text.length;
3067 }
3068#ifndef OLDXAW
3069 if (mult == 1)
3070 format = ctx->text.left_column < ctx->text.right_column;
3071#endif
3072 }
3073 else { /* == XawFmt8Bit */
3074 text.ptr = ptr = XawStackAlloc(text.length * mult, ptrbuf)((text.length * mult) <= sizeof(ptrbuf) ? (XtPointer)(ptrbuf
) : XtMalloc((unsigned)(text.length * mult)))
;
3075 for (count = 0; count < mult; count++) {
3076 strncpy(ptr, strbuf, text.length);
3077 ptr += text.length;
3078 }
3079#ifndef OLDXAW
3080 if (mult == 1)
3081 format = ctx->text.left_column < ctx->text.right_column;
3082#endif
3083 }
3084
3085 text.length = text.length * mult;
3086 text.firstPos = 0;
3087
3088 StartAction(ctx, event);
3089#ifndef OLDXAW
3090 if (mult == 1)
3091 _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True1);
3092#endif
3093
3094 from = ctx->text.insertPos;
3095#ifndef OLDXAW
3096 if (ctx->text.overwrite) {
3097 XawTextPosition tmp;
3098
3099 to = from + mult;
3100 tmp = SrcScanXawTextSourceScan(ctx->text.source, from, XawstEOL, XawsdRight, 1, False0);
3101 if (to > tmp)
3102 to = tmp;
3103 }
3104 else
3105#endif
3106 to = from;
3107
3108 error = _XawTextReplace(ctx, from , to, &text);
3109
3110 if (error == XawEditDone0) {
3111 ctx->text.from_left = -1;
3112 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.old_insert,
3113 XawstPositions, XawsdRight,
3114 text.length, True1);
3115 if (ctx->text.auto_fill) {
3116#ifndef OLDXAW
3117 if (format)
3118 (void)FormatText(ctx, SrcScanXawTextSourceScan(ctx->text.source,
3119 ctx->text.insertPos, XawstEOL,
3120 XawsdLeft, 1, False0), False0,
3121 NULL((void*)0), 0);
3122 else
3123#endif
3124 AutoFill(ctx);
3125 }
3126 }
3127 else
3128 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 50);
3129
3130 XawStackFree(text.ptr, ptrbuf)do { if ((text.ptr) != (XtPointer)(ptrbuf)) XtFree((char *)text
.ptr); } while (0)
;
3131 EndAction(ctx);
3132
3133 if (error == XawEditDone0 && text.format == XawFmt8Bit && text.length == 1
3134 && (text.ptr[0] == ')' || text.ptr[0] == ']' || text.ptr[0] == '}')
3135 && ctx->text.display_caret) {
3136 static struct timeval tmval = {0, 500000};
3137 fd_set fds;
3138 Widget source = ctx->text.source;
3139 XawTextPosition insertPos = ctx->text.insertPos, pos, tmp, last;
3140 char left, right = text.ptr[0];
3141 int level = 0;
3142 XtAppContext app_context = XtWidgetToApplicationContext(w);
3143
3144 left = right == ')' ? '(' : right == ']' ? '[' : '{';
3145
3146 last = insertPos - 1;
3147 do {
3148 text.ptr[0] = left;
3149 pos = XawTextSourceSearch(source, last, XawsdLeft, &text);
3150 if (pos == XawTextSearchError(-12345L) || !IsPositionVisible(ctx, pos)(pos >= ctx->text.lt.info[0].position && pos <
ctx->text.lt.info[ctx->text.lt.lines].position)
)
3151 return;
3152 text.ptr[0] = right;
3153 tmp = pos;
3154 do {
3155 tmp = XawTextSourceSearch(source, tmp, XawsdRight, &text);
3156 if (tmp == XawTextSearchError(-12345L))
3157 return;
3158 if (tmp <= last)
3159 ++level;
3160 } while (++tmp <= last);
3161 --level;
3162 last = pos;
3163 } while (level);
3164
3165 StartAction(ctx, NULL((void*)0));
3166#ifndef OLDXAW
3167 _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True1);
3168#endif
3169 ctx->text.insertPos = pos;
3170 EndAction(ctx);
3171
3172 XSync(XtDisplay(w)(((w)->core.screen)->display), False0);
3173 while (XtAppPending(app_context) & XtIMXEvent1) {
3174 XEvent ev;
3175 if (! XtAppPeekEvent(app_context, &ev))
3176 break;
3177 if (ev.type == KeyPress2 || ev.type == ButtonPress4)
3178 break;
3179 XtAppProcessEvent(app_context, XtIMXEvent1);
3180 }
3181 FD_ZERO(&fds)do { unsigned int __i; fd_set *__arr = (&fds); for (__i =
0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) ((__arr
)->fds_bits)[__i] = 0; } while (0)
;
3182 FD_SET(ConnectionNumber(XtDisplay(w)), &fds)((void) (((&fds)->fds_bits)[(((((_XPrivDisplay)(((w)->
core.screen)->display))->fd)) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << (((((_XPrivDisplay)(((w)->
core.screen)->display))->fd)) % (8 * (int) sizeof (__fd_mask
))))))
;
3183 (void)select(FD_SETSIZE1024, &fds, NULL((void*)0), NULL((void*)0), &tmval);
3184 if (tmval.tv_usec != 500000)
3185 usleep(40000);
3186
3187 StartAction(ctx, NULL((void*)0));
3188#ifndef OLDXAW
3189 _XawSourceSetUndoMerge((TextSrcObject)ctx->text.source, True1);
3190#endif
3191 ctx->text.insertPos = insertPos;
3192 EndAction(ctx);
3193 }
3194}
3195
3196/* IfHexConvertHexElseReturnParam() - called by InsertString
3197 *
3198 * i18n requires the ability to specify multiple characters in a hexa-
3199 * decimal string at once. Since Insert was already too long, I made
3200 * this a seperate routine.
3201 *
3202 * A legal hex string in MBNF: '0' 'x' ( HEX-DIGIT HEX-DIGIT )+ '\0'
3203 *
3204 * WHEN: the passed param is a legal hex string
3205 * RETURNS: a pointer to that converted, null terminated hex string;
3206 * len_return holds the character count of conversion result
3207 *
3208 * WHEN: the passed param is not a legal hex string:
3209 * RETURNS: the parameter passed;
3210 * len_return holds the char count of param.
3211 *
3212 * NOTE: In neither case will there be strings to free. */
3213static char *
3214IfHexConvertHexElseReturnParam(char *param, int *len_return)
3215{
3216 char *p; /* steps through param char by char */
3217 char c; /* holds the character pointed to by p */
3218 int ind; /* steps through hexval buffer char by char */
3219 static char hexval[XawTextActionMaxHexChars100];
3220 Boolean first_digit;
3221
3222 /* reject if it doesn't begin with 0x and at least one more character. */
3223 if ((param[0] != '0') || (param[1] != 'x') || (param[2] == '\0')) {
3224 *len_return = strlen(param);
3225 return(param);
3226 }
3227
3228 /* Skip the 0x; go character by character shifting and adding. */
3229 first_digit = True1;
3230 ind = 0;
3231 hexval[ind] = '\0';
3232
3233 for (p = param+2; (c = *p) != '\0'; p++) {
3234 hexval[ind] *= 16;
3235 if (c >= '0' && c <= '9')
3236 hexval[ind] += c - '0';
3237 else if (c >= 'a' && c <= 'f')
3238 hexval[ind] += c - 'a' + 10;
3239 else if (c >= 'A' && c <= 'F')
3240 hexval[ind] += c - 'A' + 10;
3241 else
3242 break;
3243
3244 /* If we didn't break in preceding line, it was a good hex char. */
3245 if (first_digit)
3246 first_digit = False0;
3247 else {
3248 first_digit = True1;
3249 if (++ind < XawTextActionMaxHexChars100)
3250 hexval[ind] = '\0';
3251 else {
3252 *len_return = strlen(param);
3253 return(param);
3254 }
3255 }
3256 }
3257
3258 /* We quit the above loop becasue we hit a non hex. If that char is \0... */
3259 if ((c == '\0') && first_digit) {
3260 *len_return = strlen(hexval);
3261 return (hexval); /* ...it was a legal hex string, so return it */
3262 }
3263
3264 /* Else, there were non-hex chars or odd digit count, so... */
3265
3266 *len_return = strlen(param);
3267 return (param); /* ...return the verbatim string. */
3268}
3269
3270/* InsertString() - action
3271 *
3272 * Mostly rewritten for R6 i18n.
3273 *
3274 * Each parameter, in turn, will be insert at the inputPos
3275 * and the inputPos advances to the insertion's end.
3276 *
3277 * The exception is that parameters composed of the two
3278 * characters 0x, followed only by an even number of
3279 * hexadecimal digits will be converted to characters */
3280/*ARGSUSED*/
3281static void
3282InsertString(Widget w, XEvent *event, String *params, Cardinal *num_params)
3283{
3284 TextWidget ctx = (TextWidget)w;
3285 XtAppContext app_con = XtWidgetToApplicationContext(w);
3286 XawTextBlock text;
3287 int i;
3288
3289 text.firstPos = 0;
3290 text.format = _XawTextFormat(ctx);
3291
3292 StartAction(ctx, event);
3293 for (i = *num_params; i; i--, params++) { /* DO FOR EACH PARAMETER */
3294 text.ptr = IfHexConvertHexElseReturnParam(*params, &text.length);
3295
3296 if (text.length == 0)
3297 continue;
3298
3299 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) { /* convert to WC */
3300 int temp_len;
3301
3302 text.ptr = (char*)_XawTextMBToWC(XtDisplay(w)(((w)->core.screen)->display), text.ptr,
3303 &text.length);
3304
3305 if (text.ptr == NULL((void*)0)) { /* conversion error */
3306 XtAppWarningMsg(app_con,
3307 "insertString", "textAction", "XawError",
3308 "insert-string()'s parameter contents "
3309 "not legal in this locale.",
3310 NULL((void*)0), NULL((void*)0));
3311 ParameterError(w, *params);
3312 continue;
3313 }
3314
3315 /* Double check that the new input is legal: try to convert to MB. */
3316
3317 temp_len = text.length; /* _XawTextWCToMB's 3rd arg is in_out */
3318 if (_XawTextWCToMB(XtDisplay(w)(((w)->core.screen)->display), (wchar_t*)text.ptr, &temp_len)
3319 == NULL((void*)0)) {
3320 XtAppWarningMsg( app_con,
3321 "insertString", "textAction", "XawError",
3322 "insert-string()'s parameter contents "
3323 "not legal in this locale.",
3324 NULL((void*)0), NULL((void*)0));
3325 ParameterError(w, *params);
3326 continue;
3327 }
3328 } /* convert to WC */
3329
3330 if (_XawTextReplace(ctx, ctx->text.insertPos,
3331 ctx->text.insertPos, &text)) {
3332 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 50);
3333 EndAction(ctx);
3334 return;
3335 }
3336
3337 ctx->text.from_left = -1;
3338 /* Advance insertPos to the end of the string we just inserted. */
3339 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.old_insert,
3340 XawstPositions, XawsdRight, text.length,
3341 True1);
3342
3343 } /* DO FOR EACH PARAMETER */
3344
3345 EndAction(ctx);
3346}
3347
3348/* DisplayCaret() - action
3349 *
3350 * The parameter list should contain one boolean value. If the
3351 * argument is true, the cursor will be displayed. If false, not.
3352 *
3353 * The exception is that EnterNotify and LeaveNotify events may
3354 * have a second argument, "always". If they do not, the cursor
3355 * is only affected if the focus member of the event is true. */
3356static void
3357DisplayCaret(Widget w, XEvent *event, String *params, Cardinal *num_params)
3358{
3359 TextWidget ctx = (TextWidget)w;
3360 Boolint display_caret = True1;
3361
3362 if ((event->type == EnterNotify7 || event->type == LeaveNotify8)
3363 && ((*num_params >= 2) && (strcmp(params[1], "always") == 0))
3364 && (!event->xcrossing.focus))
3365 return;
3366
3367 if (*num_params > 0) { /* default arg is "True" */
3368 XrmValue from, to;
3369 from.size = strlen(from.addr = params[0]);
3370 XtConvert(w, XtRString((char*)&XtStrings[1797]), &from, XtRBoolean((char*)&XtStrings[1561]), &to);
3371
3372 if (to.addr != NULL((void*)0))
3373 display_caret = *(Boolean*)to.addr;
3374 if (ctx->text.display_caret == display_caret)
3375 return;
3376 }
3377 StartAction(ctx, event);
3378 ctx->text.display_caret = display_caret;
3379 EndAction(ctx);
3380}
3381
3382#ifndef OLDXAW
3383static void
3384Numeric(Widget w, XEvent *event, String *params, Cardinal *num_params)
3385{
3386 TextWidget ctx = (TextWidget)w;
3387
3388 if (ctx->text.numeric) {
3389 long mult = ctx->text.mult;
3390
3391 if (*num_params != 1 || strlen(params[0]) != 1
3392 || (!isdigit(params[0][0])((*__ctype_b_loc ())[(int) ((params[0][0]))] & (unsigned short
int) _ISdigit)
3393 && (params[0][0] != '-' || mult != 0))) {
3394 char err_buf[256];
3395
3396 if (event && (event->type == KeyPress2 || event->type == KeyRelease3)
3397 && params[0][0] == '-') {
3398 InsertChar(w, event, params, num_params);
3399 return;
3400 }
3401 snprintf(err_buf, sizeof(err_buf),
3402 "numeric: Invalid argument%s'%s'",
3403 *num_params ? ", " : "",
3404 *num_params ? params[0] : "");
3405 XtAppWarning(XtWidgetToApplicationContext(w), err_buf);
3406 ctx->text.numeric = False0;
3407 ctx->text.mult = 1;
3408 return;
3409 }
3410 if (params[0][0] == '-') {
3411 ctx->text.mult = 32767;
3412 return;
3413 }
3414 else if (mult == 32767) {
3415 mult = ctx->text.mult = - (params[0][0] - '0');
3416 return;
3417 }
3418 else {
3419 mult = mult * 10 + (params[0][0] - '0') * (mult < 0 ? -1 : 1);
3420 ctx->text.mult = ctx->text.mult * 10 + (params[0][0] - '0') *
3421 (mult < 0 ? -1 : 1);
3422 }
3423 if (mult != ctx->text.mult || mult >= 32767) { /* checks for overflow */
3424 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
3425 ctx->text.mult = 1;
3426 ctx->text.numeric = False0;
3427 return;
3428 }
3429 }
3430 else
3431 InsertChar(w, event, params, num_params);
3432}
3433
3434/*ARGSUSED*/
3435static void
3436KeyboardReset(Widget w, XEvent *event, String *params, Cardinal *num_params)
3437{
3438 TextWidget ctx = (TextWidget)w;
3439
3440 ctx->text.numeric = False0;
3441 ctx->text.mult = 1;
3442
3443 (void)_XawTextSrcToggleUndo((TextSrcObject)ctx->text.source);
3444
3445 if (ctx->text.kill_ring_ptr) {
3446 --ctx->text.kill_ring_ptr->refcount;
3447 ctx->text.kill_ring_ptr = NULL((void*)0);
3448 }
3449 ctx->text.kill_ring = 0;
3450
3451 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
3452}
3453#endif /* OLDXAW */
3454
3455/* Multiply() - action
3456 *
3457 * The parameter list may contain either a number or the string 'Reset'.
3458 *
3459 * A number will multiply the current multiplication factor by that number.
3460 * Many of the text widget actions will will perform n actions, where n is
3461 * the multiplication factor.
3462 *
3463 * The string reset will reset the mutiplication factor to 1. */
3464/*ARGSUSED*/
3465static void
3466Multiply(Widget w, XEvent *event, String *params, Cardinal *num_params)
3467{
3468 TextWidget ctx = (TextWidget)w;
3469 int mult;
3470
3471 if (*num_params != 1) {
3472 XtAppError(XtWidgetToApplicationContext(w),
3473 "Xaw Text Widget: multiply() takes exactly one argument.");
3474 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
3475 return;
3476 }
3477
3478 if ((params[0][0] == 'r') || (params[0][0] == 'R')) {
3479 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
3480#ifndef OLDXAW
3481 ctx->text.numeric = False0;
3482#endif
3483 ctx->text.mult = 1;
3484 return;
3485 }
3486
3487#ifndef OLDXAW
3488 if (params[0][0] == 's' || params[0][0] == 'S') {
3489 ctx->text.numeric = True1;
3490 ctx->text.mult = 0;
3491 return;
3492 }
3493 else
3494#endif
3495 if ((mult = atoi(params[0])) == 0) {
3496 char buf[BUFSIZ8192];
3497
3498 snprintf(buf, sizeof(buf),
3499 "Xaw Text Widget: multiply() argument "
3500 "must be a number greater than zero, or 'Reset'.");
3501 XtAppError(XtWidgetToApplicationContext(w), buf);
3502 XBell(XtDisplay(w)(((w)->core.screen)->display), 50);
3503 return;
3504 }
3505
3506 ctx->text.mult *= mult;
3507}
3508
3509/* StripOutOldCRs() - called from FormRegion
3510 *
3511 * removes CRs in widget ctx, from from to to.
3512 *
3513 * RETURNS: the new ending location (we may add some characters),
3514 * or XawReplaceError if the widget can't be written to. */
3515static XawTextPosition
3516StripOutOldCRs(TextWidget ctx, XawTextPosition from, XawTextPosition to,
3517 XawTextPosition *pos, int num_pos)
3518{
3519 XawTextPosition startPos, endPos, eop_begin, eop_end, temp;
3520 Widget src = ctx->text.source;
3521 XawTextBlock text;
3522 char *buf;
3523 static wchar_t wc_two_spaces[3];
3524 int idx;
3525
3526 /* Initialize our TextBlock with two spaces. */
3527 text.firstPos = 0;
3528 text.format = _XawTextFormat(ctx);
3529 if (text.format == XawFmt8Bit)
3530 text.ptr= " ";
3531 else {
3532 wc_two_spaces[0] = _Xaw_atowc(XawSP0x20);
3533 wc_two_spaces[1] = _Xaw_atowc(XawSP0x20);
3534 wc_two_spaces[2] = 0;
3535 text.ptr = (char*)wc_two_spaces;
3536 }
3537
3538 /* Strip out CR's. */
3539 eop_begin = eop_end = startPos = endPos = from;
3540
3541 /* CONSTCOND */
3542 while (TRUE1) {
3543 endPos=SrcScanXawTextSourceScan(src, startPos, XawstEOL, XawsdRight, 1, False0);
3544
3545 temp = SrcScanXawTextSourceScan(src, endPos, XawstWhiteSpace, XawsdLeft, 1, False0);
3546 temp = SrcScanXawTextSourceScan(src, temp, XawstWhiteSpace, XawsdRight,1, False0);
3547
3548 if (temp > startPos)
3549 endPos = temp;
3550
3551 if (endPos >= to)
3552 break;
3553
3554 if (endPos >= eop_begin) {
3555 startPos = eop_end;
3556 eop_begin=SrcScanXawTextSourceScan(src, startPos, XawstParagraph,
3557 XawsdRight, 1,False0);
3558 eop_end = SrcScanXawTextSourceScan(src, startPos, XawstParagraph,
3559 XawsdRight, 1, True1);
3560 }
3561 else {
3562 XawTextPosition periodPos, next_word;
3563 int i, len;
3564
3565 periodPos = SrcScanXawTextSourceScan(src, endPos, XawstPositions,
3566 XawsdLeft, 1, True1);
3567 next_word = SrcScanXawTextSourceScan(src, endPos, XawstWhiteSpace,
3568 XawsdRight, 1, False0);
3569
3570 len = next_word - periodPos;
3571
3572 text.length = 1;
3573 buf = _XawTextGetText(ctx, periodPos, next_word);
3574 if (text.format == XawFmtWide) {
3575 if (periodPos < endPos && ((wchar_t*)buf)[0] == _Xaw_atowc('.'))
3576 text.length++;
3577 }
3578 else
3579 if (periodPos < endPos && buf[0] == '.')
3580 text.length++; /* Put in two spaces. */
3581
3582 /*
3583 * Remove all extra spaces.
3584 */
3585 for (i = 1 ; i < len; i++)
3586 if (text.format == XawFmtWide) {
3587 if (!iswspace(((wchar_t*)buf)[i])((((((wchar_t*)buf)[i]) & ~0x7f) == 0) && ((*__ctype_b_loc
())[(int) ((((((wchar_t*)buf)[i]) & 0x7f)))] & (unsigned
short int) _ISspace))
|| ((periodPos + i) >= to))
3588 break;
3589 }
3590 else if (!isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| (periodPos + i) >= to)
3591 break;
3592
3593 XtFree(buf);
3594
3595 to -= (i - text.length - 1);
3596 startPos = SrcScanXawTextSourceScan(src, periodPos, XawstPositions,
3597 XawsdRight, i, True1);
3598 if (_XawTextReplace(ctx, endPos, startPos, &text) != XawEditDone0)
3599 return (XawReplaceError-1);
3600
3601 for (idx = 0; idx < num_pos; idx++) {
3602 if (endPos < pos[idx]) {
3603 if (startPos < pos[idx])
3604 pos[idx] -= startPos - endPos;
3605 else
3606 pos[idx] = endPos;
3607 pos[idx] += text.length;
3608 }
3609 }
3610
3611 startPos -= i - text.length;
3612 }
3613 }
3614
3615 return (to);
3616}
3617
3618/* InsertNewCRs() - called from FormRegion
3619 *
3620 * inserts new CRs for FormRegion, thus for FormParagraph action */
3621static void
3622InsertNewCRs(TextWidget ctx, XawTextPosition from, XawTextPosition to,
3623 XawTextPosition *pos, int num_pos)
3624{
3625 XawTextPosition startPos, endPos, space, eol;
3626 XawTextBlock text;
3627 int i, width, height, len, wwidth, idx;
3628 char *buf;
3629 static wchar_t wide_CR[2];
3630
3631 text.firstPos = 0;
3632 text.length = 1;
3633 text.format = _XawTextFormat(ctx);
3634
3635 if (text.format == XawFmt8Bit)
3636 text.ptr = "\n";
3637 else {
3638 wide_CR[0] = _Xaw_atowc(XawLF0x0a);
3639 wide_CR[1] = 0;
3640 text.ptr = (char*)wide_CR;
3641 }
3642
3643 startPos = from;
3644
3645 wwidth = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - (int)HMargins(ctx)((ctx)->text.left_margin + (ctx)->text.margin.right);
3646 if (ctx->text.wrap != XawtextWrapNever) {
3647 XRectangle cursor;
3648
3649 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
3650 wwidth -= (int)cursor.width;
3651 }
3652 wwidth = XawMax(0, wwidth)((0) > (wwidth) ? (0) : (wwidth));
3653
3654 /* CONSTCOND */
3655 while (TRUE1) {
3656 XawTextSinkFindPosition(ctx->text.sink, startPos,
3657 (int)ctx->text.r_margin.left, wwidth,
3658 True1, &eol, &width, &height);
3659 if (eol == startPos)
3660 ++eol;
3661 if (eol >= to)
3662 break;
3663
3664 eol = SrcScanXawTextSourceScan(ctx->text.source, eol, XawstPositions,
3665 XawsdLeft, 1, True1);
3666 space = SrcScanXawTextSourceScan(ctx->text.source, eol, XawstWhiteSpace,
3667 XawsdRight,1, True1);
3668
3669 startPos = endPos = eol;
3670 if (eol == space)
3671 return;
3672
3673 len = (int)(space - eol);
3674 buf = _XawTextGetText(ctx, eol, space);
3675 for (i = 0 ; i < len ; i++)
3676 if (text.format == XawFmtWide) {
3677 if (!iswspace(((wchar_t*)buf)[i])((((((wchar_t*)buf)[i]) & ~0x7f) == 0) && ((*__ctype_b_loc
())[(int) ((((((wchar_t*)buf)[i]) & 0x7f)))] & (unsigned
short int) _ISspace))
)
3678 break;
3679 }
3680 else if (!isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
)
3681 break;
3682
3683 to -= (i - 1);
3684 endPos = SrcScanXawTextSourceScan(ctx->text.source, endPos,
3685 XawstPositions, XawsdRight, i, True1);
3686 XtFree(buf);
3687
3688 if (_XawTextReplace(ctx, startPos, endPos, &text))
3689 return;
3690
3691 for (idx = 0; idx < num_pos; idx++) {
3692 if (startPos < pos[idx]) {
3693 if (endPos < pos[idx])
3694 pos[idx] -= endPos - startPos;
3695 else
3696 pos[idx] = startPos;
3697 pos[idx] += text.length;
3698 }
3699 }
3700
3701 startPos = SrcScanXawTextSourceScan(ctx->text.source, startPos,
3702 XawstPositions, XawsdRight, 1, True1);
3703 }
3704}
3705
3706/* FormRegion() - called by FormParagraph
3707 *
3708 * oversees the work of paragraph-forming a region
3709 *
3710 * Return:
3711 * XawEditDone if successful, or XawReplaceError
3712 */
3713static int
3714FormRegion(TextWidget ctx, XawTextPosition from, XawTextPosition to,
3715 XawTextPosition *pos, int num_pos)
3716{
3717#ifndef OLDXAW
3718 Boolint format = ctx->text.auto_fill
3719 && ctx->text.left_column < ctx->text.right_column;
3720#endif
3721
3722 if (from >= to)
3723 return (XawEditDone0);
3724
3725#ifndef OLDXAW
3726 if (format) {
3727 XawTextPosition len = ctx->text.lastPos;
3728 int inc = 0;
3729
3730 if (ctx->text.justify == XawjustifyLeft ||
3731 ctx->text.justify == XawjustifyFull) {
3732 Untabify(ctx, from, to, pos, num_pos, NULL((void*)0));
3733 to += ctx->text.lastPos - len;
3734 len = ctx->text.insertPos;
3735 (void)BlankLine((Widget)ctx, from, &inc);
3736 if (from + inc >= to)
3737 return (XawEditDone0);
3738 }
3739 if (!StripSpaces(ctx, from + inc, to, pos, num_pos, NULL((void*)0)))
3740 return (XawReplaceError-1);
3741 to += ctx->text.lastPos - len;
3742
3743 FormatText(ctx, from, ctx->text.justify != XawjustifyFull, pos, num_pos);
3744 }
3745 else {
3746#endif
3747 if ((to = StripOutOldCRs(ctx, from, to, pos, num_pos)) == XawReplaceError-1)
3748 return (XawReplaceError-1);
3749 InsertNewCRs(ctx, from, to, pos, num_pos);
3750#ifndef OLDXAW
3751 }
3752#endif
3753 ctx->text.from_left = -1;
3754
3755 return (XawEditDone0);
3756}
3757
3758#ifndef OLDXAW
3759static Boolint
3760BlankLine(Widget w, XawTextPosition pos, int *blanks_return)
3761{
3762 int i, blanks = 0;
3763 XawTextBlock block;
3764 Widget src = XawTextGetSource(w);
3765 XawTextPosition l = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdLeft, 1, False0);
3766 XawTextPosition r = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdRight, 1, False0);
3767
3768 while (l < r) {
3769 l = XawTextSourceRead(src, l, &block, r - l);
3770 if (block.length == 0) {
3771 if (blanks_return)
3772 *blanks_return = blanks;
3773 return (True1);
3774 }
3775 if (XawTextFormat((TextWidget)w, XawFmt8Bit)((unsigned long)_XawTextFormat((TextWidget)w) == (XawFmt8Bit)
)
) {
3776 for (i = 0; i < block.length; i++, blanks++)
3777 if (block.ptr[i] != ' ' &&
3778 block.ptr[i] != '\t') {
3779 if (blanks_return)
3780 *blanks_return = blanks;
3781 return (block.ptr[i] == '\n');
3782 }
3783 }
3784 else if (XawTextFormat((TextWidget)w, XawFmtWide)((unsigned long)_XawTextFormat((TextWidget)w) == (XawFmtWide)
)
) {
3785 for (i = 0; i < block.length; i++, blanks++)
3786 if (_Xaw_atowc(XawSP0x20) != ((wchar_t*)block.ptr)[i] &&
3787 _Xaw_atowc(XawTAB0x09) != ((wchar_t*)block.ptr)[i]) {
3788 if (blanks_return)
3789 *blanks_return = blanks;
3790 return (_Xaw_atowc(XawLF0x0a) == ((wchar_t*)block.ptr)[i]);
3791 }
3792 }
3793 }
3794
3795 return (True1);
3796}
3797
3798static Boolint
3799GetBlockBoundaries(TextWidget ctx,
3800 XawTextPosition *from_return, XawTextPosition *to_return)
3801{
3802 XawTextPosition from, to;
3803
3804 if (ctx->text.auto_fill && ctx->text.left_column < ctx->text.right_column) {
3805 if (ctx->text.s.left != ctx->text.s.right) {
3806 from = SrcScanXawTextSourceScan(ctx->text.source,
3807 XawMin(ctx->text.s.left, ctx->text.s.right)((ctx->text.s.left) < (ctx->text.s.right) ? (ctx->
text.s.left) : (ctx->text.s.right))
,
3808 XawstEOL, XawsdLeft, 1, False0);
3809 to = SrcScanXawTextSourceScan(ctx->text.source,
3810 XawMax(ctx->text.s.right, ctx->text.s.right)((ctx->text.s.right) > (ctx->text.s.right) ? (ctx->
text.s.right) : (ctx->text.s.right))
,
3811 XawstEOL, XawsdRight, 1, False0);
3812 }
3813 else {
3814 XawTextBlock block;
3815 XawTextPosition tmp;
3816 Boolint first;
3817
3818 from = to = ctx->text.insertPos;
3819
3820 /* find from position */
3821 first = True1;
3822 while (1) {
3823 tmp = from;
3824 from = SrcScanXawTextSourceScan(ctx->text.source, from, XawstEOL, XawsdLeft,
3825 1 + !first, False0);
3826 XawTextSourceRead(ctx->text.source, from, &block, 1);
3827 if (block.length == 0 ||
3828 (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit)) &&
3829 block.ptr[0] != ' ' &&
3830 block.ptr[0] != '\t' &&
3831 !isalnum(*(unsigned char*)block.ptr)((*__ctype_b_loc ())[(int) ((*(unsigned char*)block.ptr))] &
(unsigned short int) _ISalnum)
) ||
3832 (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) &&
3833 _Xaw_atowc(XawSP0x20) != *(wchar_t*)block.ptr &&
3834 _Xaw_atowc(XawTAB0x09) != *(wchar_t*)block.ptr &&
3835 !iswalnum(*(wchar_t*)block.ptr)) ||
3836 BlankLine((Widget)ctx, from, NULL((void*)0))) {
3837 from = tmp;
3838 break;
3839 }
3840 if (from == tmp && !first)
3841 break;
3842 first = False0;
3843 }
3844 if (first)
3845 return (False0);
3846
3847 /* find to position */
3848 first = True1;
3849 while (1) {
3850 tmp = to;
3851 to = SrcScanXawTextSourceScan(ctx->text.source, to, XawstEOL, XawsdRight,
3852 1 + !first, False0);
3853 XawTextSourceRead(ctx->text.source, to + (to < ctx->text.lastPos),
3854 &block, 1);
3855 if (block.length == 0 ||
3856 (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit)) &&
3857 block.ptr[0] != ' ' &&
3858 block.ptr[0] != '\t' &&
3859 !isalnum(*(unsigned char*)block.ptr)((*__ctype_b_loc ())[(int) ((*(unsigned char*)block.ptr))] &
(unsigned short int) _ISalnum)
) ||
3860 (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) &&
3861 _Xaw_atowc(XawSP0x20) != *(wchar_t*)block.ptr &&
3862 _Xaw_atowc(XawTAB0x09) != *(wchar_t*)block.ptr &&
3863 !iswalnum(*(wchar_t*)block.ptr)) ||
3864 BlankLine((Widget)ctx, to, NULL((void*)0)))
3865 break;
3866 if (to == tmp && !first)
3867 break;
3868 first = False0;
3869 }
3870 }
3871 }
3872 else {
3873 from = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
3874 XawsdLeft, 1, False0);
3875 if (BlankLine((Widget)ctx, from, NULL((void*)0)))
3876 return (False0);
3877 from = SrcScanXawTextSourceScan(ctx->text.source, from, XawstParagraph,
3878 XawsdLeft, 1, False0);
3879 if (BlankLine((Widget)ctx, from, NULL((void*)0)))
3880 from = SrcScanXawTextSourceScan(ctx->text.source, from, XawstEOL,
3881 XawsdRight, 1, True1);
3882 to = SrcScanXawTextSourceScan(ctx->text.source, from, XawstParagraph,
3883 XawsdRight, 1, False0);
3884 }
3885
3886 if (from < to) {
3887 *from_return = from;
3888 *to_return = to;
3889 return (True1);
3890 }
3891
3892 return (False0);
3893}
3894#endif /* OLDXAW */
3895
3896/* FormParagraph() - action
3897 *
3898 * removes and reinserts CRs to maximize line length without clipping */
3899/*ARGSUSED*/
3900static void
3901FormParagraph(Widget w, XEvent *event, String *params, Cardinal *num_params)
3902{
3903 TextWidget ctx = (TextWidget)w;
3904 XawTextPosition from, to, buf[32], *pos;
3905#ifndef OLDXAW
3906 XawTextPosition endPos = 0;
3907 char *lbuf = NULL((void*)0), *rbuf;
3908 TextSrcObject src = (TextSrcObject)ctx->text.source;
3909 Cardinal i;
3910 Boolint undo = src->textSrc.enable_undo && src->textSrc.undo_state == False0;
3911#endif
3912
3913 StartAction(ctx, event);
3914
3915#ifndef OLDXAW
3916 pos = XawStackAlloc(sizeof(XawTextPosition) * src->textSrc.num_text, buf)((sizeof(XawTextPosition) * src->textSrc.num_text) <= sizeof
(buf) ? (XtPointer)(buf) : XtMalloc((unsigned)(sizeof(XawTextPosition
) * src->textSrc.num_text)))
;
3917 for (i = 0; i < src->textSrc.num_text; i++)
3918 pos[i] = ((TextWidget)src->textSrc.text[i])->text.old_insert;
3919#else
3920 pos = buf;
3921 *pos = ctx->text.old_insert;
3922#endif
3923
3924#ifndef OLDXAW
3925 if (!GetBlockBoundaries(ctx, &from, &to)) {
3926 EndAction(ctx);
3927 XawStackFree(pos, buf)do { if ((pos) != (XtPointer)(buf)) XtFree((char *)pos); } while
(0)
;
3928 return;
3929 }
3930
3931 if (undo) {
3932 src->textSrc.undo_state = True1;
3933 lbuf = _XawTextGetText(ctx, from, to);
3934 endPos = ctx->text.lastPos;
3935 }
3936
3937 if (FormRegion(ctx, from, to, pos, src->textSrc.num_text) == XawReplaceError-1) {
3938 XawStackFree(pos, buf)do { if ((pos) != (XtPointer)(buf)) XtFree((char *)pos); } while
(0)
;
3939 pos = buf;
3940#else
3941 from = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
3942 XawstParagraph, XawsdLeft, 1, False0);
3943 to = SrcScanXawTextSourceScan(ctx->text.source, from,
3944 XawstParagraph, XawsdRight, 1, False0);
3945
3946 if (FormRegion(ctx, from, to, pos, 1) == XawReplaceError-1) {
3947#endif
3948 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
3949#ifndef OLDXAW
3950 if (undo) {
3951 src->textSrc.undo_state = False0;
3952 XtFree(lbuf);
3953 }
3954#endif
3955 }
3956#ifndef OLDXAW
3957 else if (undo) {
3958 /* makes the form-paragraph only one undo/redo step */
3959 unsigned llen, rlen, size;
3960 XawTextBlock block;
3961
3962 llen = to - from;
3963 rlen = llen + (ctx->text.lastPos - endPos);
3964
3965 block.firstPos = 0;
3966 block.format = _XawTextFormat(ctx);
3967
3968 rbuf = _XawTextGetText(ctx, from, from + rlen);
3969
3970 size = XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) ? sizeof(wchar_t) : sizeof(char);
3971 if (llen != rlen || memcmp(lbuf, rbuf, llen * size)) {
3972 block.ptr = lbuf;
3973 block.length = llen;
3974 _XawTextReplace(ctx, from, from + rlen, &block);
3975
3976 src->textSrc.undo_state = False0;
3977 block.ptr = rbuf;
3978 block.length = rlen;
3979 _XawTextReplace(ctx, from, from + llen, &block);
3980 }
3981 else
3982 src->textSrc.undo_state = False0;
3983 XtFree(lbuf);
3984 XtFree(rbuf);
3985 }
3986
3987 for (i = 0; i < src->textSrc.num_text; i++) {
3988 TextWidget tw = (TextWidget)src->textSrc.text[i];
3989
3990 tw->text.old_insert = tw->text.insertPos = pos[i];
3991 _XawTextBuildLineTable(tw, SrcScanXawTextSourceScan((Widget)src, tw->text.lt.top, XawstEOL,
3992 XawsdLeft, 1, False0), False0);
3993 tw->text.clear_to_eol = True1;
3994 }
3995 XawStackFree(pos, buf)do { if ((pos) != (XtPointer)(buf)) XtFree((char *)pos); } while
(0)
;
3996#else
3997 ctx->text.old_insert = ctx->text.insertPos = *pos;
3998 _XawTextBuildLineTable(ctx, SrcScanXawTextSourceScan(ctx->text.source, ctx->text.lt.top,
3999 XawstEOL, XawsdLeft, 1, False0), False0);
4000 ctx->text.clear_to_eol = True1;
4001#endif
4002 ctx->text.showposition = True1;
4003
4004 EndAction(ctx);
4005}
4006
4007/* TransposeCharacters() - action
4008 *
4009 * Swaps the character to the left of the mark
4010 * with the character to the right of the mark */
4011/*ARGSUSED*/
4012static void
4013TransposeCharacters(Widget w, XEvent *event,
4014 String *params, Cardinal *num_params)
4015{
4016 TextWidget ctx = (TextWidget)w;
4017 XawTextPosition start, end;
4018 XawTextBlock text;
4019 char *buf;
4020 int i, mult = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
4021
4022 if (mult < 0) {
4023 ctx->text.mult = 1;
4024 return;
4025 }
4026
4027 StartAction(ctx, event);
4028
4029 /* Get bounds. */
4030
4031 start = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos, XawstPositions,
4032 XawsdLeft, 1, True1);
4033 end = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos, XawstPositions,
4034 XawsdRight, mult, True1);
4035
4036 /* Make sure we aren't at the very beginning or end of the buffer. */
4037
4038 if (start == ctx->text.insertPos || end == ctx->text.insertPos) {
4039 XBell(XtDisplay(w)(((w)->core.screen)->display), 0); /* complain. */
4040 EndAction(ctx);
4041 return;
4042 }
4043
4044 ctx->text.from_left = -1;
4045 ctx->text.insertPos = end;
4046
4047 text.firstPos = 0;
4048 text.format = _XawTextFormat(ctx);
4049
4050 /* Retrieve text and swap the characters. */
4051 if (text.format == XawFmtWide) {
4052 wchar_t wc;
4053 wchar_t *wbuf;
4054
4055 wbuf = (wchar_t*)_XawTextGetText(ctx, start, end);
4056 text.length = wcslen(wbuf);
4057 wc = wbuf[0];
4058 for (i = 1; i < text.length; i++)
4059 wbuf[i - 1] = wbuf[i];
4060 wbuf[i - 1] = wc;
4061 buf = (char*)wbuf; /* so that it gets assigned and freed */
4062 }
4063 else { /* thus text.format == XawFmt8Bit */
4064 char c;
4065
4066 buf = _XawTextGetText(ctx, start, end);
4067 text.length = strlen(buf);
4068 c = buf[0];
4069 for (i = 1; i < text.length; i++)
4070 buf[i - 1] = buf[i];
4071 buf[i - 1] = c;
4072 }
4073
4074 text.ptr = buf;
4075
4076 /* Store new text in source. */
4077
4078 if (_XawTextReplace (ctx, start, end, &text))
4079 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
4080 XtFree((char *)buf);
4081 EndAction(ctx);
4082}
4083
4084#ifndef OLDXAW
4085/*ARGSUSED*/
4086static void
4087Undo(Widget w, XEvent *event, String *params, Cardinal *num_params)
4088{
4089 TextWidget ctx = (TextWidget)w;
4090 int mul = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
4091 Boolint toggle = False0;
4092
4093 if (mul < 0) {
4094 toggle = True1;
4095 _XawTextSrcToggleUndo((TextSrcObject)ctx->text.source);
4096 ctx->text.mult = mul = -mul;
4097 }
4098
4099 StartAction(ctx, event);
4100 for (; mul; --mul)
4101 if (!_XawTextSrcUndo((TextSrcObject)ctx->text.source, &ctx->text.insertPos))
4102 break;
4103 ctx->text.showposition = True1;
4104
4105 if (toggle)
4106 _XawTextSrcToggleUndo((TextSrcObject)ctx->text.source);
4107 EndAction(ctx);
4108}
4109#endif
4110
4111/* NoOp() - action
4112 * This action performs no action, and allows the user or
4113 * application programmer to unbind a translation.
4114 *
4115 * Note: If the parameter list contains the string "RingBell" then
4116 * this action will ring the bell.
4117 */
4118/*ARGSUSED*/
4119static void
4120NoOp(Widget w, XEvent *event, String *params, Cardinal *num_params)
4121{
4122 if (*num_params != 1)
4123 return;
4124
4125 switch(params[0][0]) {
4126 case 'R':
4127 case 'r':
4128 XBell(XtDisplay(w)(((w)->core.screen)->display), 0);
4129 /*FALLTROUGH*/
4130 default:
4131 break;
4132 }
4133}
4134
4135/* Reconnect() - action
4136 * This reconnects to the input method. The user will typically call
4137 * this action if/when connection has been severed, or when the app
4138 * was started up before an IM was started up
4139 */
4140/*ARGSUSED*/
4141static void
4142Reconnect(Widget w, XEvent *event, String *params, Cardinal *num_params)
4143{
4144 _XawImReconnect(w);
4145}
4146
4147#define CAPITALIZE 1
4148#define DOWNCASE 2
4149#define UPCASE 3
4150
4151#ifdef NO_LIBC_I18N
4152static int
4153ToLowertolower(int ch)
4154{
4155 char buf[2];
4156
4157 *buf = ch;
4158 XmuNCopyISOLatin1Lowered(buf, buf, sizeof(buf));
4159
4160 return (*buf);
4161}
4162
4163static int
4164ToUppertoupper(int ch)
4165{
4166 char buf[2];
4167
4168 *buf = ch;
4169 XmuNCopyISOLatin1Uppered(buf, buf, sizeof(buf));
4170
4171 return (*buf);
4172}
4173
4174static int
4175IsAlnum(int ch)((*__ctype_b_loc ())[(int) ((int ch))] & (unsigned short int
) _ISalnum)
4176{
4177 return ((ch >= '0' && ch <= '9') || ToUppertoupper(ch) != ch || ToLowertolower(ch) != ch);
4178}
4179
4180static int
4181IsLower(int ch)((*__ctype_b_loc ())[(int) ((int ch))] & (unsigned short int
) _ISlower)
4182{
4183 char upbuf[2];
4184 char lobuf[2];
4185
4186 *upbuf = *lobuf = ch;
4187 XmuNCopyISOLatin1Lowered(lobuf, lobuf, sizeof(lobuf));
4188 XmuNCopyISOLatin1Uppered(upbuf, upbuf, sizeof(upbuf));
4189
4190 return (*lobuf != *upbuf && ch == *lobuf);
4191}
4192
4193static int
4194IsUpper(int ch)((*__ctype_b_loc ())[(int) ((int ch))] & (unsigned short int
) _ISupper)
4195{
4196 char upbuf[2];
4197 char lobuf[2];
4198
4199 *upbuf = *lobuf = ch;
4200 XmuNCopyISOLatin1Lowered(lobuf, lobuf, sizeof(lobuf));
4201 XmuNCopyISOLatin1Uppered(upbuf, upbuf, sizeof(upbuf));
4202
4203 return (*lobuf != *upbuf && ch == *upbuf);
4204}
4205#else
4206#define ToLowertolower tolower
4207#define ToUppertoupper toupper
4208#define IsAlnumisalnum isalnum
4209#define IsLowerislower islower
4210#define IsUpperisupper isupper
4211#endif
4212
4213static void
4214CaseProc(Widget w, XEvent *event, int cmd)
4215{
4216 TextWidget ctx = (TextWidget)w;
4217 short mul = MULT(ctx)(ctx->text.mult == 0 ? 4 : ctx->text.mult == 32767 ? -4
: ctx->text.mult)
;
4218 XawTextPosition left, right;
4219 XawTextBlock block;
4220 Boolint changed = False0;
4221 unsigned char ch, mb[sizeof(wchar_t)];
4222 int i, count;
4223
4224 if (mul > 0)
4225 right = SrcScanXawTextSourceScan(ctx->text.source, left = ctx->text.insertPos,
4226 XawstAlphaNumeric, XawsdRight, mul, False0);
4227 else
4228 left = SrcScanXawTextSourceScan(ctx->text.source, right = ctx->text.insertPos,
4229 XawstAlphaNumeric, XawsdLeft, 1 + -mul, False0);
4230 block.firstPos = 0;
4231 block.format = _XawTextFormat(ctx);
4232 block.length = right - left;
4233 block.ptr = _XawTextGetText(ctx, left, right);
4234
4235 count = 0;
4236 if (block.format == XawFmt8Bit)
4237 for (i = 0; i < block.length; i++) {
4238 if (!IsAlnum(*mb = (unsigned char)block.ptr[i])((*__ctype_b_loc ())[(int) ((*mb = (unsigned char)block.ptr[i
]))] & (unsigned short int) _ISalnum)
)
4239 count = 0;
4240 else if (++count == 1 || cmd != CAPITALIZE) {
4241 ch = cmd == DOWNCASE ? ToLowertolower(*mb) : ToUppertoupper(*mb);
4242 if (ch != *mb) {
4243 changed = True1;
4244 block.ptr[i] = ch;
4245 }
4246 }
4247 else if (cmd == CAPITALIZE) {
4248 if ((ch = ToLowertolower(*mb)) != *mb) {
4249 changed = True1;
4250 block.ptr[i] = ch;
4251 }
4252 }
4253 }
4254 else
4255 for (i = 0; i < block.length; i++) {
4256 wctomb((char*)mb, ((wchar_t*)block.ptr)[i]);
4257 if (!IsAlnum(*mb)((*__ctype_b_loc ())[(int) ((*mb))] & (unsigned short int
) _ISalnum)
)
4258 count = 0;
4259 else if (++count == 1 || cmd != CAPITALIZE) {
4260 ch = cmd == DOWNCASE ? ToLowertolower(*mb) : ToUppertoupper(*mb);
4261 if (ch != *mb) {
4262 changed = True1;
4263 ((wchar_t*)block.ptr)[i] = _Xaw_atowc(ch);
4264 }
4265 }
4266 else if (cmd == CAPITALIZE) {
4267 if ((ch = ToLowertolower(*mb)) != *mb) {
4268 changed = True1;
4269 ((wchar_t*)block.ptr)[i] = _Xaw_atowc(ch);
4270 }
4271 }
4272 }
4273
4274 StartAction(ctx, event);
4275 if (changed && _XawTextReplace(ctx, left, right, &block) != XawEditDone0)
4276 XBell(XtDisplay(ctx)(((ctx)->core.screen)->display), 0);
4277 ctx->text.insertPos = right;
4278 EndAction(ctx);
4279
4280 XtFree(block.ptr);
4281}
4282
4283/*ARGSUSED*/
4284static void
4285CapitalizeWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
4286{
4287 CaseProc(w, event, CAPITALIZE);
4288}
4289
4290/*ARGSUSED*/
4291static void
4292DowncaseWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
4293{
4294 CaseProc(w, event, DOWNCASE);
4295}
4296
4297/*ARGSUSED*/
4298static void
4299UpcaseWord(Widget w, XEvent *event, String *params, Cardinal *num_params)
4300{
4301 CaseProc(w, event, UPCASE);
4302}
4303#undef CAPITALIZE
4304#undef DOWNCASE
4305#undef UPCASE
4306
4307XtActionsRec _XawTextActionsTable[] = {
4308 /* motion */
4309 {"forward-character", MoveForwardChar},
4310 {"backward-character", MoveBackwardChar},
4311 {"forward-word", MoveForwardWord},
4312 {"backward-word", MoveBackwardWord},
4313 {"forward-paragraph", MoveForwardParagraph},
4314 {"backward-paragraph", MoveBackwardParagraph},
4315 {"beginning-of-line", MoveToLineStart},
4316 {"end-of-line", MoveToLineEnd},
4317 {"next-line", MoveNextLine},
4318 {"previous-line", MovePreviousLine},
4319 {"next-page", MoveNextPage},
4320 {"previous-page", MovePreviousPage},
4321 {"beginning-of-file", MoveBeginningOfFile},
4322 {"end-of-file", MoveEndOfFile},
4323 {"scroll-one-line-up", ScrollOneLineUp},
4324 {"scroll-one-line-down", ScrollOneLineDown},
4325
4326 /* delete */
4327 {"delete-next-character", DeleteForwardChar},
4328 {"delete-previous-character", DeleteBackwardChar},
4329 {"delete-next-word", DeleteForwardWord},
4330 {"delete-previous-word", DeleteBackwardWord},
4331 {"delete-selection", DeleteCurrentSelection},
4332 {"delete", Delete},
4333
4334 /* kill */
4335 {"kill-word", KillForwardWord},
4336 {"backward-kill-word", KillBackwardWord},
4337 {"kill-selection", KillCurrentSelection},
4338 {"kill-to-end-of-line", KillToEndOfLine},
4339 {"kill-to-end-of-paragraph", KillToEndOfParagraph},
4340
4341 /* new line */
4342 {"newline-and-indent", InsertNewLineAndIndent},
4343 {"newline-and-backup", InsertNewLineAndBackup},
4344 {"newline", InsertNewLine},
4345
4346 /* selection */
4347 {"select-word", SelectWord},
4348 {"select-all", SelectAll},
4349 {"select-start", SelectStart},
4350 {"select-adjust", SelectAdjust},
4351 {"select-end", SelectEnd},
4352 {"select-save", SelectSave},
4353 {"extend-start", ExtendStart},
4354 {"extend-adjust", ExtendAdjust},
4355 {"extend-end", ExtendEnd},
4356 {"insert-selection", InsertSelection},
4357
4358 /* miscellaneous */
4359 {"redraw-display", RedrawDisplay},
4360 {"insert-file", _XawTextInsertFile},
4361 {"search", _XawTextSearch},
4362 {"insert-char", InsertChar},
4363 {"insert-string", InsertString},
4364 {"focus-in", TextFocusIn},
4365 {"focus-out", TextFocusOut},
4366 {"enter-window", TextEnterWindow},
4367 {"leave-window", TextLeaveWindow},
4368 {"display-caret", DisplayCaret},
4369 {"multiply", Multiply},
4370 {"form-paragraph", FormParagraph},
4371 {"transpose-characters", TransposeCharacters},
4372 {"set-keyboard-focus", SetKeyboardFocus},
4373#ifndef OLDXAW
4374 {"numeric", Numeric},
4375 {"undo", Undo},
4376 {"keyboard-reset", KeyboardReset},
4377 {"kill-ring-yank", KillRingYank},
4378 {"toggle-overwrite", ToggleOverwrite},
4379 {"indent", Indent},
4380#endif
4381 {"no-op", NoOp},
4382
4383 /* case transformations */
4384 {"capitalize-word", CapitalizeWord},
4385 {"downcase-word", DowncaseWord},
4386 {"upcase-word", UpcaseWord},
4387
4388 /* action to bind translations for text dialogs */
4389 {"InsertFileAction", _XawTextInsertFileAction},
4390 {"DoSearchAction", _XawTextDoSearchAction},
4391 {"DoReplaceAction", _XawTextDoReplaceAction},
4392 {"SetField", _XawTextSetField},
4393 {"PopdownSearchAction", _XawTextPopdownSearchAction},
4394
4395 /* reconnect to Input Method */
4396 {"reconnect-im", Reconnect} /* Li Yuhong, Omron KK, 1991 */
4397};
4398
4399Cardinal _XawTextActionsTableCount = XtNumber(_XawTextActionsTable)((Cardinal) (sizeof(_XawTextActionsTable) / sizeof(_XawTextActionsTable
[0])))
;