shithub: drawterm

Download patch

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)