+void xtest_sync_with_i3() {
+ xcb_client_message_event_t ev;
+ memset(&ev, '\0', sizeof(xcb_client_message_event_t));
+
+ const int nonce = rand() % 255;
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.window = sync_window;
+ ev.type = i3_sync_atom;
+ ev.format = 32;
+ ev.data.data32[0] = sync_window;
+ ev.data.data32[1] = nonce;
+
+ xcb_send_event(conn, false, root_window, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)&ev);
+ xcb_flush(conn);
+
+ xcb_generic_event_t *event = NULL;
+ while (1) {
+ free(event);
+ if ((event = xcb_wait_for_event(conn)) == NULL) {
+ break;
+ }
+ if (event->response_type == 0) {
+ fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
+ continue;
+ }
+
+ /* Strip off the highest bit (set if the event is generated) */
+ const int type = (event->response_type & 0x7F);
+ switch (type) {
+ case XCB_CLIENT_MESSAGE: {
+ xcb_client_message_event_t *ev = (xcb_client_message_event_t *)event;
+ {
+ const uint32_t got = ev->data.data32[0];
+ const uint32_t want = sync_window;
+ if (got != want) {
+ fprintf(stderr, "Ignoring ClientMessage: unknown window: got %d, want %d\n", got, want);
+ continue;
+ }
+ }
+ {
+ const uint32_t got = ev->data.data32[1];
+ const uint32_t want = nonce;
+ if (got != want) {
+ fprintf(stderr, "Ignoring ClientMessage: unknown nonce: got %d, want %d\n", got, want);
+ continue;
+ }
+ }
+ return;
+ }
+ default:
+ fprintf(stderr, "Unexpected X11 event of type %d received (XCB_CLIENT_MESSAGE = %d)\n", type, XCB_CLIENT_MESSAGE);
+ break;
+ }
+ }
+ free(event);
+}
+