init with waymini
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
CC ?= gcc
|
||||
CFLAGS := -Wall -Wextra -O2 $(shell pkg-config --cflags wayland-client 2>/dev/null)
|
||||
LDFLAGS := $(shell pkg-config --libs wayland-client 2>/dev/null)
|
||||
|
||||
# Fallback if pkg-config is unavailable or returns nothing.
|
||||
ifeq ($(LDFLAGS),)
|
||||
LDFLAGS := -lwayland-client -lm
|
||||
endif
|
||||
|
||||
LIB_SRC := waymini.c xdg-shell-client-protocol.c
|
||||
LIB_OBJ := $(LIB_SRC:.c=.o)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: libwaymini.a example waymini
|
||||
|
||||
libwaymini.a: $(LIB_OBJ)
|
||||
ar rcs $@ $^
|
||||
|
||||
example: example.c libwaymini.a
|
||||
$(CC) $(CFLAGS) -o $@ example.c -L. -lwaymini $(LDFLAGS)
|
||||
|
||||
waymini: waymini_standalone.c waymini.c xdg-shell-client-protocol.c
|
||||
$(CC) $(CFLAGS) -o $@ waymini_standalone.c waymini.c xdg-shell-client-protocol.c $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(LIB_OBJ) libwaymini.a example waymini
|
||||
|
||||
xdg-shell-client-protocol.c xdg-shell-client-protocol.h: gen-protocols.sh
|
||||
bash gen-protocols.sh
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Example program that links against the waymini library.
|
||||
* No external dependencies beyond waymini itself and the C standard library.
|
||||
*/
|
||||
|
||||
#include "waymini.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void on_key(void *user, uint32_t keycode, uint32_t state) {
|
||||
(void)user;
|
||||
const char *label = state ? "down" : "up ";
|
||||
printf("key %s: %u\n", label, keycode);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint32_t w = 800, h = 480;
|
||||
|
||||
struct waymini *wm = waymini_create(w, h, on_key, NULL);
|
||||
if (!wm) return 1;
|
||||
|
||||
printf("surface: %ux%u stride=%u\n",
|
||||
waymini_get_width(wm), waymini_get_height(wm), waymini_get_stride(wm));
|
||||
|
||||
uint8_t *pixels = (uint8_t *)waymini_get_pixels(wm);
|
||||
if (!pixels) {
|
||||
waymini_destroy(wm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Fill a simple gradient. Each row is stride bytes. */
|
||||
for (uint32_t y = 0; y < h; y++) {
|
||||
for (uint32_t x = 0; x < w; x++) {
|
||||
size_t i = (size_t)y * waymini_get_stride(wm) + (size_t)x * 4;
|
||||
pixels[i + 0] = (uint8_t)(y * 255 / h); /* B */
|
||||
pixels[i + 1] = 0x00; /* G */
|
||||
pixels[i + 2] = (uint8_t)(x * 255 / w); /* R */
|
||||
pixels[i + 3] = 0xFF; /* A (ignored for XRGB) */
|
||||
}
|
||||
}
|
||||
|
||||
waymini_present(wm);
|
||||
pixels[200001] = 255;
|
||||
|
||||
while (!waymini_should_close(wm)) {
|
||||
if (waymini_dispatch(wm) < 0) break;
|
||||
}
|
||||
|
||||
waymini_destroy(wm);
|
||||
return 0;
|
||||
}
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
XML="/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml"
|
||||
if [ ! -f "$XML" ]; then
|
||||
echo "Cannot find xdg-shell XML at: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTDIR="."
|
||||
mkdir -p "$OUTDIR"
|
||||
|
||||
wayland-scanner client-header "$XML" "$OUTDIR/xdg-shell-client-protocol.h"
|
||||
wayland-scanner private-code "$XML" "$OUTDIR/xdg-shell-client-protocol.c"
|
||||
|
||||
echo "Generated:"
|
||||
ls -l "$OUTDIR/xdg-shell-client-protocol.h" "$OUTDIR/xdg-shell-client-protocol.c"
|
||||
Binary file not shown.
@@ -0,0 +1,366 @@
|
||||
#define _GNU_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "waymini.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/memfd.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
struct shm_state {
|
||||
int fd;
|
||||
size_t size;
|
||||
void *map;
|
||||
struct wl_shm *shm_iface;
|
||||
struct wl_buffer *wl_buffer;
|
||||
};
|
||||
|
||||
struct window_state {
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_surface *surface;
|
||||
struct xdg_wm_base *wm_base;
|
||||
struct xdg_surface *xdg_surface;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
|
||||
uint32_t width, height;
|
||||
uint32_t bpp;
|
||||
uint32_t stride;
|
||||
int configured;
|
||||
};
|
||||
|
||||
struct input_state {
|
||||
struct wl_seat *seat;
|
||||
struct wl_keyboard *keyboard;
|
||||
|
||||
waymini_key_cb on_keycode;
|
||||
void *user;
|
||||
};
|
||||
|
||||
struct waymini {
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm_iface;
|
||||
struct xdg_wm_base *wm_base;
|
||||
|
||||
struct shm_state shm;
|
||||
struct window_state win;
|
||||
struct input_state in;
|
||||
|
||||
int should_close;
|
||||
};
|
||||
|
||||
static void on_xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) {
|
||||
struct waymini *wm = data;
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
wm->win.configured = 1;
|
||||
}
|
||||
|
||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||
.configure = on_xdg_surface_configure,
|
||||
};
|
||||
|
||||
static void on_toplevel_configure(void *data, struct xdg_toplevel *toplevel,
|
||||
int32_t width, int32_t height,
|
||||
struct wl_array *states) {
|
||||
(void)data; (void)toplevel; (void)width; (void)height; (void)states;
|
||||
}
|
||||
|
||||
static void on_toplevel_close(void *data, struct xdg_toplevel *toplevel) {
|
||||
(void)toplevel;
|
||||
struct waymini *wm = data;
|
||||
wm->should_close = 1;
|
||||
}
|
||||
|
||||
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
||||
.configure = on_toplevel_configure,
|
||||
.close = on_toplevel_close,
|
||||
};
|
||||
|
||||
static void on_wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial) {
|
||||
(void)data;
|
||||
xdg_wm_base_pong(wm_base, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_listener wm_base_listener = {
|
||||
.ping = on_wm_base_ping,
|
||||
};
|
||||
|
||||
static void on_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {
|
||||
(void)keyboard;
|
||||
struct input_state *in = data;
|
||||
|
||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
char *buf = malloc(size);
|
||||
if (buf) {
|
||||
size_t off = 0;
|
||||
while (off < size) {
|
||||
ssize_t r = read(fd, buf + off, size - off);
|
||||
if (r <= 0) break;
|
||||
off += (size_t)r;
|
||||
}
|
||||
free(buf);
|
||||
} else {
|
||||
(void)read(fd, buf, 0);
|
||||
}
|
||||
close(fd);
|
||||
(void)in;
|
||||
}
|
||||
|
||||
static void on_keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
|
||||
uint32_t time, uint32_t key, uint32_t state) {
|
||||
(void)keyboard; (void)serial; (void)time;
|
||||
struct input_state *in = data;
|
||||
if (in->on_keycode) in->on_keycode(in->user, key, state);
|
||||
}
|
||||
|
||||
static void on_keyboard_enter(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, struct wl_surface *surface,
|
||||
struct wl_array *keys) {
|
||||
(void)data; (void)keyboard; (void)serial; (void)surface; (void)keys;
|
||||
}
|
||||
|
||||
static void on_keyboard_leave(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, struct wl_surface *surface) {
|
||||
(void)data; (void)keyboard; (void)serial; (void)surface;
|
||||
}
|
||||
|
||||
static void on_keyboard_modifiers(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, uint32_t mods_depressed,
|
||||
uint32_t mods_latched, uint32_t mods_locked,
|
||||
uint32_t group) {
|
||||
(void)data; (void)keyboard; (void)serial;
|
||||
(void)mods_depressed; (void)mods_latched; (void)mods_locked; (void)group;
|
||||
}
|
||||
|
||||
static void on_keyboard_repeat_info(void *data, struct wl_keyboard *keyboard,
|
||||
int32_t rate, int32_t delay) {
|
||||
(void)data; (void)keyboard; (void)rate; (void)delay;
|
||||
}
|
||||
|
||||
static const struct wl_keyboard_listener keyboard_listener = {
|
||||
.keymap = on_keymap,
|
||||
.enter = on_keyboard_enter,
|
||||
.leave = on_keyboard_leave,
|
||||
.key = on_keyboard_key,
|
||||
.modifiers = on_keyboard_modifiers,
|
||||
.repeat_info = on_keyboard_repeat_info,
|
||||
};
|
||||
|
||||
static void on_seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) {
|
||||
struct input_state *in = data;
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !in->keyboard) {
|
||||
in->seat = seat;
|
||||
in->keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(in->keyboard, &keyboard_listener, in);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_seat_name(void *data, struct wl_seat *seat, const char *name) {
|
||||
(void)data; (void)seat; (void)name;
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
.capabilities = on_seat_capabilities,
|
||||
.name = on_seat_name,
|
||||
};
|
||||
|
||||
static void on_registry_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version) {
|
||||
struct waymini *wm = data;
|
||||
(void)registry;
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0) {
|
||||
wm->compositor = wl_registry_bind(wm->registry, name, &wl_compositor_interface, 4);
|
||||
} else if (strcmp(interface, "wl_shm") == 0) {
|
||||
wm->shm_iface = wl_registry_bind(wm->registry, name, &wl_shm_interface, 1);
|
||||
wm->shm.shm_iface = wm->shm_iface;
|
||||
} else if (strcmp(interface, "xdg_wm_base") == 0) {
|
||||
wm->wm_base = wl_registry_bind(wm->registry, name, &xdg_wm_base_interface, 1);
|
||||
xdg_wm_base_add_listener(wm->wm_base, &wm_base_listener, wm);
|
||||
} else if (strcmp(interface, "wl_seat") == 0) {
|
||||
struct wl_seat *seat = wl_registry_bind(wm->registry, name, &wl_seat_interface, version);
|
||||
wl_seat_add_listener(seat, &seat_listener, &wm->in);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_registry_global_remove(void *data, struct wl_registry *registry, uint32_t name) {
|
||||
(void)data; (void)registry; (void)name;
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = on_registry_global,
|
||||
.global_remove = on_registry_global_remove,
|
||||
};
|
||||
|
||||
static void waymini_destroy_internal(struct waymini *wm);
|
||||
|
||||
static int create_shm_buffer(struct waymini *wm) {
|
||||
struct shm_state *s = &wm->shm;
|
||||
struct window_state *w = &wm->win;
|
||||
|
||||
s->size = (size_t)w->stride * (size_t)w->height;
|
||||
s->fd = memfd_create("waymini-shm", MFD_CLOEXEC);
|
||||
if (s->fd < 0) { perror("memfd_create"); return -1; }
|
||||
|
||||
if (ftruncate(s->fd, (off_t)s->size) < 0) { perror("ftruncate"); return -1; }
|
||||
|
||||
s->map = mmap(NULL, s->size, PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, 0);
|
||||
if (s->map == MAP_FAILED) { perror("mmap"); return -1; }
|
||||
|
||||
struct wl_buffer *buf;
|
||||
struct wl_shm_pool *pool = wl_shm_create_pool(s->shm_iface, s->fd, (int)s->size);
|
||||
buf = wl_shm_pool_create_buffer(pool, 0, w->width, w->height, (int)w->stride, WL_SHM_FORMAT_XRGB8888);
|
||||
wl_shm_pool_destroy(pool);
|
||||
if (!buf) { fprintf(stderr, "wl_shm_pool_create_buffer failed\n"); return -1; }
|
||||
|
||||
s->wl_buffer = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct waymini *waymini_create(uint32_t width, uint32_t height,
|
||||
waymini_key_cb key_cb, void *user) {
|
||||
struct waymini *wm = calloc(1, sizeof(*wm));
|
||||
if (!wm) return NULL;
|
||||
|
||||
wm->display = wl_display_connect(NULL);
|
||||
if (!wm->display) { fprintf(stderr, "wl_display_connect failed\n"); free(wm); return NULL; }
|
||||
|
||||
wm->registry = wl_display_get_registry(wm->display);
|
||||
wl_registry_add_listener(wm->registry, ®istry_listener, wm);
|
||||
wl_display_roundtrip(wm->display);
|
||||
|
||||
if (!wm->compositor || !wm->shm_iface || !wm->wm_base) {
|
||||
fprintf(stderr, "missing globals\n");
|
||||
waymini_destroy_internal(wm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wm->win.compositor = wm->compositor;
|
||||
wm->win.surface = wl_compositor_create_surface(wm->compositor);
|
||||
|
||||
wm->win.xdg_surface = xdg_wm_base_get_xdg_surface(wm->wm_base, wm->win.surface);
|
||||
xdg_surface_add_listener(wm->win.xdg_surface, &xdg_surface_listener, wm);
|
||||
|
||||
wm->win.xdg_toplevel = xdg_surface_get_toplevel(wm->win.xdg_surface);
|
||||
xdg_toplevel_add_listener(wm->win.xdg_toplevel, &xdg_toplevel_listener, wm);
|
||||
xdg_toplevel_set_title(wm->win.xdg_toplevel, "waymini");
|
||||
xdg_toplevel_set_app_id(wm->win.xdg_toplevel, "waymini");
|
||||
|
||||
wm->in.on_keycode = key_cb;
|
||||
wm->in.user = user;
|
||||
|
||||
wm->win.width = width;
|
||||
wm->win.height = height;
|
||||
wm->win.bpp = 4;
|
||||
wm->win.stride = width * wm->win.bpp;
|
||||
|
||||
wl_surface_commit(wm->win.surface);
|
||||
|
||||
while (!wm->win.configured) {
|
||||
if (wl_display_dispatch(wm->display) < 0) {
|
||||
fprintf(stderr, "dispatch failed waiting for configure\n");
|
||||
waymini_destroy_internal(wm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (create_shm_buffer(wm) < 0) {
|
||||
fprintf(stderr, "create_shm_buffer failed\n");
|
||||
waymini_destroy_internal(wm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wm;
|
||||
}
|
||||
|
||||
uint32_t waymini_get_width(const struct waymini *wm) { return wm ? wm->win.width : 0; }
|
||||
uint32_t waymini_get_height(const struct waymini *wm) { return wm ? wm->win.height : 0; }
|
||||
uint32_t waymini_get_stride(const struct waymini *wm) { return wm ? wm->win.stride : 0; }
|
||||
void *waymini_get_pixels(const struct waymini *wm) { return wm ? wm->shm.map : NULL; }
|
||||
|
||||
void waymini_present(struct waymini *wm) {
|
||||
if (!wm || !wm->win.configured) return;
|
||||
wl_surface_attach(wm->win.surface, wm->shm.wl_buffer, 0, 0);
|
||||
wl_surface_commit(wm->win.surface);
|
||||
wl_display_flush(wm->display);
|
||||
}
|
||||
|
||||
int waymini_dispatch(struct waymini *wm) {
|
||||
if (!wm || !wm->display) return -1;
|
||||
return wl_display_dispatch(wm->display);
|
||||
}
|
||||
|
||||
int waymini_poll(struct waymini *wm) {
|
||||
if (!wm || !wm->display) return -1;
|
||||
wl_display_dispatch_pending(wm->display);
|
||||
wl_display_flush(wm->display);
|
||||
int ret = wl_display_prepare_read(wm->display);
|
||||
if (ret < 0) return wl_display_dispatch_pending(wm->display) >= 0 ? 1 : -1;
|
||||
|
||||
int fd = wl_display_get_fd(wm->display);
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
struct timeval tv = { 0, 0 };
|
||||
ret = select(fd + 1, &rfds, NULL, NULL, &tv);
|
||||
if (ret > 0) {
|
||||
wl_display_read_events(wm->display);
|
||||
wl_display_dispatch_pending(wm->display);
|
||||
return 1;
|
||||
}
|
||||
wl_display_cancel_read(wm->display);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void waymini_request_close(struct waymini *wm) {
|
||||
if (wm) wm->should_close = 1;
|
||||
}
|
||||
|
||||
int waymini_should_close(const struct waymini *wm) {
|
||||
return wm ? wm->should_close : 0;
|
||||
}
|
||||
|
||||
static void waymini_destroy_internal(struct waymini *wm) {
|
||||
if (!wm) return;
|
||||
|
||||
if (wm->in.keyboard) wl_keyboard_destroy(wm->in.keyboard);
|
||||
if (wm->in.seat) wl_seat_destroy(wm->in.seat);
|
||||
|
||||
if (wm->shm.wl_buffer) wl_buffer_destroy(wm->shm.wl_buffer);
|
||||
if (wm->shm.map && wm->shm.size) munmap(wm->shm.map, wm->shm.size);
|
||||
if (wm->shm.fd >= 0) close(wm->shm.fd);
|
||||
|
||||
if (wm->win.xdg_toplevel) xdg_toplevel_destroy(wm->win.xdg_toplevel);
|
||||
if (wm->win.xdg_surface) xdg_surface_destroy(wm->win.xdg_surface);
|
||||
if (wm->win.surface) wl_surface_destroy(wm->win.surface);
|
||||
|
||||
if (wm->wm_base) xdg_wm_base_destroy(wm->wm_base);
|
||||
if (wm->compositor) wl_compositor_destroy(wm->compositor);
|
||||
if (wm->shm_iface) wl_shm_destroy(wm->shm_iface);
|
||||
|
||||
if (wm->registry) wl_registry_destroy(wm->registry);
|
||||
if (wm->display) wl_display_disconnect(wm->display);
|
||||
free(wm);
|
||||
}
|
||||
|
||||
void waymini_destroy(struct waymini *wm) {
|
||||
waymini_destroy_internal(wm);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef WAYMINI_H
|
||||
#define WAYMINI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct waymini;
|
||||
|
||||
typedef void (*waymini_key_cb)(void *user, uint32_t keycode, uint32_t state);
|
||||
|
||||
/* Create a Wayland surface of the requested dimensions.
|
||||
* key_cb may be NULL if keyboard input is not needed.
|
||||
*/
|
||||
struct waymini *waymini_create(uint32_t width, uint32_t height,
|
||||
waymini_key_cb key_cb, void *user);
|
||||
|
||||
/* Dimensions and pixel access. */
|
||||
uint32_t waymini_get_width(const struct waymini *wm);
|
||||
uint32_t waymini_get_height(const struct waymini *wm);
|
||||
uint32_t waymini_get_stride(const struct waymini *wm);
|
||||
void *waymini_get_pixels(const struct waymini *wm);
|
||||
|
||||
/* Mark the SHM buffer as changed and commit it to the compositor. */
|
||||
void waymini_present(struct waymini *wm);
|
||||
|
||||
/* Dispatch one or more Wayland events. Returns 0 on success, -1 on error.
|
||||
* Blocks until at least one event is processed.
|
||||
*/
|
||||
int waymini_dispatch(struct waymini *wm);
|
||||
|
||||
/* Non-blocking poll for events. Returns 1 if events were dispatched, 0 if no
|
||||
* events were available, and -1 on error.
|
||||
*/
|
||||
int waymini_poll(struct waymini *wm);
|
||||
|
||||
/* Request a graceful close (e.g. from the toplevel close button). */
|
||||
void waymini_request_close(struct waymini *wm);
|
||||
|
||||
/* Returns non-zero when the compositor asked us to close. */
|
||||
int waymini_should_close(const struct waymini *wm);
|
||||
|
||||
/* Clean up. */
|
||||
void waymini_destroy(struct waymini *wm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WAYMINI_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
/* Standalone demo equivalent to the original waymini.c main(). */
|
||||
|
||||
#include "waymini.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void on_keycode(void *user, uint32_t keycode, uint32_t state) {
|
||||
(void)user;
|
||||
printf("key=%u state=%u\n", keycode, state);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint32_t w = 320, h = 200;
|
||||
struct waymini *wm = waymini_create(w, h, on_keycode, NULL);
|
||||
if (!wm) return 1;
|
||||
|
||||
uint8_t *p = (uint8_t *)waymini_get_pixels(wm);
|
||||
for (uint32_t y = 0; y < h; y++) {
|
||||
for (uint32_t x = 0; x < w; x++) {
|
||||
size_t i = (size_t)y * waymini_get_stride(wm) + (size_t)x * 4;
|
||||
p[i + 0] = 0x20;
|
||||
p[i + 1] = (uint8_t)(y * 255 / h);
|
||||
p[i + 2] = (uint8_t)(x * 255 / w);
|
||||
p[i + 3] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
waymini_present(wm);
|
||||
|
||||
while (!waymini_should_close(wm)) {
|
||||
if (waymini_dispatch(wm) < 0) break;
|
||||
}
|
||||
|
||||
waymini_destroy(wm);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/* Generated by wayland-scanner 1.25.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2008-2013 Kristian Høgsberg
|
||||
* Copyright © 2013 Rafael Antognolli
|
||||
* Copyright © 2013 Jasper St. Pierre
|
||||
* Copyright © 2010-2013 Intel Corporation
|
||||
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||
* Copyright © 2015-2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface xdg_positioner_interface;
|
||||
extern const struct wl_interface xdg_surface_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *xdg_shell_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&xdg_popup_interface,
|
||||
&xdg_surface_interface,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_output_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||
{ "pong", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_events[] = {
|
||||
{ "ping", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||
"xdg_wm_base", 7,
|
||||
4, xdg_wm_base_requests,
|
||||
1, xdg_wm_base_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_positioner_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||
"xdg_positioner", 7,
|
||||
10, xdg_positioner_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_events[] = {
|
||||
{ "configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||
"xdg_surface", 7,
|
||||
5, xdg_surface_requests,
|
||||
1, xdg_surface_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||
{ "set_title", "s", xdg_shell_types + 0 },
|
||||
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||
{ "move", "ou", xdg_shell_types + 16 },
|
||||
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_events[] = {
|
||||
{ "configure", "iia", xdg_shell_types + 0 },
|
||||
{ "close", "", xdg_shell_types + 0 },
|
||||
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||
"xdg_toplevel", 7,
|
||||
14, xdg_toplevel_requests,
|
||||
4, xdg_toplevel_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "grab", "ou", xdg_shell_types + 22 },
|
||||
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_events[] = {
|
||||
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||
{ "popup_done", "", xdg_shell_types + 0 },
|
||||
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||
"xdg_popup", 7,
|
||||
3, xdg_popup_requests,
|
||||
3, xdg_popup_events,
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Reference in New Issue
Block a user