/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenMesh. If not, *
* see . *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#include
#include
// ----------------------------------------------------------------- Win32 ----
#ifdef WIN32
#include
namespace OpenMesh {
namespace Utils {
int kbhit() { return ::kbhit(); }
int getch() { return ::getch(); }
int getche() { return ::getche(); }
} // Tools
} // AS
// ----------------------------------------------------------------- Other ----
#else
// Based on code published by Floyd Davidson in a newsgroup.
#include /* stdout, fflush() */
#if !defined(POSIX_1003_1_2001)
# include
# include
#else
# include /* select() */
#endif
#include /* tcsetattr() */
#include /* ioctl() */
#include /* struct timeval */
namespace OpenMesh {
namespace Utils {
#ifdef CTIME
# undef CTIME
#endif
#define CTIME 1
#define CMIN 1
int kbhit(void)
{
int cnt = 0;
int error;
static struct termios Otty, Ntty;
tcgetattr(0, &Otty);
Ntty = Otty;
Ntty.c_iflag = 0; /* input mode */
Ntty.c_oflag = 0; /* output mode */
Ntty.c_lflag &= ~ICANON; /* raw mode */
Ntty.c_cc[VMIN] = CMIN; /* minimum chars to wait for */
Ntty.c_cc[VTIME] = CTIME; /* minimum wait time */
if (0 == (error = tcsetattr(0, TCSANOW, &Ntty)))
{
struct timeval tv;
error += ioctl(0, FIONREAD, &cnt);
error += tcsetattr(0, TCSANOW, &Otty);
tv.tv_sec = 0;
tv.tv_usec = 100; /* insert at least a minimal delay */
select(1, NULL, NULL, NULL, &tv);
}
return (error == 0 ? cnt : -1 );
}
int getch(void)
{
char ch = ' ';
int error;
static struct termios Otty, Ntty;
fflush(stdout);
tcgetattr(0, &Otty);
Ntty = Otty;
Ntty.c_iflag = 0; // input mode
Ntty.c_oflag = 0; // output mode
Ntty.c_lflag &= ~ICANON; // line settings
Ntty.c_lflag &= ~ECHO; // enable echo
Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
Ntty.c_cc[VTIME] = CTIME; // minimum wait time
// Conditionals allow compiling with or without flushing pre-existing
// existing buffered input before blocking.
#if 1
// use this to flush the input buffer before blocking for new input
# define FLAG TCSAFLUSH
#else
// use this to return a char from the current input buffer, or block if
// no input is waiting.
# define FLAG TCSANOW
#endif
if (0 == (error = tcsetattr(0, FLAG, &Ntty)))
{
error = read(0, &ch, 1 ); // get char from stdin
error += tcsetattr(0, FLAG, &Otty); // restore old settings
}
return (error == 1 ? (int) ch : -1 );
}
int getche(void)
{
char ch = ' ';
int error;
static struct termios Otty, Ntty;
fflush(stdout);
tcgetattr(0, &Otty);
Ntty = Otty;
Ntty.c_iflag = 0; // input mode
Ntty.c_oflag = 0; // output mode
Ntty.c_lflag &= ~ICANON; // line settings
Ntty.c_lflag |= ECHO; // enable echo
Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
Ntty.c_cc[VTIME] = CTIME; // minimum wait time
// Conditionals allow compiling with or without flushing pre-existing
// existing buffered input before blocking.
#if 1
// use this to flush the input buffer before blocking for new input
# define FLAG TCSAFLUSH
#else
// use this to return a char from the current input buffer, or block if
// no input is waiting.
# define FLAG TCSANOW
#endif
if (0 == (error = tcsetattr(0, FLAG, &Ntty))) {
error = read(0, &ch, 1 ); // get char from stdin
error += tcsetattr(0, FLAG, &Otty); // restore old settings
}
return (error == 1 ? (int) ch : -1 );
}
} // namespace Tools
} // namespace AS
// ----------------------------------------------------------------------------
#endif // System dependent parts
// ============================================================================
//#define Test
#if defined(Test)
#include
int main (void)
{
char msg[] = "press key to continue...";
char *ptr = msg, tmp;
while ( !OpenMesh::Utils::kbhit() )
{
tmp = *ptr;
*ptr = islower(tmp) ? toupper(tmp) : tolower(tmp);
printf("\r%s", msg); fflush(stdout);
*ptr = (char)tmp;
if (!*(++ptr))
ptr = msg;
usleep(20000);
}
printf("\r%s.", msg); fflush(stdout);
OpenMesh::Utils::getch();
printf("\r%s..", msg); fflush(stdout);
OpenMesh::Utils::getche();
return 0;
}
#endif // Test
// ============================================================================