1*37da2899SCharles.Forsythimplement Print; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsythinclude "draw.m"; 6*37da2899SCharles.Forsyth draw: Draw; 7*37da2899SCharles.Forsyth Display, Font, Rect, Point, Image, Screen: import draw; 8*37da2899SCharles.Forsythinclude "bufio.m"; 9*37da2899SCharles.Forsyth bufio: Bufio; 10*37da2899SCharles.Forsythinclude "string.m"; 11*37da2899SCharles.Forsyth str: String; 12*37da2899SCharles.Forsyth 13*37da2899SCharles.Forsythinclude "print.m"; 14*37da2899SCharles.Forsyth 15*37da2899SCharles.ForsythMAXNAME: con 80; 16*37da2899SCharles.ForsythDEFMODE: con 8r664; 17*37da2899SCharles.Forsyth 18*37da2899SCharles.ForsythPAPER_CONFIG: con CONFIG_PATH + "paper.cfg"; 19*37da2899SCharles.ForsythPTYPE_CONFIG: con CONFIG_PATH + "ptype.cfg"; 20*37da2899SCharles.ForsythPMODE_CONFIG: con CONFIG_PATH + "pmode.cfg"; 21*37da2899SCharles.ForsythPOPT_CONFIG: con CONFIG_PATH + "popt.cfg"; 22*37da2899SCharles.ForsythPRINTER_CONFIG: con CONFIG_PATH + "printer.cfg"; 23*37da2899SCharles.ForsythDEFPRINTER: con CONFIG_PATH + "defprinter"; 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth 26*37da2899SCharles.ForsythCfg: adt { 27*37da2899SCharles.Forsyth name: string; 28*37da2899SCharles.Forsyth pairs: list of (string, string); 29*37da2899SCharles.Forsyth}; 30*37da2899SCharles.Forsyth 31*37da2899SCharles.ForsythDEBUG :=0; 32*37da2899SCharles.Forsyth 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsythall_papers: list of ref Paper; 35*37da2899SCharles.Forsythall_pmodes: list of ref Pmode; 36*37da2899SCharles.Forsythall_ptypes: list of ref Ptype; 37*37da2899SCharles.Forsythall_popts: list of ref Popt; 38*37da2899SCharles.Forsythall_printers: list of ref Printer; 39*37da2899SCharles.Forsythdefault_printer: ref Printer; 40*37da2899SCharles.Forsythstderr: ref Sys->FD; 41*37da2899SCharles.Forsythprintfd: ref Sys->FD; 42*37da2899SCharles.Forsyth 43*37da2899SCharles.Forsyth# Initialization 44*37da2899SCharles.Forsyth 45*37da2899SCharles.Forsythinit(): int 46*37da2899SCharles.Forsyth{ 47*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 48*37da2899SCharles.Forsyth stderr = sys->fildes(2); 49*37da2899SCharles.Forsyth draw = load Draw Draw->PATH; 50*37da2899SCharles.Forsyth bufio = load Bufio Bufio->PATH; 51*37da2899SCharles.Forsyth str = load String String->PATH; 52*37da2899SCharles.Forsyth all_papers = read_paper_config(); 53*37da2899SCharles.Forsyth if (all_papers == nil) return 1; 54*37da2899SCharles.Forsyth all_pmodes = read_pmode_config(); 55*37da2899SCharles.Forsyth if (all_pmodes == nil) return 1; 56*37da2899SCharles.Forsyth all_ptypes = read_ptype_config(); 57*37da2899SCharles.Forsyth if (all_ptypes == nil) return 1; 58*37da2899SCharles.Forsyth all_printers = read_printer_config(); 59*37da2899SCharles.Forsyth if (all_printers == nil) return 1; 60*37da2899SCharles.Forsyth all_popts = read_popt_config(); 61*37da2899SCharles.Forsyth for (pl:=all_printers; pl!=nil; pl=tl pl) { 62*37da2899SCharles.Forsyth p := hd pl; 63*37da2899SCharles.Forsyth opt := find_popt(all_popts, p.name); 64*37da2899SCharles.Forsyth if (opt != nil) p.popt = opt; 65*37da2899SCharles.Forsyth else { 66*37da2899SCharles.Forsyth p.popt = ref Popt (p.name, hd all_pmodes, hd all_papers, 0, 0); 67*37da2899SCharles.Forsyth all_popts = p.popt :: all_popts; 68*37da2899SCharles.Forsyth } 69*37da2899SCharles.Forsyth } 70*37da2899SCharles.Forsyth return 0; 71*37da2899SCharles.Forsyth} 72*37da2899SCharles.Forsyth 73*37da2899SCharles.Forsyth# Set printer FD 74*37da2899SCharles.Forsyth 75*37da2899SCharles.Forsythset_printfd(fd: ref Sys->FD) 76*37da2899SCharles.Forsyth{ 77*37da2899SCharles.Forsyth printfd = fd; 78*37da2899SCharles.Forsyth} 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth 81*37da2899SCharles.Forsyth# Get default printer 82*37da2899SCharles.Forsyth 83*37da2899SCharles.Forsythget_defprinter(): ref Printer 84*37da2899SCharles.Forsyth{ 85*37da2899SCharles.Forsyth if (len all_printers == 1) return hd all_printers; # If there's only 1 printer 86*37da2899SCharles.Forsyth df := sys->open(DEFPRINTER, Sys->OREAD); 87*37da2899SCharles.Forsyth if (df == nil) { 88*37da2899SCharles.Forsyth if (all_printers != nil) return hd all_printers; 89*37da2899SCharles.Forsyth else return nil; 90*37da2899SCharles.Forsyth } 91*37da2899SCharles.Forsyth a := array[MAXNAME] of byte; 92*37da2899SCharles.Forsyth nb := sys->read(df, a, MAXNAME); 93*37da2899SCharles.Forsyth if (nb < 2) return nil; 94*37da2899SCharles.Forsyth name := string a[:nb-1]; 95*37da2899SCharles.Forsyth def := find_printer(all_printers, name); 96*37da2899SCharles.Forsyth if (def != nil) return def; 97*37da2899SCharles.Forsyth else return hd all_printers; 98*37da2899SCharles.Forsyth} 99*37da2899SCharles.Forsyth 100*37da2899SCharles.Forsyth# Set default printer 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsythset_defprinter(p: ref Printer) 103*37da2899SCharles.Forsyth{ 104*37da2899SCharles.Forsyth df := sys->create(DEFPRINTER, Sys->OWRITE, DEFMODE); 105*37da2899SCharles.Forsyth if (df == nil) return; 106*37da2899SCharles.Forsyth sys->fprint(df, "%s\n", p.name); 107*37da2899SCharles.Forsyth} 108*37da2899SCharles.Forsyth 109*37da2899SCharles.Forsyth# Set paper size 110*37da2899SCharles.Forsyth 111*37da2899SCharles.Forsythget_size(p: ref Printer): (int, int, int) # dpi, xpixels, ypixels 112*37da2899SCharles.Forsyth{ 113*37da2899SCharles.Forsyth if (p == nil) return (0, 0, 0); 114*37da2899SCharles.Forsyth load_driver(p); 115*37da2899SCharles.Forsyth dpi := p.popt.mode.resx; 116*37da2899SCharles.Forsyth (xpix, ypix) := p.pdriver->printable_pixels(p); # This takes account of orientation 117*37da2899SCharles.Forsyth return (dpi, xpix, ypix); 118*37da2899SCharles.Forsyth} 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth 121*37da2899SCharles.Forsyth 122*37da2899SCharles.Forsyth# Get list of all printers 123*37da2899SCharles.Forsyth 124*37da2899SCharles.Forsythget_printers(): list of ref Printer 125*37da2899SCharles.Forsyth{ 126*37da2899SCharles.Forsyth return all_printers; 127*37da2899SCharles.Forsyth} 128*37da2899SCharles.Forsyth 129*37da2899SCharles.Forsyth# Return list of printer types 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsythget_ptypes(): list of ref Ptype 132*37da2899SCharles.Forsyth{ 133*37da2899SCharles.Forsyth return all_ptypes; 134*37da2899SCharles.Forsyth} 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth# Return list of print modes 137*37da2899SCharles.Forsyth 138*37da2899SCharles.Forsythget_pmodes(): list of ref Pmode 139*37da2899SCharles.Forsyth{ 140*37da2899SCharles.Forsyth return all_pmodes; 141*37da2899SCharles.Forsyth} 142*37da2899SCharles.Forsyth 143*37da2899SCharles.Forsyth# Return list of paper types 144*37da2899SCharles.Forsyth 145*37da2899SCharles.Forsythget_papers(): list of ref Paper 146*37da2899SCharles.Forsyth{ 147*37da2899SCharles.Forsyth return all_papers; 148*37da2899SCharles.Forsyth} 149*37da2899SCharles.Forsyth 150*37da2899SCharles.Forsyth# Return list of print options 151*37da2899SCharles.Forsyth 152*37da2899SCharles.Forsythget_popts(): list of ref Popt 153*37da2899SCharles.Forsyth{ 154*37da2899SCharles.Forsyth return all_popts; 155*37da2899SCharles.Forsyth} 156*37da2899SCharles.Forsyth 157*37da2899SCharles.Forsyth# Save option settings 158*37da2899SCharles.Forsyth 159*37da2899SCharles.Forsythsave_settings(): int 160*37da2899SCharles.Forsyth{ 161*37da2899SCharles.Forsyth return write_popt_config(all_popts); 162*37da2899SCharles.Forsyth 163*37da2899SCharles.Forsyth} 164*37da2899SCharles.Forsyth 165*37da2899SCharles.Forsyth 166*37da2899SCharles.Forsyth# Print an image 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsythprint_image(p: ref Printer, display: ref Draw->Display, im: ref Draw->Image, pcwidth: int, cancel: chan of int): int 169*37da2899SCharles.Forsyth{ 170*37da2899SCharles.Forsyth if (p == nil || im == nil) return 1; 171*37da2899SCharles.Forsyth load_driver(p); 172*37da2899SCharles.Forsyth popen(p); 173*37da2899SCharles.Forsyth (xpix, ypix) := p.pdriver->printable_pixels(p); 174*37da2899SCharles.Forsyth imwidth := im.r.max.x - im.r.min.x; 175*37da2899SCharles.Forsyth imheight := im.r.max.y - im.r.min.y; 176*37da2899SCharles.Forsyth if (pcwidth > 0) pixwidth := int (real xpix * real pcwidth/100.0); 177*37da2899SCharles.Forsyth else pixwidth = imwidth; 178*37da2899SCharles.Forsyth lmar := (xpix - pixwidth)/2; 179*37da2899SCharles.Forsyth fpixwidth := pixwidth; 180*37da2899SCharles.Forsyth if (p.popt.orientation != PORTRAIT) { 181*37da2899SCharles.Forsyth lmar += pixwidth; 182*37da2899SCharles.Forsyth fpixwidth = pixwidth*imheight/imwidth; 183*37da2899SCharles.Forsyth } 184*37da2899SCharles.Forsyth if (lmar < 0) lmar = 0; 185*37da2899SCharles.Forsyth return p.pdriver->sendimage(p, printfd, display, im, fpixwidth, lmar, cancel); 186*37da2899SCharles.Forsyth} 187*37da2899SCharles.Forsyth 188*37da2899SCharles.Forsyth# Print text 189*37da2899SCharles.Forsyth 190*37da2899SCharles.Forsythprint_textfd(p: ref Printer, fd: ref Sys->FD, ps: real, pr: int, wrap: int): int 191*37da2899SCharles.Forsyth{ 192*37da2899SCharles.Forsyth load_driver(p); 193*37da2899SCharles.Forsyth popen(p); 194*37da2899SCharles.Forsyth return p.pdriver->sendtextfd(p, printfd, fd, ps, pr, wrap); 195*37da2899SCharles.Forsyth 196*37da2899SCharles.Forsyth} 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth 199*37da2899SCharles.Forsyth# Open printer device if necessary 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsythpopen(p: ref Printer) 202*37da2899SCharles.Forsyth{ 203*37da2899SCharles.Forsyth if (printfd != nil) return; 204*37da2899SCharles.Forsyth printfd = sys->create(p.device, Sys->OWRITE, DEFMODE); 205*37da2899SCharles.Forsyth} 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth# Find printer item 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsythfind_printer(all: list of ref Printer, name: string): ref Printer 210*37da2899SCharles.Forsyth{ 211*37da2899SCharles.Forsyth for (p:=all; p!=nil; p=tl p) if ((hd p).name == name) return hd p; 212*37da2899SCharles.Forsyth return nil; 213*37da2899SCharles.Forsyth} 214*37da2899SCharles.Forsyth 215*37da2899SCharles.Forsyth# Find popt item 216*37da2899SCharles.Forsyth 217*37da2899SCharles.Forsythfind_popt(all: list of ref Popt, name: string): ref Popt 218*37da2899SCharles.Forsyth{ 219*37da2899SCharles.Forsyth for (p:=all; p!=nil; p=tl p) if ((hd p).name == name) return hd p; 220*37da2899SCharles.Forsyth return nil; 221*37da2899SCharles.Forsyth} 222*37da2899SCharles.Forsyth 223*37da2899SCharles.Forsyth 224*37da2899SCharles.Forsyth# Find paper item 225*37da2899SCharles.Forsyth 226*37da2899SCharles.Forsythfind_paper(all: list of ref Paper, name: string): ref Paper 227*37da2899SCharles.Forsyth{ 228*37da2899SCharles.Forsyth for (p:=all; p!=nil; p=tl p) if ((hd p).name == name) return hd p; 229*37da2899SCharles.Forsyth return nil; 230*37da2899SCharles.Forsyth} 231*37da2899SCharles.Forsyth 232*37da2899SCharles.Forsyth# Find pmode item 233*37da2899SCharles.Forsyth 234*37da2899SCharles.Forsythfind_pmode(all: list of ref Pmode, name: string): ref Pmode 235*37da2899SCharles.Forsyth{ 236*37da2899SCharles.Forsyth for (p:=all; p!=nil; p=tl p) if ((hd p).name == name) return hd p; 237*37da2899SCharles.Forsyth return nil; 238*37da2899SCharles.Forsyth} 239*37da2899SCharles.Forsyth 240*37da2899SCharles.Forsyth# Find ptype item 241*37da2899SCharles.Forsyth 242*37da2899SCharles.Forsythfind_ptype(all: list of ref Ptype, name: string): ref Ptype 243*37da2899SCharles.Forsyth{ 244*37da2899SCharles.Forsyth for (p:=all; p!=nil; p=tl p) if ((hd p).name == name) return hd p; 245*37da2899SCharles.Forsyth return nil; 246*37da2899SCharles.Forsyth} 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth 249*37da2899SCharles.Forsyth# Read paper config file 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsythread_paper_config(): list of ref Paper 252*37da2899SCharles.Forsyth{ 253*37da2899SCharles.Forsyth (clist, aliases) := read_config(PAPER_CONFIG); 254*37da2899SCharles.Forsyth rlist: list of ref Paper; 255*37da2899SCharles.Forsyth while (clist != nil) { 256*37da2899SCharles.Forsyth this := hd clist; 257*37da2899SCharles.Forsyth clist = tl clist; 258*37da2899SCharles.Forsyth item := ref Paper(this.name, "", 0.0, 0.0); 259*37da2899SCharles.Forsyth for (pairs:= this.pairs; pairs != nil; pairs = tl pairs) { 260*37da2899SCharles.Forsyth (name, value) := hd pairs; 261*37da2899SCharles.Forsyth case (name) { 262*37da2899SCharles.Forsyth "hpcode" => 263*37da2899SCharles.Forsyth item.hpcode = value; 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth "width_inches" => 266*37da2899SCharles.Forsyth item.width_inches = real value; 267*37da2899SCharles.Forsyth 268*37da2899SCharles.Forsyth "height_inches" => 269*37da2899SCharles.Forsyth item.height_inches = real value; 270*37da2899SCharles.Forsyth 271*37da2899SCharles.Forsyth * => 272*37da2899SCharles.Forsyth sys->fprint(stderr, "Unknown paper config file option: %s\n", name); 273*37da2899SCharles.Forsyth } 274*37da2899SCharles.Forsyth } 275*37da2899SCharles.Forsyth rlist =item :: rlist; 276*37da2899SCharles.Forsyth } 277*37da2899SCharles.Forsyth for (al:=aliases; al!=nil; al=tl al) { 278*37da2899SCharles.Forsyth (new, old) := hd al; 279*37da2899SCharles.Forsyth olda := find_paper(rlist, old); 280*37da2899SCharles.Forsyth if (olda == nil) sys->fprint(stderr, "Paper alias %s not found\n", old); 281*37da2899SCharles.Forsyth else { 282*37da2899SCharles.Forsyth newa := ref *olda; 283*37da2899SCharles.Forsyth newa.name = new; 284*37da2899SCharles.Forsyth rlist = newa :: rlist; 285*37da2899SCharles.Forsyth } 286*37da2899SCharles.Forsyth } 287*37da2899SCharles.Forsyth return rlist; 288*37da2899SCharles.Forsyth} 289*37da2899SCharles.Forsyth 290*37da2899SCharles.Forsyth 291*37da2899SCharles.Forsyth# Read pmode config file 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsythread_pmode_config(): list of ref Pmode 294*37da2899SCharles.Forsyth{ 295*37da2899SCharles.Forsyth (clist, aliases) := read_config(PMODE_CONFIG); 296*37da2899SCharles.Forsyth rlist: list of ref Pmode; 297*37da2899SCharles.Forsyth while (clist != nil) { 298*37da2899SCharles.Forsyth this := hd clist; 299*37da2899SCharles.Forsyth clist = tl clist; 300*37da2899SCharles.Forsyth item := ref Pmode(this.name, "", 0, 0, 1, 1, 1); 301*37da2899SCharles.Forsyth for (pairs:= this.pairs; pairs != nil; pairs = tl pairs) { 302*37da2899SCharles.Forsyth (name, value) := hd pairs; 303*37da2899SCharles.Forsyth case (name) { 304*37da2899SCharles.Forsyth "desc" => 305*37da2899SCharles.Forsyth item.desc = value; 306*37da2899SCharles.Forsyth 307*37da2899SCharles.Forsyth "resx" => 308*37da2899SCharles.Forsyth item.resx = int value; 309*37da2899SCharles.Forsyth 310*37da2899SCharles.Forsyth "resy" => 311*37da2899SCharles.Forsyth item.resy = int value; 312*37da2899SCharles.Forsyth 313*37da2899SCharles.Forsyth "coldepth" => 314*37da2899SCharles.Forsyth item.coldepth = int value; 315*37da2899SCharles.Forsyth 316*37da2899SCharles.Forsyth "blackdepth" => 317*37da2899SCharles.Forsyth item.blackdepth = int value; 318*37da2899SCharles.Forsyth 319*37da2899SCharles.Forsyth "blackresmult" => 320*37da2899SCharles.Forsyth item.blackresmult = int value; 321*37da2899SCharles.Forsyth 322*37da2899SCharles.Forsyth * => 323*37da2899SCharles.Forsyth sys->fprint(stderr, "Unknown pmode config file option: %s\n", name); 324*37da2899SCharles.Forsyth 325*37da2899SCharles.Forsyth } 326*37da2899SCharles.Forsyth } 327*37da2899SCharles.Forsyth rlist =item :: rlist; 328*37da2899SCharles.Forsyth } 329*37da2899SCharles.Forsyth for (al:=aliases; al!=nil; al=tl al) { 330*37da2899SCharles.Forsyth (new, old) := hd al; 331*37da2899SCharles.Forsyth olda := find_pmode(rlist, old); 332*37da2899SCharles.Forsyth if (olda == nil) sys->fprint(stderr, "Pmode alias %s not found\n", old); 333*37da2899SCharles.Forsyth else { 334*37da2899SCharles.Forsyth newa := ref *olda; 335*37da2899SCharles.Forsyth newa.name = new; 336*37da2899SCharles.Forsyth rlist = newa :: rlist; 337*37da2899SCharles.Forsyth } 338*37da2899SCharles.Forsyth } 339*37da2899SCharles.Forsyth return rlist; 340*37da2899SCharles.Forsyth} 341*37da2899SCharles.Forsyth 342*37da2899SCharles.Forsyth 343*37da2899SCharles.Forsyth 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsyth# Readp Ptype config file 346*37da2899SCharles.Forsyth 347*37da2899SCharles.Forsythread_ptype_config(): list of ref Ptype 348*37da2899SCharles.Forsyth{ 349*37da2899SCharles.Forsyth (clist, aliases) := read_config(PTYPE_CONFIG); 350*37da2899SCharles.Forsyth rlist: list of ref Ptype; 351*37da2899SCharles.Forsyth while (clist != nil) { 352*37da2899SCharles.Forsyth this := hd clist; 353*37da2899SCharles.Forsyth clist = tl clist; 354*37da2899SCharles.Forsyth item := ref Ptype(this.name, "", nil, "", ""); 355*37da2899SCharles.Forsyth for (pairs:= this.pairs; pairs != nil; pairs = tl pairs) { 356*37da2899SCharles.Forsyth (name, value) := hd pairs; 357*37da2899SCharles.Forsyth case (name) { 358*37da2899SCharles.Forsyth "desc" => 359*37da2899SCharles.Forsyth item.desc = value; 360*37da2899SCharles.Forsyth 361*37da2899SCharles.Forsyth "driver" => 362*37da2899SCharles.Forsyth item.driver = value; 363*37da2899SCharles.Forsyth 364*37da2899SCharles.Forsyth "hpmapfile" => 365*37da2899SCharles.Forsyth item.hpmapfile = value; 366*37da2899SCharles.Forsyth 367*37da2899SCharles.Forsyth "modes" => 368*37da2899SCharles.Forsyth item.modes = make_pmode_list(value); 369*37da2899SCharles.Forsyth 370*37da2899SCharles.Forsyth * => 371*37da2899SCharles.Forsyth sys->fprint(stderr, "Unknown ptype config file option: %s\n", name); 372*37da2899SCharles.Forsyth } 373*37da2899SCharles.Forsyth } 374*37da2899SCharles.Forsyth if (item.modes == nil) { 375*37da2899SCharles.Forsyth sys->fprint(stderr, "No print modes for ptype %s\n", item.name); 376*37da2899SCharles.Forsyth continue; 377*37da2899SCharles.Forsyth } 378*37da2899SCharles.Forsyth rlist = item :: rlist; 379*37da2899SCharles.Forsyth } 380*37da2899SCharles.Forsyth for (al:=aliases; al!=nil; al=tl al) { 381*37da2899SCharles.Forsyth (new, old) := hd al; 382*37da2899SCharles.Forsyth olda := find_ptype(rlist, old); 383*37da2899SCharles.Forsyth if (olda == nil) sys->fprint(stderr, "Ptype alias %s not found\n", old); 384*37da2899SCharles.Forsyth else { 385*37da2899SCharles.Forsyth newa := ref *olda; 386*37da2899SCharles.Forsyth newa.name = new; 387*37da2899SCharles.Forsyth rlist = newa :: rlist; 388*37da2899SCharles.Forsyth } 389*37da2899SCharles.Forsyth } 390*37da2899SCharles.Forsyth return rlist; 391*37da2899SCharles.Forsyth} 392*37da2899SCharles.Forsyth 393*37da2899SCharles.Forsyth 394*37da2899SCharles.Forsyth# Make a list of pmodes from a string 395*37da2899SCharles.Forsyth 396*37da2899SCharles.Forsythmake_pmode_list(sl: string): list of ref Pmode 397*37da2899SCharles.Forsyth{ 398*37da2899SCharles.Forsyth pml: list of ref Pmode; 399*37da2899SCharles.Forsyth (n, toks) := sys->tokenize(sl, " \t"); 400*37da2899SCharles.Forsyth if (n == 0) return nil; 401*37da2899SCharles.Forsyth for (i:=0; i<n; i++) { 402*37da2899SCharles.Forsyth pms := hd toks; 403*37da2899SCharles.Forsyth toks = tl toks; 404*37da2899SCharles.Forsyth pm := find_pmode(all_pmodes, pms); 405*37da2899SCharles.Forsyth if (pm == nil) { 406*37da2899SCharles.Forsyth sys->fprint(stderr, "unknown pmode: %s\n", pms); 407*37da2899SCharles.Forsyth continue; 408*37da2899SCharles.Forsyth } 409*37da2899SCharles.Forsyth pml = pm :: pml; 410*37da2899SCharles.Forsyth } 411*37da2899SCharles.Forsyth return pml; 412*37da2899SCharles.Forsyth} 413*37da2899SCharles.Forsyth 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth# Read popt config file 416*37da2899SCharles.Forsyth 417*37da2899SCharles.Forsythread_popt_config(): list of ref Popt 418*37da2899SCharles.Forsyth{ 419*37da2899SCharles.Forsyth (clist, aliases) := read_config(POPT_CONFIG); 420*37da2899SCharles.Forsyth rlist: list of ref Popt; 421*37da2899SCharles.Forsyth while (clist != nil) { 422*37da2899SCharles.Forsyth this := hd clist; 423*37da2899SCharles.Forsyth clist = tl clist; 424*37da2899SCharles.Forsyth item := ref Popt(this.name, nil, nil, 0, 0); 425*37da2899SCharles.Forsyth for (pairs:= this.pairs; pairs != nil; pairs = tl pairs) { 426*37da2899SCharles.Forsyth (name, value) := hd pairs; 427*37da2899SCharles.Forsyth case (name) { 428*37da2899SCharles.Forsyth 429*37da2899SCharles.Forsyth "mode" => 430*37da2899SCharles.Forsyth item.mode = find_pmode(all_pmodes, value); 431*37da2899SCharles.Forsyth if (item.mode == nil) sys->fprint(stderr, "Config error: Pmode not found: %s\n", value); 432*37da2899SCharles.Forsyth 433*37da2899SCharles.Forsyth "paper" => 434*37da2899SCharles.Forsyth item.paper = find_paper(all_papers, value); 435*37da2899SCharles.Forsyth if (item.paper == nil) sys->fprint(stderr, "Config error: paper not found: %s\n", value); 436*37da2899SCharles.Forsyth 437*37da2899SCharles.Forsyth "orientation" => 438*37da2899SCharles.Forsyth item.orientation = int value; 439*37da2899SCharles.Forsyth "duplex" => 440*37da2899SCharles.Forsyth item.duplex = int value; 441*37da2899SCharles.Forsyth 442*37da2899SCharles.Forsyth * => 443*37da2899SCharles.Forsyth sys->fprint(stderr, "Unknown popt config file option: %s\n", name); 444*37da2899SCharles.Forsyth } 445*37da2899SCharles.Forsyth } 446*37da2899SCharles.Forsyth if (item.mode == nil) { 447*37da2899SCharles.Forsyth sys->fprint(stderr, "No print mode for printer %s\n", item.name); 448*37da2899SCharles.Forsyth continue; 449*37da2899SCharles.Forsyth } 450*37da2899SCharles.Forsyth if (item.paper == nil) { 451*37da2899SCharles.Forsyth sys->fprint(stderr, "No paper size for printer %s\n", item.name); 452*37da2899SCharles.Forsyth continue; 453*37da2899SCharles.Forsyth } 454*37da2899SCharles.Forsyth rlist = item :: rlist; 455*37da2899SCharles.Forsyth } 456*37da2899SCharles.Forsyth for (al:=aliases; al!=nil; al=tl al) { 457*37da2899SCharles.Forsyth (new, old) := hd al; 458*37da2899SCharles.Forsyth olda := find_popt(rlist, old); 459*37da2899SCharles.Forsyth if (olda == nil) sys->fprint(stderr, "Popt alias %s not found\n", old); 460*37da2899SCharles.Forsyth else { 461*37da2899SCharles.Forsyth newa := ref *olda; 462*37da2899SCharles.Forsyth newa.name = new; 463*37da2899SCharles.Forsyth rlist = newa :: rlist; 464*37da2899SCharles.Forsyth } 465*37da2899SCharles.Forsyth } 466*37da2899SCharles.Forsyth return rlist; 467*37da2899SCharles.Forsyth} 468*37da2899SCharles.Forsyth 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth 471*37da2899SCharles.Forsyth 472*37da2899SCharles.Forsyth# Read printer config file 473*37da2899SCharles.Forsyth 474*37da2899SCharles.Forsythread_printer_config(): list of ref Printer 475*37da2899SCharles.Forsyth{ 476*37da2899SCharles.Forsyth (clist, aliases) := read_config(PRINTER_CONFIG); 477*37da2899SCharles.Forsyth rlist: list of ref Printer; 478*37da2899SCharles.Forsyth while (clist != nil) { 479*37da2899SCharles.Forsyth this := hd clist; 480*37da2899SCharles.Forsyth clist = tl clist; 481*37da2899SCharles.Forsyth item := ref Printer(this.name, nil, "", nil, nil); 482*37da2899SCharles.Forsyth for (pairs:= this.pairs; pairs != nil; pairs = tl pairs) { 483*37da2899SCharles.Forsyth (name, value) := hd pairs; 484*37da2899SCharles.Forsyth case (name) { 485*37da2899SCharles.Forsyth "ptype" => 486*37da2899SCharles.Forsyth item.ptype = find_ptype(all_ptypes, value); 487*37da2899SCharles.Forsyth if (item.ptype == nil) sys->fprint(stderr, "Config error: Ptype not found: %s\n", value); 488*37da2899SCharles.Forsyth 489*37da2899SCharles.Forsyth "device" => 490*37da2899SCharles.Forsyth item.device = value; 491*37da2899SCharles.Forsyth 492*37da2899SCharles.Forsyth * => 493*37da2899SCharles.Forsyth sys->fprint(stderr, "Unknown printer config file option: %s\n", name); 494*37da2899SCharles.Forsyth } 495*37da2899SCharles.Forsyth } 496*37da2899SCharles.Forsyth if (item.ptype == nil) { 497*37da2899SCharles.Forsyth sys->fprint(stderr, "No printer type for printer %s\n", item.name); 498*37da2899SCharles.Forsyth continue; 499*37da2899SCharles.Forsyth } 500*37da2899SCharles.Forsyth rlist = item :: rlist; 501*37da2899SCharles.Forsyth } 502*37da2899SCharles.Forsyth for (al:=aliases; al!=nil; al=tl al) { 503*37da2899SCharles.Forsyth (new, old) := hd al; 504*37da2899SCharles.Forsyth olda := find_printer(rlist, old); 505*37da2899SCharles.Forsyth if (olda == nil) sys->fprint(stderr, "Ptype alias %s not found\n", old); 506*37da2899SCharles.Forsyth else { 507*37da2899SCharles.Forsyth newa := ref *olda; 508*37da2899SCharles.Forsyth newa.name = new; 509*37da2899SCharles.Forsyth rlist = newa :: rlist; 510*37da2899SCharles.Forsyth } 511*37da2899SCharles.Forsyth } 512*37da2899SCharles.Forsyth return rlist; 513*37da2899SCharles.Forsyth} 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth# Write opt config file 516*37da2899SCharles.Forsyth 517*37da2899SCharles.Forsythwrite_popt_config(plist: list of ref Popt): int 518*37da2899SCharles.Forsyth{ 519*37da2899SCharles.Forsyth cfl: list of Cfg; 520*37da2899SCharles.Forsyth for (pl:=plist; pl!=nil; pl=tl pl) { 521*37da2899SCharles.Forsyth po := hd pl; 522*37da2899SCharles.Forsyth cf := Cfg(po.name, nil); 523*37da2899SCharles.Forsyth cf.pairs = ("mode", po.mode.name) :: cf.pairs; 524*37da2899SCharles.Forsyth cf.pairs = ("paper", po.paper.name) :: cf.pairs; 525*37da2899SCharles.Forsyth cf.pairs = ("orientation", sys->sprint("%d", po.orientation)) :: cf.pairs; 526*37da2899SCharles.Forsyth cf.pairs = ("duplex", sys->sprint("%d", po.duplex)) :: cf.pairs; 527*37da2899SCharles.Forsyth cfl = cf :: cfl; 528*37da2899SCharles.Forsyth } 529*37da2899SCharles.Forsyth return write_config(POPT_CONFIG, cfl, nil); 530*37da2899SCharles.Forsyth} 531*37da2899SCharles.Forsyth 532*37da2899SCharles.Forsyth 533*37da2899SCharles.Forsythwrite_config(fspec: string, clist: list of Cfg, aliases: list of (string, string)): int 534*37da2899SCharles.Forsyth{ 535*37da2899SCharles.Forsyth fd := sys->create(fspec, Sys->OWRITE, DEFMODE); 536*37da2899SCharles.Forsyth if (fd == nil) { 537*37da2899SCharles.Forsyth sys->fprint(stderr, "Failed to write to config file %s: %r\n", fspec); 538*37da2899SCharles.Forsyth return 1; 539*37da2899SCharles.Forsyth } 540*37da2899SCharles.Forsyth for (cfl:=clist; cfl!=nil; cfl=tl cfl) { 541*37da2899SCharles.Forsyth cf := hd cfl; 542*37da2899SCharles.Forsyth sys->fprint(fd, "%s=\n", cf.name); 543*37da2899SCharles.Forsyth for (pl:=cf.pairs; pl!=nil; pl=tl pl) { 544*37da2899SCharles.Forsyth (name, value) := hd pl; 545*37da2899SCharles.Forsyth if (sys->fprint(fd, "\t%s=%s\n", name, value) < 0) return 2; 546*37da2899SCharles.Forsyth } 547*37da2899SCharles.Forsyth } 548*37da2899SCharles.Forsyth for (al:=aliases; al!=nil; al=tl al) { 549*37da2899SCharles.Forsyth (new, old) := hd al; 550*37da2899SCharles.Forsyth if (sys->fprint(fd, "%s=%s\n", new, old)) return 2; 551*37da2899SCharles.Forsyth } 552*37da2899SCharles.Forsyth return 0; 553*37da2899SCharles.Forsyth} 554*37da2899SCharles.Forsyth 555*37da2899SCharles.Forsyth 556*37da2899SCharles.Forsyth# Read in a config file and return list of items and aliases 557*37da2899SCharles.Forsyth 558*37da2899SCharles.Forsythread_config(fspec: string): (list of Cfg, list of (string, string)) 559*37da2899SCharles.Forsyth{ 560*37da2899SCharles.Forsyth ib := bufio->open(fspec, Bufio->OREAD); 561*37da2899SCharles.Forsyth if (ib == nil) { 562*37da2899SCharles.Forsyth sys->fprint(stderr, "Failed to open config file %s: %r\n", fspec); 563*37da2899SCharles.Forsyth return (nil, nil); 564*37da2899SCharles.Forsyth } 565*37da2899SCharles.Forsyth clist: list of Cfg; 566*37da2899SCharles.Forsyth plist: list of (string, string); 567*37da2899SCharles.Forsyth section := ""; 568*37da2899SCharles.Forsyth aliases : list of (string, string); 569*37da2899SCharles.Forsyth while ((line := bufio->ib.gets('\n')) != nil) { 570*37da2899SCharles.Forsyth if (line[0] == '#') continue; 571*37da2899SCharles.Forsyth if (line[len line-1] == '\n') line = line[:len line-1]; 572*37da2899SCharles.Forsyth if (len line == 0) continue; 573*37da2899SCharles.Forsyth if (line[0] != ' ' && line[0] != '\t') { 574*37da2899SCharles.Forsyth if (section != "") clist = Cfg (section, plist) :: clist; 575*37da2899SCharles.Forsyth section = ""; 576*37da2899SCharles.Forsyth plist = nil; 577*37da2899SCharles.Forsyth sspec := strip(line); 578*37da2899SCharles.Forsyth (n, toks) := sys->tokenize(sspec, "="); 579*37da2899SCharles.Forsyth if (n == 0) continue; 580*37da2899SCharles.Forsyth if (n > 2) { 581*37da2899SCharles.Forsyth sys->fprint(stderr, "Error in config file %s\n", fspec); 582*37da2899SCharles.Forsyth continue; 583*37da2899SCharles.Forsyth } 584*37da2899SCharles.Forsyth if (n == 2) { 585*37da2899SCharles.Forsyth asection := hd toks; 586*37da2899SCharles.Forsyth toks = tl toks; 587*37da2899SCharles.Forsyth alias := hd toks; 588*37da2899SCharles.Forsyth aliases = (asection, alias) :: aliases; 589*37da2899SCharles.Forsyth continue; 590*37da2899SCharles.Forsyth } 591*37da2899SCharles.Forsyth section = hd toks; 592*37da2899SCharles.Forsyth } else { 593*37da2899SCharles.Forsyth (n, toks) := sys->tokenize(line, "="); 594*37da2899SCharles.Forsyth if (n == 2) { 595*37da2899SCharles.Forsyth name := strip(hd toks); 596*37da2899SCharles.Forsyth toks = tl toks; 597*37da2899SCharles.Forsyth value := strip(hd toks); 598*37da2899SCharles.Forsyth plist = (name, value) :: plist; 599*37da2899SCharles.Forsyth } 600*37da2899SCharles.Forsyth } 601*37da2899SCharles.Forsyth } 602*37da2899SCharles.Forsyth if (section != "") clist = Cfg (section, plist) :: clist; 603*37da2899SCharles.Forsyth return (clist, aliases); 604*37da2899SCharles.Forsyth} 605*37da2899SCharles.Forsyth 606*37da2899SCharles.Forsyth 607*37da2899SCharles.Forsyth# Load printer driver if necessary 608*37da2899SCharles.Forsythload_driver(p: ref Printer) 609*37da2899SCharles.Forsyth{ 610*37da2899SCharles.Forsyth if (p.pdriver != nil) return; 611*37da2899SCharles.Forsyth modpath := Pdriver->PATHPREFIX + p.ptype.driver; 612*37da2899SCharles.Forsyth p.pdriver = load Pdriver modpath; 613*37da2899SCharles.Forsyth if (p.pdriver == nil) sys->fprint(stderr, "Failed to load driver %s: %r\n", modpath); 614*37da2899SCharles.Forsyth p.pdriver->init(DEBUG); 615*37da2899SCharles.Forsyth} 616*37da2899SCharles.Forsyth 617*37da2899SCharles.Forsyth 618*37da2899SCharles.Forsyth# Strip leading/trailing spaces 619*37da2899SCharles.Forsyth 620*37da2899SCharles.Forsythstrip(s: string): string 621*37da2899SCharles.Forsyth{ 622*37da2899SCharles.Forsyth (dummy1, s1) := str->splitl(s, "^ \t"); 623*37da2899SCharles.Forsyth (s2, dummy2) := str->splitr(s1, "^ \t"); 624*37da2899SCharles.Forsyth return s2; 625*37da2899SCharles.Forsyth} 626