Developer Documentation
conio.cc
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 
44 #include <OpenMesh/Tools/Utils/conio.hh>
45 
46 // ----------------------------------------------------------------- MSVC Compiler ----
47 #ifdef _MSC_VER
48 
49 #include <conio.h>
50 
51 namespace OpenMesh {
52 namespace Utils {
53 
54 int kbhit() { return ::_kbhit(); }
55 int getch() { return ::_getch(); }
56 int getche() { return ::_getche(); }
57 
58 } // Tools
59 } // AS
60 
61 // ----------------------------------------------------------------- Win32 ----
62 #elif defined(WIN32) || defined(__MINGW32__)
63 
64 #include <conio.h>
65 
66 namespace OpenMesh {
67 namespace Utils {
68 
69 int kbhit() { return ::kbhit(); }
70 int getch() { return ::getch(); }
71 int getche() { return ::getche(); }
72 
73 } // Tools
74 } // AS
75 // ----------------------------------------------------------------- Other ----
76 #else
77 
78 // Based on code published by Floyd Davidson in a newsgroup.
79 
80 #include <stdio.h> /* stdout, fflush() */
81 #if !defined(POSIX_1003_1_2001)
82 # include <fcntl.h>
83 # include <unistd.h>
84 #else
85 # include <select.h> /* select() */
86 #endif
87 #include <termios.h> /* tcsetattr() */
88 #include <sys/ioctl.h> /* ioctl() */
89 #include <sys/time.h> /* timeval struct */
90 
91 namespace OpenMesh {
92 namespace Utils {
93 
94 #ifdef CTIME
95 # undef CTIME
96 #endif
97 #define CTIME 1
98 #define CMIN 1
99 
100 
101 int kbhit(void)
102 {
103  int cnt = 0;
104  int error;
105  static struct termios Otty, Ntty;
106 
107  tcgetattr(0, &Otty);
108  Ntty = Otty;
109 
110  Ntty.c_iflag = 0; /* input mode */
111  Ntty.c_oflag = 0; /* output mode */
112  Ntty.c_lflag &= ~ICANON; /* raw mode */
113  Ntty.c_cc[VMIN] = CMIN; /* minimum chars to wait for */
114  Ntty.c_cc[VTIME] = CTIME; /* minimum wait time */
115 
116  if (0 == (error = tcsetattr(0, TCSANOW, &Ntty)))
117  {
118  struct timeval tv;
119  error += ioctl(0, FIONREAD, &cnt);
120  error += tcsetattr(0, TCSANOW, &Otty);
121  tv.tv_sec = 0;
122  tv.tv_usec = 100; /* insert at least a minimal delay */
123  select(1, nullptr, nullptr, nullptr, &tv);
124  }
125  return (error == 0 ? cnt : -1 );
126 }
127 
128 
129 int getch(void)
130 {
131  char ch = ' ';
132  int error;
133  static struct termios Otty, Ntty;
134 
135  fflush(stdout);
136  tcgetattr(0, &Otty);
137  Ntty = Otty;
138 
139  Ntty.c_iflag = 0; // input mode
140  Ntty.c_oflag = 0; // output mode
141  Ntty.c_lflag &= ~ICANON; // line settings
142  Ntty.c_lflag &= ~ECHO; // enable echo
143  Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
144  Ntty.c_cc[VTIME] = CTIME; // minimum wait time
145 
146  // Conditionals allow compiling with or without flushing pre-existing
147  // existing buffered input before blocking.
148 #if 1
149  // use this to flush the input buffer before blocking for new input
150 # define FLAG TCSAFLUSH
151 #else
152  // use this to return a char from the current input buffer, or block if
153  // no input is waiting.
154 # define FLAG TCSANOW
155 #endif
156 
157  if (0 == (error = tcsetattr(0, FLAG, &Ntty)))
158  {
159  error = read(0, &ch, 1 ); // get char from stdin
160  error += tcsetattr(0, FLAG, &Otty); // restore old settings
161  }
162  return (error == 1 ? (int) ch : -1 );
163 }
164 
165 
166 int getche(void)
167 {
168  char ch = ' ';
169  int error;
170  static struct termios Otty, Ntty;
171 
172  fflush(stdout);
173  tcgetattr(0, &Otty);
174  Ntty = Otty;
175 
176  Ntty.c_iflag = 0; // input mode
177  Ntty.c_oflag = 0; // output mode
178  Ntty.c_lflag &= ~ICANON; // line settings
179  Ntty.c_lflag |= ECHO; // enable echo
180  Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
181  Ntty.c_cc[VTIME] = CTIME; // minimum wait time
182 
183  // Conditionals allow compiling with or without flushing pre-existing
184  // existing buffered input before blocking.
185 #if 1
186  // use this to flush the input buffer before blocking for new input
187 # define FLAG TCSAFLUSH
188 #else
189  // use this to return a char from the current input buffer, or block if
190  // no input is waiting.
191 # define FLAG TCSANOW
192 #endif
193 
194  if (0 == (error = tcsetattr(0, FLAG, &Ntty))) {
195  error = read(0, &ch, 1 ); // get char from stdin
196  error += tcsetattr(0, FLAG, &Otty); // restore old settings
197  }
198 
199  return (error == 1 ? (int) ch : -1 );
200 }
201 
202 } // namespace Tools
203 } // namespace AS
204 // ----------------------------------------------------------------------------
205 #endif // System dependent parts
206 // ============================================================================
207 
208 //#define Test
209 #if defined(Test)
210 
211 #include <ctype.h>
212 
213 int main (void)
214 {
215  char msg[] = "press key to continue...";
216  char *ptr = msg;
217 
218  while ( !OpenMesh::Utils::kbhit() )
219  {
220  char* tmp = *ptr;
221  *ptr = islower(tmp) ? toupper(tmp) : tolower(tmp);
222  printf("\r%s", msg); fflush(stdout);
223  *ptr = (char)tmp;
224  if (!*(++ptr))
225  ptr = msg;
226  usleep(20000);
227  }
228 
229  printf("\r%s.", msg); fflush(stdout);
231  printf("\r%s..", msg); fflush(stdout);
233  return 0;
234 }
235 
236 #endif // Test
237 
238 // ============================================================================
int getch(void)
Definition: conio.cc:129
int kbhit(void)
Definition: conio.cc:101
int getche(void)
Definition: conio.cc:166