JeVois  1.18
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Console.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2020 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 #ifdef JEVOIS_PRO
19 
20 #include <jevois/Util/Console.H>
21 #include <stdexcept>
22 #include <string>
23 
24 #include <linux/input.h>
25 #include <linux/kd.h>
26 #include <linux/keyboard.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <cctype>
32 
33 #define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
34 
35 // ##############################################################################################################
37 {
38 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
39 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
40 #define OFF(x) ((x)%BITS_PER_LONG)
41 #define LONG(x) ((x)/BITS_PER_LONG)
42 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
43 
44  unsigned long bitmask_ev[NBITS(EV_MAX)];
45  unsigned long bitmask_key[NBITS(KEY_MAX)];
46  unsigned long bitmask_abs[NBITS(ABS_MAX)];
47  unsigned long bitmask_rel[NBITS(REL_MAX)];
48 
49  if (ioctl(fd, EVIOCGBIT(0, sizeof(bitmask_ev)), &bitmask_ev) == -1) return false;
50  if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitmask_key)), &bitmask_key) == -1) return false;
51  if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitmask_abs)), &bitmask_abs) == -1) return false;
52  if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitmask_rel)), &bitmask_rel) == -1) return false;
53 
54  bool is_keyboard = (bitmask_key[0] & 0xFFFFFFFE);
55  bool is_abs = test_bit(EV_ABS, bitmask_ev) && test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs);
56  bool is_rel = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
57  bool is_mouse = (is_abs || is_rel) && test_bit(BTN_MOUSE, bitmask_key);
58  bool is_touch = is_abs && (test_bit(BTN_TOOL_FINGER, bitmask_key) || test_bit(BTN_TOUCH, bitmask_key));
59 
60  return is_keyboard || is_mouse || is_touch;
61 #undef BITS_PER_LONG
62 #undef NBITS
63 #undef OFF
64 #undef LONG
65 #undef test_bit
66 }
67 
68 // ##############################################################################################################
69 #ifndef KDSKBMUTE
70 #define KDSKBMUTE 0x4B51
71 #endif
72 #ifndef KDSKBMODE
73 #define KDSKBMODE 0x4B45
74 #endif
75 #ifndef K_OFF
76 #define K_OFF 0x04
77 #endif
78 
79 static char const * const consoles[] =
80 { "/proc/self/fd/0", "/dev/tty", "/dev/tty0", "/dev/tty1", "/dev/tty2", "/dev/tty3", "/dev/tty4",
81  "/dev/tty5", "/dev/tty6", "/dev/vc/0", "/dev/console" };
82 
83 #define IS_CONSOLE(fd) isatty(fd) && ioctl(fd, KDGKBTYPE, &arg) == 0 && ((arg == KB_101) || (arg == KB_84))
84 
86 {
87  char arg;
88 
89  // Try a few consoles to see which one we have read access to:
90  for (size_t i = 0; i < NELEMS(consoles); ++i)
91  {
92  int fd = open(consoles[i], O_RDONLY);
93  if (fd >= 0) { if (IS_CONSOLE(fd)) return fd; else close(fd); }
94  }
95 
96  // Also try stdin, stdout, stderr:
97  for (int fd = 0; fd < 3; ++fd) if (IS_CONSOLE(fd)) return fd;
98 
99  throw std::runtime_error("Could not get console fd");
100 }
101 
102 // ##############################################################################################################
103 void jevois::muteKeyboard(int tty, int & kb_mode)
104 {
105  kb_mode = 0; char arg;
106  if (!IS_CONSOLE(tty)) throw std::runtime_error("Tried to mute an invalid tty");
107 
108  ioctl(tty, KDGKBMODE, &kb_mode); // Not fatal if fails
109  if (ioctl(tty, KDSKBMUTE, 1) && ioctl(tty, KDSKBMODE, K_OFF)) throw std::runtime_error("Failed muting keyboard");
110 }
111 
112 // ##############################################################################################################
113 // Restore the keyboard mode for given tty:
114 void jevois::unMuteKeyboard(int tty, int kb_mode)
115 {
116  if (ioctl(tty, KDSKBMUTE, 0) && ioctl(tty, KDSKBMODE, kb_mode))
117  throw std::runtime_error("Failed restoring keyboard mode");
118 }
119 
120 // ##############################################################################################################
122 {
123  char ttyname[256];
124  char arg;
125 
126  int fd = open("/sys/class/tty/tty0/active", O_RDONLY);
127  if (fd < 0) throw std::runtime_error("Could not determine which tty is active -- IGNORED");
128  ssize_t len = read(fd, ttyname, 255);
129  close(fd);
130  if (len <= 0) throw std::runtime_error("Could not read which tty is active");
131 
132  if (ttyname[len-1] == '\n') ttyname[len-1] = '\0';
133  else ttyname[len] = '\0';
134 
135  std::string const ttypath = std::string("/dev/") + ttyname;
136  fd = open(ttypath.c_str(), O_RDWR | O_NOCTTY);
137  if (fd < 0) throw std::runtime_error("Could not open tty: " + ttypath);
138  if (!IS_CONSOLE(fd)) { close(fd); throw std::runtime_error("Invalid tty obtained: " + ttypath); }
139 
140  return fd;
141 }
142 
143 #endif // JEVOIS_PRO
NBITS
#define NBITS(x)
jevois::unMuteKeyboard
void unMuteKeyboard(int tty, int kb_mode)
Restore the keyboard mode for given tty.
Definition: Console.C:114
Console.H
test_bit
#define test_bit(bit, array)
jevois::getActiveTTY
int getActiveTTY()
Get current active tty.
Definition: Console.C:121
K_OFF
#define K_OFF
Definition: Console.C:76
jevois::isInputDevice
bool isInputDevice(int fd)
Indicate whether this fd (which should be from /dev/input/eventX) is keyboard, mouse,...
Definition: Console.C:36
jevois::muteKeyboard
void muteKeyboard(int tty, int &kb_mode)
Prevent keystrokes from reaching the tty.
Definition: Console.C:103
KDSKBMODE
#define KDSKBMODE
Definition: Console.C:73
IS_CONSOLE
#define IS_CONSOLE(fd)
Definition: Console.C:83
jevois::getConsoleFd
int getConsoleFd()
Get a file descriptor to the console.
Definition: Console.C:85
KDSKBMUTE
#define KDSKBMUTE
Definition: Console.C:70
NELEMS
#define NELEMS(x)
Definition: Console.C:33