add GHC.HetMet.{hetmet_kappa,hetmet_kappa_app}
[ghc-base.git] / cbits / consUtils.c
1 /* 
2  * (c) The University of Glasgow 2002
3  *
4  * Win32 Console API support
5  */
6 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32) || defined(__CYGWIN__)
7 /* to the end */
8
9 #include "consUtils.h"
10 #include <windows.h>
11 #include <io.h>
12
13 #if defined(__CYGWIN__)
14 #define _get_osfhandle get_osfhandle
15 #endif
16
17 int is_console__(int fd) {
18     DWORD st;
19     HANDLE h;
20     if (!_isatty(fd)) {
21         /* TTY must be a character device */
22         return 0;
23     }
24     h = (HANDLE)_get_osfhandle(fd);
25     if (h == INVALID_HANDLE_VALUE) {
26         /* Broken handle can't be terminal */
27         return 0;
28     }
29     if (!GetConsoleMode(h, &st)) {
30         /* GetConsoleMode appears to fail when it's not a TTY.  In
31            particular, it's what most of our terminal functions
32            assume works, so if it doesn't work for all intents
33            and purposes we're not dealing with a terminal. */
34         return 0;
35     }
36     return 1;
37 }
38
39
40 int
41 set_console_buffering__(int fd, int cooked)
42 {
43     HANDLE h;
44     DWORD  st;
45     /* According to GetConsoleMode() docs, it is not possible to
46        leave ECHO_INPUT enabled without also having LINE_INPUT,
47        so we have to turn both off here. */
48     DWORD flgs = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
49     
50     if ( (h = (HANDLE)_get_osfhandle(fd)) != INVALID_HANDLE_VALUE ) {
51         if ( GetConsoleMode(h,&st) &&
52              SetConsoleMode(h, cooked ? (st | ENABLE_LINE_INPUT) : st & ~flgs)  ) {
53             return 0;
54         }
55     }
56     return -1;
57 }
58
59 int
60 set_console_echo__(int fd, int on)
61 {
62     HANDLE h;
63     DWORD  st;
64     DWORD flgs = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
65     
66     if ( (h = (HANDLE)_get_osfhandle(fd)) != INVALID_HANDLE_VALUE ) {
67         if ( GetConsoleMode(h,&st) && 
68              SetConsoleMode(h,( on ? (st | flgs) : (st & ~ENABLE_ECHO_INPUT))) ) {
69             return 0;
70         }
71     }
72     return -1;
73 }
74
75 int
76 get_console_echo__(int fd)
77 {
78     HANDLE h;
79     DWORD  st;
80     
81     if ( (h = (HANDLE)_get_osfhandle(fd)) != INVALID_HANDLE_VALUE ) {
82         if ( GetConsoleMode(h,&st) ) {
83             return (st & ENABLE_ECHO_INPUT ? 1 : 0);
84         }
85     }
86     return -1;
87 }
88
89 int
90 flush_input_console__(int fd)
91 {
92     HANDLE h = (HANDLE)_get_osfhandle(fd);
93     
94     if ( h != INVALID_HANDLE_VALUE ) {
95         /* If the 'fd' isn't connected to a console; treat the flush
96          * operation as a NOP.
97          */
98         DWORD unused;
99         if ( !GetConsoleMode(h,&unused) &&
100              GetLastError() == ERROR_INVALID_HANDLE ) {
101             return 0;
102         }
103         if ( FlushConsoleInputBuffer(h) ) {
104             return 0;
105         }
106     }
107     /* ToDo: translate GetLastError() into something errno-friendly */
108     return -1;
109 }
110
111 #endif /* defined(__MINGW32__) || ... */