Ejemplo n.º 1
0
static Window createWindow(Display *dpy, int width, int height) {
	GLXFBConfig *fbc;
	XVisualInfo *vi;
	Colormap cmap;
	XSetWindowAttributes swa;
	GLXContext cx;
	XEvent event;
	int nElements;

	int attr[] = { GLX_DOUBLEBUFFER, True, None };

	fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), attr, &nElements);
	vi = glXGetVisualFromFBConfig(dpy, fbc[0]);

	cx = glXCreateNewContext(dpy, fbc[0], GLX_RGBA_TYPE, 0, GL_FALSE);
	cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);

	swa.colormap = cmap;
	swa.border_pixel = 0;
	swa.event_mask = 0;
	Window win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
	XSelectInput(dpy, win, StructureNotifyMask | KeyPressMask | KeyReleaseMask);
	XMapWindow(dpy, win);
	XIfEvent(dpy, &event, waitMapNotify, (char *)win);

	XMoveWindow(dpy, win, 100, 100);
	XIfEvent(dpy, &event, waitConfigureNotify, (char *)win);

	glXMakeCurrent(dpy, win, cx);
	return win;
}
Ejemplo n.º 2
0
void XWindow::openWindow(const Pnt2f& ScreenPosition,
                    const Vec2f& Size,
                    const std::string& WindowName)
{

    int argc(1);
    char **argv = new char*[1];
    (*argv)= "Bla";
     XSetStandardProperties(this->getDisplay(), this->getWindow(), WindowName.c_str(), WindowName.c_str(), None, argv, argc, NULL);
    attachWindow();
    

    this->init();
    
    XMapWindow(this->getDisplay(),
               this->getWindow());
    XEvent event;
    XIfEvent(this->getDisplay(), &event, wait_for_map_notify, (char *)(this->getWindow()));
    produceWindowOpened();
    
    this->activate();
    
    setPosition(ScreenPosition);
    setSize(Vec2us(Size[0], Size[1]));
    
    //Set things up to capture the delete window event
    Atom wm_delete_window=XInternAtom(this->getDisplay(), "WM_DELETE_WINDOW", False);
    XSetWMProtocols(this->getDisplay(), this->getWindow(), &wm_delete_window, 1);
    Atom wm_protocols=XInternAtom(this->getDisplay(), "WM_PROTOCOLS", False); 
}
Ejemplo n.º 3
0
void PrintableWindow::xmove(int left1, int top) {
	const Display& d = *display();
	XEvent event;

	int x = 0, y = 0;
	static int xoff = 0, yoff = 0;
	WindowRep& w = *((Window*)this)->rep();
	get_position(d.rep()->display_, w.xwindow_, &x, &y);

	for (int i= 0; (left1 != x || top != y) && i < 10; i++) {
		XMoveWindow(d.rep()->display_, w.xwindow_,
				left1+xoff, top+yoff);
		XPeekIfEvent(d.rep()->display_, &event, WaitForEvent,
				(char *)ConfigureNotify);
		get_position(d.rep()->display_, w.xwindow_, &x, &y);

		if (left1 != x || top != y) {
			XIfEvent(d.rep()->display_, &event, WaitForEvent,
					(char *)ConfigureNotify);
			xoff = left1 - x;
			yoff = top - y;
		}
printf("x=%d y=%d, left1=%d top=%d xoff = %d yoff = %d\n",
	x, y, left1, top, xoff, yoff);
	}
}
Ejemplo n.º 4
0
void wsMainLoop( void )
{
 int delay=20;
 mp_msg( MSGT_GPLAYER,MSGL_V,"[ws] init threads: %d\n",XInitThreads() );
 XSynchronize( wsDisplay,False );
 XLockDisplay( wsDisplay );
// XIfEvent( wsDisplay,&wsEvent,wsEvents,NULL );

#if 1

while(wsTrue){
 // handle pending events
 while ( XPending(wsDisplay) ){
   XNextEvent( wsDisplay,&wsEvent );
   wsEvents( wsDisplay,&wsEvent,NULL );
   delay=0;
 }
 usleep(delay*1000); // FIXME!
 if(delay<10*20) delay+=20; // pump up delay up to 0.2 sec (low activity)
}

#else

 while( wsTrue )
  {
   XIfEvent( wsDisplay,&wsEvent,wsDummyEvents,NULL );
   wsEvents( wsDisplay,&wsEvent,NULL );
  }
#endif

 XUnlockDisplay( wsDisplay );
}
Ejemplo n.º 5
0
void X11WindowImpl::show()
{
  XMapWindow(factory->xdisplay, xwindow);
  XEvent ev;
  XIfEvent(factory->xdisplay, &ev, IsMapNotify, (XPointer) xwindow );
  factory->processEvents();
  update();
}
Ejemplo n.º 6
0
static void
openWindow(Display *&display, Window &window, unsigned int windowX,
	   unsigned int windowY, char *title)
