Skip to content

Commit 739b0ad

Browse files
committed
Improve support for OSC 4 by cleaning up parsing code and adding support for reporting 8-bit color rgb values. Issue 3007
1 parent 588e65b commit 739b0ad

File tree

6 files changed

+67
-49
lines changed

6 files changed

+67
-49
lines changed

VT100Output.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#import <Foundation/Foundation.h>
1+
#import <Cocoa/Cocoa.h>
22
#import "VT100GridTypes.h"
33

44
typedef enum {
@@ -49,6 +49,7 @@ typedef enum {
4949
- (NSData *)reportStatus;
5050
- (NSData *)reportDeviceAttribute;
5151
- (NSData *)reportSecondaryDeviceAttribute;
52+
- (NSData *)reportColor:(NSColor *)color atIndex:(int)index;
5253

5354
- (void)setTermTypeIsValid:(BOOL)termTypeIsValid;
5455

VT100Output.m

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#import "VT100Output.h"
2-
#import <Cocoa/Cocoa.h>
32
#include <term.h>
43

54
// Indexes into _keyStrings.
@@ -544,6 +543,16 @@ - (NSData *)reportSecondaryDeviceAttribute
544543
length:STATIC_STRLEN(REPORT_SDA)];
545544
}
546545

546+
- (NSData *)reportColor:(NSColor *)color atIndex:(int)index {
547+
NSString *string = [NSString stringWithFormat:@"%c]4;%d;rgb:%02x/%02x/%02x%c",
548+
ESC, index,
549+
(int) ([color redComponent] * 255.0),
550+
(int) ([color greenComponent] * 255.0),
551+
(int) ([color blueComponent] * 255.0),
552+
7];
553+
return [string dataUsingEncoding:NSUTF8StringEncoding];
554+
}
555+
547556
#pragma mark - Private
548557

549558
- (NSData *)specialKey:(int)terminfo

VT100Screen.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,13 @@ - (void)terminalSetTabColorBlueComponentTo:(CGFloat)color {
31093109
[delegate_ screenSetTabColorBlueComponentTo:color];
31103110
}
31113111

3112+
- (NSColor *)terminalColorForIndex:(int)index {
3113+
if (index < 0 || index > 255) {
3114+
return nil;
3115+
}
3116+
return [[delegate_ screenColorMap] colorForKey:kColorMap8bitBase + index];
3117+
}
3118+
31123119
- (int)terminalCursorX {
31133120
return MIN([self cursorX], [self width]);
31143121
}

VT100Terminal.m

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,53 +1593,49 @@ - (void)executeToken:(VT100Token *)token {
15931593
}
15941594

15951595
- (void)executeXtermSetRgb:(VT100Token *)token {
1596-
// The format of this command is "<index>;rgb:<redhex>/<greenhex>/<bluehex>", e.g. "105;rgb:00/cc/ff"
1597-
// TODO(georgen): xterm has extended this quite a bit and we're behind. Catch up.
1598-
const char *s = [token.string UTF8String];
1599-
int theIndex = 0;
1600-
while (isdigit(*s)) {
1601-
theIndex = 10*theIndex + *s++ - '0';
1602-
}
1603-
if (*s++ != ';') {
1604-
return;
1605-
}
1606-
if (*s++ != 'r') {
1607-
return;
1608-
}
1609-
if (*s++ != 'g') {
1610-
return;
1611-
}
1612-
if (*s++ != 'b') {
1613-
return;
1614-
}
1615-
if (*s++ != ':') {
1616-
return;
1617-
}
1618-
int r = 0, g = 0, b = 0;
1619-
1620-
while (isxdigit(*s)) {
1621-
r = 16*r + (*s>='a' ? *s++ - 'a' + 10 : *s>='A' ? *s++ - 'A' + 10 : *s++ - '0');
1622-
}
1623-
if (*s++ != '/') {
1624-
return;
1625-
}
1626-
while (isxdigit(*s)) {
1627-
g = 16*g + (*s>='a' ? *s++ - 'a' + 10 : *s>='A' ? *s++ - 'A' + 10 : *s++ - '0');
1628-
}
1629-
if (*s++ != '/') {
1630-
return;
1631-
}
1632-
while (isxdigit(*s)) {
1633-
b = 16*b + (*s>='a' ? *s++ - 'a' + 10 : *s>='A' ? *s++ - 'A' + 10 : *s++ - '0');
1634-
}
1635-
if (theIndex >= 0 && theIndex <= 255 &&
1636-
r >= 0 && r <= 255 &&
1637-
g >= 0 && g <= 255 &&
1638-
b >= 0 && b <= 255) {
1639-
[delegate_ terminalSetColorTableEntryAtIndex:theIndex
1640-
color:[NSColor colorWith8BitRed:r
1641-
green:g
1642-
blue:b]];
1596+
NSArray *parts = [token.string componentsSeparatedByString:@";"];
1597+
int theIndex;
1598+
for (int i = 0; i < parts.count; i++) {
1599+
NSString *part = parts[i];
1600+
if ((i % 2) == 0 ) {
1601+
theIndex = [part intValue];
1602+
} else {
1603+
if ([part hasPrefix:@"rgb:"]) {
1604+
// The format of this command is "<index>;rgb:<redhex>/<greenhex>/<bluehex>", e.g. "105;rgb:00/cc/ff"
1605+
NSString *componentsString = [part substringFromIndex:4];
1606+
NSArray *components = [componentsString componentsSeparatedByString:@"/"];
1607+
if (components.count == 3) {
1608+
CGFloat colors[3];
1609+
BOOL ok = YES;
1610+
for (int j = 0; j < 3; j++) {
1611+
NSScanner *scanner = [NSScanner scannerWithString:components[j]];
1612+
unsigned int intValue;
1613+
if (![scanner scanHexInt:&intValue]) {
1614+
ok = NO;
1615+
} else {
1616+
ok = (intValue <= 255);
1617+
}
1618+
if (ok) {
1619+
int limit = 1 << ((4 * [components[j] length]) - 1);
1620+
colors[j] = (CGFloat)intValue / (CGFloat)limit;
1621+
} else {
1622+
break;
1623+
}
1624+
}
1625+
if (ok) {
1626+
NSColor *theColor = [NSColor colorWithCalibratedRed:colors[0]
1627+
green:colors[1]
1628+
blue:colors[2]
1629+
alpha:1];
1630+
[delegate_ terminalSetColorTableEntryAtIndex:theIndex
1631+
color:theColor];
1632+
}
1633+
}
1634+
} else if ([part isEqualToString:@"?"]) {
1635+
NSColor *theColor = [delegate_ terminalColorForIndex:theIndex];
1636+
[delegate_ terminalSendReport:[self.output reportColor:theColor atIndex:theIndex]];
1637+
}
1638+
}
16431639
}
16441640
}
16451641

VT100TerminalDelegate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ typedef enum {
332332
- (void)terminalSetTabColorGreenComponentTo:(CGFloat)color;
333333
- (void)terminalSetTabColorBlueComponentTo:(CGFloat)color;
334334

335+
- (NSColor *)terminalColorForIndex:(int)index;
336+
335337
// Returns the current cursor position.
336338
- (int)terminalCursorX;
337339
- (int)terminalCursorY;

tests/query_color_105_and_106

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This should output:
2+
^[]4;105;rgb:87/87/ff^G^[]4;106;rgb:87/af/00^G
3+
]4;105;?;106;?

0 commit comments

Comments
 (0)