1a5f0fb15SPaul Saab /* 26dcb072bSXin LI * Copyright (C) 1984-2004 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 * 7a5f0fb15SPaul Saab * For more information about less, or for information on how to 8a5f0fb15SPaul Saab * contact the author, see the README file. 9a5f0fb15SPaul Saab */ 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab 12a5f0fb15SPaul Saab /* 13a5f0fb15SPaul Saab * Routines dealing with getting input from the keyboard (i.e. from the user). 14a5f0fb15SPaul Saab */ 15a5f0fb15SPaul Saab 16a5f0fb15SPaul Saab #include "less.h" 17c9346414SPaul Saab #if OS2 18c9346414SPaul Saab #include "cmd.h" 19c9346414SPaul Saab #include "pckeys.h" 20c9346414SPaul Saab #endif 21a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 22a5f0fb15SPaul Saab #include "windows.h" 23a5f0fb15SPaul Saab extern char WIN32getch(); 24a5f0fb15SPaul Saab static DWORD console_mode; 25a5f0fb15SPaul Saab #endif 26a5f0fb15SPaul Saab 27000ba3e8STim J. Robbins public int tty; 28a5f0fb15SPaul Saab extern int sigs; 296dcb072bSXin LI extern int utf_mode; 30a5f0fb15SPaul Saab 31a5f0fb15SPaul Saab /* 32a5f0fb15SPaul Saab * Open keyboard for input. 33a5f0fb15SPaul Saab */ 34a5f0fb15SPaul Saab public void 35a5f0fb15SPaul Saab open_getchr() 36a5f0fb15SPaul Saab { 37a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 38a5f0fb15SPaul Saab /* Need this to let child processes inherit our console handle */ 39a5f0fb15SPaul Saab SECURITY_ATTRIBUTES sa; 40a5f0fb15SPaul Saab memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); 41a5f0fb15SPaul Saab sa.nLength = sizeof(SECURITY_ATTRIBUTES); 42a5f0fb15SPaul Saab sa.bInheritHandle = TRUE; 43a5f0fb15SPaul Saab tty = (int) CreateFile("CONIN$", GENERIC_READ, 44a5f0fb15SPaul Saab FILE_SHARE_READ, &sa, 45a5f0fb15SPaul Saab OPEN_EXISTING, 0L, NULL); 46a5f0fb15SPaul Saab GetConsoleMode((HANDLE)tty, &console_mode); 47a5f0fb15SPaul Saab /* Make sure we get Ctrl+C events. */ 48a5f0fb15SPaul Saab SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT); 49a5f0fb15SPaul Saab #else 50c9346414SPaul Saab #if MSDOS_COMPILER 51a5f0fb15SPaul Saab extern int fd0; 52a5f0fb15SPaul Saab /* 53a5f0fb15SPaul Saab * Open a new handle to CON: in binary mode 54a5f0fb15SPaul Saab * for unbuffered keyboard read. 55a5f0fb15SPaul Saab */ 56a5f0fb15SPaul Saab fd0 = dup(0); 57a5f0fb15SPaul Saab close(0); 58a5f0fb15SPaul Saab tty = open("CON", OPEN_READ); 59a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 60a5f0fb15SPaul Saab /* 61a5f0fb15SPaul Saab * Setting stdin to binary causes Ctrl-C to not 62a5f0fb15SPaul Saab * raise SIGINT. We must undo that side-effect. 63a5f0fb15SPaul Saab */ 64a5f0fb15SPaul Saab (void) __djgpp_set_ctrl_c(1); 65a5f0fb15SPaul Saab #endif 66a5f0fb15SPaul Saab #else 67a5f0fb15SPaul Saab /* 68a5f0fb15SPaul Saab * Try /dev/tty. 69a5f0fb15SPaul Saab * If that doesn't work, use file descriptor 2, 70a5f0fb15SPaul Saab * which in Unix is usually attached to the screen, 71a5f0fb15SPaul Saab * but also usually lets you read from the keyboard. 72a5f0fb15SPaul Saab */ 73c9346414SPaul Saab #if OS2 74c9346414SPaul Saab /* The __open() system call translates "/dev/tty" to "con". */ 75c9346414SPaul Saab tty = __open("/dev/tty", OPEN_READ); 76c9346414SPaul Saab #else 77a5f0fb15SPaul Saab tty = open("/dev/tty", OPEN_READ); 78c9346414SPaul Saab #endif 79a5f0fb15SPaul Saab if (tty < 0) 80a5f0fb15SPaul Saab tty = 2; 81a5f0fb15SPaul Saab #endif 82a5f0fb15SPaul Saab #endif 83a5f0fb15SPaul Saab } 84a5f0fb15SPaul Saab 85a5f0fb15SPaul Saab /* 86a5f0fb15SPaul Saab * Close the keyboard. 87a5f0fb15SPaul Saab */ 88a5f0fb15SPaul Saab public void 89a5f0fb15SPaul Saab close_getchr() 90a5f0fb15SPaul Saab { 91a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 92a5f0fb15SPaul Saab SetConsoleMode((HANDLE)tty, console_mode); 93a5f0fb15SPaul Saab CloseHandle((HANDLE)tty); 94a5f0fb15SPaul Saab #endif 95a5f0fb15SPaul Saab } 96a5f0fb15SPaul Saab 97a5f0fb15SPaul Saab /* 98a5f0fb15SPaul Saab * Get a character from the keyboard. 99a5f0fb15SPaul Saab */ 100a5f0fb15SPaul Saab public int 101a5f0fb15SPaul Saab getchr() 102a5f0fb15SPaul Saab { 103a5f0fb15SPaul Saab char c; 104a5f0fb15SPaul Saab int result; 1056dcb072bSXin LI int hex_in = 0; 1066dcb072bSXin LI int hex_value = 0; 107a5f0fb15SPaul Saab 108a5f0fb15SPaul Saab do 109a5f0fb15SPaul Saab { 110a5f0fb15SPaul Saab #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC 111a5f0fb15SPaul Saab /* 112a5f0fb15SPaul Saab * In raw read, we don't see ^C so look here for it. 113a5f0fb15SPaul Saab */ 114a5f0fb15SPaul Saab flush(); 115a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 116a5f0fb15SPaul Saab if (ABORT_SIGS()) 117a5f0fb15SPaul Saab return (READ_INTR); 118a5f0fb15SPaul Saab c = WIN32getch(tty); 119a5f0fb15SPaul Saab #else 120a5f0fb15SPaul Saab c = getch(); 121a5f0fb15SPaul Saab #endif 122a5f0fb15SPaul Saab result = 1; 123a5f0fb15SPaul Saab if (c == '\003') 124a5f0fb15SPaul Saab return (READ_INTR); 125a5f0fb15SPaul Saab #else 126a5f0fb15SPaul Saab result = iread(tty, &c, sizeof(char)); 127a5f0fb15SPaul Saab if (result == READ_INTR) 128a5f0fb15SPaul Saab return (READ_INTR); 129a5f0fb15SPaul Saab if (result < 0) 130a5f0fb15SPaul Saab { 131a5f0fb15SPaul Saab /* 132a5f0fb15SPaul Saab * Don't call error() here, 133a5f0fb15SPaul Saab * because error calls getchr! 134a5f0fb15SPaul Saab */ 135a5f0fb15SPaul Saab quit(QUIT_ERROR); 136a5f0fb15SPaul Saab } 137a5f0fb15SPaul Saab #endif 1386dcb072bSXin LI #if 0 /* allow entering arbitrary hex chars for testing */ 1396dcb072bSXin LI /* ctrl-A followed by two hex chars makes a byte */ 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 } 1656dcb072bSXin LI #endif 166a5f0fb15SPaul Saab /* 167a5f0fb15SPaul Saab * Various parts of the program cannot handle 168a5f0fb15SPaul Saab * an input character of '\0'. 169a5f0fb15SPaul Saab * If a '\0' was actually typed, convert it to '\340' here. 170a5f0fb15SPaul Saab */ 171a5f0fb15SPaul Saab if (c == '\0') 172a5f0fb15SPaul Saab c = '\340'; 173a5f0fb15SPaul Saab } while (result != 1); 174a5f0fb15SPaul Saab 1756dcb072bSXin LI return (c & 0xFF); 176a5f0fb15SPaul Saab } 177