1 /******************************************************************************
2 *
3 * NSSDC/CDF Windowing functions.
4 *
5 * Version 4.0a, 15-Dec-97, Hughes STX.
6 *
7 * Modification history:
8 *
9 * V1.0 29-Jan-91, H Leckner Original version (for CDF V2.0).
10 * V1.1 4-Aug-91, J Love TRUE/FALSE. Minor change to borders (well
11 * H Leckner maybe).
12 * V1.2 13-Aug-91, H Leckner Fixed border labeling.
13 * V1.3 8-Oct-91, J Love Modified for IRIX 4.0 port, etc.
14 * H Leckner
15 * V2.0 30-Apr-92, H Leckner CDF V2.2. IBM PC port. Added `input_field'
16 * J Love and `get_input'.
17 * V2.1 20-Jul-92, J Love CDF V2.3 (shareable/NeXT/zVar).
18 * V3.0 9-Dec-93, J Love CDF V2.4. Generalized for all platforms.
19 * V3.1 21-Dec-94, J Love CDF V2.5.
20 * V3.2 23-Jan-95, J Love IRIX 6.x (64-bit).
21 * V3.2a 31-Jan-95, J Love Fixed `WindowSize' for VMS.
22 * V3.2b 7-Feb-95, J Love Made `WindowLocation' and `WindowSize'
23 * function prototypes `static'.
24 * V3.2c 3-Mar-95, J Love Moved `EncodeKeyDefinitions', etc. to this
25 * file.
26 * V3.3 4-Apr-95, J Love POSIX.
27 * V3.3a 18-Apr-95, J Love More POSIX.
28 * V3.3b 13-Jun-95, J Love Linux.
29 * V3.4 16-Jun-95, J Love `key_waiting'.
30 * V3.4a 11-Jul-95, J Love `key_waiting' for UNIX.
31 * V3.4b 7-Sep-95, J Love CDFexport-related changes.
32 * V3.4c 19-Sep-95, J Love Macintosh event handling.
33 * V3.4d 28-Sep-95, J Love Increased precision of `zzzzz' on Macintosh.
34 * The CDF cursor.
35 * V3.5 3-Oct-96, J Love CDF V2.6.
36 * V3.5a 2-Sep-97, J Love Special keys for AIX.
37 * V4.0 14-Nov-97, J Love Windows NT/Visual C++.
38 * V4.0a 15-Dec-97, J Love IEEE floating-point on Alpha/OpenVMS.
39 * V4.1 2-May-01, M Liu Special keys for CYGWIN.
40 * V4.2 11-Jul-05, M Liu Added MingW port for PC.
41 *
42 *******************************************************************************
43 * NOTES:
44 * 1. All functions return TRUE if successful, FALSE if an error occurred.
45 * 2. The borders provided by SMG are not used. SMG$DRAW_RECTANGLE is used
46 * if a border is requested. This is to allow the `draw_horizontal_line'
47 * and 'draw_vertical_line' functions the ability to draw a line all the
48 * way to the border (where SMG "tees" the line).
49 * 3. On the IBM PC...
50 * a) It doesn't seem to be possible to OR in attributes with a
51 * character. Currently using `wattrset' before writing characters.
52 * b) The cursor cannot be positioned on a character position that has
53 * not been written to.
54 * 4. On the VAX (SMG), using SMG$SET_CURSOR_ABS doesn't seem to work if
55 * the pasteboard is being batched (SMG$BEGIN/END_PASTEBOARD_UPDATE).
56 * The cursor is always placed at (1,1) when the screen is updated. So
57 * don't do that.
58 ******************************************************************************/
59
60 /******************************************************************************
61 * Include files.
62 ******************************************************************************/
63
64 #include "windoz.h"
65
66 #if defined(win32)
67 #include "windows.h"
68 #endif
69
70 #if defined(mac)
71 #include "fsi.rh"
72 #endif
73
74 /******************************************************************************
75 * Macros.
76 ******************************************************************************/
77
78 #define INTERPRET_ESC_SEQUENCES 1
79 #define ESC 27
80
81 /******************************************************************************
82 * Global variables.
83 ******************************************************************************/
84
85 #if defined(SMGui)
86 static long pbid;
87 static long kbid;
88 static int keyWaiting;
89 #endif
90
91 #if defined(CURSESui)
92 static int batchCount; /* When zero (0), updates to screen
93 (pasteboard) are applied
94 immediately. */
95 #endif
96
97 #if defined(COWui)
98 #if defined(mac)
99 static WindowPtr fsiWindowP; /* Full screen interface window
100 pointer. */
101 static MenuHandle appleMenuHfsi; /* Menu handle for apple. */
102 #endif
103 static WINDOWid cursorWIND; /* Window in which the cursor was
104 last set. */
105 static int cursorRow; /* Row at which cursor was last set. */
106 static int cursorCol; /* Column at which cursor was last
107 set. */
108 static Logical cursorVisible; /* TRUE if the cursor is currently
109 visible. */
110 static int batchCount; /* When zero (0), updates to screen
111 (pasteboard) are applied
112 immediately. */
113 static char *pbNewChars; /* New characters for the
114 pasteboard. */
115 static char *pbNewAttrs; /* New attributes for the
116 pasteboard. */
117 static char *pbCurrentChars; /* Current characters on the
118 pasteboard. */
119 static char *pbCurrentAttrs; /* Current attributes on the
120 pasteboard. */
121 static char *pbNullChars; /* Pasteboard of null characters. */
122 static char *pbBlankChars; /* Pasteboard of blank characters. */
123 static char *pbNormalAttrs; /* Normal pasteboard of attributes. */
124 #endif
125
126 static WINDOWid WINDhead; /* Head of window linked list. 1st
127 window on list is most occluded.
128 Last window on list is on top of
129 all other windows (most recently
130 pasted). */
131 static Logical cursorOn; /* TRUE if the cursor has been set to
132 be visible (when not occluded). */
133
134 /******************************************************************************
135 * Local function prototypes.
136 ******************************************************************************/
137
138 #if defined(SMGui)
139 static void KeyWaitingAST PROTOARGs((void));
140 #endif
141
142 #if defined(CURSESui)
143 static void WindowLocation PROTOARGs((LocalId id, int *row, int *col));
144 #endif
145
146 #if defined(CURSESui) || defined(SMGui)
147 static void WindowSize PROTOARGs((LocalId id, int *rows, int *cols));
148 #endif
149
150 static int RenditionMapping PROTOARGs((int));
151 static WINDOWid AddWIND PROTOARGs((LocalId, Logical, Logical));
152 static Logical MoveWINDtoEnd PROTOARGs((WINDOWid));
153 static Logical DeleteWIND PROTOARGs((WINDOWid));
154 static Logical DeleteWINDs PROTOARGs((void));
155
156 #if defined(CURSESui) || defined(COWui)
157 static Logical RefreshWINDs PROTOARGs((int level));
158 #endif
159
160 #if defined(CURSESui)
161 static int EraseWindow PROTOARGs((LocalId));
162 #endif
163
164 #if defined(COWui)
165 #if defined(mac)
166 static void InvertCursor PROTOARGs((WINDOWid wid, int rowN, int colN));
167 #endif
168 static Logical CharOccluded PROTOARGs((WINDOWid wid, int rowN, int colN));
169 #endif
170
171 static char *KeyToken PROTOARGs((int, int));
172 static char *AlphaKey PROTOARGs((int, int));
173 static char *ControlKey PROTOARGs((int, int));
174
175 /******************************************************************************
176 * begin_pasteboard_update.
177 ******************************************************************************/
178
begin_pasteboard_update()179 int begin_pasteboard_update () {
180 #if defined(SMGui)
181 if (StatusBad(smg$begin_pasteboard_update(&pbid))) return FALSE;
182 return TRUE;
183 #endif
184 #if defined(CURSESui)
185 batchCount++;
186 return TRUE;
187 #endif
188 #if defined(COWui)
189 batchCount++;
190 return TRUE;
191 #endif
192 }
193
194 /******************************************************************************
195 * change_rendition.
196 ******************************************************************************/
197
change_rendition(wid,row,col,num_rows,num_cols,rendition)198 int change_rendition (wid, row, col, num_rows, num_cols, rendition)
199 WINDOWid wid;
200 int row;
201 int col;
202 int num_rows;
203 int num_cols;
204 int rendition;
205 {
206 #if defined(SMGui)
207 long rowN = row + 1;
208 long colN = col + 1;
209 uLong rend = RenditionMapping (rendition);
210 if (StatusBad(smg$change_rendition(&(wid->id),&rowN,&colN,
211 &num_rows,&num_cols,&rend))) return FALSE;
212 return TRUE;
213 #endif
214 #if defined(CURSESui)
215 int i,j;
216 wattrset (wid->id, RenditionMapping(rendition));
217 for (i = 0; i < num_rows; i++)
218 for (j = 0; j < num_cols; j++)
219 mvwaddch (wid->id, row+i, col+j,
220 mvwinch(wid->id,row+i,col+j) & A_CHARTEXT);
221 if (!RefreshWINDs(UPDATE_)) return FALSE;
222 return TRUE;
223 #endif
224 #if defined(COWui)
225 char rend = RenditionMapping (rendition);
226 char *attrs = wid->id->attrs;
227 int i, j;
228 for (i = 0; i < num_rows; i++)
229 for (j = 0; j < num_cols; j++) {
230 int charN = (wid->id->nCols*(row+i)) + (col+j);
231 attrs[charN] = rend;
232 }
233 if (!RefreshWINDs(UPDATE_)) return FALSE;
234 return TRUE;
235 #endif
236 }
237
238 /******************************************************************************
239 * create_pasteboard.
240 ******************************************************************************/
241
create_pasteboard()242 int create_pasteboard () {
243 #if defined(SMGui)
244 if (StatusBad(smg$create_pasteboard(&pbid,NULL,NULL,NULL,NULL,NULL))) {
245 return FALSE;
246 }
247 if (StatusBad(smg$create_virtual_keyboard(&kbid,NULL,NULL,NULL,NULL))) {
248 return FALSE;
249 }
250 if (StatusBad(smg$enable_unsolicited_input(&pbid,KeyWaitingAST,NULL))) {
251 return FALSE;
252 }
253 keyWaiting = 0;
254 WINDhead = NULL;
255 set_cursor_mode (CURSORon);
256 return TRUE;
257 #endif
258 #if defined(CURSESui)
259 initscr ();
260 keypad (stdscr, TRUE);
261 noecho ();
262 nonl ();
263 raw ();
264 refresh (); /* Clears screen. */
265 batchCount = 0;
266 WINDhead = NULL;
267 set_cursor_mode (CURSORon);
268 return TRUE;
269 #endif
270 #if defined(COWui)
271 int charN, nChars = NUMfsiROWS * NUMfsiCOLS;
272 #if defined(mac)
273 Rect eraseRect = { 0, 0, WINDOWfsiHEIGHT, WINDOWfsiWIDTH };
274 #endif
275 batchCount = 0;
276 WINDhead = NULL;
277 cursorWIND = NULL;
278 cursorVisible = FALSE;
279 cursorOn = FALSE;
280 pbCurrentChars = (char *) cdf_AllocateMemory (nChars, FatalError);
281 pbCurrentAttrs = (char *) cdf_AllocateMemory (nChars, FatalError);
282 pbNewChars = (char *) cdf_AllocateMemory (nChars, FatalError);
283 pbNewAttrs = (char *) cdf_AllocateMemory (nChars, FatalError);
284 pbNullChars = (char *) cdf_AllocateMemory (nChars, FatalError);
285 pbBlankChars = (char *) cdf_AllocateMemory (nChars, FatalError);
286 pbNormalAttrs = (char *) cdf_AllocateMemory (nChars, FatalError);
287 for (charN = 0; charN < nChars; charN++) {
288 pbNullChars[charN] = 0;
289 pbBlankChars[charN] = ' ';
290 pbNormalAttrs[charN] = 0;
291 }
292 memmove (pbCurrentChars, pbBlankChars, nChars);
293 memmove (pbCurrentAttrs, pbNormalAttrs, nChars);
294 set_cursor_mode (CURSORon);
295 #if defined(mac)
296 EraseRect (&eraseRect);
297 ShowWindow (fsiWindowP);
298 #endif
299 #if defined(win32)
300 /* Jeff...maybe nothing needs to be done. */
301 #endif
302 return TRUE;
303 #endif
304 }
305
306 /******************************************************************************
307 * create_virtual_display.
308 * The window is not visibile until the function `paste_virtual_display' is
309 * used.
310 ******************************************************************************/
311
create_virtual_display(num_rows,num_cols,wid,borderMode,rendition)312 int create_virtual_display (num_rows, num_cols, wid, borderMode, rendition)
313 int num_rows;
314 int num_cols;
315 WINDOWid *wid;
316 int borderMode; /* If BORDER, draw border around display. */
317 int rendition; /* Rendition of border (if bordered). */
318 {
319 #if defined(SMGui)
320 LocalId id;
321 uLong attrs = 0;
322 uLong rend = RenditionMapping (NORMAL); /* Default for display. */
323 long nRows = num_rows;
324 long nCols = num_cols;
325 if (StatusBad(smg$create_virtual_display(&nRows,&nCols,&id,
326 &attrs,&rend,NULL))) return FALSE;
327 *wid = AddWIND (id, FALSE, (borderMode == BORDER));
328 if (borderMode == BORDER) draw_rectangle (*wid, 0, 0, num_rows - 1,
329 num_cols - 1, rendition);
330 return TRUE;
331 #endif
332 #if defined(CURSESui)
333 LocalId id = newwin (num_rows, num_cols, 0, 0);
334 if (id == NULL) return FALSE;
335 keypad (id, TRUE);
336 *wid = AddWIND (id, FALSE, (borderMode == BORDER));
337 erase_display (*wid, 0, 0, num_rows - 1, num_cols - 1);
338 if (borderMode == BORDER) draw_rectangle (*wid, 0, 0, num_rows - 1,
339 num_cols - 1, rendition);
340 return TRUE;
341 #endif
342 #if defined(COWui)
343 LocalId id;
344 int nChars = num_rows * num_cols;
345 if (num_rows < 1 || num_rows > NUMfsiROWS) return FALSE;
346 if (num_cols < 1 || num_cols > NUMfsiCOLS) return FALSE;
347 id = (LocalId) cdf_AllocateMemory (sizeof(COWvd), FatalError);
348 id->nRows = num_rows;
349 id->nCols = num_cols;
350 id->atRowN = 0;
351 id->atColN = 0;
352 id->chars = (char *) cdf_AllocateMemory (nChars, FatalError);
353 id->attrs = (char *) cdf_AllocateMemory (nChars, FatalError);
354 *wid = AddWIND (id, FALSE, (borderMode == BORDER));
355 memmove (id->chars, pbBlankChars, nChars);
356 memmove (id->attrs, pbNormalAttrs, nChars);
357 if (borderMode == BORDER) draw_rectangle (*wid, 0, 0, num_rows - 1,
358 num_cols - 1, rendition);
359 return TRUE;
360 #endif
361 }
362
363 /******************************************************************************
364 * delete_pasteboard.
365 ******************************************************************************/
366
delete_pasteboard(eraseMode)367 int delete_pasteboard (eraseMode)
368 int eraseMode;
369 {
370 #if defined(SMGui)
371 uLong flags = (eraseMode == ERASE ? SMG$M_ERASE_PBD : 0);
372 Logical status = DeleteWINDs();
373 if (StatusBad(smg$delete_pasteboard(&pbid,&flags))) return FALSE;
374 return status;
375 #endif
376 #if defined(CURSESui)
377 Logical status = DeleteWINDs();
378 if (eraseMode == ERASE) { /* Don't change default attributes first. */
379 EraseWindow (stdscr);
380 wrefresh (stdscr);
381 }
382 endwin ();
383 return status;
384 #endif
385 #if defined(COWui)
386 Logical status = DeleteWINDs();
387 #if defined(mac)
388 Rect eraseRect = { 0, 0, WINDOWfsiHEIGHT, WINDOWfsiWIDTH };
389 #endif
390 #if defined(mac)
391 if (eraseMode == ERASE) EraseRect (&eraseRect);
392 #endif
393 cdf_FreeMemory (pbCurrentChars, FatalError);
394 cdf_FreeMemory (pbCurrentAttrs, FatalError);
395 cdf_FreeMemory (pbNewChars, FatalError);
396 cdf_FreeMemory (pbNewAttrs, FatalError);
397 cdf_FreeMemory (pbNullChars, FatalError);
398 cdf_FreeMemory (pbBlankChars, FatalError);
399 cdf_FreeMemory (pbNormalAttrs, FatalError);
400 #if defined(mac)
401 HideWindow (fsiWindowP);
402 #endif
403 return status;
404 #endif
405 }
406
407 /******************************************************************************
408 * delete_virtual_display.
409 ******************************************************************************/
410
delete_virtual_display(wid)411 int delete_virtual_display (wid)
412 WINDOWid wid;
413 {
414 if (!DeleteWIND(wid)) return FALSE;
415 return TRUE;
416 }
417
418 /******************************************************************************
419 * draw_horizontal_line.
420 ******************************************************************************/
421
draw_horizontal_line(wid,rowN,LcolN,RcolN,rendition,teeEnds)422 int draw_horizontal_line (wid, rowN, LcolN, RcolN, rendition, teeEnds)
423 WINDOWid wid; /* Window id. */
424 int rowN; /* Row number. */
425 int LcolN; /* Left column number (start) -- numbered from zero. */
426 int RcolN; /* Right column number (stop) -- numbered from zero. */
427 int rendition; /* Rendition to use. */
428 Logical teeEnds; /* If TRUE, draw ACS_LTEE and ACS_RTEE at the ends of
429 the line (ACS_HLINE is drawn at all of the other
430 positions). If FALSE, draw ACS_HLINE at all of the
431 positions. On SMG systems (VAX/VMS), this option
432 is ignored (SMG decides whether or not to tee the
433 ends based on the existing characters at those
434 positions). */
435 {
436 #if defined(SMGui)
437 long startRowN = rowN + 1;
438 long endRowN = startRowN;
439 long startColN = LcolN + 1;
440 long endColN = RcolN + 1;
441 uLong rend = RenditionMapping(rendition);
442 if (StatusBad(smg$draw_line(&(wid->id),&startRowN,&startColN,
443 &endRowN,&endColN,&rend,NULL))) return FALSE;
444 #endif
445 #if defined(CURSESui)
446 int colN; /* Column number -- numbered from zero. */
447 wattrset (wid->id, RenditionMapping(rendition));
448 mvwaddch (wid->id, rowN, LcolN, (teeEnds ? ACS_LTEE : ACS_HLINE));
449 for (colN = LcolN + 1; colN < RcolN; colN++)
450 mvwaddch (wid->id, rowN, colN, ACS_HLINE);
451 mvwaddch (wid->id, rowN, RcolN, (teeEnds ? ACS_RTEE : ACS_HLINE));
452 if (!RefreshWINDs(UPDATE_)) return FALSE;
453 return TRUE;
454 #endif
455 #if defined(COWui)
456 int colN, /* Column number -- numbered from zero. */
457 charN; /* Character number -- numbered from zero. */
458 char rend = RenditionMapping (rendition);
459 short nCols = wid->id->nCols;
460 char *chars = wid->id->chars,
461 *attrs = wid->id->attrs;
462 charN = (rowN * nCols) + LcolN;
463 chars[charN] = (teeEnds ? ACS_LTEE : ACS_HLINE);
464 attrs[charN] = rend;
465 for (colN = LcolN + 1; colN < RcolN; colN++) {
466 charN = (rowN * nCols) + colN;
467 chars[charN] = ACS_HLINE;
468 attrs[charN] = rend;
469 }
470 charN = (rowN * nCols) + RcolN;
471 chars[charN] = (teeEnds ? ACS_RTEE : ACS_HLINE);
472 attrs[charN] = rend;
473 if (!RefreshWINDs(UPDATE_)) return FALSE;
474 return TRUE;
475 #endif
476 }
477
478 /******************************************************************************
479 * draw_vertical_line.
480 ******************************************************************************/
481
draw_vertical_line(wid,TrowN,BrowN,colN,rendition,teeEnds)482 int draw_vertical_line (wid, TrowN, BrowN, colN, rendition, teeEnds)
483 WINDOWid wid; /* Window id. */
484 int TrowN; /* Top row number (start) -- numbered from zero. */
485 int BrowN; /* Bottom row number (stop) -- numbered from zero. */
486 int colN; /* Column number -- numbered from zero. */
487 int rendition; /* Rendition to use. */
488 Logical teeEnds; /* If TRUE, draw ACS_TTEE and ACS_BTEE at the ends of
489 the line (ACS_VLINE is drawn at all of the other
490 positions). If FALSE, draw ACS_VLINE at all of the
491 positions. On SMG systems (VAX/VMS), this option
492 is ignored (SMG decides whether or not to tee the
493 ends based on the existing characters at those
494 positions). */
495 {
496 #if defined(SMGui)
497 long startRowN = TrowN + 1;
498 long endRowN = BrowN + 1;
499 long startColN = colN + 1;
500 long endColN = startColN;
501 uLong rend = RenditionMapping(rendition);
502 if (StatusBad(smg$draw_line(&(wid->id),&startRowN,&startColN,
503 &endRowN,&endColN,&rend,NULL))) return FALSE;
504 #endif
505 #if defined(CURSESui)
506 int rowN; /* Row number -- numbered from zero. */
507 wattrset (wid->id, RenditionMapping(rendition));
508 mvwaddch (wid->id, TrowN, colN, (teeEnds ? ACS_TTEE : ACS_VLINE));
509 for (rowN = TrowN + 1; rowN < BrowN; rowN++)
510 mvwaddch (wid->id, rowN, colN, ACS_VLINE);
511 mvwaddch (wid->id, BrowN, colN, (teeEnds ? ACS_BTEE : ACS_VLINE));
512 if (!RefreshWINDs(UPDATE_)) return FALSE;
513 return TRUE;
514 #endif
515 #if defined(COWui)
516 int rowN, /* Row number -- numbered from zero. */
517 charN; /* Character number -- numbered from zero. */
518 char rend = RenditionMapping (rendition);
519 short nCols = wid->id->nCols;
520 char *chars = wid->id->chars,
521 *attrs = wid->id->attrs;
522 charN = (TrowN * nCols) + colN;
523 chars[charN] = (teeEnds ? ACS_TTEE : ACS_VLINE);
524 attrs[charN] = rend;
525 for (rowN = TrowN + 1; rowN < BrowN; rowN++) {
526 charN = (rowN * nCols) + colN;
527 chars[charN] = ACS_VLINE;
528 attrs[charN] = rend;
529 }
530 charN = (BrowN * nCols) + colN;
531 chars[charN] = (teeEnds ? ACS_BTEE : ACS_VLINE);
532 attrs[charN] = rend;
533 if (!RefreshWINDs(UPDATE_)) return FALSE;
534 return TRUE;
535 #endif
536 }
537
538 /******************************************************************************
539 * draw_rectangle.
540 ******************************************************************************/
541
draw_rectangle(wid,Trow,Lcol,Brow,Rcol,rendition)542 int draw_rectangle (wid, Trow, Lcol, Brow, Rcol, rendition)
543 WINDOWid wid;
544 int Trow; /* Top row number. */
545 int Lcol; /* Left column number. */
546 int Brow; /* Bottom row number. */
547 int Rcol; /* Right column number. */
548 int rendition; /* Video attributes. */
549 {
550 #if defined(SMGui)
551 long startRow = Trow + 1;
552 long startCol = Lcol + 1;
553 long endRow = Brow + 1;
554 long endCol = Rcol + 1;
555 uLong rend = RenditionMapping (rendition);
556 if (StatusBad(smg$draw_rectangle(&(wid->id),&startRow,&startCol,
557 &endRow,&endCol,&rend,NULL))) return FALSE;
558 return TRUE;
559 #endif
560 #if defined(CURSESui)
561 int x, y;
562 wattrset (wid->id, RenditionMapping(rendition));
563 mvwaddch (wid->id, Trow, Lcol, ACS_ULCORNER);
564 for (x = Lcol+1; x <= Rcol-1; x++) mvwaddch (wid->id, Trow, x, ACS_HLINE);
565 mvwaddch (wid->id, Trow, Rcol, ACS_URCORNER);
566 for (y = Trow+1; y <= Brow-1; y++) mvwaddch (wid->id, y, Rcol, ACS_VLINE);
567 mvwaddch (wid->id, Brow, Rcol, ACS_LRCORNER);
568 for (x = Rcol-1; x >= Lcol+1; x--) mvwaddch (wid->id, Brow, x, ACS_HLINE);
569 mvwaddch (wid->id, Brow, Lcol, ACS_LLCORNER);
570 for (y = Brow-1; y >= Trow+1; y--) mvwaddch (wid->id, y, Lcol, ACS_VLINE);
571 if (!RefreshWINDs(UPDATE_)) return FALSE;
572 return TRUE;
573 #endif
574 #if defined(COWui)
575 char rend = RenditionMapping (rendition);
576 short nCols = wid->id->nCols;
577 char *chars = wid->id->chars,
578 *attrs = wid->id->attrs;
579 int charN, x, y;
580 charN = (Trow * nCols) + Lcol;
581 chars[charN] = ACS_ULCORNER;
582 attrs[charN] = rend;
583 for (x = Lcol + 1; x <= Rcol - 1; x++) {
584 charN = (Trow * nCols) + x;
585 chars[charN] = ACS_HLINE;
586 attrs[charN] = rend;
587 }
588 charN = (Trow * nCols) + Rcol;
589 chars[charN] = ACS_URCORNER;
590 attrs[charN] = rend;
591 for (y = Trow + 1; y <= Brow - 1; y++) {
592 charN = (y * nCols) + Rcol;
593 chars[charN] = ACS_VLINE;
594 attrs[charN] = rend;
595 }
596 charN = (Brow * nCols) + Rcol;
597 chars[charN] = ACS_LRCORNER;
598 attrs[charN] = rend;
599 for (x = Rcol - 1; x >= Lcol + 1; x--) {
600 charN = (Brow * nCols) + x;
601 chars[charN] = ACS_HLINE;
602 attrs[charN] = rend;
603 }
604 charN = (Brow * nCols) + Lcol;
605 chars[charN] = ACS_LLCORNER;
606 attrs[charN] = rend;
607 for (y = Brow - 1; y >= Trow + 1; y--) {
608 charN = (y * nCols) + Lcol;
609 chars[charN] = ACS_VLINE;
610 attrs[charN] = rend;
611 }
612 if (!RefreshWINDs(UPDATE_)) return FALSE;
613 return TRUE;
614 #endif
615 }
616
617 /******************************************************************************
618 * end_pasteboard_update.
619 ******************************************************************************/
620
end_pasteboard_update()621 int end_pasteboard_update ()
622 {
623 #if defined(SMGui)
624 if (StatusBad(smg$end_pasteboard_update(&pbid))) return FALSE;
625 return TRUE;
626 #endif
627 #if defined(CURSESui)
628 batchCount = MaxInt (0, batchCount - 1);
629 if (!RefreshWINDs(UPDATE_)) return FALSE;
630 return TRUE;
631 #endif
632 #if defined(COWui)
633 batchCount = MaxInt (0, batchCount - 1);
634 if (!RefreshWINDs(UPDATE_)) return FALSE;
635 return TRUE;
636 #endif
637 }
638
639 /******************************************************************************
640 * erase_display.
641 * This routine erases the BOX specified by the starting and ending character
642 * positions (which is different from what SMG$ERASE_DISPLAY does on a VAX).
643 ******************************************************************************/
644
erase_display(wid,startRow,startCol,endRow,endCol)645 int erase_display (wid, startRow, startCol, endRow, endCol)
646 WINDOWid wid;
647 int startRow;
648 int startCol;
649 int endRow;
650 int endCol;
651 {
652 #if defined(SMGui)
653 long startRowN = startRow + 1;
654 long endRowN = endRow + 1;
655 long startColN = startCol + 1;
656 long nCols = endCol - startCol + 1;
657 long rowN;
658 for (rowN = startRowN; rowN <= endRowN; rowN++)
659 if (StatusBad(smg$erase_chars(&(wid->id),&nCols,
660 &rowN,&startColN))) return FALSE;
661 return TRUE;
662 #endif
663 #if defined(CURSESui)
664 int i, j;
665 wattrset (wid->id, RenditionMapping(NORMAL));
666 for (i = startRow; i <= endRow; i++)
667 for (j = startCol; j <= endCol; j++) mvwaddch (wid->id, i, j, ' ');
668 if (!RefreshWINDs(UPDATE_)) return FALSE;
669 return TRUE;
670 #endif
671 #if defined(COWui)
672 int i, j, charN;
673 char rend = RenditionMapping (NORMAL);
674 char *chars = wid->id->chars,
675 *attrs = wid->id->attrs;
676 short nCols = wid->id->nCols;
677 for (i = startRow; i <= endRow; i++)
678 for (j = startCol; j <= endCol; j++) {
679 charN = (i * nCols) + j;
680 chars[charN] = ' ';
681 attrs[charN] = rend;
682 }
683 if (!RefreshWINDs(UPDATE_)) return FALSE;
684 return TRUE;
685 #endif
686 }
687
688 /******************************************************************************
689 * input_field.
690 * The caller must turn the cursor on/off before calling this routine.
691 * This is only used by CDFlist and CDFwalk (ie. expendable).
692 ******************************************************************************/
693
input_field(wid,field,fieldRow,fieldCol,fieldLen,exitKeys,exitKey,toggleInsertModeKey,moveToSOLkey,moveToEOLkey,deleteToSOLkey,deleteToEOLkey,refreshKey)694 int input_field (wid, field, fieldRow, fieldCol, fieldLen, exitKeys, exitKey,
695 toggleInsertModeKey, moveToSOLkey, moveToEOLkey,
696 deleteToSOLkey, deleteToEOLkey, refreshKey)
697 WINDOWid wid;
698 char *field; /* The field may contain an initial value. */
699 int fieldRow;
700 int fieldCol;
701 int fieldLen; /* Maximum length of field. */
702 int *exitKeys; /* Keys which cause input field to be
703 exited (NUL-terminated). */
704 int *exitKey; /* Key which actually caused exit. */
705 int toggleInsertModeKey; /* Key causing insert mode to be toggled
706 (between insert and overstrike). */
707 int moveToSOLkey; /* Key causing cursor to move to the start
708 of the field. */
709 int moveToEOLkey; /* Key causing cursor to move to the end of
710 the field. */
711 int deleteToSOLkey; /* Key causing the characters in front of
712 the cursor to be deleted (and then the
713 cursor/remaining characters are moved up. */
714 int deleteToEOLkey; /* Key causing the characters starting at the
715 cursor to be deleted. */
716 int refreshKey; /* Key causing the screen to be refreshed. */
717 {
718 int curLen = (int) strlen(field);
719 int insertMode = FALSE; /* Initially in insert mode. */
720 int firstCol = fieldCol;
721 int lastCol = fieldCol + fieldLen - 1;
722 int curChar, colN, key, i;
723 /****************************************************************************
724 * Write current field contents and position cursor.
725 ****************************************************************************/
726 if (!put_chars(wid,field,curLen,
727 fieldRow,fieldCol,FALSE,NORMAL)) return FALSE;
728 for (colN = firstCol + curLen; colN <= lastCol; colN++)
729 if (!put_chars(wid," ",1,fieldRow,colN,FALSE,NORMAL)) return FALSE;
730 curChar = 0;
731 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
732 /****************************************************************************
733 * Read keystrokes until return/exit.
734 ****************************************************************************/
735 for (;;) {
736 if (!read_input(
737 #if defined(CURSESui)
738 wid,
739 #endif
740 &key,PASSTHRUri,TRUE)) return FALSE;
741 /*************************************************************************
742 * Check for an exit key.
743 *************************************************************************/
744 for (i = 0; exitKeys[i] != NUL; i++)
745 if (key == exitKeys[i]) {
746 *exitKey = key;
747 return TRUE;
748 }
749 /*************************************************************************
750 * Left arrow key.
751 *************************************************************************/
752 if (key == KB_LEFTARROW) {
753 if (curChar > 0) {
754 curChar--;
755 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
756 }
757 else
758 ring_bell ();
759 continue;
760 }
761 /*************************************************************************
762 * Right arrow key.
763 *************************************************************************/
764 if (key == KB_RIGHTARROW) {
765 if (curChar < curLen && curChar < fieldLen - 1) {
766 curChar++;
767 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
768 }
769 else
770 ring_bell ();
771 continue;
772 }
773 /*************************************************************************
774 * Delete key.
775 *************************************************************************/
776 if (key == KB_DELETE) {
777 if (curChar > 0) {
778 int charsToEnd = curLen - curChar;
779 memmove (&field[curChar-1], &field[curChar], charsToEnd + 1);
780 curLen--;
781 curChar--;
782 if (charsToEnd > 0)
783 if (!put_chars(wid,&field[curChar],charsToEnd,fieldRow,
784 firstCol+curChar,FALSE,NORMAL)) return FALSE;
785 if (!put_chars(wid," ",1,fieldRow,
786 firstCol+curLen,FALSE,NORMAL)) return FALSE;
787 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
788 }
789 else
790 ring_bell ();
791 continue;
792 }
793 /*************************************************************************
794 * Move to start-of-line (SOL) key.
795 *************************************************************************/
796 if (key == moveToSOLkey) {
797 if (curChar > 0) {
798 curChar = 0;
799 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
800 }
801 else
802 ring_bell ();
803 continue;
804 }
805 /*************************************************************************
806 * Move to end-of-line (EOL) key.
807 *************************************************************************/
808 if (key == moveToEOLkey) {
809 if (curLen < fieldLen && curChar < curLen) {
810 curChar = curLen;
811 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
812 continue;
813 }
814 if (curLen == fieldLen && curChar < curLen - 1) {
815 curChar = curLen - 1;
816 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
817 continue;
818 }
819 ring_bell ();
820 continue;
821 }
822 /*************************************************************************
823 * Delete to start-of-line (SOL) key.
824 *************************************************************************/
825 if (key == deleteToSOLkey) {
826 if (curChar > 0) {
827 int charsToEnd = curLen - curChar;
828 int charsToStart = curChar + 1;
829 int colN, i;
830 memmove (field, &field[curChar], charsToEnd + 1);
831 curLen = charsToEnd;
832 curChar = 0;
833 if (!put_chars(wid,field,curLen,
834 fieldRow,firstCol,FALSE,NORMAL)) return FALSE;
835 for (colN = firstCol+curLen, i = 0; i < charsToStart-1; colN++, i++)
836 if (!put_chars(wid," ",1,fieldRow,colN,FALSE,NORMAL)) return FALSE;
837 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
838 }
839 else
840 ring_bell ();
841 continue;
842 }
843 /*************************************************************************
844 * Delete to end-of-line (EOL) key.
845 *************************************************************************/
846 if (key == deleteToEOLkey) {
847 if (curChar < curLen) {
848 int charsToEnd = curLen - curChar;
849 int colN, i;
850 field[curChar] = NUL;
851 curLen = curChar;
852 for (colN = firstCol+curChar, i = 0; i < charsToEnd; colN++, i++)
853 if (!put_chars(wid," ",1,fieldRow,colN,FALSE,NORMAL)) return FALSE;
854 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
855 }
856 else
857 ring_bell ();
858 continue;
859 }
860 /*************************************************************************
861 * Toggle insert mode key.
862 *************************************************************************/
863 if (key == toggleInsertModeKey) {
864 insertMode = (insertMode ? FALSE : TRUE);
865 continue;
866 }
867 /*************************************************************************
868 * Refresh key.
869 *************************************************************************/
870 if (key == refreshKey) {
871 repaint_screen ();
872 continue;
873 }
874 /*************************************************************************
875 * All the other keys (ignored if not printable).
876 *************************************************************************/
877 if (Printable(key)) {
878 if (insertMode) {
879 if (curLen < fieldLen) {
880 int charsToEnd = curLen - curChar;
881 memmove (&field[curChar+1], &field[curChar], charsToEnd + 1);
882 field[curChar] = key;
883 curLen++;
884 if (!put_chars(wid,&field[curChar],charsToEnd+1,fieldRow,
885 firstCol+curChar,FALSE,NORMAL)) return FALSE;
886 if (curChar < fieldLen - 1) curChar++;
887 }
888 else
889 ring_bell ();
890 }
891 else {
892 field[curChar] = key;
893 if (curChar == curLen) {
894 curLen++;
895 field[curLen] = NUL;
896 }
897 if (!put_chars(wid,&field[curChar],1,fieldRow,
898 firstCol+curChar,FALSE,NORMAL)) return FALSE;
899 if (curChar < fieldLen - 1) curChar++;
900 }
901 if (!set_cursor_abs(wid,fieldRow,firstCol+curChar)) return FALSE;
902 }
903 else
904 ring_bell ();
905 }
906 }
907
908 /******************************************************************************
909 * inq_cursor_mode.
910 ******************************************************************************/
911
inq_cursor_mode(cursorMode)912 int inq_cursor_mode (cursorMode)
913 int *cursorMode;
914 {
915 *cursorMode = (cursorOn ? CURSORon : CURSORoff);
916 return TRUE;
917 }
918
919 /******************************************************************************
920 * label_border.
921 ******************************************************************************/
922
label_border(wid,label,rendition)923 int label_border(wid, label, rendition)
924 WINDOWid wid;
925 char *label;
926 int rendition;
927 {
928 #if defined(SMGui)
929 int len = (int) strlen(label);
930 static struct dsc$descriptor_s descr = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL};
931 uLong position = SMG$K_TOP;
932 uLong rend = RenditionMapping(rendition);
933 int nRows, nCols;
934 long startRow = 1;
935 long startCol;
936 WindowSize (wid->id, &nRows, &nCols);
937 if (!wid->bordered) return FALSE;
938 if (len > nCols - 2) return FALSE;
939 startCol = (nCols - len) / 2 + 1;
940 descr.dsc$w_length = len;
941 descr.dsc$a_pointer = label;
942 if (StatusBad(smg$put_chars(&(wid->id),&descr,&startRow,&startCol,
943 NULL,&rend,NULL,NULL))) return FALSE;
944 return TRUE;
945 #endif
946 #if defined(CURSESui)
947 int len = (int) strlen (label);
948 int nRows, nCols, i, startCol;
949 WindowSize (wid->id, &nRows, &nCols);
950 if (!wid->bordered) return FALSE;
951 if (len > nCols - 2) return FALSE;
952 wattrset (wid->id, RenditionMapping(rendition));
953 startCol = (nCols - len) / 2;
954 for (i = 0; i < len; i++) mvwaddch (wid->id, 0, startCol + i, label[i]);
955 if (!RefreshWINDs(UPDATE_)) return FALSE;
956 return TRUE;
957 #endif
958 #if defined(COWui)
959 int len = (int) strlen (label);
960 int nCols = wid->id->nCols;
961 char rend = RenditionMapping (rendition);
962 char *chars = wid->id->chars,
963 *attrs = wid->id->attrs;
964 int i, startCol;
965 if (!wid->bordered) return FALSE;
966 if (len > nCols - 2) return FALSE;
967 startCol = (nCols - len) / 2;
968 for (i = 0; i < len; i++) {
969 chars[startCol+i] = label[i];
970 attrs[startCol+i] = rend;
971 }
972 if (!RefreshWINDs(UPDATE_)) return FALSE;
973 return TRUE;
974 #endif
975 }
976
977 /******************************************************************************
978 * paste_virtual_display.
979 * It is illegal to paste a virtual display that is already pasted (use
980 * `repaste_virtual_display'). It is also illegal to paste a virtual display
981 * that is being batched.
982 ******************************************************************************/
983
paste_virtual_display(wid,row,col)984 int paste_virtual_display (wid, row, col)
985 WINDOWid wid;
986 int row;
987 int col;
988 {
989 #if defined(SMGui)
990 long rowN = row + 1;
991 long colN = col + 1;
992 if (wid->pasted) return FALSE;
993 if (StatusBad(smg$paste_virtual_display(&(wid->id),&pbid,
994 &rowN,&colN,NULL))) return FALSE;
995 wid->pasted = TRUE;
996 if (!MoveWINDtoEnd(wid)) return FALSE;
997 return TRUE;
998 #endif
999 #if defined(CURSESui)
1000 if (wid->pasted) return FALSE;
1001 mvwin (wid->id, row, col);
1002 wid->pasted = TRUE;
1003 if (!MoveWINDtoEnd(wid)) return FALSE;
1004 if (!RefreshWINDs(UPDATE_)) return FALSE;
1005 return TRUE;
1006 #endif
1007 #if defined(COWui)
1008 if (wid->pasted) return FALSE;
1009 wid->id->atRowN = row;
1010 wid->id->atColN = col;
1011 wid->pasted = TRUE;
1012 if (!MoveWINDtoEnd(wid)) return FALSE;
1013 if (!RefreshWINDs(UPDATE_)) return FALSE;
1014 return TRUE;
1015 #endif
1016 }
1017
1018 /******************************************************************************
1019 * put_chars.
1020 ******************************************************************************/
1021
put_chars(wid,string,len,row,col,eraseMode,rendition)1022 int put_chars (wid, string, len, row, col, eraseMode, rendition)
1023 WINDOWid wid;
1024 char *string;
1025 int len;
1026 int row;
1027 int col;
1028 int eraseMode;
1029 int rendition;
1030 {
1031 #if defined(SMGui)
1032 static struct dsc$descriptor_s descr = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL};
1033 uLong rend = RenditionMapping (rendition);
1034 long rowN = row + 1;
1035 long colN = col + 1;
1036 if (eraseMode == ERASE) {
1037 int nRows, nCols;
1038 long nChars, startCol;
1039 WindowSize (wid->id, &nRows, &nCols);
1040 nChars = (wid->bordered ? nCols - 2 : nCols);
1041 startCol = (wid->bordered ? 2 : 1);
1042 if (StatusBad(smg$erase_chars(&(wid->id),&nChars,
1043 &rowN,&startCol))) return FALSE;
1044 }
1045 descr.dsc$w_length = len;
1046 descr.dsc$a_pointer = string;
1047 if (StatusBad(smg$put_chars(&(wid->id),&descr,&rowN,
1048 &colN,NULL,&rend,NULL,NULL))) return FALSE;
1049 return TRUE;
1050 #endif
1051 #if defined(CURSESui)
1052 int nRows, nCols, colN, i;
1053 WindowSize (wid->id, &nRows, &nCols);
1054 if (eraseMode == ERASE) {
1055 wattrset (wid->id, RenditionMapping(NORMAL));
1056 for (colN = 1; colN <= nCols - 2; colN++) mvwaddch (wid->id,row,colN,' ');
1057 }
1058 wattrset (wid->id, RenditionMapping(rendition));
1059 for (i = 0; i < len; i++) mvwaddch (wid->id, row, col + i, string[i]);
1060 if (!RefreshWINDs(UPDATE_)) return FALSE;
1061 return TRUE;
1062 #endif
1063 #if defined(COWui)
1064 short nCols = wid->id->nCols;
1065 char rend;
1066 char *chars = wid->id->chars;
1067 char *attrs = wid->id->attrs;
1068 int colN, i, charN;
1069 if (eraseMode == ERASE) {
1070 rend = RenditionMapping (NORMAL);
1071 for (colN = 1; colN <= nCols - 2; colN++) {
1072 charN = (row * nCols) + colN;
1073 chars[charN] = ' ';
1074 attrs[charN] = rend;
1075 }
1076 }
1077 rend = RenditionMapping (rendition);
1078 for (i = 0; i < len; i++) {
1079 charN = (row * nCols) + (col + i);
1080 chars[charN] = string[i];
1081 attrs[charN] = rend;
1082 }
1083 if (!RefreshWINDs(UPDATE_)) return FALSE;
1084 return TRUE;
1085 #endif
1086 }
1087
1088 /******************************************************************************
1089 * read_display.
1090 * Use only by CDFlist and CDFwalk (ie. expendable).
1091 ******************************************************************************/
1092
read_display(wid,row,string)1093 int read_display (wid, row, string)
1094 WINDOWid wid;
1095 int row;
1096 char *string;
1097 {
1098 #if defined(SMGui)
1099 static struct dsc$descriptor_s descr = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL};
1100 int nRows, nCols; long rowN = row + 1; char *stringT;
1101 WindowSize (wid->id, &nRows, &nCols);
1102 stringT = (char *) cdf_AllocateMemory (nCols, FatalError);
1103 descr.dsc$w_length = nCols;
1104 descr.dsc$a_pointer = stringT;
1105 if (StatusBad(smg$read_from_display(&(wid->id),&descr,NULL,&rowN))) {
1106 cdf_FreeMemory (stringT, FatalError);
1107 return FALSE;
1108 }
1109 if (wid->bordered) {
1110 memmove (string, &stringT[1], nCols-2);
1111 string[nCols-2] = NUL;
1112 }
1113 else {
1114 memmove (string, stringT, nCols);
1115 string[nCols] = NUL;
1116 }
1117 cdf_FreeMemory (stringT, FatalError);
1118 return TRUE;
1119 #endif
1120 #if defined(CURSESui)
1121 int colN, charN, nRows, nCols, nChars, startCol;
1122 WindowSize (wid->id, &nRows, &nCols);
1123 nChars = (wid->bordered ? nCols - 2 : nCols);
1124 startCol = (wid->bordered ? 1 : 0);
1125 for (colN = startCol, charN = 0; charN < nChars; colN++, charN++)
1126 string[charN] = (char) mvwinch (wid->id, row, colN);
1127 string[nChars] = NUL;
1128 return TRUE;
1129 #endif
1130 #if defined(COWui)
1131 int charN, i;
1132 int nCols = wid->id->nCols;
1133 int nChars = (wid->bordered ? nCols - 2 : nCols);
1134 int startCol = (wid->bordered ? 1 : 0);
1135 char *chars = wid->id->chars;
1136 for (i = 0; i < nChars; i++) {
1137 charN = (row * nCols) + (startCol + i);
1138 string[i] = chars[charN];
1139 }
1140 string[nChars] = NUL;
1141 return TRUE;
1142 #endif
1143 }
1144
1145 /******************************************************************************
1146 * read_input.
1147 *
1148 * TRUE is returned if a key was read. FALSE is returned if blocking is
1149 * disabled and a key is not available or if an error occurred.
1150 *
1151 * The `wid' parameter is only used on CURSES-based systems. This is because
1152 * `getch' on POSIXshell systems (VAX and DEC Alpha) would move the cursor to
1153 * `0,0' (which isn't where it should be). `wgetch' is used instead because
1154 * the cursor will be positioned in the proper place in the window. If
1155 * `wgetch' (on POSIXshell systems) moves the cursor at least it will move to
1156 * the right place (which is probably where it already is) and not to `0,0'.
1157 ******************************************************************************/
1158
read_input(wid,tcode,mode,block)1159 int read_input (
1160 #if defined(CURSESui)
1161 wid,
1162 #endif
1163 tcode, mode, block)
1164 #if defined(CURSESui)
1165 WINDOWid wid;
1166 #endif
1167 int *tcode; /* Out: key entered. */
1168 int mode; /* Case conversion mode. */
1169 Logical block; /* Block until key available? */
1170 {
1171 #if defined(SMGui)
1172 /****************************************************************************
1173 * SMG.
1174 ****************************************************************************/
1175 uShort terminator_code;
1176 if (!block) {
1177 if (keyWaiting == 0) return FALSE;
1178 }
1179 if (StatusBad(smg$read_keystroke(&kbid,&terminator_code,
1180 NULL,NULL,NULL,NULL,NULL))) return FALSE;
1181 *tcode = terminator_code;
1182 if (keyWaiting > 0) keyWaiting--;
1183 if (ABORTkey(*tcode)) {
1184 set_cursor_mode (CURSORon);
1185 delete_pasteboard (ERASE);
1186 cdf_FreeMemory (NULL, FatalError);
1187 Exit;
1188 }
1189 switch (mode) {
1190 case PASSTHRUri: break;
1191 case TOUPPERri: *tcode = MakeUpper (*tcode); break;
1192 case TOLOWERri: *tcode = MakeLower (*tcode); break;
1193 }
1194 return TRUE;
1195 #endif
1196 /****************************************************************************
1197 * Curses.
1198 ****************************************************************************/
1199 #if defined(CURSESui)
1200 if (!block) {
1201 #if defined(unix)
1202 fd_set rset;
1203 static struct timeval tv = { 0L, 0L };
1204 FD_ZERO (&rset);
1205 FD_SET (STDIN_FILENO, &rset);
1206 if (select(STDIN_FILENO+1,
1207 #if defined(hpux)
1208 (int *) /* HP-UX has this as an `int *'. */
1209 #endif
1210 &rset,NULL,NULL,&tv) == 0) return FALSE;
1211 #endif
1212 #if defined(dos)
1213 if (!kbhit()) return FALSE;
1214 #endif
1215 }
1216 *tcode = wgetch (wid->id);
1217 if (ABORTkey(*tcode)) {
1218 set_cursor_mode (CURSORon);
1219 delete_pasteboard (ERASE);
1220 cdf_FreeMemory (NULL, FatalError);
1221 Exit;
1222 }
1223 switch (*tcode) {
1224 #if defined(sgi)
1225 case SGI_CONSOLE_RETURN: *tcode = KB_RETURN; break;
1226 #endif
1227 #if defined(posixSHELL)
1228 case POSIX_SHELL_DELETE: *tcode = KB_DELETE; break;
1229 #endif
1230 #if defined(hpux)
1231 case HPUX_DELETE: *tcode = KB_DELETE; break;
1232 #endif
1233 #if defined(AIX)
1234 case AIX_RETURN: *tcode = KB_RETURN; break;
1235 case AIX_DELETE: *tcode = KB_DELETE; break;
1236 #endif
1237 #if defined(__CYGWIN__)
1238 case CYGWIN_DELETE: *tcode = KB_DELETE; break;
1239 #endif
1240 #if defined(__MINGW32__)
1241 case MINGW32_DELETE: *tcode = KB_DELETE; break;
1242 #endif
1243 default: break;
1244 }
1245 switch (mode) {
1246 case PASSTHRUri: break;
1247 case TOUPPERri: *tcode = MakeUpper (*tcode); break;
1248 case TOLOWERri: *tcode = MakeLower (*tcode); break;
1249 }
1250 #if INTERPRET_ESC_SEQUENCES
1251 if (*tcode == ESC) {
1252 int key1 = wgetch (wid->id);
1253 int key2 = wgetch (wid->id);
1254 switch (key1) {
1255 case 'O':
1256 switch (key2) {
1257 case 'A': *tcode = KEY_UP; break;
1258 case 'B': *tcode = KEY_DOWN; break;
1259 case 'C': *tcode = KEY_RIGHT; break;
1260 case 'D': *tcode = KEY_LEFT; break;
1261 default: break;
1262 }
1263 break;
1264 default:
1265 break;
1266 }
1267 }
1268 #endif
1269 return TRUE;
1270 #endif
1271 /****************************************************************************
1272 * COW.
1273 ****************************************************************************/
1274 #if defined(COWui)
1275 #if defined(win32)
1276 MSG msg;
1277 for (;;) {
1278 if (!PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
1279 if (block) continue;
1280 return FALSE;
1281 }
1282 if (msg.message == WM_KEYDOWN) {
1283 int scanCode = (msg.lParam & 0x00FF0000) >> 16;
1284 switch (scanCode) {
1285 case 0x4B:
1286 *tcode = KB_LEFTARROW;
1287 return TRUE;
1288 case 0x4D:
1289 *tcode = KB_RIGHTARROW;
1290 return TRUE;
1291 case 0x48:
1292 *tcode = KB_UPARROW;
1293 return TRUE;
1294 case 0x50:
1295 *tcode = KB_DOWNARROW;
1296 return TRUE;
1297 }
1298 }
1299 if (msg.message == WM_CHAR) {
1300 *tcode = (int) msg.wParam;
1301 switch (mode) {
1302 case PASSTHRUri: break;
1303 case TOUPPERri: *tcode = MakeUpper (*tcode); break;
1304 case TOLOWERri: *tcode = MakeLower (*tcode); break;
1305 }
1306 return TRUE;
1307 }
1308 if (!TranslateMessage(&msg)) DispatchMessage (&msg);
1309 }
1310 #endif
1311 #if defined(mac)
1312 EventRecord event;
1313 for (;;) {
1314 SystemTask ();
1315 GetNextEvent(everyEvent,&event);
1316 switch (event.what) {
1317 /*********************************************************************
1318 * Null event.
1319 *********************************************************************/
1320 case nullEvent: {
1321 WindowPtr whichWindow;
1322 switch (FindWindow(event.where,&whichWindow)) {
1323 case inContent:
1324 SetCursor (CDF_CURSOR);
1325 break;
1326 default:
1327 SetCursor (ARROW_CURSOR);
1328 break;
1329 }
1330 break;
1331 }
1332 /*********************************************************************
1333 * Mouse down event.
1334 *********************************************************************/
1335 case mouseDown: {
1336 WindowPtr whichWindow;
1337 switch (FindWindow(event.where,&whichWindow)) {
1338 case inMenuBar: {
1339 long tempL = MenuSelect (event.where);
1340 short menuId = HighSHORTinLONG (tempL);
1341 short itemN = LowSHORTinLONG (tempL);
1342 switch (menuId) {
1343 case APPLEmi:
1344 switch (itemN) {
1345 case ABOUTin:
1346 DisplayAbout ();
1347 break;
1348 default: {
1349 Str255 name;
1350 GetItem (appleMenuHfsi, itemN, name);
1351 OpenDeskAcc (name);
1352 SetPort (fsiWindowP);
1353 break;
1354 }
1355 }
1356 break;
1357 }
1358 HiliteMenu (0);
1359 break;
1360 }
1361 case inDrag: {
1362 RectPtr screen = &qd.screenBits.bounds; Rect dRect;
1363 dRect.top = screen->top + 40;
1364 dRect.left = screen->left + 40;
1365 dRect.bottom = screen->bottom - 40;
1366 dRect.right = screen->right - 40;
1367 DragWindow (whichWindow, event.where, &dRect);
1368 break;
1369 }
1370 case inSysWindow:
1371 SystemClick (&event, whichWindow);
1372 break;
1373 }
1374 break;
1375 }
1376 /*********************************************************************
1377 * Key down event.
1378 *********************************************************************/
1379 case keyDown:
1380 case autoKey: {
1381 *tcode = (int) (event.message & charCodeMask);
1382 if (ABORTkeyMAC(event)) {
1383 delete_pasteboard (ERASE);
1384 cdf_FreeMemory (NULL, FatalError);
1385 Exit;
1386 }
1387 /*******************************************************************
1388 * If the command key was held down, convert the character to the
1389 * corresponding control character.
1390 *******************************************************************/
1391 if ((event.modifiers & cmdKey) != 0 &&
1392 'a' <= *tcode && *tcode <= 'z') *tcode = *tcode & 0x1F;
1393 /*******************************************************************
1394 * Convert to uppercase/lowercase if requested.
1395 *******************************************************************/
1396 switch (mode) {
1397 case PASSTHRUri: break;
1398 case TOUPPERri: *tcode = MakeUpper (*tcode); break;
1399 case TOLOWERri: *tcode = MakeLower (*tcode); break;
1400 }
1401 return TRUE;
1402 }
1403 /*********************************************************************
1404 * Active event.
1405 *********************************************************************/
1406 case activateEvt:
1407 if ((event.modifiers & activeFlag) != 0) { /* Activate. */
1408 SetCursor (CDF_CURSOR);
1409 }
1410 else { /* Deactivate. */
1411 /* Nothing to be done. */
1412 }
1413 break;
1414 /*********************************************************************
1415 * Update event.
1416 *********************************************************************/
1417 case updateEvt:
1418 BeginUpdate ((WindowPtr) event.message);
1419 if (!RefreshWINDs(SOFT_)) return FALSE;
1420 EndUpdate ((WindowPtr) event.message);
1421 break;
1422 }
1423 if (!block) return FALSE;
1424 }
1425 #endif
1426 #endif
1427 }
1428
1429 /******************************************************************************
1430 * repaint_screen.
1431 ******************************************************************************/
1432
repaint_screen()1433 int repaint_screen () {
1434 #if defined(SMGui)
1435 if (StatusBad(smg$repaint_screen(&pbid))) return FALSE;
1436 return TRUE;
1437 #endif
1438 #if defined(CURSESui)
1439 #if defined(posixSHELL)
1440 wrefresh (stdscr);
1441 #else
1442 wrefresh (curscr);
1443 #endif
1444 return TRUE;
1445 #endif
1446 #if defined(COWui)
1447 if (!RefreshWINDs(HARD_)) return FALSE;
1448 return TRUE;
1449 #endif
1450 }
1451
1452 /******************************************************************************
1453 * repaste_virtual_display.
1454 ******************************************************************************/
1455
repaste_virtual_display(wid,row,col)1456 int repaste_virtual_display (wid, row, col)
1457 WINDOWid wid;
1458 int row;
1459 int col;
1460 {
1461 #if defined(SMGui)
1462 long rowN = row + 1;
1463 long colN = col + 1;
1464 if (StatusBad(smg$repaste_virtual_display(&(wid->id),&pbid,
1465 &rowN,&colN,NULL))) return FALSE;
1466 if (!MoveWINDtoEnd(wid)) return FALSE;
1467 return TRUE;
1468 #endif
1469 #if defined(CURSESui)
1470 if (!wid->pasted) return FALSE;
1471 mvwin (wid->id, row, col);
1472 if (!MoveWINDtoEnd(wid)) return FALSE;
1473 if (!RefreshWINDs(UPDATE_)) return FALSE;
1474 return TRUE;
1475 #endif
1476 #if defined(COWui)
1477 if (!wid->pasted) return FALSE;
1478 wid->id->atRowN = row;
1479 wid->id->atColN = col;
1480 if (!MoveWINDtoEnd(wid)) return FALSE;
1481 if (!RefreshWINDs(UPDATE_)) return FALSE;
1482 return TRUE;
1483 #endif
1484 }
1485
1486 /******************************************************************************
1487 * ring_bell.
1488 ******************************************************************************/
1489
ring_bell()1490 int ring_bell () {
1491 #if defined(SMGui)
1492 long nRows = 1;
1493 long nCols = 1;
1494 long rowN = 1;
1495 long colN = 1;
1496 long cursorRow, cursorCol;
1497 LocalId id, cursorId;
1498 if (StatusBad(smg$find_cursor_display(&pbid,&cursorId,
1499 NULL,NULL))) return FALSE;
1500 if (cursorId != 0) cursorRow = smg$cursor_row (&cursorId);
1501 if (cursorId != 0) cursorCol = smg$cursor_column (&cursorId);
1502 if (StatusBad(smg$begin_pasteboard_update(&pbid))) return FALSE;
1503 if (StatusBad(smg$create_virtual_display(&nRows,&nCols,&id,
1504 NULL,NULL,NULL))) return FALSE;
1505 if (StatusBad(smg$paste_virtual_display(&id,&pbid,
1506 &rowN,&colN,NULL))) return FALSE;
1507 if (StatusBad(smg$ring_bell(&id))) return FALSE;
1508 if (StatusBad(smg$delete_virtual_display(&id))) return FALSE;
1509 if (StatusBad(smg$end_pasteboard_update(&pbid))) return FALSE;
1510 if (cursorId != 0)
1511 if (StatusBad(smg$set_cursor_abs(&cursorId,
1512 &cursorRow,
1513 &cursorCol))) return FALSE;
1514 return TRUE;
1515 #endif
1516 #if defined(CURSESui)
1517 beep ();
1518 return TRUE;
1519 #endif
1520 #if defined(COWui)
1521 #if defined(win32)
1522 Beep ((DWORD) 800, (DWORD) 150);
1523 #endif
1524 #if defined(mac)
1525 short ticks = 1;
1526 SysBeep (ticks);
1527 #endif
1528 return TRUE;
1529 #endif
1530 }
1531
1532 /******************************************************************************
1533 * set_cursor_abs.
1534 *
1535 * CURSES:
1536 * After setting the cursor position in the specified window, only refresh that
1537 * window. Refreshing all windows (using `RefreshWINDs') will put the physical
1538 * screen cursor where the `top' window's virtual cursor is.
1539 ******************************************************************************/
1540
set_cursor_abs(wid,row,col)1541 int set_cursor_abs (wid, row, col)
1542 WINDOWid wid;
1543 int row;
1544 int col;
1545 {
1546 #if defined(SMGui)
1547 long rowN = row + 1;
1548 long colN = col + 1;
1549 if (StatusBad(smg$set_cursor_abs(&(wid->id),&rowN,&colN))) return FALSE;
1550 return TRUE;
1551 #endif
1552 #if defined(CURSESui)
1553 wmove (wid->id, row, col);
1554 wrefresh (wid->id);
1555 return TRUE;
1556 #endif
1557 #if defined(COWui)
1558 /****************************************************************************
1559 * Undisplay current cursor (if it exists and is visible).
1560 ****************************************************************************/
1561 if (cursorOn && cursorWIND != NULL && cursorWIND->pasted &&
1562 !CharOccluded(cursorWIND,cursorRow,cursorCol)) {
1563 #if defined(mac)
1564 InvertCursor (cursorWIND, cursorRow, cursorCol);
1565 #endif
1566 #if defined(win32)
1567 SetCursorPosition (-1, -1);
1568 #endif
1569 }
1570 /****************************************************************************
1571 * Set/display new cursor (if it is visible).
1572 ****************************************************************************/
1573 cursorWIND = wid;
1574 cursorRow = row;
1575 cursorCol = col;
1576 if (cursorOn && cursorWIND != NULL && cursorWIND->pasted &&
1577 !CharOccluded(cursorWIND,cursorRow,cursorCol)) {
1578 #if defined(mac)
1579 InvertCursor (cursorWIND, cursorRow, cursorCol);
1580 #endif
1581 #if defined(win32)
1582 SetCursorPosition (cursorWIND->id->atRowN + cursorRow,
1583 cursorWIND->id->atColN + cursorCol);
1584 #endif
1585 }
1586 return TRUE;
1587 #endif
1588 }
1589
1590 /******************************************************************************
1591 * set_cursor_mode.
1592 ******************************************************************************/
1593
set_cursor_mode(cursorMode)1594 int set_cursor_mode (cursorMode)
1595 int cursorMode; /* CURSORon/CURSORoff */
1596 {
1597 #if defined(SMGui)
1598 uLong mode = (cursorMode == CURSORon ? SMG$M_CURSOR_ON :
1599 SMG$M_CURSOR_OFF);
1600 if (StatusBad(smg$set_cursor_mode(&pbid,&mode))) return FALSE;
1601 cursorOn = (cursorMode == CURSORon);
1602 return TRUE;
1603 #endif
1604 #if defined(CURSESui)
1605 #if defined(unix) || defined(posixSHELL)
1606 #if CURS_SETavail
1607 int visibility = (cursorMode == CURSORon ? 1 : 0);
1608 curs_set (visibility);
1609 #endif
1610 cursorOn = (cursorMode == CURSORon);
1611 return TRUE;
1612 #endif
1613 #if defined(dos)
1614 if (cursorMode == CURSORon)
1615 curson ();
1616 else
1617 cursoff ();
1618 cursorOn = (cursorMode == CURSORon);
1619 return TRUE;
1620 #endif
1621 #endif
1622 #if defined(COWui)
1623 /****************************************************************************
1624 * If the new mode is different than the old mode, set the new mode and
1625 * invert the current cursor (if one exists and is visible).
1626 ****************************************************************************/
1627 if (cursorMode != BOO(cursorOn,CURSORon,CURSORoff)) {
1628 cursorOn = (cursorMode == CURSORon);
1629 if (cursorWIND != NULL && cursorWIND->pasted &&
1630 !CharOccluded(cursorWIND,cursorRow,cursorCol)) {
1631 #if defined(mac)
1632 InvertCursor (cursorWIND, cursorRow, cursorCol);
1633 #endif
1634 #if defined(win32)
1635 SetCursorPosition (BOO(cursorOn,cursorWIND->id->atRowN + cursorRow,-1),
1636 BOO(cursorOn,cursorWIND->id->atColN + cursorCol,-1));
1637 #endif
1638 }
1639 }
1640 return TRUE;
1641 #endif
1642 }
1643
1644 /******************************************************************************
1645 * unpaste_virtual_display.
1646 ******************************************************************************/
1647
unpaste_virtual_display(wid)1648 int unpaste_virtual_display (wid)
1649 WINDOWid wid;
1650 {
1651 #if defined(SMGui)
1652 if (StatusBad(smg$unpaste_virtual_display(&(wid->id),&pbid))) return FALSE;
1653 wid->pasted = FALSE;
1654 return TRUE;
1655 #else
1656 # if defined(CURSESui)
1657 LocalId tempId;
1658 int nRows, nCols, row, col;
1659 WindowSize (wid->id, &nRows, &nCols);
1660 WindowLocation (wid->id, &row, &col);
1661 tempId = newwin (nRows, nCols, row, col);
1662 if (tempId == NULL) return FALSE;
1663 wattrset (tempId, RenditionMapping(BLACK));
1664 EraseWindow (tempId);
1665 wnoutrefresh (tempId);
1666 delwin (tempId);
1667 wid->pasted = FALSE;
1668 if (!RefreshWINDs(UPDATE_)) return FALSE;
1669 return TRUE;
1670 # else
1671 # if defined(COWui)
1672 wid->pasted = FALSE;
1673 if (!RefreshWINDs(UPDATE_)) return FALSE;
1674 return TRUE;
1675 # else
1676 return TRUE;
1677 # endif
1678 # endif
1679 #endif
1680 }
1681
1682 /******************************************************************************
1683 * zzzzz.
1684 * Sleep, get it?
1685 ******************************************************************************/
1686
zzzzz(seconds)1687 int zzzzz (seconds)
1688 double seconds;
1689 {
1690 #if defined(SMGui) /* ie. VMS */
1691 #if defined(alphavmsI)
1692 time_t start_time, current_time;
1693 time (&start_time);
1694 time (¤t_time);
1695 while (current_time - start_time < seconds + 1.0) time (¤t_time);
1696 #else
1697 float seconds4 = seconds;
1698 if (StatusBad(lib$wait(&seconds4))) return FALSE;
1699 #endif
1700 return TRUE;
1701 #endif
1702 #if defined(CURSESui)
1703 #if defined(unix)
1704 int ms = (int) seconds;
1705 #if !defined(__QNX__) /* Due to a `ncurses' bug under QNX. */
1706 ms *= 1000;
1707 #endif
1708 napms (ms);
1709 return TRUE;
1710 #endif
1711 #if defined(MICROSOFTC) || defined(posixSHELL)
1712 time_t start_time, current_time;
1713 time (&start_time);
1714 time (¤t_time);
1715 while (current_time - start_time < seconds + 1.0) time (¤t_time);
1716 return TRUE;
1717 #endif
1718 #if defined(BORLANDC)
1719 sleep ((uInt) seconds + 0.5);
1720 return TRUE;
1721 #endif
1722 #endif
1723 #if defined(COWui)
1724 #if defined(win32)
1725 MSG msg;
1726 UINT timerId = SetTimer (NULL, 0, (UINT) (1000 * seconds), NULL);
1727 for (;;) {
1728 GetMessage (&msg, NULL, 0, 0);
1729 if (msg.message == WM_TIMER) {
1730 KillTimer (NULL, timerId);
1731 break;
1732 }
1733 DispatchMessage (&msg);
1734 }
1735 #endif
1736 #if defined(mac)
1737 EventRecord event; long untilTick; short nullEventMask = 0;
1738 EventAvail (nullEventMask, &event);
1739 untilTick = event.when + (long) (seconds * 60);
1740 for (;;) {
1741 EventAvail (nullEventMask, &event);
1742 if (event.when > untilTick) break;
1743 }
1744 #endif
1745 return TRUE;
1746 #endif
1747 }
1748
1749 /******************************************************************************
1750 * AddWIND. Add a WIND to the linked list (at the end).
1751 ******************************************************************************/
1752
AddWIND(id,pasted,bordered)1753 static WINDOWid AddWIND (id, pasted, bordered)
1754 LocalId id;
1755 Logical pasted;
1756 Logical bordered;
1757 {
1758 WINDOWid newWIND, tW;
1759 newWIND = (WINDOWid) cdf_AllocateMemory (sizeof(WIND), FatalError);
1760 if (WINDhead == NULL)
1761 WINDhead = newWIND;
1762 else {
1763 tW = WINDhead;
1764 while (tW->next != NULL) tW = tW->next;
1765 tW->next = newWIND;
1766 }
1767 newWIND->id = id;
1768 newWIND->pasted = pasted;
1769 newWIND->bordered = bordered;
1770 newWIND->next = NULL;
1771 return newWIND;
1772 }
1773
1774 /******************************************************************************
1775 * MoveWINDtoEnd.
1776 * Move a WIND to the end of the linked list. The case where WIND is already
1777 * at the end of the linked list is handled (but not as a special case).
1778 ******************************************************************************/
1779
MoveWINDtoEnd(wid)1780 static Logical MoveWINDtoEnd (wid)
1781 WINDOWid wid;
1782 {
1783 WINDOWid tW = WINDhead;
1784 WINDOWid prevW = NULL;
1785 while (tW != NULL) {
1786 if (tW == wid) {
1787 if (prevW == NULL)
1788 WINDhead = tW->next;
1789 else
1790 prevW->next = tW->next;
1791 if (WINDhead == NULL)
1792 WINDhead = tW;
1793 else {
1794 WINDOWid sW = WINDhead;
1795 while (sW->next != NULL) sW = sW->next;
1796 sW->next = tW;
1797 tW->next = NULL;
1798 }
1799 return TRUE;
1800 }
1801 prevW = tW;
1802 tW = tW->next;
1803 }
1804 return FALSE; /* Wasn't found. */
1805 }
1806
1807 /******************************************************************************
1808 * DeleteWIND. Delete a WIND from the linked list.
1809 ******************************************************************************/
1810
DeleteWIND(wid)1811 static Logical DeleteWIND (wid)
1812 WINDOWid wid;
1813 {
1814 WINDOWid tW = WINDhead;
1815 WINDOWid prevW = NULL;
1816 while (tW != NULL) {
1817 if (tW == wid) {
1818 #if defined(SMGui)
1819 if (StatusBad(smg$delete_virtual_display(&(tW->id)))) return FALSE;
1820 #endif
1821 #if defined(CURSESui)
1822 if (tW->pasted) {
1823 wattrset (tW->id, RenditionMapping(BLACK));
1824 EraseWindow (tW->id);
1825 wnoutrefresh (tW->id);
1826 }
1827 delwin (tW->id);
1828 #endif
1829 #if defined(COWui)
1830 if (tW == cursorWIND) cursorWIND = NULL;
1831 #endif
1832 if (prevW == NULL)
1833 WINDhead = tW->next;
1834 else
1835 prevW->next = tW->next;
1836 #if defined(COWui)
1837 cdf_FreeMemory (tW->id->chars, FatalError);
1838 cdf_FreeMemory (tW->id->attrs, FatalError);
1839 cdf_FreeMemory (tW->id, FatalError);
1840 #endif
1841 cdf_FreeMemory (tW, FatalError);
1842 #if defined(CURSESui) || defined(COWui)
1843 if (!RefreshWINDs(UPDATE_)) return FALSE;
1844 #endif
1845 return TRUE;
1846 }
1847 prevW = tW;
1848 tW = tW->next;
1849 }
1850 return FALSE; /* Wasn't found. */
1851 }
1852
1853 /******************************************************************************
1854 * DeleteWINDs. Delete all of the WINDs.
1855 ******************************************************************************/
1856
DeleteWINDs()1857 static Logical DeleteWINDs () {
1858 while (WINDhead != NULL) {
1859 if (!DeleteWIND(WINDhead)) return FALSE;
1860 }
1861 return TRUE;
1862 }
1863
1864 /******************************************************************************
1865 * RefreshWINDs.
1866 * Refresh all windows (that are pasted). Note that this has no affect if
1867 * updates are being batched (with begin/end_pasteboard_update).
1868 ******************************************************************************/
1869
1870 #if defined(CURSESui)
RefreshWINDs(level)1871 static Logical RefreshWINDs (level)
1872 int level;
1873 {
1874 if (batchCount < 1) {
1875 WINDOWid tW;
1876 switch (level) {
1877 case HARD_:
1878 case SOFT_:
1879 case UPDATE_:
1880 /* Do nothing if CURSES. */
1881 break;
1882 }
1883 tW = WINDhead;
1884 while (tW != NULL) {
1885 if (tW->pasted) {
1886 touchwin (tW->id);
1887 wnoutrefresh (tW->id);
1888 }
1889 tW = tW->next;
1890 }
1891 doupdate ();
1892 }
1893 return TRUE;
1894 }
1895 #endif
1896
1897 #if defined(COWui)
RefreshWINDs(level)1898 static Logical RefreshWINDs (level)
1899 int level;
1900 {
1901 WINDOWid tW;
1902 char *savePtr;
1903 int nChars = NUMfsiROWS * NUMfsiCOLS, rowN, windCharN, pbCharN;
1904 /****************************************************************************
1905 * If updates are being batched, do nothing.
1906 ****************************************************************************/
1907 if (batchCount > 0) return TRUE;
1908 /****************************************************************************
1909 * Check level of refresh.
1910 * Hard: Erases window and force all non-blank/non-normal character
1911 * positions to be redrawn. This will causes the characters in
1912 * the window to "flash" (off then on). In this case the cursor
1913 * does not need to be turned off.
1914 * Soft: Force all character positions to be redrawn. The characters
1915 * should not "flash". In this case the cursor does not need to
1916 * be turned off (it will be overwritten by a character).
1917 * Update: In this case the cursor does need to be turned off if it is
1918 * actually visible (not if it should be visible). This is
1919 * because the operations before this refresh could have occluded
1920 * the cursor.
1921 ****************************************************************************/
1922 switch (level) {
1923 case HARD_: {
1924 int nChars = NUMfsiROWS * NUMfsiCOLS;
1925 #if defined(win32)
1926 /* Jeff...maybe nothing needs to be done. */
1927 #endif
1928 #if defined(mac)
1929 Rect eraseRect = { 0, 0, WINDOWfsiHEIGHT, WINDOWfsiWIDTH };
1930 EraseRect (&eraseRect);
1931 #endif
1932 memmove (pbCurrentChars, pbNullChars, nChars);
1933 memmove (pbCurrentAttrs, pbNormalAttrs, nChars);
1934 break;
1935 }
1936 case SOFT_: {
1937 int nChars = NUMfsiROWS * NUMfsiCOLS;
1938 memmove (pbCurrentChars, pbNullChars, nChars);
1939 memmove (pbCurrentAttrs, pbNormalAttrs, nChars);
1940 break;
1941 }
1942 case UPDATE_:
1943 #if defined(mac)
1944 if (cursorVisible) InvertCursor (cursorWIND, cursorRow, cursorCol);
1945 #endif
1946 #if defined(win32)
1947 SetCursorPosition (-1, -1);
1948 #endif
1949 break;
1950 }
1951 /****************************************************************************
1952 * Reset new characters/attributes...
1953 ****************************************************************************/
1954 memmove (pbNewChars, pbBlankChars, nChars);
1955 memmove (pbNewAttrs, pbNormalAttrs, nChars);
1956 /****************************************************************************
1957 * ...and then generate what the window should look like.
1958 ****************************************************************************/
1959 tW = WINDhead;
1960 while (tW != NULL) {
1961 if (tW->pasted) {
1962 for (rowN = 0; rowN < tW->id->nRows; rowN++) {
1963 windCharN = rowN * tW->id->nCols;
1964 pbCharN = ((tW->id->atRowN + rowN) * NUMfsiCOLS) + tW->id->atColN;
1965 memmove (&pbNewChars[pbCharN], &(tW->id->chars[windCharN]),
1966 tW->id->nCols);
1967 memmove (&pbNewAttrs[pbCharN], &(tW->id->attrs[windCharN]),
1968 tW->id->nCols);
1969 }
1970 }
1971 tW = tW->next;
1972 }
1973 /****************************************************************************
1974 * Redraw the characters/attributes which have changed.
1975 ****************************************************************************/
1976 #if defined(win32)
1977 TransferTextAttrs (pbNewChars, pbNewAttrs);
1978 #endif
1979 #if defined(mac)
1980 for (rowN = 0; rowN < NUMfsiROWS; rowN++) {
1981 rowCharN = rowN * NUMfsiCOLS;
1982 if (memcmp(&pbNewChars[rowCharN],
1983 &pbCurrentChars[rowCharN],NUMfsiCOLS) != 0 ||
1984 memcmp(&pbNewAttrs[rowCharN],
1985 &pbCurrentAttrs[rowCharN],NUMfsiCOLS) != 0) {
1986 startN = rowCharN;
1987 while (pbNewChars[startN] == pbCurrentChars[startN] &&
1988 pbNewAttrs[startN] == pbCurrentAttrs[startN]) startN++;
1989 endN = rowCharN + NUMfsiCOLS - 1;
1990 while (pbNewChars[startN] == pbCurrentChars[startN] &&
1991 pbNewAttrs[startN] == pbCurrentAttrs[startN]) endN--;
1992 for (;;) {
1993 upToN = startN;
1994 thisAttr = pbNewAttrs[startN];
1995 while (upToN+1 <= endN && pbNewAttrs[upToN+1] == thisAttr &&
1996 !LINEdrawingCHAR(pbNewChars[upToN]) &&
1997 !LINEdrawingCHAR(pbNewChars[upToN+1])) upToN++;
1998 if (BITSET(thisAttr,REVERSEbit))
1999 TextMode (notSrcCopy);
2000 else
2001 TextMode (srcCopy);
2002 if (BITSET(thisAttr,BOLDbit))
2003 TextFace (bold);
2004 else
2005 TextFace (0);
2006 /* BLINKINGbit is not yet supported. */
2007 startX = (FONTfsiWIDTH * (startN % NUMfsiCOLS)) + MARGINfsiSIZE;
2008 startY = (FONTfsiHEIGHT * rowN) + MARGINfsiSIZE;
2009 MoveTo (startX, startY);
2010 if (LINEdrawingCHAR(pbNewChars[startN])) {
2011 /******************************************************************
2012 * A line drawing character. First erase the entire character
2013 * cell (including the leading line).
2014 ******************************************************************/
2015 Rect eraseRect;
2016 eraseRect.top = startY;
2017 eraseRect.bottom = startY + FONTfsiHEIGHT;
2018 eraseRect.left = startX;
2019 eraseRect.right = startX + FONTfsiWIDTH;
2020 EraseRect (&eraseRect);
2021 switch (pbNewChars[startN]) {
2022 case ACS_PLUS:
2023 Move (FONTfsiHALFwidth, 0);
2024 Line (0, FONTfsiHEIGHT-1);
2025 Move (-FONTfsiHALFwidth, -(FONTfsiHALFheight-1));
2026 Line (FONTfsiWIDTH-1, 0);
2027 break;
2028 case ACS_TTEE:
2029 Move (0, FONTfsiHALFheight);
2030 Line (FONTfsiWIDTH-1, 0);
2031 Move (-FONTfsiHALFwidth, 0);
2032 Line (0, FONTfsiHALFheight-1);
2033 break;
2034 case ACS_BTEE:
2035 Move (0, FONTfsiHALFheight);
2036 Line (FONTfsiWIDTH-1, 0);
2037 Move (-FONTfsiHALFwidth, 0);
2038 Line (0, -FONTfsiHALFheight);
2039 break;
2040 case ACS_LTEE:
2041 Move (FONTfsiHALFwidth, 0);
2042 Line (0, FONTfsiHEIGHT-1);
2043 Move (0, -(FONTfsiHALFheight-1));
2044 Line (FONTfsiHALFwidth, 0);
2045 break;
2046 case ACS_RTEE:
2047 Move (FONTfsiHALFwidth, 0);
2048 Line (0, FONTfsiHEIGHT-1);
2049 Move (0, -(FONTfsiHALFheight-1));
2050 Line (-FONTfsiHALFwidth, 0);
2051 break;
2052 case ACS_HLINE:
2053 Move (0, FONTfsiHALFheight);
2054 Line (FONTfsiWIDTH-1, 0);
2055 break;
2056 case ACS_VLINE:
2057 Move (FONTfsiHALFwidth, 0);
2058 Line (0, FONTfsiHEIGHT-1);
2059 break;
2060 case ACS_ULCORNER:
2061 Move (FONTfsiHALFwidth, FONTfsiHEIGHT-1);
2062 Line (0, -(FONTfsiHALFheight-1));
2063 Line (FONTfsiHALFwidth, 0);
2064 break;
2065 case ACS_URCORNER:
2066 Move (0, FONTfsiHALFheight);
2067 Line (FONTfsiHALFwidth, 0);
2068 Line (0, FONTfsiHALFheight-1);
2069 break;
2070 case ACS_LRCORNER:
2071 Move (FONTfsiHALFwidth, 0);
2072 Line (0, FONTfsiHALFheight);
2073 Line (-FONTfsiHALFwidth, 0);
2074 break;
2075 case ACS_LLCORNER:
2076 Move (FONTfsiHALFwidth, 0);
2077 Line (0, FONTfsiHALFheight);
2078 Line (FONTfsiHALFwidth, 0);
2079 break;
2080 }
2081 }
2082 else {
2083 /******************************************************************
2084 * Drawing text characters. Since one or more line drawing
2085 * characters (or the cursor) may be written over, erase the
2086 * leading line first (which is used by the line drawing characters
2087 * but not the text characters).
2088 ******************************************************************/
2089 Rect eRect;
2090 short nChars = upToN - startN + 1;
2091 eRect.top = startY + FONTfsiHEIGHT - 1;
2092 eRect.bottom = startY + FONTfsiHEIGHT;
2093 eRect.left = startX;
2094 eRect.right = startX + (nChars * FONTfsiWIDTH);
2095 EraseRect (&eRect);
2096 Move (0, FONTfsiASCENT);
2097 DrawText (&pbNewChars[startN], 0, nChars);
2098 }
2099 if (upToN == endN) break;
2100 startN = upToN + 1;
2101 }
2102 }
2103 }
2104 #endif
2105 /****************************************************************************
2106 * Make the new characters/attributes the current characters/attributes.
2107 ****************************************************************************/
2108 savePtr = pbCurrentChars;
2109 pbCurrentChars = pbNewChars;
2110 pbNewChars = savePtr;
2111 savePtr = pbCurrentAttrs;
2112 pbCurrentAttrs = pbNewAttrs;
2113 pbNewAttrs = savePtr;
2114 /****************************************************************************
2115 * Redisplay cursor (if appropriate).
2116 ****************************************************************************/
2117 if (cursorOn && cursorWIND != NULL && cursorWIND->pasted &&
2118 !CharOccluded(cursorWIND,cursorRow,cursorCol)) {
2119 #if defined(mac)
2120 InvertCursor (cursorWIND, cursorRow, cursorCol);
2121 #endif
2122 #if defined(win32)
2123 SetCursorPosition (cursorWIND->id->atRowN + cursorRow,
2124 cursorWIND->id->atColN + cursorCol);
2125 #endif
2126 }
2127 return TRUE;
2128 }
2129 #endif
2130
2131 /******************************************************************************
2132 * CharOccluded.
2133 ******************************************************************************/
2134
2135 #if defined(COWui)
CharOccluded(wid,rowN,colN)2136 static Logical CharOccluded (wid, rowN, colN)
2137 WINDOWid wid;
2138 int rowN;
2139 int colN;
2140 {
2141 WINDOWid tW = wid->next;
2142 int pbRowN = wid->id->atRowN + rowN,
2143 pbColN = wid->id->atColN + colN;
2144 while (tW != NULL) {
2145 if (tW->pasted &&
2146 tW->id->atRowN <= pbRowN &&
2147 pbRowN <= (tW->id->atRowN + tW->id->nRows - 1) &&
2148 tW->id->atColN <= pbColN &&
2149 pbColN <= (tW->id->atColN + tW->id->nCols - 1)) return TRUE;
2150 tW = tW->next;
2151 }
2152 return FALSE;
2153 }
2154 #endif
2155
2156 /******************************************************************************
2157 * InvertCursor.
2158 * This is used to turn a cursor on or off.
2159 ******************************************************************************/
2160
2161 #if defined(COWui)
2162 #if defined(mac)
InvertCursor(wid,rowN,colN)2163 static void InvertCursor (wid, rowN, colN)
2164 WINDOWid wid;
2165 int rowN;
2166 int colN;
2167 {
2168 Rect iRect;
2169 int startX = (FONTfsiWIDTH * (wid->id->atColN + colN)) + MARGINfsiSIZE,
2170 startY = (FONTfsiHEIGHT * (wid->id->atRowN + rowN)) + MARGINfsiSIZE;
2171 iRect.top = startY;
2172 iRect.bottom = startY + FONTfsiHEIGHT - 1; /* -1 for leading line. */
2173 iRect.left = startX;
2174 iRect.right = startX + FONTfsiWIDTH;
2175 InvertRect (&iRect);
2176 cursorVisible = BOO(cursorVisible,FALSE,TRUE);
2177 return;
2178 }
2179 #endif
2180 #endif
2181
2182 /******************************************************************************
2183 * WindowLocation.
2184 * Passes back row/column at which window is pasted.
2185 ******************************************************************************/
2186
2187 #if defined(CURSESui)
WindowLocation(id,row,col)2188 static void WindowLocation (id, row, col)
2189 LocalId id;
2190 int *row;
2191 int *col;
2192 {
2193 #if defined(unix) || defined(posixSHELL)
2194 #if GETBEGavail
2195 getbegyx (id, *row, *col); /* `getbegyx' is a macro. */
2196 #else
2197 *row = id->_begy;
2198 *col = id->_begx;
2199 #endif
2200 #endif
2201 #if defined(dos)
2202 *row = id->_begy;
2203 *col = id->_begx;
2204 #endif
2205 return;
2206 }
2207 #endif
2208
2209 /******************************************************************************
2210 * WindowSize.
2211 * Passes back number of rows/columns in window.
2212 ******************************************************************************/
2213
2214 #if defined(CURSESui) || defined(SMGui)
WindowSize(id,rows,cols)2215 static void WindowSize (id, rows, cols)
2216 LocalId id;
2217 int *rows;
2218 int *cols;
2219 {
2220 #if defined(SMGui)
2221 long height = -1, width = -1;
2222 smg$get_display_attr (&id, &height, &width, NULL, NULL, NULL, NULL);
2223 *rows = height;
2224 *cols = width;
2225 #endif
2226 #if defined(CURSESui)
2227 #if defined(unix) || defined(posixSHELL)
2228 #if GETMAXavail
2229 getmaxyx (id, *rows, *cols); /* `getmaxyx' is a macro. */
2230 #else
2231 *rows = id->_maxy;
2232 *cols = id->_maxx;
2233 #endif
2234 #endif
2235 #if defined(dos)
2236 *rows = id->_maxy;
2237 *cols = id->_maxx;
2238 #endif
2239 #endif
2240 return;
2241 }
2242 #endif
2243
2244 /******************************************************************************
2245 * RenditionMapping.
2246 * The BLACK rendition is ignored on non-IBM PC machines (it is the same as
2247 * NORMAL). On IBM PCs it overrides all other renditions.
2248 ******************************************************************************/
2249
RenditionMapping(rendition)2250 static int RenditionMapping (rendition)
2251 int rendition;
2252 {
2253 int mapped;
2254 #if defined(SMGui)
2255 mapped = 0;
2256 if ((rendition & BOLD) != 0) mapped = mapped | SMG$M_BOLD;
2257 if ((rendition & REVERSE) != 0 ||
2258 (rendition & REVERSE1) != 0 ||
2259 (rendition & REVERSE2) != 0) mapped = mapped | SMG$M_REVERSE;
2260 if ((rendition & BLINKING) != 0) mapped = mapped | SMG$M_BLINK;
2261 #endif
2262 #if defined(CURSESui)
2263 #if defined(unix) || defined(posixSHELL)
2264 mapped = A_NORMAL;
2265 if ((rendition & BOLD) != 0) mapped = mapped | A_BOLD;
2266 if ((rendition & REVERSE) != 0 ||
2267 (rendition & REVERSE1) != 0 ||
2268 (rendition & REVERSE2) != 0) mapped = mapped | A_REVERSE;
2269 if ((rendition & BLINKING) != 0) mapped = mapped | A_BLINK;
2270 #endif
2271 #if defined(dos)
2272 if ((rendition & BLACK) != 0)
2273 mapped = A_NORMAL | F_BLACK | B_BLACK;
2274 else {
2275 if ((rendition & REVERSE) != 0 ||
2276 (rendition & REVERSE1) != 0 ||
2277 (rendition & REVERSE2) != 0) {
2278 if ((rendition & REVERSE) != 0)
2279 mapped = A_REVERSE | F_GRAY | B_BLUE;
2280 else
2281 if ((rendition & REVERSE1) != 0)
2282 mapped = A_BOLD | F_GRAY | B_RED;
2283 else /*REVERSE2*/
2284 mapped = A_BOLD | F_GRAY | B_CYAN;
2285 }
2286 else
2287 mapped = A_NORMAL | F_GRAY | B_BLUE;
2288 if ((rendition & BOLD) != 0) mapped = mapped | A_BOLD;
2289 if ((rendition & BLINKING) != 0) mapped = mapped | A_BLINK;
2290 }
2291 #endif
2292 #endif
2293 #if defined(COWui)
2294 mapped = 0;
2295 if ((rendition & BOLD) != 0) mapped = mapped | BOLD;
2296 if ((rendition & REVERSE) != 0 ||
2297 (rendition & REVERSE1) != 0 ||
2298 (rendition & REVERSE2) != 0) mapped = mapped | REVERSE;
2299 if ((rendition & BLINKING) != 0) mapped = mapped | BLINKING;
2300 #endif
2301 return mapped;
2302 }
2303
2304 /******************************************************************************
2305 * EraseWindow.
2306 * On DECstations, DEC Alphas running OSF/1, and IBM RS6000s, `werase' doesn't
2307 * work - no idea why not. Also, putting blanks to each position in the window
2308 * doesn't work either. A non-blank character must first be put and then a
2309 * blank. Again I'm baffled. Anyway, this function is used in several places
2310 * to erase the contents of a window.
2311 ******************************************************************************/
2312
2313 #if defined(CURSESui)
EraseWindow(id)2314 static int EraseWindow (id)
2315 LocalId id;
2316 {
2317 #if WERASEworks
2318 werase (id);
2319 #else
2320 int nRows, nCols, rowN, colN;
2321 WindowSize (id, &nRows, &nCols);
2322 for (rowN = 0; rowN < nRows; rowN++) {
2323 for (colN = 0; colN < nCols; colN++) {
2324 mvwaddch (id, rowN, colN, '*');
2325 mvwaddch (id, rowN, colN, ' ');
2326 }
2327 }
2328 #endif
2329 return TRUE;
2330 }
2331 #endif
2332
2333 /******************************************************************************
2334 * MacExecuteFSI.
2335 ******************************************************************************/
2336
2337 #if defined(mac)
2338 void MacExecuteFSI (exeFnc, qopFnc)
2339 Logical (*exeFnc) PROTOARGs((int argC, char *argV[]));
2340 Logical (*qopFnc) PROTOARGs((int *argC, char **argV[]));
2341 {
2342 int argC;
2343 char **argV;
2344 InitMacUI ();
2345 InitMacMenusFSI ();
2346 InitMacFSI ();
2347 for (;;) {
2348 if ((*qopFnc)(&argC,&argV)) {
2349 (*exeFnc) (argC, argV);
2350 FreeMacQOPs (argC, argV);
2351 }
2352 else
2353 return;
2354 }
2355 }
2356 #endif
2357
2358 /******************************************************************************
2359 * InitMacMenusFSI.
2360 * Initialize the Macintosh menus for the full screen interface window.
2361 ******************************************************************************/
2362
2363 #if defined(mac)
InitMacMenusFSI()2364 void InitMacMenusFSI () {
2365 appleMenuHfsi = GetMenu (APPLEri);
2366 AddResMenu (appleMenuHfsi, *((long *) "DRVR"));
2367 InsertMenu (appleMenuHfsi, 0);
2368 DrawMenuBar ();
2369 return;
2370 }
2371 #endif
2372
2373 /******************************************************************************
2374 * InitMacFSI.
2375 * Initialize the Macintosh full screen interface window (pasteboard).
2376 ******************************************************************************/
2377
2378 #if defined(mac)
InitMacFSI()2379 void InitMacFSI () {
2380 static WindowRecord wRecord;
2381 WindowPtr behindWindow = (WindowPtr) -1;
2382 fsiWindowP = GetNewWindow (FSIri, &wRecord, behindWindow);
2383 SetPort (fsiWindowP);
2384 TextFont (monaco);
2385 return;
2386 }
2387 #endif
2388
2389 /******************************************************************************
2390 * EncodeKeyDefinitions.
2391 ******************************************************************************/
2392
2393 #if defined(STDARG)
EncodeKeyDefinitions(int nLines,char ** lineS,...)2394 void EncodeKeyDefinitions (int nLines, char **lineS, ...)
2395 #else
2396 void EncodeKeyDefinitions (va_alist)
2397 va_dcl
2398 #endif
2399 {
2400 #if !defined(STDARG)
2401 int nLines;
2402 char **lineS; /* Capital `S' because of the IBM RS6000. */
2403 #endif
2404 int lineN; /* Line number. */
2405 va_list ap;
2406 /****************************************************************************
2407 * Start variable-length argument list scanning.
2408 ****************************************************************************/
2409 #if defined(STDARG)
2410 va_start (ap, lineS);
2411 #else
2412 VA_START (ap);
2413 nLines = va_arg (ap, int);
2414 lineS = va_arg (ap, char **);
2415 #endif
2416 /****************************************************************************
2417 * Scan lines replacing ______'s with corresponding key tokens.
2418 ****************************************************************************/
2419 for (lineN = 0; lineN < nLines; lineN++) {
2420 char *ptr1 = strchr(lineS[lineN],'_');
2421 while (ptr1 != NULL) {
2422 char *ptr2 = ptr1, *ptr = ptr1, token[MAX_KEY_TOKEN_LEN+1];
2423 int i, lenT, lenL, count, pad, key = va_arg(ap,int);
2424 while (*(ptr2+1) == '_') ptr2++;
2425 lenL = (int) (ptr2 - ptr1 + 1);
2426 strcpyX (token, KeyToken(key,lenL), MAX_KEY_TOKEN_LEN);
2427 lenT = (int) strlen (token);
2428 count = MINIMUM(lenT,lenL);
2429 pad = (lenT < lenL ? lenL - lenT : 0);
2430 for (i = 0; i < count; i++) *ptr++ = token[i];
2431 for (i = 0; i < pad; i++) *ptr++ = ' ';
2432 ptr1 = strchr (ptr2 + 1, '_');
2433 }
2434 }
2435 va_end (ap);
2436 return;
2437 }
2438
2439 /******************************************************************************
2440 * KeyToken.
2441 * Return address of character string for key.
2442 ******************************************************************************/
2443
KeyToken(key,maxL)2444 static char *KeyToken(key,maxL)
2445 int key;
2446 int maxL;
2447 {
2448 switch (key) {
2449 case KB_a: return AlphaKey('a',maxL);
2450 case KB_b: return AlphaKey('b',maxL);
2451 case KB_c: return AlphaKey('c',maxL);
2452 case KB_d: return AlphaKey('d',maxL);
2453 case KB_e: return AlphaKey('e',maxL);
2454 case KB_f: return AlphaKey('f',maxL);
2455 case KB_g: return AlphaKey('g',maxL);
2456 case KB_h: return AlphaKey('h',maxL);
2457 case KB_i: return AlphaKey('i',maxL);
2458 case KB_j: return AlphaKey('j',maxL);
2459 case KB_k: return AlphaKey('k',maxL);
2460 case KB_l: return AlphaKey('l',maxL);
2461 case KB_m: return AlphaKey('m',maxL);
2462 case KB_n: return AlphaKey('n',maxL);
2463 case KB_o: return AlphaKey('o',maxL);
2464 case KB_p: return AlphaKey('p',maxL);
2465 case KB_q: return AlphaKey('q',maxL);
2466 case KB_r: return AlphaKey('r',maxL);
2467 case KB_s: return AlphaKey('s',maxL);
2468 case KB_t: return AlphaKey('t',maxL);
2469 case KB_u: return AlphaKey('u',maxL);
2470 case KB_v: return AlphaKey('v',maxL);
2471 case KB_w: return AlphaKey('w',maxL);
2472 case KB_x: return AlphaKey('x',maxL);
2473 case KB_y: return AlphaKey('y',maxL);
2474 case KB_z: return AlphaKey('z',maxL);
2475 case KB_A: return AlphaKey('A',maxL);
2476 case KB_B: return AlphaKey('B',maxL);
2477 case KB_C: return AlphaKey('C',maxL);
2478 case KB_D: return AlphaKey('D',maxL);
2479 case KB_E: return AlphaKey('E',maxL);
2480 case KB_F: return AlphaKey('F',maxL);
2481 case KB_G: return AlphaKey('G',maxL);
2482 case KB_H: return AlphaKey('H',maxL);
2483 case KB_I: return AlphaKey('I',maxL);
2484 case KB_J: return AlphaKey('J',maxL);
2485 case KB_K: return AlphaKey('K',maxL);
2486 case KB_L: return AlphaKey('L',maxL);
2487 case KB_M: return AlphaKey('M',maxL);
2488 case KB_N: return AlphaKey('N',maxL);
2489 case KB_O: return AlphaKey('O',maxL);
2490 case KB_P: return AlphaKey('P',maxL);
2491 case KB_Q: return AlphaKey('Q',maxL);
2492 case KB_R: return AlphaKey('R',maxL);
2493 case KB_S: return AlphaKey('S',maxL);
2494 case KB_T: return AlphaKey('T',maxL);
2495 case KB_U: return AlphaKey('U',maxL);
2496 case KB_V: return AlphaKey('V',maxL);
2497 case KB_W: return AlphaKey('W',maxL);
2498 case KB_X: return AlphaKey('X',maxL);
2499 case KB_Y: return AlphaKey('Y',maxL);
2500 case KB_Z: return AlphaKey('Z',maxL);
2501 case KB_PLUS: return AlphaKey('+',maxL);
2502 case KB_MINUS: return AlphaKey('-',maxL);
2503 case KB_CTRL_at: return ControlKey('@',maxL);
2504 case KB_CTRL_A: return ControlKey('A',maxL);
2505 case KB_CTRL_B: return ControlKey('B',maxL);
2506 case KB_CTRL_C: return ControlKey('C',maxL);
2507 case KB_CTRL_D: return ControlKey('D',maxL);
2508 case KB_CTRL_E: return ControlKey('E',maxL);
2509 case KB_CTRL_F: return ControlKey('F',maxL);
2510 case KB_CTRL_G: return ControlKey('G',maxL);
2511 #if !defined(dos) && !defined(mac) && !defined(win32)
2512 /**************************************************************************
2513 * Same as DELETE on IBM PC and Macintosh.
2514 **************************************************************************/
2515 case KB_CTRL_H: return ControlKey('H',maxL);
2516 #endif
2517 case KB_TAB:
2518 switch (maxL) {
2519 case 3: case 4:
2520 return "TAB";
2521 default:
2522 return "<Tab>";
2523 }
2524 case KB_CTRL_J: return ControlKey('J',maxL);
2525 case KB_CTRL_K: return ControlKey('K',maxL);
2526 case KB_CTRL_L: return ControlKey('L',maxL);
2527 case KB_RETURN:
2528 switch (maxL) {
2529 case 3: case 4:
2530 return "RET";
2531 case 5: case 6: case 7:
2532 return "<RET>";
2533 default:
2534 return "<Return>";
2535 }
2536 case KB_CTRL_N: return ControlKey('N',maxL);
2537 case KB_CTRL_O: return ControlKey('O',maxL);
2538 case KB_CTRL_P: return ControlKey('P',maxL);
2539 case KB_CTRL_Q: return ControlKey('Q',maxL);
2540 case KB_CTRL_R: return ControlKey('R',maxL);
2541 case KB_CTRL_S: return ControlKey('S',maxL);
2542 case KB_CTRL_T: return ControlKey('T',maxL);
2543 case KB_CTRL_U: return ControlKey('U',maxL);
2544 case KB_CTRL_V: return ControlKey('V',maxL);
2545 case KB_CTRL_W: return ControlKey('W',maxL);
2546 case KB_CTRL_X: return ControlKey('X',maxL);
2547 case KB_CTRL_Y: return ControlKey('Y',maxL);
2548 case KB_CTRL_Z: return ControlKey('Z',maxL);
2549 case KB_ESCAPE:
2550 switch (maxL) {
2551 case 3: case 4:
2552 return "ESC";
2553 default:
2554 return "<Esc>";
2555 }
2556 case KB_DELETE:
2557 switch (maxL) {
2558 case 3: case 4:
2559 return "DEL";
2560 case 5: case 6: case 7:
2561 return "<DEL>";
2562 default:
2563 return "<Delete>";
2564 }
2565 case KB_UPARROW:
2566 switch (maxL) {
2567 case 2: case 3:
2568 return "UP";
2569 case 4: case 5: case 6:
2570 return "<UP>";
2571 case 7: case 8:
2572 return "UpArrow";
2573 default:
2574 return "<UpArrow>";
2575 }
2576 case KB_DOWNARROW:
2577 switch (maxL) {
2578 case 3:
2579 return "DWN";
2580 case 4: case 5:
2581 return "DOWN";
2582 case 6: case 7: case 8:
2583 return "<DOWN>";
2584 case 9: case 10:
2585 return "DownArrow";
2586 default:
2587 return "<DownArrow>";
2588 }
2589 case KB_LEFTARROW:
2590 switch (maxL) {
2591 case 3:
2592 return "LFT";
2593 case 4: case 5:
2594 return "LEFT";
2595 case 6: case 7: case 8:
2596 return "<LEFT>";
2597 case 9: case 10:
2598 return "LeftArrow";
2599 default:
2600 return "<LeftArrow>";
2601 }
2602 case KB_RIGHTARROW:
2603 switch (maxL) {
2604 case 3:
2605 return "RHT";
2606 case 5: case 6:
2607 return "RIGHT";
2608 case 7: case 8: case 9:
2609 return "<RIGHT>";
2610 case 10: case 11:
2611 return "RightArrow";
2612 default:
2613 return "<RightArrow>";
2614 }
2615 }
2616 return "?";
2617 }
2618
2619 /******************************************************************************
2620 * AlphaKey.
2621 ******************************************************************************/
2622
AlphaKey(key,maxL)2623 static char *AlphaKey (key, maxL)
2624 int key;
2625 int maxL;
2626 {
2627 static char token[MAX_KEY_TOKEN_LEN+1];
2628 switch (maxL) {
2629 case 1: case 2:
2630 sprintf (token, "%c", key);
2631 break;
2632 default:
2633 sprintf (token, "<%c>", key);
2634 break;
2635 }
2636 return token;
2637 }
2638
2639 /******************************************************************************
2640 * ControlKey.
2641 ******************************************************************************/
2642
ControlKey(key,maxL)2643 static char *ControlKey (key, maxL)
2644 int key;
2645 int maxL;
2646 {
2647 static char token[MAX_KEY_TOKEN_LEN+1];
2648 switch (maxL) {
2649 case 3: case 4:
2650 sprintf (token, "C-%c", key);
2651 break;
2652 case 5:
2653 sprintf (token, "CTL-%c", key);
2654 break;
2655 case 6: case 7:
2656 sprintf (token, "Ctrl-%c", key);
2657 break;
2658 default:
2659 sprintf (token, "<Ctrl-%c>", key);
2660 break;
2661 }
2662 return token;
2663 }
2664
2665 /******************************************************************************
2666 * KeyWaitingAST.
2667 ******************************************************************************/
2668
2669 #if defined(SMGui)
KeyWaitingAST()2670 void KeyWaitingAST () {
2671 keyWaiting++;
2672 return;
2673 }
2674 #endif
2675