Skip to content

Commit

Permalink
wip: devdraw: wayland support
Browse files Browse the repository at this point in the history
Absolutum obsoletum

Signed-off-by: Hank Donnay <[email protected]>
  • Loading branch information
hdonnay committed Apr 23, 2022
1 parent c44015f commit 4f5a918
Show file tree
Hide file tree
Showing 15 changed files with 1,928 additions and 1 deletion.
5 changes: 5 additions & 0 deletions bin/9l
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ then
fi
libsl="$libsl -lX11"
fi

if [ "x$needwayland" = xtrue -a "x$WSYSTYPE" != xnowsys ]
then
libsl="$(echo $libsl | sed 's/wayland/wayland-client -lwayland-cursor -lrt/')"
fi
fi
if $doautoframework
then
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/devdraw/mkfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ HFILES=\

<$PLAN9/src/mkone

<mkwayland

$O.drawclient: drawclient.$O
$LD -o $target $prereq

Expand Down
19 changes: 19 additions & 0 deletions src/cmd/devdraw/mkwayland
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
way_proto=/usr/share/wayland-protocols

xdg-shell-protocol.c: $way_proto/stable/xdg-shell/xdg-shell.xml
wayland-scanner private-code < $prereq > $target

xdg-shell-client-protocol.h: $way_proto/stable/xdg-shell/xdg-shell.xml
wayland-scanner client-header < $prereq > $target

xdg-decoration-protocol.c: $way_proto/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
wayland-scanner private-code < $prereq > $target

xdg-decoration-client-protocol.h: $way_proto/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
wayland-scanner client-header < $prereq > $target

pointer-constraints-client-protocol.h: $way_proto/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
wayland-scanner client-header < $prereq > $target

pointer-constraints-protocol.c: $way_proto/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
wayland-scanner private-code < $prereq > $target
9 changes: 9 additions & 0 deletions src/cmd/devdraw/mkwsysrules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ if [ "x$WSYSTYPE" = "x" ]; then
exit 1
fi
WSYSTYPE=mac
elif command -v wayland-scanner >/dev/null 2>&1; then
WSYSTYPE=wayland
elif [ -d "$X11" ]; then
WSYSTYPE=x11
else
Expand All @@ -54,6 +56,13 @@ if [ $WSYSTYPE = x11 ]; then
XO=`ls x11-*.c 2>/dev/null | sed 's/\.c$/.o/'`
echo 'WSYSOFILES=$WSYSOFILES '$XO
echo 'WSYSHFILES=x11-inc.h x11-keysym2ucs.h x11-memdraw.h'
elif [ $WSYSTYPE = wayland ]; then
protos='pointer-constraints xdg-decoration xdg-shell'
PROTOO=$(for p in $protos; do printf '%s-protocol.o ' $p; done; printf '\n'; )
PROTOH=$(for p in $protos; do printf '%s-client-protocol.h ' $p; done; printf '\n'; )
WAYO=`ls wayland-*.c 2>/dev/null | sed 's/\.c$/.o/' | paste -s -d ' '`
echo "WSYSOFILES=\$WSYSOFILES $WAYO $PROTOO"
echo "WSYSHFILES=wayland-inc.h $PROTOH"
elif [ $WSYSTYPE = mac ]; then
echo 'WSYSOFILES=$WSYSOFILES mac-draw.o mac-screen.o'
echo 'WSYSHFILES='
Expand Down
157 changes: 157 additions & 0 deletions src/cmd/devdraw/wayland-draw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#include <u.h>
#include "wayland-inc.h"
#include <libc.h>
#include <draw.h>
#include <memdraw.h>

#include "wayland-shm.h"
#include <sys/mman.h>

AUTOLIB(wayland);

Memimage *
allocmemimage(Rectangle r, u32int chan) {
int d;
Memimage *i;
if ((d = chantodepth(chan)) == 0) {
werrstr("bad channel descriptor %.8lux", chan);
return nil;
}
// fprint(2, "allocmemimage: start\n");
// Too lazy to write a real allocator, just create shm mappings and rely on
// wayland's book-keeping to tear them down.
int l = wordsperline(r, d);
int nw = l * Dy(r);
uint32 sz = sizeof(shmTab) + ((1 + nw) * sizeof(ulong));
Memdata *md = malloc(sizeof(Memdata));
if (md == nil) {
// fprint(2, "allocmemimage: malloc fail\n");
return nil;
}
// fprint(2, "allocmemimage: shm\n");
int fd = allocate_shm_file(sz);
if (fd == -1) {
// fprint(2, "allocmemimage: shm fail\n");
free(md);
return nil;
}
// fprint(2, "allocmemimage: mmap\n");
uchar *data = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
// fprint(2, "allocmemimage: map fail\n");
free(md);
close(fd);
return nil;
}

md->ref = 1;
md->base = (u32int *)data;
shmTab *t = (shmTab *)data;
t->md = md;
t->fd = fd;
t->sz = sz;
// Should only be 24 bytes used, max.
md->bdata = (uchar *)(md->base + sizeof(shmTab));
md->allocd = 1;
// fprint(2, "allocmemimage: allocmemimaged\n");
i = allocmemimaged(r, chan, md, t);
if (i == nil) {
// fprint(2, "allocmemimage: allocmemimaged fail\n");
munmap(data, sz);
free(md);
close(fd);
return nil;
}
md->imref = i;
return i;
}

