missing files and previous update were fixed
[ZeXOS.git] / kernel / drivers / char / kbd / kbd.c
blob1d6c60d9eaf04d3a66f60768d3f796ab682bdc70
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <build.h>
23 #include <system.h>
24 #include <arch/io.h>
25 #include <string.h>
26 #include <signal.h>
27 #include <config.h>
28 #include <console.h>
29 #include <proc.h>
30 #include "kbd.h"
33 unsigned char scancode = 0;
34 unsigned modes = 0;
35 bool upped = 0;
37 kbd_quaue kbd_q;
39 char kbdmap[3];
41 unsigned keyboard_setlayout (char *layout)
43 if (!strcmp (layout, "us")) {
44 kbd_layout[0] = (unsigned char *) &kbdus;
45 kbd_layout[1] = (unsigned char *) &kbdus_shift;
47 strcpy (kbdmap, "us");
49 return 1;
52 if (!strcmp (layout, "cz")) {
53 kbd_layout[0] = (unsigned char *) &kbdcz;
54 kbd_layout[1] = (unsigned char *) &kbdcz_shift;
56 strcpy (kbdmap, "cz");
58 return 1;
61 return 0;
64 unsigned keyboard_getlayout (char *layout)
66 if (!strcmp (kbdmap, layout))
67 return 1;
69 return 0;
72 char getkey ()
74 #ifdef ARCH_arm
75 char k = rs232_read ();
77 if (!k)
78 return 0;
80 if ((k >= '0' && k <= '9') || (k >= 'A' && k <= 'Z') || (k >= 'a' && k <= 'z')) {
81 kbd_q.key[0] = k;
82 kbd_q.p = 1;
83 } else if (k == 13) {
84 kbd_q.key[0] = '\n';
85 kbd_q.p = 1;
86 } else if (k == 32) {
87 kbd_q.key[0] = ' ';
88 kbd_q.p = 1;
89 } else if (k == 127) {
90 kbd_q.key[0] = '\b';
91 kbd_q.p = 1;
93 #endif
94 char s[KBD_MAX_QUAUE];
96 if (!kbd_q.p)
97 return 0;
99 char key = kbd_q.key[0];
101 kbd_q.p --;
103 memcpy (s, kbd_q.key+1, kbd_q.p);
105 memcpy (kbd_q.key, s, kbd_q.p);
107 return key;
110 void setkey (char key)
112 char s[KBD_MAX_QUAUE];
114 if (kbd_q.p >= KBD_MAX_QUAUE)
115 return;
117 kbd_q.p ++;
119 memcpy (s+1, kbd_q.key, kbd_q.p);
121 s[0] = key;
123 memcpy (kbd_q.key, s, kbd_q.p);
126 unsigned key_pressed (int keycode)
128 if (scancode == keycode)
129 return 1;
131 if (scancode == keycode+128)
132 return 2;
133 else
134 return 0;
137 #ifdef ARCH_i386
138 void keyboard_handler (struct regs *r)
140 int i, setsignal = 0;
142 /* Read from the keyboard's data buffer */
143 scancode = inb (0x60);
145 /* If the top bit of the byte we read from the keyboard is
146 * set, that means that a key has just been released */
147 if (scancode & 0x80) {
148 /* You can use this one to see if the user released the
149 * shift, alt, or control keys... */
150 //DPRINT ("key up: %d", scancode);
152 //kbd_q.state[0] = 2; // up
154 if (key_pressed (CTRL) == 2)
155 modes &= ~0x1;
156 if (key_pressed (ALT) == 2)
157 modes &= ~0x2;
158 if (key_pressed (DEL) == 2)
159 modes &= ~0x4;
160 if (key_pressed (SHIFTL) == 2 || key_pressed (SHIFTR) == 2)
161 modes &= ~0x8;
162 } else {
163 /* Here, a key was just pressed. Please note that if you
164 * hold a key down, you will get repeated key press
165 * interrupts. */
167 /* Just to show you how this works, we simply translate
168 * the keyboard scancode into an ASCII value, and then
169 * display it to the screen. You can get creative and
170 * use some flags to see if a shift is pressed and use a
171 * different layout, or you can add another 128 entries
172 * to the above layout to correspond to 'shift' being
173 * held. If shift is held using the larger lookup table,
174 * you would add 128 to the scancode when you look for it */
176 //DPRINT ("key down: %d", scancode);
178 /* CTRL+ALT+DEL - magic keys */
179 if (key_pressed (CTRL))
180 modes |= 0x1;
181 if (key_pressed (ALT))
182 modes |= 0x2;
183 if (key_pressed (DEL))
184 modes |= 0x4;
186 /* big letters */
187 if (key_pressed (SHIFTL) || key_pressed (SHIFTR))
188 modes |= 0x8;
190 /* TTY changing - alt+F1-F4*/
191 if (modes & 0x2) {
192 if (key_pressed (F1))
193 tty_change ((tty_t *) tty_find ("tty0"));
194 else if (key_pressed (F2))
195 tty_change ((tty_t *) tty_find ("tty1"));
196 else if (key_pressed (F3))
197 tty_change ((tty_t *) tty_find ("tty2"));
198 else if (key_pressed (F4))
199 tty_change ((tty_t *) tty_find ("tty3"));
200 else if (key_pressed (PAGEUP))
201 tty_switch ('+');
202 else if (key_pressed (PAGEDOWN))
203 tty_switch ('-');
206 if (key_pressed (ARROWUP))
207 consolelog_prev ();
208 if (key_pressed (ARROWDOWN))
209 consolelog_next ();
211 /* reboot pc, when are pressed ctrl+alt+del */
212 if (modes & 0x1 && modes & 0x2) {
213 if (modes & 0x4) {
214 printf ("\nRebooting ..");
216 outb (0x64, 0xFE);
217 while(1);
221 /* CTRL + C - sigterm */
222 if (modes & 0x1) {
223 if (key_pressed (KB_C)) {
224 setsignal = 1;
225 scancode = 0;
229 /* SHIFT - BIG LETTERS */
230 if (modes & 0x8)
231 setkey (kbd_layout[1][scancode]);
232 else
233 setkey (kbd_layout[0][scancode]);
237 outb (0x20, 0x20);
239 /* CTRL + C was pressed - send sigterm to app */
240 if (setsignal) {
241 if (!signal (SIGTERM, (sighandler_t) SIG_IGN))
242 DPRINT ("signal () - error\n");
245 #endif
247 unsigned int init_keyboard ()
249 #ifdef ARCH_i386
250 #ifdef CONFIG_DRV_KEYBOARD
251 int i;
252 irq_install_handler (1, keyboard_handler);
254 /* set default kbd layout - US */
255 kbd_layout[0] = (unsigned char *) &kbdus;
256 kbd_layout[1] = (unsigned char *) &kbdus_shift;
258 strcpy (kbdmap, CONFIG_UI_KBD_LAYOUT);
260 if (!strcmp (kbdmap, "us")) {
261 keyboard_setlayout ("us");
263 kprintf ("Loaded en_US keyboard layout\n");
266 if (!strcmp (kbdmap, "cz")) {
267 keyboard_setlayout ("cz");
269 kprintf ("Loaded cs_CZ keyboard layout\n");
272 for(i = 0; i < 20; i++)
273 currtty->shell[i] = '\0';
275 for(i = 0; i < KBD_MAX_QUAUE; i++)
276 kbd_q.key[i] = '\0';
278 kbd_q.p = 0;
279 #endif
280 #endif
281 return 1;