Patch title: Release 94 bulk changes
Abstract:
File: /pliant/graphic/browser/client/window.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/compiler.pli"
module "/pliant/language/stream.pli"
module "/pliant/graphic/layout/prototype.pli"
module "/pliant/graphic/layout/helper/position.pli"
module "/pliant/graphic/draw/image.pli"
module "/pliant/graphic/image/pixmap.pli"
module "/pliant/graphic/image/antialiasing.pli"
module "/pliant/graphic/console/prototype.pli"
module "context.pli"
module "connect.pli"
module "/pliant/graphic/layout/restyle.pli"

constant verify false
constant flick false


method w draw x0 y0 x1 y1
  arg_rw BrowserWindow w ; arg Int x0 y0 x1 y1
  check w:x0<>undefined and x0>=w:x0 and y0>=w:y0 and x1<=w:x1 and y1<=w:y1 and x1>x0 and y1>y0
  var Pointer:BrowserConsole c :> w:session console
  if c:canceled
    return
  var LayoutDC dc
  dc style :> c default_style
  dc gamut :> c gamut
  dc window :> w
  var Link:ImagePixmap pm :> new ImagePixmap
  pm setup (image_prototype (w:scroll_x+x0-w:x0)*c:unit_x (w:scroll_y+y0-w:y0)*c:unit_y (w:scroll_x+x1-w:x0)*c:unit_x (w:scroll_y+y1-w:y0)*c:unit_y (x1-x0)*w:antialiasing (y1-y0)*w:antialiasing c:gamut) ""
  if flick
    var Int zero := 0
    for (var Int y) 0 pm:size_y-1
      pm fill 0 y pm:size_x addressof:zero
    if w:antialiasing>1
      var Link:ImageAntiAliasing aa :> new ImageAntiAliasing
      aa bind pm w:antialiasing w:antialiasing
      c:console paint aa x0 y0
    else
      c:console paint pm x0 y0
    sleep 0.2
  for (var Int y) 0 pm:size_y-1
    pm fill 0 y pm:size_x (dc color w:padding_color)
  var Link:DrawImage d :> new DrawImage
  d bind pm (shunt w:antialiasing>1 "text_speedup 1" "text_speedup 2")
  dc:bbox x0 := pm x0 ; dc:bbox y0 := pm y0 ; dc:bbox x1 := pm x1 ; dc:bbox y1 := pm y1
  if (exists w:root)
    w:root draw d dc
  if c:canceled
    return
  if (exists w:overlay)
    w:overlay draw d dc
  if c:canceled
    return
  if w:antialiasing>1
    var Link:ImageAntiAliasing aa :> new ImageAntiAliasing
    aa bind pm w:antialiasing w:antialiasing
    c:console paint aa x0 y0
  else
    c:console paint pm x0 y0
  if flick
    sleep 0.2

method w draw_area x0 y0 x1 y1
  arg_rw BrowserWindow w ; arg Float x0 y0 x1 y1
  var Pointer:BrowserConsole c :> w:session console
  var Int ix0 := max (cast x0/c:unit_x-0.5 Int)-w:scroll_x+w:x0 w:x0
  var Int iy0 := max (cast y0/c:unit_y-0.5 Int)-w:scroll_y+w:y0 w:y0
  var Int ix1 := min (cast x1/c:unit_x+0.5 Int)-w:scroll_x+w:x0 w:x1
  var Int iy1 := min (cast y1/c:unit_y+0.5 Int)-w:scroll_y+w:y0 w:y1
  if ix1>ix0 and iy1>iy0 and not w:refresh and not w:orefresh
    w draw ix0 iy0 ix1 iy1


method d surface -> s
  arg BrowserRedraw d ; arg Int s
  s := (d:x1-d:x0)*(d:y1-d:y0)

