Skip to content
Commits on Source (9)
......@@ -1696,8 +1696,8 @@ simple_head_enable(struct wet_compositor *wet, struct weston_head *head)
struct weston_output *output;
int ret = 0;
output = weston_compositor_create_output_with_head(wet->compositor,
head);
output = weston_compositor_create_output(wet->compositor, head,
head->name);
if (!output) {
weston_log("Could not create an output for head \"%s\".\n",
weston_head_get_name(head));
......@@ -2152,7 +2152,9 @@ wet_output_handle_destroy(struct wl_listener *listener, void *data)
}
static struct wet_output *
wet_layoutput_create_output(struct wet_layoutput *lo, const char *name)
wet_layoutput_create_output_with_head(struct wet_layoutput *lo,
const char *name,
struct weston_head *head)
{
struct wet_output *output;
......@@ -2162,7 +2164,7 @@ wet_layoutput_create_output(struct wet_layoutput *lo, const char *name)
output->output =
weston_compositor_create_output(lo->compositor->compositor,
name);
head, name);
if (!output->output) {
free(output);
return NULL;
......@@ -2315,8 +2317,8 @@ drm_try_attach(struct weston_output *output,
{
unsigned i;
/* try to attach all heads, this probably succeeds */
for (i = 0; i < add->n; i++) {
/* try to attach remaining heads, this probably succeeds */
for (i = 1; i < add->n; i++) {
if (!add->heads[i])
continue;
......@@ -2432,7 +2434,8 @@ drm_process_layoutput(struct wet_compositor *wet, struct wet_layoutput *lo)
if (ret < 0)
return -1;
}
output = wet_layoutput_create_output(lo, name);
output = wet_layoutput_create_output_with_head(lo, name,
lo->add.heads[0]);
free(name);
name = NULL;
......
......@@ -11,7 +11,7 @@ msc {
--- [label = "Compositor creates an output for a head"];
c box c [label = "Have an existing head to process."];
c => w [label = "weston_compositor_create_output_with_head()"];
c => w [label = "weston_compositor_create_output()"];
w => b [label = "weston_backend::create_output()"];
w << b [label = "an empty output, no hw resources"];
w => b [label = "weston_output::attach_head()"];
......
......@@ -90,7 +90,7 @@ weston_drm_output_get_api(struct weston_compositor *compositor)
return (const struct weston_drm_output_api *)api;
}
#define WESTON_DRM_VIRTUAL_OUTPUT_API_NAME "weston_drm_virtual_output_api_v1"
#define WESTON_DRM_VIRTUAL_OUTPUT_API_NAME "weston_drm_virtual_output_api_v2"
struct drm_fb;
typedef int (*submit_frame_cb)(struct weston_output *output, int fd,
......@@ -101,12 +101,16 @@ struct weston_drm_virtual_output_api {
* This is a low-level function, where the caller is expected to wrap
* the weston_output function pointers as necessary to make the virtual
* output useful. The caller must set up output make, model, serial,
* physical size, the mode list and current mode.
* physical size, the mode list and current mode. The destroy function
* pointer must not be overwritten, as it is used by the DRM backend to
* recognize its outputs. Instead, an auxiliary destroy callback has to
* be provided as a parameter.
*
* Returns output on success, NULL on failure.
*/
struct weston_output* (*create_output)(struct weston_compositor *c,
char *name);
char *name,
void (*destroy_func)(struct weston_output *base));
/** Set pixel format same as drm_output set_gbm_format().
*
......
......@@ -395,6 +395,9 @@ struct weston_head {
/** Current content protection status */
enum weston_hdcp_protection current_protection;
/** Opaque pointer used by backends to identify heads as theirs */
const void *backend_id;
};
/** Output properties derived from its color characteristics and profile
......@@ -2225,11 +2228,7 @@ weston_compositor_find_output_by_name(struct weston_compositor *compositor,
struct weston_output *
weston_compositor_create_output(struct weston_compositor *compositor,
const char *name);
struct weston_output *
weston_compositor_create_output_with_head(struct weston_compositor *compositor,
struct weston_head *head);
struct weston_head *head, const char *name);
void
weston_output_destroy(struct weston_output *output);
......
......@@ -579,19 +579,36 @@ struct drm_output {
struct wl_event_source *pageflip_timer;
bool virtual;
void (*virtual_destroy)(struct weston_output *base);
submit_frame_cb virtual_submit_frame;
};
void
drm_head_destroy(struct weston_head *head_base);
static inline struct drm_head *
to_drm_head(struct weston_head *base)
{
if (base->backend_id != drm_head_destroy)
return NULL;
return container_of(base, struct drm_head, base);
}
void
drm_output_destroy(struct weston_output *output_base);
void
drm_virtual_output_destroy(struct weston_output *output_base);
static inline struct drm_output *
to_drm_output(struct weston_output *base)
{
if (
#ifdef BUILD_DRM_VIRTUAL
base->destroy != drm_virtual_output_destroy &&
#endif
base->destroy != drm_output_destroy)
return NULL;
return container_of(base, struct drm_output, base);
}
......
......@@ -245,7 +245,7 @@ drm_virtual_output_deinit(struct weston_output *base)
drm_virtual_crtc_destroy(output->crtc);
}
static void
void
drm_virtual_output_destroy(struct weston_output *base)
{
struct drm_output *output = to_drm_output(base);
......@@ -259,6 +259,9 @@ drm_virtual_output_destroy(struct weston_output *base)
drm_output_state_free(output->state_cur);
if (output->virtual_destroy)
output->virtual_destroy(base);
free(output);
}
......@@ -324,7 +327,8 @@ drm_virtual_output_disable(struct weston_output *base)
}
static struct weston_output *
drm_virtual_output_create(struct weston_compositor *c, char *name)
drm_virtual_output_create(struct weston_compositor *c, char *name,
void (*destroy_func)(struct weston_output *))
{
struct drm_output *output;
struct drm_backend *b = to_drm_backend(c);
......@@ -343,6 +347,7 @@ drm_virtual_output_create(struct weston_compositor *c, char *name)
}
output->virtual = true;
output->virtual_destroy = destroy_func;
output->gbm_bo_flags = GBM_BO_USE_LINEAR | GBM_BO_USE_RENDERING;
weston_output_init(&output->base, c, name);
......
......@@ -164,9 +164,6 @@ drm_output_pageflip_timer_create(struct drm_output *output)
return 0;
}
static void
drm_output_destroy(struct weston_output *output_base);
/**
* Returns true if the plane can be used on the given output for its current
* repaint cycle.
......@@ -214,6 +211,8 @@ drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id)
wl_list_for_each(base,
&backend->compositor->head_list, compositor_link) {
head = to_drm_head(base);
if (!head)
continue;
if (head->connector.connector_id == connector_id)
return head;
}
......@@ -451,6 +450,7 @@ drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
struct drm_pending_state *pending_state;
struct drm_device *device;
assert(output);
assert(!output->virtual);
device = output->device;
......@@ -689,8 +689,11 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
struct drm_output *output = to_drm_output(output_base);
struct drm_device *device = output->device;
struct drm_backend *b = device->backend;
struct drm_mode *drm_mode = drm_output_choose_mode(output, mode);
struct drm_mode *drm_mode;
assert(output);
drm_mode = drm_output_choose_mode(output, mode);
if (!drm_mode) {
weston_log("%s: invalid resolution %dx%d\n",
output_base->name, mode->width, mode->height);
......@@ -1053,6 +1056,7 @@ drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
struct drm_output_state *state;
int ret;
assert(output);
assert(!output->virtual);
if (output->state_cur->dpms == level)
......@@ -1491,6 +1495,8 @@ drm_output_pick_crtc(struct drm_output *output)
match = false;
wl_list_for_each(base, &compositor->head_list, compositor_link) {
head = to_drm_head(base);
if (!head)
continue;
if (head->base.output == &output->base)
continue;
......@@ -1808,6 +1814,7 @@ drm_output_enable(struct weston_output *base)
struct drm_backend *b = device->backend;
int ret;
assert(output);
assert(!output->virtual);
if (output->gbm_format == DRM_FORMAT_INVALID) {
......@@ -1885,15 +1892,13 @@ drm_output_deinit(struct weston_output *base)
}
}
static void
drm_head_destroy(struct drm_head *head);
static void
void
drm_output_destroy(struct weston_output *base)
{
struct drm_output *output = to_drm_output(base);
struct drm_device *device = output->device;
assert(output);
assert(!output->virtual);
if (output->page_flip_pending || output->atomic_complete_pending) {
......@@ -1927,6 +1932,7 @@ drm_output_disable(struct weston_output *base)
{
struct drm_output *output = to_drm_output(base);
assert(output);
assert(!output->virtual);
if (output->page_flip_pending || output->atomic_complete_pending) {
......@@ -2197,6 +2203,8 @@ drm_head_create(struct drm_device *device, drmModeConnector *conn,
weston_head_init(&head->base, name);
free(name);
head->base.backend_id = drm_head_destroy;
ret = drm_head_update_info(head, conn);
if (ret < 0)
goto err_update;
......@@ -2226,9 +2234,13 @@ err:
return -1;
}
static void
drm_head_destroy(struct drm_head *head)
void
drm_head_destroy(struct weston_head *base)
{
struct drm_head *head = to_drm_head(base);
assert(head);
weston_head_release(&head->base);
drm_connector_fini(&head->connector);
......@@ -2466,6 +2478,8 @@ drm_backend_update_connectors(struct drm_device *device,
wl_list_for_each_safe(base, base_next,
&b->compositor->head_list, compositor_link) {
head = to_drm_head(base);
if (!head)
continue;
connector_id = head->connector.connector_id;
if (head->connector.device != device)
......@@ -2476,7 +2490,7 @@ drm_backend_update_connectors(struct drm_device *device,
weston_log("DRM: head '%s' (connector %d) disappeared.\n",
head->base.name, connector_id);
drm_head_destroy(head);
drm_head_destroy(base);
}
/* Destroy writeback objects of writeback connectors that have
......@@ -2630,8 +2644,10 @@ drm_destroy(struct weston_compositor *ec)
wl_list_for_each_safe(crtc, crtc_tmp, &b->drm->crtc_list, link)
drm_crtc_destroy(crtc);
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
drm_head_destroy(to_drm_head(base));
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
if (to_drm_head(base))
drm_head_destroy(base);
}
wl_list_for_each_safe(writeback, writeback_tmp,
&b->drm->writeback_connector_list, link)
......
......@@ -487,6 +487,8 @@ drm_output_set_gamma(struct weston_output *output_base,
struct drm_output *output = to_drm_output(output_base);
struct drm_device *device = output->device;
assert(output);
/* check */
if (output_base->gamma_size != size)
return;
......
......@@ -926,6 +926,8 @@ drm_assign_planes(struct weston_output *output_base)
struct weston_plane *primary = &output_base->compositor->primary_plane;
enum drm_output_propose_state_mode mode = DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY;
assert(output);
drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n",
output_base->name, (unsigned long) output_base->id);
......
......@@ -79,15 +79,25 @@ static const uint32_t headless_formats[] = {
DRM_FORMAT_ARGB8888,
};
static void
headless_head_destroy(struct weston_head *base);
static inline struct headless_head *
to_headless_head(struct weston_head *base)
{
if (base->backend_id != headless_head_destroy)
return NULL;
return container_of(base, struct headless_head, base);
}
static void
headless_output_destroy(struct weston_output *base);
static inline struct headless_output *
to_headless_output(struct weston_output *base)
{
if (base->destroy != headless_output_destroy)
return NULL;
return container_of(base, struct headless_output, base);
}
......@@ -125,7 +135,11 @@ headless_output_repaint(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct headless_output *output = to_headless_output(output_base);
struct weston_compositor *ec = output->base.compositor;
struct weston_compositor *ec;
assert(output);
ec = output->base.compositor;
ec->renderer->repaint_output(&output->base, damage);
......@@ -158,11 +172,15 @@ static int
headless_output_disable(struct weston_output *base)
{
struct headless_output *output = to_headless_output(base);
struct headless_backend *b = to_headless_backend(base->compositor);
struct headless_backend *b;
assert(output);
if (!output->base.enabled)
return 0;
b = to_headless_backend(base->compositor);
wl_event_source_remove(output->finish_frame_timer);
switch (b->renderer_type) {
......@@ -184,6 +202,8 @@ headless_output_destroy(struct weston_output *base)
{
struct headless_output *output = to_headless_output(base);
assert(output);
headless_output_disable(&output->base);
weston_output_release(&output->base);
......@@ -246,10 +266,14 @@ static int
headless_output_enable(struct weston_output *base)
{
struct headless_output *output = to_headless_output(base);
struct headless_backend *b = to_headless_backend(base->compositor);
struct headless_backend *b;
struct wl_event_loop *loop;
int ret = 0;
assert(output);
b = to_headless_backend(base->compositor);
loop = wl_display_get_event_loop(b->compositor->wl_display);
output->finish_frame_timer =
wl_event_loop_add_timer(loop, finish_frame_handler, output);
......@@ -286,6 +310,9 @@ headless_output_set_size(struct weston_output *base,
struct weston_head *head;
int output_width, output_height;
if (!output)
return -1;
/* We can only be called once. */
assert(!output->base.current_mode);
......@@ -360,6 +387,9 @@ headless_head_create(struct weston_compositor *compositor,
return -1;
weston_head_init(&head->base, name);
head->base.backend_id = headless_head_destroy;
weston_head_set_connection_status(&head->base, true);
weston_head_set_supported_eotf_mask(&head->base,
WESTON_EOTF_MODE_ALL_MASK);
......@@ -375,8 +405,12 @@ headless_head_create(struct weston_compositor *compositor,
}
static void
headless_head_destroy(struct headless_head *head)
headless_head_destroy(struct weston_head *base)
{
struct headless_head *head = to_headless_head(base);
assert(head);
weston_head_release(&head->base);
free(head);
}
......@@ -389,8 +423,10 @@ headless_destroy(struct weston_compositor *ec)
weston_compositor_shutdown(ec);
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
headless_head_destroy(to_headless_head(base));
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
if (to_headless_head(base))
headless_head_destroy(base);
}
free(b);
}
......
......@@ -273,6 +273,8 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
next_frame_delta = refresh_msec;
}
assert(output);
pixman_renderer_output_set_buffer(output_base, output->shadow_surface);
ec->renderer->repaint_output(&output->base, damage);
......@@ -344,6 +346,8 @@ rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode)
struct weston_mode *local_mode;
const struct pixman_renderer_output_options options = { .use_shadow = true, };
assert(output);
local_mode = ensure_matching_mode(output, target_mode);
if (!local_mode) {
rdp_debug(rdpBackend, "mode %dx%d not available\n", target_mode->width, target_mode->height);
......@@ -396,6 +400,8 @@ rdp_output_set_size(struct weston_output *base,
struct weston_mode *currentMode;
struct weston_mode initMode;
assert(output);
/* We can only be called once. */
assert(!output->base.current_mode);
......@@ -433,12 +439,16 @@ 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 rdp_backend *b;
struct wl_event_loop *loop;
const struct pixman_renderer_output_options options = {
.use_shadow = true,
};
assert(output);
b = to_rdp_backend(base->compositor);
output->shadow_surface = pixman_image_create_bits(PIXMAN_x8r8g8b8,
output->base.current_mode->width,
output->base.current_mode->height,
......@@ -466,7 +476,11 @@ 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);
struct rdp_backend *b;
assert(output);
b = to_rdp_backend(base->compositor);
if (!output->base.enabled)
return 0;
......@@ -480,11 +494,13 @@ rdp_output_disable(struct weston_output *base)
return 0;
}
static void
void
rdp_output_destroy(struct weston_output *base)
{
struct rdp_output *output = to_rdp_output(base);
assert(output);
rdp_output_disable(&output->base);
weston_output_release(&output->base);
......@@ -522,15 +538,22 @@ rdp_head_create(struct weston_compositor *compositor, const char *name)
return -1;
weston_head_init(&head->base, name);
head->base.backend_id = rdp_head_destroy;
weston_head_set_connection_status(&head->base, true);
weston_compositor_add_head(compositor, &head->base);
return 0;
}
static void
rdp_head_destroy(struct rdp_head *head)
void
rdp_head_destroy(struct weston_head *base)
{
struct rdp_head *head = to_rdp_head(base);
assert(head);
weston_head_release(&head->base);
free(head);
}
......@@ -577,8 +600,10 @@ rdp_destroy(struct weston_compositor *ec)
weston_compositor_shutdown(ec);
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
rdp_head_destroy(to_rdp_head(base));
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
if (to_rdp_head(base))
rdp_head_destroy(base);
}
freerdp_listener_free(b->listener);
......@@ -1734,8 +1759,10 @@ err_output:
if (b->output)
weston_output_release(&b->output->base);
err_compositor:
wl_list_for_each_safe(base, next, &compositor->head_list, compositor_link)
rdp_head_destroy(to_rdp_head(base));
wl_list_for_each_safe(base, next, &compositor->head_list, compositor_link) {
if (to_rdp_head(base))
rdp_head_destroy(base);
}
weston_compositor_shutdown(compositor);
err_free_strings:
......
......@@ -232,15 +232,25 @@ rdp_clipboard_init(freerdp_peer *client);
void
rdp_clipboard_destroy(RdpPeerContext *peerCtx);
void
rdp_head_destroy(struct weston_head *base);
static inline struct rdp_head *
to_rdp_head(struct weston_head *base)
{
if (base->backend_id != rdp_head_destroy)
return NULL;
return container_of(base, struct rdp_head, base);
}
void
rdp_output_destroy(struct weston_output *base);
static inline struct rdp_output *
to_rdp_output(struct weston_output *base)
{
if (base->destroy != rdp_output_destroy)
return NULL;
return container_of(base, struct rdp_output, base);
}
......
......@@ -231,15 +231,25 @@ struct wayland_input {
struct gl_renderer_interface *gl_renderer;
static void
wayland_head_destroy(struct weston_head *base);
static inline struct wayland_head *
to_wayland_head(struct weston_head *base)
{
if (base->backend_id != wayland_head_destroy)
return NULL;
return container_of(base, struct wayland_head, base);
}
static void
wayland_output_destroy(struct weston_output *base);
static inline struct wayland_output *
to_wayland_output(struct weston_output *base)
{
if (base->destroy != wayland_output_destroy)
return NULL;
return container_of(base, struct wayland_output, base);
}
......@@ -499,8 +509,11 @@ static int
wayland_output_start_repaint_loop(struct weston_output *output_base)
{
struct wayland_output *output = to_wayland_output(output_base);
struct wayland_backend *wb =
to_wayland_backend(output->base.compositor);
struct wayland_backend *wb;
assert(output);
wb = to_wayland_backend(output->base.compositor);
/* If this is the initial frame, we need to attach a buffer so that
* the compositor can map the surface and include it in its render
......@@ -527,7 +540,11 @@ wayland_output_repaint_gl(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct wayland_output *output = to_wayland_output(output_base);
struct weston_compositor *ec = output->base.compositor;
struct weston_compositor *ec;
assert(output);
ec = output->base.compositor;
output->frame_cb = wl_surface_frame(output->parent.surface);
wl_callback_add_listener(output->frame_cb, &frame_listener, output);
......@@ -638,10 +655,13 @@ wayland_output_repaint_pixman(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct wayland_output *output = to_wayland_output(output_base);
struct wayland_backend *b =
to_wayland_backend(output->base.compositor);
struct wayland_backend *b;
struct wayland_shm_buffer *sb;
assert(output);
b = to_wayland_backend(output->base.compositor);
if (output->frame) {
if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
wl_list_for_each(sb, &output->shm.buffers, link)
......@@ -709,7 +729,11 @@ static int
wayland_output_disable(struct weston_output *base)
{
struct wayland_output *output = to_wayland_output(base);
struct wayland_backend *b = to_wayland_backend(base->compositor);
struct wayland_backend *b;
assert(output);
b = to_wayland_backend(base->compositor);
if (!output->base.enabled)
return 0;
......@@ -743,6 +767,8 @@ wayland_output_destroy(struct weston_output *base)
{
struct wayland_output *output = to_wayland_output(base);
assert(output);
wayland_output_disable(&output->base);
weston_output_release(&output->base);
......@@ -1045,7 +1071,7 @@ static int
wayland_output_switch_mode(struct weston_output *output_base,
struct weston_mode *mode)
{
struct wayland_output *output = to_wayland_output(output_base);
struct wayland_output *output;
struct wayland_backend *b;
struct wl_surface *old_surface;
struct weston_mode *old_mode;
......@@ -1056,6 +1082,9 @@ wayland_output_switch_mode(struct weston_output *output_base,
return -1;
}
output = to_wayland_output(output_base);
assert(output);
if (mode == NULL) {
weston_log("mode is NULL.\n");
return -1;
......@@ -1212,10 +1241,14 @@ static int
wayland_output_enable(struct weston_output *base)
{
struct wayland_output *output = to_wayland_output(base);
struct wayland_backend *b = to_wayland_backend(base->compositor);
struct wayland_backend *b;
enum mode_status mode_status;
int ret = 0;
assert(output);
b = to_wayland_backend(base->compositor);
wl_list_init(&output->shm.buffers);
wl_list_init(&output->shm.free_buffers);
......@@ -1291,9 +1324,16 @@ static int
wayland_output_attach_head(struct weston_output *output_base,
struct weston_head *head_base)
{
struct wayland_backend *b = to_wayland_backend(output_base->compositor);
struct wayland_output *output = to_wayland_output(output_base);
struct wayland_head *head = to_wayland_head(head_base);
struct wayland_backend *b;
assert(output);
if (!head)
return -1;
b = to_wayland_backend(output_base->compositor);
if (!wl_list_empty(&output->base.head_list))
return -1;
......@@ -1318,6 +1358,8 @@ wayland_output_detach_head(struct weston_output *output_base,
{
struct wayland_output *output = to_wayland_output(output_base);
assert(output);
/* Rely on the disable hook if the output was enabled. We do not
* support cloned heads, so detaching is guaranteed to disable the
* output.
......@@ -1376,6 +1418,9 @@ wayland_head_create(struct weston_compositor *compositor, const char *name)
return NULL;
weston_head_init(&head->base, name);
head->base.backend_id = wayland_head_destroy;
weston_head_set_connection_status(&head->base, true);
weston_compositor_add_head(compositor, &head->base);
......@@ -1423,8 +1468,12 @@ wayland_head_create_for_parent_output(struct weston_compositor *compositor,
}
static void
wayland_head_destroy(struct wayland_head *head)
wayland_head_destroy(struct weston_head *base)
{
struct wayland_head *head = to_wayland_head(base);
assert(head);
if (head->parent_output)
head->parent_output->head = NULL;
......@@ -1439,6 +1488,9 @@ wayland_output_set_size(struct weston_output *base, int width, int height)
struct weston_head *head;
int output_width, output_height;
if (!output)
return -1;
/* We can only be called once. */
assert(!output->base.current_mode);
......@@ -2555,7 +2607,7 @@ wayland_parent_output_destroy(struct wayland_parent_output *output)
wl_callback_destroy(output->sync_cb);
if (output->head)
wayland_head_destroy(output->head);
wayland_head_destroy(&output->head->base);
wl_output_destroy(output->global);
free(output->physical.make);
......@@ -2670,8 +2722,10 @@ wayland_destroy(struct weston_compositor *ec)
weston_compositor_shutdown(ec);
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
wayland_head_destroy(to_wayland_head(base));
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
if (to_wayland_head(base))
wayland_head_destroy(base);
}
wl_list_for_each_safe(input, next_input, &b->input_list, link)
wayland_input_destroy(input);
......
......@@ -151,15 +151,25 @@ struct window_delete_data {
struct gl_renderer_interface *gl_renderer;
static void
x11_head_destroy(struct weston_head *base);
static inline struct x11_head *
to_x11_head(struct weston_head *base)
{
if (base->backend_id != x11_head_destroy)
return NULL;
return container_of(base, struct x11_head, base);
}
static void
x11_output_destroy(struct weston_output *base);
static inline struct x11_output *
to_x11_output(struct weston_output *base)
{
if (base->destroy != x11_output_destroy)
return NULL;
return container_of(base, struct x11_output, base);
}
......@@ -420,7 +430,11 @@ x11_output_repaint_gl(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct x11_output *output = to_x11_output(output_base);
struct weston_compositor *ec = output->base.compositor;
struct weston_compositor *ec;
assert(output);
ec = output->base.compositor;
ec->renderer->repaint_output(output_base, damage);
......@@ -435,8 +449,8 @@ static void
set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region)
{
struct x11_output *output = to_x11_output(output_base);
struct weston_compositor *ec = output->base.compositor;
struct x11_backend *b = to_x11_backend(ec);
struct weston_compositor *ec;
struct x11_backend *b;
pixman_region32_t transformed_region;
pixman_box32_t *rects;
xcb_rectangle_t *output_rects;
......@@ -444,6 +458,12 @@ set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region
int nrects, i;
xcb_generic_error_t *err;
if (!output)
return;
ec = output->base.compositor;
b = to_x11_backend(ec);
pixman_region32_init(&transformed_region);
pixman_region32_copy(&transformed_region, region);
pixman_region32_translate(&transformed_region,
......@@ -488,11 +508,16 @@ x11_output_repaint_shm(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct x11_output *output = to_x11_output(output_base);
struct weston_compositor *ec = output->base.compositor;
struct x11_backend *b = to_x11_backend(ec);
struct weston_compositor *ec;
struct x11_backend *b;
xcb_void_cookie_t cookie;
xcb_generic_error_t *err;
assert(output);
ec = output->base.compositor;
b = to_x11_backend(ec);
pixman_renderer_output_set_buffer(output_base, output->hw_surface);
ec->renderer->repaint_output(output_base, damage);
......@@ -565,13 +590,13 @@ x11_output_set_wm_protocols(struct x11_backend *b,
}
struct wm_normal_hints {
uint32_t flags;
uint32_t flags;
uint32_t pad[4];
int32_t min_width, min_height;
int32_t max_width, max_height;
int32_t width_inc, height_inc;
int32_t min_aspect_x, min_aspect_y;
int32_t max_aspect_x, max_aspect_y;
int32_t width_inc, height_inc;
int32_t min_aspect_x, min_aspect_y;
int32_t max_aspect_x, max_aspect_y;
int32_t base_width, base_height;
int32_t win_gravity;
};
......@@ -801,12 +826,13 @@ static int
x11_output_switch_mode(struct weston_output *base, struct weston_mode *mode)
{
struct x11_backend *b;
struct x11_output *output;
struct x11_output *output = to_x11_output(base);
static uint32_t values[2];
int ret;
assert(output);
b = to_x11_backend(base->compositor);
output = to_x11_output(base);
if (mode->width == output->mode.width &&
mode->height == output->mode.height)
......@@ -878,7 +904,11 @@ static int
x11_output_disable(struct weston_output *base)
{
struct x11_output *output = to_x11_output(base);
struct x11_backend *backend = to_x11_backend(base->compositor);
struct x11_backend *backend;
assert(output);
backend = to_x11_backend(base->compositor);
if (!output->base.enabled)
return 0;
......@@ -903,6 +933,8 @@ x11_output_destroy(struct weston_output *base)
{
struct x11_output *output = to_x11_output(base);
assert(output);
x11_output_disable(&output->base);
weston_output_release(&output->base);
......@@ -913,7 +945,11 @@ static int
x11_output_enable(struct weston_output *base)
{
struct x11_output *output = to_x11_output(base);
struct x11_backend *b = to_x11_backend(base->compositor);
struct x11_backend *b;
assert(output);
b = to_x11_backend(base->compositor);
static const char name[] = "Weston Compositor";
static const char class[] = "weston-1\0Weston Compositor";
......@@ -1077,11 +1113,17 @@ static int
x11_output_set_size(struct weston_output *base, int width, int height)
{
struct x11_output *output = to_x11_output(base);
struct x11_backend *b = to_x11_backend(base->compositor);
struct x11_backend *b;
struct weston_head *head;
xcb_screen_t *scrn = b->screen;
xcb_screen_t *scrn;
int output_width, output_height;
if (!output)
return -1;
b = to_x11_backend(base->compositor);
scrn = b->screen;
/* We can only be called once. */
assert(!output->base.current_mode);
......@@ -1163,6 +1205,9 @@ x11_head_create(struct weston_compositor *compositor, const char *name)
return -1;
weston_head_init(&head->base, name);
head->base.backend_id = x11_head_destroy;
weston_head_set_connection_status(&head->base, true);
weston_compositor_add_head(compositor, &head->base);
......@@ -1170,8 +1215,12 @@ x11_head_create(struct weston_compositor *compositor, const char *name)
}
static void
x11_head_destroy(struct x11_head *head)
x11_head_destroy(struct weston_head *base)
{
struct x11_head *head = to_x11_head(base);
assert(head);
weston_head_release(&head->base);
free(head);
}
......@@ -1790,8 +1839,10 @@ x11_destroy(struct weston_compositor *ec)
weston_compositor_shutdown(ec); /* destroys outputs, too */
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
x11_head_destroy(to_x11_head(base));
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
if (to_x11_head(base))
x11_head_destroy(base);
}
XCloseDisplay(backend->dpy);
free(backend);
......
......@@ -7306,13 +7306,15 @@ weston_compositor_find_output_by_name(struct weston_compositor *compositor,
return NULL;
}
/** Create a named output
/** Create a named output for an unused head
*
* \param compositor The compositor.
* \param head The head to attach to the output.
* \param name The name for the output.
* \return A new \c weston_output, or NULL on failure.
*
* This creates a new weston_output that starts with no heads attached.
* This creates a new weston_output that starts with the given head attached.
* The head must not be already attached to another output.
*
* An output must be configured and it must have at least one head before
* it can be enabled.
......@@ -7321,8 +7323,11 @@ weston_compositor_find_output_by_name(struct weston_compositor *compositor,
*/
WL_EXPORT struct weston_output *
weston_compositor_create_output(struct weston_compositor *compositor,
struct weston_head *head,
const char *name)
{
struct weston_output *output;
assert(compositor->backend->create_output);
if (weston_compositor_find_output_by_name(compositor, name)) {
......@@ -7331,34 +7336,11 @@ weston_compositor_create_output(struct weston_compositor *compositor,
return NULL;
}
return compositor->backend->create_output(compositor, name);
}
/** Create an output for an unused head
*
* \param compositor The compositor.
* \param head The head to attach to the output.
* \return A new \c weston_output, or NULL on failure.
*
* This creates a new weston_output that starts with the given head attached.
* The output inherits the name of the head. The head must not be already
* attached to another output.
*
* An output must be configured before it can be enabled.
*
* \ingroup compositor
*/
WL_EXPORT struct weston_output *
weston_compositor_create_output_with_head(struct weston_compositor *compositor,
struct weston_head *head)
{
struct weston_output *output;
output = weston_compositor_create_output(compositor, head->name);
output = compositor->backend->create_output(compositor, name);
if (!output)
return NULL;
if (weston_output_attach_head(output, head) < 0) {
if (head && weston_output_attach_head(output, head) < 0) {
weston_output_destroy(output);
return NULL;
}
......
......@@ -67,7 +67,6 @@ struct weston_pipewire {
struct pipewire_output {
struct weston_output *output;
void (*saved_destroy)(struct weston_output *output);
int (*saved_enable)(struct weston_output *output);
int (*saved_disable)(struct weston_output *output);
int (*saved_start_repaint_loop)(struct weston_output *output);
......@@ -316,8 +315,6 @@ pipewire_output_destroy(struct weston_output *base_output)
free(mode);
}
output->saved_destroy(base_output);
pw_stream_destroy(output->stream);
wl_list_remove(&output->link);
......@@ -536,14 +533,12 @@ pipewire_output_create(struct weston_compositor *c, char *name)
pw_stream_add_listener(output->stream, &output->stream_listener,
&stream_events, output);
output->output = api->create_output(c, name);
output->output = api->create_output(c, name, pipewire_output_destroy);
if (!output->output) {
weston_log("Cannot create virtual output\n");
goto err;
}
output->saved_destroy = output->output->destroy;
output->output->destroy = pipewire_output_destroy;
output->saved_enable = output->output->enable;
output->output->enable = pipewire_output_enable;
output->saved_disable = output->output->disable;
......
......@@ -95,7 +95,6 @@ static const struct remoted_output_support_gbm_format supported_formats[] = {
struct remoted_output {
struct weston_output *output;
void (*saved_destroy)(struct weston_output *output);
int (*saved_enable)(struct weston_output *output);
int (*saved_disable)(struct weston_output *output);
int (*saved_start_repaint_loop)(struct weston_output *output);
......@@ -642,8 +641,6 @@ remoting_output_destroy(struct weston_output *output)
free(mode);
}
remoted_output->saved_destroy(output);
remoting_gst_pipeline_deinit(remoted_output);
remoting_gstpipe_release(&remoted_output->gstpipe);
......@@ -763,14 +760,12 @@ remoting_output_create(struct weston_compositor *c, char *name)
goto err;
}
output->output = api->create_output(c, name);
output->output = api->create_output(c, name, remoting_output_destroy);
if (!output->output) {
weston_log("Can not create virtual output\n");
goto err;
}
output->saved_destroy = output->output->destroy;
output->output->destroy = remoting_output_destroy;
output->saved_enable = output->output->enable;
output->output->enable = remoting_output_enable;
output->saved_disable = output->output->disable;
......