/****************************************************************************
* *
* W gaptext . c XGAP source Frank Celler
* *
* *
* Y Copyright 1995 - 1997 , Lehrstuhl D fuer Mathematik , RWTH Aachen , Germany
* Y Copyright 1997 , Frank Celler , Huerth , Germany
* *
* * The GapTextWidget is intended to be used as a simple front end to the
* * text widget with a gap text source and an ascii sink attached to it . It
* * is a subclass of the standard text widget supplied with X11R4 and should
* * work with X11R5 and X11R6 .
*/
#include "utils.h"
#include "gaptext.h"
extern void _XawTextPrepareToUpdate(TextWidget);
extern int _XawTextReplace(TextWidget, XawTextPosition, XawTextPosition, XawTextBlock *);
extern void _XawTextSetScrollBars(TextWidget);
extern void _XawTextCheckResize(TextWidget);
extern void _XawTextExecuteUpdate(TextWidget);
/****************************************************************************
* *
* F * * * * * * * * * * * * * * gap text widget * * * * * * * * * * * * * * *
*/
/****************************************************************************
* *
* F GapTextInsertSelection ( < w > , < evt > , < parms > , < nums > ) . . . . insert text
* *
* * DESCRIPTION
* * Handle a selection insert event . ' GapTextInsertSelection ' calls the
* * input callback method with the selected string .
*/
#define CTR(a) ( a & 0 x1f )
static void GetSelection ( Widget, Time, String *, Cardinal );
static void GapTextInsertSelection (
Widget w,
XEvent * evt,
String * parms,
Cardinal * nums )
{
Time time = 0 ;
/* get the time of the event */
if ( evt != NULL )
switch ( evt->type )
{
case ButtonPress:
case ButtonRelease:
time = evt->xbutton.time;
break ;
case KeyPress:
case KeyRelease:
time = evt->xkey.time;
break ;
default :
time = CurrentTime;
break ;
}
/* and insert the selection */
GetSelection( w, time, parms, *nums );
}
struct _SelectionList
{
String * params;
Cardinal count;
Time time;
};
static void DoSelection (
Widget w,
XtPointer cd,
Atom * selection,
Atom * type,
XtPointer value,
UInt * length,
Int * format )
{
GapTextWidget gap = (GapTextWidget) w;
char buf[2 ];
String ptr;
Boolean nl;
Int len;
if ( *type == 0 || *length == 0 )
{
struct _SelectionList* list = (struct _SelectionList*)cd;
if ( list != NULL )
{
GetSelection( w, list->time, list->params, list->count );
XtFree(cd);
}
return ;
}
/* check if string begins with gap prompt */
ptr = (char *) value;
len = *length;
if ( gap->gap.drop_gap_prompt )
{
if ( 2 < len && ptr[0 ] == '>' && ptr[1 ] == ' ' )
{
ptr += 2 ;
len -= 2 ;
}
else if ( 5 < len && !strncmp( ptr, "gap> " , 5 ) )
{
ptr += 5 ;
len -= 5 ;
}
else if ( 5 < len && !strncmp( ptr, "brk> " , 5 ) )
{
ptr += 5 ;
len -= 5 ;
}
}
/* and call the callback */
buf[0 ] = '@' ;
for ( nl = False ; 0 < len; len--, ptr++ )
{
if ( nl && gap->gap.drop_gap_prompt )
{
if ( 2 < len && ptr[0 ] == '>' && ptr[1 ] == ' ' )
{
ptr += 1 ;
len -= 1 ;
continue ;
}
else if ( 5 < len && !strncmp( ptr, "gap> " , 5 ) )
{
ptr += 4 ;
len -= 4 ;
continue ;
}
else if ( 5 < len && !strncmp( ptr, "brk> " , 5 ) )
{
ptr += 4 ;
len -= 4 ;
}
}
if ( CTR('@' ) < *ptr && *ptr <= CTR('Z' ) )
{
buf[1 ] = '@' + *ptr;
gap->gap.input_callback( buf, 2 );
}
else if ( *ptr == '@' )
{
buf[1 ] = '@' ;
gap->gap.input_callback( buf, 2 );
}
else
gap->gap.input_callback( ptr, 1 );
nl = *ptr == '\n' || *ptr == '\r' ;
}
XtFree(cd);
XFree(value);
}
static void GetSelection (
Widget w,
Time time,
String * parms,
Cardinal nums )
{
Atom selection;
Int buffer;
/* try to find which buffer <*parms> is pointing to */
selection = XInternAtom( XtDisplay(w), *parms, False );
switch (selection)
{
case XA_CUT_BUFFER0: buffer = 0 ; break ;
case XA_CUT_BUFFER1: buffer = 1 ; break ;
case XA_CUT_BUFFER2: buffer = 2 ; break ;
case XA_CUT_BUFFER3: buffer = 3 ; break ;
case XA_CUT_BUFFER4: buffer = 4 ; break ;
case XA_CUT_BUFFER5: buffer = 5 ; break ;
case XA_CUT_BUFFER6: buffer = 6 ; break ;
case XA_CUT_BUFFER7: buffer = 7 ; break ;
default : buffer = -1 ; break ;
}
/* if <*parms> is a cut buffer insert its contents */
if ( buffer >= 0 )
{
Atom type = XA_STRING;
Int fmt8 = 8 ;
Int nbytes;
String line;
UInt length;
line = XFetchBuffer( XtDisplay(w), &nbytes, buffer );
if ( 0 < ( length = nbytes ) )
DoSelection( w, NULL, &selection, &type, (caddr_t) line,
&length, &fmt8 );
else if ( 1 < nums )
GetSelection( w, time, parms+1 , nums-1 );
}
else
{
struct _SelectionList * list;
if ( --nums )
{
list = XtNew(struct _SelectionList);
list->params = parms + 1 ;
list->count = nums;
list->time = time;
}
else
list = NULL;
XtGetSelectionValue( w, selection, XA_STRING,
(XtSelectionCallbackProc) DoSelection, (XtPointer)list, time );
}
}
/****************************************************************************
* *
* F GapTextInsertChar ( < w > , < evt > , < parms > , < nums > ) . . . . . . handle keys
* *
* * DESCRIPTION
* * Handle a key event . ' GapTextInsertChar ' calls the input callback method
* * with a one ( or possible more ) character string .
*/
static void GapTextInsertChar (
Widget w,
XEvent * evt,
String * parms,
Cardinal * nums )
{
GapTextWidget gap = (GapTextWidget) w;
Int len;
KeySym keysym;
String ptr;
char buf[2 ];
char str[128 ];
/* if no input call is registered return */
if ( gap->gap.input_callback == 0 )
return ;
/* convert key event into text string */
len = XLookupString( &(evt->xkey), str, 128 , &keysym, 0 );
/* handle arrows keys, etc */
if ( len == 0 )
{
len = 1 ;
str[len] = 0 ;
/* Switched Arrow Up and PageUp behaviour, and
Arrow Down and PageDown behaviour resp., 22.3.1999 Max */
if ( keysym == XK_Left )
str[0 ] = CTR('B' );
else if ( keysym == XK_Up )
str[0 ] = CTR('P' );
else if ( keysym == XK_Right )
str[0 ] = CTR('F' );
else if ( keysym == XK_Down )
str[0 ] = CTR('N' );
else if ( keysym == XK_Prior )
{
len = 2 ;
strcpy( str, "\001\020" );
}
else if ( keysym == XK_Next )
{
len = 2 ;
strcpy( str, "\001\016" );
}
else if ( keysym == XK_Home )
{
len = 2 ;
strcpy( str, "\033<" );
}
else if ( keysym == XK_Insert )
str[0 ] = CTR('L' );
else
return ;
}
/* and call the callback */
buf[0 ] = '@' ;
for ( ptr = str; 0 < len; len--, ptr++ )
{
if ( CTR('@' ) < *ptr && *ptr <= CTR('Z' ) )
{
buf[1 ] = '@' + *ptr;
gap->gap.input_callback( buf, 2 );
}
else if ( *str == '@' )
{
buf[1 ] = '@' ;
gap->gap.input_callback( buf, 2 );
}
else
gap->gap.input_callback( ptr, 1 );
}
return ;
}
/****************************************************************************
* *
* F GapTextSelectStart ( < w > , < evt > , < parms > , < nums > ) . . . . pointer select
*/
static void GapTextSelectStart (
Widget w,
XEvent * evt,
String * parms,
Cardinal * nums )
{
GapTextWidget gap = (GapTextWidget) w;
TextWidget ctx = (TextWidget) w;
XawTextPosition oldPos;
XawTextPosition newPos;
/* save text position */
oldPos = gap->text.insertPos;
/* hide cursor, it will be make visible again in 'GapTextExtendEnd' */
XawTextDisplayCaret( w, False );
/* call our superclass */
XtCallActionProc( w, "select-start" , evt, parms, *nums );
/* and restore text position */
if ( gap->gap.check_caret_pos != 0 )
newPos = oldPos+gap->gap.check_caret_pos(gap->text.insertPos,oldPos);
else
newPos = oldPos;
if ( newPos == oldPos )
ctx->text.insertPos = oldPos;
else
XawTextSetInsertionPoint( w, newPos );
}
/****************************************************************************
* *
* F GapTextExtendAdjust ( < w > , < evt > , < parms > , < nums > ) . . . pointer adjust
*/
static void GapTextExtendAdjust (
Widget w,
XEvent * evt,
String * parms,
Cardinal * nums )
{
GapTextWidget gap = (GapTextWidget) w;
TextWidget ctx = (TextWidget) w;
XawTextPosition oldPos;
/* save text position */
oldPos = gap->text.insertPos;
/* call our superclass */
XtCallActionProc( w, "extend-adjust" , evt, parms, *nums );
/* and restore text position */
ctx->text.insertPos = oldPos;
/* XawTextSetInsertionPoint( w, oldPos ); */
}
/****************************************************************************
* *
* F GapTextExtendEnd ( < w > , < evt > , < parms > , < nums > ) . . . pointer select end
*/
static void GapTextExtendEnd (
Widget w,
XEvent * evt,
String * parms,
Cardinal * nums )
{
GapTextWidget gap = (GapTextWidget) w;
TextWidget ctx = (TextWidget) w;
XawTextPosition oldPos;
/* save text position */
oldPos = gap->text.insertPos;
/* call our superclass */
XtCallActionProc( w, "extend-end" , evt, parms, *nums );
/* and restore text position */
ctx->text.insertPos = oldPos;
/* show cursor again, it is hidden in 'GapTextSelectStart' */
XawTextDisplayCaret( w, True );
/* XawTextSetInsertionPoint( w, oldPos ); */
}
/****************************************************************************
* *
* F GapTextInitialize ( < req > , < new > , < args > , < nums > ) . . . . make new widget
*/
static void GapTextInitialize (
Widget request,
Widget new ,
ArgList args,
Cardinal * nums )
{
GapTextWidget w = (GapTextWidget) new ;
Int i;
Int tabs[64 ];
Int tab;
/* initialize gap source and ascii sink */
if ( request->core.height == DEFAULT_TEXT_HEIGHT )
new ->core.height = DEFAULT_TEXT_HEIGHT;
w->text.source = XtCreateWidget( "textSource" ,
gapSrcObjectClass,
new ,
args, *nums );
w->text.sink = XtCreateWidget( "textSink" ,
asciiSinkObjectClass,
new ,
args, *nums );
if ( w->core.height == DEFAULT_TEXT_HEIGHT )
w->core.height = VMargins(w)+XawTextSinkMaxHeight(w->text.sink,1 );
w->gap.drop_gap_prompt = False ;
/* set tab stops */
for ( i = 0 , tab = 0 ; i < 64 ; i++)
tabs[i] = (tab += 8 );
XawTextSinkSetTabs( w->text.sink, 64 , tabs );
/* enable redisplay in text object */
XawTextDisableRedisplay(new );
XawTextEnableRedisplay(new );
}
/****************************************************************************
* *
* F GapTextDestroy ( < w > ) . . . . . . . . . . . . destroy a gap text widget
*/
static void GapTextDestroy (
Widget w )
{
GapTextWidget gap = (GapTextWidget) w;
if ( w == XtParent(gap->text.source) )
XtDestroyWidget( gap->text.source );
if ( w == XtParent(gap->text.sink) )
XtDestroyWidget( gap->text.sink );
}
/****************************************************************************
* *
* V GapTextResources . . . . . . . . . . . . . . . . . resources of gap text
*/
#define offset(field) XtOffset(GapTextWidget, gap.field)
static XtResource GapTextResources[] =
{
/* gap text resources */
{ XtNinputCallback, XtCInputCallback, XtRPointer,
sizeof (char *), offset(input_callback), XtRPointer,
0
},
{ XtNcheckCaretPos, XtCCheckCaretPos, XtRPointer,
sizeof (char *), offset(check_caret_pos), XtRPointer,
0
},
/* other resources */
{ XtNtinyFont, XtCTinyFont, XtRFontStruct,
sizeof (XFontStruct*), offset(tiny_font), XtRString,
"-*-*-*-r-*-*-8-*-*-*-*-*-*-1"
},
{ XtNsmallFont, XtCSmallFont, XtRFontStruct,
sizeof (XFontStruct*), offset(small_font), XtRString,
"-*-*-*-r-*-*-10-*-*-*-*-*-*-1"
},
{ XtNnormalFont, XtCNormalFont, XtRFontStruct,
sizeof (XFontStruct*), offset(normal_font), XtRString,
"-*-*-*-r-*-*-13-*-*-*-*-*-*-1"
},
{ XtNlargeFont, XtCLargeFont, XtRFontStruct,
sizeof (XFontStruct*), offset(large_font), XtRString,
"-*-*-*-r-*-*-15-*-*-*-*-*-*-1"
},
{ XtNhugeFont, XtCHugeFont, XtRFontStruct,
sizeof (XFontStruct*), offset(huge_font), XtRString,
"-*-*-*-r-*-*-20-*-*-*-*-*-*-1"
},
{ XtNtitlePosition, XtCTitlePosition, XtRString,
sizeof (String), offset(title_position), XtRString,
"middle"
},
{ XtNpasteGapPrompt, XtCPasteGapPrompt, XtRBoolean,
sizeof (Boolean), offset(paste_gap_prompt), XtRString,
"False"
},
{ XtNquitGapCtrD, XtCQuitGapCtrD, XtRBoolean,
sizeof (Boolean), offset(quit_gap_ctrd), XtRString,
"False"
},
{ XtNcolorModel, XtCColorModel, XtRString,
sizeof (String), offset(color_model), XtRString,
"default"
},
{ XtNcolors, XtCColors, XtRString,
sizeof (String), offset(colors), XtRString,
"default"
}
};
#undef offset
/****************************************************************************
* *
* V GapTextActions . . . . . . . . . . . . . . . . . . actions for gap text
*/
static XtActionsRec GapTextActions[] =
{
{ "gap-insert-char" , GapTextInsertChar },
{ "gap-insert-selection" , GapTextInsertSelection },
{ "gap-select-start" , GapTextSelectStart },
{ "gap-extend-adjust" , GapTextExtendAdjust },
{ "gap-extend-end" , GapTextExtendEnd }
};
/****************************************************************************
* *
* V GapTextTranslations . . . . . . . . . . . . . . . . . action translations
*/
static char GapTextTranslations[] =
"\
<Key>: gap-insert-char ()\n\
<Btn1Down>: gap-select-start()\n\
<Btn1Motion>: gap-extend-adjust()\n\
<Btn1Up>: gap-extend-end( PRIMARY, CUT_BUFFER0 )\n\
<Btn2Down>: gap-insert-selection( PRIMARY, CUT_BUFFER0 )\n\
";
/****************************************************************************
* *
* V gapTextWidgetClass . . . . . . . . . . . . . . . . gap text class record
*/
GapTextClassRec gapTextClassRec =
{
{ /* Core fields */
/* superclass */ (WidgetClass) &textClassRec,
/* class_name */ "GapText",
/* widget_size */ sizeof(GapRec),
/* class_initialize */ XawInitializeWidgetSet,
/* class_part_init */ NULL,
/* class_inited */ FALSE,
/* initialize */ GapTextInitialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ GapTextActions,
/* num_actions */ XtNumber(GapTextActions),
/* resources */ GapTextResources,
/* num_resource */ XtNumber(GapTextResources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ XtExposeGraphicsExpose | XtExposeNoExpose,
/* compress_enterleave*/ TRUE,
/* visible_interest */ FALSE,
/* destroy */ GapTextDestroy,
/* resize */ XtInheritResize,
/* expose */ XtInheritExpose,
/* set_values */ NULL,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ XtInheritAcceptFocus,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ GapTextTranslations,
/* query_geometry */ XtInheritQueryGeometry
},
{ /* Simple fields */
/* change_sensitive */ XtInheritChangeSensitive
},
{ /* Text fields */
/* empty */ 0
},
{ /* Gap fields */
/* empty */ 0
}
};
WidgetClass gapTextWidgetClass = (WidgetClass)&gapTextClassRec;
/****************************************************************************
* *
* F * * * * * * * * * * * * gap text source widget * * * * * * * * * * * * *
*/
/****************************************************************************
* *
* F GapSrcInitialize ( < req > , < new > , < args > , < nums > ) . . . . . new gap source
*/
static void GapSrcInitialize (
Widget request,
Widget new ,
ArgList args,
Cardinal * nums )
{
GapSrcObject src = (GapSrcObject) new ;
/* initially we use a 16KByte output buffer */
src->gap_src.size = 16 * 1024 ;
src->gap_src.buffer = XtMalloc(src->gap_src.size);
src->gap_src.length = 0 ;
}
/****************************************************************************
* *
* F GapSrcDestroy ( < w > ) . . . . . . . . . . . . destroy a gap source object
*/
static void GapSrcDestroy (
Widget w )
{
GapSrcObject src = (GapSrcObject) w;
/* free the output buffer */
XtFree( src->gap_src.buffer );
}
/****************************************************************************
* *
* F GapSrcReadText ( < w > , < pos > , < text > , < len > ) . . . get a piece of our text
* *
* * DESCRIPTION
* * ' GapSrcReadText ' sets the pointer < text > . ptr to the text of < w >
* * starting at position < pos > and length < len > .
* *
* * RETURNS
* * ' GapSrcReadText ' returns the position relative to the beginning of text
* * of < w > of the last character in < text > .
*/
static XawTextPosition GapSrcReadText (
Widget w,
XawTextPosition pos,
XawTextBlock * text,
Int length )
{
GapSrcObject src = (GapSrcObject) w;
text->firstPos = pos;
text->ptr = src->gap_src.buffer + pos;
text->length = src->gap_src.length - pos;
text->format = FMT8BIT;
if ( length < text->length )
text->length = length;
return pos + text->length;
}
/****************************************************************************
* *
* F GapSrcReplaceText ( < w > , < start > , < end > , < text > ) . replace a text piece
* *
* * DESCRIPTION
* * Replace the text of < w > starting with < start > and ending before < end >
* * with the text given in < text > .
* *
* * RETURNS
* * Either ' XawEditDone ' or ' XawPositionError ' .
*/
static int GapSrcReplaceText (
Widget w,
XawTextPosition start,
XawTextPosition end,
XawTextBlock * text )
{
GapSrcObject src = (GapSrcObject) w;
String p;
String q;
String e;
/* remove text from <start> to end */
p = src->gap_src.buffer + start;
q = src->gap_src.buffer + end;
e = src->gap_src.buffer + src->gap_src.length;
while ( p < e )
*p++ = *q++;
src->gap_src.length += start - end;
/* now insert the new text */
if ( 0 < text->length )
{
if ( src->gap_src.size < src->gap_src.length + text->length )
{
src->gap_src.size += 16 *1024 + text->length;
src->gap_src.buffer = XtRealloc( src->gap_src.buffer,
src->gap_src.size );
}
p = ( src->gap_src.buffer + src->gap_src.length ) - 1 ;
q = p + text->length;
e = src->gap_src.buffer + start;
while ( e <= p )
*q-- = *p--;
q = text->ptr;
p = e;
e = p + text->length;
while ( p < e )
*p++ = *q++;
src->gap_src.length += text->length;
}
return XawEditDone;
}
/****************************************************************************
* *
* F GapSrcScan ( < w > , < pos > , < type > , < dir > , < cnt > , < inc > ) . . . . . scan text
* *
* * DESCRIPTION
* * Scan the text in < w > . buffer for the < cnt > . th occurrence of a boundary of
* * type < type > . Start the scan at position < pos > . If < include > is true
* * include the boundary in the returned position .
* *
* * RETURNS
* * ' Scan ' returns the position of the boundary .
*/
static XawTextPosition GapSrcScan (
Widget w,
XawTextPosition pos,
XawTextScanType type,
XawTextScanDirection dir,
int cnt,
int ind )
{
GapSrcObject src = (GapSrcObject) w;
Int inc;
String p;
/* first or last position in our text */
if ( type == XawstAll )
return (dir == XawsdRight) ? src->gap_src.length : 0 ;
/* set <pos> to a sensible value */
if ( pos > src->gap_src.length )
pos = src->gap_src.length;
/* we cannot scan left of position 0 or right of the text end */
if ( dir == XawsdRight && pos == src->gap_src.length )
return src->gap_src.length;
else if ( dir == XawsdLeft && pos == 0 )
return 0 ;
else if ( dir == XawsdLeft )
pos--;
/* <inc> is used to increment (decrement) <p> and <pos> */
inc = (dir == XawsdRight) ? 1 : -1 ;
/* handle different types of boundaries <cnt> times */
switch ( type )
{
case XawstAll: /* is not possible */
return (dir == XawsdRight) ? src->gap_src.length : 0 ;
break ;
case XawstEOL:
case XawstParagraph:
if ( dir == XawsdRight )
{
for ( ; 0 < cnt; cnt-- )
{
p = src->gap_src.buffer + pos;
while ( pos < src->gap_src.length )
{
if ( *p == '\n' )
break ;
pos++; p++;
}
if ( src->gap_src.length < pos )
return src->gap_src.length;
pos++;
}
}
else
{
for ( ; 0 < cnt; cnt-- )
{
p = src->gap_src.buffer + pos;
while ( 0 <= pos )
{
if ( *p == '\n' )
break ;
pos--; p--;
}
if ( pos < 0 )
return 0 ;
pos--;
}
}
if ( !ind )
pos -= inc;
break ;
case XawstWhiteSpace:
for ( ; 0 < cnt; cnt-- )
{
Boolean nonSpace = FALSE ;
p = src->gap_src.buffer + pos;
while ( 0 <= pos && pos < src->gap_src.length )
{
if ( *p == ' ' || *p == '\t' || *p == '\n' )
{
if ( nonSpace )
break ;
}
else
nonSpace = TRUE ;
pos += inc;
p += inc;
}
if ( pos < 0 )
return 0 ;
if ( src->gap_src.length < pos )
return src->gap_src.length;
pos += inc;
}
if ( !ind )
pos -= inc;
break ;
case XawstPositions:
pos += cnt * inc;
break ;
default :
break ;
}
if ( dir == XawsdLeft )
pos++;
/* set <pos> to a sensible value and return */
if ( pos >= src->gap_src.length )
return src->gap_src.length;
else if ( pos < 0 )
return 0 ;
else
return pos;
}
/****************************************************************************
* *
* V gapSrcObjectClass . . . . . . . . . . . . . . . . gap source class record
*/
GapSrcClassRec gapSrcClassRec =
{
{ /* core_class fields */
/* superclass */ (WidgetClass) (&textSrcClassRec),
/* class_name */ "GapSrc",
/* widget_size */ sizeof(GapSrcRec),
/* class_initialize */ XawInitializeWidgetSet,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ (XtInitProc) GapSrcInitialize,
/* initialize_hook */ NULL,
/* realize */ NULL,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ NULL,
/* num_resources */ 0,
/* xrm_class */ NULLQUARK,
/* compress_motion */ FALSE,
/* compress_exposure */ FALSE,
/* compress_enterleave */ FALSE,
/* visible_interest */ FALSE,
/* destroy */ GapSrcDestroy,
/* resize */ NULL,
/* expose */ NULL,
/* set_values */ NULL,
/* set_values_hook */ NULL,
/* set_values_almost */ NULL,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ NULL,
/* display_accelerator */ NULL,
/* extension */ NULL
},
{ /* textSrc_class fields */
/* Read */ GapSrcReadText,
/* Replace */ GapSrcReplaceText,
/* Scan */ GapSrcScan,
/* Search */ XtInheritSearch,
/* SetSelection */ XtInheritSetSelection,
/* ConvertSelection */ XtInheritConvertSelection
},
{ /* GapSrc_class fields */
/* Keep the compiler happy */ NULL
}
};
WidgetClass gapSrcObjectClass = (WidgetClass)&gapSrcClassRec;
/* * * * * * * * * * * * * gap text widget functions * * * * * * * * * * * */
/****************************************************************************
* *
* F CheckTextBlock ( < block > ) . . . . . . . . check a block for special chars
*/
#if 0
static char * CheckTextBlockTmp = 0 ;
static void CheckTextBlock ( XawTextBlock * block )
{
unsigned char * p;
unsigned char * q;
unsigned int i;
unsigned int s;
p = (unsigned char *) block->ptr;
for ( s = 0 , i = 0 ; i < block->length; i++, p++ )
if ( *p < 32 && *p != '\n' && *p != '\r' )
s++;
if ( s == 0 )
return ;
if ( CheckTextBlockTmp != 0 )
XtFree(CheckTextBlockTmp);
CheckTextBlockTmp = XtMalloc(block->length + s);
p = (unsigned char *) block->ptr;
q = (unsigned char *) CheckTextBlockTmp;
for ( i = 0 ; i < block->length; i++, p++ )
{
if ( *p < 32 )
{
*q++ = '^' ;
*q++ = *p + 'A' ;
}
else
*q++ = *p;
}
block->ptr = CheckTextBlockTmp;
}
#endif
/****************************************************************************
* *
* F GTPosition ( < w > ) . . . . . . . . . . . . . . . . return insertion point
*/
Int GTPosition ( Widget w )
{
GapTextWidget gap = (GapTextWidget) w;
return gap->text.insertPos;
}
/****************************************************************************
* *
* F GTSetPosition ( < w > , < pos > ) . . . . . . . . . . . . set insertion point
*/
void GTSetPosition ( Widget w, Int pos )
{
XawTextSetInsertionPoint( w, pos );
}
/****************************************************************************
* *
* F GTDelete ( < w > , < dir > , < type > ) . . . . . . . . . delete a piece of text
*/
void GTDelete ( Widget w, XawTextScanDirection dir, XawTextScanType type )
{
GapTextWidget gap = (GapTextWidget) w;
XawTextBlock text;
Int to;
Int from;
/* prepare text for update */
_XawTextPrepareToUpdate((TextWidget)gap);
gap->text.time = CurrentTime;
/* find <to> and <from> */
to = GapSrcScan(gap->text.source,gap->text.insertPos,type,dir,1 ,TRUE );
if ( to == gap->text.insertPos )
to = GapSrcScan(gap->text.source,gap->text.insertPos,type,dir,2 ,TRUE );
if (dir == XawsdLeft)
{
from = to;
to = gap->text.insertPos;
}
else
from = gap->text.insertPos;
/* remove text */
text.length = 0 ;
text.firstPos = 0 ;
if ( _XawTextReplace( (TextWidget)gap, from, to, &text ) )
{
XBell(XtDisplay(gap), 50 );
goto error;
}
gap->text.insertPos = from;
gap->text.showposition = TRUE ;
_XawTextSetScrollBars((TextWidget)gap);
/* do update */
error:
_XawTextCheckResize((TextWidget)gap);
_XawTextExecuteUpdate((TextWidget)gap);
gap->text.mult = 1 ;
}
/****************************************************************************
* *
* F GTInsertText ( < w > , < str > , < len > ) . . . . . insert < str > into a gap text
* *
* * DESCRIPTION
* * This functions insert the text pointed to by < str > of length < len > in
* * the gap text widget at the current position . It is the responsibility
* * of the caller to set the current insertion position .
*/
void GTInsertText ( Widget w, String str, Int len )
{
GapTextWidget gap = (GapTextWidget) w;
XawTextBlock block;
/* convert text into a text block */
block.firstPos = 0 ;
block.ptr = (char *) str;
block.format = FMT8BIT;
block.length = len;
#if 0
CheckTextBlock(&block);
#endif
/* insert text at current position */
XawTextReplace( w, gap->text.insertPos, gap->text.insertPos, &block );
/* move insertion position */
XawTextSetInsertionPoint( w, gap->text.insertPos+len );
}
/****************************************************************************
* *
* F GTReplaceText ( < w > , < str > , < len > ) . . . . . replace last line by < str >
* *
* * DESCRIPTION
* * This functions replaces the text right of the insert point by the text
* * pointed to by < str > of length < len > . It is the responsibility of the
* * caller to set the current insertion position .
*/
void GTReplaceText ( Widget w, String str, Int len )
{
GapTextWidget gap = (GapTextWidget) w;
XawTextBlock block;
/* convert text into a text block */
block.firstPos = 0 ;
block.ptr = (char *) str;
block.format = FMT8BIT;
block.length = len;
#if 0
CheckTextBlock(&block);
#endif
/* insert text at current position */
XawTextReplace(w,gap->text.insertPos,gap->text.insertPos+len,&block);
/* move insertion position */
XawTextSetInsertionPoint( w, gap->text.insertPos+len );
}
/****************************************************************************
* *
* F GTMoveCaret ( < w > , < rpos > ) . . . move caret relative to current position
*/
void GTMoveCaret ( Widget w, Int rpos )
{
GapTextWidget gap = (GapTextWidget) w;
Int pos;
pos = gap->text.insertPos+rpos;
if ( pos < 0 )
pos = 0 ;
if ( ((GapSrcObject)gap->text.source)->gap_src.length < pos )
pos = ((GapSrcObject)gap->text.source)->gap_src.length;
XawTextSetInsertionPoint( w, pos );
}
/****************************************************************************
* *
* F GTDeleteLeft ( < w > ) . . . . . . . . . . . delete a char left of the caret
*/
void GTDeleteLeft ( Widget w )
{
GapTextWidget gap = (GapTextWidget) w;
/* check if there is a character to the left */
if ( gap->text.insertPos <= 0 )
return ;
/* use 'GTDelete' */
GTDelete( w, XawsdLeft, XawstPositions );
}
/****************************************************************************
* *
* F GTDeleteRight ( < w > ) . . . . . . . . . delete a char right of the caret
*/
void GTDeleteRight ( Widget w )
{
GapTextWidget gap = (GapTextWidget) w;
/* check if there is a character to the right */
if ( ((GapSrcObject)gap->text.source)->gap_src.length
<=
gap->text.insertPos )
return ;
/* use 'GTDelete' */
GTDelete( w, XawsdRight, XawstPositions );
}
/****************************************************************************
* *
* F GTBell ( < w > ) . . . . . . . . . . . . . . . . . . . . . . . ring my bell
*/
void GTBell ( Widget w )
{
XBell( XtDisplay(w), 50 );
}
/****************************************************************************
* *
* F GTDropGapPrompt ( < w > , < flag > ) . . . . . . . . set drop gap prompt flag
*/
void GTDropGapPrompt ( Widget w, Boolean flag )
{
GapTextWidget gap = (GapTextWidget) w;
gap->gap.drop_gap_prompt = flag;
}
/****************************************************************************
* *
* E gaptext . c . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/
Messung V0.5 in Prozent C=87 H=91 G=88
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet am 2026-07-01)
¤
*© Formatika GbR, Deutschland