~goleo/wio

57b8611e7b3b8078a29cc67760f046b1c185f0fa — Drew DeVault 2 years ago 5e6aeab
"Add" "HiDPI" "support"
6 files changed, 113 insertions(+), 51 deletions(-)

M include/view.h
M input.c
M main.c
M meson.build
M output.c
M view.c
M include/view.h => include/view.h +1 -0
@@ 19,5 19,6 @@ void server_new_xdg_surface(struct wl_listener *listener, void *data);
void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy);
void wio_view_move(struct wio_view *view, int x, int y);

#endif

M input.c => input.c +5 -6
@@ 341,8 341,8 @@ static void handle_button_internal(
			y1 = y2;
			y2 = _;
		}
		server->interactive.view->x = x1 + window_border;
		server->interactive.view->y = y1 + window_border;
		wio_view_move(server->interactive.view,
				x1 + window_border, y1 + window_border);
		uint32_t width = x2 - x1, height = y2 - y1;
		if (width < 100) {
			width = 100;


@@ 369,10 369,9 @@ static void handle_button_internal(
		}
		break;
	case INPUT_STATE_MOVE:
		server->interactive.view->x =
			server->cursor->x - server->interactive.sx;
		server->interactive.view->y =
			server->cursor->y - server->interactive.sy;
		wio_view_move(server->interactive.view,
			server->cursor->x - server->interactive.sx,
			server->cursor->y - server->interactive.sy);
		view_end_interactive(server);
		break;
	case INPUT_STATE_DELETE_SELECT:

M main.c => main.c +7 -0
@@ 179,6 179,13 @@ int main(int argc, char **argv) {
	server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
	wlr_xcursor_manager_load(server.cursor_mgr, 1);

	struct wio_output_config *config;
	wl_list_for_each(config, &server.output_configs, link) {
		if (config->scale > 1){
			wlr_xcursor_manager_load(server.cursor_mgr, config->scale);
		}
	}

	server.cursor_motion.notify = server_cursor_motion;
	wl_signal_add(&server.cursor->events.motion, &server.cursor_motion);
	server.cursor_motion_absolute.notify = server_cursor_motion_absolute;

M meson.build => meson.build +4 -0
@@ 21,7 21,10 @@ add_project_arguments(
	language: 'c',
)

cc = meson.get_compiler('c')

cairo = dependency('cairo')
math = cc.find_library('m')
wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots'])
wayland_server = dependency('wayland-server')
wayland_protos = dependency('wayland-protocols')


@@ 44,6 47,7 @@ executable(
	include_directories: [wio_inc],
	dependencies: [
		cairo,
		math,
		server_protos,
		wayland_server,
		wlroots,

M output.c => output.c +77 -41
@@ 1,6 1,7 @@
#define _POSIX_C_SOURCE 200112L
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <wayland-server.h>
#include <wlr/types/wlr_matrix.h>


@@ 45,6 46,17 @@ static void render_surface(struct wlr_surface *surface,
	wlr_surface_send_frame_done(surface, rdata->when);
}

static int scale_length(int length, int offset, float scale) {
	return round((offset + length) * scale) - round(offset * scale);
}

void scale_box(struct wlr_box *box, float scale) {
	box->width = scale_length(box->width, box->x, scale);
	box->height = scale_length(box->height, box->y, scale);
	box->x = round(box->x * scale);
	box->y = round(box->y * scale);
}

static void render_menu(struct wio_output *output) {
	struct wio_server *server = output->server;
	struct wlr_renderer *renderer = server->renderer;


@@ 52,7 64,8 @@ static void render_menu(struct wio_output *output) {
	size_t ntextures =
		sizeof(server->menu.inactive_textures) /
		sizeof(server->menu.inactive_textures[0]);
	const int border = 3, margin = 4;
	int scale = output->wlr_output->scale;
	int border = 3 * scale, margin = 4 * scale;
	int text_height = 0, text_width = 0;
	for (size_t i = 0; i < ntextures; ++i) {
		int width, height;


@@ 60,6 73,7 @@ static void render_menu(struct wio_output *output) {
		// (they probably are)
		wlr_texture_get_size(
				server->menu.inactive_textures[i], &width, &height);
		width /= scale, height /= scale;
		text_height += height + margin;
		if (width >= text_width) {
			text_width = width;


@@ 72,29 86,46 @@ static void render_menu(struct wio_output *output) {
	wlr_output_layout_output_coords(
			server->output_layout, output->wlr_output, &ox, &oy);
	ox += server->menu.x, oy += server->menu.y;
	int scale = output->wlr_output->scale;

	struct wlr_box bg_box = {
		.x = ox * scale,
		.y = oy * scale,
		.width = text_width * scale,
		.height = text_height * scale,
	};
	struct wlr_box bg_box = { 0 };
	// Background
	bg_box.x = ox;
	bg_box.y = oy;
	bg_box.width = text_width;
	bg_box.height = text_height;
	scale_box(&bg_box, scale);
	wlr_render_rect(renderer, &bg_box, menu_unselected,
			output->wlr_output->transform_matrix);
	// Top
	bg_box.x = ox;
	bg_box.y = oy;
	bg_box.width = text_width;
	bg_box.height = border;
	scale_box(&bg_box, scale);
	wlr_render_rect(renderer, &bg_box, menu_border,
			output->wlr_output->transform_matrix);
	bg_box.width += border;
	bg_box.y = (oy + text_height) * scale;
	// Bottom
	bg_box.x = ox;
	bg_box.y = oy + text_height;
	bg_box.width = text_width + border;
	bg_box.height = border;
	scale_box(&bg_box, scale);
	wlr_render_rect(renderer, &bg_box, menu_border,
			output->wlr_output->transform_matrix);
	bg_box.y = oy * scale;
	bg_box.height = text_height * scale;
	// Left
	bg_box.x = ox;
	bg_box.y = oy;
	bg_box.width = border;
	bg_box.height = text_height;
	scale_box(&bg_box, scale);
	wlr_render_rect(renderer, &bg_box, menu_border,
			output->wlr_output->transform_matrix);
	bg_box.x = (ox + text_width) * scale;
	// Right
	bg_box.x = ox + text_width;
	bg_box.y = oy;
	bg_box.width = border;
	bg_box.height = text_height;
	scale_box(&bg_box, scale);
	wlr_render_rect(renderer, &bg_box, menu_border,
			output->wlr_output->transform_matrix);



@@ 105,19 136,22 @@ static void render_menu(struct wio_output *output) {
		int width, height;
		struct wlr_texture *texture = server->menu.inactive_textures[i];
		wlr_texture_get_size(texture, &width, &height);
		width /= scale, height /= scale;
		struct wlr_box box = { 0 };
		box.x = ox - 1 * scale;
		box.y = oy - 1 * scale;
		box.width = (text_width - border) * scale;
		box.height = (height + margin) * scale;
		box.x = ox - scale /* fudge */;
		box.y = oy - scale /* fudge */;
		box.width = text_width - border;
		box.height = height + margin;
		if (wlr_box_contains_point(
					&box, server->cursor->x, server->cursor->y)) {
			server->menu.selected = i;
			texture = server->menu.active_textures[i];
			scale_box(&box, scale);
			wlr_render_rect(renderer, &box, menu_selected,
					output->wlr_output->transform_matrix);
		} else {
			wlr_texture_get_size(texture, &width, &height);
			width /= scale, height /= scale;
		}
		box.x = (ox + (text_width / 2 - width / 2)) * scale;
		box.y = oy * scale;


@@ 143,9 177,10 @@ static void render_view_border(struct wlr_renderer *renderer,
	} else {
		memcpy(color, inactive_border, sizeof(color));
	}
	struct wlr_output *wlr_output = output->wlr_output;
	double ox, oy;
	wlr_output_layout_output_coords(
			output->server->output_layout, output->wlr_output, &ox, &oy);
	wlr_output_layout_output_coords(output->server->output_layout,
			wlr_output, &ox, &oy);
	struct wlr_box borders;
	// Top
	borders.x = x - window_border;


@@ 154,8 189,8 @@ static void render_view_border(struct wlr_renderer *renderer,
	borders.y += oy;
	borders.width = width + window_border * 2;
	borders.height = window_border;
	wlr_render_rect(renderer, &borders, color,
			output->wlr_output->transform_matrix);
	scale_box(&borders, wlr_output->scale);
	wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
	// Right
	borders.x = x + width;
	borders.y = y - window_border;


@@ 163,8 198,8 @@ static void render_view_border(struct wlr_renderer *renderer,
	borders.y += oy;
	borders.width = window_border;
	borders.height = height + window_border * 2;
	wlr_render_rect(renderer, &borders, color,
			output->wlr_output->transform_matrix);
	scale_box(&borders, wlr_output->scale);
	wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
	// Bottom
	borders.x = x - window_border;
	borders.x += ox;


@@ 172,8 207,8 @@ static void render_view_border(struct wlr_renderer *renderer,
	borders.y += oy;
	borders.width = width + window_border * 2;
	borders.height = window_border;
	wlr_render_rect(renderer, &borders, color,
			output->wlr_output->transform_matrix);
	scale_box(&borders, wlr_output->scale);
	wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
	// Left
	borders.x = x - window_border;
	borders.x += ox;


@@ 181,8 216,8 @@ static void render_view_border(struct wlr_renderer *renderer,
	borders.y += oy;
	borders.width = window_border;
	borders.height = height + window_border * 2;
	wlr_render_rect(renderer, &borders, color,
			output->wlr_output->transform_matrix);
	scale_box(&borders, wlr_output->scale);
	wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
}

static void output_frame(struct wl_listener *listener, void *data) {


@@ 197,10 232,8 @@ static void output_frame(struct wl_listener *listener, void *data) {
		return;
	}

	int width, height;
	wlr_output_effective_resolution(output->wlr_output, &width, &height);
	wlr_renderer_begin(renderer, width, height);

	struct wlr_output *wlr_output = output->wlr_output;
	wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
	wlr_renderer_clear(renderer, background);

	struct wio_view *view;


@@ 209,7 242,7 @@ static void output_frame(struct wl_listener *listener, void *data) {
			continue;
		}
		struct render_data rdata = {
			.output = output->wlr_output,
			.output = wlr_output,
			.view = view,
			.renderer = renderer,
			.when = &now,


@@ 245,9 278,9 @@ static void output_frame(struct wl_listener *listener, void *data) {
		render_menu(output);
	}

	wlr_output_render_software_cursors(output->wlr_output, NULL);
	wlr_output_render_software_cursors(wlr_output, NULL);
	wlr_renderer_end(renderer);
	wlr_output_commit(output->wlr_output);
	wlr_output_commit(wlr_output);
}

void server_new_output(struct wl_listener *listener, void *data) {


@@ 278,19 311,22 @@ void server_new_output(struct wl_listener *listener, void *data) {
			wlr_output_layout_add(server->output_layout, wlr_output,
					config->x, config->y);
		}
		bool modeset = false;
		if (config->width && config->height
				&& !wl_list_empty(&wlr_output->modes)) {
			bool set = false;
			struct wlr_output_mode *mode;
			wl_list_for_each(mode, &wlr_output->modes, link) {
				if (mode->width == config->width
						&& mode->height == config->height) {
					wlr_output_set_mode(wlr_output, mode);
					set = true;
					modeset = true;
				}
			}
			if (!set) {
				mode = wl_container_of(wlr_output->modes.prev, mode, link);
		}
		if (!modeset) {
			struct wlr_output_mode *mode =
				wlr_output_preferred_mode(wlr_output);
			if (mode) {
				wlr_output_set_mode(wlr_output, mode);
			}
		}


@@ 301,9 337,9 @@ void server_new_output(struct wl_listener *listener, void *data) {
			wlr_output_set_transform(wlr_output, config->transform);
		}
	} else {
		if (!wl_list_empty(&wlr_output->modes)) {
			struct wlr_output_mode *mode =
				wl_container_of(wlr_output->modes.prev, mode, link);
		struct wlr_output_mode *mode =
			wlr_output_preferred_mode(wlr_output);
		if (mode) {
			wlr_output_set_mode(wlr_output, mode);
		}
		wlr_output_layout_add_auto(server->output_layout, wlr_output);

M view.c => view.c +19 -4
@@ 15,10 15,14 @@ static void xdg_surface_map(struct wl_listener *listener, void *data) {
	struct wlr_output_layout_output *layout = wlr_output_layout_get(
			server->output_layout, output);
	if (view->x == -1 || view->y == -1) {
		view->x = layout->x +
			(output->width / 2 - view->xdg_surface->surface->current.width / 2);
		view->y = layout->y +
			(output->height / 2 - view->xdg_surface->surface->current.height / 2);
		struct wlr_surface_state *current =
			&view->xdg_surface->surface->current;
		wio_view_move(view,
				layout->x + (output->width / 2 - current->width / 2),
				layout->y + (output->height / 2 - current->height / 2));
	} else {
		// Sends wl_surface_enter
		wio_view_move(view, view->x, view->y);
	}
}



@@ 126,3 130,14 @@ struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
	}
	return NULL;
}

void wio_view_move(struct wio_view *view, int x, int y) {
	view->x = x;
	view->y = y;

	// Cheating as FUCK because I'm lazy
	struct wio_output *output;
	wl_list_for_each(output, &view->server->outputs, link) {
		wlr_surface_send_enter(view->xdg_surface->surface, output->wlr_output);
	}
}