手機 - Motorola XT894 - Sailfish OS - Wayland (Client) - Create Buffer



參考資訊:
https://jan.newmarch.name/Wayland/index.html
https://wayland.freedesktop.org/docs/html/apa.html
https://bugaevc.gitbooks.io/writing-wayland-clients/content/

main.c

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include <wayland-client.h>
  
#define WIDTH       540
#define HEIGHT      960
#define STRIDE      (WIDTH * 2)
#define SIZE        (STRIDE * HEIGHT)
#define SHM_NAME    "/tmp/shm"

struct wl_shm *shm = NULL;
struct wl_buffer *buf = NULL;
struct wl_shell *shell = NULL;
struct wl_display *dis = NULL;
struct wl_surface *surf = NULL;
struct wl_registry *reg = NULL;
struct wl_shm_pool *pool = NULL;
struct wl_compositor *comp = NULL;
struct wl_shell_surface *shell_surf = NULL;
  
void cb_handle(void *dat, struct wl_registry *reg, uint32_t id, const char *intf, uint32_t ver)
{
    if (strcmp(intf, "wl_compositor") == 0) {
        comp = wl_registry_bind(reg, id, &wl_compositor_interface, 3);
    }
    else if (strcmp(intf, "wl_shm") == 0) {
        shm = wl_registry_bind(reg, id, &wl_shm_interface, 1);
    }
    else if (strcmp(intf, "wl_shell") == 0) {
        shell = wl_registry_bind(reg, id, &wl_shell_interface, 1);
    }
}
  
void cb_remove(void *dat, struct wl_registry *reg, uint32_t id)
{
}
  
struct wl_registry_listener cb = {
    .global = cb_handle,
    .global_remove = cb_remove
};
  
int main(int argc, char **argv)
{
    dis = wl_display_connect(NULL);
    reg = wl_display_get_registry(dis);
   
    wl_registry_add_listener(reg, &cb, NULL);
    wl_display_dispatch(dis);
    wl_display_roundtrip(dis);
    surf = wl_compositor_create_surface(comp);
    shell_surf = wl_shell_get_shell_surface(shell, surf);
    wl_shell_surface_set_toplevel(shell_surf);
   
    int fd = open(SHM_NAME, O_RDWR | O_EXCL | O_CREAT);
    ftruncate(fd, SIZE);
   
    uint16_t *addr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    pool = wl_shm_create_pool(shm, fd, SIZE);
    buf = wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, STRIDE, WL_SHM_FORMAT_RGB565);
    wl_shm_pool_destroy(pool);
  
    printf("pool = 0x%08x\n", pool);
    printf("buf  = 0x%08x\n", buf);
    printf("mmap = 0x%08x\n", addr);
   
    wl_surface_attach(surf, buf, 0, 0);
    wl_surface_commit(surf);
    wl_display_dispatch(dis);
    wl_display_roundtrip(dis);
 
    wl_shell_surface_destroy(shell_surf);
    wl_shell_destroy(shell);
    wl_surface_destroy(surf);
    wl_buffer_destroy(buf);
    wl_shm_destroy(shm);
    wl_compositor_destroy(comp);
    wl_registry_destroy(reg);
    wl_display_disconnect(dis);
    munmap(addr, SIZE);
    close(fd);
    unlink(SHM_NAME);
    return 0;
}

編譯、執行

$ gcc main.c -o main -lwayland-client
$ ./main
    pool = 0x01f1b2e8
    buf  = 0x01f1b318
    mmap = 0x401fd000