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