1
/* mftalk.c -- generic Metafont window server.
2
Copyright (C) 1994 Ralph Schleicher
3
Slightly modified for Web2c 7.0 by kb@mail.tug.org.
4
Further modifications for Web2C 7.2 by Mathias.Herberts@irisa.fr */
6
/* This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License as
8
published by the Free Software Foundation; either version 2 of
9
the License, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this library; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
/* Please remember the following for porting to UNIX:
24
execve (...); pid = spawnve (mode, ...);
25
else if (pid == -1) if (pid == -1)
28
success (); success ();
30
Spawnve(2) has many different modes and a `session' is indicated by
31
running on an extra terminal. */
44
#include <sys/param.h>
46
extern int close (int);
47
extern int pipe (int *);
48
extern int read (int, void *, size_t);
49
extern int setmode (int, int);
50
extern int write (int, const void *, size_t);
54
#include <kpathsea/variable.h>
57
/* We use SIGCHLD, but fall back on SIGCLD if that's all we have. */
58
#if !defined (SIGCHLD) && defined (SIGCLD)
59
#define SIGCHLD SIGCLD
62
#define fatal(func, cond) do { if (cond) FATAL_PERROR ("perror"); } while (0)
64
static RETSIGTYPE child_died P1H(int sig);
65
static string app_type P2H(char *prog, int *app);
67
static int pid = -1; /* Process ID of our child. */
68
static int win = -1; /* Write handle to the `window'. */
69
static int buf[8]; /* Temporary buffer. */
70
static RETSIGTYPE (*old) (); /* Old signal handler. */
74
mf_mftalk_initscreen P1H(void)
76
int app; /* Client application type. */
77
char *prog, *name; /* Client program name. */
78
/* Size of METAFONT window. */
79
char height[MAX_INT_LENGTH], width[MAX_INT_LENGTH];
80
/* Inherited pipe handles. */
81
char input[MAX_INT_LENGTH], output[MAX_INT_LENGTH];
82
char parent[MAX_INT_LENGTH]; /* My own process ID. */
83
int sc_pipe[2]; /* Server->Client pipe. */
84
int cs_pipe[2]; /* Client->Server pipe. */
85
int res, ack; /* Wait until child is ready. */
87
prog = kpse_var_value ("MFTALK");
91
name = app_type (prog, &app);
95
if (pipe (sc_pipe) == -1)
97
if (pipe (cs_pipe) == -1)
104
fatal (setmode, setmode (sc_pipe[0], O_BINARY) == -1);
105
fatal (setmode, setmode (sc_pipe[1], O_BINARY) == -1);
106
fatal (setmode, setmode (cs_pipe[0], O_BINARY) == -1);
107
fatal (setmode, setmode (cs_pipe[1], O_BINARY) == -1);
110
old = signal (SIGCHLD, child_died);
111
fatal (old, old == SIG_ERR);
113
sprintf (height, "-h%d", screendepth);
114
sprintf (width, "-w%d", screenwidth);
115
sprintf (input, "-i%d", sc_pipe[0]);
116
sprintf (output, "-o%d", cs_pipe[1]);
117
sprintf (parent, "-p%d", getpid ());
120
pid = spawnl (app, name, prog, height, width, input, output, parent, NULL);
125
fatal (close, close (0) == -1);
126
fatal (dup, dup (sc_pipe[0]) != 0);
127
fatal (close, close (sc_pipe[0]) == -1);
128
fatal (close, close (sc_pipe[1]) == -1);
129
fatal (close, close (1) == -1);
130
fatal (dup, dup (cs_pipe[1]) != 1);
131
fatal (close, close (cs_pipe[0]) == -1);
132
fatal (close, close (cs_pipe[1]) == -1);
134
/* We still pass the file handles as parameters for
135
* backward compatibility. instead of sc_pipe[0] and
136
* cs_pipe[1] we just pass 0 (stdin) and 1 (stdout).
139
sprintf (input, "-i0");
140
sprintf (output, "-o1");
142
execl (name, prog, height, width, input, output, parent, NULL);
149
fatal (close, close (sc_pipe[0]) == -1);
150
fatal (close, close (sc_pipe[1]) == -1);
151
fatal (close, close (cs_pipe[0]) == -1);
152
fatal (close, close (cs_pipe[1]) == -1);
153
fatal (signal, signal (SIGCHLD, old) == SIG_ERR);
156
res = read (cs_pipe[0], &ack, sizeof (int));
157
if (res != sizeof (int) || ack != MF_ACK)
159
fatal (close, close (cs_pipe[0]) == -1);
164
return (win == -1) ? 0 : 1;
169
mf_mftalk_updatescreen P1H(void)
172
write (win, buf, sizeof (int));
177
mf_mftalk_blankrectangle P4C(screencol, left,
189
write (win, buf, 6 * sizeof (int));
194
mf_mftalk_paintrow P4C(screenrow, row,
195
pixelcolor, init_color,
196
transspec, transition_vector,
197
screencol, vector_size)
200
buf[1] = init_color == 0 ? MF_WHITE : MF_BLACK;
201
buf[2] = *transition_vector++;
203
buf[4] = --vector_size;
205
write (win, buf, 5 * sizeof (int));
206
write (win, transition_vector, vector_size * sizeof (int));
211
app_type P2C(string, prog, int *, app)
216
res = DosSearchPath (0x02 | 0x01, "PATH", prog, buf, len);
220
res = DosQueryAppType (buf, &app);
224
switch (app & 0x07) /* Quick guess. */
226
case 0x00: return (P_SESSION | P_DEFAULT);
227
case 0x01: return (P_SESSION | P_FULLSCREEN);
228
case 0x02: return (P_SESSION | P_WINDOWED);
229
case 0x03: return (P_PM);
233
*app = 0; /* Irrelevant. */
242
fatal (signal, signal (sig, SIG_ACK) == SIG_ERR);
244
fatal (signal, signal (sig, SIG_IGN) == SIG_ERR);
246
if (pid == -1 || kill (-pid, 0) == 0) /* This was not our child. */
250
fatal (signal, signal (sig, old) == SIG_ERR);
251
fatal (raise, raise (sig) == -1);
253
fatal (signal, signal (sig, child_died) == SIG_ERR);
257
close (win); /* This may fail. */
262
screenstarted = false; /* METAFONT variables. */
265
fatal (signal, signal (sig, old) == SIG_ERR);
269
#else /* !MFTALKWIN */
273
#endif /* !MFTALKWIN */