int main(void) { assert(chck_equalld(LDBL_MIN, LDBL_MIN + LDBL_MIN, LDBL_DIG / LDBL_EPSILON)); assert(!chck_equalld(LDBL_MIN, LDBL_MIN + LDBL_MIN, 1.0l)); assert(chck_equal(DBL_MIN, DBL_MIN + DBL_MIN, DBL_DIG / DBL_EPSILON)); assert(!chck_equal(DBL_MIN, DBL_MIN + DBL_MIN, 1.0)); assert(chck_equalf(FLT_MIN, FLT_MIN + FLT_MIN, FLT_DIG / FLT_EPSILON)); assert(!chck_equalf(FLT_MIN, FLT_MIN + FLT_MIN, 1.0f)); for (uint32_t i = 0xFFFF; i < 0xFFFFFF; ++i) { assert(chck_minu32(i, i - 20) == i - 20); assert(chck_minu32(i, i + 20) == i); assert(chck_maxu32(i, i - 20) == i); assert(chck_maxu32(i, i + 20) == i + 20); assert(chck_clampu32(i, i - 20, i + 20) == i); assert(chck_clampu32(i, i - 40, i - 20) == i - 20); assert(chck_clampu32(i, i + 20, i + 40) == i + 20); assert(chck_modn32(i, i * 2 + 20) == (int32_t)i); assert(chck_modn32(i, i * 2 - 20) == -(int32_t)(i - 20)); assert((int32_t)chck_modnf(i, i * 2 + 20) == (int32_t)i); assert((int32_t)chck_modnf(i, i * 2 - 20) == -(int32_t)(i - 20)); assert((int32_t)chck_modn(i, i * 2 + 20) == (int32_t)i); assert((int32_t)chck_modn(i, i * 2 - 20) == -(int32_t)(i - 20)); } assert(chck_max32(-20, 20) == 20); assert(chck_max32(40, 20) == 40); assert(chck_min32(-20, 20) == -20); assert(chck_min32(-40, 20) == -40); assert(chck_clamp32(40, -20, 60) == 40); assert(chck_clamp32(40, 50, 60) == 50); assert(chck_clamp32(40, -20, 20) == 20); assert((int32_t)chck_modn(20 - 340, 360) == 40); assert((int32_t)chck_modn(340 - 20, 360) == -40); assert((int32_t)chck_modnf(20 - 340, 360) == 40); assert((int32_t)chck_modnf(340 - 20, 360) == -40); assert(chck_npotu8(3) == 4); assert(chck_npotu8(1) == 1); assert(chck_npotu16(25) == 32); assert(chck_npotu16(48) == 64); assert(chck_npotu32(0) == 1); assert(chck_npotu32(4097) == 8192); assert(chck_npotsz(1025) == 2048); return EXIT_SUCCESS; }
void wlc_view_ack_surface_attach(struct wlc_view *view, struct wlc_surface *surface) { assert(view && surface); if (is_x11_view(view)) { surface->pending.opaque.extents = (pixman_box32_t){ 0, 0, surface->size.w, surface->size.h }; view->surface_pending.visible = (struct wlc_geometry){ wlc_point_zero, surface->size }; } const bool resizing = (view->pending.state & WLC_BIT_RESIZING || view->commit.state & WLC_BIT_RESIZING); if (!resizing && !wlc_geometry_equals(&view->surface_pending.visible, &view->surface_commit.visible)) { struct wlc_geometry g = (struct wlc_geometry){ view->pending.geometry.origin, view->surface_pending.visible.size }; wlc_view_request_geometry(view, &g); } view->surface_commit = view->surface_pending; } void wlc_view_get_bounds(struct wlc_view *view, struct wlc_geometry *out_bounds, struct wlc_geometry *out_visible) { assert(view && out_bounds && out_bounds != out_visible); memcpy(out_bounds, &view->commit.geometry, sizeof(struct wlc_geometry)); struct wlc_surface *surface; if (!(surface = convert_from_wlc_resource(view->surface, "surface"))) return; if (view->xdg_surface && !wlc_size_equals(&view->surface_commit.visible.size, &wlc_size_zero)) { // xdg-surface client that draws drop shadows or other stuff. struct wlc_geometry v = view->surface_commit.visible; v.origin.x = chck_clamp32(v.origin.x, 0, surface->size.w); v.origin.y = chck_clamp32(v.origin.y, 0, surface->size.h); v.size.w = chck_clampu32(surface->size.w - v.size.w, 0, surface->size.w); v.size.h = chck_clampu32(surface->size.h - v.size.h, 0, surface->size.h); assert(surface->size.w > 0 && surface->size.h > 0); const float wa = (float)out_bounds->size.w / surface->size.w, ha = (float)out_bounds->size.h / surface->size.h; out_bounds->origin.x -= v.origin.x * wa; out_bounds->origin.y -= v.origin.y * ha; out_bounds->size.w += v.size.w * wa; out_bounds->size.h += v.size.h * ha; } // Make sure bounds is never 0x0 w/h wlc_size_max(&out_bounds->size, &(struct wlc_size){ 1, 1 }, &out_bounds->size); if (!out_visible) return; // Actual visible area of the view // The idea is to draw black borders to the bounds area, while centering the visible area. if ((is_x11_view(view) || view->shell_surface) && !wlc_size_equals(&surface->size, &out_bounds->size)) { out_visible->size = surface->size; // Scale visible area retaining aspect assert(surface->size.w > 0 && surface->size.h > 0); const float ba = (float)out_bounds->size.w / (float)out_bounds->size.h; const float sa = (float)surface->size.w / (float)surface->size.h; if (ba < sa) { out_visible->size.w *= (float)out_bounds->size.w / surface->size.w; out_visible->size.h *= (float)out_bounds->size.w / surface->size.w; } else { out_visible->size.w *= (float)out_bounds->size.h / surface->size.h; out_visible->size.h *= (float)out_bounds->size.h / surface->size.h; } // Center visible area out_visible->origin.x = out_bounds->origin.x + out_bounds->size.w * 0.5 - out_visible->size.w * 0.5; out_visible->origin.y = out_bounds->origin.y + out_bounds->size.h * 0.5 - out_visible->size.h * 0.5; // Make sure visible is never 0x0 w/h out_visible->size.w = chck_maxu32(out_visible->size.w, 1); out_visible->size.h = chck_maxu32(out_visible->size.h, 1); } else { // For non wl_shell or x11 surfaces, just memcpy memcpy(out_visible, out_bounds, sizeof(struct wlc_geometry)); } }