Skip to content

Instantly share code, notes, and snippets.

@xzfc
Created November 7, 2018 08:51
Show Gist options
  • Save xzfc/d3b28cc800e477a89cb70b7bf081f3cd to your computer and use it in GitHub Desktop.
Save xzfc/d3b28cc800e477a89cb70b7bf081f3cd to your computer and use it in GitHub Desktop.
// gcc test.c -lX11 -lXext
/* Some clumsy app to test X11 Shape extension.
*
* The app window consists of three zones:
* +-------+
* | A |
* +---+---+
* | B | C |
* +---+---+
*
* - Zone A is completly transparent.
* - Zones B and C is white.
* - Zone B should be clickable through, i.e. you should able to click the window underneath.
* - Clicking on zone C causes printing "ButtonPress" to stdout.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
/* size of the window */
#define W_WIDTH 500
#define W_HEIGHT 500
int main(int argc, char **argv)
{
Display *dpy;
Window w;
Pixmap pmap;
GC shape_gc;
GC win_gc;
XGCValues xgcv;
/* open the display */
if(!(dpy = XOpenDisplay(getenv("DISPLAY")))) {
fprintf(stderr, "can't open display\n");
return EXIT_FAILURE;
}
/* create the window */
w = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, W_WIDTH,
W_HEIGHT, 0, CopyFromParent, InputOutput,
CopyFromParent, 0, NULL);
/* create a graphics context for drawing on the window */
xgcv.foreground = WhitePixel(dpy, DefaultScreen(dpy));
xgcv.line_width = 1;
xgcv.line_style = LineSolid;
win_gc = XCreateGC(dpy, w, GCForeground | GCLineWidth | GCLineStyle, &xgcv);
/* create the pixmap that we'll use for shaping the window */
pmap = XCreatePixmap(dpy, w, W_WIDTH, W_HEIGHT, 1);
/* create a graphics context for drawing on the pixmap */
shape_gc = XCreateGC(dpy, pmap, 0, &xgcv);
XSelectInput(dpy, w, ButtonPressMask | ExposureMask | StructureNotifyMask);
XMapWindow(dpy, w);
XSync(dpy, False);
while(1) {
XEvent xe;
XNextEvent(dpy, &xe);
switch (xe.type) {
case Expose:
XSetForeground(dpy, win_gc, WhitePixel(dpy, DefaultScreen(dpy)));
XFillRectangle(dpy, w, win_gc, 0, 0, W_WIDTH, W_HEIGHT);
XSync(dpy, False);
break;
case ConfigureNotify:
XSetForeground(dpy, shape_gc, 0);
XFillRectangle(dpy, pmap, shape_gc, 0, 0, W_WIDTH, W_HEIGHT);
XSetForeground(dpy, shape_gc, 1);
XFillRectangle(dpy, pmap, shape_gc, W_WIDTH/2, 0, W_WIDTH/2, W_HEIGHT);
XShapeCombineMask (dpy, w, ShapeInput, 0, 0, pmap, ShapeSet);
XSetForeground(dpy, shape_gc, 0);
XFillRectangle(dpy, pmap, shape_gc, 0, 0, W_WIDTH, W_HEIGHT);
XSetForeground(dpy, shape_gc, 1);
XFillRectangle(dpy, pmap, shape_gc, 0, W_HEIGHT/2, W_WIDTH, W_HEIGHT/2);
XShapeCombineMask (dpy, w, ShapeBounding, 0, 0, pmap, ShapeSet);
XSync(dpy, False);
break;
case ButtonPress:
printf("ButtonPress\n");
break;
default:
printf("Caught event %i\n", xe.type);
}
}
XFreePixmap(dpy, pmap);
XDestroyWindow(dpy, w);
XCloseDisplay(dpy);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment