diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-04-29 12:28:29 +0200 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-04-29 12:57:26 +0200 |
commit | 49fdeaaba798a255001108a5be5261fa0d0b3176 (patch) | |
tree | 8170b1ce97f0d0aa373f580846de5ab85a4f1b0c | |
parent | 328d762dcfc9ea4b6a6bcac208860209bdbb55b5 (diff) |
Fix attach/detach detection
Need to cache all connectors in wfd_device,
in order do find attach/detaches for ports
that are created as well as non-yet created ports.
-rw-r--r-- | src/wfddevice.c | 63 | ||||
-rw-r--r-- | src/wfddevice.h | 5 | ||||
-rw-r--r-- | src/wfdevent.c | 2 | ||||
-rw-r--r-- | src/wfdport.c | 67 | ||||
-rw-r--r-- | src/wfdport.h | 5 |
5 files changed, 69 insertions, 73 deletions
diff --git a/src/wfddevice.c b/src/wfddevice.c index 3cb4ed1..f3ccc83 100644 --- a/src/wfddevice.c +++ b/src/wfddevice.c @@ -49,6 +49,9 @@ struct wfd_device { drmModeResPtr resources; + uint32_t count_connectors; + drmModeConnectorPtr connectors; + uint32_t choosen_crtcs; struct { @@ -178,6 +181,7 @@ wfd_device_destroy(struct wfd_device *device) registry->devices[device->device_index].created = 0; + free(device->connectors); drmModeFreeResources(device->resources); udev_device_unref(device->dev); close(device->fd); @@ -245,8 +249,28 @@ wfd_create_device(WFDint device_id, const WFDint *attrib_list) registry->devices[device_index].created = 1; + device->connectors = calloc(device->resources->count_connectors, + sizeof *device->connectors); + if (device->connectors == NULL) + goto cleanup_resources; + + device->count_connectors = 0; + for (i = 0; i < device->resources->count_connectors; ++i) { + drmModeConnectorPtr connector = + drmModeGetConnector(device->fd, + device->resources->connectors[i]); + if (connector == NULL) + continue; + + device->connectors[device->count_connectors++] = *connector; + drmModeFreeConnector(connector); + + } + return device; +cleanup_resources: + drmModeFreeResources(device->resources); cleanup_udev_device: udev_device_unref(device->dev); cleanup_fd: @@ -310,3 +334,42 @@ wfd_device_commit(struct wfd_device *device) return 0; } + +WFDEventType +wfd_device_find_attach_detach(struct wfd_device *device, + WFDint *port_id, + WFDboolean *state) +{ + drmModeConnectorPtr connector = NULL; + WFDEventType event_type = WFD_EVENT_NONE; + int i; + + for (i = 0; i < device->count_connectors && + event_type == WFD_EVENT_NONE; ++i) { + if (connector) + drmModeFreeConnector(connector); + + connector = + drmModeGetConnector(device->fd, + device->connectors[i].connector_id); + if (connector == NULL) + continue; + + if (connector->connection != device->connectors[i].connection) { + event_type = WFD_EVENT_PORT_ATTACH_DETACH; + device->connectors[i] = *connector; + *port_id = connector->connector_id; + *state = connector->connection == DRM_MODE_CONNECTED; + + /* FIXME: do not break here? + * search for more, and queue them? */ + break; + } + } + + if (connector) + drmModeFreeConnector(connector); + + return event_type; +} + diff --git a/src/wfddevice.h b/src/wfddevice.h index 2f051ed..53ab23f 100644 --- a/src/wfddevice.h +++ b/src/wfddevice.h @@ -65,4 +65,9 @@ wfd_device_get_fd(struct wfd_device *device); int wfd_device_commit(struct wfd_device *device); +WFDEventType +wfd_device_find_attach_detach(struct wfd_device *device, + WFDint *port_id, + WFDboolean *state); + #endif /* _WFD_DEVICE_H_ */ diff --git a/src/wfdevent.c b/src/wfdevent.c index 3d98b61..0a91ea1 100644 --- a/src/wfdevent.c +++ b/src/wfdevent.c @@ -358,7 +358,7 @@ wfd_event_wait(struct wfd_device *device, u_event = udev_monitor_receive_device(event->udev_monitor); if (udev_event_is_hotplug_for_device(u_event, device)) { - event_type = wfd_ports_find_attach_detach(device, + event_type = wfd_device_find_attach_detach(device, &event->attach_port_id, &event->attach_state); } diff --git a/src/wfdport.c b/src/wfdport.c index 2e86186..da56552 100644 --- a/src/wfdport.c +++ b/src/wfdport.c @@ -793,70 +793,3 @@ wfd_port_bind_pipeline(struct wfd_device *device, return 0; } - -struct id_search { - uint32_t connector_id; - void *object; -}; - -static void -port_search(void *object, void *user_data) -{ - struct wfd_port *port = object; - struct id_search *search = user_data; - - if (search->connector_id == port->connector->connector_id) - search->object = object; -} - -static struct wfd_port * -id_get_port(int connector_id) -{ - struct id_search search = { connector_id, NULL }; - - wf_handle_foreach(PORT_HANDLE, - port_search, - &search); - - return search.object; -} - -WFDEventType -wfd_ports_find_attach_detach(struct wfd_device *device, - WFDint *port_id, - WFDboolean *state) -{ - drmModeResPtr resources = wfd_device_get_resources(device); - struct wfd_port *port; - int drm_fd = wfd_device_get_fd(device); - drmModeConnectorPtr connector; - int i; - WFDEventType event_type = WFD_EVENT_NONE; - - for (i = 0; i < resources->count_connectors && - event_type == WFD_EVENT_NONE; ++i) { - connector = drmModeGetConnector(drm_fd, resources->connectors[i]); - port = id_get_port(connector->connector_id); - - /* new one? */ - if (port == NULL && connector->connection == DRM_MODE_CONNECTED) { - *state = WFD_TRUE; - *port_id = connector->connector_id; - event_type = WFD_EVENT_PORT_ATTACH_DETACH; - } else if (port != NULL && - connector->connection == DRM_MODE_DISCONNECTED) { - *state = WFD_FALSE; - *port_id = connector->connector_id; - event_type = WFD_EVENT_PORT_ATTACH_DETACH; - - drmModeConnectorPtr tmp = port->connector; - port->connector = connector; - connector = tmp; - } - - drmModeFreeConnector(connector); - } - - return event_type; -} - diff --git a/src/wfdport.h b/src/wfdport.h index 28a24b1..e4ece14 100644 --- a/src/wfdport.h +++ b/src/wfdport.h @@ -131,9 +131,4 @@ int wfd_port_commit(struct wfd_device *device, struct wfd_port *port); -WFDEventType -wfd_ports_find_attach_detach(struct wfd_device *device, - WFDint *port_id, - WFDboolean *state); - #endif /* _WFD_PORT_H_ */ |