sync-ing asm and dis for minimal shaders
[vulkan-misc.git] / 2d / kickstart / xcb.c
blobe9f1d97f1247c8c8f5a81cc28bc542e7193dd817
1 #ifndef APP_XCB_C
2 #define APP_XCB_C
3 /*
4 * this is public domain without any warranties of any kind
5 * Sylvain BERTRAND
6 */
7 /* XXX: KEEP AN EYE ON ABBREVIATIONS */
8 #include <string.h>
9 #include <stdlib.h>
10 #include <xcb.h>
12 #include "log.h"
13 #include "app_core_types.h"
14 #include "xcb_syms.c"
15 #include "app_state.c"
17 #define LINUX_KEY_ESC 0x01
18 #define LINUX_KEY_SPACE 0x39
19 /* x11 keycodes do offset linux keycodes by 8 */
20 #define X11_KEYCODE_ESC (LINUX_KEY_ESC + 8)
21 #define X11_KEYCODE_SPACE (LINUX_KEY_SPACE + 8)
23 struct app_xcb_t {
24 u8 *disp_env;
25 xcb_connection_t *c;
26 xcb_setup_t *setup;
27 int scr_idx;
28 xcb_screen_t *scr;
29 u32 win_id;
31 static struct app_xcb_t app_xcb;
33 static void app_xcb_win_create(void)
35 u32 value_mask;
36 u32 value_list[2];
37 xcb_void_cookie_t cookie;
38 xcb_generic_error_t *e;
40 app_xcb.win_id = dl_xcb_generate_id(app_xcb.c);
41 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:window id=%#x\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.win_id);
43 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
44 value_list[0] = app_xcb.scr->black_pixel;
45 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE
46 | XCB_EVENT_MASK_RESIZE_REDIRECT;
48 dl_xcb_create_window(app_xcb.c, XCB_COPY_FROM_PARENT, app_xcb.win_id,
49 app_xcb.scr->root, 0, 0,
50 APP_WIN_WIDTH, APP_WIN_HEIGHT, 0,
51 XCB_WINDOW_CLASS_INPUT_OUTPUT,
52 app_xcb.scr->root_visual,
53 value_mask, value_list);
54 cookie = dl_xcb_map_window_checked(app_xcb.c, app_xcb.win_id);
55 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:window id:%#x:map window request cookie=%#x\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.win_id, cookie);
57 e = dl_xcb_request_check(app_xcb.c, cookie);
58 if (e != 0) {
59 LOG("0:MAIN:FATAL:xcb:'%s':connection:%p:screen:%d:root window id:%#x:window id:%#x:unable to map window\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.win_id);
60 exit(1);
62 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:window id:%#x:window mapped\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.win_id);
66 * a disp is n scrs and 1 [set of] keyboard[s] and 1 [set of] mouse[s]
67 * 1 scr could be n monitors
68 * nowdays: usually 1 scr per display
69 * 1 scr has 1 root win
71 static void app_xcb_connect(void)
73 int r;
75 app_xcb.disp_env = getenv("DISPLAY");
76 if (app_xcb.disp_env == 0 || app_xcb.disp_env[0] == 0) {
77 LOG("0:MAIN:no x11 DISPLAY environment variable, exiting\n");
78 exit(0);
81 app_xcb.scr_idx = 0;
82 app_xcb.c = dl_xcb_connect(0, &app_xcb.scr_idx); /* should be 0 though */
83 r = dl_xcb_connection_has_error(app_xcb.c);
84 if (r > 0) {
85 LOG("0:MAIN:FATAL:%d:%s:error while connecting to the x11 server\n", r, app_xcb.disp_env);
86 exit(1);
88 LOG("0:MAIN:xcb:'%s':connection=%p, default screen index is %d (should be 0)\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx);
91 static void app_xcb_scr_get(void)
93 xcb_screen_iterator_t iter;
94 int scrs_n;
95 int i;
97 app_xcb.setup = dl_xcb_get_setup(app_xcb.c);
99 scrs_n = dl_xcb_setup_roots_length(app_xcb.setup);
100 LOG("0:MAIN:xcb:'%s':connection:%p:has %d screens (should be 1)\n", app_xcb.disp_env, app_xcb.c, scrs_n);
102 iter = dl_xcb_setup_roots_iterator(app_xcb.setup);
103 i = 0;
104 app_xcb.scr = 0;
105 loop {
106 if (iter.rem == 0)
107 break; /* no more scr to iterate on */
109 if (i == app_xcb.scr_idx) {
110 app_xcb.scr = iter.data;
111 break;
113 dl_xcb_screen_next(&iter);
115 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:width=%d pixels\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.scr->width_in_pixels);
116 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:height=%d pixels\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.scr->height_in_pixels);
117 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:white pixel=0x%08x\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.scr->white_pixel);
118 LOG("0:MAIN:xcb:'%s':connection:%p:screen:%d:root window id:%#x:black pixel=0x%08x\n", app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.scr->black_pixel);
121 #define MIN_SZ_BIT (1 << 4)
122 #define MAX_SZ_BIT (1 << 5)
123 #define FLAGS 0
124 /* 4 padding dwords */
125 #define MIN_WIDTH 5
126 #define MIN_HEIGHT 6
127 #define MAX_WIDTH 7
128 #define MAX_HEIGHT 8
129 #define DWORDS_N 18
130 static void app_xcb_wm_hints(void)
132 u32 data[DWORDS_N];
134 memset(data, 0, sizeof(data));
135 data[FLAGS] = MIN_SZ_BIT | MAX_SZ_BIT;
136 data[MIN_WIDTH] = APP_WIN_WIDTH;
137 data[MIN_HEIGHT] = APP_WIN_HEIGHT;
138 data[MAX_WIDTH] = APP_WIN_WIDTH;
139 data[MAX_HEIGHT] = APP_WIN_HEIGHT;
141 dl_xcb_change_property(app_xcb.c, XCB_PROP_MODE_REPLACE, app_xcb.win_id,
142 XCB_ATOM_WM_NORMAL_HINTS, XCB_ATOM_WM_SIZE_HINTS, 32, DWORDS_N,
143 data);
145 #undef MIN_SZ_BIT
146 #undef MAX_SZ_BIT
147 #undef FLAGS
148 #undef MIN_WIDTH
149 #undef MIN_HEIGHT
150 #undef MAX_WIDTH
151 #undef MAX_HEIGHT
152 #undef DWORDS_N
154 static void app_xcb_init(void)
156 int r;
158 app_xcb_client_lib_load();
159 app_xcb_syms();
161 app_xcb_connect();
162 app_xcb_scr_get();
163 app_xcb_win_create();
164 app_xcb_wm_hints();
166 r = dl_xcb_flush(app_xcb.c);
167 if (r <= 0) {
168 LOG("0:MAIN:FATAL:%d:xcb:'%s':connection:%p:screen:%d:root window id:%#x:window id:%#x:unable to flush the connection\n", r, app_xcb.disp_env, app_xcb.c, app_xcb.scr_idx, app_xcb.scr->root, app_xcb.win_id);
169 exit(1);
171 LOG("0:MAIN:xcb:'%s':connection:%p:connection flushed\n", app_xcb.disp_env, app_xcb.c);
174 static void app_xcb_evt_key_release(xcb_generic_event_t *evt)
176 xcb_key_release_event_t *key;
178 key = (xcb_key_release_event_t*)evt;
180 switch (key->detail) {
181 case X11_KEYCODE_ESC:
182 app_state = app_state_quit;
183 break;
184 case X11_KEYCODE_SPACE:
185 app_do_render = true;
186 break;
187 default:
188 LOG("0:MAIN:xcb:'%s':connection:%p:event:key release:keycode:%#02x\n", app_xcb.disp_env, app_xcb.c, key->detail);
189 break;
193 static void app_xcb_evt_resz_request(xcb_generic_event_t *evt)
195 xcb_resize_request_event_t *rre;
198 * the x11 server is not resizing the win, it is asking us to
199 * actually do it (and we won't)
201 rre = (xcb_resize_request_event_t*)evt;
202 LOG("0:MAIN:xcb:'%s':connection:%p:event:resize request:window=%u width=%u,height=%u\n", app_xcb.disp_env, app_xcb.c, rre->window, rre->width, rre->height);
205 static void app_xcb_evt_handle(xcb_generic_event_t *evt)
207 u8 evt_code;
210 * do not discriminate evts generated by clients using sendevent
211 * requests (note: "client message" evts have always their most
212 * significant bit set)
214 evt_code = evt->response_type & 0x7f;
216 switch (evt_code) {
217 case XCB_KEY_RELEASE:
218 app_xcb_evt_key_release(evt);
219 break;
220 case XCB_RESIZE_REQUEST:
221 app_xcb_evt_resz_request(evt);
222 break;
223 default:
224 break;
227 #endif