Patch title: Release 84 bulk changes
Abstract:
File: /pliant/protocol/lpr/spool.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/unsafe.pli"
module "/pliant/language/schedule/daemon.pli"
module "/pliant/language/schedule/resourcesem.pli"
module "/pliant/language/context.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/admin/file.pli"
submodule "database.pli"

module "/pliant/language/stream/pipe.pli"
module "/pliant/graphic/color/gamut.pli"
module "/pliant/graphic/image/prototype.pli"
module "/pliant/graphic/image/resampling.pli"
module "/pliant/graphic/image/antialiasing.pli"
module "/pliant/graphic/image/convert.pli"
module "/pliant/graphic/image/sharpening.pli"
module "/pliant/graphic/image/lazy.pli"
module "/pliant/graphic/filter/io.pli"
module "device.pli"
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/unsafe.pli"
module "/pliant/language/schedule/daemon.pli"
module "/pliant/language/schedule/resourcesem.pli"
module "/pliant/language/context.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/admin/file.pli"
submodule "database.pli"

module "/pliant/language/stream/pipe.pli"
module "/pliant/graphic/color/gamut.pli"
module "/pliant/graphic/image/prototype.pli"
module "/pliant/graphic/image/resampling.pli"
module "/pliant/graphic/image/antialiasing.pli"
module "/pliant/graphic/image/convert.pli"
module "/pliant/graphic/image/sharpening.pli"
module "/pliant/graphic/image/lazy.pli"
module "/pliant/graphic/filter/io.pli"
module "device.pli"
module "embedded.pli"
module "/pliant/admin/execute.pli"

constant print_postscript os_api="linux"
module "/pliant/admin/execute.pli"

constant print_postscript os_api="linux"
constant print_pdf true
constant print_pdf os_api="linux"
constant print_png true
constant print_jpeg true
constant print_packed true
constant print_html true
constant print_png true
constant print_jpeg true
constant print_packed true
constant print_html true
constant embedded file_os_name:"embedded:/"<>file_os_name:"file:/" and (file_query "file:/bin/gs" standard)=undefined
constant uid_gid 7


function lpr_print image options job prn -> status
  oarg_rw ImagePrototype image ; arg Str options ; arg_rw Da
  var Data:LprQueue printer :> job printer


