From fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 8 Jul 2015 20:46:52 -0400 Subject: Initial commit --- vendor/x11iraf/ximtool/print.c | 387 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 vendor/x11iraf/ximtool/print.c (limited to 'vendor/x11iraf/ximtool/print.c') diff --git a/vendor/x11iraf/ximtool/print.c b/vendor/x11iraf/ximtool/print.c new file mode 100644 index 00000000..63822aa4 --- /dev/null +++ b/vendor/x11iraf/ximtool/print.c @@ -0,0 +1,387 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ximtool.h" + + +/* +** PRINT.C -- Printer interface. +** +** xim_print (xim, x0,y0, nx,ny) +** +** ximp_rename (xim, old, new) # print alert action +** ximp_cancel (xim, fname) # print alert action +** +** xim_initPrinterOps (xim) +** xim_initPrinterList (xim) +** xim_getPrinterInfo (xim, printer) +** +** xim_print prints the indicated region of the display frame (raster 0). +** If nx or ny is zero the full display frame is printed. The output device +** or file and all print options are maintained in the printer context within +** the XIM descriptor. The xim_initPrinter routines should be called at +** startup to initialize the print options and load the list of local printers. +*/ + +void xim_initPrinterOps(); +int xim_getPrinterInfo(); + +static void printstat(); +static void xim_initPrinterList(); + + +/* XIM_PRINT -- Print the indicated region of the current display frame to +** the printer device or to a file. +*/ + +xim_print (xim, x0,y0, nx,ny) +register XimDataPtr xim; +int x0,y0, nx,ny; /* region of source raster */ +{ + register PSImagePtr psim = xim->psim; + register PrintCfgPtr pcp = xim->pcp; + register FrameBufPtr fb = xim->df_p; + register ColorMapPtr cm = &colormaps[fb->colormap-1]; + unsigned char r[256], g[256], b[256]; + unsigned char *pixels = NULL; + static char tmpfile[SZ_FNAME]; + static char fname[SZ_FNAME]; + static char text[SZ_LINE]; + int w, h, ncolors; + FILE *fp; + char *mktemp(); + + + bzero (text, SZ_LINE); + bzero (fname, SZ_FNAME); + bzero (tmpfile, SZ_FNAME); + + + /* Get the display pixels and colormap. The routine allocates a + * pointer to the pixels we'll need to free when we're done. + */ + printstat (xim, "Get image data..."); + pixels = xim_readDisplay (xim, x0,y0,nx,ny, &w,&h, r,g,b, &ncolors); + if (!pixels) + return (-1); + + /* Set up some of the EPS options and load the colormap. */ + if (psim->label && (psim->page.flags & EPS_DOTITLE)) + eps_setLabel (psim, fb->ctran.imtitle); + eps_setCmap (psim, r, g, b, ncolors); + eps_setTransform (psim, fb->ctran.z1, fb->ctran.z2, fb->ctran.zt, + fb->offset, fb->scale, cm->name); + + + /* Now call the main routine to output the EPS file. + */ + if (pcp->diskfile) { + + /* Print to a file. If we are not clobbering an existing file + * and we can open the output file write to it directly and be + * done with it. If there is any problem we we to a temporary + * file and issue an alert with actions to be taken if the user + * decides to proceed or cancel the operation. + */ + if (strchr (pcp->printFile, (int)'%')) + sprintf (fname, pcp->printFile, pcp->seqno++); + else + strcpy (fname, pcp->printFile); + + if (access (fname, F_OK) < 0) { + if (fp = fopen (fname, "w")) { + struct stat fs; + + printstat (xim, "Generating postscript output..."); + eps_print (psim, fp, pixels, w, h, 8, 0); + fclose (fp); + + stat (fname, &fs); + sprintf (text, "Wrote %d bytes to '%s'", + (int)fs.st_size, fname); + printstat (xim, text); + + } else { + sprintf (text, "Could not open file %s", fname); + xim_alert (xim, text, NULL, NULL); + } + + } else { + /* Named file already exists. Write a temporary file and + * post an alert to ask the user if they want to overwrite + * the existing file. + */ + char ok_action[SZ_LINE]; + char cancel_action[SZ_LINE]; + char tmpfile[SZ_FNAME]; + char *ip, *op, *last; + + + bzero (tmpfile, SZ_FNAME); + bzero (ok_action, SZ_LINE); + bzero (cancel_action, SZ_LINE); + + /* Write to a temporary file in the same directory as fname. + */ + for (ip=fname, op=tmpfile, last=tmpfile; *op = *ip++; op++) { + if (*op == '/') + last = op + 1; + } + *last = '\0'; + strcat (tmpfile, "ximpXXXXXX"); + if (mktemp(tmpfile) == (char *)NULL) + return (-1); + + if (!(fp = fopen (tmpfile, "w"))) { + sprintf (text, "Cannot open temporary file:\n%s", tmpfile); + xim_alert (xim, text, NULL, NULL); + return (-1); + } + printstat (xim, "Generating postscript output..."); + eps_print (psim, fp, pixels, w, h, 8, 0); + fclose (fp); + + for (ip=fname; *ip!='\0' ; ip++) ; + for ( ; *ip != '/' && ip > fname; ip--) ; + sprintf (text, "%s\n%s\n%s", + "File already exists:", (ip == fname ? fname : ++ip), + "Overwrite this file?"); + + sprintf (ok_action, "print rename %s %s", tmpfile, fname); + sprintf (cancel_action, "print cancel %s", tmpfile); + + xim_alert (xim, text, ok_action, cancel_action); + } + + } else { + /* Print to a printer device. */ + strcpy (tmpfile, "/tmp/ximpXXXXXX"); + if (mktemp(tmpfile) == (char *)NULL) + return (-1); + + if (!(fp = fopen (tmpfile, "w"))) + return (-1); + printstat (xim, "Generating postscript output..."); + eps_print (psim, fp, pixels, w, h, 8, 0); + fclose (fp); + + printstat (xim, "Printing file..."); + sprintf (text, "cat %s | %s", tmpfile, pcp->printCmd); + system (text); /* dispose to printer */ + unlink (tmpfile); /* delete tmp file */ + + printstat (xim, "Done."); + } + + /* Clean up and return. */ + free ((char *) pixels); + return (0); +} + +pbob () { int i = 0; } + + +/* The following implement the ok and cancel actions posted by the alert in +** xim_print above. +*/ + +void +ximp_rename (xim, old, new) +register XimDataPtr xim; +char *old, *new; +{ + char text[SZ_LINE]; + struct stat fs; + + bzero (text, SZ_LINE); + unlink (new); + + if (rename(old,new) != 0 || stat(new,&fs) != 0) { + sprintf (text, "Could not write file %s", new); + printstat (xim, text); + } else { + sprintf (text, "Wrote %d bytes to %s", fs.st_size, new); + printstat (xim, text); + } +} + +void +ximp_cancel (xim, fname) +register XimDataPtr xim; +char *fname; +{ + printstat (xim, "Print cancelled."); + unlink (fname); +} + + +/* XIM_INITPRINTEROPS -- Initialize the printer operations. +*/ +void +xim_initPrinterOps (xim) +register XimDataPtr xim; +{ + register PrintCfgPtr pcp; + char buf[SZ_LINE]; + PSImagePtr eps_init(); + + + /* Open a pointer to the EPS structure. */ + xim->psim = eps_init(); + + /* Read the printer configuration file. */ + xim_initPrinterList (xim); + + /* Initialize options. */ + xim_message (xim, "printOptions", "papersize letter"); + xim_message (xim, "printOptions", "orientation portrait"); + xim_message (xim, "printOptions", "colortype gray"); + xim_message (xim, "printOptions", "autoscale True"); + xim_message (xim, "printOptions", "annotate True"); + xim_message (xim, "printOptions", "dotitle True"); + xim_message (xim, "printOptions", "docolorbar True"); + xim_message (xim, "printOptions", "doborders True"); + + /* Allocate the printer configuration struct. */ + xim->pcp = pcp = (PrintCfgPtr) malloc (sizeof (PrintCfg)); + + pcp->seqno = 0; + pcp->printno = 0; + pcp->diskfile = 0; + strcpy (pcp->printFile, "frame%d.eps"); + + bzero (buf, SZ_LINE); + sprintf (buf, "printerName %s", printer_list[0].printerName); + xim_message (xim, "printOptions", buf); + + strcpy (pcp->printCmd, printer_list[0].printCmd); + sprintf (buf, "printCmd %s", pcp->printCmd); + xim_message (xim, "printOptions", buf); +} + + +/* XIM_INITPRINTERLIST -- Read the printer configuration file and initialize +** the structure with the list of printers and commands. Send the printer +** list to the GUI, maintain the command list internally. +*/ + +static void +xim_initPrinterList (xim) +register XimDataPtr xim; +{ + register int i; + register FILE *fp; + char buf[SZ_LINE], plist[MAX_PRINTERS*20]; + char *ip, *pn, *pc, *pl; + + + bzero (buf, SZ_LINE); + bzero (plist, MAX_PRINTERS*20); + + if (access (xim->printConfig, R_OK) == 0) { + if (!(fp = fopen (xim->printConfig, "r"))) + return; + + /* Scan the printer configuration file. + */ + while (fgets (buf, SZ_LINE, fp) != NULL) { + /* Skip comment lines and blank lines. */ + for (ip=buf; *ip == ' ' || *ip == '\t'; ip++) + ; + if (*ip == '\n' || *ip == '#') + continue; + + /* Now scan up to the tab for the list entry, i.e the printer + * name we'll use in the GUI. + */ + pn = printer_list[nprinters].printerName; + while (*ip != '\t') + *pn++ = *ip++; + *pn++ = '\0'; + ip++; + + while (!isalnum(*ip)) + ip++; + + /* Everything up to a comment char or the newline is the + * command to be used to dispose the EPS. + */ + pc = printer_list[nprinters].printCmd; + while (*ip != '#' && *ip != '\n') + *pc++ = *ip++; + *pc++ = '\0'; + + nprinters++; + bzero (buf, SZ_LINE); + } + fclose (fp); + + /* Erase the remaining entries in the default printer list */ + for (i=nprinters; i < MAX_PRINTERS; i++) { + strcpy (printer_list[i].printerName, " "); + printer_list[i].printCmd[0] = '\0'; + } + } else { + while (printer_list[nprinters].printerName[0] != '\0' && + nprinters < MAX_PRINTERS) + nprinters++; + } + + + /* Now build up a list of the printers, either from the config + * file or the fallback, and send it to the GUI. + */ + for (i=0, pl=plist; i < nprinters; i++) { + *pl++ = '"'; + for (ip = printer_list[i].printerName; *pl = *ip++; pl++) + ; + *pl++ = '"'; + *pl++ = '\n'; + } + *pl++ = '\0'; + + xim_message (xim, "printerList", plist); +} + + +/* XIM_GETPRINTERINFO -- For a given printer name search the printer list +** array and update the GUI with the selected printer name and command. +*/ + +int +xim_getPrinterInfo (xim, printer) +register XimDataPtr xim; +char *printer; +{ + register int i; + register PrintCfgPtr pcp = xim->pcp; + + /* Scan down the printer list until we find the requested device. */ + for (i=0; strcmp(printer_list[i].printerName, printer) != 0; i++) + if (i >= MAX_PRINTERS) + return (pcp->printno); + + return (pcp->printno = i); +} + + +/* PRINTSTAT -- Internal routine for print status messages. +*/ + +static void +printstat (xim, message) +register XimDataPtr xim; +char *message; +{ + char text[SZ_LINE]; + + bzero (text, SZ_LINE); + sprintf (text, "status {%s}", message); + xim_message (xim, "printOptions", text); +} -- cgit