Search code examples
c++copenglxlibglx

XLib with GLX Error Produced when Calling XCreateWindow()


Edited and simplified from original post:

I am getting the following error:

X Error of failed request: BadMatch (invalid parameter attributes)
  Major opcode of failed request: 1 (X_CreateWindow)
  Serial number of failed request: 38
  Current serial number in output stream: 41

Using the code below from my perspective the code is crashing in window object (see below) when calling XCreateWindow():

app object

#ifndef APP_H
#define APP_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>

class app
{
public:
    app();
    void run();
    Display *getDisplay();
    Display *_xDisplay;
};

#endif // APP_H

#include "app.h"

app::app()
{
    _xDisplay = XOpenDisplay(NULL);
    if (_xDisplay == NULL)
        throw "Failed to get XDisplay";
}

Display *app::getDisplay()
{
    return _xDisplay;
}

void app::run()
{
    static bool run = true;
    static Display *lDisplay = _xDisplay;
    XEvent xEvent;
    while (run)
    {
        do
        {
            XNextEvent(lDisplay, &xEvent);
            switch (xEvent.type)
            {
            }
        } while (_xDisplay);
    }
}

window object

#ifndef WINDOW_H
#define WINDOW_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "app.h"

class app;
class ogldevice;

class window
{
public:
    window(app *a);
    app *a;
    ogldevice *od;
    Window xWindow;
};

#endif // WINDOW_H

#include "window.h"
#include "ogldevice.h"

window::window(app *a) :
    a(a)
{
    int width = 800;
    int height = 800;
    od = new ogldevice(a);

    Display *xDisplay = a->getDisplay();
    unsigned long valuemask = CWEventMask | CWBackPixel | CWBorderPixel | CWCursor;

    XSetWindowAttributes xAttributes;
    xAttributes.border_pixel = 0;
    xAttributes.colormap = od->glxDevice.glxColorMap;
    xAttributes.event_mask =  ExposureMask | KeyPressMask | ButtonPress |
                              StructureNotifyMask | ButtonReleaseMask |
                              KeyReleaseMask | EnterWindowMask | LeaveWindowMask |
                              PointerMotionMask | Button1MotionMask | VisibilityChangeMask |
                              ColormapChangeMask;

    xWindow = XCreateWindow(
                xDisplay,
                RootWindow(xDisplay, od->glxDevice.xVisual->screen),
                0, 0,
                width, height,
                0,
                od->glxDevice.xVisual->depth,
                InputOutput,
                od->glxDevice.xVisual->visual,
                valuemask,
                &xAttributes
                );

      XSetStandardProperties(
                  xDisplay,
                  xWindow,
                  "glxsimple",
                  "glxsimple",
                  None,
                  NULL,
                  0,
                  NULL
                  );

      XMapWindow(a->getDisplay(), xWindow);
}

ogldevice object

#ifndef OGLDEVICE_H
#define OGLDEVICE_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>

class app;

class ogldevice
{
public:
    ogldevice(app *a);
    struct GlxDevice
    {
        XVisualInfo *xVisual;
        Colormap glxColorMap;
        GLXContext glxContext;
    } glxDevice;
    app *a;
};

#endif // OGLDEVICE_H

#include "ogldevice.h"
#include "app.h"

ogldevice::ogldevice(app *a) :
    a(a)
{
    int errno, extension;
    if (!glXQueryExtension(a->getDisplay(), &errno, &extension))
    {
        throw "Glx Extension not Supported";
    }

    static int glx_attributes[] = {
        GLX_RGBA,
        GLX_RED_SIZE, 4,
        GLX_GREEN_SIZE, 4,
        GLX_BLUE_SIZE, 4,
        GLX_DOUBLEBUFFER,
        None
    };

    glxDevice.xVisual = glXChooseVisual(
                a->getDisplay(),
                DefaultScreen(a->getDisplay()),
                glx_attributes
                );

    if (glxDevice.xVisual == NULL)
        throw "Failure to get Double Buffer";

    glxDevice.glxContext = glXCreateContext(
                a->getDisplay(),
                glxDevice.xVisual,
                None, /* Don't share display lists */
                True
                );

    if (glxDevice.glxContext == NULL)
        throw "Failure to get GLX Context";

    glxDevice.glxColorMap = XCreateColormap(
                a->getDisplay(),
                RootWindow(a->getDisplay(), glxDevice.xVisual->screen),
                glxDevice.xVisual->visual,
                AllocNone
                );
}