function lpr_print image options job prn -> status
  oarg_rw ImagePrototype image ; arg Str options ; arg_rw Da
  var Data:LprQueue printer :> job printer
  var Int divisor := cast image:size_x/(abs image:x1-image:x
  var Link:ImageAntiAliasing aa
  if divisor>1
    aa :> new ImageAntiAliasing
    status := aa bind image divisor
    if status=failure
      return
  else
    aa :> addressof:image map ImageAntiAliasing
  var Link:ImagePrototype img :> image
  var Str pgamut := shunt printer:gamut<>"" printer:gamut "r
  var Str pgamut := shunt printer:gamut<>"" printer:gamut "r
  var Link:ImageConvert conv
  if pgamut<>image:gamut:name
  if pgamut<>image:gamut:name
    conv :> new ImageConvert
    status := conv bind aa color_gamut:pgamut (shunt image:g
    var Link:ImageConvert conv :> new ImageConvert
    status := conv bind img color_gamut:pgamut (shunt image:gamut:name="rgb" "grid_steps "+(string printer:grid_steps) "")
    if status=failure
      return
    if status=failure
      return
  else
    conv :> addressof:aa map ImageConvert
  var Link:ImageSharpening sharpen
    img :> conv
  var Int divisor_x := cast image:size_x/(abs image:x1-image:x0)*25.4/printer:resolution_x Int
  var Int divisor_y := cast image:size_y/(abs image:y1-image:y0)*25.4/printer:resolution_y Int
  if divisor_x>1 or divisor_y>1
    var Link:ImageAntiAliasing aa :> new ImageAntiAliasing
    status := aa bind img divisor_x divisor_y
    if status=failure
      return
    img :> aa
  if printer:sharpening=defined
  if printer:sharpening=defined
    sharpen :> new ImageSharpening
    status := sharpen bind conv printer:sharpening
    var Link:ImageSharpening sharpen :> new ImageSharpening
    status := sharpen bind img printer:sharpening
    if status=failure
      return
    if status=failure
      return
  else
    sharpen :> addressof:conv map ImageSharpening
    img :> sharpen
  var Str opt := "filter "+(string "."+printer:driver)+" mod
  if ((options (options option_position "offset" 0) options:
    if not ((printer:options (printer:options option_positio
      base_x := 0 ; base_y := 0
    opt := "offset "+(string base_x+offset_x)+" "+(string ba
  var Str opt := "filter "+(string "."+printer:driver)+" mod
  if ((options (options option_position "offset" 0) options:
    if not ((printer:options (printer:options option_positio
      base_x := 0 ; base_y := 0
    opt := "offset "+(string base_x+offset_x)+" "+(string ba
  status := sharpen save prn opt
  status := img save prn opt

if print_postscript or print_pdf
  function lpr_print_postscript file job prn -> status
    arg Str file ; arg_rw Data:LprJob job ; arg_rw Stream pr
    var Data:LprQueue printer :> job printer

if print_postscript or print_pdf
  function lpr_print_postscript file job prn -> status
    arg Str file ; arg_rw Data:LprJob job ; arg_rw Stream pr
    var Data:LprQueue printer :> job printer
    var Str temp := replace file_temporary "file:/" "embedde
    if (file_clone file temp)=failure
      file_copy file temp
    if embedded
      var Str temp := replace file_temporary "file:/" "embedded:/"
      if (file_clone file temp)=failure
        file_copy file temp
    part rip
      stream_pipe (var Str in_pipe) (var Str out_pipe)
    part rip
      stream_pipe (var Str in_pipe) (var Str out_pipe)
      var Str gs_resolution := (string printer:resolution_x*
      var Str gs_resolution := (string printer:resolution_x*printer:antialiasing_x)+"x"+(string printer:resolution_y*printer:antialiasing_y)
      thread
      thread
        execute "gs -sDEVICE=ppmraw -r"+gs_resolution+" -sOu
        if embedded
          execute "gs -sDEVICE=ppmraw -r"+gs_resolution+" -sOutputFile=- -q -dNOPAUSE -dSAFER "+file_os_name:(replace temp "embedded:/" "file:/")+" -c quit" root "embedded:/" path "embedded:/" output out_pipe
        else
          execute "gs -sDEVICE=ppmraw -r"+gs_resolution+" -sOutputFile=- -q -dNOPAUSE -dSAFER "+file_os_name:file+" -c quit" user uid_gid group uid_gid output out_pipe
      var Link:Stream s :> new Stream
      s open in_pipe in+safe+bigcache ; var Int page := 0
      while not s:atend
        page += 1 ; job r_comment := "page "+string:page
        var Link:ImageLazy lazy :> new ImageLazy
      var Link:Stream s :> new Stream
      s open in_pipe in+safe+bigcache ; var Int page := 0
      while not s:atend
        page += 1 ; job r_comment := "page "+string:page
        var Link:ImageLazy lazy :> new ImageLazy
        status := lazy bind s "filter [dq].ppm[dq] resolutio
        status := lazy bind s "filter [dq].ppm[dq] resolution "+(string printer:resolution_x*printer:antialiasing_x)+" "+(string printer:resolution_y*printer:antialiasing_y)+(shunt (printer:options option "burst") " backward "+(string 16*(max printer:antialiasing_x printer:antialiasing_y)) "")
        if lazy=failure
          leave rip
        var Link:ImageResampling rs
        if printer:margin_left<>0 or printer:margin_top<>0 o
          var Int ix0 := lazy index_x printer:margin_left
          var Float fx0 := lazy:x0+(lazy:x1-lazy:x0)*ix0/laz
          var Int iy0 := lazy index_y printer:margin_left
          var Float fy0 := lazy:y0+(lazy:y1-lazy:y0)*iy0/laz
          var Int ix1 := lazy index_x printer:size_x-printer
          var Float fx1 := lazy:x0+(lazy:x1-lazy:x0)*ix1/laz
          var Int iy1 := lazy index_y printer:size_y-printer
          var Float fy1 := lazy:y0+(lazy:y1-lazy:y0)*iy1/laz
          var Link:ImageResampling rs :> new ImageResampling
          status := rs bind lazy fx0 fy0 fx1 fy1 ix1-ix0 iy1
          if status=failure
            leave rip
        else
          rs :> addressof:lazy map ImageResampling
        status := lpr_print rs "" job prn
        if status=failure
          leave rip
        lazy read 0 lazy:size_y-1 1 addressof:(var ColorBuff
      status := success
        if lazy=failure
          leave rip
        var Link:ImageResampling rs
        if printer:margin_left<>0 or printer:margin_top<>0 o
          var Int ix0 := lazy index_x printer:margin_left
          var Float fx0 := lazy:x0+(lazy:x1-lazy:x0)*ix0/laz
          var Int iy0 := lazy index_y printer:margin_left
          var Float fy0 := lazy:y0+(lazy:y1-lazy:y0)*iy0/laz
          var Int ix1 := lazy index_x printer:size_x-printer
          var Float fx1 := lazy:x0+(lazy:x1-lazy:x0)*ix1/laz
          var Int iy1 := lazy index_y printer:size_y-printer
          var Float fy1 := lazy:y0+(lazy:y1-lazy:y0)*iy1/laz
          var Link:ImageResampling rs :> new ImageResampling
          status := rs bind lazy fx0 fy0 fx1 fy1 ix1-ix0 iy1
          if status=failure
            leave rip
        else
          rs :> addressof:lazy map ImageResampling
        status := lpr_print rs "" job prn
        if status=failure
          leave rip
        lazy read 0 lazy:size_y-1 1 addressof:(var ColorBuff
      status := success
    file_delete temp
    if embedded
      file_delete temp

if print_png or print_jpeg or print_packed
  function lpr_print_image file job prn -> status
    arg Str file ; arg_rw Data:LprJob job ; arg_rw Stream pr
    var Data:LprQueue printer :> job printer
    var Link:Stream input :> new Stream
    input open file in+safe
    while not input:atend
      var Link:ImageLazy image :> new ImageLazy

if print_png or print_jpeg or print_packed
  function lpr_print_image file job prn -> status
    arg Str file ; arg_rw Data:LprJob job ; arg_rw Stream pr
    var Data:LprQueue printer :> job printer
    var Link:Stream input :> new Stream
    input open file in+safe
    while not input:atend
      var Link:ImageLazy image :> new ImageLazy
      status := image bind input "filter [dq]."+job:format+"
      status := image bind input "filter [dq]."+job:format+"[dq] resolution "+(string printer:resolution_x*printer:antialiasing_x)+" "+(string printer:resolution_y*printer:antialiasing_y)
      if status=failure
        return
      var Link:ImageResampling rs :> new ImageResampling
      if status=failure
        return
      var Link:ImageResampling rs :> new ImageResampling
      var ImagePrototype proto := image_prototype image:x0 i
      var ImagePrototype proto := image_prototype image:x0 image:y0 image:x1 image:y1 printer:resolution_x*printer:antialiasing_x printer:resolution_y*printer:antialiasing_y printer:antialiasing_x printer:antialiasing_y image_adjust_reduce image:gamut
      status := rs bind image proto:x0 proto:y0 proto:x1 pro
      if status=failure
        return
      status := lpr_print rs "" job prn
      if status=failure
        return

if print_html
  function lpr_print_html file job prn -> status
    arg Str file ; arg_rw Data:LprJob job ; arg_rw Stream pr
    var Data:LprQueue printer :> job printer
    var Str url := file
    var Str form := ""
    var Str options := ""
    var Link:D2Box drawing :> html_parse url form options
      status := rs bind image proto:x0 proto:y0 proto:x1 pro
      if status=failure
        return
      status := lpr_print rs "" job prn
      if status=failure
        return

if print_html
  function lpr_print_html file job prn -> status
    arg Str file ; arg_rw Data:LprJob job ; arg_rw Stream pr
    var Data:LprQueue printer :> job printer
    var Str url := file
    var Str form := ""
    var Str options := ""
    var Link:D2Box drawing :> html_parse url form options
    var ImagePrototype page := image_prototype 0 0 printer:s
    var ImagePrototype page := image_prototype 0 0 printer:size_x-printer:margin_left-printer:margin_right printer:size_y-printer:margin_top-printer:margin_bottom printer:resolution_x*printer:antialiasing_x printer:resolution_y*printer:antialiasing_y printer:antialiasing_x printer:antialiasing_y image_adjust_reduce color_gamut:"rgb"
    (var D2Context context) bind page
    drawing position context
    var Link:ImagePacked image :> new ImagePacked
    image setup page ""
    (var D2Context context) bind image
    image fill image:x0 image:y0 image:x1 image:y1 (addresso
    drawing draw image context
    status := lpr_print image "" job prn




function lpr_spool
  daemon "print spooler daemon"
    while not daemon_emergency
    (var D2Context context) bind page
    drawing position context
    var Link:ImagePacked image :> new ImagePacked
    image setup page ""
    (var D2Context context) bind image
    image fill image:x0 image:y0 image:x1 image:y1 (addresso
    drawing draw image context
    status := lpr_print image "" job prn




function lpr_spool
  daemon "print spooler daemon"
    while not daemon_emergency
      lpr_embedded_migrate "embedded:/"
      lpr_queue_sem request
      each job lpr_database:data:job filter job:s_status<>"W
        var Str id := keyof job
        var Data:LprQueue queue :> job printer
        if queue:once or job:s_status="T"
          if job:format=""
            if job:s_status="T" or (file_query (lpr_filename
              part computer_format "Compute print job '"+id+
                lpr_compute_format job
          eif job:r_status="W" and job:s_status="T"
            if (lpr_rip_slot nowait_request 1)
              job r_startup := datetime
              job r_status := "R"
              thread
                var Data:LprJob j :> lpr_database:data:job i
                var Data:LprQueue q :> j printer
                part rip "Rip '"+j:format+"' job '"+id+"' fo
                  var Str file := lpr_filename j j:format
                  var Link:Stream prn :> new Stream
                  prn open (lpr_filename j "prn") out+safe
                  if prn=failure
                    lpr_error j "Failed to open the printer 
                  var ExtendedStatus rs
                  if (print_postscript and j:format="ps") or
                    rs := lpr_print_postscript file j prn
                  eif (print_png and j:format="png") or (pri
                    rs := lpr_print_image file j prn
                  eif print_html and j:format="html"
                    rs := lpr_print_html file j prn
                  else
                    rs := failure "unsupported '"+j:format+"
                    plugin rip
                  if rs=failure
                    lpr_error j "Ripping error: "+rs:message
                  if prn:close=failure
                    lpr_error j "Failed to store the printer
                  j r_status := "T" ; j r_comment := ""
                  lpr_rip_slot release 1
          eif job:p_status="W" and ( job:r_status="T" or (qu
            if (lpr_printer_sem nowait_request queue:printer
              job p_startup := datetime
              job p_status := "R"
              thread
                var Data:LprJob j :> lpr_database:data:job i
                var Data:LprQueue q :> j printer
                part rip "Print job '"+id+"' on '"+keyof:q+"
                  (var Stream src) open (lpr_filename j "prn
                  var Str target := lpr_device_search q:devi
                  if target:len>0 and (target target:len-1)=
                    target += shunt j:file<>"" j:file keyof:
                  (var Stream dest) open (string target)+" t
                  part copy
                    src read_available (var Address adr) (va
                    if size=0 and src=success and (j:s_statu
                      j p_comment := string:offset+" stalled
                      sleep 1
                      restart copy
                    if size>0
                      if j:p_status<>"R"
                        leave copy
                      dest raw_write adr size
                      if dest=success
                        offset += size ; j p_comment := stri
                        restart copy
                      else
                        lpr_error j (shunt offset=0 "Printer
                  src close
                  dest close
                  j p_status := "T" ; j p_comment := ""
                  lpr_cancel j dest
                  if strict_order
                    lpr_queue_sem rd_request ; lpr_queue_sem
                  lpr_printer_sem release q:printer
      lpr_queue_sem release
      lpr_queue_sem request
      each job lpr_database:data:job filter job:s_status<>"W
        var Str id := keyof job
        var Data:LprQueue queue :> job printer
        if queue:once or job:s_status="T"
          if job:format=""
            if job:s_status="T" or (file_query (lpr_filename
              part computer_format "Compute print job '"+id+
                lpr_compute_format job
          eif job:r_status="W" and job:s_status="T"
            if (lpr_rip_slot nowait_request 1)
              job r_startup := datetime
              job r_status := "R"
              thread
                var Data:LprJob j :> lpr_database:data:job i
                var Data:LprQueue q :> j printer
                part rip "Rip '"+j:format+"' job '"+id+"' fo
                  var Str file := lpr_filename j j:format
                  var Link:Stream prn :> new Stream
                  prn open (lpr_filename j "prn") out+safe
                  if prn=failure
                    lpr_error j "Failed to open the printer 
                  var ExtendedStatus rs
                  if (print_postscript and j:format="ps") or
                    rs := lpr_print_postscript file j prn
                  eif (print_png and j:format="png") or (pri
                    rs := lpr_print_image file j prn
                  eif print_html and j:format="html"
                    rs := lpr_print_html file j prn
                  else
                    rs := failure "unsupported '"+j:format+"
                    plugin rip
                  if rs=failure
                    lpr_error j "Ripping error: "+rs:message
                  if prn:close=failure
                    lpr_error j "Failed to store the printer
                  j r_status := "T" ; j r_comment := ""
                  lpr_rip_slot release 1
          eif job:p_status="W" and ( job:r_status="T" or (qu
            if (lpr_printer_sem nowait_request queue:printer
              job p_startup := datetime
              job p_status := "R"
              thread
                var Data:LprJob j :> lpr_database:data:job i
                var Data:LprQueue q :> j printer
                part rip "Print job '"+id+"' on '"+keyof:q+"
                  (var Stream src) open (lpr_filename j "prn
                  var Str target := lpr_device_search q:devi
                  if target:len>0 and (target target:len-1)=
                    target += shunt j:file<>"" j:file keyof:
                  (var Stream dest) open (string target)+" t
                  part copy
                    src read_available (var Address adr) (va
                    if size=0 and src=success and (j:s_statu
                      j p_comment := string:offset+" stalled
                      sleep 1
                      restart copy
                    if size>0
                      if j:p_status<>"R"
                        leave copy
                      dest raw_write adr size
                      if dest=success
                        offset += size ; j p_comment := stri
                        restart copy
                      else
                        lpr_error j (shunt offset=0 "Printer
                  src close
                  dest close
                  j p_status := "T" ; j p_comment := ""
                  lpr_cancel j dest
                  if strict_order
                    lpr_queue_sem rd_request ; lpr_queue_sem
                  lpr_printer_sem release q:printer
      lpr_queue_sem release
      sleep 2
      daemon_sleep (min (max lpr_database:data:job:size 1) 5)



export lpr_filename lpr_open lpr_close lpr_error lpr_cancel 
export lpr_init lpr_spool lpr_stop lpr_restart lpr_rip_slot



export lpr_filename lpr_open lpr_close lpr_error lpr_cancel 
export lpr_init lpr_spool lpr_stop lpr_restart lpr_rip_slot