[Xcb] xcb_randr_set_screen_size_checked error
Andrey Af
public.irkutsk at gmail.com
Thu Sep 2 00:57:59 UTC 2021
Hi,
I'm trying to use this function but I get an error:
error code: 8, major: 0x8c, minor: 0x07, sequence: 4
I checked the version of extension, and get:
RANDR extension, version: 1.6
I have successfully received a list of modes:
size: 1920x1080
size: 1680x1050
size: 1280x1024
size: 1440x900
size: 1280x960
size: 1280x720
size: 1024x768
size: 832x624
size: 800x600
size: 720x576
size: 720x480
size: 640x480
size: 720x400
test program:
//
// build: g++ -Wall -std=c++17 -I /usr/include/xcb -lxcb -lxcb-randr
test.cpp -o test
//
#include <xcb/xcb.h>
#include <xcb/randr.h>
#include <xcb/xproto.h>
#include <list>
#include <iomanip>
#include <iostream>
#include <algorithm>
void dumpError(const char* func, const xcb_generic_error_t* err)
{
std::cerr << func << ": error code: " <<
static_cast<int>(err->error_code) <<
", major: 0x" << std::setw(2) << std::setfill('0') <<
std::hex << static_cast<int>(err->major_code) <<
", minor: 0x" << std::setw(2) << std::setfill('0') <<
std::hex << static_cast<int>(err->minor_code) <<
", sequence: " << std::dec << err->sequence << std::endl;
}
bool checkRandrExtension(xcb_connection_t* _conn)
{
auto _randr = xcb_get_extension_data(_conn, &xcb_randr_id);
if(! _randr || ! _randr->present)
return false;
xcb_generic_error_t* error;
auto cookie = xcb_randr_query_version(_conn,
XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION);
auto reply = xcb_randr_query_version_reply(_conn, cookie, &error);
if(error)
{
dumpError(__FUNCTION__, error);
std::free(error);
return false;
}
if(reply)
{
std::cout << "RANDR extension, version: " <<
reply->major_version << "." << reply->minor_version << std::endl;
std::free(reply);
return true;
}
return false;
}
std::list<xcb_randr_screen_size_t> getScreenSizes(xcb_connection_t*
_conn, xcb_screen_t* _screen)
{
std::list<xcb_randr_screen_size_t> res;
xcb_generic_error_t* error;
auto cookie = xcb_randr_get_screen_info(_conn, _screen->root);
auto reply = xcb_randr_get_screen_info_reply(_conn, cookie, &error);
if(error)
{
dumpError(__FUNCTION__, error);
std::free(error);
return res;
}
if(reply)
{
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(reply);
int length = xcb_randr_get_screen_info_sizes_length(reply);
for(int pos = 0; pos < length; ++pos)
res.push_back(sizes[pos]);
std::free(reply);
}
return res;
}
int main(int argc, char** argv)
{
auto _conn = xcb_connect(":0", nullptr);
if(xcb_connection_has_error(_conn))
return EXIT_FAILURE;
if(checkRandrExtension(_conn))
{
auto setup = xcb_get_setup(_conn);
auto _screen = xcb_setup_roots_iterator(setup).data;
auto sizes = getScreenSizes(_conn, _screen);
for(auto & sz : sizes)
std::cout << "size: " << sz.width << "x" << sz.height << std::endl;
auto it = std::find_if(sizes.begin(), sizes.end(), [](auto &
sz){ return sz.width == 1680 && sz.height == 1050; });
if(it != sizes.end())
{
auto cookie = xcb_randr_set_screen_size_checked(_conn,
_screen->root, (*it).width, (*it).height, (*it).mwidth,
(*it).mheight);
auto error = xcb_request_check(_conn, cookie);
if(error)
{
dumpError(__FUNCTION__, error);
std::free(error);
}
}
else
{
std::cerr << "1680x1050 mode not found" << std::endl;
}
}
xcb_disconnect(_conn);
return 0;
}
More information about the Xcb
mailing list