Loop your X cursor around the screen 👉😎👉
git clone https://mcol.xyz/code/xoop
Log | Files | Refs | README | LICENSE

commit f7d9deef0f47263068cc799c074105e8ae5a6c0f
parent b33ae8ecbbad7be4705da00d9d7c4bf0e1847111
Author: mcol <mcol@posteo.net>
Date:   Sat, 18 Apr 2020 14:57:53 +0100

translate to XCB and organise parts

Diffstat:
Mmakefile | 2+-
Mxinf.c | 155++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 128 insertions(+), 29 deletions(-)

diff --git a/makefile b/makefile @@ -1,6 +1,6 @@ OUT = xinf SRC = xinf.c -CFLAGS += -lX11 +CFLAGS += -Wall -Wextra -pedantic -lxcb PREFIX ?= /usr/local BINPREFIX ?= $(PREFIX)/bin diff --git a/xinf.c b/xinf.c @@ -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; }