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
| | Name | Class | Type | Default
| | XtNtext | XtCText | String | NULL
| | XtNtemplate | XtCTemplate | String | NULL
| | XtNpattern | XtCPattern | String | NULL
| | XtNvalidate | XtCValidate | Callback | NULL
| | XtNleave | XtCLeave | Callback | NULL
| | XtNactivate | XtCActivate | Callback | NULL
| | XtNcomplete | XtCComplete | Boolean | True
| | XtNplaceholder | XtCPlaceholder | char | '_'
| | | |
|
|
- 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
| | Name | Class | Type | Default
| | XtNlabel | XtCLabel | String | NULL
| | XtNtablist | XtCTablist | String | NULL
| | XtNfont | XtCFont | FontStruct | XtDefaultFont
| | XtNforeground | XtCForeground | Pixel | XtDefaultForeground
| | XtNhlForeground | XtCHlForeground | Pixel | XtDefaultForeground
| | XtNalignment | XtCAlignment | Alignment | 0
| | XtNtopMargin | XtCTopMargin | Dimension | 2
| | XtNbottomMargin | XtCBottomMargin | Dimension | 2
| | XtNleftMargin | XtCLeftMargin | Dimension | 2
| | XtNrightMargin | XtCRightMargin | Dimension | 2
| | XtNshrinkToFit | XtCShrinkToFit | Boolean | False
| | XtNrvStart | XtCRvStart | Int | 0
| | XtNrvLength | XtCRvLength | Int | 0
| | XtNhlStart | XtCHlStart | Int | 0
| | XtNhlLength | XtCHlLength | Int | 0
| | | |
|
|
XfwfBoard
| | Name | Class | Type | Default
| | XtNabs_x | XtCAbs_x | Position | 0
| | XtNrel_x | XtCRel_x | Float | "0.0"
| | XtNabs_y | XtCAbs_y | Position | 0
| | XtNrel_y | XtCRel_y | Float | "0.0"
| | XtNabs_width | XtCAbs_width | Position | 0
| | XtNrel_width | XtCRel_width | Float | "1.0"
| | XtNabs_height | XtCAbs_height | Position | 0
| | XtNrel_height | XtCRel_height | Float | "1.0"
| | XtNhunit | XtCHunit | Float | "1.0"
| | XtNvunit | XtCVunit | Float | "1.0"
| | XtNlocation | XtCLocation | String | NULL
| | | |
|
|
XfwfFrame
| | Name | Class | Type | Default
| | XtNcursor | XtCCursor | Cursor | None
| | XtNframeType | XtCFrameType | FrameType | XfwfRaised
| | XtNframeWidth | XtCFrameWidth | Dimension | 0
| | XtNouterOffset | XtCOuterOffset | Dimension | 0
| | XtNinnerOffset | XtCInnerOffset | Dimension | 0
| | XtNshadowScheme | XtCShadowScheme | ShadowScheme | XfwfAuto
| | XtNtopShadowColor | XtCTopShadowColor | Pixel | compute_topcolor
| | XtNbottomShadowColor | XtCBottomShadowColor | Pixel | compute_bottomcolor
| | XtNtopShadowStipple | XtCTopShadowStipple | Bitmap | NULL
| | XtNbottomShadowStipple | XtCBottomShadowStipple | Bitmap | NULL
| | | |
|
|
XfwfCommon
| | Name | Class | Type | Default
| | XtNtraversalOn | XtCTraversalOn | Boolean | True
| | XtNhighlightThickness | XtCHighlightThickness | Dimension | 2
| | XtNhighlightColor | XtCHighlightColor | Pixel | XtDefaultForeground
| | XtNhighlightPixmap | XtCHighlightPixmap | Pixmap | None
| | XtNnextTop | XtCNextTop | Callback | NULL
| | XtNuserData | XtCUserData | Pointer | NULL
| | | |
|
|
Composite
| | Name | Class | Type | Default
| | XtNchildren | XtCChildren | WidgetList | NULL
| | insertPosition | XtCInsertPosition | XTOrderProc | NULL
| | numChildren | XtCNumChildren | Cardinal | 0
| | | |
|
|
Core
| | Name | Class | Type | Default
| | XtNx | XtCX | Position | 0
| | XtNy | XtCY | Position | 0
| | XtNwidth | XtCWidth | Dimension | 0
| | XtNheight | XtCHeight | Dimension | 0
| | borderWidth | XtCBorderWidth | Dimension | 0
| | XtNcolormap | XtCColormap | Colormap | NULL
| | XtNdepth | XtCDepth | Int | 0
| | destroyCallback | XtCDestroyCallback | XTCallbackList | NULL
| | XtNsensitive | XtCSensitive | Boolean | True
| | XtNtm | XtCTm | XTTMRec | NULL
| | ancestorSensitive | XtCAncestorSensitive | Boolean | False
| | accelerators | XtCAccelerators | XTTranslations | NULL
| | borderColor | XtCBorderColor | Pixel | 0
| | borderPixmap | XtCBorderPixmap | Pixmap | NULL
| | background | XtCBackground | Pixel | 0
| | backgroundPixmap | XtCBackgroundPixmap | Pixmap | NULL
| | mappedWhenManaged | XtCMappedWhenManaged | Boolean | True
| | XtNscreen | XtCScreen | Screen * | 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.