Skip to content
GitLab
Explore
Sign in
Commits on Source (2)
Rework colour handling with a view to making it more flexible
· 3b97891f
Alice Mitchell
authored
Mar 28, 2019
3b97891f
Add simple ANSI-256 colour sequences with &ff& and &ff:ff& sequences
· 15a0fb44
Alice Mitchell
authored
Mar 28, 2019
implements
#38
15a0fb44
Hide whitespace changes
Inline
Side-by-side
src/client/colour.c
View file @
15a0fb44
...
...
@@ -22,85 +22,166 @@ static char *colour_set=NULL;
/* the current user template */
extern
struct
user
*
const
user
;
/*
return colour code sequence
*/
char
*
colour
(
char
*
tex
t
)
/*
safe copy string
*/
static
void
copy_in
(
char
*
dest
,
int
len
,
const
char
*
inpu
t
)
{
s
tatic
char
line
[
40
]
;
int
i
;
s
nprintf
(
dest
,
len
,
"%s"
,
input
)
;
}
line
[
0
]
=
0
;
static
int
hex_decode
(
const
char
*
input
,
int
len
)
{
int
i
=
0
;
int
total
=
0
;
/* system colour chart */
if
(
strchr
(
"0123456789"
,
text
[
0
]))
{
i
=
atoi
(
text
);
if
(
i
<
0
||
i
>=
COLOUR_LIMIT
)
return
(
line
);
if
(
colour_chart
[
i
]
==
NULL
)
if
(
colour_chart
[
0
]
==
NULL
)
return
(
line
);
else
return
(
colour_chart
[
0
]);
while
(
i
<
len
&&
*
input
)
{
total
<<=
4
;
if
(
*
input
>=
'0'
&&
*
input
<=
'9'
)
total
|=
*
input
-
'0'
;
else
return
(
colour_chart
[
i
]);
}
i
=
0
;
line
[
i
++
]
=
033
;
line
[
i
++
]
=
'['
;
/* reset string ? */
if
(
strchr
(
"-n"
,
text
[
0
])
&&
strchr
(
"-n"
,
text
[
1
])
)
{
line
[
i
++
]
=
'm'
;
line
[
i
]
=
0
;
return
(
line
);
}
/* high intensity mode? */
if
(
isupper
(
text
[
0
]))
{
line
[
i
++
]
=
'1'
;
line
[
i
++
]
=
';'
;
}
else
{
line
[
i
++
]
=
'0'
;
line
[
i
++
]
=
';'
;
if
(
*
input
>=
'a'
&&
*
input
<=
'f'
)
total
|=
(
*
input
-
'a'
)
+
10
;
else
if
(
*
input
>=
'A'
&&
*
input
<=
'F'
)
total
|=
(
*
input
-
'a'
)
+
10
;
input
++
;
i
++
;
}
return
total
;
}
if
(
strchr
(
"kKrRgGyYbBmMcCwW"
,
text
[
0
])
!=
NULL
)
{
if
(
strchr
(
"n-"
,
text
[
0
])
==
NULL
)
line
[
i
++
]
=
'3'
;
if
(
strchr
(
"kK"
,
text
[
0
]))
line
[
i
++
]
=
'0'
;
else
if
(
strchr
(
"rR"
,
text
[
0
]))
line
[
i
++
]
=
'1'
;
else
if
(
strchr
(
"gG"
,
text
[
0
]))
line
[
i
++
]
=
'2'
;
else
if
(
strchr
(
"yY"
,
text
[
0
]))
line
[
i
++
]
=
'3'
;
else
if
(
strchr
(
"bB"
,
text
[
0
]))
line
[
i
++
]
=
'4'
;
else
if
(
strchr
(
"mM"
,
text
[
0
]))
line
[
i
++
]
=
'5'
;
else
if
(
strchr
(
"cC"
,
text
[
0
]))
line
[
i
++
]
=
'6'
;
else
if
(
strchr
(
"wW"
,
text
[
0
]))
line
[
i
++
]
=
'7'
;
/* seperator */
if
(
strchr
(
"n-"
,
text
[
0
])
==
NULL
&&
strchr
(
"n-"
,
text
[
1
])
==
NULL
)
line
[
i
++
]
=
';'
;
/* return colour code sequence */
int
colour
(
const
char
*
input
,
char
*
output
,
int
outlen
)
{
int
consume
=
0
;
/* original colour mode */
if
(
*
input
==
033
)
{
char
text
[
3
];
int
i
=
0
;
consume
=
1
;
/* build the string, skipping unicode sequences */
while
(
i
<
2
&&
input
[
consume
]
!=
0
)
{
if
((
input
[
consume
]
&
192
)
==
192
)
{
consume
++
;
text
[
i
++
]
=
'-'
;
while
((
input
[
consume
]
&
192
)
==
128
)
consume
++
;
}
else
{
text
[
i
++
]
=
input
[
consume
++
];
}
}
text
[
2
]
=
'\0'
;
/* system colour chart */
if
(
strchr
(
"0123456789"
,
text
[
0
]))
{
i
=
atoi
(
text
);
if
(
i
>=
0
&&
i
<
COLOUR_LIMIT
)
{
if
(
colour_chart
[
i
]
!=
NULL
)
copy_in
(
output
,
outlen
,
colour_chart
[
i
]);
else
if
(
colour_chart
[
0
]
!=
NULL
)
copy_in
(
output
,
outlen
,
colour_chart
[
0
]);
}
return
consume
;
}
i
=
0
;
output
[
i
++
]
=
033
;
output
[
i
++
]
=
'['
;
/* reset string ? */
if
(
strchr
(
"-n"
,
text
[
0
])
&&
strchr
(
"-n"
,
text
[
1
])
)
{
output
[
i
++
]
=
'm'
;
output
[
i
]
=
'\0'
;
return
(
consume
);
}
/* high intensity mode? */
if
(
isupper
(
text
[
0
]))
{
output
[
i
++
]
=
'1'
;
output
[
i
++
]
=
';'
;
}
else
{
output
[
i
++
]
=
'0'
;
output
[
i
++
]
=
';'
;
}
if
(
strchr
(
"kKrRgGyYbBmMcCwW"
,
text
[
0
])
!=
NULL
)
{
if
(
strchr
(
"n-"
,
text
[
0
])
==
NULL
)
output
[
i
++
]
=
'3'
;
if
(
strchr
(
"kK"
,
text
[
0
]))
output
[
i
++
]
=
'0'
;
else
if
(
strchr
(
"rR"
,
text
[
0
]))
output
[
i
++
]
=
'1'
;
else
if
(
strchr
(
"gG"
,
text
[
0
]))
output
[
i
++
]
=
'2'
;
else
if
(
strchr
(
"yY"
,
text
[
0
]))
output
[
i
++
]
=
'3'
;
else
if
(
strchr
(
"bB"
,
text
[
0
]))
output
[
i
++
]
=
'4'
;
else
if
(
strchr
(
"mM"
,
text
[
0
]))
output
[
i
++
]
=
'5'
;
else
if
(
strchr
(
"cC"
,
text
[
0
]))
output
[
i
++
]
=
'6'
;
else
if
(
strchr
(
"wW"
,
text
[
0
]))
output
[
i
++
]
=
'7'
;
/* seperator */
if
(
strchr
(
"n-"
,
text
[
0
])
==
NULL
&&
strchr
(
"n-"
,
text
[
1
])
==
NULL
)
output
[
i
++
]
=
';'
;
}
if
(
strchr
(
"kKrRgGyYbBmMcCwW"
,
text
[
1
])
!=
NULL
)
{
/* now background colour */
if
(
strchr
(
"n-"
,
text
[
1
])
==
NULL
)
output
[
i
++
]
=
'4'
;
if
(
strchr
(
"kK"
,
text
[
1
]))
output
[
i
++
]
=
'0'
;
else
if
(
strchr
(
"rR"
,
text
[
1
]))
output
[
i
++
]
=
'1'
;
else
if
(
strchr
(
"gG"
,
text
[
1
]))
output
[
i
++
]
=
'2'
;
else
if
(
strchr
(
"yY"
,
text
[
1
]))
output
[
i
++
]
=
'3'
;
else
if
(
strchr
(
"bB"
,
text
[
1
]))
output
[
i
++
]
=
'4'
;
else
if
(
strchr
(
"mM"
,
text
[
1
]))
output
[
i
++
]
=
'5'
;
else
if
(
strchr
(
"cC"
,
text
[
1
]))
output
[
i
++
]
=
'6'
;
else
if
(
strchr
(
"wW"
,
text
[
1
]))
output
[
i
++
]
=
'7'
;
}
output
[
i
++
]
=
'm'
;
output
[
i
]
=
'\0'
;
}
if
(
strchr
(
"kKrRgGyYbBmMcCwW"
,
text
[
1
])
!=
NULL
)
{
/* now background colour */
if
(
strchr
(
"n-"
,
text
[
1
])
==
NULL
)
line
[
i
++
]
=
'4'
;
if
(
strchr
(
"kK"
,
text
[
1
]))
line
[
i
++
]
=
'0'
;
else
if
(
strchr
(
"rR"
,
text
[
1
]))
line
[
i
++
]
=
'1'
;
else
if
(
strchr
(
"gG"
,
text
[
1
]))
line
[
i
++
]
=
'2'
;
else
if
(
strchr
(
"yY"
,
text
[
1
]))
line
[
i
++
]
=
'3'
;
else
if
(
strchr
(
"bB"
,
text
[
1
]))
line
[
i
++
]
=
'4'
;
else
if
(
strchr
(
"mM"
,
text
[
1
]))
line
[
i
++
]
=
'5'
;
else
if
(
strchr
(
"cC"
,
text
[
1
]))
line
[
i
++
]
=
'6'
;
else
if
(
strchr
(
"wW"
,
text
[
1
]))
line
[
i
++
]
=
'7'
;
if
(
*
input
==
'&'
)
{
/* first let us test this is a valid colour string */
const
char
*
p
=
input
+
1
;
/* skip past all valid chars */
while
(
*
p
&&
strchr
(
"0123456789AbBcCdDeEfF:"
,
*
p
))
p
++
;
/* not the ending we were expecting, ignore it then */
if
(
*
p
!=
'&'
)
return
0
;
char
hex
[
7
];
int
i
=
0
;
consume
=
1
;
while
(
i
<
7
&&
input
[
consume
]
&&
strchr
(
"0123456789AbBcCdDeEfF"
,
input
[
consume
]))
hex
[
i
++
]
=
input
[
consume
++
];
hex
[
i
]
=
'\0'
;
if
(
i
==
2
)
{
int
col
=
hex_decode
(
hex
,
2
);
snprintf
(
output
,
outlen
,
"
\033
[38;5;%dm"
,
col
);
}
if
(
input
[
consume
]
==
':'
)
{
consume
++
;
i
=
0
;
while
(
i
<
7
&&
input
[
consume
]
&&
strchr
(
"0123456789AbBcCdDeEfF"
,
input
[
consume
]))
hex
[
i
++
]
=
input
[
consume
++
];
hex
[
i
]
=
'\0'
;
if
(
i
==
2
)
{
int
col
=
hex_decode
(
hex
,
2
);
int
off
=
strlen
(
output
);
snprintf
(
&
output
[
off
],
outlen
-
off
,
"
\033
[48;5;%dm"
,
col
);
}
}
while
(
input
[
consume
]
&&
strchr
(
"0123456789AbBcCdDeEfF:"
,
input
[
consume
]))
consume
++
;
if
(
input
[
consume
]
==
'&'
)
consume
++
;
}
line
[
i
++
]
=
'm'
;
line
[
i
]
=
0
;
return
(
line
);
return
(
consume
);
}
void
colour_free
(
void
)
...
...
src/client/colour.h
View file @
15a0fb44
...
...
@@ -7,7 +7,7 @@ void init_colour(void);
void
destroy_colours
(
void
);
void
colour_load
(
char
*
file
,
int
quiet
);
void
colour_free
(
void
);
char
*
colour
(
c
har
*
text
);
int
colour
(
c
onst
char
*
input
,
char
*
output
,
int
outlen
);
char
*
get_colour
(
void
);
#endif
/* COLOUR_H */
src/client/main.c
View file @
15a0fb44
...
...
@@ -1070,140 +1070,83 @@ void format_message(const char *format, ...)
void
display_message
(
const
char
*
text
,
int
beeps
,
int
newline
)
{
static
int
count
=
0
;
char
line
[
MAXTEXTLENGTH
];
int
i
,
j
,
colrstart
;
int
hascolour
;
char
outline
[
MAXTEXTLENGTH
];
int
olen
=
0
;
int
screen_width
=
screen_w
();
char
*
colr
=
NULL
;
int
endline
;
char
colr
[
128
];
int
convert_warnings
=
0
;
const
unsigned
char
*
ptr
=
(
const
unsigned
char
*
)
text
;
const
unsigned
char
*
end
;
int
charcount
=
0
;
bool
endline
;
size_t
not_in_local
=
0
;
size_t
len
;
if
(
text
==
NULL
||
(
len
=
strlen
(
text
)
)
==
0
)
{
if
(
text
==
NULL
||
strlen
(
text
)
==
0
)
{
printf
(
"%s"
,
_
(
"Error: Urk, no message to print.
\n
"
));
return
;
}
if
(
UseRL
&&
disable_rl
(
1
))
count
=
0
;
i
=
0
;
hascolour
=
0
;
colrstart
=-
1
;
end
=
ptr
+
len
;
while
(
ptr
<
end
)
{
if
(
*
ptr
==
033
)
{
char
str
[
3
];
ptr
++
;
if
(
ptr
<
end
)
{
if
((
*
ptr
&
192
)
==
192
)
{
ptr
++
;
str
[
0
]
=
'-'
;
while
((
*
ptr
&
192
)
==
128
&&
ptr
<
end
)
ptr
++
;
}
else
{
str
[
0
]
=
*
ptr
;
ptr
++
;
}
}
if
(
ptr
<
end
)
{
if
((
*
ptr
&
192
)
==
192
)
{
ptr
++
;
str
[
1
]
=
'-'
;
while
((
*
ptr
&
192
)
==
128
&&
ptr
<
end
)
ptr
++
;
}
else
{
str
[
1
]
=
*
ptr
;
ptr
++
;
}
}
if
(
UseRL
&&
disable_rl
(
1
))
charcount
=
0
;
while
(
*
text
)
{
if
(
*
text
==
033
||
*
text
==
'&'
)
{
/* escape sequence, skip next two chars */
if
(
s_colouroff
(
user
))
goto
eolprint
;
hascolour
++
;
str
[
2
]
=
0
;
colr
=
colour
(
str
);
text
+=
colour
(
text
,
colr
,
sizeof
(
colr
));
if
(
colr
!=
NULL
)
{
if
(
colrstart
>=
0
)
i
=
colrstart
;
else
colrstart
=
i
;
for
(
j
=
0
;
j
<
strlen
(
colr
);
j
++
)
line
[
i
++
]
=
colr
[
j
];
if
(
colr
[
0
]
&&
!
s_colouroff
(
user
))
{
for
(
int
j
=
0
;
j
<
strlen
(
colr
);
j
++
)
outline
[
olen
++
]
=
colr
[
j
];
}
}
else
if
(
*
ptr
>=
040
&&
*
ptr
<=
0176
)
{
line
[
i
++
]
=
*
ptr
;
count
++
;
colrstart
=
-
1
;
ptr
++
;
}
else
if
((
*
ptr
&
192
)
==
192
)
{
line
[
i
++
]
=
*
ptr
;
count
++
;
colrstart
=
-
1
;
ptr
++
;
}
else
if
(
*
text
>=
040
&&
*
text
<=
0176
)
{
outline
[
olen
++
]
=
*
text
++
;
charcount
++
;
}
else
if
((
*
text
&
192
)
==
192
)
{
outline
[
olen
++
]
=
*
text
++
;
// stops us randomly splitting over a unicode multibyte character
while
((
*
ptr
&
192
)
==
128
&&
ptr
<
end
)
{
line
[
i
++
]
=
*
ptr
;
colrstart
=
-
1
;
ptr
++
;
while
((
*
text
&
192
)
==
128
&&
*
text
)
{
outline
[
olen
++
]
=
*
text
++
;
}
charcount
++
;
}
else
{
ptr
++
;
text
++
;
}
if
(
i
>=
(
MAXTEXTLENGTH
-
20
))
{
line
[
i
]
=
'\0'
;
printline_in_local
(
line
,
&
convert_warnings
,
&
not_in_local
)
;
i
=
0
;
if
(
olen
>=
(
MAXTEXTLENGTH
-
20
))
{
outline
[
olen
]
=
'\0'
;
printline_in_local
(
outline
,
&
convert_warnings
,
&
not_in_local
)
;
olen
=
0
;
charcount
=
0
;
}
eolprint:
if
(
s_nolinewrap
(
user
))
endline
=
(
ptr
>=
end
);
endline
=
(
*
text
==
0
);
else
endline
=
((
count
>=
screen_width
)
||
(
ptr
>=
end
)
);
endline
=
((
char
count
>=
screen_width
)
||
*
text
==
0
);
if
(
endline
)
{
if
(
!
s_colouroff
(
user
)
&&
hascolour
)
{
line
[
i
++
]
=
033
;
line
[
i
++
]
=
'['
;
line
[
i
++
]
=
'm'
;
if
(
!
s_colouroff
(
user
)
&&
colr
[
0
])
{
outline
[
olen
++
]
=
033
;
outline
[
olen
++
]
=
'['
;
outline
[
olen
++
]
=
'm'
;
}
if
(
newline
||
(
ptr
<
end
))
{
line
[
i
++
]
=
'\n'
;
count
=
0
;
if
(
newline
||
*
text
)
{
outline
[
olen
++
]
=
'\n'
;
charcount
=
0
;
}
line
[
i
]
=
'\0'
;
printline_in_local
(
line
,
&
convert_warnings
,
&
not_in_local
);
outline
[
olen
++
]
=
'\0'
;
printline_in_local
(
outline
,
&
convert_warnings
,
&
not_in_local
);
olen
=
0
;
if
(
newline
)
charcount
=
0
;
if
(
*
text
)
{
outline
[
olen
++
]
=
' '
;
charcount
=
1
;
if
(
ptr
>=
end
)
{
i
=
0
;
if
(
newline
)
count
=
0
;
}
else
{
i
=
2
;
count
=
2
;
strcpy
(
line
,
" "
);
/* Restore the colour from the last line */
if
(
!
s_colouroff
(
user
)
&&
hascolour
&&
colr
!=
NULL
)
{
for
(
j
=
0
;
j
<
strlen
(
colr
);
j
++
)
line
[
i
++
]
=
colr
[
j
];
if
(
!
s_colouroff
(
user
)
&&
colr
[
0
])
{
for
(
int
j
=
0
;
j
<
strlen
(
colr
);
j
++
)
outline
[
olen
++
]
=
colr
[
j
];
}
}
}
...
...