Good news: Cursor keys working in GRASS shell windows
Markus Neteler
neteler at geog.uni-hannover.de
Tue Jul 6 04:57:46 EDT 1999
Hi!
On Tue, 6 Jul 1999, Phisan Santitamnont wrote:
> > - RETURN cycles through the input lines (as usual)
> > - cursor keys left and right are working (new)
> > - cursor keys up and down are working (new)
> > - ESC-RETURN take you out of the screen (modified)
> can i get the code to patch into 5.0
Yes, find it attached.
Replace this V_call.c with original version in:
src/libes/vask
Please save the original file first!
It works for GRASS 4.2.1 as well.
Cheers
Markus
-------------- next part --------------
#define TELLME(x) fprintf(stderr,"V_call %d\n",x) ;
#
/***********************************************************************
Modified by Jacques Bouchard and Markus Neteler 6/99 to make cursor
keys working. Exit now with ESC-CR.
NAME: V_call()
FUNCTION: Interactively allow the user to enter answers into all
available fields (as previously defined).
Answer fields have been created with calls to V_ques()
Information fields have been created using V_const()
General text has been created with calls to V_line()
USAGE: V_call()
PARAMETERS:
RETURNS: 1 user entered ESC to continue
0 user entered ctrl-C to cancel
ALGORITHM:
| Zero out screen answer locations
| Initial curses screens
| Display text, constants, and answer fields
| Write text (results from V_line() calls) to curses window
| Write constants (results from V_const() calls) to curses window
| Write answers (results from V_ques() calls) to curses window
| Take commands from the keyboard
| switch on commands:
| case CR: case NL: case UP: case ESC:
| switch on answer type
| case string
| remove trailing non-alphanumeric characters
| copy answer to target denoted in V_ques() call
| blank out screen line
| copy target to curses window
| case integer
| run atoi on answer, putting results in target
| denoted in V_ques() call
| blank out screen line
| printf target to curses window
| case long
| run atol on answer, putting results in target
| denoted in V_ques() call
| blank out screen line
| printf target to curses window
| case float, double
| run sscanf on answer, putting results in target
| denoted in V_ques() call
| blank out screen line
| printf target to curses window
| default:
| do nothing
| if ESC+CR return from V_call()
| if UP shift to previous question
| if CR or NL shift to next question
| case BS: Move cursor back one column in current question
| case FS: Move cursor forward one column in current
| question
| case RPLT: Replot the current screen image
| case DUMP: Dump (append) the current window to the user's
| home dir.
| default: If an alphanumeric, put that char on the screen
| and in the current answer field
| call V_exit (erase screen and exit curses)
CALLS:
V_init() Vask routine to initialize curses
V_exit() Vask routine to exit curses
V__dump_window() V_ask
V__remove_trail() V_ask
addch() curses routine
addstr() curses routine
move() curses routine
putc() curses routine
refresh() curses routine
getch() curses routine
wrefresh() curses routine
sprintf() UNIX
strcpy() UNIX
***********************************************************************/
#include "vask.h"
/* define the V__ struct defined in vask.h */
struct V__ V__ ;
#define DUMP 001
#define BELL 007
#define BS 010
#define FS 014
#define NL 012
#define UP 013
#define CR 015
#define RPLT 022
#define ESC 033
#define CTRLC 003
#define TARGET V__.usr_answ[at_answer].targetptr
#define ROW V__.usr_answ[at_answer].row
#define COL V__.usr_answ[at_answer].col
#define LENGTH V__.usr_answ[at_answer].length
#define TYPE V__.usr_answ[at_answer].var_type
#define ANSWER scr_answ[at_answer].position
#define RELINE move(ROW, COL) ; \
for (incr2=0;incr2<LENGTH; incr2++) \
addch('_') ; \
move(ROW, COL)
/* flag ctrl-c is to be allowed */
static int interrupts_ok = 0; /* mod shapiro */
V_call()
{
int incr ;
int incr2 ;
int num_answers ;
int at_answer ;
int at_constant ;
int ans_col ;
char newchar ;
char lastchar = 0;
int c;
struct { char position[80]; } scr_answ[MAX_ANSW] ;
long atol() ;
int y,x; /* shapiro */
char temp[100];
/* Zero out screen answer locations */
for(incr=0; incr<MAX_ANSW; incr++)
for(incr2=0; incr2<80; incr2++)
scr_answ[incr].position[incr2] = 000 ;
/* Initialize the curses windows */
V_init() ;
/* Display text */
for (incr=0; incr<MAX_LINE; incr++)
{
move (incr, 0) ;
addstr(V__.page.line[incr]) ;
}
/* Display constants */
for (at_constant=0; at_constant < V__.NUM_CONST; at_constant++)
{
move(V__.constant[at_constant].row, V__.constant[at_constant].col) ;
switch (V__.constant[at_constant].var_type)
{
case 's':
addstr(V__.constant[at_constant].targetptr.c) ;
break ;
case 'i':
sprintf(temp,"%d", *V__.constant[at_constant].targetptr.i) ;
addstr (temp) ;
break ;
case 'l':
sprintf(temp,"%ld", *V__.constant[at_constant].targetptr.l) ;
addstr (temp) ;
break ;
case 'f':
fmt (temp, V__.constant[at_constant].decimal_places,
(double)*V__.constant[at_constant].targetptr.f) ;
addstr (temp) ;
break ;
case 'd':
fmt (temp, V__.constant[at_constant].decimal_places,
(double)*V__.constant[at_constant].targetptr.d) ;
addstr (temp) ;
break ;
default:
break ;
}
}
/* Display answer locations */
for (at_answer=0; at_answer < V__.NUM_ANSW; at_answer++)
{
/* clear ANSWER */
for (incr=0; incr<80; incr++)
scr_answ[at_answer].position[incr] = 000 ;
switch (TYPE)
{
case 's':
strcpy(ANSWER, TARGET.c) ;
RELINE ;
for (incr=0; incr<LENGTH; incr++)
{
if ( *(TARGET.c + incr) == '\000')
while (incr++ < LENGTH)
addch('_') ;
else addch( *(TARGET.c + incr) ) ;
}
break ;
case 'i':
sprintf(ANSWER,"%d",*TARGET.i) ;
RELINE ;
addstr (ANSWER);
break ;
case 'l':
sprintf(ANSWER,"%ld",*TARGET.l) ;
RELINE ;
addstr (ANSWER);
break ;
case 'f':
fmt (ANSWER, V__.usr_answ[at_answer].decimal_places, (double)*TARGET.f);
RELINE ;
addstr (ANSWER);
break ;
case 'd':
fmt (ANSWER, V__.usr_answ[at_answer].decimal_places, (double)*TARGET.d);
RELINE ;
addstr (ANSWER);
break ;
default:
break ;
}
}
num_answers = at_answer ;
if (interrupts_ok)
move(22,0) ;
else
move(23,0) ;
centered("AFTER COMPLETING ALL ANSWERS, HIT <ESC><ENTER> TO CONTINUE") ;
if (interrupts_ok)
{
sprintf(temp,"(OR <Ctrl-C> TO %s)", V__.interrupt_msg);
centered(temp);
}
/* Begin taking commands/answers from terminal */
at_answer = 0 ;
ans_col = 0 ;
move(ROW, COL) ;
refresh() ;
while(1)
{
getyx (stdscr, y, x);
c = getch() & 0177;
if(c == EOF)
{
move (y, x);
refresh();
continue;
}
if (c == CTRLC && interrupts_ok == 0)
{
move (y, x);
refresh();
continue;
}
if (V__.NUM_ANSW <= 0)
{
if (c == ESC || c == CTRLC)
{
interrupts_ok = 0;
V_exit() ;
return(c == ESC) ;
}
move (y, x);
refresh();
continue;
}
newchar = c;
switch (newchar)
{
case CR: case NL: case UP: case ESC: case CTRLC:
V__remove_trail(LENGTH, ANSWER) ;
switch (TYPE)
{
case 's':
/*
ans_col = (LENGTH) ;
while((ANSWER[--ans_col] < 041) || (ANSWER[ans_col] > 0175));
ANSWER[++ans_col] = 000 ;
*/
/*
V__remove_trail(LENGTH, ANSWER) ;
*/
strcpy(TARGET.c, ANSWER) ;
RELINE ;
addstr(TARGET.c) ;
break ;
case 'i':
*TARGET.i = atoi(ANSWER) ;
RELINE ;
sprintf(temp,"%d", *TARGET.i) ;
addstr (temp) ;
break ;
case 'l':
*TARGET.l = atol(ANSWER) ;
RELINE ;
sprintf(temp,"%ld", *TARGET.l) ;
addstr (temp) ;
break ;
case 'f':
sscanf (ANSWER,"%f",TARGET.f);
RELINE ;
fmt (ANSWER, V__.usr_answ[at_answer].decimal_places,
(double)*TARGET.f);
sscanf (ANSWER,"%f",TARGET.f);
addstr (ANSWER) ;
break ;
case 'd':
sscanf (ANSWER,"%lf",TARGET.d);
RELINE ;
fmt (ANSWER, V__.usr_answ[at_answer].decimal_places,
(double)*TARGET.d);
sscanf (ANSWER,"%lf",TARGET.d);
addstr (ANSWER) ;
break ;
default:
break ;
}
if ((newchar == CR && lastchar == ESC)|| newchar == CTRLC)
{
interrupts_ok = 0;
V_exit() ;
return(c == CR) ;
}
if (newchar == ESC)
{
lastchar = ESC;
break;
}
if (newchar == UP)
at_answer = (at_answer+num_answers-1) % num_answers ;
else
at_answer = (at_answer+1) % num_answers ;
ans_col = 0 ;
move(ROW, COL) ;
refresh() ;
break ;
case BS:
ans_col = (ans_col-1 >= 0) ? ans_col-1 : 0 ;
move(ROW, COL + ans_col) ;
refresh() ;
break ;
case FS:
if (ANSWER[ans_col+1] != NULL)
{
ans_col = (ans_col+1 <= LENGTH) ? ans_col+1 : LENGTH ;
move(ROW, COL + ans_col) ;
refresh() ;
}
else
putc(BELL, stderr) ;
break ;
case RPLT:
getyx (stdscr, y, x); /* shapiro */
wrefresh(curscr) ;
move (y, x); /* shapiro */
refresh(); /* shapiro */
break ;
case DUMP:
V__dump_window() ;
break ;
default:
if (newchar == 91 && lastchar == ESC) {
lastchar = -91;
break;
}
if (lastchar == -91) {
lastchar = 0;
if (newchar == 49) { /* HOME */
ans_col = 0 ;
} else if (newchar == 52) { /* END */
for (c = 0; c < LENGTH && ANSWER[c]; c++) {}
ans_col = --c ;
} else if (newchar == 65) { /* UP */
at_answer = (at_answer+num_answers-1) % num_answers ;
ans_col = 0 ;
} else if (newchar == 66) { /* DOWN */
at_answer = (at_answer+1) % num_answers ;
ans_col = 0 ;
} else if (newchar == 67) { /* LEFT */
if (ans_col+1 < LENGTH && ANSWER[ans_col+1]) ++ans_col;
} else if (newchar == 68) { /* RIGHT */
ans_col = (ans_col-1 >= 0) ? ans_col-1 : 0 ;
} else if (newchar == 50) { /* DELETE */
break;
}
move(ROW, COL + ans_col) ;
refresh() ;
break;
}
if (ans_col >= LENGTH)
break ;
if ((newchar >= '\040') && (newchar < '\176'))
{
addch(newchar) ;
ANSWER[ans_col] = newchar ;
ans_col++ ;
refresh() ;
}
break ;
}
}
}
V_intrpt_ok()
{
interrupts_ok = 1; /* will be set false when V_call() exists */
}
V_intrpt_msg (msg)
char *msg;
{
strcpy (V__.interrupt_msg, msg);
}
static
fmt(s,n,x)
char *s;
double x;
{
char buf[20];
if (n >= 0)
sprintf (buf, "%%.%dlf", n);
else
strcpy (buf, "%.5lf");
/* I had to use .5lf instead of just lf since a number like 65.8 got sprintf'ed as 65.800003
* this is a hack - I admit it.
*/
sprintf (s, buf, x);
if (n < 0)
V__trim_decimal(s);
}
static
centered(msg)
char *msg;
{
int indent;
indent = (80 - strlen(msg))/2;
while (indent-- > 0)
addstr(" ");
addstr(msg);
addstr("\n");
}
More information about the grass-user
mailing list