github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/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 setCursorHome() { 25 getbackend().SetPos(0) 26 } 27 28 func eraseLine(method EraseMethod) { 29 backend := getbackend() 30 pos := backend.GetPos() 31 switch method { 32 case EraseMethod_Line: 33 end := (pos/80 + 1) * 80 34 for i := pos; i < end; i++ { 35 backend.WritePos(i, ' ') 36 } 37 38 case EraseMethod_All: 39 for i := 0; i < 25*80; i++ { 40 backend.WritePos(i, ' ') 41 } 42 43 default: 44 panic("unsupported erase line method") 45 } 46 } 47 48 func writeCSI(action byte, params []string) { 49 // fmt.Fprintf(os.Stderr, "action:%c, params:%v\n", action, params) 50 switch action { 51 // set cursor column 52 case 'G': 53 if len(params) == 0 { 54 setCursorColumn(1) 55 } else { 56 n, _ := strconv.Atoi(params[0]) 57 setCursorColumn(n) 58 } 59 // erase line 60 case 'K': 61 if len(params) == 0 { 62 eraseLine(EraseMethod_Line) 63 } else { 64 //n, _ := strconv.Atoi(params[0]) 65 eraseLine(EraseMethod_Unknown) 66 } 67 68 // Erase screen - note; this action *looks* like it ought 69 // to be just <ESC>[J - which is 'erase from current line to 70 // bottom of screen', but I actually want it to mimic <ESC>[2J 71 // which is 'erase screen and return to top' 72 // 73 // Hopefully nobody ever uses my fork if they expect that functionality 74 case 'J': 75 eraseLine(EraseMethod_All) 76 setCursorHome() 77 78 default: 79 // ignore 80 } 81 } 82 83 func WriteByte(ch byte) { 84 switch parser.step(ch) { 85 case errNormalChar: 86 backend := getbackend() 87 88 switch ch { 89 case '\n', '\r', '\b': 90 backend.WriteByte(ch) 91 case '\t': 92 for i := 0; i < 4; i++ { 93 backend.WriteByte(' ') 94 } 95 default: 96 if ch >= 32 && ch <= 127 { 97 backend.WriteByte(ch) 98 } else { 99 backend.WriteByte('?') 100 } 101 } 102 103 // do normal char 104 case errCSIDone: 105 // do csi 106 writeCSI(parser.Action(), parser.Params()) 107 parser.Reset() 108 case errInvalidChar: 109 parser.Reset() 110 default: 111 getbackend().WriteByte(ch) 112 // ignore 113 } 114 }