12/08/2013

OLinuXino A13: touchscreen support in Linux


Take From blog http://www.dimrobotics.com/2013/06/olinuxino-a13-touchscreen-support-in.html

OLinuXino A13: touchscreen support in Linux

One of the first problems we had with OLinuxIno-A13 board is the touchscreen support. The manual was published on the official Olimex blog, but source packages had updated, so old solution didn't give an effect. After some experiments, we solved this problem. Here is a full step-by-step manual how to get the device works well under Debian.


Required:
  • installed xorg-dev, xserver-xorg-dev, x11proto-core-dev, git, make, automake:
    aptitude install xorg-dev xserver-xorg-dev x11proto-core-dev git automake make
  • tslib sources - get it from Github:
    git clone https://github.com/kergoth/tslib.git
  • xf86-input-tslib sources - from Debian Git repository:
    git clone git://git.debian.org/git/collab-maint/xf86-input-tslib

Now it's time to build this stuff. (All commands are performed as root).

tslib


tslib is a library that allows programmer to use data from touchscreens. It is only API, but not a driver for Xorg (there is xf86-input-tslib package for this).

It works well for most of different touchscreens without any changes. But, suddenly, Olinuxino's touchscreen is an exception, and we need to patch original library.

First, download tslib source code and go to its directory:

# git clone https://github.com/kergoth/tslib.git
# cd tslib

Download and apply the patch using GNU patch utility:

# wget https://raw.github.com/webconn/OLINUXINO/master/SOFTWARE/A13/TOUCHSCREEN/tslib.patch
# patch -p0 < tslib.patch

Configure, make and install:

# autoreconf -vi
# ./configure --prefix=/usr
# make
# make install

Then, let's load a kernel module and check touchscreen:

# modprobe sun4i-ts
# dmesg | grep sun4i-ts

If it's all right, there will be some messages in dmesg like this:

[    9.010000] sun4i-ts.c: sun4i_ts_init: start ...
[    9.020000] sun4i-ts: tp_screen_size is 5 inch.
[    9.030000] sun4i-ts: tp_regidity_level is 5.
[    9.030000] sun4i-ts: tp_press_threshold_enable is 0.
[    9.040000] sun4i-ts: rtp_sensitive_level is 15.
[    9.050000] sun4i-ts: rtp_exchange_x_y_flag is 0.
[    9.060000] sun4i-ts.c: sun4i_ts_probe: start...
[    9.080000] input: sun4i-ts as /devices/platform/sun4i-ts/input/input1
[    9.100000] sun4i-ts.c: sun4i_ts_probe: end

Highlighted 1 there is a number of touchscreen event device. Later we will get a raw data from device using the path /dev/input/event1 (change higlighted number to your).

To load this kernel module automatically, add a line into /etc/modules:

# echo sun4i-ts >> /etc/modules
 Now let's check the touchscreen in use. We need to export some environment variables which contains basic configuration for library. Do not forget to change highlighted number:

# export TSLIB_TSEVENTTYPE=raw
# export TSLIB_CONSOLEDEVICE=none
# export TSLIB_FBDEVICE=/dev/fb0
# export TSLIB_TSDEVICE=/dev/input/event1
# export TSLIB_CALIBFILE=/usr/etc/pointercal
# export TSLIB_CONFFILE=/usr/etc/ts.conf
# export TSLIB_PLUGINDIR=/usr/lib/ts

Next, configure raw input module of the tslib. Open /usr/etc/ts.conf and uncomment the line which contains "module_raw input".

After this, we should make a test. Let's calibrate the touchscreen and try to do something with it.

# ts_calibrate
# ts_test

To get out from ts_test, you should press "Quit" button on the screen, or use Ctrl+C in emergency case (if screen is not calibrated or configured successfully).

To load configuration variables while system is loading, write these lines into /etc/environment file (check highlighted number):
 
TSLIB_TSEVENTTYPE=raw
TSLIB_CONSOLEDEVICE=none
TSLIB_FBDEVICE=/dev/fb0
TSLIB_TSDEVICE=/dev/input/event1
TSLIB_CALIBFILE=/etc/pointercal
TSLIB_CONFFILE=/usr/etc/ts.conf
TSLIB_PLUGINDIR=/usr/lib/ts

Now we need to modify and install xf86-input-tslib driver.

xf86-input-tslib


xf86-input-tslib allows us to use tslib device like our touchscreen as pointer device.

