Linux X11 Entry Point#
/*!***************************************************************************
\File OpenGLESHelloAPI_LinuxX11.cpp
\Title OpenGL ES 2.0 HelloAPI Tutorial
\Author PowerVR by Imagination, Developer Technology Team
\Copyright Copyright (c) Imagination Technologies Limited.
\brief Basic Tutorial that shows step-by-step how to initialize OpenGL ES 2.0, use it for drawing a triangle and terminate it.
Entry Point: main
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "OpenGLESHelloAPI.h"
/*!***************************************************************************
\param[in] nativeDisplay Handle to the display
\param[in] error The error event to handle
\return Result code to send to the X window system
\brief Processes event messages for the main window
*****************************************************************************/
int handleX11Errors(Display* nativeDisplay, XErrorEvent* error)
{
Get the X Error
char errorStringBuffer[256];
XGetErrorText(nativeDisplay, error->error_code, errorStringBuffer, 256);
Print the error
printf("%s", errorStringBuffer);
Exit the application
exit(-1);
return 0;
}
/*!***************************************************************************
\param[out] nativeDisplay Native display to create
\return Whether the function succeeded or not.
\brief Creates a native isplay for the application to render into.
*****************************************************************************/
bool createNativeDisplay(Display** nativeDisplay)
{
Check for a valid display
if (!nativeDisplay)
{
return false;
}
Open the display
*nativeDisplay = XOpenDisplay(0);
if (!*nativeDisplay)
{
printf("Error: Unable to open X display\n");
return false;
}
return true;
}
/*!***************************************************************************
\param[in] nativeDisplay Native display used by the application
\param[out] nativeWindow Native window type to create
\return Whether the function succeeded or not.
\brief Creates a native window for the application to render into.
*****************************************************************************/
bool createNativeWindow(Display* nativeDisplay, Window* nativeWindow SurfaceData surfaceData)
{
Get the default screen for the display
int defaultScreen = XDefaultScreen(nativeDisplay);
Get the default depth of the display
int defaultDepth = DefaultDepth(nativeDisplay, defaultScreen);
Select a visual info
std::unique_ptr<XVisualInfo> visualInfo(new XVisualInfo);
XMatchVisualInfo(nativeDisplay, defaultScreen, defaultDepth, TrueColor, visualInfo.get());
if (!visualInfo.get())
{
printf("Error: Unable to acquire visual\n");
return false;
}
Get the root window for the display and default screen
Window rootWindow = RootWindow(nativeDisplay, defaultScreen);
Create a color map from the display, root window and visual info
Colormap colorMap = XCreateColormap(nativeDisplay, rootWindow, visualInfo->visual, AllocNone);
Now setup the final window by specifying some attributes
XSetWindowAttributes windowAttributes;
Set the color map that was just created
windowAttributes.colormap = colorMap;
Set events that will be handled by the app, add to these for other events.
windowAttributes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask;
Create the window
*nativeWindow = XCreateWindow(nativeDisplay, // The display used to create the window
rootWindow, // The parent (root) window - the desktop
0, // The horizontal (x) origin of the window
0, // The vertical (y) origin of the window
surfaceData.width, // The width of the window
surfaceData.height, // The height of the window
0, // Border size - set it to zero
visualInfo->depth, // Depth from the visual info
InputOutput, // Window type - this specifies InputOutput.
visualInfo->visual, // Visual to use
CWEventMask | CWColormap, // Mask specifying these have been defined in the window attributes
&windowAttributes); // Pointer to the window attribute structure
Make the window viewable by mapping it to the display
XMapWindow(nativeDisplay, *nativeWindow);
Set the window title
XStoreName(nativeDisplay, *nativeWindow, ApplicationName);
Setup the window manager protocols to handle window deletion events
Atom windowManagerDelete = XInternAtom(nativeDisplay, "WM_DELETE_WINDOW", True);
XSetWMProtocols(nativeDisplay, *nativeWindow, &windowManagerDelete, 1);
return true;
}
/*!***************************************************************************
\param[in] nativeDisplay The native display to release
\param[in] nativeWindow The native window to destroy
\brief Releases all resources allocated by the windowing system
*****************************************************************************/
void releaseNativeResources(Display* nativeDisplay, Window nativeWindow)
{
Destroy the window
if (nativeWindow)
{
XDestroyWindow(nativeDisplay, nativeWindow);
}
Release the display.
if (nativeDisplay)
{
XCloseDisplay(nativeDisplay);
}
}
/*!***************************************************************************
\param[in] argc Number of arguments passed to the application, ignored.
\param[in] argv Command line strings passed to the application, ignored.
\return Result code to send to the Operating System
\brief Main function of the program, executes other functions.
*****************************************************************************/
int main(int /*argc*/, char** /*argv*/)
{
HelloAPI handle
OpenGLESAPI helloAPI;
Get access to a native display
createNativeDisplay(&helloAPI._surfaceData.deviceContext);
Setup the windowing system, create a window
createNativeWindow(helloAPI._surfaceData.deviceContext, &helloAPI._surfaceData.window);
Setup OpenGLES state and objects
helloAPI.initializeEGL();
helloAPI.initializeGLES();
Renders a triangle for 800 frames using the state setup in the previous function
for (int i = 0; i < 800; ++i)
{
if (!helloAPI.drawFrame() || !helloAPI.swapEGLBuffers())
{
break;
}
Check for messages from the windowing system.
int numberOfMessages = XPending(helloAPI._surfaceData.deviceContext);
for (int i = 0; i < numberOfMessages; i++)
{
XEvent event;
XNextEvent(helloAPI._surfaceData.deviceContext, &event);
switch (event.type)
{
Exit on window close
case ClientMessage:
Exit on mouse click
case ButtonPress:
case DestroyNotify:
return false;
default:
break;
}
}
}
Release any resources we created in the Initialize functions
helloAPI.releaseGLState();
helloAPI.releaseEGLState();
Release the windowing system resources
releaseNativeResources(helloAPI._surfaceData.deviceContext, helloAPI._surfaceData.window);
Destroy the eglWindow
return 0;
}