Init
Signed-off-by: Arkadiusz Rychliński <ar@ar76.eu>
This commit is contained in:
commit
517e2c3892
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
build/
|
||||
.vscode/
|
38
CMakeLists.txt
Normal file
38
CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(tetris)
|
||||
|
||||
# Pobranie pliku xdg-shell.xml
|
||||
# file(DOWNLOAD "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/stable/xdg-shell/xdg-shell.xml" "${CMAKE_CURRENT_BINARY_DIR}/xdg-shell.xml")
|
||||
|
||||
# Wygenerowanie plików xdg-shell.h i xdg-shell.c
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/xdg-shell.h
|
||||
COMMAND wayland-scanner client-header ${CMAKE_SOURCE_DIR}/xdg-shell.xml ${CMAKE_CURRENT_BINARY_DIR}/include/xdg-shell.h
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/xdg-shell.xml
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell.c
|
||||
COMMAND wayland-scanner private-code ${CMAKE_SOURCE_DIR}/xdg-shell.xml ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell.c
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/xdg-shell.xml
|
||||
)
|
||||
|
||||
# Dodanie plików źródłowych
|
||||
set(SOURCES
|
||||
tetris.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell.c
|
||||
)
|
||||
|
||||
# Dodaj pliki nagłówkowe do źródeł tetris
|
||||
set(HEADERS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/xdg-shell.h
|
||||
)
|
||||
|
||||
# Kompilacja
|
||||
add_executable(tetris ${SOURCES} ${HEADERS})
|
||||
|
||||
# Dodaj pliki nagłówkowe do kompilacji
|
||||
target_include_directories(tetris PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
|
||||
# Dodanie biblioteki wayland-client
|
||||
target_link_libraries(tetris wayland-client)
|
216
tetris.c
Normal file
216
tetris.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <xdg-shell.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct xdg_wm_base *xdg_shell;
|
||||
struct wl_seat *wl_seat;
|
||||
|
||||
int running = 1;
|
||||
|
||||
// registry
|
||||
void registry_global_handler(
|
||||
void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
// printf(" -> %s\n", interface);
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0)
|
||||
{
|
||||
compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 3);
|
||||
printf("Got wl_compositor\n");
|
||||
}
|
||||
else if (strcmp(interface, wl_shm_interface.name) == 0)
|
||||
{
|
||||
shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
||||
printf("Got wl_shm\n");
|
||||
}
|
||||
else if (strcmp(interface, xdg_wm_base_interface.name) == 0)
|
||||
{
|
||||
xdg_shell = wl_registry_bind(registry, name, &xdg_wm_base_interface, 4);
|
||||
printf("Got xdg_wm_base\n");
|
||||
}
|
||||
else if (strcmp(interface, wl_seat_interface.name) == 0)
|
||||
{
|
||||
wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 5);
|
||||
printf("Got wl_seat (%d)\n", version);
|
||||
}
|
||||
}
|
||||
|
||||
void registry_global_remove_handler(
|
||||
void *data, struct wl_registry *registry,
|
||||
uint32_t name)
|
||||
{
|
||||
// notging
|
||||
}
|
||||
|
||||
const struct wl_registry_listener registry_listener = {
|
||||
.global = registry_global_handler,
|
||||
.global_remove = registry_global_remove_handler};
|
||||
|
||||
// xdg_toplevel
|
||||
void xdg_toplevel_configure_handler(
|
||||
void *data,
|
||||
struct xdg_toplevel *xdg_toplevel,
|
||||
int32_t width, int32_t height,
|
||||
struct wl_array *states)
|
||||
{
|
||||
printf("xdg_toplevel_configure: %dx%d\n", width, height);
|
||||
}
|
||||
|
||||
void xdg_toplevel_close_handler(void *data, struct xdg_toplevel *xdg_toplevel)
|
||||
{
|
||||
printf("xdg_toplevel_close\n");
|
||||
running = 0;
|
||||
}
|
||||
|
||||
void xdg_toplevel_configure_bounds_handler(
|
||||
void *data,
|
||||
struct xdg_toplevel *xdg_toplevel,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
||||
.configure = xdg_toplevel_configure_handler,
|
||||
.close = xdg_toplevel_close_handler,
|
||||
.configure_bounds = xdg_toplevel_configure_bounds_handler};
|
||||
|
||||
// xdg_surface
|
||||
void xdg_surface_configure_handler(void *data, struct xdg_surface *xdg_surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
printf("xdg_surface_configure\n");
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
}
|
||||
|
||||
const struct xdg_surface_listener xdg_surface_listener = {
|
||||
.configure = xdg_surface_configure_handler};
|
||||
|
||||
// xdg_shell
|
||||
void xdg_wm_base_ping_handler(void *data, struct xdg_wm_base *xdg_shell,
|
||||
uint32_t serial)
|
||||
{
|
||||
xdg_wm_base_pong(xdg_shell, serial);
|
||||
printf("wm_base ping-pong\n");
|
||||
}
|
||||
|
||||
const struct xdg_wm_base_listener xdg_shell_listener = {
|
||||
.ping = xdg_wm_base_ping_handler};
|
||||
|
||||
// main
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct wl_display *display = wl_display_connect(NULL);
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||
|
||||
// wait for the "initial" set of globals to appear
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
xdg_wm_base_add_listener(xdg_shell, &xdg_shell_listener, NULL);
|
||||
|
||||
struct wl_surface *surface = wl_compositor_create_surface(compositor);
|
||||
struct xdg_surface *xdg_surface = xdg_wm_base_get_xdg_surface(xdg_shell, surface);
|
||||
struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);
|
||||
|
||||
xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL);
|
||||
xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL);
|
||||
|
||||
xdg_toplevel_set_app_id(xdg_toplevel, "ark-1");
|
||||
xdg_toplevel_set_title(xdg_toplevel, "Ark Jeden.");
|
||||
|
||||
// signal that the surface is ready to be configured
|
||||
wl_surface_commit(surface);
|
||||
|
||||
struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat);
|
||||
|
||||
int width = 600;
|
||||
int height = 800;
|
||||
int stride = width * 4;
|
||||
int size = stride * height; // bytes
|
||||
|
||||
// open an anonymous file and write some zero bytes to it
|
||||
int fd = syscall(SYS_memfd_create, "buffer", 0);
|
||||
ftruncate(fd, size);
|
||||
|
||||
// map it to the memory
|
||||
unsigned char *data =
|
||||
mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
// turn it into a shared memory pool
|
||||
struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
|
||||
|
||||
// allocate the buffer in that pool
|
||||
struct wl_buffer *buffer = wl_shm_pool_create_buffer(
|
||||
pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
|
||||
|
||||
// draw into buffer
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
|
||||
struct pixel
|
||||
{
|
||||
// little-endian ARGB
|
||||
unsigned char blue;
|
||||
unsigned char green;
|
||||
unsigned char red;
|
||||
unsigned char alpha;
|
||||
} *px = (struct pixel *)(data + y * stride + x * 4);
|
||||
|
||||
// draw a stripes pattern
|
||||
if ((x + y) % 30 < 10)
|
||||
{
|
||||
// transparent
|
||||
px->alpha = 0;
|
||||
}
|
||||
else if ((x + y) % 30 < 20)
|
||||
{
|
||||
// yellow
|
||||
px->alpha = 255;
|
||||
px->red = 255;
|
||||
px->green = 255;
|
||||
px->blue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// semitransparent red
|
||||
px->alpha = 128;
|
||||
px->red = 255;
|
||||
px->green = 0;
|
||||
px->blue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wait for the surface to be configured
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
wl_surface_attach(surface, buffer, 0, 0);
|
||||
wl_surface_damage(surface, 0, 0, UINT32_MAX, UINT32_MAX);
|
||||
wl_surface_commit(surface);
|
||||
|
||||
while (wl_display_dispatch(display) != -1 && running)
|
||||
{
|
||||
// nothing inside
|
||||
}
|
||||
|
||||
xdg_toplevel_destroy(xdg_toplevel);
|
||||
xdg_surface_destroy(xdg_surface);
|
||||
wl_surface_destroy(surface);
|
||||
wl_registry_destroy(registry);
|
||||
}
|
1386
xdg-shell.xml
Normal file
1386
xdg-shell.xml
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user