This driver is old a bit, so while it works with newer Xorg server, it faluts, because xf86InputSetScreen function is removed from Xorg, but driver tries to call it. I had just removed this call from driver's source code and the problem was solved.

Download source code, go to its directory:

# git clone git://git.debian.org/git/collab-maint/xf86-input-tslib
# cd xf86-input-tslib

Get and apply required patches (including my solution):

# wget https://raw.github.com/webconn/OLINUXINO/master/SOFTWARE/A13/TOUCHSCREEN/1-xf86tslib-sigfault.patch https://raw.github.com/webconn/OLINUXINO/master/SOFTWARE/A13/TOUCHSCREEN/xf86-input-tslib-port-ABI-12-r48.patch https://github.com/webconn/OLINUXINO/blob/master/SOFTWARE/A13/TOUCHSCREEN/xf86tslib-xorg-update.patch
# patch -p0 < 1-xf86tslib-sigfault.patch
# patch -p0 < xf86-input-tslib-port-ABI-12-r48.patch
# patch -p0 < xf86tslib-xorg-update.patch

Configure, make and install:

# ./configure --prefix=/usr
# make
# make install

Now describe the device as InputClass of Xorg in your xorg.conf (or in /usr/share/X11/xorg.conf.d/20-ts.conf as I did):

Section "InputClass"
    Identifier "Sun4i-Touchscreen"
    MatchDevicePath "/dev/input/event*"
    MatchProduct "sun4i-ts"
    Driver "tslib"
EndSection


If you had successfully calibrated and tested the touchscreen, when you start X server by

# startx

the screen should work well. Also it should work when X server is launched by desktop manager (ex. LightDM).

P.S. This solution is tested at Olinuxino A13 with Debian GNU/Linux 7.0 (wheezy). Last commit of tslib was 158ee49, version of xf86-input-tslib was 0.0.6.

11/29/2013

android call intent the other package. example source code.

package lowmans.test.MyTest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MyTest extends Activity {
private Intent intent;
private final String packageName = "com.android.music";   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        intent = this.getPackageManager().getLaunchIntentForPackage(packageName);
        Button btn  = (Button)findViewById(R.id.Button01);
        btn.setOnClickListener(new OnClickListener(){
         public void onClick(View v){
         MyTest.this.startActivity(intent);
         }
        });
    }

}

9/03/2013

OpenGL FOG simple. - NEHE-GL GLX

/*
 * This code was created by Jeff Molofee '99
 * (ported to Linux/GLX by Mihael Vrbanec '00)
 *
 * If you've found this code useful, please let me know.
 *
 * Visit Jeff at http://nehe.gamedev.net/
 *
 * or for port-specific comments, questions, bugreports etc.
 * email to Mihael.Vrbanec@stud.uni-karlsruhe.de
 */

#include
#include
#include
#include
#include
#include
#include

/* stuff about our window grouped together */
typedef struct {
    Display *dpy;
    int screen;
    Window win;
    GLXContext ctx;
    XSetWindowAttributes attr;
    Bool fs;
    XF86VidModeModeInfo deskMode;
    int x, y;
    unsigned int width, height;
    unsigned int depth;  
} GLWindow;

typedef struct {
    int width;
    int height;
    unsigned char *data;
} textureImage;

/* attributes for a single buffered visual in RGBA format with at least
 * 4 bits per color and a 16 bit depth buffer */
static int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 4,
    GLX_GREEN_SIZE, 4,
    GLX_BLUE_SIZE, 4,
    GLX_DEPTH_SIZE, 16,
    None};

/* attributes for a double buffered visual in RGBA format with at least
 * 4 bits per color and a 16 bit depth buffer */
static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
    GLX_RED_SIZE, 4,
    GLX_GREEN_SIZE, 4,
    GLX_BLUE_SIZE, 4,
    GLX_DEPTH_SIZE, 16,
    None };

GLWindow GLWin;
Bool done;

Bool light;    /* Lighting on/off */
GLfloat rotX;  /* X Rotation */
GLfloat rotY;  /* Y Rotation */
GLfloat speedX;  /* X Rotation speed */
GLfloat speedY;  /* Y Rotation speed */
GLfloat z;     /* depth into the screen */
GLfloat lightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat lightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };
GLuint filter;      /* which filter to use */
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };  /* three types of fog */
GLuint fogFilter = 0;   /* which fog to use */
GLfloat fogColor[] = { 0.5f, 0.5f, 0.5f, 1.0f };    /* fog color */
GLuint texture[3];  /* storage for three textures */

