Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

611014 views
1
/****************************************************************************
2
**
3
*W gaptext.c XGAP source Frank Celler
4
**
5
**
6
*Y Copyright 1995-1997, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
7
*Y Copyright 1997, Frank Celler, Huerth, Germany
8
**
9
** The GapTextWidget is intended to be used as a simple front end to the
10
** text widget with a gap text source and an ascii sink attached to it. It
11
** is a subclass of the standard text widget supplied with X11R4 and should
12
** work with X11R5 and X11R6.
13
*/
14
#include "utils.h"
15
#include "gaptext.h"
16
17
extern void _XawTextPrepareToUpdate();
18
extern int _XawTextReplace();
19
extern void _XawTextSetScrollBars();
20
extern void _XawTextCheckResize();
21
extern void _XawTextExecuteUpdate();
22
23
24
/****************************************************************************
25
**
26
27
*F * * * * * * * * * * * * * * gap text widget * * * * * * * * * * * * * * *
28
*/
29
30
31
/****************************************************************************
32
**
33
34
*F GapTextInsertSelection( <w>, <evt>, <parms>, <nums> ) . . . . insert text
35
**
36
** DESCRIPTION
37
** Handle a selection insert event. 'GapTextInsertSelection' calls the
38
** input callback method with the selected string.
39
*/
40
#define CTR(a) ( a & 0x1f )
41
42
static void GetSelection ( Widget, Time, String *, Cardinal );
43
44
static void GapTextInsertSelection (
45
Widget w,
46
XEvent * evt,
47
String * parms,
48
Cardinal * nums )
49
{
50
Time time = 0;
51
52
/* get the time of the event */
53
if ( evt != NULL )
54
switch ( evt->type )
55
{
56
case ButtonPress:
57
case ButtonRelease:
58
time = evt->xbutton.time;
59
break;
60
case KeyPress:
61
case KeyRelease:
62
time = evt->xkey.time;
63
break;
64
default:
65
time = CurrentTime;
66
break;
67
}
68
69
/* and insert the selection */
70
GetSelection( w, time, parms, *nums );
71
}
72
73
struct _SelectionList
74
{
75
String * params;
76
Cardinal count;
77
Time time;
78
};
79
80
static void DoSelection (
81
Widget w,
82
XtPointer cd,
83
Atom * selection,
84
Atom * type,
85
XtPointer value,
86
UInt * length,
87
Int * format )
88
{
89
GapTextWidget gap = (GapTextWidget) w;
90
char buf[2];
91
String ptr;
92
Boolean nl;
93
Int len;
94
95
if ( *type == 0 || *length == 0 )
96
{
97
struct _SelectionList* list = (struct _SelectionList*)cd;
98
99
if ( list != NULL )
100
{
101
GetSelection( w, list->time, list->params, list->count );
102
XtFree(cd);
103
}
104
return;
105
}
106
107
/* check if string begins with gap prompt */
108
ptr = (char*) value;
109
len = *length;
110
if ( gap->gap.drop_gap_prompt )
111
{
112
if ( 2 < len && ptr[0] == '>' && ptr[1] == ' ' )
113
{
114
ptr += 2;
115
len -= 2;
116
}
117
else if ( 5 < len && !strncmp( ptr, "gap> ", 5 ) )
118
{
119
ptr += 5;
120
len -= 5;
121
}
122
else if ( 5 < len && !strncmp( ptr, "brk> ", 5 ) )
123
{
124
ptr += 5;
125
len -= 5;
126
}
127
}
128
129
/* and call the callback */
130
buf[0] = '@';
131
for ( nl = False; 0 < len; len--, ptr++ )
132
{
133
if ( nl && gap->gap.drop_gap_prompt )
134
{
135
if ( 2 < len && ptr[0] == '>' && ptr[1] == ' ' )
136
{
137
ptr += 1;
138
len -= 1;
139
continue;
140
}
141
else if ( 5 < len && !strncmp( ptr, "gap> ", 5 ) )
142
{
143
ptr += 4;
144
len -= 4;
145
continue;
146
}
147
else if ( 5 < len && !strncmp( ptr, "brk> ", 5 ) )
148
{
149
ptr += 4;
150
len -= 4;
151
}
152
}
153
if ( CTR('@') < *ptr && *ptr <= CTR('Z') )
154
{
155
buf[1] = '@' + *ptr;
156
gap->gap.input_callback( buf, 2 );
157
}
158
else if ( *ptr == '@' )
159
{
160
buf[1] = '@';
161
gap->gap.input_callback( buf, 2 );
162
}
163
else
164
gap->gap.input_callback( ptr, 1 );
165
nl = *ptr == '\n' || *ptr == '\r';
166
}
167
XtFree(cd);
168
XFree(value);
169
}
170
171
static void GetSelection (
172
Widget w,
173
Time time,
174
String * parms,
175
Cardinal nums )
176
{
177
Atom selection;
178
Int buffer;
179
180
/* try to find which buffer <*parms> is pointing to */
181
selection = XInternAtom( XtDisplay(w), *parms, False );
182
switch (selection)
183
{
184
case XA_CUT_BUFFER0: buffer = 0; break;
185
case XA_CUT_BUFFER1: buffer = 1; break;
186
case XA_CUT_BUFFER2: buffer = 2; break;
187
case XA_CUT_BUFFER3: buffer = 3; break;
188
case XA_CUT_BUFFER4: buffer = 4; break;
189
case XA_CUT_BUFFER5: buffer = 5; break;
190
case XA_CUT_BUFFER6: buffer = 6; break;
191
case XA_CUT_BUFFER7: buffer = 7; break;
192
default: buffer = -1; break;
193
}
194
195
/* if <*parms> is a cut buffer insert its contents */
196
if ( buffer >= 0 )
197
{
198
Atom type = XA_STRING;
199
Int fmt8 = 8;
200
Int nbytes;
201
String line;
202
UInt length;
203
204
line = XFetchBuffer( XtDisplay(w), &nbytes, buffer );
205
if ( 0 < ( length = nbytes ) )
206
DoSelection( w, NULL, &selection, &type, (caddr_t) line,
207
&length, &fmt8 );
208
else if ( 1 < nums )
209
GetSelection( w, time, parms+1, nums-1 );
210
}
211
else
212
{
213
struct _SelectionList * list;
214
215
if ( --nums )
216
{
217
list = XtNew(struct _SelectionList);
218
list->params = parms + 1;
219
list->count = nums;
220
list->time = time;
221
}
222
else
223
list = NULL;
224
XtGetSelectionValue( w, selection, XA_STRING,
225
(XtSelectionCallbackProc) DoSelection, (XtPointer)list, time );
226
}
227
}
228
229
230
/****************************************************************************
231
**
232
*F GapTextInsertChar( <w>, <evt>, <parms>, <nums> ) . . . . . . handle keys
233
**
234
** DESCRIPTION
235
** Handle a key event. 'GapTextInsertChar' calls the input callback method
236
** with a one (or possible more) character string.
237
*/
238
static void GapTextInsertChar (
239
Widget w,
240
XEvent * evt,
241
String * parms,
242
Cardinal * nums )
243
{
244
GapTextWidget gap = (GapTextWidget) w;
245
Int len;
246
KeySym keysym;
247
String ptr;
248
char buf[2];
249
char str[128];
250
251
/* if no input call is registered return */
252
if ( gap->gap.input_callback == 0 )
253
return;
254
255
/* convert key event into text string */
256
len = XLookupString( &(evt->xkey), str, 128, &keysym, 0 );
257
258
/* handle arrows keys, etc */
259
if ( len == 0 )
260
{
261
len = 1;
262
str[len] = 0;
263
/* Switched Arrow Up and PageUp behaviour, and
264
Arrow Down and PageDown behaviour resp., 22.3.1999 Max */
265
if ( keysym == XK_Left )
266
str[0] = CTR('B');
267
else if ( keysym == XK_Up )
268
str[0] = CTR('P');
269
else if ( keysym == XK_Right )
270
str[0] = CTR('F');
271
else if ( keysym == XK_Down )
272
str[0] = CTR('N');
273
else if ( keysym == XK_Prior )
274
{
275
len = 2;
276
strcpy( str, "\001\020" );
277
}
278
else if ( keysym == XK_Next )
279
{
280
len = 2;
281
strcpy( str, "\001\016" );
282
}
283
else if ( keysym == XK_Home )
284
{
285
len = 2;
286
strcpy( str, "\033<" );
287
}
288
else if ( keysym == XK_Insert )
289
str[0] = CTR('L');
290
else
291
return;
292
}
293
294
/* and call the callback */
295
buf[0] = '@';
296
for ( ptr = str; 0 < len; len--, ptr++ )
297
{
298
if ( CTR('@') < *ptr && *ptr <= CTR('Z') )
299
{
300
buf[1] = '@' + *ptr;
301
gap->gap.input_callback( buf, 2 );
302
}
303
else if ( *str == '@' )
304
{
305
buf[1] = '@';
306
gap->gap.input_callback( buf, 2 );
307
}
308
else
309
gap->gap.input_callback( ptr, 1 );
310
}
311
return;
312
}
313
314
315
/****************************************************************************
316
**
317
*F GapTextSelectStart( <w>, <evt>, <parms>, <nums> ) . . . . pointer select
318
*/
319
static void GapTextSelectStart (
320
Widget w,
321
XEvent * evt,
322
String * parms,
323
Cardinal * nums )
324
{
325
GapTextWidget gap = (GapTextWidget) w;
326
TextWidget ctx = (TextWidget) w;
327
XawTextPosition oldPos;
328
XawTextPosition newPos;
329
330
/* save text position */
331
oldPos = gap->text.insertPos;
332
333
/* hide cursor, it will be make visible again in 'GapTextExtendEnd' */
334
XawTextDisplayCaret( w, False );
335
336
/* call our superclass */
337
XtCallActionProc( w, "select-start", evt, parms, *nums );
338
339
/* and restore text position */
340
if ( gap->gap.check_caret_pos != 0 )
341
newPos = oldPos+gap->gap.check_caret_pos(gap->text.insertPos,oldPos);
342
else
343
newPos = oldPos;
344
if ( newPos == oldPos )
345
ctx->text.insertPos = oldPos;
346
else
347
XawTextSetInsertionPoint( w, newPos );
348
}
349
350
351
/****************************************************************************
352
**
353
*F GapTextExtendAdjust( <w>, <evt>, <parms>, <nums> ) . . . pointer adjust
354
*/
355
static void GapTextExtendAdjust (
356
Widget w,
357
XEvent * evt,
358
String * parms,
359
Cardinal * nums )
360
{
361
GapTextWidget gap = (GapTextWidget) w;
362
TextWidget ctx = (TextWidget) w;
363
XawTextPosition oldPos;
364
365
/* save text position */
366
oldPos = gap->text.insertPos;
367
368
/* call our superclass */
369
XtCallActionProc( w, "extend-adjust", evt, parms, *nums );
370
371
/* and restore text position */
372
ctx->text.insertPos = oldPos;
373
374
/* XawTextSetInsertionPoint( w, oldPos ); */
375
}
376
377
378
/****************************************************************************
379
**
380
*F GapTextExtendEnd( <w>, <evt>, <parms>, <nums> ) . . . pointer select end
381
*/
382
static void GapTextExtendEnd (
383
Widget w,
384
XEvent * evt,
385
String * parms,
386
Cardinal * nums )
387
{
388
GapTextWidget gap = (GapTextWidget) w;
389
TextWidget ctx = (TextWidget) w;
390
XawTextPosition oldPos;
391
392
/* save text position */
393
oldPos = gap->text.insertPos;
394
395
/* call our superclass */
396
XtCallActionProc( w, "extend-end", evt, parms, *nums );
397
398
/* and restore text position */
399
ctx->text.insertPos = oldPos;
400
401
/* show cursor again, it is hidden in 'GapTextSelectStart' */
402
XawTextDisplayCaret( w, True );
403
404
/* XawTextSetInsertionPoint( w, oldPos ); */
405
}
406
407
408
/****************************************************************************
409
**
410
*F GapTextInitialize( <req>, <new>, <args>, <nums> ) . . . . make new widget
411
*/
412
static void GapTextInitialize (
413
Widget request,
414
Widget new,
415
ArgList args,
416
Cardinal * nums )
417
{
418
GapTextWidget w = (GapTextWidget) new;
419
Int i;
420
Int tabs[64];
421
Int tab;
422
423
/* initialize gap source and ascii sink */
424
if ( request->core.height == DEFAULT_TEXT_HEIGHT )
425
new->core.height = DEFAULT_TEXT_HEIGHT;
426
w->text.source = XtCreateWidget( "textSource",
427
gapSrcObjectClass,
428
new,
429
args, *nums );
430
w->text.sink = XtCreateWidget( "textSink",
431
asciiSinkObjectClass,
432
new,
433
args, *nums );
434
435
if ( w->core.height == DEFAULT_TEXT_HEIGHT )
436
w->core.height = VMargins(w)+XawTextSinkMaxHeight(w->text.sink,1);
437
w->gap.drop_gap_prompt = False;
438
439
/* set tab stops */
440
for ( i = 0, tab = 0; i < 64; i++)
441
tabs[i] = (tab += 8);
442
XawTextSinkSetTabs( w->text.sink, 64, tabs );
443
444
/* enable redisplay in text object */
445
XawTextDisableRedisplay(new);
446
XawTextEnableRedisplay(new);
447
}
448
449
450
/****************************************************************************
451
**
452
*F GapTextDestroy( <w> ) . . . . . . . . . . . . destroy a gap text widget
453
*/
454
static void GapTextDestroy (
455
Widget w )
456
{
457
GapTextWidget gap = (GapTextWidget) w;
458
459
if ( w == XtParent(gap->text.source) )
460
XtDestroyWidget( gap->text.source );
461
462
if ( w == XtParent(gap->text.sink) )
463
XtDestroyWidget( gap->text.sink );
464
}
465
466
467
/****************************************************************************
468
**
469
470
*V GapTextResources . . . . . . . . . . . . . . . . . resources of gap text
471
*/
472
#define offset(field) XtOffset(GapTextWidget, gap.field)
473
474
static XtResource GapTextResources[] =
475
{
476
/* gap text resources */
477
{ XtNinputCallback, XtCInputCallback, XtRPointer,
478
sizeof(char*), offset(input_callback), XtRPointer,
479
0
480
},
481
{ XtNcheckCaretPos, XtCCheckCaretPos, XtRPointer,
482
sizeof(char*), offset(check_caret_pos), XtRPointer,
483
0
484
},
485
486
/* other resources */
487
{ XtNtinyFont, XtCTinyFont, XtRFontStruct,
488
sizeof(XFontStruct*), offset(tiny_font), XtRString,
489
"-*-*-*-r-*-*-8-*-*-*-*-*-*-1"
490
},
491
{ XtNsmallFont, XtCSmallFont, XtRFontStruct,
492
sizeof(XFontStruct*), offset(small_font), XtRString,
493
"-*-*-*-r-*-*-10-*-*-*-*-*-*-1"
494
},
495
{ XtNnormalFont, XtCNormalFont, XtRFontStruct,
496
sizeof(XFontStruct*), offset(normal_font), XtRString,
497
"-*-*-*-r-*-*-13-*-*-*-*-*-*-1"
498
},
499
{ XtNlargeFont, XtCLargeFont, XtRFontStruct,
500
sizeof(XFontStruct*), offset(large_font), XtRString,
501
"-*-*-*-r-*-*-15-*-*-*-*-*-*-1"
502
},
503
{ XtNhugeFont, XtCHugeFont, XtRFontStruct,
504
sizeof(XFontStruct*), offset(huge_font), XtRString,
505
"-*-*-*-r-*-*-20-*-*-*-*-*-*-1"
506
},
507
{ XtNtitlePosition, XtCTitlePosition, XtRString,
508
sizeof(String), offset(title_position), XtRString,
509
"middle"
510
},
511
{ XtNpasteGapPrompt, XtCPasteGapPrompt, XtRBoolean,
512
sizeof(Boolean), offset(paste_gap_prompt), XtRString,
513
"False"
514
},
515
{ XtNquitGapCtrD, XtCQuitGapCtrD, XtRBoolean,
516
sizeof(Boolean), offset(quit_gap_ctrd), XtRString,
517
"False"
518
},
519
{ XtNcolorModel, XtCColorModel, XtRString,
520
sizeof(String), offset(color_model), XtRString,
521
"default"
522
},
523
{ XtNcolors, XtCColors, XtRString,
524
sizeof(String), offset(colors), XtRString,
525
"default"
526
}
527
};
528
529
#undef offset
530
531
532
/****************************************************************************
533
**
534
*V GapTextActions . . . . . . . . . . . . . . . . . . actions for gap text
535
*/
536
static XtActionsRec GapTextActions[] =
537
{
538
{ "gap-insert-char", GapTextInsertChar },
539
{ "gap-insert-selection", GapTextInsertSelection },
540
{ "gap-select-start", GapTextSelectStart },
541
{ "gap-extend-adjust", GapTextExtendAdjust },
542
{ "gap-extend-end", GapTextExtendEnd }
543
};
544
545
546
/****************************************************************************
547
**
548
*V GapTextTranslations . . . . . . . . . . . . . . . . . action translations
549
*/
550
static char GapTextTranslations[] =
551
"\
552
<Key>: gap-insert-char()\n\
553
<Btn1Down>: gap-select-start()\n\
554
<Btn1Motion>: gap-extend-adjust()\n\
555
<Btn1Up>: gap-extend-end( PRIMARY, CUT_BUFFER0 )\n\
556
<Btn2Down>: gap-insert-selection( PRIMARY, CUT_BUFFER0 )\n\
557
";
558
559
560
/****************************************************************************
561
**
562
*V gapTextWidgetClass . . . . . . . . . . . . . . . . gap text class record
563
*/
564
GapTextClassRec gapTextClassRec =
565
{
566
{ /* Core fields */
567
/* superclass */ (WidgetClass) &textClassRec,
568
/* class_name */ "GapText",
569
/* widget_size */ sizeof(GapRec),
570
/* class_initialize */ XawInitializeWidgetSet,
571
/* class_part_init */ NULL,
572
/* class_inited */ FALSE,
573
/* initialize */ GapTextInitialize,
574
/* initialize_hook */ NULL,
575
/* realize */ XtInheritRealize,
576
/* actions */ GapTextActions,
577
/* num_actions */ XtNumber(GapTextActions),
578
/* resources */ GapTextResources,
579
/* num_resource */ XtNumber(GapTextResources),
580
/* xrm_class */ NULLQUARK,
581
/* compress_motion */ TRUE,
582
#if HAVE_BROKEN_TEXT_EXPORE_COMPRESS
583
/* compress_exposure */ XtExposeNoCompress,
584
#else
585
/* compress_exposure */ XtExposeGraphicsExpose | XtExposeNoExpose,
586
#endif
587
/* compress_enterleave*/ TRUE,
588
/* visible_interest */ FALSE,
589
/* destroy */ GapTextDestroy,
590
/* resize */ XtInheritResize,
591
/* expose */ XtInheritExpose,
592
/* set_values */ NULL,
593
/* set_values_hook */ NULL,
594
/* set_values_almost */ XtInheritSetValuesAlmost,
595
/* get_values_hook */ NULL,
596
/* accept_focus */ XtInheritAcceptFocus,
597
/* version */ XtVersion,
598
/* callback_private */ NULL,
599
/* tm_table */ GapTextTranslations,
600
/* query_geometry */ XtInheritQueryGeometry
601
},
602
{ /* Simple fields */
603
/* change_sensitive */ XtInheritChangeSensitive
604
},
605
{ /* Text fields */
606
/* empty */ 0
607
},
608
{ /* Gap fields */
609
/* empty */ 0
610
}
611
};
612
613
WidgetClass gapTextWidgetClass = (WidgetClass)&gapTextClassRec;
614
615
616
/****************************************************************************
617
**
618
619
*F * * * * * * * * * * * * gap text source widget * * * * * * * * * * * * *
620
*/
621
622
623
/****************************************************************************
624
**
625
626
*F GapSrcInitialize( <req>, <new>, <args>, <nums> ) . . . . .new gap source
627
*/
628
static void GapSrcInitialize (
629
Widget request,
630
Widget new,
631
ArgList args,
632
Cardinal * nums )
633
{
634
GapSrcObject src = (GapSrcObject) new;
635
636
/* initially we use a 16KByte output buffer */
637
src->gap_src.size = 16 * 1024;
638
src->gap_src.buffer = XtMalloc(src->gap_src.size);
639
src->gap_src.length = 0;
640
}
641
642
643
/****************************************************************************
644
**
645
*F GapSrcDestroy( <w> ) . . . . . . . . . . . . destroy a gap source object
646
*/
647
static void GapSrcDestroy (
648
Widget w )
649
{
650
GapSrcObject src = (GapSrcObject) w;
651
652
/* free the output buffer */
653
XtFree( src->gap_src.buffer );
654
}
655
656
657
/****************************************************************************
658
**
659
*F GapSrcReadText( <w>, <pos>, <text>, <len> ) . . . get a piece of our text
660
**
661
** DESCRIPTION
662
** 'GapSrcReadText' sets the pointer <text>.ptr to the text of <w>
663
** starting at position <pos> and length <len>.
664
**
665
** RETURNS
666
** 'GapSrcReadText' returns the position relative to the beginning of text
667
** of <w> of the last character in <text>.
668
*/
669
static XawTextPosition GapSrcReadText (
670
Widget w,
671
XawTextPosition pos,
672
XawTextBlock * text,
673
unsigned long length )
674
{
675
GapSrcObject src = (GapSrcObject) w;
676
677
text->firstPos = pos;
678
text->ptr = src->gap_src.buffer + pos;
679
text->length = src->gap_src.length - pos;
680
text->format = FMT8BIT;
681
if ( length < text->length )
682
text->length = length;
683
return pos + text->length;
684
}
685
686
687
/****************************************************************************
688
**
689
*F GapSrcReplaceText( <w>, <start>, <end>, <text> ) . replace a text piece
690
**
691
** DESCRIPTION
692
** Replace the text of <w> starting with <start> and ending before <end>
693
** with the text given in <text>.
694
**
695
** RETURNS
696
** Either 'XawEditDone' or 'XawPositionError'.
697
*/
698
static int GapSrcReplaceText (
699
Widget w,
700
XawTextPosition start,
701
XawTextPosition end,
702
XawTextBlock * text )
703
{
704
GapSrcObject src = (GapSrcObject) w;
705
String p;
706
String q;
707
String e;
708
709
/* remove text from <start> to end */
710
p = src->gap_src.buffer + start;
711
q = src->gap_src.buffer + end;
712
e = src->gap_src.buffer + src->gap_src.length;
713
while ( p < e )
714
*p++ = *q++;
715
src->gap_src.length += start - end;
716
717
/* now insert the new text */
718
if ( 0 < text->length )
719
{
720
if ( src->gap_src.size < src->gap_src.length + text->length )
721
{
722
src->gap_src.size += 16*1024 + text->length;
723
src->gap_src.buffer = XtRealloc( src->gap_src.buffer,
724
src->gap_src.size );
725
}
726
p = ( src->gap_src.buffer + src->gap_src.length ) - 1;
727
q = p + text->length;
728
e = src->gap_src.buffer + start;
729
while ( e <= p )
730
*q-- = *p--;
731
q = text->ptr;
732
p = e;
733
e = p + text->length;
734
while ( p < e )
735
*p++ = *q++;
736
src->gap_src.length += text->length;
737
}
738
return XawEditDone;
739
}
740
741
742
/****************************************************************************
743
**
744
*F GapSrcScan( <w>, <pos>, <type>, <dir>, <cnt>, <inc> ) . . . . . scan text
745
**
746
** DESCRIPTION
747
** Scan the text in <w>.buffer for the <cnt>.th occurance of a boundary of
748
** type <type>. Start the scan at position <pos>. If <include> is true
749
** include the boundary in the returned position.
750
**
751
** RETURNS
752
** 'Scan' returns the position of the boundary.
753
*/
754
static XawTextPosition GapSrcScan (
755
Widget w,
756
XawTextPosition pos,
757
XawTextScanType type,
758
XawTextScanDirection dir,
759
int cnt,
760
int ind )
761
{
762
GapSrcObject src = (GapSrcObject) w;
763
Int inc;
764
String p;
765
766
/* first or last position in our text */
767
if ( type == XawstAll )
768
return (dir == XawsdRight) ? src->gap_src.length : 0;
769
770
/* set <pos> to a sensible value */
771
if ( pos > src->gap_src.length )
772
pos = src->gap_src.length;
773
774
/* we cannot scan left of position 0 or right of the text end */
775
if ( dir == XawsdRight && pos == src->gap_src.length )
776
return src->gap_src.length;
777
else if ( dir == XawsdLeft && pos == 0 )
778
return 0;
779
else if ( dir == XawsdLeft )
780
pos--;
781
782
/* <inc> is used to increment (decrement) <p> and <pos> */
783
inc = (dir == XawsdRight) ? 1 : -1;
784
785
/* handle different types of boundaries <cnt> times */
786
switch ( type )
787
{
788
case XawstAll: /* is not possible */
789
return (dir == XawsdRight) ? src->gap_src.length : 0;
790
break;
791
792
case XawstEOL:
793
case XawstParagraph:
794
if ( dir == XawsdRight )
795
{
796
for ( ; 0 < cnt; cnt-- )
797
{
798
p = src->gap_src.buffer + pos;
799
while ( pos < src->gap_src.length )
800
{
801
if ( *p == '\n' )
802
break;
803
pos++; p++;
804
}
805
if ( src->gap_src.length < pos )
806
return src->gap_src.length;
807
pos++;
808
}
809
}
810
else
811
{
812
for ( ; 0 < cnt; cnt-- )
813
{
814
p = src->gap_src.buffer + pos;
815
while ( 0 <= pos )
816
{
817
if ( *p == '\n' )
818
break;
819
pos--; p--;
820
}
821
if ( pos < 0 )
822
return 0;
823
pos--;
824
}
825
}
826
if ( !ind )
827
pos -= inc;
828
break;
829
830
831
case XawstWhiteSpace:
832
for ( ; 0 < cnt; cnt-- )
833
{
834
Boolean nonSpace = FALSE;
835
836
p = src->gap_src.buffer + pos;
837
while ( 0 <= pos && pos < src->gap_src.length )
838
{
839
if ( *p == ' ' || *p == '\t' || *p == '\n' )
840
{
841
if ( nonSpace )
842
break;
843
}
844
else
845
nonSpace = TRUE;
846
pos += inc;
847
p += inc;
848
}
849
if ( pos < 0 )
850
return 0;
851
if ( src->gap_src.length < pos )
852
return src->gap_src.length;
853
pos += inc;
854
}
855
if ( !ind )
856
pos -= inc;
857
break;
858
859
case XawstPositions:
860
pos += cnt * inc;
861
break;
862
863
default:
864
break;
865
}
866
if ( dir == XawsdLeft )
867
pos++;
868
869
/* set <pos> to a sensible value and return */
870
if ( pos >= src->gap_src.length )
871
return src->gap_src.length;
872
else if ( pos < 0 )
873
return 0;
874
else
875
return pos;
876
}
877
878
879
/****************************************************************************
880
**
881
*V gapSrcObjectClass . . . . . . . . . . . . . . . . gap source class record
882
*/
883
GapSrcClassRec gapSrcClassRec =
884
{
885
{ /* core_class fields */
886
/* superclass */ (WidgetClass) (&textSrcClassRec),
887
/* class_name */ "GapSrc",
888
/* widget_size */ sizeof(GapSrcRec),
889
/* class_initialize */ XawInitializeWidgetSet,
890
/* class_part_initialize */ NULL,
891
/* class_inited */ FALSE,
892
/* initialize */ (XtInitProc) GapSrcInitialize,
893
/* initialize_hook */ NULL,
894
/* realize */ NULL,
895
/* actions */ NULL,
896
/* num_actions */ 0,
897
/* resources */ NULL,
898
/* num_resources */ 0,
899
/* xrm_class */ NULLQUARK,
900
/* compress_motion */ FALSE,
901
/* compress_exposure */ FALSE,
902
/* compress_enterleave */ FALSE,
903
/* visible_interest */ FALSE,
904
/* destroy */ GapSrcDestroy,
905
/* resize */ NULL,
906
/* expose */ NULL,
907
/* set_values */ NULL,
908
/* set_values_hook */ NULL,
909
/* set_values_almost */ NULL,
910
/* get_values_hook */ NULL,
911
/* accept_focus */ NULL,
912
/* version */ XtVersion,
913
/* callback_private */ NULL,
914
/* tm_table */ NULL,
915
/* query_geometry */ NULL,
916
/* display_accelerator */ NULL,
917
/* extension */ NULL
918
},
919
{ /* textSrc_class fields */
920
/* Read */ (XawTextPosition (*)())GapSrcReadText,
921
/* Replace */ (int (*)()) GapSrcReplaceText,
922
/* Scan */ (XawTextPosition (*)()) GapSrcScan,
923
/* Search */ XtInheritSearch,
924
/* SetSelection */ XtInheritSetSelection,
925
/* ConvertSelection */ XtInheritConvertSelection
926
},
927
{ /* GapSrc_class fields */
928
/* Keep the compiler happy */ NULL
929
}
930
};
931
932
WidgetClass gapSrcObjectClass = (WidgetClass)&gapSrcClassRec;
933
934
935
/* * * * * * * * * * * * * gap text widget functions * * * * * * * * * * * */
936
937
938
/****************************************************************************
939
**
940
941
*F CheckTextBlock( <block> ) . . . . . . . . check a block for special chars
942
*/
943
#if 0
944
static char * CheckTextBlockTmp = 0;
945
946
static void CheckTextBlock ( XawTextBlock * block )
947
{
948
unsigned char * p;
949
unsigned char * q;
950
unsigned int i;
951
unsigned int s;
952
953
p = (unsigned char*) block->ptr;
954
for ( s = 0, i = 0; i < block->length; i++, p++ )
955
if ( *p < 32 && *p != '\n' && *p != '\r' )
956
s++;
957
if ( s == 0 )
958
return;
959
if ( CheckTextBlockTmp != 0 )
960
XtFree(CheckTextBlockTmp);
961
CheckTextBlockTmp = XtMalloc(block->length + s);
962
p = (unsigned char*) block->ptr;
963
q = (unsigned char*) CheckTextBlockTmp;
964
for ( i = 0; i < block->length; i++, p++ )
965
{
966
if ( *p < 32 )
967
{
968
*q++ = '^';
969
*q++ = *p + 'A';
970
}
971
else
972
*q++ = *p;
973
}
974
block->ptr = CheckTextBlockTmp;
975
}
976
#endif
977
978
979
/****************************************************************************
980
**
981
*F GTPosition( <w> ) . . . . . . . . . . . . . . . . return insertion point
982
*/
983
Int GTPosition ( Widget w )
984
{
985
GapTextWidget gap = (GapTextWidget) w;
986
987
return gap->text.insertPos;
988
}
989
990
991
/****************************************************************************
992
**
993
*F GTSetPosition( <w>, <pos> ) . . . . . . . . . . . . set insertion point
994
*/
995
void GTSetPosition ( Widget w, Int pos )
996
{
997
XawTextSetInsertionPoint( w, pos );
998
}
999
1000
1001
/****************************************************************************
1002
**
1003
*F GTDelete( <w>, <dir>, <type> ) . . . . . . . . . delete a piece of text
1004
*/
1005
void GTDelete ( Widget w, XawTextScanDirection dir, XawTextScanType type )
1006
{
1007
GapTextWidget gap = (GapTextWidget) w;
1008
XawTextBlock text;
1009
Int to;
1010
Int from;
1011
1012
/* prepare text for update */
1013
_XawTextPrepareToUpdate(gap);
1014
gap->text.time = CurrentTime;
1015
1016
/* find <to> and <from> */
1017
to = GapSrcScan(gap->text.source,gap->text.insertPos,type,dir,1,TRUE);
1018
1019
if ( to == gap->text.insertPos )
1020
to = GapSrcScan(gap->text.source,gap->text.insertPos,type,dir,2,TRUE);
1021
if (dir == XawsdLeft)
1022
{
1023
from = to;
1024
to = gap->text.insertPos;
1025
}
1026
else
1027
from = gap->text.insertPos;
1028
1029
/* remove text */
1030
text.length = 0;
1031
text.firstPos = 0;
1032
if ( _XawTextReplace( gap, from, to, &text ) )
1033
{
1034
XBell(XtDisplay(gap), 50);
1035
goto error;
1036
}
1037
gap->text.insertPos = from;
1038
gap->text.showposition = TRUE;
1039
_XawTextSetScrollBars(gap);
1040
1041
/* do update */
1042
error:
1043
_XawTextCheckResize(gap);
1044
_XawTextExecuteUpdate(gap);
1045
gap->text.mult = 1;
1046
}
1047
1048
1049
/****************************************************************************
1050
**
1051
*F GTInsertText( <w>, <str>, <len> ) . . . . . insert <str> into a gap text
1052
**
1053
** DESCRIPTION
1054
** This functions insert the text pointed to by <str> of length <len> in
1055
** the gap text widget at the current position. It is the responsibility
1056
** of the caller to set the current insertion position.
1057
*/
1058
void GTInsertText ( Widget w, String str, Int len )
1059
{
1060
GapTextWidget gap = (GapTextWidget) w;
1061
XawTextBlock block;
1062
1063
/* convert text into a text block */
1064
block.firstPos = 0;
1065
block.ptr = (char*) str;
1066
block.format = FMT8BIT;
1067
block.length = len;
1068
#if 0
1069
CheckTextBlock(&block);
1070
#endif
1071
1072
/* insert text at current position */
1073
XawTextReplace( w, gap->text.insertPos, gap->text.insertPos, &block );
1074
1075
/* move insertion position */
1076
XawTextSetInsertionPoint( w, gap->text.insertPos+len );
1077
}
1078
1079
1080
/****************************************************************************
1081
**
1082
*F GTReplaceText( <w>, <str>, <len> ) . . . . . replace last line by <str>
1083
**
1084
** DESCRIPTION
1085
** This functions replaces the text right of the insert point by the text
1086
** pointed to by <str> of length <len>. It is the responsibility of the
1087
** caller to set the current insertion position.
1088
*/
1089
void GTReplaceText ( Widget w, String str, Int len )
1090
{
1091
GapTextWidget gap = (GapTextWidget) w;
1092
XawTextBlock block;
1093
1094
/* convert text into a text block */
1095
block.firstPos = 0;
1096
block.ptr = (char*) str;
1097
block.format = FMT8BIT;
1098
block.length = len;
1099
#if 0
1100
CheckTextBlock(&block);
1101
#endif
1102
1103
/* insert text at current position */
1104
XawTextReplace(w,gap->text.insertPos,gap->text.insertPos+len,&block);
1105
1106
/* move insertion position */
1107
XawTextSetInsertionPoint( w, gap->text.insertPos+len );
1108
}
1109
1110
1111
/****************************************************************************
1112
**
1113
*F GTMoveCaret( <w>, <rpos> ) . . . move caret relative to current position
1114
*/
1115
void GTMoveCaret ( Widget w, Int rpos )
1116
{
1117
GapTextWidget gap = (GapTextWidget) w;
1118
Int pos;
1119
1120
pos = gap->text.insertPos+rpos;
1121
if ( pos < 0 )
1122
pos = 0;
1123
if ( ((GapSrcObject)gap->text.source)->gap_src.length < pos )
1124
pos = ((GapSrcObject)gap->text.source)->gap_src.length;
1125
XawTextSetInsertionPoint( w, pos );
1126
}
1127
1128
1129
/****************************************************************************
1130
**
1131
*F GTDeleteLeft( <w> ) . . . . . . . . . . . delete a char left of the caret
1132
*/
1133
void GTDeleteLeft ( Widget w )
1134
{
1135
GapTextWidget gap = (GapTextWidget) w;
1136
1137
/* check if there is a character to the left */
1138
if ( gap->text.insertPos <= 0 )
1139
return;
1140
1141
/* use 'GTDelete' */
1142
GTDelete( w, XawsdLeft, XawstPositions );
1143
}
1144
1145
1146
/****************************************************************************
1147
**
1148
*F GTDeleteRight( <w> ) . . . . . . . . . delete a char right of the caret
1149
*/
1150
void GTDeleteRight ( Widget w )
1151
{
1152
GapTextWidget gap = (GapTextWidget) w;
1153
1154
/* check if there is a character to the right */
1155
if ( ((GapSrcObject)gap->text.source)->gap_src.length
1156
<=
1157
gap->text.insertPos )
1158
return;
1159
1160
/* use 'GTDelete' */
1161
GTDelete( w, XawsdRight, XawstPositions );
1162
}
1163
1164
1165
/****************************************************************************
1166
**
1167
*F GTBell( <w> ) . . . . . . . . . . . . . . . . . . . . . . . ring my bell
1168
*/
1169
void GTBell ( Widget w )
1170
{
1171
XBell( XtDisplay(w), 50 );
1172
}
1173
1174
1175
/****************************************************************************
1176
**
1177
*F GTDropGapPrompt( <w>, <flag> ) . . . . . . . . set drop gap prompt flag
1178
*/
1179
void GTDropGapPrompt ( Widget w, Boolean flag )
1180
{
1181
GapTextWidget gap = (GapTextWidget) w;
1182
1183
gap->gap.drop_gap_prompt = flag;
1184
}
1185
1186
1187
/****************************************************************************
1188
**
1189
1190
*E gaptext.c . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
1191
*/
1192
1193