summaryrefslogtreecommitdiffstats
path: root/uwac/libuwac/uwac-output.c
diff options
context:
space:
mode:
Diffstat (limited to 'uwac/libuwac/uwac-output.c')
-rw-r--r--uwac/libuwac/uwac-output.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/uwac/libuwac/uwac-output.c b/uwac/libuwac/uwac-output.c
new file mode 100644
index 0000000..079018e
--- /dev/null
+++ b/uwac/libuwac/uwac-output.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright © 2014 David FORT <contact@hardening-consulting.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#include "uwac-priv.h"
+#include "uwac-utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#define TARGET_OUTPUT_INTERFACE 2U
+
+static bool dupstr(char** dst, const char* src)
+{
+ assert(dst);
+ free(*dst);
+ *dst = NULL;
+ if (!src)
+ return true;
+ *dst = strdup(src);
+ return *dst != NULL;
+}
+
+static void output_handle_geometry(void* data, struct wl_output* wl_output, int x, int y,
+ int physical_width, int physical_height, int subpixel,
+ const char* make, const char* model, int transform)
+{
+ UwacOutput* output = data;
+ assert(output);
+
+ output->position.x = x;
+ output->position.y = y;
+ output->transform = transform;
+
+ if (!dupstr(&output->make, make))
+ {
+ assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
+ __func__));
+ }
+
+ if (!dupstr(&output->model, model))
+ {
+ assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY,
+ "%s: unable to strdup model\n", __func__));
+ }
+
+ UwacEvent* event = UwacDisplayNewEvent(output->display, UWAC_EVENT_OUTPUT_GEOMETRY);
+ event->output_geometry.output = output;
+ event->output_geometry.x = x;
+ event->output_geometry.y = y;
+ event->output_geometry.physical_width = physical_width;
+ event->output_geometry.physical_height = physical_height;
+ event->output_geometry.subpixel = subpixel;
+ event->output_geometry.make = output->make;
+ event->output_geometry.model = output->model;
+ event->output_geometry.transform = transform;
+}
+
+static void output_handle_done(void* data, struct wl_output* wl_output)
+{
+ UwacOutput* output = data;
+ assert(output);
+
+ output->doneReceived = true;
+}
+
+static void output_handle_scale(void* data, struct wl_output* wl_output, int32_t scale)
+{
+ UwacOutput* output = data;
+ assert(output);
+
+ output->scale = scale;
+ if (scale > output->display->actual_scale)
+ output->display->actual_scale = scale;
+}
+
+static void output_handle_name(void* data, struct wl_output* wl_output, const char* name)
+{
+ UwacOutput* output = data;
+ assert(output);
+
+ if (!dupstr(&output->name, name))
+ {
+ assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
+ __func__));
+ }
+}
+
+static void output_handle_description(void* data, struct wl_output* wl_output,
+ const char* description)
+{
+ UwacOutput* output = data;
+ assert(output);
+
+ if (!dupstr(&output->description, description))
+ {
+ assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
+ __func__));
+ }
+}
+
+static void output_handle_mode(void* data, struct wl_output* wl_output, uint32_t flags, int width,
+ int height, int refresh)
+{
+ UwacOutput* output = data;
+ assert(output);
+ // UwacDisplay *display = output->display;
+
+ if (output->doneNeeded && output->doneReceived)
+ {
+ /* TODO: we should clear the mode list */
+ }
+
+ if (flags & WL_OUTPUT_MODE_CURRENT)
+ {
+ output->resolution.width = width;
+ output->resolution.height = height;
+ /* output->allocation.width = width;
+ output->allocation.height = height;
+ if (display->output_configure_handler)
+ (*display->output_configure_handler)(
+ output, display->user_data);*/
+ }
+}
+
+static const struct wl_output_listener output_listener = {
+ output_handle_geometry, output_handle_mode, output_handle_done,
+ output_handle_scale, output_handle_name, output_handle_description
+};
+
+UwacOutput* UwacCreateOutput(UwacDisplay* d, uint32_t id, uint32_t version)
+{
+ UwacOutput* o = xzalloc(sizeof *o);
+ if (!o)
+ return NULL;
+
+ o->display = d;
+ o->server_output_id = id;
+ o->doneNeeded = (version > 1);
+ o->doneReceived = false;
+ o->output = wl_registry_bind(d->registry, id, &wl_output_interface,
+ min(TARGET_OUTPUT_INTERFACE, version));
+ wl_output_add_listener(o->output, &output_listener, o);
+
+ wl_list_insert(d->outputs.prev, &o->link);
+ return o;
+}
+
+int UwacDestroyOutput(UwacOutput* output)
+{
+ if (!output)
+ return UWAC_SUCCESS;
+
+ free(output->make);
+ free(output->model);
+ free(output->name);
+ free(output->description);
+
+ wl_output_destroy(output->output);
+ wl_list_remove(&output->link);
+ free(output);
+
+ return UWAC_SUCCESS;
+}