summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-29 12:28:29 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-29 12:57:26 +0200
commit49fdeaaba798a255001108a5be5261fa0d0b3176 (patch)
tree8170b1ce97f0d0aa373f580846de5ab85a4f1b0c
parent328d762dcfc9ea4b6a6bcac208860209bdbb55b5 (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.c63
-rw-r--r--src/wfddevice.h5
-rw-r--r--src/wfdevent.c2
-rw-r--r--src/wfdport.c67
-rw-r--r--src/wfdport.h5
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_ */