diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index abbe4884..f537c418 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -107,10 +107,10 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, /** * Get the box of the layout for the given reference output in layout * coordinates. If `reference` is NULL, the box will be for the extents of the - * entire layout. + * entire layout. If the output isn't in the layout, the box will be empty. */ -struct wlr_box *wlr_output_layout_get_box( - struct wlr_output_layout *layout, struct wlr_output *reference); +void wlr_output_layout_get_box(struct wlr_output_layout *layout, + struct wlr_output *reference, struct wlr_box *dest_box); /** * Add an auto configured output to the layout. This will place the output in a diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index a6b0716c..97a4d1e9 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -237,33 +237,32 @@ static void cursor_warp_unchecked(struct wlr_cursor *cur, * Absolute movement for touch and pen devices will be relative to this box and * pointer movement will be constrained to this box. * - * If none of these are set, returns NULL and absolute movement should be + * If none of these are set, empties the box and absolute movement should be * relative to the extents of the layout. */ -static struct wlr_box *get_mapping(struct wlr_cursor *cur, - struct wlr_input_device *dev) { +static void get_mapping(struct wlr_cursor *cur, + struct wlr_input_device *dev, struct wlr_box *box) { assert(cur->state->layout); struct wlr_cursor_device *c_device = get_cursor_device(cur, dev); if (c_device) { if (c_device->mapped_box) { - return c_device->mapped_box; - } - if (c_device->mapped_output) { - return wlr_output_layout_get_box(cur->state->layout, - c_device->mapped_output); + *box = *c_device->mapped_box; + } else if (c_device->mapped_output) { + wlr_output_layout_get_box(cur->state->layout, + c_device->mapped_output, box); } + return; } if (cur->state->mapped_box) { - return cur->state->mapped_box; + *box = *cur->state->mapped_box; + } else if (cur->state->mapped_output) { + wlr_output_layout_get_box(cur->state->layout, + cur->state->mapped_output, box); + } else { + box->width = box->height = 0; } - if (cur->state->mapped_output) { - return wlr_output_layout_get_box(cur->state->layout, - cur->state->mapped_output); - } - - return NULL; } bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, @@ -271,9 +270,10 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, assert(cur->state->layout); bool result = false; - struct wlr_box *mapping = get_mapping(cur, dev); - if (mapping) { - result = wlr_box_contains_point(mapping, lx, ly); + struct wlr_box mapping; + get_mapping(cur, dev, &mapping); + if (!wlr_box_empty(&mapping)) { + result = wlr_box_contains_point(&mapping, lx, ly); } else { result = wlr_output_layout_contains_point(cur->state->layout, NULL, lx, ly); @@ -288,9 +288,10 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, void wlr_cursor_warp_closest(struct wlr_cursor *cur, struct wlr_input_device *dev, double lx, double ly) { - struct wlr_box *mapping = get_mapping(cur, dev); - if (mapping) { - wlr_box_closest_point(mapping, lx, ly, &lx, &ly); + struct wlr_box mapping; + get_mapping(cur, dev, &mapping); + if (!wlr_box_empty(&mapping)) { + wlr_box_closest_point(&mapping, lx, ly, &lx, &ly); if (isnan(lx) || isnan(ly)) { lx = 0; ly = 0; @@ -308,13 +309,14 @@ void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, double *lx, double *ly) { assert(cur->state->layout); - struct wlr_box *mapping = get_mapping(cur, dev); - if (!mapping) { - mapping = wlr_output_layout_get_box(cur->state->layout, NULL); + struct wlr_box mapping; + get_mapping(cur, dev, &mapping); + if (wlr_box_empty(&mapping)) { + wlr_output_layout_get_box(cur->state->layout, NULL, &mapping); } - *lx = !isnan(x) ? mapping->width * x + mapping->x : cur->x; - *ly = !isnan(y) ? mapping->height * y + mapping->y : cur->y; + *lx = !isnan(x) ? mapping.width * x + mapping.x : cur->x; + *ly = !isnan(y) ? mapping.height * y + mapping.y : cur->y; } void wlr_cursor_warp_absolute(struct wlr_cursor *cur, diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index eb672f06..b102fdae 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -73,15 +73,13 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) { free(layout); } -static struct wlr_box *output_layout_output_get_box( - struct wlr_output_layout_output *l_output) { - l_output->state->_box.x = l_output->x; - l_output->state->_box.y = l_output->y; - int width, height; - wlr_output_effective_resolution(l_output->output, &width, &height); - l_output->state->_box.width = width; - l_output->state->_box.height = height; - return &l_output->state->_box; +static void output_layout_output_get_box( + struct wlr_output_layout_output *l_output, + struct wlr_box *box) { + box->x = l_output->x; + box->y = l_output->y; + wlr_output_effective_resolution(l_output->output, + &box->width, &box->height); } /** @@ -98,15 +96,17 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) { // find the rightmost x coordinate occupied by a manually configured output // in the layout struct wlr_output_layout_output *l_output; + struct wlr_box output_box; + wl_list_for_each(l_output, &layout->outputs, link) { if (l_output->state->auto_configured) { continue; } - struct wlr_box *box = output_layout_output_get_box(l_output); - if (box->x + box->width > max_x) { - max_x = box->x + box->width; - max_x_y = box->y; + output_layout_output_get_box(l_output, &output_box); + if (output_box.x + output_box.width > max_x) { + max_x = output_box.x + output_box.width; + max_x_y = output_box.y; } } @@ -120,10 +120,10 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) { if (!l_output->state->auto_configured) { continue; } - struct wlr_box *box = output_layout_output_get_box(l_output); + output_layout_output_get_box(l_output, &output_box); l_output->x = max_x; l_output->y = max_x_y; - max_x += box->width; + max_x += output_box.width; } wlr_signal_emit_safe(&layout->events.change, layout); @@ -242,8 +242,9 @@ bool wlr_output_layout_contains_point(struct wlr_output_layout *layout, if (reference) { struct wlr_output_layout_output *l_output = wlr_output_layout_get(layout, reference); - struct wlr_box *box = output_layout_output_get_box(l_output); - return wlr_box_contains_point(box, lx, ly); + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + return wlr_box_contains_point(&output_box, lx, ly); } else { return !!wlr_output_layout_output_at(layout, lx, ly); } @@ -256,9 +257,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, if (reference == NULL) { struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { - struct wlr_box *output_box = - output_layout_output_get_box(l_output); - if (wlr_box_intersection(&out_box, output_box, target_lbox)) { + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + if (wlr_box_intersection(&out_box, &output_box, target_lbox)) { return true; } } @@ -270,8 +271,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, return false; } - struct wlr_box *output_box = output_layout_output_get_box(l_output); - return wlr_box_intersection(&out_box, output_box, target_lbox); + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + return wlr_box_intersection(&out_box, &output_box, target_lbox); } } @@ -279,8 +281,9 @@ struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, double lx, double ly) { struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { - struct wlr_box *box = output_layout_output_get_box(l_output); - if (wlr_box_contains_point(box, lx, ly)) { + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + if (wlr_box_contains_point(&output_box, lx, ly)) { return l_output->output; } } @@ -342,8 +345,9 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, } double output_x, output_y, output_distance; - struct wlr_box *box = output_layout_output_get_box(l_output); - wlr_box_closest_point(box, lx, ly, &output_x, &output_y); + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + wlr_box_closest_point(&output_box, lx, ly, &output_x, &output_y); // calculate squared distance suitable for comparison output_distance = @@ -368,17 +372,17 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, } } -struct wlr_box *wlr_output_layout_get_box( - struct wlr_output_layout *layout, struct wlr_output *reference) { +void wlr_output_layout_get_box(struct wlr_output_layout *layout, + struct wlr_output *reference, struct wlr_box *dest_box) { struct wlr_output_layout_output *l_output; if (reference) { // output extents l_output = wlr_output_layout_get(layout, reference); if (l_output) { - return output_layout_output_get_box(l_output); + output_layout_output_get_box(l_output, dest_box); } else { - return NULL; + dest_box->width = dest_box->height = 0; } } else { // layout extents @@ -387,31 +391,28 @@ struct wlr_box *wlr_output_layout_get_box( min_x = min_y = INT_MAX; max_x = max_y = INT_MIN; wl_list_for_each(l_output, &layout->outputs, link) { - struct wlr_box *box = output_layout_output_get_box(l_output); - if (box->x < min_x) { - min_x = box->x; + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + if (output_box.x < min_x) { + min_x = output_box.x; } - if (box->y < min_y) { - min_y = box->y; + if (output_box.y < min_y) { + min_y = output_box.y; } - if (box->x + box->width > max_x) { - max_x = box->x + box->width; + if (output_box.x + output_box.width > max_x) { + max_x = output_box.x + output_box.width; } - if (box->y + box->height > max_y) { - max_y = box->y + box->height; + if (output_box.y + output_box.height > max_y) { + max_y = output_box.y + output_box.height; } } } - layout->state->_box.x = min_x; - layout->state->_box.y = min_y; - layout->state->_box.width = max_x - min_x; - layout->state->_box.height = max_y - min_y; - - return &layout->state->_box; + dest_box->x = min_x; + dest_box->y = min_y; + dest_box->width = max_x - min_x; + dest_box->height = max_y - min_y; } - - // not reached } void wlr_output_layout_add_auto(struct wlr_output_layout *layout, @@ -442,9 +443,10 @@ struct wlr_output *wlr_output_layout_get_center_output( return NULL; } - struct wlr_box *extents = wlr_output_layout_get_box(layout, NULL); - double center_x = extents->width / 2. + extents->x; - double center_y = extents->height / 2. + extents->y; + struct wlr_box extents; + wlr_output_layout_get_box(layout, NULL, &extents); + double center_x = extents.width / 2. + extents.x; + double center_y = extents.height / 2. + extents.y; double dest_x = 0, dest_y = 0; wlr_output_layout_closest_point(layout, NULL, center_x, center_y, @@ -464,7 +466,8 @@ static struct wlr_output *wlr_output_layout_output_in_direction( enum distance_selection_method distance_method) { assert(reference); - struct wlr_box *ref_box = wlr_output_layout_get_box(layout, reference); + struct wlr_box ref_box; + wlr_output_layout_get_box(layout, reference, &ref_box); double min_distance = (distance_method == NEAREST) ? DBL_MAX : DBL_MIN; struct wlr_output *closest_output = NULL; @@ -473,21 +476,23 @@ static struct wlr_output *wlr_output_layout_output_in_direction( if (reference != NULL && reference == l_output->output) { continue; } - struct wlr_box *box = output_layout_output_get_box(l_output); + + struct wlr_box box; + output_layout_output_get_box(l_output, &box); bool match = false; // test to make sure this output is in the given direction if (direction & WLR_DIRECTION_LEFT) { - match = box->x + box->width <= ref_box->x || match; + match = box.x + box.width <= ref_box.x || match; } if (direction & WLR_DIRECTION_RIGHT) { - match = box->x >= ref_box->x + ref_box->width || match; + match = box.x >= ref_box.x + ref_box.width || match; } if (direction & WLR_DIRECTION_UP) { - match = box->y + box->height <= ref_box->y || match; + match = box.y + box.height <= ref_box.y || match; } if (direction & WLR_DIRECTION_DOWN) { - match = box->y >= ref_box->y + ref_box->height || match; + match = box.y >= ref_box.y + ref_box.height || match; } if (!match) { continue;