/*
static void
buffer_release(void *opaque, struct wl_buffer *buf) {
wl_buffer_destroy(buf);
}
static struct wl_buffer_listener kill_buffer = {
.release = buffer_release,
};
void
mk_buffer(window *w, Memimage *i) {
if (i == nil)
return;
if (i->X != nil)
return;
if (i->data->ref == 0 || !i->data->allocd) // zombie memimage ???
return;
shmTab *tab = (shmTab *)i->data->base;
Globals *g = w->global;
struct wl_shm_pool *pool = wl_shm_create_pool(g->wl_shm, tab->fd, tab->sz);
if (pool == nil) {
fprint(2, "mk_buffer: pool fail\n");
return;
}
struct wl_buffer *buf = wl_shm_pool_create_buffer(
pool, 64, Dx(i->r), Dy(i->r), Dx(i->r) * 4, WL_SHM_FORMAT_XRGB8888);
if (buf == nil) {
fprint(2, "mk_buffer: buffer fail\n");
return;
}
wl_shm_pool_destroy(pool);
fprint(2, "mkbuffer: %p\n", i);
i->X = buf;
wl_buffer_add_listener(buf, &kill_buffer, NULL);
}
*/

void
freememimage(Memimage *i) {
if (i == nil)
return;
if (i->data->ref-- == 1 && i->data->allocd) {
if (i->data->base) {
shmTab *tab = (shmTab *)i->data->base;
if (tab->md != i->data) {
fprint(2, "maritan memdata\n");
return _freememimage(i);
};
close(tab->fd);
munmap(i->data->base, tab->sz);
}
free(i->data);
}
free(i);
}

/*
void
memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
Memimage *mask, Point mp, int op) {
fprint(2, "memimagedraw\n");
}
void
memfillcolor(Memimage *m, u32int val) {
_memfillcolor(m, val);
}
u32int
pixelbits(Memimage *m, Point p) {
return _pixelbits(m, p);
}
*/

int
loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) {
return _loadmemimage(i, r, data, ndata);
}

int
cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) {
return _cloadmemimage(i, r, data, ndata);
}

int
unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) {
return _unloadmemimage(i, r, data, ndata);
}
104 changes: 104 additions & 0 deletions src/cmd/devdraw/wayland-inc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include <u.h>
#include <libc.h>
#include <wayland-client.h>
#include <wayland-cursor.h>
#include <xkbcommon/xkbcommon.h>

#include "xdg-shell-client-protocol.h"
#include "xdg-decoration-client-protocol.h"
#include "pointer-constraints-client-protocol.h"

struct bounds {
int x, y;
};

typedef struct Globals {
struct wl_display *wl_display;
struct wl_registry *wl_registry;
struct wl_shm *wl_shm;
struct wl_cursor_theme *wl_cursor_theme;
struct wl_compositor *wl_compositor;
struct wl_subcompositor *wl_subcompositor;
struct xdg_wm_base *xdg_wm_base;
struct wl_seat *wl_seat;
struct wl_data_device_manager *data_device_manager;
struct wl_data_device *data_device;
struct wl_data_offer *snarf_offer;
int snarf_fd;
char *snarf_buf;
struct zwp_pointer_constraints_v1 *pointer_constraints;
struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1;

uint32_t seat_capabilities;
struct pixfmt {
uint32_t wl;
uint32_t p9;
} pixfmt;
struct bounds bounds;
} Globals;

// This is the singleton for a given process.
//
// Wayland specific code should be using the passed data pointer, this is just
// for the plan9 interface callbacks.
extern Globals procState;

// Window is a big bag of state for painting a window on screen.
typedef struct window {
// RWLock mu;
Globals *global;
struct wl_keyboard *wl_keyboard;
struct wl_pointer *wl_pointer;
struct wl_surface *wl_surface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *xdg_toplevel;
struct zwp_pointer_constraints_v1 *pointer_constraints;
// Frame and border need to be re-organized: "frame" was originally the
// window contents with the main surface being the border, but this
// arrangement breaks pointer warping in GNOME. This state of affair is
// weird, but actually works.
struct border {
struct edge {
struct wl_subsurface *subsurface;
struct wl_surface *surface;
int skip;
int x, y;
} edge[4]; // top, bottom, left, right
struct wl_shm_pool *x, *y;
} decoration;
struct bounds bounds, cursize, wantsize;
// Mouse members: x, y, button state, time and entry serial.
struct mouse {
// RWLock mu;
int X, Y, B, T, S;
int in; // which surface?
} m;
struct cursor {
// RWLock mu;
struct wl_surface *surface;
struct wl_cursor *arrow;
struct wl_shm_pool *pool;
uint32 *buf;
int x, y;
} cursor;
// Keyboard members: xkb members and serial
struct keyboard {
// RWLock mu;
struct xkb_context *context;
struct xkb_keymap *keymap;
struct xkb_state *state;
int S;
int32 rate, delay;
int32 time, key, event, delayed;
} kb;
} window;

struct Memdata;
typedef struct shmTab {
struct Memdata *md;
int fd;
size_t sz;
} shmTab;

extern int borderSz;
extern int barSz;
Loading

0 comments on commit 4f5a918

Please sign in to comment.