169 lines
6.2 KiB
Plaintext
169 lines
6.2 KiB
Plaintext
----------------------------------------------------------------------
|
|
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];
|
|
}
|
|
}
|
|
|