OSDN Git Service

v3.0.0 Alpha5 OSDN最終版
[hengband/hengband.git] / src / main-cap.c
1 /* File: main-cap.c */
2
3 /* Purpose: Support for "term.c" using "termcap" calls */
4
5 #include "angband.h"
6
7
8 #ifdef USE_CAP
9
10
11 /*
12  * This file is a total hack, but is often very helpful.  :-)
13  *
14  * This file allows use of the terminal without requiring the
15  * "curses" routines.  In fact, if "USE_HARDCODE" is defined,
16  * this file will attempt to use various hard-coded "vt100"
17  * escape sequences to also avoid the use of the "termcap"
18  * routines.  I do not know if this will work on System V.
19  *
20  * This file is intended for use only on those machines which are
21  * unable, for whatever reason, to compile the "main-gcu.c" file,
22  * but which seem to be able to support the "termcap" library, or
23  * which at least seem able to support "vt100" terminals.
24  *
25  * Large portions of this file were stolen from "main-gcu.c"
26  *
27  * This file incorrectly handles output to column 80, I think.
28  */
29
30
31 /*
32  * Require a "system"
33  */
34 #if !defined(USE_TERMCAP) && !defined(USE_HARDCODE)
35 # define USE_TERMCAP
36 #endif
37
38 /*
39  * Hack -- try to guess which systems use what commands
40  * Hack -- allow one of the "USE_Txxxxx" flags to be pre-set.
41  * Mega-Hack -- try to guess when "POSIX" is available.
42  * If the user defines two of these, we will probably crash.
43  */
44 #if !defined(USE_TPOSIX)
45 # if !defined(USE_TERMIO) && !defined(USE_TCHARS)
46 #  if defined(_POSIX_VERSION)
47 #   define USE_TPOSIX
48 #  else
49 #   if defined(USG) || defined(linux) || defined(SOLARIS)
50 #    define USE_TERMIO
51 #   else
52 #    define USE_TCHARS
53 #   endif
54 #  endif
55 # endif
56 #endif
57
58
59
60 /*
61  * POSIX stuff
62  */
63 #ifdef USE_TPOSIX
64 # include <sys/ioctl.h>
65 # include <termios.h>
66 #endif
67
68 /*
69  * One version needs these files
70  */
71 #ifdef USE_TERMIO
72 # include <sys/ioctl.h>
73 # include <termio.h>
74 #endif
75
76 /*
77  * The other needs these files
78  */
79 #ifdef USE_TCHARS
80 # include <sys/ioctl.h>
81 # include <sys/resource.h>
82 # include <sys/param.h>
83 # include <sys/file.h>
84 # include <sys/types.h>
85 #endif
86
87
88 /*
89  * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
90  *
91  * They should both work due to the "(i != 1)" test in the code
92  * which checks for the result of the "read()" command.
93  */
94 #ifndef O_NDELAY
95 # define O_NDELAY O_NONBLOCK
96 #endif
97
98
99
100
101 #ifdef USE_TERMCAP
102
103 /*
104  * Termcap string information
105  */
106
107 static char blob[1024];         /* The "termcap" entry */
108 static char area[1024];         /* The string extraction buffer */
109 static char *next = area;       /* The current "index" into "area" */
110 static char *desc;              /* The terminal name */
111
112 #endif
113
114
115 /*
116  * Pointers into the "area"
117  */
118
119 static char *cm;        /* Move cursor */
120 static char *ch;        /* Move cursor to horizontal location */
121 static char *cv;        /* Move cursor to vertical location */
122 static char *ho;        /* Move cursor to top left */
123 static char *ll;        /* Move cursor to bottom left */
124 static char *cs;        /* Set scroll area */
125 static char *cl;        /* Clear screen */
126 static char *cd;        /* Clear to end of display */
127 static char *ce;        /* Clear to end of line */
128 static char *cr;        /* Move to start of line */
129 static char *so;        /* Turn on standout */
130 static char *se;        /* Turn off standout */
131 static char *md;        /* Turn on bold */
132 static char *me;        /* Turn off bold */
133 static char *vi;        /* Cursor - invisible */
134 static char *ve;        /* Cursor - normal */
135 static char *vs;        /* Cursor - bright */
136
137
138 /*
139  * State variables
140  */
141
142 static int rows;        /* Screen size (Y) */
143 static int cols;        /* Screen size (X) */
144 static int curx;        /* Cursor location (X) */
145 static int cury;        /* Cursor location (Y) */
146 static int curv;        /* Cursor visibility */
147
148
149 /*
150  * Extern functions
151  */
152 extern char *getenv();
153 extern char *tgoto();
154 extern char *tgetstr();
155
156
157 /*
158  * Write some chars to the terminal
159  */
160 static void ewrite(char *str)
161 {
162         int numtowrite, numwritten;
163
164         /* See how much work we have */
165         numtowrite = strlen(str);
166
167         /* Write until done */
168         while (numtowrite > 0)
169         {
170                 /* Try to write the chars */
171                 numwritten = write(1, str, numtowrite);
172
173                 /* Handle FIFOs and EINTR */
174                 if (numwritten < 0) numwritten = 0;
175
176                 /* See what we completed */
177                 numtowrite -= numwritten;
178                 str += numwritten;
179
180                 /* Hack -- sleep if not done */
181                 if (numtowrite > 0) sleep(1);
182         }
183 }
184
185
186
187 #ifdef USE_TERMCAP
188
189 static char write_buffer[128];
190 static char *write_buffer_ptr;
191
192 static void output_one(char c)
193 {
194         *write_buffer_ptr++ = c;
195 }
196
197 static void tp(char *s)
198 {
199         /* Dump the string into us */
200         write_buffer_ptr = write_buffer;
201
202         /* Write the string with padding */
203         tputs (s, 1, output_one);
204
205         /* Finish the string */
206         *write_buffer_ptr = '\0';
207
208         /* Dump the recorded buffer */
209         ewrite (write_buffer);
210 }
211
212 #endif
213
214 #ifdef USE_HARDCODE
215
216 static void tp(char *s)
217 {
218         ewrite(s);
219 }
220
221 #endif
222
223
224
225
226
227
228
229 /*
230  * Clear the screen
231  */
232 static void do_cl(void)
233 {
234         if (cl) tp (cl);
235 }
236
237 /*
238  * Clear to the end of the line
239  */
240 static void do_ce(void)
241 {
242         if (ce) tp(ce);
243 }
244
245
246 /*
247  * Set the cursor visibility (0 = invis, 1 = normal, 2 = bright)
248  */
249 static void curs_set(int vis)
250 {
251         char *v = NULL;
252
253         if (!vis)
254         {
255                 v = vi;
256         }
257         else if (vis > 1)
258         {
259                 v = vs ? vs : ve;
260         }
261         else
262         {
263                 v = ve ? ve : vs;
264         }
265
266         if (v) tp(v);
267 }
268
269
270
271 /*
272  * Restrict scrolling to within these rows
273  */
274 static void do_cs(int y1, int y2)
275 {
276
277 #ifdef USE_TERMCAP
278         if (cs) tp(tgoto(cs, y2, y1));
279 #endif
280
281 #ifdef USE_HARDCODE
282         char temp[64];
283         sprintf(temp, cs, y1, y2);
284         tp (temp);
285 #endif
286
287 }
288
289
290
291 /*
292  * Go to the given screen location directly
293  */
294 static void do_cm(int x, int y)
295 {
296
297 #ifdef USE_TERMCAP
298         if (cm) tp(tgoto(cm, x, y));
299 #endif
300
301 #ifdef USE_HARDCODE
302         char temp[64];
303         sprintf(temp, cm, y+1, x+1);
304         tp(temp);
305 #endif
306
307 }
308
309
310 /*
311  * Go to the given screen location in a "clever" manner
312  *
313  * XXX XXX XXX This function could use some work!
314  */
315 static void do_move(int x1, int y1, int x2, int y2)
316 {
317         /* Hack -- unknown start location */
318         if ((x1 == x2) && (y1 == y2)) do_cm(x2, y2);
319
320         /* Left edge */
321         else if (x2 == 0)
322         {
323                 if ((y2 <= 0) && ho) tp(ho);
324                 else if ((y2 >= rows-1) && ll) tp(ll);
325                 else if ((y2 == y1) && cr) tp(cr);
326 #if 0
327                 else if ((y2 == y1+1) && cr && dn)
328                 { tp(cr); tp(dn); }
329                 else if ((y2 == y1-1) && cr && up)
330                 { tp(cr); tp(up); }
331 #endif
332                 else do_cm(x2, y2);
333         }
334
335 #if 0
336         /* Up/Down one line */
337         else if ((x2 == x1) && (y2 == y1+1) && dn) tp(dn);
338         else if ((x2 == x1) && (y2 == y1-1) && up) tp(up);
339 #endif
340
341         /* Default -- go directly there */
342         else do_cm(x2, y2);
343 }
344
345
346
347
348 /*
349  * Help initialize this file (see below)
350  */
351 errr init_cap_aux(void)
352 {
353
354 #ifdef USE_TERMCAP
355
356         /* Get the terminal name (if possible) */
357         desc = getenv("TERM");
358         if (!desc) return (1);
359
360         /* Get the terminal info */
361         if (tgetent(blob, desc) != 1) return (2);
362
363         /* Get the (initial) columns and rows, or default */
364         if ((cols = tgetnum("co")) == -1) cols = 80;
365         if ((rows = tgetnum("li")) == -1) rows = 24;
366
367         /* Find out how to move the cursor to a given location */
368         cm = tgetstr("cm", &next);
369         if (!cm) return (10);
370
371         /* Find out how to move the cursor to a given position */
372         ch = tgetstr("ch", &next);
373         cv = tgetstr("cv", &next);
374
375         /* Find out how to "home" the screen */
376         ho = tgetstr("ho", &next);
377
378         /* Find out how to "last-line" the screen */
379         ll = tgetstr("ll", &next);
380
381         /* Find out how to do a "carriage return" */
382         cr = tgetstr("cr", &next);
383         if (!cr) cr = "\r";
384
385         /* Find out how to clear the screen */
386         cl = tgetstr("cl", &next);
387         if (!cl) return (11);
388
389         /* Find out how to clear to the end of display */
390         cd = tgetstr("cd", &next);
391
392         /* Find out how to clear to the end of the line */
393         ce = tgetstr("ce", &next);
394
395         /* Find out how to scroll (set the scroll region) */
396         cs = tgetstr("cs", &next);
397
398         /* Find out how to hilite */
399         so = tgetstr("so", &next);
400         se = tgetstr("se", &next);
401         if (!so || !se) so = se = NULL;
402
403         /* Find out how to bold */
404         md = tgetstr("md", &next);
405         me = tgetstr("me", &next);
406         if (!md || !me) md = me = NULL;
407
408         /* Check the cursor visibility stuff */
409         vi = tgetstr("vi", &next);
410         vs = tgetstr("vs", &next);
411         ve = tgetstr("ve", &next);
412
413 #endif
414
415 #ifdef USE_HARDCODE
416
417         /* Assume some defualt information */
418         rows = 24;
419         cols = 80;
420
421         /* Clear screen */
422         cl = "\033[2J\033[H";   /* --]--]-- */
423
424         /* Clear to end of line */
425         ce = "\033[K";  /* --]-- */
426
427         /* Hilite on/off */
428         so = "\033[7m"; /* --]-- */
429         se = "\033[m";  /* --]-- */
430
431         /* Scroll region */
432         cs = "\033[%d;%dr";     /* --]-- */
433
434         /* Move cursor */
435         cm = "\033[%d;%dH";     /* --]-- */
436
437 #endif
438
439         /* Success */
440         return (0);
441 }
442
443
444
445
446
447
448
449 /*
450  * Save the "normal" and "angband" terminal settings
451  */
452
453 #ifdef USE_TPOSIX
454
455 static struct termios  norm_termios;
456
457 static struct termios  game_termios;
458
459 #endif
460
461 #ifdef USE_TERMIO
462
463 static struct termio  norm_termio;
464
465 static struct termio  game_termio;
466
467 #endif
468
469 #ifdef USE_TCHARS
470
471 static struct sgttyb  norm_ttyb;
472 static struct tchars  norm_tchars;
473 static struct ltchars norm_ltchars;
474 static int            norm_local_chars;
475
476 static struct sgttyb  game_ttyb;
477 static struct tchars  game_tchars;
478 static struct ltchars game_ltchars;
479 static int            game_local_chars;
480
481 #endif
482
483
484
485 /*
486  * Are we active?  Not really needed.
487  */
488 static int active = FALSE;
489
490
491 /*
492  * The main screen (no sub-screens)
493  */
494 static term term_screen_body;
495
496
497
498 /*
499  * Place the "keymap" into its "normal" state
500  */
501 static void keymap_norm(void)
502 {
503
504 #ifdef USE_TPOSIX
505
506         /* restore the saved values of the special chars */
507         (void)tcsetattr(0, TCSAFLUSH, &norm_termios);
508
509 #endif
510
511 #ifdef USE_TERMIO
512
513         /* restore the saved values of the special chars */
514         (void)ioctl(0, TCSETA, (char *)&norm_termio);
515
516 #endif
517
518 #ifdef USE_TCHARS
519
520         /* restore the saved values of the special chars */
521         (void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
522         (void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
523         (void)ioctl(0, TIOCSLTC, (char *)&norm_ltchars);
524         (void)ioctl(0, TIOCLSET, (char *)&norm_local_chars);
525
526 #endif
527
528 }
529
530
531 /*
532  * Place the "keymap" into the "game" state
533  */
534 static void keymap_game(void)
535 {
536
537 #ifdef USE_TPOSIX
538
539         /* restore the saved values of the special chars */
540         (void)tcsetattr(0, TCSAFLUSH, &game_termios);
541
542 #endif
543
544 #ifdef USE_TERMIO
545
546         /* restore the saved values of the special chars */
547         (void)ioctl(0, TCSETA, (char *)&game_termio);
548
549 #endif
550
551 #ifdef USE_TCHARS
552
553         /* restore the saved values of the special chars */
554         (void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
555         (void)ioctl(0, TIOCSETC, (char *)&game_tchars);
556         (void)ioctl(0, TIOCSLTC, (char *)&game_ltchars);
557         (void)ioctl(0, TIOCLSET, (char *)&game_local_chars);
558
559 #endif
560
561 }
562
563
564 /*
565  * Save the normal keymap
566  */
567 static void keymap_norm_prepare(void)
568 {
569
570 #ifdef USE_TPOSIX
571
572         /* Get the normal keymap */
573         tcgetattr(0, &norm_termios);
574
575 #endif
576
577 #ifdef USE_TERMIO
578
579         /* Get the normal keymap */
580         (void)ioctl(0, TCGETA, (char *)&norm_termio);
581
582 #endif
583
584 #ifdef USE_TCHARS
585
586         /* Get the normal keymap */
587         (void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
588         (void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
589         (void)ioctl(0, TIOCGLTC, (char *)&norm_ltchars);
590         (void)ioctl(0, TIOCLGET, (char *)&norm_local_chars);
591
592 #endif
593
594 }
595
596
597 /*
598  * Save the keymaps (normal and game)
599  */
600 static void keymap_game_prepare(void)
601 {
602
603 #ifdef USE_TPOSIX
604
605         /* Acquire the current mapping */
606         tcgetattr(0, &game_termios);
607
608         /* Force "Ctrl-C" to interupt */
609         game_termios.c_cc[VINTR] = (char)3;
610
611         /* Force "Ctrl-Z" to suspend */
612         game_termios.c_cc[VSUSP] = (char)26;
613
614         /* Hack -- Leave "VSTART/VSTOP" alone */
615
616         /* Disable the standard control characters */
617         game_termios.c_cc[VQUIT] = (char)-1;
618         game_termios.c_cc[VERASE] = (char)-1;
619         game_termios.c_cc[VKILL] = (char)-1;
620         game_termios.c_cc[VEOF] = (char)-1;
621         game_termios.c_cc[VEOL] = (char)-1;
622
623         /* Normally, block until a character is read */
624         game_termios.c_cc[VMIN] = 1;
625         game_termios.c_cc[VTIME] = 0;
626
627         /* Hack -- Turn off "echo" and "canonical" mode */
628         game_termios.c_lflag &= ~(ECHO | ICANON);
629
630         /* Turn off flow control */
631         game_termios.c_iflag &= ~IXON;
632
633 #endif
634
635 #ifdef USE_TERMIO
636
637         /* Acquire the current mapping */
638         (void)ioctl(0, TCGETA, (char *)&game_termio);
639
640         /* Force "Ctrl-C" to interupt */
641         game_termio.c_cc[VINTR] = (char)3;
642
643         /* Force "Ctrl-Z" to suspend */
644         game_termio.c_cc[VSUSP] = (char)26;
645
646         /* Hack -- Leave "VSTART/VSTOP" alone */
647
648         /* Disable the standard control characters */
649         game_termio.c_cc[VQUIT] = (char)-1;
650         game_termio.c_cc[VERASE] = (char)-1;
651         game_termio.c_cc[VKILL] = (char)-1;
652         game_termio.c_cc[VEOF] = (char)-1;
653         game_termio.c_cc[VEOL] = (char)-1;
654
655 #if 0
656         /* Disable the non-posix control characters */
657         game_termio.c_cc[VEOL2] = (char)-1;
658         game_termio.c_cc[VSWTCH] = (char)-1;
659         game_termio.c_cc[VDSUSP] = (char)-1;
660         game_termio.c_cc[VREPRINT] = (char)-1;
661         game_termio.c_cc[VDISCARD] = (char)-1;
662         game_termio.c_cc[VWERASE] = (char)-1;
663         game_termio.c_cc[VLNEXT] = (char)-1;
664         game_termio.c_cc[VSTATUS] = (char)-1;
665 #endif
666
667         /* Normally, block until a character is read */
668         game_termio.c_cc[VMIN] = 1;
669         game_termio.c_cc[VTIME] = 0;
670
671         /* Hack -- Turn off "echo" and "canonical" mode */
672         game_termio.c_lflag &= ~(ECHO | ICANON);
673
674         /* Turn off flow control */
675         game_termio.c_iflag &= ~IXON;
676
677 #endif
678
679 #ifdef USE_TCHARS
680
681         /* Get the default game characters */
682         (void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
683         (void)ioctl(0, TIOCGETC, (char *)&game_tchars);
684         (void)ioctl(0, TIOCGLTC, (char *)&game_ltchars);
685         (void)ioctl(0, TIOCLGET, (char *)&game_local_chars);
686
687         /* Force interupt (^C) */
688         game_tchars.t_intrc = (char)3;
689
690         /* Force start/stop (^Q, ^S) */
691         game_tchars.t_startc = (char)17;
692         game_tchars.t_stopc = (char)19;
693
694         /* Cancel some things */
695         game_tchars.t_quitc = (char)-1;
696         game_tchars.t_eofc = (char)-1;
697         game_tchars.t_brkc = (char)-1;
698
699         /* Force suspend (^Z) */
700         game_ltchars.t_suspc = (char)26;
701
702         /* Cancel some things */
703         game_ltchars.t_dsuspc = (char)-1;
704         game_ltchars.t_rprntc = (char)-1;
705         game_ltchars.t_flushc = (char)-1;
706         game_ltchars.t_werasc = (char)-1;
707         game_ltchars.t_lnextc = (char)-1;
708
709         /* XXX XXX XXX XXX Verify this before use */
710         /* Hack -- Turn off "echo" and "canonical" mode */
711         /* game_termios.c_lflag &= ~(ECHO | ICANON); */
712         game_ttyb.flag &= ~(ECHO | ICANON);
713
714         /* XXX XXX XXX  Should maybe turn off flow control too.  How? */
715
716 #endif
717
718 }
719
720
721
722
723
724
725
726
727 /*
728  * Suspend/Resume
729  */
730 static errr Term_xtra_cap_alive(int v)
731 {
732         /* Suspend */
733         if (!v)
734         {
735                 if (!active) return (1);
736
737                 /* Hack -- make sure the cursor is visible */
738                 curs_set(1);
739
740                 /* Move to bottom right */
741                 do_move(0, rows - 1, 0, rows - 1);
742
743                 /* Go to normal keymap mode */
744                 keymap_norm();
745
746                 /* No longer active */
747                 active = FALSE;
748         }
749
750         /* Resume */
751         else
752         {
753                 if (active) return (1);
754
755                 /* Hack -- restore the cursor location */
756                 do_move(curx, cury, curx, cury);
757
758                 /* Hack -- restore the cursor visibility */
759                 curs_set(curv);
760
761                 /* Go to angband keymap mode */
762                 keymap_game();
763
764                 /* Now we are active */
765                 active = TRUE;
766         }
767
768         /* Success */
769         return (0);
770 }
771
772
773
774 /*
775  * Process an event
776  */
777 static errr Term_xtra_cap_event(int v)
778 {
779         int i, arg;
780         char buf[2];
781
782         /* Wait */
783         if (v)
784         {
785                 /* Wait for one byte */
786                 i = read(0, buf, 1);
787
788                 /* Hack -- Handle "errors" */
789                 if ((i <= 0) && (errno != EINTR)) exit_game_panic();
790         }
791
792         /* Do not wait */
793         else
794         {
795                 /* Get the current flags for stdin */
796                 if ((arg = fcntl(0, F_GETFL, 0)) < 1) return (1);
797
798                 /* Tell stdin not to block */
799                 if (fcntl(0, F_SETFL, arg | O_NDELAY) < 0) return (1);
800
801                 /* Read one byte, if possible */
802                 i = read(0, buf, 1);
803
804                 /* Replace the flags for stdin */
805                 if (fcntl(0, F_SETFL, arg)) return (1);
806         }
807
808         /* No keys ready */
809         if ((i != 1) || (!buf[0])) return (1);
810
811         /* Enqueue the keypress */
812         Term_keypress(buf[0]);
813
814         /* Success */
815         return (0);
816 }
817
818
819
820
821 /*
822  * Actually move the hardware cursor
823  */
824 static errr Term_curs_cap(int x, int y)
825 {
826         /* Literally move the cursor */
827         do_move(curx, cury, x, y);
828
829         /* Save the cursor location */
830         curx = x;
831         cury = y;
832
833         /* Success */
834         return (0);
835 }
836
837
838 /*
839  * Erase a grid of space
840  *
841  * XXX XXX XXX Note that we will never be asked to clear the
842  * bottom line all the way to the bottom right edge, since we
843  * have set the "avoid the bottom right corner" flag.
844  */
845 static errr Term_wipe_cap(int x, int y, int n)
846 {
847         int dx;
848
849         /* Place the cursor */
850         Term_curs_cap(x, y);
851
852         /* Wipe to end of line */
853         if (x + n >= 80)
854         {
855                 do_ce();
856         }
857
858         /* Wipe region */
859         else
860         {
861                 for (dx = 0; dx < n; ++dx)
862                 {
863                         putc(' ', stdout);
864                         curx++;
865                 }
866         }
867
868         /* Success */
869         return (0);
870 }
871
872
873 /*
874  * Place some text on the screen using an attribute
875  */
876 static errr Term_text_cap(int x, int y, int n, byte a, concptr s)
877 {
878         int i;
879
880         /* Move the cursor */
881         Term_curs_cap(x, y);
882
883         /* Dump the text, advance the cursor */
884         for (i = 0; s[i]; i++)
885         {
886                 /* Dump the char */
887                 putc(s[i], stdout);
888
889                 /* Advance cursor 'X', and wrap */
890                 if (++curx >= cols)
891                 {
892                         /* Reset cursor 'X' */
893                         curx = 0;
894
895                         /* Hack -- Advance cursor 'Y', and wrap */
896                         if (++cury == rows) cury = 0;
897                 }
898         }
899
900         /* Success */
901         return (0);
902 }
903
904
905 /*
906  * Handle a "special request"
907  */
908 static errr Term_xtra_cap(int n, int v)
909 {
910         /* Analyze the request */
911         switch (n)
912         {
913                 /* Clear the screen */
914                 case TERM_XTRA_CLEAR:
915                 do_cl();
916                 do_move(0, 0, 0, 0);
917                 return (0);
918
919                 /* Make a noise */
920                 case TERM_XTRA_NOISE:
921                 (void)write(1, "\007", 1);
922                 return (0);
923
924                 /* Change the cursor visibility */
925                 case TERM_XTRA_SHAPE:
926                 curv = v;
927                 curs_set(v);
928                 return (0);
929
930                 /* Suspend/Resume */
931                 case TERM_XTRA_ALIVE:
932                 return (Term_xtra_cap_alive(v));
933
934                 /* Process events */
935                 case TERM_XTRA_EVENT:
936                 return (Term_xtra_cap_event(v));
937
938                 /* Flush events */
939                 case TERM_XTRA_FLUSH:
940                 while (!Term_xtra_cap_event(FALSE));
941                 return (0);
942
943                 /* Delay */
944                 case TERM_XTRA_DELAY:
945                 usleep(1000 * v);
946                 return (0);
947         }
948
949         /* Not parsed */
950         return (1);
951 }
952
953
954
955
956 /*
957  * Init a "term" for this file
958  */
959 static void Term_init_cap(term *t)
960 {
961         if (active) return;
962
963         /* Assume cursor at top left */
964         curx = 0;
965         cury = 0;
966
967         /* Assume visible cursor */
968         curv = 1;
969
970         /* Clear the screen */
971         do_cl();
972
973         /* Hack -- visible cursor */
974         curs_set(1);
975
976         /* Assume active */
977         active = TRUE;
978 }
979
980
981 /*
982  * Nuke a "term" for this file
983  */
984 static void Term_nuke_cap(term *t)
985 {
986         if (!active) return;
987
988         /* Hack -- make sure the cursor is visible */
989         curs_set(1);
990
991         /* Move to bottom right */
992         do_move(0, rows - 1, 0, rows - 1);
993
994         /* Normal keymap */
995         keymap_norm();
996
997         /* No longer active */
998         active = FALSE;
999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 /*
1011  * Prepare this file for Angband usage
1012  */
1013 errr init_cap(void)
1014 {
1015         term *t = &term_screen_body;
1016
1017
1018         /*** Initialize ***/
1019
1020         /* Initialize the screen */
1021         if (init_cap_aux()) return (-1);
1022
1023         /* Hack -- Require large screen, or Quit with message */
1024         if ((rows < 24) || (cols < 80)) quit("Screen too small!");
1025
1026
1027         /*** Prepare to play ***/
1028
1029         /* Extract the normal keymap */
1030         keymap_norm_prepare();
1031
1032         /* Extract the game keymap */
1033         keymap_game_prepare();
1034
1035         /* Hack -- activate the game keymap */
1036         keymap_game();
1037
1038         /* Hack -- Do NOT buffer stdout */
1039         setbuf(stdout, NULL);
1040
1041
1042         /*** Now prepare the term ***/
1043
1044         /* Initialize the term */
1045         term_init(t, 80, 24, 256);
1046
1047         /* Avoid the bottom right corner */
1048         t->icky_corner = TRUE;
1049
1050         /* Erase with "white space" */
1051         t->attr_blank = TERM_WHITE;
1052         t->char_blank = ' ';
1053
1054         /* Set some hooks */
1055         t->init_hook = Term_init_cap;
1056         t->nuke_hook = Term_nuke_cap;
1057
1058         /* Set some more hooks */
1059         t->text_hook = Term_text_cap;
1060         t->wipe_hook = Term_wipe_cap;
1061         t->curs_hook = Term_curs_cap;
1062         t->xtra_hook = Term_xtra_cap;
1063
1064         /* Save the term */
1065         term_screen = t;
1066
1067         /* Activate it */
1068         Term_activate(term_screen);
1069
1070         /* Success */
1071         return (0);
1072 }
1073
1074
1075 #endif /* USE_CAP */
1076
1077