initial commit 🤞️
This commit is contained in:
15
README
Normal file
15
README
Normal 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. 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
|
||||
33
inc/put.h
Normal file
33
inc/put.h
Normal 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
31
inc/screen.h
Normal 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
49
inc/thing.h
Normal 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
30
src/main.c
Normal 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
96
src/screen_xcb.c
Normal 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
26
src/thing.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user