/* * Copyright (C) 2003 Ferran Pegueroles, Hudson Reis. *. * 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 */ /* Screen routines */ #include #include #if defined(__MINGW32__) # include # include "mwindows.h" #else # include # include #endif #include "globals.h" #include // for read() struct screenArea { char initLine; char initColumn; char endLine; char endColumn; } *screenArea; struct screenposition { short line; short column; } *screenposition; char *windows[99]; struct windpos { unsigned char id, fu, ls, ce, nl, tl, atr; char dados[4000]; } *windpos; struct windmenu { unsigned char id, fu, ls, ce, nl, tl, atr, nlm, tlm, rtm; char dados[4000]; } *windmenu; int lastWindow = -1; bool initColor = 0; /* Prototypes */ /* Functions */ //cbl_t cbl_clear_scr(void) { // clear(); // return 0; //} //void cbl_get_csr_pos(int *x, int *y, int *retorno) { // getsyx((int)*y,(int)*x); // printf("Y: %d\n", *y); // printf("X: %d\n", *x); // *retorno = 0; //} //cbl_t cbl_get_kbd_status(void) { // nodelay(stdscr,TRUE); // timeout(10); // return(getch()); //} //cbl_t cbl_read_kbd_char(void) { // return (getch()); //} /*---------------------------------------------------------------------------------------- Routine: cbl_save_screen Purpose: Saves all screen contents on a user program buffer. ----------------------------------------------------------------------------------------*/ void cbl_save_screen( chtype *buffer ) { int l = 0; int c = 0; int i = 0; for ( l = 0 ; l < 24 ; l++ ) for ( c = 0 ; c < 80 ; c++ ) buffer[i++] = mvinch(l,c); } /*---------------------------------------------------------------------------------------- Routine: cbl_restore_screen Purpose: Restores all screen contents from a user program buffer. ----------------------------------------------------------------------------------------*/ void cbl_restore_screen( chtype *buffer ) { int l = 0; int c = 0; int i = 0; chtype k; for ( l = 0 ; l < 24 ; l++ ) for ( c = 0 ; c < 80 ; c++ ) { k = buffer[i++]; attron( (k & A_ATTRIBUTES) | (k & A_COLOR) ); mvaddch(l, c, (k & A_CHARTEXT)); } } /*---------------------------------------------------------------------------------------- Routine: cbl_save_partial_screen Purpose: Saves a screen portion's contents on a user program buffer. ----------------------------------------------------------------------------------------*/ void cbl_save_partial_screen( struct screenArea *screenArea , chtype *buffer ) { int l = 0; int c = 0; int i = 0; int initLine = (int)screenArea->initLine; int initCol = (int)screenArea->initColumn; int endLine = (int)screenArea->endLine; int endCol = (int)screenArea->endColumn; // mvprintw(23,0,"OnSave: %d %d %d %d",initLine,initCol,endLine,endCol); // getch(); // refresh(); for ( l = initLine-1 ; l < endLine ; l++ ) for ( c = initCol-1 ; c < endCol ; c++ ) buffer[i++] = mvinch(l,c); } /*---------------------------------------------------------------------------------------- Routine: cbl_restore_partial_screen Purpose: Restores a screen portion's contents from a user program buffer. ----------------------------------------------------------------------------------------*/ void cbl_restore_partial_screen( struct screenArea *screenArea , chtype *buffer ) { int l = 0; int c = 0; int i = 0; chtype k; int initLine = (int)screenArea->initLine; int initCol = (int)screenArea->initColumn; int endLine = (int)screenArea->endLine; int endCol = (int)screenArea->endColumn; // mvprintw(23,0,"OnRestore: %d %d %d %d",initLine,initCol,endLine,endCol); // getch(); // refresh(); for ( l = initLine-1 ; l < endLine ; l++ ) for ( c = initCol-1 ; c < endCol ; c++ ) { k = buffer[i++]; attron( (k & A_ATTRIBUTES) | (k & A_COLOR) ); mvaddch(l, c, (k & A_CHARTEXT)); } } /* void cbl_read_scr_chars (struct posicaotela *posicao, char *buffer_caracteres, short *buffer_tamanho, int *retorno) { printf("Reading scr chars...\n"); int y, x, i, t; *retorno = 0; posicaotela = posicao; x = posicao->coluna; y = posicao->linha; t = *buffer_tamanho - x; memset(buffer_caracteres,' ',t); for (i=(x-1);i<=t;i++) { buffer_caracteres[i] = mvinch(y,i) & A_CHARTEXT; } } void cbl_read_scr_attrs (struct posicaotela *posicao, char *buffer_atributos, short *buffer_tamanho, int *retorno) { int y, x, i, t; *retorno = 0; posicaotela = posicao; x = posicao->coluna; y = posicao->linha; t = *buffer_tamanho - x; memset(buffer_atributos,' ',t); for (i=(x-1);i<=t;i++) { buffer_atributos[i] = mvinch(y,i) & A_ATTRIBUTES; } } void cbl_read_scr_chattrs (struct posicaotela *posicao, char *buffer_caracteres, char *buffer_atributos, short *buffer_tamanho, int *retorno) { chtype k; int y, x, i, t, c; *retorno = 0; posicaotela = posicao; x = posicao->coluna; y = posicao->linha; memset(buffer_atributos, ' ',*buffer_tamanho * 2); memset(buffer_caracteres,' ',*buffer_tamanho); i = 0, t = 0, c = 0; while(i++ < *buffer_tamanho) { k = mvinch(y, x); buffer_caracteres[c++] = (k & A_CHARTEXT); buffer_atributos[t++] = (k & A_ATTRIBUTES)/65536; //buffer_atributos[t++] = k & A_COLOR; buffer_atributos[t++] = (k & A_COLOR)/256; //printf("color on read:%d\n",(char)((k & A_COLOR)/256)); mvprintw(1,1,"col:%d lin:%d char:%c color:%d",x,y,(k & A_CHARTEXT),(k & A_COLOR)/256); refresh(); getch(); refresh(); x++; } } */ /*---------------------------------------------------------------------------------------------- cbl_set_csr_pos Sets the cursor position ----------------------------------------------------------------------------------------------*/ //void cbl_set_csr_pos(int *x, int *y, int *retorno) { // *retorno = 0; // setsyx((int)*y,(int)*x); // move((int)*y,(int)*x); // refresh(); //} /* void cbl_write_scr_attrs (struct posicaotela *posicao, char *buffer_atributos, short *buffer_tamanho, int *retorno) { printf("Writing scr attributes...\n"); int y, x, i, t; *retorno = 0; posicaotela = posicao; x = posicao->coluna; y = posicao->linha; t = *buffer_tamanho + x; initscr(); for (i=(x-1);i<=t;i++) { mvaddch(y, x, *buffer_atributos); x++; *buffer_atributos++; } // refresh(); endwin(); } void cbl_write_scr_chars (struct posicaotela *posicao, char *buffer_caracteres, short *buffer_tamanho, int *retorno) { printf("Writing scr chars...\n"); int y, x, i, t; *retorno = 0; posicaotela = posicao; x = posicao->coluna; y = posicao->linha; t = *buffer_tamanho + x; initscr(); for (i=(x-1);i<=t;i++) { mvaddch(y, x, *buffer_caracteres); x++; *buffer_caracteres++; } // refresh(); endwin(); } cbl_t cbl_write_scr_chars_attr(void) { return 0; } void cbl_write_scr_chattrs (struct posicaotela *posicao, char *buffer_caracteres, char *buffer_atributos, short *buffer_tamanho, int *retorno) { chtype k; int y, x, i, k1, c, att, cor; //addstr("to em cbl_write_scr_chattrs"); refresh(); getch(); refresh(); *retorno = 0; posicaotela = posicao; x = posicao->coluna; y = posicao->linha; mvprintw(1,1,"col:%d lin:%d",x,y); refresh(); getch(); refresh(); i = 0, c = 0; while(i < *buffer_tamanho) { att = ((int) *(buffer_atributos + (c++))) * 65536; cor = ((int) *(buffer_atributos + (c++))) * 256; cor = buffer_atributos[c++]; k1 = *(buffer_caracteres + i); k1 += (k1<0?256:0); k = k1 | att | cor; mvaddch(y, x++, k); i++; } refresh(); } cbl_t cbl_write_scr_n_attr(void) { return 0; } cbl_t cbl_write_scr_n_char(void) { return 0; } cbl_t cbl_write_scr_n_chattr(void) { return 0; } cbl_t cbl_write_scr_tty(void) { return 0; } cbl_t cbl_get_scr_type(void) { return 0; } */ // ---------------------------------------------------------------------- // Implemented by Walter Garrote // garrote@dm.com.br // Brazil // Go��nia-Goi�s // ---------------------------------------------------------------------- // Obs: As subrotinas que manipulam acesso a video devem ser executadas // depois de ser chamado no programa cobol uma instru��o que fa�a a inicializa��o // da biblioteca ncurses. Se isso n�o ocorrer, teremos problema. // inicia par de cores void cbl_windms_inicia_cor() { int i; if(initColor) // ja passamos por aqui; return; if(has_colors()) { // temos suporte a cores start_color(); for(i = 0; i < COLOR_PAIRS; i++) init_pair(i, i % COLORS, i / COLORS); } initColor++; // na lib do tiny na parte de inicializacao de cores, n�o est� definido os pares // foi criada o par com fg e bg = 0 } // retorna cor de fundo e de frente usando o codigo de cor void cbl_windms_color_pair(short cor, short *fg, short *bg) { if(cor == 0) // cor padrao 7 (frente branca, fundo preto) cor = 7; *fg = cor % 8; // cor de frente *bg = cor / 8; // cor de fundo } // retorna o codigo de cor usando cor de frente e de fundo short cbl_windms_monta_cor(short fg, short bg) { return ((bg * 8) + fg); } // escreve na janela // para se pensar, podemos colocar um byte a mais como sendo o tipo do caracter (highlight, blink etc) void cbl_windms_escreve(struct windpos *lk) { int y, x; short fg, bg, atr; char *dados = NULL; switch(lk->fu) { // qual a funcao case 1: case 2: dados = windows[lk->id]; // posiciona na memoria alocada pelo subrotina break; case 10: dados = lk->dados; // estamos recebendo a tela via cobol atr = lk->atr; cbl_windms_color_pair(atr, &bg, &fg); attron(COLOR_PAIR(atr)); break; } move(lk->ls, lk->ce); refresh(); // apenas para garantir, caso haja um display antes for(y = lk->ls; y < (lk->ls + lk->nl); y++) { // escreve as linhas for(x = lk->ce; x < (lk->ce + lk->tl); x++) { // escreve as colunas if(*dados == '~') { // mudanca de atributo dados++; // proxima posicao fg = (int) *(dados++) - 48; // cor de frente bg = (int) *(dados++) - 48; // cor de fundo atr = cbl_windms_monta_cor(fg, bg); // qual o par ? attron(COLOR_PAIR(atr)); // set atributo } mvaddch(y, x, *dados++); } } refresh(); } // muda moldura da janela void cbl_windms_moldura(struct windpos *lk) { int i; short fg, bg, atr; atr = lk->atr; cbl_windms_color_pair(lk->atr, &fg, &bg); attron(COLOR_PAIR(atr)); mvaddch (lk->ls, lk->ce , ACS_ULCORNER); // canto esquerdo superior mvaddch (lk->ls, lk->ce + lk->tl - 1, ACS_URCORNER); // canto direito superior mvaddch (lk->ls + lk->nl - 1, lk->ce , ACS_LLCORNER); // canto esquerdo inferior mvaddch (lk->ls + lk->nl - 1, lk->ce + lk->tl - 1, ACS_LRCORNER); // canto direito inferior for(i = lk->ls + 1; i < lk->ls + lk->nl - 1; i++) { mvaddch(i, lk->ce , ACS_VLINE); // linha esquerda mvaddch(i, lk->ce + lk->tl - 1, ACS_VLINE); // linha direita } for(i = lk->ce + 1; i < lk->ce + lk->tl - 1; i++) { mvaddch(lk->ls, i , ACS_HLINE); // linha superior mvaddch(lk->ls + lk->nl - 1, i , ACS_HLINE); // linha inferior } refresh(); return; } // muda cor da janela void cbl_windms_mudacor(struct windpos *lk) { short fg, bg; cbl_windms_color_pair(lk->atr, &fg, &bg); attron(COLOR_PAIR(lk->atr)); } // guarda porcao da janela na memoria int cbl_windms_guarda(struct windpos *lk) { int y, x, tamanho; short fg, bg, atr, oldatr; // variaveis auxiliares char *dados; if(lastWindow == 99) // limite de janelas return -1; tamanho = 4; for(y = lk->ls; y < lk->ls + lk->nl + 1; y++) // quantos bytes serao necessarios ? for(x = lk->ce; x < lk->ce + lk->tl + 1; x++) { atr = (mvinch(y, x) & A_ATTRIBUTES) / 256; if(atr != oldatr) { tamanho += 3; oldatr = atr; } tamanho++; } lastWindow++; // janela a ser utilizada windows[lastWindow] = (char *) malloc(sizeof(char) * tamanho); //(lk->nl * lk->tl * 3)); // ponteiro para memoria de video dados = windows[lastWindow]; oldatr = 0; for(y = lk->ls; y < lk->ls + lk->nl; y++) { // guarda janela for(x = lk->ce; x < lk->ce + lk->tl; x++) { atr = (mvinch(y, x) & A_ATTRIBUTES) / 256; if(atr != oldatr) { cbl_windms_color_pair(atr, &bg, &fg); *dados++ = '~'; *dados++ = (char) ( ( atr % 8 ) + 48 ); *dados++ = (char) ( ( atr / 8 ) + 48 ); oldatr = atr; } *dados++ = mvinch(y, x) & A_CHARTEXT; } } return lastWindow; } // remove janela int cbl_windms_remove(struct windpos *lk) { while(lastWindow >= lk->id) if(windows[lastWindow]) { if(lk->fu == 2) // restaura janela antes cbl_windms_escreve(lk); free(windows[lastWindow--]); } return lastWindow; } // auxilio na montagem do menu void cbl_windms_display_menu(struct windpos *lk, char *dados, int linha) { } char * cbl_windms_pos(int nlm, int tlm, int l, int c, char *dad) { // int tc, l1, c1; // char *dat; return NULL; } // menu pop int cbl_windms_menu(struct windpos *lk) { //int t, y, int tecla = 0, nlm, tlm, rtm; char *dad; //, *dat; struct windpos *lkm; lkm = calloc(sizeof(struct windpos),0); // parametros lkm->id = lk->id; lkm->ls = lk->ls; lkm->ce = lk->ce; lkm->nl = lk->nl; lkm->tl = lk->tl; dad = lk->dados; nlm = (int) *dad++; tlm = (int) *dad++; rtm = (int) *dad++; //t = //while(t>0) { // lkm->dados[y++]=*dad++; // t--; //} //lkm->dados = *dad; lkm->fu = 11; cbl_windms_moldura(lkm); // moldura lkm->fu = 10; cbl_windms_escreve(lkm); cbl_windms_display_menu(lk, dad, rtm); noecho(); tecla = getch(); do { // switch(tecla) { // case 27: printf("27\n"); // tecla = getch(); // switch(tecla) { // case 79: tecla = getch(); // break; // case 91: tecla = getch(); // switch(tecla) { // case 49: // case 50: // case 51: // case 52: // case 53: // case 54: do { // tecla = getch(); // } while(tecla != 126); // break; // } // break; // default: break; // } // break; // default: printf("oia %i,%c\n",tecla,tecla); // break; // } move(5, 1); addch(32); refresh(); switch(tecla) { case KEY_UP: printf("UP %i\t%c ",tecla,tecla); break; case KEY_DOWN: printf("Down %i\t%c ",tecla,tecla); break; case KEY_LEFT: printf("Left %i\t%c ",tecla,tecla); break; case KEY_RIGHT: printf("Right %i\t%c ",tecla,tecla); break; case KEY_HOME: printf("Home %i\t%c ",tecla,tecla); break; case KEY_END: printf("End %i\t%c ",tecla,tecla); break; case KEY_NPAGE: printf("Npage %i\t%c ",tecla,tecla); break; case KEY_PPAGE: printf("Ppage %i\t%c ",tecla,tecla); break; default: break; } move(5, 1); addch(32); refresh(); tecla = getch(); } while(tecla != KEY_EXIT); echo(); return 1; } // funcao principal int windms(struct windpos *lk) { struct windpos *lkaux; // ajusta valores lkaux = (struct windpos *) malloc(sizeof(struct windpos)); *lkaux = *lk; lkaux->ls--; lkaux->ce--; cbl_windms_inicia_cor(); if( //(lkaux->ls < 0 || lkaux->ls > 24) || (lkaux->ce < 0 || lkaux->ce > 79) || (lkaux->nl < 1 || lkaux->nl > 24) || (lkaux->tl < 1 || lkaux->tl > 79)) // parametros errados return 0; switch(lk->fu) { case 0: lk->id = cbl_windms_guarda(lkaux); // guarda janela break; case 2: // restaura janela case 3: lk->id = cbl_windms_remove(lkaux); // elimina janela sem restaurar break; case 1: // restaura janela case 10: cbl_windms_escreve(lkaux); // escreve janela break; case 11: cbl_windms_moldura(lkaux); // moldura a janela break; case 12: cbl_windms_mudacor(lkaux); // muda cor da janela break; case 13: cbl_windms_menu(lkaux); // menu getch(); break; } return 1; } // Function to allocate dinamyc memory // receive: pointer = pointer to memory allocated // size = size of memory to allocate // flags = only for compatibility // return: 0 = ok, memory allocated // 1 = error int cbl_alloc_mem(char **pointer, unsigned int size, unsigned int flagsmem ) { if((*pointer = (char *) malloc(sizeof(char) * size))) // memset(*pointer, 32, size); for compatibility, microfocus doesn�t initialize the memory allocated return 0; return 1; } // free the memory previous allocated // receive: pointer // return: none void cbl_free_mem(char **pointer) { free(*pointer); } // clear the window with character and attribute // receive: character = that will paint the screen // attribute = pair of attribute // return: none void cbl_clear_scr(short character, short atr) { int normal = A_NORMAL | character; cbl_windms_inicia_cor(); if(has_colors()) normal |= COLOR_PAIR(atr); bkgdset(normal); erase(); return; } // return the position of cursor // receive: structure with line and column // return: position of cursor void cbl_get_csr_pos(struct screenposition *scr) { getsyx(scr->line, scr->column); scr->line++; // adjust the line scr->column++; // adjust the column return; } // return the state of keyboard // receive: none // return: state of keyboard : 0 none, 1 has key // modified from scr_curses void cbl_get_kbd_status(short *state) { int c; nodelay(stdscr,TRUE); c=getch(); nodelay(stdscr,FALSE); if(c > 0) { ungetch(c); *state = 1; } else *state = 0; return; } // return the size of screen // receive: none // return: depth and width void cbl_get_scr_size(short *depth, short *width) { getmaxyx(stdscr, *depth, *width); return; } // return the character in keyboard buffer // receive: none // return: character //void cbl_read_kbd_char2(char *character) { // *character = (char) getch(); // return; //} void clr_clear_kbd_buffer() { nodelay(stdscr, TRUE); while( getch() != ERR ); nodelay(stdscr,FALSE); } //static struct termios initial_settings, new_settings; static int peek_character = -1; void init_keyboard() { // tcgetattr(0,&initial_settings); // new_settings = initial_settings; // new_settings.c_lflag &= ~ICANON; // new_settings.c_lflag &= ~ECHO; // new_settings.c_lflag &= ~ISIG; // new_settings.c_cc[VMIN] = 1; // new_settings.c_cc[VTIME] = 0; // tcsetattr(0, TCSANOW, &new_settings); } void close_keyboard() { // tcsetattr(0, TCSANOW, &initial_settings); } int readch() { char ch; if(peek_character != -1) { ch = peek_character; peek_character = -1; return ch; } read(0,&ch,1); return ch; }