const std = @import("std"); const xcb = @import("xcb"); const WM_PROTOCOLS = "WM_PROTOCOLS"; const WM_DELETE_WINDOW = "WM_DELETE_WINDOW"; pub fn main(init: std.process.Init) !void { _ = init; const connection = xcb.import.xcb_connect(null, null); defer xcb.import.xcb_disconnect(connection); { const res = xcb.import.xcb_connection_has_error(connection); if (res != 0) { std.debug.print("Error: xcb_connection_has_error returned {}", .{res}); return error.XcbConnection; } } const screen = xcb.import.xcb_setup_roots_iterator(xcb.import.xcb_get_setup(connection)).data.?; const mask: xcb.Cw = .{ .BACK_PIXEL = true, .EVENT_MASK = true, }; const values = [_]u32{ screen.white_pixel, @bitCast(xcb.EventMask{ .KEY_PRESS = true, }), }; const window: xcb.Window = @enumFromInt(xcb.import.xcb_generate_id(connection)); _ = xcb.import.xcb_create_window( connection, xcb.COPY_FROM_PARENT, window, screen.root, 10, 10, 640, 480, 1, @intFromEnum(xcb.WindowClass.INPUT_OUTPUT), screen.root_visual, @bitCast(mask), &values, ); const wm_protocols_atom_cookie = xcb.import.xcb_intern_atom(connection, 1, WM_PROTOCOLS.len, WM_PROTOCOLS); const wm_delete_window_atom_cookie = xcb.import.xcb_intern_atom(connection, 0, WM_DELETE_WINDOW.len, WM_DELETE_WINDOW); const wm_protocols_atom_reply: *xcb.InternAtomReply = xcb.import.xcb_intern_atom_reply(connection, wm_protocols_atom_cookie, null) orelse return error.XcbInternAtom; const wm_delete_window_atom_reply: *xcb.InternAtomReply = xcb.import.xcb_intern_atom_reply(connection, wm_delete_window_atom_cookie, null) orelse return error.XcbInternAtom; _ = xcb.import.xcb_change_property( connection, @intFromEnum(xcb.PropMode.REPLACE), window, wm_protocols_atom_reply.atom, .ATOM, 32, 1, &wm_delete_window_atom_reply.atom, ); _ = xcb.import.xcb_map_window(connection, window); _ = xcb.import.xcb_flush(connection); var running = true; while (running) { const maybe_event: ?*xcb.GenericEvent = xcb.import.xcb_wait_for_event(connection); if (maybe_event) |event| { defer std.c.free(event); switch (event.response_type & ~@as(u8, 0x80)) { xcb.CLIENT_MESSAGE => { const client_message_event: *xcb.ClientMessageEvent = @ptrCast(event); if (client_message_event.data.data32[0] == @intFromEnum(wm_delete_window_atom_reply.atom)) { running = false; } }, else => {}, } } else { std.debug.print("Error: xcb_wait_for_event returned null", .{}); return error.XcbWaitForEvent; } } }