1 // Copyright 2012 Intel Corporation
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice, this
9 // list of conditions and the following disclaimer.
10 //
11 // - Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 #include <stdlib.h>
27
28 #include "api_priv.h"
29
30 #include "wcore_attrib_list.h"
31 #include "wcore_config.h"
32 #include "wcore_error.h"
33 #include "wcore_platform.h"
34 #include "wcore_window.h"
35
36 WAFFLE_API struct waffle_window*
waffle_window_create2(struct waffle_config * config,const intptr_t attrib_list[])37 waffle_window_create2(
38 struct waffle_config *config,
39 const intptr_t attrib_list[])
40 {
41 struct wcore_window *wc_self = NULL;
42 struct wcore_config *wc_config = wcore_config(config);
43 intptr_t *attrib_list_filtered = NULL;
44 intptr_t width = 1, height = 1;
45 bool need_size = true;
46 intptr_t fullscreen = WAFFLE_DONT_CARE;
47
48 const struct api_object *obj_list[] = {
49 wc_config ? &wc_config->api : NULL,
50 };
51
52 if (!api_check_entry(obj_list, 1)) {
53 goto done;
54 }
55
56 attrib_list_filtered = wcore_attrib_list_copy(attrib_list);
57
58 wcore_attrib_list_pop(attrib_list_filtered,
59 WAFFLE_WINDOW_FULLSCREEN, &fullscreen);
60 if (fullscreen == WAFFLE_DONT_CARE)
61 fullscreen = 0; // default
62
63 if (fullscreen == 1) {
64 need_size = false;
65 } else if (fullscreen != 0) {
66 // Same error message as in wcore_config_attrs.c.
67 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
68 "WAFFLE_WINDOW_FULLSCREEN has bad value 0x%x. "
69 "Must be true(1), false(0), or WAFFLE_DONT_CARE(-1)",
70 fullscreen);
71 goto done;
72 }
73
74 if (!wcore_attrib_list_pop(attrib_list_filtered,
75 WAFFLE_WINDOW_WIDTH, &width) && need_size) {
76 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
77 "required attribute WAFFLE_WINDOW_WIDTH is missing");
78 goto done;
79 }
80
81 if (!wcore_attrib_list_pop(attrib_list_filtered,
82 WAFFLE_WINDOW_HEIGHT, &height) && need_size) {
83 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
84 "required attribute WAFFLE_WINDOW_HEIGHT is missing");
85 goto done;
86 }
87
88 if (width <= 0) {
89 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
90 "WAFFLE_WINDOW_WIDTH is not positive");
91 goto done;
92 } else if (width > INT32_MAX) {
93 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
94 "WAFFLE_WINDOW_WIDTH is greater than INT32_MAX");
95 goto done;
96 }
97
98 if (height <= 0) {
99 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
100 "WAFFLE_WINDOW_HEIGHT is not positive");
101 goto done;
102 } else if (height > INT32_MAX) {
103 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE,
104 "WAFFLE_WINDOW_HEIGHT is greater than INT32_MAX");
105 goto done;
106 }
107
108 if (fullscreen)
109 width = height = -1;
110
111 wc_self = api_platform->vtbl->window.create(api_platform,
112 wc_config,
113 (int32_t) width,
114 (int32_t) height,
115 attrib_list_filtered);
116
117 done:
118 free(attrib_list_filtered);
119
120 if (!wc_self) {
121 return NULL;
122 }
123
124 return waffle_window(wc_self);
125 }
126
127 WAFFLE_API struct waffle_window*
waffle_window_create(struct waffle_config * config,int32_t width,int32_t height)128 waffle_window_create(
129 struct waffle_config *config,
130 int32_t width, int32_t height)
131 {
132 const intptr_t attrib_list[] = {
133 WAFFLE_WINDOW_WIDTH, width,
134 WAFFLE_WINDOW_HEIGHT, height,
135 0,
136 };
137
138 return waffle_window_create2(config, attrib_list);
139 }
140
141 WAFFLE_API bool
waffle_window_destroy(struct waffle_window * self)142 waffle_window_destroy(struct waffle_window *self)
143 {
144 struct wcore_window *wc_self = wcore_window(self);
145
146 const struct api_object *obj_list[] = {
147 wc_self ? &wc_self->api : NULL,
148 };
149
150 if (!api_check_entry(obj_list, 1))
151 return false;
152
153 return api_platform->vtbl->window.destroy(wc_self);
154 }
155
156 WAFFLE_API bool
waffle_window_show(struct waffle_window * self)157 waffle_window_show(struct waffle_window *self)
158 {
159 struct wcore_window *wc_self = wcore_window(self);
160
161 const struct api_object *obj_list[] = {
162 wc_self ? &wc_self->api : NULL,
163 };
164
165 if (!api_check_entry(obj_list, 1))
166 return false;
167
168 return api_platform->vtbl->window.show(wc_self);
169 }
170
171 WAFFLE_API bool
waffle_window_resize(struct waffle_window * self,int32_t width,int32_t height)172 waffle_window_resize(
173 struct waffle_window *self,
174 int32_t width,
175 int32_t height)
176 {
177 struct wcore_window *wc_self = wcore_window(self);
178
179 const struct api_object *obj_list[] = {
180 wc_self ? &wc_self->api : NULL,
181 };
182
183 if (!api_check_entry(obj_list, 1))
184 return false;
185
186 if (api_platform->vtbl->window.resize) {
187 return api_platform->vtbl->window.resize(wc_self, width, height);
188 }
189 else {
190 wcore_error(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM);
191 return false;
192 }
193 }
194
195 WAFFLE_API bool
waffle_window_swap_buffers(struct waffle_window * self)196 waffle_window_swap_buffers(struct waffle_window *self)
197 {
198 struct wcore_window *wc_self = wcore_window(self);
199
200 const struct api_object *obj_list[] = {
201 wc_self ? &wc_self->api : NULL,
202 };
203
204 if (!api_check_entry(obj_list, 1))
205 return false;
206
207 return api_platform->vtbl->window.swap_buffers(wc_self);
208 }
209
210 WAFFLE_API union waffle_native_window*
waffle_window_get_native(struct waffle_window * self)211 waffle_window_get_native(struct waffle_window *self)
212 {
213 struct wcore_window *wc_self = wcore_window(self);
214
215 const struct api_object *obj_list[] = {
216 wc_self ? &wc_self->api : NULL,
217 };
218
219 if (!api_check_entry(obj_list, 1))
220 return NULL;
221
222 if (api_platform->vtbl->window.get_native) {
223 return api_platform->vtbl->window.get_native(wc_self);
224 }
225 else {
226 wcore_error(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM);
227 return NULL;
228 }
229 }
230