ref: 001c653ef2089aef37c84617a6baeb25a0137335
parent: 65e8a26e1dac4a0f589f615126ad87a92c9c11ab
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 26 08:13:22 EST 2022
x11: Fix colormap allocation When the Visual is not the default visual, we must not use the DefaultColormap() from the default visual, but allocate our own.
--- a/gui-x11/x11.c
+++ b/gui-x11/x11.c
@@ -74,12 +74,12 @@
else
offset = r.min.x&(31/d);
r.min.x -= offset;
-
+
assert(wordsperline(r, m->depth) <= m->width);
xi = XCreateImage(xdisplay, xvis, m->depth==32?24:m->depth, ZPixmap, 0,
(char*)m->data->bdata, Dx(r), Dy(r), 32, m->width*sizeof(ulong));
-
+
if(xi == nil){
freememimage(m);
return nil;
@@ -114,7 +114,7 @@
static Colormap xcmap; /* Default shared colormap */
/* for copy/paste, lifted from plan9ports */
-static Atom clipboard;
+static Atom clipboard;
static Atom utf8string;
static Atom targets;
static Atom text;
@@ -131,7 +131,7 @@
static void xdestroy(XEvent*);
static void xselect(XEvent*, XDisplay*);
static void xproc(void*);
-static void initmap(Window);
+static void initmap(XDisplay*, int, Visual*);
static GC creategc(Drawable);
static void graphicscmap(XColor*);
static int xscreendepth;
@@ -141,7 +141,6 @@
static int putsnarf, assertsnarf;
Memimage *gscreen;
-Screeninfo screen;
static int
shutup(XDisplay *d, XErrorEvent *e)
@@ -178,7 +177,7 @@
for(y=r.min.y; y<r.max.y; y++)
for(x=r.min.x, p=byteaddr(gscreen, Pt(x,y)); x<r.max.x; x++, p++)
*p = plan9tox11[*p];
-
+
XPutImage(xdisplay, xscreenid, xgccopy, xscreenimage, r.min.x, r.min.y, r.min.x, r.min.y, Dx(r), Dy(r));
if(xtblbit && gscreen->chan == CMAP8)
@@ -195,12 +194,10 @@
{
int i, n, x, y;
char *argv[2];
- Window rootwin;
Rectangle r;
XWMHints hints;
- XScreen *screen;
XVisualInfo xvi;
- int rootscreennum;
+ int screen;
XTextProperty name;
XClassHint classhints;
XSizeHints normalhints;
@@ -234,24 +231,22 @@
if(xsnarfcon == 0)
panic("XOpenDisplay: %r [DISPLAY=%s]", getenv("DISPLAY"));
- rootscreennum = DefaultScreen(xdisplay);
- rootwin = DefaultRootWindow(xdisplay);
-
- xscreendepth = DefaultDepth(xdisplay, rootscreennum);
- if(XMatchVisualInfo(xdisplay, rootscreennum, 16, TrueColor, &xvi)
- || XMatchVisualInfo(xdisplay, rootscreennum, 16, DirectColor, &xvi)){
+ screen = DefaultScreen(xdisplay);
+ xscreendepth = DefaultDepth(xdisplay, screen);
+ if(XMatchVisualInfo(xdisplay, screen, 16, TrueColor, &xvi)
+ || XMatchVisualInfo(xdisplay, screen, 16, DirectColor, &xvi)){
xvis = xvi.visual;
xscreendepth = 16;
xtblbit = 1;
}
- else if(XMatchVisualInfo(xdisplay, rootscreennum, 24, TrueColor, &xvi)
- || XMatchVisualInfo(xdisplay, rootscreennum, 24, DirectColor, &xvi)){
+ else if(XMatchVisualInfo(xdisplay, screen, 24, TrueColor, &xvi)
+ || XMatchVisualInfo(xdisplay, screen, 24, DirectColor, &xvi)){
xvis = xvi.visual;
xscreendepth = 24;
xtblbit = 1;
}
- else if(XMatchVisualInfo(xdisplay, rootscreennum, 8, PseudoColor, &xvi)
- || XMatchVisualInfo(xdisplay, rootscreennum, 8, StaticColor, &xvi)){
+ else if(XMatchVisualInfo(xdisplay, screen, 8, PseudoColor, &xvi)
+ || XMatchVisualInfo(xdisplay, screen, 8, StaticColor, &xvi)){
if(xscreendepth > 8)
panic("can't deal with colormapped depth %d screens", xscreendepth);
xvis = xvi.visual;
@@ -260,7 +255,7 @@
else{
if(xscreendepth != 8)
panic("can't deal with depth %d screens", xscreendepth);
- xvis = DefaultVisual(xdisplay, rootscreennum);
+ xvis = DefaultVisual(xdisplay, screen);
}
/*
@@ -299,40 +294,34 @@
}
if(xscreenchan == 0)
panic("unknown screen pixel format");
-
- screen = DefaultScreenOfDisplay(xdisplay);
- xcmap = DefaultColormapOfScreen(screen);
- if(xvis->class != StaticColor){
- graphicscmap(map);
- initmap(rootwin);
- }
+ initmap(xdisplay, screen, xvis);
x = y = 0;
r = ZR;
if(geometry != nil)
- XParseGeometry(geometry, &x, &y, &r.max.x, &r.max.y);
+ XParseGeometry(geometry, &x, &y, (unsigned int*)&r.max.x, (unsigned int*)&r.max.y);
+
if(r.max.x == 0)
- r.max.x = WidthOfScreen(screen)*3/4;
+ r.max.x = WidthOfScreen(ScreenOfDisplay(xdisplay, screen))*3/4;
if(r.max.y == 0)
- r.max.y = HeightOfScreen(screen)*3/4;
-
+ r.max.y = HeightOfScreen(ScreenOfDisplay(xdisplay, screen))*3/4;
+
attrs.colormap = xcmap;
attrs.background_pixel = 0;
attrs.border_pixel = 0;
/* attrs.override_redirect = 1;*/ /* WM leave me alone! |CWOverrideRedirect */
- xdrawable = XCreateWindow(xkmcon, rootwin, x, y, Dx(r), Dy(r), 0,
+ xdrawable = XCreateWindow(xkmcon, RootWindow(xdisplay, screen), x, y, Dx(r), Dy(r), 0,
xscreendepth, InputOutput, xvis, CWBackPixel|CWBorderPixel|CWColormap, &attrs);
/* load the given bitmap data and create an X pixmap containing it. */
- icon_pixmap = XCreateBitmapFromData(xkmcon,
- rootwin, (char *)glenda_t_bits,
- glenda_t_width, glenda_t_height);
+ icon_pixmap = XCreateBitmapFromData(xkmcon, RootWindow(xdisplay, screen),
+ (char *)glenda_t_bits, glenda_t_width, glenda_t_height);
/*
* set up property as required by ICCCM
*/
- if((name.value = getenv("WM_NAME")) == nil)
+ if((name.value = (uchar*)getenv("WM_NAME")) == nil)
name.value = (uchar*)"drawterm";
name.encoding = XA_STRING;
name.format = 8;
@@ -370,7 +359,7 @@
1); /* int nelements */
XFlush(xkmcon);
}
-
+
/*
* put the window on the screen
*/
@@ -618,9 +607,9 @@
/*
* Initialize and install the drawterm colormap as a private colormap for this
* application. Drawterm gets the best colors here when it has the cursor focus.
- */
-static void
-initmap(Window w)
+ */
+static void
+initmap(XDisplay *xdisplay, int screen, Visual *xvis)
{
XColor c;
int i;
@@ -627,6 +616,11 @@
ulong p, pp;
char buf[30];
+ xcmap = DefaultColormap(xdisplay, screen);
+ if(xvis->class == StaticColor)
+ return;
+
+ graphicscmap(map);
if(xscreendepth <= 1)
return;
@@ -634,16 +628,15 @@
/* The pixel value returned from XGetPixel needs to
* be converted to RGB so we can call rgb2cmap()
* to translate between 24 bit X and our color. Unfortunately,
- * the return value appears to be display server endian
+ * the return value appears to be display server endian
* dependant. Therefore, we run some heuristics to later
* determine how to mask the int value correctly.
- * Yeah, I know we can look at xvis->byte_order but
+ * Yeah, I know we can look at xvis->byte_order but
* some displays say MSB even though they run on LSB.
* Besides, this is more anal.
*/
- if(xscreendepth != DefaultDepth(xdisplay, DefaultScreen(xdisplay)))
- xcmap = XCreateColormap(xdisplay, w, xvis, AllocNone);
-
+ if(xvis != DefaultVisual(xdisplay, screen))
+ xcmap = XCreateColormap(xdisplay, RootWindow(xdisplay, screen), xvis, AllocNone);
c = map[19];
/* find out index into colormap for our RGB */
if(!XAllocColor(xdisplay, xcmap, &c))
@@ -664,7 +657,7 @@
xscreenchan = XBGR32;
break;
default:
- panic("don't know how to byteswap channel %s",
+ panic("don't know how to byteswap channel %s",
chantostr(buf, xscreenchan));
break;
}
@@ -672,7 +665,7 @@
} else if(xvis->class == TrueColor || xvis->class == DirectColor) {
} else if(xvis->class == PseudoColor) {
if(xtblbit == 0){
- xcmap = XCreateColormap(xdisplay, w, xvis, AllocAll);
+ xcmap = XCreateColormap(xdisplay, RootWindow(xdisplay, screen), xvis, AllocAll);
XStoreColors(xdisplay, xcmap, map, 256);
for(i = 0; i < 256; i++) {
plan9tox11[i] = i;
@@ -859,7 +852,7 @@
case XK_KP_End:
k = Kend;
break;
- case XK_Page_Up:
+ case XK_Page_Up:
case XK_KP_Page_Up:
k = Kpgup;
break;
@@ -959,7 +952,7 @@
switch(e->type){
case ButtonPress:
be = (XButtonEvent *)e;
- /*
+ /*
* Fake message, just sent to make us announce snarf.
* Apparently state and button are 16 and 8 bits on
* the wire, since they are truncated by the time they
@@ -1045,7 +1038,7 @@
getcolor(ulong i, ulong *r, ulong *g, ulong *b)
{
ulong v;
-
+
v = cmap2rgb(i);
*r = (v>>16)&0xFF;
*g = (v>>8)&0xFF;
@@ -1118,7 +1111,7 @@
data = nil;
goto out;
}
-
+
/*
* We should be waiting for SelectionNotify here, but it might never
* come, and we have no way to time out. Instead, we will clear
@@ -1144,7 +1137,7 @@
}
/* get the property */
data = nil;
- XGetWindowProperty(xd, xdrawable, prop, 0, SnarfSize/sizeof(unsigned long), 0,
+ XGetWindowProperty(xd, xdrawable, prop, 0, SnarfSize/sizeof(unsigned long), 0,
AnyPropertyType, &type, &fmt, &len, &dummy, &xdata);
if((type != XA_STRING && type != utf8string) || len == 0){
if(xdata)