Logiciel libre, droits d'utilisation précisés en français
dans le fichier : licence-fr.txt
Traductions des droits d'utilisation dans les fichiers :
licence-de.txt , licence-en.txt , licence-es.txt ,
licence-it.txt , licence-nl.txt , licence-pt.txt ,
licence-eo.txt , licence-eo-utf.txt
Droits d'utilisation également sur la page web :
http://libremail.tuxfamily.org/voir.php?page=droits
Bibliothèque de fonctions permettant de gérer l'affichage en mode page
Certaines de ces fonctions sont des macros de modepage.h
On peut remarquer que les fonctions de déplacement dans le texte
et d'affichage d'une page ne manipulent que des indicateurs
de position dans le texte.
La fonction affligne reste dans le fichier source principal de
chaque application, ce qui permet d'avoir un affichage adapté
aux données à traiter.
*/
#define modepage // pour la déclaration de variables globales à l'application
/* teste si l'ordinateur a été démarré avec init ou avec systemd */
int util_systemd ()
{
// si libremail compilé seulement pour init ou pour systemd
#ifdef systemd
// retourner directement le résultat
return (systemd > 0);
// sinon la détection du système de démarrage est nécessaire
#else
static int sysinit = 0; // mémorise si le système de démarrage a été détecté
static int resultat; // résultat du test
FILE *descfic; // descripteur du fichier indiquant le système de démarrage
int car; // caractère du fichier indiquant le système de démarrage
// si le système de démarrage n'a pas encore été détecté
if (! sysinit)
{
// lancer la commande de recherche du processus d'initialisation
system ("ps 1 > /tmp/sys_init");
// ouvrir en lecture le fichier contenant l'information
descfic = fopen ("/tmp/sys_init", "r");
// si l'ouverture s'est bien passée
if (descfic)
{
// lire les caractères jusqu'à trouver un :
do
car = getc (descfic);
while (car != ':' && car != EOF);
// continuer jusqu'à trouver une voyelle minuscule
while (car < 'a' && car != EOF)
car = getc (descfic);
// terminé avec la lecture du fichier
fclose (descfic);
}
// sinon message d'erreur
else
{
affiche_err ("PB_ACCES_TMP");
sleep (2);
}
// test simplifié pour savoir si démarré avec init
// dans tous les autres cas, on considère que démarré avec systemd
resultat = (car != 'i');
// on a détecté le système de démarrage
sysinit = 1;
// on peut supprimer le fichier qui a servi à la détection
unlink ("/tmp/sys_init");
}
// retourner le résultat du test
return (resultat);
#endif
}
/* lecture du clavier en mode raw (caractère par caractère sans écho) */
void mode_raw ()
{
// si libremail compilé seulement pour init ou pour systemd
#ifdef systemd
// exécuter la commande stty la mieux adaptée
#if systemd > 0
system (cmd_mode_raw_systemd);
#else
system (cmd_mode_raw_init);
#endif
// sinon
#else
// selon le système de démarrage détecté, exécuter la bonne commande stty
if (util_systemd ())
system (cmd_mode_raw_systemd);
else
system (cmd_mode_raw_init);
#endif
}
/* lecture du clavier en mode normal (ligne par ligne avec écho) */
void mode_normal ()
{
system (cmd_mode_normal);
}
/* affichage en surbrillance */
void clair ()
{
static char sequence [8] = ""; // séquence de changement de couleur
char *valenv; // contenu de la variable d'environnement libremail_bright
int valcoul; // couleur pour la séquence d'échappement
// si aucune séquence d'échappement déja mémorisée
if (! *sequence)
{
// tenter de récupérer la variable d'environnement libremail_bright
valenv = getenv ("libremail_bright");
// si la variable d'environnement existe
if (valenv)
{
// convertir le contenu de la variable en un numéro de couleur
valcoul = (valenv [0] & 1) + ((valenv [1] & 1) * 2)
+ ((valenv [2] & 1) * 4);
// et générer la séquence d'échappement avec couleur en surbrillance
sprintf (sequence, "%c[%d;1m", ESC, valcoul + 30);
}
else
// sinon générer la séquence d'échappement pour passer surbrillance
sprintf (sequence, "%c[1m", ESC);
}
// envoyer la séquence d'échappement
printf ("%s", sequence);
}
/* affichage en bleu foncé par défaut */
void sombre ()
{
static char sequence [6] = ""; // séquence de changement de couleur
char *valenv; // contenu de la variable d'environnement libremail_dark
int valcoul; // couleur pour la séquence d'échappement
// si aucune séquence d'échappement déja mémorisée
if (! *sequence)
{
// tenter de récupérer la variable d'environnement libremail_dark
valenv = getenv ("libremail_dark");
// si variable d'environnement utilisée
if (valenv)
{
// convertir le contenu de la variable en un numéro de couleur
valcoul = (valenv [0] & 1) + ((valenv [1] & 1) * 2)
+ ((valenv [2] & 1) * 4);
// et générer la séquence d'échappement
sprintf (sequence, "%c[%dm", ESC, valcoul + 30);
}
else
// sinon générer la séquence d'échappement pour passer en bleu foncé
sprintf (sequence, "%c[34m", ESC);
}
// envoyer la séquence d'échappement
printf ("%s", sequence);
}
/* réaffiche la page d'écran courante en tenant
compte du changement de taille de la fenêtre */
void affpage ()
{
int i, j;
// récupérer la taille de la fenêtre (qui peut avoir changé)
lig_col ();
// se positionner en haut d'écran et l'effacer
debpage ();
effpage ();
// réafficher toutes les lignes de la page
while (i++ < lignepage && j < nb_lignes)
{
affligne (j++);
putchar ('\n');
}
// remonter à la ligne sur laquelle on était
while (--i > lignecran)
montecurs ();
}
/* remonte de n lignes (max) dans le texte affiché */
void monte (int n)
{
// limiter le déplacement pour ne pas sortir du texte
if (n > lignecour)
n = lignecour;
// tant qu'on n'est pas en haut de page et déplacement non terminé
while (n > 0 && lignecran > 1)
{
// remonter d'une ligne
montecurs ();
// et mettre à jour les variables
lignecran --;
lignecour --;
n--;
}
// si déplacement de plus d'une page
if (n > lignepage)
{
// on n'affichera pas les lignes intermédiaires
lignecour = lignecour + lignepage - n;
n = lignepage;
}
// tant que déplacement non terminé
while (n-- > 0)
{
// descendre le texte affiché d'une ligne
insligne ();
// et afficher la ligne à rajouter en haut d'écran
affligne (--lignecour);
putchar ('\r');
}
}
/* descend de n lignes (max) dans le texte affiché */
void descend (int n)
{
// limiter le déplacement pour ne pas sortir du texte
if (n > nb_lignes - lignecour - 1)
n = nb_lignes - lignecour - 1;
// tant qu'on n'est pas en bas de page et déplacement non terminé
while (n > 0 && lignecran < lignepage - 1)
{
// descendre d'une ligne
putchar ('\n');
// et mettre à jour les variables
lignecran ++;
lignecour ++;
n--;
}
// si déplacement de plus d'une page
if (n > lignepage)
{
// on n'affichera pas les lignes intermédiaires
lignecour = lignecour + n - lignepage;
n = lignepage;
}
// tant que déplacement non terminé
while (n-- > 0)
{
// afficher la ligne à rajouter en bas de page
// et remonter tout le texte d'une ligne
putchar ('\n');
affligne (++lignecour);
putchar ('\n');
// remonter sur la ligne insérée
montecurs ();
}
}
/* récupère le nombre de lignes et de colonnes d'affichage */
// récupérer les caractéristiques du terminal
sprintf (commande, "stty size > /tmp/fich%X", getpid ());
system (commande);
// ouvrir le fichier créé par la commande stty
fcaract = fopen (commande + 12, "r");
// si ouverture réussie
if (fcaract)
{
// lire le nombre de lignes et de colonnes
fscanf (fcaract, "%d%d", &lignepage, &colonpage);
// fermer et détruire le fichier
fclose (fcaract);
unlink (commande + 12);
}
// cas très particulier : problème de droits d'accès à /tmp
else
{
// message d'avertissement
// "Droit d'accès insuffisants à /tmp, le fonctionnement peut être dégradé"
affiche_msg_nocr ("PB_ACCES_TMP");
attendre (3);
// on prend les valeurs par défaut
lignepage = defaut_ligne;
colonpage = defaut_colon;
}
// corriger avec des valeurs par défaut si l'on a récupéré des 0
// (par exemple depuis une fenêtre telnet)
if (! lignepage)
lignepage = defaut_ligne;
if (! colonpage)
colonpage = defaut_colon;
}
/* lit un caractère au clavier et le traite si caractère spécial */
int leccar ()
{
int car, carsuiv;
// attendre qu'un caractère soit tapé
do
car = getchar ();
while (car == -1);
// si caractère ordinaire, on le retourne
if (car != ESC)
return (car);
// lire le caractère qui suit le ESC
car = getchar ();
// traitement du caractère ESC et des séquences d'échappement
if (car == '[' || car == 'O')
{
car = getchar ();
if ('1' <= car && car <= '9')
{
// séquence ESC[n~ où n est une valeur numérique
carsuiv = getchar ();
car = car & 0x0F;
// récupérer la valeur numérique
while ('0' <= carsuiv && carsuiv <= '9')
{
car = (car * 10) + (carsuiv & 0x0F);
carsuiv = getchar ();
}
if (carsuiv == '~')
return (CARSPE | car);
else
// "Caractère spécial non traité"
affiche_msg ("CARSPE_INVALIDE");
}
else if (car == '[')
{
// séquence ESC[[n (certaines touches de fonction)
car = getchar ();
return (CARSPE + 0x0F + car);
}
else
// séquence ESC[lettre
return (CARSPE | car);
}
// caractère ESC classique
else
{
// si après le ESC on a eu un autre caractère de suite
// le remettre dans le buffer
if (car != -1)
ungetc (car, stdin);
// retour du caractère ESCape
return (ESC);
}
}
/* exécute une commande, puis repasse en mode page */
void execom (char *outil, char *fichier)
{
char commande [130]; // chaine contenant la commande à exécuter
unsigned long heuredeb; // pour détecter problème exécution commandes
// effacer le bas de page
effpage ();
fflush (stdout);
// fabriquer la commande à éxécuter
sprintf (commande, "%s %s", outil, fichier);
// récupérer l'heure courante
heuredeb = time (0);
// lancer la commande
system (commande);
// si la commande a rendu la main trop rapidement
// et que c'est une commande interactive
if ((time (0) <= heuredeb + 1) && (strcmp (outil, "lp") != 0)
&& (strcmp (outil, "recuppj") != 0))
{
// attendre lecture du message d'erreur
montecurs ();
attendre (2);
}
// reconfigurer la voie que commande a remit en mode normal en se terminant
mode_raw ();
}
/* attente en seconde pour l'affichage d'un message qui sera ensuite effacé */