initial commit 🤞

This commit is contained in:
betty
2025-12-27 20:47:41 -05:00
commit c06f9aeefe
8 changed files with 281 additions and 0 deletions

1
LICENSE Normal file
View File

@@ -0,0 +1 @@
Mine, don't steal

15
README Normal file
View File

@@ -0,0 +1,15 @@
X Put Thing On Screen
abstraction (capability, semantic) layer that calls libraries to simply use X to Put Thing On Screen
which is what everyone actually wants, but has failed at for forever
if i end up running into a brick wall with X, i may devise "Y" windowing, but i don't want to throw out 40 years of programming at first
"I must stress this to listeners over and over. Todays operating systems rule out interconnection between windows at the system level—only within a restricted “application” can such windows be interconnected, and only if you create a new set of windows internal to the application. Of course, one sneaky method is to seize the whole screen as a transparent canvas, but this still does not give access to the windows provided by the operating system.
It is still hard for many people to understand that I mean actually showing visible connections between pages on the screen, and hard for them to imagine writing based on this capability, though it is the only kind of writing I wish to do. For instance, I would like to rewrite my autobiography into parallel, visibly connected pages, in case I have the time and tools to do so."
-- Theodore Holm Nelson, Intertwingled
License: see LICENSE

33
inc/put.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef PUT_H
#define PUT_H
#include <stdint.h>
enum put_event_type {
PUT_EXPOSE,
PUT_MOUSE_DOWN,
PUT_MOUSE_UP,
PUT_MOUSE_MOVE,
PUT_KEY,
PUT_SCROLL
};
enum {
PUT_MOD_SHIFT = 1 << 0,
PUT_MOD_CTRL = 1 << 1,
PUT_MOD_ALT = 1 << 2,
PUT_MOD_SUPER = 1 << 3
};
struct put_event {
enum put_event_type type;
int x;
int y;
int dx;
int dy;
int key;
uint32_t mods;
};
#endif /* PUT_H */

31
inc/screen.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef SCREEN_H
#define SCREEN_H
/*
#include <libpng.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xcb.h>
#include <xcb/xcb.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
*/
#include "thing.h"
#include "put.h"
typedef struct screen screen_t;
// func decs
screen_t *screen_create(int width, int height);
void screen_destroy(screen_t *s);
void screen_add(screen_t *s, thing_t *t);
void screen_remove(screen_t *s, thing_t *t);
void screen_raise(screen_t *s, thing_t *t);
void screen_lower(screen_t *s, thing_t *t);
void screen_dispatch(screen_t *s, const put_event *ev);
void screen_redraw(screen_t *s);
#endif

49
inc/thing.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef THING_H
#define THING_H
/*
#include <libpng.h>
#include <pango.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xcb.h>
#include <xcb/xcb.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
*/
#include <stdint.h>
typedef struct thing thing_t;
typedef uint64_t thing_id_t;
thing_id_t thing_id(const thing_t *);
typedef struct {
int x;
int y;
int w;
int h;
} thing_geom;
struct put_event;
struct link {
thing_id_t from;
thing_id_t to;
uint32_t type;
};
typedef struct {
void (*draw)(thing_t *self, void *render_ctx);
int (*hit)(thing_t *self, int x, int y);
void (*event)(thing_t *self, const struct put_event *ev);
} thing_ops;
thing_t *thing_create(const thing_ops *ops, void *userdata, thing_geom geom);
void thing_set_geom(thing_t *t, thing_geom g);
thing_geom thing_get_geom(const thing_t *t);
void *thing_userdata(const thing_t *t);
void thing_destroy(thing_t *t);
#endif /* THING_H */

30
src/main.c Normal file
View File

@@ -0,0 +1,30 @@
// literal red square
#include <cairo/cairo.h>
#include "thing.h"
#include "screen.h"
static void draw_red_box(thing_t*, void *ctx) {
cairo_t *cr = ctx;
thing_geom g = thing_get_geom(t);
cairo_set_source_rbg(cr, 1, 0, 0);
cairo_rectangle(cr, g.x, g.y, g.w, g.h);
cairo_fill(cr);
}
int main(void) {
screen_t *s = screen_create(800, 600);
thing_ops ops = { .draw = draw_red_box };
thing_geom g = { 100, 100, 200, 150 };
thing_t *box = thing_create(&ops, NULL, g);
screen_add(s, box);
for (;;) {
screen_redraw(s);
usleep(16000);
}
}

96
src/screen_xcb.c Normal file
View File

@@ -0,0 +1,96 @@
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xcb.h>
#include "screen.h"
#include "thing.h"
struct screen {
xcb_connection_t *conn;
xcb_screen_t *xscreen;
xcb_window_t win;
cairo_surface_t *surface;
cairo_t *cr;
int width;
int height;
thing_t **things;
size_t thing_count;
};
screen_t *screen_create(int width, int height) {
screen_t *s = calloc(1, sizeof(*s));
if (!s) return NULL;
int scrno;
s->conn = xcb_connect(NULL, &scrno);
if (xcb_connection_has_error(s->conn)) {
fprintf(stderr, "xcb_connect failed\n");
exit(1);
}
const xcb_setup_t *setup = xcb_get_setup(s->conn);
xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
for (int i = 0; i < scrno; i++) xcb_screen_next(&it);
s->xscreen = it.data;
s->width = width;
s->height = height;
s->win = xcb_generate_id(s->conn);
uint32_t mask =
XCB_CW_BACK_PIXEL |
XCB_CW_EVENT_MASK;
uint32_t values[] = {
s->xscreen->black_pixel,
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_POINTER_MOTION |
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE
};
xcb_create_window(
s->conn,
XCB_COPY_FROM_PARENT,
s->win,
s->xscreen->root,
0, 0,
width, height,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
s->xscreen->root_visual,
mask,
values
);
xcb_map_window(s->conn, s->win);
xcb_flush(s->conn);
s->surface = cairo_xcb_surface_create(
s->conn,
s->win,
cairo_xcb_visual_get(s->xscreen),
width,
height
);
s->cr = cairo_create(s->surface);
return s;
}
// where Things end up
void screen_redraw(screen_t *s) {
ciaro_set_source_rbg(s->cr, 0, 0, 0);
cairo_paint(s->cr);
for (size_t i = 0; i < s->thing_count; i++) {
thing_draw(s->things[i], s->cr);
}
cairo_surface_flush(s->surface);
xcb_flush(s->conn);
}

26
src/thing.c Normal file
View File

@@ -0,0 +1,26 @@
// rect only
#include <stdlib.h>
#include "thing.h"
struct thing {
thing_geom geom;
const thing_ops *ops;
void *userdata;
};
thing_t *thing_create(const thing_ops *ops, void *userdata, thing_geom geom) {
thing_t *t = calloc(1, sizeof(*t));
t->ops = ops;
t->userdata = userdata;
t->geom = geom;
return t;
}
void thing_draw(thing_t *t, void *render_ctx) {
if (t->ops && t->ops->draw)
t->ops->draw(t, render_ctx);
}
thing_geom thing_get_geom(const thing_t *t) {
return t->geom;
}