+#define okCOLOR(n) ((n) >= 0 && (n) < max_colors)
+#define okRGB(n) ((n) >= 0 && (n) <= 1000)
+#define DecodeRGB(n) (NCURSES_COLOR_T) ((n * 1000) / 0xffff)
+
+static void
+init_all_colors(bool xterm_colors, char *palette_file)
+{
+ NCURSES_PAIRS_T cp;
+ all_colors = typeMalloc(RGB_DATA, (unsigned) max_colors);
+ if (!all_colors)
+ failed("all_colors");
+ for (cp = 0; cp < max_colors; ++cp) {
+ color_content(cp,
+ &all_colors[cp].red,
+ &all_colors[cp].green,
+ &all_colors[cp].blue);
+ }
+ /* xterm and compatible terminals can read results of an OSC string
+ * asking for the current color palette.
+ */
+ if (xterm_colors) {
+ int n;
+ int got;
+ char result[BUFSIZ];
+ int check_n;
+ unsigned check_r, check_g, check_b;
+
+ raw();
+ noecho();
+ for (n = 0; n < max_colors; ++n) {
+ fprintf(stderr, "\033]4;%d;?\007", n);
+ got = (int) read(0, result, sizeof(result) - 1);
+ if (got < 0)
+ break;
+ result[got] = '\0';
+ if (sscanf(result, "\033]4;%d;rgb:%x/%x/%x\007",
+ &check_n,
+ &check_r,
+ &check_g,
+ &check_b) == 4 &&
+ check_n == n) {
+ all_colors[n].red = DecodeRGB(check_r);
+ all_colors[n].green = DecodeRGB(check_g);
+ all_colors[n].blue = DecodeRGB(check_b);
+ } else {
+ break;
+ }
+ }
+ reset_prog_mode();
+ }
+ if (palette_file != 0) {
+ FILE *fp = fopen(palette_file, "r");
+ if (fp != 0) {
+ char buffer[BUFSIZ];
+ int red, green, blue;
+ int scale = 1000;
+ int c;
+ while (fgets(buffer, sizeof(buffer), fp) != 0) {
+ if (sscanf(buffer, "scale:%d", &c) == 1) {
+ scale = c;
+ } else if (sscanf(buffer, "%d:%d %d %d",
+ &c,
+ &red,
+ &green,
+ &blue) == 4
+ && okCOLOR(c)
+ && okRGB(red)
+ && okRGB(green)
+ && okRGB(blue)) {
+#define Scaled(n) (NCURSES_COLOR_T) (((n) * 1000) / scale)
+ all_colors[c].red = Scaled(red);
+ all_colors[c].green = Scaled(green);
+ all_colors[c].blue = Scaled(blue);
+ }
+ }
+ fclose(fp);
+ }
+ }
+}
+