home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
lyx-0.13.2.tar.gz
/
lyx-0.13.2.tar
/
lyx-0.13.2
/
src
/
gsqueue.C
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-23
|
8KB
|
289 lines
#include <config.h>
#include <unistd.h>
#include "gsqueue.h"
#include "error.h"
#include "lyx_main.h"
#include "filetools.h"
#include "lyxrc.h"
#include "syscall.h"
extern int reverse_video;
extern long int background_pixels;
extern FL_OBJECT *figinset_canvas;
extern char **environ; // is this only redundtant on linux systems? Lgb.
bool gs_color; // do we allocate colors for gs?
static bool gs_xcolor = false; // allocated extended colors
bool gs_gray; // is grayscale?
// the queue of images to be rendered.
GSQueue gsQ;
const short MAXGS = 3; /* maximum 3 gs's at a time */
void GSQueue::runqueue()
{
// run queued requests for ghostscript, if any
if (!gsworking() && gs_color && !gs_xcolor) {
// here alloc all colors, so that gs will use only
// those we allocated for it
// *****
gs_xcolor = true;
}
while (gsrunning < MAXGS) {
Queue *p;
int pid;
LString tbuf;
LString tbuf2;
//char tbuf[384], tbuf2[80];
Atom *prop;
int nprop, i;
if (!queue) {
if (!gsworking() && gs_xcolor) {
// de-allocate rest of colors
// *****
gs_xcolor = false;
}
return;
}
p = queue;
if (!p->data) {
delete p;
continue;
}
//if (pid == -1) { // no fork
switch (pid=fork()) {
case -1: // no fork
if (lyxerr.debugging()) {
printf("GS start error!!! Cannot fork.\n");
}
p->data->broken = true;
p->data->reading = false;
return;
case 0: // child
{
char **env; // rbuf[80], gbuf[40];
LString rbuf;
LString gbuf;
int ne = 0;
Display* tempdisp = XOpenDisplay(XDisplayName(NULL));
// create translation file
//sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(),
//int(getpid()));
tbuf = system_tempdir + "/~lyxgs"
+ int(getpid()) + ".ps";
FilePtr f(tbuf, FilePtr::write);
fprintf(f, "gsave clippath pathbbox grestore\n"
"4 dict begin\n"
"/ury exch def /urx exch def /lly exch def "
"/llx exch def\n"
"%g %g translate\n"
"%g rotate\n"
"%g %g translate\n"
"%g %g scale\n"
"%d %d translate\nend\n",
p->data->wid / 2.0, p->data->hgh / 2.0,
p->data->angle,
- (p->data->raw_wid / 2.0), -(p->data->raw_hgh / 2.0),
p->rx / 72.0, p->ry / 72.0,
-p->ofsx, -p->ofsy
);
// DON'T EVER remove this!!
f.close(); // was this all? (Lgb)
// gs process - set ghostview environment first
//sprintf(tbuf2, "GHOSTVIEW=%ld %ld", fl_get_canvas_id(
//figinset_canvas), p->data->bitmap);
tbuf2 = LString("GHOSTVIEW=")
+ long(fl_get_canvas_id(figinset_canvas))
+ LString(" ") + long(p->data->bitmap);
// now set up ghostview property on a window
//sprintf(tbuf, "0 0 0 0 %d %d 72 72 0 0 0 0",
// p->data->wid, p->data->hgh);
tbuf = LString("0 0 0 0 ") + int(p->data->wid) + LString(" ") + int(p->data->hgh) + "72 72 0 0 0 0";
//#warning BUG seems that the only bug here might be the hardcoded dpi.. Bummer!
if (lyxerr.debugging()) {
lyxerr.print("Will set GHOSTVIEW property to ["
+ tbuf + "]");
}
// wait until property is deleted if executing multiple
// ghostscripts
for (;;) {
// grab server to prevent other child interfering
// with setting GHOSTVIEW property
if (lyxerr.debugging()) {
lyxerr.print("Grabbing the server");
}
XGrabServer(tempdisp);
prop = XListProperties(tempdisp, fl_get_canvas_id(
figinset_canvas), &nprop);
if (!prop) break;
bool err = true;
for (i = 0; i < nprop; ++i) {
char *p = XGetAtomName(tempdisp, prop[i]);
if (strcmp(p, "GHOSTVIEW") == 0) {
err = false;
break;
}
XFree(p);
}
XFree((char *)prop); /* jc: */
if (err) break;
// release the server
XUngrabServer(tempdisp);
XFlush(tempdisp);
// ok, property found, we must wait until ghostscript
// deletes it
if (lyxerr.debugging()) {
lyxerr.print("Releasing the server");
lyxerr.print(LString("[") +
int(getpid()) +
"] GHOSTVIEW property"
" found. Waiting.");
}
}
XChangeProperty(tempdisp,
fl_get_canvas_id(figinset_canvas),
XInternAtom(tempdisp, "GHOSTVIEW", false),
XInternAtom(tempdisp, "STRING", false),
8, PropModeAppend,
//(unsigned char *) tbuf,
(const unsigned char *)tbuf.c_str(),
//strlen(tbuf));
tbuf.length());
switch (p->data->flags & 3) {
case 0: //tbuf[0] = 'H'; break; // Hidden
tbuf = "H"; break;
case 1: //tbuf[0] = 'M'; break; // Mono
tbuf = "M"; break;
case 2: //tbuf[0] = 'G'; break; // Gray
tbuf = "G"; break;
case 3:
if (gs_color && !gs_gray)
//tbuf[0] = 'C'; // Color
tbuf = "C";
else
//tbuf[0] = 'G'; // Gray
tbuf = "G";
break;
}
if (reverse_video) {
//sprintf(tbuf+1, " %ld %ld", WhitePixelOfScreen(
//DefaultScreenOfDisplay(fl_display)),
//background_pixels);
tbuf += LString(" ")
+ long(WhitePixelOfScreen(DefaultScreenOfDisplay(fl_display)))
+ LString(" ")
+ long(background_pixels);
} else {
//sprintf(tbuf+1, " %ld %ld", BlackPixelOfScreen(
//DefaultScreenOfDisplay(fl_display)),
//background_pixels);
tbuf += LString(" ")
+ long(BlackPixelOfScreen(DefaultScreenOfDisplay(fl_display)))
+ LString(" ")
+ long(background_pixels);
}
XChangeProperty(tempdisp,
fl_get_canvas_id(figinset_canvas),
XInternAtom(tempdisp, "GHOSTVIEW_COLORS", false),
XInternAtom(tempdisp, "STRING", false),
8, PropModeReplace,
//(unsigned char *) tbuf,
(const unsigned char *) tbuf.c_str(),
//strlen(tbuf));
tbuf.length());
XUngrabServer(tempdisp);
XFlush(tempdisp);
if (lyxerr.debugging()) {
lyxerr.print("Releasing the server\n");
}
XCloseDisplay(tempdisp);
// set up environment
while (environ[ne]) ++ne;
env = (char **) malloc(sizeof(char*)*(ne+2));
#warning Oops.
env[0] = strdup(tbuf2.c_str());
memcpy(&env[1], environ, sizeof(char*)*(ne+1));
environ = env;
// now make gs command
// close(0);
// close(1); do NOT close. If GS writes out
// errors it would hang. (Matthias 290596)
//sprintf(rbuf, "-r%gx%g", p->rx, p->ry);
//sprintf(gbuf, "-g%dx%d", p->data->wid, p->data->hgh);
// now chdir into dir with .eps file, to be on the safe
// side
chdir(OnlyPath(p->data->fname).c_str());
// make temp file name
//sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(),
//int(getpid()));
//if (lyxerr.debugging()) {
// printf("starting gs %s %s, pid: %d\n", tbuf,
// p->data->fname.c_str(), int(getpid()));
//}
LString argv = lyxrc->ps_command + " -sDEVICE=x11 -dNOPAUSE -dSAFER";
#warning Fix this!
argv += LString(" -r") + int(p->rx) + LString("x") + int(p->ry);
argv += LString(" -g") + int(p->data->wid) + LString("x") + int(p->data->hgh);
argv += " " + system_tempdir + "/~lyxgs" + int(getpid()) + ".ps";
argv += " showpage.ps";
if (lyxerr.debugging()) {
lyxerr.print("starting:" + argv);
}
Systemcalls(Systemcalls::DontWait, argv);
//int err = execlp(lyxrc->ps_command.c_str(),
// lyxrc->ps_command.c_str(),
// "-sDEVICE=x11",
// "-dNOPAUSE",// "-dQUIET",
// "-dSAFER",
// rbuf, gbuf, tbuf,
// p->data->fname.c_str(),
// "showpage.ps", NULL);
// if we are still there, an error occurred.
lyxerr.print(LString("Error executing ghostscript. "));
lyxerr.print("Cmd: "
+argv);
//+ lyxrc->ps_command
// +" -sDEVICE=x11 "
// + tbuf + LString(" ")
// + p->data->fname);
_exit(0); // no gs?
}
default:
// normal process (parent)
if (lyxerr.debugging()) {
printf("GS [%d] started\n", pid);
}
queue = queue->next;
gsrunning++;
p->data->gspid = pid;
delete p;
break;
}
}
}