method w redraw x0 y0 x1 y1
  arg_rw BrowserWindow w ; arg Int x0 y0 x1 y1
  var BrowserRedraw d ; d x0 := x0 ; d y0 := y0 ; d x1 := x1 ; d y1 := y1
  var Int sd := d surface
  each e w:redraw
    var Int se := e surface
    var BrowserRedraw i ; i x0 := max e:x0 d:x0 ; i y0 := max e:y0 d:y0 ; i x1 := min e:x1 d:x1 ; i y1 := min e:y1 d:y1
    var Int si := i surface
    if si<=se+sd
      e x0 := min e:x0 d:x0 ; e y0 := min e:y0 d:y0 ; e x1 := max e:x1 d:x1 ; e y1 := max e:y1 d:y1
      return
  w redraw += d

method w redraw_area x0 y0 x1 y1
  arg_rw BrowserWindow w ; arg Float x0 y0 x1 y1
  var Pointer:BrowserConsole c :> w:session console
  var Int ix0 := max (cast x0/c:unit_x-0.5 Int)-w:scroll_x+w:x0 w:x0
  var Int iy0 := max (cast y0/c:unit_y-0.5 Int)-w:scroll_y+w:y0 w:y0
  var Int ix1 := min (cast x1/c:unit_x+0.5 Int)-w:scroll_x+w:x0 w:x1
  var Int iy1 := min (cast y1/c:unit_y+0.5 Int)-w:scroll_y+w:y0 w:y1
  if ix1>ix0 and iy1>iy0 and not w:refresh and not w:orefresh
    w redraw ix0 iy0 ix1 iy1


type BrowserDraw2
  field Int dx0 dy0 dx1 dy1
  field Pointer:BrowserWindow w
  field Int sx0 sy0 sx1 sy1
  field CBool processed

function browser_draw dx0 dy0 dx1 dy1 w sx0 sy0 sx1 sy1 -> d
  arg Int dx0 dy0 dx1 dy1 ; arg BrowserWindow w ; arg Int sx0 sy0 sx1 sy1 ; arg BrowserDraw2 d
  if sx1<sx0 or sy1<sy0
    error "wrong copy area source "+string:sx0+" "+string:sy0+" "+string:sx1+" "+string:sy1
  if dx1<dx0 or dy1<dy0
    error "wrong copy area dest "+string:dx0+" "+string:dy0+" "+string:dx1+" "+string:dy1
  d dx0 := dx0 ; d dy0 := dy0 ; d dx1 := dx1 ; d dy1 := dy1 
  d w :> w 
  d sx0 := sx0 ; d sy0 := sy0 ; d sx1 := sx1 ; d sy1 := sy1 
  d processed := false

method w move x0 y0 x1 y1 dl
  arg_rw BrowserWindow w ; arg Int x0 y0 x1 y1 ; arg_rw List:BrowserDraw2 dl
  var Pointer:BrowserConsole c :> w:session console
  if x0<>w:x0 or y0<>w:y0 or x1<>w:x1 or y1<>w:y1
    c brefresh := true
  if x0=undefined or w:refresh or w:orefresh
    w x0 := x0 ; w y0 := y0 ; w x1 := x1 ; w y1 := y1
  eif w:x0=undefined
    check x0>=0 and y0>=0 and x1<=c:size_x and y1<=c:size_y and x1>x0 and y1>y0
    w x0 := x0 ; w y0 := y0 ; w x1 := x1 ; w y1 := y1
    dl += browser_draw x0 y0 x1 y1 w undefined undefined undefined undefined
  else
    check x0>=0 and y0>=0 and x1<=c:size_x and y1<=c:size_y and x1>x0 and y1>y0
    w x1 := min w:x1 w:x0+x1-x0
    w y1 := min w:y1 w:y0+y1-y0
    if w:x1>w:x0 and w:y1>w:y0 and (x0<>w:x0 or y0<>w:y0)
      dl += browser_draw x0 y0 x0+(w:x1-w:x0) y0+(w:y1-w:y0) (null map BrowserWindow) w:x0 w:y0 w:x1 w:y1
    w x1 += x0-w:x0 ; w x0 := x0
    w y1 += y0-w:y0 ; w y0 := y0
    if w:x1<x1
      var Int dx := x1-w:x1 ; w x1 := x1
      if w:y1>w:y0
        dl += browser_draw w:x1-dx w:y0 w:x1 w:y1 w undefined undefined undefined undefined
    if w:y1<y1
      var Int dy := y1-w:y1 ; w y1 := y1
      if w:x1>w:x0
        dl += browser_draw w:x0 w:y1-dy w:x1 w:y1 w undefined undefined undefined undefined
    check w:x0=x0 and w:y0=y0 and w:x1=x1 and w:y1=y1
  if false # (exists w:overlay)
    var Link:ImagePixmap pm :> new ImagePixmap
    pm setup (image_prototype w:scroll_x*c:unit_x w:scroll_y*c:unit_y (w:scroll_x+x1-x0)*c:unit_x (w:scroll_y+y1-y0)*c:unit_y x1-x0 y1-y0 c:gamut) ""
    w underlay :> pm


