Skip to content

Commit

Permalink
Use query interface for void returning X requests
Browse files Browse the repository at this point in the history
  • Loading branch information
m-seker committed Aug 4, 2020
1 parent 13205a9 commit 602b88e
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 23 deletions.
41 changes: 30 additions & 11 deletions libsrc/grabber/xcb/XcbCommandExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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, 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;
}
80 changes: 80 additions & 0 deletions libsrc/grabber/xcb/XcbCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct ShmAttach
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_shm_attach;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct ShmDetach
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_shm_detach;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct CreatePixmap
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_create_pixmap;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct RenderCreatePicture
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_render_create_picture;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct RenderSetPictureFilter
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_render_set_picture_filter;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct RenderSetPictureTransform
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_render_set_picture_transform;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct RenderComposite
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_render_composite;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct RenderFreePicture
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_render_free_picture;
static constexpr auto ReplyFunction = xcb_request_check;
};

struct FreePixmap
{
typedef xcb_void_cookie_t ResponseType;

static constexpr auto RequestFunction = xcb_free_pixmap;
static constexpr auto ReplyFunction = xcb_request_check;
};

24 changes: 12 additions & 12 deletions libsrc/grabber/xcb/XcbGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ void XcbGrabber::freeResources()

if(_XcbShmAvailable)
{
xcb_shm_detach(_connection, _shminfo);
query<ShmDetach>(_connection, _shminfo);
shmdt(_shmData);
shmctl(_shminfo, IPC_RMID, 0);

}

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);
}
}

Expand All @@ -88,7 +88,7 @@ void XcbGrabber::setupResources()
_shminfo = xcb_generate_id(_connection);
int id = shmget(IPC_PRIVATE, _width * _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)
Expand All @@ -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);
Expand All @@ -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
{
Expand Down Expand Up @@ -241,8 +241,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),
Expand Down

0 comments on commit 602b88e

Please sign in to comment.