1a5f0fb15SPaul Saab /* 2*b7780dbeSXin LI * Copyright (C) 1984-2019 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 * 796e55cc7SXin 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 21*b7780dbeSXin LI #define WIN32_LEAN_AND_MEAN 22*b7780dbeSXin LI #ifndef _WIN32_WINNT 23*b7780dbeSXin LI #define _WIN32_WINNT 0x400 24a5f0fb15SPaul Saab #endif 25*b7780dbeSXin LI #include <windows.h> 26*b7780dbeSXin LI static DWORD console_mode; 27*b7780dbeSXin LI public HANDLE tty; 28*b7780dbeSXin LI #else 29000ba3e8STim J. Robbins public int tty; 30*b7780dbeSXin LI #endif 31a5f0fb15SPaul Saab extern int sigs; 326dcb072bSXin LI extern int utf_mode; 33*b7780dbeSXin LI extern int wheel_lines; 34a5f0fb15SPaul Saab 35a5f0fb15SPaul Saab /* 36a5f0fb15SPaul Saab * Open keyboard for input. 37a5f0fb15SPaul Saab */ 38a5f0fb15SPaul Saab public void 39*b7780dbeSXin LI open_getchr(VOID_PARAM) 40a5f0fb15SPaul Saab { 41a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 42a5f0fb15SPaul Saab /* Need this to let child processes inherit our console handle */ 43a5f0fb15SPaul Saab SECURITY_ATTRIBUTES sa; 44a5f0fb15SPaul Saab memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); 45a5f0fb15SPaul Saab sa.nLength = sizeof(SECURITY_ATTRIBUTES); 46a5f0fb15SPaul Saab sa.bInheritHandle = TRUE; 47*b7780dbeSXin LI tty = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, 48a5f0fb15SPaul Saab FILE_SHARE_READ, &sa, 49a5f0fb15SPaul Saab OPEN_EXISTING, 0L, NULL); 50*b7780dbeSXin LI GetConsoleMode(tty, &console_mode); 51a5f0fb15SPaul Saab /* Make sure we get Ctrl+C events. */ 52*b7780dbeSXin LI SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); 53a5f0fb15SPaul Saab #else 54c9346414SPaul Saab #if MSDOS_COMPILER 55a5f0fb15SPaul Saab extern int fd0; 56a5f0fb15SPaul Saab /* 57a5f0fb15SPaul Saab * Open a new handle to CON: in binary mode 58a5f0fb15SPaul Saab * for unbuffered keyboard read. 59a5f0fb15SPaul Saab */ 60a5f0fb15SPaul Saab fd0 = dup(0); 61a5f0fb15SPaul Saab close(0); 62a5f0fb15SPaul Saab tty = open("CON", OPEN_READ); 63a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 64a5f0fb15SPaul Saab /* 65a5f0fb15SPaul Saab * Setting stdin to binary causes Ctrl-C to not 66a5f0fb15SPaul Saab * raise SIGINT. We must undo that side-effect. 67a5f0fb15SPaul Saab */ 68a5f0fb15SPaul Saab (void) __djgpp_set_ctrl_c(1); 69a5f0fb15SPaul Saab #endif 70a5f0fb15SPaul Saab #else 71a5f0fb15SPaul Saab /* 72a5f0fb15SPaul Saab * Try /dev/tty. 73a5f0fb15SPaul Saab * If that doesn't work, use file descriptor 2, 74a5f0fb15SPaul Saab * which in Unix is usually attached to the screen, 75a5f0fb15SPaul Saab * but also usually lets you read from the keyboard. 76a5f0fb15SPaul Saab */ 77c9346414SPaul Saab #if OS2 78c9346414SPaul Saab /* The __open() system call translates "/dev/tty" to "con". */ 79c9346414SPaul Saab tty = __open("/dev/tty", OPEN_READ); 80c9346414SPaul Saab #else 81a5f0fb15SPaul Saab tty = open("/dev/tty", OPEN_READ); 82c9346414SPaul Saab #endif 83a5f0fb15SPaul Saab if (tty < 0) 84a5f0fb15SPaul Saab tty = 2; 85a5f0fb15SPaul Saab #endif 86a5f0fb15SPaul Saab #endif 87a5f0fb15SPaul Saab } 88a5f0fb15SPaul Saab 89a5f0fb15SPaul Saab /* 90a5f0fb15SPaul Saab * Close the keyboard. 91a5f0fb15SPaul Saab */ 92a5f0fb15SPaul Saab public void 93*b7780dbeSXin LI close_getchr(VOID_PARAM) 94a5f0fb15SPaul Saab { 95a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 96*b7780dbeSXin LI SetConsoleMode(tty, console_mode); 97*b7780dbeSXin LI CloseHandle(tty); 98a5f0fb15SPaul Saab #endif 99a5f0fb15SPaul Saab } 100a5f0fb15SPaul Saab 101*b7780dbeSXin LI #if MSDOS_COMPILER==WIN32C 102*b7780dbeSXin LI /* 103*b7780dbeSXin LI * Close the pipe, restoring the keyboard (CMD resets it, losing the mouse). 104*b7780dbeSXin LI */ 105*b7780dbeSXin LI int 106*b7780dbeSXin LI pclose(f) 107*b7780dbeSXin LI FILE *f; 108*b7780dbeSXin LI { 109*b7780dbeSXin LI int result; 110*b7780dbeSXin LI 111*b7780dbeSXin LI result = _pclose(f); 112*b7780dbeSXin LI SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); 113*b7780dbeSXin LI return result; 114*b7780dbeSXin LI } 115*b7780dbeSXin LI #endif 116*b7780dbeSXin LI 117*b7780dbeSXin LI /* 118*b7780dbeSXin LI * Get the number of lines to scroll when mouse wheel is moved. 119*b7780dbeSXin LI */ 120*b7780dbeSXin LI public int 121*b7780dbeSXin LI default_wheel_lines(VOID_PARAM) 122*b7780dbeSXin LI { 123*b7780dbeSXin LI int lines = 1; 124*b7780dbeSXin LI #if MSDOS_COMPILER==WIN32C 125*b7780dbeSXin LI if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0)) 126*b7780dbeSXin LI { 127*b7780dbeSXin LI if (lines == WHEEL_PAGESCROLL) 128*b7780dbeSXin LI lines = 3; 129*b7780dbeSXin LI } 130*b7780dbeSXin LI #endif 131*b7780dbeSXin LI return lines; 132*b7780dbeSXin LI } 133*b7780dbeSXin LI 134a5f0fb15SPaul Saab /* 135a5f0fb15SPaul Saab * Get a character from the keyboard. 136a5f0fb15SPaul Saab */ 137a5f0fb15SPaul Saab public int 138*b7780dbeSXin LI getchr(VOID_PARAM) 139a5f0fb15SPaul Saab { 140a5f0fb15SPaul Saab char c; 141a5f0fb15SPaul Saab int result; 142a5f0fb15SPaul Saab 143a5f0fb15SPaul Saab do 144a5f0fb15SPaul Saab { 145a5f0fb15SPaul Saab #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC 146a5f0fb15SPaul Saab /* 147a5f0fb15SPaul Saab * In raw read, we don't see ^C so look here for it. 148a5f0fb15SPaul Saab */ 149a5f0fb15SPaul Saab flush(); 150a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 151a5f0fb15SPaul Saab if (ABORT_SIGS()) 152a5f0fb15SPaul Saab return (READ_INTR); 153*b7780dbeSXin LI c = WIN32getch(); 154a5f0fb15SPaul Saab #else 155a5f0fb15SPaul Saab c = getch(); 156a5f0fb15SPaul Saab #endif 157a5f0fb15SPaul Saab result = 1; 158a5f0fb15SPaul Saab if (c == '\003') 159a5f0fb15SPaul Saab return (READ_INTR); 160a5f0fb15SPaul Saab #else 161f6b74a7dSXin LI { 162f6b74a7dSXin LI unsigned char uc; 163f6b74a7dSXin LI result = iread(tty, &uc, sizeof(char)); 164f6b74a7dSXin LI c = (char) uc; 165f6b74a7dSXin LI } 166a5f0fb15SPaul Saab if (result == READ_INTR) 167a5f0fb15SPaul Saab return (READ_INTR); 168a5f0fb15SPaul Saab if (result < 0) 169a5f0fb15SPaul Saab { 170a5f0fb15SPaul Saab /* 171a5f0fb15SPaul Saab * Don't call error() here, 172a5f0fb15SPaul Saab * because error calls getchr! 173a5f0fb15SPaul Saab */ 174a5f0fb15SPaul Saab quit(QUIT_ERROR); 175a5f0fb15SPaul Saab } 176a5f0fb15SPaul Saab #endif 1776dcb072bSXin LI #if 0 /* allow entering arbitrary hex chars for testing */ 1786dcb072bSXin LI /* ctrl-A followed by two hex chars makes a byte */ 1797f074f9cSXin LI { 180f6b74a7dSXin LI static int hex_in = 0; 181f6b74a7dSXin LI static int hex_value = 0; 1826dcb072bSXin LI if (c == CONTROL('A')) 1836dcb072bSXin LI { 1846dcb072bSXin LI hex_in = 2; 1856dcb072bSXin LI result = 0; 1866dcb072bSXin LI continue; 1876dcb072bSXin LI } 1886dcb072bSXin LI if (hex_in > 0) 1896dcb072bSXin LI { 1906dcb072bSXin LI int v; 1916dcb072bSXin LI if (c >= '0' && c <= '9') 1926dcb072bSXin LI v = c - '0'; 1936dcb072bSXin LI else if (c >= 'a' && c <= 'f') 1946dcb072bSXin LI v = c - 'a' + 10; 1956dcb072bSXin LI else if (c >= 'A' && c <= 'F') 1966dcb072bSXin LI v = c - 'A' + 10; 1976dcb072bSXin LI else 198*b7780dbeSXin LI v = 0; 1996dcb072bSXin LI hex_value = (hex_value << 4) | v; 2006dcb072bSXin LI if (--hex_in > 0) 2016dcb072bSXin LI { 2026dcb072bSXin LI result = 0; 2036dcb072bSXin LI continue; 2046dcb072bSXin LI } 2056dcb072bSXin LI c = hex_value; 2066dcb072bSXin LI } 2077f074f9cSXin LI } 2086dcb072bSXin LI #endif 209a5f0fb15SPaul Saab /* 210a5f0fb15SPaul Saab * Various parts of the program cannot handle 211a5f0fb15SPaul Saab * an input character of '\0'. 212a5f0fb15SPaul Saab * If a '\0' was actually typed, convert it to '\340' here. 213a5f0fb15SPaul Saab */ 214a5f0fb15SPaul Saab if (c == '\0') 215a5f0fb15SPaul Saab c = '\340'; 216a5f0fb15SPaul Saab } while (result != 1); 217a5f0fb15SPaul Saab 2186dcb072bSXin LI return (c & 0xFF); 219a5f0fb15SPaul Saab } 220