Created
November 7, 2021 15:00
-
-
Save matyklug18/1f589b5de426b1e207e06fa5a36aa45e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
+ main.c [No Name] X | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <X11/Xlib.h> | |
#include <X11/Xatom.h> | |
#include <X11/Xutil.h> | |
#include <X11/extensions/Xcomposite.h> | |
#include <X11/extensions/Xrender.h> | |
#include <X11/extensions/Xdamage.h> | |
#include <X11/extensions/shape.h> | |
Window root; | |
int scr; | |
Display* dpy; | |
Picture frontbuffer; | |
Picture backbuffer; | |
#define WIDTH DisplayWidth(dpy, scr) | |
#define HEIGHT DisplayHeight(dpy, scr) | |
#define DEPTH DefaultDepth(dpy, scr) | |
// Register a CM | |
int reg_cm() { | |
Window w; | |
Atom a; | |
static char net_wm_cm[] = "_NET_WM_CM_Sxx"; | |
snprintf(net_wm_cm, sizeof(net_wm_cm), "_NET_WM_CM_S%d", scr); | |
a = XInternAtom(dpy, net_wm_cm, False); | |
// Error Handling | |
w = XGetSelectionOwner(dpy, a); | |
if(w != None) { | |
XTextProperty tp; | |
char** strs; | |
int count; | |
Atom win_name_atom = XInternAtom(dpy, "_NET_WM_NAME", False); | |
if(!XGetTextProperty(dpy, w, &tp, win_name_atom) && !XGetTextProperty(dpy, w, &tp, XA_WM_NAME)) { | |
fprintf(stderr,"Another composite manager is already running (0x%lx)\n",(unsigned long) w); | |
return False; | |
} | |
if(XmbTextPropertyToTextList(dpy, &tp, &strs, &count) == Success) { | |
fprintf(stderr,"Another composite manager is already running (%s)\n",strs[0]); | |
XFreeStringList(strs); | |
} | |
XFree(tp.value); | |
return False; | |
} | |
// Actual Registering | |
w = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, None, None); | |
Xutf8SetWMProperties(dpy, w, "jacc", "jacc", NULL, 0, NULL, NULL, NULL); | |
XSetSelectionOwner(dpy, a, w, 0); | |
return True; | |
} | |
void setup_events() { | |
XGrabServer(dpy); | |
XCompositeRedirectSubwindows(dpy, root, CompositeRedirectManual); | |
XSelectInput(dpy, root, | |
SubstructureNotifyMask| | |
ExposureMask| | |
StructureNotifyMask| | |
PropertyChangeMask); | |
XUngrabServer(dpy); | |
} | |
void setup_xrender() { | |
XRenderPictFormat* d_format = XRenderFindVisualFormat(dpy, DefaultVisual(dpy, scr)); | |
XRenderPictureAttributes pa; | |
pa.subwindow_mode = IncludeInferiors; | |
frontbuffer = XRenderCreatePicture(dpy, root, d_format, CPSubwindowMode, &pa); | |
Pixmap root_pixmap = XCreatePixmap(dpy, root, WIDTH, HEIGHT, DEPTH); | |
backbuffer = XRenderCreatePicture(dpy, root_pixmap, d_format, 0, NULL); | |
XFreePixmap(dpy, root_pixmap); | |
XSync(dpy, False); | |
} | |
void damage_all() { | |
Window* children; | |
uint children_count; | |
Window root_o, parent; | |
XShapeSelectInput (dpy, root, ShapeNotifyMask); | |
XQueryTree(dpy, root, &root_o, &parent, &children, &children_count); | |
XSync(dpy, False); | |
for(uint i = 0; i < children_count; i++) { | |
//usleep(1000*10); | |
XWindowAttributes attrs; | |
XGetWindowAttributes(dpy, children[i], &attrs); | |
if(attrs.class != InputOnly) { | |
XDamageCreate(dpy, children[i], XDamageReportNonEmpty); | |
XSync(dpy, False); | |
} | |
} | |
} | |
void paint() { | |
Window* children; | |
uint children_count; | |
Window root_o, parent; | |
XQueryTree(dpy, root, &root_o, &parent, &children, &children_count); | |
XRenderColor color; | |
color.alpha = 50000; | |
color.red = 0; | |
color.green = 20000; | |
color.blue = 40000; | |
XRenderFillRectangle(dpy, PictOpSrc, backbuffer, &color, | |
0, 0, WIDTH, HEIGHT); | |
for(uint i = 0; i < children_count; i++) { | |
XSync(dpy, False); | |
XWindowAttributes attrs; | |
XGetWindowAttributes(dpy, children[i], &attrs); | |
XSync(dpy, False); | |
XRenderPictFormat* pict_format = XRenderFindVisualFormat(dpy, attrs.visual); | |
XSync(dpy, False); | |
if(!pict_format || (pict_format->type == picttypedirect || pict_format->direct.alphamask)) { | |
printf("discard:%ld(%d,%d)\n", children[i], pict_format->type, pict_format->direct.alphaMask); | |
continue; | |
} | |
printf("naming:%ld(%d,%d)\n", children[i], pict_format->type, pict_format->direct.alphaMask); | |
Pixmap pixmap = XCompositeNameWindowPixmap(dpy, children[i]); | |
XSync(dpy, False); | |
printf("pict:%ld\n", children[i]); | |
Picture picture = XRenderCreatePicture(dpy, pixmap, pict_format, 0, 0); | |
XSync(dpy, False); | |
XRenderComposite(dpy, PictOpOver, | |
picture, None, backbuffer, | |
0, 0, 0, 0, | |
attrs.x, attrs.y, attrs.width, attrs.height); | |
XSync(dpy, False); | |
} | |
XRenderComposite(dpy, PictOpSrc, | |
backbuffer, None, frontbuffer, | |
0, 0, 0, 0, | |
0, 0, WIDTH, HEIGHT); | |
XSync(dpy, False); | |
XFlush(dpy); | |
} | |
int main() { | |
dpy = XOpenDisplay(NULL); | |
scr = DefaultScreen(dpy); | |
root = DefaultRootWindow(dpy); | |
XGrabServer(dpy); | |
if(!reg_cm(dpy)) { | |
exit(1); | |
} | |
setup_events(); | |
setup_xrender(); | |
XUngrabServer(dpy); | |
int damage_event, damage_error; | |
if (!XDamageQueryExtension(dpy, &damage_event, &damage_error)) { | |
fprintf(stderr, "No damage extension\n"); | |
exit(1); | |
} | |
damage_all(); | |
usleep(100*1000); | |
paint(); | |
while(1) { | |
XEvent e; | |
XNextEvent(dpy, &e); | |
if(e.type == MapNotify) { | |
XCreateWindowEvent ev = e.xcreatewindow; | |
XWindowAttributes attrs; | |
XGetWindowAttributes(dpy, ev.window, &attrs); | |
if(attrs.class != InputOnly) { | |
XDamageCreate(dpy, ev.window, XDamageReportNonEmpty); | |
} | |
} else if(e.type == damage_event + XDamageNotify) { | |
paint(); | |
printf("paint\n"); | |
XDamageNotifyEvent* ev = (XDamageNotifyEvent*)&e; | |
XDamageSubtract(dpy, ev->damage, None, None); | |
} else { | |
printf("uncaught event:%d\n", e.type); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment