gitlab-ci: enable sanitizers for the meson builds
[mesa-waffle.git] / src / waffle / x11 / x11_window.c
blobab2c93fad4d5a11859e2fbcb334c781f5264b233
1 // SPDX-FileCopyrightText: Copyright 2012 Intel Corporation
2 // SPDX-License-Identifier: BSD-2-Clause
4 #include <assert.h>
6 #include "wcore_error.h"
8 #include "x11_display.h"
9 #include "x11_window.h"
11 static uint8_t
12 x11_winddow_get_depth(xcb_connection_t *conn,
13 const xcb_screen_t *screen,
14 xcb_visualid_t id)
16 for (xcb_depth_iterator_t depth =
17 xcb_screen_allowed_depths_iterator(screen);
18 depth.rem;
19 xcb_depth_next(&depth))
21 for (xcb_visualtype_iterator_t visual =
22 xcb_depth_visuals_iterator (depth.data);
23 visual.rem;
24 xcb_visualtype_next(&visual))
26 if (visual.data->visual_id == id)
27 return depth.data->depth;
31 return 0;
34 static xcb_screen_t *
35 get_xcb_screen(const xcb_setup_t *setup, int screen)
37 xcb_screen_iterator_t iter;
39 iter = xcb_setup_roots_iterator(setup);
40 for (; iter.rem; --screen, xcb_screen_next(&iter))
41 if (screen == 0)
42 return iter.data;
44 return NULL;
47 bool
48 x11_window_init(struct x11_window *self,
49 struct x11_display *dpy,
50 xcb_visualid_t visual_id,
51 int32_t width,
52 int32_t height)
54 xcb_colormap_t colormap = 0;
55 xcb_window_t window = 0;
57 bool ok = true;
58 xcb_connection_t *conn = dpy->xcb;
60 const xcb_setup_t *setup = xcb_get_setup(conn);
61 if (!setup){
62 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "xcb_get_setup() failed");
63 goto error;
66 const xcb_screen_t *screen = get_xcb_screen(setup, dpy->screen);
67 if (!screen) {
68 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "failed to get xcb screen");
69 goto error;
72 colormap = xcb_generate_id(conn);
73 window = xcb_generate_id(conn);
74 if (colormap <= 0 || window <= 0) {
75 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "xcb_generate_id() failed");
76 goto error;
79 xcb_void_cookie_t colormap_cookie = xcb_create_colormap_checked(
80 conn,
81 XCB_COLORMAP_ALLOC_NONE,
82 colormap,
83 screen->root,
84 visual_id);
86 const uint32_t event_mask = XCB_EVENT_MASK_BUTTON_PRESS
87 | XCB_EVENT_MASK_EXPOSURE
88 | XCB_EVENT_MASK_KEY_PRESS;
90 // Please keep attrib_mask sorted the same as attrib_list.
91 const uint32_t attrib_mask = XCB_CW_BORDER_PIXEL
92 | XCB_CW_EVENT_MASK
93 | XCB_CW_COLORMAP;
95 // XCB requires that attrib_list be sorted in the same order as
96 // `enum xcb_cw_t`.
97 const uint32_t attrib_list[] = {
98 /* border_pixel */ 0,
99 event_mask,
100 colormap,
103 xcb_void_cookie_t create_cookie = xcb_create_window_checked(
104 conn,
105 x11_winddow_get_depth(conn, screen, visual_id),
106 window,
107 screen->root, // parent
108 0, 0, // x, y
109 width, height,
110 0, // border width
111 XCB_WINDOW_CLASS_INPUT_OUTPUT,
112 visual_id,
113 attrib_mask,
114 attrib_list);
116 // Check errors.
117 xcb_generic_error_t *error;
118 error = xcb_request_check(conn, colormap_cookie);
119 if (error) {
120 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
121 "xcb_create_colormap() failed on visual_id=0x%x with "
122 "error=0x%x\n", visual_id, error->error_code);
123 goto error;
125 error = xcb_request_check(conn, create_cookie);
126 if (error) {
127 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
128 "xcb_create_window_checked() failed: error=0x%x",
129 error->error_code);
130 goto error;
133 self->display = dpy;
134 self->xcb = window;
135 goto end;
137 error:
138 ok = false;
140 if (colormap)
141 xcb_free_colormap(conn, colormap);
143 if (window)
144 xcb_destroy_window(conn, window);
146 end:
147 return ok;
150 bool
151 x11_window_teardown(struct x11_window *self)
153 xcb_void_cookie_t cookie;
154 xcb_generic_error_t *error;
156 if (!self->xcb)
157 return true;
159 cookie = xcb_destroy_window_checked(self->display->xcb, self->xcb);
160 error = xcb_request_check(self->display->xcb, cookie);
162 if (error) {
163 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
164 "xcb_destroy_window_checked() failed: error=0x%x",
165 error->error_code);
168 return !error;
171 bool
172 x11_window_show(struct x11_window *self)
174 xcb_void_cookie_t cookie;
175 xcb_generic_error_t *error;
177 cookie = xcb_map_window_checked(self->display->xcb, self->xcb);
178 error = xcb_request_check(self->display->xcb, cookie);
180 if (error) {
181 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
182 "xcb_map_window_checked() failed: error=0x%x",
183 error->error_code);
186 return !error;
189 bool
190 x11_window_resize(struct x11_window *self, int32_t width, int32_t height)
192 xcb_void_cookie_t cookie;
193 xcb_generic_error_t *error;
195 cookie = xcb_configure_window(
196 self->display->xcb, self->xcb,
197 XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
198 (uint32_t[]){width, height});
200 error = xcb_request_check(self->display->xcb, cookie);
201 if (error) {
202 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
203 "xcb_configure_window() failed to resize width, "
204 "height: error=0x%x\n", error->error_code);
205 return false;
208 return true;