method w scroll sx sy
  arg_rw BrowserWindow w ; arg Int sx sy
  var Pointer:BrowserConsole c :> w:session console
  var Int mini := cast w:bbox:x0/c:unit_x-0.5 Int
  var Int maxi := (cast w:bbox:x1/c:unit_x+0.5 Int)-(w:x1-w:x0)
  var Int dx := w:scroll_x-(max (min sx maxi) mini)
  w scroll_x -= dx
  var Int mini := cast w:bbox:y0/c:unit_y-0.5 Int
  var Int maxi := (cast w:bbox:y1/c:unit_y+0.5 Int)-(w:y1-w:y0)
  var Int dy := w:scroll_y-(max (min sy maxi) mini)
  w scroll_y -= dy
  if dx=0 and dy=0
    void
  eif abs:dx<w:x1-w:x0 and abs:dy<w:y1-w:y0
    c:console copy w:x0+(max -dx 0) w:y0+(max -dy 0) w:x1-(max dx 0) w:y1-(max dy 0) w:x0+(max dx 0) w:y0+(max dy 0)
    if dx>0
      w draw w:x0 w:y0 w:x0+dx w:y1
    eif dx<0
      w draw w:x1+dx w:y0 w:x1 w:y1
    if dy>0
      w draw w:x0 w:y0 w:x1 w:y0+dy
    eif dy<0
      w draw w:x0 w:y1+dy w:x1 w:y1
  else
    w draw w:x0 w:y0 w:x1 w:y1


method w focus_area x0 y0 x1 y1
  arg_rw BrowserWindow w ; arg Float x0 y0 x1 y1
  var Pointer:BrowserSession s :> w session
  var Pointer:BrowserConsole c :> s console
  check w:x0<>undefined and addressof:w=(addressof s:focus_window)
  var Int ix0 := cast x0/c:unit_x-0.5 Int
  var Int iy0 := cast y0/c:unit_y-0.5 Int
  var Int ix1 := cast x1/c:unit_x-0.5 Int
  var Int iy1 := cast y1/c:unit_y-0.5 Int
  var Int sx := w scroll_x
  var Int sy := w scroll_y
  sx := min sx ix1-(w:x1-w:x0)\12
  sy := min sy iy1-(w:y1-w:y0)\12
  sx := max sx ix0-(w:x1-w:x0)*11\12
  sy := max sy iy0-(w:y1-w:y0)*11\12
  s focus_scroll_x := sx
  s focus_scroll_y := sy
  s focus_scroll_stage := 1

