void X11OpenGLWindow::pumpMessage() { int buttonState = 1; // Process all pending events while( XPending( m_data->m_dpy ) ) { XNextEvent(m_data->m_dpy, &m_data->m_xev); // printf("#"); // fflush(stdout); switch( m_data->m_xev.type ) { case KeyPress: { if (m_data->m_keyboardCallback) { int keycode = getAsciiCodeFromVirtualKeycode(m_data->m_xev.xkey.keycode); int state = 1; (*m_data->m_keyboardCallback)(keycode,state); // printf("keycode %d",keycode); // fflush(stdout); } break; } case KeyRelease: { // fflush(stdout); if (m_data->m_keyboardCallback) { unsigned short is_retriggered = 0; ///filter out keyboard repeat //see http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications if (XEventsQueued(m_data->m_dpy, QueuedAfterReading)) { XEvent nev; XPeekEvent(m_data->m_dpy, &nev); if (nev.type == KeyPress && nev.xkey.time == m_data->m_xev.xkey.time && nev.xkey.keycode == m_data->m_xev.xkey.keycode) { fprintf (stdout, "key #%ld was retriggered.\n", (long) XLookupKeysym (&nev.xkey, 0)); // delete retriggered KeyPress event XNextEvent (m_data->m_dpy, & m_data->m_xev); is_retriggered = 1; } } int keycode = getAsciiCodeFromVirtualKeycode( m_data->m_xev.xkey.keycode); int state = 0; (*m_data->m_keyboardCallback)(keycode,state); } break; } case ButtonRelease: buttonState = 0; //continue with ButtonPress code case ButtonPress: { // printf("!"); // fflush(stdout); int button=-1; switch (m_data->m_xev.xbutton.button) { case Button1: { button=0; break; } case Button2: { button=1; break; } case Button3: { button=2; break; } case Button4: { if (m_data->m_wheelCallback) { (*m_data->m_wheelCallback)(0,10); } break; } case Button5: { if (m_data->m_wheelCallback) { (*m_data->m_wheelCallback)(0,-10); } break; } } int xpos = m_data->m_xev.xmotion.x; int ypos = m_data->m_xev.xmotion.y; if (button>=0 && m_data->m_mouseButtonCallback) { // printf("xpos = %d, ypos = %d\n",xpos,ypos); (*m_data->m_mouseButtonCallback)(button,buttonState,xpos,ypos); } break; } case MotionNotify: { // printf("!"); // fflush(0); if (m_data->m_mouseMoveCallback) { int xpos = m_data->m_xev.xmotion.x; int ypos = m_data->m_xev.xmotion.y; (*m_data->m_mouseMoveCallback)(xpos,ypos); } break; } case ConfigureNotify: { // printf("@"); // fflush(0); if (m_data->m_resizeCallback) { (*m_data->m_resizeCallback)(m_data->m_xev.xconfigure.width,m_data->m_xev.xconfigure.height); } break; } case ClientMessage: { // printf("?"); // fflush(stdout); break; } case Expose: { break; } case DestroyNotify: { break; } default: { //XRRUpdateConfiguration( &event ); } }; } }
void GLWindow::initWindow(const char* sWindowName,int* visualProperties) { /* Get a handle to the root window: */ root=RootWindow(display,screen); /* Query for GLX extension: */ int errorBase,eventBase; if(!glXQueryExtension(display,&errorBase,&eventBase)) Misc::throwStdErr("GLWindow: GLX extension not supported"); /* Find a suitable, OpenGL-capable visual: */ static int defaultVisualProperties[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None}; XVisualInfo* visInfo=glXChooseVisual(display,screen,visualProperties!=0?visualProperties:defaultVisualProperties); if(visInfo==0) Misc::throwStdErr("GLWindow: No suitable visual found"); /* Create an OpenGL context: */ context=glXCreateContext(display,visInfo,0,GL_TRUE); if(context==0) Misc::throwStdErr("GLWindow: Unable to create GL context"); /* Create an X colormap (visual might not be default): */ colorMap=XCreateColormap(display,root,visInfo->visual,AllocNone); /* Create an X window with the selected visual: */ XSetWindowAttributes swa; swa.colormap=colorMap; swa.border_pixel=0; if(fullscreen) // Create a fullscreen window { windowPos.origin[0]=0; windowPos.origin[1]=0; windowPos.size[0]=DisplayWidth(display,screen); windowPos.size[1]=DisplayHeight(display,screen); swa.override_redirect=True; } else swa.override_redirect=False; swa.event_mask=PointerMotionMask|EnterWindowMask|LeaveWindowMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask|ExposureMask|StructureNotifyMask; unsigned long attributeMask=CWBorderPixel|CWColormap|CWOverrideRedirect|CWEventMask; window=XCreateWindow(display,root, windowPos.origin[0],windowPos.origin[1],windowPos.size[0],windowPos.size[1], 0,visInfo->depth,InputOutput,visInfo->visual,attributeMask,&swa); XSetStandardProperties(display,window,sWindowName,sWindowName,None,0,0,0); /* Delete the visual information structure: */ XFree(visInfo); /* Initiate window manager communication: */ wmProtocolsAtom=XInternAtom(display,"WM_PROTOCOLS",False); wmDeleteWindowAtom=XInternAtom(display,"WM_DELETE_WINDOW",False); XSetWMProtocols(display,window,&wmDeleteWindowAtom,1); /* Display the window on the screen: */ XMapWindow(display,window); if(fullscreen) { /* Grab pointer and keyboard: */ XGrabPointer(display,window,True,0,GrabModeAsync,GrabModeAsync,None,None,CurrentTime); XGrabKeyboard(display,window,True,GrabModeAsync,GrabModeAsync,CurrentTime); } /* Gobble up the initial rush of X events regarding window creation: */ #if 0 XEvent event; while(XCheckWindowEvent(display,window,StructureNotifyMask,&event)) { switch(event.type) { case ConfigureNotify: /* Retrieve the final window size: */ windowWidth=event.xconfigure.width; windowHeight=event.xconfigure.height; break; } } #else while(true) { /* Look at the next event: */ XEvent event; XPeekEvent(display,&event); if(event.type==Expose) break; // Leave this event for the caller to process /* Process the next event: */ XNextEvent(display,&event); switch(event.type) { case ConfigureNotify: /* Retrieve the final window position and size: */ windowPos.origin[0]=event.xconfigure.x; windowPos.origin[1]=event.xconfigure.y; windowPos.size[0]=event.xconfigure.width; windowPos.size[1]=event.xconfigure.height; break; } } #endif }