github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/cga/cga.go (about) 1 package cga 2 3 import ( 4 "strconv" 5 ) 6 7 var ( 8 parser = ansiParser{} 9 backend = cgabackend{} 10 ) 11 12 func WriteString(s string) { 13 for i := range s { 14 WriteByte(s[i]) 15 } 16 } 17 18 func setCursorColumn(n int) { 19 pos := getbackend().GetPos() 20 pos = (pos/80)*80 + n - 1 21 getbackend().SetPos(pos) 22 } 23 24 func eraseLine(method int) { 25 backend := getbackend() 26 pos := backend.GetPos() 27 switch method { 28 case 0: 29 end := (pos/80 + 1) * 80 30 for i := pos; i < end; i++ { 31 backend.WritePos(i, ' ') 32 } 33 default: 34 panic("unsupported erase line method") 35 } 36 } 37 38 func writeCSI(action byte, params []string) { 39 // fmt.Fprintf(os.Stderr, "action:%c, params:%v\n", action, params) 40 switch action { 41 // set cursor 42 case 'G': 43 if len(params) == 0 { 44 setCursorColumn(1) 45 } else { 46 n, _ := strconv.Atoi(params[0]) 47 setCursorColumn(n) 48 } 49 // erase line 50 case 'K': 51 if len(params) == 0 { 52 eraseLine(0) 53 } else { 54 n, _ := strconv.Atoi(params[0]) 55 eraseLine(n) 56 } 57 default: 58 panic("unsupported CSI action") 59 } 60 } 61 62 func WriteByte(ch byte) { 63 switch parser.step(ch) { 64 case errNormalChar: 65 backend := getbackend() 66 67 switch ch { 68 case '\n', '\r', '\b': 69 backend.WriteByte(ch) 70 case '\t': 71 for i := 0; i < 4; i++ { 72 backend.WriteByte(' ') 73 } 74 default: 75 if ch >= 32 && ch <= 127 { 76 backend.WriteByte(ch) 77 } else { 78 backend.WriteByte('?') 79 } 80 } 81 82 // do normal char 83 case errCSIDone: 84 // do csi 85 writeCSI(parser.Action(), parser.Params()) 86 parser.Reset() 87 case errInvalidChar: 88 parser.Reset() 89 default: 90 // ignore 91 } 92 }