Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

Commit

Permalink
backend: add output state allow-lists
Browse files Browse the repository at this point in the history
Right now, when a new output state field is added, all backends by
default won't reject it. This means we need to add new checks to
each and every backend when we introduce a new state field.

Instead, introduce a bitmask of supported output state fields in
each backend, and error out if the user has submitted an unknown
field.

Some fields don't need any backend involvment to work. These are
listed in WLR_OUTPUT_STATE_BACKEND_OPTIONAL as a convenience.
  • Loading branch information
emersion authored and kennylevinsen committed Jun 20, 2021
1 parent 15c8453 commit 2f61546
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 8 deletions.
14 changes: 14 additions & 0 deletions backend/drm/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
#include "types/wlr_buffer.h"
#include "util/signal.h"

static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
WLR_OUTPUT_STATE_BUFFER |
WLR_OUTPUT_STATE_MODE |
WLR_OUTPUT_STATE_ENABLED |
WLR_OUTPUT_STATE_GAMMA_LUT;

bool check_drm_features(struct wlr_drm_backend *drm) {
if (drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &drm->cursor_width)) {
drm->cursor_width = 64;
Expand Down Expand Up @@ -435,6 +442,13 @@ static bool drm_connector_test(struct wlr_output *output) {
return false;
}

uint32_t unsupported = output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
if (unsupported != 0) {
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
unsupported);
return false;
}

if ((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) &&
output->pending.enabled) {
if (output->current_mode == NULL &&
Expand Down
12 changes: 10 additions & 2 deletions backend/headless/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include "backend/headless.h"
#include "util/signal.h"

static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
WLR_OUTPUT_STATE_BUFFER |
WLR_OUTPUT_STATE_MODE;

static struct wlr_headless_output *headless_output_from_output(
struct wlr_output *wlr_output) {
assert(wlr_output_is_headless(wlr_output));
Expand All @@ -29,8 +34,11 @@ static bool output_set_custom_mode(struct wlr_output *wlr_output, int32_t width,
}

static bool output_test(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable a headless output");
uint32_t unsupported =
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
if (unsupported != 0) {
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
unsupported);
return false;
}

Expand Down
11 changes: 9 additions & 2 deletions backend/noop/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include "backend/noop.h"
#include "util/signal.h"

static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
WLR_OUTPUT_STATE_MODE;

static struct wlr_noop_output *noop_output_from_output(
struct wlr_output *wlr_output) {
assert(wlr_output_is_noop(wlr_output));
Expand All @@ -22,8 +26,11 @@ static void output_rollback_render(struct wlr_output *wlr_output) {
}

static bool output_commit(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable a noop output");
uint32_t unsupported =
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
if (unsupported != 0) {
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
unsupported);
return false;
}

Expand Down
12 changes: 10 additions & 2 deletions backend/wayland/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
#include "xdg-decoration-unstable-v1-client-protocol.h"
#include "xdg-shell-client-protocol.h"

static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
WLR_OUTPUT_STATE_BUFFER |
WLR_OUTPUT_STATE_MODE;

static struct wlr_wl_output *get_wl_output_from_output(
struct wlr_output *wlr_output) {
assert(wlr_output_is_wl(wlr_output));
Expand Down Expand Up @@ -244,8 +249,11 @@ static bool output_test(struct wlr_output *wlr_output) {
struct wlr_wl_output *output =
get_wl_output_from_output(wlr_output);

if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable a Wayland output");
uint32_t unsupported =
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
if (unsupported != 0) {
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
unsupported);
return false;
}

Expand Down
12 changes: 10 additions & 2 deletions backend/x11/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#include "util/signal.h"
#include "util/time.h"

static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
WLR_OUTPUT_STATE_BUFFER |
WLR_OUTPUT_STATE_MODE;

static void parse_xcb_setup(struct wlr_output *output,
xcb_connection_t *xcb) {
const xcb_setup_t *xcb_setup = xcb_get_setup(xcb);
Expand Down Expand Up @@ -94,8 +99,11 @@ static void output_destroy(struct wlr_output *wlr_output) {
}

static bool output_test(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable an X11 output");
uint32_t unsupported =
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
if (unsupported != 0) {
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
unsupported);
return false;
}

Expand Down
10 changes: 10 additions & 0 deletions include/wlr/interfaces/wlr_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_output.h>

/**
* Output state fields that don't require backend support. Backends can ignore
* them without breaking the API contract.
*/
#define WLR_OUTPUT_STATE_BACKEND_OPTIONAL \
(WLR_OUTPUT_STATE_DAMAGE | \
WLR_OUTPUT_STATE_SCALE | \
WLR_OUTPUT_STATE_TRANSFORM | \
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED)

/**
* A backend implementation of wlr_output.
*
Expand Down

0 comments on commit 2f61546

Please sign in to comment.