mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Add dynamic output resizing for Wayland backend
This allows outputs to: - Not support modesetting - Resize themselves
This commit is contained in:
		
							parent
							
								
									c9d5a0b2fb
								
							
						
					
					
						commit
						b9d36c8149
					
				
					 10 changed files with 75 additions and 90 deletions
				
			
		| 
						 | 
					@ -260,6 +260,7 @@ static bool wlr_drm_output_set_mode(struct wlr_output_state *output,
 | 
				
			||||||
	output->width = output->wlr_output->width = mode->width;
 | 
						output->width = output->wlr_output->width = mode->width;
 | 
				
			||||||
	output->height = output->wlr_output->height = mode->height;
 | 
						output->height = output->wlr_output->height = mode->height;
 | 
				
			||||||
	output->wlr_output->current_mode = mode;
 | 
						output->wlr_output->current_mode = mode;
 | 
				
			||||||
 | 
						wl_signal_emit(&output->wlr_output->events.resolution, output->wlr_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!display_init_renderer(&state->renderer, output)) {
 | 
						if (!display_init_renderer(&state->renderer, output)) {
 | 
				
			||||||
		wlr_log(L_ERROR, "Failed to initalise renderer for %s", output->wlr_output->name);
 | 
							wlr_log(L_ERROR, "Failed to initalise renderer for %s", output->wlr_output->name);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,18 +12,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dispatch_events(int fd, uint32_t mask, void *data) {
 | 
					static int dispatch_events(int fd, uint32_t mask, void *data) {
 | 
				
			||||||
	struct wlr_backend_state *state = data;
 | 
						struct wlr_backend_state *state = data;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	int count = 0;
 | 
						int count = 0;
 | 
				
			||||||
	if(mask & WL_EVENT_READABLE)
 | 
						if (mask & WL_EVENT_READABLE) {
 | 
				
			||||||
		count = wl_display_dispatch(state->remote_display);
 | 
							count = wl_display_dispatch(state->remote_display);
 | 
				
			||||||
	if(mask & WL_EVENT_WRITABLE)
 | 
						}
 | 
				
			||||||
 | 
						if (mask & WL_EVENT_WRITABLE) {
 | 
				
			||||||
		count = wl_display_flush(state->remote_display);
 | 
							count = wl_display_flush(state->remote_display);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (mask == 0) {
 | 
						if (mask == 0) {
 | 
				
			||||||
		count = wl_display_dispatch_pending(state->remote_display);
 | 
							count = wl_display_dispatch_pending(state->remote_display);
 | 
				
			||||||
		wl_display_flush(state->remote_display);
 | 
							wl_display_flush(state->remote_display);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return count;
 | 
						return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,49 +38,9 @@ static struct wl_callback_listener frame_listener = {
 | 
				
			||||||
	.done = surface_frame_callback
 | 
						.done = surface_frame_callback
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: enable/cursor etc
 | 
					 | 
				
			||||||
static void wlr_wl_output_enable(struct wlr_output_state *output, bool enable) {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool wlr_wl_output_set_mode(struct wlr_output_state *output,
 | 
					 | 
				
			||||||
		struct wlr_output_mode *mode) {
 | 
					 | 
				
			||||||
	output->output->current_mode = mode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// start rendering loop per callbacks by rendering first frame
 | 
					 | 
				
			||||||
	if (!eglMakeCurrent(output->backend->egl.display,
 | 
					 | 
				
			||||||
		output->egl_surface, output->egl_surface,
 | 
					 | 
				
			||||||
		output->backend->egl.context)) {
 | 
					 | 
				
			||||||
		wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error());
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	glViewport(0, 0, output->width, output->height);
 | 
					 | 
				
			||||||
	glClearColor(1.0, 1.0, 1.0, 1.0);
 | 
					 | 
				
			||||||
	glClear(GL_COLOR_BUFFER_BIT);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	output->frame_callback = wl_surface_frame(output->surface);
 | 
					 | 
				
			||||||
	wl_callback_add_listener(output->frame_callback, &frame_listener, output);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!eglSwapBuffers(output->backend->egl.display, output->egl_surface)) {
 | 
					 | 
				
			||||||
		wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error());
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void wlr_wl_output_transform(struct wlr_output_state *output,
 | 
					static void wlr_wl_output_transform(struct wlr_output_state *output,
 | 
				
			||||||
		enum wl_output_transform transform) {
 | 
							enum wl_output_transform transform) {
 | 
				
			||||||
}
 | 
						// TODO
 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool wlr_wl_output_set_cursor(struct wlr_output_state *output,
 | 
					 | 
				
			||||||
		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) {
 | 
					 | 
				
			||||||
	return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool wlr_wl_output_move_cursor(struct wlr_output_state *output,
 | 
					 | 
				
			||||||
		int x, int y) {
 | 
					 | 
				
			||||||
	return false;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void wlr_wl_output_destroy(struct wlr_output_state *output) {
 | 
					static void wlr_wl_output_destroy(struct wlr_output_state *output) {
 | 
				
			||||||
| 
						 | 
					@ -93,11 +53,7 @@ static void wlr_wl_output_destroy(struct wlr_output_state *output) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_output_impl output_impl = {
 | 
					static struct wlr_output_impl output_impl = {
 | 
				
			||||||
	.enable = wlr_wl_output_enable,
 | 
					 | 
				
			||||||
	.set_mode = wlr_wl_output_set_mode,
 | 
					 | 
				
			||||||
	.transform = wlr_wl_output_transform,
 | 
						.transform = wlr_wl_output_transform,
 | 
				
			||||||
	.set_cursor = wlr_wl_output_set_cursor,
 | 
					 | 
				
			||||||
	.move_cursor = wlr_wl_output_move_cursor,
 | 
					 | 
				
			||||||
	.destroy = wlr_wl_output_destroy,
 | 
						.destroy = wlr_wl_output_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,11 +65,18 @@ void handle_ping(void* data, struct wl_shell_surface* ssurface, uint32_t serial)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void handle_configure(void *data, struct wl_shell_surface *wl_shell_surface,
 | 
					void handle_configure(void *data, struct wl_shell_surface *wl_shell_surface,
 | 
				
			||||||
		uint32_t edges, int32_t width, int32_t height){
 | 
							uint32_t edges, int32_t width, int32_t height){
 | 
				
			||||||
	wlr_log(L_DEBUG, "resize %d %d", width, height);
 | 
						struct wlr_output_state *ostate = data;
 | 
				
			||||||
 | 
						assert(ostate && ostate->shell_surface == wl_shell_surface);
 | 
				
			||||||
 | 
						struct wlr_output *output = ostate->output;
 | 
				
			||||||
 | 
						wl_egl_window_resize(ostate->egl_window, width, height, 0, 0);
 | 
				
			||||||
 | 
						output->width = width;
 | 
				
			||||||
 | 
						output->height = height;
 | 
				
			||||||
 | 
						wlr_output_update_matrix(output);
 | 
				
			||||||
 | 
						wl_signal_emit(&output->events.resolution, output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void handle_popup_done(void *data, struct wl_shell_surface *wl_shell_surface) {
 | 
					void handle_popup_done(void *data, struct wl_shell_surface *wl_shell_surface) {
 | 
				
			||||||
	wlr_log(L_ERROR, "Unexpected call");
 | 
						wlr_log(L_ERROR, "Unexpected wl_shell_surface.popup_done event");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wl_shell_surface_listener shell_surface_listener = {
 | 
					static struct wl_shell_surface_listener shell_surface_listener = {
 | 
				
			||||||
| 
						 | 
					@ -124,10 +87,6 @@ static struct wl_shell_surface_listener shell_surface_listener = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_output *wlr_wl_output_create(struct wlr_backend_state* backend,
 | 
					struct wlr_output *wlr_wl_output_create(struct wlr_backend_state* backend,
 | 
				
			||||||
		size_t id) {
 | 
							size_t id) {
 | 
				
			||||||
	// TODO: dont hardcode stuff like size
 | 
					 | 
				
			||||||
	static unsigned int width = 800;
 | 
					 | 
				
			||||||
	static unsigned int height = 500;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wlr_output_state *ostate;
 | 
						struct wlr_output_state *ostate;
 | 
				
			||||||
	if (!(ostate = calloc(sizeof(struct wlr_output_state), 1))) {
 | 
						if (!(ostate = calloc(sizeof(struct wlr_output_state), 1))) {
 | 
				
			||||||
		wlr_log(L_ERROR, "Failed to allocate wlr_output_state");
 | 
							wlr_log(L_ERROR, "Failed to allocate wlr_output_state");
 | 
				
			||||||
| 
						 | 
					@ -141,24 +100,14 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend_state* backend,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output->width = width;
 | 
						wlr_output->width = 640;
 | 
				
			||||||
	wlr_output->height = height;
 | 
						wlr_output->height = 480;
 | 
				
			||||||
	wlr_output->scale = 1;
 | 
						wlr_output->scale = 1;
 | 
				
			||||||
	strncpy(wlr_output->make, "wayland", sizeof(wlr_output->make));
 | 
						strncpy(wlr_output->make, "wayland", sizeof(wlr_output->make));
 | 
				
			||||||
	strncpy(wlr_output->model, "wayland", sizeof(wlr_output->model));
 | 
						strncpy(wlr_output->model, "wayland", sizeof(wlr_output->model));
 | 
				
			||||||
	snprintf(wlr_output->name, sizeof(wlr_output->name), "WL-%d", 1);
 | 
						snprintf(wlr_output->name, sizeof(wlr_output->name), "WL-%d", 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_output_mode mode = {
 | 
					 | 
				
			||||||
		.width = width,
 | 
					 | 
				
			||||||
		.height = height,
 | 
					 | 
				
			||||||
		.refresh = 60,
 | 
					 | 
				
			||||||
		.flags = 0,
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	list_add(wlr_output->modes, &mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ostate->id = id;
 | 
						ostate->id = id;
 | 
				
			||||||
	ostate->width = width;
 | 
					 | 
				
			||||||
	ostate->height = height;
 | 
					 | 
				
			||||||
	ostate->backend = backend;
 | 
						ostate->backend = backend;
 | 
				
			||||||
	ostate->output = wlr_output;
 | 
						ostate->output = wlr_output;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,9 +120,30 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend_state* backend,
 | 
				
			||||||
	wl_shell_surface_add_listener(ostate->shell_surface, &shell_surface_listener, ostate);
 | 
						wl_shell_surface_add_listener(ostate->shell_surface, &shell_surface_listener, ostate);
 | 
				
			||||||
	wl_shell_surface_set_toplevel(ostate->shell_surface);
 | 
						wl_shell_surface_set_toplevel(ostate->shell_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ostate->egl_window = wl_egl_window_create(ostate->surface, width, height);
 | 
						ostate->egl_window = wl_egl_window_create(ostate->surface,
 | 
				
			||||||
 | 
								wlr_output->width, wlr_output->height);
 | 
				
			||||||
	ostate->egl_surface = wlr_egl_create_surface(&backend->egl, ostate->egl_window);
 | 
						ostate->egl_surface = wlr_egl_create_surface(&backend->egl, ostate->egl_window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// start rendering loop per callbacks by rendering first frame
 | 
				
			||||||
 | 
						if (!eglMakeCurrent(ostate->backend->egl.display,
 | 
				
			||||||
 | 
							ostate->egl_surface, ostate->egl_surface,
 | 
				
			||||||
 | 
							ostate->backend->egl.context)) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error());
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glViewport(0, 0, wlr_output->width, wlr_output->height);
 | 
				
			||||||
 | 
						glClearColor(1.0, 1.0, 1.0, 1.0);
 | 
				
			||||||
 | 
						glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ostate->frame_callback = wl_surface_frame(ostate->surface);
 | 
				
			||||||
 | 
						wl_callback_add_listener(ostate->frame_callback, &frame_listener, ostate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!eglSwapBuffers(ostate->backend->egl.display, ostate->egl_surface)) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error());
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_emit(&backend->backend->events.output_add, wlr_output);
 | 
						wl_signal_emit(&backend->backend->events.output_add, wlr_output);
 | 
				
			||||||
	return wlr_output;
 | 
						return wlr_output;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,15 +110,14 @@ int main(int argc, char *argv[]) {
 | 
				
			||||||
		.default_color = { 0.25f, 0.25f, 0.25f, 1 },
 | 
							.default_color = { 0.25f, 0.25f, 0.25f, 1 },
 | 
				
			||||||
		.clear_color = { 0.25f, 0.25f, 0.25f, 1 }
 | 
							.clear_color = { 0.25f, 0.25f, 0.25f, 1 }
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	struct compositor_state compositor = { 0,
 | 
						struct compositor_state compositor = { 0 };
 | 
				
			||||||
		.data = &state,
 | 
						compositor.data = &state;
 | 
				
			||||||
		.output_add_cb = handle_output_add,
 | 
						compositor.output_add_cb = handle_output_add;
 | 
				
			||||||
		.output_frame_cb = handle_output_frame,
 | 
						compositor.output_frame_cb = handle_output_frame;
 | 
				
			||||||
		.keyboard_key_cb = handle_keyboard_key,
 | 
						compositor.keyboard_key_cb = handle_keyboard_key;
 | 
				
			||||||
		.pointer_motion_cb = handle_pointer_motion,
 | 
						compositor.pointer_motion_cb = handle_pointer_motion;
 | 
				
			||||||
		.pointer_button_cb = handle_pointer_button,
 | 
						compositor.pointer_button_cb = handle_pointer_button;
 | 
				
			||||||
		.pointer_axis_cb = handle_pointer_axis,
 | 
						compositor.pointer_axis_cb = handle_pointer_axis;
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	compositor_init(&compositor);
 | 
						compositor_init(&compositor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	state.renderer = wlr_gles3_renderer_init();
 | 
						state.renderer = wlr_gles3_renderer_init();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,13 +197,12 @@ int main(int argc, char *argv[]) {
 | 
				
			||||||
	wl_list_init(&state.config);
 | 
						wl_list_init(&state.config);
 | 
				
			||||||
	parse_args(argc, argv, &state.config);
 | 
						parse_args(argc, argv, &state.config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct compositor_state compositor = { 0,
 | 
						struct compositor_state compositor = { 0 };
 | 
				
			||||||
		.data = &state,
 | 
						compositor.data = &state;
 | 
				
			||||||
		.output_add_cb = handle_output_add,
 | 
						compositor.output_add_cb = handle_output_add;
 | 
				
			||||||
		.output_remove_cb = handle_output_remove,
 | 
						compositor.output_remove_cb = handle_output_remove;
 | 
				
			||||||
		.output_frame_cb = handle_output_frame,
 | 
						compositor.output_frame_cb = handle_output_frame;
 | 
				
			||||||
		.keyboard_key_cb = handle_keyboard_key,
 | 
						compositor.keyboard_key_cb = handle_keyboard_key;
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	compositor_init(&compositor);
 | 
						compositor_init(&compositor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	state.renderer = wlr_gles3_renderer_init();
 | 
						state.renderer = wlr_gles3_renderer_init();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,7 +383,9 @@ static void output_add_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	fprintf(stderr, "Output '%s' added\n", output->name);
 | 
						fprintf(stderr, "Output '%s' added\n", output->name);
 | 
				
			||||||
	fprintf(stderr, "%s %s %"PRId32"mm x %"PRId32"mm\n", output->make, output->model,
 | 
						fprintf(stderr, "%s %s %"PRId32"mm x %"PRId32"mm\n", output->make, output->model,
 | 
				
			||||||
		output->phys_width, output->phys_height);
 | 
							output->phys_width, output->phys_height);
 | 
				
			||||||
	wlr_output_set_mode(output, output->modes->items[0]);
 | 
						if (output->modes->length > 0) {
 | 
				
			||||||
 | 
							wlr_output_set_mode(output, output->modes->items[0]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	struct output_state *ostate = calloc(1, sizeof(struct output_state));
 | 
						struct output_state *ostate = calloc(1, sizeof(struct output_state));
 | 
				
			||||||
	clock_gettime(CLOCK_MONOTONIC, &ostate->last_frame);
 | 
						clock_gettime(CLOCK_MONOTONIC, &ostate->last_frame);
 | 
				
			||||||
	ostate->output = output;
 | 
						ostate->output = output;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,8 +32,6 @@ struct wlr_backend_state {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_output_state {
 | 
					struct wlr_output_state {
 | 
				
			||||||
	size_t id;
 | 
						size_t id;
 | 
				
			||||||
	unsigned int width;
 | 
					 | 
				
			||||||
	unsigned int height;
 | 
					 | 
				
			||||||
	struct wlr_backend_state *backend;
 | 
						struct wlr_backend_state *backend;
 | 
				
			||||||
	struct wlr_output *output;
 | 
						struct wlr_output *output;
 | 
				
			||||||
	struct wl_surface *surface;
 | 
						struct wl_surface *surface;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ struct wlr_output_impl {
 | 
				
			||||||
struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
 | 
					struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
 | 
				
			||||||
		struct wlr_output_state *state);
 | 
							struct wlr_output_state *state);
 | 
				
			||||||
void wlr_output_free(struct wlr_output *output);
 | 
					void wlr_output_free(struct wlr_output *output);
 | 
				
			||||||
 | 
					void wlr_output_update_matrix(struct wlr_output *output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_keyboard_impl {
 | 
					struct wlr_keyboard_impl {
 | 
				
			||||||
	void (*destroy)(struct wlr_keyboard_state *state);
 | 
						void (*destroy)(struct wlr_keyboard_state *state);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,11 +33,13 @@ struct wlr_output {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float transform_matrix[16];
 | 
						float transform_matrix[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Note: some backends may have zero modes */
 | 
				
			||||||
	list_t *modes;
 | 
						list_t *modes;
 | 
				
			||||||
	struct wlr_output_mode *current_mode;
 | 
						struct wlr_output_mode *current_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct wl_signal frame;
 | 
							struct wl_signal frame;
 | 
				
			||||||
 | 
							struct wl_signal resolution;
 | 
				
			||||||
	} events;
 | 
						} events;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,10 @@ static void set_matrix(float mat[static 16], int32_t width, int32_t height,
 | 
				
			||||||
	mat[15] = 1.0f;
 | 
						mat[15] = 1.0f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_output_update_matrix(struct wlr_output *output) {
 | 
				
			||||||
 | 
						set_matrix(output->transform_matrix, output->width, output->height, output->transform);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
 | 
					struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
 | 
				
			||||||
		struct wlr_output_state *state) {
 | 
							struct wlr_output_state *state) {
 | 
				
			||||||
	struct wlr_output *output = calloc(1, sizeof(struct wlr_output));
 | 
						struct wlr_output *output = calloc(1, sizeof(struct wlr_output));
 | 
				
			||||||
| 
						 | 
					@ -73,6 +77,7 @@ struct wlr_output *wlr_output_create(struct wlr_output_impl *impl,
 | 
				
			||||||
	output->modes = list_create();
 | 
						output->modes = list_create();
 | 
				
			||||||
	output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
						output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
				
			||||||
	wl_signal_init(&output->events.frame);
 | 
						wl_signal_init(&output->events.frame);
 | 
				
			||||||
 | 
						wl_signal_init(&output->events.resolution);
 | 
				
			||||||
	return output;
 | 
						return output;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,22 +86,31 @@ void wlr_output_enable(struct wlr_output *output, bool enable) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_output_set_mode(struct wlr_output *output, struct wlr_output_mode *mode) {
 | 
					bool wlr_output_set_mode(struct wlr_output *output, struct wlr_output_mode *mode) {
 | 
				
			||||||
	set_matrix(output->transform_matrix, mode->width, mode->height, output->transform);
 | 
						if (!output->impl || !output->impl->set_mode) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						wlr_output_update_matrix(output);
 | 
				
			||||||
	return output->impl->set_mode(output->state, mode);
 | 
						return output->impl->set_mode(output->state, mode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_output_transform(struct wlr_output *output,
 | 
					void wlr_output_transform(struct wlr_output *output,
 | 
				
			||||||
		enum wl_output_transform transform) {
 | 
							enum wl_output_transform transform) {
 | 
				
			||||||
	set_matrix(output->transform_matrix, output->width, output->height, transform);
 | 
						wlr_output_update_matrix(output);
 | 
				
			||||||
	output->impl->transform(output->state, transform);
 | 
						output->impl->transform(output->state, transform);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_output_set_cursor(struct wlr_output *output,
 | 
					bool wlr_output_set_cursor(struct wlr_output *output,
 | 
				
			||||||
		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) {
 | 
							const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) {
 | 
				
			||||||
 | 
						if (!output->impl || !output->impl->set_cursor) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return output->impl->set_cursor(output->state, buf, stride, width, height);
 | 
						return output->impl->set_cursor(output->state, buf, stride, width, height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_output_move_cursor(struct wlr_output *output, int x, int y) {
 | 
					bool wlr_output_move_cursor(struct wlr_output *output, int x, int y) {
 | 
				
			||||||
 | 
						if (!output->impl || !output->impl->move_cursor) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return output->impl->move_cursor(output->state, x, y);
 | 
						return output->impl->move_cursor(output->state, x, y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue