home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / common / winprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-12  |  18.9 KB  |  690 lines

  1. /* Print plug-in for the GIMP on Windows.
  2.  * Copyright 1999 Tor Lillqvist <tml@iki.fi>
  3.  * 
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. /*
  20.  * TODO:
  21.  *
  22.  * Own dialog box, with similar options as the Unix print plug-in?
  23.  * (at least those that aren't already covered in the Windows standard
  24.  * page setup and/or print dialogs):
  25.  * - brighness and gamma adjustment
  26.  * - scaling
  27.  * - image placement on paper (at least centering should be offered)
  28.  *
  29.  * Speed up the StretchBlt'ing. Now we StretchBlt one pixel row at
  30.  * a time, and in pieces. Quite ad hoc.
  31.  *
  32.  * Handle the file_print procedure's parameters as much as possible
  33.  * like the print plug-in does. (They are currently cheerfully ignored.)
  34.  *
  35.  * Etc.
  36.  */
  37.  
  38. #include "config.h"
  39.  
  40. #include <stdlib.h>
  41. #include <windows.h>
  42.  
  43. #include <libgimp/gimp.h>
  44.  
  45. #include "libgimp/stdplugins-intl.h"
  46.  
  47.  
  48. #define NAME_PRINT "file_print"
  49. #define NAME_PAGE_SETUP "file_page_setup"
  50.  
  51. #define PING() g_message ("%s: %d", __FILE__, __LINE__)
  52.  
  53. static struct
  54. {
  55.   PRINTDLG prDlg;
  56.   PAGESETUPDLG psDlg;
  57.   int devmodeSize;
  58. } vars =
  59. {
  60.   { 0, },
  61.   { 0, },
  62.   0
  63. };
  64.  
  65. /* These two functions lifted from the print plug-in and modified
  66.  * to build BGR format pixel rows.
  67.  */
  68.  
  69. static void
  70. indexed_to_bgr(guchar *indexed,
  71.                guchar *bgrout,
  72.                int     width,
  73.                int     bpp,
  74.                guchar *cmap,
  75.            int     ncolours)
  76. {
  77.   if (bpp == 1)
  78.     {
  79.       /* No alpha in image. */
  80.  
  81.       while (width > 0)
  82.     {
  83.       bgrout[2] = cmap[*indexed * 3 + 0];
  84.       bgrout[1] = cmap[*indexed * 3 + 1];
  85.       bgrout[0] = cmap[*indexed * 3 + 2];
  86.       bgrout += 3;
  87.       indexed ++;
  88.       width --;
  89.     }
  90.     }
  91.   else
  92.     {
  93.       /* Indexed alpha image. */
  94.  
  95.       while (width > 0)
  96.     {
  97.       bgrout[2] = cmap[indexed[0] * 3 + 0] * indexed[1] / 255 +
  98.         255 - indexed[1];
  99.       bgrout[1] = cmap[indexed[0] * 3 + 1] * indexed[1] / 255 +
  100.         255 - indexed[1];
  101.       bgrout[0] = cmap[indexed[0] * 3 + 2] * indexed[1] / 255 +
  102.         255 - indexed[1];
  103.       bgrout += 3;
  104.       indexed += bpp;
  105.       width --;
  106.     }
  107.     }
  108. }
  109.  
  110. static void
  111. rgb_to_bgr(guchar *rgbin,
  112.            guchar *bgrout,
  113.            int     width,
  114.            int     bpp,
  115.            guchar *cmap,
  116.        int       ncolours)
  117.  
  118. {
  119.   if (bpp == 3)
  120.     {
  121.       /* No alpha in image. */
  122.  
  123.       while (width > 0)
  124.     {
  125.       bgrout[2] = rgbin[0];
  126.       bgrout[1] = rgbin[1];
  127.       bgrout[0] = rgbin[2];
  128.       rgbin += 3;
  129.       bgrout += 3;
  130.       width --;
  131.     }
  132.     }
  133.   else
  134.     {
  135.       /* RGBA image. */
  136.  
  137.       while (width > 0)
  138.     {
  139.       bgrout[2] = rgbin[0] * rgbin[3] / 255 + 255 - rgbin[3];
  140.       bgrout[1] = rgbin[1] * rgbin[3] / 255 + 255 - rgbin[3];
  141.       bgrout[0] = rgbin[2] * rgbin[3] / 255 + 255 - rgbin[3];
  142.       rgbin += bpp;
  143.       bgrout += 3;
  144.       width --;
  145.     }
  146.     }
  147. }
  148.  
  149. /* Respond to a plug-in query. */
  150.  
  151. static void
  152. query(void)
  153. {
  154.   static GimpParamDef    print_args[] =
  155.   {
  156.     { GIMP_PDB_INT32,    "run_mode",    "Interactive, non-interactive" },
  157.     { GIMP_PDB_IMAGE,    "image",    "Input image" },
  158.     { GIMP_PDB_DRAWABLE,    "drawable",    "Input drawable" },
  159.     { GIMP_PDB_STRING,    "printer",    "Printer" },
  160.     { GIMP_PDB_STRING,    "ppd_file",    "PPD file" },
  161.     { GIMP_PDB_INT32,    "output_type",    "Output type (0 = gray, 1 = color)" },
  162.     { GIMP_PDB_STRING,    "resolution",    "Resolution (\"300\", \"720\", etc.)" },
  163.     { GIMP_PDB_STRING,    "media_size",    "Media size (\"Letter\", \"A4\", etc.)" },
  164.     { GIMP_PDB_STRING,    "media_type",    "Media type (\"Plain\", \"Glossy\", etc.)" },
  165.     { GIMP_PDB_STRING,    "media_source",    "Media source (\"Tray1\", \"Manual\", etc.)" },
  166.     { GIMP_PDB_INT32,    "brightness",    "Brightness (0-200%)" },
  167.     { GIMP_PDB_FLOAT,    "scaling",    "Output scaling (0-100%, -PPI)" },
  168.     { GIMP_PDB_INT32,    "orientation",    "Output orientation (-1 = auto, 0 = portrait, 1 = landscape)" },
  169.     { GIMP_PDB_INT32,    "left",        "Left offset (points, -1 = centered)" },
  170.     { GIMP_PDB_INT32,    "top",        "Top offset (points, -1 = centered)" }
  171.   };
  172.   static gint print_nargs = sizeof (print_args) / sizeof (print_args[0]);
  173.  
  174.   static GimpParamDef    pagesetup_args[] =
  175.   {
  176.     { GIMP_PDB_INT32,    "run_mode",    "Interactive, non-interactive" },
  177.     { GIMP_PDB_IMAGE,    "image",    "Input image" },
  178.     { GIMP_PDB_DRAWABLE,    "drawable",    "Input drawable" }
  179.   };
  180.   static gint pagesetup_nargs = (sizeof (pagesetup_args) /
  181.                  sizeof (pagesetup_args[0]));
  182.  
  183.   gimp_install_procedure (NAME_PRINT,
  184.               "This plug-in prints images from the GIMP.",
  185.               "Prints images to any printer recognized by Windows.",
  186.               "Tor Lillqvist <tml@iki.fi>",
  187.               "Copyright 1999 Tor Lillqvist",
  188.               "$Id: winprint.c,v 1.7 2000/08/24 17:53:31 tml Exp $",
  189.               N_("<Image>/File/Print"),
  190.               "RGB*,GRAY*,INDEXED*",
  191.               GIMP_PLUGIN,
  192.               print_nargs, 0,
  193.               print_args, NULL);
  194.  
  195.   gimp_install_procedure (NAME_PAGE_SETUP,
  196.               "This plug-in sets up the page for printing from the GIMP.",
  197.               "Sets up the page parameters for printing to any Windows printer.",
  198.               "Tor Lillqvist <tml@iki.fi>",
  199.               "Copyright 1999 Tor Lillqvist",
  200.               "$Id: winprint.c,v 1.7 2000/08/24 17:53:31 tml Exp $",
  201.               N_("<Image>/File/Page Setup"),
  202.               "RGB*,GRAY*,INDEXED*",
  203.               GIMP_PLUGIN,
  204.               pagesetup_nargs, 0,
  205.               pagesetup_args, NULL);
  206. }
  207.  
  208. /*
  209.  * 'run()' - Run the plug-in...
  210.  */
  211.  
  212. static void
  213. run (gchar   *name,
  214.      gint     nparams,
  215.      GimpParam  *param,
  216.      gint    *nreturn_vals,
  217.      GimpParam **return_vals)
  218. {
  219.   GimpDrawable    *drawable;
  220.   GimpRunModeType    run_mode;
  221.   GimpPDBStatusType   status = GIMP_PDB_SUCCESS;
  222.   GimpParam       *values;
  223.   GimpPixelRgn    rgn;
  224.   guchar       *cmap;        /* Colourmap (indexed images only) */
  225.   DEVMODE      *dmp;
  226.   int        ncolours;
  227.   int        width, height;
  228.   int        devWidth, devHeight;
  229.   int        y;
  230.   double    devY, devYstep;
  231.   int        iDevY, iDevYstep;
  232.   int        iDevLeftMargin, iDevTopMargin;
  233.   guchar       *inRow;
  234.   guchar       *bgrRow;
  235.   HGLOBAL    hDevMode, hDevNames;
  236.   DOCINFO    docInfo;
  237.   double    devResX, devResY;
  238.   double    imgResX, imgResY;
  239.   HDC        hdcMem;
  240.   HBITMAP    hBitmap;
  241.   HANDLE    oldBm;
  242.   BITMAPV4HEADER bmHeader;
  243.  
  244.   INIT_I18N();
  245.  
  246.   run_mode = param[0].data.d_int32;
  247.  
  248.   values = g_new(GimpParam, 1);
  249.  
  250.   values[0].type = GIMP_PDB_STATUS;
  251.  
  252.   *nreturn_vals = 1;
  253.   *return_vals  = values;
  254.  
  255.   hDevMode = NULL;
  256.   hDevNames = NULL;
  257.  
  258.   drawable = gimp_drawable_get(param[2].data.d_drawable);
  259.  
  260.   width  = drawable->width;
  261.   height = drawable->height;
  262.  
  263.   if (strcmp (name, NAME_PRINT) == 0)
  264.     {
  265.       switch (run_mode)
  266.     {
  267.     case GIMP_RUN_INTERACTIVE:
  268.       if (gimp_get_data_size (NAME_PRINT) > 0)
  269.         {
  270.           g_assert (gimp_get_data_size (NAME_PRINT) == sizeof (vars));
  271.           gimp_get_data (NAME_PRINT, &vars);
  272.           if (vars.devmodeSize > 0)
  273.         {
  274.           /* Restore saved DEVMODE. */
  275.           g_assert (gimp_get_data_size (NAME_PRINT "devmode")
  276.                 == vars.devmodeSize);
  277.           hDevMode = GlobalAlloc (GMEM_MOVEABLE, vars.devmodeSize);
  278.           g_assert (hDevMode != NULL);
  279.           dmp = GlobalLock (hDevMode);
  280.           g_assert (dmp != NULL);
  281.           gimp_get_data (NAME_PRINT "devmode", dmp);
  282.           GlobalUnlock (hDevMode);
  283.           vars.prDlg.hDevMode = hDevMode;
  284.         }
  285.           else
  286.         {
  287.           vars.prDlg.hDevMode = NULL;
  288.         }
  289.         }
  290.       else
  291.         vars.prDlg.Flags = 0;
  292.       vars.prDlg.hwndOwner = NULL;
  293.       vars.prDlg.hDevNames = NULL;
  294.       vars.prDlg.Flags |=
  295.         PD_RETURNDC | PD_DISABLEPRINTTOFILE | PD_HIDEPRINTTOFILE
  296.         | PD_NOSELECTION;
  297.       vars.prDlg.nMinPage = vars.prDlg.nMaxPage = 0;
  298.       vars.prDlg.nCopies = 1;
  299.       vars.prDlg.lStructSize = sizeof (PRINTDLG);
  300.       if (!PrintDlg (&vars.prDlg))
  301.         {
  302.           if (CommDlgExtendedError ())
  303.         g_message (_("PrintDlg failed: %d"),
  304.                CommDlgExtendedError ());
  305.           status = GIMP_PDB_EXECUTION_ERROR;
  306.           break;
  307.         }
  308.       hDevMode = vars.prDlg.hDevMode;
  309.       hDevNames = vars.prDlg.hDevNames;
  310.       break;
  311.  
  312.     case GIMP_RUN_NONINTERACTIVE:
  313.       if (nparams >= 3)    /* Printer name? */
  314.         {
  315.           
  316.         }
  317.       if (nparams >= 5)    /* PPD file */
  318.         {
  319.           /* Ignored */
  320.         }
  321.       status = GIMP_PDB_EXECUTION_ERROR;
  322.       break;
  323.  
  324.     default:
  325.       status = GIMP_PDB_CALLING_ERROR;
  326.       break;
  327.     }
  328.  
  329.       /*
  330.        * Print the image.
  331.        */
  332.  
  333.       if (status == GIMP_PDB_SUCCESS)
  334.     {
  335.       /* Check if support for BitBlt */
  336.       if (!(GetDeviceCaps(vars.prDlg.hDC, RASTERCAPS) & RC_BITBLT)) 
  337.         {
  338.           status = GIMP_PDB_EXECUTION_ERROR;
  339.           g_message (_("Printer doesn't support bitmaps"));
  340.         }
  341.     }
  342.  
  343.       if (status == GIMP_PDB_SUCCESS)
  344.     {
  345.       /* Set the tile cache size. */
  346.       
  347.       if (height > width)
  348.         gimp_tile_cache_ntiles((drawable->height + gimp_tile_width() - 1) /
  349.                    gimp_tile_width() + 1);
  350.       else
  351.         gimp_tile_cache_ntiles((width + gimp_tile_width() - 1) /
  352.                    gimp_tile_width() + 1);
  353.       
  354.       /* Is the image indexed?  If so we need the colourmap. */
  355.       
  356.       if (gimp_image_base_type(param[1].data.d_image) == GIMP_INDEXED)
  357.         cmap = gimp_image_get_cmap(param[1].data.d_image, &ncolours);
  358.       else
  359.         {
  360.           cmap = NULL;
  361.           ncolours = 0;
  362.         }
  363.       
  364.       /* Start print job. */
  365.       docInfo.cbSize = sizeof (DOCINFO);
  366.       docInfo.lpszDocName =
  367.         gimp_image_get_filename (param[1].data.d_image);
  368.       docInfo.lpszOutput = NULL;
  369.       docInfo.lpszDatatype = NULL;
  370.       docInfo.fwType = 0;
  371.  
  372.       if (StartDoc (vars.prDlg.hDC, &docInfo) == SP_ERROR)
  373.         status = GIMP_PDB_EXECUTION_ERROR;
  374.     }
  375.  
  376.       if (status == GIMP_PDB_SUCCESS)
  377.     {
  378.       /* Prepare printer to accept a page. */
  379.       if (StartPage (vars.prDlg.hDC) <= 0)
  380.         {
  381.           status = GIMP_PDB_EXECUTION_ERROR;
  382.           g_message (_("StartPage failed"));
  383.           AbortDoc (vars.prDlg.hDC);
  384.         }
  385.     }
  386.       
  387.       /* Actually print. */
  388.  
  389.       if (status == GIMP_PDB_SUCCESS)
  390.     {
  391.       gimp_progress_init(_("Printing..."));
  392.  
  393.       gimp_pixel_rgn_init(&rgn, drawable, 0, 0,
  394.                   width, height,
  395.                   FALSE, FALSE);
  396.  
  397.       inRow = g_malloc (width * drawable->bpp);
  398.  
  399.       hdcMem = CreateCompatibleDC (vars.prDlg.hDC);
  400.       
  401.       bmHeader.bV4Size = sizeof (BITMAPV4HEADER);
  402.       bmHeader.bV4Width = width;
  403.       bmHeader.bV4Height = -1;
  404.       bmHeader.bV4Planes = 1;
  405.       bmHeader.bV4BitCount = 24;
  406.       bmHeader.bV4V4Compression = BI_RGB;
  407.       bmHeader.bV4SizeImage = 0;
  408.       bmHeader.bV4XPelsPerMeter = 0;
  409.       bmHeader.bV4YPelsPerMeter = 0;
  410.       bmHeader.bV4ClrUsed = 0;
  411.       bmHeader.bV4ClrImportant = 0;
  412.       bmHeader.bV4CSType = 0;
  413.       
  414.       hBitmap = CreateDIBSection (hdcMem,
  415.                       (BITMAPINFO *) &bmHeader,
  416.                       DIB_RGB_COLORS,
  417.                       (PVOID *) &bgrRow,
  418.                       NULL,
  419.                       0);
  420.       if (hBitmap == NULL)
  421.         {
  422.           status = GIMP_PDB_EXECUTION_ERROR;
  423.           g_message (_("CreateDIBSection failed"));
  424.           AbortDoc (vars.prDlg.hDC);
  425.         }
  426.     }
  427.  
  428.       if (status == GIMP_PDB_SUCCESS)
  429.     {
  430.       void (*pixel_transfer)(guchar *, guchar *, int, int, guchar *, int);
  431.  
  432.       if (cmap != NULL)
  433.         pixel_transfer = indexed_to_bgr;
  434.       else
  435.         pixel_transfer = rgb_to_bgr;
  436.  
  437.       devResX = GetDeviceCaps(vars.prDlg.hDC, LOGPIXELSX); 
  438.       devResY = GetDeviceCaps(vars.prDlg.hDC, LOGPIXELSY); 
  439.       gimp_image_get_resolution (param[1].data.d_image,
  440.                      &imgResX, &imgResY);
  441.  
  442.       /* Here we assume that the printer's resolution is many
  443.        * times higher than the image's. Otherwise we probably
  444.        * get strange artefacts from StretchBlt'ing a row at
  445.        * a time, if each image row maps to a little over one
  446.        * printer row (or even less than one)?
  447.        */
  448.  
  449.       devWidth = (devResX / imgResX) * width;
  450.       devHeight = (devResY / imgResY) * height;
  451.       devYstep = (double) devHeight / height;
  452. #if 0
  453.       g_message ("devWidth = %d, devHeight = %d, devYstep = %g",
  454.              devWidth, devHeight, devYstep);
  455. #endif
  456.       if (!SetStretchBltMode (vars.prDlg.hDC, HALFTONE))
  457.         g_message (_("SetStretchBltMode failed (warning only)"));
  458.  
  459.       oldBm = SelectObject (hdcMem, hBitmap);
  460.       
  461.       if (vars.psDlg.Flags & PSD_MARGINS)
  462.         if (vars.psDlg.Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
  463.           {
  464.         /* Hundreths of millimeters */
  465.         iDevLeftMargin = vars.psDlg.rtMargin.left / 2540.0 * devResX;
  466.         iDevTopMargin = vars.psDlg.rtMargin.top / 2540.0 * devResY;
  467.           }
  468.         else
  469.           {
  470.         /* Thousandths of inches */
  471.         iDevLeftMargin = vars.psDlg.rtMargin.left / 1000.0 * devResX;
  472.         iDevTopMargin = vars.psDlg.rtMargin.top / 1000.0 * devResY;
  473.           }
  474.       else
  475.         iDevLeftMargin = iDevTopMargin = 0;
  476.  
  477.       devY = 0.0;
  478.       iDevY = 0;
  479.       for (y = 0; y < height; y++)
  480.         {
  481.           if ((y & 0x0F) == 0)
  482.         gimp_progress_update ((double)y / (double)drawable->height);
  483.  
  484.           gimp_pixel_rgn_get_row (&rgn, inRow, 0, y, width);
  485.  
  486.           (* pixel_transfer) (inRow, bgrRow, width, drawable->bpp, cmap, ncolours);
  487.           iDevYstep = ((int) (devY + devYstep)) - iDevY;
  488.           if (iDevYstep > 0)
  489.         {
  490.           /* StretchBlt seems to fail if we do it in "too large"
  491.            * pieces at a time, a least with my printer.
  492.            * Arbitrarily limit to 4000 destination columns
  493.            * at a time...
  494.            */
  495.           int x, iDevX, xstep, iDevXstep;
  496.  
  497.           iDevX = 0;
  498.           x = 0;
  499.           iDevXstep = 4000;
  500.           xstep = (imgResX / devResX ) * iDevXstep;
  501.           while (x <= width)
  502.             {
  503.               int w, devW;
  504.  
  505.               if (x + xstep > width)
  506.             w = width - x;
  507.               else
  508.             w = xstep;
  509.               if (iDevX + iDevXstep > devWidth)
  510.             devW = devWidth - iDevX;
  511.               else
  512.             devW = iDevXstep;
  513.               if (!StretchBlt (vars.prDlg.hDC,
  514.                        iDevX + iDevLeftMargin,
  515.                        iDevY + iDevTopMargin,
  516.                        devW, iDevYstep,
  517.                        hdcMem, x, 0, w, 1, SRCCOPY))
  518.             {
  519.               status = GIMP_PDB_EXECUTION_ERROR;
  520.               g_message (_("StretchBlt (hDC, %d, %d, "
  521.                        "%d, %d, "
  522.                        "hdcMem, %d, 0, %d, 1, SRCCOPY) "
  523.                        "failed, error = %d, y = %d"),
  524.                      iDevX, iDevY,
  525.                      devW, iDevYstep,
  526.                      x, w,
  527.                      GetLastError (), y);
  528.               AbortDoc (vars.prDlg.hDC);
  529.               break;
  530.             }
  531.               x += xstep;
  532.               iDevX += iDevXstep;
  533.             }
  534.         }
  535.           devY += devYstep;
  536.           iDevY += iDevYstep;
  537.         }
  538.  
  539.       SelectObject (hdcMem, oldBm);
  540.       DeleteObject (hBitmap);
  541.       gimp_progress_update (1.0);
  542.     }
  543.       
  544.       if (status == GIMP_PDB_SUCCESS)
  545.     {
  546.       if (EndPage (vars.prDlg.hDC) <= 0)
  547.         {
  548.           status = GIMP_PDB_EXECUTION_ERROR;
  549.           g_message (_("EndPage failed"));
  550.           EndDoc (vars.prDlg.hDC);
  551.         }
  552.     }
  553.  
  554.       if (status == GIMP_PDB_SUCCESS)
  555.     {
  556.       EndDoc (vars.prDlg.hDC);
  557.     }
  558.  
  559.       DeleteDC (vars.prDlg.hDC);
  560.     }
  561.   else if (strcmp (name, NAME_PAGE_SETUP) == 0)
  562.     {
  563.       switch (run_mode)
  564.     {
  565.     case GIMP_RUN_INTERACTIVE:
  566.       if (gimp_get_data_size (NAME_PRINT) > 0)
  567.         {
  568.           g_assert (gimp_get_data_size (NAME_PRINT) == sizeof (vars));
  569.           gimp_get_data (NAME_PRINT, &vars);
  570.           if (vars.devmodeSize > 0)
  571.         {
  572.           /* Restore saved DEVMODE. */
  573.           g_assert (gimp_get_data_size (NAME_PRINT "devmode")
  574.                 == vars.devmodeSize);
  575.           hDevMode = GlobalAlloc (GMEM_MOVEABLE, vars.devmodeSize);
  576.           g_assert (hDevMode != NULL);
  577.           dmp = GlobalLock (hDevMode);
  578.           g_assert (dmp != NULL);
  579.           gimp_get_data (NAME_PRINT "devmode", dmp);
  580.           GlobalUnlock (hDevMode);
  581.           vars.psDlg.hDevMode = hDevMode;
  582.         }
  583.           else
  584.         {
  585.           vars.psDlg.hDevMode = NULL;
  586.         }
  587.         }
  588.       else
  589.         vars.psDlg.Flags = 0;
  590.       vars.psDlg.hwndOwner = NULL;
  591.       vars.psDlg.hDevNames = NULL;
  592.       vars.psDlg.lStructSize = sizeof (PAGESETUPDLG);
  593.       if (!PageSetupDlg (&vars.psDlg))
  594.         {
  595.           if (CommDlgExtendedError ())
  596.         g_message (_("PageSetupDlg failed: %d"),
  597.                CommDlgExtendedError ());
  598.           status = GIMP_PDB_EXECUTION_ERROR;
  599.           break;
  600.         }
  601.       vars.psDlg.Flags |= PSD_MARGINS;
  602.       hDevMode = vars.psDlg.hDevMode;
  603.       hDevNames = vars.psDlg.hDevNames;
  604.       break;
  605.  
  606.     default:
  607.       status = GIMP_PDB_CALLING_ERROR;
  608.       break;
  609.     }
  610.     }
  611.   else
  612.     status = GIMP_PDB_CALLING_ERROR;
  613.  
  614.  
  615.   /* Store data. */
  616.   if (status == GIMP_PDB_SUCCESS && run_mode == GIMP_RUN_INTERACTIVE)
  617.     {
  618.       /* Save DEVMODE */
  619.       dmp = GlobalLock (hDevMode);
  620.       vars.devmodeSize = dmp->dmSize + dmp->dmDriverExtra;
  621. #if 0
  622.       g_message("vars.devmodeSize = %d, DeviceName = %.*s, Orientation = %s, PaperSize = %s, "
  623.         "Scale = %d%%, Copies = %d, PrintQuality = %s, "
  624.         "%s, ICMMethod = %s, ICMIntent = %s, MediaType = %s, "
  625.         "DitherType = %s",
  626.         vars.devmodeSize,
  627.         CCHDEVICENAME, dmp->dmDeviceName,
  628.         (dmp->dmOrientation == DMORIENT_PORTRAIT ? "PORTRAIT" :
  629.          (dmp->dmOrientation == DMORIENT_LANDSCAPE ? "LANDSCAPE" :
  630.           "?")),
  631.         (dmp->dmPaperSize == DMPAPER_LETTER ? "LETTER" :
  632.          (dmp->dmPaperSize == DMPAPER_LEGAL ? "LEGAL" :
  633.           (dmp->dmPaperSize == DMPAPER_A3 ? "A3" :
  634.            (dmp->dmPaperSize == DMPAPER_A4 ? "A4" :
  635.             "?"))))
  636.         ,
  637.         dmp->dmScale, dmp->dmCopies,
  638.         (dmp->dmPrintQuality == DMRES_HIGH ? "HIGH" :
  639.          (dmp->dmPrintQuality == DMRES_MEDIUM ? "MEDIUM" :
  640.           (dmp->dmPrintQuality == DMRES_LOW ? "LOW" :
  641.            (dmp->dmPrintQuality == DMRES_DRAFT ? "DRAFT" :
  642.             "?")))),
  643.         (dmp->dmColor == DMCOLOR_COLOR ? "COLOR" :
  644.          (dmp->dmColor == DMCOLOR_MONOCHROME ? "MONOCHROME" :
  645.           "?")),
  646.         (dmp->dmICMMethod == DMICMMETHOD_NONE ? "NONE" :
  647.          (dmp->dmICMMethod == DMICMMETHOD_SYSTEM ? "SYSTEM" :
  648.           (dmp->dmICMMethod == DMICMMETHOD_DRIVER ? "DRIVER" :
  649.            (dmp->dmICMMethod == DMICMMETHOD_DEVICE ? "DEVICE" :
  650.             "?")))),
  651.         (dmp->dmICMIntent == DMICM_CONTRAST ? "CONTRAST" :
  652.          (dmp->dmICMIntent == DMICM_SATURATE ? "SATURATE" :
  653.           "?")),
  654.         (dmp->dmMediaType == DMMEDIA_STANDARD ? "STANDARD" :
  655.          (dmp->dmMediaType == DMMEDIA_GLOSSY ? "GLOSSY" :
  656.           (dmp->dmMediaType == DMMEDIA_TRANSPARENCY ? "TRANSPARENCY" :
  657.            "?"))),
  658.         (dmp->dmDitherType == DMDITHER_NONE ? "NONE" :
  659.          (dmp->dmDitherType == DMDITHER_COARSE ? "COARSE" :
  660.           (dmp->dmDitherType == DMDITHER_FINE ? "FINE" :
  661.            (dmp->dmDitherType == DMDITHER_LINEART ? "LINEART" :
  662.             (dmp->dmDitherType == DMDITHER_ERRORDIFFUSION ? "ERRORDIFFUSION" :
  663.              (dmp->dmDitherType == DMDITHER_GRAYSCALE ? "GRAYSCALE" :
  664.              
  665.               "?")))))));
  666. #endif
  667.       gimp_set_data (NAME_PRINT "devmode", dmp, vars.devmodeSize);
  668.       GlobalUnlock (hDevMode);
  669.       gimp_set_data (NAME_PRINT, &vars, sizeof(vars));
  670.     }
  671.   
  672.   if (hDevMode != NULL)
  673.     GlobalFree (hDevMode);
  674.   if (hDevNames != NULL)
  675.     GlobalFree (hDevNames);
  676.  
  677.   values[0].data.d_status = status;
  678.   gimp_drawable_detach(drawable);
  679. }
  680.  
  681. GimpPlugInInfo    PLUG_IN_INFO =        /* Plug-in information */
  682. {
  683.   NULL,  /* init_proc  */
  684.   NULL,  /* quit_proc  */
  685.   query, /* query_proc */
  686.   run,   /* run_proc   */
  687. };
  688.  
  689. MAIN ()
  690.