@@ 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