Having problems with your account or logging in?
A lot of changes are happening in the community right now. Some may affect you. READ MORE HERE

UNIX terminal escape sequences.

UNIX terminal escape sequences.

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("%02x", (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("\\%03o", 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.

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2015-11-24 10:40
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.