summaryrefslogtreecommitdiff
path: root/iup/srcgl
diff options
context:
space:
mode:
Diffstat (limited to 'iup/srcgl')
-rwxr-xr-xiup/srcgl/Makefile6
-rwxr-xr-xiup/srcgl/config.mak20
-rwxr-xr-xiup/srcgl/iup_glcanvas_win.c411
-rwxr-xr-xiup/srcgl/iup_glcanvas_x.c448
-rwxr-xr-xiup/srcgl/iupgl.def9
-rw-r--r--iup/srcgl/iupgl.dep5
-rwxr-xr-xiup/srcgl/make_uname3
-rwxr-xr-xiup/srcgl/make_uname.bat4
8 files changed, 906 insertions, 0 deletions
diff --git a/iup/srcgl/Makefile b/iup/srcgl/Makefile
new file mode 100755
index 0000000..882d0d2
--- /dev/null
+++ b/iup/srcgl/Makefile
@@ -0,0 +1,6 @@
+
+.PHONY: do_all iupgl
+do_all: iupgl
+
+iupgl:
+ @$(MAKE) --no-print-directory -f ../tecmake_compact.mak
diff --git a/iup/srcgl/config.mak b/iup/srcgl/config.mak
new file mode 100755
index 0000000..49599a5
--- /dev/null
+++ b/iup/srcgl/config.mak
@@ -0,0 +1,20 @@
+PROJNAME = iup
+LIBNAME = iupgl
+OPT = YES
+
+ifdef DBG
+ DEFINES += IUP_ASSERT
+endif
+
+INCLUDES = ../include ../src
+LDIR = ../lib/$(TEC_UNAME)
+LIBS = iup
+
+USE_OPENGL = Yes
+
+ifneq ($(findstring Win, $(TEC_SYSNAME)), )
+ SRC = iup_glcanvas_win.c
+else
+ SRC = iup_glcanvas_x.c
+ USE_X11 = Yes
+endif
diff --git a/iup/srcgl/iup_glcanvas_win.c b/iup/srcgl/iup_glcanvas_win.c
new file mode 100755
index 0000000..06cb66b
--- /dev/null
+++ b/iup/srcgl/iup_glcanvas_win.c
@@ -0,0 +1,411 @@
+/** \file
+ * \brief iupgl control for Windows
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <windows.h>
+#include <GL/gl.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupgl.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_stdcontrols.h"
+#include "iup_assert.h"
+#include "iup_register.h"
+
+
+struct _IcontrolData
+{
+ iupCanvas canvas; /* from IupCanvas (must reserve it) */
+ HWND window;
+ HDC device;
+ HGLRC context;
+ HPALETTE palette;
+ int is_owned_dc;
+};
+
+static int wGLCanvasDefaultResize_CB(Ihandle *ih, int width, int height)
+{
+ IupGLMakeCurrent(ih);
+ glViewport(0,0,width,height);
+ return IUP_DEFAULT;
+}
+
+static int wGLCanvasCreateMethod(Ihandle* ih, void** params)
+{
+ (void)params;
+ free(ih->data); /* allocated by the iCanvasCreateMethod of IupCanvas */
+ ih->data = iupALLOCCTRLDATA();
+ IupSetCallback(ih, "RESIZE_CB", (Icallback)wGLCanvasDefaultResize_CB);
+ return IUP_NOERROR;
+}
+
+static int wGLCreateContext(Ihandle* ih)
+{
+ Ihandle* ih_shared;
+ int number;
+ int isIndex = 0;
+ int pixelFormat;
+ PIXELFORMATDESCRIPTOR test_pfd;
+ PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
+ 1, /* version number */
+ PFD_DRAW_TO_WINDOW | /* support window */
+ PFD_SUPPORT_OPENGL, /* support OpenGL */
+ PFD_TYPE_RGBA, /* RGBA type */
+ 24, /* 24-bit color depth */
+ 0, 0, 0, 0, 0, 0, /* color bits ignored */
+ 0, /* no alpha buffer */
+ 0, /* shift bit ignored */
+ 0, /* no accumulation buffer */
+ 0, 0, 0, 0, /* accum bits ignored */
+ 16, /* 32-bit z-buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffer */
+ PFD_MAIN_PLANE, /* main layer */
+ 0, /* reserved */
+ 0, 0, 0 /* layer masks ignored */
+ };
+
+ /* the IupCanvas is already mapped, just initialize the OpenGL context */
+
+ /* double or single buffer */
+ if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE"))
+ pfd.dwFlags |= PFD_DOUBLEBUFFER;
+
+ /* stereo */
+ if (iupAttribGetBoolean(ih,"STEREO"))
+ pfd.dwFlags |= PFD_STEREO;
+
+ /* rgba or index */
+ if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX"))
+ {
+ isIndex = 1;
+ pfd.iPixelType = PFD_TYPE_COLORINDEX;
+ pfd.cColorBits = 8; /* assume 8 bits when indexed */
+ number = iupAttribGetInt(ih,"BUFFER_SIZE");
+ if (number > 0) pfd.cColorBits = (BYTE)number;
+ }
+
+ /* red, green, blue bits */
+ number = iupAttribGetInt(ih,"RED_SIZE");
+ if (number > 0) pfd.cRedBits = (BYTE)number;
+ pfd.cRedShift = 0;
+
+ number = iupAttribGetInt(ih,"GREEN_SIZE");
+ if (number > 0) pfd.cGreenBits = (BYTE)number;
+ pfd.cGreenShift = pfd.cRedBits;
+
+ number = iupAttribGetInt(ih,"BLUE_SIZE");
+ if (number > 0) pfd.cBlueBits = (BYTE)number;
+ pfd.cBlueShift = pfd.cRedBits + pfd.cGreenBits;
+
+ number = iupAttribGetInt(ih,"ALPHA_SIZE");
+ if (number > 0) pfd.cAlphaBits = (BYTE)number;
+ pfd.cAlphaShift = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits;
+
+ /* depth and stencil size */
+ number = iupAttribGetInt(ih,"DEPTH_SIZE");
+ if (number > 0) pfd.cDepthBits = (BYTE)number;
+
+ /* stencil */
+ number = iupAttribGetInt(ih,"STENCIL_SIZE");
+ if (number > 0) pfd.cStencilBits = (BYTE)number;
+
+ /* red, green, blue accumulation bits */
+ number = iupAttribGetInt(ih,"ACCUM_RED_SIZE");
+ if (number > 0) pfd.cAccumRedBits = (BYTE)number;
+
+ number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE");
+ if (number > 0) pfd.cAccumGreenBits = (BYTE)number;
+
+ number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE");
+ if (number > 0) pfd.cAccumBlueBits = (BYTE)number;
+
+ number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE");
+ if (number > 0) pfd.cAccumAlphaBits = (BYTE)number;
+
+ pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits;
+
+ /* get a device context */
+ {
+ LONG style = GetClassLong(ih->data->window, GCL_STYLE);
+ ih->data->is_owned_dc = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC));
+ }
+
+ ih->data->device = GetDC(ih->data->window);
+ iupAttribSetStr(ih, "VISUAL", (char*)ih->data->device);
+
+ /* choose pixel format */
+ pixelFormat = ChoosePixelFormat(ih->data->device, &pfd);
+ if (pixelFormat == 0)
+ {
+ iupAttribSetStr(ih, "ERROR", "No appropriate pixel format.");
+ return IUP_NOERROR;
+ }
+ SetPixelFormat(ih->data->device,pixelFormat,&pfd);
+
+ /* create rendering context */
+ ih->data->context = wglCreateContext(ih->data->device);
+ if (!ih->data->context)
+ {
+ iupAttribSetStr(ih, "ERROR", "Could not create a rendering context.");
+ return IUP_NOERROR;
+ }
+ iupAttribSetStr(ih, "CONTEXT", (char*)ih->data->context);
+
+ ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT");
+ if (ih_shared && iupStrEqual(ih_shared->iclass->name, "glcanvas")) /* must be an IupGLCanvas */
+ wglShareLists(ih_shared->data->context, ih->data->context);
+
+ DescribePixelFormat(ih->data->device, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &test_pfd);
+ if ((pfd.dwFlags & PFD_STEREO) && !(test_pfd.dwFlags & PFD_STEREO))
+ {
+ iupAttribSetStr(ih, "ERROR", "Stereo not available.");
+ return IUP_NOERROR;
+ }
+
+ /* create colormap for index mode */
+ if (isIndex)
+ {
+ if (!ih->data->palette)
+ {
+ LOGPALETTE lp = {0x300,1,{255,255,255,PC_NOCOLLAPSE}}; /* set first color as white */
+ ih->data->palette = CreatePalette(&lp);
+ ResizePalette(ih->data->palette,1<<pfd.cColorBits);
+ iupAttribSetStr(ih, "COLORMAP", (char*)ih->data->palette);
+ }
+
+ SelectPalette(ih->data->device,ih->data->palette,FALSE);
+ RealizePalette(ih->data->device);
+ }
+
+ return IUP_NOERROR;
+}
+
+static int wGLCanvasMapMethod(Ihandle* ih)
+{
+ /* get a device context */
+ ih->data->window = (HWND)iupAttribGet(ih, "HWND"); /* check first in the hash table, can be defined by the IupFileDlg */
+ if (!ih->data->window)
+ ih->data->window = (HWND)IupGetAttribute(ih, "HWND"); /* works for Win32 and GTK, only after mapping the IupCanvas */
+ if (!ih->data->window)
+ return IUP_NOERROR;
+
+ {
+ LONG style = GetClassLong(ih->data->window, GCL_STYLE);
+ ih->data->is_owned_dc = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC));
+ }
+
+ return wGLCreateContext(ih);
+}
+
+static void wGLCanvasUnMapMethod(Ihandle* ih)
+{
+ if (ih->data->context)
+ {
+ if (ih->data->context == wglGetCurrentContext())
+ wglMakeCurrent(NULL, NULL);
+
+ wglDeleteContext(ih->data->context);
+ }
+
+ if (ih->data->palette)
+ DeleteObject((HGDIOBJ)ih->data->palette);
+
+ if (ih->data->device)
+ ReleaseDC(ih->data->window, ih->data->device);
+}
+
+static int wGLCanvasSetRefreshContextAttrib(Ihandle* ih, const char* value)
+{
+ if (!ih->data->is_owned_dc)
+ {
+ if (ih->data->context)
+ {
+ if (ih->data->context == wglGetCurrentContext())
+ wglMakeCurrent(NULL, NULL);
+
+ wglDeleteContext(ih->data->context);
+ }
+
+ if (ih->data->device)
+ ReleaseDC(ih->data->window, ih->data->device);
+
+ wGLCreateContext(ih);
+ }
+
+ (void)value;
+ return 0;
+}
+
+static Iclass* wGlCanvasGetClass(void)
+{
+ Iclass* ic = iupClassNew(iupCanvasGetClass());
+
+ ic->name = "glcanvas";
+ ic->format = "A"; /* one optional callback name */
+ ic->nativetype = IUP_TYPECANVAS;
+ ic->childtype = IUP_CHILDNONE;
+ ic->is_interactive = 1;
+
+ ic->Create = wGLCanvasCreateMethod;
+ ic->Map = wGLCanvasMapMethod;
+ ic->UnMap = wGLCanvasUnMapMethod;
+
+ iupClassRegisterAttribute(ic, "BUFFER", NULL, NULL, IUPAF_SAMEASSYSTEM, "SINGLE", IUPAF_DEFAULT);
+ iupClassRegisterAttribute(ic, "COLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "RGBA", IUPAF_DEFAULT);
+
+ iupClassRegisterAttribute(ic, "CONTEXT", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+ iupClassRegisterAttribute(ic, "VISUAL", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+ iupClassRegisterAttribute(ic, "COLORMAP", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+
+ iupClassRegisterAttribute(ic, "REFRESHCONTEXT", NULL, wGLCanvasSetRefreshContextAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+
+ return ic;
+}
+
+/******************************************* Exported functions */
+
+void IupGLCanvasOpen(void)
+{
+ if (!IupGetGlobal("_IUP_GLCANVAS_OPEN"))
+ {
+ iupRegisterClass(wGlCanvasGetClass());
+ IupSetGlobal("_IUP_GLCANVAS_OPEN", "1");
+ }
+}
+
+Ihandle* IupGLCanvas(const char *action)
+{
+ void *params[2];
+ params[0] = (void*)action;
+ params[1] = NULL;
+ return IupCreatev("glcanvas", params);
+}
+
+int IupGLIsCurrent(Ihandle* ih)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return 0;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return 0;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return 0;
+
+ if (ih->data->context == wglGetCurrentContext())
+ return 1;
+
+ return 0;
+}
+
+void IupGLMakeCurrent(Ihandle* ih)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ wglMakeCurrent(ih->data->device, ih->data->context);
+}
+
+void IupGLSwapBuffers(Ihandle* ih)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ SwapBuffers(ih->data->device);
+}
+
+void IupGLPalette(Ihandle* ih, int index, float r, float g, float b)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ /* must have a palette */
+ if (ih->data->palette)
+ {
+ PALETTEENTRY entry;
+ entry.peRed = (BYTE)(r*255);
+ entry.peGreen = (BYTE)(g*255);
+ entry.peBlue = (BYTE)(b*255);
+ entry.peFlags = PC_NOCOLLAPSE;
+ SetPaletteEntries(ih->data->palette,index,1,&entry);
+ UnrealizeObject(ih->data->device);
+ SelectPalette(ih->data->device,ih->data->palette,FALSE);
+ RealizePalette(ih->data->device);
+ }
+}
+
+void IupGLUseFont(Ihandle* ih, int first, int count, int list_base)
+{
+ HFONT old_font, font;
+
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ font = (HFONT)IupGetAttribute(ih, "HFONT");
+ if (font)
+ {
+ old_font = SelectObject(ih->data->device, font);
+ wglUseFontBitmaps(ih->data->device, first, count, list_base);
+ SelectObject(ih->data->device, old_font);
+ }
+}
+
+void IupGLWait(int gl)
+{
+ if (gl)
+ glFinish();
+ else
+ GdiFlush();
+}
diff --git a/iup/srcgl/iup_glcanvas_x.c b/iup/srcgl/iup_glcanvas_x.c
new file mode 100755
index 0000000..adddeb1
--- /dev/null
+++ b/iup/srcgl/iup_glcanvas_x.c
@@ -0,0 +1,448 @@
+/** \file
+ * \brief iupgl control for X11
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupgl.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_stdcontrols.h"
+#include "iup_assert.h"
+#include "iup_register.h"
+
+
+struct _IcontrolData
+{
+ iupCanvas canvas; /* from IupCanvas (must reserve it) */
+
+ Display* display;
+ Drawable window;
+
+ Colormap colormap;
+ XVisualInfo *vinfo;
+ GLXContext context;
+};
+
+static int xGLCanvasDefaultResize(Ihandle *ih, int width, int height)
+{
+ IupGLMakeCurrent(ih);
+ glViewport(0,0,width,height);
+ return IUP_DEFAULT;
+}
+
+static int xGLCanvasCreateMethod(Ihandle* ih, void** params)
+{
+ (void)params;
+ free(ih->data); /* allocated by the iCanvasCreateMethod of IupCanvas */
+ ih->data = iupALLOCCTRLDATA();
+ IupSetCallback(ih, "RESIZE_CB", (Icallback)xGLCanvasDefaultResize);
+ return IUP_NOERROR;
+}
+
+static void xGLCanvasGetVisual(Ihandle* ih)
+{
+ int erb, evb, number;
+ int n = 0;
+ int alist[40];
+
+ if (!ih->data->display)
+ ih->data->display = (Display*)IupGetGlobal("XDISPLAY"); /* works for Motif and GTK, can be called before mapped */
+ if (!ih->data->display)
+ return;
+
+ /* double or single buffer */
+ if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE"))
+ {
+ alist[n++] = GLX_DOUBLEBUFFER;
+ }
+
+ /* stereo */
+ if (iupAttribGetBoolean(ih,"STEREO"))
+ {
+ alist[n++] = GLX_STEREO;
+ }
+
+ /* rgba or index */
+ if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX"))
+ {
+ /* buffer size (for index mode) */
+ number = iupAttribGetInt(ih,"BUFFER_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_BUFFER_SIZE;
+ alist[n++] = number;
+ }
+ }
+ else
+ {
+ alist[n++] = GLX_RGBA; /* assume rgba as default */
+ }
+
+ /* red, green, blue bits */
+ number = iupAttribGetInt(ih,"RED_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_RED_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"GREEN_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_GREEN_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"BLUE_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_BLUE_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"ALPHA_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_ALPHA_SIZE;
+ alist[n++] = number;
+ }
+
+ /* depth and stencil size */
+ number = iupAttribGetInt(ih,"DEPTH_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_DEPTH_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"STENCIL_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_STENCIL_SIZE;
+ alist[n++] = number;
+ }
+
+ /* red, green, blue accumulation bits */
+ number = iupAttribGetInt(ih,"ACCUM_RED_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_ACCUM_RED_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_ACCUM_GREEN_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_ACCUM_BLUE_SIZE;
+ alist[n++] = number;
+ }
+
+ number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE");
+ if (number > 0)
+ {
+ alist[n++] = GLX_ACCUM_ALPHA_SIZE;
+ alist[n++] = number;
+ }
+ alist[n++] = None;
+
+ /* check out X extension */
+ if (!glXQueryExtension(ih->data->display, &erb, &evb))
+ {
+ iupAttribSetStr(ih, "ERROR", "X server has no OpenGL GLX extension");
+ return;
+ }
+
+ /* choose visual */
+ ih->data->vinfo = glXChooseVisual(ih->data->display, DefaultScreen(ih->data->display), alist);
+ if (!ih->data->vinfo)
+ iupAttribSetStr(ih, "ERROR", "No appropriate visual");
+}
+
+static char* xGLCanvasGetVisualAttrib(Ihandle *ih)
+{
+ /* This must be available before mapping, because IupCanvas uses it during map in GTK and Motif. */
+ if (ih->data->vinfo)
+ return (char*)ih->data->vinfo->visual;
+
+ xGLCanvasGetVisual(ih);
+
+ if (ih->data->vinfo)
+ return (char*)ih->data->vinfo->visual;
+
+ return NULL;
+}
+
+static int xGLCanvasMapMethod(Ihandle* ih)
+{
+ GLXContext shared_context = NULL;
+ Ihandle* ih_shared;
+
+ /* the IupCanvas is already mapped, just initialize the OpenGL context */
+
+ if (!xGLCanvasGetVisualAttrib(ih))
+ return IUP_NOERROR; /* do not abort mapping */
+
+ ih->data->window = (XID)iupAttribGet(ih, "XWINDOW"); /* check first in the hash table, can be defined by the IupFileDlg */
+ if (!ih->data->window)
+ ih->data->window = (XID)IupGetAttribute(ih, "XWINDOW"); /* works for Motif and GTK, only after mapping the IupCanvas */
+ if (!ih->data->window)
+ return IUP_NOERROR;
+
+ ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT");
+ if (ih_shared && iupStrEqual(ih_shared->iclass->name, "glcanvas")) /* must be an IupGLCanvas */
+ shared_context = ih_shared->data->context;
+
+ /* create rendering context */
+ ih->data->context = glXCreateContext(ih->data->display, ih->data->vinfo, shared_context, GL_TRUE);
+ if (!ih->data->context)
+ {
+ iupAttribSetStr(ih, "ERROR", "Could not create a rendering context");
+ return IUP_NOERROR;
+ }
+ iupAttribSetStr(ih, "CONTEXT", (char*)ih->data->context);
+
+ /* create colormap for index mode */
+ if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX") &&
+ ih->data->vinfo->class != StaticColor && ih->data->vinfo->class != StaticGray)
+ {
+ ih->data->colormap = XCreateColormap(ih->data->display, RootWindow(ih->data->display, DefaultScreen(ih->data->display)), ih->data->vinfo->visual, AllocAll);
+ iupAttribSetStr(ih, "COLORMAP", (char*)ih->data->colormap);
+ }
+
+ if (ih->data->colormap != None)
+ IupGLPalette(ih,0,1,1,1); /* set first color as white */
+
+ return IUP_NOERROR;
+}
+
+static void xGLCanvasUnMapMethod(Ihandle* ih)
+{
+ if (ih->data->context)
+ {
+ if (ih->data->context == glXGetCurrentContext())
+ glXMakeCurrent(ih->data->display, None, NULL);
+
+ glXDestroyContext(ih->data->display, ih->data->context);
+ }
+
+ if (ih->data->colormap != None)
+ XFreeColormap(ih->data->display, ih->data->colormap);
+
+ if (ih->data->vinfo)
+ XFree(ih->data->vinfo);
+}
+
+static Iclass* xGlCanvasGetClass(void)
+{
+ Iclass* ic = iupClassNew(iupCanvasGetClass());
+
+ ic->name = "glcanvas";
+ ic->format = "A"; /* one optional callback name */
+ ic->nativetype = IUP_TYPECANVAS;
+ ic->childtype = IUP_CHILDNONE;
+ ic->is_interactive = 1;
+
+ ic->Create = xGLCanvasCreateMethod;
+ ic->Map = xGLCanvasMapMethod;
+ ic->UnMap = xGLCanvasUnMapMethod;
+
+ iupClassRegisterAttribute(ic, "BUFFER", NULL, NULL, IUPAF_SAMEASSYSTEM, "SINGLE", IUPAF_DEFAULT);
+ iupClassRegisterAttribute(ic, "COLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "RGBA", IUPAF_DEFAULT);
+
+ iupClassRegisterAttribute(ic, "CONTEXT", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+ iupClassRegisterAttribute(ic, "VISUAL", xGLCanvasGetVisualAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING|IUPAF_NOT_MAPPED);
+ iupClassRegisterAttribute(ic, "COLORMAP", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+
+ return ic;
+}
+
+
+/******************************************* Exported functions */
+
+void IupGLCanvasOpen(void)
+{
+ if (!IupGetGlobal("_IUP_GLCANVAS_OPEN"))
+ {
+ iupRegisterClass(xGlCanvasGetClass());
+ IupSetGlobal("_IUP_GLCANVAS_OPEN", "1");
+ }
+}
+
+Ihandle* IupGLCanvas(const char *action)
+{
+ void *params[2];
+ params[0] = (void*)action;
+ params[1] = NULL;
+ return IupCreatev("glcanvas", params);
+}
+
+int IupGLIsCurrent(Ihandle* ih)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return 0;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return 0;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return 0;
+
+ if (ih->data->context == glXGetCurrentContext())
+ return 1;
+
+ return 0;
+}
+
+void IupGLMakeCurrent(Ihandle* ih)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ glXMakeCurrent(ih->data->display, ih->data->window, ih->data->context);
+ glXWaitX();
+}
+
+void IupGLSwapBuffers(Ihandle* ih)
+{
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ glXSwapBuffers(ih->data->display, ih->data->window);
+}
+
+static int xGLCanvasIgnoreError(Display *param1, XErrorEvent *param2)
+{
+ (void)param1;
+ (void)param2;
+ return 0;
+}
+
+void IupGLPalette(Ihandle* ih, int index, float r, float g, float b)
+{
+ XColor color;
+ int rShift, gShift, bShift;
+ XVisualInfo *vinfo;
+ XErrorHandler old_handler;
+
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ /* must have a colormap */
+ if (ih->data->colormap == None)
+ return;
+
+ /* code fragment based on the toolkit library provided with OpenGL */
+ old_handler = XSetErrorHandler(xGLCanvasIgnoreError);
+
+ vinfo = ih->data->vinfo;
+ switch (vinfo->class)
+ {
+ case DirectColor:
+ rShift = ffs((unsigned int)vinfo->red_mask) - 1;
+ gShift = ffs((unsigned int)vinfo->green_mask) - 1;
+ bShift = ffs((unsigned int)vinfo->blue_mask) - 1;
+ color.pixel = ((index << rShift) & vinfo->red_mask) |
+ ((index << gShift) & vinfo->green_mask) |
+ ((index << bShift) & vinfo->blue_mask);
+ color.red = (unsigned short)(r * 65535.0 + 0.5);
+ color.green = (unsigned short)(g * 65535.0 + 0.5);
+ color.blue = (unsigned short)(b * 65535.0 + 0.5);
+ color.flags = DoRed | DoGreen | DoBlue;
+ XStoreColor(ih->data->display, ih->data->colormap, &color);
+ break;
+ case GrayScale:
+ case PseudoColor:
+ if (index < vinfo->colormap_size)
+ {
+ color.pixel = index;
+ color.red = (unsigned short)(r * 65535.0 + 0.5);
+ color.green = (unsigned short)(g * 65535.0 + 0.5);
+ color.blue = (unsigned short)(b * 65535.0 + 0.5);
+ color.flags = DoRed | DoGreen | DoBlue;
+ XStoreColor(ih->data->display, ih->data->colormap, &color);
+ }
+ break;
+ }
+
+ XSync(ih->data->display, 0);
+ XSetErrorHandler(old_handler);
+}
+
+void IupGLUseFont(Ihandle* ih, int first, int count, int list_base)
+{
+ Font font;
+
+ iupASSERT(iupObjectCheck(ih));
+ if (!iupObjectCheck(ih))
+ return;
+
+ /* must be an IupGLCanvas */
+ if (!iupStrEqual(ih->iclass->name, "glcanvas"))
+ return;
+
+ /* must be mapped */
+ if (!ih->data->window)
+ return;
+
+ font = (Font)IupGetAttribute(ih, "XFONTID");
+ if (font)
+ glXUseXFont(font, first, count, list_base);
+}
+
+void IupGLWait(int gl)
+{
+ if (gl)
+ glXWaitGL();
+ else
+ glXWaitX();
+}
diff --git a/iup/srcgl/iupgl.def b/iup/srcgl/iupgl.def
new file mode 100755
index 0000000..d82a1b1
--- /dev/null
+++ b/iup/srcgl/iupgl.def
@@ -0,0 +1,9 @@
+EXPORTS
+IupGLCanvasOpen
+IupGLCanvas
+IupGLMakeCurrent
+IupGLSwapBuffers
+IupGLPalette
+IupGLIsCurrent
+IupGLUseFont
+IupGLWait
diff --git a/iup/srcgl/iupgl.dep b/iup/srcgl/iupgl.dep
new file mode 100644
index 0000000..52fbcfa
--- /dev/null
+++ b/iup/srcgl/iupgl.dep
@@ -0,0 +1,5 @@
+$(OBJDIR)/iup_glcanvas_x.o: iup_glcanvas_x.c ../include/iup.h ../include/iupkey.h \
+ ../include/iupdef.h ../include/iupcbs.h ../include/iupgl.h \
+ ../src/iup_object.h ../src/iup_class.h ../src/iup_table.h \
+ ../src/iup_classbase.h ../src/iup_attrib.h ../src/iup_str.h \
+ ../src/iup_stdcontrols.h ../src/iup_assert.h ../src/iup_register.h
diff --git a/iup/srcgl/make_uname b/iup/srcgl/make_uname
new file mode 100755
index 0000000..cc4b881
--- /dev/null
+++ b/iup/srcgl/make_uname
@@ -0,0 +1,3 @@
+#This builds all the libraries of the folder for 1 uname
+
+tecmake $1 $2 $3 $4 $5 $6 $7
diff --git a/iup/srcgl/make_uname.bat b/iup/srcgl/make_uname.bat
new file mode 100755
index 0000000..f0a0722
--- /dev/null
+++ b/iup/srcgl/make_uname.bat
@@ -0,0 +1,4 @@
+@echo off
+REM This builds all the libraries of the folder for 1 uname
+
+call tecmake %1 %2 %3 %4 %5 %6