Merge pull request #945 from m-seker/improvement/xcb

Use query interface for void returning X requests
This commit is contained in:
Murat Seker 2020-09-02 15:44:44 +02:00 committed by GitHub
commit 6e039a0d83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 122 additions and 23 deletions

View File

@ -4,27 +4,46 @@
#include <xcb/xcb.h>
template<class Request, class ...Args>
std::unique_ptr<typename Request::ResponseType, decltype(&free)>
query(xcb_connection_t * connection, Args&& ...args)
void check_error(xcb_generic_error_t * error)
{
auto cookie = Request::RequestFunction(connection,args...);
xcb_generic_error_t * error = nullptr;
std::unique_ptr<typename Request::ResponseType, decltype(&free)> xcbResponse(
Request::ReplyFunction(connection, cookie, &error), free);
if (error) {
Logger * LOGGER = Logger::getInstance("XCB");
Error(LOGGER,
"Cannot get the image data event_error: response_type:%u error_code:%u "
"XCB request failed, event_error: response_type:%u error_code:%u "
"sequence:%u resource_id:%u minor_code:%u major_code:%u.\n",
error->response_type, error->error_code, error->sequence,
error->resource_id, error->minor_code, error->major_code);
free(error);
return {nullptr, nullptr};
}
}
// Requests with void response type
template<class Request, class ...Args>
typename std::enable_if<std::is_same<typename Request::ResponseType, xcb_void_cookie_t>::value, void>::type
query(xcb_connection_t * connection, Args&& ...args)
{
auto cookie = Request::RequestFunction(connection, std::forward<Args>(args)...);
xcb_generic_error_t * error = Request::ReplyFunction(connection, cookie);
check_error(error);
}
// Requests with non-void response type
template<class Request, class ...Args>
typename std::enable_if<!std::is_same<typename Request::ResponseType, xcb_void_cookie_t>::value,
std::unique_ptr<typename Request::ResponseType, decltype(&free)>>::type
query(xcb_connection_t * connection, Args&& ...args)
{
auto cookie = Request::RequestFunction(connection, std::forward<Args>(args)...);
xcb_generic_error_t * error = nullptr;
std::unique_ptr<typename Request::ResponseType, decltype(&free)> xcbResponse(
Request::ReplyFunction(connection, cookie, &error), free);
check_error(error);
return xcbResponse;
}

View File

@ -53,3 +53,83 @@ struct RenderQueryPictFormats
static constexpr auto ReplyFunction = xcb_render_query_pict_formats_reply;
};
struct ShmCreatePixmap
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_shm_create_pixmap_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct ShmAttach
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_shm_attach_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct ShmDetach
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_shm_detach_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct CreatePixmap
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_create_pixmap_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct RenderCreatePicture
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_render_create_picture_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct RenderSetPictureFilter
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_render_set_picture_filter_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct RenderSetPictureTransform
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_render_set_picture_transform_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct RenderComposite
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_render_composite_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct RenderFreePicture
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_render_free_picture_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};
struct FreePixmap
{
typedef xcb_void_cookie_t ResponseType;
static constexpr auto RequestFunction = xcb_free_pixmap_checked;
static constexpr auto ReplyFunction = xcb_request_check;
};

View File

@ -62,7 +62,7 @@ void XcbGrabber::freeResources()
if(_XcbShmAvailable)
{
xcb_shm_detach(_connection, _shminfo);
query<ShmDetach>(_connection, _shminfo);
shmdt(_shmData);
shmctl(_shminfo, IPC_RMID, 0);
@ -70,9 +70,9 @@ void XcbGrabber::freeResources()
if (_XcbRenderAvailable)
{
xcb_free_pixmap(_connection, _pixmap);
xcb_render_free_picture(_connection, _srcPicture);
xcb_render_free_picture(_connection, _dstPicture);
query<FreePixmap>(_connection, _pixmap);
query<RenderFreePicture>(_connection, _srcPicture);
query<RenderFreePicture>(_connection, _dstPicture);
}
}
@ -88,7 +88,7 @@ void XcbGrabber::setupResources()
_shminfo = xcb_generate_id(_connection);
int id = shmget(IPC_PRIVATE, size_t(_width) * size_t(_height) * 4, IPC_CREAT | 0777);
_shmData = static_cast<uint8_t*>(shmat(id, nullptr, 0));
xcb_shm_attach(_connection, _shminfo, id, 0);
query<ShmAttach>(_connection, _shminfo, id, 0);
}
if (_XcbRenderAvailable)
@ -100,14 +100,14 @@ void XcbGrabber::setupResources()
if(_XcbShmPixmapAvailable)
{
_pixmap = xcb_generate_id(_connection);
xcb_shm_create_pixmap(
query<ShmCreatePixmap>(
_connection, _pixmap, _screen->root, _width,
_height, _screen->root_depth, _shminfo, 0);
}
else
{
_pixmap = xcb_generate_id(_connection);
xcb_create_pixmap(_connection, _screen->root_depth, _pixmap, _screen->root, _width, _height);
query<CreatePixmap>(_connection, _screen->root_depth, _pixmap, _screen->root, _width, _height);
}
_srcFormat = findFormatForVisual(_screen->root_visual);
@ -119,11 +119,11 @@ void XcbGrabber::setupResources()
const uint32_t value_mask = XCB_RENDER_CP_REPEAT;
const uint32_t values[] = { XCB_RENDER_REPEAT_NONE };
xcb_render_create_picture(_connection, _srcPicture, _screen->root, _srcFormat, value_mask, values);
xcb_render_create_picture(_connection, _dstPicture, _pixmap, _dstFormat, value_mask, values);
query<RenderCreatePicture>(_connection, _srcPicture, _screen->root, _srcFormat, value_mask, values);
query<RenderCreatePicture>(_connection, _dstPicture, _pixmap, _dstFormat, value_mask, values);
const std::string filter = "fast";
xcb_render_set_picture_filter(_connection, _srcPicture, filter.size(), filter.c_str(), 0, nullptr);
query<RenderSetPictureFilter>(_connection, _srcPicture, filter.size(), filter.c_str(), 0, nullptr);
}
else
{
@ -243,8 +243,8 @@ int XcbGrabber::grabFrame(Image<ColorRgb> & image, bool forceUpdate)
DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(scale)
};
xcb_render_set_picture_transform(_connection, _srcPicture, _transform);
xcb_render_composite(_connection,
query<RenderSetPictureTransform>(_connection, _srcPicture, _transform);
query<RenderComposite>(_connection,
XCB_RENDER_PICT_OP_SRC, _srcPicture,
XCB_RENDER_PICTURE_NONE, _dstPicture,
(_src_x/_pixelDecimation),