summaryrefslogtreecommitdiff
path: root/app/xterm
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2022-09-03 06:51:47 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2022-09-03 06:51:47 +0000
commit6d094594ce46895fd45b62bb0c284575920eb91d (patch)
tree42f71556d6c1adeec641094f7e592926e4cf3bd3 /app/xterm
parentc51805f95c9adb6ca062522e0083daae7dff9019 (diff)
Revert parts of the changes in versions 368 and 369 that broke
support of 30bpp displays with TrueType fonts
Diffstat (limited to 'app/xterm')
-rw-r--r--app/xterm/misc.c351
-rw-r--r--app/xterm/ptyx.h4
-rw-r--r--app/xterm/util.c8
-rw-r--r--app/xterm/xterm.h2
4 files changed, 234 insertions, 131 deletions
diff --git a/app/xterm/misc.c b/app/xterm/misc.c
index 0369ff4a4..35f12489b 100644
--- a/app/xterm/misc.c
+++ b/app/xterm/misc.c
@@ -2599,7 +2599,7 @@ maskToWidth(unsigned long mask)
return result;
}
-XVisualInfo *
+int
getVisualInfo(XtermWidget xw)
{
#define MYFMT "getVisualInfo \
@@ -2640,9 +2640,7 @@ rgb masks (%04lx/%04lx/%04lx)\n"
(vi->blue_mask != 0) &&
((vi->red_mask & vi->green_mask) == 0) &&
((vi->green_mask & vi->blue_mask) == 0) &&
- ((vi->blue_mask & vi->red_mask) == 0) &&
- (vi->class == TrueColor
- || vi->class == DirectColor));
+ ((vi->blue_mask & vi->red_mask) == 0));
if (resource.reportColors) {
printf(MYFMT, MYARG);
@@ -2652,13 +2650,9 @@ rgb masks (%04lx/%04lx/%04lx)\n"
xw->rgb_shifts[0],
xw->rgb_shifts[1],
xw->rgb_shifts[2]));
- TRACE(("...widths %u/%u/%u\n",
- xw->rgb_widths[0],
- xw->rgb_widths[1],
- xw->rgb_widths[2]));
}
}
- return (xw->visInfo != 0) && (xw->numVisuals > 0) ? xw->visInfo : NULL;
+ return (xw->visInfo != 0) && (xw->numVisuals > 0);
#undef MYFMT
#undef MYARG
}
@@ -2671,11 +2665,12 @@ ReportAnsiColorRequest(XtermWidget xw, int opcode, int colornum, int final)
if (AllowColorOps(xw, ecGetAnsiColor)) {
XColor color;
+ Colormap cmap = xw->core.colormap;
char buffer[80];
TRACE(("ReportAnsiColorRequest %d\n", colornum));
color.pixel = GET_COLOR_RES(xw, TScreenOf(xw)->Acolors[colornum]);
- (void) QueryOneColor(xw, &color);
+ XQueryColor(TScreenOf(xw)->display, cmap, &color);
sprintf(buffer, "%d;%d;rgb:%04x/%04x/%04x",
opcode,
(opcode == 5) ? (colornum - NUM_ANSI_COLORS) : colornum,
@@ -2742,70 +2737,6 @@ loadColorTable(XtermWidget xw, unsigned length)
return result;
}
-/***====================================================================***/
-
-/*
- * Call this function with def->{red,green,blue} initialized, to obtain a pixel
- * value.
- */
-Boolean
-AllocOneColor(XtermWidget xw, XColor *def)
-{
- TScreen *screen = TScreenOf(xw);
- Boolean result = True;
-
-#define MaskIt(name,nn) \
- ((unsigned long) ((def->name >> (16 - xw->rgb_widths[nn])) \
- << xw->rgb_shifts[nn]) \
- & xw->visInfo->name ##_mask)
-
- if (getVisualInfo(xw) != NULL && xw->has_rgb) {
- def->pixel = MaskIt(red, 0) | MaskIt(green, 1) | MaskIt(blue, 2);
- } else {
- Display *dpy = screen->display;
- if (!XAllocColor(dpy, xw->core.colormap, def)) {
- /*
- * Decide between foreground and background by a grayscale
- * approximation.
- */
- int bright = def->red * 3 + def->green * 10 + def->blue;
- int levels = 14 * 0x8000;
- def->pixel = ((bright >= levels)
- ? xw->dft_background
- : xw->dft_foreground);
- result = False;
- }
- }
- return result;
-}
-
-/***====================================================================***/
-
-/*
- * Call this function with def->pixel set to the color that we want to convert
- * to separate red/green/blue.
- */
-Boolean
-QueryOneColor(XtermWidget xw, XColor *def)
-{
- Boolean result = True;
-
-#define UnMaskIt(name,nn) \
- ((unsigned short)((def->pixel & xw->visInfo->name ##_mask) >> xw->rgb_shifts[nn]))
-#define UnMaskIt2(name,nn) \
- (unsigned short)((((UnMaskIt(name,nn) << 8) \
- |UnMaskIt(name,nn))) << (8 - xw->rgb_widths[nn]))
-
- if (getVisualInfo(xw) != NULL && xw->has_rgb) {
- /* *INDENT-EQLS* */
- def->red = UnMaskIt2(red, 0);
- def->green = UnMaskIt2(green, 1);
- def->blue = UnMaskIt2(blue, 2);
- } else if (!XQueryColor(TScreenOf(xw)->display, xw->core.colormap, def)) {
- result = False;
- }
- return result;
-}
/***====================================================================***/
@@ -2820,7 +2751,7 @@ QueryOneColor(XtermWidget xw, XColor *def)
* Return False if not able to find or allocate a color.
*/
static Boolean
-allocateClosestRGB(XtermWidget xw, XColor *def)
+allocateClosestRGB(XtermWidget xw, Colormap cmap, XColor *def)
{
TScreen *screen = TScreenOf(xw);
Boolean result = False;
@@ -2874,7 +2805,8 @@ allocateClosestRGB(XtermWidget xw, XColor *def)
}
}
}
- if (AllocOneColor(xw, &screen->cmap_data[bestInx])) {
+ if (XAllocColor(screen->display, cmap,
+ &screen->cmap_data[bestInx]) != 0) {
*def = screen->cmap_data[bestInx];
TRACE(("...closest %x/%x/%x\n", def->red,
def->green, def->blue));
@@ -2899,6 +2831,193 @@ allocateClosestRGB(XtermWidget xw, XColor *def)
#define ULONG_MAX (unsigned long)(~(0L))
#endif
+#define CheckColor(result, value) \
+ result = 0; \
+ if (value.red) \
+ result |= 1; \
+ if (value.green) \
+ result |= 2; \
+ if (value.blue) \
+ result |= 4
+
+#define SelectColor(state, value, result) \
+ switch (state) { \
+ default: \
+ case 1: \
+ result = value.red; \
+ break; \
+ case 2: \
+ result = value.green; \
+ break; \
+ case 4: \
+ result = value.blue; \
+ break; \
+ }
+
+/*
+ * Check if the color map consists of values in exactly one of the red, green
+ * or blue columns. If it is not, we do not know how to use it for the exact
+ * match.
+ */
+static int
+simpleColors(XColor *colortable, unsigned length)
+{
+ unsigned n;
+ int state = 0;
+ int check;
+
+ for (n = 0; n < length; ++n) {
+ if (state > 0) {
+ CheckColor(check, colortable[n]);
+ if (check > 0 && check != state) {
+ state = 0;
+ break;
+ }
+ } else {
+ CheckColor(state, colortable[n]);
+ }
+ }
+ switch (state) {
+ case 1:
+ case 2:
+ case 4:
+ break;
+ default:
+ state = 0;
+ break;
+ }
+ return state;
+}
+
+/*
+ * Shift the mask left or right to put its most significant bit at the 16-bit
+ * mark.
+ */
+static unsigned
+normalizeMask(unsigned mask)
+{
+ while (mask < 0x8000) {
+ mask <<= 1;
+ }
+ while (mask >= 0x10000) {
+ mask >>= 1;
+ }
+ return mask;
+}
+
+static unsigned
+searchColors(XColor *colortable, unsigned mask, unsigned length, unsigned
+ color, int state)
+{
+ unsigned result = 0;
+ unsigned n;
+ unsigned long best = ULONG_MAX;
+ unsigned value;
+
+ mask = normalizeMask(mask);
+ for (n = 0; n < length; ++n) {
+ unsigned long diff;
+
+ SelectColor(state, colortable[n], value);
+ diff = ((color & mask) - (value & mask));
+ diff *= diff;
+ if (diff < best) {
+#if 0
+ TRACE(("...%d:looking for %x, found %x/%x/%x (%lx)\n",
+ n, color,
+ colortable[n].red,
+ colortable[n].green,
+ colortable[n].blue,
+ diff));
+#endif
+ result = n;
+ best = diff;
+ }
+ }
+ SelectColor(state, colortable[result], value);
+ return value;
+}
+
+/*
+ * This is a workaround for a longstanding defect in the X libraries.
+ *
+ * According to
+ * http://www.unix.com/man-page/all/3x/XAllocColoA/
+ *
+ * XAllocColor() acts differently on static and dynamic visuals. On Pseu-
+ * doColor, DirectColor, and GrayScale visuals, XAllocColor() fails if
+ * there are no unallocated colorcells and no allocated read-only cell
+ * exactly matches the requested RGB values. On StaticColor, TrueColor,
+ * and StaticGray visuals, XAllocColor() returns the closest RGB values
+ * available in the colormap. The colorcell_in_out structure returns the
+ * actual RGB values allocated.
+ *
+ * That is, XAllocColor() should suffice unless the color map is full. In that
+ * case, allocateClosestRGB() is useful for the dynamic display classes such as
+ * PseudoColor. It is not useful for TrueColor, since XQueryColors() does not
+ * return regular RGB triples (unless a different scheme was used for
+ * specifying the pixel values); only the blue value is filled in. However, it
+ * is filled in with the colors that the server supports.
+ *
+ * Also (the reason for this function), XAllocColor() does not really work as
+ * described. For some TrueColor configurations it merely returns a close
+ * approximation, but not the closest.
+ */
+static Boolean
+allocateExactRGB(XtermWidget xw, Colormap cmap, XColor *def)
+{
+ XColor save = *def;
+ TScreen *screen = TScreenOf(xw);
+ Boolean result = (Boolean) (XAllocColor(screen->display, cmap, def) != 0);
+
+ /*
+ * If this is a statically allocated display with too many items to store
+ * in our array, i.e., TrueColor, see if we can improve on the result by
+ * using the color values actually supported by the server.
+ */
+ if (result) {
+ unsigned cmap_type;
+ unsigned cmap_size;
+
+ getColormapInfo(xw, &cmap_type, &cmap_size);
+
+ if (cmap_type == TrueColor) {
+ XColor temp = *def;
+ int state;
+
+ if (loadColorTable(xw, cmap_size)
+ && (state = simpleColors(screen->cmap_data, cmap_size)) > 0) {
+#define SearchColors(which) \
+ temp.which = (unsigned short) searchColors(screen->cmap_data, \
+ (unsigned) xw->visInfo->which##_mask,\
+ cmap_size, \
+ save.which, \
+ state)
+ SearchColors(red);
+ SearchColors(green);
+ SearchColors(blue);
+ if (XAllocColor(screen->display, cmap, &temp) != 0) {
+#if OPT_TRACE
+ if (temp.red != save.red
+ || temp.green != save.green
+ || temp.blue != save.blue) {
+ TRACE(("...improved %x/%x/%x ->%x/%x/%x\n",
+ save.red, save.green, save.blue,
+ temp.red, temp.green, temp.blue));
+ } else {
+ TRACE(("...no improvement for %x/%x/%x\n",
+ save.red, save.green, save.blue));
+ }
+#endif
+ *def = temp;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
/*
* Allocate a color for the "ANSI" colors. That actually includes colors up
* to 256.
@@ -2917,8 +3036,11 @@ AllocateAnsiColor(XtermWidget xw,
XColor def;
if (xtermAllocColor(xw, &def, spec)) {
- if (res->mode == True &&
- EQL_COLOR_RES(res, def.pixel)) {
+ if (
+#if OPT_COLOR_RES
+ res->mode == True &&
+#endif
+ EQL_COLOR_RES(res, def.pixel)) {
result = 0;
} else {
result = 1;
@@ -2932,9 +3054,11 @@ AllocateAnsiColor(XtermWidget xw,
def.green,
def.blue,
def.pixel));
+#if OPT_COLOR_RES
if (!res->mode)
result = 0;
res->mode = True;
+#endif
}
} else {
TRACE(("AllocateAnsiColor %s (failed)\n", spec));
@@ -2943,6 +3067,7 @@ AllocateAnsiColor(XtermWidget xw,
return (result);
}
+#if OPT_COLOR_RES
Pixel
xtermGetColorRes(XtermWidget xw, ColorRes * res)
{
@@ -2970,6 +3095,7 @@ xtermGetColorRes(XtermWidget xw, ColorRes * res)
}
return result;
}
+#endif
static int
ChangeOneAnsiColor(XtermWidget xw, int color, const char *name)
@@ -3108,15 +3234,16 @@ ResetAnsiColorRequest(XtermWidget xw, char *buf, int start)
return repaint;
}
#else
-#define allocateClosestRGB(xw, def) 0
+#define allocateClosestRGB(xw, cmap, def) 0
+#define allocateExactRGB(xw, cmap, def) XAllocColor(TScreenOf(xw)->display, cmap, def)
#endif /* OPT_ISO_COLORS */
Boolean
allocateBestRGB(XtermWidget xw, XColor *def)
{
- (void) xw;
- (void) def;
- return AllocOneColor(xw, def) || allocateClosestRGB(xw, def);
+ Colormap cmap = xw->core.colormap;
+
+ return allocateExactRGB(xw, cmap, def) || allocateClosestRGB(xw, cmap, def);
}
static Boolean
@@ -3129,7 +3256,7 @@ xtermAllocColor(XtermWidget xw, XColor *def, const char *spec)
if (have == 0 || have > MAX_U_STRING) {
if (resource.reportColors) {
- printf("color (ignored, length %lu)\n", (unsigned long) have);
+ printf("color (ignored, length %lu)\n", have);
}
} else if (XParseColor(screen->display, cmap, spec, def)) {
XColor save_def = *def;
@@ -3166,7 +3293,7 @@ int
xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue)
{
int result = -1;
-#if OPT_ISO_COLORS
+#if OPT_COLOR_RES && OPT_ISO_COLORS
int n;
int best_index = -1;
unsigned long best_value = 0;
@@ -3201,7 +3328,6 @@ xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue)
}
TRACE(("...best match at %d with diff %lx\n", best_index, best_value));
result = best_index;
-
#else
(void) xw;
(void) find_red;
@@ -3215,48 +3341,19 @@ xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue)
int
getDirectColor(XtermWidget xw, int red, int green, int blue)
{
- Pixel result = 0;
-
-#define getRGB(name,shift) \
- do { \
- Pixel value = (Pixel) name & 0xff; \
- if (xw->rgb_widths[shift] < 8) { \
- value >>= (int) (8 - xw->rgb_widths[shift]); \
- } \
- value <<= xw->rgb_shifts[shift]; \
- value &= xw->visInfo->name ##_mask; \
- result |= value; \
- } while (0)
-
- getRGB(red, 0);
- getRGB(green, 1);
- getRGB(blue, 2);
-
-#undef getRGB
-
+#define nRGB(name,shift) \
+ ((unsigned long)(name << xw->rgb_shifts[shift]) \
+ & xw->visInfo->name ##_mask)
+ MyPixel result = (MyPixel) (nRGB(red, 0) | nRGB(green, 1) | nRGB(blue, 2));
return (int) result;
}
static void
formatDirectColor(char *target, XtermWidget xw, unsigned value)
{
- Pixel result[3];
-
-#define getRGB(name, shift) \
- do { \
- result[shift] = value & xw->visInfo->name ## _mask; \
- result[shift] >>= xw->rgb_shifts[shift]; \
- if (xw->rgb_widths[shift] < 8) \
- result[shift] <<= (int) (8 - xw->rgb_widths[shift]); \
- } while(0)
-
- getRGB(red, 0);
- getRGB(green, 1);
- getRGB(blue, 2);
-
-#undef getRGB
-
- sprintf(target, "%lu:%lu:%lu", result[0], result[1], result[2]);
+#define fRGB(name, shift) \
+ (value & xw->visInfo->name ## _mask) >> xw->rgb_shifts[shift]
+ sprintf(target, "%lu:%lu:%lu", fRGB(red, 0), fRGB(green, 1), fRGB(blue, 2));
}
#endif /* OPT_DIRECT_COLOR */
@@ -3600,6 +3697,7 @@ ReportColorRequest(XtermWidget xw, int ndx, int final)
if (AllowColorOps(xw, ecGetColor)) {
XColor color;
+ Colormap cmap = xw->core.colormap;
char buffer[80];
/*
@@ -3611,7 +3709,7 @@ ReportColorRequest(XtermWidget xw, int ndx, int final)
GetOldColors(xw);
color.pixel = xw->work.oldColors->colors[ndx];
- (void) QueryOneColor(xw, &color);
+ XQueryColor(TScreenOf(xw)->display, cmap, &color);
sprintf(buffer, "%d;rgb:%04x/%04x/%04x", i + 10,
color.red,
color.green,
@@ -3752,6 +3850,8 @@ ResetColorsRequest(XtermWidget xw,
(void) code;
TRACE(("ResetColorsRequest code=%d\n", code));
+
+#if OPT_COLOR_RES
if (GetOldColors(xw)) {
ScrnColors newColors;
const char *thisName;
@@ -3777,6 +3877,7 @@ ResetColorsRequest(XtermWidget xw,
}
result = True;
}
+#endif
return result;
}
@@ -6974,9 +7075,7 @@ die_callback(Widget w GCC_UNUSED,
XtPointer client_data GCC_UNUSED,
XtPointer call_data GCC_UNUSED)
{
- TRACE(("die_callback client=%p, call=%p\n",
- (void *) client_data,
- (void *) call_data));
+ TRACE(("die_callback %p\n", die_callback));
TRACE_SM_PROPS();
NormalExit();
}
@@ -7186,7 +7285,7 @@ findFontParams(int argc, char **argv)
}
static int
-insertFontParams(XtermWidget xw, int *targetp, Bool first)
+insertFontParams(XtermWidget xw, int *targetp, Boolean first)
{
int changed = 0;
int n;
diff --git a/app/xterm/ptyx.h b/app/xterm/ptyx.h
index 037f4ae55..e392dc9fa 100644
--- a/app/xterm/ptyx.h
+++ b/app/xterm/ptyx.h
@@ -552,6 +552,10 @@ typedef enum {
#define OPT_COLOR_CLASS 1 /* true if xterm uses separate color-resource classes */
#endif
+#ifndef OPT_COLOR_RES
+#define OPT_COLOR_RES 1 /* true if xterm delays color-resource evaluation */
+#endif
+
#ifndef OPT_DABBREV
#define OPT_DABBREV 0 /* dynamic abbreviations */
#endif
diff --git a/app/xterm/util.c b/app/xterm/util.c
index b5e43debd..eca80336f 100644
--- a/app/xterm/util.c
+++ b/app/xterm/util.c
@@ -2953,7 +2953,7 @@ getXftColor(XtermWidget xw, Pixel pixel)
if (!found) {
i = oldest;
color.pixel = pixel;
- (void) QueryOneColor(xw, &color);
+ XQueryColor(TScreenOf(xw)->display, xw->core.colormap, &color);
cache[i].color.color.red = color.red;
cache[i].color.color.green = color.green;
cache[i].color.color.blue = color.blue;
@@ -5075,10 +5075,10 @@ getXtermForeground(XtermWidget xw, unsigned attr_flags, int color)
&& ((color >= 0)
|| (result != (Pixel) color))) {
XColor work;
- last_in = result;
work.pixel = result;
- if (QueryOneColor(xw, &work)) {
- DIM_IT(red);
+ last_in = result;
+ if (XQueryColor(TScreenOf(xw)->display, xw->core.colormap, &work)) {
+ DIM_IT(red);
DIM_IT(green);
DIM_IT(blue);
if (allocateBestRGB(xw, &work)) {
diff --git a/app/xterm/xterm.h b/app/xterm/xterm.h
index 468294a99..a91b26a47 100644
--- a/app/xterm/xterm.h
+++ b/app/xterm/xterm.h
@@ -1180,7 +1180,7 @@ extern Window WMFrameWindow (XtermWidget /* xw */);
extern XtInputMask xtermAppPending (void);
extern XrmOptionDescRec * sortedOptDescs (XrmOptionDescRec *, Cardinal);
extern XtermWidget getXtermWidget (Widget /* w */);
-extern XVisualInfo *getVisualInfo (XtermWidget /* xw */);
+extern int getVisualInfo (XtermWidget /* xw */);
extern char *udk_lookup (XtermWidget /* xw */, int /* keycode */, int * /* len */);
extern char *xtermEnvEncoding (void);
extern char *xtermFindShell (char * /* leaf */, Bool /* warning */);