added license GPL
[winnie] / src / fbdev / keyboard.cc
1 /*
2 winnie - an experimental window system
3
4 Copyright (C) 2013 Eleni Maria Stea
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19 Author: Eleni Maria Stea <elene.mst@gmail.com>
20 */
21
22 #ifdef WINNIE_FBDEV
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <fcntl.h>
29 #include <sys/ioctl.h>
30 #include <termios.h>
31 #include <unistd.h>
32
33 #include "keyboard.h"
34 #include "shalloc.h"
35 #include "window.h"
36 #include "wm.h"
37
38 struct Keyboard {
39         int dev_fd;
40         enum {RAW, CANONICAL} ttystate;
41 };
42
43 static Keyboard *keyboard;
44
45 bool init_keyboard()
46 {
47         if(!(keyboard = (Keyboard*)sh_malloc(sizeof *keyboard))) {
48                 return false;
49         }
50
51         keyboard->ttystate = keyboard->CANONICAL;
52         keyboard->dev_fd = -1;
53
54         if((keyboard->dev_fd = open("/dev/tty", O_RDWR)) == -1) {
55                 fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno));
56                 return false;
57         }
58
59         struct termios buf;
60
61         if(tcgetattr(keyboard->dev_fd, &buf) < 0) {
62                 fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
63                 return false;
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                 return false;
74         }
75
76         keyboard->ttystate = keyboard->RAW;
77         return true;
78 }
79
80 void destroy_keyboard()
81 {
82         struct termios buf;
83
84         if(tcgetattr(keyboard->dev_fd, &buf) < 0) {
85                 fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
86         }
87
88         buf.c_lflag |= (ECHO | ICANON | IEXTEN | ISIG);
89         buf.c_iflag |= (BRKINT | ICRNL | INPCK | ISTRIP | IXON);
90         buf.c_cflag |= (CSIZE | PARENB);
91         buf.c_cflag &= CS8;
92         buf.c_oflag |= (OPOST);
93
94         if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) {
95                 fprintf(stderr, "Cannot set the tty parameters : %s\n", strerror(errno));
96         }
97
98         keyboard->ttystate = keyboard->CANONICAL;
99
100         if(keyboard->dev_fd != -1) {
101                 close(keyboard->dev_fd);
102                 keyboard->dev_fd = -1;
103         }
104
105         sh_free(keyboard);
106 }
107
108 int get_keyboard_fd()
109 {
110         return keyboard->dev_fd;
111 }
112
113 void process_keyboard_event()
114 {
115         char key;
116         if(read(keyboard->dev_fd, &key, 1) < 1) {
117                 return;
118         }
119
120         if(key == 'q') {
121                 exit(0);
122         }
123
124         Window *focused_win = wm->get_focused_window();
125         if(focused_win) {
126                 KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback();
127                 if(keyb_callback) {
128                         keyb_callback(focused_win, key, true); //TODO: true??
129                 }
130         }
131
132         /* TODO:
133          * - handle system-wide key combinations (alt-tab?)
134          * - otherwise send keypress/release to focused window
135          */
136 }
137 #endif // WINNIE_FBDEV