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