[PATCH weston 07/12 v2] Port RDP backend to new output handling API
Pekka Paalanen
ppaalanen at gmail.com
Thu Aug 18 12:33:02 UTC 2016
On Sun, 14 Aug 2016 17:28:16 +0200
Armin Krezović <krezovic.armin at gmail.com> wrote:
> This is a complete port of the RDP backend that uses
> recently added output handling API for output
> configuration.
>
> Output can be configured at runtime by passing the
> necessary configuration parameters, which can be
> filled in manually or obtained from the command line
> using previously added functionality. It is required
> that the scale and transform values are set using
> the previously added functionality.
>
> After everything has been set, output needs to be
> enabled manually using weston_output_enable().
>
> v2:
>
> - Rename output_configure() to output_set_size()
> in plugin API and describe it.
> - Manually fetch parsed_options from wet_compositor.
> - Call rdp_output_disable() explicitly from
> rdp_output_destroy().
>
> Signed-off-by: Armin Krezović <krezovic.armin at gmail.com>
> ---
> compositor/main.c | 52 ++++++++++++++++--
> libweston/compositor-rdp.c | 130 +++++++++++++++++++++++++++++++--------------
> libweston/compositor-rdp.h | 24 ++++++++-
> 3 files changed, 160 insertions(+), 46 deletions(-)
>
> diff --git a/compositor/main.c b/compositor/main.c
> index b26760c..a72c2f9 100644
> --- a/compositor/main.c
> +++ b/compositor/main.c
> @@ -1284,13 +1284,46 @@ load_headless_backend(struct weston_compositor *c,
> }
>
> static void
> +rdp_backend_output_configure(struct wl_listener *listener, void *data)
> +{
> + struct weston_output *output = data;
> + struct wet_compositor *compositor = to_wet_compositor(output->compositor);
> + struct wet_output_config *parsed_options = compositor->parsed_options;
> + const struct weston_rdp_output_api *api = weston_rdp_output_get_api(output->compositor);
> + int width = 640;
> + int height = 480;
> +
> + assert(parsed_options);
> +
> + if (!api) {
> + weston_log("Cannot use weston_rdp_output_api.\n");
> + return;
> + }
> +
> + if (parsed_options->width)
> + width = parsed_options->width;
> +
> + if (parsed_options->height)
> + height = parsed_options->height;
> +
> + weston_output_set_scale(output, 1);
> + weston_output_set_transform(output, WL_OUTPUT_TRANSFORM_NORMAL);
> +
> + if (api->output_set_size(output, width, height) < 0) {
> + weston_log("Cannot configure output \"%s\" using weston_rdp_output_api.\n",
> + output->name);
> + return;
> + }
> +
> + weston_output_enable(output);
> +}
> +
> +static void
> weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
> {
> config->base.struct_version = WESTON_RDP_BACKEND_CONFIG_VERSION;
> config->base.struct_size = sizeof(struct weston_rdp_backend_config);
>
> - config->width = 640;
> - config->height = 480;
> config->bind_address = NULL;
> config->port = 3389;
> config->rdp_key = NULL;
> @@ -1307,12 +1340,16 @@ load_rdp_backend(struct weston_compositor *c,
> struct weston_rdp_backend_config config = {{ 0, }};
> int ret = 0;
>
> + struct wet_output_config *parsed_options = wet_init_parsed_options(c);
> + if (!parsed_options)
> + return -1;
> +
> weston_rdp_backend_config_init(&config);
>
> const struct weston_option rdp_options[] = {
> { WESTON_OPTION_BOOLEAN, "env-socket", 0, &config.env_socket },
> - { WESTON_OPTION_INTEGER, "width", 0, &config.width },
> - { WESTON_OPTION_INTEGER, "height", 0, &config.height },
> + { WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width },
> + { WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
> { WESTON_OPTION_STRING, "address", 0, &config.bind_address },
> { WESTON_OPTION_INTEGER, "port", 0, &config.port },
> { WESTON_OPTION_BOOLEAN, "no-clients-resize", 0, &config.no_clients_resize },
> @@ -1326,10 +1363,17 @@ load_rdp_backend(struct weston_compositor *c,
> ret = weston_compositor_load_backend(c, WESTON_BACKEND_RDP,
> &config.base);
>
> + if (ret < 0)
> + goto out;
> +
> + wet_set_pending_output_handler(c, rdp_backend_output_configure);
> +
> +out:
> free(config.bind_address);
> free(config.rdp_key);
> free(config.server_cert);
> free(config.server_key);
> +
> return ret;
> }
>
Again, main.c stuff looks good.
> diff --git a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c
> index 11f5f05..ffa2fdf 100644
> --- a/libweston/compositor-rdp.c
> +++ b/libweston/compositor-rdp.c
> @@ -371,15 +371,6 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
> return 0;
> }
>
> -static void
> -rdp_output_destroy(struct weston_output *output_base)
> -{
> - struct rdp_output *output = to_rdp_output(output_base);
> -
> - wl_event_source_remove(output->finish_frame_timer);
> - free(output);
> -}
> -
> static int
> finish_frame_handler(void *data)
> {
> @@ -471,17 +462,13 @@ rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode)
> }
>
> static int
> -rdp_backend_create_output(struct rdp_backend *b, int width, int height)
> +rdp_output_configure(struct weston_output *base,
> + int width, int height)
> {
> - struct rdp_output *output;
> - struct wl_event_loop *loop;
> + struct rdp_output *output = to_rdp_output(base);
> struct weston_mode *currentMode;
> struct weston_mode initMode;
>
> - output = zalloc(sizeof *output);
> - if (output == NULL)
> - return -1;
> -
> wl_list_init(&output->peers);
> wl_list_init(&output->base.mode_list);
>
> @@ -492,48 +479,100 @@ rdp_backend_create_output(struct rdp_backend *b, int width, int height)
>
> currentMode = ensure_matching_mode(&output->base, &initMode);
> if (!currentMode)
> - goto out_free_output;
> + return -1;
>
> output->base.current_mode = output->base.native_mode = currentMode;
> - weston_output_init(&output->base, b->compositor, 0, 0, width, height,
> - WL_OUTPUT_TRANSFORM_NORMAL, 1);
>
> output->base.make = "weston";
> output->base.model = "rdp";
> + output->base.mm_width = width;
> + output->base.mm_height = height;
> +
> + output->base.start_repaint_loop = rdp_output_start_repaint_loop;
> + output->base.repaint = rdp_output_repaint;
> + output->base.assign_planes = NULL;
> + output->base.set_backlight = NULL;
> + output->base.set_dpms = NULL;
> + output->base.switch_mode = rdp_switch_mode;
> +
> + return 0;
> +}
> +
> +static int
> +rdp_output_enable(struct weston_output *base)
> +{
> + struct rdp_output *output = to_rdp_output(base);
> + struct rdp_backend *b = to_rdp_backend(base->compositor);
> + struct wl_event_loop *loop;
> +
> output->shadow_surface = pixman_image_create_bits(PIXMAN_x8r8g8b8,
> - width, height,
> + output->base.mm_width, output->base.mm_height,
Use base.current_mode.width and height.
> NULL,
> - width * 4);
> + output->base.mm_width * 4);
> if (output->shadow_surface == NULL) {
> weston_log("Failed to create surface for frame buffer.\n");
> - goto out_output;
> + return -1;
> }
>
> - if (pixman_renderer_output_create(&output->base) < 0)
> - goto out_shadow_surface;
> + if (pixman_renderer_output_create(&output->base) < 0) {
> + pixman_image_unref(output->shadow_surface);
> + return -1;
> + }
>
> loop = wl_display_get_event_loop(b->compositor->wl_display);
> output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output);
>
> - output->base.start_repaint_loop = rdp_output_start_repaint_loop;
> - output->base.repaint = rdp_output_repaint;
> - output->base.destroy = rdp_output_destroy;
> - output->base.assign_planes = NULL;
> - output->base.set_backlight = NULL;
> - output->base.set_dpms = NULL;
> - output->base.switch_mode = rdp_switch_mode;
> b->output = output;
>
> - weston_compositor_add_output(b->compositor, &output->base);
> return 0;
> +}
> +
> +static int
> +rdp_output_disable(struct weston_output *base)
> +{
> + struct rdp_output *output = to_rdp_output(base);
> + struct rdp_backend *b = to_rdp_backend(base->compositor);
> +
> + if (!output->base.enabled)
> + return 0;
>
> -out_shadow_surface:
> pixman_image_unref(output->shadow_surface);
> -out_output:
> + pixman_renderer_output_destroy(&output->base);
I don't see the pixman_image_unref() or
pixman_renderer_output_destroy() in the original code for this path,
did you add them yourself?
Adding them is correct I believe, but it should be a separate patch.
> +
> + wl_event_source_remove(output->finish_frame_timer);
> + b->output = NULL;
> +
> + return 0;
> +}
> +
> +static void
> +rdp_output_destroy(struct weston_output *base)
> +{
> + struct rdp_output *output = to_rdp_output(base);
> +
> + rdp_output_disable(&output->base);
> weston_output_destroy(&output->base);
> -out_free_output:
> +
> free(output);
> - return -1;
> +}
> +
> +static int
> +rdp_backend_create_output(struct weston_compositor *compositor)
> +{
> + struct rdp_output *output;
> +
> + output = zalloc(sizeof *output);
> + if (output == NULL)
> + return -1;
> +
> + output->base.name = NULL;
> + output->base.destroy = rdp_output_destroy;
> + output->base.disable = rdp_output_disable;
> + output->base.enable = rdp_output_enable;
> +
> + weston_output_init_pending(&output->base, compositor);
> +
> + return 0;
> }
>
> static void
> @@ -1216,6 +1255,10 @@ rdp_incoming_peer(freerdp_listener *instance, freerdp_peer *client)
> FREERDP_CB_RETURN(TRUE);
> }
>
> +static const struct weston_rdp_output_api api = {
> + rdp_output_configure,
> +};
> +
> static struct rdp_backend *
> rdp_backend_create(struct weston_compositor *compositor,
> struct weston_rdp_backend_config *config)
> @@ -1223,7 +1266,7 @@ rdp_backend_create(struct weston_compositor *compositor,
> struct rdp_backend *b;
> char *fd_str;
> char *fd_tail;
> - int fd;
> + int fd, ret;
>
> b = zalloc(sizeof *b);
> if (b == NULL)
> @@ -1251,7 +1294,7 @@ rdp_backend_create(struct weston_compositor *compositor,
> if (pixman_renderer_init(compositor) < 0)
> goto err_compositor;
>
> - if (rdp_backend_create_output(b, config->width, config->height) < 0)
> + if (rdp_backend_create_output(compositor) < 0)
> goto err_compositor;
>
> compositor->capabilities |= WESTON_CAP_ARBITRARY_MODES;
> @@ -1282,6 +1325,15 @@ rdp_backend_create(struct weston_compositor *compositor,
> }
>
> compositor->backend = &b->base;
> +
> + ret = weston_plugin_api_register(compositor, WESTON_RDP_OUTPUT_API_NAME,
> + &api, sizeof(api));
> +
> + if (ret < 0) {
> + weston_log("Failed to register output API.\n");
> + goto err_output;
> + }
> +
> return b;
>
> err_listener:
> @@ -1301,8 +1353,6 @@ err_free_strings:
> static void
> config_init_to_defaults(struct weston_rdp_backend_config *config)
> {
> - config->width = 640;
> - config->height = 480;
> config->bind_address = NULL;
> config->port = 3389;
> config->rdp_key = NULL;
> diff --git a/libweston/compositor-rdp.h b/libweston/compositor-rdp.h
> index dfa1759..44bea3d 100644
> --- a/libweston/compositor-rdp.h
> +++ b/libweston/compositor-rdp.h
> @@ -31,13 +31,33 @@ extern "C" {
> #endif
>
> #include "compositor.h"
> +#include "plugin-registry.h"
> +
> +#define WESTON_RDP_OUTPUT_API_NAME "weston_rdp_output_api_v1"
> +
> +struct weston_rdp_output_api {
> + /** Initialize a RDP output with specified width and height.
> + *
> + * Returns 0 on success, -1 on failure.
> + */
> + int (*output_set_size)(struct weston_output *output,
> + int width, int height);
> +};
> +
> +static inline const struct weston_rdp_output_api *
> +weston_rdp_output_get_api(struct weston_compositor *compositor)
> +{
> + const void *api;
> + api = weston_plugin_api_get(compositor, WESTON_RDP_OUTPUT_API_NAME,
> + sizeof(struct weston_rdp_output_api));
> +
> + return (const struct weston_rdp_output_api *)api;
> +}
>
> #define WESTON_RDP_BACKEND_CONFIG_VERSION 1
>
> struct weston_rdp_backend_config {
> struct weston_backend_config base;
> - int width;
> - int height;
> char *bind_address;
> int port;
> char *rdp_key;
Whenever you remove or change existing fields from a struct
weston_*_backend_config, you need to bump the
WESTON_*_BACKEND_CONFIG_VERSION.
This applies to all the backends. Again I just didn't notice earlier.
Not much to fix in this patch, nice!
Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20160818/9e50f4df/attachment.sig>
More information about the wayland-devel
mailing list