# HG changeset patch
# User John Tsiombikas <nuclear@member.fsf.org>
# Date 1454635998 -7200
# Node ID 1c0d056ec360b5231aed1875e30c561619cdc744
# Parent  cb636a23f4f28d1cfac119af7889842d6ab214f5
moving slowly

diff -r cb636a23f4f2 -r 1c0d056ec360 src/cwin.cc
--- a/src/cwin.cc	Thu Feb 04 04:15:15 2016 +0200
+++ b/src/cwin.cc	Fri Feb 05 03:33:18 2016 +0200
@@ -2,6 +2,7 @@
 #include <vector>
 #include <algorithm>
 #include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
 #include <X11/extensions/Xdamage.h>
 #include "cwin.h"
 #include "logger.h"
@@ -14,9 +15,12 @@
 {
 	xwin = xid;
 	xpixmap = 0;
+	pixmap_valid = false;
 	memset(&attr, 0, sizeof attr);
 	mapped = false;
 	damage = 0;
+	damaged = false;
+	tex_valid = false;
 }
 
 CompWindow::~CompWindow()
@@ -29,6 +33,43 @@
 	}
 }
 
+bool CompWindow::update_attr()
+{
+	if(!xwin) return false;
+
+	XGetWindowAttributes(dpy, xwin, &attr);
+	return true;
+}
+
+bool CompWindow::update_pixmap()
+{
+	if(!xwin) return false;
+
+	Pixmap pix = XCompositeNameWindowPixmap(dpy, xwin);
+	if(!pix) {
+		log_error("failed to get window %x pixmap\n", xwin);
+		return false;
+	}
+
+	if(pix != xpixmap) {
+		if(xpixmap) {
+			XFreePixmap(dpy, xpixmap);
+		}
+		xpixmap = pix;
+		tex_valid = false;
+	}
+	pixmap_valid = true;
+	return true;
+}
+
+bool CompWindow::update_texture()
+{
+	if(!xwin || !xpixmap) return false;
+	tex.set_image(dpy, xpixmap);
+	tex_valid = true;
+	return true;
+}
+
 void add_window(CompWindow *cwin)
 {
 	if(have_window(cwin)) {
diff -r cb636a23f4f2 -r 1c0d056ec360 src/cwin.h
--- a/src/cwin.h	Thu Feb 04 04:15:15 2016 +0200
+++ b/src/cwin.h	Fri Feb 05 03:33:18 2016 +0200
@@ -9,17 +9,24 @@
 public:
 	Window xwin;
 	Pixmap xpixmap;
+	bool pixmap_valid;
 
 	XWindowAttributes attr;
 	bool mapped;
 
 	Damage damage;
 	XRectangle damage_rect;
+	bool damaged;
 
 	Texture tex;
+	bool tex_valid;
 
 	CompWindow(Window xid = 0);
 	~CompWindow();
+
+	bool update_attr();
+	bool update_pixmap();
+	bool update_texture();
 };
 
 void add_window(CompWindow *cwin);
diff -r cb636a23f4f2 -r 1c0d056ec360 src/main.cc
--- a/src/main.cc	Thu Feb 04 04:15:15 2016 +0200
+++ b/src/main.cc	Fri Feb 05 03:33:18 2016 +0200
@@ -72,10 +72,9 @@
 			break;
 
 		case ConfigureNotify:
-			// XXX is this right?
 			if((cwin = find_window_xid(ev.xconfigure.window))) {
 				log_debug("updating window attributes for: %x\n", cwin->xwin);
-				XGetWindowAttributes(dpy, cwin->xwin, &cwin->attr);
+				cwin->update_attr();
 			}
 			break;
 
@@ -239,6 +238,7 @@
 	pop_xerr_handler();
 
 	XFixesDestroyRegion(dpy, region);
+	cwin->damaged = true;
 }
 
 static void redraw()
