9fans.net/go@v0.0.5/draw/window.go (about)

     1  package draw
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"runtime"
     7  )
     8  
     9  var screenid uint32
    10  
    11  func (i *Image) AllocScreen(fill *Image, public bool) (*Screen, error) {
    12  	i.Display.mu.Lock()
    13  	defer i.Display.mu.Unlock()
    14  	return i.allocScreen(fill, public)
    15  }
    16  
    17  func (i *Image) allocScreen(fill *Image, public bool) (*Screen, error) {
    18  	d := i.Display
    19  	if d != fill.Display {
    20  		return nil, fmt.Errorf("allocscreen: image and fill on different displays")
    21  	}
    22  	var id uint32
    23  	for try := 0; ; try++ {
    24  		if try >= 25 {
    25  			return nil, fmt.Errorf("allocscreen: cannot find free id")
    26  		}
    27  		a := d.bufimage(1 + 4 + 4 + 4 + 1)
    28  		screenid++
    29  		id = screenid
    30  		a[0] = 'A'
    31  		bplong(a[1:], id)
    32  		bplong(a[5:], i.id)
    33  		bplong(a[9:], fill.id)
    34  		if public {
    35  			a[13] = 1
    36  		}
    37  		if err := d.flush(false); err == nil {
    38  			break
    39  		}
    40  	}
    41  	s := &Screen{
    42  		Display: d,
    43  		id:      id,
    44  		Fill:    fill,
    45  	}
    46  	return s, nil
    47  }
    48  
    49  /*
    50  func publicscreen(d *Display, id, pix uint32) (*Screen, error) {
    51  	s := new(Screen)
    52  	a := d.bufimage(1+4+4)
    53  	a[0] = 'S'
    54  	bplong(a[1:], id)
    55  	bplong(a[5:], pix)
    56  	if err := d.flushimage(false); err != nil {
    57  		return nil, err
    58  	}
    59  	s.Display = d
    60  	s.id = id
    61  	return s
    62  }
    63  */
    64  
    65  // Free frees the server resources associated with the screen.
    66  func (s *Screen) Free() error {
    67  	s.Display.mu.Lock()
    68  	defer s.Display.mu.Unlock()
    69  	return s.free()
    70  }
    71  
    72  func (s *Screen) free() error {
    73  	if s == nil {
    74  		return nil
    75  	}
    76  	d := s.Display
    77  	a := d.bufimage(1 + 4)
    78  	a[0] = 'F'
    79  	bplong(a[1:], s.id)
    80  	// flush(true) because screen is likely holding the last reference to window,
    81  	// and we want it to disappear visually.
    82  	return d.flush(true)
    83  }
    84  
    85  func allocwindow(i *Image, s *Screen, r Rectangle, ref int, val Color) (*Image, error) {
    86  	d := s.Display
    87  	var err error
    88  	if runtime.GOOS == "plan9" {
    89  		const BorderWidth = 4
    90  		name, err := ioutil.ReadFile("/dev/winname")
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  		i, err = namedImage(d, i, string(name))
    95  		if err == nil {
    96  			i.R = i.R.Inset(BorderWidth)
    97  		}
    98  	} else {
    99  		i, err = allocImage(d, i, r, d.ScreenImage.Pix, false, val, s.id, ref)
   100  	}
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	i.Screen = s
   105  	i.next = s.Display.Windows
   106  	s.Display.Windows = i
   107  	return i, nil
   108  }
   109  
   110  /*
   111  func topbottom(w []*Image, top bool) {
   112  	if n == 0 {
   113  		return
   114  	}
   115  	if n < 0 || n > (w[0].Display.bufsize-100)/4 {
   116  		fmt.Fprint(os.Stderr, "top/bottom: ridiculous number of windows\n")
   117  		return
   118  	}
   119  
   120  	/*
   121  	 * this used to check that all images were on the same screen.
   122  	 * we don't know the screen associated with images we acquired
   123  	 * by name.  instead, check that all images are on the same display.
   124  	 * the display will check that they are all on the same screen.
   125  	 * /
   126  	d := w[0].Display
   127  	for i := 1; i < n; i++ {
   128  		if w[i].Display != d {
   129  			fmt.Fprint(os.Stderr, "top/bottom: windows not on same screen\n");
   130  			return
   131  		}
   132  	}
   133  
   134  	b := d.bufimage(1+1+2+4*n);
   135  	b[0] = 't';
   136  	if top {
   137  		b[1] = 1
   138  	}
   139  	bpshort(b[2:], n)
   140  	for i:=0; i<n; i++ {
   141  		bplong(b[4+4*i:], w[i].id);
   142  	}
   143  }
   144  
   145  func bottomwindow(w *Image) {
   146  	if w.Screen == nil {
   147  		return
   148  	}
   149  	topbottom([]*Image{w}, false)
   150  }
   151  
   152  func topwindow(w *Image) {
   153  	if w.Screen == nil {
   154  		return
   155  	}
   156  	topbottom([]*Image{w}, true)
   157  }
   158  
   159  func bottomnwindows(w []*Image) {
   160  	topbottom(w, false)
   161  }
   162  
   163  func topnwindows(w []*Image) {
   164  	topbottom(w, true)
   165  }
   166  
   167  func originwindow(w *Image, log, scr image.Point) error {
   168  	w.Display.flushimage(false)
   169  	b := w.Display.bufimage(1+4+2*4+2*4)
   170  	b[0] = 'o'
   171  	bplong(b[1:], w.id)
   172  	bplong(b[5:], uint32(log.X))
   173  	bplong(b[9:], uint32(log.Y))
   174  	bplong(b[13:], uint32(scr.X))
   175  	bplong(b[17:], uint32(scr.Y))
   176  	if err := w.Display.flushimage(true); err != nil {
   177  		return err
   178  	}
   179  	delta := log.Sub(w.R.Min)
   180  	w.R = w.R.Add(delta)
   181  	w.Clipr = w.Clipr.Add(delta)
   182  	return nil
   183  }
   184  */