# HG changeset patch # User John Tsiombikas # Date 1446516512 -7200 # Node ID 9b560415bad46cb3c35b88724fa6d94f552574a2 # Parent 2f02f100b20f3d2bacbc2f386b0af6c7e451b7a7 blured shadow diff -r 2f02f100b20f -r 9b560415bad4 src/main.c --- a/src/main.c Tue Nov 03 00:42:08 2015 +0200 +++ b/src/main.c Tue Nov 03 04:08:32 2015 +0200 @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include "image.h" @@ -14,6 +15,7 @@ Window create_window(int xsz, int ysz); void set_window_title(Window win, const char *title); int get_window_shape(Window win, struct image *img); +XID get_window_id(Display *dpy, int screen, int button); Display *dpy; Window win; @@ -26,6 +28,8 @@ struct texture tex; struct texture chess_tex; float aspect; +int sel_active; +Cursor sel_cursor; unsigned int target_xid = 0; @@ -35,11 +39,7 @@ char *endp; struct image chess_img; - if(!argv[1]) { - fprintf(stderr, "pass the window id to use\n"); - return 1; - } - if(!(target_xid = strtol(argv[1], &endp, 0))) { + if(argv[1] && !(target_xid = strtol(argv[1], &endp, 0))) { fprintf(stderr, "invalid argument: %s\n", argv[1]); return 1; } @@ -51,36 +51,53 @@ xa_wm_prot = XInternAtom(dpy, "WM_PROTOCOLS", False); xa_wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + sel_cursor = XCreateFontCursor(dpy, XC_crosshair); + if(!XShapeQueryExtension(dpy, &event_base, &error_base)) { fprintf(stderr, "shape extension unsupported by this X server\n"); XCloseDisplay(dpy); return 1; } - if(get_window_shape(target_xid, &img) == -1) { - XCloseDisplay(dpy); + + if(!target_xid) { + target_xid = get_window_id(dpy, 0, Button1); + } + if(target_xid) { + image_destroy(&img); + if(get_window_shape(target_xid, &img) == -1) { + destroy_texture(&tex); + } + } + + if(!(win = create_window(800 * (float)img.width / (float)img.height, 800))) { return 1; } - - if(!(win = create_window(1280, 800))) { - return 1; + if(img.pixels) { + image_texture(&tex, &img); } - image_texture(&tex, &img); - image_create(&chess_img, 256, 256); - image_chess(&chess_img, 8, 255, 128, 64, 64, 128, 255); + image_chess(&chess_img, 8, 192, 100, 64, 64, 100, 192); image_texture(&chess_tex, &chess_img); image_destroy(&chess_img); for(;;) { XEvent ev; - XNextEvent(dpy, &ev); - if(handle_event(&ev) == -1) { - break; + do { + XNextEvent(dpy, &ev); + if(handle_event(&ev) == -1) { + goto quit; + } + } while(XPending(dpy)); + + if(redisp_pending) { + redisp_pending = 0; + redraw(); } } +quit: XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; @@ -100,54 +117,67 @@ /* background */ glBegin(GL_QUADS); + glColor3f(1, 1, 1); glTexCoord2f(0, 0); glVertex2f(-aspect, -1); - glTexCoord2f(1, 0); glVertex2f(aspect, -1); - glTexCoord2f(1, 1); glVertex2f(aspect, 1); + glTexCoord2f(aspect, 0); glVertex2f(aspect, -1); + glTexCoord2f(aspect, 1); glVertex2f(aspect, 1); glTexCoord2f(0, 1); glVertex2f(-aspect, 1); glEnd(); - /* draw the window shape */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if(tex.id) { + int i, ssamples = 64; + float ssample_weight = 1.0 / (float)ssamples; + float shadow_spread = 0.05; + float img_aspect = (float)tex.width / (float)tex.height; - glBindTexture(GL_TEXTURE_2D, tex.id); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef((float)tex.width / (float)tex.tex_width, - (float)tex.height / (float)tex.tex_height, - 1.0); + /* draw the window shape */ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glScalef(0.7, 0.7, 0.7); + glBindTexture(GL_TEXTURE_2D, tex.id); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef((float)tex.width / (float)tex.tex_width, + (float)tex.height / (float)tex.tex_height, + 1.0); - /* shadow */ - glPushMatrix(); - glTranslatef(0.1, -0.1, 0); - glBegin(GL_QUADS); - glColor3f(0, 0, 0); - glTexCoord2f(0, 1); glVertex2f(-1, -1); - glTexCoord2f(1, 1); glVertex2f(1, -1); - glTexCoord2f(1, 0); glVertex2f(1, 1); - glTexCoord2f(0, 0); glVertex2f(-1, 1); - glEnd(); - glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glScalef(0.9 * img_aspect, 0.9, 0.9); - /* window */ - glBegin(GL_QUADS); - glColor3f(1, 1, 0); - glTexCoord2f(0, 1); glVertex2f(-1, -1); - glTexCoord2f(1, 1); glVertex2f(1, -1); - glTexCoord2f(1, 0); glVertex2f(1, 1); - glTexCoord2f(0, 0); glVertex2f(-1, 1); - glEnd(); + /* shadow */ + for(i=0; ixexpose.count == 0) { - redraw(); - } + redisp_pending = 1; break; case KeyPress: @@ -183,6 +211,17 @@ switch(sym) { case XK_Escape: return -1; + + case ' ': + target_xid = get_window_id(dpy, 0, Button1); + image_destroy(&img); + if(get_window_shape(target_xid, &img) == -1) { + destroy_texture(&tex); + } else { + image_texture(&tex, &img); + redisp_pending = 1; + } + break; } } break; @@ -202,6 +241,20 @@ } } break; + + case ButtonPress: + /*if(sel_active && ev->xbutton.button == Button1) { + target_xid = ev->xbutton.subwindow; + printf("clicked on window: %x\n", target_xid); + + image_destroy(&img); + if(get_window_shape(target_xid, &img) == -1) { + destroy_texture(&tex); + } else { + image_texture(&tex, &img); + } + }*/ + break; } return 0; } @@ -280,21 +333,17 @@ int bx, by, cx, cy; unsigned int bw, bh, cw, ch; int kind; - int x, y, w, h; + int w, h; XRectangle *rects; int i, rect_count, rect_order; XShapeQueryExtents(dpy, win, &buse, &bx, &by, &bw, &bh, - &cuse, &cx, &cy, &bw, &bh); + &cuse, &cx, &cy, &cw, &ch); if(cuse) { - x = cx; - y = cy; w = cw; h = ch; kind = ShapeClip; } else if(buse) { - x = bx; - y = by; w = bw; h = bh; kind = ShapeBounding; @@ -321,3 +370,49 @@ } return 0; } + +XID get_window_id(Display *dpy, int screen, int button) +{ + Window root; /* the current root */ + Window retwin = None; /* the window that got selected */ + int retbutton = -1; /* button used to select window */ + int pressed = 0; /* count of number of buttons pressed */ + +#define MASK (ButtonPressMask | ButtonReleaseMask) + + root = RootWindow(dpy, screen); + XSync(dpy, 0); /* give xterm a chance */ + + if(XGrabPointer(dpy, root, False, MASK, GrabModeSync, GrabModeAsync, + None, sel_cursor, CurrentTime) != GrabSuccess) { + fprintf (stderr, "unable to grab cursor\n"); + return 0; + } + + while (retwin == None || pressed != 0) { + XEvent event; + + XAllowEvents (dpy, SyncPointer, CurrentTime); + XWindowEvent (dpy, root, MASK, &event); + + switch (event.type) { + case ButtonPress: + if (retwin == None) { + retbutton = event.xbutton.button; + retwin = ((event.xbutton.subwindow != None) ? + event.xbutton.subwindow : root); + } + pressed++; + continue; + + case ButtonRelease: + if (pressed > 0) pressed--; + continue; + } /* end switch */ + } /* end for */ + + XUngrabPointer (dpy, CurrentTime); + XSync (dpy, 0); + + return ((button == -1 || retbutton == button) ? retwin : None); +} diff -r 2f02f100b20f -r 9b560415bad4 src/texture.c --- a/src/texture.c Tue Nov 03 00:42:08 2015 +0200 +++ b/src/texture.c Tue Nov 03 04:08:32 2015 +0200 @@ -22,6 +22,12 @@ return 0; } +void destroy_texture(struct texture *tex) +{ + glDeleteTextures(1, &tex->id); + tex->id = 0; +} + static int next_pow2(int x) { --x; diff -r 2f02f100b20f -r 9b560415bad4 src/texture.h --- a/src/texture.h Tue Nov 03 00:42:08 2015 +0200 +++ b/src/texture.h Tue Nov 03 04:08:32 2015 +0200 @@ -9,5 +9,6 @@ }; int image_texture(struct texture *tex, struct image *img); +void destroy_texture(struct texture *tex); #endif /* TEXTURE_H_ */