keyboard.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "io_common.h"
00044 #include "keyboard.h"
00045
00046 #if LASS_PLATFORM_TYPE == LASS_PLATFORM_TYPE_WIN32
00047 # pragma LASS_NOTE("io/keyboard: using win32 implementation")
00048 # define LASS_IO_KEYBOARD_HAVE_WIN32
00049 # include <conio.h>
00050 #elif LASS_HAVE_TERMIOS_H && LASS_HAVE_SYS_IOCTL_H
00051 # define LASS_IO_KEYBOARD_HAVE_TERMIOS_H_AND_IOCTL_H
00052 # include <termios.h>
00053 # include <sys/ioctl.h>
00054 # if LASS_HAVE_UNISTD_H
00055 # include <unistd.h>
00056 # endif
00057 # if LASS_HAVE_SYS_SOCKET_H
00058 # include <sys/socket.h>
00059 # endif
00060 # include "../util/impl/lass_errno.h"
00061 #else
00062 # error lass/io/keyboard.cpp not supported
00063 #endif
00064
00065 #
00066 namespace lass
00067 {
00068 namespace io
00069 {
00070
00071 #if defined(LASS_IO_KEYBOARD_HAVE_TERMIOS_H_AND_IOCTL_H)
00072 namespace impl
00073 {
00074 class TerminalAttributeSaver
00075 {
00076 public:
00077 TerminalAttributeSaver()
00078 {
00079 LASS_ENFORCE_CLIB(tcgetattr(STDIN_FILENO, &savedAttributes_));
00080 }
00081 ~TerminalAttributeSaver()
00082 {
00083 const int rc = tcsetattr(STDIN_FILENO, TCSANOW, &savedAttributes_);
00084 LASS_ASSERT(rc == 0);
00085 if (rc == -1)
00086 {
00087 const int errnum = util::impl::lass_errno();
00088 std::cerr << "[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: "
00089 << "failed to restore terminal attributes: ("
00090 << errnum << ") " << util::impl::lass_strerror(errnum)
00091 << std::endl;
00092 }
00093 }
00094 const termios& savedAttributes() const
00095 {
00096 return savedAttributes_;
00097 }
00098 private:
00099 termios savedAttributes_;
00100 };
00101 }
00102 #endif
00103
00104
00105
00106
00107 bool keyboardIsHit()
00108 {
00109 #if defined(LASS_IO_KEYBOARD_HAVE_WIN32)
00110 return _kbhit() != 0;
00111 #elif defined(LASS_IO_KEYBOARD_HAVE_TERMIOS_H_AND_IOCTL_H)
00112 impl::TerminalAttributeSaver attributeSaver;
00113 termios rawMode = attributeSaver.savedAttributes();
00114 rawMode.c_lflag &= ~ICANON;
00115 LASS_ENFORCE_CLIB(tcsetattr(STDIN_FILENO, TCSANOW, &rawMode));
00116
00117 int count = 0;
00118 LASS_ENFORCE_CLIB(ioctl(STDIN_FILENO, FIONREAD, &count));
00119 return count > 0;
00120 #else
00121 # error keyboardIsHit not supported
00122 #endif
00123 }
00124
00125
00126
00127
00128 int keyboardGetKey()
00129 {
00130 #if defined(LASS_IO_KEYBOARD_HAVE_WIN32)
00131 return _getch();
00132 #elif defined(LASS_IO_KEYBOARD_HAVE_TERMIOS_H_AND_IOCTL_H)
00133 impl::TerminalAttributeSaver attributeSaver;
00134 termios rawMode = attributeSaver.savedAttributes();
00135 rawMode.c_lflag &= ~ICANON;
00136 rawMode.c_lflag &= ~ECHO;
00137 rawMode.c_cc[VMIN] = 1;
00138 rawMode.c_cc[VTIME] = 0;
00139 LASS_ENFORCE_CLIB(tcsetattr(STDIN_FILENO, TCSANOW, &rawMode));
00140
00141 unsigned char character = 0;
00142 const ssize_t charactersRead = LASS_ENFORCE_CLIB(read(STDIN_FILENO, &character, 1));
00143 LASS_ENFORCE(charactersRead == 1);
00144 return static_cast<int>(character);
00145 #else
00146 # error keyboardIsHit not supported
00147 #endif
00148 }
00149
00150 }
00151 }
00152
00153