625647f1906458304b8d7a9c032ec81a86819880
[winnie] / src / fbdev / keyboard.cc
1 #ifdef WINNIE_FBDEV
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <fcntl.h>
8 #include <sys/ioctl.h>
9 #include <termios.h>
10 #include <unistd.h>
11
12 #include "keyboard.h"
13 #include "window.h"
14 #include "wm.h"
15
16 struct Keyboard {
17         int dev_fd;
18         enum {RAW, CANONICAL} ttystate;
19 };
20
21 static Keyboard *keyboard;
22
23 bool init_keyboard()
24 {
25         if(!(keyboard = (Keyboard*)malloc(sizeof *keyboard))) {
26                 return false;
27         }
28
29         keyboard->ttystate = keyboard->CANONICAL;
30         keyboard->dev_fd = -1;
31
32         if((keyboard->dev_fd = open("/dev/tty", O_RDWR)) == -1) {
33                 fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno));
34                 return false;
35         }
36
37         struct termios buf;
38
39         if(tcgetattr(keyboard->dev_fd, &buf) < 0) {
40                 fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
41                 return false;
42         }
43
44         buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
45         buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
46         buf.c_cflag &= ~(CSIZE | PARENB);
47         buf.c_cflag |= CS8;
48         buf.c_oflag &= ~(OPOST);
49
50         if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) {
51                 return false;
52         }
53
54         keyboard->ttystate = keyboard->RAW;
55         return true;
56 }
57
58 void destroy_keyboard()
59 {
60         struct termios buf;
61
62         if(tcgetattr(keyboard->dev_fd, &buf) < 0) {
63                 fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
64         }
65
66         buf.c_lflag |= (ECHO | ICANON | IEXTEN | ISIG);
67         buf.c_iflag |= (BRKINT | ICRNL | INPCK | ISTRIP | IXON);
68         buf.c_cflag |= (CSIZE | PARENB);
69         buf.c_cflag &= CS8;
70         buf.c_oflag |= (OPOST);
71
72         if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) {
73                 fprintf(stderr, "Cannot set the tty parameters : %s\n", strerror(errno));
74         }
75
76         keyboard->ttystate = keyboard->CANONICAL;
77
78         if(keyboard->dev_fd != -1) {
79                 close(keyboard->dev_fd);
80                 keyboard->dev_fd = -1;
81         }
82
83         free(keyboard);
84 }
85
86 int get_keyboard_fd()
87 {
88         return keyboard->dev_fd;
89 }
90
91 void process_keyboard_event()
92 {
93         char key;
94         if(read(keyboard->dev_fd, &key, 1) < 1) {
95                 return;
96         }
97
98         if(key == 'q') {
99                 exit(0);
100         }
101
102         Window *focused_win = wm->get_focused_window();
103         if(focused_win) {
104                 KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback();
105                 if(keyb_callback) {
106                         keyb_callback(focused_win, key, true); //TODO: true??
107                 }
108         }
109
110         /* TODO:
111          * - handle system-wide key combinations (alt-tab?)
112          * - otherwise send keypress/release to focused window
113          */
114 }
115 #endif // WINNIE_FBDEV