Loop your X cursor around the screen 👉😎👉
git clone https://github.com/m-col/xoop
Files | Refs | Readme | License

Commit f7d9deef0f47263068cc799c074105e8ae5a6c0f
Parent: b33ae8ecbbad7be4705da00d9d7c4bf0e1847111
Author: mcol <mcol@posteo.net>
Date: 2020-04-18 14:57:53 +0100
Committer: mcol <mcol@posteo.net>
Committed: 2020-04-18 14:57:53 +0100

translate to XCB and organise parts

xinf.c Modified

@@ -1,42 +1,141 @@
 #include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
+#include <stdio.h>
+#include <string.h>
+#include <xcb/xcb.h>
 
-int main()
+
+xcb_connection_t    *conn;
+xcb_screen_t	    *screen;
+
+
+void clip_window(xcb_window_t wid)
 {
-    Display *dpy;
-    Window root;
-    Window win;
-    XSetWindowAttributes attrs;
-    XEvent ev; 
+    uint32_t mask;
+    xcb_gcontext_t  gc;
 
-    if (NULL == (dpy = XOpenDisplay(NULL))) {
-	exit(1);
-    }
+    mask = XCB_GC_CLIP_ORIGIN_X | XCB_GC_CLIP_ORIGIN_Y;// | XCB_GC_CLIP_MASK
 
-    root = RootWindow(dpy, DefaultScreen(dpy));
-    attrs.event_mask = KeyPressMask;
-    Atom window_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
-    long value = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
+    const uint32_t values[] = {
+	1,
+	1,
+    };
 
-    win = XCreateWindow(
-        dpy, root, 10,10,200,200, 0, CopyFromParent, InputOnly, 0, 0, &attrs
+    gc = xcb_generate_id(conn);
+    xcb_create_gc(
+	conn,
+	gc,
+	wid,
+	mask,
+	values
     );
-    XChangeProperty(dpy, win, window_type, 4, 32,
-                    PropModeReplace, (unsigned char *)&value, 1);
+}
 
-    XSelectInput(dpy, win, EnterWindowMask);
-    XMapWindow(dpy, win);
-    XFlush(dpy);
 
-    while(1) {
-        XNextEvent(dpy, &ev);
-	XWarpPointer(dpy, None, root, 0, 0, 0, 0, 0, 0);
-    }   
+void set_window_type(xcb_window_t wid) {
+    xcb_intern_atom_cookie_t cookie1, cookie2;
+    xcb_intern_atom_reply_t *reply1, *reply2;
 
-    if (XCloseDisplay(dpy)) {
-	exit(1);
+    cookie1 = xcb_intern_atom(conn, 0, 19, "_NET_WM_WINDOW_TYPE");
+    reply1 = xcb_intern_atom_reply(conn, cookie1, NULL);
+    cookie2 = xcb_intern_atom(conn, 0, 32, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
+    reply2 = xcb_intern_atom_reply(conn, cookie2, NULL);
+
+    xcb_change_property(
+	conn,
+	XCB_PROP_MODE_REPLACE,
+	wid,
+	reply1->atom,
+	XCB_ATOM_ATOM,
+	32,
+	1,
+	&reply2->atom
+    );
+    free(reply1);
+    free(reply2);
+}
+
+
+xcb_window_t setup_window()
+{
+    xcb_window_t wid = xcb_generate_id(conn);
+
+    uint32_t mask_val = 0;
+    mask_val |= XCB_EVENT_MASK_ENTER_WINDOW;
+
+    xcb_create_window(
+	conn,
+	XCB_COPY_FROM_PARENT,
+	wid,
+	screen->root,
+	0,
+	0,
+	1, // screen->width_in_pixels
+	screen->height_in_pixels,
+	0,
+	XCB_WINDOW_CLASS_INPUT_ONLY,
+	XCB_COPY_FROM_PARENT,
+	XCB_CW_EVENT_MASK,
+	&mask_val
+    );
+
+    set_window_type(wid);
+    clip_window(wid);
+
+    uint32_t above = XCB_STACK_MODE_ABOVE;
+    xcb_configure_window(conn, wid, XCB_CONFIG_WINDOW_STACK_MODE, &above);
+
+    xcb_change_property(
+	conn,
+	XCB_PROP_MODE_REPLACE,
+	wid,
+	XCB_ATOM_WM_NAME,
+	XCB_ATOM_STRING,
+	8,
+	4,
+	"xinf"
+    );
+
+    xcb_map_window(conn, wid);
+    xcb_flush(conn);
+    return wid;
+}
+
+
+void event_loop()
+{
+    xcb_generic_event_t *event;
+
+    while((event = xcb_wait_for_event(conn))) {
+	switch (event->response_type) {
+
+	    case XCB_ENTER_NOTIFY:
+	    printf("# enter window\n");
+	    break;
+
+	    default:
+	    printf("# %d\n", event->response_type);
+	    break;
+	}
+
+    free(event);
     }
+}
+
+
+int main()
+{
+    xcb_window_t wid;
+
+    conn = xcb_connect(NULL, NULL);
+    if (xcb_connection_has_error(conn))
+	exit(1);
+    screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
+
+    wid = setup_window();
+    event_loop();
+
+    xcb_unmap_window(conn, wid);
+    xcb_disconnect(conn);
 
     return 0;
 }

makefile Modified

@@ -1,6 +1,6 @@
 OUT        = xinf
 SRC 	   = xinf.c
-CFLAGS 	  += -lX11
+CFLAGS 	  += -Wall -Wextra -pedantic -lxcb
 PREFIX    ?= /usr/local
 BINPREFIX ?= $(PREFIX)/bin