Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  * $Revision$ *
45  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
49 #include <OpenMesh/Tools/Utils/conio.hh>
50 
51 // ----------------------------------------------------------------- MSVC Compiler ----
52 #ifdef _MSC_VER
53 
54 #include <conio.h>
55 
56 namespace OpenMesh {
57 namespace Utils {
58 
59 int kbhit() { return ::_kbhit(); }
60 int getch() { return ::_getch(); }
61 int getche() { return ::_getche(); }
62 
63 } // Tools
64 } // AS
65 
66 // ----------------------------------------------------------------- Win32 ----
67 #elif defined(WIN32)
68 
69 #include <conio.h>
70 
71 namespace OpenMesh {
72 namespace Utils {
73 
74 int kbhit() { return ::kbhit(); }
75 int getch() { return ::getch(); }
76 int getche() { return ::getche(); }
77 
78 } // Tools
79 } // AS
80 // ----------------------------------------------------------------- Other ----
81 #else
82 
83 // Based on code published by Floyd Davidson in a newsgroup.
84 
85 #include <stdio.h> /* stdout, fflush() */
86 #if !defined(POSIX_1003_1_2001)
87 # include <fcntl.h>
88 # include <unistd.h>
89 #else
90 # include <select.h> /* select() */
91 #endif
92 #include <termios.h> /* tcsetattr() */
93 #include <sys/ioctl.h> /* ioctl() */
94 
95 namespace OpenMesh {
96 namespace Utils {
97 
98 #ifdef CTIME
99 # undef CTIME
100 #endif
101 #define CTIME 1
102 #define CMIN 1
103 
104 
105 int kbhit(void)
106 {
107  int cnt = 0;
108  int error;
109  static struct termios Otty, Ntty;
110 
111  tcgetattr(0, &Otty);
112  Ntty = Otty;
113 
114  Ntty.c_iflag = 0; /* input mode */
115  Ntty.c_oflag = 0; /* output mode */
116  Ntty.c_lflag &= ~ICANON; /* raw mode */
117  Ntty.c_cc[VMIN] = CMIN; /* minimum chars to wait for */
118  Ntty.c_cc[VTIME] = CTIME; /* minimum wait time */
119 
120  if (0 == (error = tcsetattr(0, TCSANOW, &Ntty)))
121  {
122  struct timeval tv;
123  error += ioctl(0, FIONREAD, &cnt);
124  error += tcsetattr(0, TCSANOW, &Otty);
125  tv.tv_sec = 0;
126  tv.tv_usec = 100; /* insert at least a minimal delay */
127  select(1, NULL, NULL, NULL, &tv);
128  }
129  return (error == 0 ? cnt : -1 );
130 }
131 
132 
133 int getch(void)
134 {
135  char ch = ' ';
136  int error;
137  static struct termios Otty, Ntty;
138 
139  fflush(stdout);
140  tcgetattr(0, &Otty);
141  Ntty = Otty;
142 
143  Ntty.c_iflag = 0; // input mode
144  Ntty.c_oflag = 0; // output mode
145  Ntty.c_lflag &= ~ICANON; // line settings
146  Ntty.c_lflag &= ~ECHO; // enable echo
147  Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
148  Ntty.c_cc[VTIME] = CTIME; // minimum wait time
149 
150  // Conditionals allow compiling with or without flushing pre-existing
151  // existing buffered input before blocking.
152 #if 1
153  // use this to flush the input buffer before blocking for new input
154 # define FLAG TCSAFLUSH
155 #else
156  // use this to return a char from the current input buffer, or block if
157  // no input is waiting.
158 # define FLAG TCSANOW
159 #endif
160 
161  if (0 == (error = tcsetattr(0, FLAG, &Ntty)))
162  {
163  error = read(0, &ch, 1 ); // get char from stdin
164  error += tcsetattr(0, FLAG, &Otty); // restore old settings
165  }
166  return (error == 1 ? (int) ch : -1 );
167 }
168 
169 
170 int getche(void)
171 {
172  char ch = ' ';
173  int error;
174  static struct termios Otty, Ntty;
175 
176  fflush(stdout);
177  tcgetattr(0, &Otty);
178  Ntty = Otty;
179 
180  Ntty.c_iflag = 0; // input mode
181  Ntty.c_oflag = 0; // output mode
182  Ntty.c_lflag &= ~ICANON; // line settings
183  Ntty.c_lflag |= ECHO; // enable echo
184  Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
185  Ntty.c_cc[VTIME] = CTIME; // minimum wait time
186 
187  // Conditionals allow compiling with or without flushing pre-existing
188  // existing buffered input before blocking.
189 #if 1
190  // use this to flush the input buffer before blocking for new input
191 # define FLAG TCSAFLUSH
192 #else
193  // use this to return a char from the current input buffer, or block if
194  // no input is waiting.
195 # define FLAG TCSANOW
196 #endif
197 
198  if (0 == (error = tcsetattr(0, FLAG, &Ntty))) {
199  error = read(0, &ch, 1 ); // get char from stdin
200  error += tcsetattr(0, FLAG, &Otty); // restore old settings
201  }
202 
203  return (error == 1 ? (int) ch : -1 );
204 }
205 
206 } // namespace Tools
207 } // namespace AS
208 // ----------------------------------------------------------------------------
209 #endif // System dependent parts
210 // ============================================================================
211 
212 //#define Test
213 #if defined(Test)
214 
215 #include <ctype.h>
216 
217 int main (void)
218 {
219  char msg[] = "press key to continue...";
220  char *ptr = msg;
221 
222  while ( !OpenMesh::Utils::kbhit() )
223  {
224  char* tmp = *ptr;
225  *ptr = islower(tmp) ? toupper(tmp) : tolower(tmp);
226  printf("\r%s", msg); fflush(stdout);
227  *ptr = (char)tmp;
228  if (!*(++ptr))
229  ptr = msg;
230  usleep(20000);
231  }
232 
233  printf("\r%s.", msg); fflush(stdout);
235  printf("\r%s..", msg); fflush(stdout);
237  return 0;
238 }
239 
240 #endif // Test
241 
242 // ============================================================================
int kbhit(void)
Definition: conio.cc:105
int getche(void)
Definition: conio.cc:170
int getch(void)
Definition: conio.cc:133