ttyin.c revision 238730
160107Sobrien/* 234919Simp * Copyright (C) 1984-2012 Mark Nudelman 334919Simp * 434919Simp * You may distribute under the terms of either the GNU General Public 534919Simp * License or the Less License, as specified in the README file. 634919Simp * 746664Simp * For more information, see the README file. 834919Simp */ 934919Simp 1034919Simp 1134919Simp/* 1234919Simp * Routines dealing with getting input from the keyboard (i.e. from the user). 1334919Simp */ 1434919Simp 1534919Simp#include "less.h" 1634919Simp#if OS2 1734919Simp#include "cmd.h" 1838140Syokota#include "pckeys.h" 1934919Simp#endif 2034919Simp#if MSDOS_COMPILER==WIN32C 2134919Simp#include "windows.h" 2234919Simpextern char WIN32getch(); 2334919Simpstatic DWORD console_mode; 2434919Simp#endif 2534919Simp 2634919Simppublic int tty; 2734919Simpextern int sigs; 2834919Simpextern int utf_mode; 2934919Simp 3034919Simp/* 3134919Simp * Open keyboard for input. 3234919Simp */ 3334919Simp public void 3434919Simpopen_getchr() 3534919Simp{ 3634919Simp#if MSDOS_COMPILER==WIN32C 3734919Simp /* Need this to let child processes inherit our console handle */ 3834919Simp SECURITY_ATTRIBUTES sa; 3934919Simp memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); 4034919Simp sa.nLength = sizeof(SECURITY_ATTRIBUTES); 4134919Simp sa.bInheritHandle = TRUE; 4234919Simp tty = (int) CreateFile("CONIN$", GENERIC_READ, 4334919Simp FILE_SHARE_READ, &sa, 4434919Simp OPEN_EXISTING, 0L, NULL); 4534919Simp GetConsoleMode((HANDLE)tty, &console_mode); 4634919Simp /* Make sure we get Ctrl+C events. */ 4746664Simp SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT); 4834919Simp#else 4934919Simp#if MSDOS_COMPILER 5034919Simp extern int fd0; 5134919Simp /* 5234919Simp * Open a new handle to CON: in binary mode 5334919Simp * for unbuffered keyboard read. 5434919Simp */ 5534919Simp fd0 = dup(0); 5634919Simp close(0); 5734919Simp tty = open("CON", OPEN_READ); 5834919Simp#if MSDOS_COMPILER==DJGPPC 5934919Simp /* 6034919Simp * Setting stdin to binary causes Ctrl-C to not 6146664Simp * raise SIGINT. We must undo that side-effect. 6234919Simp */ 6346664Simp (void) __djgpp_set_ctrl_c(1); 6434919Simp#endif 6534919Simp#else 6634919Simp /* 6734919Simp * Try /dev/tty. 6834919Simp * If that doesn't work, use file descriptor 2, 6934919Simp * which in Unix is usually attached to the screen, 7034919Simp * but also usually lets you read from the keyboard. 7134919Simp */ 7234919Simp#if OS2 7334919Simp /* The __open() system call translates "/dev/tty" to "con". */ 7434919Simp tty = __open("/dev/tty", OPEN_READ); 7534919Simp#else 7634919Simp tty = open("/dev/tty", OPEN_READ); 7734919Simp#endif 7834919Simp if (tty < 0) 7934919Simp tty = 2; 8034919Simp#endif 8134919Simp#endif 8234919Simp} 8334919Simp 8434919Simp/* 8534919Simp * Close the keyboard. 8634919Simp */ 8734919Simp public void 8834919Simpclose_getchr() 8934956Simp{ 9046664Simp#if MSDOS_COMPILER==WIN32C 9134919Simp SetConsoleMode((HANDLE)tty, console_mode); 9234919Simp CloseHandle((HANDLE)tty); 9334919Simp#endif 9434919Simp} 9534919Simp 9634919Simp/* 9734919Simp * Get a character from the keyboard. 9846664Simp */ 9934919Simp public int 10034919Simpgetchr() 10134919Simp{ 10234919Simp char c; 10334919Simp int result; 10434919Simp 10534919Simp do 10634919Simp { 10734919Simp#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC 10834919Simp /* 10946664Simp * In raw read, we don't see ^C so look here for it. 11046664Simp */ 11146664Simp flush(); 11246664Simp#if MSDOS_COMPILER==WIN32C 11346664Simp if (ABORT_SIGS()) 11446664Simp return (READ_INTR); 115 c = WIN32getch(tty); 116#else 117 c = getch(); 118#endif 119 result = 1; 120 if (c == '\003') 121 return (READ_INTR); 122#else 123 result = iread(tty, &c, sizeof(char)); 124 if (result == READ_INTR) 125 return (READ_INTR); 126 if (result < 0) 127 { 128 /* 129 * Don't call error() here, 130 * because error calls getchr! 131 */ 132 quit(QUIT_ERROR); 133 } 134#endif 135#if 0 /* allow entering arbitrary hex chars for testing */ 136 /* ctrl-A followed by two hex chars makes a byte */ 137 { 138 int hex_in = 0; 139 int hex_value = 0; 140 if (c == CONTROL('A')) 141 { 142 hex_in = 2; 143 result = 0; 144 continue; 145 } 146 if (hex_in > 0) 147 { 148 int v; 149 if (c >= '0' && c <= '9') 150 v = c - '0'; 151 else if (c >= 'a' && c <= 'f') 152 v = c - 'a' + 10; 153 else if (c >= 'A' && c <= 'F') 154 v = c - 'A' + 10; 155 else 156 hex_in = 0; 157 hex_value = (hex_value << 4) | v; 158 if (--hex_in > 0) 159 { 160 result = 0; 161 continue; 162 } 163 c = hex_value; 164 } 165 } 166#endif 167 /* 168 * Various parts of the program cannot handle 169 * an input character of '\0'. 170 * If a '\0' was actually typed, convert it to '\340' here. 171 */ 172 if (c == '\0') 173 c = '\340'; 174 } while (result != 1); 175 176 return (c & 0xFF); 177} 178