aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/backend.c1
-rw-r--r--backend/drm/drm.c1
-rw-r--r--backend/egl.c8
-rw-r--r--backend/wayland/output.c1
-rw-r--r--include/backend/drm.h1
-rw-r--r--include/wlr/interfaces/wlr_output.h2
-rw-r--r--include/wlr/types/wlr_output.h2
-rw-r--r--types/wlr_output.c78
8 files changed, 87 insertions, 7 deletions
diff --git a/backend/drm/backend.c b/backend/drm/backend.c
index 34c03eea..d52adba9 100644
--- a/backend/drm/backend.c
+++ b/backend/drm/backend.c
@@ -118,6 +118,7 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
state->drm_invalidated.notify = drm_invalidated;
wlr_udev_signal_add(udev, state->dev, &state->drm_invalidated);
+ state->display = display;
struct wl_event_loop *event_loop = wl_display_get_event_loop(display);
state->drm_event = wl_event_loop_add_fd(event_loop, state->fd,
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index e4790dec..c6e29b86 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -564,6 +564,7 @@ void wlr_drm_scan_connectors(struct wlr_backend_state *state) {
scan_property_ids(state->fd, conn, output);
+ wlr_output_create_global(wlr_output, state->display);
list_add(state->outputs, output);
wlr_log(L_INFO, "Found display '%s'", wlr_output->name);
} else {
diff --git a/backend/egl.c b/backend/egl.c
index f46a0c83..66aa6a4e 100644
--- a/backend/egl.c
+++ b/backend/egl.c
@@ -87,7 +87,7 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLenum platform) {
for (int i = 0; i < matched; ++i) {
EGLint gbm_format;
- if(platform == EGL_PLATFORM_WAYLAND_EXT) {
+ if (platform == EGL_PLATFORM_WAYLAND_EXT) {
*out = configs[i];
return true;
}
@@ -99,8 +99,6 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLenum platform) {
continue;
}
- // XXX: Is GBM_FORMAT_XRGB8888 what we want?
- // I don't know if this works for wl_displays.
if (gbm_format == GBM_FORMAT_XRGB8888) {
*out = configs[i];
return true;
@@ -111,7 +109,6 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLenum platform) {
return false;
}
-
bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *display) {
if (!egl_exts()) {
return false;
@@ -155,14 +152,12 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *display) {
EGL_EXTENSIONS));
wlr_log(L_INFO, "Using %s", glGetString(GL_VERSION));
wlr_log(L_INFO, "Supported OpenGL ES extensions: %s", glGetString(GL_EXTENSIONS));
-
return true;
error:
eglTerminate(egl->display);
eglReleaseThread();
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
return false;
}
@@ -180,6 +175,5 @@ EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) {
wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error());
return EGL_NO_SURFACE;
}
-
return surf;
}
diff --git a/backend/wayland/output.c b/backend/wayland/output.c
index a01ff015..babca2e1 100644
--- a/backend/wayland/output.c
+++ b/backend/wayland/output.c
@@ -150,6 +150,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) {
return false;
}
+ wlr_output_create_global(wlr_output, backend->local_display);
list_add(backend->outputs, wlr_output);
wl_signal_emit(&backend->backend->events.output_add, wlr_output);
return wlr_output;
diff --git a/include/backend/drm.h b/include/backend/drm.h
index 2c78e3d9..f37a5cd2 100644
--- a/include/backend/drm.h
+++ b/include/backend/drm.h
@@ -32,6 +32,7 @@ struct wlr_backend_state {
dev_t dev;
struct wlr_backend *backend;
+ struct wl_display *display;
struct wl_event_source *drm_event;
struct wl_listener session_signal;
diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h
index 4f29b54f..0949bca3 100644
--- a/include/wlr/interfaces/wlr_output.h
+++ b/include/wlr/interfaces/wlr_output.h
@@ -19,5 +19,7 @@ struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
struct wlr_output_state *state);
void wlr_output_free(struct wlr_output *output);
void wlr_output_update_matrix(struct wlr_output *output);
+struct wl_global *wlr_output_create_global(
+ struct wlr_output *wlr_output, struct wl_display *display);
#endif
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 8ccf87e1..71e1d0fe 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -19,6 +19,8 @@ struct wlr_output_state;
struct wlr_output {
const struct wlr_output_impl *impl;
struct wlr_output_state *state;
+ struct wl_global *wl_global;
+ struct wl_list resource_list;
uint32_t flags;
char name[16];
diff --git a/types/wlr_output.c b/types/wlr_output.c
index 5e7f9288..4d2e7778 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <tgmath.h>
@@ -5,6 +6,83 @@
#include <wlr/types/wlr_output.h>
#include <wlr/interfaces/wlr_output.h>
#include <wlr/util/list.h>
+#include <wlr/util/log.h>
+
+static void wl_output_send_to_resource(struct wl_resource *resource) {
+ assert(resource);
+ struct wlr_output *output = wl_resource_get_user_data(resource);
+ assert(output);
+ const uint32_t version = wl_resource_get_version(resource);
+ if (version >= WL_OUTPUT_GEOMETRY_SINCE_VERSION) {
+ wl_output_send_geometry(resource, 0, 0, // TODO: get position from layout?
+ output->phys_width, output->phys_height, output->subpixel,
+ output->make, output->model, output->transform);
+ }
+ if (version >= WL_OUTPUT_MODE_SINCE_VERSION) {
+ for (size_t i = 0; i < output->modes->length; ++i) {
+ struct wlr_output_mode *mode = output->modes->items[i];
+ // TODO: mode->flags should just be preferred
+ uint32_t flags = mode->flags;
+ if (output->current_mode == mode) {
+ flags |= WL_OUTPUT_MODE_CURRENT;
+ }
+ wl_output_send_mode(resource, flags,
+ mode->width, mode->height, mode->refresh);
+ }
+ }
+ if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) {
+ wl_output_send_scale(resource, output->scale);
+ }
+ if (version >= WL_OUTPUT_DONE_SINCE_VERSION) {
+ wl_output_send_done(resource);
+ }
+}
+
+static void wl_output_destroy(struct wl_resource *resource) {
+ struct wlr_output *output = wl_resource_get_user_data(resource);
+ struct wl_resource *_resource = NULL;
+ wl_resource_for_each(_resource, &output->resource_list) {
+ if (_resource == resource) {
+ struct wl_list *link = wl_resource_get_link(_resource);
+ wl_list_remove(link);
+ break;
+ }
+ }
+}
+
+static void wl_output_release(struct wl_client *client, struct wl_resource *resource) {
+ wl_output_destroy(resource);
+}
+
+static struct wl_output_interface wl_output_impl = {
+ .release = wl_output_release
+};
+
+static void wl_output_bind(struct wl_client *wl_client, void *_wlr_output,
+ uint32_t version, uint32_t id) {
+ struct wlr_output *wlr_output = _wlr_output;
+ assert(wl_client && wlr_output);
+ if (version > 3) {
+ wlr_log(L_ERROR, "Client requested unsupported wl_output version, disconnecting");
+ wl_client_destroy(wl_client);
+ return;
+ }
+ struct wl_resource *wl_resource = wl_resource_create(
+ wl_client, &wl_output_interface, version, id);
+ wl_resource_set_implementation(wl_resource, &wl_output_impl,
+ wlr_output, wl_output_destroy);
+ wl_list_insert(&wlr_output->resource_list, wl_resource_get_link(wl_resource));
+ wl_output_send_to_resource(wl_resource);
+}
+
+struct wl_global *wlr_output_create_global(
+ struct wlr_output *wlr_output, struct wl_display *display) {
+ struct wl_global *wl_global = wl_global_create(display,
+ &wl_output_interface, 3, wlr_output, wl_output_bind);
+ wlr_output->wl_global = wl_global;
+ wl_list_init(&wlr_output->resource_list);
+ return wl_global;
+}
static const float transforms[][4] = {
[WL_OUTPUT_TRANSFORM_NORMAL] = {