wgl: use correct dtor in wgl_window_priv_create error path
[mesa-waffle.git] / src / waffle / wgl / wgl_window.c
bloba557c2f89eb531374d8317b1cebd3127ee4e2fa1
1 // Copyright 2014 Emil Velikov
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.
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.
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.
26 #include <windows.h>
28 #include "wcore_error.h"
30 #include "wgl_config.h"
31 #include "wgl_platform.h"
32 #include "wgl_window.h"
34 bool
35 wgl_window_destroy(struct wcore_window *wc_self)
37 struct wgl_window *self = wgl_window(wc_self);
39 assert(self);
40 assert(self->hWnd);
42 self->created = false;
43 ShowWindow(self->hWnd, SW_HIDE);
44 return true;
47 bool
48 wgl_window_priv_destroy(struct wcore_window *wc_self)
50 struct wgl_window *self = wgl_window(wc_self);
51 bool ok = true;
53 if (!self)
54 return true;
56 if (self->hWnd) {
57 if (self->hDC) {
58 ok &= ReleaseDC(self->hWnd, self->hDC);
60 ok &= DestroyWindow(self->hWnd);
63 ok &= wcore_window_teardown(wc_self);
64 free(self);
65 return ok;
68 struct wcore_window*
69 wgl_window_create(struct wcore_platform *wc_plat,
70 struct wcore_config *wc_config,
71 int width,
72 int height)
74 struct wgl_config *config = wgl_config(wc_config);
75 bool ok;
77 assert(config->window);
79 // Currently we do not allow multiple windows per config.
80 // Neither piglit nor the waffle examples do that yet, so just
81 // return NULL in case that ever changes.
82 assert(!config->window->created);
83 if (config->window->created)
84 return NULL;
86 config->window->created = true;
88 ok = wgl_window_resize(&config->window->wcore, width, height);
89 if (!ok)
90 return NULL;
92 return &config->window->wcore;
95 struct wcore_window*
96 wgl_window_priv_create(struct wcore_platform *wc_plat,
97 struct wcore_config *wc_config,
98 int width,
99 int height)
101 struct wgl_platform *plat = wgl_platform(wc_plat);
102 struct wgl_window *self;
103 bool ok;
104 RECT rect;
106 self = wcore_calloc(sizeof(*self));
107 if (!self)
108 return NULL;
110 ok = wcore_window_init(&self->wcore, wc_config);
111 if (!ok)
112 goto error;
114 rect.left = 0;
115 rect.top = 0;
116 rect.right = rect.left + width;
117 rect.bottom = rect.top + height;
119 ok = AdjustWindowRect(&rect, WS_POPUPWINDOW, FALSE);
120 if (!ok)
121 goto error;
123 self->hWnd = CreateWindow(plat->class_name, NULL, WS_POPUPWINDOW,
124 0, 0,
125 rect.right - rect.left, rect.bottom - rect.top,
126 NULL, NULL, NULL, NULL);
127 if (!self->hWnd)
128 goto error;
130 self->hDC = GetDC(self->hWnd);
131 if (!self->hDC)
132 goto error;
134 return &self->wcore;
136 error:
137 wgl_window_priv_destroy(&self->wcore);
138 return NULL;
141 bool
142 wgl_window_show(struct wcore_window *wc_self)
144 struct wgl_window *self = wgl_window(wc_self);
146 assert(self);
147 assert(self->hWnd);
149 // If the window was previously hidden the function returns zero,
150 // and non-zero otherwise.
151 // XXX: Use SW_SHOW or SW_SHOWDEFAULT, SW_SHOWNORMAL ?
152 ShowWindow(self->hWnd, SW_SHOW);
153 return true;
156 bool
157 wgl_window_resize(struct wcore_window *wc_self,
158 int32_t width, int32_t height)
160 struct wgl_window *self = wgl_window(wc_self);
161 RECT rect;
162 bool ok;
164 assert(self);
165 assert(self->hWnd);
167 rect.left = 0;
168 rect.top = 0;
169 rect.right = rect.left + width;
170 rect.bottom = rect.top + height;
172 ok = AdjustWindowRect(&rect, WS_POPUPWINDOW, FALSE);
173 if (!ok)
174 return false;
176 ok = SetWindowPos(self->hWnd, 0, 0, 0,
177 rect.right - rect.left,
178 rect.bottom - rect.top,
179 SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
181 #ifdef DEBUG
182 // Verify the client area size matches the required size.
184 GetClientRect(self->hWnd, &rect);
185 assert(rect.left == 0);
186 assert(rect.top == 0);
187 assert(rect.right - rect.left == width);
188 assert(rect.bottom - rect.top == height);
189 #endif
190 return ok;
193 bool
194 wgl_window_swap_buffers(struct wcore_window *wc_self)
196 struct wgl_window *self = wgl_window(wc_self);
198 assert(self);
199 assert(self->hDC);
201 return SwapBuffers(self->hDC);