/* * GLIB - a Generic LIBrarian and editor for synths * * Machine dependent stuff. * * Unix version */ #include "glib.h" #include int Rows, Cols; #include /* Ultrix curses fix -- gl */ #ifdef ULTRIX #undef nl() #undef nonl() #define nl() (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty)) #define nonl() (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty)) #endif #ifdef ARROW #include #include #include jmp_buf wakeup; #endif #ifndef ARROW initkbd() {} resetkbd() {} nmgetch() { return (getchar() & 0x7f); } #else /*ARROW*/ /* Following code for arrow key support lifted from * James Gosling's sc spreadsheet calculator -- gl */ #define N_KEY 4 struct key_map { char *k_str; char k_val; char k_index; }; struct key_map km[N_KEY]; char keyarea[N_KEY*10]; char *tgetstr(); char *getenv(); #ifdef TIOCSLTC struct ltchars old_chars, new_chars; #endif char dont_use[] = { ctl('z'), ctl('r'), ctl('l'), ctl('b'), ctl('c'), ctl('f'), ctl('g'), ctl('['), ctl('h'), ctl('m'), ctl('j'), ctl('n'), ctl('p'), ctl('q'), ctl('s'), ctl('t'), ctl('u'), ctl('v'), ctl('e'), ctl('a'), 0, }; initkbd() { register struct key_map *kp; register i,j; char *ks; char *p = keyarea; static char buf[1024]; /* Why do I have to do this again? */ if (tgetent(buf, getenv("TERM")) <= 0) return; km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl('b'); km[1].k_str = tgetstr("kr", &p); km[1].k_val = ctl('f'); km[2].k_str = tgetstr("ku", &p); km[2].k_val = ctl('p'); km[3].k_str = tgetstr("kd", &p); km[3].k_val = ctl('n'); ks = tgetstr("ks",&p); if (ks) printf("%s",ks); /* Unmap arrow keys which conflict with our ctl keys */ /* Ignore unset, longer than length 1, and 1-1 mapped keys */ for (i = 0; i < N_KEY; i++) { kp = &km[i]; if (kp->k_str && (kp->k_str[1] == 0) && (kp->k_str[0] != kp->k_val)) for (j = 0; dont_use[j] != 0; j++) if (kp->k_str[0] == dont_use[j]) { kp->k_str = (char *)0; break; } } #ifdef TIOCSLTC ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars); new_chars = old_chars; if (old_chars.t_lnextc == ctl('v')) new_chars.t_lnextc = -1; if (old_chars.t_rprntc == ctl('r')) new_chars.t_rprntc = -1; ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars); #endif } resetkbd() { #ifdef TIOCSLTC ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars); #endif } nmgetch() { register int c; register struct key_map *kp; register struct key_map *biggest; register int i; int almost; int maybe; static char dumpbuf[10]; static char *dumpindex; int timeout(); if (dumpindex && *dumpindex) return (*dumpindex++); c = getchar() & 0x7f; biggest = 0; almost = 0; for (kp = &km[0]; kp < &km[N_KEY]; kp++) { if (!kp->k_str) continue; if (c == kp->k_str[kp->k_index]) { almost = 1; kp->k_index++; if (kp->k_str[kp->k_index] == 0) { c = kp->k_val; for (kp = &km[0]; kp < &km[N_KEY]; kp++) kp->k_index = 0; return(c); } } if (!biggest && kp->k_index) biggest = kp; else if (kp->k_index && biggest->k_index < kp->k_index) biggest = kp; } if (almost) { signal(SIGALRM, timeout); alarm(1); if (setjmp(wakeup) == 0) { maybe = nmgetch(); alarm(0); return(maybe); } } if (biggest) { for (i = 0; ik_index; i++) dumpbuf[i] = biggest->k_str[i]; dumpbuf[i++] = c; dumpbuf[i] = 0; dumpindex = &dumpbuf[1]; for (kp = &km[0]; kp < &km[N_KEY]; kp++) kp->k_index = 0; return (dumpbuf[0]); } return(c); } timeout() { longjmp(wakeup, -1); } #endif /* ARROW */ hello() { } bye() { windgoto(22,0); windrefresh(); resetkbd(); windexit(0); } /* getmouse - get currect row and column of mouse */ getmouse(amr,amc) int *amr; int *amc; { #ifdef USEMOUSE /* no such */ #else *amr = -1; *amc = -1; #endif } /* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */ statmouse() { #ifdef USEMOUSE /* no such */ #else return(-1); #endif } /* Return when either a console key or mouse button is pressed. */ mouseorkey() { #ifdef USEMOUSE /* no such */ #else return(nmgetch()); /* return(getconsole()); */ #endif } flushconsole() { } statconsole() { return(1); } getconsole() { return(getchar()); } getmidi() { return(-1); } statmidi() { return(0); } /*ARGSUSED*/ sendmidi(c) { } flushmidi() { while ( STATMIDI ) getmidi(); } long milliclock() { static long hzcount = 0; return(hzcount++); } millisleep(n) { sleep((n+500)/1000); } char * alloc(n) { char *p; if ( (p=malloc((unsigned)n)) == (char *)NULL ) { printf("*** Whoops *** alloc has failed?!? No more memory!\n"); fflush(stdout); bye(); } return(p); } windinit() { char *getenv(); initscr(); Cols = 80; Rows = 24; noecho(); nonl(); #ifdef BSD crmode(); #else cbreak(); #endif initkbd(); } windgoto(r,c) int r,c; { move(r,c); } windeeol() { clrtoeol(); } winderaserow(r) { windgoto(r,0); windeeol(); } windexit(r) int r; { #ifdef BSD nocrmode(); #else nocbreak(); #endif nl(); echo(); endwin(); exit(r); } windclear() { clear(); } /* windgets - get a line of input from the console, handling backspaces */ windgets(s) char *s; { char *origs = s; int c; while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) { if ( c == '\b' ) { if ( s > origs ) { windstr("\b \b"); s--; } } else { windputc(c); *s++ = c; } windrefresh(); } *s = '\0'; } windstr(s) char *s; { int c; while ( (c=(*s++)) != '\0' ) windputc(c); } windputc(c) int c; { addch(c); } windrefresh() { refresh(); } beep() { putchar('\007'); } windhigh() { standout(); } windnorm() { standend(); } /**************** * openls(), nextls(), and closels() are used to scan the current directory. ***************/ FILE *Phrlist = NULL; openls() { FILE *popen(); Phrlist = popen("ls","r"); } char * nextls() { static char fname[65]; if ( fscanf(Phrlist,"%s",fname) != 1 ) return(NULL); return(fname); } closels() { pclose(Phrlist); } #ifdef FAKECBREAK #include struct termio Initterm; static int First = 1; cbreak() { struct termio termbuff; if ( First ) { First = 0; ioctl(0,TCGETA,&Initterm); } termbuff = Initterm; termbuff.c_lflag &= (~ICANON); termbuff.c_cc[4] = 1; termbuff.c_cc[5] = 1; ioctl(0,TCSETA,&termbuff); } nocbreak() { ioctl(0,TCSETA,&Initterm); } #endif