This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.0 alpha 4
[perl5.git] / ext / curses / curses.mus
1 /* $RCSfile: curses.mus,v $$Revision: 4.1 $$Date: 92/08/07 18:28:53 $
2  *
3  * $Log:        curses.mus,v $
4  * Revision 4.1  92/08/07  18:28:53  lwall
5  * 
6  * Revision 4.0.1.2  92/06/08  16:06:12  lwall
7  * patch20: function key support added to curses.mus
8  * 
9  * Revision 4.0.1.1  91/11/05  19:06:19  lwall
10  * patch11: usub/curses.mus now supports SysV curses
11  * 
12  * Revision 4.0  91/03/20  01:56:13  lwall
13  * 4.0 baseline.
14  * 
15  * Revision 3.0.1.1  90/08/09  04:05:21  lwall
16  * patch19: Initial revision
17  * 
18  */
19
20 #include "EXTERN.h"
21 #include "perl.h"
22
23 char *savestr();
24
25 #undef bool
26 #include <curses.h>
27
28 #ifndef A_UNDERLINE
29 #define NOSETATTR
30 #define A_STANDOUT  0x0200
31 #define A_UNDERLINE 0x0100
32 #define A_REVERSE   0x0200
33 #define A_BLINK     0x0400
34 #define A_BOLD      0x0800
35 #define A_ALTCHARSET 0x1000    
36 #define A_NORMAL    0
37 #endif
38
39 #ifdef USG
40 static char *tcbuf = NULL;
41 #endif
42
43 #ifdef NOSETATTR
44 static unsigned curattr = NORMAL;
45 #endif
46
47 static enum uservars {
48     UV_curscr,
49     UV_stdscr,
50     UV_ttytype,
51     UV_LINES,
52     UV_COLS,
53     UV_ERR,
54     UV_OK,
55 #ifdef BSD
56     UV_Def_term,
57     UV_My_term,
58 #endif    
59     UV_A_STANDOUT,
60     UV_A_UNDERLINE,
61     UV_A_REVERSE,
62     UV_A_BLINK,
63     UV_A_DIM,
64     UV_A_BOLD,
65     UV_A_NORMAL,
66 };
67
68 static enum usersubs {
69     US_addch,
70     US_waddch,
71     US_addstr,
72     US_waddstr,
73     US_box,
74     US_clear,
75     US_wclear,
76     US_clearok,
77     US_clrtobot,
78     US_wclrtobot,
79     US_clrtoeol,
80     US_wclrtoeol,
81     US_delch,
82     US_wdelch,
83     US_deleteln,
84     US_wdeleteln,
85     US_erase,
86     US_werase,
87     US_idlok,
88     US_insch,
89     US_winsch,
90     US_insertln,
91     US_winsertln,
92     US_move,
93     US_wmove,
94     US_overlay,
95     US_overwrite,
96     US_refresh,
97     US_wrefresh,
98     US_standout,
99     US_wstandout,
100     US_standend,
101     US_wstandend,
102     US_cbreak,
103     US_nocbreak,
104     US_echo,
105     US_noecho,
106     US_getch,
107     US_wgetch,
108     US_getstr,
109     US_wgetstr,
110     US_raw,
111     US_noraw,
112     US_baudrate,
113     US_delwin,
114     US_endwin,
115     US_erasechar,
116     US_getyx,
117     US_inch,
118     US_winch,
119     US_initscr,
120     US_killchar,
121     US_leaveok,
122     US_longname,
123     US_mvwin,
124     US_newwin,
125     US_nl,
126     US_nonl,
127     US_scrollok,
128     US_subwin,
129     US_touchline,
130     US_touchwin,
131     US_unctrl,
132     US_gettmode,
133     US_mvcur,
134     US_scroll,
135     US_savetty,
136     US_resetty,
137     US_setterm,
138     US_attroff,
139     US_wattroff,
140     US_attron,
141     US_wattron,
142     US_attrset,
143     US_wattrset,
144 #ifdef CURSEFMT
145     US_printw, /* remove */
146     US_wprintw, /* remove */
147     US_scanw,   /* delete */
148     US_wscanw,  /* delete */
149 #endif
150     US_getcap,
151 #ifdef BSD
152     US_flushok,
153     US_fullname,
154     US_touchoverlap,
155     US_tstp,
156     US__putchar,
157 #endif
158     US_mysub,
159     US_testcallback,
160 };
161
162 static int usersub();
163 static int userset();
164 static int userval();
165
166 int
167 init_curses()
168 {
169     struct ufuncs uf;
170     char *filename = "curses.c";
171
172     uf.uf_set = userset;
173     uf.uf_val = userval;
174
175 #define MAGICVAR(name, ix) uf.uf_index = ix, magicname(name, &uf, sizeof uf)
176
177     MAGICVAR("curscr",  UV_curscr);
178     MAGICVAR("stdscr",  UV_stdscr);
179     MAGICVAR("ttytype", UV_ttytype);
180     MAGICVAR("LINES",   UV_LINES);
181     MAGICVAR("COLS",    UV_COLS);
182     MAGICVAR("ERR",     UV_ERR);
183     MAGICVAR("OK",      UV_OK);
184 #ifdef BSD
185     MAGICVAR("Def_term",UV_Def_term);
186     MAGICVAR("My_term", UV_My_term);
187 #endif
188     MAGICVAR("A_STANDOUT", UV_A_STANDOUT);
189     MAGICVAR("A_UNDERLINE", UV_A_UNDERLINE);
190     MAGICVAR("A_REVERSE", UV_A_REVERSE);
191     MAGICVAR("A_BLINK", UV_A_BLINK);
192     MAGICVAR("A_DIM", UV_A_DIM);
193     MAGICVAR("A_BOLD", UV_A_BOLD);
194     MAGICVAR("A_NORMAL", UV_A_NORMAL);
195
196     make_usub("addch",          US_addch,       usersub, filename);
197     make_usub("waddch",         US_waddch,      usersub, filename);
198     make_usub("addstr",         US_addstr,      usersub, filename);
199     make_usub("waddstr",        US_waddstr,     usersub, filename);
200     make_usub("box",            US_box,         usersub, filename);
201     make_usub("clear",          US_clear,       usersub, filename);
202     make_usub("wclear",         US_wclear,      usersub, filename);
203     make_usub("clearok",        US_clearok,     usersub, filename);
204     make_usub("clrtobot",       US_clrtobot,    usersub, filename);
205     make_usub("wclrtobot",      US_wclrtobot,   usersub, filename);
206     make_usub("clrtoeol",       US_clrtoeol,    usersub, filename);
207     make_usub("wclrtoeol",      US_wclrtoeol,   usersub, filename);
208     make_usub("delch",          US_delch,       usersub, filename);
209     make_usub("wdelch",         US_wdelch,      usersub, filename);
210     make_usub("deleteln",       US_deleteln,    usersub, filename);
211     make_usub("wdeleteln",      US_wdeleteln,   usersub, filename);
212     make_usub("erase",          US_erase,       usersub, filename);
213     make_usub("werase",         US_werase,      usersub, filename);
214     make_usub("idlok",          US_idlok,       usersub, filename);
215     make_usub("insch",          US_insch,       usersub, filename);
216     make_usub("winsch",         US_winsch,      usersub, filename);
217     make_usub("insertln",       US_insertln,    usersub, filename);
218     make_usub("winsertln",      US_winsertln,   usersub, filename);
219     make_usub("move",           US_move,        usersub, filename);
220     make_usub("wmove",          US_wmove,       usersub, filename);
221     make_usub("overlay",        US_overlay,     usersub, filename);
222     make_usub("overwrite",      US_overwrite,   usersub, filename);
223     make_usub("refresh",        US_refresh,     usersub, filename);
224     make_usub("wrefresh",       US_wrefresh,    usersub, filename);
225     make_usub("standout",       US_standout,    usersub, filename);
226     make_usub("wstandout",      US_wstandout,   usersub, filename);
227     make_usub("standend",       US_standend,    usersub, filename);
228     make_usub("wstandend",      US_wstandend,   usersub, filename);
229     make_usub("cbreak",         US_cbreak,      usersub, filename);
230     make_usub("nocbreak",       US_nocbreak,    usersub, filename);
231     make_usub("echo",           US_echo,        usersub, filename);
232     make_usub("noecho",         US_noecho,      usersub, filename);
233     make_usub("getch",          US_getch,       usersub, filename);
234     make_usub("wgetch",         US_wgetch,      usersub, filename);
235     make_usub("getstr",         US_getstr,      usersub, filename);
236     make_usub("wgetstr",        US_wgetstr,     usersub, filename);
237     make_usub("raw",            US_raw,         usersub, filename);
238     make_usub("noraw",          US_noraw,       usersub, filename);
239     make_usub("baudrate",       US_baudrate,    usersub, filename);
240     make_usub("delwin",         US_delwin,      usersub, filename);
241     make_usub("endwin",         US_endwin,      usersub, filename);
242     make_usub("erasechar",      US_erasechar,   usersub, filename);
243     make_usub("getyx",          US_getyx,       usersub, filename);
244     make_usub("inch",           US_inch,        usersub, filename);
245     make_usub("winch",          US_winch,       usersub, filename);
246     make_usub("initscr",        US_initscr,     usersub, filename);
247     make_usub("killchar",       US_killchar,    usersub, filename);
248     make_usub("leaveok",        US_leaveok,     usersub, filename);
249     make_usub("longname",       US_longname,    usersub, filename);
250     make_usub("mvwin",          US_mvwin,       usersub, filename);
251     make_usub("newwin",         US_newwin,      usersub, filename);
252     make_usub("nl",             US_nl,          usersub, filename);
253     make_usub("nonl",           US_nonl,        usersub, filename);
254     make_usub("scrollok",       US_scrollok,    usersub, filename);
255     make_usub("subwin",         US_subwin,      usersub, filename);
256     make_usub("touchline",      US_touchline,   usersub, filename);
257     make_usub("touchwin",       US_touchwin,    usersub, filename);
258     make_usub("unctrl",         US_unctrl,      usersub, filename);
259     make_usub("gettmode",       US_gettmode,    usersub, filename);
260     make_usub("mvcur",          US_mvcur,       usersub, filename);
261     make_usub("scroll",         US_scroll,      usersub, filename);
262     make_usub("savetty",        US_savetty,     usersub, filename);
263     make_usub("resetty",        US_resetty,     usersub, filename);
264     make_usub("setterm",        US_setterm,     usersub, filename);
265     make_usub("getcap",         US_getcap,      usersub, filename);
266     make_usub("attroff",        US_attroff,     usersub, filename);
267     make_usub("wattroff",       US_wattroff,    usersub, filename);
268     make_usub("attron",         US_attron,      usersub, filename);
269     make_usub("wattron",        US_wattron,     usersub, filename);
270     make_usub("attrset",        US_attrset,     usersub, filename);
271     make_usub("wattrset",       US_wattrset,    usersub, filename);
272 #ifdef CURSEFMT
273     make_usub("printw",         US_printw,      usersub, filename);
274     make_usub("wprintw",        US_wprintw,     usersub, filename);
275     make_usub("scanw",          US_scanw,       usersub, filename);
276     make_usub("wscanw",         US_wscanw,      usersub, filename);
277 #endif
278 #ifdef BSD
279     make_usub("flushok",        US_flushok,     usersub, filename);
280     make_usub("fullname",       US_fullname,    usersub, filename);
281     make_usub("touchoverlap",   US_touchoverlap,usersub, filename);
282     make_usub("tstp",           US_tstp,        usersub, filename);
283     make_usub("_putchar",       US__putchar,    usersub, filename);
284 #endif
285     make_usub("testcallback",   US_testcallback,usersub, filename);
286   };
287   
288 #ifdef USG
289 static char
290 *getcap(cap)
291 register char *cap;
292 {
293     static char nocaperr[] = "Cannot read termcap entry.";
294
295     extern char *tgetstr();
296
297     if (tcbuf == NULL) {
298         if ((tcbuf = malloc(1024)) == NULL) {
299             fatal(nocaperr);
300         }
301         if (tgetent(tcbuf, ttytype) == -1) {
302             fatal(nocaperr);
303         }
304     }
305
306     return (tgetstr(cap, NULL));
307 }
308 #endif
309
310 #ifdef NOSETATTR
311 #define attron(attr)    wattron(stdscr, attr)
312 #define attroff(attr)   wattroff(stdscr, attr)
313 #define attset(attr)    wattset(stdscr, attr)
314
315 int
316 wattron(win, attr)
317 WINDOW *win;
318 chtype attr;
319 {
320     curattr |= attr;
321     if (curattr & A_STANDOUT) {
322         return(wstandout(win));
323     } else {
324         return(wstandend(win));
325     }
326 }
327
328 int
329 wattroff(win, attr)
330 WINDOW *win;
331 chtype attr;
332 {
333     curattr &= (~attr);
334     if (curattr & A_STANDOUT) {
335         return(wstandout(win));
336     } else {
337         return(wstandend(win));
338     }
339 }
340
341 int
342 wattrset(win, attr)
343 WINDOW *win;
344 chtype attr;
345 {
346     curattr = attr;
347     if (curattr & A_STANDOUT) {
348         return(wstandout(win));
349     } else {
350         return(wstandend(win));
351     }
352 }
353
354 #endif
355     
356 static int
357 usersub(ix, sp, items)
358 int ix;
359 register int sp;
360 register int items;
361 {
362     STR **st = stack->ary_array + sp;
363     register int i;
364     register char *tmps;
365     register STR *Str;          /* used in str_get and str_gnum macros */
366
367     switch (ix) {
368 CASE int addch
369 I       char            ch
370 END
371
372 CASE int waddch
373 I       WINDOW*         win
374 I       char            ch
375 END
376
377 CASE int addstr
378 I       char*           str
379 END
380
381 CASE int waddstr
382 I       WINDOW*         win
383 I       char*           str
384 END
385
386 CASE int box
387 I       WINDOW*         win
388 I       char            vert
389 I       char            hor
390 END
391
392 CASE int clear
393 END
394
395 CASE int wclear
396 I       WINDOW*         win
397 END
398
399 CASE int clearok
400 I       WINDOW*         win
401 I       bool            boolf
402 END
403
404 CASE int clrtobot
405 END
406
407 CASE int wclrtobot
408 I       WINDOW*         win
409 END
410
411 CASE int clrtoeol
412 END
413
414 CASE int wclrtoeol
415 I       WINDOW*         win
416 END
417
418 CASE int delch
419 END
420
421 CASE int wdelch
422 I       WINDOW*         win
423 END
424
425 CASE int deleteln
426 END
427
428 CASE int wdeleteln
429 I       WINDOW*         win
430 END
431
432 CASE int erase
433 END
434
435 CASE int werase
436 I       WINDOW*         win
437 END
438
439 CASE int idlok
440 I       WINDOW*         win
441 I       bool            boolf
442 END
443
444 CASE int insch
445 I       char            c
446 END
447
448 CASE int winsch
449 I       WINDOW*         win
450 I       char            c
451 END
452
453 CASE int insertln
454 END
455
456 CASE int winsertln
457 I       WINDOW*         win
458 END
459
460 CASE int move
461 I       int             y
462 I       int             x
463 END
464
465 CASE int wmove
466 I       WINDOW*         win
467 I       int             y
468 I       int             x
469 END
470
471 CASE int overlay
472 I       WINDOW*         win1
473 I       WINDOW*         win2
474 END
475
476 CASE int overwrite
477 I       WINDOW*         win1
478 I       WINDOW*         win2
479 END
480
481 CASE int refresh
482 END
483
484 CASE int wrefresh
485 I       WINDOW*         win
486 END
487
488 CASE int standout
489 END
490
491 CASE int wstandout
492 I       WINDOW*         win
493 END
494
495 CASE int standend
496 END
497
498 CASE int wstandend
499 I       WINDOW*         win
500 END
501
502 CASE int cbreak
503 END
504
505 CASE int nocbreak
506 END
507
508 CASE int echo
509 END
510
511 CASE int noecho
512 END
513
514     case US_getch:
515         if (items != 0)
516             fatal("Usage: &getch()");
517         else {
518             int retval;
519             char retch;
520
521             retval = getch();
522             if (retval == EOF)
523                 st[0] = &str_undef;
524             else {
525                 retch = retval;
526                 if (retval > 0377)
527                         str_numset(st[0], (double) retval);
528                 else
529                         str_nset(st[0], &retch, 1);
530             }
531         }
532         return sp;
533
534     case US_wgetch:
535         if (items != 1)
536             fatal("Usage: &wgetch($win)");
537         else {
538             int retval;
539             char retch;
540             WINDOW*     win =           *(WINDOW**)     str_get(st[1]);
541
542             retval = wgetch(win);
543             if (retval == EOF)
544                 st[0] = &str_undef;
545             else {
546                 retch = retval;
547                 if (retval > 0377)
548                         str_numset(st[0], (double) retval);
549                 else
550                         str_nset(st[0], &retch, 1);
551             }
552         }
553         return sp;
554
555 CASE int getstr
556 O       char*           str
557 END
558
559 CASE int wgetstr
560 I       WINDOW*         win
561 O       char*           str
562 END
563
564 CASE int raw
565 END
566
567 CASE int noraw
568 END
569
570 CASE int baudrate
571 END
572
573 CASE int delwin
574 I       WINDOW*         win
575 END
576
577 CASE int endwin
578 END
579
580 CASE int erasechar
581 END
582
583     case US_getyx:
584         if (items != 3)
585             fatal("Usage: &getyx($win, $y, $x)");
586         else {
587             int retval;
588             STR*        str =           str_new(0);
589             WINDOW*     win =           *(WINDOW**)     str_get(st[1]);
590             int         y;
591             int         x;
592
593             do_sprintf(str, items - 1, st + 1);
594             retval = getyx(win, y, x);
595             str_numset(st[2], (double)y);
596             str_numset(st[3], (double)x);
597             str_numset(st[0], (double) retval);
598             str_free(str);
599         }
600         return sp;
601         
602 CASE int inch
603 END
604
605 CASE int winch
606 I       WINDOW*         win
607 END
608
609 CASE WINDOW* initscr
610 END
611
612 CASE int killchar
613 END
614
615 CASE int leaveok
616 I       WINDOW*         win
617 I       bool            boolf
618 END
619
620 #ifdef BSD
621 CASE char* longname
622 I       char*           termbuf
623 IO      char*           name
624 END
625 #else
626 CASE char* longname
627 I       char*           termbug
628 I       char*           name
629 END
630 #endif
631
632 CASE int mvwin
633 I       WINDOW*         win
634 I       int             y
635 I       int             x
636 END
637
638 CASE WINDOW* newwin
639 I       int             lines
640 I       int             cols
641 I       int             begin_y
642 I       int             begin_x
643 END
644
645 CASE int nl
646 END
647
648 CASE int nonl
649 END
650
651 CASE int scrollok
652 I       WINDOW*         win
653 I       bool            boolf
654 END
655
656 CASE WINDOW* subwin
657 I       WINDOW*         win
658 I       int             lines
659 I       int             cols
660 I       int             begin_y
661 I       int             begin_x
662 END
663
664 CASE int touchline
665 I       WINDOW*         win
666 I       int             y
667 I       int             startx
668 I       int             endx
669 END
670
671 CASE int touchwin
672 I       WINDOW*         win
673 END
674
675 CASE char* unctrl
676 I       char            ch
677 END
678
679 CASE int gettmode
680 END
681
682 CASE int mvcur
683 I       int             lasty
684 I       int             lastx
685 I       int             newy
686 I       int             newx
687 END
688
689 CASE int scroll
690 I       WINDOW*         win
691 END
692
693 CASE int savetty
694 END
695
696 CASE void resetty
697 END
698
699 CASE int setterm
700 I       char*           name
701 END
702
703 CASE int attroff
704 I       chtype          str
705 END
706
707 CASE int wattroff
708 I       chtype          str
709 END
710
711 CASE int wattron
712 I       chtype          str
713 END
714
715 CASE int attron
716 I       chtype          str
717 END
718
719 CASE int attrset
720 I       chtype          str
721 END
722
723 CASE int wattrset
724 I       chtype          str
725 END
726
727 #ifdef  CURSEFMT
728     case US_printw:
729         if (items < 1)
730             fatal("Usage: &printw($fmt, $arg1, $arg2, ... )");
731         else {
732             int retval;
733             STR*        str =           str_new(0);
734
735             do_sprintf(str, items, st + 1);
736             retval = addstr(str->str_ptr);
737             str_numset(st[0], (double) retval);
738             str_free(str);
739         }
740         return sp;
741
742     case US_wprintw:
743         if (items < 2)
744             fatal("Usage: &wprintw($win, $fmt, $arg1, $arg2, ... )");
745         else {
746             int retval;
747             STR*        str =           str_new(0);
748             WINDOW*     win =           *(WINDOW**)     str_get(st[1]);
749
750             do_sprintf(str, items - 1, st + 1);
751             retval = waddstr(win, str->str_ptr);
752             str_numset(st[0], (double) retval);
753             str_free(str);
754         }
755         return sp;
756
757 #endif
758
759 CASE char* getcap
760 I       char*           str
761 END
762
763 #ifdef BSD
764 CASE int flushok
765 I       WINDOW*         win
766 I       bool            boolf
767 END
768
769 CASE int fullname
770 I       char*           termbuf
771 IO      char*           name
772 END
773
774 CASE int touchoverlap
775 I       WINDOW*         win1
776 I       WINDOW*         win2
777 END
778
779 CASE int tstp
780 END
781
782 CASE int _putchar
783 I       char            ch
784 END
785
786     case US_testcallback:
787         sp = callback("callback", sp + items, curcsv->wantarray, 1, items);
788         break;
789
790 #endif
791
792     default:
793         fatal("Unimplemented user-defined subroutine");
794     }
795     return sp;
796 }
797
798 static int
799 userval(ix, str)
800 int ix;
801 STR *str;
802 {
803     switch (ix) {
804     case UV_COLS:
805         str_numset(str, (double)COLS);
806         break;
807     case UV_ERR:
808         str_numset(str, (double)ERR);
809         break;
810     case UV_LINES:
811         str_numset(str, (double)LINES);
812         break;
813     case UV_OK:
814         str_numset(str, (double)OK);
815         break;
816     case UV_curscr:
817         str_nset(str, &curscr, sizeof(WINDOW*));
818         break;
819     case UV_stdscr:
820         str_nset(str, &stdscr, sizeof(WINDOW*));
821         break;
822     case UV_ttytype:
823         str_set(str, ttytype);
824         break;
825 #ifdef BSD
826     case UV_Def_term:
827         str_set(str, Def_term);
828         break;
829     case UV_My_term:
830         str_numset(str, (double)My_term);
831         break;
832 #endif
833     case UV_A_STANDOUT:
834         str_numset(str, (double)A_STANDOUT);
835         break;
836     case UV_A_UNDERLINE:
837         str_numset(str, (double)A_UNDERLINE);
838         break;
839     case UV_A_REVERSE:
840         str_numset(str, (double)A_REVERSE);
841         break;
842     case UV_A_BLINK:
843         str_numset(str, (double)A_BLINK);
844         break;
845     case UV_A_DIM:
846         str_numset(str, (double)A_DIM);
847         break;
848     case UV_A_BOLD:
849         str_numset(str, (double)A_BOLD);
850         break;
851     case UV_A_NORMAL:
852         str_numset(str, (double)A_NORMAL);
853         break;
854     }
855     return 0;
856 }
857
858 static int
859 userset(ix, str)
860 int ix;
861 STR *str;
862 {
863     switch (ix) {
864     case UV_COLS:
865         COLS = (int)str_gnum(str);
866         break;
867     case UV_LINES:
868         LINES = (int)str_gnum(str);
869         break;
870     case UV_ttytype:
871         strcpy(ttytype, str_get(str));          /* hope it fits */
872 #ifdef USG
873         if (tcbuf != NULL) {
874             free(tcbuf);
875             tcbuf = NULL;
876         }
877 #endif  
878         break;
879 #ifdef BSD
880     case UV_Def_term:
881         Def_term = savestr(str_get(str));       /* never freed */
882         break;
883     case UV_My_term:
884         My_term = (bool)str_gnum(str);
885         break;
886 #endif
887     }
888     return 0;
889 }