method s focus_scroll
  arg_rw BrowserSession s
  if not (exists s:focus_target) or s:focus_scroll_stage=2
    return
  if s:focus_scroll_stage=0
    var Pointer:BrowserWindow w :> s focus_window
    var Pointer:BrowserConsole c :> s console
    var LayoutDC dc
    dc style :> restyle_enter c:default_style s:focus_target
    dc gamut :> c gamut
    dc window :> w
    var Link:ImagePixmap pm :> new ImagePixmap
    pm setup (image_prototype w:x0-2 w:y0-2 w:x0-1 w:y0-1 1 1 c:gamut) ""
    var Link:DrawImage d :> new DrawImage
    d bind pm ""
    dc:bbox x0 := pm x0 ; dc:bbox y0 := pm y0 ; dc:bbox x1 := pm x1 ; dc:bbox y1 := pm y1
    dc focus_scroll_study := true
    s:focus_target draw d dc
    restyle_leave c:default_style s:focus_target
  if s:focus_scroll_stage=1
    s:focus_window scroll s:focus_scroll_x s:focus_scroll_y
    s focus_scroll_stage := 2


method c raise i clone
  arg_rw BrowserConsole c ; arg Int i ; arg CBool clone
  if i=c:zorder:0
    return
  var Int j := 0
  while c:zorder:j<>i
    j += 1
  while j>0
    c:zorder j := c:zorder j-1
    j -= 1
  c:zorder 0 := i
  if clone
    j := c:zorder 1
    c:session:j history_push
    c:session:i history := c:session:j history
    c:session:j history_pull
    c:session:i history_pull
    c:session:i connect_main c:session:j:url c:session:j:context


method l reset_position_rec
  oarg_rw LayoutPrototype l
  l reset_position
  var Link:LayoutPrototype p :> l first
  while exists:p
    p reset_position_rec
    p :> p next

method c refresh repos
  arg_rw BrowserConsole c ; arg CBool repos
  for (var Int i) 0 11
    var Pointer:BrowserSession s :> c:session i
    each w s:windows
      if repos and (exists w:root)
        w:root reset_position_rec
      if repos and (exists w:overlay)
        w:overlay reset_position_rec
      w refresh := true
  c brefresh := true


#-------------------------------------------------------------------------------


method c apply_zorder
  arg_rw BrowserConsole c
  var Int exclude := 0
  for (var Int i) 0 c:zorder:size-1
    var Pointer:BrowserSession s :> c:session c:zorder:i
    var Int ix := s:position%3
    var Int iy := s:position\3
    var Int cover := (shunt ix=2 or iy=2 0 1)+(shunt ix=0 or iy=2 0 2)+(shunt ix=2 or iy=0 0 4)+(shunt ix=0 or iy=0 0 8)
    each w s:windows
      var CBool border := w:name="left" or w:name="top" or w:name="right" or w:name="bottom"
      var CBool visible := shunt w:name="right" c:zorder:i=11 border i=0 (exclude .and. cover)=0
      if visible
        if w:x0=undefined
          w x0 := 0 ; w y0 := 0 ; w x1 := 0 ; w y1 := 0
      else
        w x0 := undefined ; w y0 := undefined ; w x1 := undefined ; w y1 := undefined
      if border and visible
        exclude := exclude .or. cover


method w position flags
  arg_rw BrowserWindow w ; arg Int flags
  var Pointer:BrowserConsole c :> w:session console
  var CBool test_x := (flags .and. layout_pos_test_x)<>0
  var CBool test_y := (flags .and. layout_pos_test_y)<>0
  (var LayoutPC pc) setup w c:default_style 0 0 (shunt test_x c:size_x*w:fraction test_y c:size_x (w:x1-w:x0-0.001))*c:unit_x (shunt test_x c:size_y test_y c:size_y*w:fraction (w:y1-w:y0-0.001))*c:unit_y flags
  if (exists w:root)
    w bbox := w:root position pc
    if (exists w:overlay)
      w:bbox extend (w:overlay position pc)
  else
    w:bbox x0 := undefined ; w:bbox y0 := undefined ; w:bbox x1 := undefined ; w:bbox y1 := undefined
  