//
//////////////////////////////////////////////////////////////
{
    XVisualInfo			*vi;
    Colormap			cmap;
    XSetWindowAttributes	swa;
    GLXContext			cx;
    XEvent			event;
    static int			attributeList[] = {
	GLX_RGBA,
	GLX_RED_SIZE, 1,
	GLX_GREEN_SIZE, 1,
	GLX_BLUE_SIZE, 1,
	GLX_DEPTH_SIZE, 1,
	None,		// May be replaced w/GLX_DOUBLEBUFFER
	None,
    };

    display = XOpenDisplay(0);
    vi   = glXChooseVisual(display,
			   DefaultScreen(display),
			   attributeList);
    cx   = glXCreateContext(display, vi, 0, GL_TRUE);
    cmap = XCreateColormap(display,
			   RootWindow(display, vi->screen),
			   vi->visual, AllocNone);
    swa.colormap	= cmap;
    swa.border_pixel	= 0;
    swa.event_mask	= StructureNotifyMask;
    window = XCreateWindow(display,
	   RootWindow(display, vi->screen),
	   10, 10, windowX, windowY,
	   0, vi->depth, InputOutput, vi->visual,
	   (CWBorderPixel | CWColormap | CWEventMask), &swa);

    // Make the window appear in the lower left corner
    XSizeHints *xsh = XAllocSizeHints();
    xsh->flags = USPosition;
    XSetWMNormalHints(display, window, xsh);
    XSetStandardProperties(display, window, title, title, None, 0, 0, 0);
    XFree(xsh);

    XMapWindow(display, window);
    XIfEvent(display, &event, waitForNotify, (char *) window);
    glXMakeCurrent(display, window, cx);

    glEnable(GL_DEPTH_TEST);
    glClearColor(0.5, 0.5, 0.5, 1);
    
    // clear the graphics window and depth planes
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
Ejemplo n.º 7
0
static void
get_server_info (Window *server_window, Display **display, string identity)
{
    int scr;

    /* Open our own connection to the X server, since sending messages
       through the server's connection hangs.  */
    *display = XOpenDisplay (NULL);
    if (*display == NULL)
        FATAL1 ("limn: Could not open display `%s'", getenv ("DISPLAY"));

    /* Get the identity atom. Create it if it doesn't exist.  */
    foserver_identity_atom
        = XInternAtom (*display, FOSERVER_IDENTITY_ATOM, False);

    /* Ask to be told about most window events.  */
    XSelectInput (*display, DefaultRootWindow (*display),
                  SubstructureNotifyMask);

    /* Remove potential race condition below -- if our server has already
       had its window realized, we wouldn't find it otherwise. Search all
       windows first.  We might just as well search all screens too. */
    *server_window = None;
    for (scr = ScreenCount (*display); scr > 0 && *server_window == None; scr--)
    {
        Window root = RootWindow (*display, scr - 1);
        *server_window = search_children (*display, root, identity);
    }

    while (*server_window == None)
    {
        XEvent event;
        Window w;

        /* Wait for an event that might mean our server is ready.  */
        XIfEvent (*display, &event, window_change_p, NULL);

        /* We look for some property on the window, and rely on our server
           setting that property.  */
        switch (event.type)
        {
        case MapNotify:
            w = event.xmap.window;
            *server_window = search_children (*display, w, identity);
            break;

        default:
            FATAL1 ("limn: Unexpected event (type %d)", event.type);
        }
    }

    /* We don't want to see any events any more.  */
    XSelectInput (*display, DefaultRootWindow (*display),
                  NoEventMask);
}
Ejemplo n.º 8
0
XEvent Clipboard::checkEvent()
{
	XEvent e;
    XIfEvent(resourceManager->dpy, &e, &clipboardPredicate, reinterpret_cast<XPointer>(window.get()));
    DEBUG_CLIP("A selection notify has arrived!");
    DEBUG_CLIP("Requester = 0x" << hex << e.xselectionrequest.requestor << dec);
    DEBUG_CLIP("Target atom    = " << getAtomName(resourceManager->dpy, e.xselection.target));
    DEBUG_CLIP("Property atom  = " << getAtomName(resourceManager->dpy, e.xselection.property));
    DEBUG_CLIP("Selection atom = " << getAtomName(resourceManager->dpy, e.xselection.selection));
	return e;
}
Ejemplo n.º 9
0
Time get_server_time(Display* dpy, Window win) {
	unsigned char c = 'a';
	TimeStampInfo info;
	XEvent xev;

	info.timestamp_prop_atom = XInternAtom(dpy, "_TIMESTAMP_PROP", False);
	info.window = win;

	XChangeProperty(dpy, win, info.timestamp_prop_atom, info.timestamp_prop_atom,
			8, PropModeReplace, &c, 1);

	XIfEvent(dpy, &xev, timestamp_predicate, (XPointer)&info);
	return xev.xproperty.time;
}
Ejemplo n.º 10
0
void Close_OGLwin(void)
{

    //
    // wait for the window to be unmapped
    //
    XEvent e;

    XUnmapWindow(Dsp, XWindow);
    XIfEvent(Dsp, &e, WaitForUnmapNotify, (char *) XWindow);

    glXDestroyContext(Dsp, Cxt);
    XDestroyWindow(Dsp, XWindow);
}
Ejemplo n.º 11
0
Archivo: event.c Proyecto: bartman/wmii
void
xtime_kludge(void) {
	Window *w;
	WinAttr wa;
	XEvent e;
	long l;

	w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, &wa, 0);

	XSelectInput(display, w->xid, PropertyChangeMask);
	changeprop_long(w, "ATOM", "ATOM", &l, 0);
	XIfEvent(display, &e, findtime, (void*)w);

	destroywindow(w);
}
Ejemplo n.º 12
0
static char        *
ECommsWaitForMessage(void)
{
    XEvent              ev;
    char               *msg = NULL;

    while ((!msg) && (comms_win))
    {
        XIfEvent(dd, &ev, ev_check, NULL);
        if (ev.type == DestroyNotify)
            comms_win = 0;
        else
            msg = ECommsGet(&ev);
    }
    return msg;
}
Ejemplo n.º 13
0
Time
xfce_xsettings_get_server_time (Display *xdisplay,
                                Window   window)
{
    Atom   timestamp_atom;
    guchar c = 'a';
    XEvent xevent;

    /* get the current xserver timestamp */
    timestamp_atom = XInternAtom (xdisplay, "_TIMESTAMP_PROP", False);
    XChangeProperty (xdisplay, window, timestamp_atom, timestamp_atom,
                     8, PropModeReplace, &c, 1);
    XIfEvent (xdisplay, &xevent, xfce_xsettings_helper_timestamp_predicate,
              GUINT_TO_POINTER (window));

    return xevent.xproperty.time;
}
Ejemplo n.º 14
0
bool Window::configInitGLXWindow( GLXFBConfig* fbConfig )
{
    if( !_impl->xDisplay )
    {
        sendError( ERROR_GLXWINDOW_NO_DISPLAY );
        return false;
    }

    PixelViewport pvp = getPixelViewport();
    if( getIAttribute( IATTR_HINT_FULLSCREEN ) == ON )
    {
        const int screen = DefaultScreen( _impl->xDisplay );
        pvp.h = DisplayHeight( _impl->xDisplay, screen );
        pvp.w = DisplayWidth( _impl->xDisplay, screen );
        pvp.x = 0;
        pvp.y = 0;

        setPixelViewport( pvp );
    }

    XID drawable = _createGLXWindow( fbConfig, pvp );
    if( !drawable )
        return false;

    // map and wait for MapNotify event
    XMapWindow( _impl->xDisplay, drawable );

    XEvent event;
    XIfEvent( _impl->xDisplay, &event, WaitForNotify, (XPointer)(drawable) );

    XMoveResizeWindow( _impl->xDisplay, drawable, pvp.x, pvp.y, pvp.w, pvp.h );
    XFlush( _impl->xDisplay );

    // Grab keyboard focus in fullscreen mode
    if( getIAttribute( IATTR_HINT_FULLSCREEN ) == ON ||
        getIAttribute( IATTR_HINT_DECORATION ) == OFF )
    {
        XGrabKeyboard( _impl->xDisplay, drawable, True, GrabModeAsync,
                       GrabModeAsync, CurrentTime );
    }
    setXDrawable( drawable );

    LBVERB << "Created X11 drawable " << drawable << std::endl;
    return true;
}
Ejemplo n.º 15
0
slop::GLSelectRectangle::~GLSelectRectangle() {
    if ( m_window == None ) {
        return;
    }
    xengine->freeCRTCS( m_monitors );
    delete m_framebuffer;
    // Try to erase the window before destroying it.
    glClearColor( 0, 0, 0, 0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glXSwapBuffers( xengine->m_display, m_glxWindow );
    // Sleep for 0.1 seconds in hope that the rectangle was erased.
    usleep( 10000 );
    XDestroyWindow( xengine->m_display, m_window );
    XEvent event;
    // Block until the window is actually completely removed.
    XIfEvent( xengine->m_display, &event, &isDestroyNotify, (XPointer)&m_window );
    // Sleep for 0.1 seconds in hope that the screen actually cleared the window.
    usleep( 10000 );
}
Ejemplo n.º 16
0
void X11Window::setVisible(bool isVisible)
{
    if (isVisible)
    {
        XMapWindow(mDisplay, mWindow);

        // Wait until we get an event saying this window is mapped so that the
        // code calling setVisible can assume the window is visible.
        // This is important when creating a framebuffer as the framebuffer content
        // is undefined when the window is not visible.
        XEvent dummyEvent;
        XIfEvent(mDisplay, &dummyEvent, WaitForMapNotify, reinterpret_cast<XPointer>(mWindow));
    }
    else
    {
        XUnmapWindow(mDisplay, mWindow);
        XFlush(mDisplay);
    }
}
EGLNativeWindowType createSubWindow(FBNativeWindowType p_window,
                                    EGLNativeDisplayType display,
                                    int x, int y,int width, int height) {

    /* krnlyng */
    printf("creating sub window\n"); 
#ifndef X11
    if(get_server_references(display) < 0) return NULL;

    surface = wl_compositor_create_surface(compositor);
    if(surface == NULL)
    {
        fprintf(stderr, "Cannot create wl surface\n");
        return NULL;
    }

    shell_surface = wl_shell_get_shell_surface(shell, surface);
    wl_shell_surface_set_toplevel(shell_surface);

    create_opaque_region(width, height);

    EGLNativeWindowType win = wl_egl_window_create(surface, width, height);
    if(win == EGL_NO_SURFACE || win == NULL)
    {
        fprintf(stderr, "wl_egl_window_create failed\n");
    }
    printf("created sub window\n");

    return win;
#else
    XSetWindowAttributes wa;
    wa.event_mask = StructureNotifyMask;
    Window win = XCreateWindow(display,p_window,x,y, width,height,0,CopyFromParent,CopyFromParent,CopyFromParent,CWEventMask,&wa);
    XMapWindow(display,win);
    XEvent e;
    XIfEvent(display, &e, WaitForMapNotify, (char *)win);
    return win;
#endif
}
Ejemplo n.º 18
0
static void
meta_sync_free (MetaSync *self)
{
  /* When our assumptions don't hold, something has gone wrong but we
   * don't know what, so we reboot the ring. While doing that, we
   * trigger fences before deleting them to try to get ourselves out
   * of a potentially stuck GPU state.
   */
  switch (self->state)
    {
    case META_SYNC_STATE_WAITING:
      meta_gl_delete_sync (self->gpu_fence);
      break;
    case META_SYNC_STATE_DONE:
      /* nothing to do */
      break;
    case META_SYNC_STATE_RESET_PENDING:
      {
        XEvent event;
        XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
        meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
      }
      /* fall through */
    case META_SYNC_STATE_READY:
      XSyncTriggerFence (self->xdisplay, self->xfence);
      XFlush (self->xdisplay);
      break;
    default:
      break;
    }

  meta_gl_delete_sync (self->gl_x11_sync);
  XSyncDestroyFence (self->xdisplay, self->xfence);
  XSyncDestroyCounter (self->xdisplay, self->xcounter);
  XSyncDestroyAlarm (self->xdisplay, self->xalarm);

  g_free (self);
}
Ejemplo n.º 19
0
void init(int w, int h) {
    display = XOpenDisplay( NULL );
    if ( display == NULL ) {
        fprintf( stderr, "Bad DISPLAY (%s).\n", getenv( "DISPLAY" ) );
        exit( 1 );
    }

    int pbuffer_attributes[] = {
        GLX_RED_SIZE, 8,
        GLX_GREEN_SIZE, 8,
        GLX_BLUE_SIZE, 8,
        GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
        0
    };

    int attributes[] = {
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_RENDER_TYPE,   GLX_RGBA_BIT,
        GLX_RED_SIZE,      8,   /* Request a single buffered color buffer */
        GLX_GREEN_SIZE,    8,   /* with the maximum number of color bits  */
        GLX_BLUE_SIZE,     8,   /* for each component                     */
        None
    };


    int pb_nconfigs = 0;
    GLXFBConfig *pb_configs = glXChooseFBConfig( display,
                        DefaultScreen( display ),
                        pbuffer_attributes,
                        &pb_nconfigs );
    int nconfigs = 0;
    GLXFBConfig *configs = glXChooseFBConfig( display,
                        DefaultScreen( display ),
                        attributes,
                        &nconfigs );

    if ( !configs || !pb_configs) {
        fprintf( stderr, "Num configs: %d.\n", nconfigs );
        fprintf( stderr, "Num pbconfigs: %d.\n", pb_nconfigs );
        exit( 1 );
    }


    Window root = DefaultRootWindow(display);
    XVisualInfo* vi = glXGetVisualFromFBConfig(display, configs[0] );
    XSetWindowAttributes swa;
    swa.border_pixel = 0;
    swa.event_mask = StructureNotifyMask;
    swa.colormap = XCreateColormap( display, root, vi->visual, AllocNone );
    win = XCreateWindow(display, root, 0, 0, w, h, 0, vi->depth, InputOutput, vi->visual, CWEventMask | CWColormap, &swa);


    int pbuffer_create_attributes[] = {
        GLX_PBUFFER_WIDTH, w,
        GLX_PBUFFER_HEIGHT, h,
        0
    };


    XMapWindow(display, win);
    XStoreName(display, win, "Trajectory Visualizer");
    XEvent event;
    XIfEvent( display, &event, WaitForNotify, (XPointer) win);



    GLXPbuffer pbuffer = glXCreatePbuffer( display,
                     configs[ 0 ],
                     pbuffer_create_attributes );
    if ( !pbuffer ) {
        perror( "glXCreatePbuffer" );
        exit( 1 );
    }


    GLXWindow glxwin = glXCreateWindow( display, configs[0], win, NULL );

    GLXContext context = glXCreateNewContext( display,
                        configs[ 0 ],
                        GLX_RGBA_TYPE,
                        0,
                        GL_TRUE );


    GLXContext pbuffercontext = glXCreateNewContext( display,
                        pb_configs[ 0 ],
                        GLX_RGBA_TYPE,
                        0,
                        GL_TRUE );

    if ( glXMakeCurrent( display, pbuffer, context ) == 0 ) {
        perror( "glXMakeCurrent" );
        exit( 1 );
    }
    if (glXMakeContextCurrent( display, glxwin, glxwin, context ) == 0) {
        perror( "glXMakeContextCurrent" );
        exit( 1 );
    }
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
Ejemplo n.º 20
0
int ui_loop(int argc, char **argv, const char *name) {
	XVisualInfo *vi;
	Colormap cmap;
	XSetWindowAttributes swa;
	XSizeHints hint;
	GLXContext cx;
	XEvent event;
	int k, width, height;
	char buf[80];
	XEvent xev;
	KeySym keysym;
	XComposeStatus status;

	/* get a connection */
	dpy = XOpenDisplay(NULL);

	if (dpy == NULL) {
		fprintf(stderr, "Could not open X display\n");
		exit(1);
	}

	/* get an appropriate visual */
	vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);

	if (vi == NULL) {
		fprintf(stderr, "No suitable visual for glx\n");
		exit(1);
	}

	/* create a GLX context */
	cx = glXCreateContext(dpy, vi, 0, GL_TRUE);

	/* create a color map */
	cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
						   vi->visual, AllocNone);

	/* create a window */
	width = 400;
	height = 300;
	hint.x = 0;
	hint.y = 0;
	hint.width = width;
	hint.height = height;
	hint.flags = PPosition | PSize;
	swa.colormap = cmap;
	swa.border_pixel = 0;
	swa.event_mask = StructureNotifyMask;
	win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height,
						0, vi->depth, InputOutput, vi->visual,
						CWBorderPixel | CWColormap | CWEventMask, &swa);
	XSetStandardProperties(dpy, win, name, name, None, NULL, 0, &hint);

	XMapWindow(dpy, win);
	XIfEvent(dpy, &event, WaitForNotify, (char *)win);
	XSelectInput(dpy, win, KeyPressMask | StructureNotifyMask | ExposureMask);

	/* connect the context to the window */
	glXMakeCurrent(dpy, win, cx);

	init();
	reshape(width, height);

	while (1) {
		if (XPending(dpy) > 0) {
			XNextEvent(dpy, &xev);

			switch (xev.type) {
			case KeyPress:
				XLookupString((XKeyEvent *)&xev, buf, 80, &keysym, &status);

				switch (keysym) {
				case XK_Up:
					k = KEY_UP;
					break;

				case XK_Down:
					k = KEY_DOWN;
					break;

				case XK_Left:
					k = KEY_LEFT;
					break;

				case XK_Right:
					k = KEY_RIGHT;
					break;

				case XK_Escape:
					k = KEY_ESCAPE;
					break;

				default:
					k = keysym;
				}

				key(k, 0);
				break;

			case ConfigureNotify: {
				int width, height;
				width = xev.xconfigure.width;
				height = xev.xconfigure.height;
				glXWaitX();
				reshape(width, height);
			}
			break;
			}
		} else {
			idle();
		}
	}

	return 0;
}
Ejemplo n.º 21
0
static bool gfx_ctx_glx_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   XEvent event;
   bool true_full = false, windowed_full;
   int val, x_off = 0, y_off = 0;
   XVisualInfo *vi = NULL;
   XSetWindowAttributes swa = {0};
   int (*old_handler)(Display*, XErrorEvent*) = NULL;
   driver_t *driver = driver_get_ptr();
   gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)driver->video_context_data;
   struct sigaction sa = {{0}};
   settings_t *settings    = config_get_ptr();

   sa.sa_handler = glx_sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);

   if (!glx)
      return false;

   windowed_full = settings->video.windowed_fullscreen;
   true_full = false;

   vi = glXGetVisualFromFBConfig(glx->g_dpy, glx->g_fbc);
   if (!vi)
      goto error;

   swa.colormap = glx->g_cmap = XCreateColormap(glx->g_dpy,
         RootWindow(glx->g_dpy, vi->screen), vi->visual, AllocNone);
   swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
      ButtonReleaseMask | ButtonPressMask;
   swa.override_redirect = fullscreen ? True : False;

   if (fullscreen && !windowed_full)
   {
      if (x11_enter_fullscreen(glx->g_dpy, width, height, &glx->g_desktop_mode))
      {
         glx->g_should_reset_mode = true;
         true_full = true;
      }
      else
         RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n");
   }

   if (settings->video.monitor_index)
      glx->g_screen = settings->video.monitor_index - 1;

