-rw-r--r-- src/main.c
1 #include <stdlib.h> 2 #include <string.h> 3 #include <unistd.h> 4 #include <wlr/backend.h> 5 #include <wlr/render/wlr_renderer.h> 6 #include <wlr/types/wlr_compositor.h> 7 #include <wlr/types/wlr_xdg_shell.h> 8 #include <wlr/util/log.h> 9 10 #include "config.h" 11 #include "cursor.h" 12 #include "decorations.h" 13 #include "desk.h" 14 #include "main.h" 15 #include "input.h" 16 #include "ipc.h" 17 #include "layer_shell.h" 18 #include "log.h" 19 #include "output.h" 20 #include "scratchpad.h" 21 #include "shell.h" 22 #include "types.h" 23 24 25 struct wimp wimp = { 26 .on_mouse_motion = NULL, 27 .on_mouse_scroll = NULL, 28 .on_drag1 = NULL, 29 .on_drag2 = NULL, 30 .on_drag3 = NULL, 31 .on_pinch = NULL, 32 .desk_count = 0, 33 .mark_waiting = false, 34 .mark_indicator.box.width = 25, 35 .mark_indicator.box.height = 25, 36 .mark_indicator.box.x = 0, 37 .mark_indicator.box.y = 0, 38 .scratchpad_waiting = false, 39 .auto_focus = true, 40 .reverse_scrolling = false, 41 .zoom_min = 0.2, 42 .zoom_max = 5, 43 }; 44 45 46 static const char usage[] = 47 "usage: wimp [options...]\n" 48 " -h show this help message\n" 49 " -c <file> specify config file\n" 50 " -d set logging to debug mode\n" 51 " -i set logging to info mode\n" 52 ; 53 54 55 static void shutdown() { 56 wl_list_remove(&wimp.new_output_listener.link); 57 wl_list_remove(&wimp.new_xdg_surface_listener.link); 58 wl_list_remove(&wimp.decoration_listener.link); 59 wl_list_remove(&wimp.layer_shell_surface_listener.link); 60 wl_list_remove(&wimp.cursor_motion_listener.link); 61 wl_list_remove(&wimp.cursor_motion_absolute_listener.link); 62 wl_list_remove(&wimp.cursor_button_listener.link); 63 wl_list_remove(&wimp.cursor_axis_listener.link); 64 wl_list_remove(&wimp.cursor_frame_listener.link); 65 wl_list_remove(&wimp.new_input_listener.link); 66 wl_list_remove(&wimp.request_cursor_listener.link); 67 wl_list_remove(&wimp.request_set_selection_listener.link); 68 69 drop_scratchpads(); 70 71 struct binding *kb, *tkb; 72 wl_list_for_each_safe(kb, tkb, &wimp.mouse_bindings, link) { 73 wl_list_remove(&kb->link); 74 if (kb->data) { 75 free(kb->data); 76 } 77 free(kb); 78 }; 79 wl_list_for_each_safe(kb, tkb, &wimp.key_bindings, link) { 80 wl_list_remove(&kb->link); 81 if (kb->data) { 82 free(kb->data); 83 } 84 free(kb); 85 }; 86 87 struct desk *desk, *tdesk; 88 struct view *view, *tview; 89 wl_list_for_each_safe(desk, tdesk, &wimp.desks, link) { 90 wl_list_for_each_safe(view, tview, &desk->views, link) { 91 wl_list_remove(&view->link); 92 wl_list_remove(&view->map_listener.link); 93 wl_list_remove(&view->unmap_listener.link); 94 wl_list_remove(&view->destroy_listener.link); 95 wl_list_remove(&view->request_move_listener.link); 96 wl_list_remove(&view->request_resize_listener.link); 97 wl_list_remove(&view->request_fullscreen_listener.link); 98 free(view); 99 }; 100 wl_list_remove(&desk->link); 101 free(desk->wallpaper); 102 free(desk); 103 }; 104 105 struct mark *mark, *tmark; 106 wl_list_for_each_safe(mark, tmark, &wimp.marks, link) { 107 wl_list_remove(&mark->link); 108 free(mark); 109 }; 110 111 wlr_backend_destroy(wimp.backend); 112 wlr_output_layout_destroy(wimp.output_layout); 113 wlr_seat_destroy(wimp.seat); 114 wlr_xcursor_manager_destroy(wimp.cursor_manager); 115 wlr_cursor_destroy(wimp.cursor); 116 wl_display_destroy(wimp.display); 117 } 118 119 120 int main(int argc, char *argv[]) 121 { 122 int opt; 123 int log_level = WLR_ERROR; 124 125 while ((opt = getopt(argc, argv, "hc:di")) != -1) { 126 switch (opt) { 127 case 'h': 128 printf(usage); 129 return EXIT_SUCCESS; 130 break; 131 case 'd': 132 log_level = WLR_DEBUG; 133 break; 134 case 'i': 135 log_level = WLR_INFO; 136 break; 137 } 138 } 139 140 init_log(log_level); 141 142 // create 143 wimp.display = wl_display_create(); 144 wimp.backend = wlr_backend_autocreate(wimp.display); 145 wimp.renderer = wlr_backend_get_renderer(wimp.backend); 146 wlr_renderer_init_wl_display(wimp.renderer, wimp.display); 147 wlr_compositor_create(wimp.display, wimp.renderer); 148 149 const char *socket = wl_display_add_socket_auto(wimp.display); 150 if (!socket) { 151 wlr_log(WLR_INFO, "Could not create socket: %s.", socket); 152 return EXIT_FAILURE; 153 } 154 155 // initialise 156 wl_list_init(&wimp.desks); 157 wl_list_init(&wimp.key_bindings); 158 wl_list_init(&wimp.mouse_bindings); 159 wl_list_init(&wimp.marks); 160 wl_list_init(&wimp.scratchpads); 161 162 // configure 163 set_up_inputs(); 164 set_up_outputs(); 165 set_up_shell(); 166 set_up_cursor(); 167 set_up_decorations(); 168 set_up_layer_shell(); 169 set_up_defaults(); 170 171 // start 172 if (!start_ipc(socket) || !wlr_backend_start(wimp.backend)) { 173 shutdown(); 174 return EXIT_FAILURE; 175 } 176 setenv("WAYLAND_DISPLAY", socket, true); 177 schedule_startup(); 178 centre_cursor(); 179 wlr_log(WLR_INFO, "Starting with WAYLAND_DISPLAY=%s.", socket); 180 wl_display_run(wimp.display); 181 182 // stop 183 wl_display_destroy_clients(wimp.display); 184 close_ipc(socket); 185 shutdown(); 186 return EXIT_SUCCESS; 187 } 188