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 */