layer: Add Reply audo-delete helper for XCB replies
This commit is contained in:
parent
89456dd976
commit
ece20d0120
2 changed files with 23 additions and 35 deletions
|
|
@ -280,11 +280,11 @@ namespace GamescopeWSILayer {
|
|||
if ((res = pDispatch->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities)) != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
VkExtent2D currentExtent = {};
|
||||
if ((res = getCurrentExtent(gamescopeSurface->connection, gamescopeSurface->window, ¤tExtent)) != VK_SUCCESS)
|
||||
return res;
|
||||
auto rect = xcb::getWindowRect(gamescopeSurface->connection, gamescopeSurface->window);
|
||||
if (!rect)
|
||||
return VK_ERROR_SURFACE_LOST_KHR;
|
||||
|
||||
pSurfaceCapabilities->currentExtent = currentExtent;
|
||||
pSurfaceCapabilities->currentExtent = rect->extent;
|
||||
pSurfaceCapabilities->minImageCount = getMinImageCount();
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
@ -455,17 +455,6 @@ namespace GamescopeWSILayer {
|
|||
return s_isRunningUnderGamescope;
|
||||
}
|
||||
|
||||
static VkResult getCurrentExtent(xcb_connection_t* xcb_conn, xcb_window_t window, VkExtent2D* pExtent) {
|
||||
xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry(xcb_conn, window);
|
||||
xcb_get_geometry_reply_t* geom = xcb_get_geometry_reply(xcb_conn, geom_cookie, nullptr);
|
||||
if (!geom)
|
||||
return VK_ERROR_SURFACE_LOST_KHR;
|
||||
|
||||
*pExtent = VkExtent2D{ geom->width, geom->height };
|
||||
free(geom);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t getMinImageCount() {
|
||||
{
|
||||
const char *overrideStr = std::getenv("GAMESCOPE_WSI_MIN_IMAGE_COUNT");
|
||||
|
|
|
|||
|
|
@ -7,15 +7,24 @@
|
|||
|
||||
namespace xcb {
|
||||
|
||||
struct ReplyDeleter {
|
||||
template <typename T>
|
||||
void operator()(T* ptr) const {
|
||||
free(const_cast<std::remove_const_t<T>*>(ptr));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using Reply = std::unique_ptr<T, ReplyDeleter>;
|
||||
|
||||
static std::optional<xcb_atom_t> getAtom(xcb_connection_t* connection, std::string_view name) {
|
||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, false, name.length(), name.data());
|
||||
xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(connection, cookie, nullptr);
|
||||
auto reply = Reply<xcb_intern_atom_reply_t>{ xcb_intern_atom_reply(connection, cookie, nullptr) };
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] Failed to get xcb atom.\n");
|
||||
return std::nullopt;
|
||||
}
|
||||
xcb_atom_t atom = reply->atom;
|
||||
free(reply);
|
||||
return atom;
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +35,7 @@ namespace xcb {
|
|||
xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
|
||||
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
|
||||
xcb_get_property_reply_t* reply = xcb_get_property_reply(connection, cookie, nullptr);
|
||||
auto reply = Reply<xcb_get_property_reply_t>{ xcb_get_property_reply(connection, cookie, nullptr) };
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] Failed to read T root window property.\n");
|
||||
return std::nullopt;
|
||||
|
|
@ -34,12 +43,10 @@ namespace xcb {
|
|||
|
||||
if (reply->type != XCB_ATOM_CARDINAL) {
|
||||
fprintf(stderr, "[Gamescope WSI] Atom of T was wrong type. Expected XCB_ATOM_CARDINAL.\n");
|
||||
free(reply);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
T value = *reinterpret_cast<const T *>(xcb_get_property_value(reply));
|
||||
free(reply);
|
||||
T value = *reinterpret_cast<const T *>(xcb_get_property_value(reply.get()));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
@ -55,26 +62,23 @@ namespace xcb {
|
|||
static std::optional<xcb_window_t> getToplevelWindow(xcb_connection_t* connection, xcb_window_t window) {
|
||||
for (;;) {
|
||||
xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
|
||||
xcb_query_tree_reply_t* reply = xcb_query_tree_reply(connection, cookie, nullptr);
|
||||
auto reply = Reply<xcb_query_tree_reply_t>{ xcb_query_tree_reply(connection, cookie, nullptr) };
|
||||
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] getToplevelWindow: xcb_query_tree failed for window 0x%x.\n", window);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (reply->root == reply->parent) {
|
||||
free(reply);
|
||||
if (reply->root == reply->parent)
|
||||
return window;
|
||||
}
|
||||
|
||||
window = reply->parent;
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
static std::optional<VkRect2D> getWindowRect(xcb_connection_t* connection, xcb_window_t window) {
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connection, window);
|
||||
xcb_get_geometry_reply_t* reply = xcb_get_geometry_reply(connection, cookie, nullptr);
|
||||
auto reply = Reply<xcb_get_geometry_reply_t>{ xcb_get_geometry_reply(connection, cookie, nullptr) };
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] getWindowRect: xcb_get_geometry failed for window 0x%x.\n", window);
|
||||
return std::nullopt;
|
||||
|
|
@ -85,7 +89,6 @@ namespace xcb {
|
|||
.extent = { reply->width, reply->height },
|
||||
};
|
||||
|
||||
free(reply);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +113,7 @@ namespace xcb {
|
|||
VkExtent2D largestExtent = {};
|
||||
|
||||
xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
|
||||
xcb_query_tree_reply_t* reply = xcb_query_tree_reply(connection, cookie, nullptr);
|
||||
auto reply = Reply<xcb_query_tree_reply_t>{ xcb_query_tree_reply(connection, cookie, nullptr) };
|
||||
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] getLargestObscuringWindowSize: xcb_query_tree failed for window 0x%x.\n", window);
|
||||
|
|
@ -123,12 +126,12 @@ namespace xcb {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
xcb_window_t* children = xcb_query_tree_children(reply);
|
||||
xcb_window_t* children = xcb_query_tree_children(reply.get());
|
||||
for (uint32_t i = 0; i < reply->children_len; i++) {
|
||||
xcb_window_t child = children[i];
|
||||
|
||||
xcb_get_window_attributes_cookie_t attributeCookie = xcb_get_window_attributes(connection, child);
|
||||
xcb_get_window_attributes_reply_t *attributeReply = xcb_get_window_attributes_reply(connection, attributeCookie, nullptr);
|
||||
auto attributeReply = Reply<xcb_get_window_attributes_reply_t>{ xcb_get_window_attributes_reply(connection, attributeCookie, nullptr) };
|
||||
|
||||
const bool obscuring =
|
||||
attributeReply &&
|
||||
|
|
@ -141,12 +144,8 @@ namespace xcb {
|
|||
largestExtent = max(largestExtent, clippedRect.extent);
|
||||
}
|
||||
}
|
||||
|
||||
free(attributeReply);
|
||||
}
|
||||
|
||||
free(reply);
|
||||
|
||||
return largestExtent;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue