/* 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:
[email protected]
*
*
[email protected] 11/06/93 modifie pour HP-UX
*
[email protected] 08/09/93 modifie pour IRIX
* message fin dvips
*
[email protected] 23/09/93 modifie pour Solaris 2
*
[email protected] 11/08/94 ressource et widget => pilote
*
[email protected] 25/08/94 #define ALPR et ALPQ
*
[email protected] 08/09/94 waitpid sur tous les fils en Solaris 2
* sinon la terminaison de "xterm emacs"
* terminait aussi xlatex !
*
[email protected] 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);
}