5 #include "libds/output.h"
6 #include "libds/interfaces/output.h"
8 static void output_handle_display_destroy(struct wl_listener *listener,
10 static void output_enable(struct ds_output *output, bool enable);
11 static void output_state_clear(struct ds_output_state *state);
12 static void output_state_clear_buffer(struct ds_output_state *state);
15 ds_output_init(struct ds_output *output, struct ds_backend *backend,
16 const struct ds_output_interface *iface, struct wl_display *display)
18 assert(iface->commit);
20 output->backend = backend;
21 output->iface = iface;
22 output->display = display;
24 wl_list_init(&output->modes);
26 wl_signal_init(&output->events.destroy);
27 wl_signal_init(&output->events.frame);
28 wl_signal_init(&output->events.commit);
30 output->display_destroy.notify = output_handle_display_destroy;
31 wl_display_add_destroy_listener(display, &output->display_destroy);
35 ds_output_destroy(struct ds_output *output)
37 wl_list_remove(&output->display_destroy.link);
39 wl_signal_emit(&output->events.destroy, output);
41 if (output->iface && output->iface->destroy)
42 output->iface->destroy(output);
48 ds_output_enable(struct ds_output *output)
50 output_enable(output, true);
54 ds_output_disable(struct ds_output *output)
56 output_enable(output, false);
60 ds_output_commit(struct ds_output *output)
62 // TODO signal precommit
64 if (!output->iface->commit(output)) {
68 output_state_clear(&output->pending);
76 ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer)
78 output_state_clear_buffer(&output->pending);
79 output->pending.committed |= DS_OUTPUT_STATE_BUFFER;
80 output->pending.buffer = ds_buffer_lock(buffer);
83 WL_EXPORT const struct ds_output_mode *
84 ds_output_get_preferred_mode(struct ds_output *output)
86 struct ds_output_mode *mode;
88 if (wl_list_empty(&output->modes))
91 wl_list_for_each(mode, &output->modes, link) {
96 // No preferred mode, choose the first one
97 return wl_container_of(output->modes.next, mode, link);
101 ds_output_set_mode(struct ds_output *output, const struct ds_output_mode *mode)
103 output->pending.mode = NULL;
104 output->pending.committed &= ~DS_OUTPUT_STATE_MODE;
106 if (output->current_mode == mode) {
110 output->pending.committed |= DS_OUTPUT_STATE_MODE;
111 output->pending.mode = mode;
115 ds_output_add_destroy_listener(struct ds_output *output,
116 struct wl_listener *listener)
118 wl_signal_add(&output->events.destroy, listener);
122 ds_output_add_frame_listener(struct ds_output *output,
123 struct wl_listener *listener)
125 wl_signal_add(&output->events.frame, listener);
129 ds_output_add_commit_listener(struct ds_output *output,
130 struct wl_listener *listener)
132 wl_signal_add(&output->events.commit, listener);
136 output_handle_display_destroy(struct wl_listener *listener, void *data)
138 struct ds_output *output;
140 output = wl_container_of(listener, output, display_destroy);
146 output_state_clear(struct ds_output_state *state)
148 output_state_clear_buffer(state);
149 state->committed = 0;
153 output_state_clear_buffer(struct ds_output_state *state)
155 if (!(state->committed & DS_OUTPUT_STATE_BUFFER))
158 ds_buffer_unlock(state->buffer);
159 state->buffer = NULL;
161 state->committed &= ~DS_OUTPUT_STATE_BUFFER;
165 output_enable(struct ds_output *output, bool enable)
167 if (output->enabled == enable) {
168 output->pending.committed &= ~DS_OUTPUT_STATE_ENABLED;
172 output->pending.committed |= DS_OUTPUT_STATE_ENABLED;
173 output->pending.enabled = enable;