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 
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)32 static void output_handle_geometry(void* data, struct wl_output* wl_output, int x, int y,
33                                    int physical_width, int physical_height, int subpixel,
34                                    const char* make, const char* model, int transform)
35 {
36 	UwacOutput* output = data;
37 
38 	output->position.x = x;
39 	output->position.y = y;
40 	output->transform = transform;
41 
42 	if (output->make)
43 		free(output->make);
44 	output->make = strdup(make);
45 	if (!output->make)
46 	{
47 		assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup make\n",
48 		                        __FUNCTION__));
49 	}
50 
51 	if (output->model)
52 		free(output->model);
53 	output->model = strdup(model);
54 	if (!output->model)
55 	{
56 		assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY,
57 		                        "%s: unable to strdup model\n", __FUNCTION__));
58 	}
59 
60 	UwacEvent* event = UwacDisplayNewEvent(output->display, UWAC_EVENT_OUTPUT_GEOMETRY);
61 	event->output_geometry.output = output;
62 	event->output_geometry.x = x;
63 	event->output_geometry.y = y;
64 	event->output_geometry.physical_width = physical_width;
65 	event->output_geometry.physical_height = physical_height;
66 	event->output_geometry.subpixel = subpixel;
67 	event->output_geometry.make = output->make;
68 	event->output_geometry.model = output->model;
69 	event->output_geometry.transform = transform;
70 }
71 
output_handle_done(void * data,struct wl_output * wl_output)72 static void output_handle_done(void* data, struct wl_output* wl_output)
73 {
74 	UwacOutput* output = data;
75 
76 	output->doneReceived = true;
77 }
78 
output_handle_scale(void * data,struct wl_output * wl_output,int32_t scale)79 static void output_handle_scale(void* data, struct wl_output* wl_output, int32_t scale)
80 {
81 	UwacOutput* output = data;
82 
83 	output->scale = scale;
84 }
85 
output_handle_mode(void * data,struct wl_output * wl_output,uint32_t flags,int width,int height,int refresh)86 static void output_handle_mode(void* data, struct wl_output* wl_output, uint32_t flags, int width,
87                                int height, int refresh)
88 {
89 	UwacOutput* output = data;
90 	// UwacDisplay *display = output->display;
91 
92 	if (output->doneNeeded && output->doneReceived)
93 	{
94 		/* TODO: we should clear the mode list */
95 	}
96 
97 	if (flags & WL_OUTPUT_MODE_CURRENT)
98 	{
99 		output->resolution.width = width;
100 		output->resolution.height = height;
101 		/*	output->allocation.width = width;
102 		    output->allocation.height = height;
103 		    if (display->output_configure_handler)
104 		        (*display->output_configure_handler)(
105 		                    output, display->user_data);*/
106 	}
107 }
108 
109 static const struct wl_output_listener output_listener = { output_handle_geometry,
110 	                                                       output_handle_mode, output_handle_done,
111 	                                                       output_handle_scale };
112 
UwacCreateOutput(UwacDisplay * d,uint32_t id,uint32_t version)113 UwacOutput* UwacCreateOutput(UwacDisplay* d, uint32_t id, uint32_t version)
114 {
115 	UwacOutput* o;
116 
117 	o = xzalloc(sizeof *o);
118 	if (!o)
119 		return NULL;
120 
121 	o->display = d;
122 	o->server_output_id = id;
123 	o->doneNeeded = (version > 1);
124 	o->doneReceived = false;
125 	o->output = wl_registry_bind(d->registry, id, &wl_output_interface,
126 	                             min(TARGET_OUTPUT_INTERFACE, version));
127 	wl_output_add_listener(o->output, &output_listener, o);
128 
129 	wl_list_insert(d->outputs.prev, &o->link);
130 	return o;
131 }
132 
UwacDestroyOutput(UwacOutput * output)133 int UwacDestroyOutput(UwacOutput* output)
134 {
135 	free(output->make);
136 	free(output->model);
137 
138 	wl_output_destroy(output->output);
139 	wl_list_remove(&output->link);
140 	free(output);
141 
142 	return UWAC_SUCCESS;
143 }
144