weston-screenshooter를 이용하여 직접 명령어 라인에서 캡쳐를 해보려하면 아래와 같이 에러가 발생한다.
$ weston-screenshooter weston_screenshooter@5: error 0: screenshooter failed: permission denied. Debug protocol must be enabled |
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 }; |