drm 에서 HDMI hotplug를 아래 코드에서 처리하는데 shell로 어떻게 넘겨주는진 발견하지 못했다.
static int udev_drm_event(int fd, uint32_t mask, void *data) { struct drm_backend *b = data; struct udev_device *event; uint32_t conn_id, prop_id; event = udev_monitor_receive_device(b->udev_monitor); if (udev_event_is_hotplug(b, event)) { if (udev_event_is_conn_prop_change(b, event, &conn_id, &prop_id)) drm_backend_update_conn_props(b, conn_id, prop_id); else drm_backend_update_heads(b, event); } udev_device_unref(event); return 1; } static void drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) { /* collect new connectors that have appeared, e.g. MST */ for (i = 0; i < resources->count_connectors; i++) { uint32_t connector_id = resources->connectors[i]; head = drm_head_find_by_connector(b, connector_id); if (head) { drm_head_update_info(head); } else { head = drm_head_create(b, connector_id, drm_device); if (!head) weston_log("DRM: failed to create head for hot-added connector %d.\n", connector_id); } } } static void drm_head_update_info(struct drm_head *head) { drmModeConnector *connector; connector = drmModeGetConnector(head->backend->drm.fd, head->connector_id); if (!connector) { weston_log("DRM: getting connector info for '%s' failed.\n", head->base.name); return; } if (drm_head_assign_connector_info(head, connector) < 0) drmModeFreeConnector(connector); if (head->base.device_changed) drm_head_log_info(head, "updated"); } static void drm_head_log_info(struct drm_head *head, const char *msg) { if (head->base.connected) { weston_log("DRM: head '%s' %s, connector %d is connected, " "EDID make '%s', model '%s', serial '%s'\n", head->base.name, msg, head->connector_id, head->base.make, head->base.model, head->base.serial_number ?: ""); } else { weston_log("DRM: head '%s' %s, connector %d is disconnected.\n", head->base.name, msg, head->connector_id); } } |
다만.. 아래의 코드에서 등록되어 output이 파괴될때 트리거 되어 작동하는 녀석만 발견함.
static void handle_output_destroy(struct wl_listener *listener, void *data); static void create_shell_output(struct desktop_shell *shell, struct weston_output *output) { struct shell_output *shell_output; shell_output = zalloc(sizeof *shell_output); if (shell_output == NULL) return; shell_output->output = output; shell_output->shell = shell; shell_output->destroy_listener.notify = handle_output_destroy; wl_signal_add(&output->destroy_signal, &shell_output->destroy_listener); wl_list_insert(shell->output_list.prev, &shell_output->link); if (wl_list_length(&shell->output_list) == 1) shell_for_each_layer(shell, shell_output_changed_move_layer, NULL); } static void handle_output_create(struct wl_listener *listener, void *data) { struct desktop_shell *shell = container_of(listener, struct desktop_shell, output_create_listener); struct weston_output *output = (struct weston_output *)data; create_shell_output(shell, output); } static void setup_output_destroy_handler(struct weston_compositor *ec, struct desktop_shell *shell) { struct weston_output *output; wl_list_init(&shell->output_list); wl_list_for_each(output, &ec->output_list, link) create_shell_output(shell, output); shell->output_create_listener.notify = handle_output_create; wl_signal_add(&ec->output_created_signal, &shell->output_create_listener); shell->output_move_listener.notify = handle_output_move; wl_signal_add(&ec->output_moved_signal, &shell->output_move_listener); } WL_EXPORT int wet_shell_init(struct weston_compositor *ec, int *argc, char *argv[]) { setup_output_destroy_handler(ec, shell); } |
'프로그램 사용 > wayland' 카테고리의 다른 글
libwayland debug 메시지 (0) | 2022.06.27 |
---|---|
libwayland (0) | 2022.06.27 |
weston debug message (0) | 2022.03.18 |
weston drm atomic (0) | 2022.03.17 |
wayvnc 실행 실패 (0) | 2022.02.17 |