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); } } |