driver

#include "app.h"
#include "window.h"

int main(int argc, char *argv[])
{
    app *a = new app();
    window *w = new window(a);
    a->run();

    delete a;
    delete w;

    return 0;
}

I get the same error when running in Fedora 14, RHEL 6.1, and Ubuntu 10.04 LTS. This leads me to believe it is a problem with the glx attributes I am passing to glxChooseVisual.


Solution

  • This doesn't error out for me:

    // compile like so:
    // g++ gltest.cpp -lX11 -lGL
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <X11/Xlib.h>
    #include <GL/glx.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    
    
    class app
    {
    public:
        app()
        {
            _xDisplay = XOpenDisplay(NULL);
            if (_xDisplay == NULL)
                throw "Failed to get XDisplay";
        }
    
        void run()
        {
            static bool run = true;
            static Display *lDisplay = _xDisplay;
            XEvent xEvent;
            while (run)
            {
                do
                {
                    XNextEvent(lDisplay, &xEvent);
                    switch (xEvent.type)
                    {
                    }
                } while (_xDisplay);
            }
        }
    
        Display *getDisplay()
        { 
            return _xDisplay; 
        }
    
        Display *_xDisplay;
    };
    
    
    class ogldevice
    {
    public:
        ogldevice(app *a) : a(a)
        {
            int errno, extension;
            if (!glXQueryExtension(a->getDisplay(), &errno, &extension))
            {
                throw "Glx Extension not Supported";
            }
    
            static int glx_attributes[] = 
                {
                GLX_RGBA,
                GLX_RED_SIZE, 4,
                GLX_GREEN_SIZE, 4,
                GLX_BLUE_SIZE, 4,
                GLX_DOUBLEBUFFER,
                None
                };
    
            glxDevice.xVisual = glXChooseVisual
                (
                a->getDisplay(),
                DefaultScreen(a->getDisplay()),
                glx_attributes
                );
    
            if (glxDevice.xVisual == NULL)
                throw "Failure to get Double Buffer";
    
            glxDevice.glxContext = glXCreateContext
                (
                a->getDisplay(),
                glxDevice.xVisual,
                None, /* Don't share display lists */
                True
                );
    
            if (glxDevice.glxContext == NULL)
                throw "Failure to get GLX Context";
    
            glxDevice.glxColorMap = XCreateColormap
                (
                a->getDisplay(),
                RootWindow(a->getDisplay(), glxDevice.xVisual->screen),
                glxDevice.xVisual->visual,
                AllocNone
                );
        }
    
        struct GlxDevice
        {
            XVisualInfo *xVisual;
            Colormap glxColorMap;
            GLXContext glxContext;
        } glxDevice;
    
        app *a;
    };
    
    
    class window
    {
    public:
        window(app *a) : a(a)
        {
            int width = 800;
            int height = 800;
            od = new ogldevice(a);
    
            Display *xDisplay = a->getDisplay();
            unsigned long valuemask = CWEventMask | CWBackPixel | CWBorderPixel;
    
            XSetWindowAttributes xAttributes;
            xAttributes.border_pixel = 0;
            xAttributes.colormap = od->glxDevice.glxColorMap;
            xAttributes.event_mask =  
                ExposureMask | KeyPressMask | ButtonPress |
                StructureNotifyMask | ButtonReleaseMask |
                KeyReleaseMask | EnterWindowMask | LeaveWindowMask |
                PointerMotionMask | Button1MotionMask | VisibilityChangeMask |
                ColormapChangeMask;
    
            xWindow = XCreateWindow
                (
                xDisplay,
                RootWindow(xDisplay, od->glxDevice.xVisual->screen),
                0, 0,
                width, height,
                0,
                od->glxDevice.xVisual->depth,
                InputOutput,
                od->glxDevice.xVisual->visual,
                valuemask,
                &xAttributes
                );
    
            XSetStandardProperties
                (
                xDisplay,
                xWindow,
                "glxsimple",
                "glxsimple",
                None,
                NULL,
                0,
                NULL
                );
    
            XMapWindow(a->getDisplay(), xWindow);
        }
    
        app *a;
        ogldevice *od;
        Window xWindow;
    };
    
    
    int main(int argc, char *argv[])
    {
        app *a = new app();
        window *w = new window(a);
        a->run();
    
        delete a;
        delete w;
    
        return 0;
    }
    

    Just took CWCursor out of valuemask.

    Inspired by this page.