diff --git a/libsrc/grabber/xcb/XcbCommandExecutor.h b/libsrc/grabber/xcb/XcbCommandExecutor.h index 25e3a607..f87f4c70 100644 --- a/libsrc/grabber/xcb/XcbCommandExecutor.h +++ b/libsrc/grabber/xcb/XcbCommandExecutor.h @@ -4,27 +4,46 @@ #include -template - std::unique_ptr - 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 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 + typename std::enable_if::value, void>::type + query(xcb_connection_t * connection, Args&& ...args) +{ + auto cookie = Request::RequestFunction(connection, std::forward(args)...); + + xcb_generic_error_t * error = Request::ReplyFunction(connection, cookie); + + check_error(error); +} + +// Requests with non-void response type +template + typename std::enable_if::value, + std::unique_ptr>::type + query(xcb_connection_t * connection, Args&& ...args) +{ + auto cookie = Request::RequestFunction(connection, std::forward(args)...); + + xcb_generic_error_t * error = nullptr; + std::unique_ptr xcbResponse( + Request::ReplyFunction(connection, cookie, &error), free); + + check_error(error); return xcbResponse; } diff --git a/libsrc/grabber/xcb/XcbCommands.h b/libsrc/grabber/xcb/XcbCommands.h index c43f7166..973e87bf 100644 --- a/libsrc/grabber/xcb/XcbCommands.h +++ b/libsrc/grabber/xcb/XcbCommands.h @@ -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; +}; + diff --git a/libsrc/grabber/xcb/XcbGrabber.cpp b/libsrc/grabber/xcb/XcbGrabber.cpp index 275a6156..1e788b30 100644 --- a/libsrc/grabber/xcb/XcbGrabber.cpp +++ b/libsrc/grabber/xcb/XcbGrabber.cpp @@ -62,7 +62,7 @@ void XcbGrabber::freeResources() if(_XcbShmAvailable) { - xcb_shm_detach(_connection, _shminfo); + query(_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(_connection, _pixmap); + query(_connection, _srcPicture); + query(_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(shmat(id, nullptr, 0)); - xcb_shm_attach(_connection, _shminfo, id, 0); + query(_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( _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(_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(_connection, _srcPicture, _screen->root, _srcFormat, value_mask, values); + query(_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(_connection, _srcPicture, filter.size(), filter.c_str(), 0, nullptr); } else { @@ -243,8 +243,8 @@ int XcbGrabber::grabFrame(Image & 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(_connection, _srcPicture, _transform); + query(_connection, XCB_RENDER_PICT_OP_SRC, _srcPicture, XCB_RENDER_PICTURE_NONE, _dstPicture, (_src_x/_pixelDecimation),