한국어
Linux Programming
 

Wayland 의 Client Application 프로그래밍 시 기본 루틴을 설명

 

1. wl_display를 가져 와서 wl_registry를 얻는다. 

struct wl_display *display = NULL;

display = wl_display_connect(NULL);
struct wl_registry *registry = wl_display_get_registry(display);

 

2. 레지스트리를 스캔하고 wl_compositor 및 wl_shm_pool을 가져온다.

struct wl_compositor *compositor = NULL;

struct wl_shm_listener shm_listener = {
    shm_format
};

static void global_registry_handler(void *data, struct wl_registry *registry, uint32_t id,
      const char *interface, uint32_t version)
{
    if (strcmp(interface, "wl_compositor") == 0) {
        compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
    } else if (strcmp(interface, "wl_shell") == 0) {
        shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
    } else if (strcmp(interface, "wl_shm") == 0) {
        shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
        wl_shm_add_listener(shm, &shm_listener, NULL);
    }
}

static void global_registry_remover(void *data, struct wl_registry *registry, uint32_t id)
{
    printf("Got a registry losing event for %d\n", id);
}

static const struct wl_registry_listener registry_listener = {
    global_registry_handler,
    global_registry_remover
};

wl_registry_add_listener(registry, &registryListener, this);

 

3. wl_compositor 인터페이스를 사용하여 wl_surface를 생성한다.

struct wl_surface *surface = NULL;

surface = wl_compositor_create_surface(compositor);

 

4. 표면의 역할을 부여하기 위해 wl_shell 인터페이스를 사용

struct wl_shell_surface *shell_surface = NULL;
shell_surface = wl_shell_get_shell_surface(shell, surface); // 역할 부여

wl_shell_surface_set_toplevel(shell_surface);
wl_shell_surface_add_listener(shell_surface, &shell_surface_listener, NULL);

 

5. wl_shm 인터페이스를 사용하여 픽셀을 저장할 공유 메모리를 할당하고 공유 메모리 버퍼를 wl_surface에 연결한다.

void *shm_data;

int WIDTH = 480;
int HEIGHT = 360;

int os_create_anonymous_file(off_t size)
{
    static const char template[] = "/weston-shared-XXXXXX";
    const char *path;
    char *name;
    int fd;
    
    path = getenv("XDG_RUNTIME_DIR");
    if (!path) {
        errno = ENOENT;
        return -1;
    }
    
    name = malloc(strlen(path) + sizeof(template));
    if (!name)
        return -1;
    strcpy(name, path);
    strcat(name, template);
    
    fd = create_tmpfile_cloexec(name);
    
    free(name);
    
    if (fd < 0)
        return -1;
    
    if (ftruncate(fd, size) < 0) {
        close(fd);
        return -1;
    }
    
    return fd;
}

static struct wl_buffer *create_buffer() {
    struct wl_shm_pool *pool;
    int stride = WIDTH * 4; // 4 bytes per pixel
    int size = stride * HEIGHT;
    int fd;
    struct wl_buffer *buff;

    fd = os_create_anonymous_file(size);
    if (fd < 0) {
        fprintf(stderr, "creating a buffer file for %d B failed: %m\n", size);
        exit(1);
    }
   
    shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (shm_data == MAP_FAILED) {
        fprintf(stderr, "mmap failed: %m\n");
        close(fd);
        exit(1);
    }

    pool = wl_shm_create_pool(shm, fd, size);
    buff = wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, stride, WL_SHM_FORMAT_XRGB8888);
    //wl_buffer_add_listener(buffer, &buffer_listener, buffer);
    wl_shm_pool_destroy(pool);
    return buff;
}

static void create_shm() {
    buffer = create_buffer();
    wl_surface_attach(surface, buffer, 0, 0);
    wl_surface_commit(surface);
}

 

6. 공유 메모리 버퍼에 뭔가를 그린다.

static void paint_pixels() {
    int n;
    uint32_t *pixel = shm_data;

    fprintf(stderr, "Painting pixels\n");
    for (n =0; n < WIDTH * HEIGHT; n++) {
        *pixel++ = 0xffff;
    }
}

 

7. 이벤트 처리를 요청한다.

// 이벤트를 처리.
while (wl_display_dispatch(display) != -1) {
    ;
}

 

번호 제목 글쓴이 날짜 조회 수
36 dbus-broker를 기본 DBus 구현으로 설정 makersweb 2021.01.20 1
35 리눅스 오디오 스택과 아키텍처 file makersweb 2020.09.02 234
34 wayland-scanner 를 통해 Wayland 프로토콜 코드생성 makersweb 2020.06.08 65
» Wayland 의 Client Application 프로그래밍 기본 루틴 makersweb 2020.06.04 114
32 Wayland 의 주요 객체들 makersweb 2020.06.04 75
31 Weston 의 설명 및 관련 컴포넌트 makersweb 2020.06.03 175
30 64비트 리눅스에서 32비트 응용프로그램을 실행하려면 makersweb 2020.02.29 504
29 initramfs (initial ram file system: 초기 램 파일 시스템) makersweb 2020.02.25 251
28 플랫폼 디바이스 드라이버 개발 시 많이 사용되는 커널 API 및 매크로 makersweb 2020.01.28 637
27 PATH에 새로운 경로 추가 makersweb 2019.09.19 119
26 리눅스 컴파일러 최신으로 업데이트 linux 2018.12.26 1312
25 libblkid - USB Storage의 정보 가져오기 makersweb 2018.10.18 286
24 tslib 크로스 컴파일과 터치스크린 보정 makersweb 2018.08.02 1189
23 Ubuntu Linux에서 dbus-c++바인딩 D-Bus 테스트 file makersweb 2018.03.07 4050
22 NFS를 통해 파일시스템 공유 makersweb 2018.03.05 716
21 Wayland에 대한 간단한 소개 file makersweb 2017.12.29 1794
20 Ubuntu16.04에서 weston구동 file makersweb 2017.12.28 472
19 UVC 장치를 사용할때 v4l2: select timeout 에러 발생 makersweb 2017.12.27 813
18 [IPC]D-Bus 소개 file makersweb 2015.02.28 25934
17 리눅스 데스크탑 환경 종류 pjk 2015.02.11 4152