How to catch X errors?

眉间皱痕 提交于 2021-02-07 07:19:27

问题


I tried searching the web, but I must note that finding materials about this aspect of X programming is not really easy.

I use X with GLX to create OpenGL contexts. I already know my current graphics card driver only supports up to OpenGL API version 3.3, but I want my application to be able to try to create a context with any kind of version (as it could run on other computers). My code goes like this :

  • Version <- requested OpenGL Version (by example : 3.3)
  • Create a context :
    • if Version is 3.x or 4.x, use glXCreateContextAttribsARB
    • else use glXCreateContext
  • If creating the context failed, go down one version (3.3 becomes 3.2, or 3.0 becomes 2.1, ...)
  • Stop if a context is created or if couldn't even using the minimum OpenGL version.

My code is OK, but I'd like to be more clean on the way I retrieve the errors launched by X/GLX, as for the moment, if I use glXCreateContextAttribARB to create a 4.4 version (remember, my graphics card only supports up to 3.3), I obviously get :

X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  153 (GLX)
  Minor opcode of failed request:  34 ()
  Serial number of failed request:  33
  Current serial number in output stream:  34

I'd like to insert error handling for X in my code to handle it. X being C, not C++, exceptions are not usable at this stage. Here is where I create the context (I intentionally removed what does not directly is context creation) :

// Notes :
// mGLXContext : The GLX context we want to create
// vDepthSize, vAntialiasingLevel, vStencilSize are here to customize mGLXContext
// vTryVersion : a pointer to the API version {major, minor} we want to create
// vSharedContext : a pointer to an other (existing) context for data sharing.
// mXDisplay : the X Display


// Get the proc
const GLubyte* vProcName = reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB");
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 
    reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(vProcName));

if(glXCreateContextAttribsARB) {

    // Create the FB attributes
    int vFBAttributes[] = {
        GLX_DEPTH_SIZE, (int)(vDepthSize),
        GLX_STENCIL_SIZE, (int)(vStencilSize),
        GLX_SAMPLE_BUFFERS, vAntialiasingLevel > 0,
        GLX_SAMPLES, (int)(vAntialiasingLevel),
        GLX_RED_SIZE, 8,
        GLX_GREEN_SIZE, 8,
        GLX_BLUE_SIZE, 8,
        GLX_ALPHA_SIZE, pDepth == 32 ? 8 : 0,
        GLX_DOUBLEBUFFER, True,
        GLX_X_RENDERABLE, True,
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_CONFIG_CAVEAT, GLX_NONE,
        None
    };


    // Get the FB configs
    int vNbXConfigs = 0;
    ::GLXFBConfig* vGLXFBConfig = glXChooseFBConfig(mXDisplay, DefaultScreen(mXDisplay), vFBAttributes, &vNbXConfigs);

    if(vGLXFBConfig && vNbXConfigs) {

        // Create the context attributes
        int vAttributes[] = {
            GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(vTryVersion->major),
            GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(vTryVersion->minor),
            0, 0
        };

        // Create the context : Error is generated by GLX here
        mGLXContext = glXCreateContextAttribsARB(mXDisplay, vGLXFBConfig[0], vSharedContext, true, vAttributes);

    }
}

So my question is how can I catch X error and query them ?

Thank you for reading :)


回答1:


You need to use XSetErrorHandler to specify an error handler e.g.

XSetErrorHandler(handler);

The error handler is

int handler(Display * d, XErrorEvent * e)
{
    std::cerr << "Error code: " << e->error_code << std::endl;
    return 0;
}


来源:https://stackoverflow.com/questions/20107649/how-to-catch-x-errors

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!