summaryrefslogtreecommitdiff
path: root/src/compositor-drm.c
diff options
context:
space:
mode:
authorScott Moreau <oreaus@gmail.com>2012-08-18 01:04:05 -0600
committerKristian Høgsberg <krh@bitplanet.net>2012-08-29 14:39:13 -0400
commit1bad5db9d69cd744bc48f60bb71f7b68b6a2f770 (patch)
treec11d1122dd3e962edae4ce826eac49722e1177ba /src/compositor-drm.c
parent5418a904ca007a109f6af8c0c75ca97a134986d9 (diff)
downloadweston-1bad5db9d69cd744bc48f60bb71f7b68b6a2f770.tar.gz
weston-1bad5db9d69cd744bc48f60bb71f7b68b6a2f770.tar.bz2
weston-1bad5db9d69cd744bc48f60bb71f7b68b6a2f770.zip
Implement output transformations.
This patch allows rotation and mirroring outputs for x11 and drm backends. A new 'transform' key can be set in the [output] section. From the protocol: "The flipped values correspond to an initial flip around a vertical axis followed by rotation." The transform key can be one of the following 8 strings: normal 90 180 270 flipped flipped-90 flipped-180 flipped-270
Diffstat (limited to 'src/compositor-drm.c')
-rw-r--r--src/compositor-drm.c104
1 files changed, 77 insertions, 27 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 8c8c8c0e..bcc9a0da 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -46,6 +46,7 @@
static int option_current_mode = 0;
static char *output_name;
static char *output_mode;
+static char *output_transform;
static struct wl_list configured_output_list;
enum output_config {
@@ -60,6 +61,7 @@ enum output_config {
struct drm_configured_output {
char *name;
char *mode;
+ uint32_t transform;
int32_t width, height;
drmModeModeInfo crtc_mode;
enum output_config config;
@@ -1434,7 +1436,8 @@ create_output_for_connector(struct drm_compositor *ec,
wl_list_for_each(temp, &configured_output_list, link) {
if (strcmp(temp->name, output->name) == 0) {
- weston_log("%s mode \"%s\" in config\n",
+ if (temp->mode)
+ weston_log("%s mode \"%s\" in config\n",
temp->name, temp->mode);
o = temp;
break;
@@ -1450,9 +1453,9 @@ create_output_for_connector(struct drm_compositor *ec,
}
wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
- if (o && o->width == drm_mode->base.width &&
- o->height == drm_mode->base.height &&
- o->config == OUTPUT_CONFIG_MODE)
+ if (o && o->config == OUTPUT_CONFIG_MODE &&
+ o->width == drm_mode->base.width &&
+ o->height == drm_mode->base.height)
configured = drm_mode;
if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
current = drm_mode;
@@ -1528,7 +1531,8 @@ create_output_for_connector(struct drm_compositor *ec,
}
weston_output_init(&output->base, &ec->base, x, y,
- connector->mmWidth, connector->mmHeight);
+ connector->mmWidth, connector->mmHeight,
+ o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL);
wl_list_insert(ec->base.output_list.prev, &output->base.link);
@@ -1695,7 +1699,7 @@ create_outputs(struct drm_compositor *ec, uint32_t option_connector,
x += container_of(ec->base.output_list.prev,
struct weston_output,
- link)->current->width;
+ link)->width;
}
drmModeFreeConnector(connector);
@@ -1751,7 +1755,7 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
/* XXX: not yet needed, we die with 0 outputs */
if (!wl_list_empty(&ec->base.output_list))
- x = last->x + last->current->width;
+ x = last->x + last->width;
else
x = 0;
y = 0;
@@ -1779,7 +1783,7 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
disconnects &= ~(1 << output->connector_id);
weston_log("connector %d disconnected\n",
output->connector_id);
- x_offset += output->base.current->width;
+ x_offset += output->base.width;
drm_output_destroy(&output->base);
}
}
@@ -2412,17 +2416,54 @@ check_for_modeline(struct drm_configured_output *output)
}
static void
+drm_output_set_transform(struct drm_configured_output *output)
+{
+ if (!output_transform) {
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ return;
+ }
+
+ if (!strcmp(output_transform, "normal"))
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ else if (!strcmp(output_transform, "90"))
+ output->transform = WL_OUTPUT_TRANSFORM_90;
+ else if (!strcmp(output_transform, "180"))
+ output->transform = WL_OUTPUT_TRANSFORM_180;
+ else if (!strcmp(output_transform, "270"))
+ output->transform = WL_OUTPUT_TRANSFORM_270;
+ else if (!strcmp(output_transform, "flipped"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
+ else if (!strcmp(output_transform, "flipped-90"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
+ else if (!strcmp(output_transform, "flipped-180"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
+ else if (!strcmp(output_transform, "flipped-270"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
+ else {
+ weston_log("Invalid transform \"%s\" for output %s\n",
+ output_transform, output_name);
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ }
+
+ free(output_transform);
+ output_transform = NULL;
+}
+
+static void
output_section_done(void *data)
{
struct drm_configured_output *output;
output = malloc(sizeof *output);
- if (!output || !output_name || !output_mode) {
+ if (!output || !output_name || (output_name[0] == 'X') ||
+ (!output_mode && !output_transform)) {
free(output_name);
- output_name = NULL;
free(output_mode);
+ free(output_transform);
+ output_name = NULL;
output_mode = NULL;
+ output_transform = NULL;
return;
}
@@ -2430,24 +2471,32 @@ output_section_done(void *data)
output->name = output_name;
output->mode = output_mode;
- if (strcmp(output_mode, "off") == 0)
- output->config = OUTPUT_CONFIG_OFF;
- else if (strcmp(output_mode, "preferred") == 0)
- output->config = OUTPUT_CONFIG_PREFERRED;
- else if (strcmp(output_mode, "current") == 0)
- output->config = OUTPUT_CONFIG_CURRENT;
- else if (sscanf(output_mode, "%dx%d", &output->width, &output->height) == 2)
- output->config = OUTPUT_CONFIG_MODE;
- else if (check_for_modeline(output) == 0)
- output->config = OUTPUT_CONFIG_MODELINE;
-
- if (output->config != OUTPUT_CONFIG_INVALID)
- wl_list_insert(&configured_output_list, &output->link);
- else {
- weston_log("Invalid mode \"%s\" for output %s\n",
- output_mode, output_name);
- drm_free_configured_output(output);
+ if (output_mode) {
+ if (strcmp(output_mode, "off") == 0)
+ output->config = OUTPUT_CONFIG_OFF;
+ else if (strcmp(output_mode, "preferred") == 0)
+ output->config = OUTPUT_CONFIG_PREFERRED;
+ else if (strcmp(output_mode, "current") == 0)
+ output->config = OUTPUT_CONFIG_CURRENT;
+ else if (sscanf(output_mode, "%dx%d",
+ &output->width, &output->height) == 2)
+ output->config = OUTPUT_CONFIG_MODE;
+ else if (check_for_modeline(output) == 0)
+ output->config = OUTPUT_CONFIG_MODELINE;
+
+ if (output->config == OUTPUT_CONFIG_INVALID)
+ weston_log("Invalid mode \"%s\" for output %s\n",
+ output_mode, output_name);
+ output_mode = NULL;
}
+
+ drm_output_set_transform(output);
+
+ wl_list_insert(&configured_output_list, &output->link);
+
+ if (output_transform)
+ free(output_transform);
+ output_transform = NULL;
}
WL_EXPORT struct weston_compositor *
@@ -2471,6 +2520,7 @@ backend_init(struct wl_display *display, int argc, char *argv[],
const struct config_key drm_config_keys[] = {
{ "name", CONFIG_KEY_STRING, &output_name },
{ "mode", CONFIG_KEY_STRING, &output_mode },
+ { "transform", CONFIG_KEY_STRING, &output_transform },
};
const struct config_section config_section[] = {