UNIX terminal escape sequences.

0 Likes
over 5 years ago

Problem

The terminal emulation software escape key sequence does not match the UNIX TERMINFO escape sequence.

How do you identify the escape key sequence to use in a TERMINFO file for a particular key depression like F2 or shift F2 etc…

Resolution

Here is a program scanwinput.c to display the escape sequences received by a UNIX system, which can be used to update your TERMINFO files.

Getting this output is a good step to solving the complex issue of terminal configuration on UNIX platforms.

OUTPUT from program when pressing F2 key

lines <25> columns <70> termname

longname xterm terminal emulator (X Window System)

 

  

Enter a string or key sequence like ctrl-f4 to see hex values or q exit

<^[OQ                                                              >

You Entered       : ^[OQ

You entered in hex : 1b4f51

Press any key to continue :

 

scanwinput.c will show all available options for the TERMINFO file in use.

OUTPUT scanwinput.c option d

str ked           key_eos                      = ABSENT_STRING

str kf0             key_f0                         = ABSENT_STRING

str kf1             key_f1                         = \EOP

str kf10           key_f10                      = \E[21~

str kf2             key_f2                         = \EOQ

str kf3            key_f3                         = \EOR

 

The above shows that kf2 is ”\E” escape x’1b’ and “OQ” which is what we got when we pressed the F2 key so good match.

We can expand a mftic generated TERMINFO file using mfinfocmp to see the TERMINFO source

OUTPUT mfinfocmp

mfinfocmp -1 | grep kf2=

               kf2=\EOQ,

  

Change the output from mfinfocmp and put it back in the TERMINFO database using mftic.

 The c source code

To download the c source code, click the link and save as < scanwinput.c >

scanwinput.c

/* to see what ncurses can do see */
/* http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/index.html */
/* http://frank.harvard.edu/~coldwell/ncurses/ncurses-intro.html this one looks good first has examples */
/* now this is the mecca of ncurses sites the curses test site */
/* http://stuff.mit.edu/afs/sipb/project/ncurses/cron-working/ncurses/test/ */

#include <stdio.h>
#if defined(_AIX)
#include <curses.h>
#define ABSENT_BOOLEAN         ((signed char)-1)       /* 255 */
#define ABSENT_NUMERIC         (-1)
#define ABSENT_STRING          (char *)0
#define CANCELLED_STRING	     (char *)(-1)
#else
#include <ncurses/ncurses.h>
#include <ncurses/term.h>
#include <ncurses/tic.h>
#endif

#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#define STR1LEN 15
#define STR2LEN 30
#define FCAPDISP(type, str1, str2) "%s %-*s %-*s = ", #type, STR1LEN, str1, STR2LEN, str2

int main() {

	WINDOW *_window = initscr();

	char mesg[] =
			"Enter a string or key sequnce like ctrl-f4 to see hex values or q exit"; /* message to be appeared on the screen */
	char mesg1[] =
			"<                                                                    >"; /* place to get string data escape sequences */
	char str[strlen(mesg1) - 2];
	int row, col; /* to store the number of rows and */
	/* the number of colums of the screen */
	getmaxyx(_window, row, col); /* get the number of rows and columns */

	do {
#if defined(_AIX)
    mvprintw(row/4,(col-strlen(mesg))/2, 
        "lines <%s> columns <%s> termname <%s>", termdef(2, 'l'), termdef(2, 'c'), termdef(2, 't'));
#else
    mvprintw(row / 4, (col - strlen(mesg)) / 2,
        "lines <%d> columns <%d> termname <%s>", row, col, termname());
#endif
		mvprintw((row / 4)   1, (col - strlen(mesg)) / 2, "longname %s",
				longname());

		mvprintw(row / 2, (col - strlen(mesg)) / 2, "%s", mesg); /* print the message at the center of the screen */
		mvprintw(row / 2   1, (col - strlen(mesg)) / 2, "%s", mesg1);
		move(row / 2   1, ((col - strlen(mesg)) / 2)   1);
		refresh();

		getstr(str);
		if (str[0] == 'q')
			break;
		mvprintw(row / 2   2, (col - strlen(mesg)) / 2,
				"You Entered        : %s", str);
		mvprintw(row / 2   3, (col - strlen(mesg)) / 2,
				"You entered in hex : ");
		int n;
		for (n = 0; str[ n ] != '\0'; n  )
			printw("x", (unsigned char) str[ n ]);
		mvprintw(row / 2   4, (col - strlen(mesg)) / 2,
				"Press any key to continue : ");
		refresh();
		getch();
		clear();
	} while (true);

	mvprintw(row - 2, 0, "Press any key to exit d to see terminfo : ");
	refresh();
	char c = getch();
	endwin();

	/* using stuff from mecca site above dump terminfo stuff */
	if (c == 'd') {
		printf("mftic and mfinfocmp must be used for TERMINFOS being used by MF COBOL\n");
		printf("mftic puts key definitions in different places than tic so must use mftic\n");
		printf("mftic uses old ncurses libraries so definitions need to be compiled and extracted\n");
    printf("using mftic and mfinfocomp, enough said.\n");
		printf("\n");
#if defined(_AIX)
    printf("%s|%s\n", termdef(2, 't'), longname()); 
#else
		printf("%s|%s\n", termname(), longname());
#endif
		fflush(stdout);
		unsigned n;
		char *cap;
		char *capf;
		const char *str;
		int num;

		for (n = 0;;   n) {
			cap = boolnames[ n ];
			capf = boolfnames[ n ];
			if (cap == 0)
				break;
			num = tigetflag(cap);
			printf(FCAPDISP(flg, cap, capf));
			if (num == ABSENT_BOOLEAN) {
				printf(" ABSENT_BOOLEAN\n");
			} else {
			    printf(" %s\n", num ? "true" : "false");
			}
			fflush(stdout);
		}

		for (n = 0;;   n) {
			cap = numnames[ n ];
			capf = numfnames[ n ];
			if (cap == 0)
				break;
			printf(FCAPDISP(num, cap, capf));
			num = tigetnum(cap);
			if (num == ABSENT_NUMERIC) {
				printf(" ABSENT_NUMERIC\n");
			} else {
				printf(" %d\n", num);
			}
			fflush(stdout);
		}

		for (n = 0;;   n) {
			cap = strnames[ n ];
			capf = strfnames[ n ];
			if (cap == 0)
				break;
			printf(FCAPDISP(str, cap, capf));
			str = tigetstr(cap);
			if (str == CANCELLED_STRING) {
				str = "CANCELLED_STRING";
			} else if (str == ABSENT_STRING) {
				str = "ABSENT_STRING";
			}
			while (*str != 0) {
				int ch = (int) *str  ;
				switch (ch) {
				case '\177':
					fputs("^?", stdout);
					break;
				case '\033':
					fputs("\\E", stdout);
					break;
				case '\b':
					fputs("\\b", stdout);
					break;
				case '\f':
					fputs("\\f", stdout);
					break;
				case '\n':
					fputs("\\n", stdout);
					break;
				case '\r':
					fputs("\\r", stdout);
					break;
				case ' ':
					fputs("\\s", stdout);
					break;
				case '\t':
					fputs("\\t", stdout);
					break;
				case '^':
					fputs("\\^", stdout);
					break;
				case ':':
					fputs("\\072", stdout);
					break;
				case '\\':
					fputs("\\\\", stdout);
					break;
				default:
					if (isgraph(ch))
						fputc(ch, stdout);
					else if (ch < 32)
						printf("^%c", ch   '@');
					else
						printf("\\o", ch);
					break;
				}
			}
			printf("\n");
			fflush(stdout);
		}

	}

	return 0;
}

 

To compile on UNIX

cob -xv scanwinput.c -lcurses -o scanwinput

 

This is just a starting point for solving TERMINFO problems.

Comment List
Anonymous
Related Discussions
Recommended