method w layout x0 y0 x1 y1 dl
  arg_rw BrowserWindow w ; arg Int x0 y0 x1 y1 ; arg_rw List:BrowserDraw2 dl
  var Pointer:BrowserConsole c :> w:session console
  check x0>=0 and y0>=0 and x1<=c:size_x and y1<=c:size_y and x1>x0 and y1>y0
  var Int wx0 wy0 wx1 wy1
  wx0 := x0 ; wy0 := y0 ; wx1 := x1 ; wy1 := y1
  var Int b := w padding_size
  if b>0
    var BrowserSpace sp ; sp color := w padding_color
    sp x0 := wx0 ; sp y0 := wy0 ; sp x1 := wx1 ; sp y1 := wy0+b ; c spaces += sp
    wy0 += b
    sp x0 := wx0 ; sp y0 := wy0 ; sp x1 := wx0+b ; sp y1 := wy1 ; c spaces += sp
    wx0 += b
    sp x0 := wx1-b ; sp y0 := wy0 ; sp x1 := wx1 ; sp y1 := wy1 ; c spaces += sp
    wx1 -= b
    sp x0 := wx0 ; sp y0 := wy1-b ; sp x1 := wx1 ; sp y1 := wy1 ; c spaces += sp
    wy1 -= b
  w move wx0 wy0 wx1 wy1 dl


