160786Sps/* 2240121Sdelphij * Copyright (C) 1984-2012 Mark Nudelman 360786Sps * 460786Sps * You may distribute under the terms of either the GNU General Public 560786Sps * License or the Less License, as specified in the README file. 660786Sps * 7240121Sdelphij * For more information, see the README file. 860786Sps */ 960786Sps 1060786Sps 1160786Sps/* 1260786Sps * Routines dealing with getting input from the keyboard (i.e. from the user). 1360786Sps */ 1460786Sps 1560786Sps#include "less.h" 1689019Sps#if OS2 1789019Sps#include "cmd.h" 1889019Sps#include "pckeys.h" 1989019Sps#endif 2060786Sps#if MSDOS_COMPILER==WIN32C 2160786Sps#include "windows.h" 2260786Spsextern char WIN32getch(); 2360786Spsstatic DWORD console_mode; 2460786Sps#endif 2560786Sps 26128345Stjrpublic int tty; 2760786Spsextern int sigs; 28161475Sdelphijextern int utf_mode; 2960786Sps 3060786Sps/* 3160786Sps * Open keyboard for input. 3260786Sps */ 3360786Sps public void 3460786Spsopen_getchr() 3560786Sps{ 3660786Sps#if MSDOS_COMPILER==WIN32C 3760786Sps /* Need this to let child processes inherit our console handle */ 3860786Sps SECURITY_ATTRIBUTES sa; 3960786Sps memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); 4060786Sps sa.nLength = sizeof(SECURITY_ATTRIBUTES); 4160786Sps sa.bInheritHandle = TRUE; 4260786Sps tty = (int) CreateFile("CONIN$", GENERIC_READ, 4360786Sps FILE_SHARE_READ, &sa, 4460786Sps OPEN_EXISTING, 0L, NULL); 4560786Sps GetConsoleMode((HANDLE)tty, &console_mode); 4660786Sps /* Make sure we get Ctrl+C events. */ 4760786Sps SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT); 4860786Sps#else 4989019Sps#if MSDOS_COMPILER 5060786Sps extern int fd0; 5160786Sps /* 5260786Sps * Open a new handle to CON: in binary mode 5360786Sps * for unbuffered keyboard read. 5460786Sps */ 5560786Sps fd0 = dup(0); 5660786Sps close(0); 5760786Sps tty = open("CON", OPEN_READ); 5860786Sps#if MSDOS_COMPILER==DJGPPC 5960786Sps /* 6060786Sps * Setting stdin to binary causes Ctrl-C to not 6160786Sps * raise SIGINT. We must undo that side-effect. 6260786Sps */ 6360786Sps (void) __djgpp_set_ctrl_c(1); 6460786Sps#endif 6560786Sps#else 6660786Sps /* 6760786Sps * Try /dev/tty. 6860786Sps * If that doesn't work, use file descriptor 2, 6960786Sps * which in Unix is usually attached to the screen, 7060786Sps * but also usually lets you read from the keyboard. 7160786Sps */ 7289019Sps#if OS2 7389019Sps /* The __open() system call translates "/dev/tty" to "con". */ 7489019Sps tty = __open("/dev/tty", OPEN_READ); 7589019Sps#else 7660786Sps tty = open("/dev/tty", OPEN_READ); 7789019Sps#endif 7860786Sps if (tty < 0) 7960786Sps tty = 2; 8060786Sps#endif 8160786Sps#endif 8260786Sps} 8360786Sps 8460786Sps/* 8560786Sps * Close the keyboard. 8660786Sps */ 8760786Sps public void 8860786Spsclose_getchr() 8960786Sps{ 9060786Sps#if MSDOS_COMPILER==WIN32C 9160786Sps SetConsoleMode((HANDLE)tty, console_mode); 9260786Sps CloseHandle((HANDLE)tty); 9360786Sps#endif 9460786Sps} 9560786Sps 9660786Sps/* 9760786Sps * Get a character from the keyboard. 9860786Sps */ 9960786Sps public int 10060786Spsgetchr() 10160786Sps{ 10260786Sps char c; 10360786Sps int result; 10460786Sps 10560786Sps do 10660786Sps { 10760786Sps#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC 10860786Sps /* 10960786Sps * In raw read, we don't see ^C so look here for it. 11060786Sps */ 11160786Sps flush(); 11260786Sps#if MSDOS_COMPILER==WIN32C 11360786Sps if (ABORT_SIGS()) 11460786Sps return (READ_INTR); 11560786Sps c = WIN32getch(tty); 11660786Sps#else 11760786Sps c = getch(); 11860786Sps#endif 11960786Sps result = 1; 12060786Sps if (c == '\003') 12160786Sps return (READ_INTR); 12260786Sps#else 12360786Sps result = iread(tty, &c, sizeof(char)); 12460786Sps if (result == READ_INTR) 12560786Sps return (READ_INTR); 12660786Sps if (result < 0) 12760786Sps { 12860786Sps /* 12960786Sps * Don't call error() here, 13060786Sps * because error calls getchr! 13160786Sps */ 13260786Sps quit(QUIT_ERROR); 13360786Sps } 13460786Sps#endif 135161475Sdelphij#if 0 /* allow entering arbitrary hex chars for testing */ 136161475Sdelphij /* ctrl-A followed by two hex chars makes a byte */ 137170256Sdelphij { 138170256Sdelphij int hex_in = 0; 139170256Sdelphij int hex_value = 0; 140161475Sdelphij if (c == CONTROL('A')) 141161475Sdelphij { 142161475Sdelphij hex_in = 2; 143161475Sdelphij result = 0; 144161475Sdelphij continue; 145161475Sdelphij } 146161475Sdelphij if (hex_in > 0) 147161475Sdelphij { 148161475Sdelphij int v; 149161475Sdelphij if (c >= '0' && c <= '9') 150161475Sdelphij v = c - '0'; 151161475Sdelphij else if (c >= 'a' && c <= 'f') 152161475Sdelphij v = c - 'a' + 10; 153161475Sdelphij else if (c >= 'A' && c <= 'F') 154161475Sdelphij v = c - 'A' + 10; 155161475Sdelphij else 156161475Sdelphij hex_in = 0; 157161475Sdelphij hex_value = (hex_value << 4) | v; 158161475Sdelphij if (--hex_in > 0) 159161475Sdelphij { 160161475Sdelphij result = 0; 161161475Sdelphij continue; 162161475Sdelphij } 163161475Sdelphij c = hex_value; 164161475Sdelphij } 165170256Sdelphij } 166161475Sdelphij#endif 16760786Sps /* 16860786Sps * Various parts of the program cannot handle 16960786Sps * an input character of '\0'. 17060786Sps * If a '\0' was actually typed, convert it to '\340' here. 17160786Sps */ 17260786Sps if (c == '\0') 17360786Sps c = '\340'; 17460786Sps } while (result != 1); 17560786Sps 176161475Sdelphij return (c & 0xFF); 17760786Sps} 178