int PandoraGraphics::InitialiseX11( int w, int h, bool fullscreen, bool vsync, bool fsaa, bool hideCursor )
{
Window sRootWindow;
XSetWindowAttributes sWA;
unsigned int ui32Mask;
int i32Depth;
int x11Screen;
XVisualInfo * x11Visual;
Colormap x11Colormap;
EGLConfig eglConfig;
m_Display = XOpenDisplay( ":0" );
if (!m_Display)
{
Pi.Error( EVeryHigh, "Unable to open X display" );
return false;
}
x11Screen = XDefaultScreen( m_Display );
sRootWindow = RootWindow(m_Display, x11Screen);
i32Depth = DefaultDepth(m_Display, x11Screen);
x11Visual = (XVisualInfo *)Pi.Memory.Allocate(
PI_DEBUG,
sizeof(XVisualInfo)
);
XMatchVisualInfo( m_Display, x11Screen, i32Depth, TrueColor, x11Visual);
if (!x11Visual)
{
Pi.Error( EVeryHigh, "Unable to acquire visual" );
return false;
}
// Colormap of the specified visual type for the display.
x11Colormap = XCreateColormap( m_Display, sRootWindow, x11Visual->visual, AllocNone );
sWA.colormap = x11Colormap;
// List of events to be handled by the application. Add to these for handling other events.
sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;
// Display capabilities list.
ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
// Creates the X11 window
m_Window = XCreateWindow( m_Display, RootWindow(m_Display, x11Screen), 0, 0, w, h,
0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);
// Make the window viewable and flush the output buffer.
XMapWindow(m_Display, m_Window);
XFlush(m_Display);
// Hide cursor if required.
if ( hideCursor )
{
// Hide pointer by creating an empty cursor
XColor black = XColor( );
char buff[ 64 ] = { 0 };
Pixmap bmp = XCreateBitmapFromData( m_Display, m_Window, buff, 8, 8 );
Cursor cursor = XCreatePixmapCursor( m_Display, bmp, bmp, &black, &black, 0, 0 );
XDefineCursor( m_Display, m_Window, cursor );
XFreeCursor( m_Display, cursor );
XFreePixmap( m_Display, bmp );
// XUndefineCursor( m_Display, m_Window );
// XMapRaised( m_Display, m_Window );
// XFlush( m_Display );
}
// Generate full screen event if required.
if ( fullscreen )
{
XEvent x11_event;
Atom x11_state_atom;
Atom x11_fs_atom;
x11_state_atom = XInternAtom( m_Display, "_NET_WM_STATE", False );
x11_fs_atom = XInternAtom( m_Display, "_NET_WM_STATE_FULLSCREEN", False );
x11_event.xclient.type = ClientMessage;
x11_event.xclient.serial = 0;
x11_event.xclient.send_event = True;
x11_event.xclient.window = m_Window;
x11_event.xclient.message_type = x11_state_atom;
x11_event.xclient.format = 32;
x11_event.xclient.data.l[ 0 ] = 1;
x11_event.xclient.data.l[ 1 ] = x11_fs_atom;
x11_event.xclient.data.l[ 2 ] = 0;
XSendEvent( m_Display, sRootWindow, False, SubstructureRedirectMask | SubstructureNotifyMask, &x11_event );
}
m_EglDisplay = eglGetDisplay( ( NativeDisplayType ) m_Display );
EGLint iMajorVersion, iMinorVersion;
if ( ! eglInitialize( m_EglDisplay, &iMajorVersion, &iMinorVersion ) )
{
Pi.Error( EVeryHigh, "eglInitialize() failed" );
return false;
}
EGLint pi32ConfigAttribs[5];
int attrib = 0;
pi32ConfigAttribs[attrib++] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[attrib++] = EGL_WINDOW_BIT;
pi32ConfigAttribs[attrib++] = EGL_NONE;
if ( fsaa )
{
pi32ConfigAttribs[attrib++] = EGL_SAMPLE_BUFFERS, 1;
pi32ConfigAttribs[attrib++] = EGL_SAMPLES, 4;
}
pi32ConfigAttribs[attrib++] = EGL_NONE;
int iConfigs;
if (!eglChooseConfig(m_EglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
{
Pi.Error( EVeryHigh, "eglChooseConfig() failed" );
return false;
}
m_EglSurface = eglCreateWindowSurface(m_EglDisplay, eglConfig, (NativeWindowType)m_Window, NULL);
if ( ! CheckIfEglSurfaceValid( true ) )
{
Pi.Error( EVeryHigh, "eglCreateWindowSurface() failed" );
return false;
}
m_EglContext = eglCreateContext(m_EglDisplay, eglConfig, NULL, NULL);
if ( ! CheckIfEglContextValid( true ) )
{
Pi.Error( EVeryHigh, "eglCreateContext( ) failed" );
return false;
}
eglMakeCurrent(m_EglDisplay, m_EglSurface, m_EglSurface, m_EglContext);
// TODO: error check.
if ( vsync )
{
#ifdef _PANDORA
#else
eglSwapInterval( m_EglDisplay, 1 );
#endif
}
// Find out what size window we actually got.
XWindowAttributes xWindowAttributes;
XGetWindowAttributes( m_Display, m_Window, &xWindowAttributes );
m_Width = xWindowAttributes.width;
m_Height = xWindowAttributes.height;
return true;
}