SYSTÈME D’EXPLOITATION I SIF-1015
Contenu du cours 5 Entrées/Sorties écran –Concepts –I/O avec libc –I/O avec ncurses –LECTURES: Chapitres 5 et 6 (Matthew) Chapitre 9 (Card), Chapitre 8 (The LINUX programmer’s guide, Goldt)
Concepts
Les I/O écran peuvent être orientées pixels ou caractères Un caractère représente une composition de pixels qui peut être changée en fonction de la police de caractères (charset) Les cartes graphiques offrent déjà une ou plusieurs polices de caractères et opèrent en mode texte par défaut parce que le texte est traité plus rapidement qu’en mode graphique Les terminaux/consoles LINUX offrent différentes possibilités: –Fonctions de libc permettent des sorties formatées de chaînes de caractères sur stdout (standard output), stderr (standard error) ou dans des fichiers; ainsi que des entrées formatées à partir de stdin (standard input) –Accès à la base de données termcap (TERMinal CAPabilitie) qui est un ensemble d’entrées de descripteurs de terminaux dans le fichier ASCII /etc/termcap –Accès à la base de données terminfo (TERMinal INFOrmation) qui décrit comme termcap mais à un niveau plus élevé (changement des attributs d’écran). La base de données est dans /usr/lib/terminfo/
Concepts Les terminaux/consoles LINUX offrent différentes possibilités: –La librairie curses permet l’accès de haut niveau aux terminaux et est basée sur terminfo. Curses permet l’ouverture et la manipulation de fenêtres sur l’écran, fournit un ensemble de fonctions I/O et permet la modification des attributs vidéo. La librairie curses est dans le fichier /usr/lib/libcurses.a (version BSD) –La librairie ncurses est une amélioration de la librairie curses au niveau de la manipulation des couleurs et d’optimisations diverses
I/O avec libc Sorties formatées –Les fonctions printf() de libc permettent des sorties formatées int fprintf(FILE *stream, const char *format,... arguments …); Cette fonction permet la création de la sortie et son écriture dans un fichier. Le format fournit est aussi écrit. La fonction retourne le nombre de caractères écrits. Le champ format peut contenir des caractères normaux et des paramètres de formatage (ex: %d, %s …) permettant le formatage des arguments int printf(const char *format,... arguments …); Même fonction que int fprintf(stdout, const char *format,... arguments …); int sprintf(char *s, const char *format,... arguments …); Même fonction que printf(), sauf que la sortie est écrite sur le pointeur de caractères s avec un caractère \0 en fin de chaîne
I/O avec libc Entrées formatées –Les fonctions scanf() de libc permettent des sorties formatées int fscanf(FILE *stream, const char *format,... arguments …); Cette fonction permet de lire à partir d’un fichier et transforme les entrées selon les règles fournies dans le champ format. Les éléments lus sont déposés dans les arguments. Chaque argument doit être défini par un pointeur. int scanf(const char *format,... arguments …); Même fonction que int fscanf(stdin, const char *format,... arguments …); int sscanf(char *s, const char *format,... arguments …); Même fonction que scanf(), sauf que la lecture est faite à partir du pointeur de caractères s
I/O avec ncurses Avant d’utiliser la librairie ncurses nous devons définir les termes suivants: –Fenêtre (window): représentation interne d’une image d’une partie de l’écran. WINDOW est définit dans le fichier ncurses.h –Écran (screen): fenêtre avec la dimension de l’écran complet. Stdscr et curscr sont des écrans –Terminal: écran spécial avec des informations (attributs) sur cet écran –Constantes et variables importantes définies dans ncurses.h: WINDOW *curscr: écran actuel WINDOW *stdscr: écran standard int LINES: nombre de lignes sur le terminal int COLS: nombre de colonnes sur le terminal –Pour utiliser la librairie ncurses dans un programme C, il faut alors inclure le fichier ncurses.h qui définit les variables, les types (ex: WINDOW) et les prototypes de fonctions. De plus, stdio.h, stdarg.h, termios.h, et unctrl.h sont inclus automatiquement dans ncurses.h.
I/O avec ncurses Forme générale d’un programme #include main() { ….. initscr(); /* appels de fonctions ncurses */ endwin(); …. } initscr() initialise les structures de données ncurses et fait la lecture du fichier terminfo approprié. La mémoire est allouée pour stdscr et curscr.
I/O avec ncurses initscr() retourne si aucune erreur n’est survenue (ERR), un pointeur sur l’écran standard stdscr. LINES ET COLS sont initialisés et l’écran effacé endwin() libère les diverses ressources allouées et restaure le mode terminal (tty) d’avant l’appel à initscr() Pour compiler un programme utilisant les librairies ncurses: gcc [flag] files –lncurses Le chemin d’accès à ncurses.h est donné par: -I/usr/include/ncurses La librairie ncurses se situe dans le répertoire /usr/lib/
I/O avec ncurses Les structures de données associées à l’écran sont appelées windows et sont définies dans ncurses.h Une fenêtre est en fait une matrice en mémoire qui peut être manipulée par le programmeur sans même faire de sorties au terminal La fenêtre par défaut est l’écran standard (stdscr) avec la dimension du terminal La commande newwin() permet de créer d’autres fenêtres Ncurses facilite la mise à jour optimale du terminal physique en déclarant une autre fenêtre: curscr. Curscr est une image de ce que le terminal à l’air actuellement et stdscr une image de ce que le terminal devrait avoir l’air
I/O avec ncurses Le rafraîchissement (les sorties) du terminal est fait par la fonction refresh(). Ncurses met alors à jour curscr et le terminal physique avec l’information dans stdscr Ncurses permet la manipulation des structures window. Les fonctions dont le nom commence par w permettent la référence à une fenêtre. Par défaut, les fonctions ncurses font référence à stdscr. Les fonctions dont le nom commence par mv permettent au préalable un déplacement à une position y,x dans une fenêtre
I/O avec ncurses Initialisation –WINDOW *initscr(); Lecture du fichier terminfo Initialisation des structures de données ncurses Allocation de mémoire pour curscr et stdscr Initialisation des dimensions du terminal: LINES et COLS Retourne un pointeur sur stdscr ou ERR si une erreur survient –int endwin(); Restaure l’état du terminal avant l’appel à initscr() Déplacement du curseur dans le coin inférieur gauche
I/O avec ncurses Les fenêtres (windows) –WINDOW *newwin(nlines,ncols,begy,begx); Création d’une fenêtre begy, begx: coordonnées du coin supérieur gauche de la fenêtre nlines: nombre de lignes de la fenêtre ncols: nombre de colonnes de la fenêtre Quand nlines==0, la fenêtre a LINES-begy lignes Quand ncols==0, la fenêtre a COLS-begx colonnes L’appel newwin(0,0,0,0) ouvre une fenêtre de dimension de l’écran WINDOW *fenetre; fenetre = newwin(10,60,10,10);
I/O avec ncurses Les fenêtres (windows) –WINDOW *newwin(nlines,ncols,begy,begx);
I/O avec ncurses Les fenêtres (windows) –int delwin(win); Efface la fenêtre win Effacer toutes les fenêtres avant l’appel à endwin() –int mvwin(win,by,bx); Déplacement de la fenêtre win de by lignes et bx colonnes à l’intérieur de l’écran
I/O avec ncurses Les sorties –Ncurses offre des fonctions permettant l’affichage de caractères dans une fenêtre –Ces fonctions permettent la manipulation des fenêtres, refresh() permet d’actualiser ces manipulations à l’écran –int addch(ch); Écriture d’un caractère ch dans la fenêtre stdscr –int waddch(win, ch); Écriture d’un caractère ch dans la fenêtre win –int mvaddch(y,x,ch); Écriture d’un caractère ch dans la fenêtre stdscr à la position y,x –int mvwaddch(win,y,x,ch); Écriture d’un caractère ch dans la fenêtre win à la position y,x
I/O avec ncurses Les sorties –int addstr(str); Écriture d’une chaîne de caractères str dans la fenêtre stdscr (str est une chaîne de caractères terminée par le caractère null \0) –int waddstr(win, str); Écriture d’une chaîne de caractères str dans la fenêtre win –int mvaddstr(y,x,str); Écriture d’une chaîne de caractères str dans la fenêtre stdscr à la position y,x –int mvwaddstr(win,y,x,str); Écriture d’une chaîne de caractères str dans la fenêtre win à la position y,x
I/O avec ncurses Les sorties –int addchstr(chstr); Écriture d’une chaîne de caractères chstr dans la fenêtre stdscr (chstr est une chaîne de caractères simple sans le caractère null \0 à la fin) –int waddchstr(win, chstr); Écriture d’une chaîne de caractères chstr dans la fenêtre win –int mvaddchstr(y,x,chstr); Écriture d’une chaîne de caractères chstr dans la fenêtre stdscr à la position y,x –int mvwaddchstr(win,y,x,chstr); Écriture d’une chaîne de caractères chstr dans la fenêtre win à la position y,x
I/O avec ncurses Les entrées –int getch(); Lecture d’un caractère au terminal. Si le mode délai est actif getch() attend qu’un caractère soit tapé ou retourne un caractère du tampon du clavier ou ERR si ce tampon est vide. getch() permet la lecture au terminal associé à la fenêtre stdscr –int wgetch(win); Lecture d’un caractère au terminal de la fenêtre win –int mvgetch(y,x); Lecture d’un caractère dans la fenêtre stdscr à la position y,x –int mvwgetch(win,y,x); Lecture d’un caractère dans la fenêtre win à la position y,x
I/O avec ncurses Les entrées –int getstr(str); Lecture d’une chaîne de caractères str au terminal jusqu’au retour de chariot. Si le mode écho est actif, la chaîne est affichée –int wgetstr(win, str); Lecture d’une chaîne de caractères str au terminal de la fenêtre win –int mvgetstr(y,x,str); Lecture d’une chaîne de caractères str dans la fenêtre stdscr à la position y,x –int mvwgetstr(win,y,x,str); Lecture d’une chaîne de caractères dans la fenêtre win à la position y,x
I/O avec ncurses Les entrées (options) –int cbreak(); Active le mode CBREAK. Dans ce mode les entrées sont immédiatement disponibles au programme. Quand ce mode est inactif (nocbreak()) les entrées sont temporisées jusqu’au prochain retour de chariot –int raw(); Active le mode RAW. Ce mode est semblable au mode CBREAK sauf que les caractères spéciaux ne sont pas traités –int echo(); Permet l’affichage à l’écran des caractères introduits. noecho() inhibe cet affichage –int timeout(t); Le résultat de getch() dépend du délai de t. Si t est positif, la lecture est bloquée pour t millisecondes, Si t est 0, pas de blocage de la lecture, Si t est négatif la lecture est bloquée tant qu’une entrée ne sera pas disponible
I/O avec ncurses Les entrées (options) –int wtimeout(win,t); Même chose que timeout(), mais sur la fenêtre win –int keypad(win, bf); Si bf est TRUE, le clavier numérique sur le clavier peut être utilisé en input. keypad() retourne alors le code de la clé correspondant aux touches du clavier numérique (touches de fonctions et flèches) –int nl(); nl() permet de transposer un newline en un carriage return/line feed en sortie. nonl() ne permet aucune transposition
I/O avec ncurses Les entrées (options) –Exemple d’un programme qui attend des caractères et affiche les touches du clavier numérique enfoncées (keypad.c répertoire exemple/Chap6ProgLinux)
I/O avec ncurses Les entrées (options) –Exemple d’un programme qui attend des caractères et affichage les touches du clavier numérique (suite) Clear to end of line
I/O avec ncurses Les entrées (options) –Exemple d’un programme qui attend des caractères et affichage les touches du clavier numérique (exécution)
I/O avec ncurses Effacement d’une fenêtre –int erase(); Permet de remplacer chaque position de la fenêtre (stdscr, ou win avec werase(win)) par un blanc –int clear(); Même fonctionnement que erase() mais active aussi clearok() (l’écran est alors effacé lors du prochain refresh()). wclear(win) est un clear() sur la fenêtre win
I/O avec ncurses Mise à jour du terminal –int refresh(); Les fenêtres sont des images en mémoire sur lesquelles des changements ne sont affichés sur l’écran physique que lorsque qu’un rafraîchissement est effectué. refresh() copie l’image de stdscr au terminal et wrefresh(win) copie l’image de la fenêtre win au stdscr et au curscr Coordonnées fenêtre et curseur –int move(y,x); Déplacement du curseur dans stdscr à la position y,x. wmove(win,y,x) fait la même chose mais dans la fenêtre win –void getyx(win,y,x); Retourne la position y,x du curseur dans la fenêtre win
I/O avec ncurses Défilement de fenêtre (scrolling) –int scrollok(win, bf); Si bf est TRUE, le texte dans la fenêtre win défilera vers le haut d’une ligne lorsque le curseur atteindra le coin inférieur droit et qu’un autre caractère est tapé. Si bf est FALSE, le curseur reste à la même position (coin inférieur droit). Par la suite, les fonctions scroll(win), scrl(n), wscrl(win,n), ou l’introduction d’un retour de chariot (new line) permettront un défilement dans la fenêtre –int scroll(win); Défilement vers le haut d’une ligne dans la fenêtre win –int scrl(n); Défilement de n lignes dans la direction donnée par le signe de n. wscrl(win,n) même fonction que scrl(n) mais dans la fenêtre win
Exemple de création de fenêtre void creer_fenetreTxD1(void) { int ligne=15, colonne=55; fen1=newwin(ligne,colonne,0,0); //Cree une fenetre de 15 lignes, 55 colonnes placée à la ligne 0 et colonne 0 box(fen1,ls, bs); /* creation de la bordure */ /* #define ls ACS_VLINE Bordure verticale */ /* #define bs ACS_HLINE Bordure horizontale */ mvwaddstr(fen1,0,colonne/4," USER 1 - Transmission "); wrefresh(fen1); transmetteur1=newwin(ligne-2,colonne-2,1,1); /*Cree une fenetre de 13 lignes,52 colonnes placée à la ligne 1 et colonne 1*/ wrefresh(transmetteur1); scrollok(transmetteur1,TRUE); /* définition du défilement vertical de la fenêtre */ wrefresh(transmetteur1); /* rafraîchissement de la fenêtre de transmission */ }
Exemple de création de fenêtres (multiw1.c)
Permet d’afficher une fenêtre même si son contenu n’est pas modifié
Exemple de création de fenêtres (multiw1.c)
Gestion de la couleur (color.c) Détermine si le terminal supporte la couleur Initialise la table de couleurs
Gestion de la couleur (color.c) Permet d’initialiser une paire de couleur Désactive l’attribut BOLD Active la paire de couleur i Réactive l’attribut BOLD Couleur texte Couleur fond
Gestion de la couleur (color.c)