Developer Documentation
conio.cc
1/* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2025, 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
51namespace OpenMesh {
52namespace Utils {
53
54int kbhit() { return ::_kbhit(); }
55int getch() { return ::_getch(); }
56int getche() { return ::_getche(); }
57
58} // Tools
59} // AS
60
61// ----------------------------------------------------------------- Win32 ----
62#elif defined(WIN32) || defined(__MINGW32__)
63
64#include <conio.h>
65
66namespace OpenMesh {
67namespace Utils {
68
69int kbhit() { return ::kbhit(); }
70int getch() { return ::getch(); }
71int 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
91namespace OpenMesh {
92namespace Utils {
93
94#ifdef CTIME
95# undef CTIME
96#endif
97#define CTIME 1
98#define CMIN 1
99
100
101int 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
129int 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
166int 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
213int 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 getche(void)
Definition: conio.cc:166
int getch(void)
Definition: conio.cc:129
int kbhit(void)
Definition: conio.cc:101