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;
}