#ifdef HAVE_XINERAMA
   if (fullscreen || glx->g_screen != 0)
   {
      unsigned new_width  = width;
      unsigned new_height = height;

      if (x11_get_xinerama_coord(glx->g_dpy, glx->g_screen,
               &x_off, &y_off, &new_width, &new_height))
         RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", glx->g_screen);
      else
         RARCH_LOG("[GLX]: Xinerama is not active on screen.\n");

      if (fullscreen)
      {
         width  = new_width;
         height = new_height;
      }
   }
#endif

   RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n",
         x_off, y_off, width, height);

   glx->g_win = XCreateWindow(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen),
         x_off, y_off, width, height, 0,
         vi->depth, InputOutput, vi->visual, 
         CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa);
   XSetWindowBackground(glx->g_dpy, glx->g_win, 0);

   glx->g_glx_win = glXCreateWindow(glx->g_dpy, glx->g_fbc, glx->g_win, 0);

   x11_set_window_attr(glx->g_dpy, glx->g_win);

   if (fullscreen)
      x11_show_mouse(glx->g_dpy, glx->g_win, false);

   if (true_full)
   {
      RARCH_LOG("[GLX]: Using true fullscreen.\n");
      XMapRaised(glx->g_dpy, glx->g_win);
   }
   else if (fullscreen) /* We attempted true fullscreen, but failed. Attempt using windowed fullscreen. */
   {
      XMapRaised(glx->g_dpy, glx->g_win);
      RARCH_LOG("[GLX]: Using windowed fullscreen.\n");
      /* We have to move the window to the screen we want to go fullscreen on first.
       * x_off and y_off usually get ignored in XCreateWindow().
       */
      x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height);
      x11_windowed_fullscreen(glx->g_dpy, glx->g_win);
   }
   else
   {
      XMapWindow(glx->g_dpy, glx->g_win);
      // If we want to map the window on a different screen, we'll have to do it by force.
      // Otherwise, we should try to let the window manager sort it out.
      // x_off and y_off usually get ignored in XCreateWindow().
      if (glx->g_screen)
         x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height);
   }

   XIfEvent(glx->g_dpy, &event, glx_wait_notify, NULL);

   if (!glx->g_ctx)
   {
      if (glx->g_core_es || glx->g_debug)
      {
         int attribs[16];
         int *aptr = attribs;

         if (glx->g_core_es)
         {
            *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB;
            *aptr++ = g_major;
            *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB;
            *aptr++ = g_minor;

            if (glx->g_core_es_core)
            {
               /* Technically, we don't have core/compat until 3.2.
                * Version 3.1 is either compat or not depending on GL_ARB_compatibility.
                */
               *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB;
#ifdef HAVE_OPENGLES2
               *aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT;
#else
               *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
#endif
            }
         }

         if (glx->g_debug)
         {
            *aptr++ = GLX_CONTEXT_FLAGS_ARB;
            *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB;
         }

         *aptr = None;
         glx->g_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, NULL, True, attribs);
         if (glx->g_use_hw_ctx)
         {
            RARCH_LOG("[GLX]: Creating shared HW context.\n");
            glx->g_hw_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, glx->g_ctx, True, attribs);
            if (!glx->g_hw_ctx)
               RARCH_ERR("[GLX]: Failed to create new shared context.\n");
         }
      }
      else
      {
         glx->g_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, 0, True);
         if (glx->g_use_hw_ctx)
         {
            glx->g_hw_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, glx->g_ctx, True);
            if (!glx->g_hw_ctx)
               RARCH_ERR("[GLX]: Failed to create new shared context.\n");
         }
      }

      if (!glx->g_ctx)
      {
         RARCH_ERR("[GLX]: Failed to create new context.\n");
         goto error;
      }
   }
   else
   {
      driver->video_cache_context_ack = true;
      RARCH_LOG("[GLX]: Using cached GL context.\n");
   }

   glXMakeContextCurrent(glx->g_dpy, glx->g_glx_win, glx->g_glx_win, glx->g_ctx);
   XSync(glx->g_dpy, False);

   g_quit_atom = XInternAtom(glx->g_dpy, "WM_DELETE_WINDOW", False);
   if (g_quit_atom)
      XSetWMProtocols(glx->g_dpy, glx->g_win, &g_quit_atom, 1);

   glXGetConfig(glx->g_dpy, vi, GLX_DOUBLEBUFFER, &val);
   glx->g_is_double = val;

   if (glx->g_is_double)
   {
      const char *swap_func = NULL;

      g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
      g_pglSwapIntervalSGI = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
      g_pglSwapInterval    = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");

      if (g_pglSwapIntervalEXT)
         swap_func = "glXSwapIntervalEXT";
      else if (g_pglSwapInterval)
         swap_func = "glXSwapIntervalMESA";
      else if (g_pglSwapIntervalSGI)
         swap_func = "glXSwapIntervalSGI";

      if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI)
         RARCH_WARN("[GLX]: Cannot find swap interval call.\n");
      else
         RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func);
   }
   else
      RARCH_WARN("[GLX]: Context is not double buffered!.\n");

   gfx_ctx_glx_swap_interval(data, glx->g_interval);

   /* This can blow up on some drivers. It's not fatal, so override errors for this call. */
   old_handler = XSetErrorHandler(glx_nul_handler);
   XSetInputFocus(glx->g_dpy, glx->g_win, RevertToNone, CurrentTime);
   XSync(glx->g_dpy, False);
   XSetErrorHandler(old_handler);

   XFree(vi);
   glx->g_has_focus = true;

   if (!x11_create_input_context(glx->g_dpy, glx->g_win, &glx->g_xim, &glx->g_xic))
      goto error;

   driver->display_type  = RARCH_DISPLAY_X11;
   driver->video_display = (uintptr_t)glx->g_dpy;
   driver->video_window  = (uintptr_t)glx->g_win;
   glx->g_true_full = true_full;

   return true;

