mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Add client support for HiDPI
This adds HiDPI support to swaybar, swaybg, and swaylock.
This commit is contained in:
		
							parent
							
								
									61184e3208
								
							
						
					
					
						commit
						b2226ac655
					
				
					 9 changed files with 96 additions and 61 deletions
				
			
		|  | @ -51,12 +51,14 @@ struct window { | ||||||
| 	struct wl_callback *frame_cb; | 	struct wl_callback *frame_cb; | ||||||
| 	struct cursor cursor; | 	struct cursor cursor; | ||||||
| 	uint32_t width, height; | 	uint32_t width, height; | ||||||
|  | 	int32_t scale; | ||||||
| 	char *font; | 	char *font; | ||||||
| 	cairo_t *cairo; | 	cairo_t *cairo; | ||||||
| 	struct pointer_input pointer_input; | 	struct pointer_input pointer_input; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, bool shell_surface); | struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, | ||||||
|  | 		int32_t scale, bool shell_surface); | ||||||
| void window_teardown(struct window *state); | void window_teardown(struct window *state); | ||||||
| int window_prerender(struct window *state); | int window_prerender(struct window *state); | ||||||
| int window_render(struct window *state); | int window_render(struct window *state); | ||||||
|  |  | ||||||
|  | @ -152,12 +152,15 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | ||||||
| 
 | 
 | ||||||
| 		struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; | 		struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; | ||||||
| 
 | 
 | ||||||
| 		bar_output->window = window_setup(bar_output->registry, output->width * output->scale, 30 * output->scale, false); | 		bar_output->window = window_setup(bar_output->registry, | ||||||
|  | 				output->width / output->scale, 30, output->scale, false); | ||||||
| 		if (!bar_output->window) { | 		if (!bar_output->window) { | ||||||
| 			sway_abort("Failed to create window."); | 			sway_abort("Failed to create window."); | ||||||
| 		} | 		} | ||||||
| 		desktop_shell_set_panel(bar_output->registry->desktop_shell, output->output, bar_output->window->surface); | 		desktop_shell_set_panel(bar_output->registry->desktop_shell, | ||||||
| 		desktop_shell_set_panel_position(bar_output->registry->desktop_shell, bar->config->position); | 				output->output, bar_output->window->surface); | ||||||
|  | 		desktop_shell_set_panel_position(bar_output->registry->desktop_shell, | ||||||
|  | 				bar->config->position); | ||||||
| 
 | 
 | ||||||