/* simple loader for 24bit bitmaps (data is in rgb-format) */
int loadBMP(char *filename, textureImage *texture)
{
    FILE *file;
    unsigned short int bfType;
    int bfOffBits;
    short int biPlanes;
    short int biBitCount;
    int biSizeImage;
    int i;
    unsigned char temp;
    /* make sure the file is there and open it read-only (binary) */
    if ((file = fopen(filename, "rb")) == NULL)
    {
        printf("File not found : %s\n", filename);
        return 0;
    }
    if(!fread(&bfType, sizeof(short int), 1, file))
    {
        printf("Error reading file!\n");
        return 0;
    }
    /* check if file is a bitmap */
    if (bfType != 19778)
    {
        printf("Not a Bitmap-File!\n");
        return 0;
    }      
    /* get the file size */
    /* skip file size and reserved fields of bitmap file header */
    fseek(file, 8, SEEK_CUR);
    /* get the position of the actual bitmap data */
    if (!fread(&bfOffBits, sizeof(int), 1, file))
    {
        printf("Error reading file!\n");
        return 0;
    }
    printf("Data at Offset: %d\n", bfOffBits);
    /* skip size of bitmap info header */
    fseek(file, 4, SEEK_CUR);
    /* get the width of the bitmap */
    fread(&texture->width, sizeof(int), 1, file);
    printf("Width of Bitmap: %d\n", texture->width);
    /* get the height of the bitmap */
    fread(&texture->height, sizeof(int), 1, file);
    printf("Height of Bitmap: %d\n", texture->height);
    /* get the number of planes (must be set to 1) */
    fread(&biPlanes, sizeof(short int), 1, file);
    if (biPlanes != 1)
    {
        printf("Error: number of Planes not 1!\n");
        return 0;
    }
    /* get the number of bits per pixel */
    if (!fread(&biBitCount, sizeof(short int), 1, file))
    {
        printf("Error reading file!\n");
        return 0;
    }
    printf("Bits per Pixel: %d\n", biBitCount);
    if (biBitCount != 24)
    {
        printf("Bits per Pixel not 24\n");
        return 0;
    }
    /* calculate the size of the image in bytes */
    biSizeImage = texture->width * texture->height * 3;
    printf("Size of the image data: %d\n", biSizeImage);
    texture->data = malloc(biSizeImage);
    /* seek to the actual data */
    fseek(file, bfOffBits, SEEK_SET);
    if (!fread(texture->data, biSizeImage, 1, file))
    {
        printf("Error loading file!\n");
        return 0;
    }
    /* swap red and blue (bgr -> rgb) */
    for (i = 0; i < biSizeImage; i += 3)
    {
        temp = texture->data[i];
        texture->data[i] = texture->data[i + 2];
        texture->data[i + 2] = temp;
    }
    return 1;
}

Bool loadGLTextures()   /* Load Bitmaps And Convert To Textures */
{
    Bool status;
    textureImage *texti;
   
    status = False;
    texti = malloc(sizeof(textureImage));
    if (loadBMP("Data/crate.bmp", texti))
    {
        status = True;
        glGenTextures(3, &texture[0]);   /* create three textures */
        glBindTexture(GL_TEXTURE_2D, texture[0]);
        /* actually generate the texture */
        glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
            GL_RGB, GL_UNSIGNED_BYTE, texti->data);
        /* use no filtering */
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        /* the second texture */
        glBindTexture(GL_TEXTURE_2D, texture[1]);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
            GL_RGB, GL_UNSIGNED_BYTE, texti->data);
        /* use linear filtering */
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        /* the third texture */
        glBindTexture(GL_TEXTURE_2D, texture[2]);
        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texti->width,
            texti->height, GL_RGB, GL_UNSIGNED_BYTE, texti->data);
        /* use mipmapping */
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
            GL_LINEAR_MIPMAP_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }
    /* free the ram we used in our texture generation process */
    if (texti)
    {
        if (texti->data)
            free(texti->data);
        free(texti);
    }  
    return status;
}

/* function called when our window is resized (should only happen in window mode) */
void resizeGLScene(unsigned int width, unsigned int height)
{
    if (height == 0)    /* Prevent A Divide By Zero If The Window Is Too Small */
        height = 1;
    /* Reset The Current Viewport And Perspective Transformation */
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);
}

/* general OpenGL initialization function */
int initGL(GLvoid)
{
    if (!loadGLTextures())
    {
        return False;
    }
    glEnable(GL_TEXTURE_2D);       /* Enable Texture Mapping */
    glShadeModel(GL_SMOOTH);
    /* clear to fog color */
    glClearColor(fogColor[0], fogColor[1], fogColor[2], fogColor[3]);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    /* set up our lighting */
    glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse);
    glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
    glEnable(GL_LIGHT1);
    glFogi(GL_FOG_MODE, fogMode[fogFilter]);
    glFogfv(GL_FOG_COLOR, fogColor);
    glFogf(GL_FOG_DENSITY, 0.35f);
    glHint(GL_FOG_HINT, GL_DONT_CARE);
    glFogf(GL_FOG_START, 1.0f);
    glFogf(GL_FOG_END, 5.0f);
    glEnable(GL_FOG);
    /* we use resizeGLScene once to set up our initial perspective */
    resizeGLScene(GLWin.width, GLWin.height);
    if (light)
        glEnable(GL_LIGHTING);
    glFlush();
    return True;
}

/* Here goes our drawing code */
int drawGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, z);
    glRotatef(rotX, 1.0f, 0.0f, 0.0f);  /* rotate on the X axis */
    glRotatef(rotY, 0.0f, 1.0f, 0.0f);  /* rotate on the Y axis */
    glBindTexture(GL_TEXTURE_2D, texture[filter]);  /* select our texture */
   
    glBegin(GL_QUADS);
        /* front face */
        glNormal3f(0.0f, 0.0f, 1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, 1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, 1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, 1.0f);
        /* back face */
        glNormal3f(0.0f, 0.0f, -1.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, -1.0f);
        /* right face */
        glNormal3f(1.0f, 0.0f, 0.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, 1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, 1.0f);
        /* left face */
        glNormal3f(-1.0f, 0.0f, 0.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, 1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, -1.0f);
        /* top face */
        glNormal3f(0.0f, 1.0f, 0.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(1.0f, 1.0f, 1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-1.0f, 1.0f, 1.0f);
        /* bottom face */
        glNormal3f(0.0f, -1.0f, 0.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(1.0f, -1.0f, 1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, -1.0f);
    glEnd();
    /* change the rotation angles */
    rotX += speedX;
    rotY += speedY;
    glXSwapBuffers(GLWin.dpy, GLWin.win);
    return True;  
}

/* function to release/destroy our resources and restoring the old desktop */
GLvoid killGLWindow(GLvoid)
{
    if (GLWin.ctx)
    {
        if (!glXMakeCurrent(GLWin.dpy, None, NULL))
        {
            printf("Could not release drawing context.\n");
        }
        glXDestroyContext(GLWin.dpy, GLWin.ctx);
        GLWin.ctx = NULL;
    }
    /* switch back to original desktop resolution if we were in fs */
    if (GLWin.fs)
    {
        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
    }
    XCloseDisplay(GLWin.dpy);
}

/* this function creates our window and sets it up properly */
/* FIXME: bits is currently unused */
Bool createGLWindow(char* title, int width, int height, int bits,
                    Bool fullscreenflag)
{
    XVisualInfo *vi;
    Colormap cmap;
    int dpyWidth, dpyHeight;
    int i;
    int glxMajorVersion, glxMinorVersion;
    int vidModeMajorVersion, vidModeMinorVersion;
    XF86VidModeModeInfo **modes;
    int modeNum;
    int bestMode;
    Atom wmDelete;
    Window winDummy;
    unsigned int borderDummy;
   
    GLWin.fs = fullscreenflag;
    /* set best mode to current */
    bestMode = 0;
    /* get a connection */
    GLWin.dpy = XOpenDisplay(0);
    GLWin.screen = DefaultScreen(GLWin.dpy);
    XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
        &vidModeMinorVersion);
    printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
        vidModeMinorVersion);
    XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
    /* save desktop-resolution before switching modes */
    GLWin.deskMode = *modes[0];
    /* look for mode with requested resolution */
    for (i = 0; i < modeNum; i++)
    {
        if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
        {
            bestMode = i;
        }
    }
    /* get an appropriate visual */
    vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
    if (vi == NULL)
    {
        vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
        printf("Only Singlebuffered Visual!\n");
    }
    else
    {
        printf("Got Doublebuffered Visual!\n");
    }
    glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
    printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
    /* create a GLX context */
    GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
    /* create a color map */
    cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
        vi->visual, AllocNone);
    GLWin.attr.colormap = cmap;
    GLWin.attr.border_pixel = 0;

    if (GLWin.fs)
    {
        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
        dpyWidth = modes[bestMode]->hdisplay;
        dpyHeight = modes[bestMode]->vdisplay;
        printf("Resolution %dx%d\n", dpyWidth, dpyHeight);
        XFree(modes);
   
        /* create a fullscreen window */
        GLWin.attr.override_redirect = True;
        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
            StructureNotifyMask;
        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
            0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
            &GLWin.attr);
        XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
