ARPDAS_QNX6 1.0
nctable.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <ncurses.h>
00004 #include <unistd.h>
00005 #include "nortlib.h"
00006 #include "nctable.h"
00007 #include "tm.h"
00008 #include "nl_assert.h"
00009 #include "oui.h"
00010 
00011 #define MAX_DEVS 34
00012 
00013 typedef struct {
00014   char *dev_name;
00015   SCREEN *screen;
00016   FILE *ofp, *ifp;
00017   int ifd;
00018   int dirty;
00019 } nct_display_t;
00020 
00021 static nct_display_t nct_display[MAX_DEVS];
00022 static int n_devs = 0;
00023 static int n_scrs = 0;
00024 static int cur_scr_num;
00025 static char *ttype;
00026 static int ifds_opened = 0;
00027 static int nct_cmd_quit_fd = -1;
00028 
00029 static inline void nct_select(int n) {
00030   nl_assert(n < n_scrs );
00031   if (cur_scr_num != n) {
00032     cur_scr_num = n;
00033     set_term(nct_display[n].screen);
00034   }
00035 }
00036 
00037 static inline void mark_dirty(void) {
00038   nct_display[cur_scr_num].dirty = 1;
00039 }
00040 
00041 static inline int is_dirty(int n) {
00042   return nct_display[n].dirty;
00043 }
00044 
00045 void nct_args( char *dev_name ) {
00046   if ( n_devs >= MAX_DEVS )
00047     nl_error( 2, "Too many devices specified" );
00048   else nct_display[n_devs++].dev_name = dev_name;
00049 }
00050 
00051 void nct_init_options(int argc, char **argv) {
00052   int optltr;
00053 
00054   optind = OPTIND_RESET;
00055   opterr = 0;
00056   while ((optltr = getopt(argc, argv, opt_string)) != -1) {
00057     switch (optltr) {
00058       case 'a':
00059         nct_charset(NCT_CHARS_ASCII);
00060         break;
00061       case '?':
00062         nl_error(3, "Unrecognized Option -%c", optopt);
00063       default:
00064         break;
00065     }
00066   }
00067   for (; optind < argc; optind++) {
00068     nct_args(argv[optind]);
00069   }
00070 }
00071 
00072 static void nct_shutdown(void) {
00073   int i;
00074   for ( i = 0; i < n_scrs; i++ ) {
00075     nct_display_t *d = &nct_display[i];
00076     set_term(d->screen);
00077     clear();
00078     refresh();
00079     reset_prog_mode();
00080     endwin();
00081     delscreen(d->screen);
00082     fclose(d->ofp);
00083     fclose(d->ifp);
00084   }
00085   while ( ifds_opened > 0 ) {
00086     close(nct_display[--ifds_opened].ifd);
00087   }
00088 }
00089 
00090 /**
00091  * Initializes an ncurses display. nct_init() cannot be called
00092  * after nct_getch().
00093  * @return the screen number.
00094  */
00095 int nct_init( const char *winname, int n_rows, int n_cols ) {
00096   FILE *ofp, *ifp;
00097   char *dev_name;
00098   SCREEN *scr;
00099   nct_display_t *d;
00100 
00101   if ( n_scrs >= n_devs )
00102     nl_error( 3, "Not enough devices specified" );
00103   if ( ttype == NULL ) {
00104     ttype = getenv("TERM");
00105     if ( ttype == NULL )
00106       nl_error(3, "Cannot determine terminal type");
00107   }
00108   d = &nct_display[n_scrs];
00109   dev_name = d->dev_name;
00110   d->ofp = ofp = fopen( dev_name, "w" );
00111   if (ofp == NULL)
00112     nl_error( 3, "Cannot open %s for write", dev_name ); 
00113   d->ifp = ifp = fopen( dev_name, "r" );
00114   if (ifp == NULL)
00115     nl_error( 3, "Cannot open %s for read", dev_name );
00116   d->screen = scr = newterm(ttype, ofp, ifp );
00117   d->dirty = 0;
00118   set_term(scr);
00119   def_prog_mode();
00120   curs_set(0);
00121   if ( n_scrs == 0 )
00122     atexit( &nct_shutdown );
00123   return n_scrs++;
00124 }
00125 
00126 int nct_cmdclt_init() {
00127   int nct_win = nct_init("cmd", 2, 80);
00128   if (cic_init()) exit(1);
00129   nct_cmd_quit_fd = cic_cmd_quit_fd;
00130   return nct_win;
00131 }
00132 
00133 void nct_refresh(void) {
00134   int i;
00135   for (i = 0; i < n_scrs; i++) {
00136     if (is_dirty(i)) {
00137       nct_select(i);
00138       refresh();
00139       nct_display[i].dirty = 0;
00140     }
00141   }
00142 }
00143 
00144 /** \brief Write string to an ncurses display
00145  *
00146  * winnum is the window number returned by nct_init();
00147  * attr is the atribute number (a small integer) as set
00148  * by nctable. This should map to screen colors, but
00149  * the implementation of that will have to wait.
00150  *
00151  */
00152 void nct_string( int winnum, int attr, int row, int col, const char *text ) {
00153   nct_select(winnum);
00154   // color_set(color_pair_table(attr), NULL);
00155   mvaddstr(row, col, text);
00156   mark_dirty();
00157 }
00158 
00159 void nct_clear( int winnum ) {
00160   nct_select(winnum);
00161   clear();
00162   mark_dirty();
00163 }
00164 
00165 static unsigned char grphchar[81] = {
00166   '\x20', /*  0 = 0000 */
00167   '\xB3', /*  1 = 0001 */
00168   '\xBA', /*  2 = 0002 */
00169   '\xB3', /*  3 = 0010 */
00170   '\xB3', /*  4 = 0011 */
00171   '\xBA', /*  5 = 0012 */
00172   '\xBA', /*  6 = 0020 */
00173   '\xBA', /*  7 = 0021 */
00174   '\xBA', /*  8 = 0022 */
00175   '\xC4', /*  9 = 0100 */
00176   '\xDA', /* 10 = 0101 */
00177   '\xD6', /* 11 = 0102 */
00178   '\xC0', /* 12 = 0110 */
00179   '\xC3', /* 13 = 0111 */
00180   '\xD6', /* 14 = 0112 */
00181   '\xD3', /* 15 = 0120 */
00182   '\xD3', /* 16 = 0121 */
00183   '\xC7', /* 17 = 0122 */
00184   '\xCD', /* 18 = 0200 */
00185   '\xD5', /* 19 = 0201 */
00186   '\xC9', /* 20 = 0202 */
00187   '\xD4', /* 21 = 0210 */
00188   '\xC6', /* 22 = 0211 */
00189   '\xC9', /* 23 = 0212 */
00190   '\xC8', /* 24 = 0220 */
00191   '\xC8', /* 25 = 0221 */
00192   '\xCC', /* 26 = 0222 */
00193   '\xC4', /* 27 = 1000 */
00194   '\xBF', /* 28 = 1001 */
00195   '\xB7', /* 29 = 1002 */
00196   '\xD9', /* 30 = 1010 */
00197   '\xB4', /* 31 = 1011 */
00198   '\xB7', /* 32 = 1012 */
00199   '\xBD', /* 33 = 1020 */
00200   '\xBD', /* 34 = 1021 */
00201   '\xB6', /* 35 = 1022 */
00202   '\xC4', /* 36 = 1100 */
00203   '\xC2', /* 37 = 1101 */
00204   '\xD2', /* 38 = 1102 */
00205   '\xC1', /* 39 = 1110 */
00206   '\xC5', /* 40 = 1111 */
00207   '\xD2', /* 41 = 1112 */
00208   '\xD0', /* 42 = 1120 */
00209   '\xD0', /* 43 = 1121 */
00210   '\xD7', /* 44 = 1122 */
00211   '\xCD', /* 45 = 1200 */
00212   '\x20', /* 46 = 1201 */
00213   '\x20', /* 47 = 1202 */
00214   '\x20', /* 48 = 1210 */
00215   '\x20', /* 49 = 1211 */
00216   '\x20', /* 50 = 1212 */
00217   '\x20', /* 51 = 1220 */
00218   '\x20', /* 52 = 1221 */
00219   '\x20', /* 53 = 1222 */
00220   '\xCD', /* 54 = 2000 */
00221   '\xB8', /* 55 = 2001 */
00222   '\xBB', /* 56 = 2002 */
00223   '\xBE', /* 57 = 2010 */
00224   '\xB5', /* 58 = 2011 */
00225   '\x20', /* 59 = 2012 */
00226   '\xBC', /* 60 = 2020 */
00227   '\x20', /* 61 = 2021 */
00228   '\xB9', /* 62 = 2022 */
00229   '\x20', /* 63 = 2100 */
00230   '\x20', /* 64 = 2101 */
00231   '\x20', /* 65 = 2102 */
00232   '\x20', /* 66 = 2110 */
00233   '\x20', /* 67 = 2111 */
00234   '\x20', /* 68 = 2112 */
00235   '\x20', /* 69 = 2120 */
00236   '\x20', /* 70 = 2121 */
00237   '\x20', /* 71 = 2122 */
00238   '\xCD', /* 72 = 2200 */
00239   '\xD1', /* 73 = 2201 */
00240   '\xCB', /* 74 = 2202 */
00241   '\xCF', /* 75 = 2210 */
00242   '\xD8', /* 76 = 2211 */
00243   '\x20', /* 77 = 2212 */
00244   '\xCA', /* 78 = 2220 */
00245   '\x20', /* 79 = 2221 */
00246   '\xCE'  /* 80 = 2222 */
00247 };
00248 
00249 static unsigned char asciichar[81] = {
00250   ' ', /*  0 = LRTB */
00251   ',', /*  1 = 0001 */
00252   ',', /*  2 = 0002 */
00253   '\'', /*  3 = 0010 */
00254   '|', /*  4 = 0011 */
00255   '|', /*  5 = 0012 */
00256   '"', /*  6 = 0020 */
00257   '|', /*  7 = 0021 */
00258   '|', /*  8 = 0022 */
00259   '-', /*  9 = 0100 */
00260   '+', /* 10 = 0101 */
00261   '+', /* 11 = 0102 */
00262   '+', /* 12 = 0110 */
00263   '|', /* 13 = 0111 */
00264   '|', /* 14 = 0112 */
00265   '+', /* 15 = 0120 */
00266   '+', /* 16 = 0121 */
00267   '+', /* 17 = 0122 */
00268   '=', /* 18 = 0200 */
00269   '+', /* 19 = 0201 */
00270   '+', /* 20 = 0202 */
00271   '+', /* 21 = 0210 */
00272   '+', /* 22 = 0211 */
00273   '+', /* 23 = 0212 */
00274   '+', /* 24 = 0220 */
00275   '+', /* 25 = 0221 */
00276   '+', /* 26 = 0222 */
00277   '-', /* 27 = 1000 */
00278   '+', /* 28 = 1001 */
00279   '+', /* 29 = 1002 */
00280   '+', /* 30 = 1010 */
00281   '+', /* 31 = 1011 */
00282   '+', /* 32 = 1012 */
00283   '+', /* 33 = 1020 */
00284   '+', /* 34 = 1021 */
00285   '+', /* 35 = 1022 */
00286   '-', /* 36 = 1100 */
00287   '+', /* 37 = 1101 */
00288   '+', /* 38 = 1102 */
00289   '+', /* 39 = 1110 */
00290   '+', /* 40 = 1111 */
00291   '+', /* 41 = 1112 */
00292   '+', /* 42 = 1120 */
00293   '+', /* 43 = 1121 */
00294   '+', /* 44 = 1122 */
00295   '-', /* 45 = 1200 */
00296   '+', /* 46 = 1201 */
00297   '+', /* 47 = 1202 */
00298   '+', /* 48 = 1210 */
00299   '+', /* 49 = 1211 */
00300   '+', /* 50 = 1212 */
00301   '+', /* 51 = 1220 */
00302   '+', /* 52 = 1221 */
00303   '+', /* 53 = 1222 */
00304   '=', /* 54 = 2000 */
00305   '+', /* 55 = 2001 */
00306   '+', /* 56 = 2002 */
00307   '+', /* 57 = 2010 */
00308   '+', /* 58 = 2011 */
00309   '+', /* 59 = 2012 */
00310   '+', /* 60 = 2020 */
00311   '+', /* 61 = 2021 */
00312   '+', /* 62 = 2022 */
00313   '-', /* 63 = 2100 */
00314   '+', /* 64 = 2101 */
00315   '+', /* 65 = 2102 */
00316   '+', /* 66 = 2110 */
00317   '+', /* 67 = 2111 */
00318   '+', /* 68 = 2112 */
00319   '+', /* 69 = 2120 */
00320   '+', /* 70 = 2121 */
00321   '+', /* 71 = 2122 */
00322   '=', /* 72 = 2200 */
00323   '+', /* 73 = 2201 */
00324   '+', /* 74 = 2202 */
00325   '+', /* 75 = 2210 */
00326   '+', /* 76 = 2211 */
00327   '+', /* 77 = 2212 */
00328   '+', /* 78 = 2220 */
00329   '+', /* 79 = 2221 */
00330   '+'  /* 80 = 2222 */
00331 };
00332 
00333 static unsigned char *nct_boxchars = grphchar;
00334 
00335 void nct_charset(int n) {
00336   switch (n) {
00337     case NCT_CHARS_GR:
00338       nct_boxchars = grphchar;
00339       break;
00340     case NCT_CHARS_ASCII:
00341       nct_boxchars = asciichar;
00342       break;
00343     default:
00344       nl_error(2, "Invalid charset code" );
00345   }
00346 }
00347 
00348 void nct_hrule( int winnum, int attr, int row, int col,
00349                 unsigned char *rule ) {
00350   unsigned char *r = rule;
00351   nct_select(winnum);
00352   // color_set(color_pair_table(attr), NULL);
00353   while (*r) {
00354     mvaddch(row, col, nct_boxchars[*r]);
00355     ++r;
00356     ++col;
00357   }
00358 }
00359 
00360 void nct_vrule( int winnum, int attr, int row, int col,
00361                 unsigned char *rule ) {
00362   unsigned char *r = rule;
00363   nct_select(winnum);
00364   // color_set(color_pair_table(attr), NULL);
00365   while (*r) {
00366     mvaddch(row, col, nct_boxchars[*r]);
00367     ++r;
00368     ++row;
00369   }
00370 }
00371 
00372 #include <fcntl.h>
00373 #include <unix.h>
00374 #include <sys/select.h>
00375 
00376 #define IBUFSIZE 16
00377 
00378 char nct_getch(void) {
00379   static char ibuf[IBUFSIZE];
00380   static int nc = 0;
00381   static int bp = 0;
00382 
00383   while ( ifds_opened < n_devs ) {
00384     nct_display_t *d = &nct_display[ifds_opened++];
00385     d->ifd = open( d->dev_name, O_RDONLY|O_NONBLOCK );
00386     if ( d->ifd == -1 )
00387       nl_error(3, "Unable to read from %s: %d", d->dev_name, errno );
00388     if (ifds_opened < n_scrs) {
00389       nct_select(ifds_opened);
00390       curs_set(1); // Turn on the cursor
00391     }
00392   }
00393   nl_assert(ifds_opened >= n_devs);
00394   if (ifds_opened == n_devs && nct_cmd_quit_fd >= 0) {
00395     nct_display[ifds_opened++].ifd = nct_cmd_quit_fd;
00396   }
00397   for (;;) {
00398     if ( nc > 0 && bp < nc ) {
00399       return ibuf[bp++];
00400     } else {
00401       int i, width = 0, rv;
00402 
00403       nc = 0;
00404       bp = 0;
00405       fd_set fs;
00406       FD_ZERO(&fs);
00407       for ( i = 0; i < ifds_opened; i++ ) {
00408         int ifd = nct_display[i].ifd;
00409         FD_SET( ifd, &fs );
00410         if ( ifd >= width )
00411           width = ifd + 1;
00412       }
00413       rv = select(width, &fs, NULL, NULL, NULL);
00414       if ( rv == -1 ) {
00415         if ( errno != EINTR )
00416           nl_error( 3, "Error %d from select", errno );
00417       } else {
00418         for ( i = 0; i < ifds_opened; i++ ) {
00419           int ifd = nct_display[i].ifd;
00420           if ( FD_ISSET( ifd, &fs ) ) {
00421             int nb = read( ifd, &ibuf[nc], IBUFSIZE-nc );
00422             if ( nb == -1 ) {
00423               if (errno != EAGAIN && errno != EINTR)
00424                 nl_error( 3, "Error %d from read()", errno );
00425             } else if ( nb == 0 ) {
00426               nl_error( 0, "Read 0 bytes" );
00427               exit(0);
00428             } else {
00429               nc += nb;
00430             }
00431           }
00432         }
00433       }
00434     }
00435   }
00436 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines