Hello,

I'm happy with this patch. This patch implement an hybrid option 2-3 
that we previously discussed. compositor-drm.h provide the expected 
public API. The compositor-drm-static.h is a private header that define 
the opaque struct weston_drm_backend_config. The 
compositor-drm-static.c implement function that are always loaded. The 
compositor-drm.c is used for the loadable drm-backend.so -- as before 
the patch -- but libweston users are not expected to known or see it.

The patch also remove the configure_output callback, which is replaced 
by an internal function that take output configuration from a list 
passed in the struct weston_drm_backend_config.output_list.

The libweston users are expected to implement a similar function to 
load_drm_backend in main.c. This function is the reference implementation 
about how to fill the opaque configuration structure for the drm back-end.

Finally, I taken care of memory leak of previous draft, and this patch 
is ready for deep review.

Best regards.

---
 Makefile.am                 |   3 +
 src/compositor-drm-static.c | 206 ++++++++++++++++++++++++++++++++++++++++++++
 src/compositor-drm-static.h |  87 +++++++++++++++++++
 src/compositor-drm.c        | 179 +++++++++++++++++---------------------
 src/compositor-drm.h        | 140 ++++++++++++++++++++++++++++++
 src/main.c                  | 127 ++++++++++++++++++++++++++-
 6 files changed, 640 insertions(+), 102 deletions(-)
 create mode 100644 src/compositor-drm-static.c
 create mode 100644 src/compositor-drm-static.h
 create mode 100644 src/compositor-drm.h

diff --git a/Makefile.am b/Makefile.am
index 623621d..fca1d38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -72,6 +72,9 @@ weston_SOURCES =                                      \
        src/log.c                                       \
        src/compositor.c                                \
        src/compositor.h                                \
+       src/compositor-drm-static.c                     \
+       src/compositor-drm-static.h                     \
+       src/compositor-drm.h                    \
        src/input.c                                     \
        src/data-device.c                               \
        src/screenshooter.c                             \
diff --git a/src/compositor-drm-static.c b/src/compositor-drm-static.c
new file mode 100644
index 0000000..cb8329b
--- /dev/null
+++ b/src/compositor-drm-static.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "compositor-drm.h"
+#include "compositor-drm-static.h"
+
+struct weston_drm_backend_config *
+weston_drm_backend_config_create() {
+       struct weston_drm_backend_config * ths =
+                       (__typeof__(ths))malloc(sizeof *ths);
+
+       if(!ths)
+               return 0;
+
+       wl_list_init(&ths->outputs_list);
+
+       ths->connector = 0;
+       ths->tty = 0;
+       ths->seat_id = strdup("seat0");
+       ths->format = strdup("xrgb8888");
+       ths->use_pixman = false;
+
+       return ths;
+
+}
+
+void
+weston_drm_backend_config_clear_outputs_setup(struct weston_drm_backend_config 
* ths) {
+       struct weston_drm_backend_output_config * pos;
+       struct weston_drm_backend_output_config * tmp;
+       wl_list_for_each_safe(pos, tmp, &ths->outputs_list, link) {
+               wl_list_remove(&pos->link);
+               free(pos->name);
+               free(pos->format);
+               free(pos->seat);
+               free(pos->modeline);
+               free(pos);
+       }
+}
+
+void
+weston_drm_backend_config_destroy(struct weston_drm_backend_config * ths) {
+       if(!ths)
+               return;
+
+       free(ths->seat_id);
+       free(ths->format);
+
+       weston_drm_backend_config_clear_outputs_setup(ths);
+
+       free(ths);
+
+}
+
+void
+weston_drm_backend_config_set_connector(
+               struct weston_drm_backend_config * ths,
+               int connector) {
+       ths->connector = connector;
+}
+
+/** The tty to be used. default: use the current tty. */
+void
+weston_drm_backend_config_set_tty(
+               struct weston_drm_backend_config * ths,
+               int tty) {
+       ths->tty = tty;
+}
+
+/** If true the pixman renderer will be used instead of the OpenGL ES
+ * renderer. */
+void weston_drm_backend_config_set_use_pixman(
+               struct weston_drm_backend_config * ths,
+               bool x) {
+       ths->use_pixman = x;
+}
+
+/** The seat to be used for input and output. If NULL the default "seat0"
+ * will be used.
+ * The backend will take ownership of the seat_id pointer and will free
+ * it on backend destruction. */
+void
+weston_drm_backend_config_set_seat_id(
+               struct weston_drm_backend_config * ths,
+               char const * seat_id) {
+       free(ths->seat_id);
+       if(seat_id)
+               ths->seat_id = strdup(seat_id);
+       else
+               ths->seat_id = strdup("seat0");
+}
+
+/** The pixel format of the framebuffer to be used. Valid values are:
+ * - NULL - The default format ("xrgb8888") will be used;
+ * - "xrgb8888";
+ * - "rgb565"
+ * - "xrgb2101010"
+ * The backend will take ownership of the format pointer and will free
+ * it on backend destruction. */
+/* TODO: enums ? */
+void
+weston_drm_backend_config_set_format(
+               struct weston_drm_backend_config * ths,
+               char const * format) {
+       free(ths->format);
+       if(ths->format)
+               ths->format = strdup(format);
+       else
+               ths->format = strdup("xrgb8888");
+}
+
+void
+weston_drm_backend_config_set_use_current_mode(
+               struct weston_drm_backend_config * ths,
+               bool x) {
+       ths->use_current_mode = x;
+}
+
+bool
+weston_drm_backend_config_get_use_current_mode(
+               struct weston_drm_backend_config * ths) {
+       return ths->use_current_mode;
+}
+
+void
+weston_drm_backend_add_output_setup(
+               struct weston_drm_backend_config * ths,
+               char const * name,
+               int scale,
+               uint32_t transform,
+               char const * format,
+               char const * seat,
+               enum weston_drm_backend_output_mode mode,
+               char const * modeline
+) {
+
+       struct weston_drm_backend_output_config * output =
+                       (__typeof__(output))zalloc(sizeof *output);
+
+       wl_list_init(&output->link);
+
+       output->name = strdup(name);
+       output->base.scale = scale;
+       output->base.transform = transform;
+
+       if(format)
+               output->format = strdup(format);
+
+       if(seat)
+               output->seat = strdup(seat);
+
+       output->mode = mode;
+
+       if(modeline)
+               output->modeline = strdup(modeline);
+
+       wl_list_insert(&ths->outputs_list, &output->link);
+
+}
+
+/* new load function that need weston_backend_config */
+int
+weston_drm_backend_load(struct weston_compositor *compositor,
+                int *argc, char **argv, struct weston_config *wc,
+                struct weston_drm_backend_config *wbc)
+{
+       int (*backend_init)(struct weston_compositor *c,
+                           int *argc, char *argv[],
+                           struct weston_config *config,
+                           struct weston_backend_config *config_base);
+
+       backend_init = weston_load_module("drm-backend.so", "backend_init");
+       if (!backend_init)
+               return -1;
+
+       return backend_init(compositor, argc, argv, wc, &wbc->base);
+}
+
+
+
+
diff --git a/src/compositor-drm-static.h b/src/compositor-drm-static.h
new file mode 100644
index 0000000..7722b85
--- /dev/null
+++ b/src/compositor-drm-static.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ * Copyright © 2015 Giulio Camuffo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef SRC_COMPOSITOR_DRM_STATIC_H_
+#define SRC_COMPOSITOR_DRM_STATIC_H_
+
+#include <wayland-util.h>
+
+struct weston_drm_backend_output_config {
+       struct weston_backend_output_config base;
+
+       struct wl_list link; /* link defined output from config file */
+
+       enum weston_drm_backend_output_mode mode;
+
+       char *name;
+       char *format;
+       char *seat;
+       char *modeline;
+
+};
+
+/** The backend configuration struct.
+ *
+ * weston_drm_backend_config contains the configuration used by a DRM
+ * backend. The backend will take ownership of the weston_backend_config
+ * object passed to it on initialization and will free it on destruction. */
+struct weston_drm_backend_config {
+       struct weston_backend_config base;
+
+       /** The connector id of the output to be initialized. A value of 0 will
+        * enable all available outputs. */
+       int connector;
+       /** The tty to be used. Set to 0 to use the current tty. */
+       int tty;
+       /** If true the pixman renderer will be used instead of the OpenGL ES
+        * renderer. */
+       bool use_pixman;
+
+       /** reuse the current output mode */
+       bool use_current_mode;
+
+       /** The seat to be used for input and output. If NULL the default 
"seat0"
+        * will be used.
+        * The backend will take ownership of the seat_id pointer and will free
+        * it on backend destruction. */
+       char *seat_id;
+       /** The pixel format of the framebuffer to be used. Valid values are:
+        * - NULL - The default format ("xrgb8888") will be used;
+        * - "xrgb8888";
+        * - "rgb565"
+        * - "xrgb2101010"
+        * The backend will take ownership of the format pointer and will free
+        * it on backend destruction. */
+       char *format;
+
+       /** possible outputs setup */
+       struct wl_list outputs_list;
+
+};
+
+
+#endif /* SRC_COMPOSITOR_DRM_STATIC_H_ */
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 538e56e..0baa24c 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -50,6 +50,8 @@
 #include "shared/timespec-util.h"
 #include "libbacklight.h"
 #include "compositor.h"
