home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-02-04 | 46.3 KB | 1,124 lines |
- /* > $.CLIB.C.printer
- *
- * HASWIN Graphics Library
- * =========================
- *
- * Copyright (C) H.A.Shaw 1990.
- * Howard A. Shaw.
- * The Unit for Space Sciences,
- * Room 165,
- * Physics Building,
- * University of Kent at Canterbury.
- * Canterbury.
- * Kent. CT2 7NJ
- * You may use and distribute this code freely, however please leave
- * it alone. If you find bugs (and there will be many) please contact
- * me and the master source can be modified. If you keep me informed
- * of who you give copies of this to then I can get release upgrades
- * to them.
- *
- * Printer control routines. Provide an interface to the central
- * printer drivers and the Acorn Printer applications.
- */
- #include "includes.h"
- #include <math.h>
- #define DEG_RAD 57.29577951307
-
- pdriver *haswin_pjob = 0;
- static window *haswin_printwin = 0;
- static icon *haswin_mugs = 0;
- static icon *haswin_stat = 0;
- static icon *haswin_wind = 0;
- static icon *haswin_pict = 0;
- static icon *haswin_name = 0;
- static icon *haswin_file = 0;
- static icon *haswin_titl = 0;
- static icon *haswin_stop = 0;
- static icon *haswin_cont = 0;
- static int haswin_ended = HASWIN_FALSE;
- static double haswin_punit = 1.0;
- static int psetupmouse(icon *, buffer *);
- static int psetupopen(window *, buffer *);
-
- /*
- * Initialisation of the printer system. We check that printer driver
- * SWIs exist and do the initialisation and then set the printer flag.
- */
- int haswin_initialisepdriver(void) {
-
- int oldflags;
-
- if (!haswin_doespdriverexist()) {
- haswin_flags &= ~HASWIN_FLAGS_PRINTER;
- return(HASWIN_FALSE);
- }
- haswin_flags |= HASWIN_FLAGS_PRINTER;
- /*
- * the printer has a little information window. We look around for it
- * First in the existing windows, then the open template, then the
- * HASWIN system template file.
- * In the printer information window...
- *
- * icon
- * 0 - mugwatch icon.
- * 1 - status string icon.
- * 2 - window name icon.
- * 3 - Print job title icon.
- * 4 - Printer name icon.
- * 5 - Printer file output icon.
- * 6 - Printer picture icon (click to select printer details).
- * 7 - Cancel (stop) icon.
- * 8 - Continue icon.
- */
- if ((haswin_printwin=haswin_findwindowname("printer")) == 0) {
- oldflags = haswin_flags & HASWIN_FLAGS_VERBOSE;
- haswin_flags &= ~HASWIN_FLAGS_VERBOSE;
- if ((haswin_printwin=haswin_loadwindow("printer",SPRITE_HASWIN_AREA)) == 0) {
- haswin_pushtemplate(HASWIN_TEMPLATEFILE);
- if ((haswin_printwin=haswin_loadwindow("printer",SPRITE_HASWIN_AREA)) == 0) {
- haswin_poptemplate();
- haswin_flags |= oldflags;
- return(HASWIN_FALSE);
- }
- haswin_poptemplate();
- }
- haswin_flags |= oldflags;
- haswin_mugs = haswin_findiconhandle(haswin_printwin, 0);
- haswin_stat = haswin_findiconhandle(haswin_printwin, 1);
- haswin_wind = haswin_findiconhandle(haswin_printwin, 2);
- haswin_titl = haswin_findiconhandle(haswin_printwin, 3);
- haswin_name = haswin_findiconhandle(haswin_printwin, 4);
- haswin_file = haswin_findiconhandle(haswin_printwin, 5);
- haswin_pict = haswin_findiconhandle(haswin_printwin, 6);
- haswin_stop = haswin_findiconhandle(haswin_printwin, 7);
- haswin_cont = haswin_findiconhandle(haswin_printwin, 8);
- /*
- * the printer has selection window. We look for it first in the
- * existing windows, then the HASWIN system template file.
- * In the printer selection window...
- *
- * icon
- * 0 - direction
- * 1 - paper hieght.
- * 2 - paper width.
- * 3 - print area left margin.
- * 4 - print area right margin.
- * 5 - print area top margin.
- * 6 - print area bottom margin.
- * 7 - Scale X direction.
- * 8 - Scale Y direction.
- * 9 - OK icon.
- * 10 - Rotation icon.
- */
- if ((haswin_pict->window=haswin_findwindowname("printset")) == 0) {
- oldflags = haswin_flags & HASWIN_FLAGS_VERBOSE;
- haswin_flags &= ~HASWIN_FLAGS_VERBOSE;
- haswin_pushtemplate(HASWIN_TEMPLATEFILE);
- haswin_pict->window = haswin_loadwindow("printset",
- SPRITE_HASWIN_AREA);
- haswin_poptemplate();
- haswin_flags |= oldflags;
- }
- if (haswin_pict->window) {
- haswin_pict->window->openroutine = psetupopen;
- haswin_findiconhandle(haswin_pict->window,0)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,1)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,2)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,3)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,4)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,5)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,6)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,7)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,8)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,9)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,10)->mousebutton = psetupmouse;
- haswin_findiconhandle(haswin_pict->window,11)->mousebutton = psetupmouse;
- haswin_pict->window->openroutine = psetupopen;
- }
- }
- haswin_pjob = haswin_getpdriverinfo(haswin_pjob);
- return(HASWIN_TRUE);
- }
-
- /*
- * Does the Printer Driver exist?.
- */
- int haswin_doespdriverexist(void) {
-
- _kernel_swi_regs regs;
-
- if (_kernel_swi(SWI_X|HASWIN_PD_Info, ®s, ®s))
- return(HASWIN_FALSE);
- return(HASWIN_TRUE);
- }
-
- void haswin_pdriverclosedown() {
-
- _kernel_swi_regs regs;
-
- if (!haswin_doespdriverexist()) {
- if ((haswin_pjob) && (haswin_pjob->jobid)) {
- regs.r[0] = 0;
- regs.r[1] = haswin_pjob->jobid;
- haswin_swi(SWI_X|OS_Find, ®s);
- }
- haswin_pjob = 0;
- haswin_flags &= ~HASWIN_FLAGS_PRINTER;
- return;
- }
- if (haswin_pjob) {
- if (haswin_pjob->jobid) {
- regs.r[0] = haswin_pjob->jobid;
- haswin_swi(SWI_X|HASWIN_PD_AbortJob, ®s);
- regs.r[0] = 0;
- regs.r[1] = haswin_pjob->jobid;
- haswin_swi(OS_Find, ®s);
- }
- if (haswin_pjob->fname)
- haswin_free(haswin_pjob->fname);
- if (haswin_pjob->title)
- haswin_free(haswin_pjob->title);
- haswin_free(haswin_pjob);
- }
- }
-
- /*
- * Get information on the printer driver.
- */
- pdriver *haswin_getpdriverinfo(pdriver *prt) {
-
- _kernel_swi_regs regs;
- int new = HASWIN_FALSE;
-
- if (!(haswin_flags & HASWIN_FLAGS_PRINTER))
- return(0);
- if (!prt) {
- prt=haswin_malloc(sizeof(pdriver), "haswin_getprinterinfo", "printer data block");
- new = HASWIN_TRUE;
- }
- if (!haswin_swi(HASWIN_PD_Info, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_FALSE);
- }
- prt->version = regs.r[0];
- prt->xres = regs.r[1];
- prt->yres = regs.r[2];
- prt->features = regs.r[3];
- prt->name = (char *)regs.r[4];
- prt->xhres = regs.r[5];
- prt->yhres = regs.r[6];
- prt->ident = regs.r[7];
- if (!haswin_swi(HASWIN_PD_PageSize, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_FALSE);
- }
- prt->xpaper = regs.r[1];
- prt->ypaper = regs.r[2];
- prt->lprint = regs.r[3];
- prt->bprint = regs.r[4];
- prt->rprint = regs.r[5];
- prt->tprint = regs.r[6];
- if (new) {
- prt->rotate = 0;
- prt->xscale = 1<<16;
- prt->yscale = 1<<16;
- prt->jobid = 0;
- prt->title = 0;
- prt->fname = 0;
- prt->xsize = HASWIN_UNKNOWN;
- prt->ysize = HASWIN_UNKNOWN;
- }
- return(prt);
- }
-
- /*
- * add a new printer driver job to the linked list. Note that we have
- * to use direct RISCOS calls to open files cos we need the file handle
- * and can't use "stdio".
- */
- pdriver *haswin_pdrivermakejob(char *fname, char *title, pdriver *prt) {
-
-
- if ((!fname) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
- return(0);
- if ((prt=haswin_getpdriverinfo(prt)) == 0)
- return(0);
- if ((prt->title=haswin_malloc(strlen(title)+1,"haswin_makenewjob","title data block")) == 0) {
- haswin_free(prt);
- return(0);
- }
- strcpy(prt->title, title);
- if ((prt->fname=haswin_malloc(strlen(fname)+1,"haswin_makenewjob","filename data block")) == 0) {
- haswin_free(prt->title);
- haswin_free(prt);
- return(0);
- }
- strcpy(prt->fname, fname);
- return(prt);
- }
-
- /*
- * abort this printer job and remove it from the linked list of
- * printer jobs and delete the job.
- */
- int haswin_pdriverkilljob(pdriver *prt) {
-
- _kernel_swi_regs regs;
-
- if ((!prt) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
- return(HASWIN_FALSE);
- if (prt->jobid) {
- /*
- * job has been started sometime and has a file, stop the
- * job and close the file.
- */
- regs.r[0] = prt->jobid;
- if (!haswin_swi(HASWIN_PD_AbortJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_FALSE);
- }
- regs.r[0] = 0;
- regs.r[1] = prt->jobid;
- haswin_swi(OS_Find, ®s);
- }
- haswin_free(prt->fname);
- haswin_free(prt->title);
- haswin_free(prt);
- return(HASWIN_TRUE);
- }
-
- /*
- * this print job is finished. Don't close the file, just in case
- * the printer driver is going to print some more.
- */
- int haswin_pdriverendjob(pdriver *prt) {
-
- _kernel_swi_regs regs;
-
- if ((!prt) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
- return(HASWIN_FALSE);
- if (prt->jobid) {
- /*
- * job has been started sometime and has a file, stop the
- * job and leave the file.
- */
- regs.r[0] = prt->jobid;
- if (!haswin_swi(HASWIN_PD_EndJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_FALSE);
- }
- regs.r[0] = 0;
- regs.r[1] = prt->jobid;
- haswin_swi(OS_Find, ®s);
- }
- haswin_free(prt->fname);
- haswin_free(prt->title);
- haswin_free(prt);
- return(HASWIN_TRUE);
- }
-
- /*
- * this print job is cancelled, dont do anything else.
- */
- int haswin_pdrivercanceljob(pdriver *prt) {
-
- _kernel_swi_regs regs;
-
- if ((!prt) || (!(haswin_flags & HASWIN_FLAGS_PRINTER)))
- return(HASWIN_FALSE);
- if (prt->jobid) {
- /*
- * job has been started sometime and has a file, stop the
- * job and leave the file.
- */
- regs.r[0] = prt->jobid;
- if (!haswin_swi(HASWIN_PD_CancelJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_FALSE);
- }
- }
- return(HASWIN_TRUE);
- }
-
- /*
- * select the given job and return the job number of the old job
- * or HASWIN_UNKNOWN on an error.
- */
- int haswin_pdriverselectjob(pdriver *prt) {
-
- _kernel_swi_regs regs;
- int id;
-
- if (!(haswin_flags & HASWIN_FLAGS_PRINTER))
- return(HASWIN_UNKNOWN);
- if (!prt) {
- regs.r[0] = 0;
- if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_UNKNOWN);
- }
- return(regs.r[0]);
- }
- if (!prt->jobid) {
- /*
- * selecting job for the first time, open the file
- */
- regs.r[0] = 0x84;
- regs.r[1] = (int)prt->fname;
- regs.r[2] = 0;
- haswin_swi(OS_Find, ®s);
- if (regs.r[0] <= 0)
- return(HASWIN_UNKNOWN);
- id = regs.r[0];
- regs.r[1] = (int)prt->title;
- if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_UNKNOWN);
- }
- prt->jobid = id;
- return(regs.r[0]);
- }
- regs.r[0] = prt->jobid;
- regs.r[1] = 0;
- if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_UNKNOWN);
- }
- return(regs.r[0]);
- }
-
-
- /*
- * select the given job number and return the job number of the old job
- * or HASWIN_UNKNOWN on an error. Since this is not given a job
- * structure it cannot open the file or anything.
- */
- int haswin_pdriverselect(int jobid) {
-
- _kernel_swi_regs regs;
-
- if (!(haswin_flags & HASWIN_FLAGS_PRINTER))
- return(HASWIN_UNKNOWN);
- regs.r[0] = jobid;
- if (!haswin_swi(HASWIN_PD_SelectJob, ®s)) {
- haswin_pdriverclosedown();
- return(HASWIN_UNKNOWN);
- }
- return(regs.r[0]);
- }
-
- /*
- *
- *
- */
- static int psetupopen(window *win, buffer *buff) {
-
- char tmp[16];
- double scaler;
-
- if (haswin_punit == 1.0)
- haswin_seticondata(haswin_findiconhandle(win,11), "inches");
- else if (haswin_punit == 0.3937)
- haswin_seticondata(haswin_findiconhandle(win,11), "cm");
- else
- haswin_seticondata(haswin_findiconhandle(win,11), "??");
-
- if (!haswin_pjob) {
- strcpy(tmp, "???");
- haswin_seticondata(haswin_findiconhandle(win,0),"printport");
- haswin_seticondata(haswin_findiconhandle(win, 1), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 2), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 3), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 4), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 5), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 6), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 7), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 8), tmp);
- haswin_seticondata(haswin_findiconhandle(win, 13), "?");
- haswin_seticondata(haswin_findiconhandle(win, 14), "?");
- return(HASWIN_TRUE);
- }
- if ((haswin_pjob->rotate > 315) || (haswin_pjob->rotate < 45))
- haswin_seticondata(haswin_findiconhandle(win,0),"printdir0");
- else if (haswin_pjob->rotate < 135)
- haswin_seticondata(haswin_findiconhandle(win,0),"printdir1");
- else if (haswin_pjob->rotate < 225)
- haswin_seticondata(haswin_findiconhandle(win,0),"printdir2");
- else
- haswin_seticondata(haswin_findiconhandle(win,0),"printdir3");
- scaler = 72000.0*haswin_punit;
- sprintf(tmp, "%.2f", haswin_pjob->ypaper/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 1), tmp);
- sprintf(tmp, "%.2f", haswin_pjob->xpaper/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 2), tmp);
- sprintf(tmp, "%.2f", haswin_pjob->lprint/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 3), tmp);
- sprintf(tmp, "%.2f", haswin_pjob->rprint/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 4), tmp);
- sprintf(tmp, "%.2f", haswin_pjob->tprint/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 5), tmp);
- sprintf(tmp, "%.2f", haswin_pjob->bprint/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 6), tmp);
- sprintf(tmp, "%.3f", haswin_pjob->xscale/65536.0);
- haswin_seticondata(haswin_findiconhandle(win, 7), tmp);
- sprintf(tmp, "%.3f", haswin_pjob->yscale/65536.0);
- haswin_seticondata(haswin_findiconhandle(win, 8), tmp);
- sprintf(tmp, "%3.3d", haswin_pjob->rotate);
- haswin_seticondata(haswin_findiconhandle(win, 10), tmp);
- if (haswin_pjob->ysize > 0) {
- sprintf(tmp, "%.2f", haswin_pjob->ysize/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 13), tmp);
- } else
- haswin_seticondata(haswin_findiconhandle(win, 13), "?");
- if (haswin_pjob->xsize > 0) {
- sprintf(tmp, "%.2f", haswin_pjob->xsize/scaler);
- haswin_seticondata(haswin_findiconhandle(win, 14), tmp);
- } else
- haswin_seticondata(haswin_findiconhandle(win, 14), "?");
- return(HASWIN_TRUE);
- }
-
- /*
- * called by icon selections in the printer selection window
- */
- static int psetupmouse(icon *ic, buffer *buff) {
-
- int i;
- double f;
-
- if (ic->whandle != haswin_pict->window->handle)
- return(HASWIN_FALSE);
- switch (ic->ihandle) {
- case 0: /* portrat/landscape selection */
- haswin_pjob->rotate = ((haswin_pjob->rotate/90)+1)*90 % 360;
- break;
- case 1: /* paper hieght selection */
- f = atof(haswin_geticontitle(ic));
- if (f > 0)
- haswin_pjob->ypaper = (int)(f*72000.0*haswin_punit);
- break;
- case 2: /* paper width selection */
- f = atof(haswin_geticontitle(ic));
- if (f > 0)
- haswin_pjob->xpaper = (int)(f*72000.0*haswin_punit);
- break;
- case 3: /* print area left margin selection */
- f = atof(haswin_geticontitle(ic));
- if (f > 0)
- haswin_pjob->lprint = (int)(f*72000.0*haswin_punit);
- break;
- case 4: /* print area right margin selection */
- f = atof(haswin_geticontitle(ic));
- if (f > 0)
- haswin_pjob->rprint = (int)(f*72000.0*haswin_punit);
- break;
- case 5: /* print area top margin selection */
- f = atof(haswin_geticontitle(ic));
- if (f > 0)
- haswin_pjob->tprint = (int)(f*72000.0*haswin_punit);
- break;
- case 6: /* print area bottom margin selection */
- f = atof(haswin_geticontitle(ic));
- if (f > 0)
- haswin_pjob->bprint = (int)(f*72000.0*haswin_punit);
- break;
- case 7: /* X scale selection */
- f = atof(haswin_geticontitle(ic));
- if (f)
- haswin_pjob->xscale = (int)(f*65536.0*haswin_punit);
- break;
- case 8: /* Y scale selection */
- f = atof(haswin_geticontitle(ic));
- if (f)
- haswin_pjob->yscale = (int)(f*65536.0*haswin_punit);
- break;
- case 9: /* OK icon selection */
- haswin_closewindow(haswin_pict->window);
- return(HASWIN_TRUE);
- case 10: /* Rotate icon selection */
- /* can only do this if driver can do arbitary
- transformations */
- i = atoi(haswin_geticontitle(ic)) % 360;
- if (!(haswin_pjob->features & 0x02000000)) {
- i = i/90;
- i = i*90;
- }
- if (i >= 0)
- haswin_pjob->rotate = i;
- break;
- case 11: /* change units */
- if (haswin_punit == 1.0)
- haswin_punit = 0.3937;
- else
- haswin_punit = 1.00;
- }
- psetupopen(haswin_pict->window, 0);
- return(HASWIN_TRUE);
- }
-
- static int printmousebutton(icon *ic, buffer *buff) {
-
- if ((ic == haswin_stop) || (ic == haswin_cont)) {
- haswin_ended = HASWIN_TRUE;
- return(HASWIN_TRUE);
- }
- return(HASWIN_FALSE);
- }
-
- static void haswin_awaitterminate(void) {
-
- haswin_reopenwindow(haswin_printwin);
- haswin_ended = HASWIN_FALSE;
- haswin_seticonbcol(haswin_cont, 11);
- haswin_seticonfcol(haswin_cont, 9);
- haswin_cont->mousebutton = printmousebutton;
- haswin_stop->mousebutton = 0;
- while (!haswin_ended) {
- haswin_seticonbcol(haswin_cont, 11);
- haswin_seticonfcol(haswin_cont, 9);
- haswin_poll();
- haswin_seticonbcol(haswin_cont, 9);
- haswin_seticonfcol(haswin_cont, 11);
- haswin_poll();
- }
- haswin_ended = HASWIN_FALSE;
- haswin_seticonbcol(haswin_cont, 1);
- haswin_seticonfcol(haswin_cont, 1);
- haswin_cont->mousebutton = 0;
- haswin_stop->mousebutton = printmousebutton;
- haswin_closewindow(haswin_pict->window);
- haswin_closewindow(haswin_printwin);
- return;
- }
-
-
- /*
- * do the mugwatch bits for the print status window.
- */
- static void _haswin_printmugwatch(int onoff) {
-
- static char spin[] = "rotor_0";
-
- if (!onoff)
- spin[6] = '0';
- else if (++spin[6] >= '9')
- spin[6] = '1';
- haswin_seticondata(haswin_mugs, spin);
- }
- /*
- * recursive search of all window panes and slides attacted to
- * the window "wptr". Add these to the print job that must
- * be open. Internal routine used ONLY by haswin_printwindow().
- * Returns number of windows scanned at each level, or -1 for error.
- * -1 is passed back though recursion levels.
- */
- static int _haswin_printwindow1(window *wptr, int *trans, int l, int b, int xm, int ym) {
-
- int rect[4];
- int plotpos[2], xpos, ypos;
- int ans, winnum;
- _kernel_swi_regs regs;
-
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_pjob = 0;
- return(-1);
- }
- if (!wptr)
- return(-1);
- winnum = 1;
- haswin_updatewindowinfo(wptr);
- rect[0] = -4;
- rect[1] = -4;
- rect[2] = haswin_getwindowxextent(wptr)+4;
- rect[3] = haswin_getwindowyextent(wptr)+4;
- /* adjust the plot position for the transformation matrix */
- xpos = haswin_getwindowxmin(wptr)*400;
- ypos = haswin_getwindowymin(wptr)*400;
- plotpos[0] =
- l +(int)(xpos*(trans[0]/65536.0)+ypos*(trans[2]/65536.0)) -xm;
- plotpos[1] =
- b +(int)(xpos*(trans[1]/65536.0)+ypos*(trans[3]/65536.0)) -ym;
- regs.r[0] = (int)wptr; /* the identifier is the window */
- regs.r[1] = (int)rect;
- regs.r[2] = (int)trans;
- regs.r[3] = (int)plotpos;
- regs.r[4] = 0xFFFFFF00;
- if (!haswin_swi(HASWIN_PD_GiveRectangle, ®s))
- return(-1);
- if (wptr->pane) {
- ans = _haswin_printwindow1(wptr->pane, trans, l, b, xm, ym);
- if (ans == -1)
- return(-1);
- winnum += ans;
- }
- if (wptr->slide) {
- ans = _haswin_printwindow1(wptr->slide, trans, l, b, xm, ym);
- if (ans == -1)
- return(-1);
- winnum += ans;
- }
- return(winnum);
- }
-
- /*
- * create a printer job to print the window given. Call the printer
- * to print the job and remember also to print slides and panes. Try
- * to get the slides and panes in the correct orders, but it is
- * difficult. Remarkably enough this routine seems to be able to cope
- * with windows bigger than the real screen.
- */
- int haswin_printwindow(window *win, char *fname, char *title) {
-
- int oldjob,rect[4],trans[4],winnum,more,tmpjob;
- int xmin,ymin,xmax,ymax,txmin,tymin,txmax,tymax;
- double f, g;
- int *sarea = 0;
- char sname[64];
- buffer buff;
- _kernel_swi_regs regs;
- icon *ic;
- window *wptr;
-
- if (!haswin_doespdriverexist()) {
- haswin_flags &= ~HASWIN_FLAGS_PRINTER;
- return(HASWIN_FALSE);
- }
- if (!fname)
- fname = "printer:";
- if (!title)
- title = haswin_getwindowtitle(win);
- haswin_pjob=haswin_getpdriverinfo(haswin_pjob);
- if (!(haswin_pjob)) {
- haswin_reopenwindow(haswin_printwin);
- haswin_seticondata(haswin_name, "<Unknown>");
- haswin_seticondata(haswin_file, fname);
- haswin_seticondata(haswin_titl, title);
- haswin_seticondata(haswin_wind, haswin_getwindowtitle(win));
- haswin_seticondata(haswin_stat, "Cannot Start Job");
- haswin_awaitterminate();
- return(HASWIN_FALSE);
- }
- if ((haswin_pjob) && (haswin_pjob->jobid)) {
- haswin_reopenwindow(haswin_printwin);
- strcpy(sname, haswin_geticontitle(haswin_stat));
- haswin_seticondata(haswin_name, "<Unknown>");
- haswin_seticondata(haswin_file, fname);
- haswin_seticondata(haswin_titl, title);
- haswin_seticondata(haswin_stat, "Already Printing A Job");
- haswin_awaitterminate();
- haswin_seticondata(haswin_file, haswin_pjob->fname);
- haswin_seticondata(haswin_name, haswin_pjob->name);
- haswin_seticondata(haswin_titl, haswin_pjob->title);
- haswin_seticondata(haswin_stat, sname);
- haswin_reopenwindow(haswin_printwin);
- return(HASWIN_FALSE);
- }
- if (!win) {
- return(HASWIN_FALSE);
- }
- haswin_ended = HASWIN_FALSE;
- haswin_stop->mousebutton = printmousebutton;
- haswin_seticondata(haswin_file, fname);
- haswin_seticondata(haswin_titl, title);
- haswin_seticondata(haswin_name, "");
- haswin_seticondata(haswin_wind, "");
- haswin_seticondata(haswin_stat, "Ready to Print");
- haswin_seticondata(haswin_cont, "Go");
- haswin_awaitterminate();
- haswin_seticondata(haswin_cont, "Abort");
- haswin_reopenwindow(haswin_printwin);
- haswin_pollcomplete();
- _haswin_printmugwatch(HASWIN_FALSE);
- if ((haswin_pjob=haswin_pdrivermakejob(fname, title, haswin_pjob)) == 0) {
- haswin_seticondata(haswin_name, "<Not Known>");
- haswin_seticondata(haswin_stat, "Cannot Create Job");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- return(HASWIN_FALSE);
- }
- haswin_seticondata(haswin_name, haswin_pjob->name);
- haswin_seticondata(haswin_stat, "Scaning Job Windows");
- haswin_pollcomplete();
- /*
- * First pass through the windows. This does two jobs.
- * 1) get the overall rectangle for the windows, so we can
- * scale the picture later.
- * 2) turn all the icons into sprites named from the address
- * of their ic structures so we can draw them later.
- */
- /* reserve 100K for sprites in these windows. */
- sarea = haswin_clearsprites(102400, 0);
- haswin_addspritearea(&sarea);
- xmin = 0x7FFFFFFF;
- xmax = 0;
- ymin = 0x7FFFFFFF;
- ymax = 0;
- for (wptr=win; wptr; wptr=wptr->slide) {
- haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
- tmpjob = haswin_getwindowxmin(wptr);
- if (tmpjob < xmin)
- xmin = tmpjob;
- tmpjob += haswin_getwindowxextent(wptr);
- if (tmpjob > xmax)
- xmax = tmpjob;
- tmpjob = haswin_getwindowymin(wptr);
- if (tmpjob < ymin)
- ymin = tmpjob;
- tmpjob += haswin_getwindowyextent(wptr);
- if (tmpjob > ymax)
- ymax = tmpjob;
- for (ic=wptr->icons; ic; ic=ic->next) {
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- sprintf(sname, "%X", (int)ic);
- if (!haswin_icontosprite(ic, sname, sarea))
- haswin_errorprintf("can't create sprite '%s' from icon %s in window %s", sname, ic->name, haswin_getwindowtitle(wptr));
- }
- }
- for (wptr=win->pane; wptr; wptr=wptr->pane) {
- haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
- tmpjob = haswin_getwindowxmin(wptr);
- if (tmpjob < xmin)
- xmin = tmpjob;
- tmpjob += haswin_getwindowxextent(wptr);
- if (tmpjob > xmax)
- xmax = tmpjob;
- tmpjob = haswin_getwindowymin(wptr);
- if (tmpjob < ymin)
- ymin = tmpjob;
- tmpjob += haswin_getwindowyextent(wptr);
- if (tmpjob > ymax)
- ymax = tmpjob;
- for (ic=wptr->icons; ic; ic=ic->next) {
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- sprintf(sname, "%X", (int)ic);
- if (!haswin_icontosprite(ic, sname, sarea))
- haswin_errorprintf("can't create sprite '%s' from icon %s in window %s", sname, ic->name, haswin_getwindowtitle(wptr));
- }
- }
- /*
- * we now have all the icons in sprites and the overall window
- * sized (xmin,ymin) to (xmax,ymax) in OS units.
- * Now we calculate the transformation matrix given the rotation
- * and the scaling factors for this job.
- * x' = (X*trans[0] + Y*trans[2])>>16
- * y' = (X*trans[1] + Y*trans[3])>>16
- * for scaling trans[0] = xscale
- * trans[1] = xscale
- * trans[2] = yscale
- * trans[3] = yscale
- * for rotation trans[0] = +cos(360-rotate)
- * trans[1] = +sin(360-rotate)
- * trans[2] = -sin(360-rotate)
- * trans[3] = -cos(360-rotate) { +cos() }
- *
- * this might result in a window too large for our purposes, if so
- * then calculate the correct scaling factors and put the printer
- * selection box up to allow the user to change things before
- * repeating the calculations.
- */
- xmin *= 400;
- xmax *= 400;
- ymin *= 400;
- ymax *= 400;
- do {
- f = cos((360.0-haswin_pjob->rotate)/DEG_RAD);
- trans[0] = (int)(f*haswin_pjob->xscale);
- trans[3] = (int)(f*haswin_pjob->yscale);
- g = sin((360.0-haswin_pjob->rotate)/DEG_RAD);
- trans[1] = (int)(g*haswin_pjob->xscale);
- trans[2] = (int)((-g)*haswin_pjob->yscale);
- /*
- * Next we transform the overall window to the
- * transformation matrix.
- */
- txmin=(int)(xmin*(trans[0]/65536.0)+ymin*(trans[2]/65536.0));
- tymin=(int)(xmin*(trans[1]/65536.0)+ymin*(trans[3]/65536.0));
- txmax=(int)(xmax*(trans[0]/65536.0)+ymax*(trans[2]/65536.0));
- tymax=(int)(xmax*(trans[1]/65536.0)+ymax*(trans[3]/65536.0));
- /*
- * now, of course txmin, tymin, txmax and tymax may not
- * form a rectangle on the paper. adjust them to the
- * enclosing rectangle.
- */
- if (txmin > txmax) {
- tmpjob = txmax;
- txmax = txmin;
- txmin = tmpjob;
- }
- if (tymin > tymax) {
- tmpjob = tymax;
- tymax = tymin;
- tymin = tmpjob;
- }
- haswin_pjob->xsize = txmax - txmin;
- haswin_pjob->ysize = tymax - tymin;
- if ((haswin_pjob->xsize > haswin_pjob->rprint-haswin_pjob->lprint) || (haswin_pjob->ysize > haswin_pjob->tprint-haswin_pjob->bprint)) {
- f=(double)(haswin_pjob->rprint-haswin_pjob->lprint)/
- (double)haswin_pjob->xsize;
- g=(double)(haswin_pjob->tprint-haswin_pjob->bprint)/
- (double)haswin_pjob->ysize;
- if (f < g) {
- haswin_pjob->xscale =
- (int)(haswin_pjob->xscale*f);
- haswin_pjob->yscale =
- (int)(haswin_pjob->yscale*f);
- } else {
- haswin_pjob->xscale =
- (int)(haswin_pjob->xscale*g);
- haswin_pjob->yscale =
- (int)(haswin_pjob->yscale*g);
- }
- strcpy(sname, haswin_geticontitle(haswin_stat));
- haswin_seticondata(haswin_cont, "Try Again");
- haswin_seticondata(haswin_stat, "Drawing too big");
- haswin_reopenwindow(haswin_pict->window);
- haswin_awaitterminate();
- haswin_seticondata(haswin_cont, "Abort");
- haswin_seticondata(haswin_stat, sname);
- haswin_reopenwindow(haswin_printwin);
- more = HASWIN_TRUE;
- } else
- more = HASWIN_FALSE;
- } while (more);
- /* select the printer job */
- haswin_seticondata(haswin_stat, "Starting Job");
- haswin_pollcomplete();
- if ((oldjob=haswin_pdriverselectjob(haswin_pjob))==HASWIN_UNKNOWN) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Cannot Start Job");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- /* we will have one rectangle for each window, pane and slide. */
- /* get scaling and rotation transform from haswin_pjob */
- /* position of first (master) window is bottom left of page */
- /* size of rectangle from window description */
- winnum = _haswin_printwindow1(win, trans, haswin_pjob->lprint,
- haswin_pjob->bprint, txmin, tymin);
- if (winnum == -1) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Cannot Process Job");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- regs.r[0] = 1;
- regs.r[1] = (int)rect;
- regs.r[2] = 0;
- regs.r[3] = 0;
- regs.r[4] = 0xFFFFFF00;
- if (!haswin_swi(HASWIN_PD_DrawPage, ®s)) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- more = regs.r[0];
- wptr = (window *)regs.r[2];
- while (more) {
- tmpjob = haswin_pdriverselect(0);
- haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
- haswin_seticondata(haswin_stat, "Processing Job");
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- haswin_pdriverselect(tmpjob);
- /*
- * plot the given window. Make it look like the draw
- * request is coming from a window redraw. Therefore
- * we have to first make the buffer. We make the
- * window look like full size and not scrolled.
- */
- haswin_updatewindowinfo(wptr);
- buff.i[ 0] = wptr->handle;
- buff.i[ 1] = 0;
- buff.i[ 2] = 0;
- buff.i[ 3] = haswin_getwindowxextent(wptr);
- buff.i[ 4] = haswin_getwindowyextent(wptr);
- buff.i[ 5] = 0;
- buff.i[ 6] = 0;
- buff.i[ 7] = rect[0];
- buff.i[ 8] = rect[1];
- buff.i[ 9] = rect[2];
- buff.i[10] = rect[3];
- graphics_gcol(0, wptr->win[35]);
- graphics_rectanglefill(rect[0], rect[1], rect[2]-rect[0], rect[3]-rect[1]);
- tmpjob = haswin_pdriverselect(0);
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- haswin_pdriverselect(tmpjob);
- if (!((wptr->drawroutine) &&
- (!wptr->drawroutine(wptr, &buff)))) {
- if (wptr->text) {
- text_plot(wptr->text, wptr->orgx,
- buff.i[4]+wptr->orgy,
- rect[0], rect[2], rect[1], rect[3]);
- }
- tmpjob = haswin_pdriverselect(0);
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- haswin_pdriverselect(tmpjob);
- if (wptr->picture) {
- graphics_plot(wptr->picture, wptr->orgx,
- buff.i[4]+wptr->orgy,
- rect[0], rect[2], rect[1], rect[3]);
- }
- }
- tmpjob = haswin_pdriverselect(0);
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- haswin_pdriverselect(tmpjob);
- for (ic=wptr->icons; ic; ic=ic->next) {
- tmpjob = haswin_pdriverselect(0);
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat,
- "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- haswin_pdriverselect(tmpjob);
- sprintf(sname, "%X", (int)ic);
- /* search for the sprite */
- regs.r[0] = 0x118;
- regs.r[1] = (int)sarea;
- regs.r[2] = (int)sname;
- haswin_spriteop(0, ®s);
- /* now we plot the sprite */
- regs.r[0] = 0x222;
- regs.r[3] = wptr->orgx+ic->ic[0];
- regs.r[4] = buff.i[4]+wptr->orgy+ic->ic[1];
- regs.r[5] = 0;
- haswin_spriteop(0, ®s);
- }
- tmpjob = haswin_pdriverselect(0);
- haswin_seticondata(haswin_wind, haswin_getwindowname(wptr));
- haswin_seticondata(haswin_stat, "Printing Job");
- _haswin_printmugwatch(HASWIN_TRUE);
- haswin_pollcomplete();
- if (haswin_ended) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Job Cancelled");
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- haswin_pdriverselect(tmpjob);
- haswin_hourglass(HASWIN_TRUE);
- regs.r[1] = (int)rect;
- if (!haswin_swi(HASWIN_PD_GetRectangle, ®s)) {
- haswin_pdriverkilljob(haswin_pjob);
- haswin_hourglass(HASWIN_FALSE);
- haswin_awaitterminate();
- haswin_closewindow(haswin_printwin);
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_pjob = 0;
- return(HASWIN_FALSE);
- }
- more = regs.r[0];
- wptr = (window *)regs.r[2];
- haswin_hourglass(HASWIN_FALSE);
- }
- /* select the old job if there was one */
- if (oldjob)
- haswin_pdriverselect(oldjob);
- /* now we terminate the print job */
- haswin_pdriverendjob(haswin_pjob);
- haswin_seticondata(haswin_stat, "Finished Job");
- haswin_seticondata(haswin_cont, "Continue");
- haswin_awaitterminate();
- haswin_pjob = 0;
- haswin_removespritearea(&sarea);
- haswin_free(sarea);
- haswin_closewindow(haswin_printwin);
- return(HASWIN_TRUE);
- }
-
- /*
- * Printer control routines. We provide an interface to the Acorn
- * printer applications. This is done in the same way as the Filer
- * file save interface and requires a single user print routine.
- */
-
- void haswin_setprintfileroutine(int (*user)(char *, buffer *)) {
-
- haswin_printfileroutine = user;
- }
-
-