method c adjust_windows_size
  arg_rw BrowserConsole c
  var Pointer:BrowserSession s :> c:session c:zorder:0
  var Pointer:BrowserWindow left :> s window "left"
  var Pointer:BrowserWindow top :> s window "top"
  var Pointer:BrowserWindow right :> c:session:11 window "right"
  var Pointer:BrowserWindow bottom :> s window "bottom"
  c spaces := var List:BrowserSpace empty_space_list
  var List:BrowserDraw2 dl
  var Int x0 := 0
  var Int y0 := 0
  var Int x1 := c size_x
  var Int y1 := c size_y
  if exists:top and top:bbox:x0=defined
    var Int n := min (cast (top:bbox:y1-top:bbox:y0)/c:unit_y+0.5 Int)+2*top:padding_size (cast c:size_y*top:fraction Int)
    if x1-x0>2*bottom:padding_size and n>2*top:padding_size
      top layout x0 y0 x1 y0+n dl
      y0 += n
      if s:border_size>0
        var BrowserSpace sp ; sp x0 := x0 ; sp y0 := y0 ; sp x1 := x1 ; sp y1 := y0+s:border_size ; sp color := s border_color ; c spaces += sp
        y0 += s border_size    
    else
      top x0 := undefined ; top y0 := undefined ; top x1 := undefined ; top y1 := undefined
  else
    top x0 := undefined ; top y0 := undefined ; top x1 := undefined ; top y1 := undefined
  if exists:bottom and bottom:bbox:x0=defined
    var Int n := min (cast (bottom:bbox:y1-bottom:bbox:y0)/c:unit_y+0.5 Int)+2*bottom:padding_size (cast c:size_y*bottom:fraction Int)
    if x1-x0>2*bottom:padding_size and n>2*bottom:padding_size
      bottom layout x0 y1-n x1 y1 dl
      y1 -= n
      if s:border_size>0
        var BrowserSpace sp ; sp x0 := x0 ; sp y0 := y1-s:border_size ; sp x1 := x1 ; sp y1 := y1 ; sp color := s border_color ; c spaces += sp
        y1 -= s border_size    
    else
      bottom x0 := undefined ; bottom y0 := undefined ; bottom x1 := undefined ; bottom y1 := undefined
  else
    bottom x0 := undefined ; bottom y0 := undefined ; bottom x1 := undefined ; bottom y1 := undefined
  if exists:left and left:bbox:x0=defined
    var Int n := min (cast (left:bbox:x1-left:bbox:x0)/c:unit_x+0.5 Int)+2*left:padding_size (cast c:size_x*left:fraction Int)
    if n>2*left:padding_size and y1-y0>2*left:padding_size
      left layout x0 y0 x0+n y1 dl
      x0 += n
      if s:border_size>0
        var BrowserSpace sp ; sp x0 := x0 ; sp y0 := y0 ; sp x1 := x0+s:border_size ; sp y1 := y1 ; sp color := s border_color ; c spaces += sp
        x0 += s border_size    
    else
      left x0 := undefined ; left y0 := undefined ; left x1 := undefined ; left y1 := undefined
  else
    left x0 := undefined ; left y0 := undefined ; left x1 := undefined ; left y1 := undefined
  if exists:right and right:bbox:x0=defined
    var Int n := min (cast (right:bbox:x1-right:bbox:x0)/c:unit_x+0.5 Int)+2*right:padding_size (cast c:size_x*right:fraction Int)
    if n>2*right:padding_size and y1-y0>2*right:padding_size
      right layout x1-n y0 x1 y1 dl
      x1 -= n
      if s:border_size>0
        var BrowserSpace sp ; sp x0 := x1-s:border_size ; sp y0 := y0 ; sp x1 := x1 ; sp y1 := y1 ; sp color := s border_color ; c spaces += sp
        x1 -= s border_size    
    else
      right x0 := undefined ; right y0 := undefined ; right x1 := undefined ; right y1 := undefined
  else
    right x0 := undefined ; right y0 := undefined ; right x1 := undefined ; right y1 := undefined
  var Int exclude := 0
  var Int mx0 := cast x0*(1-c:middle_x)+x1*c:middle_x-s:border_size/2 Int
  var Int mx1 := mx0+s:border_size
  var Int my0 := cast y0*(1-c:middle_y)+y1*c:middle_y-s:border_size/2 Int
  var Int my1 := my0+s:border_size
  for (var Int i) 0 c:zorder:size-1
    var Pointer:BrowserSession s :> c:session c:zorder:i
    var Pointer:BrowserWindow w :> s window "main"
    if exists:w
      var Int ix := s:position%3
      var Int iy := s:position\3
      var Int wx0 := shunt ix<2 x0 mx1
      var Int wy0 := shunt iy<2 y0 my1
      var Int wx1 := shunt ix>0 x1 mx0
      var Int wy1 := shunt iy>0 y1 my0
      var Int cover := (shunt ix=2 or iy=2 0 1)+(shunt ix=0 or iy=2 0 2)+(shunt ix=2 or iy=0 0 4)+(shunt ix=0 or iy=0 0 8)
      if (exclude .and. cover)=0
        w layout wx0 wy0 wx1 wy1 dl
        if ix<>1 or iy<>1
          var BrowserSpace sp ; sp x0 := mx0 ; sp y0 := my0 ; sp x1 := mx1 ; sp y1 := my1 ; sp color := s border_color ; c spaces += sp
          if ix<>1
            var BrowserSpace sp ; sp x0 := mx0 ; sp y0 := wy0 ; sp x1 := mx1 ; sp y1 := wy1 ; sp color := s border_color ; c spaces += sp
          if iy<>1
            var BrowserSpace sp ; sp x0 := wx0 ; sp y0 := my0 ; sp x1 := wx1 ; sp y1 := my1 ; sp color := s border_color ; c spaces += sp
        exclude := exclude .or. cover
      else
        w x0 := undefined ; w y0 := undefined ; w x1 := undefined ; w y1 := undefined
  for (var Int i) 0 3
    if (exclude .and. 2^i)=0
      var Pointer:BrowserWindow w :> c:session:0 window "right"
      if exists:w
        var Int wx0 := shunt i%2=0 x0 mx1
        var Int wy0 := shunt i\2=0 y0 my1
        var Int wx1 := shunt i%2=1 x1 (shunt (exclude .and. 2^(i+1))=0 mx1 mx0)
        var Int wy1 := shunt i\2=1 y1 (shunt (exclude .and. 2^(i+2))=0 my1 my0)
        var BrowserSpace sp ; sp x0 := wx0 ; sp y0 := wy0 ; sp x1 := wx1 ; sp y1 := wy1 ; sp color := w padding_color ; c spaces += sp
  var Pointer:BrowserSession s :> c:session c:zorder:0
  var Pointer:BrowserWindow w :> s window "main"
  if exists:w and s:position<>4
    var BrowserSpace sp ; sp color := s border_active_color
    var Int b := w padding_size
    sp x0 := max w:x0-b-1 0 ; sp y0 := max w:y0-b-1 0 ; sp x1 := min w:x1+b+1 c:size_x ; sp y1 := w:y0-b
    if sp:x1>sp:x0 and sp:y1>sp:y0
      c spaces += sp
    sp x0 := max w:x0-b-1 0 ; sp y0 := max w:y0-b-1 0 ; sp x1 := w:x0-b ; sp y1 := min w:y1+b+1 c:size_y
    if sp:x1>sp:x0 and sp:y1>sp:y0
      c spaces += sp
    sp x0 := w:x1+b ; sp y0 := max w:y0-b-1 0 ; sp x1 := min w:x1+b+1 c:size_x ; sp y1 := min w:y1+b+1 c:size_y
    if sp:x1>sp:x0 and sp:y1>sp:y0
      c spaces += sp
    sp x0 := max w:x0-b-1 0 ; sp y0 := w:y1+b ; sp x1 := min w:x1+b+1 c:size_x ; sp y1 := min w:y1+b+1 c:size_y
    if sp:x1>sp:x0 and sp:y1>sp:y0
      c spaces += sp
  function process d dl c
    arg_rw BrowserDraw2 d ; arg_rw List:BrowserDraw2 dl ; arg_rw BrowserConsole c
    d processed := true
    each d2 dl
      if not d2:processed and d2:sx0<d:dx1 and d2:sy0<d:dy1 and d2:sx1>d:dx0 and d2:sy1>d:dy0
        process d2 dl c
    if (exists d:w)
      d:w draw d:dx0 d:dy0 d:dx1 d:dy1
    else
      c:console copy d:sx0 d:sy0 d:sx1 d:sy1 d:dx0 d:dy0
  each d dl
    if not d:processed
      process d dl c


