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_