OpenCOBOL 1.1pre-rel
screenio.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2009 Keisuke Nishida
00003  * Copyright (C) 2007-2009 Roger While
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public License
00007  * as published by the Free Software Foundation; either version 2.1,
00008  * or (at your option) any later version.
00009  * 
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU Lesser General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; see the file COPYING.LIB.  If
00017  * not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor
00018  * Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #ifdef  HAVE_UNISTD_H
00027 #include <unistd.h>
00028 #endif
00029 
00030 #define _XOPEN_SOURCE_EXTENDED
00031 #ifdef HAVE_NCURSES_H
00032 #include <ncursesw/ncurses.h>
00033 #define COB_GEN_SCREENIO
00034 #elif defined(HAVE_NCURSES_NCURSES_H)
00035 #include <ncursesw/ncurses.h>
00036 #define COB_GEN_SCREENIO
00037 #elif defined(HAVE_PDCURSES_H)
00038 #include <pdcurses.h>
00039 #define COB_GEN_SCREENIO
00040 #elif defined(HAVE_CURSES_H)
00041 #include <curses.h>
00042 #define COB_GEN_SCREENIO
00043 #endif
00044 
00045 #include "move.h"
00046 #include "coblocal.h"
00047 #include "screenio.h"
00048 
00049 /* Global variables */
00050 
00051 int     cob_screen_initialized = 0;
00052 int     cob_screen_mode = 0;
00053 
00054 #ifdef COB_GEN_SCREENIO
00055 
00056 struct cob_inp_struct {
00057         cob_screen      *scr;
00058         size_t          up_index;
00059         size_t          down_index;
00060         int             this_y;
00061         int             this_x;
00062 };
00063 
00064 #define COB_INP_SIZE    1920 * sizeof(struct cob_inp_struct)
00065 
00066 /* Local variables */
00067 
00068 static struct cob_inp_struct    *cob_base_inp = NULL;
00069 static size_t                   curr_index = 0;
00070 static size_t                   totl_index = 0;
00071 static size_t                   cob_has_color = 0;
00072 static size_t                   cob_extended_status = 0;
00073 static size_t                   cob_use_esc = 0;
00074 static int                      global_return;
00075 static int                      cob_current_y = 0;
00076 static int                      cob_current_x = 0;
00077 static int                      cob_max_y = 0;
00078 static int                      cob_max_x = 0;
00079 static short                    fore_color;
00080 static short                    back_color;
00081 
00082 /* Local functions */
00083 
00084 static void
00085 get_line_column (cob_field *fline, cob_field *fcol, int *line, int *col)
00086 {
00087         int     l;
00088         int     c;
00089         int     p;
00090 
00091         if (fline == NULL) {
00092                 *line = 0;
00093                 *col = 0;
00094                 return;
00095         }
00096 
00097         p = cob_get_int (fline);
00098 
00099         if (fcol == NULL) {
00100                 if (fline->size == 4) {
00101                         l = p / 100;
00102                         c = p % 100;
00103                 } else {
00104                         l = p / 1000;
00105                         c = p % 1000;
00106                 }
00107         } else {
00108                 l = p;
00109                 c = cob_get_int (fcol);
00110         }
00111         if (l > 0) {
00112                 l--;
00113         }
00114         if (c > 0) {
00115                 c--;
00116         }
00117         *line = l;
00118         *col = c;
00119 }
00120 
00121 static void
00122 cob_screen_attr (cob_field *fgc, cob_field *bgc, const int attr)
00123 {
00124         size_t          i;
00125         int             styles = 0;
00126         int             line;
00127         int             column;
00128         short           fgcolor;
00129         short           bgcolor;
00130         short           fgdef;
00131         short           bgdef;
00132 
00133         attrset (A_NORMAL);
00134         if (attr & COB_SCREEN_REVERSE) {
00135                 styles |= A_REVERSE;
00136         }
00137         if (attr & COB_SCREEN_HIGHLIGHT) {
00138                 styles |= A_BOLD;
00139         }
00140         if (attr & COB_SCREEN_BLINK) {
00141                 styles |= A_BLINK;
00142         }
00143         if (attr & COB_SCREEN_UNDERLINE) {
00144                 styles |= A_UNDERLINE;
00145         }
00146         if (styles) {
00147                 attron (styles);
00148         }
00149         if (cob_has_color) {
00150                 fgcolor = fore_color;
00151                 bgcolor = back_color;
00152                 if (fgc) {
00153                         switch (cob_get_int (fgc)) {
00154                         case COB_SCREEN_BLACK:
00155                                 fgcolor = COLOR_BLACK;
00156                                 break;
00157                         case COB_SCREEN_BLUE:
00158                                 fgcolor = COLOR_BLUE;
00159                                 break;
00160                         case COB_SCREEN_GREEN:
00161                                 fgcolor = COLOR_GREEN;
00162                                 break;
00163                         case COB_SCREEN_CYAN:
00164                                 fgcolor = COLOR_CYAN;
00165                                 break;
00166                         case COB_SCREEN_RED:
00167                                 fgcolor = COLOR_RED;
00168                                 break;
00169                         case COB_SCREEN_MAGENTA:
00170                                 fgcolor = COLOR_MAGENTA;
00171                                 break;
00172                         case COB_SCREEN_YELLOW:
00173                                 fgcolor = COLOR_YELLOW;
00174                                 break;
00175                         case COB_SCREEN_WHITE:
00176                                 fgcolor = COLOR_WHITE;
00177                                 break;
00178                         default:
00179                                 break;
00180                         }
00181                 }
00182                 if (bgc) {
00183                         switch (cob_get_int (bgc)) {
00184                         case COB_SCREEN_BLACK:
00185                                 bgcolor = COLOR_BLACK;
00186                                 break;
00187                         case COB_SCREEN_BLUE:
00188                                 bgcolor = COLOR_BLUE;
00189                                 break;
00190                         case COB_SCREEN_GREEN:
00191                                 bgcolor = COLOR_GREEN;
00192                                 break;
00193                         case COB_SCREEN_CYAN:
00194                                 bgcolor = COLOR_CYAN;
00195                                 break;
00196                         case COB_SCREEN_RED:
00197                                 bgcolor = COLOR_RED;
00198                                 break;
00199                         case COB_SCREEN_MAGENTA:
00200                                 bgcolor = COLOR_MAGENTA;
00201                                 break;
00202                         case COB_SCREEN_YELLOW:
00203                                 bgcolor = COLOR_YELLOW;
00204                                 break;
00205                         case COB_SCREEN_WHITE:
00206                                 bgcolor = COLOR_WHITE;
00207                                 break;
00208                         default:
00209                                 break;
00210                         }
00211                 }
00212                 for (i = 0; i < (size_t)COLOR_PAIRS; i++) {
00213                         pair_content ((short)i, &fgdef, &bgdef);
00214                         if (fgdef == fgcolor && bgdef == bgcolor) {
00215                                 break;
00216                         }
00217                         if (fgdef == 0 && bgdef == 0) {
00218                                 init_pair ((short)i, fgcolor, bgcolor);
00219                                 break;
00220                         }
00221                 }
00222                 if (i != (size_t)COLOR_PAIRS) {
00223 #ifdef  HAVE_COLOR_SET
00224                         color_set (COLOR_PAIR(i), (void *)0);
00225 #else
00226                         attrset (COLOR_PAIR(i));
00227 #endif
00228                         bkgdset (COLOR_PAIR(i));
00229                 } else {
00230                         attrset (A_NORMAL);
00231                 }
00232         }
00233         if (attr & COB_SCREEN_BLANK_SCREEN) {
00234                 getyx (stdscr, line, column);
00235                 clear ();
00236                 move (line, column);
00237         }
00238         if (attr & COB_SCREEN_BLANK_LINE) {
00239                 getyx (stdscr, line, column);
00240                 move (line, 0);
00241                 clrtoeol ();
00242                 move (line, column);
00243         }
00244         if (attr & COB_SCREEN_ERASE_EOL) {
00245                 clrtoeol ();
00246         }
00247         if (attr & COB_SCREEN_ERASE_EOS) {
00248                 clrtobot ();
00249         }
00250         if (attr & COB_SCREEN_BELL) {
00251                 beep ();
00252         }
00253 }
00254 
00255 static void COB_NOINLINE
00256 cob_screen_init (void)
00257 {
00258         char    *s;
00259 
00260         if (!cob_screen_initialized) {
00261                 s = getenv ("COB_SCREEN_EXCEPTIONS");
00262                 if (s) {
00263                         if (*s == 'Y' || *s == 'y') {
00264                                 cob_extended_status = 1;
00265                                 s = getenv ("COB_SCREEN_ESC");
00266                                 if (s) {
00267                                         if (*s == 'Y' || *s == 'y') {
00268                                                         cob_use_esc = 1;
00269                                         }
00270                                 }
00271                         }
00272                 }
00273                 fflush (stdout);
00274                 fflush (stderr);
00275                 if (!initscr ()) {
00276                         cob_runtime_error ("Failed to initialize curses");
00277                         cob_stop_run (1);
00278                 }
00279                 cbreak ();
00280                 keypad (stdscr, 1);
00281                 nl ();
00282                 noecho ();
00283                 if (has_colors ()) {
00284                         start_color ();
00285                         pair_content ((short)0, &fore_color, &back_color);
00286                         if (COLOR_PAIRS) {
00287                                 cob_has_color = 1;
00288                         }
00289                 }
00290                 attrset (A_NORMAL);
00291                 getmaxyx (stdscr, cob_max_y, cob_max_x);
00292                 cob_screen_initialized = 1;
00293         }
00294 }
00295 
00296 void
00297 cob_screen_terminate (void)
00298 {
00299         if (cob_screen_initialized) {
00300                 cob_screen_initialized = 0;
00301                 endwin ();
00302         }
00303 }
00304 
00305 static void COB_NOINLINE
00306 cob_check_pos_status (int fret)
00307 {
00308         cob_field       *f;
00309         int             sline;
00310         int             scolumn;
00311         char            datbuf[8];
00312 
00313         if (fret) {
00314                 cob_set_exception (COB_EC_IMP_ACCEPT);
00315         }
00316         if (cob_current_module->crt_status) {
00317                 if (COB_FIELD_IS_NUMERIC (cob_current_module->crt_status)) {
00318                         cob_set_int (cob_current_module->crt_status, fret);
00319                 } else {
00320                         sprintf(datbuf, "%4.4d", fret);
00321                         memcpy (cob_current_module->crt_status->data, datbuf, 4);
00322                 }
00323         }
00324         if (cob_current_module->cursor_pos) {
00325                 getyx (stdscr, sline, scolumn);
00326                 f = cob_current_module->cursor_pos;
00327                 if (COB_FIELD_IS_NUMERIC (f) &&
00328                     COB_FIELD_TYPE (f) != COB_TYPE_NUMERIC_DISPLAY) {
00329                         sline *= 1000;
00330                         sline += scolumn;
00331                         cob_set_int (f, sline);
00332                 } else {
00333                         if (f->size < 6) {
00334                                 sline *= 100;
00335                                 sline += scolumn;
00336                                 sprintf(datbuf, "%4.4d", sline);
00337                                 memcpy (f->data, datbuf, 4);
00338                         } else {
00339                                 sline *= 1000;
00340                                 sline += scolumn;
00341                                 sprintf(datbuf, "%6.6d", sline);
00342                                 memcpy (f->data, datbuf, 6);
00343                         }
00344                 }
00345         }
00346 }
00347 
00348 static void
00349 cob_screen_puts (cob_screen *s, cob_field *f)
00350 {
00351         unsigned char   *p;
00352         size_t          size;
00353         int             y;
00354         int             x;
00355         int             line;
00356         int             column;
00357 
00358         getyx (stdscr, y, x);
00359         if (!s->line) {
00360                 line = y;
00361         } else {
00362                 line = cob_get_int (s->line) - 1;
00363                 if (line < 0) {
00364                         line = y;
00365                 }
00366         }
00367         if (!s->column) {
00368                 column = x;
00369         } else {
00370                 column = cob_get_int (s->column) - 1;
00371                 if (column < 0) {
00372                         column = x;
00373                 }
00374         }
00375         if (s->attr & COB_SCREEN_LINE_PLUS) {
00376                 line = y + line + 1;
00377         } else if (s->attr & COB_SCREEN_LINE_MINUS) {
00378                 line = y - line + 1;
00379         }
00380         if (s->attr & COB_SCREEN_COLUMN_PLUS) {
00381                 column = x + column + 1;
00382         } else if (s->attr & COB_SCREEN_COLUMN_MINUS) {
00383                 column = x - column + 1;
00384         }
00385         move (line, column);
00386         cob_current_y = line;
00387         cob_current_x = column;
00388         cob_screen_attr (s->foreg, s->backg, s->attr);
00389         if (s->attr & COB_SCREEN_INPUT) {
00390                 p = f->data;
00391                 for (size = 0; size < f->size; size++, p++) {
00392                         if (s->attr & COB_SCREEN_SECURE) {
00393                                 addch ('*');
00394                         } else if (*p <= ' ') {
00395                                 addch ('_');
00396                         } else {
00397                                 addch (*p);
00398                         }
00399                 }
00400         } else {
00401                 addnstr ((char *)f->data, (int)f->size);
00402         }
00403         refresh ();
00404 }
00405 
00406 static void
00407 cob_screen_get_all (void)
00408 {
00409         struct cob_inp_struct   *sptr;
00410         cob_screen              *s;
00411         unsigned char           *p;
00412         int                     keyp;
00413         int                     sline;
00414         int                     scolumn;
00415         int                     cline;
00416         int                     ccolumn;
00417         int                     rightpos;
00418         int                     ateof;
00419         int                     gotbacksp;
00420         int                     ungetched;
00421 
00422         sptr = cob_base_inp;
00423         s = sptr->scr;
00424         sline = sptr->this_y;
00425         scolumn = sptr->this_x;
00426         move (sline, scolumn);
00427         cob_screen_attr (s->foreg, s->backg, s->attr);
00428 /* RXW
00429         p = s->field->data;
00430         for (count = 0; count < s->field->size; count++) {
00431                 if (s->attr & COB_SCREEN_UPDATE) {
00432                         keyp = *p++;
00433                         addch (keyp);
00434                 } else if (s->attr & COB_SCREEN_PROMPT) {
00435                         addch ('_');
00436                 } else {
00437                         addch (' ');
00438                 }
00439         }
00440         move (sline, scolumn);
00441 */
00442         ateof = 0;
00443         gotbacksp = 0;
00444         ungetched = 0;
00445         rightpos = scolumn + s->field->size - 1;
00446         p = s->field->data;
00447         for (; ;) {
00448                 refresh ();
00449                 keyp = getch ();
00450                 if (keyp == KEY_ENTER || keyp == '\n') {
00451                         break;
00452                 }
00453                 if (keyp > KEY_F0 && keyp < KEY_F(65)) {
00454                         global_return = 1000 + keyp - KEY_F0;
00455                         break;
00456                 }
00457                 if (cob_extended_status) {
00458                         if (keyp == KEY_PPAGE) {
00459                                 global_return = 2001;
00460                                 break;
00461                         }
00462                         if (keyp == KEY_NPAGE) {
00463                                 global_return = 2002;
00464                                 break;
00465                         }
00466                         if (keyp == KEY_PRINT) {
00467                                 global_return = 2006;
00468                                 break;
00469                         }
00470                         if (cob_use_esc) {
00471                                 if (keyp == 033) {
00472                                         global_return = 2005;
00473                                         break;
00474                                 }
00475                         }
00476                 }
00477                 if (keyp == 011) {
00478                         if (curr_index < totl_index - 1) {
00479                                 curr_index++;
00480                         } else {
00481                                 curr_index = 0;
00482                         }
00483                         sptr = cob_base_inp + curr_index;
00484                         s = sptr->scr;
00485                         sline = sptr->this_y;
00486                         scolumn = sptr->this_x;
00487                         ateof = 0;
00488                         gotbacksp = 0;
00489                         rightpos = scolumn + s->field->size - 1;
00490                         p = s->field->data;
00491                         move (sline, scolumn);
00492                         cob_screen_attr (s->foreg, s->backg, s->attr);
00493                         continue;
00494                 }
00495                 if (keyp == KEY_BTAB) {
00496                         if (curr_index > 0) {
00497                                 curr_index--;
00498                         } else {
00499                                 curr_index = totl_index - 1;
00500                         }
00501                         sptr = cob_base_inp + curr_index;
00502                         s = sptr->scr;
00503                         sline = sptr->this_y;
00504                         scolumn = sptr->this_x;
00505                         ateof = 0;
00506                         gotbacksp = 0;
00507                         rightpos = scolumn + s->field->size - 1;
00508                         if (ungetched) {
00509                                 ungetched = 0;
00510                                 p = s->field->data + rightpos;
00511                                 move (sline, rightpos);
00512                         } else {
00513                                 p = s->field->data;
00514                                 move (sline, scolumn);
00515                         }
00516                         cob_screen_attr (s->foreg, s->backg, s->attr);
00517                         continue;
00518                 }
00519                 if (keyp == KEY_UP) {
00520                         curr_index = sptr->up_index;
00521                         sptr = cob_base_inp + curr_index;
00522                         s = sptr->scr;
00523                         sline = sptr->this_y;
00524                         scolumn = sptr->this_x;
00525                         ateof = 0;
00526                         gotbacksp = 0;
00527                         rightpos = scolumn + s->field->size - 1;
00528                         p = s->field->data;
00529                         move (sline, scolumn);
00530                         cob_screen_attr (s->foreg, s->backg, s->attr);
00531                         continue;
00532                 }
00533                 if (keyp == KEY_DOWN) {
00534                         curr_index = sptr->down_index;
00535                         sptr = cob_base_inp + curr_index;
00536                         s = sptr->scr;
00537                         sline = sptr->this_y;
00538                         scolumn = sptr->this_x;
00539                         ateof = 0;
00540                         gotbacksp = 0;
00541                         rightpos = scolumn + s->field->size - 1;
00542                         p = s->field->data;
00543                         move (sline, scolumn);
00544                         cob_screen_attr (s->foreg, s->backg, s->attr);
00545                         continue;
00546                 }
00547                 if (keyp == KEY_HOME) {
00548                         curr_index = 0;
00549                         sptr = cob_base_inp;
00550                         s = sptr->scr;
00551                         sline = sptr->this_y;
00552                         scolumn = sptr->this_x;
00553                         ateof = 0;
00554                         gotbacksp = 0;
00555                         rightpos = scolumn + s->field->size - 1;
00556                         p = s->field->data;
00557                         move (sline, scolumn);
00558                         cob_screen_attr (s->foreg, s->backg, s->attr);
00559                         continue;
00560                 }
00561                 if (keyp == KEY_END) {
00562                         curr_index = totl_index - 1;
00563                         sptr = cob_base_inp + curr_index;
00564                         s = sptr->scr;
00565                         sline = sptr->this_y;
00566                         scolumn = sptr->this_x;
00567                         ateof = 0;
00568                         gotbacksp = 0;
00569                         rightpos = scolumn + s->field->size - 1;
00570                         p = s->field->data;
00571                         move (sline, scolumn);
00572                         cob_screen_attr (s->foreg, s->backg, s->attr);
00573                         continue;
00574                 }
00575                 getyx (stdscr, cline, ccolumn);
00576                 if (keyp == KEY_BACKSPACE || keyp == ('H' & 037) ||
00577                     keyp == 0177) {
00578                         if (ccolumn > scolumn) {
00579                                 if (gotbacksp || ccolumn != rightpos) {
00580                                         ccolumn--;
00581                                 } else {
00582                                         ateof = 0;
00583                                 }
00584                                 gotbacksp = 1;
00585                                 move (cline, ccolumn);
00586                                 if (s->attr & COB_SCREEN_SECURE) {
00587                                         addch ('*');
00588                                 } else {
00589                                         addch ('_');
00590                                 }
00591                                 move (cline, ccolumn);
00592                                 p = s->field->data + ccolumn - scolumn;
00593                                 *p = ' ';
00594                         } else {
00595                                 ungetched = 1;
00596                                 gotbacksp = 0;
00597                                 ungetch (KEY_BACKSPACE);
00598                                 ungetch (KEY_BTAB);
00599                         }
00600                         continue;
00601                 }
00602                 if (keyp == KEY_LEFT) {
00603                         gotbacksp = 0;
00604                         if (ccolumn > scolumn) {
00605                                 ccolumn--;
00606                                 move (cline, ccolumn);
00607                                 p = s->field->data + ccolumn - scolumn;
00608                         } else {
00609                                 ungetched = 1;
00610                                 ungetch (KEY_BTAB);
00611                         }
00612                         continue;
00613                 }
00614                 if (keyp == KEY_RIGHT) {
00615                         gotbacksp = 0;
00616                         if (ccolumn < rightpos) {
00617                                 ccolumn++;
00618                                 move (cline, ccolumn);
00619                                 p = s->field->data + ccolumn - scolumn;
00620                         } else {
00621                                 ungetch (011);
00622                         }
00623                         continue;
00624                 }
00625                 if (keyp > 037 && keyp < (int)A_CHARTEXT) {
00626                         if (COB_FIELD_IS_NUMERIC (s->field)) {
00627                                 if (keyp < '0' || keyp > '9') {
00628                                         beep ();
00629                                         continue;
00630                                 }
00631                         }
00632                         gotbacksp = 0;
00633                         *p = keyp;
00634                         if (s->attr & COB_SCREEN_SECURE) {
00635                                 addch ('*');
00636                         } else {
00637                                 addch ((unsigned int)keyp);
00638                         }
00639                         if (ccolumn == rightpos) {
00640                                 if (s->attr & COB_SCREEN_AUTO) {
00641                                         if (curr_index == totl_index - 1) {
00642                                                 break;
00643                                         } else {
00644                                                 ungetch (011);
00645                                         }
00646                                 }
00647                                 move (cline, ccolumn);
00648                                 if (ateof) {
00649                                         beep ();
00650                                 } else {
00651                                         ateof = 1;
00652                                 }
00653                         } else {
00654                                 p++;
00655                         }
00656                         continue;
00657                 }
00658                 gotbacksp = 0;
00659                 beep ();
00660         }
00661         refresh ();
00662 }
00663 
00664 static int
00665 compare_yx (const void *m1, const void *m2)
00666 {
00667         const struct cob_inp_struct     *s1;
00668         const struct cob_inp_struct     *s2;
00669 
00670         s1 = m1;
00671         s2 = m2;
00672         if (s1->this_y < s2->this_y) {
00673                 return -1;
00674         }
00675         if (s1->this_y > s2->this_y) {
00676                 return 1;
00677         }
00678         if (s1->this_x < s2->this_x) {
00679                 return -1;
00680         }
00681         if (s1->this_x > s2->this_x) {
00682                 return 1;
00683         }
00684         return 0;
00685 }
00686 
00687 static void
00688 cob_prep_input (cob_screen *s)
00689 {
00690         struct cob_inp_struct   *sptr;
00691         int                     n;
00692 
00693         switch (s->type) {
00694         case COB_SCREEN_TYPE_GROUP:
00695                 for (s = s->child; s; s = s->next) {
00696                         cob_prep_input (s);
00697                 }
00698                 break;
00699         case COB_SCREEN_TYPE_FIELD:
00700                 cob_screen_puts (s, s->field);
00701                 if (s->attr & COB_SCREEN_INPUT) {
00702                         sptr = cob_base_inp + totl_index;
00703                         sptr->scr = s;
00704                         sptr->this_y = cob_current_y;
00705                         sptr->this_x = cob_current_x;
00706                         totl_index++;
00707                 }
00708                 break;
00709         case COB_SCREEN_TYPE_VALUE:
00710                 cob_screen_puts (s, s->value);
00711                 if (s->occurs) {
00712                         for (n = 1; n < s->occurs; ++n) {
00713                                 cob_screen_puts (s, s->value);
00714                         }
00715                 }
00716                 break;
00717         case COB_SCREEN_TYPE_ATTRIBUTE:
00718                 cob_screen_attr (s->foreg, s->backg, s->attr);
00719                 break;
00720         }
00721 }
00722 
00723 /* Global functions */
00724 
00725 void
00726 cob_screen_display (cob_screen *s, cob_field *line, cob_field *column)
00727 {
00728         int     n;
00729 
00730         if (!cob_screen_initialized) {
00731                 cob_screen_init ();
00732         }
00733 
00734         switch (s->type) {
00735         case COB_SCREEN_TYPE_GROUP:
00736                 for (s = s->child; s; s = s->next) {
00737                         cob_screen_display (s, line, column);
00738                 }
00739                 break;
00740         case COB_SCREEN_TYPE_FIELD:
00741                 cob_screen_puts (s, s->field);
00742                 break;
00743         case COB_SCREEN_TYPE_VALUE:
00744                 cob_screen_puts (s, s->value);
00745                 if (s->occurs) {
00746                         for (n = 1; n < s->occurs; ++n) {
00747                                 cob_screen_puts (s, s->value);
00748                         }
00749                 }
00750                 break;
00751         case COB_SCREEN_TYPE_ATTRIBUTE:
00752                 cob_screen_attr (s->foreg, s->backg, s->attr);
00753                 break;
00754         }
00755         refresh ();
00756 }
00757 
00758 void
00759 cob_screen_accept (cob_screen *s, cob_field *line, cob_field *column)
00760 {
00761         struct cob_inp_struct   *sptr;
00762         struct cob_inp_struct   *sptr2;
00763         size_t                  idx;
00764         size_t                  n;
00765         size_t                  posu;
00766         size_t                  posd;
00767         size_t                  prevy;
00768         size_t                  firsty;
00769         int                     starty;
00770 
00771         if (!cob_screen_initialized) {
00772                 cob_screen_init ();
00773         }
00774         if (!cob_base_inp) {
00775                 cob_base_inp = cob_malloc (COB_INP_SIZE);
00776         } else {
00777                 memset (cob_base_inp, 0, COB_INP_SIZE);
00778         }
00779         cob_exception_code = 0;
00780         cob_current_y = 0;
00781         cob_current_x = 0;
00782         totl_index = 0;
00783         move (0, 0);
00784         cob_prep_input (s);
00785         /* No input fields is an error */
00786         if (!totl_index) {
00787                 cob_check_pos_status (8000);
00788                 return;
00789         }
00790         qsort (cob_base_inp, totl_index, sizeof(struct cob_inp_struct), compare_yx);
00791         sptr = cob_base_inp;
00792         starty = sptr->this_y;
00793         posu = 0;
00794         posd = 0;
00795         prevy = 0;
00796         firsty = 0;
00797         /* Set up array for Cursor UP/DOWN */
00798         for (n = 0; n < totl_index; n++) {
00799                 sptr = cob_base_inp + n;
00800                 if (sptr->this_y > starty) {
00801                         if (!firsty) {
00802                                 firsty = n;
00803                         }
00804                         starty = sptr->this_y;
00805                         sptr2 = cob_base_inp + posd;
00806                         for (idx = posd; idx < n; idx++, sptr2++) {
00807                                 sptr2->down_index = n;
00808                         }
00809                         posu = prevy;
00810                         prevy = n;
00811                         posd = n;
00812                 }
00813                 sptr->up_index = posu;
00814         }
00815         sptr = cob_base_inp;
00816         for (n = 0; n < firsty; n++, sptr++) {
00817                 sptr->up_index = posd;
00818         }
00819         curr_index = 0;
00820         global_return = 0;
00821         cob_screen_get_all ();
00822         cob_check_pos_status (global_return);
00823 }
00824 
00825 void
00826 cob_field_display (cob_field *f, cob_field *line, cob_field *column,
00827                    cob_field *fgc, cob_field *bgc, cob_field *scroll,
00828                    const int attr)
00829 {
00830         int sline;
00831         int scolumn;
00832 
00833         if (!cob_screen_initialized) {
00834                 cob_screen_init ();
00835         }
00836 
00837         if (scroll) {
00838                 sline = cob_get_int (scroll);
00839                 if (attr & COB_SCREEN_SCROLL_DOWN) {
00840                         sline = -sline;
00841                 }
00842                 scrollok (stdscr, 1);
00843                 scrl (sline);
00844                 scrollok (stdscr, 0);
00845                 refresh ();
00846         }
00847         get_line_column (line, column, &sline, &scolumn);
00848         move (sline, scolumn);
00849         cob_screen_attr (fgc, bgc, attr);
00850         addnstr ((char *)f->data, (int)f->size);
00851         refresh ();
00852 }
00853 
00854 void
00855 cob_field_accept (cob_field *f, cob_field *line, cob_field *column,
00856                   cob_field *fgc, cob_field *bgc, cob_field *scroll,
00857                   const int attr)
00858 {
00859         unsigned char   *p;
00860         size_t          count;
00861         int             keyp;
00862         int             fret;
00863         int             sline;
00864         int             scolumn;
00865         int             cline;
00866         int             ccolumn;
00867         int             rightpos;
00868         int             ateof;
00869         int             gotbacksp;
00870 
00871         if (!cob_screen_initialized) {
00872                 cob_screen_init ();
00873         }
00874 
00875         if (scroll) {
00876                 keyp = cob_get_int (scroll);
00877                 if (attr & COB_SCREEN_SCROLL_DOWN) {
00878                         keyp = -keyp;
00879                 }
00880                 scrollok (stdscr, 1);
00881                 scrl (keyp);
00882                 scrollok (stdscr, 0);
00883                 refresh ();
00884         }
00885         cob_exception_code = 0;
00886         get_line_column (line, column, &sline, &scolumn);
00887         move (sline, scolumn);
00888         cob_screen_attr (fgc, bgc, attr);
00889         p = f->data;
00890         for (count = 0; count < f->size; count++) {
00891                 if (attr & COB_SCREEN_SECURE) {
00892                         addch ('*');
00893                 } else if (attr & COB_SCREEN_UPDATE) {
00894                         fret = *p++;
00895                         addch ((unsigned int)fret);
00896                 } else if (attr & COB_SCREEN_PROMPT) {
00897                         addch ('_');
00898                 } else {
00899                         addch (' ');
00900                 }
00901         }
00902         move (sline, scolumn);
00903         if (!(attr & COB_SCREEN_UPDATE)) {
00904                 if (COB_FIELD_IS_NUMERIC (f)) {
00905                         cob_move (&cob_zero, f);
00906                 } else {
00907                         memset (f->data, ' ', f->size);
00908                 }
00909         }
00910 
00911         fret = 0;
00912         ateof = 0;
00913         gotbacksp = 0;
00914         rightpos = scolumn + f->size - 1;
00915         p = f->data;
00916         for (; ;) {
00917                 refresh ();
00918                 keyp = getch ();
00919                 if (keyp == KEY_ENTER || keyp == '\n') {
00920                         break;
00921                 }
00922                 if (keyp > KEY_F0 && keyp < KEY_F(65)) {
00923                         fret = 1000 + keyp - KEY_F0;
00924                         break;
00925                 }
00926                 if (cob_extended_status) {
00927                         if (keyp == KEY_PPAGE) {
00928                                 fret = 2001;
00929                                 break;
00930                         }
00931                         if (keyp == KEY_NPAGE) {
00932                                 fret = 2002;
00933                                 break;
00934                         }
00935                         if (keyp == KEY_UP) {
00936                                 fret = 2003;
00937                                 break;
00938                         }
00939                         if (keyp == KEY_DOWN) {
00940                                 fret = 2004;
00941                                 break;
00942                         }
00943                         if (keyp == KEY_PRINT) {
00944                                 fret = 2006;
00945                                 break;
00946                         }
00947                         if (cob_use_esc) {
00948                                 if (keyp == 033) {
00949                                         fret = 2005;
00950                                         break;
00951                                 }
00952                         }
00953                 }
00954                 getyx (stdscr, cline, ccolumn);
00955                 if (keyp == KEY_BACKSPACE || keyp == ('H' & 037) ||
00956                     keyp == 0177) {
00957                         if (ccolumn > scolumn) {
00958                                 if (gotbacksp || ccolumn != rightpos) {
00959                                         ccolumn--;
00960                                 } else {
00961                                         ateof = 0;
00962                                 }
00963                                 gotbacksp = 1;
00964                                 move (cline, ccolumn);
00965                                 if (attr & COB_SCREEN_SECURE) {
00966                                         addch ('*');
00967                                 } else {
00968                                         addch ('_');
00969                                 }
00970                                 move (cline, ccolumn);
00971                                 p = f->data + ccolumn - scolumn;
00972                                 *p = ' ';
00973                                 continue;
00974                         }
00975                 }
00976                 if (keyp == KEY_HOME) {
00977                         move (sline, scolumn);
00978                         p = f->data;
00979                         ateof = 0;
00980                         gotbacksp = 0;
00981                         continue;
00982                 }
00983                 if (keyp == KEY_END) {
00984                         move (sline, rightpos);
00985                         p = f->data + f->size - 1;
00986                         ateof = 0;
00987                         gotbacksp = 0;
00988                         continue;
00989                 }
00990                 if (keyp == KEY_LEFT) {
00991                         if (ccolumn > scolumn) {
00992                                 ccolumn--;
00993                                 move (cline, ccolumn);
00994                                 p = f->data + ccolumn - scolumn;
00995                                 continue;
00996                         }
00997                         gotbacksp = 0;
00998                 }
00999                 if (keyp == KEY_RIGHT) {
01000                         if (ccolumn < rightpos) {
01001                                 ccolumn++;
01002                                 move (cline, ccolumn);
01003                                 p = f->data + ccolumn - scolumn;
01004                                 continue;
01005                         }
01006                         gotbacksp = 0;
01007                 }
01008                 if (keyp > 037 && keyp < (int)A_CHARTEXT) {
01009                         if (COB_FIELD_IS_NUMERIC (f)) {
01010                                 if (keyp < '0' || keyp > '9') {
01011                                         beep ();
01012                                         continue;
01013                                 }
01014                         }
01015                         gotbacksp = 0;
01016                         *p = keyp;
01017                         if (attr & COB_SCREEN_SECURE) {
01018                                 addch ('*');
01019                         } else {
01020                                 addch ((unsigned int)keyp);
01021                         }
01022                         if (ccolumn == rightpos) {
01023                                 if (attr & COB_SCREEN_AUTO) {
01024                                         break;
01025                                 }
01026                                 move (cline, ccolumn);
01027                                 if (ateof) {
01028                                         beep ();
01029                                 } else {
01030                                         ateof = 1;
01031                                 }
01032                         } else {
01033                                 p++;
01034                         }
01035                         continue;
01036                 }
01037                 gotbacksp = 0;
01038                 beep ();
01039         }
01040         cob_check_pos_status (fret);
01041         refresh ();
01042 }
01043 
01044 void
01045 cob_screen_line_col (cob_field *f, const int l_or_c)
01046 {
01047         if (!cob_screen_initialized) {
01048                 cob_screen_init ();
01049         }
01050         if (!l_or_c) {
01051                 cob_set_int (f, (int)LINES);
01052         } else {
01053                 cob_set_int (f, (int)COLS);
01054         }
01055 }
01056 
01057 void
01058 cob_screen_set_mode (const size_t smode)
01059 {
01060         if (!smode) {
01061                 refresh ();
01062                 def_prog_mode ();
01063                 endwin ();
01064         } else {
01065                 reset_prog_mode ();
01066                 refresh ();
01067         }
01068 }
01069 
01070 #else
01071 
01072 void
01073 cob_screen_terminate (void)
01074 {
01075 }
01076 
01077 void
01078 cob_field_display (cob_field *f, cob_field *line, cob_field *column,
01079                    cob_field *fgc, cob_field *bgc, const int attr)
01080 {
01081 }
01082 
01083 void
01084 cob_field_accept (cob_field *f, cob_field *line, cob_field *column,
01085                   cob_field *fgc, cob_field *bgc, const int attr)
01086 {
01087 }
01088 
01089 void
01090 cob_screen_display (cob_screen *s, cob_field *line, cob_field *column)
01091 {
01092 }
01093 
01094 void
01095 cob_screen_accept (cob_screen *s, cob_field *line, cob_field *column)
01096 {
01097 }
01098 
01099 void
01100 cob_screen_line_col (cob_field *f, const int l_or_c)
01101 {
01102 }
01103 
01104 void
01105 cob_screen_set_mode (const size_t smode)
01106 {
01107 }
01108 
01109 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines