Curses

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher
image illustrant un logiciel
Cet article est une ébauche concernant un logiciel.

Vous pouvez partager vos connaissances en l’améliorant (comment ?) selon les recommandations des projets correspondants.

 Ne doit pas être confondu avec Curse.

Curses est le nom d'une bibliothèque logicielle permettant le développement sous Unix d'environnements plein écran en mode texte, indépendamment du terminal informatique utilisé, et pour tout type d'applications.

Elle est issue de la distribution BSD d'Unix, dans laquelle elle était employée pour l'éditeur de texte vi et le jeu Rogue.

En utilisant curses, les programmeurs peuvent concevoir des applications basées sur le mode texte, sans tenir compte des particularités de chaque terminal. La bibliothèque curses s'occupe d'envoyer les caractères de contrôle appropriés vers le moniteur lors de l'exécution du programme, en essayant d'optimiser ce qu'elle peut quand elle le peut.

Rester en mode texte, mais en y utilisant ainsi l'adressage direct de tout endroit de l'écran, permet aussi de ne pas avoir à s'occuper du gestionnaire graphique utilisé parmi les nombreux que peut utiliser Linux ou Unix.

Plusieurs installeurs de Linux dans les années 1990 utilisaient le mode texte en plein écran, à commencer par celui de la célèbre Slackware.

Avantages[modifier | modifier le code]

Avec curses, il est possible d'écrire à tout moment en toute position de l'écran, ce qui permet de suivre facilement le déroulement d'un programme dans des conditions moins fatigantes que le mode de déroulement du genre machine à écrire. On peut également effectuer des entrées par ce moyen, et créer par exemple des formulaires simples en mode texte, voire simuler complètement un terminal plein écran comme un 3270[1]. Des variantes existent même permettant de simuler un Minitel[2].

Fonctionnement[modifier | modifier le code]

Les fonctions principales sont très simples :

initscr() initialise le mode plein écran.

move(ligne, colonne) déplace virtuellement le curseur

addstr(chaîne) écrit une chaîne de caractères là où est le curseur

refresh() met en conformité l'écran réel et l'affichage virtuel

endwin() met fin au mode plein écran et restaure l'état où était l'écran avant que l'on ne s'y place.

Curses/ncurses est installé en standard dans quelques distributions. Sur d'autres comme Ubuntu Studio ou Mint, on doit l'installer par exemple comme ceci pour le gcc5 depuis une console : sudo apt install libncurses5-dev[3].

Exemple simple[modifier | modifier le code]

Exemple de curses : comptage des mots du dictionnaire /usr/share/dict/french en les répartissant par longueur

Le très simple programme suivant[4] compte en les répartissant par longueur les mots du dictionnaire français /usr/share/dict/french de GNU/Linux.

// Se compile par exemple avec gcc cursef.c -lcurses && ./a.out

#include <curses.h> 
#include <string.h>

int c;                 // colonne ((0,0) en haut à gauche)
int count[128], total; // à 0; comptage des mots de chaque longueur

int main()
{ 
  WINDOW* win;
  FILE* infile;
  char d, xxx[128], out[128];
  infile = fopen("/usr/share/dict/french", "r"); // Dictionnaire
  
  win = initscr(); // Initialisation
  cbreak();        // Ne pas exiger ENTER
  noecho();        // Pas d'écho demandé
  clear();         // Fenêtre à blanc
  refresh();       // Exécution de ce qui a été préparé dans la fenêtre

  int octets, glyphes; // En unicode, quelques glyphes sont multi-octets
  while (!feof(infile))
  { 
    fgets(xxx, 100,infile);
       // Bidouillage pour unicode (car glyphes multioctets)
       octets=0; glyphes=0; 
       while (xxx[octets])
       { 
        if ((xxx[octets] & 0xC0) != 0x80 ) ++glyphes;
        ++octets;
       }
       --glyphes; ++count[glyphes]; // négliger retour ligne
       // Fin du bidouillage
    sprintf(out, "%7d %s", count[glyphes], xxx);
    move(glyphes-1,0);
    addstr(out); // préparer la ligne dans la fenêtre
    refresh();   // afficher la fenêtre

    ++total;
  }

  sprintf(out, "%7d mots au total", total);
  move (26,0); addstr(out); refresh();
  d=getch();   // Attente d'un caractère pour effacer fenêtre et sortir

  endwin();    // curses call to restore the original window and leave
}

Alternative[modifier | modifier le code]

L'envoi direct de commandes de déplacement du curseur au terminal (ainsi de de changement de teinte de caractère et de fond) est également possible sur la plupart des écrans caractère, ceux-ci honorant en général les séquences ANSI dites CSI (Control Sequence Introducer), en compatibilité avec le VT100. Dans la pratique, l'emploi de curses rend plus aisée la maintenance des programmes (l'usage de CSI reste inévitable dans des scripts). Par ailleurs, le fait qu'un nouvel affichage n'ait lieu avec curses qu'à chaque refresh() et non à chaque nouvelle écriture sur le terminal peut procurer une meilleure expérience visuelle à l'utilisateur par l'affichage de tout l'écran une fois complet plutôt qu'à chaque modification partielle de celui-ci.

Notes et références[modifier | modifier le code]

  1. Simulation d'un terminal 3270 avec curses.
  2. Minicurses : simulation d'un Minitel "à la curses".
  3. Les bibliothèques curses et ncurses ne se distinguent pas ici fonctionnellement
  4. surtout si l'on n'avait pas besoin de distinguer entre nombre d'octets et nombre de caractères en unicode. Cela aurait été facile en convertissant le ficher du codage UTF-8 au codage ISO-8859-15 où chaque caractère français tient sur un octet (iconv -f UTF-8 -t ISO8859-15 /usr/share/dict/french >xxx). Le fichier dans sa version d'avril 2016 passe alors de 1542061 caractères à 1480824 caractères à contenu strictement égal. La pénalité relativement faible de l'Unicode (4%) en contrepartie de la liberté qu'il apporte a joué dans son adoption rapide.

Voir aussi[modifier | modifier le code]

Articles connexes[modifier | modifier le code]

  • ncurses, successeur de curses.
  • PDcurses, version curses dans le domaine public.

Bibliographie[modifier | modifier le code]

Liens externes[modifier | modifier le code]