write a gotoXY method to set the cursor; throw away ununsed event code
4 files changed, 48 insertions(+), 79 deletions(-)

M event.go
M simscreen.go
M terminfo/terminfo.go
M tscreen.go
M event.go +2 -17
@@ 36,24 36,9 @@ func newEvent() *event {
 	return &event{time.Now()}
 }
 
-// EventInterrupt is a generic wakeup event.  Its can be used to
-// to request a redraw.  It can carry an arbitrary payload, as well.
-type EventInterrupt struct {
-	*event
-	v interface{}
-}
-
-// Data is used to obtain the opaque event payload.
-func (ev *EventInterrupt) Data() interface{} {
-	return ev.v
-}
-
-// NewEventInterrupt creates an EventInterrupt with the given payload.
-func NewEventInterrupt(data interface{}) *EventInterrupt {
-	return &EventInterrupt{newEvent(), data}
-}
-
 // EventResize is sent when the window size changes.
+//
+// todo: used in simulation screen only
 type EventResize struct {
 	*event
 	w, h int

          
M simscreen.go +1 -2
@@ 279,8 279,7 @@ func (s *SimScreen) resize() {
 	ow, oh := s.back.Size()
 	if w != ow || h != oh {
 		s.back.Resize(w, h)
-		ev := NewEventResize(w, h)
-		s.PostEvent(ev)
+		s.PostEvent(NewEventResize(w, h))
 	}
 }
 

          
M terminfo/terminfo.go +1 -1
@@ 341,7 341,7 @@ func (pb *paramsBuffer) PutString(s stri
 	pb.out.WriteString(s)
 }
 
-var pb = &paramsBuffer{}
+var pb = new(paramsBuffer)
 
 // TParm takes a terminfo parameterized string, such as setaf or cup, and
 // evaluates the string, and returns the result with the parameter

          
M tscreen.go +44 -59
@@ 58,7 58,6 @@ func NewTerminfoScreen() (Screen, error)
 	for k, v := range RuneFallbacks {
 		t.fallback[k] = v
 	}
-	// init part
 	t.evch = make(chan Event, 10)
 	t.indoneq = make(chan struct{})
 	t.keychan = make(chan []byte, 10)

          
@@ 108,18 107,20 @@ func NewTerminfoScreen() (Screen, error)
 		}
 	}
 
+	t.quit = make(chan struct{})
+
 	t.TPuts(ti.EnterCA)
 	t.TPuts(ti.HideCursor)
 	t.TPuts(ti.EnableAcs)
 	t.TPuts(ti.Clear)
 
-	t.quit = make(chan struct{})
-
 	t.cx, t.cy = -1, -1
 	t.style = StyleDefault
 	t.cells.Resize(w, h)
 	t.cursorx, t.cursory = -1, -1
-	t.resize()
+	if err := t.resize(); err != nil {
+		return nil, fmt.Errorf("resize terminal: %v", err)
+	}
 
 	go t.mainLoop()
 	go t.inputLoop()

          
