/***************************************************************************** Gestionnaire de terminal Unix: keyboard.h (c) Pierre Adriaans 1994 ------------------------------------------------------------------------------ Include de keyboard.c Module de gestion de clavier. - Travaille avec un fichier de mapping de touches cree en interractif et place dans le home directory du user. - Toujours initialiser l'unite par un appel a la fonction InitKeyboard(), celle-ci assurant la lecture ou la creation du fichier de mapping associe au terminal courant. - la fonction Getch() fonctionne comme sur PC DOS: lecture d'un caractere sans echo ni return ni traitement. - La fonction KeyPressed() est plus interessante: elle lit une TOUCHE sans echo ni return de facon non bloquante et la stocke dans une queue FIFO: - si cette touche est une touche de controle connue, son code symbolique defini dans keyboard.h est stocke. - si cette touche est une touche classique, son code ASCII est stocke - si cette touche est une touche de controle non geree, le code. symbolique K_UNKNOWN est stocke. Cette fonction renvoie 1 (true) si une touche a ete frappee, et renvoie 0 (false) sinon. ------------------------------------------------------------------------------ ATTENTION: Il existe plusieurs facons de passer le terminal en mode non bloquant dans la fonction KeyPressed() et fonction de la norme UNIX utilisee. Il faut preciser a la fonction d'inititalisation le type de gestion a appliquer. ------------------------------------------------------------------------------ - Un appel a la fonction ReadKbd() permet une lecture synchrone du clavier par le meme mecanisme que KeyPressed(). Il aurait ete possible d'implementer ReadKbd() comme une boucle d'appels a KeyPressed(). J'ai essaye, ca marche, mais ca consomme du processeur de facon incroyable a cause des multiples changement d'etat du terminal. ReadKbd() est donc implemente comme une lecture bloquante. - Lors de l'initialisation de l'unite, la configuration du terminal est modifiee: - ISIG est annule pour eviter qu'un utilisateur qui s'acharne sur le sur PC (qui genere un SIGINT) ne termine un process sans le vouloir. Ce qui signifie que si le programme utilisateur desire utiliser le pour interrompre qque chose, il doit modifier par un ioctl le terminal pour retablir la transmission du SIGINT. - ECHO est annule pour eviter les parasites. Ne pas oublier de les retablir si execution d'une commande dans un sous-shell (fonction RestoreTerminal()). - Les fonctions Getch() et ReadKbd() transmettent les caracteres accentues avec un code negatif. - Ordre d'initialisation normal des unites: - keyboard.c - screen.c - clock.c *****************************************************************************/ #ifndef _KEYBOARD_H_ #define _KEYBOARD_H_ #include #include #include #include #include #include #include #include #include #include #include #include "ansi.h" /* Signal si erreur de malloc() */ #define SIGME SIGABRT /*---------------------------------------------------------------------------- Tupe de mapping ----------------------------------------------------------------------------*/ #define TERMCAP_MAP 0 #define INTERACTIVE_MAP 1 /*---------------------------------------------------------------------------- Type de passage de clavier en asynchrone ----------------------------------------------------------------------------*/ #define POSIX_KBD 0 #define SYSTEM_V_KBD 1 #define BSD_KBD 2 #define USR_GROUP_KBD 3 #ifndef O_NONBLOCK /* Pour autoriser la compilation */ #define O_NONBLOCK O_NDELAY /* sur des UNIX non POSIX */ #endif #ifndef ESC #define ESC 27 #endif /* Codes symboliques et ASCII des touches */ #define BACKSP 8 #define TAB 9 #define SPACE ' ' #define DELETE 127 #define CR 13 #define LF 10 #define BELL 7 #define CTRL_A 1 #define CTRL_B 2 #define CTRL_C 3 #define CTRL_D 4 #define CTRL_E 5 #define CTRL_F 6 #define CTRL_G 7 #define CTRL_H 8 #define CTRL_I 9 #define CTRL_J 10 #define CTRL_K 11 #define CTRL_L 12 #define CTRL_M 13 #define CTRL_N 14 #define CTRL_O 15 #define CTRL_P 16 #define CTRL_Q 17 #define CTRL_R 18 #define CTRL_S 19 #define CTRL_T 20 #define CTRL_U 21 #define CTRL_V 22 #define CTRL_W 23 #define CTRL_X 24 #define CTRL_Y 25 #define CTRL_Z 26 /* Codes des touches de controle: valeurs arbitraires et internes */ #define CTRL_KEYS_START 1200 #define K_UP 1200 #define K_DOWN 1201 #define K_RIGHT 1202 #define K_LEFT 1203 #define K_END 1204 #define K_HOME 1205 #define K_PGUP 1206 #define K_PGDN 1207 #define K_INS 1208 #define K_F1 1209 #define K_F2 1210 #define K_F3 1211 #define K_F4 1212 #define K_F5 1213 #define K_F6 1214 #define K_F7 1215 #define K_F8 1216 #define K_F9 1217 #define K_F10 1218 #define K_F11 1219 #define K_F12 1220 #define K_F13 1221 #define K_F14 1222 #define K_F15 1223 #define K_F16 1224 #define K_F17 1225 #define K_F18 1226 #define K_F19 1227 #define K_F20 1228 #define K_HELP 1229 #define K_DO 1230 #define K_FIND 1231 #define K_PF1 1232 #define K_PF2 1233 #define K_PF3 1234 #define K_PF4 1235 #define K_SELECT 1236 #define K_REMOVE 1237 #define K_UNKNOWN 1500 #define NO_KEY_AVAIL 2000 /* Longueur maxi d'un code de touche */ #define MAX_KEY 12 /* Longueur maxi d'un texte de saisie */ #define MAX_TEXT 25 /* Taille d'une sequence dans TERMCAP */ #define MAX_TCAP_SEQ 7 /* Descripteur d'entree clavier pour la table de comparaison */ struct KbEntry_s { char Sequence[MAX_KEY]; /* La sequence generee */ int SymbolicCode; /* Le code symbolique */ char Texte[MAX_TEXT]; /* Le texte affiche lors de la saisie interractive et stocke dans le fichier de mapping */ char TCapSeq[MAX_TCAP_SEQ]; }; typedef struct KbEntry_s KbEntry_t; /* Queue FIFO de stockage des touches entrees, realise par KeyPressed() */ struct KeyQueue_s { int Code; struct KeyQueue_s *Suivant; }; typedef struct KeyQueue_s KeyQueue_t; /***************************************************************************** Gestion de la queue FIFO d'entrees clavier *****************************************************************************/ /* Recuperation de l'adresse de depart de la queue d'entrees */ KeyQueue_t *GetKeyQueueAdress(void); /* Placement d'une entree dans la queue */ int KeyInQueue(int Code); /* Recuperer la plus ancienne entree */ int OldestKey(void); /* Libere toute la queue */ void FreeKeyQueue(void); /***************************************************************************** Gestion de la table de conversion sequences terminal - code symbolique *****************************************************************************/ /* Renvoyer le nombre de codes connus de la table */ int GetNbreKeys(void); /* Renvoyer l'adresse de la table */ struct KbEntry_s *GetKbCodesAdress(void); /* Recuperation d'une sequence terminal par pression de la touche */ void GetKey(char *Buf); /***************************************************************************** Gestion du clavier proprement dit *****************************************************************************/ /* Effacer le buffer clavier */ void WipeKbd(void); /* Fonction BOOL de test d'entree */ int KeyPressed(void); /* Lecture intelligente du clavier: renvoie le code symbolique ou ASCII */ int ReadKbd(void); /* Lecture brute du clavier: renvoie un caractere */ int getch(void); /* Fonction de detournement des signaux de terminaison du noyau */ void _terminate_(int Num); /***************************************************************************** Initialisation du gestionnaire de clavier *****************************************************************************/ void SetOneKey(char *FileBuf); int InitKbFromFile(char *KeyFile); void GetOneKey(char *Texte,char* Buffer); void InitKbFromKeyboard(char* KeyFile); void SetKeyboard(void); void RestoreKeyboard(void); void _SetSig_(void); void InitKeyboard(char *KeyFile,int KbType,int MappingType); void ExitKeyboard(void); /* Check de signaux recus pendant un free(). Retablir si necassaire */ /* #ifndef _KEYBOARD_SOURCE_CODE_ extern int _InFree_; #endif #define free(X) { _InFree_ = 1; free(X); _InFree_ = 0; } */ #endif