| 		window_make_shell(bar_output->window); | 		window_make_shell(bar_output->window); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| #include "swaybar/config.h" | #include "swaybar/config.h" | ||||||
| #include "swaybar/status_line.h" | #include "swaybar/status_line.h" | ||||||
| #include "swaybar/render.h" | #include "swaybar/render.h" | ||||||
|  | #include "log.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* internal spacing */ | /* internal spacing */ | ||||||
|  | @ -283,7 +284,8 @@ void render(struct output *output, struct config *config, struct status_line *li | ||||||
| 
 | 
 | ||||||
| 	if (line->protocol == TEXT) { | 	if (line->protocol == TEXT) { | ||||||
| 		get_text_size(window->cairo, window->font, &width, &height, config->pango_markup, "%s", line->text_line); | 		get_text_size(window->cairo, window->font, &width, &height, config->pango_markup, "%s", line->text_line); | ||||||
| 		cairo_move_to(cairo, window->width - margin - width, margin); | 		cairo_move_to(cairo, (window->width * window->scale) | ||||||
|  | 				- margin - width, margin); | ||||||
| 		pango_printf(window->cairo, window->font, config->pango_markup, "%s", line->text_line); | 		pango_printf(window->cairo, window->font, config->pango_markup, "%s", line->text_line); | ||||||
| 	} else if (line->protocol == I3BAR && line->block_line) { | 	} else if (line->protocol == I3BAR && line->block_line) { | ||||||
| 		double pos = window->width - 0.5; | 		double pos = window->width - 0.5; | ||||||
|  | @ -315,12 +317,13 @@ void render(struct output *output, struct config *config, struct status_line *li | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void set_window_height(struct window *window, int height) { | void set_window_height(struct window *window, int height) { | ||||||
| 		int text_width, text_height; | 	int text_width, text_height; | ||||||
| 		get_text_size(window->cairo, window->font, &text_width, &text_height, false, | 	get_text_size(window->cairo, window->font, | ||||||
| 				"Test string for measuring purposes"); | 			&text_width, &text_height, false, | ||||||
| 		if (height > 0) { | 			"Test string for measuring purposes"); | ||||||
| 			margin = (height - text_height) / 2; | 	if (height > 0) { | ||||||
| 			ws_vertical_padding = margin - 1.5; | 		margin = (height - text_height) / 2; | ||||||
| 		} | 		ws_vertical_padding = margin - 1.5; | ||||||
| 		window->height = text_height + margin * 2; | 	} | ||||||
|  | 	window->height = (text_height + margin * 2) / window->scale; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -69,7 +69,8 @@ int main(int argc, const char **argv) { | ||||||
| 	sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length); | 	sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length); | ||||||
| 	int i; | 	int i; | ||||||
| 	struct output_state *output = registry->outputs->items[desired_output]; | 	struct output_state *output = registry->outputs->items[desired_output]; | ||||||
| 	struct window *window = window_setup(registry, output->width, output->height, false); | 	struct window *window = window_setup(registry, | ||||||
|  | 			output->width, output->height, output->scale, false); | ||||||
| 	if (!window) { | 	if (!window) { | ||||||
| 		sway_abort("Failed to create surfaces."); | 		sway_abort("Failed to create surfaces."); | ||||||
| 	} | 	} | ||||||
|  | @ -115,60 +116,63 @@ int main(int argc, const char **argv) { | ||||||
| 			sway_abort("Unsupported scaling mode: %s", scaling_mode_str); | 			sway_abort("Unsupported scaling mode: %s", scaling_mode_str); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		int wwidth = window->width * window->scale; | ||||||
|  | 		int wheight = window->height * window->scale; | ||||||
|  | 
 | ||||||
| 		for (i = 0; i < surfaces->length; ++i) { | 		for (i = 0; i < surfaces->length; ++i) { | ||||||
| 			struct window *window = surfaces->items[i]; | 			struct window *window = surfaces->items[i]; | ||||||
| 			if (window_prerender(window) && window->cairo) { | 			if (window_prerender(window) && window->cairo) { | ||||||
| 				switch (scaling_mode) { | 				switch (scaling_mode) { | ||||||
| 				case SCALING_MODE_STRETCH: | 				case SCALING_MODE_STRETCH: | ||||||
| 					cairo_scale(window->cairo, | 					cairo_scale(window->cairo, | ||||||
| 							(double) window->width / width, | 							(double) wwidth / width, | ||||||
| 							(double) window->height / height); | 							(double) wheight / height); | ||||||
| 					cairo_set_source_surface(window->cairo, image, 0, 0); | 					cairo_set_source_surface(window->cairo, image, 0, 0); | ||||||
| 					break; | 					break; | ||||||
| 				case SCALING_MODE_FILL: | 				case SCALING_MODE_FILL: | ||||||
| 				{ | 				{ | ||||||
| 					double window_ratio = (double) window->width / window->height; | 					double window_ratio = (double) wwidth / wheight; | ||||||
| 					double bg_ratio = width / height; | 					double bg_ratio = width / height; | ||||||
| 
 | 
 | ||||||
| 					if (window_ratio > bg_ratio) { | 					if (window_ratio > bg_ratio) { | ||||||
| 						double scale = (double) window->width / width; | 						double scale = (double) wwidth / width; | ||||||
| 						cairo_scale(window->cairo, scale, scale); | 						cairo_scale(window->cairo, scale, scale); | ||||||
| 						cairo_set_source_surface(window->cairo, image, | 						cairo_set_source_surface(window->cairo, image, | ||||||
| 								0, | 								0, | ||||||
| 								(double) window->height/2 / scale - height/2); | 								(double) wheight/2 / scale - height/2); | ||||||
| 					} else { | 					} else { | ||||||
| 						double scale = (double) window->height / height; | 						double scale = (double) wheight / height; | ||||||
| 						cairo_scale(window->cairo, scale, scale); | 						cairo_scale(window->cairo, scale, scale); | ||||||
| 						cairo_set_source_surface(window->cairo, image, | 						cairo_set_source_surface(window->cairo, image, | ||||||
| 								(double) window->width/2 / scale - width/2, | 								(double) wwidth/2 / scale - width/2, | ||||||
| 								0); | 								0); | ||||||
| 					} | 					} | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 				case SCALING_MODE_FIT: | 				case SCALING_MODE_FIT: | ||||||
| 				{ | 				{ | ||||||
| 					double window_ratio = (double) window->width / window->height; | 					double window_ratio = (double) wwidth / wheight; | ||||||
| 					double bg_ratio = width / height; | 					double bg_ratio = width / height; | ||||||
| 
 | 
 | ||||||
| 					if (window_ratio > bg_ratio) { | 					if (window_ratio > bg_ratio) { | ||||||
| 						double scale = (double) window->height / height; | 						double scale = (double) wheight / height; | ||||||
| 						cairo_scale(window->cairo, scale, scale); | 						cairo_scale(window->cairo, scale, scale); | ||||||
| 						cairo_set_source_surface(window->cairo, image, | 						cairo_set_source_surface(window->cairo, image, | ||||||
| 								(double) window->width/2 / scale - width/2, | 								(double) wwidth/2 / scale - width/2, | ||||||
| 								0); | 								0); | ||||||
| 					} else { | 					} else { | ||||||
| 						double scale = (double) window->width / width; | 						double scale = (double) wwidth / width; | ||||||
| 						cairo_scale(window->cairo, scale, scale); | 						cairo_scale(window->cairo, scale, scale); | ||||||
| 						cairo_set_source_surface(window->cairo, image, | 						cairo_set_source_surface(window->cairo, image, | ||||||
| 								0, | 								0, | ||||||
| 								(double) window->height/2 / scale - height/2); | 								(double) wheight/2 / scale - height/2); | ||||||
| 					} | 					} | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 				case SCALING_MODE_CENTER: | 				case SCALING_MODE_CENTER: | ||||||
| 					cairo_set_source_surface(window->cairo, image, | 					cairo_set_source_surface(window->cairo, image, | ||||||
| 							(double) window->width/2 - width/2, | 							(double) wwidth/2 - width/2, | ||||||
| 							(double) window->height/2 - height/2); | 							(double) wheight/2 - height/2); | ||||||
| 					break; | 					break; | ||||||
| 				case SCALING_MODE_TILE: | 				case SCALING_MODE_TILE: | ||||||
| 				{ | 				{ | ||||||
|  |  | ||||||
|  | @ -223,58 +223,60 @@ void render_color(struct window *window, uint32_t color) { | ||||||
| void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { | void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { | ||||||
| 	double width = cairo_image_surface_get_width(image); | 	double width = cairo_image_surface_get_width(image); | ||||||
| 	double height = cairo_image_surface_get_height(image); | 	double height = cairo_image_surface_get_height(image); | ||||||
|  | 	int wwidth = window->width * window->scale; | ||||||
|  | 	int wheight = window->height * window->scale; | ||||||
| 
 | 
 | ||||||
| 	switch (scaling_mode) { | 	switch (scaling_mode) { | ||||||
| 	case SCALING_MODE_STRETCH: | 	case SCALING_MODE_STRETCH: | ||||||
| 		cairo_scale(window->cairo, | 		cairo_scale(window->cairo, | ||||||
| 				(double) window->width / width, | 				(double) wwidth / width, | ||||||
| 				(double) window->height / height); | 				(double) wheight / height); | ||||||
| 		cairo_set_source_surface(window->cairo, image, 0, 0); | 		cairo_set_source_surface(window->cairo, image, 0, 0); | ||||||
| 		break; | 		break; | ||||||
| 	case SCALING_MODE_FILL: | 	case SCALING_MODE_FILL: | ||||||
| 	{ | 	{ | ||||||
| 		double window_ratio = (double) window->width / window->height; | 		double window_ratio = (double) wwidth / wheight; | ||||||
| 		double bg_ratio = width / height; | 		double bg_ratio = wheight; | ||||||
| 
 | 
 | ||||||
| 		if (window_ratio > bg_ratio) { | 		if (window_ratio > bg_ratio) { | ||||||
| 			double scale = (double) window->width / width; | 			double scale = (double) wwidth / width; | ||||||
| 			cairo_scale(window->cairo, scale, scale); | 			cairo_scale(window->cairo, scale, scale); | ||||||
| 			cairo_set_source_surface(window->cairo, image, | 			cairo_set_source_surface(window->cairo, image, | ||||||
| 					0, | 					0, | ||||||
| 					(double) window->height/2 / scale - height/2); | 					(double) wheight/2 / scale - height/2); | ||||||
| 		} else { | 		} else { | ||||||
| 			double scale = (double) window->height / height; | 			double scale = (double) wheight / height; | ||||||
| 			cairo_scale(window->cairo, scale, scale); | 			cairo_scale(window->cairo, scale, scale); | ||||||
| 			cairo_set_source_surface(window->cairo, image, | 			cairo_set_source_surface(window->cairo, image, | ||||||
| 					(double) window->width/2 / scale - width/2, | 					(double) wwidth/2 / scale - width/2, | ||||||
| 					0); | 					0); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	case SCALING_MODE_FIT: | 	case SCALING_MODE_FIT: | ||||||
| 	{ | 	{ | ||||||
| 		double window_ratio = (double) window->width / window->height; | 		double window_ratio = (double) wwidth / wheight; | ||||||
| 		double bg_ratio = width / height; | 		double bg_ratio = width / height; | ||||||
| 
 | 
 | ||||||
| 		if (window_ratio > bg_ratio) { | 		if (window_ratio > bg_ratio) { | ||||||
| 			double scale = (double) window->height / height; | 			double scale = (double) wheight / height; | ||||||
| 			cairo_scale(window->cairo, scale, scale); | 			cairo_scale(window->cairo, scale, scale); | ||||||
| 			cairo_set_source_surface(window->cairo, image, | 			cairo_set_source_surface(window->cairo, image, | ||||||
| 					(double) window->width/2 / scale - width/2, | 					(double) wwidth/2 / scale - width/2, | ||||||
| 					0); | 					0); | ||||||
| 		} else { | 		} else { | ||||||
| 			double scale = (double) window->width / width; | 			double scale = (double) wwidth / width; | ||||||
| 			cairo_scale(window->cairo, scale, scale); | 			cairo_scale(window->cairo, scale, scale); | ||||||
| 			cairo_set_source_surface(window->cairo, image, | 			cairo_set_source_surface(window->cairo, image, | ||||||
| 					0, | 					0, | ||||||
| 					(double) window->height/2 / scale - height/2); | 					(double) wheight/2 / scale - height/2); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	case SCALING_MODE_CENTER: | 	case SCALING_MODE_CENTER: | ||||||
| 		cairo_set_source_surface(window->cairo, image, | 		cairo_set_source_surface(window->cairo, image, | ||||||
| 				(double) window->width/2 - width/2, | 				(double) wwidth/2 - width/2, | ||||||
| 				(double) window->height/2 - height/2); | 				(double) wheight/2 - height/2); | ||||||
| 		break; | 		break; | ||||||
| 	case SCALING_MODE_TILE: | 	case SCALING_MODE_TILE: | ||||||
| 	{ | 	{ | ||||||
|  | @ -477,7 +479,8 @@ int main(int argc, char **argv) { | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < registry->outputs->length; ++i) { | 	for (i = 0; i < registry->outputs->length; ++i) { | ||||||
| 		struct output_state *output = registry->outputs->items[i]; | 		struct output_state *output = registry->outputs->items[i]; | ||||||
| 		struct window *window = window_setup(registry, output->width, output->height, true); | 		struct window *window = window_setup(registry, | ||||||
|  | 				output->width, output->height, output->scale, true); | ||||||
| 		if (!window) { | 		if (!window) { | ||||||
| 			sway_abort("Failed to create surfaces."); | 			sway_abort("Failed to create surfaces."); | ||||||
| 		} | 		} | ||||||
|  | @ -564,6 +567,8 @@ void render(struct render_data *render_data) { | ||||||
| 		if (!window_prerender(window) || !window->cairo) { | 		if (!window_prerender(window) || !window->cairo) { | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  | 		int wwidth = window->width * window->scale; | ||||||
|  | 		int wheight = window->height * window->scale; | ||||||
| 
 | 
 | ||||||
| 		// Reset the transformation matrix
 | 		// Reset the transformation matrix
 | ||||||
| 		cairo_identity_matrix(window->cairo); | 		cairo_identity_matrix(window->cairo); | ||||||
|  | @ -595,7 +600,7 @@ void render(struct render_data *render_data) { | ||||||
| 		if (show_indicator && render_data->auth_state != AUTH_STATE_IDLE) { | 		if (show_indicator && render_data->auth_state != AUTH_STATE_IDLE) { | ||||||
| 			// Draw circle
 | 			// Draw circle
 | ||||||
| 			cairo_set_line_width(window->cairo, ARC_THICKNESS); | 			cairo_set_line_width(window->cairo, ARC_THICKNESS); | ||||||
| 			cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, 0, 2 * M_PI); | 			cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, 0, 2 * M_PI); | ||||||
| 			switch (render_data->auth_state) { | 			switch (render_data->auth_state) { | ||||||
| 			case AUTH_STATE_INPUT: | 			case AUTH_STATE_INPUT: | ||||||
| 			case AUTH_STATE_BACKSPACE: { | 			case AUTH_STATE_BACKSPACE: { | ||||||
|  | @ -638,8 +643,8 @@ void render(struct render_data *render_data) { | ||||||
| 				double x, y; | 				double x, y; | ||||||
| 
 | 
 | ||||||
| 				cairo_text_extents(window->cairo, text, &extents); | 				cairo_text_extents(window->cairo, text, &extents); | ||||||
| 				x = window->width/2 - ((extents.width/2) + extents.x_bearing); | 				x = wwidth/2 - ((extents.width/2) + extents.x_bearing); | ||||||
| 				y = window->height/2 - ((extents.height/2) + extents.y_bearing); | 				y = wheight/2 - ((extents.height/2) + extents.y_bearing); | ||||||
| 
 | 
 | ||||||
| 				cairo_move_to(window->cairo, x, y); | 				cairo_move_to(window->cairo, x, y); | ||||||
| 				cairo_show_text(window->cairo, text); | 				cairo_show_text(window->cairo, text); | ||||||
|  | @ -651,7 +656,7 @@ void render(struct render_data *render_data) { | ||||||
| 			if (render_data->auth_state == AUTH_STATE_INPUT || render_data->auth_state == AUTH_STATE_BACKSPACE) { | 			if (render_data->auth_state == AUTH_STATE_INPUT || render_data->auth_state == AUTH_STATE_BACKSPACE) { | ||||||
| 				static double highlight_start = 0; | 				static double highlight_start = 0; | ||||||
| 				highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; | 				highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; | ||||||
| 				cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); | 				cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); | ||||||
| 				if (render_data->auth_state == AUTH_STATE_INPUT) { | 				if (render_data->auth_state == AUTH_STATE_INPUT) { | ||||||
| 					cairo_set_source_rgb(window->cairo, 51.0 / 255, 219.0 / 255, 0); | 					cairo_set_source_rgb(window->cairo, 51.0 / 255, 219.0 / 255, 0); | ||||||
| 				} else { | 				} else { | ||||||
|  | @ -661,19 +666,19 @@ void render(struct render_data *render_data) { | ||||||
| 
 | 
 | ||||||
| 				// Draw borders
 | 				// Draw borders
 | ||||||
| 				cairo_set_source_rgb(window->cairo, 0, 0, 0); | 				cairo_set_source_rgb(window->cairo, 0, 0, 0); | ||||||
| 				cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS); | 				cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS); | ||||||
| 				cairo_stroke(window->cairo); | 				cairo_stroke(window->cairo); | ||||||
| 
 | 
 | ||||||
| 				cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, highlight_start + TYPE_INDICATOR_RANGE, (highlight_start + TYPE_INDICATOR_RANGE) + TYPE_INDICATOR_BORDER_THICKNESS); | 				cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start + TYPE_INDICATOR_RANGE, (highlight_start + TYPE_INDICATOR_RANGE) + TYPE_INDICATOR_BORDER_THICKNESS); | ||||||
| 				cairo_stroke(window->cairo); | 				cairo_stroke(window->cairo); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// Draw inner + outer border of the circle
 | 			// Draw inner + outer border of the circle
 | ||||||
| 			cairo_set_source_rgb(window->cairo, 0, 0, 0); | 			cairo_set_source_rgb(window->cairo, 0, 0, 0); | ||||||
| 			cairo_set_line_width(window->cairo, 2.0); | 			cairo_set_line_width(window->cairo, 2.0); | ||||||
| 			cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS - ARC_THICKNESS/2, 0, 2*M_PI); | 			cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS - ARC_THICKNESS/2, 0, 2*M_PI); | ||||||
| 			cairo_stroke(window->cairo); | 			cairo_stroke(window->cairo); | ||||||
| 			cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS + ARC_THICKNESS/2, 0, 2*M_PI); | 			cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS + ARC_THICKNESS/2, 0, 2*M_PI); | ||||||
| 			cairo_stroke(window->cairo); | 			cairo_stroke(window->cairo); | ||||||
| 		} | 		} | ||||||
| 		window_render(window); | 		window_render(window); | ||||||
|  |  | ||||||
|  | @ -50,8 +50,10 @@ static const struct wl_buffer_listener buffer_listener = { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct buffer *create_buffer(struct window *window, struct buffer *buf, | static struct buffer *create_buffer(struct window *window, struct buffer *buf, | ||||||
| 		int32_t width, int32_t height, uint32_t format) { | 		int32_t width, int32_t height, int32_t scale, uint32_t format) { | ||||||
| 
 | 
 | ||||||
|  | 	width *= scale; | ||||||
|  | 	height *= scale; | ||||||
| 	uint32_t stride = width * 4; | 	uint32_t stride = width * 4; | ||||||
| 	uint32_t size = stride * height; | 	uint32_t size = stride * height; | ||||||
| 
 | 
 | ||||||
|  | @ -63,7 +65,8 @@ static struct buffer *create_buffer(struct window *window, struct buffer *buf, | ||||||
| 	} | 	} | ||||||
| 	void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | 	void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||||
| 	struct wl_shm_pool *pool = wl_shm_create_pool(window->registry->shm, fd, size); | 	struct wl_shm_pool *pool = wl_shm_create_pool(window->registry->shm, fd, size); | ||||||
| 	buf->buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, format); | 	buf->buffer = wl_shm_pool_create_buffer(pool, 0, | ||||||
|  | 			width, height, stride, format); | ||||||
| 	wl_shm_pool_destroy(pool); | 	wl_shm_pool_destroy(pool); | ||||||
| 	close(fd); | 	close(fd); | ||||||
| 	unlink(name); | 	unlink(name); | ||||||
|  | @ -72,10 +75,10 @@ static struct buffer *create_buffer(struct window *window, struct buffer *buf, | ||||||
| 
 | 
 | ||||||
| 	buf->width = width; | 	buf->width = width; | ||||||
| 	buf->height = height; | 	buf->height = height; | ||||||
| 	buf->surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, stride); | 	buf->surface = cairo_image_surface_create_for_data(data, | ||||||
|  | 			CAIRO_FORMAT_ARGB32, width, height, stride); | ||||||
| 	buf->cairo = cairo_create(buf->surface); | 	buf->cairo = cairo_create(buf->surface); | ||||||
| 	buf->pango = pango_cairo_create_context(buf->cairo); | 	buf->pango = pango_cairo_create_context(buf->cairo); | ||||||
| 	pango_cairo_context_set_resolution(buf->pango, 96 * 2); |  | ||||||
| 
 | 
 | ||||||
| 	wl_buffer_add_listener(buf->buffer, &buffer_listener, buf); | 	wl_buffer_add_listener(buf->buffer, &buffer_listener, buf); | ||||||
| 	return buf; | 	return buf; | ||||||
|  | @ -114,7 +117,9 @@ struct buffer *get_next_buffer(struct window *window) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!buffer->buffer) { | 	if (!buffer->buffer) { | ||||||
| 		if (!create_buffer(window, buffer, window->width, window->height, WL_SHM_FORMAT_ARGB8888)) { | 		if (!create_buffer(window, buffer, | ||||||
|  | 					window->width, window->height, window->scale, | ||||||
|  | 					WL_SHM_FORMAT_ARGB8888)) { | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ | ||||||
| 
 | 
 | ||||||
| PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text, bool markup) { | PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text, bool markup) { | ||||||
| 	PangoLayout *layout = pango_cairo_create_layout(cairo); | 	PangoLayout *layout = pango_cairo_create_layout(cairo); | ||||||
|  | 	PangoAttrList *attrs = pango_attr_list_new(); | ||||||
|  | 	pango_attr_list_insert(attrs, pango_attr_scale_new(2)); | ||||||
| 	if (markup) { | 	if (markup) { | ||||||
| 		pango_layout_set_markup(layout, text, -1); | 		pango_layout_set_markup(layout, text, -1); | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -17,6 +19,8 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text | ||||||
| 	PangoFontDescription *desc = pango_font_description_from_string(font); | 	PangoFontDescription *desc = pango_font_description_from_string(font); | ||||||
| 	pango_layout_set_font_description(layout, desc); | 	pango_layout_set_font_description(layout, desc); | ||||||
| 	pango_layout_set_single_paragraph_mode(layout, 1); | 	pango_layout_set_single_paragraph_mode(layout, 1); | ||||||
|  | 	pango_layout_set_attributes(layout, attrs); | ||||||
|  | 	pango_attr_list_unref(attrs); | ||||||
| 	pango_font_description_free(desc); | 	pango_font_description_free(desc); | ||||||
| 	return layout; | 	return layout; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ static void display_handle_mode(void *data, struct wl_output *wl_output, | ||||||
| 		state->flags = flags; | 		state->flags = flags; | ||||||
| 		state->width = width; | 		state->width = width; | ||||||
| 		state->height = height; | 		state->height = height; | ||||||
|  | 		sway_log(L_DEBUG, "Got mode %dx%x:0x%X for output %p", | ||||||
|  | 				width, height, flags, data); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -34,6 +36,7 @@ static void display_handle_done(void *data, struct wl_output *wl_output) { | ||||||
| static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) { | static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) { | ||||||
| 	struct output_state *state = data; | 	struct output_state *state = data; | ||||||
| 	state->scale = factor; | 	state->scale = factor; | ||||||
|  | 	sway_log(L_DEBUG, "Got scale factor %d for output %p", factor, data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct wl_output_listener output_listener = { | static const struct wl_output_listener output_listener = { | ||||||
|  |  | ||||||
|  | @ -93,11 +93,13 @@ void window_make_shell(struct window *window) { | ||||||
| 	wl_shell_surface_set_toplevel(window->shell_surface); | 	wl_shell_surface_set_toplevel(window->shell_surface); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, bool shell_surface) { | struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, | ||||||
|  | 		int32_t scale, bool shell_surface) { | ||||||
| 	struct window *window = malloc(sizeof(struct window)); | 	struct window *window = malloc(sizeof(struct window)); | ||||||
| 	memset(window, 0, sizeof(struct window)); | 	memset(window, 0, sizeof(struct window)); | ||||||
| 	window->width = width; | 	window->width = width; | ||||||
| 	window->height = height; | 	window->height = height; | ||||||
|  | 	window->scale = scale; | ||||||
| 	window->registry = registry; | 	window->registry = registry; | ||||||
| 	window->font = "monospace 10"; | 	window->font = "monospace 10"; | ||||||
| 
 | 
 | ||||||
|  | @ -121,15 +123,18 @@ struct window *window_setup(struct registry *registry, uint32_t width, uint32_t | ||||||
| 			cursor_size = "16"; | 			cursor_size = "16"; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		sway_log(L_DEBUG, "Cursor scale: %d", scale); | ||||||
| 		window->cursor.cursor_theme = wl_cursor_theme_load(cursor_theme, | 		window->cursor.cursor_theme = wl_cursor_theme_load(cursor_theme, | ||||||
| 				atoi(cursor_size), registry->shm); | 				atoi(cursor_size) * scale, registry->shm); | ||||||
| 		window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr"); | 		window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr"); | ||||||
| 		window->cursor.surface = wl_compositor_create_surface(registry->compositor); | 		window->cursor.surface = wl_compositor_create_surface(registry->compositor); | ||||||
| 
 | 
 | ||||||
| 		struct wl_cursor_image *image = window->cursor.cursor->images[0]; | 		struct wl_cursor_image *image = window->cursor.cursor->images[0]; | ||||||
| 		struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image); | 		struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image); | ||||||
| 		wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0); | 		wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0); | ||||||
| 		wl_surface_damage(window->cursor.surface, 0, 0, image->width, image->height); | 		wl_surface_set_buffer_scale(window->cursor.surface, scale); | ||||||
|  | 		wl_surface_damage(window->cursor.surface, 0, 0, | ||||||
|  | 				image->width, image->height); | ||||||
| 		wl_surface_commit(window->cursor.surface); | 		wl_surface_commit(window->cursor.surface); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -159,8 +164,9 @@ int window_render(struct window *window) { | ||||||
| 	window->frame_cb = wl_surface_frame(window->surface); | 	window->frame_cb = wl_surface_frame(window->surface); | ||||||
| 	wl_callback_add_listener(window->frame_cb, &listener, window); | 	wl_callback_add_listener(window->frame_cb, &listener, window); | ||||||
| 
 | 
 | ||||||
| 	wl_surface_damage(window->surface, 0, 0, window->buffer->width, window->buffer->height); |  | ||||||
| 	wl_surface_attach(window->surface, window->buffer->buffer, 0, 0); | 	wl_surface_attach(window->surface, window->buffer->buffer, 0, 0); | ||||||
|  | 	wl_surface_set_buffer_scale(window->surface, window->scale); | ||||||
|  | 	wl_surface_damage(window->surface, 0, 0, window->width, window->height); | ||||||
| 	wl_surface_commit(window->surface); | 	wl_surface_commit(window->surface); | ||||||
| 
 | 
 | ||||||
| 	return 1; | 	return 1; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Drew DeVault
						Drew DeVault