|  | /* Code example to illustrate the use of OpenGL rendering into */
/* Motif DrawingArea widgets with overlay planes               */
#include <math.h>
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <Xm/Xm.h>
#include <Xm/BulletinB.h>
#include <Xm/DrawingA.h>
#include <X11/GLw/GLwMDrawA.h>
#include <GL/gl.h>
#define WIDTH 300
#define HEIGHT 300
static void init_window();
static void window_expose();
Display       *display;
Widget	       draw, overlay;
GLXContext cx, cx_overlay;
/******************************************************************************/
int main (int argc, char* argv[])
/******************************************************************************/
{
    XtAppContext   application_context;
    int            screen_number;
    XSizeHints     size_hints;
    Widget         toplevel_application_shell;
    Widget         toplevel_shell;
    Arg            args[10];
    int            n;
    /******************************************** create Application Shell ****/
    printf("Motif version %d\n", XmVersion);
    XtToolkitInitialize();
    application_context = XtCreateApplicationContext();
    display = XtOpenDisplay(application_context,
                            NULL, NULL, "Display",
                            NULL, 0, &argc, argv);
    XSynchronize(display, True);
    if (!display)
    {
        XtWarning("Test program: The XtOpenDisplay won't open the display. \n");
        exit(0);
    }
    screen_number  = DefaultScreen(display);
    toplevel_application_shell = XtAppCreateShell("main",
                                                  "Freddy",
                                                  applicationShellWidgetClass,
                                                  display,
                                                  args,
                                                  0);
    /******************************************** create Toplevel Shell *******/
    n=0;
    XtSetArg(args[n], XmNx, (Position)500);
    n++;
    XtSetArg(args[n], XmNy, (Position)50);
    n++;
    toplevel_shell = XtCreatePopupShell("Test program",
                                        topLevelShellWidgetClass,
                                        toplevel_application_shell ,
                                        args,
                                        n);
    /************ create GL Overlay planes ********/
    n=0;
    XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
    n++;
    XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
    n++;
    XtSetArg(args[n], XmNmarginWidth,  (Dimension)0);
    n++;
    XtSetArg(args[n], XmNmarginHeight, (Dimension)0);
    n++;
    XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
    n++;
    XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
    n++;
    XtSetArg(args[n], GLwNrgba, FALSE );
    n++;
    XtSetArg(args[n], GLwNlevel, 1 );
    n++;
    overlay = GLwCreateMDrawingArea(toplevel_shell, "overlay", args, n);
    XtManageChild(overlay);
    XtAddCallback(overlay, GLwNexposeCallback, window_expose, 0);
    XtAddCallback(overlay, GLwNginitCallback, init_window, 0);
    /************ create GL Drawing Area ********/
    n=0;
    XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
    n++;
    XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
    n++;
    XtSetArg(args[n], XmNmarginWidth,  (Dimension)0);
    n++;
    XtSetArg(args[n], XmNmarginHeight, (Dimension)0);
    n++;
    XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
    n++;
    XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
    n++;
    XtSetArg(args[n], GLwNrgba, TRUE );
    n++;
    XtSetArg(args[n], GLwNallocateBackground, TRUE );
    n++;
    XtSetArg(args[n], GLwNlevel, 0 );
    n++;
    draw = GLwCreateMDrawingArea(toplevel_shell, "draw", args, n);
    XtManageChild(draw);
    XtAddCallback(draw, GLwNexposeCallback, window_expose, 0);
/* if XtRealizeWidget and XtAddCallback are switched around all is well */
/* the GLwNginitCallback must be registered before the widget tree is realised 
*/
/* as the callback appears to happen at realisation */
    XtAddCallback(draw, GLwNginitCallback, init_window, 0);
    XtRealizeWidget(toplevel_shell);
    XtPopup(toplevel_shell, XtGrabNone);
    XtAppMainLoop(application_context);
}
static void init_window(Widget widget, XtPointer client_data, XtPointer
call_data)
{
    Arg args[1];
    XVisualInfo *vi;
    XColor c;
    XSetWindowAttributes      win_attr;
    Colormap colormap;
    unsigned long backpixel = 0;
    int i;
    GLenum error;
    printf("GLwNginitCallback\n");
    XtSetArg(args[0], GLwNvisualInfo, &vi);
    XtGetValues(widget, args, 1);
    printf("visual ID = %d\n", vi->visualid);
    printf("depth = %d\n", vi->depth);
    /* if (vi->depth > 4) { */
    if (widget != overlay) {
        cx = glXCreateContext(XtDisplay(widget), vi, 0, GL_TRUE);
        GLwDrawingAreaMakeCurrent(widget, cx);
        glClearColor(1.0, 1.0, 0.0, 1.0);
    } else {
        colormap = XCreateColormap(XtDisplay(widget), XtWindow(widget),
vi->visual, AllocAll);
	for (i=0; i<16; i++){
	  if (i != backpixel){
	    c.pixel = i;
	    c.red = (65535/16)*i;
	    c.green = (65535/16)*i;
	    c.blue = (65535/16)*i;
	    c.flags = DoRed | DoGreen | DoBlue;
	    XStoreColor(XtDisplay(widget), colormap, &c);
	  }
	}
	/* set up window attributes */
	win_attr.background_pixel = backpixel;
	win_attr.border_pixel = backpixel;
	win_attr.colormap = colormap;
	XChangeWindowAttributes(XtDisplay(widget), XtWindow(widget), 
			CWBackPixel | CWBorderPixel | CWColormap , 
			&win_attr);
        XInstallColormap(XtDisplay(widget), colormap);
        cx_overlay = glXCreateContext(XtDisplay(widget), vi, 0, GL_TRUE);
        GLwDrawingAreaMakeCurrent(widget, cx_overlay);
        glClearIndex(0.0);
    }
    while (error = glGetError()) 
    	printf("glGetError returns %s\n",gluErrorString(error));
}
static void window_expose( widget, tag, callback_data )
        Widget  widget;
        char    *tag;
        XmAnyCallbackStruct *callback_data;
{
    float x;
    int i;
    GLenum error;
    printf("Expose event on ");
    if (widget == draw) {
        printf("main window\n");
        GLwDrawingAreaMakeCurrent(draw, cx);
        /* clear the buffer */
        glClear(GL_COLOR_BUFFER_BIT);
        /* draw a blue polygon (square) in main window */
        glColor3f(0.0, 0.0, 1.0);
        glBegin(GL_POLYGON);
            glVertex2f(-0.5, -0.5);
            glVertex2f(-0.5, 0.5);
            glVertex2f(0.5, 0.5);
            glVertex2f(0.5, -0.5);
        glEnd(); 
    } else {
        printf("overlay window\n");
        /* draw lines in the overlay planes */
        GLwDrawingAreaMakeCurrent(overlay, cx_overlay);
        glClear(GL_COLOR_BUFFER_BIT);
        for (i = 1; i < 16; i++) {
            glIndexi(i);
            x = ((float) i) / 17.0;
            glBegin(GL_LINES);
                glIndexi(i);
                glVertex2f(x, 0.1);
                glVertex2f(x, 0.9);
            glEnd(); 
        }
    }
    glFlush();
    while (error = glGetError()) 
    	printf("glGetError returns %s\n",gluErrorString(error));
}
 |