한국어
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) {
    ;
}

 

이 글과 연관된 다른 글
  1. [2020/06/04] Wayland 의 주요 객체들 by makersweb (15)
  2. [2020/06/03] Weston 의 설명 및 관련 컴포넌트 by makersweb (15)
  3. [2019/05/12] Wayland IVI Extension 간단 리뷰 by makersweb (928)
  4. [2017/12/29] Wayland에 대한 간단한 소개 by makersweb (1543)
  5. [2017/12/28] Ubuntu16.04에서 weston구동 by makersweb (413)
번호 제목 글쓴이 날짜 조회 수
35 리눅스 오디오 스택과 아키텍처 file makersweb 2020.09.02 21
34 wayland-scanner 를 통해 Wayland 프로토콜 코드생성 makersweb 2020.06.08 6
» Wayland 의 Client Application 프로그래밍 기본 루틴 makersweb 2020.06.04 23
32 Wayland 의 주요 객체들 makersweb 2020.06.04 15
31 Weston 의 설명 및 관련 컴포넌트 makersweb 2020.06.03 15
30 64비트 리눅스에서 32비트 응용프로그램을 실행하려면 makersweb 2020.02.29 309
29 initramfs (initial ram file system: 초기 램 파일 시스템) makersweb 2020.02.25 85
28 플랫폼 디바이스 드라이버 개발 시 많이 사용되는 커널 API 및 매크로 makersweb 2020.01.28 338
27 PATH에 새로운 경로 추가 makersweb 2019.09.19 90
26 리눅스 컴파일러 최신으로 업데이트 linux 2018.12.26 1165
25 libblkid - USB Storage의 정보 가져오기 makersweb 2018.10.18 241
24 tslib 크로스 컴파일과 터치스크린 보정 makersweb 2018.08.02 1016
23 Ubuntu Linux에서 dbus-c++바인딩 D-Bus 테스트 file makersweb 2018.03.07 3650
22 NFS를 통해 파일시스템 공유 makersweb 2018.03.05 666
21 Wayland에 대한 간단한 소개 file makersweb 2017.12.29 1543
20 Ubuntu16.04에서 weston구동 file makersweb 2017.12.28 413
19 UVC 장치를 사용할때 v4l2: select timeout 에러 발생 makersweb 2017.12.27 651
18 [IPC]D-Bus 소개 file makersweb 2015.02.28 25321
17 리눅스 데스크탑 환경 종류 pjk 2015.02.11 4114
16 디바이스 드라이버에 대해서 makersweb 2014.04.19 3754