From 8ec2b4f18b86d1df792f1611a3a21b38c6c8742c Mon Sep 17 00:00:00 2001 From: Liam Galvin Date: Mon, 22 Oct 2018 11:10:34 +0100 Subject: [PATCH] Add true colour support --- README.md | 2 + terminal/sgr.go | 234 ++++++++++++++++++++++++------------------------ 2 files changed, 121 insertions(+), 115 deletions(-) diff --git a/README.md b/README.md index cd9a7cb..9ff9349 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ Ensure you have your latest graphics card drivers installed before use. |-----------------------------|------|-------| | Pty allocation | ✔ | Needs work for OSX + Windows | OpenGL rendering | ✔ | +| 8-bit (256) colour | ✔ | +| 24-bit (true) colour | ✔ | | Resizing/content reordering | ⏳ | | ANSI escape codes | ⏳ | Most of these are handled now | UTF-8 input | ✔ | diff --git a/terminal/sgr.go b/terminal/sgr.go index c9d3520..7e08c66 100644 --- a/terminal/sgr.go +++ b/terminal/sgr.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/liamg/aminal/buffer" + "github.com/liamg/aminal/config" ) func sgrSequenceHandler(params []string, intermediate string, terminal *Terminal) error { @@ -13,121 +14,123 @@ func sgrSequenceHandler(params []string, intermediate string, terminal *Terminal return nil } - param := params[0] - - switch param { - case "00", "0", "": - attr := terminal.ActiveBuffer().CursorAttr() - *attr = buffer.CellAttributes{ - FgColour: terminal.config.ColourScheme.Foreground, - BgColour: terminal.config.ColourScheme.Background, + for i := range params { + switch params[i] { + case "00", "0", "": + attr := terminal.ActiveBuffer().CursorAttr() + *attr = buffer.CellAttributes{ + FgColour: terminal.config.ColourScheme.Foreground, + BgColour: terminal.config.ColourScheme.Background, + } + case "1", "01": + terminal.ActiveBuffer().CursorAttr().Bold = true + case "2", "02": + terminal.ActiveBuffer().CursorAttr().Dim = true + case "4", "04": + terminal.ActiveBuffer().CursorAttr().Underline = true + case "5", "05": + terminal.ActiveBuffer().CursorAttr().Blink = true + case "7", "07": + terminal.ActiveBuffer().CursorAttr().Reverse = true + case "8", "08": + terminal.ActiveBuffer().CursorAttr().Hidden = true + case "21": + terminal.ActiveBuffer().CursorAttr().Bold = false + case "22": + terminal.ActiveBuffer().CursorAttr().Dim = false + case "24": + terminal.ActiveBuffer().CursorAttr().Underline = false + case "25": + terminal.ActiveBuffer().CursorAttr().Blink = false + case "27": + terminal.ActiveBuffer().CursorAttr().Reverse = false + case "28": + terminal.ActiveBuffer().CursorAttr().Hidden = false + case "39": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Foreground + case "30": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Black + case "31": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Red + case "32": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Green + case "33": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Yellow + case "34": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Blue + case "35": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Magenta + case "36": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Cyan + case "37": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White + case "90": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.DarkGrey + case "91": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightRed + case "92": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightGreen + case "93": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightYellow + case "94": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightBlue + case "95": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightMagenta + case "96": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightCyan + case "97": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White + case "49": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Background + case "40": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Black + case "41": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Red + case "42": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Green + case "43": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Yellow + case "44": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Blue + case "45": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Magenta + case "46": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Cyan + case "47": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White + case "100": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.DarkGrey + case "101": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightRed + case "102": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightGreen + case "103": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightYellow + case "104": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightBlue + case "105": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightMagenta + case "106": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightCyan + case "107": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White + case "38": // set foreground + c, err := terminal.getANSIColour(params[i:]) + if err != nil { + return err + } + terminal.ActiveBuffer().CursorAttr().FgColour = c + return nil + case "48": // set background + c, err := terminal.getANSIColour(params[i:]) + if err != nil { + return err + } + terminal.ActiveBuffer().CursorAttr().BgColour = c + return nil + default: + return fmt.Errorf("Unknown SGR control sequence: (ESC[%s%sm)", params[i:], intermediate) } - case "1", "01": - terminal.ActiveBuffer().CursorAttr().Bold = true - case "2", "02": - terminal.ActiveBuffer().CursorAttr().Dim = true - case "4", "04": - terminal.ActiveBuffer().CursorAttr().Underline = true - case "5", "05": - terminal.ActiveBuffer().CursorAttr().Blink = true - case "7", "07": - terminal.ActiveBuffer().CursorAttr().Reverse = true - case "8", "08": - terminal.ActiveBuffer().CursorAttr().Hidden = true - case "21": - terminal.ActiveBuffer().CursorAttr().Bold = false - case "22": - terminal.ActiveBuffer().CursorAttr().Dim = false - case "24": - terminal.ActiveBuffer().CursorAttr().Underline = false - case "25": - terminal.ActiveBuffer().CursorAttr().Blink = false - case "27": - terminal.ActiveBuffer().CursorAttr().Reverse = false - case "28": - terminal.ActiveBuffer().CursorAttr().Hidden = false - case "39": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Foreground - case "30": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Black - case "31": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Red - case "32": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Green - case "33": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Yellow - case "34": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Blue - case "35": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Magenta - case "36": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Cyan - case "37": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White - case "90": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.DarkGrey - case "91": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightRed - case "92": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightGreen - case "93": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightYellow - case "94": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightBlue - case "95": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightMagenta - case "96": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightCyan - case "97": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White - case "49": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Background - case "40": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Black - case "41": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Red - case "42": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Green - case "43": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Yellow - case "44": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Blue - case "45": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Magenta - case "46": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Cyan - case "47": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White - case "100": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.DarkGrey - case "101": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightRed - case "102": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightGreen - case "103": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightYellow - case "104": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightBlue - case "105": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightMagenta - case "106": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightCyan - case "107": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White - case "38": // set foreground - c, err := terminal.getANSIColour(params) - if err != nil { - return err - } - terminal.ActiveBuffer().CursorAttr().FgColour = c - case "48": // set background - c, err := terminal.getANSIColour(params) - if err != nil { - return err - } - terminal.ActiveBuffer().CursorAttr().BgColour = c - default: - return fmt.Errorf("Unknown SGR control sequence: (ESC[%s%sm)", param, intermediate) } //terminal.logger.Debugf("SGR control sequence: (ESC[%s%sm)", param, intermediate) @@ -135,7 +138,7 @@ func sgrSequenceHandler(params []string, intermediate string, terminal *Terminal return nil } -func (terminal *Terminal) getANSIColour(params []string) ([3]float32, error) { +func (terminal *Terminal) getANSIColour(params []string) (config.Colour, error) { if len(params) > 2 { switch params[1] { @@ -154,6 +157,7 @@ func (terminal *Terminal) getANSIColour(params []string) ([3]float32, error) { } // 24 bit colour if len(params) == 5 { // standard true colour + r, err := strconv.Atoi(params[2]) if err != nil { return [3]float32{0, 0, 0}, fmt.Errorf("Invalid true colour specifier")