home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / haswinlib / c / printer < prev    next >
Encoding:
Text File  |  1991-02-04  |  46.3 KB  |  1,124 lines

  1. /* > $.CLIB.C.printer
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *      Printer control routines.  Provide an interface to the central
  21.  *      printer drivers and the Acorn Printer applications.  
  22.  */
  23. #include "includes.h"
  24. #include <math.h>
  25. #define DEG_RAD        57.29577951307
  26.  
  27.        pdriver *haswin_pjob = 0;
  28. static window  *haswin_printwin = 0;
  29. static icon    *haswin_mugs = 0;
  30. static icon    *haswin_stat = 0;
  31. static icon    *haswin_wind = 0;
  32. static icon    *haswin_pict = 0;
  33. static icon    *haswin_name = 0;
  34. static icon    *haswin_file = 0;
  35. static icon    *haswin_titl = 0;
  36. static icon    *haswin_stop = 0;
  37. static icon    *haswin_cont = 0;
  38. static int     haswin_ended = HASWIN_FALSE;
  39. static double  haswin_punit = 1.0;
  40. static int     psetupmouse(icon *, buffer *);
  41. static int     psetupopen(window *, buffer *);
  42.  
  43. /*
  44.  *      Initialisation of the printer system.  We check that printer driver
  45.  *      SWIs exist and do the initialisation and then set the printer flag.
  46.  */
  47. int haswin_initialisepdriver(void) {
  48.  
  49.         int     oldflags;
  50.  
  51.         if (!haswin_doespdriverexist()) {
  52.                 haswin_flags &= ~HASWIN_FLAGS_PRINTER;
  53.                 return(HASWIN_FALSE);
  54.         }
  55.         haswin_flags |= HASWIN_FLAGS_PRINTER;
  56. /*
  57.  *      the printer has a little information window.  We look around for it
  58.  *      First in the existing windows, then the open template, then the
  59.  *      HASWIN system template file.
  60.  *      In the printer information window...
  61.  *
  62.  *      icon
  63.  *       0     - mugwatch icon.
  64.  *       1     - status string icon.
  65.  *       2     - window name icon.
  66.  *       3     - Print job title icon.
  67.  *       4     - Printer name icon.
  68.  *       5     - Printer file output icon.
  69.  *       6     - Printer picture icon (click to select printer details).
  70.  *       7     - Cancel (stop) icon.
  71.  *       8     - Continue icon.
  72.  */
  73.         if ((haswin_printwin=haswin_findwindowname("printer")) == 0) {
  74.                 oldflags = haswin_flags & HASWIN_FLAGS_VERBOSE;
  75.                 haswin_flags &= ~HASWIN_FLAGS_VERBOSE;
  76.                 if ((haswin_printwin=haswin_loadwindow("printer",SPRITE_HASWIN_AREA)) == 0) {
  77.                         haswin_pushtemplate(HASWIN_TEMPLATEFILE);
  78.                         if ((haswin_printwin=haswin_loadwindow("printer",SPRITE_HASWIN_AREA)) == 0) {
  79.                                 haswin_poptemplate();
  80.                                 haswin_flags |= oldflags;
  81.                                 return(HASWIN_FALSE);
  82.                         }
  83.                         haswin_poptemplate();
  84.                 }
  85.                 haswin_flags |= oldflags;
  86.                 haswin_mugs = haswin_findiconhandle(haswin_printwin, 0);
  87.                 haswin_stat = haswin_findiconhandle(haswin_printwin, 1);
  88.                 haswin_wind = haswin_findiconhandle(haswin_printwin, 2);
  89.                 haswin_titl = haswin_findiconhandle(haswin_printwin, 3);
  90.                 haswin_name = haswin_findiconhandle(haswin_printwin, 4);
  91.                 haswin_file = haswin_findiconhandle(haswin_printwin, 5);
  92.                 haswin_pict = haswin_findiconhandle(haswin_printwin, 6);
  93.                 haswin_stop = haswin_findiconhandle(haswin_printwin, 7);
  94.                 haswin_cont = haswin_findiconhandle(haswin_printwin, 8);
  95. /*
  96.  *      the printer has selection window.  We look for it first in the
  97.  *      existing windows, then the HASWIN system template file.
  98.  *      In the printer selection window...
  99.  *
  100.  *      icon
  101.  *       0     - direction
  102.  *       1     - paper hieght.
  103.  *       2     - paper width.
  104.  *       3     - print area left margin.
  105.  *       4     - print area right margin.
  106.  *       5     - print area top margin.
  107.  *       6     - print area bottom margin.
  108.  *       7     - Scale X direction.
  109.  *       8     - Scale Y direction.
  110.  *       9     - OK icon.
  111.  *      10     - Rotation icon.
  112.  */
  113.                 if ((haswin_pict->window=haswin_findwindowname("printset")) == 0) {
  114.                         oldflags = haswin_flags & HASWIN_FLAGS_VERBOSE;
  115.                         haswin_flags &= ~HASWIN_FLAGS_VERBOSE;
  116.                         haswin_pushtemplate(HASWIN_TEMPLATEFILE);
  117.                         haswin_pict->window = haswin_loadwindow("printset",
  118.                                                       SPRITE_HASWIN_AREA);
  119.                         haswin_poptemplate();
  120.                         haswin_flags |= oldflags;
  121.                 }
  122.                 if (haswin_pict->window) {
  123.                         haswin_pict->window->openroutine = psetupopen;
  124.                         haswin_findiconhandle(haswin_pict->window,0)->mousebutton = psetupmouse;
  125.                         haswin_findiconhandle(haswin_pict->window,1)->mousebutton = psetupmouse;
  126.                         haswin_findiconhandle(haswin_pict->window,2)->mousebutton = psetupmouse;
  127.                         haswin_findiconhandle(haswin_pict->window,3)->mousebutton = psetupmouse;
  128.                         haswin_findiconhandle(haswin_pict->window,4)->mousebutton = psetupmouse;
  129.                         haswin_findiconhandle(haswin_pict->window,5)->mousebutton = psetupmouse;
  130.                         haswin_findiconhandle(haswin_pict->window,6)->mousebutton = psetupmouse;
  131.                         haswin_findiconhandle(haswin_pict->window,7)->mousebutton = psetupmouse;
  132.                         haswin_findiconhandle(haswin_pict->window,8)->mousebutton = psetupmouse;
  133.                         haswin_findiconhandle(haswin_pict->window,9)->mousebutton = psetupmouse;
  134.                         haswin_findiconhandle(haswin_pict->window,10)->mousebutton = psetupmouse;
  135.                         haswin_findiconhandle(haswin_pict->window,11)->mousebutton = psetupmouse;
  136.                         haswin_pict->window->openroutine = psetupopen;
  137.                 }
  138.         }
  139.         haswin_pjob = haswin_getpdriverinfo(haswin_pjob);
  140.         return(HASWIN_TRUE);
  141. }
  142.  
  143. /*
  144.  *      Does the Printer Driver exist?.
  145.  */
  146. int haswin_doespdriverexist(void) {
  147.  
  148.         _kernel_swi_regs        regs;
  149.  
  150.         if (_kernel_swi(SWI_X|HASWIN_PD_Info, ®s, ®s))
  151.                 return(HASWIN_FALSE);
  152.         return(HASWIN_TRUE);
  153. }
  154.  
  155. void haswin_pdriverclosedown() {
  156.  
  157.         _kernel_swi_regs        regs;
  158.  
  159.         if (!haswin_doespdriverexist()) {
  160.                 if ((haswin_pjob) && (haswin_pjob->jobid)) {
  161.                         regs.r[0] = 0;
  162.                         regs.r[1] = haswin_pjob->jobid;
  163.                         haswin_swi(SWI_X|OS_Find, ®s);
  164.                 }
  165.                 haswin_pjob = 0;
  166.                 haswin_flags &= ~HASWIN_FLAGS_PRINTER;
  167.                 return;
  168.         }
  169.         if (haswin_pjob) {
  170.                 if (haswin_pjob->jobid) {
  171.                         regs.r[0] = haswin_pjob->jobid;
  172.                         haswin_swi(SWI_X|HASWIN_PD_AbortJob, ®s);
  173.                         regs.r[0] = 0;
  174.                         regs.r[1] = haswin_pjob->jobid;
  175.                         haswin_swi(OS_Find, ®s);
  176.                 }
  177.                 if (haswin_pjob->fname)
  178.                         haswin_free(haswin_pjob->fname);
  179.                 if (haswin_pjob->title)
  180.                         haswin_free(haswin_pjob->title);
  181.                 haswin_free(haswin_pjob);
  182.         }
  183. }
  184.  
  185. /*
  186.  *      Get information on the printer driver.
  187.  */
  188. pdriver *haswin_getpdriverinfo(pdriver *prt) {
  189.  
  190.         _kernel_swi_regs        regs;
  191.         int                     new = HASWIN_FALSE;
  192.  
  193.         if (!(haswin_flags & HASWIN_FLAGS_PRINTER))
  194.                 return(0);
  195.         if (!prt) {
  196.                 prt=haswin_malloc(sizeof(pdriver), "haswin_getprinterinfo", "printer data block");
  197.                 new = HASWIN_TRUE;
  198.         }
  199.         if (!haswin_swi(HASWIN_PD_Info, ®s)) {
  200.                 haswin_pdriverclosedown();
  201.                 return(HASWIN_FALSE);
  202.         }
  203.         prt->version  = regs.r[0];
  204.         prt->xres     = regs.r[1];
  205.         prt->yres     = regs.r[2];
  206.         prt->features = regs.r[3];
  207.         prt->name     = (char *)regs.r[4];
  208.         prt->xhres    = regs.r[5];
  209.         prt->yhres    = regs.r[6];
  210.         prt->ident    = regs.r[7];
  211.         if (!haswin_swi(HASWIN_PD_PageSize, ®s)) {
  212.                 haswin_pdriverclosedown();
  213.                 return(HASWIN_FALSE);
  214.         }
  215.         prt->xpaper   = regs.r[1];
  216.         prt->ypaper   = regs.r[2];
  217.         prt->lprint   = regs.r[3];
  218.         prt->bprint   = regs.r[4];
  219.         prt->rprint   = regs.r[5];
  220.         prt->tprint   = regs.r[6];
  221.         if (new) {
  222.                 prt->rotate   = 0;
  223.                 prt->xscale   = 1<<16;
  224.                 prt->yscale   = 1<<16;
  225.                 prt->jobid    = 0;
  226.                 prt->title    = 0;
  227.                 prt->fname    = 0;
  228.                 prt->xsize    = HASWIN_UNKNOWN;
  229.                 prt->ysize    = HASWIN_UNKNOWN;
  230.         }
  231.         return(prt);
  232. }
  233.  
  234. /*
  235.  *      add a new printer driver job to the linked list.  Note that we have
  236.  *      to use direct RISCOS calls to open files cos we need the file handle
  237.  *      and can't use "stdio".
  238.  */
  239. pdriver *haswin_pdrivermakejob(char *fname, char *title, pdriver *prt) {
  240.  
  241.  
  242.         if ((!fname) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
  243.                 return(0);
  244.         if ((prt=haswin_getpdriverinfo(prt)) == 0)
  245.                 return(0);
  246.         if ((prt->title=haswin_malloc(strlen(title)+1,"haswin_makenewjob","title data block")) == 0) {
  247.                 haswin_free(prt);
  248.                 return(0);
  249.         }
  250.         strcpy(prt->title, title);
  251.         if ((prt->fname=haswin_malloc(strlen(fname)+1,"haswin_makenewjob","filename data block")) == 0) {
  252.                 haswin_free(prt->title);
  253.                 haswin_free(prt);
  254.                 return(0);
  255.         }
  256.         strcpy(prt->fname, fname);
  257.         return(prt);
  258. }
  259.  
  260. /*
  261.  *      abort this printer job and remove it from the linked list of
  262.  *      printer jobs and delete the job.
  263.  */
  264. int haswin_pdriverkilljob(pdriver *prt) {
  265.  
  266.         _kernel_swi_regs        regs;
  267.  
  268.         if ((!prt) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
  269.                 return(HASWIN_FALSE);
  270.         if (prt->jobid) {
  271.                 /*
  272.                  * job has been started sometime and has a file, stop the
  273.                  * job and close the file.
  274.                  */
  275.                 regs.r[0] = prt->jobid;
  276.                 if (!haswin_swi(HASWIN_PD_AbortJob, ®s)) {
  277.                         haswin_pdriverclosedown();
  278.                         return(HASWIN_FALSE);
  279.                 }
  280.                 regs.r[0] = 0;
  281.                 regs.r[1] = prt->jobid;
  282.                 haswin_swi(OS_Find, ®s);
  283.         }
  284.         haswin_free(prt->fname);
  285.         haswin_free(prt->title);
  286.         haswin_free(prt);
  287.         return(HASWIN_TRUE);
  288. }
  289.  
  290. /*
  291.  *      this print job is finished.  Don't close the file, just in case
  292.  *      the printer driver is going to print some more.
  293.  */
  294. int haswin_pdriverendjob(pdriver *prt) {
  295.  
  296.         _kernel_swi_regs        regs;
  297.  
  298.         if ((!prt) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
  299.                 return(HASWIN_FALSE);
  300.         if (prt->jobid) {
  301.                 /*
  302.                  * job has been started sometime and has a file, stop the
  303.                  * job and leave the file.
  304.                  */
  305.                 regs.r[0] = prt->jobid;
  306.                 if (!haswin_swi(HASWIN_PD_EndJob, ®s)) {
  307.                         haswin_pdriverclosedown();
  308.                         return(HASWIN_FALSE);
  309.                 }
  310.                 regs.r[0] = 0;
  311.                 regs.r[1] = prt->jobid;
  312.                 haswin_swi(OS_Find, ®s);
  313.         }
  314.         haswin_free(prt->fname);
  315.         haswin_free(prt->title);
  316.         haswin_free(prt);
  317.         return(HASWIN_TRUE);
  318. }
  319.  
  320. /*
  321.  *      this print job is cancelled, dont do anything else.
  322.  */
  323. int haswin_pdrivercanceljob(pdriver *prt) {
  324.  
  325.         _kernel_swi_regs        regs;
  326.  
  327.         if ((!prt) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
  328.                 return(HASWIN_FALSE);
  329.         if (prt->jobid) {
  330.                 /*
  331.                  * job has been started sometime and has a file, stop the
  332.                  * job and leave the file.
  333.                  */
  334.                 regs.r[0] = prt->jobid;
  335.                 if (!haswin_swi(HASWIN_PD_CancelJob, ®s)) {
  336.                         haswin_pdriverclosedown();
  337.                         return(HASWIN_FALSE);
  338.                 }
  339.         }
  340.         return(HASWIN_TRUE);
  341. }
  342.  
  343. /*
  344.  *      select the given job and return the job number of the old job
  345.  *      or HASWIN_UNKNOWN on an error.
  346.  */
  347. int haswin_pdriverselectjob(pdriver *prt) {
  348.  
  349.         _kernel_swi_regs        regs;
  350.         int                     id;
  351.  
  352.         if (!(haswin_flags & HASWIN_FLAGS_PRINTER))
  353.                 return(HASWIN_UNKNOWN);
  354.         if (!prt) {
  355.                 regs.r[0] = 0;
  356.                 if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
  357.                         haswin_pdriverclosedown();
  358.                         return(HASWIN_UNKNOWN);
  359.                 }
  360.                 return(regs.r[0]);
  361.         }
  362.         if (!prt->jobid) {
  363.                 /*
  364.                  *      selecting job for the first time, open the file
  365.                  */
  366.                 regs.r[0] = 0x84;
  367.                 regs.r[1] = (int)prt->fname;
  368.                 regs.r[2] = 0;
  369.                 haswin_swi(OS_Find, ®s);
  370.                 if (regs.r[0] <= 0)
  371.                         return(HASWIN_UNKNOWN);
  372.                 id = regs.r[0];
  373.                 regs.r[1] = (int)prt->title;
  374.                 if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
  375.                         haswin_pdriverclosedown();
  376.                         return(HASWIN_UNKNOWN);
  377.                 }
  378.                 prt->jobid = id;
  379.                 return(regs.r[0]);
  380.         }
  381.         regs.r[0] = prt->jobid;
  382.         regs.r[1] = 0;
  383.         if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
  384.                 haswin_pdriverclosedown();
  385.                 return(HASWIN_UNKNOWN);
  386.         }
  387.         return(regs.r[0]);
  388. }
  389.  
  390.  
  391. /*
  392.  *      select the given job number and return the job number of the old job
  393.  *      or HASWIN_UNKNOWN on an error.  Since this is not given a job
  394.  *      structure it cannot open the file or anything.
  395.  */
  396. int haswin_pdriverselect(int jobid) {
  397.  
  398.         _kernel_swi_regs        regs;
  399.  
  400.         if (!(haswin_flags & HASWIN_FLAGS_PRINTER))
  401.                 return(HASWIN_UNKNOWN);
  402.         regs.r[0] = jobid;
  403.         if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
  404.                 haswin_pdriverclosedown();
  405.                 return(HASWIN_UNKNOWN);
  406.         }
  407.         return(regs.r[0]);
  408. }
  409.  
  410. /*
  411.  *
  412.  *
  413.  */
  414. static int psetupopen(window *win, buffer *buff) {
  415.  
  416.         char    tmp[16];
  417.         double  scaler;
  418.  
  419.         if (haswin_punit == 1.0)
  420.                 haswin_seticondata(haswin_findiconhandle(win,11), "inches");
  421.         else if (haswin_punit == 0.3937)
  422.                 haswin_seticondata(haswin_findiconhandle(win,11), "cm");
  423.         else
  424.                 haswin_seticondata(haswin_findiconhandle(win,11), "??");
  425.  
  426.         if (!haswin_pjob) {
  427.                 strcpy(tmp, "???");
  428.                 haswin_seticondata(haswin_findiconhandle(win,0),"printport");
  429.                 haswin_seticondata(haswin_findiconhandle(win, 1), tmp);
  430.                 haswin_seticondata(haswin_findiconhandle(win, 2), tmp);
  431.                 haswin_seticondata(haswin_findiconhandle(win, 3), tmp);
  432.                 haswin_seticondata(haswin_findiconhandle(win, 4), tmp);
  433.                 haswin_seticondata(haswin_findiconhandle(win, 5), tmp);
  434.                 haswin_seticondata(haswin_findiconhandle(win, 6), tmp);
  435.                 haswin_seticondata(haswin_findiconhandle(win, 7), tmp);
  436.                 haswin_seticondata(haswin_findiconhandle(win, 8), tmp);
  437.                 haswin_seticondata(haswin_findiconhandle(win, 13), "?");
  438.                 haswin_seticondata(haswin_findiconhandle(win, 14), "?");
  439.                 return(HASWIN_TRUE);
  440.         }
  441.         if ((haswin_pjob->rotate > 315) || (haswin_pjob->rotate < 45))
  442.                 haswin_seticondata(haswin_findiconhandle(win,0),"printdir0");
  443.         else if (haswin_pjob->rotate < 135)
  444.                 haswin_seticondata(haswin_findiconhandle(win,0),"printdir1");
  445.         else if (haswin_pjob->rotate < 225)
  446.                 haswin_seticondata(haswin_findiconhandle(win,0),"printdir2");
  447.         else 
  448.                 haswin_seticondata(haswin_findiconhandle(win,0),"printdir3");
  449.         scaler = 72000.0*haswin_punit;
  450.         sprintf(tmp, "%.2f", haswin_pjob->ypaper/scaler);
  451.         haswin_seticondata(haswin_findiconhandle(win, 1), tmp);
  452.         sprintf(tmp, "%.2f", haswin_pjob->xpaper/scaler);
  453.         haswin_seticondata(haswin_findiconhandle(win, 2), tmp);
  454.         sprintf(tmp, "%.2f", haswin_pjob->lprint/scaler);
  455.         haswin_seticondata(haswin_findiconhandle(win, 3), tmp);
  456.         sprintf(tmp, "%.2f", haswin_pjob->rprint/scaler);
  457.         haswin_seticondata(haswin_findiconhandle(win, 4), tmp);
  458.         sprintf(tmp, "%.2f", haswin_pjob->tprint/scaler);
  459.         haswin_seticondata(haswin_findiconhandle(win, 5), tmp);
  460.         sprintf(tmp, "%.2f", haswin_pjob->bprint/scaler);
  461.         haswin_seticondata(haswin_findiconhandle(win, 6), tmp);
  462.         sprintf(tmp, "%.3f", haswin_pjob->xscale/65536.0);
  463.         haswin_seticondata(haswin_findiconhandle(win, 7), tmp);
  464.         sprintf(tmp, "%.3f", haswin_pjob->yscale/65536.0);
  465.         haswin_seticondata(haswin_findiconhandle(win, 8), tmp);
  466.         sprintf(tmp, "%3.3d", haswin_pjob->rotate);
  467.         haswin_seticondata(haswin_findiconhandle(win, 10), tmp);
  468.         if (haswin_pjob->ysize > 0) {
  469.                 sprintf(tmp, "%.2f", haswin_pjob->ysize/scaler);
  470.                 haswin_seticondata(haswin_findiconhandle(win, 13), tmp);
  471.         } else
  472.                 haswin_seticondata(haswin_findiconhandle(win, 13), "?");
  473.         if (haswin_pjob->xsize > 0) {
  474.                 sprintf(tmp, "%.2f", haswin_pjob->xsize/scaler);
  475.                 haswin_seticondata(haswin_findiconhandle(win, 14), tmp);
  476.         } else
  477.                 haswin_seticondata(haswin_findiconhandle(win, 14), "?");
  478.         return(HASWIN_TRUE);
  479. }
  480.  
  481. /*
  482.  *      called by icon selections in the printer selection window
  483.  */
  484. static int psetupmouse(icon *ic, buffer *buff) {
  485.  
  486.         int     i;
  487.         double  f;
  488.  
  489.         if (ic->whandle != haswin_pict->window->handle)
  490.                 return(HASWIN_FALSE);
  491.         switch (ic->ihandle) {
  492.         case  0: /* portrat/landscape selection */
  493.                 haswin_pjob->rotate = ((haswin_pjob->rotate/90)+1)*90 % 360;
  494.                 break;
  495.         case  1: /* paper hieght selection */
  496.                 f = atof(haswin_geticontitle(ic));
  497.                 if (f > 0)
  498.                         haswin_pjob->ypaper = (int)(f*72000.0*haswin_punit);
  499.                 break;
  500.         case  2: /* paper width selection */
  501.                 f = atof(haswin_geticontitle(ic));
  502.                 if (f > 0)
  503.                         haswin_pjob->xpaper = (int)(f*72000.0*haswin_punit);
  504.                 break;
  505.         case  3: /* print area left margin selection */
  506.                 f = atof(haswin_geticontitle(ic));
  507.                 if (f > 0)
  508.                         haswin_pjob->lprint = (int)(f*72000.0*haswin_punit);
  509.                 break;
  510.         case  4: /* print area right margin selection */
  511.                 f = atof(haswin_geticontitle(ic));
  512.                 if (f > 0)
  513.                         haswin_pjob->rprint = (int)(f*72000.0*haswin_punit);
  514.                 break;
  515.         case  5: /* print area top margin selection */
  516.                 f = atof(haswin_geticontitle(ic));
  517.                 if (f > 0)
  518.                         haswin_pjob->tprint = (int)(f*72000.0*haswin_punit);
  519.                 break;
  520.         case  6: /* print area bottom margin selection */
  521.                 f = atof(haswin_geticontitle(ic));
  522.                 if (f > 0)
  523.                         haswin_pjob->bprint = (int)(f*72000.0*haswin_punit);
  524.                 break;
  525.         case  7: /* X scale selection */
  526.                 f = atof(haswin_geticontitle(ic));
  527.                 if (f)
  528.                         haswin_pjob->xscale = (int)(f*65536.0*haswin_punit);
  529.                 break;
  530.         case  8: /* Y scale selection */
  531.                 f = atof(haswin_geticontitle(ic));
  532.                 if (f)
  533.                         haswin_pjob->yscale = (int)(f*65536.0*haswin_punit);
  534.                 break;
  535.         case  9: /* OK icon selection */
  536.                 haswin_closewindow(haswin_pict->window);
  537.                 return(HASWIN_TRUE);
  538.         case 10: /* Rotate icon selection */
  539.                 /* can only do this if driver can do arbitary
  540.                    transformations */
  541.                 i = atoi(haswin_geticontitle(ic)) % 360;
  542.                 if (!(haswin_pjob->features & 0x02000000)) {
  543.                         i = i/90;
  544.                         i = i*90;
  545.                 }
  546.                 if (i >= 0)
  547.                         haswin_pjob->rotate = i;
  548.                 break;
  549.         case 11: /* change units */
  550.                 if (haswin_punit == 1.0)
  551.                         haswin_punit = 0.3937;
  552.                 else
  553.                         haswin_punit = 1.00;
  554.         }
  555.         psetupopen(haswin_pict->window, 0);
  556.         return(HASWIN_TRUE);
  557. }
  558.  
  559. static int printmousebutton(icon *ic, buffer *buff) {
  560.  
  561.         if ((ic == haswin_stop) || (ic == haswin_cont)) {
  562.                 haswin_ended = HASWIN_TRUE;
  563.                 return(HASWIN_TRUE);
  564.         }
  565.         return(HASWIN_FALSE);
  566. }
  567.  
  568. static void haswin_awaitterminate(void) {
  569.  
  570.         haswin_reopenwindow(haswin_printwin);
  571.         haswin_ended = HASWIN_FALSE;
  572.         haswin_seticonbcol(haswin_cont, 11);
  573.         haswin_seticonfcol(haswin_cont,  9);
  574.         haswin_cont->mousebutton = printmousebutton;
  575.         haswin_stop->mousebutton = 0;
  576.         while (!haswin_ended) {
  577.                 haswin_seticonbcol(haswin_cont, 11);
  578.                 haswin_seticonfcol(haswin_cont,  9);
  579.                 haswin_poll();
  580.                 haswin_seticonbcol(haswin_cont,  9);
  581.                 haswin_seticonfcol(haswin_cont, 11);
  582.                 haswin_poll();
  583.         }
  584.         haswin_ended = HASWIN_FALSE;
  585.         haswin_seticonbcol(haswin_cont, 1);
  586.         haswin_seticonfcol(haswin_cont, 1);
  587.         haswin_cont->mousebutton = 0;
  588.         haswin_stop->mousebutton = printmousebutton;
  589.         haswin_closewindow(haswin_pict->window);
  590.         haswin_closewindow(haswin_printwin);
  591.         return;
  592. }
  593.  
  594.  
  595. /*
  596.  *      do the mugwatch bits for the print status window.
  597.  */
  598. static void _haswin_printmugwatch(int onoff) {
  599.  
  600. static  char    spin[] = "rotor_0";
  601.  
  602.         if (!onoff)
  603.                 spin[6] = '0';
  604.         else if (++spin[6] >= '9')
  605.                 spin[6] = '1';
  606.         haswin_seticondata(haswin_mugs, spin);
  607. }
  608. /*
  609.  *      recursive search of all window panes and slides attacted to
  610.  *      the window "wptr".  Add these to the print job that must
  611.  *      be open.  Internal routine used ONLY by haswin_printwindow().
  612.  *      Returns number of windows scanned at each level, or -1 for error.
  613.  *      -1 is passed back though recursion levels.
  614.  */
  615. static int _haswin_printwindow1(window *wptr, int *trans, int l, int b, int xm, int ym) {
  616.  
  617.         int                     rect[4];
  618.         int                     plotpos[2], xpos, ypos;
  619.         int                     ans, winnum;
  620.         _kernel_swi_regs        regs;
  621.  
  622.         haswin_pollcomplete();
  623.         if (haswin_ended) {
  624.                 haswin_pdriverkilljob(haswin_pjob);
  625.                 haswin_seticondata(haswin_stat, "Job Cancelled");
  626.                 haswin_awaitterminate();
  627.                 haswin_closewindow(haswin_printwin);
  628.                 haswin_pjob = 0;
  629.                 return(-1);
  630.         }
  631.         if (!wptr)
  632.                 return(-1);
  633.         winnum = 1;
  634.         haswin_updatewindowinfo(wptr);
  635.         rect[0] = -4;
  636.         rect[1] = -4;
  637.         rect[2] = haswin_getwindowxextent(wptr)+4;
  638.         rect[3] = haswin_getwindowyextent(wptr)+4;
  639.         /* adjust the plot position for the transformation matrix */
  640.         xpos = haswin_getwindowxmin(wptr)*400;
  641.         ypos = haswin_getwindowymin(wptr)*400;
  642.         plotpos[0] =
  643.              l +(int)(xpos*(trans[0]/65536.0)+ypos*(trans[2]/65536.0)) -xm;
  644.         plotpos[1] =
  645.              b +(int)(xpos*(trans[1]/65536.0)+ypos*(trans[3]/65536.0)) -ym;
  646.         regs.r[0] = (int)wptr; /* the identifier is the window */
  647.         regs.r[1] = (int)rect;
  648.         regs.r[2] = (int)trans;
  649.         regs.r[3] = (int)plotpos;
  650.         regs.r[4] = 0xFFFFFF00;
  651.         if (!haswin_swi(HASWIN_PD_GiveRectangle, ®s))
  652.                 return(-1);
  653.         if (wptr->pane) {
  654.                 ans = _haswin_printwindow1(wptr->pane, trans, l, b, xm, ym);
  655.                 if (ans == -1)
  656.                         return(-1);
  657.                 winnum += ans;
  658.         }
  659.         if (wptr->slide) {
  660.                 ans = _haswin_printwindow1(wptr->slide, trans, l, b, xm, ym);
  661.                 if (ans == -1)
  662.                         return(-1);
  663.                 winnum += ans;
  664.         }
  665.         return(winnum);
  666. }
  667.  
  668. /*
  669.  *      create a printer job to print the window given.  Call the printer
  670.  *      to print the job and remember also to print slides and panes.  Try
  671.  *      to get the slides and panes in the correct orders, but it is
  672.  *      difficult.  Remarkably enough this routine seems to be able to cope
  673.  *      with windows bigger than the real screen.
  674.  */
  675. int haswin_printwindow(window *win, char *fname, char *title) {
  676.  
  677.         int                     oldjob,rect[4],trans[4],winnum,more,tmpjob;
  678.         int                     xmin,ymin,xmax,ymax,txmin,tymin,txmax,tymax;
  679.         double                  f, g;
  680.         int                     *sarea = 0;
  681.         char                    sname[64];
  682.         buffer                  buff;
  683.         _kernel_swi_regs        regs;
  684.         icon                    *ic;
  685.         window                  *wptr;
  686.  
  687.         if (!haswin_doespdriverexist()) {
  688.                 haswin_flags &= ~HASWIN_FLAGS_PRINTER;
  689.                 return(HASWIN_FALSE);
  690.         }
  691.         if (!fname)
  692.                 fname = "printer:";
  693.         if (!title)
  694.                 title = haswin_getwindowtitle(win);
  695.         haswin_pjob=haswin_getpdriverinfo(haswin_pjob);
  696.         if (!(haswin_pjob)) {
  697.                 haswin_reopenwindow(haswin_printwin);
  698.                 haswin_seticondata(haswin_name, "<Unknown>");
  699.                 haswin_seticondata(haswin_file, fname);
  700.                 haswin_seticondata(haswin_titl, title);
  701.                 haswin_seticondata(haswin_wind, haswin_getwindowtitle(win));
  702.                 haswin_seticondata(haswin_stat, "Cannot Start Job");
  703.                 haswin_awaitterminate();
  704.                 return(HASWIN_FALSE);
  705.         }
  706.         if ((haswin_pjob) && (haswin_pjob->jobid)) {
  707.                 haswin_reopenwindow(haswin_printwin);
  708.                 strcpy(sname, haswin_geticontitle(haswin_stat));
  709.                 haswin_seticondata(haswin_name, "<Unknown>");
  710.                 haswin_seticondata(haswin_file, fname);
  711.                 haswin_seticondata(haswin_titl, title);
  712.                 haswin_seticondata(haswin_stat, "Already Printing A Job");
  713.                 haswin_awaitterminate();
  714.                 haswin_seticondata(haswin_file, haswin_pjob->fname);
  715.                 haswin_seticondata(haswin_name, haswin_pjob->name);
  716.                 haswin_seticondata(haswin_titl, haswin_pjob->title);
  717.                 haswin_seticondata(haswin_stat, sname);
  718.                 haswin_reopenwindow(haswin_printwin);
  719.                 return(HASWIN_FALSE);
  720.         }
  721.         if (!win) {
  722.                 return(HASWIN_FALSE);
  723.         }
  724.         haswin_ended = HASWIN_FALSE;
  725.         haswin_stop->mousebutton = printmousebutton;
  726.         haswin_seticondata(haswin_file, fname);
  727.         haswin_seticondata(haswin_titl, title);
  728.         haswin_seticondata(haswin_name, "");
  729.         haswin_seticondata(haswin_wind, "");
  730.         haswin_seticondata(haswin_stat, "Ready to Print");
  731.         haswin_seticondata(haswin_cont, "Go");
  732.         haswin_awaitterminate();
  733.         haswin_seticondata(haswin_cont, "Abort");
  734.         haswin_reopenwindow(haswin_printwin);
  735.         haswin_pollcomplete();
  736.         _haswin_printmugwatch(HASWIN_FALSE);
  737.         if ((haswin_pjob=haswin_pdrivermakejob(fname, title, haswin_pjob)) == 0) {
  738.                 haswin_seticondata(haswin_name, "<Not Known>");
  739.                 haswin_seticondata(haswin_stat, "Cannot Create Job");
  740.                 haswin_awaitterminate();
  741.                 haswin_closewindow(haswin_printwin);
  742.                 return(HASWIN_FALSE);
  743.         }
  744.         haswin_seticondata(haswin_name, haswin_pjob->name);
  745.         haswin_seticondata(haswin_stat, "Scaning Job Windows");
  746.         haswin_pollcomplete();
  747.         /*
  748.          *      First pass through the windows.  This does two jobs.
  749.          *      1)  get the overall rectangle for the windows, so we can
  750.          *          scale the picture later.
  751.          *      2)  turn all the icons into sprites named from the address
  752.          *          of their ic structures so we can draw them later.
  753.          */
  754.         /* reserve 100K for sprites in these windows. */
  755.         sarea = haswin_clearsprites(102400, 0);
  756.         haswin_addspritearea(&sarea);
  757.         xmin = 0x7FFFFFFF;
  758.         xmax = 0;
  759.         ymin = 0x7FFFFFFF;
  760.         ymax = 0;
  761.         for (wptr=win; wptr; wptr=wptr->slide) {
  762.                 haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
  763.                 tmpjob = haswin_getwindowxmin(wptr);
  764.                 if (tmpjob < xmin)
  765.                         xmin = tmpjob;
  766.                 tmpjob += haswin_getwindowxextent(wptr);
  767.                 if (tmpjob > xmax)
  768.                         xmax = tmpjob;
  769.                 tmpjob = haswin_getwindowymin(wptr);
  770.                 if (tmpjob < ymin)
  771.                         ymin = tmpjob;
  772.                 tmpjob += haswin_getwindowyextent(wptr);
  773.                 if (tmpjob > ymax)
  774.                         ymax = tmpjob;
  775.                 for (ic=wptr->icons; ic; ic=ic->next) {
  776.                         _haswin_printmugwatch(HASWIN_TRUE);
  777.                         haswin_pollcomplete();
  778.                         if (haswin_ended) {
  779.                                 haswin_pdriverkilljob(haswin_pjob);
  780.                                 haswin_seticondata(haswin_stat, "Job Cancelled");
  781.                                 haswin_awaitterminate();
  782.                                 haswin_closewindow(haswin_printwin);
  783.                                 haswin_removespritearea(&sarea);
  784.                                 haswin_free(sarea);
  785.                                 haswin_pjob = 0;
  786.                                 return(HASWIN_FALSE);
  787.                         }
  788.                         sprintf(sname, "%X", (int)ic);
  789.                         if (!haswin_icontosprite(ic, sname, sarea))
  790.                                 haswin_errorprintf("can't create sprite '%s' from icon %s in window %s", sname, ic->name, haswin_getwindowtitle(wptr));
  791.                 }
  792.         }
  793.         for (wptr=win->pane; wptr; wptr=wptr->pane) {
  794.                 haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
  795.                 tmpjob = haswin_getwindowxmin(wptr);
  796.                 if (tmpjob < xmin)
  797.                         xmin = tmpjob;
  798.                 tmpjob += haswin_getwindowxextent(wptr);
  799.                 if (tmpjob > xmax)
  800.                         xmax = tmpjob;
  801.                 tmpjob = haswin_getwindowymin(wptr);
  802.                 if (tmpjob < ymin)
  803.                         ymin = tmpjob;
  804.                 tmpjob += haswin_getwindowyextent(wptr);
  805.                 if (tmpjob > ymax)
  806.                         ymax = tmpjob;
  807.                 for (ic=wptr->icons; ic; ic=ic->next) {
  808.                         _haswin_printmugwatch(HASWIN_TRUE);
  809.                         haswin_pollcomplete();
  810.                         if (haswin_ended) {
  811.                                 haswin_pdriverkilljob(haswin_pjob);
  812.                                 haswin_seticondata(haswin_stat, "Job Cancelled");
  813.                                 haswin_awaitterminate();
  814.                                 haswin_closewindow(haswin_printwin);
  815.                                 haswin_removespritearea(&sarea);
  816.                                 haswin_free(sarea);
  817.                                 haswin_pjob = 0;
  818.                                 return(HASWIN_FALSE);
  819.                         }
  820.                         sprintf(sname, "%X", (int)ic);
  821.                         if (!haswin_icontosprite(ic, sname, sarea))
  822.                                 haswin_errorprintf("can't create sprite '%s' from icon %s in window %s", sname, ic->name, haswin_getwindowtitle(wptr));
  823.                 }
  824.         }
  825.         /*
  826.          *      we now have all the icons in sprites and the overall window
  827.          *      sized (xmin,ymin) to (xmax,ymax) in OS units.
  828.          *      Now we calculate the transformation matrix given the rotation
  829.          *      and the scaling factors for this job.
  830.          * x' = (X*trans[0] + Y*trans[2])>>16
  831.          * y' = (X*trans[1] + Y*trans[3])>>16
  832.          * for scaling  trans[0] = xscale
  833.          *              trans[1] = xscale
  834.          *              trans[2] = yscale
  835.          *              trans[3] = yscale
  836.          * for rotation trans[0] = +cos(360-rotate)
  837.          *              trans[1] = +sin(360-rotate)
  838.          *              trans[2] = -sin(360-rotate)
  839.          *              trans[3] = -cos(360-rotate)  { +cos() }
  840.          *
  841.          * this might result in a window too large for our purposes, if so
  842.          * then calculate the correct scaling factors and put the printer
  843.          * selection box up to allow the user to change things before
  844.          * repeating the calculations.
  845.          */
  846.         xmin *= 400;
  847.         xmax *= 400;
  848.         ymin *= 400;
  849.         ymax *= 400;
  850.         do {
  851.                 f = cos((360.0-haswin_pjob->rotate)/DEG_RAD);
  852.                 trans[0] = (int)(f*haswin_pjob->xscale);
  853.                 trans[3] = (int)(f*haswin_pjob->yscale);
  854.                 g = sin((360.0-haswin_pjob->rotate)/DEG_RAD);
  855.                 trans[1] = (int)(g*haswin_pjob->xscale);
  856.                 trans[2] = (int)((-g)*haswin_pjob->yscale);
  857.                 /*
  858.                  *      Next we transform the overall window to the
  859.                  *      transformation matrix.
  860.                  */
  861.                 txmin=(int)(xmin*(trans[0]/65536.0)+ymin*(trans[2]/65536.0));
  862.                 tymin=(int)(xmin*(trans[1]/65536.0)+ymin*(trans[3]/65536.0));
  863.                 txmax=(int)(xmax*(trans[0]/65536.0)+ymax*(trans[2]/65536.0));
  864.                 tymax=(int)(xmax*(trans[1]/65536.0)+ymax*(trans[3]/65536.0));
  865.                 /*
  866.                  *      now, of course txmin, tymin, txmax and tymax may not
  867.                  *      form a rectangle on the paper.  adjust them to the
  868.                  *      enclosing rectangle.
  869.                  */
  870.                 if (txmin > txmax) {
  871.                         tmpjob = txmax;
  872.                         txmax  = txmin;
  873.                         txmin  = tmpjob;
  874.                 }
  875.                 if (tymin > tymax) {
  876.                         tmpjob = tymax;
  877.                         tymax  = tymin;
  878.                         tymin  = tmpjob;
  879.                 }
  880.                 haswin_pjob->xsize = txmax - txmin;
  881.                 haswin_pjob->ysize = tymax - tymin;
  882.                 if ((haswin_pjob->xsize > haswin_pjob->rprint-haswin_pjob->lprint) || (haswin_pjob->ysize > haswin_pjob->tprint-haswin_pjob->bprint)) {
  883.                         f=(double)(haswin_pjob->rprint-haswin_pjob->lprint)/
  884.                           (double)haswin_pjob->xsize;
  885.                         g=(double)(haswin_pjob->tprint-haswin_pjob->bprint)/
  886.                           (double)haswin_pjob->ysize;
  887.                         if (f < g) {
  888.                                 haswin_pjob->xscale =
  889.                                         (int)(haswin_pjob->xscale*f);
  890.                                 haswin_pjob->yscale =
  891.                                         (int)(haswin_pjob->yscale*f);
  892.                         } else {
  893.                                 haswin_pjob->xscale =
  894.                                         (int)(haswin_pjob->xscale*g);
  895.                                 haswin_pjob->yscale =
  896.                                         (int)(haswin_pjob->yscale*g);
  897.                         }
  898.                         strcpy(sname, haswin_geticontitle(haswin_stat));
  899.                         haswin_seticondata(haswin_cont, "Try Again");
  900.                         haswin_seticondata(haswin_stat, "Drawing too big");
  901.                         haswin_reopenwindow(haswin_pict->window);
  902.                         haswin_awaitterminate();
  903.                         haswin_seticondata(haswin_cont, "Abort");
  904.                         haswin_seticondata(haswin_stat, sname);
  905.                         haswin_reopenwindow(haswin_printwin);
  906.                         more = HASWIN_TRUE;
  907.                 } else
  908.                         more = HASWIN_FALSE;
  909.         } while (more);
  910.         /* select the printer job */
  911.         haswin_seticondata(haswin_stat, "Starting Job");
  912.         haswin_pollcomplete();
  913.         if ((oldjob=haswin_pdriverselectjob(haswin_pjob))==HASWIN_UNKNOWN) {
  914.                 haswin_pdriverkilljob(haswin_pjob);
  915.                 haswin_seticondata(haswin_stat, "Cannot Start Job");
  916.                 haswin_awaitterminate();
  917.                 haswin_closewindow(haswin_printwin);
  918.                 haswin_removespritearea(&sarea);
  919.                 haswin_free(sarea);
  920.                 haswin_pjob = 0;
  921.                 return(HASWIN_FALSE);
  922.         }
  923.         /* we will have one rectangle for each window, pane and slide.     */
  924.         /* get scaling and rotation transform from haswin_pjob             */
  925.         /* position of first (master) window is bottom left of page */
  926.         /* size of rectangle from window description */
  927.         winnum = _haswin_printwindow1(win, trans, haswin_pjob->lprint,
  928.                 haswin_pjob->bprint, txmin, tymin);
  929.         if (winnum == -1) {
  930.                 haswin_pdriverkilljob(haswin_pjob);
  931.                 haswin_seticondata(haswin_stat, "Cannot Process Job");
  932.                 haswin_awaitterminate();
  933.                 haswin_closewindow(haswin_printwin);
  934.                 haswin_removespritearea(&sarea);
  935.                 haswin_free(sarea);
  936.                 haswin_pjob = 0;
  937.                 return(HASWIN_FALSE);
  938.         }
  939.         regs.r[0] = 1;
  940.         regs.r[1] = (int)rect;
  941.         regs.r[2] = 0;
  942.         regs.r[3] = 0;
  943.         regs.r[4] = 0xFFFFFF00;
  944.         if (!haswin_swi(HASWIN_PD_DrawPage, ®s)) {
  945.                 haswin_pdriverkilljob(haswin_pjob);
  946.                 haswin_awaitterminate();
  947.                 haswin_closewindow(haswin_printwin);
  948.                 haswin_removespritearea(&sarea);
  949.                 haswin_free(sarea);
  950.                 haswin_pjob = 0;
  951.                 return(HASWIN_FALSE);
  952.         }
  953.         more = regs.r[0];
  954.         wptr = (window *)regs.r[2];
  955.         while (more) {
  956.                 tmpjob = haswin_pdriverselect(0);
  957.                 haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
  958.                 haswin_seticondata(haswin_stat, "Processing Job");
  959.                 _haswin_printmugwatch(HASWIN_TRUE);
  960.                 haswin_pollcomplete();
  961.                 if (haswin_ended) {
  962.                         haswin_pdriverkilljob(haswin_pjob);
  963.                         haswin_seticondata(haswin_stat, "Job Cancelled");
  964.                         haswin_awaitterminate();
  965.                         haswin_closewindow(haswin_printwin);
  966.                         haswin_removespritearea(&sarea);
  967.                         haswin_free(sarea);
  968.                         haswin_pjob = 0;
  969.                         return(HASWIN_FALSE);
  970.                 }
  971.                 haswin_pdriverselect(tmpjob);
  972.                 /*
  973.                  *      plot the given window.  Make it look like the draw
  974.                  *      request is coming from a window redraw.  Therefore
  975.                  *      we have to first make the buffer.  We make the
  976.                  *      window look like full size and not scrolled.
  977.                  */
  978.                 haswin_updatewindowinfo(wptr);
  979.                 buff.i[ 0] = wptr->handle;
  980.                 buff.i[ 1] = 0;
  981.                 buff.i[ 2] = 0;
  982.                 buff.i[ 3] = haswin_getwindowxextent(wptr);
  983.                 buff.i[ 4] = haswin_getwindowyextent(wptr);
  984.                 buff.i[ 5] = 0;
  985.                 buff.i[ 6] = 0;
  986.                 buff.i[ 7] = rect[0];
  987.                 buff.i[ 8] = rect[1];
  988.                 buff.i[ 9] = rect[2];
  989.                 buff.i[10] = rect[3];
  990.                 graphics_gcol(0, wptr->win[35]);
  991.                 graphics_rectanglefill(rect[0], rect[1], rect[2]-rect[0], rect[3]-rect[1]);
  992.                 tmpjob = haswin_pdriverselect(0);
  993.                 _haswin_printmugwatch(HASWIN_TRUE);
  994.                 haswin_pollcomplete();
  995.                 haswin_pdriverselect(tmpjob);
  996.                 if (!((wptr->drawroutine) &&
  997.                      (!wptr->drawroutine(wptr, &buff)))) {
  998.                         if (wptr->text) {
  999.                                 text_plot(wptr->text, wptr->orgx,
  1000.                                         buff.i[4]+wptr->orgy,
  1001.                                         rect[0], rect[2], rect[1], rect[3]);
  1002.                         }
  1003.                         tmpjob = haswin_pdriverselect(0);
  1004.                         _haswin_printmugwatch(HASWIN_TRUE);
  1005.                         haswin_pollcomplete();
  1006.                         if (haswin_ended) {
  1007.                                 haswin_pdriverkilljob(haswin_pjob);
  1008.                                 haswin_seticondata(haswin_stat, "Job Cancelled");
  1009.                                 haswin_awaitterminate();
  1010.                                 haswin_closewindow(haswin_printwin);
  1011.                                 haswin_removespritearea(&sarea);
  1012.                                 haswin_free(sarea);
  1013.                                 haswin_pjob = 0;
  1014.                                 return(HASWIN_FALSE);
  1015.                         }
  1016.                         haswin_pdriverselect(tmpjob);
  1017.                         if (wptr->picture) {
  1018.                                 graphics_plot(wptr->picture, wptr->orgx,
  1019.                                         buff.i[4]+wptr->orgy,
  1020.                                         rect[0], rect[2], rect[1], rect[3]);
  1021.                         }
  1022.                 }
  1023.                 tmpjob = haswin_pdriverselect(0);
  1024.                 _haswin_printmugwatch(HASWIN_TRUE);
  1025.                 haswin_pollcomplete();
  1026.                 if (haswin_ended) {
  1027.                         haswin_pdriverkilljob(haswin_pjob);
  1028.                         haswin_seticondata(haswin_stat, "Job Cancelled");
  1029.                         haswin_awaitterminate();
  1030.                         haswin_closewindow(haswin_printwin);
  1031.                         haswin_removespritearea(&sarea);
  1032.                         haswin_free(sarea);
  1033.                         haswin_pjob = 0;
  1034.                         return(HASWIN_FALSE);
  1035.                 }
  1036.                 haswin_pdriverselect(tmpjob);
  1037.                 for (ic=wptr->icons; ic; ic=ic->next) {
  1038.                         tmpjob = haswin_pdriverselect(0);
  1039.                         _haswin_printmugwatch(HASWIN_TRUE);
  1040.                         haswin_pollcomplete();
  1041.                         if (haswin_ended) {
  1042.                                 haswin_pdriverkilljob(haswin_pjob);
  1043.                                 haswin_seticondata(haswin_stat,
  1044.                                         "Job Cancelled");
  1045.                                 haswin_awaitterminate();
  1046.                                 haswin_closewindow(haswin_printwin);
  1047.                                 haswin_removespritearea(&sarea);
  1048.                                 haswin_free(sarea);
  1049.                                 haswin_pjob = 0;
  1050.                                 return(HASWIN_FALSE);
  1051.                         }
  1052.                         haswin_pdriverselect(tmpjob);
  1053.                         sprintf(sname, "%X", (int)ic);
  1054.                         /* search for the sprite */
  1055.                         regs.r[0] = 0x118;
  1056.                         regs.r[1] = (int)sarea;
  1057.                         regs.r[2] = (int)sname;
  1058.                         haswin_spriteop(0, ®s);
  1059.                         /* now we plot the sprite */
  1060.                         regs.r[0] = 0x222;
  1061.                         regs.r[3] = wptr->orgx+ic->ic[0];
  1062.                         regs.r[4] = buff.i[4]+wptr->orgy+ic->ic[1];
  1063.                         regs.r[5] = 0;
  1064.                         haswin_spriteop(0, ®s);
  1065.                 }
  1066.                 tmpjob = haswin_pdriverselect(0);
  1067.                 haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
  1068.                 haswin_seticondata(haswin_stat, "Printing Job");
  1069.                 _haswin_printmugwatch(HASWIN_TRUE);
  1070.                 haswin_pollcomplete();
  1071.                 if (haswin_ended) {
  1072.                         haswin_pdriverkilljob(haswin_pjob);
  1073.                         haswin_seticondata(haswin_stat, "Job Cancelled");
  1074.                         haswin_awaitterminate();
  1075.                         haswin_closewindow(haswin_printwin);
  1076.                         haswin_removespritearea(&sarea);
  1077.                         haswin_free(sarea);
  1078.                         haswin_pjob = 0;
  1079.                         return(HASWIN_FALSE);
  1080.                 }
  1081.                 haswin_pdriverselect(tmpjob);
  1082.                 haswin_hourglass(HASWIN_TRUE);
  1083.                 regs.r[1] = (int)rect;
  1084.                 if (!haswin_swi(HASWIN_PD_GetRectangle, ®s)) {
  1085.                         haswin_pdriverkilljob(haswin_pjob);
  1086.                         haswin_hourglass(HASWIN_FALSE);
  1087.                         haswin_awaitterminate();
  1088.                         haswin_closewindow(haswin_printwin);
  1089.                         haswin_removespritearea(&sarea);
  1090.                         haswin_free(sarea);
  1091.                         haswin_pjob = 0;
  1092.                         return(HASWIN_FALSE);
  1093.                 }
  1094.                 more = regs.r[0];
  1095.                 wptr = (window *)regs.r[2];
  1096.                 haswin_hourglass(HASWIN_FALSE);
  1097.         }
  1098.         /* select the old job if there was one */
  1099.         if (oldjob)
  1100.                 haswin_pdriverselect(oldjob);
  1101.         /* now we terminate the print job */
  1102.         haswin_pdriverendjob(haswin_pjob);
  1103.         haswin_seticondata(haswin_stat, "Finished Job");
  1104.         haswin_seticondata(haswin_cont, "Continue");
  1105.         haswin_awaitterminate();
  1106.         haswin_pjob = 0;
  1107.         haswin_removespritearea(&sarea);
  1108.         haswin_free(sarea);
  1109.         haswin_closewindow(haswin_printwin);
  1110.         return(HASWIN_TRUE);
  1111. }
  1112.  
  1113. /*
  1114.  *      Printer control routines.  We provide an interface to the Acorn
  1115.  *      printer applications.  This is done in the same way as the Filer
  1116.  *      file save interface and requires a single user print routine.
  1117.  */
  1118.  
  1119. void haswin_setprintfileroutine(int (*user)(char *, buffer *)) {
  1120.  
  1121.         haswin_printfileroutine = user;
  1122. }
  1123.  
  1124.