SEARCH
NEW RPMS
DIRECTORIES
ABOUT
FAQ
VARIOUS
BLOG

BotDetect - Real-Time Bot Detection API
 
 

MAN page from Mandrake Other XITE-3.3-3.i386.rpm

Section: Free Widget Foundation (3)
Updated:
Index 

NAME

XfwfPrompt 

DESCRIPTION

The Prompt widget is used for short (no more than a few lines) textentry. It can be used in two modes: either with or without a template.If there is a template, input will be checked against it and onlyaccepted if it matches. A template must be accompanied by a pattern,that gives the acceptable character classes for each position in thetemplate. A template can include literal characters, e.g., "Enterdate: __-__-__ (DD-MM-YY)" with pattern "99-99-99" means that theuser may enter only digits on the `_' positions.

If the pattern and template do not provide enough validation, or ifthere is no template, there is also the possibility of using acallback after each character is entered. The callback can accept orreject the new text.

The rvStart resource is used as cursor position.

 

Public variables

XfwfPrompt
NameClassTypeDefault
XtNtextXtCTextString NULL
XtNtemplateXtCTemplateString NULL
XtNpatternXtCPatternString NULL
XtNvalidateXtCValidateCallbackNULL
XtNleaveXtCLeaveCallbackNULL
XtNactivateXtCActivateCallbackNULL
XtNcompleteXtCCompleteBoolean True
XtNplaceholderXtCPlaceholderchar '_'

XtNtext
The text resource is what is modified by the user. If there is atemplate defined, the text will be the portion of the template fromthe first `_' to the last.

        

String text = NULL

XtNtemplate
The template consists of text with at least one `_' (or, to beprecise, the value of placeholder). If there is no template, inputof any length is accepted (but see the validate callback below).

Note that the label resource that is inherited from XfwfLabel isused to hold the combination of template and text. Setting labelhas no effect, and, indeed, will cause a warning message to beprinted.

        

String template = NULL

XtNpattern
The pattern is only used if there is a template. The length ofthe pattern must be the length from the first `_' in template tothe last. Where the template has a `_', the pattern must haveone of:

* `9' only digits are allowed.

* `a' digits, upper- and lowercase letters and spaces.

* `A' digits, uppercase letters and spaces.

* `F' only `safe' file name characters.

