/* * Copyright (C) 2005 Walter Garrote * * 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 #include #include #include "screen.h" extern char *last_screen_status; void cbl_read_keyboard(char *str6); char * cbl_avanca_posicao(char *dad, unsigned int qtd); void cbl_windms_mudacor_posicao(short y, short x, int cor); void tcob_init_screen(void); int tcob_scr_kbdstatus(void); // inicia par de cores void cbl_windms_inicia_cor() { int i; if(initcor) // 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); } initcor++; // 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); } attr_t encontra_atributo(char *dados) { attr_t atr = A_NORMAL; bool normal = true, standout = false, underline = false, blink = false, reverse = false, dim = false, protect = false, invisible = false, bold = false, horiz = false, left = false, low = false, right = false, top = false, vertical = false, neg = false; if(*dados == '/') { neg = true; *dados++; } else neg = false; while(*dados != '}') { *dados = tolower(*dados); switch(*dados) { case 'n': normal = ((neg) ? false : true); // normal if(normal) { blink = false; standout = false; underline = false; reverse = false; protect = false; invisible = false; bold = false; dim = false; horiz = false; left = false; low = false; right = false; top = false; vertical = false; } break; case 'b': blink = ((neg) ? false : true); // blink if(blink) normal = false; break; case 's': standout = ((neg) ? false : true); // standout if(standout) normal = false; break; case 'u': underline= ((neg) ? false : true); // underline if(underline) normal = false; break; case 'r': reverse = ((neg) ? false : true); // reverse if(reverse) normal = false; break; case 'd': dim = ((neg) ? false : true); // dim if(dim) normal = false; break; case 'p': protect = ((neg) ? false : true); // protect if(protect) normal = false; break; case 'i': invisible= ((neg) ? false : true); // invisible if(invisible) normal = false; break; case 'o': bold = ((neg) ? false : true); // bold if(bold) normal = false; break; case 'h': horiz = ((neg) ? false : true); // horizontal if(horiz) normal = false; break; case 'l': left = ((neg) ? false : true); // left if(left) normal = false; break; case 'w': low = ((neg) ? false : true); // low if(low) normal = false; break; case 'g': right = ((neg) ? false : true); // right if(right) normal = false; break; case 't': top = ((neg) ? false : true); // top if(top) normal = false; break; case 'v': vertical = ((neg) ? false : true); // vertical if(vertical) normal = false; break; } *dados++; } if(normal) atr = A_NORMAL; else { atr = ((blink) ? A_BLINK : 0) | ((standout) ? A_STANDOUT : 0) | ((underline) ? A_UNDERLINE : 0) | ((reverse) ? A_REVERSE : 0) | ((dim) ? A_DIM : 0) | ((protect) ? A_PROTECT : 0) | ((invisible) ? A_INVIS : 0) | ((bold) ? A_BOLD : 0) | ((horiz) ? A_HORIZONTAL: 0) | ((left) ? A_LEFT : 0) | ((low) ? A_LOW : 0) | ((right) ? A_RIGHT : 0) | ((top) ? A_TOP : 0) | ((vertical) ? A_VERTICAL : 0) ; } return atr; } // escreve na janela // para se pensar, podemos colocar um byte a mais como sendo o tipo do caracter (highlight, blink etc) //2005-11-10 void cbl_windms_escreve(struct windpos *lk, unsigned int ponteiro, unsigned int salto, unsigned int ini, unsigned int ul) { void cbl_windms_escreve(struct windmenu *lk, char *dados, unsigned int ponteiro, unsigned int salto, unsigned int ini, unsigned int ul) { int y, x, cor, atr, tlaux; short fg, bg; char *dados1; chtype caracter; //, xu; unsigned char ls, ce, nl, tl; bool disp; ls = lk->ls; ce = lk->ce; nl = lk->nl; tl = lk->tl; atr = A_NORMAL; switch(lk->fu) { // qual a funcao case 1: case 2: //2005-11-10 dados = salvawind[lk->id]->ponteiros; // posiciona na memoria alocada pelo subrotina ls = salvawind[lk->id]->ls; ce = salvawind[lk->id]->ce; nl = salvawind[lk->id]->nl; tl = salvawind[lk->id]->tl; fg = 0; bg = 0; cor = 0; break; case 10: //2005-11-10 dados = &lk->dados[0]; // estamos recebendo a tela via cobol cbl_windms_color_pair(lk->atr, &bg, &fg); cor = COLOR_PAIR(cbl_windms_monta_cor(fg, bg)); // qual o par ? break; case 23: case 13: //2005-11-10 dados = &lk->dados[0]; dados += ponteiro; cbl_windms_color_pair(lk->atr, &bg, &fg); cor = COLOR_PAIR(cbl_windms_monta_cor(fg, bg)); // qual o par ? break; } tlaux = tl; if(salto && salto < tl) tlaux = salto; dados1 = dados; if(ini) // menu dados = cbl_avanca_posicao(dados, ini); attroff(A_BLINK); attroff(A_STANDOUT); attroff(A_UNDERLINE); attroff(A_REVERSE); attroff(A_DIM); attroff(A_PROTECT); attroff(A_INVIS); attroff(A_BOLD); attroff(A_HORIZONTAL); attroff(A_LEFT); attroff(A_LOW); attroff(A_RIGHT); attroff(A_TOP); attroff(A_VERTICAL); standend(); color_set(0, NULL); // attron(atr); // color_set(cor, NULL); // attrset(atr); // move(ls, ce); refresh(); // apenas para garantir, caso haja um display antes for(y = ls; y < (ls + nl); y++) { // escreve as linhas x = ce; while(x < (ce + tlaux)) { // escreve as colunas disp = false; switch(*dados) { case '~': // mudanca de cor *dados++; // proxima posicao fg = (int) *(dados++) - 48; // cor de frente bg = (int) *(dados++) - 48; // cor de fundo cor = COLOR_PAIR(cbl_windms_monta_cor(fg, bg)); // par // color_set(cor, NULL); break; case '^': // mudanca de atributo e caracter especial *dados++; switch(*dados) { case '{': // mudanca de atributo *dados++; // proxima posicao // attroff(atr); atr = encontra_atributo(dados); while(*dados != '}') *dados++; *dados++; // attron(atr); break; case '[': // alternate character *dados++; caracter = NCURSES_ACS(*dados++) | cor | atr; disp = true; break; default: caracter = *dados | cor | atr; disp = true; break; } break; default: caracter = *dados | cor | atr; disp = true; break; } if(disp) { // xu = ' ' | 0 | A_NORMAL; attrset(0); color_set(0, NULL); // mvaddch(y, x, xu); // if(lk->fu == 2){ refresh();getch();} mvaddch(y, x, caracter); *dados++; x++; // if(lk->fu == 2){ refresh();getch();} } } if(salto) // menu dados = cbl_avanca_posicao(dados, (unsigned int) (salto - tlaux)); } if(ul) { // limpar ate o final da janela menu caracter = ' ' | cor | atr; while(y
    atr, &bg, &fg); cor = COLOR_PAIR(cbl_windms_monta_cor(fg, bg)); // qual o par ? c = ACS_ULCORNER | cor | atr; mvaddch (lk->ls, lk->ce , c); // cnt esq superior c = ACS_URCORNER | cor | atr; mvaddch (lk->ls, lk->ce + lk->tl - 1, c); // cnt dir superior c = ACS_LLCORNER | cor | atr; mvaddch (lk->ls + lk->nl - 1, lk->ce , c); // cnt esq inferior c = ACS_LRCORNER | cor | atr; mvaddch (lk->ls + lk->nl - 1, lk->ce + lk->tl - 1, c); // cnt dir inferior c = ACS_VLINE | cor | atr; for(i = lk->ls + 1; i < lk->ls + lk->nl - 1; i++) { mvaddch(i, lk->ce , c); // linha esquerda mvaddch(i, lk->ce + lk->tl - 1, c); // linha direita } c = ACS_HLINE | cor | atr; for(i = lk->ce + 1; i < lk->ce + lk->tl - 1; i++) { mvaddch(lk->ls, i , c); // linha superior mvaddch(lk->ls + lk->nl - 1, i , c); // linha inferior } refresh(); return; } // faz sombra na janela //2005-11-10 void cbl_windms_sombra(struct windpos *lk) { void cbl_windms_sombra(struct windmenu *lk) { short i, ce, li; int sombra; ce = lk->ce + lk->tl; li = lk->ls + lk->nl; if(ce < 80) { for(i = lk->ls + 1; (i < li + 1 && i < 25); i++) { sombra = mvinch(i, ce) & A_COLOR; if(sombra > 8) cbl_windms_mudacor_posicao(i, ce, sombra / 8); } } if(li < 25) { for(i = lk->ce + 1; (i < ce && i < 80); i++) { sombra = mvinch(li, i) & A_COLOR; if(sombra > 8) cbl_windms_mudacor_posicao(li, i, sombra / 8); } } return; } // muda cor da posicao void cbl_windms_mudacor_posicao(short y, short x, int cor) { chtype pos; short car; attr_t atr; pos = mvinch(y, x); car = pos & A_CHARTEXT; atr = ( pos & A_ATTRIBUTES ) / 65536; pos = car | atr | cor; addch(pos); return; } // muda cor da janela //2005-11-10 void cbl_windms_mudacor(struct windpos *lk) { void cbl_windms_mudacor(struct windmenu *lk) { int cor; short fg, bg; short x, y; // variaveis auxiliares cbl_windms_color_pair(lk->atr, &bg, &fg); cor = COLOR_PAIR(cbl_windms_monta_cor(fg, bg)); // qual o par ? 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 cbl_windms_mudacor_posicao(y, x, cor); return; } // retorna tipo do atributo void retorna_atributo(char *atrc, attr_t atr) { *atrc = 'n'; // A_NORMAL *atrc=(atr & A_STANDOUT ?'s':*atrc); *atrc=(atr & A_UNDERLINE ?'u':*atrc); *atrc=(atr & A_REVERSE ?'r':*atrc); *atrc=(atr & A_BLINK ?'b':*atrc); *atrc=(atr & A_DIM ?'d':*atrc); *atrc=(atr & A_BOLD ?'o':*atrc); *atrc=(atr & A_PROTECT ?'p':*atrc); *atrc=(atr & A_INVIS ?'i':*atrc); *atrc=(atr & A_HORIZONTAL?'h':*atrc); *atrc=(atr & A_LEFT ?'l':*atrc); *atrc=(atr & A_LOW ?'w':*atrc); *atrc=(atr & A_RIGHT ?'g':*atrc); *atrc=(atr & A_TOP ?'t':*atrc); *atrc=(atr & A_VERTICAL ?'v':*atrc); } // guarda porcao da janela na memoria //2005-11-10 int cbl_windms_guarda(struct windpos *lk) { int cbl_windms_guarda(struct windmenu *lk) { int y, x, tamanho; chtype pos; short cor, oldcor, car, fg, bg; // variaveis auxiliares attr_t atr; char *dados, *dados1; char atrc, oldatrc; if(ultima_janela == 99) // limite de janelas return -1; oldcor = -1; oldatrc = '\0'; tamanho = 0; // quantos bytes serao necessarios ? for(y = lk->ls; y < lk->ls + lk->nl + 1; y++) for(x = lk->ce; x < lk->ce + lk->tl + 1; x++) { pos = mvinch(y, x); cor = (pos & A_COLOR) / 256; atr = (pos & A_ATTRIBUTES); car = (pos & A_CHARTEXT); if(cor != oldcor) { // mudou a cor tamanho += 3; oldcor = cor; } retorna_atributo(&atrc, atr); // pega codigo atributo if(atrc != oldatrc) { // atributo diferente tamanho += 4; oldatrc = atrc; } if(atr & A_ALTCHARSET) // caracter especial tamanho += 4; else tamanho++; } ultima_janela++; // janela a ser utilizada salvawind[ultima_janela] = malloc(sizeof(struct salvawind)); salvawind[ultima_janela]->ls = lk->ls; salvawind[ultima_janela]->ce = lk->ce; salvawind[ultima_janela]->nl = lk->nl; salvawind[ultima_janela]->tl = lk->tl; salvawind[ultima_janela]->ponteiros = malloc(sizeof(char) * tamanho); dados = salvawind[ultima_janela]->ponteiros; dados1 = dados; oldcor = -1; oldatrc = '\0'; for(y = lk->ls; y < lk->ls + lk->nl; y++) { // guarda janela for(x = lk->ce; x < lk->ce + lk->tl; x++) { pos = mvinch(y, x); cor = (pos & A_COLOR) / 256; atr = (pos & A_ATTRIBUTES); car = (pos & A_CHARTEXT); if(cor != oldcor) { // mudou a cor cbl_windms_color_pair(cor, &bg, &fg); oldcor = cor; *dados++ = '~'; *dados++ = (char) ( ( cor % 8 ) + 48 ); *dados++ = (char) ( ( cor / 8 ) + 48 ); } retorna_atributo(&atrc, atr); // pega codigo atributo if(atrc != oldatrc) { // atributo diferente oldatrc = atrc; *dados++ = '^'; *dados++ = '{'; *dados++ = atrc; *dados++ = '}'; } if(atr & A_ALTCHARSET) { // caracter especial *dados++ = '^'; *dados++ = '['; *dados++ = car; *dados++ = ']'; } else *dados++ = car; } } return ultima_janela; } // remove janela //2005-11-10 int cbl_windms_remove(struct windpos *lk) { int cbl_windms_remove(struct windmenu *lk) { while(ultima_janela >= lk->id) if(salvawind[ultima_janela]->ponteiros) { if(lk->fu == 2) // restaura janela antes //2005-11-10 cbl_windms_escreve(lk, 0, 0, 0, 0); cbl_windms_escreve(lk, salvawind[ultima_janela]->ponteiros, 0, 0, 0, 0); free(salvawind[ultima_janela]->ponteiros); free(salvawind[ultima_janela]); ultima_janela--; } return ultima_janela; } // avanca n casas considerando atributos e cores char * cbl_avanca_posicao(char *dad, unsigned int qtd) { while(qtd) { switch(*dad) { case '~': dad += 3; break; case '^': if(*(dad + 1) == '[') dad += 6; else { qtd--; dad++; } break; default: qtd--; dad++; break; } } return dad; } /* menu pop */ int cbl_windms_menu(struct windmenu *lk, char *dados) { int refaz = 0; char str6[6], *dad; unsigned int tecla=0, ci, li, lj, pos; char tmp[5]; cbl_windms_moldura(lk); /* display the box before */ /* ajust the size of the window and other parameters */ lk->ls++; lk->ce++; lk->nl -= 2; lk->tl -= 2; if(lk->lim == 0) lk->lim = 1; if(lk->lam == 0) lk->lam = 1; if(lk->lam > (lk->ls + lk->nl)) lk->lam = lk->ls; if(lk->cam > (lk->ce + lk->tl)) lk->cam = lk->ce; dad = cbl_avanca_posicao(dados, (lk->lim - 1) * lk->tlm); /* move pointer to the first characeter */ cbl_windms_escreve(lk, dados, (unsigned int) (dad - dados), lk->tlm, lk->cam, (unsigned int) lk->nl); /* write window */ ci = lk->cam; /* column in window */ li = lk->lim; /* first line in windows */ lj = lk->lam; /* atual line in window */ tecla = 0; /* return key */ noecho(); while(tecla != KEY_EXIT && tecla != KEY_ENTER && tecla != 13 && tecla != 27) { move(lj + lk->ls - 1, lk->ce); tecla = getch(); refaz = 0; switch(tecla) { case 13: case KEY_ENTER: lk->ktm = tecla; break; case KEY_UP: if(lj > 1) lj--; else { if(li > 1) { li--; refaz = 2; } } break; case KEY_DOWN: if(lj < lk->nl - 2) lj++; else { if(lj + li <= lk->nlm) { li++; refaz = 2; } } break; case KEY_LEFT: if(ci > 0) { ci--; refaz = 1; } break; case KEY_RIGHT: if((ci + lk->tl) < lk->tlm) { ci++; refaz = 1; } break; case KEY_NPAGE: if(li < lk->nlm - lk->nl - 2) li += lk->nl - 2; else { li = lk->nlm; } lj = 1; refaz = 2; break; case KEY_PPAGE: if(li > lk->nl - 3) li -= lk->nl - 3; else { li = 1; } lj = 1; refaz = 2; break; case 'i': case 'I': li = 1; lj = 1; refaz = 2; break; case 'f': case 'F': li = lk->nlm; lj = 1; refaz = 2; break; case ' ': if(lk->fu == 23) { dad = cbl_avanca_posicao(dados, (li + lj - 2) * (lk->tlm)); pos = (unsigned int) (dad - dados); dados[pos] = (dados[pos] == ' ' ?'*':' '); addch(dados[pos]); refresh(); } break; case 'm': case 'M': if(lk->fu == 23) { lk->ktm = 'M'; tecla = 27; } break; case 'd': case 'D': if(lk->fu == 23) { lk->ktm = 'D'; tecla = 27; } break; default: if(tecla == 27) { ungetch(tecla); cbl_read_keyboard(&str6[0]); } tecla = 0; if(str6[0] == 27 && str6[1] == 0) { tecla = 27; lk->ktm = tecla; } break; } switch(refaz) { case 1: lk->nl = ((lk->nlm - li) < lk->nl-2 ? (lk->nlm - li + 1):(lk->nl - 2)); cbl_windms_escreve(lk, dad, (unsigned int) (dad - dados), lk->tlm, ci, (unsigned int) lk->nl-2); break; case 2: dad = cbl_avanca_posicao(dados, (li - 1) * (lk->tlm)); lk->nl = ((lk->nlm - li) < lk->nl-2 ? (lk->nlm - li + 1):(lk->nl - 2)); cbl_windms_escreve(lk, dad, (unsigned int) (dad - dados), lk->tlm, ci, (unsigned int) lk->nl-2); break; } } echo(); tmp[4]='\0'; sprintf(tmp, "%04i", tecla); memcpy(last_screen_status, tmp, 4); lk->rtm = lj + li - 1; lk->lim = li; lk->lam = lj; lk->cam = ci; 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 ) { *pointer=NULL; if((*pointer = malloc(sizeof(char) * *(size)))) 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(int character, int cor) { cbl_windms_inicia_cor(); if(has_colors()) character = character | COLOR_PAIR(cor); bkgdset(character); 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 position of cursor receive: structure with line and column return: position of cursor */ void cbl_set_csr_pos(struct screenposition *scr) { move(scr->line - 1, scr->column - 1); 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(char *state) { int c; nodelay(stdscr,TRUE); c=getch(); nodelay(stdscr,FALSE); if(c > 0) { ungetch(c); *state = 49; } else *state = 48; return; } /* set the state of keypad */ void cbl_set_keypad(int state) { keypad(stdscr, (state==1?TRUE:FALSE)); 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_char(char *character) { *character = (char) getch(); return; } /* return the keyboard string */ void cbl_read_keyboard(char *str6) { int c, p; char *s; s = str6; memset(s, 0, 6); cbl_set_keypad(0); c = getch(); *s++ = (char) c; p = 0; if(c == 27) { while(tcob_scr_kbdstatus() && ++p < 6) *s++ = (char) getch(); } cbl_set_keypad(1); } // controle de janelas // lk_info = ponteiro para cabecalho da janela (janela ou menu) // lk_dados = dados da janela int windms2(char *lk_info, char *lk_dados) { struct windpos2 *lk2=NULL; struct windmenu *lk=NULL; if(last_screen_status == NULL) /* alloc memory for last_screen_status */ last_screen_status = malloc(sizeof(char) * 5); tcob_init_screen(); /* check to see if ncurses was started */ cbl_windms_inicia_cor(); /* colors */ lk = malloc(sizeof(struct windmenu)); /* make a copy of parameters */ lk2 = (struct windpos2 *) lk_info; if(*(lk_info + 1) == 13 || *(lk_info + 1) == 23) { /* menu */ lk->id = lk2->id; lk->fu = lk2->fu; lk->ls = lk2->ls; lk->ce = lk2->ce; lk->nl = lk2->nl; lk->tl = lk2->tl; lk->atr = lk2->atr; lk->nlm = (unsigned int) *(lk_info + 7); lk->tlm = (unsigned int) *(lk_info + 11); lk->ktm = (unsigned int) *(lk_info + 15); lk->rtm = (unsigned int) *(lk_info + 19); lk->lim = (unsigned int) *(lk_info + 23); lk->lam = (unsigned int) *(lk_info + 27); lk->cam = (unsigned int) *(lk_info + 31); } else { /* other functions */ lk->id = lk2->id; lk->fu = lk2->fu; lk->ls = lk2->ls; lk->ce = lk2->ce; lk->nl = lk2->nl; lk->tl = lk2->tl; lk->atr = lk2->atr; lk->nlm = 0; lk->tlm = 0; lk->ktm = 0; lk->rtm = 0; lk->lim = 0; lk->lam = 0; lk->cam = 0; } /* verify the parameters */ if((lk->ls == 0 || lk->ce == 0)) { /* if line or column didn´t exists, use the cursor position */ int lin, col; getsyx(lin, col); if(lk->ls == 0) lk->ls = lin + 1; if(lk->ce == 0) lk->ce = col + 1; } if(lk->ls > 25) lk->ls = 25; if(lk->ce > 80) lk->ce = 80; if(lk->nl > 25) lk->nl = 25; if(lk->tl > 80) lk->tl = 80; lk->ls--; lk->ce--; switch(lk->fu) { /* execute the function */ case 0: lk->id = cbl_windms_guarda(lk); /* store the window */ break; case 2: /* restore the window and remove them */ case 3: lk->id = cbl_windms_remove(lk); /* just remove the window */ break; case 1: /* restore the window without remove */ case 10: cbl_windms_escreve(lk, lk_dados, 0, 0, 0, 0); /* write the window */ break; case 11: case 14: cbl_windms_moldura(lk); /* display a box */ if(lk->fu == 14) cbl_windms_sombra(lk); /* shadow the box */ break; case 12: cbl_windms_mudacor(lk); /* change color of the window */ break; case 13: case 23: cbl_windms_menu(lk, lk_dados); /* menu */ break; } /* return the values acording to the funcions */ switch(lk->fu) { case 0: /* free window */ case 2: *(lk_info) = lk->id; /* last window saved */ break; case 13: /* menu */ case 23: *(lk_info+15) = lk->ktm; /* last keycode */ *(lk_info+19) = lk->rtm; /* line in array */ *(lk_info+23) = lk->lim; /* first line number in actual box */ *(lk_info+27) = lk->lam; /* line in the box */ *(lk_info+31) = lk->cam; /* column in the box */ break; } return 1; }