error:
   if (vi)
      XFree(vi);

   ctx_glx_destroy_resources(glx);

   if (glx)
      free(glx);

   return false;
}
Ejemplo n.º 22
0
// Initialize GLUT & OpenSG and start the cluster server
int main(int argc,char **argv)
{
    const char     *name           = "ClusterServer";
    const char     *connectionType = "StreamSock";
    bool            fullscreen     = true;
    std::string     address        = "";
    bool            doStereo       = false;
    std::string     serviceGroup   = "224.245.211.234";


    // evaluate params
    for(int a=1 ; a<argc ; ++a)
    {
        if(argv[a][0] == '-')
        {
            switch(argv[a][1])
            {
                case 'm': 
                    connectionType="Multicast";
                          break;

                case 's':
                    doStereo=true;
                    break;

                case 'w': 
                    fullscreen=false;
                    break;

                case 'e':
                    exitOnError=true;
                    break;

                case 'a': address = argv[a][2] ? argv[a]+2 : argv[++a];
                          if(address == argv[argc])
                          { 
                              SLOG << "address missing" << OSG::endLog;
                              return 0;
                          }
                          std::cout << address << OSG::endLog;
                          break;


                case 'j':
                    if(argv[a][2] != '\0')
                        serviceGroup=argv[a]+2;
                    else
                        serviceGroup=argv[++a];
                    break;
              
                case 'h':
                default:  
                    std::cout << argv[0] 
                              << "-m "
                              << "-s "
                              << "-w "
                              << "-e "
                              << "-a Address "
                              << "-j group "
                              << std::endl;
                    std::cout << "-m         use multicast" << std::endl;
                    std::cout << "-s         enable stereo" << std::endl;
                    std::cout << "-w         no fullscreen" << std::endl;
                    std::cout << "-e         exit after closed connection" 
                              << std::endl;
                    std::cout << "-a Address Server network address"
                              << std::endl;
                    std::cout << "-m Address wait for requests on "
                              << "multicast group" << std::endl;
                    std::cout << "-p port    wait for requests on port"
                              << std::endl;
                    return 0;
            }
        }
        else
        {
            name=argv[a];
        }
    }
    try
    {
        // init OpenSG
        OSG::osgInit(argc, argv);

        int snglBuf[] = {GLX_RGBA, 
                         GLX_DEPTH_SIZE, 16, 
                         None};
        
        int dblBuf[16];

        dblBuf[0] = GLX_RGBA;
        dblBuf[1] = GLX_DEPTH_SIZE;
        dblBuf[2] = 16;
        dblBuf[3] = GLX_DOUBLEBUFFER;
        dblBuf[4] = (doStereo == true) ? GLX_STEREO : None;
        dblBuf[5] = None;

        // X init
        OSG::DisplayP dpy = XOpenDisplay(NULL);

        if(dpy == NULL) 
        {
            std::cerr << "Error: Could not open display!" << std::endl;
        }

        int dummy;

        if(!glXQueryExtension( dpy, &dummy, &dummy))
        {
            std::cerr << "Error: X server has no OpenGL GLX extension"
                      << std::endl;
        }
        
        XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);

        if(vi == NULL) 
        {
            vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);

            if(vi == NULL)
            {
                std::cerr << "no RGB visual with depth buffer" << std::endl;
            }
        }

        if(vi->c_class != TrueColor)
        {
            std::cerr << "TrueColor visual required for this program"
                      << std::endl;
        }
        
        Colormap cmap = XCreateColormap(dpy, 
                                        RootWindow(dpy, vi->screen), 
                                        vi->visual, 
                                        AllocNone);
        XSetWindowAttributes swa;

        swa.colormap = cmap;
        swa.border_pixel = 0;
        swa.event_mask = 
            ExposureMask      | 
            ButtonPressMask   | 
            ButtonReleaseMask |
            KeyPressMask      |
            Button1MotionMask |
            Button2MotionMask |
            Button3MotionMask | 
            StructureNotifyMask;
        
        // Create Window
        
        // Create a Window and connect it to the main display dpy
        OSG::X11Window hwin = XCreateWindow(dpy, 
                                            RootWindow(dpy, vi->screen), 
                                            0, 0, 300, 300, 
                                            0, 
                                            vi->depth,
                                            InputOutput, 
                                            vi->visual, 
                                            CWBorderPixel | 
                                            CWColormap    | 
                                            CWEventMask, 
                                            &swa );
        
        XSetStandardProperties(dpy, hwin, "testWindowX", "testWindowX", 
                               None, argv, argc, NULL);
        
        if(fullscreen == true)
        {
            Atom noDecorAtom = XInternAtom(dpy, 
                                           "_MOTIF_WM_HINTS",
                                           0);
            
            if(noDecorAtom == None) 
            {
                fprintf(stderr,
                        "Could not intern X atom for _MOTIF_WM_HINTS.\n");
            }
            
            struct NoDecorHints 
            {
                long flags;
                long functions;
                long decorations;
                long input_mode;
            };
            
            NoDecorHints oHints;
            
            oHints.flags = 2;
            oHints.decorations = 0;
            
            XChangeProperty(dpy, 
                            hwin,
                            noDecorAtom, 
                            noDecorAtom, 
                            32,
                            PropModeReplace, 
                            reinterpret_cast<unsigned char *>(&oHints), 4);

        }
        

        // create the render action
        ract = OSG::RenderAction::create();

        // setup the OpenSG Glut window
        window     = OSG::XWindow::create();
        window->setDisplay ( dpy );
        window->setWindow ( hwin );
        window->init();

        XEvent        event;

        XMapWindow(dpy, hwin);
        XIfEvent(dpy, &event, wait_for_map_notify, reinterpret_cast<char *>(hwin));

        if(fullscreen == true)
        {
            XMoveWindow  (dpy, hwin, 0, 0);
            XResizeWindow(dpy, hwin,
                          DisplayWidth (dpy, vi->screen),
                          DisplayHeight(dpy, vi->screen));

            static char data[1] = {0};

            Cursor cursor;
            Pixmap blank;
            XColor dummyCol;
            
            blank = XCreateBitmapFromData(dpy, 
                                          hwin,
                                          data, 1, 1);

            cursor = XCreatePixmapCursor(dpy, 
                                         blank, 
                                         blank,
                                         &dummyCol, &dummyCol, 0, 0);

            XFreePixmap(dpy, blank);

            XDefineCursor(dpy,
                          hwin, 
                          cursor);
            XFlush(dpy);
        }

        window->activate();
       
        glEnable( GL_LIGHTING );
        glEnable( GL_LIGHT0 );
        glEnable( GL_NORMALIZE );

        // create the cluster server
        server     = new OSG::ClusterServer(window,name,connectionType,address);
        // start the server
        server->start();

        bool   stopIt = false;
        int ip;

        while(!stopIt) 
        {
            while((ip = XPending(dpy)) != 0)
            {
                XNextEvent(dpy, &event);

                switch (event.type) 
                {
                    case ConfigureNotify:
                    {
                        reshape(event.xconfigure.width,
                                event.xconfigure.height);
                    }
                    break;

                    case Expose:
                        display();
                        break;

                } 
                
            }

            display();
        }   
    }
    catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
    {
        SLOG << e.what() << OSG::endLog;
        delete server;

        ract   = NULL;
        window = NULL;
        
        OSG::osgExit(); 
    }
    return 0;
}
Ejemplo n.º 23
0
/*!***********************************************************************
 @Function		OpenX11Window
 @Return		true on success
 @Description	Opens an X11 window. This must be called after
				SelectEGLConfiguration() for gEglConfig to be valid
*************************************************************************/
int PVRShellInitOS::OpenX11Window(const PVRShell &shell)
{
    XSetWindowAttributes	WinAttibutes;
    XSizeHints				sh;
    XEvent					event;
    unsigned long			mask;

#ifdef BUILD_OGL
    XF86VidModeModeInfo **modes;       // modes of display
    int numModes;                      // number of modes of display
    int chosenMode;
    int edimx,edimy;                   //established width and height of the chosen modeline
    int i;
#endif

	int depth = DefaultDepth(m_X11Display, m_X11Screen);
	m_X11Visual = new XVisualInfo;
	XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual);

    if( !m_X11Visual )
    {
    	shell.PVRShellOutputDebug( "Unable to acquire visual" );
    	return false;
    }

    m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone );

