xglcomp

diff src/main.cc @ 2:876efea9424c

OpenGL
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 22 Jan 2016 06:31:03 +0200
parents b2b7cb950c28
children e831d38e6faa
line diff
     1.1 --- a/src/main.cc	Thu Jan 21 22:50:10 2016 +0200
     1.2 +++ b/src/main.cc	Fri Jan 22 06:31:03 2016 +0200
     1.3 @@ -6,16 +6,21 @@
     1.4  #include <X11/Xatom.h>
     1.5  #include <X11/extensions/Xcomposite.h>
     1.6  #include <X11/extensions/Xdamage.h>
     1.7 -#include <GL/glew.h>
     1.8  #include "cwin.h"
     1.9 +#include "opengl.h"
    1.10  #include "logger.h"
    1.11  
    1.12  static bool register_compositor();
    1.13 +static void start_comp();
    1.14 +static void manage_window(Window xwin);
    1.15 +static void unmanage_window(Window xwin);
    1.16 +static void redraw();
    1.17 +static void reshape(int x, int y);
    1.18  
    1.19 -static Display *dpy;
    1.20 -static int scr;
    1.21 -static Window root_win;
    1.22 -static int root_width, root_height;
    1.23 +Display *dpy;
    1.24 +int screen_num;
    1.25 +Window root_win, comp_win;
    1.26 +int root_width, root_height;
    1.27  
    1.28  int main(int argc, char **argv)
    1.29  {
    1.30 @@ -23,21 +28,23 @@
    1.31  		log_error("failed to open X display\n");
    1.32  		return 1;
    1.33  	}
    1.34 -	scr = DefaultScreen(dpy);
    1.35 -	root_win = RootWindow(dpy, scr);
    1.36 -	root_width = DisplayWidth(dpy, scr);
    1.37 -	root_height = DisplayHeight(dpy, scr);
    1.38 +	screen_num = DefaultScreen(dpy);
    1.39 +	root_win = RootWindow(dpy, screen_num);
    1.40 +	root_width = DisplayWidth(dpy, screen_num);
    1.41 +	root_height = DisplayHeight(dpy, screen_num);
    1.42  	log_info("display size %dx%d\n", root_width, root_height);
    1.43  
    1.44 -	int xcomp_ev_base, xcomp_err_base, xcomp_ver_major, xcomp_ver_minor;
    1.45 +	int xcomp_ev_base, xcomp_err_base;
    1.46  	if(!XCompositeQueryExtension(dpy, &xcomp_ev_base, &xcomp_err_base)) {
    1.47  		log_error("X server doesn't support the composite extension\n");
    1.48  		return 1;
    1.49  	}
    1.50 +	int xcomp_ver_major = 0, xcomp_ver_minor = 4;
    1.51  	XCompositeQueryVersion(dpy, &xcomp_ver_major, &xcomp_ver_minor);
    1.52  	log_info("Found composite extension version %d.%d\n", xcomp_ver_major, xcomp_ver_minor);
    1.53 -	if(xcomp_ver_major <= 10 && xcomp_ver_minor < 2) {
    1.54 -		log_error("I need at least version 1.2\n");	// for NameWindowPixmap
    1.55 +	if(xcomp_ver_major <= 0 && xcomp_ver_minor < 3) {
    1.56 +		// for NameWindowPixmap & CompositeGetoverlayWindow
    1.57 +		log_error("I need at least version 0.3\n");
    1.58  		return 1;
    1.59  	}
    1.60  
    1.61 @@ -52,21 +59,65 @@
    1.62  		return 1;
    1.63  	}
    1.64  
    1.65 -	XGrabServer(dpy);
    1.66 -	XCompositeRedirectSubwindows(dpy, root_win, CompositeRedirectAutomatic);
    1.67 -	XUngrabServer(dpy);
    1.68 +	comp_win = XCompositeGetOverlayWindow(dpy, root_win);
    1.69 +	if(!create_gl(comp_win)) {
    1.70 +		return 1;
    1.71 +	}
    1.72 +
    1.73 +	start_comp();
    1.74 +	reshape(root_width, root_height);
    1.75 +	redraw();
    1.76  
    1.77  	for(;;) {
    1.78  		XEvent ev;
    1.79  		XNextEvent(dpy, &ev);
    1.80 -		// TODO
    1.81 +
    1.82 +		switch(ev.type) {
    1.83 +		case CreateNotify:
    1.84 +			manage_window(ev.xcreatewindow.window);
    1.85 +			break;
    1.86 +
    1.87 +		case ConfigureNotify:
    1.88 +			break;
    1.89 +
    1.90 +		case DestroyNotify:
    1.91 +			unmanage_window(ev.xdestroywindow.window);
    1.92 +			break;
    1.93 +
    1.94 +		case MapNotify:
    1.95 +			break;
    1.96 +		case UnmapNotify:
    1.97 +			break;
    1.98 +
    1.99 +		case ReparentNotify:
   1.100 +			if(ev.xreparent.parent == root_win) {
   1.101 +				manage_window(ev.xreparent.window);
   1.102 +			} else {
   1.103 +				unmanage_window(ev.xreparent.window);
   1.104 +			}
   1.105 +			break;
   1.106 +
   1.107 +		case CirculateNotify:
   1.108 +			break;
   1.109 +
   1.110 +		case Expose:
   1.111 +			if(ev.xexpose.window == root_win) {
   1.112 +				log_debug("expose\n");
   1.113 +				// TODO
   1.114 +			}
   1.115 +			break;
   1.116 +
   1.117 +		default:
   1.118 +			if(ev.type == xdmg_ev_base + XDamageNotify) {
   1.119 +			}
   1.120 +		}
   1.121  	}
   1.122  }
   1.123  
   1.124  static bool register_compositor()
   1.125  {
   1.126  	char atom_name[64];
   1.127 -	sprintf(atom_name, "_NET_WM_CM_S%d", scr);
   1.128 +	sprintf(atom_name, "_NET_WM_CM_S%d", screen_num);
   1.129  	Atom xa_wm_cm = XInternAtom(dpy, atom_name, False);
   1.130  
   1.131  	Window win = XGetSelectionOwner(dpy, xa_wm_cm);
   1.132 @@ -79,3 +130,76 @@
   1.133  	XSetSelectionOwner(dpy, xa_wm_cm, win, 0);
   1.134  	return true;
   1.135  }
   1.136 +
   1.137 +static void start_comp()
   1.138 +{
   1.139 +	XGrabServer(dpy);
   1.140 +	XCompositeRedirectSubwindows(dpy, root_win, CompositeRedirectManual);
   1.141 +	XSelectInput(dpy, root_win, SubstructureNotifyMask | ExposureMask | StructureNotifyMask);
   1.142 +
   1.143 +	// manage all top-level windows
   1.144 +	Window root_ret, parent;
   1.145 +	Window *children;
   1.146 +	unsigned int num_children;
   1.147 +	XQueryTree(dpy, root_win, &root_ret, &parent, &children, &num_children);
   1.148 +
   1.149 +	for(unsigned int i=0; i<num_children; i++) {
   1.150 +		manage_window(children[i]);
   1.151 +	}
   1.152 +	log_info("starting compositor, managing %u top-level windows\n", num_children);
   1.153 +	XFree(children);
   1.154 +
   1.155 +	XUngrabServer(dpy);
   1.156 +}
   1.157 +
   1.158 +static void manage_window(Window xwin)
   1.159 +{
   1.160 +	//log_debug("manage_window %u\n", xwin);
   1.161 +	CompWindow *cwin = new CompWindow(xwin);
   1.162 +	XGetWindowAttributes(dpy, xwin, &cwin->attr);
   1.163 +	add_window(cwin);
   1.164 +}
   1.165 +
   1.166 +static void unmanage_window(Window xwin)
   1.167 +{
   1.168 +	//log_debug("unmanage_window %u\n", xwin);
   1.169 +	CompWindow *cwin = find_window_xid(xwin);
   1.170 +	if(cwin) {
   1.171 +		remove_window(cwin);
   1.172 +		delete cwin;
   1.173 +	}
   1.174 +}
   1.175 +
   1.176 +static void redraw()
   1.177 +{
   1.178 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   1.179 +
   1.180 +	glEnable(GL_BLEND);
   1.181 +	glBlendFunc(GL_ONE, GL_ONE);
   1.182 +
   1.183 +	int num_win = get_window_count();
   1.184 +	for(int i=0; i<num_win; i++) {
   1.185 +		CompWindow *cwin = get_window(i);
   1.186 +
   1.187 +		glBegin(GL_QUADS);
   1.188 +		glColor3f(0.4, 0.1, 0.05);
   1.189 +		glVertex2f(cwin->attr.x, cwin->attr.y);
   1.190 +		glVertex2f(cwin->attr.x + cwin->attr.width, cwin->attr.y);
   1.191 +		glVertex2f(cwin->attr.x + cwin->attr.width, cwin->attr.y + cwin->attr.height);
   1.192 +		glVertex2f(cwin->attr.x, cwin->attr.y + cwin->attr.height);
   1.193 +		glEnd();
   1.194 +	}
   1.195 +
   1.196 +	glDisable(GL_BLEND);
   1.197 +
   1.198 +	glXSwapBuffers(dpy, comp_win);
   1.199 +}
   1.200 +
   1.201 +static void reshape(int x, int y)
   1.202 +{
   1.203 +	glViewport(0, 0, x, y);
   1.204 +
   1.205 +	glMatrixMode(GL_PROJECTION);
   1.206 +	glLoadIdentity();
   1.207 +	glOrtho(0, x, y, 0, -1, 1);
   1.208 +}