@@ 164,7 165,6 @@ type tScreen struct {
 	cells CellBuffer
 	// current style when drawing. if the style between cells does not change
 	// no style attributes have to be written to the terminal
-	//	curstyle Style
 	style            Style
 	quit             chan struct{}
 	cursorx, cursory int

          
@@ 175,10 175,8 @@ type tScreen struct {
 
 	colors map[Color]Color
 
-	// maybe
-
-	wasbtn bool
-
+	// maybe todo:
+	wasbtn   bool
 	escaped  bool
 	buttondn bool
 }

          
@@ 351,12 349,7 @@ func (t *tScreen) drawCell(x, y int, cur
 		// what if in this cell the style is changed?
 		return width, curr
 	}
-
-	// save a goto call
-	if t.cy != y || t.cx != x {
-		t.TPuts(ti.TGoto(x, y))
-		t.cx, t.cy = x, y
-	}
+	t.gotoXY(x, y)
 
 	if style == StyleDefault {
 		style = t.style

          
@@ 389,23 382,18 @@ func (t *tScreen) drawCell(x, y int, cur
 	if width < 1 {
 		width = 1
 	}
-
-	var str string
-
 	buf := t.encodeRune(mainc, make([]byte, 0, 6))
 	for _, r := range combc {
 		buf = t.encodeRune(r, buf)
 	}
 
-	str = string(buf)
+	str := string(buf)
 	if width > 1 && str == "?" {
 		// No FullWidth character support
 		str += " "
 		t.cx = -1
 	}
-
 	// XXX: check for hazeltine not being able to display ~
-
 	if x > t.w-width {
 		// too wide to fit; emit a single space instead
 		width = 1

          
@@ 422,8 410,7 @@ func (t *tScreen) drawCell(x, y int, cur
 
 func (t *tScreen) SetCursor(x, y int) {
 	t.Lock()
-	t.cursorx = x
-	t.cursory = y
+	t.cursorx, t.cursory = x, y
 	t.Unlock()
 }
 

          
@@ 435,10 422,8 @@ func (t *tScreen) showCursor() {
 		t.hideCursor()
 		return
 	}
-	t.TPuts(t.ti.TGoto(x, y))
+	t.gotoXY(x, y)
 	t.TPuts(t.ti.ShowCursor)
-	t.cx = x
-	t.cy = y
 }
 
 func (t *tScreen) TPuts(s string) {

          
@@ 448,6 433,7 @@ func (t *tScreen) TPuts(s string) {
 func (t *tScreen) Show() {
 	t.Lock()
 	if !t.fini {
+		// why resize here? dont we do this if an resize event occurs?
 		t.resize()
 		t.draw()
 	}

          
@@ 469,14 455,13 @@ func (t *tScreen) hideCursor() {
 	}
 	// No way to hide cursor, stick it
 	// at bottom right of screen
-	t.cx, t.cy = t.cells.Size()
-	t.TPuts(t.ti.TGoto(t.cx, t.cy))
+	x, y := t.cells.Size()
+	t.gotoXY(x, y)
 }
 
 func (t *tScreen) draw() {
 	// clobber cursor position, because we're gonna change it all
-	t.cx = -1
-	t.cy = -1
+	t.cx, t.cy = -1, -1
 
 	// hide the cursor while we move stuff around
 	t.hideCursor()

          
@@ 524,22 509,20 @@ func (t *tScreen) Size() (int, int) {
 	return w, h
 }
 
-func (t *tScreen) resize() {
-	w, h, e := t.term.ReadSize()
-	if e != nil {
-		return
+func (t *tScreen) resize() error {
+	w, h, err := t.term.ReadSize()
+	if err != nil {
+		return err
 	}
 	if w != t.w || h != t.h {
-		t.cx = -1
-		t.cy = -1
+		t.cx, t.cy = -1, -1
 
 		t.cells.Resize(w, h)
 		t.cells.Invalidate()
-		t.h = h
-		t.w = w
-		ev := NewEventResize(w, h)
-		t.PostEvent(ev)
+		t.h, t.w = h, w
+		t.PostEvent(NewEventResize(w, h))
 	}
+	return nil
 }
 
 func (t *tScreen) Colors() int {

          
@@ 644,7 627,6 @@ func (t *tScreen) postMouseEvent(x, y, b
 	// as separate press & release events.
 
 	button := ButtonNone
-	mod := ModNone
 
 	// Mouse wheel has bit 6 set, no release events.  It should be noted
 	// that wheel events are sometimes misdelivered as mouse button events

          
@@ 675,6 657,8 @@ func (t *tScreen) postMouseEvent(x, y, b
 		}
 	}
 
+	mod := ModNone
+
 	if btn&0x4 != 0 {
 		mod |= ModShift
 	}

          
@@ 704,12 688,10 @@ func (t *tScreen) parseSgrMouse(buf *byt
 	var x, y, btn, state int
 	dig := false
 	neg := false
-	motion := false
-	i := 0
 	val := 0
 
-	for i = range b {
-		switch b[i] {
+	for i, c := range b {
+		switch c {
 		case '\x1b':
 			if state != 0 {
 				return false, false

          
@@ 751,7 733,7 @@ func (t *tScreen) parseSgrMouse(buf *byt
 				return false, false
 			}
 			val *= 10
-			val += int(b[i] - '0')
+			val += int(c - '0')
 			dig = true // stay in state
 
 		case ';':

          
@@ 778,14 760,14 @@ func (t *tScreen) parseSgrMouse(buf *byt
 			}
 			y = val - 1
 
-			motion = (btn & 32) != 0
 			btn &^= 32
-			if b[i] == 'm' {
+			if c == 'm' {
 				// mouse release, clear all buttons
 				btn |= 3
 				btn &^= 0x40
 				t.buttondn = false
-			} else if motion {
+			} else if (btn & 32) != 0 {
+				// motion
 				/*
 				 * Some broken terminals appear to send
 				 * mouse button one motion events, instead of

          
@@ 950,12 932,11 @@ func (t *tScreen) scanInput(buf *bytes.B
 	defer t.Unlock()
 
 	for {
-		b := buf.Bytes()
-		if len(b) == 0 {
+		if buf.Len() == 0 {
 			buf.Reset()
 			return
 		}
-
+		b := buf.Bytes()
 		partials := 0
 		var part, comp bool
 		if part, comp = t.parseRune(buf); comp {

          
@@ 989,7 970,6 @@ func (t *tScreen) scanInput(buf *bytes.B
 				partials++
 			}
 		}
-
 		if partials == 0 || expire {
 			if b[0] == '\x1b' {
 				t.escaped = true

          
@@ 1030,8 1010,7 @@ func (t *tScreen) mainLoop() {
 		case <-t.sigwinch:
 			t.Lock()
 			// use Sync
-			t.cx = -1
-			t.cy = -1
+			t.cx, t.cy = -1, -1
 			t.resize()
 			t.cells.Invalidate()
 			t.draw()

          
@@ 1090,10 1069,17 @@ func (t *tScreen) inputLoop() {
 	}
 }
 
+func (t *tScreen) gotoXY(x, y int) {
+	// save a goto call
+	if t.cy != y || t.cx != x {
+		t.TPuts(t.ti.TGoto(x, y))
+		t.cx, t.cy = x, y
+	}
+}
+
 func (t *tScreen) Sync() {
 	t.Lock()
-	t.cx = -1
-	t.cy = -1
+	t.cx, t.cy = -1, -1
 	if !t.fini {
 		t.resize()
 		t.clear = true

          
@@ 1124,9 1110,8 @@ func (t *tScreen) CanDisplay(r rune, che
 	if enc := t.encoder; enc != nil {
 		nb := make([]byte, 6)
 		ob := make([]byte, 6)
+		enc.Reset()
 		num := utf8.EncodeRune(ob, r)
-
-		enc.Reset()
 		dst, _, err := enc.Transform(nb, ob[:num], true)
 		if dst != 0 && err == nil && nb[0] != '\x1A' {
 			return true