FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
uwac-output.c
1/*
2 * Copyright © 2014 David FORT <contact@hardening-consulting.com>
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22#include "uwac-priv.h"
23#include "uwac-utils.h"
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <assert.h>
29
30#define TARGET_OUTPUT_INTERFACE 2U
31
32static bool dupstr(char** dst, const char* src)
33{
34 assert(dst);
35 free(*dst);
36 *dst = NULL;
37 if (!src)
38 return true;
39 *dst = strdup(src);
40 return *dst != NULL;
41}
42
43static void output_handle_geometry(void* data, struct wl_output* wl_output, int x, int y,
44 int physical_width, int physical_height, int subpixel,
45 const char* make, const char* model, int transform)
46{
47 UwacOutput* output = data;
48 assert(output);
49
50 output->position.x = x;
51 output->position.y = y;
52 output->transform = transform;
53
54 if (!dupstr(&output->make, make))
55 {
56 assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
57 __func__));
58 }
59
60 if (!dupstr(&output->model, model))
61 {
62 assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY,
63 "%s: unable to strdup model\n", __func__));
64 }
65
66 UwacEvent* event = UwacDisplayNewEvent(output->display, UWAC_EVENT_OUTPUT_GEOMETRY);
67 event->output_geometry.output = output;
68 event->output_geometry.x = x;
69 event->output_geometry.y = y;
70 event->output_geometry.physical_width = physical_width;
71 event->output_geometry.physical_height = physical_height;
72 event->output_geometry.subpixel = subpixel;
73 event->output_geometry.make = output->make;
74 event->output_geometry.model = output->model;
75 event->output_geometry.transform = transform;
76}
77
78static void output_handle_done(void* data, struct wl_output* wl_output)
79{
80 UwacOutput* output = data;
81 assert(output);
82
83 output->doneReceived = true;
84}
85
86static void output_handle_scale(void* data, struct wl_output* wl_output, int32_t scale)
87{
88 UwacOutput* output = data;
89 assert(output);
90
91 output->scale = scale;
92 if (scale > output->display->actual_scale)
93 output->display->actual_scale = scale;
94}
95
96static void output_handle_name(void* data, struct wl_output* wl_output, const char* name)
97{
98 UwacOutput* output = data;
99 assert(output);
100
101 if (!dupstr(&output->name, name))
102 {
103 assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
104 __func__));
105 }
106}
107
108static void output_handle_description(void* data, struct wl_output* wl_output,
109 const char* description)
110{
111 UwacOutput* output = data;
112 assert(output);
113
114 if (!dupstr(&output->description, description))
115 {
116 assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
117 __func__));
118 }
119}
120
121static void output_handle_mode(void* data, struct wl_output* wl_output, uint32_t flags, int width,
122 int height, int refresh)
123{
124 UwacOutput* output = data;
125 assert(output);
126 // UwacDisplay *display = output->display;
127
128 if (output->doneNeeded && output->doneReceived)
129 {
130 /* TODO: we should clear the mode list */
131 }
132
133 if (flags & WL_OUTPUT_MODE_CURRENT)
134 {
135 output->resolution.width = width;
136 output->resolution.height = height;
137 /* output->allocation.width = width;
138 output->allocation.height = height;
139 if (display->output_configure_handler)
140 (*display->output_configure_handler)(
141 output, display->user_data);*/
142 }
143}
144
145static const struct wl_output_listener output_listener = {
146 output_handle_geometry, output_handle_mode, output_handle_done,
147 output_handle_scale, output_handle_name, output_handle_description
148};
149
150UwacOutput* UwacCreateOutput(UwacDisplay* d, uint32_t id, uint32_t version)
151{
152 UwacOutput* o = xzalloc(sizeof *o);
153 if (!o)
154 return NULL;
155
156 o->display = d;
157 o->server_output_id = id;
158 o->doneNeeded = (version > 1);
159 o->doneReceived = false;
160 o->output = wl_registry_bind(d->registry, id, &wl_output_interface,
161 min(TARGET_OUTPUT_INTERFACE, version));
162 wl_output_add_listener(o->output, &output_listener, o);
163
164 wl_list_insert(d->outputs.prev, &o->link);
165 return o;
166}
167
168int UwacDestroyOutput(UwacOutput* output)
169{
170 if (!output)
171 return UWAC_SUCCESS;
172
173 free(output->make);
174 free(output->model);
175 free(output->name);
176 free(output->description);
177
178 wl_output_destroy(output->output);
179 wl_list_remove(&output->link);
180 free(output);
181
182 return UWAC_SUCCESS;
183}