[PATCH weston v4 19/20] clients/clickdot: Add option for using a more complex confine region

Peter Hutterer peter.hutterer at who-t.net
Thu Nov 19 20:28:14 PST 2015


On Tue, Nov 17, 2015 at 06:11:05PM +0800, Jonas Ådahl wrote:
> By passing --complex-confine-region clickdot will draw an area looking
> like a strange H in half transparent gray. This region will act as the
> confine region when pointer confinement is activated (by right clicking).

At this point I'm think it may be better to copy clickdot into a dedicated
confinement/relative/locked test client.

> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
> ---
>  clients/clickdot.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 133 insertions(+)
> 
> diff --git a/clients/clickdot.c b/clients/clickdot.c
> index 130a166..5054a68 100644
> --- a/clients/clickdot.c
> +++ b/clients/clickdot.c
> @@ -43,6 +43,11 @@
>  #include "window.h"
>  #include "shared/helpers.h"
>  
> +#define NUM_COMPLEX_REGION_RECTS 9
> +
> +static int32_t option_complex_confine_region;
> +static int32_t option_help;
> +
>  struct clickdot {
>  	struct display *display;
>  	struct window *window;
> @@ -67,6 +72,10 @@ struct clickdot {
>  	struct task cursor_timeout_task;
>  
>  	bool pointer_confined;
> +
> +	bool complex_confine_region_enabled;
> +	bool complex_confine_region_dirty;
> +	struct rectangle complex_confine_region[NUM_COMPLEX_REGION_RECTS];
>  };
>  
>  static void
> @@ -145,6 +154,92 @@ draw_line(struct clickdot *clickdot, cairo_t *cr,
>  }
>  
>  static void
> +calculate_complex_confine_region(struct clickdot *clickdot)
> +{
> +	struct rectangle allocation;
> +	struct rectangle *rs = clickdot->complex_confine_region;
> +
> +	if (!clickdot->complex_confine_region_dirty)
> +		return;
> +
> +	widget_get_allocation(clickdot->widget, &allocation);
> +
> +	/*
> +	 * The code below constructs a region made up of rectangles that
> +	 * is then used to set up both an illustrative shaded region in the
> +	 * widget and a confine region used when confining the pointer.
> +	 */
> +
> +	rs[0].x = allocation.x + (int)round(allocation.width * 0.05);
> +	rs[0].y = allocation.y + (int)round(allocation.height * 0.15);
> +	rs[0].width = (int)round(allocation.width * 0.35);
> +	rs[0].height = (int)round(allocation.height * 0.7);
> +
> +	rs[1].x = rs[0].x + rs[0].width;
> +	rs[1].y = allocation.y + (int)round(allocation.height * 0.45);
> +	rs[1].width = (int)round(allocation.width * 0.09);
> +	rs[1].height = (int)round(allocation.height * 0.1);
> +
> +	rs[2].x = rs[1].x + rs[1].width;
> +	rs[2].y = allocation.y + (int)round(allocation.height * 0.48);
> +	rs[2].width = (int)round(allocation.width * 0.02);
> +	rs[2].height = (int)round(allocation.height * 0.04);
> +
> +	rs[3].x = rs[2].x + rs[2].width;
> +	rs[3].y = allocation.y + (int)round(allocation.height * 0.45);
> +	rs[3].width = (int)round(allocation.width * 0.09);
> +	rs[3].height = (int)round(allocation.height * 0.1);
> +
> +	rs[4].x = rs[3].x + rs[3].width;
> +	rs[4].y = allocation.y + (int)round(allocation.height * 0.15);
> +	rs[4].width = (int)round(allocation.width * 0.35);
> +	rs[4].height = (int)round(allocation.height * 0.7);
> +
> +	rs[5].x = allocation.x + (int)round(allocation.width * 0.05);
> +	rs[5].y = allocation.y + (int)round(allocation.height * 0.05);
> +	rs[5].width = rs[0].width + rs[1].width + rs[2].width +
> +		rs[3].width + rs[4].width;
> +	rs[5].height = (int)round(allocation.height * 0.10);
> +
> +	rs[6].x = allocation.x + (int)round(allocation.width * 0.1);
> +	rs[6].y = rs[4].y + rs[4].height + (int)round(allocation.height * 0.02);
> +	rs[6].width = (int)round(allocation.width * 0.8);
> +	rs[6].height = (int)round(allocation.height * 0.03);
> +
> +	rs[7].x = allocation.x + (int)round(allocation.width * 0.05);
> +	rs[7].y = rs[6].y + rs[6].height;
> +	rs[7].width = (int)round(allocation.width * 0.9);
> +	rs[7].height = (int)round(allocation.height * 0.03);
> +
> +	rs[8].x = allocation.x + (int)round(allocation.width * 0.1);
> +	rs[8].y = rs[7].y + rs[7].height;
> +	rs[8].width = (int)round(allocation.width * 0.8);
> +	rs[8].height = (int)round(allocation.height * 0.03);

just think of all the trees you'll save by using local x, y, w, h variables
instead of allocation.foo :)

Patch looks good, but as said above this seems better off in a separate
test client.

Cheers,
   Peter

> +
> +	clickdot->complex_confine_region_dirty = false;
> +}
> +
> +static void
> +draw_complex_confine_region_mask(struct clickdot *clickdot, cairo_t *cr)
> +{
> +	int i;
> +
> +	calculate_complex_confine_region(clickdot);
> +
> +	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
> +
> +	for (i = 0; i < NUM_COMPLEX_REGION_RECTS; i++) {
> +		cairo_rectangle(cr,
> +				clickdot->complex_confine_region[i].x,
> +				clickdot->complex_confine_region[i].y,
> +				clickdot->complex_confine_region[i].width,
> +				clickdot->complex_confine_region[i].height);
> +		cairo_set_source_rgba(cr, 0.14, 0.14, 0.14, 0.9);
> +		cairo_fill(cr);
> +	}
> +}
> +
> +static void
>  redraw_handler(struct widget *widget, void *data)
>  {
>  	static const double r = 10.0;
> @@ -167,6 +262,10 @@ redraw_handler(struct widget *widget, void *data)
>  	cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
>  	cairo_fill(cr);
>  
> +	if (clickdot->complex_confine_region_enabled) {
> +		draw_complex_confine_region_mask(clickdot, cr);
> +	}
> +
>  	draw_line(clickdot, cr, &allocation);
>  
>  	cairo_translate(cr, clickdot->dot.x + 0.5, clickdot->dot.y + 0.5);
> @@ -220,6 +319,13 @@ toggle_pointer_confine(struct clickdot *clickdot, struct input *input)
>  {
>  	if (clickdot->pointer_confined) {
>  		window_unconfine_pointer(clickdot->window);
> +	} else if (clickdot->complex_confine_region_enabled) {
> +		calculate_complex_confine_region(clickdot);
> +		window_confine_pointer_to_rectangles(
> +				clickdot->window,
> +				input,
> +				clickdot->complex_confine_region,
> +				NUM_COMPLEX_REGION_RECTS);
>  	} else {
>  		window_confine_pointer_to_widget(clickdot->window,
>  						 clickdot->widget,
> @@ -283,6 +389,9 @@ resize_handler(struct widget *widget,
>  	struct clickdot *clickdot = data;
>  
>  	clickdot->reset = 1;
> +
> +	if (clickdot->complex_confine_region_enabled)
> +		clickdot->complex_confine_region_dirty = true;
>  }
>  
>  static void
> @@ -374,12 +483,31 @@ clickdot_destroy(struct clickdot *clickdot)
>  	free(clickdot);
>  }
>  
> +static const struct weston_option clickdot_options[] = {
> +	{ WESTON_OPTION_BOOLEAN, "complex-confine-region", 0, &option_complex_confine_region },
> +	{ WESTON_OPTION_BOOLEAN, "help", 0, &option_help },
> +};
> +
> +static void
> +print_help(const char *argv0)
> +{
> +	printf("Usage: %s [--complex-confine-region]\n", argv0);
> +}
> +
>  int
>  main(int argc, char *argv[])
>  {
>  	struct display *display;
>  	struct clickdot *clickdot;
>  
> +	if (parse_options(clickdot_options,
> +			  ARRAY_LENGTH(clickdot_options),
> +			  &argc, argv) > 1 ||
> +	    option_help) {
> +		print_help(argv[0]);
> +		return 0;
> +	}
> +
>  	display = display_create(&argc, argv);
>  	if (display == NULL) {
>  		fprintf(stderr, "failed to create display: %m\n");
> @@ -388,6 +516,11 @@ main(int argc, char *argv[])
>  
>  	clickdot = clickdot_create(display);
>  
> +	if (option_complex_confine_region) {
> +		clickdot->complex_confine_region_dirty = true;
> +		clickdot->complex_confine_region_enabled = true;
> +	}
> +
>  	display_run(display);
>  
>  	clickdot_destroy(clickdot);
> -- 
> 2.4.3
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 


More information about the wayland-devel mailing list