summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-09-21 16:00:17 -0400
committerKristian Høgsberg <krh@redhat.com>2009-09-21 16:00:17 -0400
commit1b8b66f9387fe08dd5d0f38398f72f0d5fab2776 (patch)
tree6dd52fb55c0c816604ffdc81462ca69d8dbfb5e7
parente000d8cd23a63b6d42b4055179da68b67764c963 (diff)
downloadwayland-1b8b66f9387fe08dd5d0f38398f72f0d5fab2776.tar.gz
wayland-1b8b66f9387fe08dd5d0f38398f72f0d5fab2776.tar.xz
wayland-1b8b66f9387fe08dd5d0f38398f72f0d5fab2776.zip
Light up multiple outputs when possible
Multihead is still a little confused, but this is a first step.
-rw-r--r--wayland-system-compositor.c92
1 files changed, 54 insertions, 38 deletions
diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c
index 45dad32..9e8b50b 100644
--- a/wayland-system-compositor.c
+++ b/wayland-system-compositor.c
@@ -72,7 +72,7 @@ struct wlsc_output {
EGLSurface surface;
int32_t x, y, width, height;
- drmModeModeInfo *mode;
+ drmModeModeInfo mode;
uint32_t crtc_id;
uint32_t connector_id;
@@ -1187,50 +1187,22 @@ static drmModeModeInfo builtin_1024x768 = {
};
static int
-create_output(struct wlsc_compositor *ec, struct udev_device *device)
+create_output_for_connector(struct wlsc_compositor *ec,
+ drmModeRes *resources,
+ drmModeConnector *connector)
{
- drmModeConnector *connector;
- drmModeRes *resources;
+ struct wlsc_output *output;
drmModeEncoder *encoder;
drmModeModeInfo *mode;
- struct wlsc_output *output;
uint32_t name, handle, stride;
int i, ret, fd;
- if (ec->display == NULL && init_egl(ec, device) < 0) {
- fprintf(stderr, "failed to initialize egl\n");
- return -1;
- }
+ fd = eglGetDisplayFD(ec->display);
output = malloc(sizeof *output);
if (output == NULL)
return -1;
- fd = eglGetDisplayFD(ec->display);
- resources = drmModeGetResources(fd);
- if (!resources) {
- fprintf(stderr, "drmModeGetResources failed\n");
- return -1;
- }
-
- for (i = 0; i < resources->count_connectors; i++) {
- connector = drmModeGetConnector(fd, resources->connectors[i]);
- if (connector == NULL)
- continue;
-
- if (connector->connection == DRM_MODE_CONNECTED &&
- (option_connector == 0 ||
- connector->connector_id == option_connector))
- break;
-
- drmModeFreeConnector(connector);
- }
-
- if (i == resources->count_connectors) {
- fprintf(stderr, "No currently active connector found.\n");
- return -1;
- }
-
if (connector->count_modes > 0)
mode = &connector->modes[0];
else
@@ -1254,7 +1226,7 @@ create_output(struct wlsc_compositor *ec, struct udev_device *device)
output->compositor = ec;
output->crtc_id = resources->crtcs[i];
output->connector_id = connector->connector_id;
- output->mode = mode;
+ output->mode = *mode;
output->x = 0;
output->y = 0;
output->width = mode->hdisplay;
@@ -1266,6 +1238,8 @@ create_output(struct wlsc_compositor *ec, struct udev_device *device)
encoder->encoder_id,
mode->name);
+ drmModeFreeEncoder(encoder);
+
output->surface = eglCreateSurface(ec->display,
ec->config,
output->width,
@@ -1291,7 +1265,7 @@ create_output(struct wlsc_compositor *ec, struct udev_device *device)
output->current = 0;
ret = drmModeSetCrtc(fd, output->crtc_id,
output->fb_id[output->current ^ 1], 0, 0,
- &output->connector_id, 1, mode);
+ &output->connector_id, 1, &output->mode);
if (ret) {
fprintf(stderr, "failed to set mode: %m\n");
return -1;
@@ -1312,6 +1286,44 @@ create_output(struct wlsc_compositor *ec, struct udev_device *device)
return 0;
}
+static int
+create_outputs(struct wlsc_compositor *ec)
+{
+ drmModeConnector *connector;
+ drmModeRes *resources;
+ int fd, i;
+
+ fd = eglGetDisplayFD(ec->display);
+ resources = drmModeGetResources(fd);
+ if (!resources) {
+ fprintf(stderr, "drmModeGetResources failed\n");
+ return -1;
+ }
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(fd, resources->connectors[i]);
+ if (connector == NULL)
+ continue;
+
+ if (connector->connection == DRM_MODE_CONNECTED &&
+ (option_connector == 0 ||
+ connector->connector_id == option_connector))
+ if (create_output_for_connector(ec, resources, connector) < 0)
+ return -1;
+
+ drmModeFreeConnector(connector);
+ }
+
+ if (wl_list_empty(&ec->output_list)) {
+ fprintf(stderr, "No currently active connector found.\n");
+ return -1;
+ }
+
+ drmModeFreeResources(resources);
+
+ return 0;
+}
+
static const struct wl_interface visual_interface = {
"visual", 1,
};
@@ -1351,7 +1363,7 @@ static void on_enter_vt(int signal_number, void *data)
while (&output->link != &ec->output_list) {
ret = drmModeSetCrtc(fd, output->crtc_id,
output->fb_id[output->current ^ 1], 0, 0,
- &output->connector_id, 1, output->mode);
+ &output->connector_id, 1, &output->mode);
if (ret)
fprintf(stderr, "failed to set mode for connector %d: %m\n",
output->connector_id);
@@ -1474,7 +1486,11 @@ init_libudev(struct wlsc_compositor *ec)
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
path = udev_list_entry_get_name(entry);
device = udev_device_new_from_syspath(ec->udev, path);
- if (create_output(ec, device) < 0) {
+ if (init_egl(ec, device) < 0) {
+ fprintf(stderr, "failed to initialize egl\n");
+ return -1;
+ }
+ if (create_outputs(ec) < 0) {
fprintf(stderr, "failed to create output for %s\n", path);
return -1;
}