method c draw x0 y0 x1 y1 force
  arg_rw BrowserConsole c ; arg Int x0 y0 x1 y1 ; arg CBool force
  var LayoutDC dc
  dc style :> c default_style
  dc gamut :> c gamut
  if c:brefresh or force
    each sp c:spaces
      var Int xx0 := max x0 sp:x0
      var Int yy0 := max y0 sp:y0
      var Int xx1 := min x1 sp:x1
      var Int yy1 := min y1 sp:y1
      if xx1>xx0 and yy1>yy0
        var Link:ImagePixmap pm :> new ImagePixmap
        pm setup (image_prototype 0 0 1 1 xx1-xx0 yy1-yy0 c:gamut) ""
        for (var Int y) 0 pm:size_y-1
          pm fill 0 y pm:size_x (dc color sp:color)
        c:console paint pm xx0 yy0
  var Pointer:BrowserSession s :> c:session c:zorder:0
  var Pointer:BrowserWindow w :> s window "background"
  if exists:w and w:x0<>undefined
    var Int xx0 := max x0 w:x0
    var Int yy0 := max y0 w:y0
    var Int xx1 := min x1 w:x1
    var Int yy1 := min y1 w:y1
    if xx1>xx0 and yy1>yy0
      w draw xx0 yy0 xx1 yy1
  for (var Int i) 0 11
    var Pointer:BrowserSession s :> c:session i
    each w s:windows
      if w:x0<>undefined and (w:refresh or w:orefresh or force)
        var Int xx0 := max x0 w:x0
        var Int yy0 := max y0 w:y0
        var Int xx1 := min x1 w:x1
        var Int yy1 := min y1 w:y1
        if xx1>xx0 and yy1>yy0
          w draw xx0 yy0 xx1 yy1


