// // Copyright (C) 2002,2001, 2000, 1999, Rildo Pragana, Jim Noeth, // Andrew Cameron, David Essex. // Copyright (C) 1993, 1991 Rildo Pragana. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation; either version 2.1, // or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; see the file COPYING.LIB. If // not, write to the Free Software Foundation, Inc., 59 Temple Place, // Suite 330, Boston, MA 02111-1307 USA // // Cobol Compiler Run Time Library // Curses Screen I/O Functions - Screen frontedn // #include "htcoblib.h" #include "mwindows.h" #if defined(SunOS) #include #else # if defined(__CYGWIN__) # include # else # if defined(__MINGW32__) # include //# include # else # include # endif # endif #endif #include "screenio.h" #include "rterrors.h" #include "config.h" /* PDcurses 2.4 does not have the following defenetion */ #ifndef KEY_CODE_YES #define KEY_CODE_YES 0x100 /* A wchar_t contains a key code */ #endif static short fore_color; // Actual fore and back colors static short back_color; static int cursor_x = 0; // Actual screen position for dinamically static int cursor_y = 0; // calculate +/- line/col extern int bDecimalComma; static struct KeyBinding *keyBindings; int tcob_isZNum(char *p); // walter // // Initialize curses // int tcob_scr_init(){ int i; initscr(); noecho(); cbreak(); keypad(stdscr,TRUE); scrollok(stdscr,FALSE); //walter: turn off scroll possibility nonl(); //raw(); noecho(); //walter 03-01-06 if (has_colors()) //walter 03-01-06 start_color(); keyBindings = tcob_get_keybindings(); // pair_content(0,&fore_color,&back_color); walter: pair_content first argument must be between 1 and COLOR_PAIRS-1 attrset(A_NORMAL); // // This is needed for pdcurses, that has all the pairs to 0-7 // //walter 03-01-06 for(i=0;i= (LINES-1)) { scrollok(stdscr,TRUE); //walter: turn on scroll possibility scrl(1); // scroll 1 line scrollok(stdscr,FALSE); //walter: turn off scroll possibility move(cursor_y,0); cursor_x=0; return 1; } return 0; } // // Set cursos position on the screen // void tcob_scr_setyx(int y, int x){ move(y,x); getyx(stdscr,cursor_y,cursor_x); } void tcob_scr_setx(int x){ tcob_scr_setyx(tcob_scr_gety(),x); } void tcob_scr_sety(int y){ tcob_scr_setyx(y,tcob_scr_getx()); } // // Get the status of keyboard. // // return TRUE if there is a char in the buffer and FALSE if not // int tcob_scr_kbdstatus(){ int c; nodelay(stdscr,TRUE); c=getch(); nodelay(stdscr,FALSE); if (c==ERR) { return 0; } ungetch(c); return 1; } /*-------------------------------------------------------------------------*\ | | | tcob_scr_action_for_key | | Looks in the table which is the action to return for the key passed. | | If exists the SCREEN STATUS field moves the value in the table to it. | | | \*-------------------------------------------------------------------------*/ int tcob_scr_action_for_key(int key,int *status) { struct KeyBinding *binding=NULL; struct KeyBinding *pbindings; for(pbindings=keyBindings; pbindings->keyCode!=0; pbindings++) { if (pbindings->keyCode == key) { binding=pbindings; break; } } if (binding==NULL) { return EDIT_NOP; } *status = binding->screenStatus; return binding->action; } /* check the configuration for "auto clean all" setting */ int tcob_autocleanall() { struct KeyBinding *binding=NULL; struct KeyBinding *pbindings; for(pbindings=keyBindings; pbindings->keyCode!=0; pbindings++) { if (pbindings->keyCode == TCOBKEY_AUTOCLEANALL) { binding=pbindings; break; } } if (binding==NULL) { return 0; } return binding->screenStatus; } // // Returns the curses color code from the cobol color number // static int get_curses_color(int cobol_color) { unsigned int colour = COLOR_BLACK; // switch(cobol_color % 8) { switch(cobol_color % COLORS) { case TC_BLUE: colour = COLOR_BLUE; break; case TC_GREEN: colour = COLOR_GREEN; break; case TC_CYAN: colour = COLOR_CYAN; break; case TC_RED: colour = COLOR_RED; break; case TC_MAGENTA: colour = COLOR_MAGENTA; break; case TC_YELLOW: colour = COLOR_YELLOW; break; case TC_WHITE: colour = COLOR_WHITE; break; case TC_BLACK: default: break; } return colour; } /*static int get_curses_color(int cobol_color) { // Color numbers from standard // // 0 - black // 1 - blue // 2 - green // 3 - cyan // 4 - red // 5 - magenta // 6 - brown/yellow // 7 - white // // Curses colors // #define COLOR_BLACK 0 // #define COLOR_RED 1 // #define COLOR_GREEN 2 // #define COLOR_YELLOW 3 // #define COLOR_BLUE 4 // #define COLOR_MAGENTA 5 // #define COLOR_CYAN 6 // #define COLOR_WHITE 7 // //switch(cobol_color % 8) { switch(cobol_color % COLORS) { case TC_BLACK: return COLOR_BLACK; case TC_BLUE: return COLOR_BLUE; case TC_GREEN: return COLOR_GREEN; case TC_CYAN: return COLOR_CYAN; case TC_RED: return COLOR_RED; case TC_MAGENTA:return COLOR_MAGENTA; case TC_YELLOW: return COLOR_YELLOW; case TC_WHITE: return COLOR_WHITE; default:return 0; } }*/ // // sets the color for the next display // static void set_colors(){ int i; // short fore,back; /*walter 03-01-06 for(i = 0; i < COLOR_PAIRS; ++i) { pair_content(i,&fore,&back); if ((fore == fore_color) && (back == back_color)) { break; } if ((fore == 0) && (back == 0)) { init_pair(i,fore_color,back_color); break; } } */ i=(back_color*8)+fore_color; if (i != COLOR_PAIRS) { #ifdef CURSES_HAS_COLOR_SET color_set(i,NULL); #else attrset(COLOR_PAIR(i)); #endif bkgdset(COLOR_PAIR(i)); } else { attrset(A_NORMAL); } } /*-------------------------------------------------------------------------*\ | | | set_attributes | | | \*-------------------------------------------------------------------------*/ static void set_atributes(struct ScrFld *pFld) { attr_t iAttr=0; chtype pos; // walter short color; // walter attrset(A_NORMAL); if (pFld->iAttributes != -1) { if ((pFld->iAttributes & SCR_HIGHLIGHT) == SCR_HIGHLIGHT) iAttr |= A_BOLD; if ((pFld->iAttributes & SCR_LOWLIGHT) == SCR_LOWLIGHT) iAttr |= A_DIM; if ((pFld->iAttributes & SCR_UNDERLINE) == SCR_UNDERLINE) iAttr |= A_UNDERLINE; if ((pFld->iAttributes & SCR_REVERSE_VIDEO) == SCR_REVERSE_VIDEO) iAttr |= A_REVERSE; if ((pFld->iAttributes & SCR_BLINK) == SCR_BLINK) { iAttr |= A_BLINK; } if ((pFld->iAttributes & SCR_BELL) == SCR_BELL) beep(); if ((pFld->iAttributes & SCR_BLANK_SCREEN) == SCR_BLANK_SCREEN) { clear(); tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx()); } attron(iAttr); } if (has_colors() == TRUE) { fore_color=COLOR_WHITE; back_color=COLOR_BLACK; pos = mvinch(pFld->iLine, pFld->iCol); color = ( pos & A_COLOR ) / 256; if (pFld->iFgColor != -1){ fore_color=get_curses_color(pFld->iFgColor); } else { // walter, get the foreground color in screen if(color) fore_color=color % 8; } // fim walter if (pFld->iBgColor != -1) { back_color=get_curses_color(pFld->iBgColor); } else { // walter, get the background color in screen if(color) back_color=color / 8; } set_colors(); } /* chtype pos; // walter unsigned int color; // walter if (pFld->iAttributes != -1) { if (pFld->iAttributes & SCR_HIGHLIGHT) attron(A_BOLD); else attroff(A_BOLD); if (pFld->iAttributes & SCR_LOWLIGHT) attron(A_DIM); else attroff(A_DIM); if(pFld->iAttributes & SCR_UNDERLINE) attron(A_UNDERLINE); else attroff(A_UNDERLINE); if(pFld->iAttributes & SCR_REVERSE_VIDEO) attron(A_REVERSE); else attroff(A_REVERSE); if(pFld->iAttributes & SCR_BLINK) attron(A_BLINK); else attroff(A_BLINK); if(pFld->iAttributes & SCR_BELL) beep(); if(pFld->iAttributes & SCR_BLANK_SCREEN) { clear(); tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx()); } } if (pFld->iFgColor != -1){ fore_color=get_curses_color(pFld->iFgColor); } else { // walter, get the foreground color in screen pos = mvinch(pFld->iLine, pFld->iCol); color = ( pos & A_COLOR ) / 256; fore_color=color % 8; } // fim walter if (pFld->iBgColor != -1){ back_color=get_curses_color(pFld->iBgColor); } else { // walter, get the background color in screen pos = mvinch(pFld->iLine, pFld->iCol); color = ( pos & A_COLOR ) / 256; back_color=color / 8; if(fore_color == 0 && back_color == 0) fore_color = 7; } set_colors(); */ } /*-------------------------------------------------------------------------*\ | | | _DisplayField | | | \*-------------------------------------------------------------------------*/ static void _DisplayField(struct ScrFld *pFld) { set_atributes(pFld); tcob_scr_setyx(pFld->iLine, pFld->iCol); if(pFld->iAttributes & SCR_BLANK_LINE){ // erase all the current line move(tcob_scr_gety(),0); clrtoeol(); tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx()); } if(pFld->iAttributes & SCR_ERASE_EOL) // erase to end of line clrtoeol(); if(pFld->iAttributes & SCR_ERASE_EOS) // erase to end of screen clrtobot(); if(pFld->iAttributes & SCR_BELL) beep(); if(pFld->iAttributes & SCR_BLANK_SCREEN){ clear(); tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx()); } if(pFld->iAttributes & SCR_SECURE) { tcob_scr_setchar('*', pFld->fldScr.len); } else { if((pFld->iAttributes & SCR_BLANK_WHEN_ZERO) != SCR_BLANK_WHEN_ZERO) { addnstr(pFld->caScr, pFld->fldScr.len); } else { unsigned int i, sign; tcob_scr_setyx(pFld->iLine, pFld->iCol); sign = tcob_extract_sign(&pFld->fldWk, pFld->caWk); for(i = 0; i < pFld->fldWk.len; ++i) { if(pFld->caWk[i] != '0') break; } tcob_put_sign(&pFld->fldWk, pFld->caWk, sign); if(i == pFld->fldWk.len) tcob_scr_setchar(' ', pFld->fldScr.len); else addnstr(pFld->caScr, pFld->fldScr.len); } } } /*-------------------------------------------------------------------------*\ | | | _DisplayForAccept | | | \*-------------------------------------------------------------------------*/ static void _DisplayForAccept(struct ScrFld *pFld) { set_atributes(pFld); tcob_scr_setyx(pFld->iLine, pFld->iCol); if(pFld->iAttributes & SCR_BLANK_LINE) clrtoeol(); if(pFld->iAttributes & SCR_SECURE) tcob_scr_setchar('*', pFld->fldScr.len); else if(pFld->iAttributes & SCR_NOECHO) tcob_scr_setchar(' ', pFld->fldScr.len); else addnstr(pFld->caScr, pFld->fldScr.len); } void tcob_scr_display_field(struct ScrFld *pFld){ _DisplayField(pFld); } void tcob_scr_display_for_input(struct ScrFld *pFld){ _DisplayForAccept(pFld); } void tcob_scr_display(struct ScrFld *fields){ struct ScrFld *pFld; for(pFld=fields; pFld; pFld=pFld->pNext) { // if(pFld->fldFrom) { /* if we have a from field */ // tcob_move(pFld->fldFrom, pFld->caFrom, &(pFld->fldScr), pFld->caScr); // } tcob_scr_display_field(pFld); tcob_scr_setx(tcob_scr_getx() + pFld->fldScr.len); } } static int full_field(struct ScrFld *pFld) { return ((pFld->charCount - pFld->decimals) >= (pFld->len - pFld->decimals)); } static int first_pos(struct ScrFld *pFld) { int t = pFld->fldScr.len - 1; int pos = 0; if (NUMERICFIELD(pFld->fldScr.type)) { while (pos < t && pFld->caScr[pos] == ' ') pos++; } return pos; } static int last_pos(struct ScrFld *pFld) { unsigned int b = (pFld->decimalPointPosition <= pFld->iScrPos); int full = full_field(pFld); int pos; if (NUMERICFIELD(pFld->fldScr.type)) { pos = pFld->fldScr.len - 1; if (!b && !full) { /* cursor wasn't already over the decimal point */ if (pFld->decimalPointPosition >= 0) pos = pFld->decimalPointPosition; } } else { pos = pFld->charCount; if (pos == pFld->fldScr.len) pos--; } return pos; } /*-------------------------------------------------------------------------*\ | | | move_cursor_first | | move_cursor_last | | move_cursor_left | | move_cursor_right | | | | This are helper functions for cob_accept_screen to help moving inside a | | field. | \*-------------------------------------------------------------------------*/ static void move_cursor_first(struct ScrFld *pFld) { pFld->iScrPos = first_pos(pFld); pFld->iFldPos = 0; } static void move_cursor_last(struct ScrFld *pFld) { pFld->iScrPos = last_pos(pFld); } static int move_cursor_left(struct ScrFld *pFld) { char cWk; int p = first_pos(pFld); int full = full_field(pFld); if(pFld->iScrPos > p) { --pFld->iFldPos; --pFld->iScrPos; if(pFld->iScrPos > p && EDITEDFIELD(pFld->fldScr.type)) { while(pFld->iScrPos > p) { if (DECIMALPOINT && !full) break; cWk = pFld->caScr[pFld->iScrPos]; if((cWk != '.') && (cWk != ',') && (cWk != '/') && (cWk != '-')) break; --pFld->iScrPos; } } return 1; } return 0; } static int move_cursor_right(struct ScrFld *pFld) { char cWk; int full = full_field(pFld); int l = last_pos(pFld); int f = first_pos(pFld); if (pFld->iScrPos < l) { ++pFld->iScrPos; ++pFld->iFldPos; if (EDITEDFIELD(pFld->fldScr.type)) { while(pFld->iScrPos < l) { if (DECIMALPOINT && !full) break; cWk = pFld->caScr[pFld->iScrPos]; if((cWk != '.') && (cWk != ',') && (cWk != '/') && (cWk != '-')) break; ++pFld->iScrPos; } } if (pFld->iScrPos < f) pFld->iScrPos = f; return 1; } return 0; } /*static void shift_right(char *source, int pos, int len) { char *p = source + pos; len--; memmove(p+1, p, len); *p = ' '; }*/ static void shift_left(char *source, int pos, int len) { char *p = source + pos; len--; memcpy(p, p+1, len); *(p+len) = ' '; } static void calculate_charcount(struct ScrFld *pFld) { int j, k, l; char c; if (!NUMERICFIELD(pFld->fldScr.type)) { k = pFld->fldWk.len; j = pFld->iScrPos; while (--k > j && pFld->caWk[k] == ' '); if (k >= pFld->charCount) pFld->charCount = k + 1; } else if DISPLAYFIELD(pFld->fldScr.type){ j = -1; k = pFld->fldWk.len; while (++j < k && pFld->caWk[j] == '0'); pFld->charCount = k- j; } else { /* edited */ k = pFld->fldScr.len; j = -1; l = 0; while (++j < k) { c = pFld->caScr[j]; if (c >= '0' && c <= '9') l++; pFld->charCount = l; } } } static int createdRoomToField; /* true if you need shift the field to alocate space to a digit */ static void display_field(struct ScrFld *pFld) { int j, k; tcob_move(&pFld->fldScr, pFld->caScr, &pFld->fldWk, pFld->caWk); tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr); calculate_charcount(pFld); createdRoomToField = 0; /* RP -- we never get a DISPLAYFIELD here, as it is being faked as EDITED!! */ if (DISPLAYFIELD(pFld->fldScr.type)) { j = -1; k = pFld->fldWk.len; while (++j < k && pFld->caScr[j] == '0') pFld->caScr[j] = ' '; if (pFld->charCount < pFld->fldWk.len) { /* we need room to the cursor */ shift_left(pFld->caScr, 0, pFld->fldScr.len); createdRoomToField = 1; } } else if (EDITEDFIELD(pFld->fldScr.type) && !HASDECIMALPOINT && !HASSIGN && pFld->charCount < pFld->fldWk.len) { /* we need room to the cursor */ shift_left(pFld->caScr, 0, pFld->fldScr.len); createdRoomToField = 1; } _DisplayForAccept(pFld); } static void remove_char(struct ScrFld *pFld) { if (NUMERICFIELD(pFld->fldScr.type)) { pFld->caScr[pFld->iScrPos] = ' '; display_field(pFld); if (!createdRoomToField || pFld->iScrPos < first_pos(pFld)) move_cursor_right(pFld); } else { shift_left(pFld->caScr, pFld->iScrPos, (pFld->fldScr.len - pFld->iScrPos)); display_field(pFld); } } static void process_special_char(struct ScrFld *pFld, int iKey) { int j; if (iKey == CDECIMALPOINT) { if (pFld->decimalPointPosition < 0) { beep(); return; } pFld->iScrPos = pFld->decimalPointPosition + 1; return; } if (iKey == CTHOUSANDSEPARATOR) { j = pFld->iScrPos; while (j < pFld->fldScr.len && pFld->caScr[j] != CTHOUSANDSEPARATOR) j++; j++; if (j >= pFld->fldScr.len) { beep(); return; } pFld->iScrPos = j; return; } if (iKey == '-' || iKey == '+') { if (pFld->signPosition < 0) { beep(); return; } pFld->caScr[pFld->signPosition] = (char)iKey; return; } } static int fill_field(struct ScrFld *pFld, int iKey) { int ret = 0; int l; int digit; if(pFld->fldWk.type != DTYPE_ALPHANUMERIC) { // numeric input digit = ((iKey >= '0') && (iKey <= '9')); if (!digit && (iKey != '-') && (iKey != '+') && (iKey != CTHOUSANDSEPARATOR) && (iKey != CDECIMALPOINT)) { beep(); iKey = 0; } else if (!digit) { process_special_char(pFld, iKey); display_field(pFld); iKey = 0; } else if (pFld->iScrPos == pFld->signPosition) { if (full_field(pFld)) { beep(); iKey = 0; } else { shift_left(pFld->caScr, 0, pFld->iScrPos); } } } if ( iKey ) { int k; /* upper & lower */ if (pFld->iAttributes & SCR_UPPER) iKey=toupper(iKey); if (pFld->iAttributes & SCR_LOWER) iKey=tolower(iKey); k = pFld->iScrPos; if (DECIMALPOINT) { shift_left(pFld->caScr, 0, pFld->decimalPointPosition); k--; } pFld->caScr[k] = (char)iKey; l = pFld->charCount; display_field(pFld); k = full_field(pFld); if (pFld->charCount < l) move_cursor_first(pFld); else if (!DECIMALPOINT || k) ret = move_cursor_right(pFld); ret = (pFld->charCount == pFld->fldWk.len) && (pFld->iScrPos == pFld->fldScr.len - 1) && !ret; } return ret; } /* compute offset in screen field from digit position pix -- the expanded picture for the screen field pos -- position in the digits array (something with pic like 9(n)V9(m)) */ int scr_pos(char *pix, int pos) { int n=0; while (1) { if (strchr("9ZXA",*(pix+n))) { if (!pos) break; pos--; } n++; } return n; } /* make sure no positions in the field are nonsense */ void fixField( int len, char *str, char *pix, char hasSign ) { int found=0; char *s=str; if (hasSign) { if (*s != '-' && *s != '+') *s='+'; s++; len--; } while (len) { switch (*pix) { case '9': if (!isdigit(*s)) *s='0'; break; case 'Z': if (found) { if (!isdigit(*s)) *s='0'; } else { if (!isdigit(*s)) *s=' '; else found=1; } break; case 'X': case 'A': if (((unsigned)*s) > 0x7f || ((unsigned)*s) < 0x20) { *s = ' '; } break; default: pix++; continue; } s++; pix++; len--; } } /* check if a number has all digits filled */ int filledNum( char *s, char *pic ) { while (*pic != '9' && *pic != 'Z') { s++; pic += 2; } return ((*s >= '1') && (*s <= '9')); } /* accept display (numeric) field */ int tcob_scr_accept_number(struct ScrFld *pFld,int *status){ int j, k, iKey,action,pos; int maxpos,dpos,dp=0; int blank=0,moved=0,hasz=0,is9edited=0,isZNum=0,atdp=0,hs=0; char *pix; char *s; int tmppos,scr_corr,chk_ov=0; int insmode=0; /* if the accepted field is a refmod, don't auto-clean */ if (pFld->iAttributes & SCR_IS_REFMOD) moved++; //if (pFld->fldTo->type == DTYPE_EDITED) { if (pFld->fldScr.type == DTYPE_EDITED) { isZNum = tcob_isZNum(pFld->fldScr.pic); if (!isZNum) { if (tcob_hasZ(pFld->fldScr.pic)) hasz++; else is9edited++; } } pix=tcob_picExpand( &(pFld->fldScr) ); s=pFld->caWk; maxpos=pFld->fldWk.len-1; dpos=pFld->fldWk.len-pFld->fldWk.decimals; dp=pFld->fldWk.decimals; if (*(pFld->fldWk.pic) == 'S') { hs=1; s++; dpos--; maxpos--; } /* Correct the discrepancy between the Wk field size and the requested data field (why in the earth it is like this?!). Anyway, we must align fields by the decimal point.*/ scr_corr = tcob_picEditedCompLength(&(pFld->fldScr))-pFld->fldWk.len+hs; //scr_corr = 0; tcob_move(&pFld->fldScr, pFld->caScr, &pFld->fldWk, pFld->caWk); fixField(pFld->fldWk.len,pFld->caWk,pix,hs); pos = 0; if (hasz && !tcob_autocleanall()) { moved++; } else { if (!is9edited) { while (pos < maxpos && pos < (dpos-1) && (*(s+pos) == '0' || *(s+pos) == ' ')) pos++; } else { while (pos < maxpos && pos < (dpos-1) && (*(s+pos) == ' ')) pos++; } if (isZNum && pos==(dpos-1) && dp) atdp=1; } while(1) { tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr); if (chk_ov) { chk_ov=0; if (*pFld->caScr != '0' && *pFld->caScr != ' ') { pos++; atdp=0; } } tmppos=scr_pos(pix,pos+scr_corr); if (blank && *(pFld->caScr+tmppos) == '0') { *(pFld->caScr+tmppos)=' '; } _DisplayForAccept(pFld); if (atdp) tmppos++; tcob_scr_setyx(pFld->iLine, pFld->iCol + tmppos); refresh(); iKey = getch(); if(iKey == 8) // walter iKey = 0x107; *status=0; if ((iKey >= '0') && (iKey <= '9')) { blank=0; if (!moved) { if (hs) *(pFld->caWk)='+'; memset(s,'0',pFld->fldWk.len); if (!is9edited) { if (!dp) pos = maxpos; else pos = (dpos?dpos-1:dpos); } else { pos = 0; } moved=1; } if (!dp) { /* integer numbers */ if (pos == maxpos && pos && (*s == '0' || *s == ' ')) { *(s+pos) = iKey; if (!is9edited) { memmove(s,s+1,pos); *(s+pos) = '0'; blank=1; } else if (pFld->iAttributes & SCR_AUTO) { return EDIT_DOWN_FIELD; } } else { if (insmode) { if (!hasz) { memmove(s+pos+1,s+pos,maxpos-pos); *(s+pos) = iKey; } else { if (pos) { memmove(s,s+1,pos); *(s+pos-1) = iKey; } } if (pos == maxpos && (pFld->iAttributes & SCR_AUTO)) { return EDIT_DOWN_FIELD; } } else { *(s+pos) = iKey; if (pos < maxpos) { pos++; } else if (pFld->iAttributes & SCR_AUTO) { return EDIT_DOWN_FIELD; } } } } else { /* numbers with fractional contents -- insert mode */ if (insmode || atdp) { //if (pos && pos < dpos) { if (pos < dpos) { if (atdp) { /*if (*s == '0') {*/ if (*pFld->caScr == '0' || *pFld->caScr == ' ') { memmove(s,s+1,pos+1); *(s+pos) = iKey; chk_ov=1; /*if (*s!='0') { pos++; atdp=0; }*/ } else { atdp=0; if (pos < maxpos) { pos++; } else if (pFld->iAttributes & SCR_AUTO) { return EDIT_DOWN_FIELD; } } } else { if (isZNum) { if (pos) { memmove(s,s+1,pos); *(s+pos-1) = iKey; } } else { memmove(s,s+1,pos); *(s+pos-1) = iKey; } } } else if (pos >= dpos) { if (pos < maxpos) { memmove(s+pos+1,s+pos,maxpos-dpos); } *(s+pos) = iKey; if (pos < maxpos) { pos++; } else if (pFld->iAttributes & SCR_AUTO) { return EDIT_DOWN_FIELD; } } /* fractional numbers -- replace mode */ } else { if (atdp && *s == '0') { continue; } *(s+pos) = iKey; if (isZNum) { atdp=0; if (pos < maxpos) { if (pos == (dpos-1)) { if (*s!='0') { pos++; atdp=0; } else { atdp = 1; } } else { pos++; } } } else { if (pos < maxpos) { pos++; } else if (pFld->iAttributes & SCR_AUTO) { return EDIT_DOWN_FIELD; } } } } } else if (iKey == '+') { if (hs) { *(pFld->caWk)='+'; moved=1; } } else if (iKey == '-') { if (hs) { *(pFld->caWk)='-'; moved=1; } } else { // non data key pressed action = tcob_scr_action_for_key(iKey,status); switch(action) { case EDIT_LEFT: /* move cursor to left */ if (isZNum) { if (atdp) { atdp=0; } else if (pos+scr_corr) { pos--; if (pos==(dpos-1)) atdp=1; } } else { if (!dp && blank && pos==maxpos && *(s+pos) == '0') { memmove(s+1,s,pos); *s='0'; } else if (pos+scr_corr) { pos--; } } blank=0; moved=1; break; case EDIT_RIGHT: /* move cursor to right */ blank=0; if (isZNum) { if (atdp) { atdp=0; if (pos < maxpos) pos++; } else { if (pos==(dpos-1)) { atdp=1; } else { if (pos < maxpos) pos++; } } } else { if (!is9edited && !dp && pos==maxpos && (*s == '0' || *s == ' ')) { memmove(s,s+1,pos); *(s+pos) = '0'; blank=1; } else if (pos < maxpos) { pos++; } } moved=1; break; case EDIT_FIRST: blank=0; pos=0; while (*(pFld->caScr+pos) == ' ') pos++; break; case EDIT_LAST: blank=0; pos = maxpos; break; case EDIT_BACKSPACE: if (!insmode) { if (pos && (pos < dpos || pos > dpos)) { if (pos != (dpos-1)) { pos--; *(s+pos)='0'; } else { if (blank) { memmove(s+1,s,pos-1); *s='0'; } else { if (atdp) { memmove(s+1,s,pos); *s='0'; } else { *(s+pos-1)='0'; pos--; } } } } else { if (pos) { pos--; *(s+pos)='0'; } } } else { if ((dp && pos < dpos) || !dp) { if (pos+scr_corr) { if (atdp) { memmove(s+1,s,pos); *s='0'; } else if (pos-1) { memmove(s+1,s,pos-1); *s='0'; } } } else { if (pos > dpos && (pos+scr_corr)) { if (insmode) { memmove(s+pos-1,s+pos,maxpos-pos+1); *(s+maxpos)='0'; } else { *(s+pos-1)='0'; pos--; } } } } break; case EDIT_DELETE: if (blank && pos == maxpos) { continue; } blank=0; if (pos < dpos) { if (pos+scr_corr) { memmove(s+1,s,pos); *(s+scr_corr) = '0'; if (pos < maxpos) pos++; } } else if (dp) { memmove(s+pos,s+pos+1,maxpos-pos); *(s+maxpos)='0'; } break; case EDIT_INSERT: /* toggle insert mode */ if (insmode) insmode=0; else insmode=1; moved=1; break; case EDIT_CLEAR: /* clear the current field */ blank=0; memset(pFld->caScr,' ',pFld->fldScr.len); break; case EDIT_CLEAR_TOEND: /* Clear to the end of field */ blank=0; j = pFld->fldScr.len - pFld->iFldPos - 1; k = pFld->iFldPos; memset(pFld->caScr + k,' ',j); break; case EDIT_DECIMALPT: if (dp && pos < dpos && !atdp) { memmove(s+dpos-pos,s,pos); memset(s,'0',dpos-pos); pos=dpos; } if (atdp) pos=dpos; atdp=0; moved=1; break; default: tcob_move(&pFld->fldScr, pFld->caScr, &pFld->fldWk, pFld->caWk); free(pix); return action; } } } free(pix); return EDIT_TERMINATE; } /* verify if character is valid against picture mask char */ static int valid_char(int c, int picc) { switch (picc) { case '9': case 'Z': if (isdigit(c)) return 1; else break; case 'A': if (isalpha(c)) return 1; else break; case 'X': if (c <= 0xff && c >= 0x20) return 1; else break; } return 0; } /* clean a field following its picture mask */ static void clean_field(char *s, char *pix) { while (*pix) { if (*pix == '9') { *s++ = '0'; } else if (*pix == 'A' || *pix == 'X' || *pix == 'Z') { *s++ = ' '; } pix++; } } int tcob_scr_accept_edited(struct ScrFld *pFld,int *status){ int j, k, iKey,action,pos; int maxpos=0; int moved=0; char *pix; char *s; int tmppos; int insmode=0; insmode=0; if (pFld->iAttributes & SCR_IS_REFMOD) { pix=tcob_picExpand( &(pFld->fldWk) ); } else { pix=tcob_picExpand( &(pFld->fldScr) ); } s=pFld->caWk; maxpos=pFld->fldWk.len-1; /* if the accepted field is a refmod, don't auto-clean */ if (pFld->iAttributes & SCR_IS_REFMOD) moved++; pos = 0; if (pFld->fldScr.type != 'X' && pFld->fldScr.type != 'D') { while (pos < maxpos && *(s+pos) == ' ') pos++; } else { if (!tcob_autocleanall()) moved++; } while(1) { tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr); tmppos=scr_pos(pix,pos); _DisplayForAccept(pFld); tcob_scr_setyx(pFld->iLine, pFld->iCol + tmppos); refresh(); iKey = getch(); if(iKey == 8) // walter iKey = 0x107; //walter garrote /* upper & lower */ if (pFld->iAttributes & SCR_UPPER) iKey=toupper(iKey); if (pFld->iAttributes & SCR_LOWER) iKey=tolower(iKey); //fim *status=0; if (valid_char(iKey,*(pix+scr_pos(pix,pos)))) { if (!moved) { clean_field(s,pix); //memset(s,' ',pFld->fldWk.len); pos = 0; moved=1; if (pFld->fldWk.type != 'X') { while (pos < maxpos && *(s+pos) == ' ') pos++; } } if (insmode) { if (pos < maxpos) memmove(s+pos+1,s+pos,maxpos-pos); *(s+pos) = iKey; if (pos < maxpos) { pos++; } else if (pFld->iAttributes & SCR_AUTO) { return EDIT_DOWN_FIELD; } } else { *(s+pos) = iKey; if (pos < maxpos) { pos++; } else if ((pFld->iAttributes & SCR_AUTO) && (*s != ' ')) { return EDIT_DOWN_FIELD; } else if (*s == ' ') { memmove(s,s+1,maxpos); if (pFld->fldWk.type == '9') // walter estava com = *(s+maxpos) = '0'; else *(s+maxpos) = ' '; } } } else if (iKey > 0x7f || iKey < 0x20) { // non data key pressed action = tcob_scr_action_for_key(iKey,status); switch(action) { case EDIT_LEFT: /* move cursor to left */ if (pos) { pos--; } moved=1; break; case EDIT_RIGHT: /* move cursor to right */ if (pos < maxpos) { pos++; } moved=1; break; case EDIT_FIRST: pos=0; while (*(pFld->caScr+pos) == ' ') pos++; break; case EDIT_LAST: pos = maxpos; break; case EDIT_BACKSPACE: if (!insmode) { if (*(pix+scr_pos(pix,pos)) == '9') *(s+pos)='0'; else *(s+pos)=' '; if (pos) { // walter inverti pos--; } } else { if (pos) { memmove(s+pos-1,s+pos,maxpos-pos+1); if (*(pix+scr_pos(pix,maxpos)) == '9') *(s+maxpos)='0'; else *(s+maxpos)=' '; pos--; } } break; case EDIT_DELETE: if (pos < maxpos) { /*memmove(s+1,s,pos); if (*(pix+scr_pos(pix,0)) == '9') *(s) = '0'; else *(s) = ' '; pos++;*/ memmove(s+pos,s+pos+1,maxpos-pos); *(s+maxpos) = ' '; } else { if (*(pix+scr_pos(pix,maxpos)) == '9') *(s+maxpos) = '0'; else *(s+maxpos) = ' '; } break; case EDIT_INSERT: /* toggle insert mode */ if (insmode) insmode=0; else insmode=1; moved=1; break; case EDIT_CLEAR: /* clear the current field */ memset(pFld->caScr,' ',pFld->fldScr.len); break; case EDIT_CLEAR_TOEND: /* Clear to the end of field */ j = pFld->fldScr.len - pFld->iFldPos - 1; k = pFld->iFldPos; memset(pFld->caScr + k,' ',j); break; default: free(pix); return action; } } } free(pix); return EDIT_TERMINATE; } // // Accept one field // // // int tcob_scr_accept_field(struct ScrFld *pFld,int *status){ int j, k, iKey,bAtEnd,action; //char type=pFld->fldScr.type; if (pFld->fldTo->type == DTYPE_DISPLAY || (pFld->fldTo->type == DTYPE_EDITED && tcob_isNumEdit(pFld->fldScr.pic))) { return (tcob_scr_accept_number(pFld,status)); } //if (pFld->fldTo->type == DTYPE_EDITED) { return (tcob_scr_accept_edited(pFld,status)); //} pFld->charCount = -1; display_field(pFld); //_DisplayForAccept(pFld); move_cursor_first(pFld); set_atributes(pFld); while(1) { tcob_scr_setyx(pFld->iLine, pFld->iCol + pFld->iScrPos); refresh(); iKey = getch(); *status=0; if(!(iKey & KEY_CODE_YES) && !(iKey < ' ')) { // data key pressed bAtEnd = fill_field(pFld, iKey); if((bAtEnd) && (pFld->iAttributes & SCR_AUTO)) { return EDIT_DOWN_FIELD; } } else { // non data key pressed action = tcob_scr_action_for_key(iKey,status); switch(action) { case EDIT_LEFT: /* move cursor to left */ if (!(move_cursor_left(pFld))) { beep(); } break; case EDIT_RIGHT: /* move cursor to right */ if (!(move_cursor_right(pFld))) { beep(); } break; case EDIT_FIRST: move_cursor_first(pFld); break; case EDIT_LAST: move_cursor_last(pFld); break; case EDIT_BACKSPACE: if(pFld->iScrPos > first_pos(pFld)) { pFld->iScrPos--; if (!EDITEDFIELD(pFld->fldScr.type)) remove_char(pFld); else { int k = pFld->iScrPos; while (!isdigit(pFld->caScr[k]) && --k >= 0); if (k >= 0) { pFld->iScrPos = k; remove_char(pFld); } else { beep(); } } } else { beep(); } break; case EDIT_DELETE: /* delete character under cursor */ if (pFld->iScrPos != pFld->signPosition) remove_char(pFld); else beep(); break; case EDIT_INSERT: /* insert a character before cursor */ j = pFld->fldScr.len - pFld->iFldPos - 1; k = pFld->iFldPos; memmove(pFld->caWk+k+1, pFld->caWk+k, j); pFld->caWk[k] = ' '; _DisplayForAccept(pFld); break; case EDIT_CLEAR: /* clear the current field */ memset(pFld->caWk,' ',pFld->fldWk.len); _DisplayForAccept(pFld); break; case EDIT_CLEAR_TOEND: /* Clear to the end of field */ j = pFld->fldWk.len - pFld->iFldPos - 1; k = pFld->iFldPos; memset(pFld->caWk + k,' ',j); _DisplayForAccept(pFld); break; default: // replace character under cursor return action; } } } return EDIT_TERMINATE; } // // Accept all the fields until finish of function key pressed // Return the value for the screen_status // int tcob_scr_accept(struct ScrFld *fields) { int key_status,action; struct ScrFld *pFld; struct ScrFld *pFirst=NULL; struct ScrFld *pLast=NULL; struct ScrFld *pPrev=NULL; char *pix,*s,*d; int i; for (pFld=fields; pFld; pFld=pFld->pNext) { if(pFld->fldTo) { // cursor stop if(!pFirst) pFirst = pFld; pLast = pFld; } } if(!pFirst) return 0; for(pFld=pFirst;pFld;) { //main accept loop if(pFld->fldTo) { /* this don't work with all fields types: prepare_input_field(pFld);*/ if (pFld->fldTo->type == '9') { memmove(pFld->caWk,pFld->caScr,pFld->fldScr.len); //pFld->fldWk.len = pFld->fldTo->len; } else { /* make our work copy have the significant characters */ if (pFld->iAttributes & SCR_IS_REFMOD) { pix=tcob_picExpand( &(pFld->fldWk) ); } else { pix=tcob_picExpand( &(pFld->fldScr) ); } d = pFld->caWk; s = pFld->caScr; for (i=0;ifldScr.len;i++) { if (strchr("9ZXA",*(pix+i))) { *d++ = *s++; } else { s++; } } } /*tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr);*/ } tcob_scr_display_for_input(pFld); if (pFld != pPrev) { // if new field, put the cursor on position // and display the last accepted if (pPrev) tcob_scr_display_field(pPrev); } pPrev = pFld; action = tcob_scr_accept_field(pFld,&key_status); tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr); switch(action) { case EDIT_FIRST_FIELD: /* move to first input field */ pFld = pFirst; break; case EDIT_LAST_FIELD: /* move to last input field */ pFld = pLast; break; case EDIT_DOWN_FIELD: /* move cursor to next input field */ /* find next input field in chain */ pFld = get_next_input_field(pFld); break; case EDIT_UP_FIELD: /* move cursor to prev input field */ /* find prev input field in chain */ pFld = get_prev_input_field(pFld); break; case EDIT_NEXT_FIELD: /* move cursor to next input field */ pFld = get_next_input_field(pFld); if(!pFld) /* if last field rotate */ pFld = pFirst; break; case EDIT_PREV_FIELD: /* move cursor to prev input field */ /* find prev input field in chain */ pFld = get_prev_input_field(pFld); if(!pFld) /* if last field rotate */ pFld = pLast; break; case EDIT_TERMINATE: /* we're done */ pFld = NULL; break; } // switch } // main loop if(pPrev) tcob_scr_display_field(pPrev); // Display last accepted field refresh(); return key_status; } /* scr_curses.c */