weston-screenshooter를 이용하여 직접 명령어 라인에서 캡쳐를 해보려하면 아래와 같이 에러가 발생한다.

$ weston-screenshooter
weston_screenshooter@5: error 0: screenshooter failed: permission denied. Debug protocol must be enabled

 

weston --debug를 통해 실행하라는데

$ weston --debug

[링크 : https://blog.lancitou.net/build-and-run-weston-on-ubuntu/]

[링크 : https://www.collabora.com/news-and-blog/blog/2019/04/24/weston-debugging-and-tracing-on-the-fly/]

 

시리얼 콘솔을 통해 접속을 해서 그런지 실행이 안된다.

# weston --debug
Date: 2022-01-13 KST
[11:49:13.239] weston 9.0.0
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: lf-5.10.35-2.0.0-rc2+
[11:49:13.239] Command line: weston --debug
[11:49:13.239] OS: Linux, 5.10.35-lts-5.10.y+g6369370afcb5, #1 SMP PREEMPT Tue Dec 14 09:29:50 UTC 2021, aarch64
[11:49:13.239] Using config file '/etc/xdg/weston/weston.ini'
WARNING: debug protocol has been enabled. This is a potential denial-of-service attack vector and information leak.
[11:49:13.239] Output repaint window is 16 ms maximum.
[11:49:13.240] Loading module '/usr/lib/libweston-9/drm-backend.so'
[11:49:13.244] initializing drm backend
[11:49:13.244] logind: failed to get session seat
[11:49:13.245] logind: cannot setup systemd-logind helper (-61), using legacy fallback
[11:49:13.245] <stdin> not a vt
[11:49:13.245] if running weston from ssh, use --tty to specify a tty
[11:49:13.245] fatal: drm backend should be run using weston-launch binary, or your system should provide the logind D-Bus API.
[11:49:13.245] fatal: failed to create compositor backend
Internal warning: debug scope 'drm-backend' has not been destroyed.

 

weston 실행 스크립트 에서

(내가 가진 시스템에서는 다음 경로에 존재함. /etc/systemd/system/graphical.target.wants/weston.service)

 Service 섹션 ExecStart 의 가장 마지막에 --debug를 추가해주면 문제없이 실행된다.

 

다만.. 경고가 무시무시 하구만.

 

 

+

의외로 별 내용이 없는 함수인데 얘를 실행하면 debug protol must be enabled 에러가 발생한다.

wl_display_roundtrip - Block until all pending request are processed by the server.
int wl_display_roundtrip(struct wl_display *display)
display
The display context object
Returns:
The number of dispatched events on success or -1 on failure
This function blocks until the server has processed all currently issued requests by sending a request to the display server and waiting for a reply before returning.

This function uses wl_display_dispatch_queue() internally. It is not allowed to call this function while the thread is being prepared for reading events, and doing so will cause a dead lock.

Note: This function may dispatch other events being received on the default queue.

[링크 : https://wayland.freedesktop.org/docs/html/apb.html]

[링크 : https://www.systutorials.com/docs/linux/man/3-wl_display_roundtrip/]

 

compositor/weston-screenshooter.c 에서 bind_shooter() 에서 해당 에러를 출력하고

bind_shooter()는 screenshooter_create() 에서 호출이 되고

static void
bind_shooter(struct wl_client *client,
     void *data, uint32_t version, uint32_t id)
{
struct screenshooter *shooter = data;
struct wl_resource *resource;
bool debug_enabled =
weston_compositor_is_debug_protocol_enabled(shooter->ec);

resource = wl_resource_create(client,
      &weston_screenshooter_interface, 1, id);

if (!debug_enabled && !shooter->client) {
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
       "screenshooter failed: permission denied. "\
       "Debug protocol must be enabled");
return;
} else if (!debug_enabled && client != shooter->client) {
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "screenshooter failed: permission denied.");
return;
}

wl_resource_set_implementation(resource, &screenshooter_implementation, data, NULL);
}

WL_EXPORT void
screenshooter_create(struct weston_compositor *ec)
{
struct screenshooter *shooter;

shooter = zalloc(sizeof *shooter);
if (shooter == NULL)
return;

shooter->ec = ec;

shooter->global = wl_global_create(ec->wl_display,  &weston_screenshooter_interface, 1,   shooter, bind_shooter);
weston_compositor_add_key_binding(ec, KEY_S, MODIFIER_SUPER,  screenshooter_binding, shooter);
weston_compositor_add_key_binding(ec, KEY_R, MODIFIER_SUPER,  recorder_binding, shooter);

shooter->destroy_listener.notify = screenshooter_destroy;
wl_signal_add(&ec->destroy_signal, &shooter->destroy_listener);
}

 

screenshooter_create() 는 desktop-shell/shell.c의 init 함수에서 호출하는데

WL_EXPORT int
wet_shell_init(struct weston_compositor *ec,
       int *argc, char *argv[])
{
screenshooter_create(ec);

shell_add_bindings(ec, shell);

shell_fade_init(shell);

clock_gettime(CLOCK_MONOTONIC, &shell->startup_time);

return 0;
}

 

이미 등록되어 있어서 새로 등록할 수 없다고 나오는 건진 애매하네..

위에서 wl_create() 하면서 이미 생성된 것에 bind 하려고 하다 보니 에러가 나는 것 같은데

bind 여부를 wl_display_roundtrip() 에서 하진 않을 것 같고 지연된 에러라고 보기에는

딜레이를 주고 실행해도 딱 그 위치에서 나오니 애매하네..

static void
handle_global(void *data, struct wl_registry *registry,
      uint32_t name, const char *interface, uint32_t version)
{
static struct screenshooter_output *output;
struct screenshooter_data *sh_data = data;

if (strcmp(interface, "wl_output") == 0) {
output = xmalloc(sizeof *output);
output->output = wl_registry_bind(registry, name,
  &wl_output_interface, 1);
wl_list_insert(&sh_data->output_list, &output->link);
wl_output_add_listener(output->output, &output_listener, output);
} else if (strcmp(interface, "wl_shm") == 0) {
sh_data->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, "weston_screenshooter") == 0) {
sh_data->screenshooter = wl_registry_bind(registry, name,  &weston_screenshooter_interface,  1);
}
}

static const struct wl_registry_listener registry_listener = {
handle_global,
handle_global_remove
};

'프로그램 사용 > wayland' 카테고리의 다른 글

wayland client example  (0) 2022.01.06
weston window transform  (0) 2022.01.06
weston 단축키  (0) 2022.01.04
weston.ini same-as on output section  (0) 2022.01.03
weston-image 와 cairo  (0) 2021.12.08
Posted by 구차니