1 /*! \addtogroup Consola
2 \page teclado.c Contiene las funciones de manejo de teclado.
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 */
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. */
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;
56 kprintf("Pos: %d Cursor: %d\n", _pos, _cur);
59 /* (TEMPORAL) Si se presiona CTRL + F, poner al shell en ForeGround */
61 if (toupper(car)=='F' && ctrl) {
63 goto salir_int_teclado;
69 if (buff_head
== (buff_teclado
+ MAX_BUFF_TECLADO
) ) {
70 buff_head
= buff_teclado
;
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)
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
;
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
;
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 );
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
)
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
;
120 _keymap
= keymap_std_shift
;
123 unsigned int car
= _keymap
[code
& 0x7F];
124 if ( code
>= 0x80 ) { /* tecla fue soltada */
130 alt
= TRUE
& presionada
;
131 car
= TECLA_MODIFICADORA
;
134 ctrl
= TRUE
& presionada
;
135 car
= TECLA_MODIFICADORA
;
138 shift
= TRUE
& presionada
;
139 car
= TECLA_MODIFICADORA
;
142 car
= car
| alt
| ctrl
;
150 unsigned char getchar(void)
153 while ( consola_cant
<= 0 );
155 car
= *consola_tail
++;
156 if (consola_tail
== (buff_consola
+ MAX_BUFF_CONSOLA
) )
157 consola_tail
= buff_consola
;
172 unsigned char getchar(void)
177 // Si hay un caracter en el buffer lo devolvemos
178 if ( ptrbufferTeclado >= bufferTeclado ) {
179 __asm__ __volatile__("cli");
181 caracter = *ptrbufferTeclado;
182 __asm__ __volatile__("sti");
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 ) {
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
206 // Switcheamos de proceso mediante la macro _reschedule quien realiza una llamada
207 // a la interrupción 0x51
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
216 // Devolvemos finalmente la tecla ingresada
217 __asm__ __volatile__("cli");
219 caracter = *ptrbufferTeclado;
220 __asm__ __volatile__("sti");
234 if ( valor
== '\b' ) {
240 else if ( valor
== '\0' ) { flag
--; }
245 if ( valor
== '\n' ) { string
--; flag
--; }
250 if ( string
== s
) { s
=NULL
; }
251 else { *string
= '\0'; }