1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
|
Terminal I/O requirements:
Every time a user joins a YTalk connection, he is given a window in
which his output will appear. This terminal I/O is modularized in such
a way that YTalk should be able to drive any windowing system or terminal,
as long as someone programs a set of primitive functions.
When init_term() [in term.c] is called from main(), it will select the
appropriate window system, initialize pointers to the appropriate
primitives, and call the init function for that window system. After
this initialization, YTalk will transparently communicate with the
window system by using these primitives. It is therefore important
that each primitive should be implemented exactly the same for each
windowing system. The purpose of this document is to define the
expected behavior of each of the terminal I/O functions.
A valid YTalk 3.0 terminal interface provides an input interface. Each
time the user sends keyboard input, the input should be given to YTalk
by calling this function in comm.c:
void
my_input(user, buf, len) [in comm.c]
yuser *user;
ychar *buf;
int len;
The "user" parameter should be set to the user pointer whose window
the given input was taken from (ie: I had my mouse cursor in the
window assigned to user X and typed some info). The my_input routine
will send the given info to the given user as an aside, ie: no other
users get sent this info. If a terminal interface cannot distinguish
input from various windows, or if you do not wish to bother with this,
then just send "me" as the user. Any input given the "me" user will
get sent to all connected users.
Note that it is much more optimal to call this function once with a
batch of input characters rather than calling this function once for
each character.
A valid YTalk 3.0 terminal interface provides these output functions:
void
init_???()
This is called when the terminal interface has been selected for
use. It should initialize any static variables and start any necessary
connections. It should not open or create any user windows.
Input processing (ie: calls to my_input() in comm.c) should begin after
this initialization function is called.
----------------------
void
end_???()
This is called before YTalk exits. All open windows should be shut
down, any memory should be freed, and any connections should be
terminated. Consider your terminal interface worthy if it can survive
this test indefinitely:
for(;;)
{
init_???();
end_???();
}
----------------------
int
open_???(user, title)
yuser *user;
char *title;
Zero should be returned on success; any other value will be interpreted
as an error.
This function should open a new window with the given title and assigned
to the given user. All future calls which affect this window will be
passed the same user pointer. Since the yuser structure is not passed
between clients, you may add any variables you wish to the structure
as long as you comment them as part of your terminal interface.
The terminal interface should never modify any of the other fields in
the yuser structure, especially the window height and width fields. These
should only be set by calling the resize_win() [term.c] function.
The cursor position should be preset to 0,0.
The window size is assumed to be 80 columns by 24 rows. If this is
not the case, you are required to call the function resize_win() [term.c]
with the appropriate height and width values. I suggest you always call
resize_win() from within open_???().
void
resize_win(user, height, width) [in term.c]
yuser *user;
int height, width;
----------------------
void
close_???(user)
yuser *user;
This will close the window assigned to the given user and free any
attached memory. Again, imagine the test:
for(;;)
{
open_???(user, "test");
close_???(user);
}
----------------------
void
addch_???(user, char)
yuser *user;
ychar char;
This will add the given character to the window, following the terminal
I/O rules listed below.
----------------------
void
move_???(user, y, x)
yuser *user;
int y, x;
This will move the cursor (the next output location) to the given Y,X
coordinates, following the terminal I/O rules listed below.
----------------------
void
clreol_???(user)
yuser *user;
This will clear all characters from (and including) the current cursor
position to the end of the line. The cursor position does not change.
----------------------
void
clreos_???(user)
yuser *user;
This will clear all characters from (and including) the current cursor
position to the end of the screen. The cursor position does not change.
----------------------
void
scroll_???(user)
yuser *user;
This will scroll the window up one line, losing the line at the top
of the window and creating a BLANK line at the bottom of the window.
The cursor's X and Y positions do not change.
This function can be implemented using the other primitives, so it
is therefore optional. I strongly recommend that it be included, as
it will no doubt be faster than the version implemented through the
primitives. If it is not available, then _scroll_term should be
set to NULL in term.c.
----------------------
void
rev_scroll_???(user)
yuser *user;
This will revserse-scroll the window up one line, losing the line at
the bottom of the window and creating a BLANK line at the top of the
window. The cursor's X and Y positions do not change.
This function can be implemented using the other primitives, so it
is therefore optional. I strongly recommend that it be included, as
it will no doubt be faster than the version implemented through the
primitives. If it is not available, then _rev_scroll_term should be
set to NULL in term.c.
----------------------
void
flush_???(user)
yuser *user;
If your window driver optimizes I/O by queuing updates and sending
batches of changes at a time, this function should flush any pending
output. If your window driver does not require flushes, then this
function should do nothing.
----------------------
Terminal I/O Rules:
[ For simplicity, I'll use "maxrows" to mean the maximum number of ]
[ rows and "maxcols" to mean the maximum number of columns in a window. ]
When a window is initially opened, the cursor position should start
at the upper left-hand corner. This position is Y=0,X=0, or (0,0).
The Y position is always given first and corresponds to the row
number, starting at zero and ending at (maxrows-1). The X position
is always given second and corresponds to the column number, starting
at zero and ending at (maxcols-1).
Every window is required to have at least two rows, and each row should
have at least 20 columns.
Every time a character is added to the window, it should be placed
at the cursor's current Y,X position, clearing and overwriting any
character which may already be there. Then, the cursor's X position
should be incremented by one. If the X position is now greater than
or equal to maxcols, then the X position should be set back to
(maxcols-1). THERE IS NO DEFINITION FOR WRAPPING. The cursor's
Y position is never incremented as a result of X being too large.
Instead, X is maintained at (maxcols-1) until move_???() is called
to move the cursor.
Since there is no definition for wrapping, it follows that there is
no definition for automatic scrolling. A window should only scroll
when scroll_???() is called explicitly. Note that some terminals
will scroll automatically when a character is placed in the lower
right-hand corner. If this is the case with your system, I suggest
you tell YTalk that your terminal is actually one row shorter. You
could tell YTalk it is one column skinnier, but this effect can
be visually displeasing.
The terminal interface will only be asked to display printable
characters. These are the characters in the decimal range from
32 [space] to 126 [tilde] inclusive. Therefore, the addch_???()
procedure need not consider how to display control characters or
high-bit characters, because these will never be sent.
Similarly, the move_???() procedure will never be called with
Y or X values outside the range of the current window.
-- EOF --
|