aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/ximtool/print.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /vendor/x11iraf/ximtool/print.c
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'vendor/x11iraf/ximtool/print.c')
-rw-r--r--vendor/x11iraf/ximtool/print.c387
1 files changed, 387 insertions, 0 deletions
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 <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#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);
+}