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