summaryrefslogtreecommitdiff
path: root/Build/source/texk/xdvik/psgs.c
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/xdvik/psgs.c
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/xdvik/psgs.c')
-rw-r--r--Build/source/texk/xdvik/psgs.c1085
1 files changed, 0 insertions, 1085 deletions
diff --git a/Build/source/texk/xdvik/psgs.c b/Build/source/texk/xdvik/psgs.c
deleted file mode 100644
index 4d82c5182cb..00000000000
--- a/Build/source/texk/xdvik/psgs.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-/*========================================================================*\
-
-Copyright (c) 1994-2019 Paul Vojta
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-\*========================================================================*/
-
-#ifdef PS_GS /* entire file */
-
-
-#include "xdvi-config.h"
-#include "xdvi.h"
-#include "psgs.h"
-
-#include <setjmp.h>
-#include <X11/Xatom.h>
-#include <sys/time.h> /* for timeval */
-
-#include <signal.h>
-
-/* Condition for retrying a write */
-#include <errno.h>
-#include <string.h>
-
-#include "kpathsea/c-pathmx.h"
-#include "dvi-init.h"
-#include "dvi-draw.h"
-#include "events.h"
-#include "statusline.h"
-#include "special.h"
-#include "util.h"
-
-
-#ifdef X_NOT_STDC_ENV
-extern int errno;
-#endif
-
-#ifdef EWOULDBLOCK
-# ifdef EAGAIN
-# define AGAIN_CONDITION (errno == EWOULDBLOCK || errno == EAGAIN)
-# else
-# define AGAIN_CONDITION (errno == EWOULDBLOCK)
-# endif
-#else
-# ifdef EAGAIN
-# define AGAIN_CONDITION (errno == EAGAIN)
-# endif
-#endif
-
-#if HAVE_POLL
-# include <poll.h>
-# define XIO_IN POLLIN
-# define XIO_OUT POLLOUT
-#else
-# define XIO_IN 1
-# define XIO_OUT 2
-#endif
-
-#ifdef MOTIF
-# include <Xm/Xm.h>
-#endif
-
-extern const char psheader[];
-extern unsigned psheaderlen;
-
-Boolean gs_postpone_prescan = False;
-
-/* global procedures (besides initGS) */
-
-static void toggle_gs(int flag);
-static void destroy_gs(void);
-static void interrupt_gs(void);
-static void endpage_gs(void);
-static void drawbegin_gs(int, int, const char *);
-static void drawbegin_gs_box(int, int, const char *);
-void drawraw_gs(const char *);
-static void drawfile_gs(const char *, FILE *);
-static void drawend_gs(const char *);
-static void beginheader_gs(void);
-static void endheader_gs(void);
-static void newdoc_gs(void);
-
-static struct psprocs gs_procs = {
- /* toggle */ toggle_gs,
- /* destroy */ destroy_gs,
- /* interrupt */ interrupt_gs,
- /* endpage */ endpage_gs,
- /* drawbegin */ drawbegin_gs,
- /* drawraw */ drawraw_gs,
- /* drawfile */ drawfile_gs,
- /* drawend */ drawend_gs,
- /* beginheader */ beginheader_gs,
- /* endheader */ endheader_gs,
- /* newdoc */ newdoc_gs
-};
-
-static int std_io[2];
-Pixmap bpixmap;
-
-#define GS_fd (std_io[0])
-
-/* some arguments are filled in later */
-static char arg4[] = "-dDEVICEWIDTH=xxxxxxxxxx";
-static char arg5[] = "-dDEVICEHEIGHT=xxxxxxxxxx";
-
-static const char *argv[] = {
- NULL, NULL, "-dNOPAUSE", "-q", arg4, arg5,
- "-dDEVICEXRESOLUTION=72",
- "-dDEVICEYRESOLUTION=72",
- "-dNOSAFER", "-dNOEPS", NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-static unsigned int GS_page_w; /* how big our current page is */
-static unsigned int GS_page_h;
-static Boolean GS_alpha; /* remember if we are using the alpha driver */
-static unsigned long GS_mag; /* magnification currently in use */
-static int GS_shrink; /* shrink factor currently in use */
-static Boolean GS_active; /* if we've started a page yet */
-static int GS_pending; /* number of ack's we're expecting */
-static char GS_outb[257]; /* circular output buffer */
-static char *GS_outb_in; /* next position in output buffer */
-static char *GS_outb_out; /* next byte to come out of buffer */
-#define GS_outb_limit (GS_outb + sizeof GS_outb) /* last+1 byte */
-static int GS_write_ack; /* flag to set when done writing */
-static Boolean GS_in_header; /* if we're sending a header */
-static Boolean GS_in_doc; /* if we've sent header information */
-static Boolean GS_page_dirty = False; /* if we've drawn since last erase */
-static int GS_ev_mask; /* events for which we'll stop */
-static int GS_die_ack = 0; /* flags to set when GS dies */
-static Boolean GS_timer_set; /* if there's a timer set */
-
-#define GS_MASK_NORMAL EV_GE_NEWPAGE
-#define GS_MASK_HEADER EV_GE_PS_TOGGLE
-#define GS_MASK_INIT (EV_GE_TERM | EV_PS_TOGGLE)
-
-static Atom gs_atom;
-static Atom gs_colors_atom;
-
-#define Landscape 90
-
-#define LINELEN 81
-static char line[LINELEN + 1];
-static char *linepos = line;
-static char ackstr[] = "\347\310\376";
-
-static void gs_died(int, struct xchild *);
-
-static char *read_from_gs(int, void *);
-static void write_to_gs(int, void *);
-
-static struct xio gs_xio = {NULL, 0, XIO_IN,
-#if HAVE_POLL
- NULL,
-#endif
- read_from_gs, write_to_gs,
- NULL /* data */
-};
-
-static struct xchild gs_child = { NULL, 0, NULL, NULL, NULL, SIGKILL, gs_died };
-#define GS_pid (gs_child.pid)
-
-/* It seems that XtTimers don't work reliably with xdvi's event treatment;
- so use custom timers for the time being. Search for TIMER_PROBLEM_FIXED
- to locate the relevant code parts.
-*/
-
-#if TIMER_PROBLEM_FIXED
-static XtIntervalId gs_timeout_id = 0;
-static void gs_timer_proc(XtPointer client_data, XtIntervalId * id);
-static struct xtimer gs_timer = {NULL, {0, 0}, gs_timer_proc, NULL
-#if XDVI_XT_TIMER_HACK
- , NULL, NULL
-#endif
-};
-
-#else
-static void gs_alarm(struct xtimer *this, void *data);
-static struct xtimer gs_timer = {NULL, {0, 0}, XTM_DEFAULT, gs_alarm, NULL
-#if XDVI_XT_TIMER_HACK
- , NULL, NULL
-#endif
-};
-#endif
-
-
-static void
-showto(char *q)
-{
- char *p = line;
- char *p1;
-
- while (p < q) {
- p1 = memchr(p, '\n', q - p);
- if (p1 == NULL)
- p1 = q;
- *p1 = '\0';
- printf("gs: %s\n", p);
- p = p1 + 1;
- }
-}
-
-static char *
-read_from_gs(int fd, void *data)
-{
- int bytes;
- char *line_end = NULL;
- char *p;
-
- UNUSED(data);
-
- for (;;) {
-
- bytes = read(fd, linepos, line + LINELEN - linepos);
- if (bytes < 0) {
- if (AGAIN_CONDITION)
- break;
- perror("xdvik: read_from_gs");
- break;
- }
- line_end = linepos + bytes;
-
- if (bytes == 0) {
- if (GS_pid != 0)
- XDVI_WARNING((stderr, "Read_from_gs returned 0 bytes"));
- break;
- }
-
- /* Check for ack strings */
- for (p = line; p < line_end - 2; ++p) {
- p = memchr(p, '\347', line_end - p - 2);
- if (p == NULL) break;
- if (memcmp(p, ackstr, 3) == 0) {
- --GS_pending;
- if (GS_pending == 0)
- globals.ev.flags |= EV_ACK;
- if (globals.debug & DBG_PS)
- printf("Got GS ack; %d pending.\n", GS_pending);
- } else
- continue;
-
- showto(p);
- p += 3;
- memmove(line, p, line_end - p);
- line_end -= p - line;
- linepos = p = line;
- --p;
- }
- *line_end = '\0';
- p = strrchr(linepos, '\n');
- if (p != NULL) {
- ++p;
- showto(p);
- memmove(line, p, line_end - p);
- line_end -= p - line;
- }
- linepos = line_end;
- /*
- * Normally we'd hold text until a newline character, but the
- * buffer is full. So we flush it, being careful not to cut up an
- * ack string.
- */
- if (linepos >= line + LINELEN) {
- p = line + LINELEN;
- if ((*--p != '\347' && *--p != '\347' && *--p != '\347')
- || memcmp(p, ackstr, line + LINELEN - p) != 0)
- p = line + LINELEN;
- *p = '\0';
- printf("gs: %s\n", line);
- *p = '\347';
- linepos = line;
- while (p < line + LINELEN)
- *linepos++ = *p++;
- }
- }
- return line_end; /* dummy */
-}
-
-static void
-write_to_gs(int fd, void *data)
-{
- char *send_end;
- int bytes;
-
- UNUSED(fd);
- UNUSED(data);
-
- for (;;) {
- send_end = GS_outb_in;
- if (send_end < GS_outb_out)
- send_end = GS_outb_limit;
- bytes = write(GS_fd, GS_outb_out, send_end - GS_outb_out);
-
- if (bytes < 0) {
- if (AGAIN_CONDITION)
- break;
- perror("xdvik: write_to_gs");
- break;
- }
-
- GS_outb_out += bytes;
- if (GS_outb_out == GS_outb_limit)
- GS_outb_out = GS_outb;
- if (GS_outb_out == GS_outb_in) { /* if buffer is empty */
- gs_xio.xio_events = XIO_IN;
-#if HAVE_POLL
- if (gs_xio.pfd != NULL) /* write_to_gs is called directly */
- gs_xio.pfd->events = XIO_IN;
-#endif
- break;
- }
- }
- globals.ev.flags |= GS_write_ack;
- GS_write_ack = 0;
-}
-
-/*
- * Main routine for writing to the GS interpreter.
- */
-
-static void
-gs_send(const char *cp, size_t len)
-{
- const char *cp_end = cp + len;
- char *send_end;
- size_t bytes;
- char *old_out;
- Boolean interrupting;
-
- if (GS_pid == 0 || (globals.ev.flags & GS_ev_mask))
- return;
-
- /*
- * Because cp might reside on the stack, don't return until we've
- * copied all of it to our circular output buffer.
- * Note that GS_outb_out == GS_outb_in means that the buffer is empty.
- */
-
- GS_timer_set = interrupting = False;
- for (;;) {
- send_end = GS_outb_out;
- if (send_end == GS_outb)
- send_end = GS_outb_limit;
- --send_end;
- if (send_end < GS_outb_in)
- send_end = GS_outb_limit;
- bytes = send_end - GS_outb_in;
- if (bytes > 0) {
- if (bytes >= (unsigned)(cp_end - cp))
- bytes = cp_end - cp;
- memcpy(GS_outb_in, cp, bytes);
- cp += bytes;
- GS_outb_in += bytes;
- if (GS_outb_in == GS_outb_limit)
- GS_outb_in = GS_outb;
- if (cp < cp_end)
- continue;
- }
-
- /* The buffer is now full --or-- we've run out of data */
- old_out = GS_outb_out;
- if (!(gs_xio.xio_events & XIO_OUT)) { /* restart output */
- gs_xio.xio_events = XIO_IN | XIO_OUT;
-#if HAVE_POLL
- if (gs_xio.pfd != NULL)
- gs_xio.pfd->events = POLLIN | POLLOUT;
-#endif
- write_to_gs(GS_fd, NULL);
- if (GS_outb_out != old_out) {
- if (cp == cp_end)
- break;
- else
- continue;
- }
- }
-
- if (cp == cp_end)
- break;
-
- GS_die_ack = GS_write_ack = EV_ACK;
- for (;;) { /* loop because there may be stray ACKs */
- if (!interrupting) {
- (void) read_events(GS_ev_mask | EV_ACK);
- globals.ev.flags &= ~EV_ACK;
-
- if (GS_pid == 0) { /* if GS died */
- GS_die_ack = 0;
- return;
- }
-
- if (GS_outb_out != old_out) /* if more room in buffer */
- break;
-
- if (globals.ev.flags & GS_ev_mask) { /* if a serious event */
- if (globals.debug & DBG_PS)
- puts("Setting timeout in gs_send()");
-
- set_timer(&gs_timer, resource.gs_timeout);
- GS_timer_set = interrupting = True;
- }
- }
- else {
- (void) read_events(EV_GE_TERM | EV_PS_TOGGLE | EV_ACK);
- globals.ev.flags &= ~EV_ACK;
-
- if (GS_outb_out != old_out) /* if more room in buffer */
- break;
-
- if (GS_timer_set) /* if timer still set */
- cancel_timer(&gs_timer);
-
- destroy_gs();
- GS_die_ack = 0;
- return;
- }
- }
- }
-
- if (GS_timer_set) /* if timer still set */
- cancel_timer(&gs_timer);
-
- GS_die_ack = GS_write_ack = 0;
-}
-
-static void
-#if TIMER_PROBLEM_FIXED
-gs_timer_proc(XtPointer client_data, XtIntervalId * id)
-#else
- gs_alarm(struct xtimer *this, void *data)
-#endif
-{
- UNUSED(this);
- UNUSED(data);
-
- if (globals.debug & DBG_PS)
- puts("GS timeout expired");
-
- globals.ev.flags |= EV_ACK;
- GS_timer_set = False;
-#if TIMER_PROBLEM_FIXED
- gs_timeout_id = 0;
-#endif
-}
-
-/*
- * Wait for acknowledgement from GS.
- */
-
-static void
-waitack(void)
-{
- if (GS_pending == 0) {
- globals.ev.flags &= ~EV_ACK;
- return;
- }
-
- GS_die_ack = EV_ACK;
-
- for (;;) { /* loop because there might be stray ACKs. */
- /* fprintf(stderr, "looping for stray ACKs, page %d\n", current_page); */
- (void) read_events(EV_GE_ACK);
- globals.ev.flags &= ~EV_ACK;
-
- if (GS_pending == 0) {
- GS_die_ack = 0;
- return;
- }
- if (globals.ev.flags & EV_GE_ACK)
- break;
- }
-
- if (globals.debug & DBG_PS)
- puts("Setting timeout in waitack()");
-
-#if TIMER_PROBLEM_FIXED
- if (gs_timeout_id)
- XtRemoveTimeOut(gs_timeout_id);
- gs_timeout_id = XtAppAddTimeOut(globals.app, resource.gs_timeout,
- gs_timer_proc, (XtPointer) NULL);
-#else
- set_timer(&gs_timer, resource.gs_timeout);
-#endif
- GS_timer_set = True;
-
- (void) read_events(EV_GE_TERM | EV_PS_TOGGLE | EV_ACK);
- globals.ev.flags &= ~EV_ACK;
-
- if (GS_timer_set) {
-#if TIMER_PROBLEM_FIXED
- XtRemoveTimeOut(gs_timeout_id);
- gs_timeout_id = 0;
-#else
- cancel_timer(&gs_timer);
-#endif
- }
- GS_die_ack = 0;
-
- if (GS_pending > 0)
- destroy_gs();
-}
-
-
-/*
- * Fork a process to run ghostscript. This is done using the
- * x11 device (which needs to be compiled in). Normally the x11
- * device uses ClientMessage events to communicate with the calling
- * program, but we don't do this. The reason for using the ClientMessage
- * events is that otherwise ghostview doesn't know when a non-conforming
- * postscript program calls showpage. That doesn't affect us here,
- * since in fact we disable showpage.
- *
- * SAFER mode is handled by providing both the -dNOSAFER and -dSAFER
- * options. Ghostscript versions 7.04 and earlier ignore -dNOSAFER and use
- * -dSAFER; the code in strsafe is ignored since .locksafe is not present.
- * In versions 7.04 and higher, -dNOSAFER overrides -dSAFER; SAFER mode is
- * optionally turned on by sending the strsafe string. It is possible in some
- * versions of gs prior to 7.04 to use -dDELAYSAFER instead of -dNOSAFER, but
- * there's no point in doing that since .locksafe is not defined in those
- * versions. I don't know where 7.03 fits in on all of this (but it works with
- * that version as well).
- */
-
-Boolean
-initGS(void)
-{
- char buf[100];
- static Boolean did_putenv = False;
- /*
- * This string reads chunks (delimited by %%xdvimark).
- * The first character of a chunk tells whether a given chunk
- * is to be done within save/restore or not.
- * The `H' at the end tells it that the first group is a
- * header; i.e., no save/restore.
- * `execute' is unique to ghostscript.
- */
-
- static const char strsafe[] =
- "{ << /PermitFileReading [ (*) ] /PermitFileWriting [ ] /PermitFileControl [ ] "
- ">> setuserparams .locksafe "
- "} stopped pop\n";
- static const char str1[] =
- "/xdvi$run "
- "{$error /newerror false put currentfile cvx stopped {handleerror} if} "
- "def "
- "/xdvi$ack (\347\310\376) def "
- "/xdvi$dslen countdictstack def "
- "{currentfile read pop 72 eq "
- "{xdvi$run} "
- "{/xdvi$sav save def xdvi$run "
- "clear countdictstack xdvi$dslen sub {end} repeat xdvi$sav restore} "
- "ifelse "
- "{(%%xdvimark) currentfile =string {readline} stopped "
- "{clear} {pop eq {exit} if} ifelse }loop "
- "flushpage xdvi$ack print flush "
- "}loop\nH";
-
- static const char str2[] =
- "[0 1 1 0 0 0] concat\n"
- "stop\n%%xdvimark\n";
-
- /*
- * If we're prescanning *before* setting up the widgets (to get the
- * page size, for example), then postpone starting up ghostscript.
- */
- if (mane.win == (Window)0) {
- if (globals.debug & DBG_PS)
- puts("Hit PS header in early prescan; postponing.");
- psp = no_ps_procs;
- gs_postpone_prescan = True;
- return True;
- }
-
- if (globals.debug & DBG_PS)
- puts("Running initGS ...");
-
- gs_atom = XInternAtom(DISP, "GHOSTVIEW", False);
- /* send bpixmap, orientation, bbox (in pixels), and h & v resolution */
- sprintf(buf, "%ld %d 0 0 %u %u 72 72",
- bpixmap, /* bpixmap */
- Landscape, /* orientation */
- GS_page_h = globals.page.h, GS_page_w = globals.page.w);
-
- XChangeProperty(DISP, mane.win, gs_atom, XA_STRING, 8,
- PropModeReplace, (unsigned char *)buf, strlen(buf));
- GS_alpha = resource.gs_alpha;
-
- gs_colors_atom = XInternAtom(DISP, "GHOSTVIEW_COLORS", False);
- sprintf(buf, "%s %ld %ld", resource.gs_palette,
- color_data[0].pixel, color_data[1].pixel);
-
- XChangeProperty(DISP, mane.win, gs_colors_atom, XA_STRING, 8,
- PropModeReplace, (unsigned char *)buf, strlen(buf));
-
- if (!did_putenv) {
- sprintf(buf, "%ld", mane.win);
- xputenv("GHOSTVIEW", buf);
- did_putenv = True;
- }
-
- XSync(DISP, False); /* update the window */
-
- if (xpipe(std_io) != 0) {
- perror("[xdvik] pipe");
- return False;
- }
- fflush(stderr); /* to avoid double flushing */
- GS_pid = vfork();
- if (GS_pid == 0) { /* child */
- const char **argvp = argv + 10;
-
- argv[1] = resource.gs_alpha ? "-sDEVICE=x11alpha" : "-sDEVICE=x11";
- sprintf(arg4 + 14, "%u", GS_page_w);
- sprintf(arg5 + 15, "%u", GS_page_h);
- if (resource.gs_safer)
- *argvp++ = "-dSAFER";
-
-#if 0
- if (resource.gs_alpha) {
- *argvp++ = "-dGraphicsAlphaBits=4";
- *argvp++ = "-dTextAlphaBits=4";
- *argvp++ = "-dMaxBitmap=0";
- }
-#endif
-
- *argvp = "-";
- (void) close(std_io[0]);
- (void) dup2(std_io[1], 0);
- (void) dup2(std_io[1], 1);
- (void) dup2(std_io[1], 2);
- (void) close(std_io[1]);
-
- (void)execvp(argv[0] = resource.gs_path, (char *const *)argv);
- /*TODO: use fork_process here?? */
- XDVI_ERROR((stderr, "Execvp of %s failed: %s", argv[0], strerror(errno)));
- _exit(EXIT_FAILURE);
- }
-
- (void)close(std_io[1]);
-
- if (GS_pid == -1) { /* error */
- GS_pid = 0;
- perror("[xdvik] vfork");
- (void)close(GS_fd);
-
- return False;
- }
-
- prep_fd(GS_fd, True); /* Set file descriptor for non-blocking I/O */
-
- gs_child.name = xstrdup("gs");
- gs_child.io = &gs_xio;
- set_chld(&gs_child);
-
- psp = gs_procs;
- GS_active = False;
- GS_in_header = True;
- GS_page_dirty = False;
- GS_pending = 1;
- GS_mag = GS_shrink = -1;
- gs_xio.fd = GS_fd;
- gs_xio.xio_events = XIO_IN;
- GS_write_ack = 0;
- GS_outb_in = GS_outb_out = GS_outb;
- set_io(&gs_xio);
- GS_ev_mask = GS_MASK_INIT;
- (void) signal(SIGPIPE, SIG_IGN);
-
- if (resource.gs_safer)
- gs_send(strsafe, (sizeof strsafe) - 1);
- gs_send(str1, (sizeof str1) - 1);
- gs_send(psheader, psheaderlen);
- gs_send(str2, (sizeof str2) - 1);
- waitack();
- GS_in_header = False;
- GS_ev_mask = GS_MASK_NORMAL;
-
- if (GS_pid == 0) { /* if something happened */
- destroy_gs();
- return False;
- }
- if (resource.postscript == 0)
- toggle_gs(0); /* if we got a 'v' already */
- else {
- scanned_page = scanned_page_ps = scanned_page_reset;
- globals.ev.flags |= EV_NEWPAGE; /* ||| redraw the page */
- longjmp(globals.ev.canit, 1);
- }
- return True;
-}
-
-static void
-toggle_gs(int flag) /* this routine is callable from within read_events(). */
-{
- if (globals.debug & DBG_PS)
- fprintf(stdout, "Toggling GS to %d", flag);
-
- switch (flag) {
- case 0:
- psp.drawbegin = drawbegin_none;
- break;
- case 1:
- psp.drawbegin = drawbegin_gs;
- break;
- default:
- psp.drawbegin = drawbegin_gs_box;
- break;
- }
-}
-
-void
-gs_resume_prescan(void)
-{
- if (globals.debug & DBG_PS)
- puts("Resuming prescan");
-
- gs_postpone_prescan = False;
- if (!initGS()) /* this may not return */
- psp = no_ps_procs;
-}
-
-void
-gs_erase_page(void)
-{
- static const char str[] = " erasepage stop\n%%xdvimark\n";
-
- if (!GS_page_dirty) return;
-
- if (globals.debug & DBG_PS)
- puts("Erasing gs page");
-
- if (GS_active)
- XDVI_FATAL((stderr, "Internal error in gs_erase_page()."));
-
- ++GS_pending;
- gs_send(str, sizeof(str) - 1);
- waitack();
-}
-
-static void
-gs_died(int status, struct xchild *child)
-{
- UNUSED(status);
- if (globals.debug & DBG_PS)
- fprintf(stderr, "process %s died\n", child->name);
- GS_pid = 0;
- (child->io->read_proc)(child->io->fd, NULL);
- if (linepos > line) {
- *linepos = '\0';
- printf("%s: %s\n", child->name, line);
- linepos = line;
- }
- clear_io(child->io);
- (void)close(child->io->fd);
-
- scanned_page = scanned_page_ps = scanned_page_reset;
- GS_active = GS_in_doc = GS_page_dirty = False;
- GS_pending = 0;
- globals.ev.flags |= GS_die_ack;
-}
-
-static void
-destroy_gs(void)
-{
- if (globals.debug & DBG_PS)
- puts("Destroying GS process");
- if (GS_pid != 0) {
- if (kill(GS_pid, SIGKILL) < 0 && errno != ESRCH)
- perror("xdvik: destroy_gs");
- GS_pid = 0;
- clear_chld(&gs_child);
- read_from_gs(GS_fd, NULL);
- if (linepos > line) {
- *linepos = '\0';
- printf("gs: %s\n", line);
- linepos = line;
- }
- clear_io(&gs_xio);
- (void) close(GS_fd);
-
- scanned_page = scanned_page_ps = scanned_page_reset;
- }
- GS_active = GS_in_doc = GS_page_dirty = False;
- GS_pending = 0;
-}
-
-static void
-deactivate(void)
-{
- static const char str[] = " stop\n%%xdvimark\n";
- int saved_mask;
-
- saved_mask = GS_ev_mask;
- GS_ev_mask = 0;
- gs_send(str, (sizeof str) - 1);
- GS_ev_mask = saved_mask;
-
- GS_active = False;
-}
-
-static void
-interrupt_gs(void)
-{
- if (globals.debug & DBG_PS)
- puts("Running interrupt_gs()");
- /*
- FIXME: added this special case, since otherwise EV_ACK might not get
- reset at all, and hang xdvi forever when scrolling quickly through
- a file that should be reloaded.
- */
- if (GS_pending == 0) {
- /* fprintf(stderr, "+++++++++ 1st case; waitack: %d\n", globals.ev.flags & EV_ACK); */
- globals.ev.flags &= ~EV_ACK;
- return;
- }
- else if (GS_pending < 0) {
- /* fprintf(stderr, "GS_pending: %d; waitack: %d\n", GS_pending, globals.ev.flags & EV_ACK); */
- return; /* nothing to do */
- }
-
- /*
- * ||| what I'd really like to do here is cause gs to execute
- * the interrupt routine in errordict. But so far (gs 2.6.1)
- * that has not been implemented in ghostscript.
- */
-
- if (GS_active)
- deactivate();
- waitack();
-}
-
-static void
-endpage_gs(void)
-{
- if (globals.debug & DBG_PS)
- puts("Running endpage_gs()");
- if (GS_active) {
- deactivate();
- waitack();
- }
-}
-
-/*
- * Checks that the GS interpreter is running correctly.
- */
-
-static void
-checkgs(Boolean in_header)
-{
- char buf[150];
-
- /*
- * For geometry changes, we pretty much have to restart Ghostscript.
- * This is what Ghostview does (for example, in gv-3.7.4
- * this occurs in Setup() in Ghostview.c).
- */
- if (globals.page.w > GS_page_w || globals.page.h > GS_page_h
- || GS_alpha != resource.gs_alpha)
- destroy_gs();
-
- if (GS_pid == 0)
- (void)initGS();
-
- if (!GS_active) {
- if (magnification != GS_mag) {
- if (globals.ev.flags & GS_ev_mask)
- longjmp(globals.ev.canit, 1);
- ++GS_pending;
- sprintf(buf,
- "H TeXDict begin /DVImag %ld 1000 div def end stop\n"
- "%%%%xdvimark\n",
- GS_mag = magnification);
- gs_send(buf, strlen(buf));
- }
-
- if (mane.shrinkfactor != GS_shrink) {
- if (globals.ev.flags & GS_ev_mask)
- longjmp(globals.ev.canit, 1);
- ++GS_pending;
- sprintf(buf,
- "H TeXDict begin %d %d div dup /Resolution X /VResolution X end stop\n"
- "%%%%xdvimark\n",
- resource.pixels_per_inch,
- GS_shrink = mane.shrinkfactor);
- gs_send(buf, strlen(buf));
- }
- }
-}
-
-static void
-drawbegin_gs(int xul, int yul, const char *cp)
-{
- char buf[32];
- static const char str[] = " TeXDict begin\n";
-
- checkgs(False);
-
- if (!GS_active) {
- if (globals.ev.flags & GS_ev_mask)
- longjmp(globals.ev.canit, 1);
- ++GS_pending;
- gs_send(str, (sizeof str) - 1);
- GS_active = True;
- }
-
- /* This allows the X side to clear the page */
- XSync(DISP, False);
-
- sprintf(buf, "%d %d moveto\n", xul, yul);
- gs_send(buf, strlen(buf));
- /* gs_send(clear_bg, strlen(clear_bg)); */
- if (globals.debug & DBG_PS)
- printf("drawbegin at %d,%d: sending `%s'\n", xul, yul, cp);
-
- /*
- * added SU 2000/12/18:
- * Try to detect some simple PS rotating commands, and warn about them.
- * There are surely more than that ...
- */
- if (strstr(cp, "rotate") != NULL /* used by graphics.sty */
- || strstr(cp, "RotBegin") != NULL /* used by pstricks */
- ) {
- statusline_error(STATUS_SHORT,
- "Warning: PS code on page %d may contain rotation, "
- "which is not supported by xdvi", current_page + 1);
- }
-
- gs_send(cp, strlen(cp));
-}
-
-static void
-drawbegin_gs_box(int xul, int yul, const char *cp)
-{
- drawbegin_gs(xul, yul, cp);
-}
-
-
-void
-drawraw_gs(const char *cp)
-{
- if (!GS_active)
- return;
- if (globals.debug & DBG_PS)
- printf("raw ps sent to context: %s\n", cp);
- GS_page_dirty = True;
- gs_send(cp, strlen(cp));
- gs_send("\n", 1);
-}
-
-static void
-drawfile_gs(const char *cp, FILE *f)
-{
- char canonical_path[MAXPATHLEN + 1];
- char *ret;
-
- fclose(f); /* don't need it */
-
- if (!GS_active)
- return;
-
- if (globals.debug & DBG_PS)
- printf("original path: |%s|\n", cp);
- /* drawraw_gs("newpath 0 0 moveto 0 1000 rlineto 1000 0 rlineto 0 -1000 rlineto closepath 1 setgray fill"); */
-#if 0
- /* if expand_symlinks or remove_dots from kpathsea were public,
- we could use the following: */
- ret = remove_dots(expand_symlinks(cp));
-#endif
-
- ret = REALPATH(cp, canonical_path);
- if (ret == NULL)
- XDVI_WARNING((stderr, "Couldn't canonicalize path \"%s\": %s. Sending to gs unchanged.",
- cp, strerror(errno)));
- else
- cp = canonical_path;
-
- if (globals.debug & DBG_PS)
- printf("expanded path: |%s|\n", cp);
-
- GS_page_dirty = True;
- gs_send("(", 1);
- gs_send(cp, strlen(cp));
- gs_send(")run\n", 5);
- /* { */
- /* char *clear_bg = "newpath 0 0 moveto 0 1000 rlineto 1000 0 rlineto 0 -1000 rlineto closepath .4 setgray fill\n"; */
- /* gs_send(clear_bg, strlen(clear_bg)); */
- /* } */
-}
-
-static void
-drawend_gs(const char *cp)
-{
- if (!GS_active)
- return;
- if (globals.debug & DBG_PS)
- printf("end ps: %s\n", cp);
- gs_send(cp, strlen(cp));
- gs_send("\n", 1);
- save_bbox();
-}
-
-static void
-beginheader_gs(void)
-{
- static const char str[] = "Hsave /xdvi$doc exch def\n";
-
- if (globals.debug & DBG_PS)
- puts("Running beginheader_gs()");
-
- checkgs(True);
-
- if (GS_active) {
- if (!GS_in_header)
- XDVI_FATAL((stderr, "Internal error in beginheader_gs()."));
- return;
- }
-
- if (globals.ev.flags & GS_ev_mask) {
- /* fprintf(stderr, "longjmp!"); */
- longjmp(globals.ev.canit, 1);
- }
-
- GS_in_header = True;
- GS_ev_mask = GS_MASK_HEADER;
- ++GS_pending;
- if (GS_in_doc)
- gs_send("H", 1);
- else {
- gs_send(str, (sizeof str) - 1);
- GS_in_doc = True;
- }
- GS_active = True;
-}
-
-static void
-endheader_gs(void)
-{
- if (globals.debug & DBG_PS)
- puts("Running endheader_gs()");
-
- if (GS_active) {
- deactivate();
- waitack();
- GS_in_header = False;
- GS_ev_mask = GS_MASK_NORMAL;
- }
-}
-
-static void
-newdoc_gs(void)
-{
- static const char str[] = "Hxdvi$doc restore stop\n%%xdvimark\n";
-
- if (globals.debug & DBG_PS)
- puts("Running newdoc_gs()");
-
- if (GS_in_doc) {
- ++GS_pending;
- gs_send(str, (sizeof str) - 1);
- GS_mag = GS_shrink = -1;
- GS_in_doc = False;
-
- GS_page_w = GS_page_h = 0;
- }
-}
-
-#else
-/* silence `empty compilation unit' warnings */
-static void bar(void); static void foo(void) { bar(); } static void bar(void) { foo(); }
-#endif /* PS_GS */