XMapRaised(GLWin.dpy, GLWin.win);
        XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
            GrabModeAsync, CurrentTime);
        XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
            GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
    }
    else
    {
        /* create a window in window mode*/
        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
            StructureNotifyMask;
        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
            0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
        /* only set window title and handle wm_delete_events if in windowed mode */
        wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
        XSetStandardProperties(GLWin.dpy, GLWin.win, title,
            title, None, NULL, 0, NULL);
        XMapRaised(GLWin.dpy, GLWin.win);
    }      
    /* connect the glx-context to the window */
    glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
    XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
        &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
    printf("Depth %d\n", GLWin.depth);
    if (glXIsDirect(GLWin.dpy, GLWin.ctx))
        printf("Congrats, you have Direct Rendering!\n");
    else
        printf("Sorry, no Direct Rendering possible!\n");
    if (!initGL())
    {
        printf("Could not initialize OpenGL.\nAborting...\n");
        return False;
    }      
    return True;  
}

void keyPressed(KeySym key)
{
    switch (key)
    {
        case XK_Escape:
            done = True;
            break;
        case XK_F1:
            killGLWindow();
            GLWin.fs = !GLWin.fs;
            createGLWindow("NeHe's Cool Looking Fog Tutorial",
                640, 480, 24, GLWin.fs);
            break;
        case XK_f:
            filter += 1;
            if (filter > 2)
                filter = 0;
            break;
        case XK_l:
            light = !light;
            if (!light)
                glDisable(GL_LIGHTING);
            else
                glEnable(GL_LIGHTING);
            break;
        case XK_g:
            fogFilter += 1;
            if (fogFilter > 2)
            {
                fogFilter = 0;
            }
            glFogi(GL_FOG_MODE, fogMode[fogFilter]);
            break;
        case XK_Page_Up:
            z -= 0.02f;
            break;
        case XK_Page_Down:
            z += 0.02f;
            break;
        case XK_Up:
            speedX -= 0.01f;
            break;
        case XK_Down:
            speedX += 0.01f;
            break;
        case XK_Right:
            speedY += 0.01f;
            break;
        case XK_Left:
            speedY -= 0.01f;
            break;
    }
}

int main(int argc, char **argv)
{
    XEvent event;
    KeySym key;
   
    done = False;
    z = -5.0f;      /* set the initial depth to 5 units */
    filter = 0;     /* initialize filter to no filter */
    light = False;
    /* default to fullscreen */
    GLWin.fs = True;
    if (!createGLWindow("NeHe's Cool Looking Fog Tutorial",
        640, 480, 24, GLWin.fs))
    {
        done = True;
    }
    /* wait for events*/
    while (!done)
    {
        /* handle the events in the queue */
        while (XPending(GLWin.dpy) > 0)
        {
            XNextEvent(GLWin.dpy, &event);
            switch (event.type)
            {
                case Expose:
               if (event.xexpose.count != 0)
                   break;
                    drawGLScene();
                 break;
                case ConfigureNotify:
                    /* call resizeGLScene only if our window-size changed */
                    if ((event.xconfigure.width != GLWin.width) ||
                        (event.xconfigure.height != GLWin.height))
                    {
                        GLWin.width = event.xconfigure.width;
                        GLWin.height = event.xconfigure.height;
                        printf("Resize event\n");
                        resizeGLScene(event.xconfigure.width,
                            event.xconfigure.height);
                    }
                    break;
                /* exit in case of a mouse button press */
                case ButtonPress:    
                    done = True;
                    break;
                case KeyPress:
                    key = XLookupKeysym(&event.xkey, 0);
                    keyPressed(key);
                    break;
                case ClientMessage:  
                    if (*XGetAtomName(GLWin.dpy, event.xclient.message_type)
                        == *"WM_PROTOCOLS")
                    {
                        printf("Exiting sanely...\n");
                        done = True;
                    }
                    break;
                default:
                    break;
            }
        }
        drawGLScene();
    }
    killGLWindow();
    return 0;
}


8/01/2013

safe erase

psaudo

it = list1.begin();
while( it != list1.end() )
{
    if( *it == (waste?) )
         list1.erase(it++);
    else
         ++it;     
}