ARPDAS_QNX6 1.0
|
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 }