1a5f0fb15SPaul Saab /* 2*96e55cc7SXin LI * Copyright (C) 1984-2012 Mark Nudelman 3a5f0fb15SPaul Saab * 4a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 5a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 6a5f0fb15SPaul Saab * 7*96e55cc7SXin LI * For more information, see the README file. 8a5f0fb15SPaul Saab */ 9a5f0fb15SPaul Saab 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab /* 12a5f0fb15SPaul Saab * Routines dealing with getting input from the keyboard (i.e. from the user). 13a5f0fb15SPaul Saab */ 14a5f0fb15SPaul Saab 15a5f0fb15SPaul Saab #include "less.h" 16c9346414SPaul Saab #if OS2 17c9346414SPaul Saab #include "cmd.h" 18c9346414SPaul Saab #include "pckeys.h" 19c9346414SPaul Saab #endif 20a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 21a5f0fb15SPaul Saab #include "windows.h" 22a5f0fb15SPaul Saab extern char WIN32getch(); 23a5f0fb15SPaul Saab static DWORD console_mode; 24a5f0fb15SPaul Saab #endif 25a5f0fb15SPaul Saab 26000ba3e8STim J. Robbins public int tty; 27a5f0fb15SPaul Saab extern int sigs; 286dcb072bSXin LI extern int utf_mode; 29a5f0fb15SPaul Saab 30a5f0fb15SPaul Saab /* 31a5f0fb15SPaul Saab * Open keyboard for input. 32a5f0fb15SPaul Saab */ 33a5f0fb15SPaul Saab public void 34a5f0fb15SPaul Saab open_getchr() 35a5f0fb15SPaul Saab { 36a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 37a5f0fb15SPaul Saab /* Need this to let child processes inherit our console handle */ 38a5f0fb15SPaul Saab SECURITY_ATTRIBUTES sa; 39a5f0fb15SPaul Saab memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); 40a5f0fb15SPaul Saab sa.nLength = sizeof(SECURITY_ATTRIBUTES); 41a5f0fb15SPaul Saab sa.bInheritHandle = TRUE; 42a5f0fb15SPaul Saab tty = (int) CreateFile("CONIN$", GENERIC_READ, 43a5f0fb15SPaul Saab FILE_SHARE_READ, &sa, 44a5f0fb15SPaul Saab OPEN_EXISTING, 0L, NULL); 45a5f0fb15SPaul Saab GetConsoleMode((HANDLE)tty, &console_mode); 46a5f0fb15SPaul Saab /* Make sure we get Ctrl+C events. */ 47a5f0fb15SPaul Saab SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT); 48a5f0fb15SPaul Saab #else 49c9346414SPaul Saab #if MSDOS_COMPILER 50a5f0fb15SPaul Saab extern int fd0; 51a5f0fb15SPaul Saab /* 52a5f0fb15SPaul Saab * Open a new handle to CON: in binary mode 53a5f0fb15SPaul Saab * for unbuffered keyboard read. 54a5f0fb15SPaul Saab */ 55a5f0fb15SPaul Saab fd0 = dup(0); 56a5f0fb15SPaul Saab close(0); 57a5f0fb15SPaul Saab tty = open("CON", OPEN_READ); 58a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 59a5f0fb15SPaul Saab /* 60a5f0fb15SPaul Saab * Setting stdin to binary causes Ctrl-C to not 61a5f0fb15SPaul Saab * raise SIGINT. We must undo that side-effect. 62a5f0fb15SPaul Saab */ 63a5f0fb15SPaul Saab (void) __djgpp_set_ctrl_c(1); 64a5f0fb15SPaul Saab #endif 65a5f0fb15SPaul Saab #else 66a5f0fb15SPaul Saab /* 67a5f0fb15SPaul Saab * Try /dev/tty. 68a5f0fb15SPaul Saab * If that doesn't work, use file descriptor 2, 69a5f0fb15SPaul Saab * which in Unix is usually attached to the screen, 70a5f0fb15SPaul Saab * but also usually lets you read from the keyboard. 71a5f0fb15SPaul Saab */ 72c9346414SPaul Saab #if OS2 73c9346414SPaul Saab /* The __open() system call translates "/dev/tty" to "con". */ 74c9346414SPaul Saab tty = __open("/dev/tty", OPEN_READ); 75c9346414SPaul Saab #else 76a5f0fb15SPaul Saab tty = open("/dev/tty", OPEN_READ); 77c9346414SPaul Saab #endif 78a5f0fb15SPaul Saab if (tty < 0) 79a5f0fb15SPaul Saab tty = 2; 80a5f0fb15SPaul Saab #endif 81a5f0fb15SPaul Saab #endif 82a5f0fb15SPaul Saab } 83a5f0fb15SPaul Saab 84a5f0fb15SPaul Saab /* 85a5f0fb15SPaul Saab * Close the keyboard. 86a5f0fb15SPaul Saab */ 87a5f0fb15SPaul Saab public void 88a5f0fb15SPaul Saab close_getchr() 89a5f0fb15SPaul Saab { 90a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 91a5f0fb15SPaul Saab SetConsoleMode((HANDLE)tty, console_mode); 92a5f0fb15SPaul Saab CloseHandle((HANDLE)tty); 93a5f0fb15SPaul Saab #endif 94a5f0fb15SPaul Saab } 95a5f0fb15SPaul Saab 96a5f0fb15SPaul Saab /* 97a5f0fb15SPaul Saab * Get a character from the keyboard. 98a5f0fb15SPaul Saab */ 99a5f0fb15SPaul Saab public int 100a5f0fb15SPaul Saab getchr() 101a5f0fb15SPaul Saab { 102a5f0fb15SPaul Saab char c; 103a5f0fb15SPaul Saab int result; 104a5f0fb15SPaul Saab 105a5f0fb15SPaul Saab do 106a5f0fb15SPaul Saab { 107a5f0fb15SPaul Saab #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC 108a5f0fb15SPaul Saab /* 109a5f0fb15SPaul Saab * In raw read, we don't see ^C so look here for it. 110a5f0fb15SPaul Saab */ 111a5f0fb15SPaul Saab flush(); 112a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 113a5f0fb15SPaul Saab if (ABORT_SIGS()) 114a5f0fb15SPaul Saab return (READ_INTR); 115a5f0fb15SPaul Saab c = WIN32getch(tty); 116a5f0fb15SPaul Saab #else 117a5f0fb15SPaul Saab c = getch(); 118a5f0fb15SPaul Saab #endif 119a5f0fb15SPaul Saab result = 1; 120a5f0fb15SPaul Saab if (c == '\003') 121a5f0fb15SPaul Saab return (READ_INTR); 122a5f0fb15SPaul Saab #else 123a5f0fb15SPaul Saab result = iread(tty, &c, sizeof(char)); 124a5f0fb15SPaul Saab if (result == READ_INTR) 125a5f0fb15SPaul Saab return (READ_INTR); 126a5f0fb15SPaul Saab if (result < 0) 127a5f0fb15SPaul Saab { 128a5f0fb15SPaul Saab /* 129a5f0fb15SPaul Saab * Don't call error() here, 130a5f0fb15SPaul Saab * because error calls getchr! 131a5f0fb15SPaul Saab */ 132a5f0fb15SPaul Saab quit(QUIT_ERROR); 133a5f0fb15SPaul Saab } 134a5f0fb15SPaul Saab #endif 1356dcb072bSXin LI #if 0 /* allow entering arbitrary hex chars for testing */ 1366dcb072bSXin LI /* ctrl-A followed by two hex chars makes a byte */ 1377f074f9cSXin LI { 1387f074f9cSXin LI int hex_in = 0; 1397f074f9cSXin LI int hex_value = 0; 1406dcb072bSXin LI if (c == CONTROL('A')) 1416dcb072bSXin LI { 1426dcb072bSXin LI hex_in = 2; 1436dcb072bSXin LI result = 0; 1446dcb072bSXin LI continue; 1456dcb072bSXin LI } 1466dcb072bSXin LI if (hex_in > 0) 1476dcb072bSXin LI { 1486dcb072bSXin LI int v; 1496dcb072bSXin LI if (c >= '0' && c <= '9') 1506dcb072bSXin LI v = c - '0'; 1516dcb072bSXin LI else if (c >= 'a' && c <= 'f') 1526dcb072bSXin LI v = c - 'a' + 10; 1536dcb072bSXin LI else if (c >= 'A' && c <= 'F') 1546dcb072bSXin LI v = c - 'A' + 10; 1556dcb072bSXin LI else 1566dcb072bSXin LI hex_in = 0; 1576dcb072bSXin LI hex_value = (hex_value << 4) | v; 1586dcb072bSXin LI if (--hex_in > 0) 1596dcb072bSXin LI { 1606dcb072bSXin LI result = 0; 1616dcb072bSXin LI continue; 1626dcb072bSXin LI } 1636dcb072bSXin LI c = hex_value; 1646dcb072bSXin LI } 1657f074f9cSXin LI } 1666dcb072bSXin LI #endif 167a5f0fb15SPaul Saab /* 168a5f0fb15SPaul Saab * Various parts of the program cannot handle 169a5f0fb15SPaul Saab * an input character of '\0'. 170a5f0fb15SPaul Saab * If a '\0' was actually typed, convert it to '\340' here. 171a5f0fb15SPaul Saab */ 172a5f0fb15SPaul Saab if (c == '\0') 173a5f0fb15SPaul Saab c = '\340'; 174a5f0fb15SPaul Saab } while (result != 1); 175a5f0fb15SPaul Saab 1766dcb072bSXin LI return (c & 0xFF); 177a5f0fb15SPaul Saab } 178