if verify
  method l check_parent
    oarg_rw LayoutPrototype l
    var Link:LayoutPrototype p :> l first
    while exists:p
      if (addressof p:parent)<>addressof:l
        error "bad node"
      p check_parent
      p :> p next

method c lazy_display
  arg_rw BrowserConsole c
  if verify
    for (var Int i) 0 c:zorder:size-1
      var Pointer:BrowserSession s :> c:session c:zorder:i
      each w s:windows
        if (exists w:root)
          if (addressof w:root:parent)<>null
            error "bad root"
          w:root check_parent
        if (exists w:overlay)
          if (addressof w:overlay:parent)<>null
            error "bad overlay"
          w:overlay check_parent
  if c:canceled
    return
  part display
    c cancelable := c:last_full_cycle<>undefined and datetime:seconds-c:last_full_cycle:seconds<c:force_after
    for (var Int i) 0 c:zorder:size-1
      var Pointer:BrowserSession s :> c:session c:zorder:i
      each w s:windows
        if w:refresh or w:orefresh
          w redraw := var List:BrowserRedraw empty_redraw_list
        else
          while { var Pointer:BrowserRedraw d :> w:redraw first ; exists d }
            # var DateTime dt := datetime
            w draw d:x0 d:y0 d:x1 d:y1
            if c:canceled
              leave display
            # console "draw " d:surface " -> " (string datetime:seconds-dt:seconds "fixed 2") eol
            w redraw -= d
    if flick
      var DateTime dt0 := datetime
      var Str cmd := ""
    c apply_zorder
    for (var Int i) 0 c:zorder:size-1
      var Pointer:BrowserSession s :> c:session c:zorder:i
      each w s:windows
        if w:x0<>undefined and (w:refresh or w:orefresh) and w:name<>"main"
          w position (shunt w:name="left" or w:name="right" layout_pos_test_x 0)+(shunt w:name="top" or w:name="bottom" layout_pos_test_y 0)
          if flick
            cmd += " pos0:"+w:name
          if c:canceled
            leave display
    c cancelable := false # FIXME: replace with later redraw
    c adjust_windows_size
    c cancelable := true
    if c:canceled
      leave display
    for (var Int i) 0 c:zorder:size-1
      var Pointer:BrowserSession s :> c:session c:zorder:i
      each w s:windows
        if w:x0<>undefined and (w:refresh or w:orefresh)
          w position 0
          if flick
            cmd += " pos:"+w:name
          if c:canceled
            leave display
      s focus_scroll
      if c:canceled
        leave display
    if flick
      var DateTime dt1 := datetime
    c draw 0 0 c:size_x c:size_y false
    if c:canceled
      leave display
    c brefresh := false
    for (var Int i) 0 11
      var Pointer:BrowserSession s :> c:session i
      each w s:windows
        if flick and (w:refresh or w:orefresh)
          cmd += " draw:"+w:name
        w refresh := false
        w orefresh := false
    if flick and cmd<>""
      var DateTime dt2 := datetime
      console dt2 cmd " -> " (string 1000*(dt1:seconds-dt0:seconds) "fixed 0")+"+"+(string 1000*(dt2:seconds-dt1:seconds) "fixed 0")+" ms" eol
    c last_full_cycle := datetime
  c cancelable := false

real_lazy_display_function :> the_function '. lazy_display' BrowserConsole


export '. draw' '. draw_area' '. redraw' '. redraw_area'
export '. scroll' '. focus_area' '. focus_scroll'
export '. lazy_display' '. raise' '. refresh'