diff options
Diffstat (limited to 'support/xlatex/xlatex.c')
-rw-r--r-- | support/xlatex/xlatex.c | 1935 |
1 files changed, 1935 insertions, 0 deletions
diff --git a/support/xlatex/xlatex.c b/support/xlatex/xlatex.c new file mode 100644 index 0000000000..b42a0458c2 --- /dev/null +++ b/support/xlatex/xlatex.c @@ -0,0 +1,1935 @@ +/* xlatex.c + * + * xlatex est une application X facilitant l'utilisation des produits de + * composition de texte (tels que TeX et LaTeX) librement distribuable. + * Mario Dragone en a un Copyright (1990). Vous pouvez modifier et + * utiliser ce programme, a condition de lui envoyer les modifications. Il + * peut etre inclus dans toute distribution, commerciale ou non, a + * condition que cette notice et la banniere definie ci-dessous ne soient + * pas modifies (sauf pour le numero de version) et que cette banniere + * soit affichee a l'appel du programme. Toute contribution, correction + * de bogue et commentaires doivent etre envoyes a : + * + * Mario Dragone, IUT Vannes + * rue Montaigne + * BP 1104 + * 56014 Vannes - France + * Tel: 99.46.31.06 + * + * e-mail: dragone@iu-vannes.fr + * + * picheral@univ-rennes1.fr 11/06/93 modifie pour HP-UX + * picheral@univ-rennes1.fr 08/09/93 modifie pour IRIX + * message fin dvips + * decouty@irisa.fr 23/09/93 modifie pour Solaris 2 + * picheral@univ-rennes1.fr 11/08/94 ressource et widget => pilote + * picheral@univ-rennes1.fr 25/08/94 #define ALPR et ALPQ + * picheral@univ-rennes1.fr 08/09/94 waitpid sur tous les fils en Solaris 2 + * sinon la terminaison de "xterm emacs" + * terminait aussi xlatex ! + * picheral@univ-rennes1.fr 08/09/94 LG_NOM mis a 128 au lieu de 32 + * LG_PATH mis a MAXPATHLENGTH au lieu de 128 + */ + +#define VERSION "3.3c" +#define BANNER "xlatex, version %s -- Copyright(c) 1990-1994 CICB\n" + +/************************************************************************ + * Application X concue autour des Athena Widgets pour faciliter + * l'utilisation des commandes associees a TeX et LaTeX. Appel : + * + * xlatex [options] [document] [toolkit_options] + * + * + * L'utilisateur dispose des boutons de commandes: + * + * Faconner faconnage du document courant + * Visionner epreuvage sur ecran + * PostScript production d'un document PostScript + * Imprimer impression du document sur la station courante. Une + * fenetre ``popup'' apparait pour positionner les options + * telles que: + * - commande d'impression et ses arguments + * - station de sortie + * - pages a imprimer + * - nb. de copies + * File d'attente etat de l'imprimante + * Editer session edition de texte + * Quitter fin de l'application + * + * Les champs suivants sont egalement definis: + * + * visionneur utilitaire de visualisation sur ecran du document + * repertoire repertoire courant de travail + * document nom du document (correspond au nom du fichier sans + * suffixe 'tex' + * faconnage utilitaire de faconnage de documents + * editeur editeur de texte + * pilote pilote de conversion en PostScript + * interaction c'est une fenetre 'ascenseur' qui recoit toutes les + * sorties 'ecran' des commandes generees par selection + * des boutons de commande. Elle permet egalement a + * l'utilisateur d'introduire du texte pour notamment + * dialoguer avec la commande latex. + * + * Voici la correspondance 'shell-like' des actions realisees par les boutons de + * commande : + * + * faconner <faconnage> <document> & + * imprimer <pilote> [-p page -n nbpages] [-c copies] + * -o '!<impression> + * -P<imprimante>' <document> & (BSD) + * -d<imprimante>' <document> & (System V) + * visionner <visionneur> <document> & + * file attente lpq -P<imprimante> & (BSD) + * lpstat -o<imprimante> & (System V) + * editeur xterm -e <editeur> <document>.tex & + * + * *************************************************************************** + */ + +/* + * Notes : + * - xlatex est prevu pour utiliser les versions 5.4 et ulterieures de dvips + */ + +/* + * Versions : + * 3.0 03/06/91: premiere version a diffusion restreinte X11R4 + * 3.1 26/06/91: version diffusable + * 3.2 24/09/91: adaptation X11R5, meilleure designation des champs + * et possibilite de deplacement par tabulation + * 3.3 29/01/92: ajout du bouton PostScript et possibilite d'epreuver + * le PostScript si le mode choisi est PostScript + * 3.3a 03/12/92: ajout bouton xfig et amenagements mineurs + * 3.3b 10/12/93: adaptations pour differentes plate-formes + * 3.3c 11/08/94: ajout ressource et widget => pilote + */ + +#include <stdio.h> +#include <errno.h> +#include <signal.h> +#include <search.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <sys/param.h> /* pour MAXPATHLEN */ + +#include <X11/Xos.h> +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#include <X11/Xaw/Command.h> +#include <X11/Xaw/Form.h> +#include <X11/Xaw/AsciiText.h> +#include <X11/Xaw/Label.h> +#include <X11/Xaw/Toggle.h> +#include <X11/Xaw/Dialog.h> +#include <X11/Xaw/SimpleMenu.h> +#include <X11/Xaw/SmeBSB.h> +#include <X11/Xaw/SmeLine.h> +#include <X11/Xaw/MenuButton.h> + +#if (defined(SVR4) || defined(SYSV)) +#include <sys/types.h> +#include <fcntl.h> +#if ! defined(HPUX) && ! defined(AIXV3) && ! defined(IRIX) +#include <sys/filio.h> /* pour FIOREAD */ +#endif +#endif + +#include "icone.h" + +#define LG_NOM 128 +#define LG_FICH MAXPATHLEN +#define LG_CHEMIN MAXPATHLEN +#define DVIPS "dvips" +#if (defined(SVR4) || defined(SYSV)) && ! defined(BSD_COMP) +#define LPR "lp" +#define ALPR "-d" +#define ALPQ "-o" +#define LPQ "lpstat" +#else +#define LPR "lpr" +#define ALPR "-P" +#define ALPQ "-P" +#define LPQ "lpq" +#endif + +#define POINT_INSERTION 999999 + + +#if defined(SVR4) +char *sys_errlist[0230]; +#else +char *sys_errlist[]; +#endif +int errno; + +extern char +#ifndef AIXV3 + *strrchr (), +#endif +#if (defined(SVR4) || defined(SYSV)) && ! defined(IRIX) + *getcwd (), +#else + *getwd (), +#endif + *strtok (), + *getenv (); +extern ENTRY *hsearch (); + + +/* --- STATIQUES ---*/ + +/* + * References en avant + */ + +static XtInputCallbackProc + Procedure_entreeINP (); +static void FaconnerCB (), + VisionnerCB (), + DessinerCB (), + PostScriptCB (), + ImprimerCB (), + StatutCB (), + EditerCB (), + QuitterCB (), + MenuVisionneursCB (), + MenuVisionneursPSCB (), + Toutes_pagesCB (), + De_la_pageCB (), + OkCB (), + AnnulerCB (); +static XtActionProc + FocaliserACT (), + ChampSuivantACT (), + ControlACT (), + InsertACT (), + DeleteACT (), + SendACT (); +static void Connecter_pipes (), + Reinitialiser_fenetre_interaction (), + Supprimer_suffixe_tex (); + +/* + * Implementation des groupes de tabulation des champs de saisie + * Chaque entree du tableau designe un widget et son suivant (chainage boucle) + * Pour acceder a une entree par le nom d'un widget, on utilise la fonction + * de hash-coding hsearch + */ +typedef struct { + char *nom; + int suivant; + Widget wg; +} _groupeT; + +static _groupeT TabGroup[15]; +static int IGroup = 0; +static ENTRY TabElem; + +/* + * Tableau des widgets boutons de commande et leur fonction de CallBack + */ +typedef void (*fptr) (); +typedef struct { + char *nom; + fptr CB; + Widget wg; +} _commandesT; + +static _commandesT Commandes[] = { + {"editer", EditerCB}, + {"dessiner", DessinerCB}, + {"faconner", FaconnerCB}, + {"visionner", VisionnerCB}, + {"postscript", PostScriptCB}, + {"imprimer", ImprimerCB}, + {"statut", StatutCB}, + {"quitter", QuitterCB} +}; + + +/* + * Description des ressources de l'application Xlatex + */ + +typedef struct _AppRessources { + String repertoire_initial, + dessin, + faconneur, + visionneurs, + visionneursPS, + pilote, + impression, + editeur; + Boolean editeur_avec_xterm; + /* ressources maintenues pour compatibilite avec la version anterieure */ + String repertoire; +} RessourcesXlatex; + +static RessourcesXlatex Ressources_xlatex; + +static XtResource Ressources[] = { + {"repertoireInitial", "RepertoireInitial", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, repertoire_initial), XtRString, NULL}, + {"faconneur", "Faconneur", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, faconneur), XtRString, "latex"}, + {"dessin", "Dessin", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, dessin), XtRString, "xfig"}, + {"visionneurs", "Visionneurs", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, visionneurs), XtRString, "*xdvi texx"}, + {"visionneursPS", "VisionneursPS", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, visionneursPS), XtRString, "ghostview gs"}, + {"editeur", "Editeur", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, editeur), XtRString, NULL}, + {"pilote", "Pilote", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, pilote), XtRString, NULL}, + {"impression", "Impression", XtRString, sizeof (String), + XtOffset (RessourcesXlatex *, impression), XtRString, LPR}, + {"editeurAvecXterm", "EditeurAvecXterm", XtRBoolean, sizeof (Boolean), + XtOffset (RessourcesXlatex *, editeur_avec_xterm), XtRString, NULL}, +}; + +static String Ressources_defaut[] = { + NULL, +}; + + +/* + * Table des actions + */ +static XtActionsRec Table_actions[] = { + {"Focaliser", (XtActionProc) FocaliserACT}, + {"ChampSuivant", (XtActionProc) ChampSuivantACT}, + {"Control", (XtActionProc) ControlACT}, + {"Insert", (XtActionProc) InsertACT}, + {"Delete", (XtActionProc) DeleteACT}, + {"Send", (XtActionProc) SendACT}, + {"faconner", (XtActionProc) FaconnerCB}, + {"editer", (XtActionProc) EditerCB}, + {"dessiner", (XtActionProc) DessinerCB}, + {"visionner", (XtActionProc) VisionnerCB}, + {"postscript", (XtActionProc) PostScriptCB}, + {"imprimer", (XtActionProc) ImprimerCB}, + {"statut", (XtActionProc) StatutCB}, + {"quitter", (XtActionProc) QuitterCB}, + {NULL, NULL} +}; + +static Widget Toplevel, + Document_wg, + Imprimer_wg, + Form_wg, + Popup_wg, + Repertoire_wg, + Visionneurs_wg, + Faconneur_wg, + Editeur_wg, + Dessin_wg, + Interaction_wg, + Imprimante_wg, + Impression_wg, + Pilote_wg, + ToutesLab_wg, + DeLab_wg, + De_wg, + ALab_wg, + A_wg, + CopiesLab_wg, + Copies_wg; +Widget Focus = (Widget) NULL; + +XtAppContext Xlatex_app_con; +Display *Dpy; + +static int Pipe_entree[2], + Pipe_sortie[2]; + +static char Faconneur[LG_NOM] = "", + Editeur[LG_NOM] = "", + Dessin[LG_NOM] = "", + Impression[LG_NOM] = "", + Visionneur[LG_NOM] = "", + Document[LG_FICH] = "", + Repertoire[LG_CHEMIN] = "", + Pilote[LG_NOM] = "", + Imprimante[LG_NOM] = ""; +static Boolean PostScript = False; + +static int FaconneurPid = -9999; +static Boolean FaconneurActif = False; +static int ImpressionPid = -9999; +static Boolean ImpressionActive = False; +static int PostScriptPid = -9999; +static Boolean PostScriptActif = False; +static int Pgid; +static char TamponEntree[256] = ""; +static int TamponEntree_lg = 0; + +static Boolean ToutesPages = True, + DeLaPage = False; + +static char PageDebut[5] = "0", + PageFin[5] = "0", + Pages[5] = "0", + Copies[5] = "1"; + +static Pixel CouleurDeBordure, + CouleurDeFond; + +static char *TabArg[15]; + +static char *Visionneurs[10], + *VisionneursPS[10]; + +static char Programme[] = "Xlatex"; + + +/* --- INTERNES --- */ + +#if (defined(SVR4) || defined(SYSV)) + killpg(ProcessGroup, Signal) + int ProcessGroup; + int Signal; +{ +if (ProcessGroup < 0) + { + errno = ESRCH; + return (-1); + } + return (kill(-ProcessGroup, Signal)); + } +#endif + + /************************************************************ + Changer_Repertoire + + - modification de la variable d'environnement PATH + - changement de repertoire + ************************************************************/ + +static int Changer_repertoire (repertoire) +/****************************************/ + char *repertoire; +{ + extern char **environ; + static char **nouvelEnviron = NULL; + static char pwdEnv[256]; + static Boolean nouvelEnvCree = False; + int nbVarEnv; + char **newPtr, + **oldPtr; + + if (nouvelEnvCree == False) { + + /* Enumeration des variables d'environnement */ + for (oldPtr = environ; *oldPtr; oldPtr++); + nbVarEnv = (oldPtr - environ); + + nouvelEnviron = (char **) XtMalloc ((nbVarEnv + 2) * sizeof (char **)); + if (!nouvelEnviron) { + fprintf (stderr, + "%s: echec allocation de %d pointeurs de l'environnement\n", + Programme, nbVarEnv + 2); + exit (1); + } + /* placer PWD=repertoire en premiere position */ + strcpy (pwdEnv, "PWD="); + newPtr = nouvelEnviron; + *newPtr++ = pwdEnv; + + /* copie des autres variables de l'environnement */ + for (oldPtr = environ; *oldPtr; oldPtr++) { + if (strncmp (*oldPtr, "PWD=", 4) != 0) + *newPtr++ = *oldPtr; + } + *newPtr = NULL; + environ = nouvelEnviron; + nouvelEnvCree = True; + } + /* Changement de repertoire */ + strcpy (pwdEnv + 4, repertoire); + return (chdir (repertoire)); +} + + + /************************************************************ + Connecter_pipes + + On se situe dans le cadre d'un processus FILS. + Les organes d'E/S standard sont connectes aux pipes Pipe_entree + et Pipe_sortie : + + 0 recevra les caracteres en provenance du PERE + 1,2 enverront les caracteres au PERE qui activera la procedure + Procedure_entreeINP + + PERE FILS + [1] Pipe_entree [0] == 0 + Procedure_entreeINP [0] Pipe_sortie [1] == 1, 2 + + Ce processus est affilie au 'process group' de son pere ce qui + permet a ce dernier d'envoyer un signal de terminaison a + l'ensemble du groupe en fin d'application + ************************************************************/ + +static void Connecter_pipes () +/****************************************/ +{ + long arg; + char buf[32]; + int len; + + /* + On se situe ici dans le cadre d'un processus qui s'est cree mais avant + qu'il ne realise l'execvp. on connecte 0, 1 et 2 aux pipes d'E/S + */ + dup2 (Pipe_entree[0], 0); + dup2 (Pipe_sortie[1], 1); + dup2 (Pipe_sortie[1], 2); + + close (Pipe_entree[0]); + close (Pipe_entree[1]); + close (Pipe_sortie[0]); + close (Pipe_sortie[1]); + + /* Purge des entrees anticipees */ + ioctl (0, FIONREAD, &arg); +#ifndef IRIX + while (arg > 0) { + len = read (0, buf, sizeof (buf)); + ioctl (0, FIONREAD, &arg); + } +#endif +} + + + /************************************************************ + Afficher + + Affichage d'un message suivi d'un retour a la ligne + dans le widget Interaction. + ************************************************************/ + +static int Afficher (msg) +/****************************************/ + char *msg; +{ + char aLaLigne = '\n'; + XawTextBlock text; + + /* On affiche le message dans la fenetre d'interaction */ + text.firstPos = 0; + text.ptr = msg; + text.format = FMT8BIT; + text.length = strlen (msg); + + XawTextReplace (Interaction_wg, POINT_INSERTION, POINT_INSERTION, &text); + + text.ptr = &aLaLigne; + text.length = 1; + + XawTextReplace (Interaction_wg, POINT_INSERTION, POINT_INSERTION, &text); + XawTextSetInsertionPoint (Interaction_wg, POINT_INSERTION); + + XFlush (Dpy); +} + + + /************************************************************ + Reinitialiser_fenetre_interaction + + Effacement du contenu du widget Interaction, generalement + provoque a chaque faconnage + ************************************************************/ + +static void Reinitialiser_fenetre_interaction () +/****************************************/ +{ + XawTextBlock text; + char car = '\00'; + + text.firstPos = 0; + text.ptr = &car; + text.format = FMT8BIT; + text.length = 0; + + XawTextReplace (Interaction_wg, (XawTextPosition) 0, POINT_INSERTION, &text); + XawTextSetInsertionPoint (Interaction_wg, POINT_INSERTION); +} + + + /************************************************************ + Supprimer_suffixe_tex + + Suppression du suffixe .tex du champ Document. Un suffixe + approprie est ajoute ulterieurement. + ************************************************************/ + +static void Supprimer_suffixe_tex () +/****************************************/ +{ + char *ptex; + if ((ptex = rindex (Document, '.')) == NULL) + return; + if (strcmp (ptex, ".tex") == 0) { + *ptex = '\00'; + XtVaSetValues (Document_wg, XtNstring, Document, NULL); + } +} + + + /************************************************************ + Positionner_arguments + + Analyse une ligne de commande et positionne le tableau + d'arguments TabArg + ************************************************************/ + +static void Positionner_arguments (commande) +/****************************************/ + char *commande; +{ + int i = 0; + TabArg[i] = strtok (commande, " "); + while ((TabArg[++i] = strtok (NULL, " ")) != NULL); +} + + + /************************************************************ + Acquitter_processus + + Reaction au signal de terminaison SIGCHLD. + Dans le cas du processus de faconnage, d'impression et de + generation PoscScript, on memorise et signale + sa terminaison. + ************************************************************/ + +static void Acquitter_processus () +/****************************************/ +{ + int status; + int pid; + +#if defined(SVR4) + while ((pid = waitpid ((pid_t) -1, &status, WNOHANG)) > 0) { +#else +#if defined(SYSV) && ! defined(IRIX) + while ((pid = waitpid ((pid_t) 0, &status, WNOHANG)) > 0) { +#else + while ((pid = wait3 (&status, WNOHANG, 0)) > 0) { +#endif +#endif + if (pid == FaconneurPid) { + char msg[256]; + FaconneurActif = False; + sprintf (msg, "--- Exit %s ---", Faconneur); + Afficher (msg); + } + if (pid == ImpressionPid) { + char msg[256]; + ImpressionActive = False; + sprintf (msg, "--- Exit %s ---", Impression); + Afficher (msg); + } + if (pid == PostScriptPid) { + char msg[256]; + PostScriptActif = False; + sprintf (msg, "--- Exit %s ---", Pilote); + Afficher (msg); + } + } + signal (SIGCHLD, Acquitter_processus); +} + + + /************************************************************ + Initialiser_pipes + + Creation des pipes Pipe_entree et Pipe_sortie + ************************************************************/ + +static void Initialiser_pipes () +/****************************************/ +{ + pipe (Pipe_entree); + pipe (Pipe_sortie); +#if (defined(SVR4) || defined(SYSV)) + fcntl (Pipe_entree[1], F_SETFL, O_NDELAY); + fcntl (Pipe_sortie[0], F_SETFL, O_NDELAY); +#else + fcntl (Pipe_entree[1], F_SETFL, FNDELAY); + fcntl (Pipe_sortie[0], F_SETFL, FNDELAY); +#endif +} + + + /************************************************************ + Initialiser_Xt + + Creation de l'application Xlatex, traitement des ressources + et initialisation de l'environnement de travail + ************************************************************/ + +static void Initialiser_Xt (argc, argv) +/****************************************/ + int argc; + char *argv[]; +{ + char msg[256]; + char titre[256]; + char *rep, + *doc, + *imp, + *edi; + int iv; + char *vp; + + /* Initialisation du processus de hash-coding : on prevoit 15 entrees max */ + hcreate (15); + + /* + Interception du signal de changement d'etat (en l'occurence leur + terminaison) des processus fils pour eviter leur etat <defunct> + */ + signal (SIGCHLD, Acquitter_processus); + + + /* Demarrage de l'application X */ + Toplevel = XtAppInitialize (&Xlatex_app_con, Programme, NULL, + 0, &argc, argv, + Ressources_defaut, NULL, 0); + + Dpy = XtDisplay (Toplevel); + + XtAppAddActions (Xlatex_app_con, Table_actions, XtNumber (Table_actions)); + XtAppAddInput (Xlatex_app_con, Pipe_sortie[0], (XtPointer) XtInputReadMask, + (XtInputCallbackProc) Procedure_entreeINP, NULL); + + /* Obtention des ressources de l'application */ + XtGetApplicationResources (Toplevel, (XtPointer) & Ressources_xlatex, + Ressources, XtNumber (Ressources), NULL, 0); + + /* Fabrication des listes des visionneurs */ + Visionneur[0] = '\0'; + iv = 0; + vp = strtok (Ressources_xlatex.visionneurs, " ,"); + while (vp) { + if (*vp == '*') { + vp++; + strcpy (Visionneur, vp); + PostScript = False; + } + Visionneurs[iv++]=vp; + vp = strtok (NULL, " ,"); + } + iv = 0; + vp = strtok (Ressources_xlatex.visionneursPS, " ,"); + while (vp) { + if (*vp == '*') { + vp++; + strcpy (Visionneur, vp); + PostScript = True; + } + VisionneursPS[iv++]=vp; + vp = strtok (NULL, " ,"); + } + + if (! Visionneur[0]) { + strcpy (Visionneur, Visionneurs[0]); + PostScript = False; + } + + /* Prise en compte des anciens noms de ressources */ + if (Ressources_xlatex.repertoire != NULL) + Ressources_xlatex.repertoire_initial = Ressources_xlatex.repertoire; + + /* Fabrication de l'icone */ + xlatex_bitmap = XCreateBitmapFromData (Dpy, + RootWindow (Dpy, DefaultScreen (Dpy)), + xlatex_bits, xlatex_width, xlatex_height); + sprintf (titre, "%s %s", Programme, VERSION); + XtVaSetValues (Toplevel, + XtNiconPixmap, xlatex_bitmap, + XtNtitle, titre, + NULL); + + /* + Determination du nom du document. S'il est fourni en parametre : son + chemin d'acces est expanse et on en deduit le repertoire et son nom + sinon si la ressource repertoireInitial est positionnee : elle devient + le repertoire courant de travail sinon le repertoire courant est pris + */ + + if (argc > 1) { + doc = strrchr (argv[1], '/'); + if (doc == NULL) + strcpy (Document, argv[1]); + else { + strcpy (Document, doc + 1); + *doc = '\00'; + if (Changer_repertoire (argv[1]) == -1) { + sprintf (msg, "chdir %s", argv[1]); + perror (msg); + exit (1); + } + } + } else { + strcpy (Document, "document"); + if (Ressources_xlatex.repertoire_initial != NULL) { + if (Changer_repertoire (Ressources_xlatex.repertoire_initial) == -1) { + sprintf (msg, "chdir %s", Ressources_xlatex.repertoire_initial); + perror (msg); + exit (1); + } + } + }; +#if (defined(SVR4) ||defined(SYSV)) && ! defined(IRIX) + rep = getcwd (Repertoire, MAXPATHLEN); +#else + rep = getwd (Repertoire); +#endif + + /* + Obtention du nom de l'imprimante et de l'editeur par les variables + d'environnement. + */ +#if (defined(SVR4) || defined(SYSV)) && ! defined(BSD_COMP) + imp = getenv ("LPDEST"); +#else + imp = getenv ("PRINTER"); +#endif + if (imp != NULL) + strcpy (Imprimante, imp); + if (Ressources_xlatex.editeur == NULL) { + edi = getenv ("EDITOR"); + if (edi != NULL) + strcpy (Editeur, edi); + else + strcpy (Editeur, "emacs"); + } else + strcpy (Editeur, Ressources_xlatex.editeur); + if (Ressources_xlatex.pilote != NULL) + strcpy (Pilote, Ressources_xlatex.pilote); + else + strcpy (Pilote, DVIPS); + strcpy (Dessin, Ressources_xlatex.dessin); + strcpy (Faconneur, Ressources_xlatex.faconneur); + strcpy (Impression, Ressources_xlatex.impression); +} + + + + /************************************************************ + Creer_popup_imprimer + + Creation du formulaire d'impression + Creation du groupe secondaire de tabulation pour ce formulaire. + IGroup designe la derniere entree occupee dans TabGroup + ************************************************************/ + +static void Creer_popup_imprimer () +/****************************************/ +{ + Widget form_wg, + impressionLab_wg, + imprimanteLab_wg, + toutesTog_wg, + deTog_wg, + ok_wg, + annuler_wg; + Widget widgets[30]; + Cardinal nwg = 0; + int debut; + + Popup_wg = XtVaCreatePopupShell ("popup", transientShellWidgetClass, Form_wg, NULL); + form_wg = XtVaCreateManagedWidget ("form", formWidgetClass, Popup_wg, NULL); + + widgets[nwg++] = impressionLab_wg = XtVaCreateWidget ("impressionLab", labelWidgetClass, form_wg, + NULL); + + debut = ++IGroup; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "impression"; + TabGroup[IGroup].wg = widgets[nwg++] = Impression_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, form_wg, + XtNstring, Impression, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = imprimanteLab_wg = XtVaCreateWidget ("imprimanteLab", labelWidgetClass, form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "imprimante"; + TabGroup[IGroup].wg = widgets[nwg++] = Imprimante_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, form_wg, + XtNstring, Imprimante, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = toutesTog_wg = XtVaCreateWidget ("toutesTog", toggleWidgetClass, form_wg, + XtNstate, ToutesPages, + NULL); + XtAddCallback (toutesTog_wg, XtNcallback, Toutes_pagesCB, NULL); + + widgets[nwg++] = ToutesLab_wg = XtVaCreateWidget ("toutesLab", labelWidgetClass, form_wg, + XtNsensitive, ToutesPages, + NULL); + + widgets[nwg++] = deTog_wg = XtVaCreateWidget ("deTog", toggleWidgetClass, form_wg, + XtNradioGroup, toutesTog_wg, + XtNstate, DeLaPage, + NULL); + XtAddCallback (deTog_wg, XtNcallback, De_la_pageCB, NULL); + + widgets[nwg++] = DeLab_wg = XtVaCreateWidget ("deLab", labelWidgetClass, form_wg, + XtNsensitive, DeLaPage, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "de"; + TabGroup[IGroup].wg = widgets[nwg++] = De_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, form_wg, + XtNstring, PageDebut, + XtNlength, sizeof (PageDebut), + XtNwidth, 35, + XtNsensitive, DeLaPage, + XtNborderColor, CouleurDeFond, + NULL); + + + widgets[nwg++] = ALab_wg = XtVaCreateWidget ("aLab", labelWidgetClass, form_wg, + XtNsensitive, DeLaPage, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "a"; + TabGroup[IGroup].wg = widgets[nwg++] = A_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, form_wg, + XtNstring, PageFin, + XtNlength, sizeof (PageFin), + XtNwidth, 35, + XtNsensitive, DeLaPage, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = ok_wg = XtVaCreateWidget ("ok", commandWidgetClass, form_wg, + NULL); + + XtAddCallback (ok_wg, XtNcallback, OkCB, NULL); + + widgets[nwg++] = annuler_wg = XtVaCreateWidget ("annuler", commandWidgetClass, form_wg, + NULL); + XtAddCallback (annuler_wg, XtNcallback, AnnulerCB, NULL); + + widgets[nwg++] = CopiesLab_wg = XtVaCreateWidget ("copiesLab", labelWidgetClass, form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = debut; + TabGroup[IGroup].nom = "copies"; + TabGroup[IGroup].wg = widgets[nwg++] = Copies_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, form_wg, + XtNstring, Copies, + XtNlength, sizeof (Copies), + XtNwidth, 35, + XtNborderColor, CouleurDeFond, + NULL); + + XtManageChildren (widgets, nwg); + + + /* Hash-coding du groupe de tabulation cree */ + + { + int i; + for (i=debut; i<= IGroup; i++) { + TabElem.key = TabGroup[i].nom; + TabElem.data= (char *) &TabGroup[i].suivant; + hsearch (TabElem, ENTER); + } + } + +} + + + /************************************************************ + Creer_widgets + + Creation des widgets de l'application Xlatex + Creation du groupe principal de tabulation dans TabGroup + ************************************************************/ + +static void Creer_widgets () +/****************************************/ +{ + Widget repertoireLab_wg, + modeLab_wg, + documentLab_wg, + dessinLab_wg, + visionneursLab_wg, + menuVisionneurs_wg, + faconneurLab_wg, + piloteLab_wg, + editeurLab_wg; + Widget widgets[32]; + WidgetList bouttons; + Widget wg; + int iv, i; + Cardinal nwg = 0; + + Form_wg = XtVaCreateManagedWidget ("form", formWidgetClass, Toplevel, NULL); + + for (i = 0; i < XtNumber (Commandes); i++) { + widgets[nwg++] = Commandes[i].wg = XtVaCreateWidget ( + Commandes[i].nom, commandWidgetClass, Form_wg, + XtNfromHoriz, (i == 0 ? NULL : Commandes[i - 1].wg), + NULL); + XtAddCallback (Commandes[i].wg, XtNcallback, Commandes[i].CB, NULL); + } + widgets[nwg++] = repertoireLab_wg = XtVaCreateWidget ("repertoireLab", labelWidgetClass, Form_wg, + NULL); + IGroup = 0; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "repertoire"; + TabGroup[IGroup].wg = widgets[nwg++] = Repertoire_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, Form_wg, + XtNstring, Repertoire, + XtNlength, LG_CHEMIN, + NULL); + + XtVaGetValues (Repertoire_wg, + XtNbackground, &CouleurDeFond, + XtNborderColor, &CouleurDeBordure, + NULL); + XtVaSetValues (Repertoire_wg, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = dessinLab_wg = XtVaCreateWidget ("dessinLab", labelWidgetClass, Form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "dessin"; + TabGroup[IGroup].wg = widgets[nwg++] = Dessin_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, Form_wg, + XtNstring, Dessin, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = documentLab_wg = XtVaCreateWidget ("documentLab", labelWidgetClass, Form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "document"; + TabGroup[IGroup].wg = widgets[nwg++] = Document_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, Form_wg, + XtNstring, Document, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = visionneursLab_wg = XtVaCreateWidget ("visionneursLab", labelWidgetClass, Form_wg, + NULL); + + widgets[nwg++] = Visionneurs_wg = XtVaCreateManagedWidget ("visionneurs", menuButtonWidgetClass, Form_wg, + XtNmenuName, "menuVisionneurs", + XtNlabel, Visionneur, + NULL); + + menuVisionneurs_wg = XtVaCreatePopupShell ("menuVisionneurs", simpleMenuWidgetClass, Visionneurs_wg, NULL); + + iv = 0; + while (Visionneurs[iv]) { + wg = XtVaCreateManagedWidget (Visionneurs[iv], smeBSBObjectClass, menuVisionneurs_wg, + NULL); + XtAddCallback (wg, XtNcallback, MenuVisionneursCB, (XtPointer) iv); + iv++; + } + XtVaCreateManagedWidget ("separateur", smeLineObjectClass, menuVisionneurs_wg, NULL); + iv = 0; + while (VisionneursPS[iv]) { + wg = XtVaCreateManagedWidget (VisionneursPS[iv], smeBSBObjectClass, menuVisionneurs_wg, + NULL); + XtAddCallback (wg, XtNcallback, MenuVisionneursPSCB, (XtPointer) iv); + iv++; + } + + + widgets[nwg++] = faconneurLab_wg = XtVaCreateWidget ("faconneurLab", labelWidgetClass, Form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "faconneur"; + TabGroup[IGroup].wg = widgets[nwg++] = Faconneur_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, Form_wg, + XtNstring, Faconneur, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = editeurLab_wg = XtVaCreateWidget ("editeurLab", labelWidgetClass, Form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = IGroup + 1; + TabGroup[IGroup].nom = "editeur"; + TabGroup[IGroup].wg = widgets[nwg++] = Editeur_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, Form_wg, + XtNstring, Editeur, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = piloteLab_wg = XtVaCreateWidget ("piloteLab", labelWidgetClass, Form_wg, + NULL); + + IGroup++; + TabGroup[IGroup].suivant = 0; + TabGroup[IGroup].nom = "pilote"; + TabGroup[IGroup].wg = widgets[nwg++] = Pilote_wg = XtVaCreateWidget (TabGroup[IGroup].nom, asciiTextWidgetClass, Form_wg, + XtNstring, Pilote, + XtNlength, LG_NOM, + XtNborderColor, CouleurDeFond, + NULL); + + widgets[nwg++] = Interaction_wg = XtVaCreateWidget ("interaction", asciiTextWidgetClass, Form_wg, + XtNtop, XtChainTop, + XtNright, XtChainRight, + XtNleft, XtChainLeft, + XtNbottom, XtChainBottom, + XtNuseStringInPlace, False, + NULL); + + XtManageChildren (widgets, nwg); + + /* Ajustement de la taille de la fenetre d'interaction */ + + { + Dimension largeur; + XFontStruct *police; + XtVaGetValues (Interaction_wg, XtNfont, &police, NULL); + largeur = (police->max_bounds.width + police->min_bounds.width) / 2; + XtVaSetValues (Interaction_wg, XtNwidth, largeur * 80 + 05, + XtNheight, (police->max_bounds.ascent + police->max_bounds.descent) * 20 + 10, + NULL); + } + + Supprimer_suffixe_tex (); + + /* Hash-coding du groupe de tabulation */ + + { + int i; + for (i=0; i<= IGroup; i++) { + TabElem.key = TabGroup[i].nom; + TabElem.data= (char *) &TabGroup[i].suivant; + hsearch (TabElem, ENTER); + } + } + + Focus = Repertoire_wg; +} + + + /************************************************************ + Installer_accelerateurs + + Mise en place des accelerateurs + ************************************************************/ + +static void Installer_accelerateurs () +/****************************************/ +{ + XtInstallAllAccelerators (Toplevel, Toplevel); + XtInstallAllAccelerators (Repertoire_wg, Toplevel); + XtInstallAllAccelerators (Document_wg, Toplevel); + XtInstallAllAccelerators (Visionneurs_wg, Toplevel); + XtInstallAllAccelerators (Dessin_wg, Toplevel); + XtInstallAllAccelerators (Faconneur_wg, Toplevel); + XtInstallAllAccelerators (Pilote_wg, Toplevel); + XtInstallAllAccelerators (Editeur_wg, Toplevel); + XtInstallAllAccelerators (Interaction_wg, Toplevel); + XtInstallAllAccelerators (Imprimante_wg, Toplevel); + XtInstallAllAccelerators (Impression_wg, Toplevel); +} + + +/* --- INPUT READ PROCEDURE --- */ + + /************************************************************ + Procedure_entreeINP + + Procedure activee lors de la presence de caracteres dans le + pipe Pipe_sortie[0]. + ************************************************************/ + +static XtInputCallbackProc Procedure_entreeINP (cd, s, id) +/****************************************/ + caddr_t cd; + int *s; + XtInputId *id; +{ + char tamp[100]; + XawTextBlock text; + + text.firstPos = 0; + text.ptr = tamp; + text.format = FMT8BIT; + + /* Boucle de transfert */ + while ((text.length = read (*s, tamp, sizeof (tamp))) > 0) + XawTextReplace (Interaction_wg, POINT_INSERTION, POINT_INSERTION, &text); + + XawTextSetInsertionPoint (Interaction_wg, POINT_INSERTION); + + return (0); +} + + +/* --- CALLBACKS --- */ + + /************************************************************ + OkCB + + Confirmation de l'impression. La commande d'impression est + preparee puis executee. + ************************************************************/ + +static void OkCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + int pd; + int pf; + int cp; + int etat; + char msg[256]; + + /* Calcul du nombre de pages a sortir dans Pages */ + pd = atoi (PageDebut); + pf = atoi (PageFin); + + sprintf (Pages, "%d", (pf - pd) + 1); + + if (DeLaPage == True) + if (pd > pf) { + Afficher ("Mauvais parametres de pages. DEB > FIN !"); + return; + } + cp = atoi (Copies); + if (cp < 1) { + Afficher ("Nombre de copies errone !"); + return; + } + if (Changer_repertoire (Repertoire) == -1) { + sprintf (msg, "%s: %s", Repertoire, sys_errlist[errno]); + Afficher (msg); + return; + } + Reinitialiser_fenetre_interaction (); + Supprimer_suffixe_tex (); + if (DeLaPage == True) + if (cp > 1) + sprintf (msg, "%s -c %s -p %s -n %s -o '!%s %s%s' %s", Pilote, + Copies, PageDebut, Pages, Impression, ALPR, + Imprimante, Document); + else + sprintf (msg, "%s -p %s -n %s -o '!%s %s%s' %s", Pilote, PageDebut, + Pages, Impression, ALPR, Imprimante, Document); + else + if (cp > 1) + sprintf (msg, "%s -c %s -o '!%s %s%s' %s", Pilote, Copies, + Impression, ALPR, Imprimante, Document); + else + sprintf (msg, "%s -o '!%s %s%s' %s", Pilote, Impression, + ALPR, Imprimante, Document); + Afficher (msg); + ImpressionActive = True; + if ((ImpressionPid = fork ()) == 0) { + sprintf (msg, "!%s %s%s", Impression, ALPR, Imprimante); + Connecter_pipes (); + if (DeLaPage == True) + if (cp > 1) + etat = execlp (Pilote, Pilote, "-c", Copies, "-p", PageDebut, + "-n", Pages, "-o", msg, Document, '\00'); + else + etat = execlp (Pilote, Pilote, "-p", PageDebut, + "-n", Pages, "-o", msg, Document, '\00'); + else + if (cp > 1) + etat = execlp (Pilote, Pilote, "-c", Copies, "-o", msg, Document, + '\00'); + else + etat = execlp (Pilote, Pilote, "-o", msg, Document, '\00'); + if (etat == -1) { + printf ("%s est inaccessible.\n", Pilote); + exit (-1); + } + } + else if (ImpressionPid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + ImpressionActive = False; + } + XtPopdown (Popup_wg); +} + + + /************************************************************ + MenuVisionneursCB + + Selection d'un visionneur + ************************************************************/ + +static void MenuVisionneursCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + int iv = (int) client_data; + strcpy (Visionneur, Visionneurs[iv]); + PostScript = False; + XtVaSetValues (Visionneurs_wg, XtNlabel, Visionneur, NULL); +} + + + /************************************************************ + MenuVisionneursPSCB + + Selection d'un visionneur PostScript + ************************************************************/ + +static void MenuVisionneursPSCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + int iv = (int) client_data; + strcpy (Visionneur, VisionneursPS[iv]); + PostScript = True; + XtVaSetValues (Visionneurs_wg, XtNlabel, Visionneur, NULL); +} + + + /************************************************************ + AnnulerCB + + Abandon de l'impression + ************************************************************/ + +static void AnnulerCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + XtPopdown (Popup_wg); +} + + + /************************************************************ + De_la_pageCB + + Selection de l'option 'de la page nn a mm', desensibilisation + de l'option 'toutes les pages' + ************************************************************/ + +static void De_la_pageCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + Boolean etat; + + XtVaGetValues (w, XtNstate, &etat, NULL); + if (etat == True) { + DeLaPage = True; + XtVaSetValues (DeLab_wg, XtNsensitive, True, NULL); + XtVaSetValues (De_wg, XtNsensitive, True, NULL); + XtVaSetValues (ALab_wg, XtNsensitive, True, NULL); + XtVaSetValues (A_wg, XtNsensitive, True, NULL); + } else { + DeLaPage = False; + XtVaSetValues (DeLab_wg, XtNsensitive, False, NULL); + XtVaSetValues (De_wg, XtNsensitive, False, NULL); + XtVaSetValues (ALab_wg, XtNsensitive, False, NULL); + XtVaSetValues (A_wg, XtNsensitive, False, NULL); + } +} + + + /************************************************************ + Toutes_pagesCB + + Selection de l'option 'toutes les pages' et desensibilisation + de l'option 'de la page nn a mm' + ************************************************************/ + +static void Toutes_pagesCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + Boolean etat; + + XtVaGetValues (w, XtNstate, &etat, NULL); + if (etat == True) { + ToutesPages = True; + XtVaSetValues (ToutesLab_wg, XtNsensitive, True, NULL); + } else { + ToutesPages = False; + XtVaSetValues (ToutesLab_wg, XtNsensitive, False, NULL); + } +} + + + /************************************************************ + ImprimerCB + + Apparition du formulaire d'impression + ************************************************************/ + +static void ImprimerCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + Position x, + y; + Dimension largeur, + hauteur; + + /* Calcul des coordonnees en fonction de celles de l'application */ + XtVaGetValues (Toplevel, + XtNwidth, &largeur, + XtNheight, &hauteur, + NULL); + XtTranslateCoords (Form_wg, (Position) (largeur / 3), (Position) (hauteur / 3), &x, &y); + + XtVaSetValues (Popup_wg, + XtNx, x, + XtNy, y, + NULL); + + XtPopup (Popup_wg, XtGrabNone); + XRaiseWindow (Dpy, XtWindow (Popup_wg)); +} + + + /************************************************************ + VisionnerCB + + Execution de la commande de visionnage + ************************************************************/ + +static void VisionnerCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + char msg[255]; + int pid; + + if (Changer_repertoire (Repertoire) == -1) { + sprintf (msg, "%s: %s", Repertoire, sys_errlist[errno]); + Afficher (msg); + return; + } + Supprimer_suffixe_tex (); + if (PostScript == True) { + struct stat dvi, + ps; + char fdvi[LG_CHEMIN], + fps[LG_CHEMIN]; + sprintf (fdvi, "%s.dvi", Document); + sprintf (fps , "%s.ps" , Document); + if (stat (fdvi, &dvi) == 0) { + if (stat (fps, &ps) == 0) { + if (dvi.st_mtime > ps.st_mtime) { + sprintf (msg, "PSST !! %s.ps n'est pas a jour ..."); + Afficher (msg); + } + } + } + sprintf (msg, "%s %s.ps", Visionneur, Document); + } + else + sprintf (msg, "%s %s.dvi", Visionneur, Document); + Afficher (msg); + Positionner_arguments (msg); + if ((pid = fork ()) == 0) { + Connecter_pipes (); + if (execvp (TabArg[0], TabArg) == -1) { + printf ("%s n'a pas marche.\n", msg); + exit (-1); + } + + } + else if (pid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + } +} + + + /************************************************************ + DessinerCB + + Execution de la commande de dessin + ************************************************************/ + +static void DessinerCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + char msg[255]; + int pid; + + if (Changer_repertoire (Repertoire) == -1) { + sprintf (msg, "%s: %s", Repertoire, sys_errlist[errno]); + Afficher (msg); + return; + } + sprintf (msg, "%s", Dessin); + Afficher (msg); + Positionner_arguments (msg); + if ((pid = fork ()) == 0) { + Connecter_pipes (); + if (execvp (TabArg[0], TabArg) == -1) { + printf ("%s n'a pas marche.\n", msg); + exit (-1); + } + + } + else if (pid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + } +} + + + /************************************************************ + PostScriptCB + + Production d'un document PostScript + ************************************************************/ + +static void PostScriptCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + char msg[255]; + + if (Changer_repertoire (Repertoire) == -1) { + sprintf (msg, "%s: %s", Repertoire, sys_errlist[errno]); + Afficher (msg); + return; + } + if (PostScriptActif == True) { + sprintf (msg, "%s (PID=%d) encore actif !", Pilote, PostScriptPid); + Afficher (msg); + return; + } + Supprimer_suffixe_tex (); + sprintf (msg, "%s -o %s.ps %s", Pilote, Document, Document); + Afficher (msg); + Positionner_arguments (msg); + PostScriptActif = True; + if ((PostScriptPid = fork ()) == 0) { + Connecter_pipes (); + if (execvp (TabArg[0], TabArg) == -1) { + printf ("%s n'a pas marche.\n", msg); + exit (-1); + } + + } + else if (PostScriptPid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + PostScriptActif = False; + } +} + + + /************************************************************ + FaconnerCB + + Execution de la commande de faconnage. Plusieurs processus + pouvant etre lances, un groupe de processus est cree + permettant d'agir globalement avec les signaux + ************************************************************/ + +static void FaconnerCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + char msg[255]; + + if (Changer_repertoire (Repertoire) == -1) { + sprintf (msg, "%s: %s", Repertoire, sys_errlist[errno]); + Afficher (msg); + return; + } + if (FaconneurActif == True) { + sprintf (msg, "%s (PID=%d) encore actif !", Faconneur, FaconneurPid); + Afficher (msg); + return; + } + Reinitialiser_fenetre_interaction (); + Supprimer_suffixe_tex (); + sprintf (msg, "%s %s", Faconneur, Document); + Afficher (msg); + Positionner_arguments (msg); + FaconneurActif = True; + if ((FaconneurPid = fork ()) == 0) { + Connecter_pipes (); + if (execvp (TabArg[0], TabArg) == -1) { + printf ("%s est inaccessible.\n", Faconneur); + exit (-1); + } + } + else if (FaconneurPid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + FaconneurActif = False; + } +} + + + /************************************************************ + StatutCB + + Interrogation de la file d'attente de l'imprimante + ************************************************************/ + +static void StatutCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + int pid; + char msg[255], + arg[255]; + + sprintf (msg, "%s %s%s", LPQ, ALPQ, Imprimante); + Afficher (msg); + + sprintf (arg, "%s%s", ALPQ, Imprimante); + + if ((pid = fork ()) == 0) { + Connecter_pipes (); + if (execlp (LPQ, LPQ, arg, '\00') == -1) { + printf ("%s: %s.\n", msg, sys_errlist[errno]); + exit (-1); + } + } + else if (pid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + } +} + + + /************************************************************ + EditerCB + + Execution de la commande d'edition de texte + ************************************************************/ + +static void EditerCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + char msg[255]; + int pid; + + if (Changer_repertoire (Repertoire) == -1) { + sprintf (msg, "%s: %s", Repertoire, sys_errlist[errno]); + Afficher (msg); + return; + } + Supprimer_suffixe_tex (); + if (Ressources_xlatex.editeur_avec_xterm == True) + sprintf (msg, "xterm -e %s %s.tex", Editeur, Document); + else + sprintf (msg, "%s %s.tex", Editeur, Document); + Afficher (msg); + Positionner_arguments (msg); + if ((pid = fork ()) == 0) { + Connecter_pipes (); + if (execvp (TabArg[0], TabArg) == -1) { + printf ("%s: %s.\n", msg, sys_errlist[errno]); + exit (-1); + } + } + else if (pid == -1) { + sprintf (msg, "fork: %s", sys_errlist[errno]); + Afficher (msg); + } +} + + + /************************************************************ + QuitterCB + + Fin de l'application Xlatex. + Tous les processus lances encore actifs sont termines. + ************************************************************/ + +static void QuitterCB (w, client_data, call_data) +/****************************************/ + Widget w; + XtPointer client_data, + call_data; +{ + signal (SIGTERM, SIG_IGN); + killpg (Pgid, SIGTERM); + XtDestroyWidget (Toplevel); + exit (0); +} + +/* --- ACTIONS --- */ + + /************************************************************ + FocaliserACT + + Entree de la souris dans un champ d'entree de texte. + Demarquage du pourtour du champ precedent + Marquage du pourtour du champ courant + Positionnement du focus + ************************************************************/ + +static XtActionProc FocaliserACT (wg, event, params, num_params) +/****************************************/ + Widget wg; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (XtIsSensitive(wg)) { + XtVaSetValues (Focus, XtNborderColor, CouleurDeFond, NULL); + if (*num_params == 0) { + XtVaSetValues (wg, XtNborderColor, CouleurDeBordure, NULL); + Focus = wg; + } + XtSetKeyboardFocus (XtParent (wg), wg); + } + else + ChampSuivantACT(wg, event, params, num_params); + + return (0); +} + + + /************************************************************ + ChampSuivantACT + + Recherche du champ suivant dans le groupe de tabulation + Une fois trouve, focalisation sur celui-ci + ************************************************************/ + +static XtActionProc ChampSuivantACT (wg, event, params, num_params) +/****************************************/ + Widget wg; + XEvent *event; + String *params; + Cardinal *num_params; +{ + ENTRY elem, + *elem_cherche; + char *nom; + int i; + + nom = XtName(wg); + elem.key=nom; + elem_cherche=hsearch(elem,FIND); + i = *(int *)elem_cherche->data; + FocaliserACT (TabGroup[i].wg,event,params,num_params); + return (0); +} + + + /*********************************************************** + ControlACT + + Entree d'une sequence d'interruption. + ^C -> envoi du signal SIGINT aux processus de faconnage + ^D -> envoi du signal SIGTERM aux processus de faconnage + ************************************************************/ + +static XtActionProc ControlACT (wg, event, params, num_params) +/****************************************/ + Widget wg; + XKeyEvent *event; + String *params; + Cardinal *num_params; +{ + char car; + int lg; + + /* Obtention du caractere frappe */ + lg = XLookupString (event, &car, 1, NULL, NULL); + + switch (car) { + case 3: /* Ctrl-C */ + kill (FaconneurPid, SIGINT); + break; + case 4: /* Ctrl-D */ + kill (FaconneurPid, SIGTERM); + break; + } + + TamponEntree_lg = 0; + XawTextSetInsertionPoint (Interaction_wg, POINT_INSERTION); + + return (0); +} + + + /************************************************************ + InsertACT + + Entree d'un caractere dans la fenetre d'interaction. + Le caractere est memorise dans le tampon TamponEntree + ************************************************************/ + +static XtActionProc InsertACT (wg, event, params, num_params) +/****************************************/ + Widget wg; + XKeyEvent *event; + String *params; + Cardinal *num_params; +{ + char str[32]; + int lg; + register int i; + + /* Obtention des caracteres frappes */ + lg = XLookupString (event, str, sizeof (str), NULL, NULL); + + strncat (TamponEntree, str, lg); + TamponEntree_lg += lg; + + XawTextSetInsertionPoint (Interaction_wg, POINT_INSERTION); + + return (0); +} + + + /************************************************************ + DeleteACT + + Correction de frappe dans la fenetre d'interaction. + Le tampon TamponEntree est mis a jour. + ************************************************************/ + +static XtActionProc DeleteACT (wg, event, params, num_params) +/****************************************/ + Widget wg; + XEvent *event; + String *params; + Cardinal *num_params; +{ + /* + On veille a ne pas corriger au dela des caracteres precedemment + introduits. + */ + if (TamponEntree_lg > 0) + TamponEntree[--TamponEntree_lg] = '\00'; + + return (0); +} + + + /************************************************************ + SendACT + + Frappe d'un retour a la ligne dans la fenetre d'interaction. + Le contenu du tampon TamponEntree est envoye dans le pipe + Pipe_entree[1]. + ************************************************************/ + +static XtActionProc SendACT (wg, event, params, num_params) +/****************************************/ + Widget wg; + XEvent *event; + String *params; + Cardinal *num_params; +{ + /* Envoi de la commande */ + strcat (TamponEntree, "\n"); + TamponEntree_lg++; + + (void) write (Pipe_entree[1], TamponEntree, TamponEntree_lg); + + /* + Reinitialisation de TamponEntree et mise a jour de la position dans la + fenetre d'interaction + */ + TamponEntree[0] = '\00'; + TamponEntree_lg = 0; + + return (0); +} + + +/* + * --------------------------------------------------------------------------- + * PROGRAMME PRINCIPAL + * --------------------------------------------------------------------------- + */ +main (argc, argv) +/****************************************/ + int argc; + char *argv[]; +{ +/* fprintf (stderr, BANNER, VERSION);*/ + + if ((Pgid = fork ())) + exit (0); + +/* + * La, c'est un peu galere ! Il faut assurer que ce processus est leader + * du groupe qu'il va dominer + * Sur Sun (SunOS 4.x), setsid() ou setpgrp(0,0) serait tout indique ... + */ + +#ifdef gould + setpgrp (0, Pgid); +#else + setsid (); +#endif /* gould */ + + Initialiser_pipes (); + Initialiser_Xt (argc, argv); + + Creer_widgets (); + Creer_popup_imprimer (); + + Installer_accelerateurs (); + + XtRealizeWidget (Toplevel); + + XtAppMainLoop (Xlatex_app_con); +} |