#ifdef BUILD_OGL
    m_i32OriginalModeDotClock = XF86VidModeBadClock;
    if(shell.m_pShellData->bFullScreen)
    {
        // Get mode lines to see if there is requested modeline
        XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes);

        // look for mode with requested resolution
        chosenMode = -1;
        i=0;
        while((chosenMode == -1)&&(i<numModes))
        {
            if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY))
            {
                chosenMode = i;
            }
            ++i;
        }

        // If there is no requested resolution among modelines then terminate
        if(chosenMode == -1)
        {
            shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" );
            return false;
        }

        // save desktop-resolution before switching modes
        XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode );

        XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]);
        XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0);
        edimx = modes[chosenMode]->hdisplay;
        edimy = modes[chosenMode]->vdisplay;
        printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode);
        XFree(modes);

		WinAttibutes.colormap = m_X11ColorMap;
		WinAttibutes.background_pixel = 0xFFFFFFFF;
		WinAttibutes.border_pixel = 0;
        WinAttibutes.override_redirect = true;

		// add to these for handling other events
		WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;

        // The diffrence is that we want to ignore influence of window manager for our fullscreen window
        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect;

        m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0,
                                    CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes);

        // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen
        XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0);

        // Map and then wait till mapped, grabbing should be after mapping the window
        XMapWindow( m_X11Display, m_X11Window );
        XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime);
        XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );

    }
    else
