wio

a wayland wm stylised after plan9 rio - forked from git.sr.ht/~srcmpwn/wio
git clone git://src.gearsix.net/wiowio.zip
Log | Files | Refs | Atom | Submodules | README | LICENSE

main.c (raw) (8506B)


   1 #define _POSIX_C_SOURCE 200809L
   2 #include <assert.h>
   3 #include <cairo/cairo.h>
   4 #include <drm_fourcc.h>
   5 #include <getopt.h>
   6 #include <stdlib.h>
   7 #include <string.h>
   8 #include <time.h>
   9 #include <wayland-server.h>
  10 #include <wlr/backend.h>
  11 #include <wlr/render/wlr_renderer.h>
  12 #include <wlr/render/wlr_texture.h>
  13 #include <wlr/types/wlr_compositor.h>
  14 #include <wlr/types/wlr_data_control_v1.h>
  15 #include <wlr/types/wlr_data_device.h>
  16 #include <wlr/types/wlr_export_dmabuf_v1.h>
  17 #include <wlr/types/wlr_gamma_control_v1.h>
  18 //#include <wlr/types/wlr_gtk_primary_selection.h>
  19 #include <wlr/types/wlr_layer_shell_v1.h>
  20 #include <wlr/types/wlr_primary_selection_v1.h>
  21 #include <wlr/types/wlr_screencopy_v1.h>
  22 #include <wlr/types/wlr_seat.h>
  23 #include <wlr/types/wlr_xcursor_manager.h>
  24 #include <wlr/types/wlr_xdg_shell.h>
  25 #include <wlr/types/wlr_xdg_output_v1.h>
  26 #include <wlr/util/log.h>
  27 #include "layers.h"
  28 #include "server.h"
  29 #include "view.h"
  30 
  31 static void gen_menu_textures(struct wio_server *server) {
  32 	struct wlr_renderer *renderer = server->renderer;
  33 	cairo_surface_t *surf = cairo_image_surface_create(
  34 			CAIRO_FORMAT_ARGB32, 128, 128); // numbers pulled from ass
  35 	cairo_t *cairo = cairo_create(surf);
  36 	cairo_select_font_face(cairo, "monospace",
  37 			CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  38 	cairo_set_font_size(cairo, 14);
  39 	cairo_set_source_rgb(cairo, 0, 0, 0);
  40 
  41 	char *text[] = { "New", "Resize", "Move", "Delete", "Hide" };
  42 	for (size_t i = 0; i < sizeof(text) / sizeof(text[0]); ++i) {
  43 		cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
  44 		cairo_paint(cairo);
  45 		cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
  46 		cairo_text_extents_t extents;
  47 		cairo_text_extents(cairo, text[i], &extents);
  48 		cairo_move_to(cairo, 0, extents.height);
  49 		cairo_show_text(cairo, text[i]);
  50 		cairo_surface_flush(surf);
  51 		unsigned char *data = cairo_image_surface_get_data(surf);
  52 		server->menu.inactive_textures[i] = wlr_texture_from_pixels(renderer,
  53 				DRM_FORMAT_ARGB8888,
  54 				cairo_image_surface_get_stride(surf),
  55 				extents.width + 2, extents.height + 2, data);
  56 	}
  57 
  58 	cairo_set_source_rgb(cairo, 1, 1, 1);
  59 	for (size_t i = 0; i < sizeof(text) / sizeof(text[0]); ++i) {
  60 		cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
  61 		cairo_paint(cairo);
  62 		cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
  63 		cairo_text_extents_t extents;
  64 		cairo_text_extents(cairo, text[i], &extents);
  65 		cairo_move_to(cairo, 0, extents.height);
  66 		cairo_show_text(cairo, text[i]);
  67 		cairo_surface_flush(surf);
  68 		unsigned char *data = cairo_image_surface_get_data(surf);
  69 		server->menu.active_textures[i] = wlr_texture_from_pixels(renderer,
  70 				DRM_FORMAT_ARGB8888,
  71 				cairo_image_surface_get_stride(surf),
  72 				extents.width + 2, extents.height + 2, data);
  73 	}
  74 
  75 	cairo_destroy(cairo);
  76 	cairo_surface_destroy(surf);
  77 }
  78 
  79 static enum wl_output_transform str_to_transform(const char *str) {
  80 	if (strcmp(str, "normal") == 0 || strcmp(str, "0") == 0) {
  81 		return WL_OUTPUT_TRANSFORM_NORMAL;
  82 	} else if (strcmp(str, "90") == 0) {
  83 		return WL_OUTPUT_TRANSFORM_90;
  84 	} else if (strcmp(str, "180") == 0) {
  85 		return WL_OUTPUT_TRANSFORM_180;
  86 	} else if (strcmp(str, "270") == 0) {
  87 		return WL_OUTPUT_TRANSFORM_270;
  88 	} else if (strcmp(str, "flipped") == 0) {
  89 		return WL_OUTPUT_TRANSFORM_FLIPPED;
  90 	} else if (strcmp(str, "flipped-90") == 0) {
  91 		return WL_OUTPUT_TRANSFORM_FLIPPED_90;
  92 	} else if (strcmp(str, "flipped-180") == 0) {
  93 		return WL_OUTPUT_TRANSFORM_FLIPPED_180;
  94 	} else if (strcmp(str, "flipped-270") == 0) {
  95 		return WL_OUTPUT_TRANSFORM_FLIPPED_270;
  96 	} else {
  97 		fprintf(stderr, "Invalid output transform %s\n", str);
  98 		exit(1);
  99 	}
 100 }
 101 
 102 int main(int argc, char **argv) {
 103 	struct wio_server server = { 0 };
 104 	server.cage = "cage -d";
 105 	server.term = "alacritty";
 106 	wlr_log_init(WLR_DEBUG, NULL);
 107 	wl_list_init(&server.output_configs);
 108 
 109 	int c;
 110 	while ((c = getopt(argc, argv, "c:t:o:h")) != -1) {
 111 		switch (c) {
 112 		case 'c':
 113 			server.cage = optarg;
 114 			break;
 115 		case 't':
 116 			server.term = optarg;
 117 			break;
 118 		case 'o':;
 119 			// name:x:y:width:height:scale:transform
 120 			struct wio_output_config *config =
 121 				calloc(1, sizeof(struct wio_output_config));
 122 			wl_list_insert(&server.output_configs, &config->link);
 123 			const char *tok = strtok(optarg, ":");
 124 			assert(tok);
 125 			config->name = strdup(tok);
 126 			tok = strtok(NULL, ":");
 127 			assert(tok);
 128 			config->x = atoi(tok);
 129 			tok = strtok(NULL, ":");
 130 			assert(tok);
 131 			config->y = atoi(tok);
 132 			tok = strtok(NULL, ":");
 133 			if (!tok) break;
 134 			config->width = atoi(tok);
 135 			tok = strtok(NULL, ":");
 136 			assert(tok);
 137 			config->height = atoi(tok);
 138 			tok = strtok(NULL, ":");
 139 			if (!tok) break;
 140 			config->scale = atoi(tok);
 141 			tok = strtok(NULL, ":");
 142 			if (!tok) break;
 143 			config->transform = str_to_transform(tok);
 144 			break;
 145 		case 'h':
 146 			printf("Usage: %s [-t <term>] [-c <cage>] [-o <output config>...]\n",
 147 					argv[0]);
 148 			return 0;
 149 		default:
 150 			fprintf(stderr, "Unrecognized option %c\n", c);
 151 			return 1;
 152 		}
 153 	}
 154 
 155 	server.wl_display = wl_display_create();
 156 	server.backend = wlr_backend_autocreate(server.wl_display);
 157 	server.renderer = wlr_backend_get_renderer(server.backend);
 158 	wlr_renderer_init_wl_display(server.renderer, server.wl_display);
 159 
 160 	wlr_compositor_create(server.wl_display, server.renderer);
 161 	wlr_data_device_manager_create(server.wl_display);
 162 
 163 	wlr_export_dmabuf_manager_v1_create(server.wl_display);
 164 	wlr_screencopy_manager_v1_create(server.wl_display);
 165 	wlr_data_control_manager_v1_create(server.wl_display);
 166 	wlr_primary_selection_v1_device_manager_create(server.wl_display);
 167 
 168 	wlr_gamma_control_manager_v1_create(server.wl_display);
 169 //	wlr_gtk_primary_selection_device_manager_create(server.wl_display);
 170 
 171 	wl_list_init(&server.outputs);
 172 	server.new_output.notify = server_new_output;
 173 	wl_signal_add(&server.backend->events.new_output, &server.new_output);
 174 
 175 	server.output_layout = wlr_output_layout_create();
 176 	wlr_xdg_output_manager_v1_create(server.wl_display, server.output_layout);
 177 
 178 	server.cursor = wlr_cursor_create();
 179 	wlr_cursor_attach_output_layout(server.cursor, server.output_layout);
 180 	server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
 181 	wlr_xcursor_manager_load(server.cursor_mgr, 1);
 182 
 183 	struct wio_output_config *config;
 184 	wl_list_for_each(config, &server.output_configs, link) {
 185 		if (config->scale > 1){
 186 			wlr_xcursor_manager_load(server.cursor_mgr, config->scale);
 187 		}
 188 	}
 189 
 190 	server.cursor_motion.notify = server_cursor_motion;
 191 	wl_signal_add(&server.cursor->events.motion, &server.cursor_motion);
 192 	server.cursor_motion_absolute.notify = server_cursor_motion_absolute;
 193 	wl_signal_add(&server.cursor->events.motion_absolute,
 194 			&server.cursor_motion_absolute);
 195 	server.cursor_button.notify = server_cursor_button;
 196 	wl_signal_add(&server.cursor->events.button, &server.cursor_button);
 197 	server.cursor_axis.notify = server_cursor_axis;
 198 	wl_signal_add(&server.cursor->events.axis, &server.cursor_axis);
 199 	server.cursor_frame.notify = server_cursor_frame;
 200 	wl_signal_add(&server.cursor->events.frame, &server.cursor_frame);
 201 
 202 	wl_list_init(&server.inputs);
 203 	server.new_input.notify = server_new_input;
 204 	wl_signal_add(&server.backend->events.new_input, &server.new_input);
 205 
 206 	server.seat = wlr_seat_create(server.wl_display, "seat0");
 207 	server.request_cursor.notify = seat_request_cursor;
 208 	wl_signal_add(&server.seat->events.request_set_cursor,
 209 			&server.request_cursor);
 210 	wl_list_init(&server.keyboards);
 211 	wl_list_init(&server.pointers);
 212 
 213 	wl_list_init(&server.views);
 214 	server.xdg_shell = wlr_xdg_shell_create(server.wl_display);
 215 	server.new_xdg_surface.notify = server_new_xdg_surface;
 216 	wl_signal_add(&server.xdg_shell->events.new_surface,
 217 			&server.new_xdg_surface);
 218 
 219 	wl_list_init(&server.new_views);
 220 
 221 	server.layer_shell = wlr_layer_shell_v1_create(server.wl_display);
 222 	server.new_layer_surface.notify = server_new_layer_surface;
 223 	wl_signal_add(&server.layer_shell->events.new_surface,
 224 			&server.new_layer_surface);
 225 
 226 	server.menu.x = server.menu.y = -1;
 227 	gen_menu_textures(&server);
 228 	server.input_state = INPUT_STATE_NONE;
 229 
 230 	const char *socket = wl_display_add_socket_auto(server.wl_display);
 231 	if (!socket) {
 232 		wlr_backend_destroy(server.backend);
 233 		return 1;
 234 	}
 235 
 236 	if (!wlr_backend_start(server.backend)) {
 237 		wlr_backend_destroy(server.backend);
 238 		wl_display_destroy(server.wl_display);
 239 		return 1;
 240 	}
 241 
 242 	setenv("WAYLAND_DISPLAY", socket, true);
 243 	wlr_log(WLR_INFO,
 244 			"Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
 245 	wl_display_run(server.wl_display);
 246 
 247 	wl_display_destroy_clients(server.wl_display);
 248 	wl_display_destroy(server.wl_display);
 249 	return 0;
 250 }