/* Copyright (c) 1987 Bellcore * All Rights Reserved * Permission is granted to copy or use this program, EXCEPT that it * may not be sold for profit, the copyright notice must be reproduced * on copies, and credit should be given to Bellcore where it is due. * BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. */ /* $Header: term.c,v 4.3 88/07/01 09:33:49 bianchi Exp $ $Source: /tmp/mgrsrc/lib/RCS/term.c,v $ */ static char RCSid_[] = "$Source: /tmp/mgrsrc/lib/RCS/term.c,v $$Revision: 4.3 $"; /* routines for writing to mgr terminal emulator */ #include "term.h" #include "restart.h" FILE *m_termout; FILE *m_termin; int m_flags; int m_envcount = 0; int m_saveenvcount = 0; char m_escchar = ESC; char m_menuchar = M_DELIM; jmp_buf _env; struct sgttyb sgtty__save[TTYMAX]; int sgtty_cnt = 0; char m_linebuf[MAXLINE]; static char *m_fields[16]; /****************************************************************************** * * setup */ int m_setup(flags) int flags; { m_flags = flags; #ifdef atarist _binmode(1); #endif if (!(m_flags&M_DEBUG)) { m_termout = fopen(M_DEVICEOUT,"w"); m_termin = fopen(M_DEVICEIN,"r"); } if (m_termin == NULL || m_termout == NULL) m_flags |= M_DEBUG; if (m_flags&M_DEBUG) { m_termin = stdin; m_termout = stdout; } return(m_flags); } /****************************************************************************** * * get generic window parameters */ int get_info(type,list) int type; char **list; { if (type > G_MAX ) return(-1); switch( type ) { case G_ALL: case G_ALLMINE: return(-1); } _m_ttyset(); m_getinfo(type); m_gets(m_linebuf); _m_ttyreset(); return parse(m_linebuf,list); } /****************************************************************************** * * read window parameters off of standard input */ int get_windata(windatap) struct window_data *windatap; { if( parse(m_gets(m_linebuf),m_fields) < 8 ) return 0; windatap->x = atoi(m_fields[0]); windatap->y = atoi(m_fields[1]); windatap->w = atoi(m_fields[2]); windatap->h = atoi(m_fields[3]); strcpy(windatap->tty,m_fields[4]); windatap->num = atoi(m_fields[5]); windatap->status = *m_fields[6]; windatap->setid = atoi(m_fields[7]); return 1; } /****************************************************************************** * * Get window parameters, one window at a time. * Returns 1 if window_data structure has been filled, 0 otherwise. * It is important to call get_eachwin() in a tight loop that doesn't * ever exit, so that all the data is picked up. */ int get_eachwin( windatap ) struct window_data *windatap; { static int i = 0; if( !i ) { _m_ttyset(); m_getinfo(G_ALL); } i = get_windata( windatap ); if( !i ) _m_ttyreset(); return(i); } /****************************************************************************** * * Get window parameters for the current window set, one window at a time. * Returns 1 if window_data structure has been filled, 0 otherwise. * It is important to call get_eachcleintwin() in a tight loop that * doesn' tever exit, so that all the data is picked up. */ int get_eachclientwin( windatap ) struct window_data *windatap; { static int i = 0; if( !i ) { _m_ttyset(); m_getinfo(G_ALLMINE); } i = get_windata( windatap ); if( !i ) _m_ttyreset(); return(i); } /****************************************************************************** * * Get all window parameters. * NOTE CAREFULLY: The array of window_data structures pointed to by * list must be more than the total number of windows on the screen; * not a robust technique. * get_eachwin() is recommended above this. */ int get_all(list) struct window_data *list; { register int i; for(i=0; get_eachwin( list ); i++ ) list++; return(i); } /****************************************************************************** * * Get window parameters for client windows. * NOTE CAREFULLY: The array of window_data structures pointed to by * list must be more than the total number of windows on the screen; * not a robust technique. * get_eachclientwin() is recommended above this. */ int get_client(list) struct window_data *list; { register int i; _m_ttyset(); m_getinfo(G_ALLMINE); for(i=0; get_windata( list ); i++ ) list++; _m_ttyreset(); return(i); } /****************************************************************************** * * get the window size */ int get_size(x,y,wide,high) int *x, *y, *wide, *high; { register int count; if ((count = get_info(G_COORDS,m_fields)) >= 4) { if (x) *x = atoi(m_fields[0]); if (y) *y = atoi(m_fields[1]); if (wide) *wide = atoi(m_fields[2]); if (high) *high = atoi(m_fields[3]); return(count); } else return(-count); } /****************************************************************************** * * get the mouse coords */ int get_mouse(x,y) int *x, *y; { register int count; if ((count = get_info(G_MOUSE2,m_fields)) >= 3) { if (x) *x = atoi(m_fields[0]); if (y) *y = atoi(m_fields[1]); return(atoi(m_fields[2])); } else return(-count); } /****************************************************************************** * * get system parameters */ int get_param(host,xmax,ymax,border) char *host; int *xmax, *ymax, *border; { register int count; if ((count = get_info(G_SYSTEM,m_fields)) >= 4) { if (host) strcpy(host,m_fields[0]); if (xmax) *xmax = atoi(m_fields[1]); if (ymax) *ymax = atoi(m_fields[2]); if (border) *border = atoi(m_fields[3]); return(count); } else return(-count); } /****************************************************************************** * * get the cursor position */ int get_cursor(x,y) int *x, *y; { register int count; if ((count = get_info(G_CURSOR,m_fields)) > 2) { if (x) *x = atoi(m_fields[0]); if (y) *y = atoi(m_fields[1]); return(2); } else return(-count); } /****************************************************************************** * * get the window size - rows and columns */ int get_colrow(cols,rows) int *cols, *rows; { register int count; if ((count = get_info(G_WINSIZE,m_fields)) == 2) { if (cols) *cols = atoi(m_fields[0]); if (rows) *rows = atoi(m_fields[1]); return(2); } else return(-count); } /****************************************************************************** * * get the termcap entry */ char * get_termcap() { _m_ttyset(); m_getinfo(G_TERMCAP); m_gets(m_linebuf); _m_ttyreset(); return(m_linebuf); } /****************************************************************************** * * get the font size */ int get_font(wide,high) int *wide, *high; { register int count, result; if ((count = get_info(G_FONT,m_fields)) >= 3) { if (wide) *wide = atoi(m_fields[0]); if (high) *high = atoi(m_fields[1]); result = atoi(m_fields[2]); return(result); } else return(-count); } /****************************************************************************** * * make a new window */ int m_makewindow(x,y,wide,high) int x,y,wide,high; { register int count, result; _m_ttyset(); m_newwin(x,y,wide,high); m_gets(m_linebuf); _m_ttyreset(); return(atoi(m_linebuf)); } /****************************************************************************** * * see if window is active */ int is_active() { *m_linebuf = '\0'; get_info(G_STATUS,m_fields); return(*m_linebuf == 'a'); } /****************************************************************************** * * return last line read */ char * m_lastline() { return(m_linebuf); } /****************************************************************************** * * down load a menu */ menu_load(n,count,text) int n; /* menu number */ int count; /* number of menu items */ struct menu_entry *text; /* menu choices */ { register int i, len; if (text == (struct menu_entry *) 0) return (-1); /* calculate string lengths */ len = 2 * count + 1; for (i=0;i 0) fputc(*data++,m_termout); m_flush(); } /****************************************************************************** * * Set and save the terminal mode (if required); */ m_ttyset() { int code; struct sgttyb buff; code = gtty(fileno(m_termout),sgtty__save + sgtty_cnt); if (sgtty__save[sgtty_cnt].sg_flags&(ECHO|RAW)) { buff = sgtty__save[sgtty_cnt]; buff.sg_flags &= ~(ECHO|RAW); m_flush(); stty(fileno(m_termout),&buff); } if (sgtty_cnt < TTYMAX) sgtty_cnt++; return(code); } /****************************************************************************** * * Restore the terminal mode */ m_ttyreset() { if (sgtty_cnt) sgtty_cnt--; else return(1); if (sgtty__save[sgtty_cnt].sg_flags&(ECHO|RAW)) { m_flush(); return(stty(fileno(m_termout),sgtty__save + sgtty_cnt)); } else return(0); } /****************************************************************************** * * change the terminal modes */ m_resetflags(flags) { struct sgttyb buff; gtty(fileno(m_termin),&buff); if (buff.sg_flags & flags) { buff.sg_flags &= ~flags; m_flush(); stty(fileno(m_termin),&buff); } } m_setflags(flags) { struct sgttyb buff; gtty(fileno(m_termin),&buff); if (!( buff.sg_flags & flags)) { buff.sg_flags |= flags; m_flush(); stty(fileno(m_termin),&buff); } } /** Given a bitmap id and an icon name, have mgr load that icon into that bitmap, returning the icon width and height via the given integer pointers. Return a positive number if successful. If the icon is not loaded, set the width and height values to 0 and return 0. */ int m_bitfile( bitmapid, iconname, iconwidthp, iconheightp ) int bitmapid; char *iconname; int *iconwidthp, *iconheightp; { *iconwidthp = *iconheightp = 0; m_bitfromfile( bitmapid, iconname ); m_flush(); return( sscanf( m_get(), "%d %d", iconwidthp, iconheightp ) == 2 ); } /***************************************************************************** * parse a line into fields */ #ifndef iswhite #define iswhite(x) ((x)==' ' || (x)=='\t') #endif int parse(line,fields) register char *line; register char **fields; { int inword = 0; int count = 0; char *start; register char c; for(start = line;(c = *line) && c != '\n';line++) if (inword && iswhite(c)) { inword = 0; *line = '\0'; *fields++ = start; count++; } else if (!inword && !iswhite(c)) { start = line; inword = 1; } if (inword) { *fields++ = start; count++; if (c == '\n') *line = '\0'; } *fields = (char *) 0; return(count); } /****************************************** * stuff for restarting */ _Catch() { ioctl(fileno(m_termin),TIOCFLUSH,0); #ifdef atarist _discard(m_termout); #endif longjmp(_env,1); } _Clean() { #ifdef atarist _discard(m_termout); #endif while(m_saveenvcount < m_envcount) m_pop(); exit(1); } #ifdef atarist _discard(f) FILE *f; { f->_cnt = 0; f->_ptr = f->_base; } #endif