#endif
    {
        // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it)
        // so if requested resolution differs from the display dims then we quit
        #ifndef BUILD_OGL
        int display_width  = XDisplayWidth(m_X11Display,m_X11Screen);
        int display_height = XDisplayHeight(m_X11Display,m_X11Screen);
        if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) {
            shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" );
            return false;
        }
        #endif


		WinAttibutes.colormap = m_X11ColorMap;
		WinAttibutes.background_pixel = 0xFFFFFFFF;
		WinAttibutes.border_pixel = 0;

		// add to these for handling other events
		WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;

		// The attribute mask
        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ;

        m_X11Window = XCreateWindow(  m_X11Display, 						// Display
									RootWindow(m_X11Display, m_X11Screen), 	// Parent
									shell.m_pShellData->nShellPosX, 	// X position of window
									shell.m_pShellData->nShellPosY,		// Y position of window
									shell.m_pShellData->nShellDimX,		// Window width
									shell.m_pShellData->nShellDimY,		// Window height
									0,									// Border width
									CopyFromParent, 					// Depth (taken from parent)
									InputOutput, 						// Window class
									CopyFromParent, 					// Visual type (taken from parent)
									mask, 								// Attributes mask
									&WinAttibutes);						// Attributes

		// Set the window position
        sh.flags = USPosition;
        sh.x = shell.m_pShellData->nShellPosX;
        sh.y = shell.m_pShellData->nShellPosY;
        XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh );

        // Map and then wait till mapped
        XMapWindow( m_X11Display, m_X11Window );
        XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );

        // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2)
        if(shell.m_pShellData->bFullScreen)
        {
			XEvent xev;
			Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False);
			Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False);

			memset(&xev, 0, sizeof(XEvent));
			xev.type = ClientMessage;
			xev.xclient.window = m_X11Window;
			xev.xclient.message_type = wmState;
			xev.xclient.format = 32;
			xev.xclient.data.l[0] = 1;
			xev.xclient.data.l[1] = wmStateFullscreen;
			xev.xclient.data.l[2] = 0;
			XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev);
        }

        Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1);
        XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 );
    }

    XFlush( m_X11Display );

    return true;
}
Ejemplo n.º 24
0
/////////////////////////////////////////////////////////
// createMess
//
/////////////////////////////////////////////////////////
bool gemglxwindow :: create(void)
{
  bool success=true;
  /*
   * hmm, this crashes when enabled
   * when disabled, we don't get textures on two screens
   */
  //~#warning context-sharing disabled
  bool context_sharing=false;
  if(!m_context
      && context_sharing) { /* gemglxwindow::PIMPL::s_shared.count(m_display)>0 */

    gemglxwindow::PIMPL*sharedPimpl=&gemglxwindow::PIMPL::s_shared[m_display];
    if(!sharedPimpl->glxcontext) {
      try {
        int x=0, y=0;
        unsigned int w=1, h=1;
        success=sharedPimpl->create(m_display, 2, false, false, x, y, w, h,
                                    m_transparent);
      } catch (GemException&ex) {
        error("creation of shared glxcontext failed: %s", ex.what());
        verbose(0, "continuing at your own risk!");
      }
      if(!sharedPimpl->gemcontext) {
        try {
          sharedPimpl->gemcontext = createContext();
        } catch (GemException&ex) {
          sharedPimpl->gemcontext = NULL;
          error("creation of shared gem::context failed: %s", ex.what());
        }
      }
    }

    m_context=sharedPimpl->gemcontext;
  } else { // no context sharing
    /* creation of gem::Context is deferred until *after* window creation */
  }

  int modeNum=4;
#ifdef HAVE_LIBXXF86VM
  XF86VidModeModeInfo **modes;
#endif
  char svalue[3];
  snprintf(svalue, 3, "%d", m_fsaa);
  svalue[2]=0;
  if (m_fsaa!=0) {
    setenv("__GL_FSAA_MODE", svalue, 1);  // this works only for NVIDIA-cards
  }


  try {
    success=m_pimpl->create(m_display, m_buffer, m_fullscreen, m_border,
                            m_xoffset, m_yoffset, m_width, m_height, m_transparent);
  } catch (GemException&x) {
    x.report();
    success=false;
  }
  if(!success) {
    return false;
  }

  /* create a gem::context if we don't already have (a shared) one */
  if(!m_context) {
    try {
      m_context = createContext();
    } catch (GemException&x) {
      m_context = NULL;
      error("creation of gem::context failed: %s", x.what());
    }
  }


  XMapRaised(m_pimpl->dpy, m_pimpl->win);
  //  XMapWindow(m_pimpl->dpy, m_pimpl->win);
  XEvent report;
  XIfEvent(m_pimpl->dpy, &report, WaitForNotify, (char*)m_pimpl->win);
  if (glXIsDirect(m_pimpl->dpy, m_pimpl->glxcontext)) {
    post("Direct Rendering enabled!");
  }

  cursorMess(m_cursor);
  titleMess(m_title);
  return createGemWindow();
}
Ejemplo n.º 25
0
int main(int argc, char **argv)
{
  XVisualInfo *vi;
  Colormap cmap;
  XSetWindowAttributes swa;
  Window win;
  GLXContext cx;
  XEvent event;
  fd_set readfds;
  struct timeval timeout;
  int xServerFD;
  int nselected;
    
  /* get a connection */
  xDisplay = XOpenDisplay(0);
  if (xDisplay == NULL) {
    fprintf(stderr, "can't open display\n");
    exit(1);
  }
    
  /* get an appropriate visual */
  vi = glXChooseVisual(xDisplay, DefaultScreen(xDisplay), attributeList);
  if (vi == NULL) {
    fprintf(stderr, "can't get visual\n");
    exit(1);
  }
    
  /* create a GLX context */
  cx = glXCreateContext(xDisplay, vi, 0, GL_FALSE);
  if (cx == NULL) {
    fprintf(stderr, "can't create GL context\n");
    exit(1);
  }
    
  /* create a color map */
  cmap = XCreateColormap(xDisplay, RootWindow(xDisplay, vi->screen), vi->visual, AllocNone);
    
  /* create a window */
  swa.colormap = cmap;
  swa.border_pixel = 0;
  swa.event_mask = StructureNotifyMask;

  windowWidth = 500;
  windowHeight = 500;
    
  win = XCreateWindow(xDisplay, RootWindow(xDisplay, vi->screen), 0, 0, windowWidth, windowHeight,
                      0, vi->depth, InputOutput, vi->visual,
                      CWBorderPixel|CWColormap|CWEventMask, &swa);

  XSelectInput(xDisplay, win, KeyPressMask | ExposureMask | StructureNotifyMask);
    
  XMapWindow(xDisplay, win);
  // wait for the window to be mapped
  XIfEvent(xDisplay, &event, WaitForNotify, (char*)win);
  /* connect the context to the window */
  glXMakeCurrent(xDisplay, win, cx);

  quad = gluNewQuadric();
  if (quad == NULL) {
    fprintf(stderr, "can't allocate quadric\n");
    exit(1);
  }

  resetEye();

  xServerFD = ConnectionNumber(xDisplay);
  XFlush(xDisplay);
  
  while (1) {
    while (processX()) {
    }
    if (needRepaint) {
      doPaint();
    }
    FD_ZERO(&readfds);
    if (!atEOF) {
      FD_SET(0, &readfds);
    }
    FD_SET(xServerFD, &readfds);
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    nselected = select(xServerFD+1, &readfds, NULL, NULL, atEOF ? &timeout : NULL);
    if (nselected < 0) {
      perror("select");
      continue;
    }
    if (nselected == 0) {
      continue;
    }
    if (FD_ISSET(0, &readfds)) {
      processStdin();
    }
  }
}
Ejemplo n.º 26
0
// needs to be run after SelectEGLConfiguration()
// for gEglConfig to be valid
int PVRShellInitOS::OpenX11Window(const PVRShell &shell)
{
    XSetWindowAttributes	wa;
    XSizeHints				sh;
    XEvent					event;
    unsigned long			mask;
    #ifdef BUILD_OGL
    XF86VidModeModeInfo **modes;       // modes of display
    int numModes;                      // number of modes of display
    int chosenMode;
    int edimx,edimy;                   //established width and height of the chosen modeline
    int i;
    #endif
    MyHints mwmhints;
    Atom prop;

	int depth = DefaultDepth(x11display, x11screen);
	x11visual = new XVisualInfo;
	XMatchVisualInfo( x11display, x11screen, depth, TrueColor, x11visual);

    if( !x11visual )
    {
    	shell.PVRShellOutputDebug( "Unable to acquire visual" );
    	return false;
    }

    x11colormap = XCreateColormap( x11display, RootWindow(x11display, x11screen), x11visual->visual, AllocNone );

    #ifdef BUILD_OGL
    originalMode_dotclock = XF86VidModeBadClock;
    if(shell.m_pShellData->bFullScreen) {

        // Get mode lines to see if there is requested modeline
        XF86VidModeGetAllModeLines(x11display, x11screen, &numModes, &modes);
        /* look for mode with requested resolution */
        chosenMode = -1;
        i=0;
        while((chosenMode == -1)&&(i<numModes))
        {
            if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY))
            {
                chosenMode = i;
            }
            ++i;
        }

        // If there is no requested resolution among modelines then terminate
        if(chosenMode == -1)
        {
            shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" );
            return false;
        }

        /* save desktop-resolution before switching modes */
        XF86VidModeGetModeLine(x11display,x11screen, &originalMode_dotclock, &originalMode );

        XF86VidModeSwitchToMode(x11display, x11screen, modes[chosenMode]);
        XF86VidModeSetViewPort(x11display, x11screen, 0, 0);
        edimx = modes[chosenMode]->hdisplay;
        edimy = modes[chosenMode]->vdisplay;
        printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode);
        XFree(modes);       //to musi byc globalne

        wa.colormap = x11colormap;
        wa.background_pixel = 0xFFFFFFFF;
        wa.border_pixel = 0;
        wa.override_redirect = true;

        // add to these for handling other events
        wa.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;

        // The diffrence is that we want to ignore influence of window manager for outr fullscreen window
        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect;

        x11window = XCreateWindow( x11display, RootWindow(x11display, x11screen), 0, 0, edimx, edimy, 0,
                                    CopyFromParent, InputOutput, CopyFromParent, mask, &wa);
        // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen
        XWarpPointer(x11display, None ,x11window, 0, 0, 0, 0, 0, 0);
        // Map and then wait till mapped, grabbing should be after mapping the window
        XMapWindow( x11display, x11window );
        XGrabKeyboard(x11display, x11window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(x11display, x11window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, x11window, None, CurrentTime);
        XIfEvent( x11display, &event, WaitForMapNotify, (char*)x11window );

    } else {
    #endif
        wa.colormap = x11colormap;
        wa.background_pixel = 0xFFFFFFFF;
        wa.border_pixel = 0;

        // add to these for handling other events
        wa.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;

        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ;

        x11window = XCreateWindow( x11display, RootWindow(x11display, x11screen), shell.m_pShellData->nShellPosX, shell.m_pShellData->nShellPosY,
                                    shell.m_pShellData->nShellDimX, shell.m_pShellData->nShellDimY, 0,
                                    CopyFromParent, InputOutput, CopyFromParent, mask, &wa);
        // todo:meh remove this?
        sh.flags = USPosition;
        sh.x = shell.m_pShellData->nShellPosX;
        sh.y = shell.m_pShellData->nShellPosY;
        XSetStandardProperties( x11display, x11window, szTitle, szTitle, None, 0, 0, &sh );
        // Map and then wait till mapped
        XMapWindow( x11display, x11window );
        XIfEvent( x11display, &event, WaitForMapNotify, (char*)x11window );
        // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2)
        if(shell.m_pShellData->bFullScreen) {
            memset(&mwmhints, 0, sizeof(mwmhints));
            prop = XInternAtom(x11display, "_MOTIF_WM_HINTS", False);
            mwmhints.flags = 2;//MWM_HINTS_DECORATIONS;
            mwmhints.decorations = 0;
            XChangeProperty(x11display, x11window, prop, prop, 32, PropModeReplace,
            (unsigned char *) &mwmhints,5);
        }
        //
        Atom wmDelete = XInternAtom(x11display, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(x11display, x11window, &wmDelete, 1);
        XSetWMColormapWindows( x11display, x11window, &x11window, 1 );
    #ifdef BUILD_OGL
    }
    #endif

    XFlush( x11display );

    return true;
}
Ejemplo n.º 27
0
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive)
{
	MFCALLSTACK;

	MFZeroMemory(gXKeys, sizeof(gXKeys));
	MFZeroMemory(&gXMouse, sizeof(gXMouse));
	gXMouse.x = -1;

	gDisplay.fullscreenWidth = gDisplay.width = width;
	gDisplay.fullscreenHeight = gDisplay.height = height;
	gDisplay.refreshRate = 0;
	gDisplay.colourDepth = 0; /* Use default.  Chances are, it's something sane */
	gDisplay.windowed = true;
	gDisplay.wide = false;
	gDisplay.progressive = true;

	if(!(xdisplay = XOpenDisplay(NULL)))
	{
		MFDebug_Error("Unable to open display");
		MFDisplay_DestroyDisplay();
		return 1;
	}

	screen = DefaultScreen(xdisplay);
	rootWindow = RootWindow(xdisplay, screen);

	// build our internal list of available video modes
	GetModes(&modes, !gDisplay.windowed);
	while(!FindMode(modes, width, height))
	{
		if(!gDisplay.windowed)
		{
			// no fullscreen mode, try windowed mode instead
			MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode");

			gDisplay.windowed = true;

			FreeModes();
			GetModes(&modes, false);
		}
		else
		{
			// default is some sort of custom mode that doesn't appear in the windowed mode list
			// HACK: we'll add it to the end..
			modes[numModes].width = width;
			modes[numModes].height = height;
			currentMode = numModes;
			++numModes;
			break;
		}
	}

	DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback);
	DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback);

	// Set full screen mode, if necessary
	if(!gDisplay.windowed && numModes > 1)
	{
		if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode]))
		{
			MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode");
			MFDisplay_DestroyDisplay();
			return 1;
		}
	}

	XVisualInfo *MFRenderer_GetVisualInfo();
	XVisualInfo *visualInfo = MFRenderer_GetVisualInfo();
	if(!visualInfo)
		return 1;

	if(!(colorMap = XCreateColormap(xdisplay, rootWindow, visualInfo->visual, AllocNone)))
	{
		MFDebug_Error("Unable to create colourmap");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	XSetWindowAttributes windowAttrs;
	windowAttrs.colormap = colorMap;
	windowAttrs.cursor = None;
	windowAttrs.event_mask = StructureNotifyMask;
	windowAttrs.border_pixel = BlackPixel(xdisplay, screen);
	windowAttrs.background_pixel = BlackPixel(xdisplay, screen);

	if(!(window = XCreateWindow(xdisplay, rootWindow, 0, 0, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask, &windowAttrs)))
	{
		MFDebug_Error("Unable to create X Window");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	// Tell the window manager not to allow our window to be resized.  But some window managers can ignore me and do it anyway.  Typical X-Windows.
	if((sizeHints = XAllocSizeHints()) == NULL)
	{
		MFDebug_Error("Unable to alloc XSizeHints structure, out of memory?");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	sizeHints->flags = PSize | PMinSize | PMaxSize;
    sizeHints->min_width = sizeHints->max_width = sizeHints->base_width = width;
    sizeHints->min_height = sizeHints->max_height = sizeHints->base_height = height;

	XSetWMNormalHints(xdisplay, window, sizeHints);

	// Window title
	XStoreName(xdisplay, window, gDefaults.display.pWindowTitle);

	XWMHints *wmHints;
	if((wmHints = XAllocWMHints()) == NULL)
	{
		MFDebug_Error("Unable to alloc XWMHints structure, out of memory?");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	wmHints->flags = InputHint | StateHint;
	wmHints->input = true;
	wmHints->initial_state = NormalState;
	if(!XSetWMHints(xdisplay, window, wmHints))
	{
		MFDebug_Error("Unable to set WM hints for window");
		XFree(visualInfo);
		MFDisplay_DestroyDisplay();
		return 1;
	}

	XFree(wmHints);
	XFree(visualInfo);

	// Tell the window manager that I want to be notified if the window's closed
	wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false);
	if(!XSetWMProtocols(xdisplay, window, &wm_delete_window, 1))
	{
		MFDebug_Error("Unable to set Window Manager protocols");
		MFDisplay_DestroyDisplay();
		return 1;
	}

	XSelectInput(xdisplay, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask);

	if(!XMapRaised(xdisplay, window))
	{
		MFDebug_Error("Unable to map new window");
		MFDisplay_DestroyDisplay();
		return 1;
	}

	// Wait for the window to be mapped, etc. The documentation doesn't indicate that this is necessary, but every GLX program I've ever seen does it, so I assume it is.
	XEvent event;
	XIfEvent(xdisplay, &event, WaitForNotify, (char *)window);

	MFRenderer_CreateDisplay();

	if(!gDisplay.windowed && numModes > 1)
	{
		if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode]))
		{
			MFDebug_Error("Unable to set screen mode");
			MFDisplay_DestroyDisplay();
			return 1;
		}

		XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);

		XFlush(xdisplay);
		// A little trick to make sure the entire window is on the screen
		XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1);
		XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0);
		XFlush(xdisplay);
	}

	return 0;
}
Ejemplo n.º 28
0
int wincreat( int x, int y, int width, int height, char *title)
{
    XSetWindowAttributes   swa;
    Colormap               cmap;
    XVisualInfo           *vi;
    int                    dummy;
    GLXContext             glcx;
    XEvent                 event;
    int                    attributes[] = { GLX_RGBA,
                                            GLX_DEPTH_SIZE, 16,
                                            GLX_RED_SIZE, 8,
                                            GLX_GREEN_SIZE, 8,
                                            GLX_BLUE_SIZE, 8,
                                            GLX_ALPHA_SIZE, 8,
                                            GLX_DOUBLEBUFFER,
                                            None
                                          };

    if( !(dpy = XOpenDisplay( NULL )) )    /* defaults to $DISPLAY */
    {
        fprintf( stderr, "Unable to open display.\n" );
        exit( 1 );

    } else {

        /*printf( "Connected to display... %s (%s).\n", dpy->display_name, dpy->vendor );*/

    }   /* end if( ) */

    if( !glXQueryExtension( dpy, &dummy, &dummy ) )
    {
        fprintf( stderr, "Unable to query GLX extensions.\n" );
        exit( 1 );

    }   /* end if( ) */

    if( !(vi = glXChooseVisual( dpy, DefaultScreen( dpy ), attributes )) )
    {
        fprintf( stderr, "Unable get a visual.\n" );
        exit( 1 );

    }   /* end if( ) */

    if( vi->class != TrueColor )
    {
        fprintf( stderr, "Need TrueColor class.\n" );
        exit( 1 );
    }

    if( !(glcx = glXCreateContext( dpy, vi, None, GL_TRUE )) )
    {
        fprintf( stderr, "Unable create a GL context.\n" );
        exit( 1 );

    }   /* end if( ) */

    cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ),
                            vi->visual, AllocNone );

    swa.colormap                  = cmap;
    swa.border_pixel              = 0;
    swa.event_mask                = ExposureMask
                                    | KeyPressMask
                                    | StructureNotifyMask;

    glwin = XCreateWindow(        dpy,
                                  RootWindow( dpy, vi->screen ),
                                  x,
                                  y,
                                  width,
                                  height,
                                  0,
                                  vi->depth,
                                  InputOutput,
                                  vi->visual,
                                  CWBorderPixel   |
                                  CWColormap      |
                                  CWEventMask,
                                  &swa
                         );

    /* Make a clear cursor so it looks like we have none. */
    {
        Pixmap pixmap;
        Cursor cursor;
        XColor color;
        char clear_bits[32];

        memset(clear_bits, 0, sizeof(clear_bits));

        pixmap = XCreatePixmapFromBitmapData(dpy, glwin, clear_bits,
                                             16, 16, 1, 0, 1);
        cursor = XCreatePixmapCursor(dpy, pixmap, pixmap, &color, &color, 8, 8);
        XDefineCursor(dpy, glwin, cursor);

        XFreePixmap(dpy, pixmap);
    }


    XSetStandardProperties( dpy, glwin, title, title, None, NULL, 0, NULL );

    if( !glXMakeCurrent( dpy, glwin, glcx ) )
    {
        fprintf( stderr, "Failed to make the GL context current.\n" );
        exit( 1 );
    }

    XMapWindow( dpy, glwin );
    XIfEvent( dpy, &event, WaitForMapNotify, (char *)glwin );

    return( 1 );

} /* end int APIENTRY pglc_wincreat( ) */
Ejemplo n.º 29
0
Archivo: main.c Proyecto: kuailexs/jwm
/** Prepare the connection. */
void StartupConnection(void)
{

   XSetWindowAttributes attr;
#ifdef USE_SHAPE
   int shapeError;
#endif
#ifdef USE_XRENDER
   int renderEvent;
   int renderError;
#endif
   struct sigaction sa;
   char name[32];
   Window win;
   XEvent event;
   int revert;

   initializing = 1;
   OpenConnection();

#if 0
   XSynchronize(display, True);
#endif

   /* Create the supporting window used to verify JWM is running. */
   supportingWindow = JXCreateSimpleWindow(display, rootWindow,
                                           0, 0, 1, 1, 0, 0, 0);

   /* Get the atom used for the window manager selection. */
   snprintf(name, 32, "WM_S%d", rootScreen);
   managerSelection = JXInternAtom(display, name, False);

   /* Get the current window manager and take the selection. */
   GrabServer();
   win = JXGetSelectionOwner(display, managerSelection);
   if(win != None) {
      JXSelectInput(display, win, StructureNotifyMask);
   }
   JXSetSelectionOwner(display, managerSelection,
                       supportingWindow, CurrentTime);
   UngrabServer();

   /* Wait for the current selection owner to give up the selection. */
   if(win != None) {
      /* Note that we need to wait for the current selection owner
       * to exit before we can expect to select SubstructureRedirectMask. */
      XIfEvent(display, &event, SelectionReleased, (XPointer)&win);
      JXSync(display, False);
   }

   event.xclient.display = display;
   event.xclient.type = ClientMessage;
   event.xclient.window = rootWindow;
   event.xclient.message_type = JXInternAtom(display, managerProperty, False);
   event.xclient.format = 32;
   event.xclient.data.l[0] = CurrentTime;
   event.xclient.data.l[1] = managerSelection;
   event.xclient.data.l[2] = supportingWindow;
   event.xclient.data.l[3] = 2;
   event.xclient.data.l[4] = 0;
   JXSendEvent(display, rootWindow, False, StructureNotifyMask, &event);
   JXSync(display, False);

   JXSetErrorHandler(ErrorHandler);

   clientContext = XUniqueContext();
   frameContext = XUniqueContext();

   /* Set the events we want for the root window.
    * Note that asking for SubstructureRedirect will fail
    * if another window manager is already running.
    */
   attr.event_mask
      = SubstructureRedirectMask
      | SubstructureNotifyMask
      | StructureNotifyMask
      | PropertyChangeMask
      | ColormapChangeMask
      | ButtonPressMask
      | ButtonReleaseMask
      | PointerMotionMask | PointerMotionHintMask;
   JXChangeWindowAttributes(display, rootWindow, CWEventMask, &attr);

   memset(&sa, 0, sizeof(sa));
   sa.sa_flags = 0;
   sa.sa_handler = HandleExit;
   sigaction(SIGTERM, &sa, NULL);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGHUP, &sa, NULL);

   sa.sa_flags = SA_NOCLDWAIT;
   sa.sa_handler = SIG_DFL;
   sigaction(SIGCHLD, &sa, NULL);

