Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 490 lines (439 sloc) 13.349 kb
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
1 /* gui.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
6 #ifdef FEATURE_RCSID
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
7 char id_gui[] = "$Id: gui.c,v 2.33 2004/02/12 17:57:34 steve Exp $";
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
8 #endif
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
9
10 /* This is a pointer to the chosen GUI. */
11 GUI *gui;
12
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
13 /* This function chooses a font to combine with "normal", to use for coloring
14 * normal text. This offers a way to change the background color, or some
15 * other character attribute, to reflect conditions such as input focus or
16 * readonly files. This should be called before drawing or exposing areas.
17 */
18 ELVBOOL guicolorsync(win)
19 WINDOW win;
20 {
21 unsigned short oldbits;
22 ELVBOOL retval = ElvFalse;
23
24 /* choose a font to combine with "normal" for this update */
25 oldbits = colorinfo[win->defaultfont].da.bits;
26 win->defaultfont = o_hasfocus(win) ? COLOR_FONT_NORMAL
27 : COLOR_FONT_IDLE;
28
29 /* if colors have changed, then update the GUI */
30 if (win->fgcolor != colorinfo[win->defaultfont].fg)
31 {
32 win->fgcolor = colorinfo[win->defaultfont].fg;
33 retval = ElvTrue;
34 }
35 if (win->bgcolor != colorinfo[win->defaultfont].bg)
36 {
37 win->bgcolor = colorinfo[win->defaultfont].bg;
38 if (gui->setbg)
39 (*gui->setbg)(win->gw, win->bgcolor);
40 retval = ElvTrue;
41 }
42
43 /* even if colors haven't changed, if the attributes are different
44 * then we still want to force a redraw.
45 */
46 if (((oldbits ^ colorinfo[win->defaultfont].da.bits)
47 & (COLOR_BOLD|COLOR_ITALIC|COLOR_UNDERLINED|COLOR_BOXED)) != 0)
48 {
49 retval = ElvTrue;
50 }
51
52 return retval;
53 }
54
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
55 /* This function calls the GUI's moveto() function. This function performs a
56 * tiny amount of optimization, however: if the cursor is already in the
57 * correct position, it does nothing.
58 */
59 void guimoveto(win, column, row)
60 WINDOW win; /* window whose cursor is to be moved */
61 int column; /* column where cursor should be placed */
62 int row; /* row where cursor should be placed */
63 {
8d1ac0c1 »
2011-12-10 Import Elvis 2.1 (written by Steve Kirkendall)
64 /* perform the moveto */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
65 if (gui->moveto)
66 {
67 (*gui->moveto)(win->gw, column, row);
68 win->cursx = column;
69 win->cursy = row;
70 }
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
71 }
72
73 /* This function calls the GUI's draw() function, and then updates elvis'
74 * own idea of where the cursor is. The guimove() function depends on your
75 * calling guidraw() instead of (*gui->draw)().
76 */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
77 DRAWATTR *guidraw(win, font, text, len, forcebits)
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
78 WINDOW win; /* window where text is to be drawn */
79 _char_ font; /* font to use for drawing */
80 CHAR *text; /* text to be drawn */
81 int len; /* number of characters in text */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
82 int forcebits; /* attributes to add to the font's defaults */
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
83 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
84 COLORINFO *combo;
85 static DRAWATTR da;
86
87 /* Combine font attributes, so that any attributes that are unset in
88 * this font will be inherited from the normal font. Also factor in
89 * the selection font, if appropriate.
90 */
91 if ((unsigned)font <= 1)
92 combo = &colorinfo[win->defaultfont];
93 else
94 {
95
96 if (font & 0x80)
97 combo = colorcombine(font & 0x7f,
98 &colorinfo[COLOR_FONT_SELECTION]);
99 else
100 combo = &colorinfo[font];
101 combo = colorcombine(win->defaultfont, combo);
102 }
103
104 /* Draw it */
105 (*gui->draw)(win->gw, combo->fg, combo->bg, combo->da.bits | forcebits,
106 text, len);
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
107 win->cursx += len;
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
108
109 /* return the attributes of the non-selected font, including the
110 * forcebits. If the font is selected, then also set COLOR_SEL bit.
111 */
112 da = colorinfo[font & 0x7f].da;
113 da.bits = drawfontbits(font);
114 da.bits |= forcebits;
115 return &da;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
116 }
117
118 /* This function calls the GUI's scroll() function, but only if the number of
119 * lines to be deleted/inserted is smaller than the number of lines remaining.
120 * And only if the GUI has a scroll() function, of course.
121 *
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
122 * Returns ElvTrue if the scrolling happened as requested, else ElvFalse.
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
123 */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
124 ELVBOOL guiscroll(win, qty, notlast)
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
125 WINDOW win; /* window to be scrolled */
126 int qty; /* rows to insert (may be negative to delete) */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
127 ELVBOOL notlast;/* if ElvTrue, scrolling shouldn't affect last row */
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
128 {
129 /* if there is no gui->scroll() function, or if we're trying to
130 * insert/delete too many rows, then fail.
131 */
132 if (gui->scroll == NULL || abs(qty) >= o_lines(win) - win->cursy)
133 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
134 return ElvFalse;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
135 }
136
137 /* else give the GUI a try */
138 return (*gui->scroll)(win->gw, qty, notlast);
139 }
140
141 /* This function calls the GUI's shift() function, but only if the number of
142 * characters to the right of the cursor is larger than the requested shift
143 * amount. And only if the GUI has a shift() function, of course.
144 *
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
145 * Returns ElvTrue if the shifting happened as requested, else ElvFalse.
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
146 */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
147 ELVBOOL guishift(win, qty, rows)
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
148 WINDOW win; /* window to be shifted */
149 int qty; /* columns to insert (may be negative to delete) */
150 int rows; /* number of rows affected */
151 {
152 /* if there is no gui->shift() function, or if we're trying to
153 * insert/delete too many characters, then fail.
154 */
155 if (!gui->shift || abs(qty) >= o_columns(win) - win->cursx)
156 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
157 return ElvFalse;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
158 }
159
160 /* else give the GUI a try */
161 return (*gui->shift)(win->gw, qty, rows);
162 }
163
164 /* This function calls the GUI's cltroeol() function. If it doesn't exist,
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
165 * or returns ElvFalse, then this function writes enough space characters to
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
166 * simulate a clrtoeol()
167 */
168 void guiclrtoeol(win)
169 WINDOW win; /* window whose row is to be cleared */
170 {
171 int width;
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
172 COLORINFO *n;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
173
174 /* if already at EOL, we're done */
175 width = o_columns(win) - win->cursx;
176 if (width <= 0)
177 {
178 return;
179 }
180
181 /* try to make the GUI do it */
182 if (gui->clrtoeol == NULL || !(*gui->clrtoeol)(win->gw))
183 {
184 /* No, we need to do it the hard way */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
185 n = &colorinfo[o_hasfocus(win) ? COLOR_FONT_NORMAL : COLOR_FONT_IDLE];
186 guimoveto(win, win->cursx, win->cursy);
187 while (width > QTY(blanks))
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
188 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
189 (*gui->draw)(win->gw, n->fg, n->bg, n->da.bits, blanks, QTY(blanks));
190 width -= QTY(blanks);
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
191 }
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
192 (*gui->draw)(win->gw, n->fg, n->bg, n->da.bits, blanks, width);
193 guimoveto(win, win->cursx, win->cursy);
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
194 }
195 }
196
197
198 /* This function calls the GUI's reset function (if it has one) and also
199 * resets the portable GUI wrapper functions' variables.
200 *
201 * Why do this? Because the wrapper functions, and some GUI drawing functions,
202 * perform some internal optimizations by assuming that nothing else affects
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
203 * the screen when we aren't looking; but when line noise corrupts the screen
204 * we want ^L to force the whole screen to be redrawn, that assumption is
205 * unsafe.
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
206 */
207 void guireset()
208 {
209 WINDOW w;
210
211 /* if the GUI has a reset function call it */
212 if (gui->reset)
213 {
214 (*gui->reset)();
215 }
216
217 /* reset the wrapper functions' variables */
218 for (w = windows; w; w = w->next)
219 {
220 w->cursx = w->cursy = -1;
221 }
222 }
223
224
225 /* This function calls the GUI's poll() function. If it has no poll() function
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
226 * then this function always returns ElvFalse to indicate that the current work
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
227 * should continue. This function is also sensitive to the pollfrequency
228 * option, to reduce the number of calls to poll() since poll() may be slow.
229 *
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
230 * Returns ElvFalse if the current work should continue, or ElvTrue if the user
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
231 * has requested that it be cut short.
232 */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
233 ELVBOOL guipoll(reset)
234 ELVBOOL reset; /* reset the pollctr variable? */
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
235 {
236 static long pollctr = 0;
237
238 /* if just supposed to reset, then do that and then quit */
239 if (reset)
240 {
241 pollctr = 0;
242 if (gui && gui->poll)
243 return (*gui->poll)(reset);
244 else
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
245 return ElvFalse;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
246 }
247
97d89980 »
2011-12-10 Import Elvis 2.1_4 (written by Steve Kirkendall)
248 /* if no GUI has been chosen yet, or there is no poll() function, or
249 * we're quitting, or pollfrequency indicates that poll() shouldn't
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
250 * be called yet, then return ElvFalse so the current operation will
97d89980 »
2011-12-10 Import Elvis 2.1_4 (written by Steve Kirkendall)
251 * continue.
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
252 */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
253 if (!gui || !gui->poll || !windows || ++pollctr < o_pollfrequency)
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
254 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
255 return ElvFalse;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
256 }
257
258 /* reset the pollctr variable */
259 pollctr = 0;
260
261 /* call the GUI's poll() function, and return its value */
262 reset = (*gui->poll)(reset);
263 if (reset)
264 {
265 msg(MSG_ERROR, "aborted");
266 }
267 return reset;
268 }
269
270 /* ring the bell, if there is one. Limit it to one ding per eventdraw() */
271 void guibeep(win)
272 WINDOW win; /* window to ding, or NULL to indicate an eventdraw() */
273 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
274 static ELVBOOL dingable = ElvTrue;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
275
276 if (!win)
277 {
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
278 dingable = ElvTrue;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
279 }
280 else if (gui && gui->beep && dingable)
281 {
282 (*gui->beep)(win->gw);
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
283 dingable = ElvFalse;
cf92e3be »
2011-12-10 Import Elvis 2.0 (written by Steve Kirkendall)
284 }
285 }
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
286
287 /* Translate a key name or raw key sequence into both an official key name
288 * and rawin sequence, and return the length of the rawin sequence. This is
289 * a wrapper around the (*gui->keylabel)() function, and it adds support for
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
290 * some standard keys. It also adds the intelligence needed to handle a series
291 * of keys, as opposed to a single key that sends multiple characters.
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
292 */
293 int guikeylabel(given, givenlen, label, rawptr)
294 CHAR *given; /* what the user typed in as a key code */
295 int givenlen;/* length of the given string */
296 CHAR **label; /* where to store a pointer to the symbolic name */
297 CHAR **rawptr;/* where to store a pointer to the raw characters */
298 {
299 int rawlen, labellen, i;
300 CHAR *scan;
301 static CHAR *build;
302 CHAR *symlabel, *symraw;
303 CHAR ch[1];
304 CHAR first;
305 CHAR hashnotation[30];
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
306 int keystrokes;
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
307 static struct {
308 CHAR *label;
309 int len;
310 CHAR ch;
311 } keys[] = {
312 {toCHAR("<Nul>"), 5, '\0'},
313 {toCHAR("<BS>"), 4, '\b'},
314 {toCHAR("<Tab>"), 5, '\t'},
315 {toCHAR("<FF>"), 4, '\f'},
316 {toCHAR("<NL>"), 4, '\n'},
317 {toCHAR("<LF>"), 4, '\n'},
318 {toCHAR("<EOL>"), 4, '\n'},
319 {toCHAR("<CR>"), 4, '\r'},
320 {toCHAR("<Return>"), 8, '\r'},
321 {toCHAR("<Enter>"), 7, '\r'},
322 {toCHAR("<Esc>"), 5, (CHAR)0x1b},
323 {toCHAR("<CSI>"), 5, (CHAR)0x9b},
324 {toCHAR("<Del>"), 5, (CHAR)0x7f},
325 {toCHAR("<Space>"), 7, ' '},
326 {toCHAR("<lt>"), 4, '<'},
327 {toCHAR("<gt>"), 4, '>'},
328 {toCHAR("<Bar>"), 5, '|'},
329 {toCHAR("<Bslash>"), 8, '\\'}
330 };
331
332 /* if looking up the label of a single character, then check the table */
333 if (givenlen == 1 && label)
334 {
335 for (i = 0; i < QTY(keys); i++)
336 {
337 if (keys[i].ch == *given)
338 {
339 *label = keys[i].label;
340 break;
341 }
342 }
343 if (rawptr)
344 *rawptr = given;
345 return givenlen;
346 }
347
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
348 /* Allow the GUI to translate "#number" function keys. (The "#number"
349 * notation isn't allowed to be mixed with other characters, so the
350 * <key> conversion loop below doesn't handle it. So we do it here.)
351 */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
352 if (gui->keylabel && given[0] == '#')
353 {
354 rawlen = (*gui->keylabel)(given, givenlen, label, rawptr);
355 if (rawlen > 0)
356 return rawlen;
357 }
358
359 /* if there's an old raw string lying around, free it now */
360 if (build)
361 safefree(build);
362
363 /* else we'll build a string by looking for <key> names */
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
364 keystrokes = 0;
365 symlabel = NULL;
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
366 for (build = NULL, scan = given; scan < &given[givenlen]; scan++)
367 {
368 /* anything other than '<' is added literally */
369 if (*scan != '<')
370 {
371 buildCHAR(&build, *scan);
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
372 keystrokes++;
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
373 continue;
374 }
375
376 /* count the length of the symbolic name, up to next '>' */
377 labellen = 1;
378 do
379 {
380 /* watch out for problems */
381 if (&scan[labellen] == &given[givenlen]
382 || scan[labellen] == '<'
383 || elvspace(scan[labellen]))
384 break;
385 } while (scan[labellen++] != '>');
386
387 /* does it look like a symbolic name? */
388 symraw = NULL;
389 if (scan[labellen - 1] == '>')
390 {
391 /* is it a shifted of controlled function key? */
392 first = elvtolower(scan[1]);
393 if (labellen >= 6
394 && (first == 'c' || first == 's')
395 && scan[2] == '-'
396 && elvtolower(scan[3]) == 'f'
397 && elvdigit(scan[4])
398 && gui->keylabel)
399 {
400 hashnotation[0] = '#';
401 memcpy(&hashnotation[1], &scan[4], (labellen - 5) * sizeof(CHAR));
402 hashnotation[labellen - 4] = first;
403 rawlen = (*gui->keylabel)(hashnotation, labellen - 3, &symlabel, &symraw);
404 }
405
406 /* is it a normal function key? */
407 if (!symraw
408 && labellen >= 4
409 && first == 'f'
410 && elvdigit(scan[2])
411 && gui->keylabel)
412 {
413 hashnotation[0] = '#';
414 memcpy(&hashnotation[1], &scan[2], (labellen - 3) * sizeof(CHAR));
415 rawlen = (*gui->keylabel)(hashnotation, labellen - 2, &symlabel, &symraw);
416 }
417
418 /* is it a <C-X> notation? */
419 if (!symraw && labellen == 5 && first == 'c' && scan[2] == '-')
420 {
421 if (scan[3] == '?')
422 ch[0] = '\177';
423 else
424 ch[0] = scan[3] & 0x1f;
425 symraw = ch;
426 rawlen = 1;
427 }
428
429 /* is it a <M-X> or <A-X> notation? */
430 if (!symraw
431 && labellen == 5
432 && (first == 'm' || first == 'a')
433 && scan[2] == '-')
434 {
435 ch[0] = scan[3] | 0x80;
436 symraw = ch;
437 rawlen = 1;
438 }
439
440 /* is this a standard symbol for a character? */
441 if (!symraw)
442 {
443 /* scan the list of keys */
444 for (i = 0;
445 i < QTY(keys)
446 && (keys[i].len != labellen
447 || CHARncasecmp(keys[i].label, scan, labellen));
448 i++)
449 {
450 }
451
452 /* was a key found? */
453 if (i < QTY(keys))
454 {
455 symraw = &keys[i].ch;
456 rawlen = 1;
457 }
458 }
459
460 /* if nothing standard worked, then let the GUI try */
461 if (!symraw && gui->keylabel)
462 rawlen = (*gui->keylabel)(scan, labellen, &symlabel, &symraw);
463 }
464
465 /* if no symbol was recognized, then use it literally */
466 if (!symraw)
467 {
468 /* use the label characters literally */
469 rawlen = labellen;
470 symraw = scan;
471 }
472
473 /* add the symbol's raw chars to the buffer */
474 while (rawlen-- > 0)
475 buildCHAR(&build, *symraw++);
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
476 keystrokes++;
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
477
478 /* move the scan variable past the symbolic name */
479 scan += labellen - 1;
480 }
481
482 /* stick a <nul> on the end, and return the length without the null */
483 rawlen = buildCHAR(&build, '\0') - 1;
484 *rawptr = build;
2fe6e177 »
2011-12-10 Import Elvis 2.2_1 (written by Steve Kirkendall)
485 if (keystrokes == 1 && label && symlabel)
486 *label = symlabel;
487 /* ...else leave (*label) unchanged */
9f1c6f0f »
2011-12-10 Import Elvis 2.2_0 (written by Steve Kirkendall)
488 return rawlen;
489 }
Something went wrong with that request. Please try again.