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