- add patch to improve color map choice in X windows

This commit is contained in:
Bryce Denney 2002-03-19 23:37:00 +00:00
parent cac05ef7fa
commit 5696c05b78

View File

@ -0,0 +1,168 @@
----------------------------------------------------------------------
Patch name: patch.x11-auto-private-colormap
Author: Bryce Denney
Date: Tue Mar 19 18:05:25 EST 2002
Detailed description:
This patch tries to solve the problem of poor color allocation in X
windows. Before this patch, if all the entries of the colormap were
used by other applications, Bochs would not even notice! It would
try to allocate its colors (XAllocColor), the allocation would fail,
and Bochs would display everything using invalid/unpredicatable color
values. This usually leads to black on black, except for a little white
(or yellow, or green, etc.) blinking cursor.
This patch attempts to be a little smarter about colormaps. If the
private_colormap setting is off, it first tests the colormap to check that
at least 16 colormap entries are available (this number was chosen
arbitrarily). If fewer than 16 colors are available, it automatically
turns on private_colormap mode and creates a private colormap. On my
machine at least, which has only a 256-entry colormap and always has
Netscape running, this is a big improvement.
Another potential improvement in private colormap performance would be to set
aside entries 0-15 and use only 16-255, when possible. The colors from the
default colormap can be copied into entries 0-15. The advantage of this
approach is that many things on the screen, such as window titles and borders,
are drawn in colors 0-15. Having those colors identical between the default
and private color map reduces the amount of ugly color blinking that occurs
when the mouse leaves a private colormapped window. I've used this technique
on another X11 application and it worked well. I don't want to try this
unless I understand the circumstances where Bochs needs all 256 colors.
Patch was created with:
cvs diff -u
Apply patch to what version:
current cvs
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
? gui/Makefile
? gui/a
? gui/XStoreBytes.txt
? gui/.x.cc.swp
Index: gui/x.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/gui/x.cc,v
retrieving revision 1.37
diff -u -r1.37 x.cc
--- gui/x.cc 19 Mar 2002 18:43:22 -0000 1.37
+++ gui/x.cc 19 Mar 2002 23:20:00 -0000
@@ -246,13 +246,47 @@
#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
+#define MAX_VGA_COLORS 256
-unsigned long col_vals[256]; // 256 VGA colors
+unsigned long col_vals[MAX_VGA_COLORS]; // 256 VGA colors
unsigned curr_foreground, curr_background;
static unsigned x_tilesize, y_tilesize;
+// Try to allocate NCOLORS at once in the colormap provided. If it can
+// be done, return true. If not, return false. (In either case, free
+// up the color cells so that we don't add to the problem!) This is used
+// to determine whether Bochs should use a private colormap even when the
+// user did not specify it.
+static Boolean
+test_alloc_colors (Colormap cmap, Bit32u n_tries) {
+ XColor color;
+ unsigned long pixel[MAX_VGA_COLORS];
+ Boolean pixel_valid[MAX_VGA_COLORS];
+ Bit32u n_allocated = 0;
+ Bit32u i;
+ color.flags = DoRed | DoGreen | DoBlue;
+ for (i=0; i<n_tries; i++) {
+ // choose wierd color values that are unlikely to already be in the
+ // colormap.
+ color.red = ((i+41)%MAX_VGA_COLORS) << 8;
+ color.green = ((i+42)%MAX_VGA_COLORS) << 8;
+ color.blue = ((i+43)%MAX_VGA_COLORS) << 8;
+ pixel_valid[i] = false;
+ if (XAllocColor (bx_x_display, cmap, &color)) {
+ pixel[i] = color.pixel;
+ pixel_valid[i] = true;
+ n_allocated++;
+ }
+ }
+ BX_INFO (("test_alloc_colors: %d colors available out of %d colors tried", n_allocated, n_tries));
+ // now free them all
+ for (i=0; i<n_tries; i++) {
+ if (pixel_valid[i]) XFreeColors (bx_x_display, cmap, &pixel[i], 1, 0);
+ }
+ return (n_allocated == n_tries);
+}
void
@@ -290,10 +324,6 @@
th->put("XGUI");
UNUSED(th);
-if (bx_options.Oprivate_colormap->get ()) {
- BX_ERROR(( "Oprivate_colormap option not handled yet." ));
- }
-
x_tilesize = tilewidth;
y_tilesize = tileheight;
bx_headerbar_y = headerbar_y;
@@ -347,11 +377,29 @@
default_depth = DefaultDepth(bx_x_display, bx_x_screen_num);
default_visual = DefaultVisual(bx_x_display, bx_x_screen_num);
+ if (!bx_options.Oprivate_colormap->get ()) {
+ default_cmap = DefaultColormap(bx_x_display, bx_x_screen_num);
+ // try to use default colormap. If not enough colors are available,
+ // then switch to private colormap despite the user setting. There
+ // are too many cases when no colors are available and Bochs simply
+ // draws everything in black on black.
+ if (!test_alloc_colors (default_cmap, 16)) {
+ BX_ERROR (("I can't even allocate 16 colors! Switching to a private colormap"));
+ bx_options.Oprivate_colormap->set (1);
+ }
+ col_vals[0] = BlackPixel(bx_x_display, bx_x_screen_num);
+ col_vals[15] = WhitePixel(bx_x_display, bx_x_screen_num);
+ for (i = 1; i < MAX_VGA_COLORS; i++) {
+ if (i==15) continue;
+ col_vals[i] = col_vals[0];
+ }
+ }
+
if (bx_options.Oprivate_colormap->get ()) {
default_cmap = XCreateColormap(bx_x_display, DefaultRootWindow(bx_x_display),
default_visual, AllocNone);
if (XAllocColorCells(bx_x_display, default_cmap, False,
- plane_masks_return, 0, col_vals, 256) == 0) {
+ plane_masks_return, 0, col_vals, MAX_VGA_COLORS) == 0) {
BX_PANIC(("XAllocColorCells returns error."));
}
@@ -360,7 +408,7 @@
color.flags = DoRed | DoGreen | DoBlue;
- for (i=0; i < 256; i++) {
+ for (i=0; i < MAX_VGA_COLORS; i++) {
color.pixel = i;
if (i==15) {
color.red = 0xffff;
@@ -373,15 +421,6 @@
color.blue = 0;
}
XStoreColor(bx_x_display, default_cmap, &color);
- }
- }
- else {
- default_cmap = DefaultColormap(bx_x_display, bx_x_screen_num);
- col_vals[0] = BlackPixel(bx_x_display, bx_x_screen_num);
- col_vals[15] = WhitePixel(bx_x_display, bx_x_screen_num);
- for (i = 1; i < 256; i++) {
- if (i==15) continue;
- col_vals[i] = col_vals[0];
}
}