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