mowc.c (3447B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <swc.h> 5 #include <unistd.h> 6 #include <wayland-server.h> 7 #include <xkbcommon/xkbcommon.h> 8 9 #define OVERLAY_PROGRAM MOWC_LIBEXEC "/overlay" 10 #define STATUS_BAR_PROGRAM MOWC_LIBEXEC "/status_bar" 11 12 static struct wl_display *display; 13 static struct swc_screen *curscreen; 14 static struct swc_window *curwindow; 15 static struct swc_window *overlay; 16 17 void 18 destroy(void *data) 19 { 20 curwindow = NULL; 21 } 22 23 void 24 app_id_changed(void *data) 25 { 26 struct swc_window *window = data; 27 if (!overlay && window->app_id && strcmp(window->app_id, "overlay") == 0) { 28 overlay = window; 29 swc_window_set_geometry(overlay, &curscreen->usable_geometry); 30 if (curwindow == window) 31 curwindow = NULL; 32 33 swc_window_hide(window); 34 return; 35 } 36 } 37 38 struct swc_window_handler window_handler = { 39 .destroy = destroy, 40 .app_id_changed = app_id_changed, 41 }; 42 43 void 44 new_screen(struct swc_screen *screen) 45 { 46 if (!curscreen) 47 curscreen = screen; 48 } 49 50 void 51 new_window(struct swc_window *window) 52 { 53 fprintf(stderr, "new window: %s, %s!\n", window->app_id, window->title); 54 55 if (curwindow) 56 swc_window_close(curwindow); 57 58 curwindow = window; 59 swc_window_set_geometry(window, &curscreen->usable_geometry); 60 swc_window_set_tiled(window); 61 swc_window_focus(window); 62 swc_window_set_handler(window, &window_handler, window); 63 swc_window_show(window); 64 } 65 66 struct swc_manager manager = { 67 .new_screen = new_screen, 68 .new_window = new_window, 69 }; 70 71 static void 72 quit(void *data, uint32_t time, uint32_t value, uint32_t state) 73 { 74 if (state != WL_KEYBOARD_KEY_STATE_PRESSED) 75 return; 76 77 swc_finalize(); 78 wl_display_terminate(display); 79 } 80 81 bool justawoke = false; 82 83 static void 84 power_handler(void *data, uint32_t time, uint32_t value, uint32_t state) 85 { 86 if (state) // we only care about key releases 87 return; 88 89 if (justawoke) { 90 justawoke = false; 91 return; 92 } 93 94 FILE *power = fopen("/sys/power/state", "w"); 95 if (power == NULL) 96 return; 97 98 fwrite("mem\n", sizeof(char), sizeof("mem\n") - 1, power); 99 100 fclose(power); 101 justawoke = true; 102 } 103 104 bool overlay_active = false; 105 106 static void 107 overlay_handler(void *data, uint32_t time, uint32_t value, uint32_t state) 108 { 109 if (!state) // ignore releases 110 return; 111 112 if (overlay_active) { 113 overlay_active = false; 114 swc_window_hide(overlay); 115 if (curwindow) 116 swc_window_show(curwindow); 117 } else { 118 overlay_active = true; 119 swc_window_show(overlay); 120 if (curwindow) 121 swc_window_hide(curwindow); 122 } 123 } 124 125 static int 126 launchchild(char *prog) 127 { 128 pid_t pid = fork(); 129 if (pid < 0) { 130 return -1; 131 } else if (pid == 0) { 132 execl(prog, prog, NULL); 133 } 134 return 0; 135 } 136 137 138 int 139 main(int argc, char *argv[]) 140 { 141 struct wl_event_loop *event_loop; 142 const char *socket; 143 144 display = wl_display_create(); 145 if (!display) 146 return 1; 147 148 socket = wl_display_add_socket_auto(display); 149 if (!socket) 150 return 1; 151 setenv("WAYLAND_DISPLAY", socket, 1); 152 153 if (!swc_initialize(display, NULL, &manager)) 154 return 1; 155 156 swc_add_binding(SWC_BINDING_KEY, 0, XKB_KEY_XF86PowerOff, power_handler, NULL); 157 swc_add_binding(SWC_BINDING_KEY, 0, XKB_KEY_XF86AudioLowerVolume, overlay_handler, NULL); 158 159 if (launchchild(OVERLAY_PROGRAM) < 0) { 160 fprintf(stderr, "failed to launch overlay\n"); 161 return 1; 162 } 163 164 if (launchchild(STATUS_BAR_PROGRAM) < 0) { 165 fprintf(stderr, "failed to launch status bar\n"); 166 return 1; 167 } 168 169 swc_cursor_hide(); 170 171 event_loop = wl_display_get_event_loop(display); 172 wl_display_run(display); 173 wl_display_destroy(display); 174 }