* 'f' file name character plus `*' `[', `]' and `?'

* `X' any character.

* `z' digits, upper- and lowercase letters (no spaces)

* `Z' digits, uppercase letters (no spaces).

If the pattern is empty or too short, it will be extended with X's.

        

String pattern = NULL

XtNvalidate
The validate callbacks are called when the text changes, because aletter is added or removed. The callback get a pointer to anXfwfPromptInfo structure as call_data. The structure includes afield reply, which should be set to XfwfReject, XfwfAccept orXfwfComplete. The first causes the new text to be rejected with a`beep'; the second sets the complete resource to False, toindicate that the text is valid, but not yet complete; the third setsthe complete resource to True.

        

<Callback> XtCallbackList validate = NULL

XtNleave
The leave callback is called when the focus leaves the promptwidget. This is usually a sign that the user is ready entering thetext. The final text is passed in the call_data argument.

        

<Callback> XtCallbackList leave = NULL

XtNactivate
The activate callback is invoked from the activate action, whichis normally bound to the Return key. The call_data argument of thecallbacks routines is filled with a pointer to the event thattriggered the action. This callback can be used in a dialog box, forexample, to activate the default button.

        

<Callback> XtCallbackList activate = NULL

XtNcomplete
The resource complete is always True, unless the most recentcall to the validate callback returned XfwfAccept.

        

Boolean complete = True

XtNplaceholder
The character thatis used as the placeholder can be changed from thedefault `_' by setting the placeholder resource. Note that thischaracter will also be used in the text string to indicate openplaces.

        

char placeholder = '_'

XtNcursor
The cursor is by default a vertical bar, called the `xterm' cursor.

        


 cursor = <String>"xterm"

XtNtraversalOn
Since prompts, in contrast to labels, should receive keyboardevents, the traversalOn resource is by default True.

        


 traversalOn = True 

XtNframeWidth
The default frame width is also given a different value.

        


 frameWidth = 2 

XtNframeType
As is the frame type

        


 frameType = XfwfSunken 

XtNalignment
The default alignment of text is changed to center-left.

        


 alignment = XfwfLeft 

XfwfLabel
NameClassTypeDefault
XtNlabelXtCLabelString NULL
XtNtablistXtCTablistString NULL
XtNfontXtCFontFontStructXtDefaultFont
XtNforegroundXtCForegroundPixel XtDefaultForeground
XtNhlForegroundXtCHlForegroundPixel XtDefaultForeground
XtNalignmentXtCAlignmentAlignment 0
XtNtopMarginXtCTopMarginDimension 2
XtNbottomMarginXtCBottomMarginDimension 2
XtNleftMarginXtCLeftMarginDimension 2
XtNrightMarginXtCRightMarginDimension 2
XtNshrinkToFitXtCShrinkToFitBoolean False
XtNrvStartXtCRvStartInt 0
XtNrvLengthXtCRvLengthInt 0
XtNhlStartXtCHlStartInt 0
XtNhlLengthXtCHlLengthInt 0

XfwfBoard
NameClassTypeDefault
XtNabs_xXtCAbs_xPosition 0
XtNrel_xXtCRel_xFloat "0.0"
XtNabs_yXtCAbs_yPosition 0
XtNrel_yXtCRel_yFloat "0.0"
XtNabs_widthXtCAbs_widthPosition 0
XtNrel_widthXtCRel_widthFloat "1.0"
XtNabs_heightXtCAbs_heightPosition 0
XtNrel_heightXtCRel_heightFloat "1.0"
XtNhunitXtCHunitFloat "1.0"
XtNvunitXtCVunitFloat "1.0"
XtNlocationXtCLocationString NULL

XfwfFrame
NameClassTypeDefault
XtNcursorXtCCursorCursor None
XtNframeTypeXtCFrameTypeFrameType XfwfRaised
XtNframeWidthXtCFrameWidthDimension 0
XtNouterOffsetXtCOuterOffsetDimension 0
XtNinnerOffsetXtCInnerOffsetDimension 0
XtNshadowSchemeXtCShadowSchemeShadowScheme XfwfAuto
XtNtopShadowColorXtCTopShadowColorPixel compute_topcolor
XtNbottomShadowColorXtCBottomShadowColorPixel compute_bottomcolor
XtNtopShadowStippleXtCTopShadowStippleBitmap NULL
XtNbottomShadowStippleXtCBottomShadowStippleBitmap NULL

XfwfCommon
NameClassTypeDefault
XtNtraversalOnXtCTraversalOnBoolean True
XtNhighlightThicknessXtCHighlightThicknessDimension 2
XtNhighlightColorXtCHighlightColorPixel XtDefaultForeground
XtNhighlightPixmapXtCHighlightPixmapPixmap None
XtNnextTopXtCNextTopCallbackNULL
XtNuserDataXtCUserDataPointerNULL

Composite
NameClassTypeDefault
XtNchildrenXtCChildrenWidgetList NULL
insertPositionXtCInsertPositionXTOrderProc NULL
numChildrenXtCNumChildrenCardinal 0

Core
NameClassTypeDefault
XtNxXtCXPosition 0
XtNyXtCYPosition 0
XtNwidthXtCWidthDimension 0
XtNheightXtCHeightDimension 0
borderWidthXtCBorderWidthDimension 0
XtNcolormapXtCColormapColormap NULL
XtNdepthXtCDepthInt 0
destroyCallbackXtCDestroyCallbackXTCallbackList NULL
XtNsensitiveXtCSensitiveBoolean True
XtNtmXtCTmXTTMRec NULL
ancestorSensitiveXtCAncestorSensitiveBoolean False
acceleratorsXtCAcceleratorsXTTranslations NULL
borderColorXtCBorderColorPixel 0
borderPixmapXtCBorderPixmapPixmap NULL
backgroundXtCBackgroundPixel 0
backgroundPixmapXtCBackgroundPixmapPixmap NULL
mappedWhenManagedXtCMappedWhenManagedBoolean True
XtNscreenXtCScreenScreen *NULL

 

Exports

The XfwfPromptInfo is what is passed to the validate callbackafter the text has changed. It contains pointers to the old and thenew text and a boolean field result that is initially set toXfwfComplete, but that may be changed by the callback routine, whenthe new text is unacceptable, or acceptable but not complete.

        

type XfwfPromptInfoResult = enum {                XfwfReject, XfwfAccept, XfwfComplete        }

type XfwfPromptInfo = struct {                String oldstring;                String newstring;                Boolean result;        }

 

Translations

The traversal code is added, except for <Key>Left: traverseLeft()and <Key>Right: traverseRight(), which are used for other purposes.

<FocusIn>: focusIn() 

<FocusOut>: leave() focusOut() 

removed: trans  <Visible>:              visibility()

removed: trans  <Unmap>:                unmap()

<Key>Up: traverseUp() 

<Key>Down: traverseDown() 

<Key>Next: traverseNext() 

~Shift<Key>Tab: traverseNext() 

<Key>Prior: traversePrev() 

Shift<Key>Tab: traversePrev() 

<Key>KP_Enter: traverseNextTop() 

<Key>Home: traverseHome() 

Shift<Btn1Down>: extend_select() 

<Btn1Down>: traverseCurrent() start_select() 

<Btn1Motion>: extend_select() 

<Btn1Up>: end_select() 

<Btn2Down>,<Btn2Up>: paste() 

<Key>BackSpace: cut() backspace() 

Ctrl<Key>d: cut() delete() 

<Key>Right: unselect() right() 

<Key>Left: unselect() left() 

Ctrl<Key>a: unselect() bol() 

Ctrl<Key>e: unselect() eol() 

<Key>Return: activate() 

<Key>: cut() self_insert() 

 

Actions

activate

The activate action just calls the activate callback functions,passing the XEvent pointer in the call_data argument.

void activate($, XEvent* event, String* params, Cardinal* num_params){    XtCallCallbackList($, $activate, event);}

leave

The leave action calls the leave callbacks with the currenttext as call_data.

void leave($, XEvent* event, String* params, Cardinal* num_params){    if (event->type == FocusOut         event->xfocus.detail != NotifyAncestor         event->xfocus.detail != NotifyInferior         event->xfocus.detail != NotifyNonlinear) return;    XtCallCallbackList($, $leave, $text);}

start_select

The start_select action sets the cursor position as close aspossible to the mouse position, but only if the mouse actually pointsat some text. It also removes any previous selection, preparing for anew one.

void start_select($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    Cardinal pos;    if (find_cursor($, event->xbutton, $rvStart)) {        $rvLength = 0;        $compute_inside($, x, y, w, h);        XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);    }}

extend_select

The extend_select action extends the selection to the currentcursor position.

void extend_select($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    int pos, len, start;    if (find_cursor($, event->xbutton, pos)) {        len = abs(pos - $rvStart);        start = min(pos, $rvStart);        if (len != $rvLength || start != $rvStart) {            $rvLength = len;            $rvStart = start;            $compute_inside($, x, y, w, h);            XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);        }    }}

end_select

The end_select action copies the selected text to the clipboard.

void end_select($, XEvent* event, String* params, Cardinal* num_params){    if ($rvLength == 0) return;    if (! XtOwnSelection($, XA_PRIMARY, event->xbutton.time,                         convert_proc, lose_ownership_proc, NULL)) {        XtWarning("failed attempting to become selection owner.");        return;    }    XtFree($selection_buffer);    $selection_buffer = XtMalloc(sizeof(char) * ($rvLength + 1));    (void) strncpy($selection_buffer, $label + $rvStart, $rvLength);    $selection_buffer[$rvLength] = '\0';}

paste

The paste action requests the contents of the clipboard instring-format and tries to insert it into the text.

void paste($, XEvent* event, String* params, Cardinal* num_params){    XtGetSelectionValue($, XA_PRIMARY, XA_STRING, paste_callback, NULL,                        event->xbutton.time);}

unselect

The unselect action restores the text that was shown in reverse tonormal.

void unselect($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    if ($rvLength != 0) {        $rvLength = 0;        $compute_inside($, x, y, w, h);        XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);    }}

cut

The cut action deletes the highlighted portion from the text.

void cut($, XEvent* event, String* params, Cardinal* num_params){    int j, i;    XfwfPromptInfo info;    String newlabel;    if ($rvLength == 0) return;    info.oldstring = XtNewString($text);    if ($template == NULL) {        j = strlen($text);        i = min($rvStart + $rvLength, j) - 1;        for (; i >= $rvStart; i--, j--) delete_from_run($, i, j, '\0');    } else {        i = min($rvStart + $rvLength, $text_start + $text_len) - 1;        for (; i >= $rvStart; i--) {            if ($template[i] != $placeholder) continue;            j = find_end_of_run($, i);            delete_from_run($, i - $text_start, j - $text_start, $placeholder);        }    }    info.newstring = $text;    info.result = XfwfComplete;    XtCallCallbackList($, $validate, info);    switch (info.result) {    case XfwfReject: XtFree($text); $text = info.oldstring; return;    case XfwfAccept: XtFree(info.oldstring); $complete = False; break;    case XfwfComplete: XtFree(info.oldstring); $complete = True; break;    }    if ($template == NULL) {        $set_label($, $text);    } else {        newlabel = XtNewString($template);        for (j = 0; j < $text_len; j++) newlabel[j+$text_start] = $text[j];        $set_label($, newlabel);        XtFree(newlabel);    }    $rvLength = 0;}

self_insert

The self_insert function inserts the key that was pressed into thetext. If the key is not a printable key, it does nothing. If the keydoesn't match the pattern, it does nothing. If the callback validatereturns XfwfReject, it does nothing.

void self_insert($, XEvent* event, String* params, Cardinal* num_params){    KeySym keysym;    int n, i;    char buf[100];    XfwfPromptInfo info;    String newlabel;    if (event->type != KeyPress  event->type != KeyRelease) {        XtWarning("action <self_insert> can only handle keyboard events");        return;    }    info.oldstring = XtNewString($text);    n = XLookupString(event->xkey, buf, sizeof(buf), keysym, $compose_stat);    for (i = 0; i < n; i++) insert_char($, buf[i]);    info.newstring = $text;    info.result = XfwfComplete;    XtCallCallbackList($, $validate, info);    switch (info.result) {    case XfwfReject: XtFree($text); $text = info.oldstring; return;    case XfwfAccept: XtFree(info.oldstring); $complete = False; break;    case XfwfComplete: XtFree(info.oldstring); $complete = True; break;    }    if ($template == NULL)        $set_label($, $text);    else {        newlabel = XtNewString($template);        for (i = 0; i < $text_len; i++) newlabel[i+$text_start] = $text[i];        $set_label($, newlabel);        XtFree(newlabel);    }}

bol

The bol action moves the cursor to the leftmost placeholder.

void bol($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    if ($rvStart == $text_start) return;    $rvStart = $text_start;    $compute_inside($, x, y, w, h);    XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);}

eol

The eol action moves the cursor to the end of the label, if itisn't there already.

void eol($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    if ($template == NULL) {        if ($label[$rvStart] == '\0') return;        do { $rvStart++; } while ($label[$rvStart]);    } else {        if ($rvStart == $text_start + $text_len) return;        $rvStart = $text_start + $text_len;    }    $compute_inside($, x, y, w, h);    XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);}

left

The left action moves the cursor one position to the left, unlessthere are no more placeholders in that direction.

void left($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    if ($rvStart == $text_start) return;    if ($template == NULL)        $rvStart--;    else        do { $rvStart--; } while ($template[$rvStart] != $placeholder);    $compute_inside($, x, y, w, h);    XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);}

right

The right action moves the cursor one position to the right,unless it is already at the end of the template.

void right($, XEvent* event, String* params, Cardinal* num_params){    Position x, y;    Dimension w, h;    if ($template == NULL) {        if ($label[$rvStart] == '\0') return;        $rvStart++;    } else {        if ($rvStart == $text_start + $text_len) return;        do { $rvStart++; } while ($template[$rvStart] != $placeholder);    }    $compute_inside($, x, y, w, h);    XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True);}

delete

The delete action removes the character to the right of thecursor, if there is any. The rest of the characters in the same runwill shift to the left.

void delete($, XEvent* event, String* params, Cardinal* num_params){    int j;    XfwfPromptInfo info;    String newlabel;    if ($template == NULL) {        if (! $text || $text[$rvStart] == '\0') return;        info.oldstring = XtNewString($text);        j = strlen($text);        delete_from_run($, $rvStart, j, '\0');    } else {        if ($template[$rvStart] != $placeholder) return;        info.oldstring = XtNewString($text);        j = find_end_of_run($, $rvStart) - $text_start;        delete_from_run($, $rvStart - $text_start, j, $placeholder);    }    info.newstring = $text;    info.result = XfwfComplete;    XtCallCallbackList($, $validate, info);    switch (info.result) {    case XfwfReject: XtFree($text); $text = info.oldstring; return;    case XfwfAccept: XtFree(info.oldstring); $complete = False; break;    case XfwfComplete: XtFree(info.oldstring); $complete = True; break;    }    if ($template == NULL) {        $set_label($, $text);    } else {        newlabel = XtNewString($template);        for (j = 0; j < $text_len; j++) newlabel[j+$text_start] = $text[j];        $set_label($, newlabel);        XtFree(newlabel);    }}

backspace

The backspace action removes the character to the left of thecursor, if there is any. The cursor moves left and all characters inthe same run move left.

void backspace($, XEvent* event, String* params, Cardinal* num_params){    int j;    XfwfPromptInfo info;    String newlabel;    if ($rvStart == $text_start) return;    info.oldstring = XtNewString($text);    if ($template == NULL) {        $rvStart--;        j = strlen($label);        delete_from_run($, $rvStart, j, '\0');    } else {        do { $rvStart--; } while ($template[$rvStart] != $placeholder);        j = find_end_of_run($, $rvStart) - $text_start;        delete_from_run($, $rvStart - $text_start, j, $placeholder);    }    info.newstring = $text;    info.result = XfwfComplete;    XtCallCallbackList($, $validate, info);    switch (info.result) {    case XfwfReject: XtFree($text); $text = info.oldstring; return;    case XfwfAccept: XtFree(info.oldstring); $complete = False; break;    case XfwfComplete: XtFree(info.oldstring); $complete = True; break;    }    if ($template == NULL) {        $set_label($, $text);    } else {        newlabel = XtNewString($template);        for (j = 0; j < $text_len; j++) newlabel[j+$text_start] = $text[j];        $set_label($, newlabel);        XtFree(newlabel);    }}

 

Importss

incl <ctype.h>

incl <stdio.h>

incl <X11/Xatom.h>

incl <X11/Xmu/Atoms.h>

 

Private variables

The start and length of the entry part of the template is stored intwo private variables.

        

int  text_start

int  text_len

Between keypresses, the XComposeStatus is retained.

        

XComposeStatus  compose_stat

If the widget is the owner of the selection, the text of theselection is stored here.

        

String  selection_buffer

 

Methods

The initialize method initializes the private variables, with thehelp of a utility routine. That routine also checks if pattern andtemplate agree.

All String resources are copied to new allocated space, so that theapplication can change or throw away the original strings.

initialize(Widget  request, $, ArgList  args, Cardinal * num_args){    if ($label != NULL)        XtWarning("The label resource of a Prompt should not be set");    $text_start = 0;    if ($text != NULL) $text = XtNewString($text);    if ($template != NULL) $template = XtNewString($template);    if ($pattern != NULL) $pattern = XtNewString($pattern);    set_text_start($);    while ($rvStart > $text_start + $text_len) $rvStart--;    while ($rvStart < $text_start) $rvStart++;    $selection_buffer = NULL;}

The set_values method copies all string resources that havechanged to new heap space, and calls set_text_start to compute thetext_start and text_end and to set the label resource.

Boolean  set_values(Widget  old, Widget  request, $, ArgList  args, Cardinal * num_args){    Boolean need_redisplay = False, reset_text = False;    if ($old$text != $text) {        XtFree($old$text);        $text = XtNewString($text);        reset_text = True;    }    if ($old$template !=$template) {        XtFree($old$template);        $template = XtNewString($template);        reset_text = True;    }    if ($old$pattern != $pattern) {        XtFree($old$pattern);        $pattern = XtNewString($pattern);        reset_text = True;    }    if (reset_text || $old$placeholder != $placeholder) {        set_text_start($);        need_redisplay = True;    }    return need_redisplay;}

The expose method does much of the work that is also done by thesuperclass, but without actually drawing anything. The only thing thatis drawn is the cursor.

expose($, XEvent * event, Region  region){    Region reg;    XRectangle rect;    int baseline, i, j;    Dimension w;    int x, y;    if (! XtIsRealized($)) return;    #expose($, event, region);    if ($label == NULL) return;    baseline = $font->ascent + $font->descent;    $compute_inside($, rect.x, rect.y, rect.width, rect.height);    rect.x += $leftMargin;  rect.width -= $leftMargin + $rightMargin;    rect.y += $topMargin;  rect.height -= $topMargin + $bottomMargin;    if ($alignment  XfwfTop)        y = rect.y + $font->ascent;    else if ($alignment  XfwfBottom)        y = rect.y + rect.height - $nlines * baseline + $font->ascent;    else        y = rect.y + (rect.height - $nlines * baseline)/2 + $font->ascent;    for (i = 0, j = 0; True; i++) {        if ($label[i] == '\n' || $label[i] == '\0') {            if (j <= $rvStart  $rvStart <= i) {                w = XfwfTextWidth($font, $label + j, i - j, $tabs);                if ($alignment  XfwfLeft) x = rect.x;                else if ($alignment  XfwfRight) x = rect.x + rect.width - w;                else x = rect.x + (rect.width - w)/2;                x += XfwfTextWidth($font, $label + j, $rvStart - j, $tabs);                XDrawLine(XtDisplay($), XtWindow($), $gc, x, y -                          $font->ascent, x, y + $font->descent);                break;            }            j = i + 1;            y += baseline;        }    }}

 

Utilities

The find_cursor function sets the cursor position pos to thecharacter closest to the mouse coordinates, it returns True if itsucceeded, else False.

Boolean  find_cursor($, XButtonEvent * event, int * pos){    XRectangle rect;    int baseline, i, j;    Dimension w;    int x, y;    if (! XtIsRealized($)) return False;    if ($label == NULL) return False;    baseline = $font->ascent + $font->descent;    $compute_inside($, rect.x, rect.y, rect.width, rect.height);    rect.x += $leftMargin;  rect.width -= $leftMargin + $rightMargin;    rect.y += $topMargin;  rect.height -= $topMargin + $bottomMargin;    if ($alignment  XfwfTop)        y = rect.y;    else if ($alignment  XfwfBottom)        y = rect.y + rect.height - $nlines * baseline;    else        y = rect.y + (rect.height - $nlines * baseline)/2;    i = 0;    j = 0;    do {        if ($label[i] == '\n' || $label[i] == '\0') {            if (y <= event->y  event->y < y + baseline) {                find_cursor_in_line($, rect, event->x, event->y, j, i, pos);                return True;            } else {                j = i + 1;                y += baseline;            }        }    } while ($label[i++]);    return False;}

find_cursor makes use of an auxiliary functionfind_cursor_in_line, which is called when the mouse is on the linebetween $label[j] and $label[i].

find_cursor_in_line($, XRectangle  rect, int  mx, int  my, int  j, int  i, int * pos){    Dimension w;    int x;    w = XfwfTextWidth($font, $label + j, i - j, $tabs);    if ($alignment  XfwfLeft)        x = rect.x;    else if ($alignment  XfwfRight)        x = rect.x + rect.width - w;    else        x = rect.x + (rect.width - w)/2;    if (x + w <= mx) {                          /* Mouse right of the text */        if ($template == NULL)            *pos = i;        else {                                  /* Find placeholder */            while (i > $text_start  $template[i] != $placeholder) i--;            *pos = i;        }    } else if (mx < x) {                        /* Mouse left of the text */        if ($template == NULL)            *pos = j;        else {                                  /* Find placeholder */            while (j > $text_start  $template[j] != $placeholder) j--;            *pos = j;        }    } else {                                    /* Mouse points in the text */        for (w = 0; True; j++) {            w += XfwfTextWidth($font, $label + j, 1, $tabs);            if (x + w >= mx) break;        }        if ($template == NULL)            *pos = j;        else if (j >= $text_start + $text_len)            *pos = $text_start + $text_len;        else if (j <= $text_start)            *pos = $text_start;        else {                                  /* Find nearest placeholder */            while (j > $text_start  $template[j] != $placeholder) j--;            *pos = j;        }    }}

The insert_char function tries to insert a character at the cursorposition. If it matches the pattern, it is inserted, otherwise, if itmatches the next literal character in the template, the cursor willskip to that position. If a character could be inserted, thevalidate callback is called. If that returns XfwfReject, the oldsituation is restored.

If there is no template, only the callback is called.

The first few functions deal with `runs', which are defined as rows ofconsecutive placeholders with the same pattern character.find_end_of_run looks for the first character beyond the end of therun that starts at start.

int  find_end_of_run($, int  start){    int i, j;    i = start + 1;    j = i - $text_start;    while ($template[i] == $placeholder  $pattern[j] == $pattern[j-1]) {        i++;        j++;    }    return i;}

insert_in_run inserts character c at position start intext, shifting the rest of the characters in the run one positionforward.

insert_in_run($, int  start, int  end, int  c){    int i;    for (i = end - 1; i > start; i--) $text[i] = $text[i-1];    $text[start] = c;}

delete_from_run shift all characters in the run to the left, thelast character will become a placeholder (filler), the firstcharacter will disappear.

delete_from_run($, int  start, int  end, int  filler){    int i;    for (i = start; i < end - 1; i++) $text[i] = $text[i+1];    $text[end-1] = filler;}

If the characer c is in the class indicated by class, thefunction returns True.

Boolean  matches(int  c, int  class){    if (class == '9') return isdigit(c);    if (class == 'a') return isalnum(c) || isspace(c);    if (class == 'A') return isdigit(c) || isupper(c) || isspace(c);    if (class == 'F')        return isgraph(c)  c != '*'  c != '?'  c != '['  c != ']';    if (class == 'f') return isgraph(c);    if (class == 'X') return isascii(c);    if (class == 'z') return isalnum(c);    if (class == 'Z') return isdigit(c) || isupper(c);    XtWarning("Cannot happen: incorrect pattern");    return True;}

The insert_char function. c is really a character, not an int.

insert_char($, int  c){    int j;    if (! $template) {        j = strlen($text);        $text = XtRealloc($text, j + 2);        $text[j+1] = '\0';        insert_in_run($, $rvStart, j + 1, c);        $rvStart++;    } else {        if ($template[$rvStart] != $placeholder) {            XBell(XtDisplay($), 50);            /* At end of template */            return;        }        j = find_end_of_run($, $rvStart);        if (matches(c, $pattern[$rvStart - $text_start])) {            insert_in_run($, $rvStart - $text_start, j - $text_start, c);            do {                $rvStart++;            } while ($rvStart < $text_start + $text_len                      $template[$rvStart] != $placeholder);        } else if (c == $template[j]) {            while ($template[j]  $template[j] != $placeholder) j++;            $rvStart = j;        } else {            XBell(XtDisplay($), 50);        }    }}

set_text_start checks if pattern and template agree and if so,sets the private variables text_start and text_len appropriately.The label resource is set to the value of template with textsubstituted. If text is too short, it is extended.

def pattern_char(c) =(c =='9'||c =='a'||c =='A'||c =='F'||c =='f'||c =='X'||c =='z'||c =='Z')

set_text_start($){    int i, j, k;    String newlabel;    if ($template == NULL) {        newlabel = XtNewString($text);        XtVaSetValues($, XtNlabel, newlabel, NULL);        XtFree(newlabel);        return;    }    /*     * Find start and end in template     */    for (i = 0; $template[i]  $template[i] != '_'; i++) ; /* skip */    for (k = i, j = i; $template[j]; j++) if ($template[j] == '_') k = j;    $text_start = i;    $text_len = k + 1 - i;    /*     * Check the pattern, first the length, then the contents     */    if ($pattern == NULL) {        $pattern = XtMalloc(($text_len + 1)*sizeof(char));        $pattern[0] = '\0';    } else if (strlen($pattern) < $text_len) {        $pattern = XtRealloc($pattern, ($text_len + 1)*sizeof(char));    }    for (i = strlen($pattern); i < $text_len; i++)        $pattern[i] = 'X';    for (i = $text_start, k = 0; k < $text_len; i++, k++)        if ($template[i] == $placeholder  ! pattern_char($pattern[k])) {            XtWarning("Pattern doesn't match template");            $pattern[k] = 'X';        }    $pattern[k] = '\0';    /*     * Check the length of the text     */    if ($text == NULL) {        $text = XtMalloc(($text_len + 1)*sizeof(char));        $text[0] = '\0';    } else if (strlen($text) < $text_len) {        $text = XtRealloc(XtNewString($text), ($text_len + 1)*sizeof(char));    }    for (j = strlen($text); j < $text_len; j++)        $text[j] = $template[j+$text_start];    /*     * Initialize the label     */    newlabel = XtNewString($template);    for (i = $text_start, j = 0; j < $text_len; i++, j++)        newlabel[i] = $text[j];    $set_label($, newlabel);    XtFree(newlabel);}

The procedure to convert the selection.

Boolean  convert_proc($, Atom * selection, Atom * target, Atom * type, XtPointer * value, unsigned  long * length, int * format){    Display* d = XtDisplay($);    XSelectionRequestEvent* req = XtGetSelectionRequest($, *selection, NULL);    if (*target == XA_TARGETS(d)) {        Atom* targetP;        Atom* std_targets;        unsigned long std_length;        XmuConvertStandardSelection($, req->time, selection, target,                                    type, (XtPointer*)std_targets,                                    std_length, format);        *value = XtMalloc(sizeof(Atom) * (std_length + 1));        targetP = *(Atom**) value;        *targetP++ = XA_STRING;        *length = std_length + (targetP - (*(Atom **) value));        bcopy((char*)std_targets, (char*)targetP, sizeof(Atom)*std_length);        XtFree((char*)std_targets);        *type = XA_ATOM;        *format = sizeof(Atom) * 8;        return True;    }    if (*target == XA_STRING) {        *type = XA_STRING;        *length = sizeof(char) * (strlen($selection_buffer) + 1);        *value = XtNewString($selection_buffer);        *format = 8;        return True;    }    if (XmuConvertStandardSelection($, req->time, selection, target,                                    type, value, length, format))        return True;    return False;}

The procedure lose_ownership_proc is called when another windowtakes over the ownership of the selection. There is nothing to do.(Maybe the reversed text should be restored?)

lose_ownership_proc($, Atom * selection){}

The routine paste_callback is called by Xt after the selection isrequested in the paste action. It is handed the contents of theselection, which it will insert into the text of the Prompt.

paste_callback($, XtPointer  client_data, Atom * selection, Atom * type, XtPointer  value, unsigned  long * length, int * format){    String data = (String) value;    XfwfPromptInfo info;    int i;    String newlabel;    if (value == NULL  *length == 0) {        XBell(XtDisplay($), 50);        /* XtWarning("no selection or selection timed out, try again"); */        return;    }    info.oldstring = XtNewString($text);    for (i = 0; i < *length  data[i]; i++)        insert_char($, data[i]);    info.newstring = $text;    info.result = XfwfComplete;    XtCallCallbackList($, $validate, info);    switch (info.result) {    case XfwfReject: XtFree($text); $text = info.oldstring; return;    case XfwfAccept: XtFree(info.oldstring); $complete = False; break;    case XfwfComplete: XtFree(info.oldstring); $complete = True; break;    }    if ($template == NULL)        $set_label($, $text);    else {        newlabel = XtNewString($template);        for (i = 0; i < $text_len; i++) newlabel[i+$text_start] = $text[i];        $set_label($, newlabel);        XtFree(newlabel);    }    XtFree(value);}


 

Index

NAME
DESCRIPTION
Public variables
Exports
Translations
Actions
Importss
Private variables
Methods
Utilities

This document was created byman2html,using the manual pages.
 
ICM Bot detect detector