The code fragment below can be used to find delimited text. Notice that the field_flag
value is TEXTSW_DELIMITER_FORWARD.
Textsw_index first, last_plus_one, pos;
first = (Textsw_index) xv_get(textsw, TEXTSW_INSERTION_POINT);
pos = textsw_match_bytes(textsw, &first, &last_plus_one,
"/*", 2,
"*/", 2, TEXTSW_DELIMITER_FORWARD);
if (pos > 0) {
textsw_set_selection(textsw, first, last_plus_one, 1);
xv_set(textsw, TEXTSW_INSERTION_POINT, last_plus_one, NULL);
} else
(void) window_bell(textsw);
This code searches forward from first until it finds the starting /* and matches it forward
with the next */. If no match is found, a bell will ring in the text subwindow.
8.9 Marking Positions
Often a client wants to keep track of a particular character or group of characters that are in
the text subwindow. Given that arbitrary editing can occur in a text subwindow and that it is
very tedious to intercept and track all of the editing operations applied to a text subwindow, it
is often easier to simply place one or more marks at various positions in the text subwindow.
These marks are automatically updated by the text subwindow to account for user and client
edits. There is no limit to the number of marks you can add.
A new mark is created by calling:
Textsw_mark
textsw_add_mark(textsw, position, flags)
Textsw textsw;
Textsw_index position;
unsigned flags;
The flags argument is either TEXTSW_MARK_DEFAULTS or TEXTSW_MARK_
MOVE_AT_INSERT
. The latter causes an insertion at the marked position to move the mark to
the end of the inserted text, whereas the former causes the mark to not move when text is
inserted at the mark’s current position. As an example, suppose that the text managed by the
text subwindow consists of the two lines:
this is the first line
not this, which is the second
Assume a mark is set at position 5 (just before the i in is on the first line) with flags of
TEXTSW_MARK_MOVE_AT_INSERT.
If the user makes a selection just before the is (thereby placing the insertion point before the
i, at position 5) and types an h, making the text read:
this his the first line
not this, which is the second
the mark moves with the insertion point and they both end up at position 6.
230 XView Programming Manual
However, if the flags had been TEXTSW_MARK_DEFAULTS, then the mark would remain at
position 5 after the user typed the h, although the insertion point moved on to position 6.
Now, suppose instead that the user made a selection before the this on the first line, and typed
Kep, making the text read:
Kepthis is the first line
not this, which is the second
In this case, no matter what flags the mark had been created with, it would end up at posi-
tion 8, still just before the i in is.
If a mark is in the middle of a span of characters that is subsequently deleted, the mark moves
to the beginning of the span. Going back to the original scenario, with the original text and
the mark set at position 5, assume that the user deletes from the h in this through the e in the
on the first line, resulting in the text:
te first line
not this, which is the second
When the user is done, the mark will be at position 1, just before the e in te.
The current position of a mark is determined by calling:
Textsw_index
textsw_find_mark(textsw, mark)
Textsw textsw;
Textsw_mark mark;
An existing mark is removed by calling:
void
textsw_remove_mark(textsw, mark)
Textsw textsw;
Textsw_mark mark;
Note that marks are dynamically allocated, and it is the client’s responsibility to keep track
of them and to remove them when they are no longer needed.
8.9.1 Getting a Text Selection
A user selects a portion of the contents of the text subwindow using a pointer. A text selec-
tion is indicated on the screen with reverse-video highlighting. An application needs to
know which window has the current selection and what the contents of a text selection are.
The
TEXTSW
package does not provide procedures to get this information. Instead, these
functions are carried out by the Selection Service. For an example of how this is done, see
Chapter 18, Selections. Figure 8-4 shows a text selection.
Text Subwindows
Text Subwindows 231
Figure 8-4. A text selection
8.9.2 Setting the Text Selection
Primary and secondary selections are maintained. The primary or secondary selection can be
set by calling the following:
void
textsw_set_selection(textsw, first, last_plus_one, type)
Textsw textsw;
Textsw_index first, last_plus_one;
unsigned type;
A value of 1 for type means primary selection, while a value of 2 means secondary selection
and a value of 17 is pending delete. Note that there is no requirement that all or part of the
selection be visible; use textsw_possibly_normalize() to guarantee visibility (see
Section 8.7.4, “Which File Lines are Visible?”).
8.10 Dealing with Multiple Views
By splitting a text view, the user can create multiple views of the text being managed by the
text subwindow. Although these additional views are usually transparent to the client code
controlling the text subwindow, it might occasionally be necessary for a client to deal
directly with all of the views. This is accomplished by using the following routines, with the
knowledge that split views are simply extra text subwindows that happen to share the text of
the original text subwindow.
Textsw
textsw_first(textsw)
Textsw textsw;
Given an arbitrary view out of a set of multiple views, textsw_first() returns the first
view (currently, this is the original text subwindow that the client created). To move through
the other views of the set, call:
Textsw
textsw_next(textsw)
Textsw textsw;
Given any view of the set, textsw_next() returns some other member of the set or NULL
if there are none left to enumerate. The loop coded below is guaranteed to process all of the
views in the set:
232 XView Programming Manual
for (textsw = textsw_first(any_split); textsw;
textsw = textsw_next(textsw)) {
/* processing involving textsw */
}
When you create a text subwindow, take into account that the user might split the window. If
you try to do something like enlarge the window, you might run into problems.
8.11 Text Subwindow Destroy Confirmation
A confirmation notice is displayed when a text subwindow is about to be destroyed. A text
subwindow is destroyed when the text subwindow or its enclosing frame is the object of a
xv_destroy() call (this may occur when application is quit from the window manager’s
menu). Supplying the text subwindow confirmation notice is referred to as vetoing the des-
troy. A confirmation notice is provided when the text subwindow’s ignore limit has been
reached. The ignore limit specifies the number of edits permitted before the confirmation
notice is displayed and is set with TEXTSW_IGNORE_LIMIT. Valid values for
TEXTSW_IGNORE_LIMIT are 0, meaning destroy will be vetoed if any edits have been done,
and TEXTSW_INFINITY, meaning the destroy will never be vetoed.
8.12 Notifications from a Text Subwindow
The text subwindow notifies its client about interesting changes in the subwindow’s or text’s
state by calling a notification procedure. It also calls this procedure in response to user
actions. If the client does not provide an explicit notification procedure by using the attribute
TEXTSW_NOTIFY_PROC, then the text subwindow provides a default procedure. The declara-
tion for this procedure looks like:
void
notify_proc(textsw, avlist)
Textsw textsw;
Attr_avlist avlist;
avlist contains attributes that are the members of the Textsw_action enumeration.
Your notification procedure must be careful either to process all of the possible attributes or
to pass through the attributes that it does not process to the standard notification procedure.
This is important because among the attributes that can be in the avlist are those that cause
the standard notification procedure to implement the possible Front, Back, Open, Close, and
Quit accelerators of the user interface.
Example 8-1 presents a client notify procedure for a text subwindow.
Example 8-1. Client notify procedure for a text subwindow
void (*textsw_default_notify)();
void
client_notify_proc(textsw, attributes)
Text Subwindows
Text Subwindows 233
Example 8-1. Client notify procedure for a text subwindow (continued)
Textsw textsw;
Attr_avlist attributes;
{
int pass_on = FALSE;
Attr_avlist attrs;
for (attrs = attributes; *attrs; attrs = attr_next(attrs)) {
switch ((Textsw_action)(*attrs)) {
case TEXTSW_ACTION_CAPS_LOCK:
/* Swallow this attribute */
ATTR_CONSUME(*attrs);
break;
case TEXTSW_ACTION_CHANGED_DIRECTORY:
/* Monitor the attribute, don’t swallow it */
strcpy(current_directory, (char *)attrs[1]);
pass_on = TRUE;
break;
default:
pass_on = TRUE;
break;
}
}
if (pass_on)
textsw_default_notify(textsw, attributes);
}
textsw_default_notify =
(void (*)())xv_get(textsw, TEXTSW_NOTIFY_PROC);
xv_set(textsw, TEXTSW_NOTIFY_PROC, client_notify_proc, NULL);
The Textsw_action attributes that can be passed to your notify procedure are listed in
Table 8-2. Note that in the first column, each attribute begins with the prefix
TEXTSW_ACTION_, which has been omitted from the table to improve readability. Remember
that the attributes constitute a special class that are passed to your text subwindow notifica-
tion procedure. They are not attributes of the text subwindow in the usual sense and cannot
be retrieved or modified using xv_get() or xv_set().
Table 8-2. Textsw_action Attributes
Attribute
(TEXTSW_ACTION_ . . . )
Type Description
CAPS_LOCK Boolean The user pressed the Caps Lock key to change
the setting of the Caps Lock (it is initially 0,
meaning off).
CHANGED_DIRECTORY
char * The current working directory for the process
has been changed to the directory named by the
provided string value.
EDITED_FILE char * The file named by the provided string value has
been edited. Appears once per session of edits
(see below).
234 XView Programming Manual
Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.