@@ -272,13 +272,11 @@
 
 static void draw_window(CompWindow *cwin)
 {
-	if(!cwin->xpixmap) {
-		cwin->xpixmap = XCompositeNameWindowPixmap(dpy, cwin->xwin);
-		if(!cwin->xpixmap) {
-			log_warning("failed to get pixmap\n");
-			return;
+	if(!cwin->xpixmap || !cwin->pixmap_valid) {
+		cwin->update_pixmap();
+		if(!cwin->tex_valid) {
+			cwin->update_texture();
 		}
-		cwin->tex.set_image(dpy, cwin->xpixmap);
 	}
 
 	glBindTexture(GL_TEXTURE_2D, cwin->tex.get_id());
@@ -294,6 +292,8 @@
 	glTexCoord2f(0, 1);
 	glVertex2f(cwin->attr.x, cwin->attr.y + cwin->attr.height);
 	glEnd();
+
+	cwin->damaged = false;
 }
 
 static void reshape(int x, int y)
diff -r cb636a23f4f2 -r 1c0d056ec360 src/xerr.cc
--- a/src/xerr.cc	Thu Feb 04 04:15:15 2016 +0200
+++ b/src/xerr.cc	Fri Feb 05 03:33:18 2016 +0200
@@ -6,14 +6,17 @@
 #include "xerr.h"
 #include "logger.h"
 
-static int _XPrintDefaultError( Display *dpy, XErrorEvent *event, FILE *fp);
+static int _XPrintDefaultError( Display *dpy, XErrorEvent *event);
 
 static std::stack<xerr_handler_type> func_stack;
 
 void push_xerr_handler(xerr_handler_type func)
 {
+	xerr_handler_type prev = XSetErrorHandler(func);
+	if(func_stack.empty()) {
+		func_stack.push(prev);
+	}
 	func_stack.push(func);
-	XSetErrorHandler(func);
 }
 
 void pop_xerr_handler()
@@ -29,7 +32,7 @@
 
 int xerr_debug(Display *dpy, XErrorEvent *err)
 {
-	_XPrintDefaultError(dpy, err, stderr);
+	_XPrintDefaultError(dpy, err);
 	return 0;
 }
 
@@ -40,7 +43,7 @@
 
 typedef struct _XExten _XExtension;
 
-static int _XPrintDefaultError( Display *dpy, XErrorEvent *event, FILE *fp)
+static int _XPrintDefaultError(Display *dpy, XErrorEvent *event)
 {
 	char buffer[BUFSIZ];
 	char mesg[BUFSIZ];
@@ -51,10 +54,10 @@
 
 	XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
 	XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
-	(void) fprintf(fp, "%s:  %s\n  ", mesg, buffer);
+	log_error("%s:  %s\n  ", mesg, buffer);
 	XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
 			mesg, BUFSIZ);
-	(void) fprintf(fp, mesg, event->request_code);
+	log_error(mesg, event->request_code);
 	if (event->request_code < 128) {
 		sprintf(number, "%d", event->request_code);
 		XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
@@ -69,18 +72,18 @@
 		} else
 			buffer[0] = '\0';
 	}
-	(void) fprintf(fp, " (%s)\n", buffer);
+	log_error(" (%s)\n", buffer);
 	if (event->request_code >= 128) {
 		XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
 				mesg, BUFSIZ);
-		fputs("  ", fp);
-		(void) fprintf(fp, mesg, event->minor_code);
+		log_error("  ");
+		log_error(mesg, event->minor_code);
 		if (ext) {
 			sprintf(mesg, "%s.%d", ext->name, event->minor_code);
 			XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
-			(void) fprintf(fp, " (%s)", buffer);
+			log_error(" (%s)", buffer);
 		}
-		fputs("\n", fp);
+		log_error("\n");
 	}
 	if (event->error_code >= 128) {
 		/* kludge, try to find the extension that caused it */
@@ -105,14 +108,14 @@
 			strcpy(buffer, "Value");
 		XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
 		if (mesg[0]) {
-			fputs("  ", fp);
-			(void) fprintf(fp, mesg, event->resourceid);
-			fputs("\n", fp);
+			log_error("  ");
+			log_error(mesg, event->resourceid);
+			log_error("\n");
 		}
 		/* let extensions try to print the values */
 		for (ext = dpy->ext_procs; ext; ext = ext->next) {
 			if (ext->error_values)
-				(*ext->error_values)(dpy, event, fp);
+				(*ext->error_values)(dpy, event, stderr);
 		}
 	} else if ((event->error_code == BadWindow) ||
 			(event->error_code == BadPixmap) ||
@@ -133,19 +136,19 @@
 		else
 			XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
 					mesg, BUFSIZ);
-		fputs("  ", fp);
-		(void) fprintf(fp, mesg, event->resourceid);
-		fputs("\n", fp);
+		log_error("  ");
+		log_error(mesg, event->resourceid);
+		log_error("\n");
 	}
 	XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
 			mesg, BUFSIZ);
-	fputs("  ", fp);
-	(void) fprintf(fp, mesg, event->serial);
+	log_error("  ");
+	log_error(mesg, event->serial);
 	XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
 			mesg, BUFSIZ);
-	fputs("\n  ", fp);
-	(void) fprintf(fp, mesg, dpy->request);
-	fputs("\n", fp);
+	log_error("\n  ");
+	log_error(mesg, dpy->request);
+	log_error("\n");
 	if (event->error_code == BadImplementation) return 0;
 	return 1;
 }