initial commit
[pfinal.git] / Routix / src / console / teclado.c
blob5187f44088016d5ed722500ae4675fed91276d90
1 /*! \addtogroup Consola
2 \page teclado.c Contiene las funciones de manejo de teclado.
3 */
4 #include "routix/system.h"
5 #include "drivers/teclado.h"
6 #include "drivers/video.h"
7 #include "routix/atomic.h"
8 #include "routix/event.h"
9 #include "routix/8259.h"
10 #include <routix/kstdio.h>
12 /*! Puntero a tabla de caracteres (por default keymap_std) */
13 unsigned int *keymap = keymap_std;
15 /*! Buffer driver de teclado */
16 #define MAX_BUFF_TECLADO 16
17 char buff_teclado[MAX_BUFF_TECLADO + 2];
18 char *buff_head = buff_teclado; /* Apunta al lugar donde debo guardar el prox caracter */
19 char *buff_tail = buff_teclado; /* apunta al caracter que debo sacar primero */
20 word buff_cant = 0;
22 char shift=0, alt=0, ctrl=0;
23 char num_lock, caps_lock, scr_lock;
25 /*! Buffer consola, almacenado en una cola circular */
26 #define MAX_BUFF_CONSOLA 32
27 char buff_consola[MAX_BUFF_CONSOLA + 2];
28 char *consola_head = buff_consola; /* Apunta al lugar donde debo guardar el prox caracter */
29 char *consola_tail = buff_consola; /* apunta al caracter que debo sacar primero */
30 word consola_cant = 0;
33 /*! Rutina de atención de interrupción de teclado. Solo toma los scan codes del puerto correspondiente y los coloca
34 * en una cola circular de MAX_BUFF_TECLADO caracteres. */
35 void Teclado(void)
37 byte scode;
38 scode = inportb (TECLADO_PORT);
40 if ( buff_cant >= MAX_BUFF_TECLADO ) /* Buffer lleno, no puede guardarse el scancode */
41 goto salir_int_teclado;
43 unsigned int car = _getascii (scode & 0x7F);
45 if (scode >= 0x80 ) /* Breakcode */
46 if ( car!=CTRL && car!=ALT && car!=SHIFT )
47 goto salir_int_teclado; /* Fue el release de un caracter normal... me voy */
49 /* Se presiono alguna combinacion de ALT+F ,switchear de tty en consola*/
52 if ( car==F1 && alt) {
53 unsigned long _pos, _cur;
54 _pos = pos;
55 _cur = cursorr;
56 kprintf("Pos: %d Cursor: %d\n", _pos, _cur);
59 /* (TEMPORAL) Si se presiona CTRL + F, poner al shell en ForeGround */
60 /*
61 if (toupper(car)=='F' && ctrl) {
62 shell_to_fg();
63 goto salir_int_teclado;
65 */
66 *buff_head = scode;
67 buff_head++;
68 buff_cant++;
69 if (buff_head == (buff_teclado + MAX_BUFF_TECLADO) ) {
70 buff_head = buff_teclado;
73 salir_int_teclado:
74 endOfInterrupt();
77 /*! Toma los scancodes del buffer de teclado y según el estado de las teclas especiales, los transforma en
78 * caracteres ascii los cuales coloca en el buffer "buff_consola" */
79 void leer_buff_teclado (void)
81 unsigned int car;
82 cli();
83 while ( (consola_cant <= MAX_BUFF_CONSOLA) && (buff_cant > 0) ) {
84 car = getascii (*buff_tail++);
85 if (buff_tail == (buff_teclado + MAX_BUFF_TECLADO) )
86 buff_tail = buff_teclado;
87 buff_cant--;
89 if (car > 0xff) /* Si el codigo levantado del buffer pertenece a alguna tecla de función */
90 continue; /* o ALT, CTRL, NUM_LOCK, por ahora, no la tengo en cuenta */
92 *consola_head++ = (unsigned char) car;
93 consola_cant++;
94 if (consola_head >= (buff_consola + MAX_BUFF_CONSOLA) ) {
95 consola_head = buff_consola;
98 // if (consola_cant>0)
99 // Actualizamos los eventos de TECLADO
100 // actualizar_eventos( TECLADO );
102 sti();
106 /*! Devuleve el caracter ASCII de un determinado scan code, sin tener en cuenta teclas especiales o de funciones */
107 inline unsigned int _getascii (unsigned char code)
109 return keymap[code];
112 /*! Devuelve el ASCII, teniendo en cuenta el estado de las teclas de especiales.
113 * Por ej: Si alguien presiona CTRL + m, esta función retirara primero el CTRL del buffer, y activará el flag "ctrl"
114 * cuando retire el scan code correspondiente a "m", al ver que está activado "ctrl" devolverá un entero CTRL | M
115 * Este tipo de combinaciones deberán ser reconocidas por la TTY */
116 unsigned int getascii (unsigned char code)
118 unsigned int *_keymap = keymap;
119 if (shift==1)
120 _keymap = keymap_std_shift;
122 char presionada = 1;
123 unsigned int car = _keymap[code & 0x7F];
124 if ( code >= 0x80 ) { /* tecla fue soltada */
125 presionada = 0;
128 switch (car) {
129 case ALT:
130 alt = TRUE & presionada;
131 car = TECLA_MODIFICADORA;
132 break;
133 case CTRL:
134 ctrl = TRUE & presionada;
135 car = TECLA_MODIFICADORA;
136 break;
137 case SHIFT:
138 shift = TRUE & presionada;
139 car = TECLA_MODIFICADORA;
140 break;
141 default:
142 car = car | alt | ctrl;
145 return car;
150 unsigned char getchar(void)
152 unsigned char car;
153 while ( consola_cant <= 0 );
154 cli();
155 car = *consola_tail++;
156 if (consola_tail == (buff_consola + MAX_BUFF_CONSOLA) )
157 consola_tail = buff_consola;
158 consola_cant--;
159 sti();
160 return car;
172 unsigned char getchar(void)
174 event_t *nuevo;
175 char caracter;
177 // Si hay un caracter en el buffer lo devolvemos
178 if ( ptrbufferTeclado >= bufferTeclado ) {
179 __asm__ __volatile__("cli");
180 --ptrbufferTeclado;
181 caracter = *ptrbufferTeclado;
182 __asm__ __volatile__("sti");
183 return(caracter);
186 // Sino agregamos un nodo a la lista de eventos y esperamos
188 // Alocamos un nuevo nodo en memoria
189 nuevo = (event_t *) malloc( sizeof(event_t) );
191 // Error al intentar alocar memoria (setear errno)
192 if ( nuevo == NULL ) {
193 return -1;
196 // Dispositivo TECLADO
197 nuevo->dispositivo = TECLADO;
198 nuevo->proceso=actual;
200 // Finalmente lo agregamos a la lista de eventos
201 insertar_evento(nuevo);
203 // y nos ponemos a dormir
204 dormir_task(actual);
206 // Switcheamos de proceso mediante la macro _reschedule quien realiza una llamada
207 // a la interrupción 0x51
208 _reschedule();
210 // Volvimos ! Hay por lo menos una tecla en el buffer, eliminamos el nodo de la lista de eventos
211 remover_evento(nuevo);
213 // Liberamos el espacio
214 free(nuevo);
216 // Devolvemos finalmente la tecla ingresada
217 __asm__ __volatile__("cli");
218 --ptrbufferTeclado;
219 caracter = *ptrbufferTeclado;
220 __asm__ __volatile__("sti");
222 return(caracter);
225 char *gets(char *s)
227 unsigned char valor;
228 char *string=s;
229 char flag=1;
231 while ( flag ) {
232 valor = getchar();
234 if ( valor == '\b' ) {
235 if ( string != s ) {
236 string--;
237 putchar(valor);
240 else if ( valor == '\0' ) { flag--; }
242 else {
243 *string++=valor;
244 putchar(valor);
245 if ( valor == '\n' ) { string--; flag--; }
250 if ( string == s ) { s=NULL; }
251 else { *string = '\0'; }
253 return s;