diff options
| -rw-r--r-- | xcman.c | 105 | 
1 files changed, 40 insertions, 65 deletions
| @@ -49,11 +49,13 @@ static size_t n_ignores = 0, size_ignores = 0;  static Display *dpy;  static int screen;  static Window root; +static XRenderPictFormat *visual_format;  static int root_height, root_width;  static int damage_error, xfixes_error, render_error;  static int damage_event, xshape_event;  static int composite_opcode; -static Atom opacity_atom; +static Atom opacity_atom, background_atom1, background_atom2, pixmap_atom; +static Atom *background_atoms[] = {&background_atom1, &background_atom2};  static XRenderColor alpha_colour = {.red = 0, .green = 0, .blue = 0};  static struct window *window_list; @@ -63,8 +65,6 @@ static Picture root_tile;  static XserverRegion all_damage;  static int clip_changed; -static const char *background_properties[] = {"_XROOTPMAP_ID", "_XSETROOT_ID", NULL}; -  static void  usage(const char *program)  { @@ -132,22 +132,18 @@ find_window(Window id)  static Picture  make_root_tile(void)  { -	Picture picture; +	Picture picture, pixmap;  	Atom actual_type; -	Pixmap pixmap; -	int actual_format; -	unsigned long int nitems; -	unsigned long int bytes_after; +	int i, actual_format, fill; +	unsigned long int nitems, bytes_after;  	unsigned char *prop; -	int fill;  	XRenderPictureAttributes pa; -	int i;  	pixmap = None; -	for (i = 0; background_properties[i]; i++) { -		if (!XGetWindowProperty(dpy, root, XInternAtom(dpy, background_properties[i], 0), 0, 4, 0, AnyPropertyType, +	for (i = 0; i < 2; i++) { +		if (!XGetWindowProperty(dpy, root, *(background_atoms[i]), 0, 4, 0, AnyPropertyType,  				        &actual_type, &actual_format, &nitems, &bytes_after, &prop) && -		    actual_type == XInternAtom(dpy, "PIXMAP", 0) && actual_format == 32 && nitems == 1) { +		    actual_type == pixmap_atom && actual_format == 32 && nitems == 1) {  			memcpy(&pixmap, prop, 4);  			XFree(prop);  			fill = 0; @@ -159,7 +155,7 @@ make_root_tile(void)  		fill = 1;  	}  	pa.repeat = 1; -	picture = XRenderCreatePicture(dpy, pixmap, XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)), CPRepeat, &pa); +	picture = XRenderCreatePicture(dpy, pixmap, visual_format, CPRepeat, &pa);  	if (fill) {  		alpha_colour.alpha = 0xFFFF;  		XRenderFillRectangle(dpy, PictOpSrc, picture, &alpha_colour, 0, 0, 1, 1); @@ -207,7 +203,7 @@ paint_all(XserverRegion region)  	}  	if (!root_buffer) {  		rootPixmap = XCreatePixmap(dpy, root, root_width, root_height, DefaultDepth(dpy, screen)); -		root_buffer = XRenderCreatePicture(dpy, rootPixmap, XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)), 0, NULL); +		root_buffer = XRenderCreatePicture(dpy, rootPixmap, visual_format, 0, NULL);  		XFreePixmap(dpy, rootPixmap);  	}  	XFixesSetPictureClipRegion(dpy, root_picture, 0, 0, region); @@ -312,7 +308,7 @@ get_opacity_prop(struct window *w, unsigned int def)  	int err = XGetWindowProperty(dpy, w->id, opacity_atom, 0L, 1L, 0, XA_CARDINAL, &actual, &format, &n, &left, &data);  	if (!err && data) {  		i = *(uint32_t *)data; -		XFree((void *)data); +		XFree(data);  		return i;  	}  	return def; @@ -323,18 +319,14 @@ determine_mode(struct window *w)  {  	XRenderPictFormat *format;  	XserverRegion damage; -  	if (w->alpha_picture) {  		XRenderFreePicture(dpy, w->alpha_picture);  		w->alpha_picture = None;  	} -  	w->opacity = get_opacity_prop(w, OPAQUE); -  	w->solid = (w->opacity == OPAQUE &&  		    ((format = w->a.class == InputOnly ? NULL : XRenderFindVisualFormat(dpy, w->a.visual)),  		     (!format || format->type != PictTypeDirect || !format->direct.alphaMask))); -  	if (w->extents) {  		damage = XFixesCreateRegion(dpy, NULL, 0);  		XFixesCopyRegion(dpy, damage, w->extents); @@ -348,15 +340,9 @@ map_window(Window id)  	struct window *w = find_window(id);  	if (!w)  		return; -  	w->a.map_state = IsViewable; - -	/* This needs to be here or else we lose transparency messages */ -	XSelectInput(dpy, id, PropertyChangeMask); - -	/* This needs to be here since we don't get PropertyNotify when unmapped */ -	determine_mode(w); - +	XSelectInput(dpy, id, PropertyChangeMask); /* This needs to be here or else we lose transparency messages */ +	determine_mode(w); /* This needs to be here since we don't get PropertyNotify when unmapped */  	w->damaged = 0;  } @@ -364,16 +350,14 @@ static void  finish_unmap_window(struct window *w)  {  	w->damaged = 0; -	if (w->extents != None) { +	if (w->extents) {  		add_damage(w->extents); /* destroys region */  		w->extents = None;  	} -  	if (w->pixmap) {  		XFreePixmap(dpy, w->pixmap);  		w->pixmap = None;  	} -  	if (w->picture) {  		set_ignore(NextRequest(dpy));  		XRenderFreePicture(dpy, w->picture); @@ -432,10 +416,8 @@ add_window(Window id)  static void  restack_window(struct window *w, Window new_above)  { -	Window old_above;  	struct window **prev; - -	old_above = w->next ? w->next->id : None; +	Window old_above = w->next ? w->next->id : None;  	if (old_above != new_above) {  		/* unhook */ @@ -509,13 +491,11 @@ configure_window(XConfigureEvent *ce)  static void  circulate_window(XCirculateEvent *ce)  { -	Window new_above;  	struct window *w = find_window(ce->window); -	if (!w) -		return; -	new_above = ce->place == PlaceOnTop ? window_list->id : None; -	restack_window(w, new_above); -	clip_changed = 1; +	if (w) { +		restack_window(w, ce->place == PlaceOnTop ? window_list->id : None); +		clip_changed = 1; +	}  }  static void @@ -573,10 +553,8 @@ shape_window(XShapeEvent *se)  {  	XserverRegion region0, region1;  	struct window *w = find_window(se->window); -  	if (!w)  		return; -  	if (se->kind == ShapeClip || se->kind == ShapeBounding) {  		clip_changed = 1; @@ -625,16 +603,13 @@ error(Display *display, XErrorEvent *ev)  		case BadGlyphSet:   name = "BadGlyphSet";   break;  		case BadGlyph:      name = "BadGlyph";      break;  		default: +			buffer[0] = '\0'; +			XGetErrorText(display, ev->error_code, buffer, sizeof(buffer)); +			name = buffer;  			break;  		}  	} -	if (!name) { -		buffer[0] = '\0'; -		XGetErrorText(display, ev->error_code, buffer, sizeof(buffer)); -		name = buffer; -	} -  	fprintf(stderr, "error %i: %s request %i minor %i serial %lu\n",  		ev->error_code, (strlen(name) > 0) ? name : "unknown",  		ev->request_code, ev->minor_code, ev->serial); @@ -654,8 +629,8 @@ register_composite_manager(void)  	sprintf(net_wm_cm, "_NET_WM_CM_S%i", screen);  	a = XInternAtom(dpy, net_wm_cm, 0); -  	w = XGetSelectionOwner(dpy, a); +  	if (w != None) {  		winNameAtom = XInternAtom(dpy, "_NET_WM_NAME", 0);  		if (!XGetTextProperty(dpy, w, &tp, winNameAtom) && @@ -670,7 +645,7 @@ register_composite_manager(void)  		exit(1);  	} -	w = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 0, 0, 1, 1, 0, None, None); +	w = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, None, None);  	Xutf8SetWMProperties(dpy, w, "xcman", "xcman", NULL, 0, NULL, NULL, NULL);  	XSetSelectionOwner(dpy, a, w, 0);  } @@ -712,13 +687,17 @@ main(int argc, char **argv)  		eprintf("no XShape extension\n");  	register_composite_manager(); -	opacity_atom = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", 0); +	opacity_atom      = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", 0); +	background_atom1  = XInternAtom(dpy, "_XROOTPMAP_ID", 0); +	background_atom2  = XInternAtom(dpy, "_XSETROOT_ID", 0); +	pixmap_atom       = XInternAtom(dpy, "PIXMAP", 0);  	pa.subwindow_mode = IncludeInferiors; -	root_width = DisplayWidth(dpy, screen); -	root_height = DisplayHeight(dpy, screen); -	root_picture = XRenderCreatePicture(dpy, root, XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)), CPSubwindowMode, &pa); -	all_damage = None; -	clip_changed = 1; +	root_width        = DisplayWidth(dpy, screen); +	root_height       = DisplayHeight(dpy, screen); +	visual_format     = XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)); +	root_picture      = XRenderCreatePicture(dpy, root, visual_format, CPSubwindowMode, &pa); +	all_damage        = None; +	clip_changed      = 1;  	XGrabServer(dpy);  	XCompositeRedirectSubwindows(dpy, root, CompositeRedirectManual);  	XSelectInput(dpy, root, SubstructureNotifyMask | ExposureMask | StructureNotifyMask | PropertyChangeMask); @@ -764,15 +743,11 @@ main(int argc, char **argv)  			if (ev.xproperty.atom == opacity_atom) {  				if ((w = find_window(ev.xproperty.window)))  					determine_mode(w); -			} else if (root_tile) { -				for (i = 0; background_properties[i]; i++) { -					if (ev.xproperty.atom == XInternAtom(dpy, background_properties[i], 0)) { -						XClearArea(dpy, root, 0, 0, 0, 0, 1); -						XRenderFreePicture(dpy, root_tile); -						root_tile = None; -						break; -					} -				} +			} else if (root_tile && (ev.xproperty.atom == background_atom1 || +						 ev.xproperty.atom == background_atom2)) { +				XClearArea(dpy, root, 0, 0, 0, 0, 1); +				XRenderFreePicture(dpy, root_tile); +				root_tile = None;  			}  			break;  		default: | 
