From c06f9aeefedcc5095b50da2465fcec7ab70a65d3 Mon Sep 17 00:00:00 2001 From: betty Date: Sat, 27 Dec 2025 20:47:41 -0500 Subject: [PATCH] =?UTF-8?q?initial=20commit=20=F0=9F=A4=9E=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 1 + README | 15 ++++++++ inc/put.h | 33 +++++++++++++++++ inc/screen.h | 31 ++++++++++++++++ inc/thing.h | 49 ++++++++++++++++++++++++ src/main.c | 30 +++++++++++++++ src/screen_xcb.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ src/thing.c | 26 +++++++++++++ 8 files changed, 281 insertions(+) create mode 100644 LICENSE create mode 100644 README create mode 100644 inc/put.h create mode 100644 inc/screen.h create mode 100644 inc/thing.h create mode 100644 src/main.c create mode 100644 src/screen_xcb.c create mode 100644 src/thing.c diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e789537 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +Mine, don't steal diff --git a/README b/README new file mode 100644 index 0000000..e9597b1 --- /dev/null +++ b/README @@ -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. Today’s 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 diff --git a/inc/put.h b/inc/put.h new file mode 100644 index 0000000..8e56189 --- /dev/null +++ b/inc/put.h @@ -0,0 +1,33 @@ +#ifndef PUT_H +#define PUT_H + +#include + +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 */ diff --git a/inc/screen.h b/inc/screen.h new file mode 100644 index 0000000..b9da56e --- /dev/null +++ b/inc/screen.h @@ -0,0 +1,31 @@ +#ifndef SCREEN_H +#define SCREEN_H +/* +#include +#include +#include +#include +#include +#include +*/ +#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 diff --git a/inc/thing.h b/inc/thing.h new file mode 100644 index 0000000..64f7ab9 --- /dev/null +++ b/inc/thing.h @@ -0,0 +1,49 @@ +#ifndef THING_H +#define THING_H +/* +#include +#include +#include +#include +#include +#include +#include +*/ +#include + +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 */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..51f6fdf --- /dev/null +++ b/src/main.c @@ -0,0 +1,30 @@ +// literal red square + +#include +#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); + } +} diff --git a/src/screen_xcb.c b/src/screen_xcb.c new file mode 100644 index 0000000..f983e6e --- /dev/null +++ b/src/screen_xcb.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include + +#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); +} diff --git a/src/thing.c b/src/thing.c new file mode 100644 index 0000000..bb0e898 --- /dev/null +++ b/src/thing.c @@ -0,0 +1,26 @@ +// rect only +#include +#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; +}