value returned by XCreateWindow

I am having something strange happen. I have created three windows on three different monitors. When I call XCreateWindow, it returns a value I can print out. This variable is on my programs stack. Yet after I map the window, the value has changed on my stack. How is this possible? I am including the text of the program below. I am running this on a Red Hat 6.6 machine. Can someone run this and tell me what is going on?


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/glu.h>
 
void DrawAQuad() {
 /*glClearColor(1.0, 1.0, 1.0, 1.0);*/
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(-1., 1., -1., 1., 1., 20.);

 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 gluLookAt(0., 0., 10., 0., 0., 0., 0., 1., 0.);

 glBegin(GL_QUADS);
  glColor3f(1., 0., 0.); glVertex3f(-.75, -.75, 0.);
  glColor3f(0., 1., 0.); glVertex3f( .75, -.75, 0.);
  glColor3f(0., 0., 1.); glVertex3f( .75,  .75, 0.);
  glColor3f(1., 1., 0.); glVertex3f(-.75,  .75, 0.);
 glEnd();
}

int main (int argc, char *argv[])
{
    Display                 *display;
    XVisualInfo             *visual;
    GLint                   att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
    Colormap                cmap;
    XSetWindowAttributes    swa_attributes;
    XWindowAttributes       gwa_attributes;
    int                     screen_num;
    int                     i;
    unsigned int            display_width, display_height;
    Window                  frame_window[3] = { 0 };
    GLXContext              glx_ctxt;
    XKeyEvent               event;
    long                    window_index;
 
    display = XOpenDisplay(NULL);

    screen_num = 1;

    if((visual = glXChooseVisual( display, screen_num, att )) == NULL )
    {
      fprintf( stdout, "No appropriate visual found.
" );
      exit( 0 );
    }
    else
    {
      fprintf( stdout, "Visual %p selected.
", (void*)visual->visualid );
    }

    cmap = XCreateColormap( display,
                            XRootWindow(display, screen_num),
                            visual->visual,
                            AllocNone );

    display_width  = DisplayWidth(display, screen_num);
    display_height = DisplayHeight(display, screen_num);

    swa_attributes.colormap = cmap;
    swa_attributes.event_mask = ExposureMask;
    swa_attributes.background_pixel = XBlackPixel(display, screen_num);
    swa_attributes.override_redirect = 1;

  for( i = 0; i < 3; i++ )
  {
    /* create the application window */
    frame_window[i] = XCreateWindow( display,
                                     XRootWindow(display, screen_num),
                                     1920*i, 0, 1920, display_height,
                                     0, visual->depth, InputOutput,
                                     visual->visual,
                         CWColormap|CWEventMask|CWBackPixel|CWOverrideRedirect,
                                     &swa_attributes);

fprintf( stdout, "frame_window[%d] = %d
", i,(unsigned long)(frame_window[i]));
fflush( stdout );

    XMapWindow(display, frame_window[i]);

  }
  glx_ctxt = glXCreateContext( display, visual, NULL, GL_TRUE );

  glEnable( GL_DEPTH_TEST );
 
    while ( 1 ) {
        XNextEvent(display, (XEvent *)&event);

        window_index = (unsigned long)event.window - (unsigned long)frame_window[0];
fprintf( stdout, "event window = %d frame window %d diff %d
",
         (unsigned long)event.window, (unsigned long)frame_window[0], window_index );
fflush( stdout );

        glXMakeCurrent( display, event.window, glx_ctxt );

        switch ( event.type ) {
            case Expose:
            {
                XGetWindowAttributes(display, event.window, &gwa_attributes);
                glViewport( 0, 0, gwa_attributes.width, gwa_attributes.height );
                DrawAQuad();
                glXSwapBuffers( display, event.window );
                break;
            }
            default:
                break;
        }
    }
    return(0);
}

  1. Use [ code ] tags when posting code, to preserve the indentation.
  2. This is a general programming question, unrelated to OpenGL.
  3. Actual OpenGL questions which are specific to X11 should probably go in the “OpenGL on Linux” section of the forum.
  4. Your problem is probably caused by using printf() incorrectly.

You’re passing an unsigned long but %d expects an int. Use %ld for a long or %lu or %lx for an unsigned long. But XIDs (which include Window) are 32-bit, so unsigned int would be better.


fprintf( stdout, "event window = %08x frame window = %08x diff %d
",
         (unsigned int) event.window, (unsigned int) frame_window[0], window_index);

Thank you for the reply.

I did try using the attach button, but kept getting a can’t connect to server message.

When I changed the coersion from (unsigned long) to (unsigned int). It didn’t change the outcome. The values are different the second time I print them.

fprintf( stdout, "event window = %d frame window %d diff %d
",
         (unsigned int)event.window, (unsigned int)frame_window[0], window_index );
fflush( stdout );

the output looks like this

Visual 0x306 selected.
frame_window[0] = 37748739
frame_window[1] = 37748740
frame_window[2] = 37748741
event window = 37748739 frame window 65280 diff 37683459
event window = 37748740 frame window 789 diff 37747951
event window = 37748741 frame window 65280 diff 37683461

How do I move this to the OpenGL on Linux discussion board?

You’re declaring “event” as XKeyEvent, which isn’t large enough to hold all of the event types which XNextEvent() could return, resulting in local variables being overwritten.

You are a beautiful human being. Thank you. I need to pay attention to types better. Didn’t realize there was a union involved.