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 >
C/C++ Source or Header  |  1998-04-23  |  8KB  |  289 lines

  1.  
  2. #include <config.h>
  3. #include <unistd.h>
  4.  
  5. #include "gsqueue.h"
  6. #include "error.h"
  7. #include "lyx_main.h"
  8. #include "filetools.h"
  9. #include "lyxrc.h"
  10. #include "syscall.h"
  11.  
  12. extern int    reverse_video;
  13. extern long int background_pixels;
  14. extern FL_OBJECT *figinset_canvas;
  15. extern char **environ; // is this only redundtant on linux systems? Lgb.
  16.  
  17. bool gs_color;            // do we allocate colors for gs?
  18. static bool gs_xcolor = false;        // allocated extended colors
  19. bool gs_gray;            // is grayscale?
  20.  
  21. // the queue of images to be rendered.
  22. GSQueue gsQ;
  23.  
  24. const short MAXGS = 3;            /* maximum 3 gs's at a time */
  25.  
  26. void GSQueue::runqueue()
  27. {
  28.     // run queued requests for ghostscript, if any
  29.     if (!gsworking() && gs_color && !gs_xcolor) {
  30.         // here alloc all colors, so that gs will use only
  31.         // those we allocated for it
  32.         // *****
  33.         gs_xcolor = true;
  34.     }
  35.     
  36.     while (gsrunning < MAXGS) {
  37.         Queue *p;
  38.         int pid;
  39.         LString tbuf;
  40.         LString tbuf2;
  41.         //char tbuf[384], tbuf2[80];
  42.         Atom *prop;
  43.         int nprop, i;
  44.  
  45.         if (!queue) {
  46.             if (!gsworking() && gs_xcolor) {
  47.                 // de-allocate rest of colors
  48.                 // *****
  49.                 gs_xcolor = false;
  50.             }
  51.             return;
  52.         }
  53.         p = queue;
  54.  
  55.         if (!p->data) {
  56.             delete p;
  57.             continue;
  58.         }
  59.  
  60.         //if (pid == -1) { // no fork
  61.         switch (pid=fork()) {
  62.         case -1: // no fork
  63.             if (lyxerr.debugging()) {
  64.                 printf("GS start error!!! Cannot fork.\n");
  65.             }
  66.             p->data->broken = true;
  67.             p->data->reading = false;
  68.             return;
  69.         case 0: // child
  70.         {
  71.             char **env; // rbuf[80], gbuf[40];
  72.             LString rbuf;
  73.             LString gbuf;
  74.             
  75.             int ne = 0;
  76.             Display* tempdisp = XOpenDisplay(XDisplayName(NULL));
  77.  
  78.             // create translation file
  79.             //sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(),
  80.                 //int(getpid()));
  81.  
  82.             tbuf = system_tempdir + "/~lyxgs"
  83.                 + int(getpid()) + ".ps";
  84.             
  85.             FilePtr    f(tbuf, FilePtr::write);
  86.             fprintf(f, "gsave clippath pathbbox grestore\n"
  87.                 "4 dict begin\n"
  88.                 "/ury exch def /urx exch def /lly exch def " 
  89.                 "/llx exch def\n"
  90.                 "%g %g translate\n"
  91.                 "%g rotate\n"
  92.                 "%g %g translate\n"
  93.                 "%g %g scale\n"
  94.                 "%d %d translate\nend\n",
  95.                 p->data->wid / 2.0, p->data->hgh / 2.0,
  96.                 p->data->angle,
  97.                 - (p->data->raw_wid / 2.0), -(p->data->raw_hgh / 2.0),
  98.                 p->rx / 72.0, p->ry / 72.0,
  99.                 -p->ofsx, -p->ofsy
  100.                 );
  101.  
  102.             // DON'T EVER remove this!!
  103.             f.close(); // was this all? (Lgb)
  104.             
  105.             // gs process - set ghostview environment first
  106.             //sprintf(tbuf2, "GHOSTVIEW=%ld %ld", fl_get_canvas_id(
  107.                 //figinset_canvas), p->data->bitmap);
  108.  
  109.             tbuf2 = LString("GHOSTVIEW=")
  110.                 + long(fl_get_canvas_id(figinset_canvas))
  111.                        + LString(" ") + long(p->data->bitmap);
  112.             // now set up ghostview property on a window
  113.             //sprintf(tbuf, "0 0 0 0 %d %d 72 72 0 0 0 0",
  114.             //    p->data->wid, p->data->hgh);
  115.  
  116.             tbuf = LString("0 0 0 0 ") + int(p->data->wid) + LString(" ") + int(p->data->hgh) + "72 72 0 0 0 0";
  117. //#warning BUG seems that the only bug here might be the hardcoded dpi.. Bummer!
  118.             
  119.             if (lyxerr.debugging()) {
  120.                 lyxerr.print("Will set GHOSTVIEW property to ["
  121.                          + tbuf + "]");
  122.             }
  123.             // wait until property is deleted if executing multiple
  124.             // ghostscripts
  125.             for (;;) {
  126.                 // grab server to prevent other child interfering
  127.                 // with setting GHOSTVIEW property
  128.                 if (lyxerr.debugging()) {
  129.                     lyxerr.print("Grabbing the server");
  130.                 }
  131.                 XGrabServer(tempdisp);
  132.                 prop = XListProperties(tempdisp, fl_get_canvas_id(
  133.                     figinset_canvas), &nprop);
  134.                 if (!prop) break;
  135.  
  136.                 bool err = true;
  137.                 for (i = 0; i < nprop; ++i) {
  138.                     char *p = XGetAtomName(tempdisp, prop[i]);
  139.                     if (strcmp(p, "GHOSTVIEW") == 0) {
  140.                         err = false;
  141.                         break;
  142.                     }
  143.                     XFree(p);
  144.                 }
  145.                 XFree((char *)prop);    /* jc: */
  146.                 if (err) break;
  147.                 // release the server
  148.                 XUngrabServer(tempdisp);
  149.                 XFlush(tempdisp);
  150.                 // ok, property found, we must wait until ghostscript
  151.                 // deletes it
  152.                 if (lyxerr.debugging()) {
  153.                     lyxerr.print("Releasing the server");
  154.                     lyxerr.print(LString("[") +
  155.                               int(getpid()) +
  156.                               "] GHOSTVIEW property"
  157.                               " found. Waiting.");
  158.                 }
  159.             }
  160.  
  161.             XChangeProperty(tempdisp, 
  162.                     fl_get_canvas_id(figinset_canvas),
  163.                     XInternAtom(tempdisp, "GHOSTVIEW", false),
  164.                     XInternAtom(tempdisp, "STRING", false),
  165.                     8, PropModeAppend, 
  166.                     //(unsigned char *) tbuf,
  167.                     (const unsigned char *)tbuf.c_str(),
  168.                     //strlen(tbuf));
  169.                     tbuf.length());
  170.             
  171.             switch (p->data->flags & 3) {
  172.             case 0: //tbuf[0] = 'H'; break; // Hidden
  173.                 tbuf = "H"; break;
  174.             case 1: //tbuf[0] = 'M'; break; // Mono
  175.                 tbuf = "M"; break;
  176.             case 2: //tbuf[0] = 'G'; break; // Gray
  177.                 tbuf = "G"; break;
  178.             case 3:
  179.                 if (gs_color && !gs_gray) 
  180.                     //tbuf[0] = 'C'; // Color
  181.                     tbuf = "C";
  182.                 else 
  183.                     //tbuf[0] = 'G'; // Gray
  184.                     tbuf = "G";
  185.                 break;
  186.             }
  187.  
  188.             if (reverse_video) {
  189.                 //sprintf(tbuf+1, " %ld %ld", WhitePixelOfScreen(
  190.                 //DefaultScreenOfDisplay(fl_display)),
  191.                 //background_pixels);
  192.                 tbuf += LString(" ")
  193.                     + long(WhitePixelOfScreen(DefaultScreenOfDisplay(fl_display)))
  194.                     + LString(" ")
  195.                     + long(background_pixels);
  196.             } else {
  197.                 //sprintf(tbuf+1, " %ld %ld", BlackPixelOfScreen(
  198.                 //DefaultScreenOfDisplay(fl_display)),
  199.                 //background_pixels);
  200.                 tbuf += LString(" ")
  201.                     + long(BlackPixelOfScreen(DefaultScreenOfDisplay(fl_display)))
  202.                     + LString(" ")
  203.                     + long(background_pixels);
  204.             }
  205.  
  206.             XChangeProperty(tempdisp, 
  207.                     fl_get_canvas_id(figinset_canvas),
  208.                     XInternAtom(tempdisp, "GHOSTVIEW_COLORS", false),
  209.                     XInternAtom(tempdisp, "STRING", false),
  210.                     8, PropModeReplace, 
  211.                     //(unsigned char *) tbuf,
  212.                     (const unsigned char *) tbuf.c_str(),
  213.                     //strlen(tbuf));
  214.                     tbuf.length());
  215.             XUngrabServer(tempdisp);
  216.             XFlush(tempdisp);
  217.             if (lyxerr.debugging()) {
  218.                 lyxerr.print("Releasing the server\n");
  219.             }
  220.             XCloseDisplay(tempdisp);
  221.  
  222.             // set up environment
  223.             while (environ[ne]) ++ne;
  224.             env = (char **) malloc(sizeof(char*)*(ne+2));
  225. #warning Oops.
  226.             env[0] = strdup(tbuf2.c_str());
  227.             memcpy(&env[1], environ, sizeof(char*)*(ne+1));
  228.             environ = env;
  229.  
  230.             // now make gs command
  231.             // close(0);
  232.             // close(1); do NOT close. If GS writes out
  233.             // errors it would hang. (Matthias 290596) 
  234.             //sprintf(rbuf, "-r%gx%g", p->rx, p->ry);
  235.             //sprintf(gbuf, "-g%dx%d", p->data->wid, p->data->hgh);
  236.             // now chdir into dir with .eps file, to be on the safe
  237.             // side
  238.             chdir(OnlyPath(p->data->fname).c_str());
  239.             // make temp file name
  240.             //sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(),
  241.                 //int(getpid()));
  242.             //if (lyxerr.debugging()) {
  243.             //    printf("starting gs %s %s, pid: %d\n", tbuf,
  244.             //           p->data->fname.c_str(), int(getpid()));
  245.             //}
  246.  
  247.             LString argv = lyxrc->ps_command + " -sDEVICE=x11 -dNOPAUSE -dSAFER";
  248. #warning Fix this!
  249.             argv += LString(" -r") + int(p->rx) + LString("x") + int(p->ry); 
  250.             argv += LString(" -g") + int(p->data->wid) + LString("x") + int(p->data->hgh);
  251.             argv += " " + system_tempdir + "/~lyxgs" + int(getpid()) + ".ps";
  252.             argv += " showpage.ps";
  253.             if (lyxerr.debugging()) {
  254.                 lyxerr.print("starting:" + argv);
  255.             }
  256.  
  257.             Systemcalls(Systemcalls::DontWait, argv);
  258.             //int err = execlp(lyxrc->ps_command.c_str(), 
  259.             //         lyxrc->ps_command.c_str(), 
  260.             //         "-sDEVICE=x11", 
  261.             //         "-dNOPAUSE",// "-dQUIET",
  262.             //         "-dSAFER", 
  263.             //         rbuf, gbuf, tbuf, 
  264.             //         p->data->fname.c_str(), 
  265.             //         "showpage.ps", NULL);
  266.             // if we are still there, an error occurred.
  267.             lyxerr.print(LString("Error executing ghostscript. "));
  268.             lyxerr.print("Cmd: "
  269.                      +argv);
  270.             //+ lyxrc->ps_command
  271.             //         +" -sDEVICE=x11 "
  272.             //         + tbuf + LString(" ")
  273.             //         + p->data->fname);
  274.             _exit(0);    // no gs?
  275.         }
  276.         default:
  277.             // normal process (parent)
  278.             if (lyxerr.debugging()) {
  279.                 printf("GS [%d] started\n", pid);
  280.             }
  281.             queue = queue->next;
  282.             gsrunning++;
  283.             p->data->gspid = pid;
  284.             delete p;
  285.             break;
  286.         }
  287.     }
  288. }
  289.