+#include "compositor-drm.h"
+#include "compositor-drm-static.h"
 #include "gl-renderer.h"
 #include "pixman-renderer.h"
 #include "libinput-seat.h"
@@ -130,6 +132,9 @@ struct drm_backend {
 
        int32_t cursor_width;
        int32_t cursor_height;
+
+       struct weston_drm_backend_config *config;
+
 };
 
 struct drm_mode {
@@ -2151,16 +2156,12 @@ setup_output_seat_constraint(struct drm_backend *b,
 }
 
 static int
-get_gbm_format_from_section(struct weston_config_section *section,
+parse_gbm_format(char const *s,
                            uint32_t default_value,
                            uint32_t *format)
 {
-       char *s;
        int ret = 0;
 
-       weston_config_section_get_string(section,
-                                        "gbm-format", &s, NULL);
-
        if (s == NULL)
                *format = default_value;
        else if (strcmp(s, "xrgb8888") == 0)
@@ -2174,8 +2175,6 @@ get_gbm_format_from_section(struct weston_config_section 
*section,
                ret = -1;
        }
 
-       free(s);
-
        return ret;
 }
 
@@ -2185,20 +2184,16 @@ get_gbm_format_from_section(struct 
weston_config_section *section,
  * Find the most suitable mode to use for initial setup (or reconfiguration on
  * hotplug etc) for a DRM output.
  *
- * @param output DRM output to choose mode for
- * @param kind Strategy and preference to use when choosing mode
- * @param width Desired width for this output
- * @param height Desired height for this output
+ * @param backend The DRM backend object
+ * @param config Desired configuration for the output
  * @param current_mode Mode currently being displayed on this output
- * @param modeline Manually-entered mode (may be NULL)
  * @returns A mode from the output's mode list, or NULL if none available
  */
 static struct drm_mode *
-drm_output_choose_initial_mode(struct drm_output *output,
-                              enum output_config kind,
-                              int width, int height,
-                              const drmModeModeInfo *current_mode,
-                              const drmModeModeInfo *modeline)
+drm_output_choose_initial_mode(struct drm_backend *backend,
+                                  struct drm_output *output,
+                                  struct weston_drm_backend_output_config 
const *config,
+                              const drmModeModeInfo *current_mode)
 {
        struct drm_mode *preferred = NULL;
        struct drm_mode *current = NULL;
@@ -2206,9 +2201,26 @@ drm_output_choose_initial_mode(struct drm_output *output,
        struct drm_mode *best = NULL;
        struct drm_mode *drm_mode;
 
+       drmModeModeInfo modeline;
+       int32_t width, height;
+
+       if (config->mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED && 
config->modeline) {
+               if (sscanf(config->modeline, "%dx%d", &width, &height) != 2) {
+                       width = -1;
+
+                       if (parse_modeline(config->modeline, &modeline) == 0) {
+                               configured = drm_output_add_mode(output, 
&modeline);
+                               if (!configured)
+                                       return NULL;
+                       } else {
+                               weston_log("Invalid modeline \"%s\" for output 
%s\n",
+                                          config->modeline, output->base.name);
+                       }
+               }
+       }
+
        wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
-               if (kind == OUTPUT_CONFIG_MODE &&
-                   width == drm_mode->base.width &&
+               if (width == drm_mode->base.width &&
                    height == drm_mode->base.height)
                        configured = drm_mode;
 
@@ -2222,19 +2234,13 @@ drm_output_choose_initial_mode(struct drm_output 
*output,
                best = drm_mode;
        }
 
-       if (kind == OUTPUT_CONFIG_MODELINE) {
-               configured = drm_output_add_mode(output, modeline);
-               if (!configured)
-                       return NULL;
-       }
-
        if (current == NULL && current_mode->clock != 0) {
                current = drm_output_add_mode(output, current_mode);
                if (!current)
                        return NULL;
        }
 
-       if (kind == OUTPUT_CONFIG_CURRENT)
+       if (config->mode == WESTON_DRM_BACKEND_OUTPUT_CURRENT)
                configured = current;
 
        if (option_current_mode && current)
@@ -2280,6 +2286,21 @@ connector_get_current_mode(drmModeConnector *connector, 
int drm_fd,
        return 0;
 }
 
+static struct weston_drm_backend_output_config const *
+drm_get_output_configuration(struct drm_backend *backend, const char *name)
+{
+       struct weston_drm_backend_output_config * output;
+       wl_list_for_each(output, &backend->config->outputs_list, link) {
+               if(strstr(name, output->name)) {
+                       return output;
+               }
+       }
+
+       /* if the output is not found use an ampty one */
+       static struct weston_drm_backend_output_config def = { { 0 }, { 0 }, 0 
};
+       return &def;
+}
+
 /**
  * Create and configure a Weston output structure
  *
@@ -2303,12 +2324,9 @@ create_output_for_connector(struct drm_backend *b,
        struct drm_output *output;
        struct drm_mode *drm_mode, *next, *current;
        struct weston_mode *m;
-       struct weston_config_section *section;
-       drmModeModeInfo crtc_mode, modeline;
-       int i, width, height, scale;
-       char *s;
-       enum output_config config;
-       uint32_t transform;
+       drmModeModeInfo crtc_mode;
+       int i;
+       struct weston_drm_backend_output_config const * config;
 
        i = find_crtc_for_connector(b, resources, connector);
        if (i < 0) {
@@ -2327,42 +2345,13 @@ create_output_for_connector(struct drm_backend *b,
        output->base.serial_number = "unknown";
        wl_list_init(&output->base.mode_list);
 
-       section = weston_config_get_section(b->compositor->config, "output", 
"name",
-                                           output->base.name);
-       weston_config_section_get_string(section, "mode", &s, "preferred");
-       if (strcmp(s, "off") == 0)
-               config = OUTPUT_CONFIG_OFF;
-       else if (strcmp(s, "preferred") == 0)
-               config = OUTPUT_CONFIG_PREFERRED;
-       else if (strcmp(s, "current") == 0)
-               config = OUTPUT_CONFIG_CURRENT;
-       else if (sscanf(s, "%dx%d", &width, &height) == 2)
-               config = OUTPUT_CONFIG_MODE;
-       else if (parse_modeline(s, &modeline) == 0)
-               config = OUTPUT_CONFIG_MODELINE;
-       else {
-               weston_log("Invalid mode \"%s\" for output %s\n",
-                          s, output->base.name);
-               config = OUTPUT_CONFIG_PREFERRED;
-       }
-       free(s);
-
-       weston_config_section_get_int(section, "scale", &scale, 1);
-       weston_config_section_get_string(section, "transform", &s, "normal");
-       if (weston_parse_transform(s, &transform) < 0)
-               weston_log("Invalid transform \"%s\" for output %s\n",
-                          s, output->base.name);
-
-       free(s);
+       config = drm_get_output_configuration(b, output->base.name);
 
-       if (get_gbm_format_from_section(section,
-                                       b->format,
-                                       &output->format) == -1)
+       if (parse_gbm_format(config->format, b->format, &output->format) == -1)
                output->format = b->format;
 
-       weston_config_section_get_string(section, "seat", &s, "");
-       setup_output_seat_constraint(b, &output->base, s);
-       free(s);
+       setup_output_seat_constraint(b, &output->base,
+                                    config->seat ? config->seat : "");
 
        output->crtc_id = resources->crtcs[i];
        output->pipe = i;
@@ -2382,16 +2371,15 @@ create_output_for_connector(struct drm_backend *b,
                        goto err_free;
        }
 
-       if (config == OUTPUT_CONFIG_OFF) {
+       if (config->mode == WESTON_DRM_BACKEND_OUTPUT_OFF) {
                weston_log("Disabling output %s\n", output->base.name);
                drmModeSetCrtc(b->drm.fd, output->crtc_id,
                               0, 0, 0, 0, 0, NULL);
                goto err_free;
        }
 
-       current = drm_output_choose_initial_mode(output, config,
-                                                width, height,
-                                                &crtc_mode, &modeline);
+       current = drm_output_choose_initial_mode(b, output, config,
+                                                &crtc_mode);
        if (!current)
                goto err_free;
        output->base.current_mode = &current->base;
@@ -2399,7 +2387,7 @@ create_output_for_connector(struct drm_backend *b,
 
        weston_output_init(&output->base, b->compositor, x, y,
                           connector->mmWidth, connector->mmHeight,
-                          transform, scale);
+                          config->base.transform, config->base.scale);
 
        if (b->use_pixman) {
                if (drm_output_init_pixman(output, b) < 0) {
@@ -2744,6 +2732,8 @@ drm_destroy(struct weston_compositor *ec)
 
        close(b->drm.fd);
 
+       weston_drm_backend_config_destroy(b->config);
+
        free(b);
 }
 
@@ -3067,12 +3057,9 @@ renderer_switch_binding(struct weston_keyboard 
*keyboard, uint32_t time,
 
 static struct drm_backend *
 drm_backend_create(struct weston_compositor *compositor,
-                     struct drm_parameters *param,
-                     int *argc, char *argv[],
-                     struct weston_config *config)
+                         struct weston_drm_backend_config *config)
 {
        struct drm_backend *b;
-       struct weston_config_section *section;
        struct udev_device *drm_device;
        struct wl_event_loop *loop;
        const char *path;
@@ -3095,18 +3082,20 @@ drm_backend_create(struct weston_compositor *compositor,
         */
        b->sprites_are_broken = 1;
        b->compositor = compositor;
+       b->use_pixman = config->use_pixman;
+
+       /* the backend become the owner */
+       b->config = config;
 
-       section = weston_config_get_section(config, "core", NULL, NULL);
-       if (get_gbm_format_from_section(section,
-                                       GBM_FORMAT_XRGB8888,
-                                       &b->format) == -1)
-               goto err_base;
+       b->config->seat_id = strdup(config->seat_id);
+       b->config->format = 0;
 
-       b->use_pixman = param->use_pixman;
+       if (parse_gbm_format(config->format, GBM_FORMAT_XRGB8888, &b->format) < 
0)
+               goto err_compositor;
 
        /* Check if we run drm-backend using weston-launch */
-       compositor->launcher = weston_launcher_connect(compositor, param->tty,
-                                                      param->seat_id, true);
+       compositor->launcher = weston_launcher_connect(compositor, config->tty,
+                                                      config->seat_id, true);
        if (compositor->launcher == NULL) {
                weston_log("fatal: drm backend should be run "
                           "using weston-launch binary or as root\n");
@@ -3122,7 +3111,7 @@ drm_backend_create(struct weston_compositor *compositor,
        b->session_listener.notify = session_notify;
        wl_signal_add(&compositor->session_signal, &b->session_listener);
 
-       drm_device = find_primary_gpu(b, param->seat_id);
+       drm_device = find_primary_gpu(b, config->seat_id);
        if (drm_device == NULL) {
                weston_log("no drm device found\n");
                goto err_udev;
@@ -3148,6 +3137,7 @@ drm_backend_create(struct weston_compositor *compositor,
 
        b->base.destroy = drm_destroy;
        b->base.restore = drm_restore;
+       b->base.create_output = NULL;
 
        b->prev_state = WESTON_COMPOSITOR_ACTIVE;
 
@@ -3157,12 +3147,12 @@ drm_backend_create(struct weston_compositor *compositor,
        create_sprites(b);
 
        if (udev_input_init(&b->input,
-                           compositor, b->udev, param->seat_id) < 0) {
+                           compositor, b->udev, config->seat_id) < 0) {
                weston_log("failed to create input devices\n");
                goto err_sprite;
        }
 
-       if (create_outputs(b, param->connector, drm_device) < 0) {
+       if (create_outputs(b, config->connector, drm_device) < 0) {
                weston_log("failed to create output for %s\n", path);
                goto err_udev_input;
        }
@@ -3237,7 +3227,7 @@ err_udev:
        udev_unref(b->udev);
 err_compositor:
        weston_compositor_shutdown(compositor);
-err_base:
+
        free(b);
        return NULL;
 }
@@ -3248,21 +3238,10 @@ backend_init(struct weston_compositor *compositor, int 
*argc, char *argv[],
             struct weston_backend_config *config_base)
 {
        struct drm_backend *b;
-       struct drm_parameters param = { 0, };
-
-       const struct weston_option drm_options[] = {
-               { WESTON_OPTION_INTEGER, "connector", 0, &param.connector },
-               { WESTON_OPTION_STRING, "seat", 0, &param.seat_id },
-               { WESTON_OPTION_INTEGER, "tty", 0, &param.tty },
-               { WESTON_OPTION_BOOLEAN, "current-mode", 0, 
&option_current_mode },
-               { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &param.use_pixman },
-       };
-
-       param.seat_id = default_seat;
-
-       parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
+       struct weston_drm_backend_config *drm_config =
+                       (struct weston_drm_backend_config *)config_base;
 
-       b = drm_backend_create(compositor, &param, argc, argv, config);
+       b = drm_backend_create(compositor, drm_config);
        if (b == NULL)
                return -1;
        return 0;
diff --git a/src/compositor-drm.h b/src/compositor-drm.h
new file mode 100644
index 0000000..4ffaa34
--- /dev/null
+++ b/src/compositor-drm.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ * Copyright © 2015 Giulio Camuffo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef WESTON_COMPOSITOR_DRM_H
+#define WESTON_COMPOSITOR_DRM_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include "compositor.h"
+
+struct weston_drm_backend_config;
+
+enum weston_drm_backend_output_mode {
+       /** The output is disabled */
+       WESTON_DRM_BACKEND_OUTPUT_OFF,
+       /** The output will use the current active mode */
+       WESTON_DRM_BACKEND_OUTPUT_CURRENT,
+       /** The output will use the preferred mode. A modeline can be provided
+        * by setting weston_backend_output_config::modeline in the form of
+        * "WIDTHxHEIGHT" or in the form of an explicit modeline calculated
+        * using e.g. the cvt tool. If a valid modeline is supplied it will be
+        * used, if invalid or NULL the preferred available mode will be used. 
*/
+       WESTON_DRM_BACKEND_OUTPUT_PREFERRED,
+};
+
+/** Create a new default drm backend configuration */
+WL_EXPORT struct weston_drm_backend_config *
+weston_drm_backend_config_create(void);
+
+/** destroy drm backend configuration */
+WL_EXPORT void
+weston_drm_backend_config_destroy(struct weston_drm_backend_config * ths);
+
+/** The connector id of the output to be initialized.
+ * default: enable all available outputs. */
+WL_EXPORT void
+weston_drm_backend_config_set_connector(
+               struct weston_drm_backend_config * ths,
+               int connector);
+
+/** The tty to be used. default: use the current tty. */
+WL_EXPORT void
+weston_drm_backend_config_set_tty(
+               struct weston_drm_backend_config * ths,
+               int tty);
+
+/** If true the pixman renderer will be used instead of the OpenGL ES
+ * renderer. */
+WL_EXPORT void
+weston_drm_backend_config_set_use_pixman(
+               struct weston_drm_backend_config * ths, bool x);
+
+/** reuse the current output mode */
+WL_EXPORT void
+weston_drm_backend_config_set_use_current_mode(
+               struct weston_drm_backend_config * ths, bool x);
+
+WL_EXPORT bool
+weston_drm_backend_config_get_use_current_mode(
+               struct weston_drm_backend_config * ths);
+
+/** The seat to be used for input and output. If NULL the default "seat0"
+ * will be used.
+ * The backend will take ownership of the seat_id pointer and will free
+ * it on backend destruction. */
+WL_EXPORT void
+weston_drm_backend_config_set_seat_id(
+               struct weston_drm_backend_config * ths,
+               char const * seat_id);
+
+/** The pixel format of the framebuffer to be used. Valid values are:
+ * - NULL - The default format ("xrgb8888") will be used;
+ * - "xrgb8888";
+ * - "rgb565"
+ * - "xrgb2101010"
+ * The backend will take ownership of the format pointer and will free
+ * it on backend destruction. */
+WL_EXPORT void
+weston_drm_backend_config_set_format(
+               struct weston_drm_backend_config * ths,
+               char const * format);
+
+WL_EXPORT struct weston_backend_config *
+weston_drm_backend_config_get_weston_backend_config(
+               struct weston_drm_backend_config *ths);
+
+WL_EXPORT void
+weston_drm_backend_config_clear_outputs_setup(
+               struct weston_drm_backend_config * ths);
+
+WL_EXPORT void
+weston_drm_backend_add_output_setup(
+               struct weston_drm_backend_config * ths,
+               char const * name,
+               int scale,
+               uint32_t transform,
+               char const * format,
+               char const * seat,
+               enum weston_drm_backend_output_mode mode,
+               char const * modeline
+);
+
+WL_EXPORT int
+weston_drm_backend_load(struct weston_compositor *compositor,
+                int *argc, char **argv, struct weston_config *wc,
+                struct weston_drm_backend_config *wbc);
+
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/main.c b/src/main.c
index 1850fa6..d9abe6e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -47,6 +47,8 @@
 #include "git-version.h"
 #include "version.h"
 
+#include "compositor-drm.h"
+
 static struct wl_list child_process_list;
 static struct weston_compositor *segv_compositor;
 
@@ -654,12 +656,133 @@ load_backend_old(struct weston_compositor *compositor, 
const char *backend,
 }
 
 static int
+load_drm_backend(struct weston_compositor *c, char const * backend,
+                int *argc, char **argv, struct weston_config *wc)
+{
+       struct weston_drm_backend_config *config;
+       struct weston_config_section *section;
+       int ret = 0;
+
+       config = weston_drm_backend_config_create();
+       if (!config)
+               return -1;
+
+       int cf_connector = 0;
+       int cf_tty = 0;
+       bool cf_use_pixman = false;
+       bool cf_use_current_mode = true;
+       char *cf_seat_id = NULL;
+       char *cf_format = NULL;
+
+       const struct weston_option options[] = {
+               { WESTON_OPTION_INTEGER, "connector", 0, &cf_connector },
+               { WESTON_OPTION_STRING, "seat", 0, &cf_seat_id },
+               { WESTON_OPTION_INTEGER, "tty", 0, &cf_tty },
+               { WESTON_OPTION_BOOLEAN, "current-mode", 0, 
&cf_use_current_mode },
+               { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &cf_use_pixman },
+       };
+
+       parse_options(options, ARRAY_LENGTH(options), argc, argv);
+
+       /* get format */
+       section = weston_config_get_section(wc, "core", NULL, NULL);
+       weston_config_section_get_string(section, "gbm-format", &cf_format, 
NULL);
+
+       /* fill the config structure */
+       weston_drm_backend_config_set_connector(config, cf_connector);
+       weston_drm_backend_config_set_seat_id(config, cf_seat_id);
+       weston_drm_backend_config_set_tty(config, cf_tty);
+       weston_drm_backend_config_set_use_current_mode(config, 
cf_use_current_mode);
+       weston_drm_backend_config_set_use_pixman(config, cf_use_pixman);
+
+       if(cf_format)
+               weston_drm_backend_config_set_format(config, cf_format);
+
+       /**
+        * find all output section and create settings for
+        * each of them.
+        **/
+       char const * section_name = NULL;
+       section = NULL;
+       while(weston_config_next_section(wc, &section, &section_name)) {
+
+               if(strcmp("output", section_name) == 0) {
+                       char *cf_name = NULL;
+                       char *cf_mode = NULL;
+                       int cf_scale = 1;
+                       char *cf_transform = NULL;
+                       char *cf_gbm_format = NULL;
+                       char *cf_seat = NULL;
+
+                       weston_config_section_get_string(section, "name", 
&cf_name, NULL);
+                       if(!cf_name)
+                               continue;
+
+                       /* output setup data */
+                       enum weston_drm_backend_output_mode mode;
+                       char * modeline = NULL;
+                       uint32_t transform = 0;
+                       uint32_t scale = 0;
+
+                       weston_config_section_get_string(section, "mode", 
&cf_mode, "preferred");
+                       if (strcmp(cf_mode, "off") == 0) {
+                               free(cf_mode);
+                               weston_drm_backend_add_output_setup(config, 
cf_name, 0, 0,
+                                                       NULL, NULL, 
WESTON_DRM_BACKEND_OUTPUT_OFF, NULL);
+                               continue;
+                       }
+
+                       if (cf_use_current_mode || strcmp(cf_mode, "current") 
== 0) {
+                               mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
+                       } else if (strcmp(cf_mode, "preferred") != 0) {
+                               modeline = cf_mode;
+                               modeline = NULL;
+                       }
+                       free(cf_mode);
+
+
+                       weston_config_section_get_int(section, "scale", 
&cf_scale, 1);
+                       scale = cf_scale >= 1 ? cf_scale : 1;
+
+                       weston_config_section_get_string(section, "transform",
+                                       &cf_transform, "normal");
+
+                       if (weston_parse_transform(cf_transform, &transform) < 
0)
+                               weston_log("Invalid transform \"%s\" for output 
%s\n",
+                                          cf_transform, cf_name);
+                       free(cf_transform);
+
+
+                       weston_config_section_get_string(section,
+                                                        "gbm-format", 
&cf_gbm_format, NULL);
+
+                       weston_config_section_get_string(section, "seat", 
&cf_seat, "");
+
+                       weston_drm_backend_add_output_setup(config, cf_name, 
scale,
+                                       transform, cf_gbm_format, cf_seat, 
mode, modeline);
+
+                       free(cf_name);
+                       free(cf_gbm_format);
+                       free(cf_seat);
+               }
+       }
+
+       /* load the actual drm backend and configure it */
+       if (weston_drm_backend_load(c, argc, argv, wc, config) < 0) {
+               ret = -1;
+       }
+
+       return ret;
+}
+
+
+static int
 load_backend(struct weston_compositor *compositor, const char *backend,
             int *argc, char **argv, struct weston_config *config)
 {
-#if 0
        if (strstr(backend, "drm-backend.so"))
                return load_drm_backend(compositor, backend, argc, argv, 
config);
+#if 0
        else if (strstr(backend, "wayland-backend.so"))
                return load_wayland_backend(compositor, backend, argc, argv, 
config);
        else if (strstr(backend, "x11-backend.so"))
@@ -768,7 +891,7 @@ int main(int argc, char *argv[])
                        backend = weston_choose_default_backend();
        }
 
-       ec = weston_compositor_create(display, NULL);
+       ec = weston_compositor_create(display, config);
        if (ec == NULL) {
                weston_log("fatal: failed to create compositor\n");
                goto out;
-- 
2.4.10

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to