diff options
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | src/config.c | 16 | ||||
-rw-r--r-- | src/entry.c | 22 | ||||
-rw-r--r-- | src/entry.h | 2 | ||||
-rw-r--r-- | src/main.c | 129 | ||||
-rw-r--r-- | src/scale.c | 17 | ||||
-rw-r--r-- | src/scale.h | 9 | ||||
-rw-r--r-- | src/tofi.h | 3 | ||||
-rw-r--r-- | src/wp-fractional-scale-v1.c | 73 | ||||
-rw-r--r-- | src/wp-fractional-scale-v1.h | 264 |
10 files changed, 509 insertions, 28 deletions
diff --git a/meson.build b/meson.build index b6ffb97..8eb61a6 100644 --- a/meson.build +++ b/meson.build @@ -107,11 +107,13 @@ common_sources = files( 'src/lock.c', 'src/log.c', 'src/mkdirp.c', + 'src/scale.c', 'src/shm.c', 'src/string_vec.c', 'src/surface.c', 'src/unicode.c', 'src/wlr-layer-shell-unstable-v1.c', + 'src/wp-fractional-scale-v1.c', 'src/xmalloc.c', ) diff --git a/src/config.c b/src/config.c index 31db79d..d831267 100644 --- a/src/config.c +++ b/src/config.c @@ -10,6 +10,7 @@ #include "config.h" #include "log.h" #include "nelem.h" +#include "scale.h" #include "unicode.h" #include "xmalloc.h" @@ -762,17 +763,22 @@ uint32_t fixup_percentage(uint32_t value, uint32_t base, bool is_percent) void config_fixup_values(struct tofi *tofi) { - uint32_t scale = tofi->window.scale; uint32_t base_width = tofi->output_width; uint32_t base_height = tofi->output_height; + uint32_t scale; + if (tofi->window.fractional_scale != 0) { + scale = tofi->window.fractional_scale; + } else { + scale = tofi->window.scale * 120; + } /* * If we're going to be scaling these values in Cairo, * we need to apply the inverse scale here. */ if (tofi->use_scale) { - base_width /= scale; - base_height /= scale; + base_width = scale_apply_inverse(base_width, scale); + base_height = scale_apply_inverse(base_height, scale); } tofi->window.margin_top = fixup_percentage( @@ -823,10 +829,10 @@ void config_fixup_values(struct tofi *tofi) tofi->output_height, tofi->window.height_is_percent); if (tofi->window.width_is_percent || !tofi->use_scale) { - tofi->window.width /= scale; + tofi->window.width = scale_apply_inverse(tofi->window.width, scale); } if (tofi->window.height_is_percent || !tofi->use_scale) { - tofi->window.height /= scale; + tofi->window.height = scale_apply_inverse(tofi->window.height, scale); } /* Don't attempt percentage handling if exclusive_zone is set to -1. */ diff --git a/src/entry.c b/src/entry.c index 31a7d6b..23e8575 100644 --- a/src/entry.c +++ b/src/entry.c @@ -4,6 +4,7 @@ #include "entry.h" #include "log.h" #include "nelem.h" +#include "scale.h" #undef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -43,8 +44,9 @@ static void apply_text_theme_fallback(struct text_theme *theme, const struct tex } } -void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, uint32_t height, uint32_t scale) +void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, uint32_t height, uint32_t fractional_scale_numerator) { + double scale = fractional_scale_numerator / 120.; /* * Create the cairo surfaces and contexts we'll be using. * @@ -54,6 +56,10 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u * (width * height * (sizeof(uint32_t) == 4) * 2) bytes, * to allow for double buffering. */ + log_debug("Creating %u x %u Cairo surface with scale factor %.3lf.\n", + width, + height, + fractional_scale_numerator / 120.); cairo_surface_t *surface = cairo_image_surface_create_for_data( buffer, CAIRO_FORMAT_ARGB32, @@ -78,8 +84,8 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u entry->cairo[1].cr = cairo_create(entry->cairo[1].surface); /* If we're scaling with Cairo, remember to account for that here. */ - width /= scale; - height /= scale; + width = scale_apply_inverse(width, fractional_scale_numerator); + height = scale_apply_inverse(height, fractional_scale_numerator); log_debug("Drawing window.\n"); /* Draw the background */ @@ -107,8 +113,14 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u cairo_stroke_preserve(cr); /* Clear the overdrawn bits outside of the rounded corners */ - cairo_rectangle(cr, 0, 0, width, height); - cairo_set_source_rgba(cr, 0, 0, 0, 0.5); + /* + * N.B. the +1's shouldn't be required, but certain fractional scale + * factors can otherwise cause 1-pixel artifacts on the edges + * (presumably because Cairo is performing rounding differently to us + * at some point). + */ + cairo_rectangle(cr, 0, 0, width + 1, height + 1); + cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_save(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); diff --git a/src/entry.h b/src/entry.h index 882204c..35d2302 100644 --- a/src/entry.h +++ b/src/entry.h @@ -134,7 +134,7 @@ struct entry { struct text_theme selection_theme; }; -void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, uint32_t height, uint32_t scale); +void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, uint32_t height, uint32_t fractional_scale_numerator); void entry_destroy(struct entry *entry); void entry_update(struct entry *entry); @@ -22,6 +22,7 @@ #include "log.h" #include "nelem.h" #include "lock.h" +#include "scale.h" #include "shm.h" #include "string_vec.h" #include "string_vec.h" @@ -104,8 +105,13 @@ static void zwlr_layer_surface_configure( * We want actual pixel width / height, so we have to scale the * values provided by Wayland. */ - tofi->window.surface.width = width * tofi->window.scale; - tofi->window.surface.height = height * tofi->window.scale; + if (tofi->window.fractional_scale != 0) { + tofi->window.surface.width = scale_apply(width, tofi->window.fractional_scale); + tofi->window.surface.height = scale_apply(height, tofi->window.fractional_scale); + } else { + tofi->window.surface.width = width * tofi->window.scale; + tofi->window.surface.height = height * tofi->window.scale; + } zwlr_layer_surface_v1_ack_configure( tofi->window.zwlr_layer_surface, @@ -701,6 +707,13 @@ static void registry_global( &wp_viewporter_interface, 1); log_debug("Bound to wp_viewporter %u.\n", name); + } else if (!strcmp(interface, wp_fractional_scale_manager_v1_interface.name)) { + tofi->wp_fractional_scale_manager = wl_registry_bind( + wl_registry, + name, + &wp_fractional_scale_manager_v1_interface, + 1); + log_debug("Bound to wp_fractional_scale_manager_v1 %u.\n", name); } } @@ -765,6 +778,19 @@ static const struct zwlr_layer_surface_v1_listener dummy_layer_surface_listener .closed = dummy_layer_surface_close }; +static void dummy_fractional_scale_preferred_scale( + void *data, + struct wp_fractional_scale_v1 *wp_fractional_scale, + uint32_t scale) +{ + struct tofi *tofi = data; + tofi->window.fractional_scale = scale; +} + +static const struct wp_fractional_scale_v1_listener dummy_fractional_scale_listener = { + .preferred_scale = dummy_fractional_scale_preferred_scale +}; + static void dummy_surface_enter( void *data, struct wl_surface *wl_surface, @@ -1228,20 +1254,28 @@ int main(int argc, char *argv[]) log_unindent(); log_debug("Second roundtrip done.\n"); - /* If there's more than one output, we need to select one. */ - if (wl_list_length(&tofi.output_list) > 1) { + { /* - * Determine the default output + * Determine the output we're going to appear on, and get its + * fractional scale if supported. * * This seems like an ugly solution, but as far as I know * there's no way to determine the default output other than to * call get_layer_surface with NULL as the output and see which * output our surface turns up on. * + * Additionally, determining fractional scale factors can + * currently only be done by attaching a wp_fractional_scale to + * a surface and displaying it. + * * Here we set up a single pixel surface, perform the required * two roundtrips, then tear it down. tofi.default_output - * should then contain the output our surface was assigned to. + * should then contain the output our surface was assigned to, + * and tofi.window.fractional_scale should have the scale + * factor. */ + log_debug("Determining output.\n"); + log_indent(); struct surface surface = { .width = 1, .height = 1 @@ -1253,11 +1287,38 @@ int main(int argc, char *argv[]) &dummy_surface_listener, &tofi); + struct wp_fractional_scale_v1 *wp_fractional_scale = NULL; + if (tofi.wp_fractional_scale_manager != NULL) { + wp_fractional_scale = + wp_fractional_scale_manager_v1_get_fractional_scale( + tofi.wp_fractional_scale_manager, + surface.wl_surface); + wp_fractional_scale_v1_add_listener( + wp_fractional_scale, + &dummy_fractional_scale_listener, + &tofi); + } + + /* + * If we have a desired output, make sure we appear on it so we + * can determine the correct fractional scale. + */ + struct wl_output *wl_output = NULL; + if (tofi.target_output_name[0] != '\0') { + struct output_list_element *el; + wl_list_for_each(el, &tofi.output_list, link) { + if (!strcmp(tofi.target_output_name, el->name)) { + wl_output = el->wl_output; + break; + } + } + } + struct zwlr_layer_surface_v1 *zwlr_layer_surface = zwlr_layer_shell_v1_get_layer_surface( tofi.zwlr_layer_shell, surface.wl_surface, - NULL, + wl_output, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "dummy"); /* @@ -1277,12 +1338,27 @@ int main(int argc, char *argv[]) 1, 1); wl_surface_commit(surface.wl_surface); + log_debug("First dummy roundtrip start.\n"); + log_indent(); wl_display_roundtrip(tofi.wl_display); + log_unindent(); + log_debug("First dummy roundtrip done.\n"); + log_debug("Initialising dummy surface.\n"); + log_indent(); surface_init(&surface, tofi.wl_shm); surface_draw(&surface); + log_unindent(); + log_debug("Dummy surface initialised.\n"); + log_debug("Second dummy roundtrip start.\n"); + log_indent(); wl_display_roundtrip(tofi.wl_display); + log_unindent(); + log_debug("Second dummy roundtrip done.\n"); surface_destroy(&surface); zwlr_layer_surface_v1_destroy(zwlr_layer_surface); + if (wp_fractional_scale != NULL) { + wp_fractional_scale_v1_destroy(wp_fractional_scale); + } wl_surface_destroy(surface.wl_surface); /* @@ -1324,13 +1400,11 @@ int main(int argc, char *argv[]) free(el); } } - } - { + /* * The only output left should either be the one we want, or * the first that was advertised. */ - struct output_list_element *el; el = wl_container_of(tofi.output_list.next, el, link); /* @@ -1351,6 +1425,7 @@ int main(int argc, char *argv[]) } tofi.window.scale = el->scale; tofi.window.transform = el->transform; + log_unindent(); log_debug("Selected output %s.\n", el->name); } @@ -1454,6 +1529,7 @@ int main(int argc, char *argv[]) */ log_warning("Width or height set to 0, disabling fractional scaling support.\n"); log_warning("If your compositor supports the fractional scale protocol, percentages are preferred.\n"); + tofi.window.fractional_scale = 0; wl_surface_set_buffer_scale( tofi.window.surface.wl_surface, tofi.window.scale); @@ -1564,12 +1640,28 @@ int main(int argc, char *argv[]) */ log_debug("Initialising renderer.\n"); log_indent(); - entry_init( - &tofi.window.entry, - tofi.window.surface.shm_pool_data, - tofi.window.surface.width, - tofi.window.surface.height, - tofi.use_scale ? tofi.window.scale : 1); + { + /* + * No matter how we're scaling (with fractions, integers or not + * at all), we pass a fractional scale factor (the numerator of + * a fraction with denominator 120) to our setup function for + * ease. + */ + uint32_t scale = 120; + if (tofi.use_scale) { + if (tofi.window.fractional_scale != 0) { + scale = tofi.window.fractional_scale; + } else { + scale = tofi.window.scale * 120; + } + } + entry_init( + &tofi.window.entry, + tofi.window.surface.shm_pool_data, + tofi.window.surface.width, + tofi.window.surface.height, + scale); + } log_unindent(); log_debug("Renderer initialised.\n"); @@ -1765,8 +1857,11 @@ int main(int argc, char *argv[]) } } wl_shm_destroy(tofi.wl_shm); - zwlr_layer_shell_v1_destroy(tofi.zwlr_layer_shell); + if (tofi.wp_fractional_scale_manager != NULL) { + wp_fractional_scale_manager_v1_destroy(tofi.wp_fractional_scale_manager); + } wp_viewporter_destroy(tofi.wp_viewporter); + zwlr_layer_shell_v1_destroy(tofi.zwlr_layer_shell); xkb_state_unref(tofi.xkb_state); xkb_keymap_unref(tofi.xkb_keymap); xkb_context_unref(tofi.xkb_context); diff --git a/src/scale.c b/src/scale.c new file mode 100644 index 0000000..b2b6fad --- /dev/null +++ b/src/scale.c @@ -0,0 +1,17 @@ +#include <math.h> +#include <stdint.h> + +/* + * In order to correctly scale by fractions of 120 (used by + * wp_fractional_scale_v1), we need to bias the result before rounding. + */ + +uint32_t scale_apply(uint32_t base, uint32_t scale) +{ + return round(base * (scale / 120.) + 1e-6); +} + +uint32_t scale_apply_inverse(uint32_t base, uint32_t scale) +{ + return round(base * (120. / scale) + 1e-6); +} diff --git a/src/scale.h b/src/scale.h new file mode 100644 index 0000000..47cb809 --- /dev/null +++ b/src/scale.h @@ -0,0 +1,9 @@ +#ifndef SCALE_H +#define SCALE_H + +#include <stdint.h> + +uint32_t scale_apply(uint32_t base, uint32_t scale); +uint32_t scale_apply_inverse(uint32_t base, uint32_t scale); + +#endif /* SCALE_H */ @@ -10,6 +10,7 @@ #include "entry.h" #include "surface.h" #include "wlr-layer-shell-unstable-v1.h" +#include "wp-fractional-scale-v1.h" #define MAX_OUTPUT_NAME_LEN 256 #define MAX_TERMINAL_NAME_LEN 256 @@ -35,6 +36,7 @@ struct tofi { struct wl_data_device_manager *wl_data_device_manager; struct wl_data_device *wl_data_device; struct wp_viewporter *wp_viewporter; + struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager; struct zwlr_layer_shell_v1 *zwlr_layer_shell; struct wl_list output_list; struct output_list_element *default_output; @@ -63,6 +65,7 @@ struct tofi { uint32_t width; uint32_t height; uint32_t scale; + uint32_t fractional_scale; int32_t transform; int32_t exclusive_zone; int32_t margin_top; diff --git a/src/wp-fractional-scale-v1.c b/src/wp-fractional-scale-v1.c new file mode 100644 index 0000000..0eb72f8 --- /dev/null +++ b/src/wp-fractional-scale-v1.c @@ -0,0 +1,73 @@ +/* Generated by wayland-scanner 1.21.0 */ + +/* + * Copyright © 2022 Kenny Levinsen + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdlib.h> +#include <stdint.h> +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface wp_fractional_scale_v1_interface; + +static const struct wl_interface *fractional_scale_v1_types[] = { + NULL, + &wp_fractional_scale_v1_interface, + &wl_surface_interface, +}; + +static const struct wl_message wp_fractional_scale_manager_v1_requests[] = { + { "destroy", "", fractional_scale_v1_types + 0 }, + { "get_fractional_scale", "no", fractional_scale_v1_types + 1 }, +}; + +WL_PRIVATE const struct wl_interface wp_fractional_scale_manager_v1_interface = { + "wp_fractional_scale_manager_v1", 1, + 2, wp_fractional_scale_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message wp_fractional_scale_v1_requests[] = { + { "destroy", "", fractional_scale_v1_types + 0 }, +}; + +static const struct wl_message wp_fractional_scale_v1_events[] = { + { "preferred_scale", "u", fractional_scale_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface wp_fractional_scale_v1_interface = { + "wp_fractional_scale_v1", 1, + 1, wp_fractional_scale_v1_requests, + 1, wp_fractional_scale_v1_events, +}; + diff --git a/src/wp-fractional-scale-v1.h b/src/wp-fractional-scale-v1.h new file mode 100644 index 0000000..f49178e --- /dev/null +++ b/src/wp-fractional-scale-v1.h @@ -0,0 +1,264 @@ +/* Generated by wayland-scanner 1.21.0 */ + +#ifndef FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H +#define FRACTIONAL_SCALE_V1_CLIENT_PROTOCOL_H + +#include <stdint.h> +#include <stddef.h> +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_fractional_scale_v1 The fractional_scale_v1 protocol + * Protocol for requesting fractional surface scales + * + * @section page_desc_fractional_scale_v1 Description + * + * This protocol allows a compositor to suggest for surfaces to render at + * fractional scales. + * + * A client can submit scaled content by utilizing wp_viewport. This is done by + * creating a wp_viewport object for the surface and setting the destination + * rectangle to the surface size before the scale factor is applied. + * + * The buffer size is calculated by multiplying the surface size by the + * intended scale. + * + * The wl_surface buffer scale should remain set to 1. + * + * If a surface has a surface-local size of 100 px by 50 px and wishes to + * submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should + * be used and the wp_viewport destination rectangle should be 100 px by 50 px. + * + * For toplevel surfaces, the size is rounded halfway away from zero. The + * rounding algorithm for subsurface position and size is not defined. + * + * @section page_ifaces_fractional_scale_v1 Interfaces + * - @subpage page_iface_wp_fractional_scale_manager_v1 - fractional surface scale information + * - @subpage page_iface_wp_fractional_scale_v1 - fractional scale interface to a wl_surface + * @section page_copyright_fractional_scale_v1 Copyright + * <pre> + * + * Copyright © 2022 Kenny Levinsen + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * </pre> + */ +struct wl_surface; +struct wp_fractional_scale_manager_v1; +struct wp_fractional_scale_v1; + +#ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE +#define WP_FRACTIONAL_SCALE_MANAGER_V1_INTERFACE +/** + * @page page_iface_wp_fractional_scale_manager_v1 wp_fractional_scale_manager_v1 + * @section page_iface_wp_fractional_scale_manager_v1_desc Description + * + * A global interface for requesting surfaces to use fractional scales. + * @section page_iface_wp_fractional_scale_manager_v1_api API + * See @ref iface_wp_fractional_scale_manager_v1. + */ +/** + * @defgroup iface_wp_fractional_scale_manager_v1 The wp_fractional_scale_manager_v1 interface + * + * A global interface for requesting surfaces to use fractional scales. + */ +extern const struct wl_interface wp_fractional_scale_manager_v1_interface; +#endif +#ifndef WP_FRACTIONAL_SCALE_V1_INTERFACE +#define WP_FRACTIONAL_SCALE_V1_INTERFACE +/** + * @page page_iface_wp_fractional_scale_v1 wp_fractional_scale_v1 + * @section page_iface_wp_fractional_scale_v1_desc Description + * + * An additional interface to a wl_surface object which allows the compositor + * to inform the client of the preferred scale. + * @section page_iface_wp_fractional_scale_v1_api API + * See @ref iface_wp_fractional_scale_v1. + */ +/** + * @defgroup iface_wp_fractional_scale_v1 The wp_fractional_scale_v1 interface + * + * An additional interface to a wl_surface object which allows the compositor + * to inform the client of the preferred scale. + */ +extern const struct wl_interface wp_fractional_scale_v1_interface; +#endif + +#ifndef WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM +#define WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM +enum wp_fractional_scale_manager_v1_error { + /** + * the surface already has a fractional_scale object associated + */ + WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS = 0, +}; +#endif /* WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_ENUM */ + +#define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY 0 +#define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE 1 + + +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + */ +#define WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + */ +#define WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE_SINCE_VERSION 1 + +/** @ingroup iface_wp_fractional_scale_manager_v1 */ +static inline void +wp_fractional_scale_manager_v1_set_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1, user_data); +} + +/** @ingroup iface_wp_fractional_scale_manager_v1 */ +static inline void * +wp_fractional_scale_manager_v1_get_user_data(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_manager_v1); +} + +static inline uint32_t +wp_fractional_scale_manager_v1_get_version(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1); +} + +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + * + * Informs the server that the client will not be using this protocol + * object anymore. This does not affect any other objects, + * wp_fractional_scale_v1 objects included. + */ +static inline void +wp_fractional_scale_manager_v1_destroy(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_manager_v1, + WP_FRACTIONAL_SCALE_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_wp_fractional_scale_manager_v1 + * + * Create an add-on object for the the wl_surface to let the compositor + * request fractional scales. If the given wl_surface already has a + * wp_fractional_scale_v1 object associated, the fractional_scale_exists + * protocol error is raised. + */ +static inline struct wp_fractional_scale_v1 * +wp_fractional_scale_manager_v1_get_fractional_scale(struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_v1, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_manager_v1, + WP_FRACTIONAL_SCALE_MANAGER_V1_GET_FRACTIONAL_SCALE, &wp_fractional_scale_v1_interface, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_manager_v1), 0, NULL, surface); + + return (struct wp_fractional_scale_v1 *) id; +} + +/** + * @ingroup iface_wp_fractional_scale_v1 + * @struct wp_fractional_scale_v1_listener + */ +struct wp_fractional_scale_v1_listener { + /** + * notify of new preferred scale + * + * Notification of a new preferred scale for this surface that + * the compositor suggests that the client should use. + * + * The sent scale is the numerator of a fraction with a denominator + * of 120. + * @param scale the new preferred scale + */ + void (*preferred_scale)(void *data, + struct wp_fractional_scale_v1 *wp_fractional_scale_v1, + uint32_t scale); +}; + +/** + * @ingroup iface_wp_fractional_scale_v1 + */ +static inline int +wp_fractional_scale_v1_add_listener(struct wp_fractional_scale_v1 *wp_fractional_scale_v1, + const struct wp_fractional_scale_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wp_fractional_scale_v1, + (void (**)(void)) listener, data); +} + +#define WP_FRACTIONAL_SCALE_V1_DESTROY 0 + +/** + * @ingroup iface_wp_fractional_scale_v1 + */ +#define WP_FRACTIONAL_SCALE_V1_PREFERRED_SCALE_SINCE_VERSION 1 + +/** + * @ingroup iface_wp_fractional_scale_v1 + */ +#define WP_FRACTIONAL_SCALE_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_wp_fractional_scale_v1 */ +static inline void +wp_fractional_scale_v1_set_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wp_fractional_scale_v1, user_data); +} + +/** @ingroup iface_wp_fractional_scale_v1 */ +static inline void * +wp_fractional_scale_v1_get_user_data(struct wp_fractional_scale_v1 *wp_fractional_scale_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wp_fractional_scale_v1); +} + +static inline uint32_t +wp_fractional_scale_v1_get_version(struct wp_fractional_scale_v1 *wp_fractional_scale_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1); +} + +/** + * @ingroup iface_wp_fractional_scale_v1 + * + * Destroy the fractional scale object. When this object is destroyed, + * preferred_scale events will no longer be sent. + */ +static inline void +wp_fractional_scale_v1_destroy(struct wp_fractional_scale_v1 *wp_fractional_scale_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) wp_fractional_scale_v1, + WP_FRACTIONAL_SCALE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) wp_fractional_scale_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif |