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
Posted by 구차니