#include "dwm.h" /* globals */ WindowManager dwm = { 0, .ev = { .loop = nil, .output = {.notify=ev·newmonitor}, .input = {.notify=ev·newinput}, .client = {.notify=ev·newclient}, .layer = {.notify=ev·newlayershell}, .deco = {.notify=ev·newdecoration}, }, }; void setup(void) { /* wayland boilerplate */ dwm.display = wl_display_create(); if (!dwm.display) fatal("failed to initialize display"); dwm.backend = wlr_backend_autocreate(dwm.display, nil); if (!dwm.backend) fatal("failed to create backend"); dwm.draw = wlr_backend_get_renderer(dwm.backend); if (!dwm.draw) fatal("failed to initialize renderer"); wlr_renderer_init_wl_display(dwm.draw, dwm.display); /* intialize the compositor and some automated handlers */ dwm.compositor = wlr_compositor_create(dwm.display, dwm.draw); wlr_data_device_manager_create(dwm.display); wlr_gamma_control_manager_v1_create(dwm.display); wlr_gtk_primary_selection_device_manager_create(dwm.display); /* middle management */ wlr_export_dmabuf_manager_v1_create(dwm.display); wlr_screencopy_manager_v1_create(dwm.display); wlr_data_control_manager_v1_create(dwm.display); wlr_primary_selection_v1_device_manager_create(dwm.display); dwm.ev.loop = wl_display_get_event_loop(dwm.display); if (!dwm.ev.loop) fatal("failed to initialize event loop"); dwm.layout = wlr_output_layout_create(); wlr_xdg_output_manager_v1_create(dwm.display, dwm.layout); /* grab output devices */ wl_list_init(&dwm.odevs); wl_signal_add(&dwm.backend->events.new_output, &dwm.ev.output); /* initialize window structures */ wl_list_init(&dwm.tiles); wl_list_init(&dwm.stack); wl_list_init(&dwm.focus); wl_list_init(&dwm.decos); /* layer shell */ dwm.laysh = wlr_layer_shell_v1_create(dwm.display); wl_signal_add(&dwm.laysh->events.new_surface, &dwm.ev.layer); /* xdg shell */ dwm.xdgsh = wlr_xdg_shell_create(dwm.display); wl_signal_add(&dwm.xdgsh->events.new_surface, &dwm.ev.client); /* decorations */ dwm.mngr.deco = wlr_server_decoration_manager_create(dwm.display); wlr_server_decoration_manager_set_default_mode(dwm.mngr.deco, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); wl_signal_add(&dwm.mngr.deco->events.new_decoration, &dwm.ev.deco); wl_list_init(&dwm.decos); dwm.mngr.deco = wlr_server_decoration_manager_create(dwm.display); /* grab input devices and install callbacks */ mouse.cursor = wlr_cursor_create(); if (!mouse.cursor) fatal("no mouse found"); wlr_cursor_attach_output_layout(mouse.cursor, dwm.layout); mouse.manager = wlr_xcursor_manager_create(nil, 24); /* attach the static cursor object to event handlers */ wl_signal_add(&mouse.cursor->events.axis, &mouse.ev.axis); wl_signal_add(&mouse.cursor->events.frame, &mouse.ev.frame); wl_signal_add(&mouse.cursor->events.button, &mouse.ev.button); wl_signal_add(&mouse.cursor->events.motion, &mouse.ev.motion); wl_signal_add(&mouse.cursor->events.motion_absolute, &mouse.ev.absmotion); wl_list_init(&dwm.idevs); wl_list_init(&dwm.keyboards); wl_signal_add(&dwm.backend->events.new_input, &dwm.ev.input); dwm.seat = wlr_seat_create(dwm.display, "seat0"); wl_signal_add(&dwm.seat->events.request_set_cursor, &mouse.ev.cursor); wl_signal_add(&dwm.seat->events.request_set_selection, &mouse.ev.sel); wl_signal_add(&dwm.seat->events.request_set_primary_selection, &mouse.ev.psel); } void run(void) { byte *socket; pid_t start = -1; socket = (byte*)wl_display_add_socket_auto(dwm.display); if (!socket) { wlr_backend_destroy(dwm.backend); fatal("could not open socket"); } if (!wlr_backend_start(dwm.backend)) { wlr_backend_destroy(dwm.backend); wl_display_destroy(dwm.display); fatal("failed to start backend"); } monitor = monitorat(mouse.cursor->x, mouse.cursor->y); if (!monitor) fatal("no monitor found"); wlr_cursor_warp_closest(mouse.cursor, nil, mouse.cursor->x, mouse.cursor->y); wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); setenv("WAYLAND_DISPLAY", socket, 1); wlr_log(WLR_INFO, "running dwm on WAYLAND_DISPLAY\n"); wl_display_run(dwm.display); } void cleanup(void) { wl_display_destroy_clients(dwm.display); wl_display_destroy(dwm.display); wlr_backend_destroy(dwm.backend); } void usage(void) { printf("usage: %s [-qvd] [-s startup_cmd]\n", argv0); exit(1); } int main(int argc, byte *argv[]) { byte *cmd; enum wlr_log_importance lvl; cmd = nil; lvl = WLR_ERROR; ARGBEGIN { case 'q': lvl = WLR_SILENT; break; case 'v': lvl = WLR_INFO; break; case 'd': lvl = WLR_DEBUG; break; case 's': cmd = EARGF(usage()); break; default: usage(); } ARGEND; wlr_log_init(lvl, nil); setup(); run(); cleanup(); return 0; }