#include <assert.h>
#include <stdlib.h>
+
#include <wayland-client.h>
-#include "backend.h"
#include "libds/log.h"
#include "libds/output.h"
-
#include "xdg-shell-client-protocol.h"
+#include "output.h"
+#include "backend.h"
+
const struct ds_output_interface wl_output_iface;
static const struct xdg_surface_listener wl_output_xdg_surface_listener;
static const struct xdg_toplevel_listener wl_output_xdg_toplevel_listener;
+static void output_update_cursor(struct ds_wl_output *output);
+static bool output_set_custom_mode(struct ds_output *ds_output,
+ int32_t width, int32_t height, int32_t refresh);
+
struct ds_output *
ds_wl_backend_create_output(struct ds_backend *ds_backend)
{
backend = wl_backend_from_backend(ds_backend);
+ if (!ds_backend->started) {
+ backend->requested_outputs++;
+ return NULL;
+ }
+
+ output = create_wl_output(backend);
+ if (!output) {
+ ds_err("Could not create ds_wl_output");
+ return NULL;
+ }
+
+ return &output->base;
+}
+
+struct ds_wl_output *
+create_wl_output(struct ds_wl_backend *backend)
+{
+ struct ds_wl_output *output;
+
output = calloc(1, sizeof *output);
if (!output) {
ds_log_errno(DS_ERR, "Could not allocate ds_wl_output");
ds_dbg("Wayland output(%p) created", output);
- return &output->base;
+ return output;
err:
ds_output_destroy(&output->base);
free(buffer);
}
+void
+output_enter_pointer(struct ds_wl_output *output,
+ struct ds_wl_pointer *pointer, uint32_t serial)
+{
+ output->cursor.pointer = pointer;
+ output->cursor.enter_serial = serial;
+
+ output_update_cursor(output);
+}
+
+void
+output_leave_pointer(struct ds_wl_output *output)
+{
+ output->cursor.pointer = NULL;
+ output->cursor.enter_serial = 0;
+}
+
+static void output_update_cursor(struct ds_wl_output *output)
+{
+ struct ds_wl_pointer *pointer = output->cursor.pointer;
+
+ wl_pointer_set_cursor(pointer->wl_pointer, output->cursor.enter_serial,
+ output->cursor.surface, output->cursor.hotspot_x,
+ output->cursor.hotspot_y);
+}
+
static struct ds_wl_output *
wl_output_from_output(struct ds_output *ds_output)
{
ds_buffer_unlock(buffer->buffer);
}
-static const struct wl_buffer_listener buffer_listener = {
+static const struct wl_buffer_listener buffer_listener =
+{
.release = buffer_handle_release,
};
wl_signal_emit(&output->base.events.frame, &output->base);
}
-static const struct wl_callback_listener frame_listener = {
+static const struct wl_callback_listener frame_listener =
+{
.done = surface_frame_callback
};
output = wl_output_from_output(ds_output);
+ if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) {
+ if (!output_set_custom_mode(ds_output,
+ ds_output->pending.custom_mode.width,
+ ds_output->pending.custom_mode.height,
+ ds_output->pending.custom_mode.refresh))
+ return false;
+ }
+
ds_buffer = ds_output->pending.buffer;
buffer = get_or_create_wl_buffer(output->backend, ds_buffer);
if (!buffer)
wl_surface_attach(output->surface, buffer->wl_buffer, 0, 0);
wl_surface_damage_buffer(output->surface, 0, 0, INT32_MAX, INT32_MAX);
wl_surface_commit(output->surface);
-
- ds_dbg("Swap Buffer!!!!!");
}
wl_display_flush(output->backend->server.display);
.configure = wl_output_xdg_toplevel_handle_configure,
.close = wl_output_xdg_toplevel_handle_close,
};
+
+static bool output_set_custom_mode(struct ds_output *ds_output,
+ int32_t width, int32_t height, int32_t refresh)
+{
+ ds_output_update_custom_mode(ds_output, width, height, 0);
+
+ return true;
+}