/* 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 & * imprimer [-p page -n nbpages] [-c copies] * -o '! * -P' & (BSD) * -d' & (System V) * visionner & * file attente lpq -P & (BSD) * lpstat -o & (System V) * editeur xterm -e .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 #include #include #include #include #include #include #include #include /* pour MAXPATHLEN */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if (defined(SVR4) || defined(SYSV)) #include #include #if ! defined(HPUX) && ! defined(AIXV3) && ! defined(IRIX) #include /* 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 */ 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); }