casting in fbdev
[winnie] / libwinnie / 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 "winnie.h"
37 #include "wm.h"
38
39 struct Keyboard {
40         int dev_fd;
41         enum {RAW, CANONICAL} ttystate;
42 };
43
44 static Keyboard *keyboard;
45
46 bool init_keyboard()
47 {
48         if(!(keyboard = (Keyboard*)sh_malloc(sizeof *keyboard))) {
49                 return false;
50         }
51
52         get_subsys()->keyboard_offset = (int)((char*)keyboard - (char*)get_pool());
53
54         keyboard->ttystate = keyboard->CANONICAL;
55         keyboard->dev_fd = -1;
56
57         if((keyboard->dev_fd = open("/dev/tty", O_RDWR)) == -1) {
58                 fprintf(stderr, "Cannot open /dev/tty : %s\n", strerror(errno));
59                 return false;
60         }
61
62         struct termios buf;
63
64         if(tcgetattr(keyboard->dev_fd, &buf) < 0) {
65                 fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
66                 return false;
67         }
68
69         buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
70         buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
71         buf.c_cflag &= ~(CSIZE | PARENB);
72         buf.c_cflag |= CS8;
73         buf.c_oflag &= ~(OPOST);
74
75         if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) {
76                 return false;
77         }
78
79         keyboard->ttystate = keyboard->RAW;
80         return true;
81 }
82
83 void destroy_keyboard()
84 {
85         struct termios buf;
86
87         if(tcgetattr(keyboard->dev_fd, &buf) < 0) {
88                 fprintf(stderr, "Cannot get the tty parameters : %s\n", strerror(errno));
89         }
90
91         buf.c_lflag |= (ECHO | ICANON | IEXTEN | ISIG);
92         buf.c_iflag |= (BRKINT | ICRNL | INPCK | ISTRIP | IXON);
93         buf.c_cflag |= (CSIZE | PARENB);
94         buf.c_cflag &= CS8;
95         buf.c_oflag |= (OPOST);
96
97         if(tcsetattr(keyboard->dev_fd, TCSAFLUSH, &buf) < 0) {
98                 fprintf(stderr, "Cannot set the tty parameters : %s\n", strerror(errno));
99         }
100
101         keyboard->ttystate = keyboard->CANONICAL;
102
103         if(keyboard->dev_fd != -1) {
104                 close(keyboard->dev_fd);
105                 keyboard->dev_fd = -1;
106         }
107
108         sh_free(keyboard);
109 }
110
111 bool client_open_keyboard(void *smem_start, int offset)
112 {
113         keyboard = (Keyboard*)((unsigned char*)smem_start + offset);
114         return true;
115 }
116
117 void client_close_keyboard()
118 {
119 }
120
121 int get_keyboard_fd()
122 {
123         return keyboard->dev_fd;
124 }
125
126 void process_keyboard_event()
127 {
128         char key;
129         if(read(keyboard->dev_fd, &key, 1) < 1) {
130                 return;
131         }
132
133         if(key == 'q') {
134                 exit(0);
135         }
136
137         Window *focused_win = wm->get_focused_window();
138         if(focused_win) {
139                 KeyboardFuncType keyb_callback = focused_win->get_keyboard_callback();
140                 if(keyb_callback) {
141                         keyb_callback(focused_win, key, true); //TODO: true??
142                 }
143         }
144
145         /* TODO:
146          * - handle system-wide key combinations (alt-tab?)
147          * - otherwise send keypress/release to focused window
148          */
149 }
150 #endif // WINNIE_FBDEV