Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit f68d65e8 authored by deuce's avatar deuce

Add support for two different 24-bit colour methods.

1) XTerm using semicolons.  CSI 38/48 ; 2 ; 0 ; R ; G ; B m
2) PabloDraw/TundraDraw. CSI 0/1 ; R ; G ; B m

These use a temporary internal palette of 15840 entries to ensure what's
on the screen is correct.  Scrollback data may be incorrect however.
parent 0040b1b1
......@@ -23,6 +23,15 @@
#include "vidmodes.h"
#include "bitmap_con.h"
struct palette_entry {
uint8_t red;
uint8_t green;
uint8_t blue;
time_t allocated;
};
static struct palette_entry truecolour_palette[15840]; // Big enough for a unique fg/bg for each cell in a 132x60 window
#if 0
int dbg_pthread_mutex_lock(pthread_mutex_t *lptr, unsigned line)
......@@ -1417,6 +1426,35 @@ int bitmap_set_modepalette(uint32_t p[16])
return 0;
}
uint32_t bitmap_map_rgb(uint16_t r, uint16_t g, uint16_t b)
{
time_t oldest;
int oldestoff;
int i;
time_t now = time(NULL);
oldest = now;
r>>=8;
g>>=8;
b>>=8;
for (i=0; i<sizeof(truecolour_palette) / sizeof(truecolour_palette[0]); i++) {
if (truecolour_palette[i].allocated == 0)
break;
if (truecolour_palette[i].allocated < oldest) {
oldest = truecolour_palette[i].allocated;
oldestoff = i;
}
if (truecolour_palette[i].red == r && truecolour_palette[i].green == g && truecolour_palette[i].blue == b) {
truecolour_palette[i].allocated = now;
return i + TOTAL_DAC_SIZE + 512;
}
}
ciolib_setpalette(i + TOTAL_DAC_SIZE + 512, r<<8 | r, g<<8 | g, b<<8 | b);
truecolour_palette[i].allocated = now;
return i + TOTAL_DAC_SIZE + 512;
}
/***********************/
/* Called from drivers */
/***********************/
......
......@@ -30,6 +30,7 @@ int bitmap_setpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey, uint32_
struct ciolib_pixels *bitmap_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey);
uint32_t *bitmap_get_modepalette(uint32_t p[16]);
int bitmap_set_modepalette(uint32_t p[16]);
uint32_t bitmap_map_rgb(uint16_t r, uint16_t g, uint16_t b);
#endif
#ifdef BITMAP_CIOLIB_DRIVER
......
......@@ -189,6 +189,7 @@ int try_sdl_init(int mode)
cio_api.setpixels=bitmap_setpixels;
cio_api.get_modepalette=bitmap_get_modepalette;
cio_api.set_modepalette=bitmap_set_modepalette;
cio_api.map_rgb = bitmap_map_rgb;
return(1);
}
return(0);
......@@ -243,6 +244,7 @@ int try_x_init(int mode)
cio_api.setpixels=bitmap_setpixels;
cio_api.get_modepalette=bitmap_get_modepalette;
cio_api.set_modepalette=bitmap_set_modepalette;
cio_api.map_rgb = bitmap_map_rgb;
return(1);
}
return(0);
......@@ -1911,3 +1913,12 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_set_modepalette(uint32_t p[16])
return cio_api.set_modepalette(p);
return 0;
}
CIOLIBEXPORT uint32_t CIOLIBCALL ciolib_map_rgb(uint16_t r, uint16_t g, uint16_t b)
{
CIOLIB_INIT();
if (cio_api.map_rgb)
return cio_api.map_rgb(r,g,b);
return UINT32_MAX;
}
......
......@@ -362,6 +362,7 @@ typedef struct {
int (*setpixels)(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey, uint32_t x_off, uint32_t y_off, struct ciolib_pixels *pixels, void *mask);
uint32_t *(*get_modepalette)(uint32_t[16]);
int (*set_modepalette)(uint32_t[16]);
uint32_t (*map_rgb)(uint16_t r, uint16_t g, uint16_t b);
} cioapi_t;
CIOLIBEXPORTVAR cioapi_t cio_api;
......@@ -451,6 +452,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_restorescreen(struct ciolib_screen *scrn);
CIOLIBEXPORT void CIOLIBCALL ciolib_setcolour(uint32_t fg, uint32_t bg);
CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(uint32_t[16]);
CIOLIBEXPORT int CIOLIBCALL ciolib_set_modepalette(uint32_t[16]);
CIOLIBEXPORT uint32_t CIOLIBCALL ciolib_map_rgb(uint16_t r, uint16_t g, uint16_t b);
/* DoorWay specific stuff that's only applicable to ANSI mode. */
CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
......@@ -528,6 +530,7 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
#define setcolour(a,b) ciolib_setcolour(a,b)
#define get_modepalette(a) ciolib_get_modepalette(a)
#define set_modepalette(a) ciolib_set_modepalette(a)
#define map_rgb(a,b,c) ciolib_map_rgb(a,b,c)
#endif
#ifdef WITH_SDL
......
......@@ -2463,6 +2463,13 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
cterm->fg_color = seq->param_int[i+2] + 16;
i+=2;
}
else if (i+5 < seq->param_count && seq->param_int[i+1] == 2) {
uint32_t nc;
nc = map_rgb(seq->param_int[i+3]<<8, seq->param_int[i+4]<<8, seq->param_int[i+5]<<8);
if (nc != UINT32_MAX)
cterm->fg_color = nc;
}
break;
case 37:
case 39:
......@@ -2515,6 +2522,13 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
cterm->bg_color = seq->param_int[i+2] + 16;
i+=2;
}
else if (i+5 < seq->param_count && seq->param_int[i+1] == 2) {
uint32_t nc;
nc = map_rgb(seq->param_int[i+3]<<8, seq->param_int[i+4]<<8, seq->param_int[i+5]<<8);
if (nc != UINT32_MAX)
cterm->bg_color = nc;
}
break;
}
}
......@@ -2577,6 +2591,22 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
cterm->save_xpos=WHEREX();
cterm->save_ypos=WHEREY();
break;
case 't':
if (seq->param_count >= 4) {
uint32_t *c = NULL;
uint32_t nc;
if (seq->param_int[0] == 0)
c = &cterm->bg_color;
else if (seq->param_int[0] == 1)
c = &cterm->fg_color;
if (c == NULL)
break;
nc = map_rgb(seq->param_int[1]<<8, seq->param_int[2]<<8, seq->param_int[3]<<8);
if (nc != UINT32_MAX)
*c = nc;
}
break;
case 'u':
if(cterm->save_ypos>0 && cterm->save_ypos<=cterm->height
&& cterm->save_xpos>0 && cterm->save_xpos<=cterm->width) {
......
......@@ -638,7 +638,7 @@ CSI Ps... m
35 - Magenta foreground X
36 - Cyan foreground X
37 - White foreground X
38 - Foreground from palette (see note) X
38 - Extended Foreground (see notes) X
39 - Default foreground (same as white) X
40 - Black background X
41 - Red background X
......@@ -648,13 +648,16 @@ CSI Ps... m
45 - Magenta background X
46 - Cyan background X
47 - White background X
48 - Background from palette (see note) X
48 - Extended Background (see notes) X
49 - Default background (same as black) X
All others are ignored.
Note, For 38 and 48, an additional two parameters are required
after that value. They are considered part of the 38, not separate
NOTE: For 38 and 48, two additional formats are supported, a palette
selection and a direct colour selection.
For palette selection, an additional two parameters are required
after that value. They are considered part of the 38/48, not separate
values. The first additional parameter must be a 5. The second
additional parameter specified the palette index to use. To set the
foreground to orange, and the background to a fairly dark grey, you
......@@ -664,6 +667,16 @@ CSI Ps... m
The default palette is the XTerm 256-colour palette. See here:
https://jonasjacek.github.io/colors/
For direct colour selection, an additional five parameters are required
after that value. They are considered part of the 38/48, not separate
values. The first additional parameter must be a 2. The second
additional parameter is ignored. The third, fourth, and fifth specify
the R/G/B values respectively. CTerm handles this with an internal
temporary palette, so scrollback may not have the correct colours.
The internal palette is large enough for all cells in a 132x60 screen
to have unique foreground and background colours though, so the current
screen should always be as expected.
SOURCE: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf
SOURCE: XTerm
......@@ -777,6 +790,18 @@ CSI s
SOURCE: ANSI.SYS
CSI Ps ; Pn1 ; Pn2 ; Pn3 t
NON-STANDARD EXTENSION
Select a 24-bit colour
If Ps is 0, sets the background colour.
If Ps is 1, sets the foreground colour.
Pn1, Pn2, Pn3 contains the RGB value to set.
CTerm handles this with an internal temporary palette, so scrollback
may not have the correct colours. The internal palette is large
enough for all cells in a 132x60 screen to have unique foreground
and background colours though, so the current screen should always
be as expected.
CSI ? Ps... u
NON-STANDARD EXTENSION
Restore Mode Setting
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment