xglcomp

changeset 2:876efea9424c

OpenGL
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 22 Jan 2016 06:31:03 +0200
parents b2b7cb950c28
children e831d38e6faa
files src/cwin.cc src/cwin.h src/logger.c src/main.cc src/opengl.cc src/opengl.h
diffstat 6 files changed, 228 insertions(+), 22 deletions(-) [+]
line diff
     1.1 --- a/src/cwin.cc	Thu Jan 21 22:50:10 2016 +0200
     1.2 +++ b/src/cwin.cc	Fri Jan 22 06:31:03 2016 +0200
     1.3 @@ -5,6 +5,12 @@
     1.4  
     1.5  static std::vector<CompWindow*> cwinlist;
     1.6  
     1.7 +CompWindow::CompWindow(Window xid)
     1.8 +{
     1.9 +	xwin = xid;
    1.10 +	xpixmap = 0;
    1.11 +}
    1.12 +
    1.13  void add_window(CompWindow *cwin)
    1.14  {
    1.15  	if(have_window(cwin)) {
    1.16 @@ -15,7 +21,7 @@
    1.17  	cwinlist.push_back(cwin);
    1.18  }
    1.19  
    1.20 -bool delete_window(CompWindow *cwin)
    1.21 +bool remove_window(CompWindow *cwin)
    1.22  {
    1.23  	auto it = std::find(cwinlist.begin(), cwinlist.end(), cwin);
    1.24  	if(it != cwinlist.end()) {
     2.1 --- a/src/cwin.h	Thu Jan 21 22:50:10 2016 +0200
     2.2 +++ b/src/cwin.h	Fri Jan 22 06:31:03 2016 +0200
     2.3 @@ -3,15 +3,18 @@
     2.4  
     2.5  #include <X11/Xlib.h>
     2.6  
     2.7 -struct CompWindow {
     2.8 +class CompWindow {
     2.9 +public:
    2.10  	Window xwin;
    2.11  	Pixmap xpixmap;
    2.12  
    2.13 -	struct CompWindow *next, *prev;
    2.14 +	XWindowAttributes attr;
    2.15 +
    2.16 +	CompWindow(Window xid = 0);
    2.17  };
    2.18  
    2.19  void add_window(CompWindow *cwin);
    2.20 -bool delete_window(CompWindow *cwin);
    2.21 +bool remove_window(CompWindow *cwin);
    2.22  bool have_window(CompWindow *cwin);
    2.23  CompWindow *find_window_xid(Window xid);
    2.24  CompWindow *find_window_pixmap(Pixmap pix);
     3.1 --- a/src/logger.c	Thu Jan 21 22:50:10 2016 +0200
     3.2 +++ b/src/logger.c	Fri Jan 22 06:31:03 2016 +0200
     3.3 @@ -3,6 +3,11 @@
     3.4  #include <string.h>
     3.5  #include <errno.h>
     3.6  #include <stdarg.h>
     3.7 +#ifdef _MSC_VER
     3.8 +#include <malloc.h>
     3.9 +#else
    3.10 +#include <alloca.h>
    3.11 +#endif
    3.12  #include "logger.h"
    3.13  
    3.14  #if defined(unix) || defined(__unix__) || defined(__APPLE__)
    3.15 @@ -214,7 +219,16 @@
    3.16  #if defined(unix) || defined(__unix__) || defined(__APPLE__)
    3.17  				if(isatty(fileno(targ->fp)) && type != LOG_INFO) {
    3.18  					int c = typecolor(type);
    3.19 -					fprintf(targ->fp, "\033[%dm%s\033[0m", c, str);
    3.20 +
    3.21 +					int len = strlen(str);
    3.22 +					if(str[len - 1] == '\n') {
    3.23 +						char *s = alloca(len);
    3.24 +						memcpy(s, str, len);
    3.25 +						s[len - 1] = 0;
    3.26 +						fprintf(targ->fp, "\033[%dm%s\033[0m\n", c, s);
    3.27 +					} else {
    3.28 +						fprintf(targ->fp, "\033[%dm%s\033[0m", c, str);
    3.29 +					}
    3.30  				} else
    3.31  #endif
    3.32  				{
     4.1 --- a/src/main.cc	Thu Jan 21 22:50:10 2016 +0200
     4.2 +++ b/src/main.cc	Fri Jan 22 06:31:03 2016 +0200
     4.3 @@ -6,16 +6,21 @@
     4.4  #include <X11/Xatom.h>
     4.5  #include <X11/extensions/Xcomposite.h>
     4.6  #include <X11/extensions/Xdamage.h>
     4.7 -#include <GL/glew.h>
     4.8  #include "cwin.h"
     4.9 +#include "opengl.h"
    4.10  #include "logger.h"
    4.11  
    4.12  static bool register_compositor();
    4.13 +static void start_comp();
    4.14 +static void manage_window(Window xwin);
    4.15 +static void unmanage_window(Window xwin);
    4.16 +static void redraw();
    4.17 +static void reshape(int x, int y);
    4.18  
    4.19 -static Display *dpy;
    4.20 -static int scr;
    4.21 -static Window root_win;
    4.22 -static int root_width, root_height;
    4.23 +Display *dpy;
    4.24 +int screen_num;
    4.25 +Window root_win, comp_win;
    4.26 +int root_width, root_height;
    4.27  
    4.28  int main(int argc, char **argv)
    4.29  {
    4.30 @@ -23,21 +28,23 @@
    4.31  		log_error("failed to open X display\n");
    4.32  		return 1;
    4.33  	}
    4.34 -	scr = DefaultScreen(dpy);
    4.35 -	root_win = RootWindow(dpy, scr);
    4.36 -	root_width = DisplayWidth(dpy, scr);
    4.37 -	root_height = DisplayHeight(dpy, scr);
    4.38 +	screen_num = DefaultScreen(dpy);
    4.39 +	root_win = RootWindow(dpy, screen_num);
    4.40 +	root_width = DisplayWidth(dpy, screen_num);
    4.41 +	root_height = DisplayHeight(dpy, screen_num);
    4.42  	log_info("display size %dx%d\n", root_width, root_height);
    4.43  
    4.44 -	int xcomp_ev_base, xcomp_err_base, xcomp_ver_major, xcomp_ver_minor;
    4.45 +	int xcomp_ev_base, xcomp_err_base;
    4.46  	if(!XCompositeQueryExtension(dpy, &xcomp_ev_base, &xcomp_err_base)) {
    4.47  		log_error("X server doesn't support the composite extension\n");
    4.48  		return 1;
    4.49  	}
    4.50 +	int xcomp_ver_major = 0, xcomp_ver_minor = 4;
    4.51  	XCompositeQueryVersion(dpy, &xcomp_ver_major, &xcomp_ver_minor);
    4.52  	log_info("Found composite extension version %d.%d\n", xcomp_ver_major, xcomp_ver_minor);
    4.53 -	if(xcomp_ver_major <= 10 && xcomp_ver_minor < 2) {
    4.54 -		log_error("I need at least version 1.2\n");	// for NameWindowPixmap
    4.55 +	if(xcomp_ver_major <= 0 && xcomp_ver_minor < 3) {
    4.56 +		// for NameWindowPixmap & CompositeGetoverlayWindow
    4.57 +		log_error("I need at least version 0.3\n");
    4.58  		return 1;
    4.59  	}
    4.60  
    4.61 @@ -52,21 +59,65 @@
    4.62  		return 1;
    4.63  	}
    4.64  
    4.65 -	XGrabServer(dpy);
    4.66 -	XCompositeRedirectSubwindows(dpy, root_win, CompositeRedirectAutomatic);
    4.67 -	XUngrabServer(dpy);
    4.68 +	comp_win = XCompositeGetOverlayWindow(dpy, root_win);
    4.69 +	if(!create_gl(comp_win)) {
    4.70 +		return 1;
    4.71 +	}
    4.72 +
    4.73 +	start_comp();
    4.74 +	reshape(root_width, root_height);
    4.75 +	redraw();
    4.76  
    4.77  	for(;;) {
    4.78  		XEvent ev;
    4.79  		XNextEvent(dpy, &ev);
    4.80 -		// TODO
    4.81 +
    4.82 +		switch(ev.type) {
    4.83 +		case CreateNotify:
    4.84 +			manage_window(ev.xcreatewindow.window);
    4.85 +			break;
    4.86 +
    4.87 +		case ConfigureNotify:
    4.88 +			break;
    4.89 +
    4.90 +		case DestroyNotify:
    4.91 +			unmanage_window(ev.xdestroywindow.window);
    4.92 +			break;
    4.93 +
    4.94 +		case MapNotify:
    4.95 +			break;
    4.96 +		case UnmapNotify:
    4.97 +			break;
    4.98 +
    4.99 +		case ReparentNotify:
   4.100 +			if(ev.xreparent.parent == root_win) {
   4.101 +				manage_window(ev.xreparent.window);
   4.102 +			} else {
   4.103 +				unmanage_window(ev.xreparent.window);
   4.104 +			}
   4.105 +			break;
   4.106 +
   4.107 +		case CirculateNotify:
   4.108 +			break;
   4.109 +
   4.110 +		case Expose:
   4.111 +			if(ev.xexpose.window == root_win) {
   4.112 +				log_debug("expose\n");
   4.113 +				// TODO
   4.114 +			}
   4.115 +			break;
   4.116 +
   4.117 +		default:
   4.118 +			if(ev.type == xdmg_ev_base + XDamageNotify) {
   4.119 +			}
   4.120 +		}
   4.121  	}
   4.122  }
   4.123  
   4.124  static bool register_compositor()
   4.125  {
   4.126  	char atom_name[64];
   4.127 -	sprintf(atom_name, "_NET_WM_CM_S%d", scr);
   4.128 +	sprintf(atom_name, "_NET_WM_CM_S%d", screen_num);
   4.129  	Atom xa_wm_cm = XInternAtom(dpy, atom_name, False);
   4.130  
   4.131  	Window win = XGetSelectionOwner(dpy, xa_wm_cm);
   4.132 @@ -79,3 +130,76 @@
   4.133  	XSetSelectionOwner(dpy, xa_wm_cm, win, 0);
   4.134  	return true;
   4.135  }
   4.136 +
   4.137 +static void start_comp()
   4.138 +{
   4.139 +	XGrabServer(dpy);
   4.140 +	XCompositeRedirectSubwindows(dpy, root_win, CompositeRedirectManual);
   4.141 +	XSelectInput(dpy, root_win, SubstructureNotifyMask | ExposureMask | StructureNotifyMask);
   4.142 +
   4.143 +	// manage all top-level windows
   4.144 +	Window root_ret, parent;
   4.145 +	Window *children;
   4.146 +	unsigned int num_children;
   4.147 +	XQueryTree(dpy, root_win, &root_ret, &parent, &children, &num_children);
   4.148 +
   4.149 +	for(unsigned int i=0; i<num_children; i++) {
   4.150 +		manage_window(children[i]);
   4.151 +	}
   4.152 +	log_info("starting compositor, managing %u top-level windows\n", num_children);
   4.153 +	XFree(children);
   4.154 +
   4.155 +	XUngrabServer(dpy);
   4.156 +}
   4.157 +
   4.158 +static void manage_window(Window xwin)
   4.159 +{
   4.160 +	//log_debug("manage_window %u\n", xwin);
   4.161 +	CompWindow *cwin = new CompWindow(xwin);
   4.162 +	XGetWindowAttributes(dpy, xwin, &cwin->attr);
   4.163 +	add_window(cwin);
   4.164 +}
   4.165 +
   4.166 +static void unmanage_window(Window xwin)
   4.167 +{
   4.168 +	//log_debug("unmanage_window %u\n", xwin);
   4.169 +	CompWindow *cwin = find_window_xid(xwin);
   4.170 +	if(cwin) {
   4.171 +		remove_window(cwin);
   4.172 +		delete cwin;
   4.173 +	}
   4.174 +}
   4.175 +
   4.176 +static void redraw()
   4.177 +{
   4.178 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   4.179 +
   4.180 +	glEnable(GL_BLEND);
   4.181 +	glBlendFunc(GL_ONE, GL_ONE);
   4.182 +
   4.183 +	int num_win = get_window_count();
   4.184 +	for(int i=0; i<num_win; i++) {
   4.185 +		CompWindow *cwin = get_window(i);
   4.186 +
   4.187 +		glBegin(GL_QUADS);
   4.188 +		glColor3f(0.4, 0.1, 0.05);
   4.189 +		glVertex2f(cwin->attr.x, cwin->attr.y);
   4.190 +		glVertex2f(cwin->attr.x + cwin->attr.width, cwin->attr.y);
   4.191 +		glVertex2f(cwin->attr.x + cwin->attr.width, cwin->attr.y + cwin->attr.height);
   4.192 +		glVertex2f(cwin->attr.x, cwin->attr.y + cwin->attr.height);
   4.193 +		glEnd();
   4.194 +	}
   4.195 +
   4.196 +	glDisable(GL_BLEND);
   4.197 +
   4.198 +	glXSwapBuffers(dpy, comp_win);
   4.199 +}
   4.200 +
   4.201 +static void reshape(int x, int y)
   4.202 +{
   4.203 +	glViewport(0, 0, x, y);
   4.204 +
   4.205 +	glMatrixMode(GL_PROJECTION);
   4.206 +	glLoadIdentity();
   4.207 +	glOrtho(0, x, y, 0, -1, 1);
   4.208 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/opengl.cc	Fri Jan 22 06:31:03 2016 +0200
     5.3 @@ -0,0 +1,48 @@
     5.4 +#include "opengl.h"
     5.5 +#include "logger.h"
     5.6 +
     5.7 +extern Display *dpy;
     5.8 +extern Window root_win;
     5.9 +extern int screen_num;
    5.10 +extern int root_width, root_height;
    5.11 +
    5.12 +GLXContext create_gl(Window xwin)
    5.13 +{
    5.14 +	static int glxattr[] = {
    5.15 +		GLX_USE_GL, 1,
    5.16 +		GLX_RGBA,
    5.17 +		GLX_DOUBLEBUFFER,
    5.18 +		GLX_RED_SIZE, 8,
    5.19 +		GLX_GREEN_SIZE, 8,
    5.20 +		GLX_BLUE_SIZE, 8,
    5.21 +		GLX_DEPTH_SIZE, 16,
    5.22 +		None
    5.23 +	};
    5.24 +
    5.25 +	XVisualInfo *vis_info = glXChooseVisual(dpy, screen_num, glxattr);
    5.26 +	if(!vis_info) {
    5.27 +		log_error("failed to find suitable GLX visual\n");
    5.28 +		return 0;
    5.29 +	}
    5.30 +
    5.31 +	GLXContext ctx = glXCreateContext(dpy, vis_info, 0, True);
    5.32 +	if(!ctx) {
    5.33 +		log_error("failed to create OpenGL context\n");
    5.34 +		XFree(vis_info);
    5.35 +		return 0;
    5.36 +	}
    5.37 +	XFree(vis_info);
    5.38 +
    5.39 +	if(!glXMakeCurrent(dpy, xwin, ctx)) {
    5.40 +		log_error("failed to attach OpenGL context to window\n");
    5.41 +		glXDestroyContext(dpy, ctx);
    5.42 +		return 0;
    5.43 +	}
    5.44 +	return ctx;
    5.45 +}
    5.46 +
    5.47 +void destroy_gl(GLXContext ctx)
    5.48 +{
    5.49 +	glXMakeCurrent(dpy, 0, 0);
    5.50 +	glXDestroyContext(dpy, ctx);
    5.51 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/opengl.h	Fri Jan 22 06:31:03 2016 +0200
     6.3 @@ -0,0 +1,11 @@
     6.4 +#ifndef OPENGL_H_
     6.5 +#define OPENGL_H_
     6.6 +
     6.7 +#include <GL/gl.h>
     6.8 +#include <GL/glx.h>
     6.9 +#include <X11/Xlib.h>
    6.10 +
    6.11 +GLXContext create_gl(Window xwin);
    6.12 +void destroy_gl(GLXContext ctx);
    6.13 +
    6.14 +#endif	// OPENGL_H_