#ifdef USE_SHAPE
   haveShape = JXShapeQueryExtension(display, &shapeEvent, &shapeError);
   if (haveShape) {
      Debug("shape extension enabled");
   } else {
      Debug("shape extension disabled");
   }
#endif

#ifdef USE_XRENDER
   haveRender = JXRenderQueryExtension(display, &renderEvent, &renderError);
   if(haveRender) {
      Debug("render extension enabled");
   } else {
      Debug("render extension disabled");
   }
#endif

   /* Make sure we have input focus. */
   win = None;
   JXGetInputFocus(display, &win, &revert);
   if(win == None) {
      JXSetInputFocus(display, rootWindow, RevertToParent, CurrentTime);
   }

   initializing = 0;

}
Ejemplo n.º 30
0
// Create the X11 window (and its colormap)
//
static GLboolean createWindow(_GLFWwindow* window,
                              const _GLFWwndconfig* wndconfig)
{
    unsigned long wamask;
    XSetWindowAttributes wa;
    XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL;

    // Every window needs a colormap
    // Create one based on the visual used by the current context
    // TODO: Decouple this from context creation

    window->x11.colormap = XCreateColormap(_glfw.x11.display,
                                           _glfw.x11.root,
                                           visual->visual,
                                           AllocNone);

    // Create the actual window
    {
        wamask = CWBorderPixel | CWColormap | CWEventMask;

        wa.colormap = window->x11.colormap;
        wa.border_pixel = 0;
        wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
                        PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
                        ExposureMask | FocusChangeMask | VisibilityChangeMask |
                        EnterWindowMask | LeaveWindowMask | PropertyChangeMask;

        _glfwGrabXErrorHandler();

        window->x11.handle = XCreateWindow(_glfw.x11.display,
                                           _glfw.x11.root,
                                           0, 0,
                                           wndconfig->width, wndconfig->height,
                                           0,              // Border width
                                           visual->depth,  // Color depth
                                           InputOutput,
                                           visual->visual,
                                           wamask,
                                           &wa);

        _glfwReleaseXErrorHandler();

        if (!window->x11.handle)
        {
            _glfwInputXError(GLFW_PLATFORM_ERROR,
                             "X11: Failed to create window");
            return GL_FALSE;
        }

        if (!wndconfig->decorated)
        {
            MotifWmHints hints;
            hints.flags = MWM_HINTS_DECORATIONS;
            hints.decorations = 0;

            XChangeProperty(_glfw.x11.display, window->x11.handle,
                            _glfw.x11.MOTIF_WM_HINTS,
                            _glfw.x11.MOTIF_WM_HINTS, 32,
                            PropModeReplace,
                            (unsigned char*) &hints,
                            sizeof(MotifWmHints) / sizeof(long));
        }

        XSaveContext(_glfw.x11.display,
                     window->x11.handle,
                     _glfw.x11.context,
                     (XPointer) window);
    }

    if (window->monitor && !_glfw.x11.hasEWMH)
    {
        // This is the butcher's way of removing window decorations
        // Setting the override-redirect attribute on a window makes the window
        // manager ignore the window completely (ICCCM, section 4)
        // The good thing is that this makes undecorated fullscreen windows
        // easy to do; the bad thing is that we have to do everything manually
        // and some things (like iconify/restore) won't work at all, as those
        // are tasks usually performed by the window manager

        XSetWindowAttributes attributes;
        attributes.override_redirect = True;
        XChangeWindowAttributes(_glfw.x11.display,
                                window->x11.handle,
                                CWOverrideRedirect,
                                &attributes);

        window->x11.overrideRedirect = GL_TRUE;
    }

    // Declare the WM protocols supported by GLFW
    {
        int count = 0;
        Atom protocols[2];

        // The WM_DELETE_WINDOW ICCCM protocol
        // Basic window close notification protocol
        if (_glfw.x11.WM_DELETE_WINDOW)
            protocols[count++] = _glfw.x11.WM_DELETE_WINDOW;

        // The _NET_WM_PING EWMH protocol
        // Tells the WM to ping the GLFW window and flag the application as
        // unresponsive if the WM doesn't get a reply within a few seconds
        if (_glfw.x11.NET_WM_PING)
            protocols[count++] = _glfw.x11.NET_WM_PING;

        if (count > 0)
        {
            XSetWMProtocols(_glfw.x11.display, window->x11.handle,
                            protocols, count);
        }
    }

    if (_glfw.x11.NET_WM_PID)
    {
        const pid_t pid = getpid();

        XChangeProperty(_glfw.x11.display,  window->x11.handle,
                        _glfw.x11.NET_WM_PID, XA_CARDINAL, 32,
                        PropModeReplace,
                        (unsigned char*) &pid, 1);
    }

    // Set ICCCM WM_HINTS property
    {
        XWMHints* hints = XAllocWMHints();
        if (!hints)
        {
            _glfwInputError(GLFW_OUT_OF_MEMORY,
                            "X11: Failed to allocate WM hints");
            return GL_FALSE;
        }

        hints->flags = StateHint;
        hints->initial_state = NormalState;

        XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
        XFree(hints);
    }

    // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set)
    {
        XSizeHints* hints = XAllocSizeHints();
        hints->flags = 0;

        if (wndconfig->monitor)
        {
            hints->flags |= PPosition;
            _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y);
        }
        else
        {
            // HACK: Explicitly setting PPosition to any value causes some WMs,
            //       notably Compiz and Metacity, to honor the position of
            //       unmapped windows set by XMoveWindow
            hints->flags |= PPosition;
            hints->x = hints->y = 0;
        }

        if (!wndconfig->resizable)
        {
            hints->flags |= (PMinSize | PMaxSize);
            hints->min_width  = hints->max_width  = wndconfig->width;
            hints->min_height = hints->max_height = wndconfig->height;
        }

        XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
        XFree(hints);
    }

    // Set ICCCM WM_CLASS property
    // HACK: Until a mechanism for specifying the application name is added, the
    //       initial window title is used as the window class name
    if (strlen(wndconfig->title))
    {
        XClassHint* hint = XAllocClassHint();
        hint->res_name = (char*) wndconfig->title;
        hint->res_class = (char*) wndconfig->title;

        XSetClassHint(_glfw.x11.display, window->x11.handle, hint);
        XFree(hint);
    }

    if (_glfw.x11.xi.available)
    {
        // Select for XInput2 events

        XIEventMask eventmask;
        unsigned char mask[] = { 0 };

        eventmask.deviceid = 2;
        eventmask.mask_len = sizeof(mask);
        eventmask.mask = mask;
        XISetMask(mask, XI_Motion);

        XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);
    }

    if (_glfw.x11.XdndAware)
    {
        // Announce support for Xdnd (drag and drop)
        const Atom version = 5;
        XChangeProperty(_glfw.x11.display, window->x11.handle,
                        _glfw.x11.XdndAware, XA_ATOM, 32,
                        PropModeReplace, (unsigned char*) &version, 1);
    }

    if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
    {
        // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
        // function before the window is mapped

        XEvent event;
        memset(&event, 0, sizeof(event));

        event.type = ClientMessage;
        event.xclient.window = window->x11.handle;
        event.xclient.format = 32; // Data is 32-bit longs
        event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS;

        XSendEvent(_glfw.x11.display,
                   _glfw.x11.root,
                   False,
                   SubstructureNotifyMask | SubstructureRedirectMask,
                   &event);
        XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window);
    }

    _glfwPlatformSetWindowTitle(window, wndconfig->title);

    XRRSelectInput(_glfw.x11.display, window->x11.handle,
                   RRScreenChangeNotifyMask);

    _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
    _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);

    return GL_TRUE;
}