aboutsummaryrefslogtreecommitdiffstats
path: root/CNativeCode
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2001-02-13 05:39:47 +0000
committerSven Gothel <[email protected]>2001-02-13 05:39:47 +0000
commitf36d363033840c84c76bf5285a252846aa9a7e96 (patch)
tree677c2801966164f79110bdc1038b997f037399f0 /CNativeCode
parent3e2b16a820bfe03f8f3837c3aaa615c8c4b7f18c (diff)
JAWT Support JDK >=1.3rel-2-5-2-0-test1
Diffstat (limited to 'CNativeCode')
-rwxr-xr-xCNativeCode/OpenGL_Win32_common.c655
-rwxr-xr-xCNativeCode/OpenGL_Win32_common.h44
-rwxr-xr-xCNativeCode/OpenGL_Win32_jawt.c650
-rw-r--r--CNativeCode/OpenGL_X11_common.c622
-rw-r--r--CNativeCode/OpenGL_X11_common.h82
-rw-r--r--CNativeCode/OpenGL_X11_jawt.c951
-rw-r--r--CNativeCode/jawt_misc.c365
-rw-r--r--CNativeCode/jawt_misc.h84
8 files changed, 3453 insertions, 0 deletions
diff --git a/CNativeCode/OpenGL_Win32_common.c b/CNativeCode/OpenGL_Win32_common.c
new file mode 100755
index 0000000..8727ca4
--- /dev/null
+++ b/CNativeCode/OpenGL_Win32_common.c
@@ -0,0 +1,655 @@
+/*
+ * Original Author: Leo Chan -- 1995
+ *
+ * Adam King 1997
+ * Ported to Win32 from X
+ *
+ * This file takes care of the C implementation of finding the correct
+ * Win32 window, assigning an OpenGL graphics context to it, storing that
+ * graphics context in the java class data structure.
+ *
+ * also contains the use() and swap() functions for double buffering
+ *
+ * September 12, 1997 - Adam King
+ * - Added support for rendering directly into a Canvas ( BIG rewrite )
+ */
+
+#include "OpenGL_Win32_common.h"
+
+// Color Palette handle
+static HPALETTE hPalette = NULL;
+static HGLRC tempRC;
+
+
+HGLRC LIBAPIENTRY get_GC( HDC * hDC, jboolean doubleBuffer,
+ jboolean stereo, jint stencilBits, HGLRC shareWith,
+ jboolean offScreenRenderer,
+ int width, int height, HBITMAP *pix,
+ jboolean verbose)
+
+{
+ const char * text=0;
+ HDC hDCOrig = 0;
+
+
+ if( *hDC == 0 && !offScreenRenderer)
+ printf( "get_GC: Error, HDC is zero\n");
+
+ // Select the pixel format
+ if(offScreenRenderer)
+ {
+ hDCOrig = *hDC;
+ *hDC = CreateCompatibleDC(hDCOrig);
+ // setupDIB(*hDC, pix, width, height);
+ setupDIB(hDCOrig, *hDC, pix, width, height);
+ /* SetDCPixelFormat(hDCOffScr, doubleBuffer, stereo, stencilBits, offScreenRenderer); */
+ /* setupPalette(hDC); USE MY PROC */
+ }
+
+ SetDCPixelFormat(*hDC, doubleBuffer, stereo, stencilBits, offScreenRenderer, verbose);
+
+ // Create palette if needed
+ hPalette = GetOpenGLPalette(*hDC);
+
+ tempRC = wglCreateContext( *hDC );
+
+ if(verbose==JNI_TRUE)
+ {
+ fprintf(stderr,"\n\nPIXELFORMAT OF GL-Context SETTINGS:\n");
+ text=GetTextualPixelFormatByHDC(*hDC);
+ fprintf(stderr,text);
+ }
+
+ /* check if the context could be created */
+ if( tempRC == NULL ) {
+ fprintf(stderr, "getGC context could NOT be created \n");
+ return( 0 );
+ }
+
+ /* associated the context with the X window */
+ if( wglMakeCurrent( *hDC, tempRC ) == FALSE) {
+ fprintf(stderr,"wglMakeCurrent(%d,%d) failed on new context!!!\n",(int)*hDC,(int)tempRC);
+ fprintf(stderr,"Error code = %d\n",(int)GetLastError());
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext( tempRC );
+ return( 0 );
+ }
+
+ if(shareWith!=NULL && wglShareLists(shareWith, tempRC)==FALSE)
+ {
+ fprintf(stderr,"\nERROR: Could not share lists between the new and the given GLContext (Win32Native)!\n");
+ fprintf(stderr,"Error code = %d\n",(int)GetLastError());
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext( tempRC );
+ return( 0 );
+ }
+
+ if(JNI_TRUE==verbose)
+ printf( "HGLRC (glContext) created: %d\n", tempRC );
+
+ return tempRC;
+}
+
+// Select the pixel format for a given device context
+void LIBAPIENTRY SetDCPixelFormat(HDC hDC, jboolean doubleBuffer,
+ jboolean stereo, jint stencilBits, jboolean offScreenRenderer,
+ jboolean verbose)
+{
+ int nPixelFormat=0;
+ const char * text=0;
+
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
+ 1, // Version of this structure
+ 0, // will be defined later !!!!
+ PFD_TYPE_RGBA, // RGBA Color mode
+ 24, // Want 24bit color
+ 0,0,0,0,0,0, // Not used to select mode
+ 0,0, // Not used to select mode
+ 0,0,0,0,0, // Not used to select mode
+ 32, // Size of depth buffer
+ 0, // Not used to select mode
+ 0, // Not used to select mode
+ PFD_MAIN_PLANE, // Draw in main plane
+ 0, // Not used to select mode
+ 0,0,0 }; // Not used to select mode
+
+
+ // customize dw_flags
+ DWORD dw_flags = PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED; // Support accelerated OpenGL calls in window
+
+ if(offScreenRenderer)
+ dw_flags |= PFD_DRAW_TO_BITMAP; // Draw to Bitmap
+ else
+ dw_flags |= PFD_DRAW_TO_WINDOW; // Draw to Window (not to bitmap)
+
+
+ if(doubleBuffer==JNI_TRUE)
+ dw_flags |= PFD_DOUBLEBUFFER ; // Double buffered is optional
+
+ if(stereo==JNI_TRUE)
+ dw_flags |= PFD_STEREO ; // Stereo is optional
+
+ pfd.dwFlags = dw_flags;
+
+ pfd.cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
+
+ if(stencilBits>0)
+ pfd.cStencilBits = (BYTE) stencilBits;
+
+ if(verbose==JNI_TRUE)
+ {
+ fprintf(stderr,"\n\nUSER CHOOSED PIXELFORMAT (TRYING):\n");
+ text=GetTextualPixelFormatByPFD(&pfd, 0);
+ fprintf(stderr,text);
+ }
+
+ // Choose a pixel format that best matches that described in pfd
+ if( hDC == 0 )
+ printf( "SetDCPixelFormat: Error, no HDC-Contex is given\n");
+ else
+ nPixelFormat = ChoosePixelFormat(hDC, &pfd);
+
+ if( nPixelFormat == 0 )
+ printf( "SetDCPixelFormat: Error with PixelFormat\n" );
+
+ // Set the pixel format for the device context
+ if( SetPixelFormat(hDC, nPixelFormat, &pfd) == FALSE)
+ printf( "setpixel failed\n" );
+}
+
+
+// If necessary, creates a 3-3-2 palette for the device context listed.
+HPALETTE LIBAPIENTRY GetOpenGLPalette(HDC hDC)
+{
+ HPALETTE hRetPal = NULL; // Handle to palette to be created
+ PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
+ LOGPALETTE *pPal; // Pointer to memory for logical palette
+ int nPixelFormat; // Pixel format index
+ int nColors; // Number of entries in palette
+ int i; // Counting variable
+ BYTE RedRange,GreenRange,BlueRange;
+ // Range for each color entry (7,7,and 3)
+
+
+ // Get the pixel format index and retrieve the pixel format description
+ nPixelFormat = GetPixelFormat(hDC);
+ DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+
+ // Does this pixel format require a palette? If not, do not create a
+ // palette and just return NULL
+ if(!(pfd.dwFlags & PFD_NEED_PALETTE))
+ return NULL;
+
+ // Number of entries in palette. 8 bits yeilds 256 entries
+ nColors = 1 << pfd.cColorBits;
+
+ // Allocate space for a logical palette structure plus all the palette entries
+ pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + nColors*sizeof(PALETTEENTRY));
+
+ // Fill in palette header
+ pPal->palVersion = 0x300; // Windows 3.0
+ pPal->palNumEntries = nColors; // table size
+
+ // Build mask of all 1's. This creates a number represented by having
+ // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
+ // pfd.cBlueBits.
+ RedRange = (1 << pfd.cRedBits) -1;
+ GreenRange = (1 << pfd.cGreenBits) - 1;
+ BlueRange = (1 << pfd.cBlueBits) -1;
+
+ // Loop through all the palette entries
+ for(i = 0; i < nColors; i++)
+ {
+ // Fill in the 8-bit equivalents for each component
+ pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
+ pPal->palPalEntry[i].peRed = (unsigned char)(
+ (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
+
+ pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
+ pPal->palPalEntry[i].peGreen = (unsigned char)(
+ (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
+
+ pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
+ pPal->palPalEntry[i].peBlue = (unsigned char)(
+ (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
+
+ pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
+ }
+
+
+ // Create the palette
+ hRetPal = CreatePalette(pPal);
+
+ // Go ahead and select and realize the palette for this device context
+ SelectPalette(hDC,hRetPal,FALSE);
+ RealizePalette(hDC);
+
+ // Free the memory used for the logical palette structure
+ free(pPal);
+
+ // Return the handle to the new palette
+ return hRetPal;
+}
+
+
+jboolean LIBAPIENTRY testWin32Java()
+{
+ jboolean ret=JNI_TRUE;
+
+ /* NON DEPENDENCE CHECKS */
+
+ /* FIRST OF ALL CHECK IF A NATIVE POINTER OR WIN32-TYPE FITS IN �jint� */
+
+ if( sizeof(jlong) < sizeof(int *) )
+ {
+ fprintf(stderr,"(int *) fits not in jlong\n");
+ ret = JNI_FALSE;
+ }
+
+ if( sizeof(jlong) < sizeof(HDC) )
+ {
+ fprintf(stderr,"HDC fits not in jlong\n");
+ ret = JNI_FALSE;
+ }
+
+ if( sizeof(jlong) < sizeof(HGLRC) )
+ {
+ fprintf(stderr,"HGLRC fits not in jlong\n");
+ ret = JNI_FALSE;
+ }
+
+ if(ret==JNI_FALSE)
+ {
+ fflush(stderr);
+ }
+
+ return ret;
+}
+
+
+static void
+PrintMessage( const char *Format, ... )
+{
+ va_list ArgList;
+ char Buffer[256];
+
+ va_start(ArgList, Format);
+ vsprintf(Buffer, Format, ArgList);
+ va_end(ArgList);
+
+ fprintf(stderr, Buffer);
+}
+
+
+int LIBAPIENTRY
+PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd )
+{
+ int PfdIndex;
+
+ if ( 0 < (PfdIndex = GetPixelFormat( Dc )) )
+ {
+ if ( 0 < DescribePixelFormat( Dc, PfdIndex, sizeof(*Pfd), Pfd ) )
+ {
+ return(PfdIndex);
+ }
+ else
+ {
+ PrintMessage("Could not get a description of pixel format %d\n",
+ PfdIndex );
+ }
+ }
+ else
+ {
+ PrintMessage("Could not get pixel format for Dc 0x%08lX\n", Dc );
+ }
+ return( 0 );
+}
+
+
+const char * LIBAPIENTRY
+GetTextualPixelFormatByPFD(PIXELFORMATDESCRIPTOR *ppfd, int format)
+{
+ static char buffer[2000];
+ char line[200];
+
+ sprintf(buffer,"Pixel format %d\n", format);
+ sprintf(line," dwFlags - 0x%x\n", ppfd->dwFlags);
+ if (ppfd->dwFlags & PFD_DOUBLEBUFFER) { strcat(buffer, line); sprintf(line,"\tPFD_DOUBLEBUFFER\n "); }
+ if (ppfd->dwFlags & PFD_STEREO) { strcat(buffer, line); sprintf(line,"\tPFD_STEREO\n "); }
+ if (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) { strcat(buffer, line); sprintf(line,"\tPFD_DRAW_TO_WINDOW\n "); }
+ if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) { strcat(buffer, line); sprintf(line,"\tPFD_DRAW_TO_BITMAP\n "); }
+ if (ppfd->dwFlags & PFD_SUPPORT_GDI) { strcat(buffer, line); sprintf(line,"\tPFD_SUPPORT_GDI\n "); }
+ if (ppfd->dwFlags & PFD_SUPPORT_OPENGL) { strcat(buffer, line); sprintf(line,"\tPFD_SUPPORT_OPENGL\n "); }
+ if (ppfd->dwFlags & PFD_GENERIC_ACCELERATED) { strcat(buffer, line); sprintf(line,"\tPFD_GENERIC_ACCELERATED\n "); }
+ if (ppfd->dwFlags & PFD_GENERIC_FORMAT) { strcat(buffer, line); sprintf(line,"\tPFD_GENERIC_FORMAT\n "); }
+ if (ppfd->dwFlags & PFD_NEED_PALETTE) { strcat(buffer, line); sprintf(line,"\tPFD_NEED_PALETTE\n "); }
+ if (ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE) { strcat(buffer, line); sprintf(line,"\tPFD_NEED_SYSTEM_PALETTE\n "); }
+ strcat(buffer, line); sprintf(line,"\n");
+ strcat(buffer, line); sprintf(line," iPixelType - %d\n", ppfd->iPixelType);
+ if (ppfd->iPixelType == PFD_TYPE_RGBA) { strcat(buffer, line); sprintf(line,"\tPGD_TYPE_RGBA\n"); }
+ if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) { strcat(buffer, line); sprintf(line,"\tPGD_TYPE_COLORINDEX\n"); }
+ strcat(buffer, line); sprintf(line," cColorBits - %d\n", ppfd->cColorBits);
+ strcat(buffer, line); sprintf(line," cRedBits - %d\n", ppfd->cRedBits);
+ strcat(buffer, line); sprintf(line," cRedShift - %d\n", ppfd->cRedShift);
+ strcat(buffer, line); sprintf(line," cGreenBits - %d\n", ppfd->cGreenBits);
+ strcat(buffer, line); sprintf(line," cGreenShift - %d\n", ppfd->cGreenShift);
+ strcat(buffer, line); sprintf(line," cBlueBits - %d\n", ppfd->cBlueBits);
+ strcat(buffer, line); sprintf(line," cBlueShift - %d\n", ppfd->cBlueShift);
+ strcat(buffer, line); sprintf(line," cAlphaBits - %d\n", ppfd->cAlphaBits);
+ strcat(buffer, line); sprintf(line," cAlphaShift - 0x%x\n", ppfd->cAlphaShift);
+ strcat(buffer, line); sprintf(line," cAccumBits - %d\n", ppfd->cAccumBits);
+ strcat(buffer, line); sprintf(line," cAccumRedBits - %d\n", ppfd->cAccumRedBits);
+ strcat(buffer, line); sprintf(line," cAccumGreenBits - %d\n", ppfd->cAccumGreenBits);
+ strcat(buffer, line); sprintf(line," cAccumBlueBits - %d\n", ppfd->cAccumBlueBits);
+ strcat(buffer, line); sprintf(line," cAccumAlphaBits - %d\n", ppfd->cAccumAlphaBits);
+ strcat(buffer, line); sprintf(line," cDepthBits - %d\n", ppfd->cDepthBits);
+ strcat(buffer, line); sprintf(line," cStencilBits - %d\n", ppfd->cStencilBits);
+ strcat(buffer, line); sprintf(line," cAuxBuffers - %d\n", ppfd->cAuxBuffers);
+ strcat(buffer, line); sprintf(line," iLayerType - %d\n", ppfd->iLayerType);
+ strcat(buffer, line); sprintf(line," bReserved - %d\n", ppfd->bReserved);
+ strcat(buffer, line); sprintf(line," dwLayerMask - 0x%x\n", ppfd->dwLayerMask);
+ strcat(buffer, line); sprintf(line," dwVisibleMask - 0x%x\n", ppfd->dwVisibleMask);
+ strcat(buffer, line); sprintf(line," dwDamageMask - 0x%x\n", ppfd->dwDamageMask);
+ strcat(buffer, line);
+ return buffer;
+}
+
+const char * LIBAPIENTRY GetTextualPixelFormatByHDC(HDC hdc)
+{
+ PIXELFORMATDESCRIPTOR pfd, *ppfd;
+ int format;
+
+ ppfd = &pfd;
+ format = PixelFormatDescriptorFromDc( hdc, ppfd );
+
+ return GetTextualPixelFormatByPFD(ppfd, format);
+}
+
+/*****************************************************************/
+
+/* Struct used to manage color ramps */
+static struct colorIndexState {
+ GLfloat amb[3]; /* ambient color / bottom of ramp */
+ GLfloat diff[3]; /* diffuse color / middle of ramp */
+ GLfloat spec[3]; /* specular color / top of ramp */
+ GLfloat ratio; /* ratio of diffuse to specular in ramp */
+ GLint indexes[3]; /* where ramp was placed in palette */
+};
+#define NUM_COLORS (sizeof(colors) / sizeof(colors[0]))
+static struct colorIndexState colors[] = {
+ {
+ { 0.0F, 0.0F, 0.0F },
+ { 0.1F, 0.6F, 0.3F },
+ { 1.0F, 1.0F, 1.0F },
+ 0.75F, { 0, 0, 0 },
+ },
+ {
+ { 0.0F, 0.0F, 0.0F },
+ { 0.0F, 0.2F, 0.5F },
+ { 1.0F, 1.0F, 1.0F },
+ 0.75F, { 0, 0, 0 },
+ },
+ {
+ { 0.0F, 0.05F, 0.05F },
+ { 0.6F, 0.0F, 0.8F },
+ { 1.0F, 1.0F, 1.0F },
+ 0.75F, { 0, 0, 0 },
+ },
+};
+
+
+void LIBAPIENTRY
+setupDIB(HDC hDCOrig, HDC hDC, HBITMAP * hBitmap, int width, int height)
+{
+ BITMAPINFO *bmInfo;
+ BITMAPINFOHEADER *bmHeader;
+ UINT usage;
+ VOID *base;
+ int bmiSize;
+ int bitsPerPixel;
+ HBITMAP hOldBitmap=0;
+
+ bmiSize = sizeof(*bmInfo);
+ bitsPerPixel = GetDeviceCaps(hDC, BITSPIXEL);
+
+ switch (bitsPerPixel) {
+ case 8:
+ // bmiColors is 256 WORD palette indices
+ bmiSize += (256 * sizeof(WORD)) - sizeof(RGBQUAD);
+ break;
+ case 16:
+ // bmiColors is 3 WORD component masks
+ bmiSize += (3 * sizeof(DWORD)) - sizeof(RGBQUAD);
+ break;
+ case 24:
+ case 32:
+ default:
+ // bmiColors not used
+ break;
+ }
+
+ bmInfo = (BITMAPINFO *) calloc(1, bmiSize);
+ bmHeader = &bmInfo->bmiHeader;
+
+ bmHeader->biSize = sizeof(*bmHeader);
+ bmHeader->biWidth = width;
+ bmHeader->biHeight = height;
+ bmHeader->biPlanes = 1; // must be 1
+ bmHeader->biBitCount = bitsPerPixel;
+ bmHeader->biXPelsPerMeter = 0;
+ bmHeader->biYPelsPerMeter = 0;
+ bmHeader->biClrUsed = 0; // all are used
+ bmHeader->biClrImportant = 0; // all are important
+
+ switch (bitsPerPixel) {
+ case 8:
+ bmHeader->biCompression = BI_RGB;
+ bmHeader->biSizeImage = 0;
+ usage = DIB_PAL_COLORS;
+ // bmiColors is 256 WORD palette indices
+ {
+ WORD *palIndex = (WORD *) &bmInfo->bmiColors[0];
+ int i;
+
+ for (i=0; i<256; i++) {
+ palIndex[i] = i;
+ }
+ }
+ break;
+ case 16:
+ bmHeader->biCompression = BI_RGB;
+ bmHeader->biSizeImage = 0;
+ usage = DIB_RGB_COLORS;
+ // bmiColors is 3 WORD component masks
+ {
+ DWORD *compMask = (DWORD *) &bmInfo->bmiColors[0];
+
+ compMask[0] = 0xF800;
+ compMask[1] = 0x07E0;
+ compMask[2] = 0x001F;
+ }
+ break;
+ case 24:
+ case 32:
+ default:
+ bmHeader->biCompression = BI_RGB;
+ bmHeader->biSizeImage = 0;
+ usage = DIB_RGB_COLORS;
+ // bmiColors not used
+ break;
+ }
+
+ *hBitmap = CreateDIBSection(hDC, bmInfo, usage, &base, NULL, 0);
+ if (*hBitmap == NULL) {
+ (void) MessageBox(WindowFromDC(hDC),
+ "Failed to create DIBSection.",
+ "OpenGL application error",
+ MB_ICONERROR | MB_OK);
+ exit(1);
+ }
+
+ hOldBitmap = SelectObject(hDC, *hBitmap);
+ if(hOldBitmap!=0)
+ DeleteObject(hOldBitmap);
+
+ free(bmInfo);
+}
+
+
+/*
+static void
+setupDIB(HDC hDCOrig, HDC hDC, HBITMAP * hBitmap, int width, int height)
+{
+ HBITMAP hOldBitmap=0;
+
+ *hBitmap = CreateCompatibleBitmap( hDCOrig, width, height );
+ if (*hBitmap == NULL) {
+ fprintf(stderr,"Failed to create CreateCompatibleBitmap! \n");
+ fflush(stderr);
+ return;
+ }
+
+ hOldBitmap = SelectObject(hDC, *hBitmap);
+ if(hOldBitmap!=0)
+ DeleteObject(hOldBitmap);
+}
+*/
+
+
+void LIBAPIENTRY resizeDIB(HDC hDC, HBITMAP *hOldBitmap, HBITMAP *hBitmap)
+{
+ /*
+ SelectObject(hDC, *hOldBitmap);
+ DeleteObject(*hBitmap);
+ setupDIB(hDC, hBitmap);
+ */
+}
+
+void LIBAPIENTRY setupPalette(HDC hDC)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ LOGPALETTE* pPal;
+ int pixelFormat = GetPixelFormat(hDC);
+ int paletteSize;
+
+ DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+
+ /*
+ ** Determine if a palette is needed and if so what size.
+ */
+ if (pfd.dwFlags & PFD_NEED_PALETTE) {
+ paletteSize = 1 << pfd.cColorBits;
+ } else if (pfd.iPixelType == PFD_TYPE_COLORINDEX) {
+ paletteSize = 4096;
+ } else {
+ return;
+ }
+
+ pPal = (LOGPALETTE*)
+ malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
+ pPal->palVersion = 0x300;
+ pPal->palNumEntries = paletteSize;
+
+ if (pfd.iPixelType == PFD_TYPE_RGBA) {
+ /*
+ ** Fill the logical paletee with RGB color ramps
+ */
+ int redMask = (1 << pfd.cRedBits) - 1;
+ int greenMask = (1 << pfd.cGreenBits) - 1;
+ int blueMask = (1 << pfd.cBlueBits) - 1;
+ int i;
+
+ for (i=0; i<paletteSize; ++i) {
+ pPal->palPalEntry[i].peRed =
+ (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
+ pPal->palPalEntry[i].peGreen =
+ (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
+ pPal->palPalEntry[i].peBlue =
+ (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
+ pPal->palPalEntry[i].peFlags = 0;
+ }
+ } else {
+ /*
+ ** Fill the logical palette with color ramps.
+ **
+ ** Set up the logical palette so that it can be realized
+ ** into the system palette as an identity palette.
+ **
+ ** 1) The default static entries should be present and at the right
+ ** location. The easiest way to do this is to grab them from
+ ** the current system palette.
+ **
+ ** 2) All non-static entries should be initialized to unique values.
+ ** The easiest way to do this is to ensure that all of the non-static
+ ** entries have the PC_NOCOLLAPSE flag bit set.
+ */
+ int numRamps = NUM_COLORS;
+ int rampSize = (paletteSize - 20) / numRamps;
+ int extra = (paletteSize - 20) - (numRamps * rampSize);
+ int i, r;
+
+ /*
+ ** Initialize static entries by copying them from the
+ ** current system palette.
+ */
+ GetSystemPaletteEntries(hDC, 0, paletteSize, &pPal->palPalEntry[0]);
+
+ /*
+ ** Fill in non-static entries with desired colors.
+ */
+ for (r=0; r<numRamps; ++r) {
+ int rampBase = r * rampSize + 10;
+ PALETTEENTRY *pe = &pPal->palPalEntry[rampBase];
+ int diffSize = (int) (rampSize * colors[r].ratio);
+ int specSize = rampSize - diffSize;
+
+ for (i=0; i<rampSize; ++i) {
+ GLfloat *c0, *c1;
+ GLint a;
+
+ if (i < diffSize) {
+ c0 = colors[r].amb;
+ c1 = colors[r].diff;
+ a = (i * 255) / (diffSize - 1);
+ } else {
+ c0 = colors[r].diff;
+ c1 = colors[r].spec;
+ a = ((i - diffSize) * 255) / (specSize - 1);
+ }
+
+ pe[i].peRed = (BYTE) (a * (c1[0] - c0[0]) + 255 * c0[0]);
+ pe[i].peGreen = (BYTE) (a * (c1[1] - c0[1]) + 255 * c0[1]);
+ pe[i].peBlue = (BYTE) (a * (c1[2] - c0[2]) + 255 * c0[2]);
+ pe[i].peFlags = PC_NOCOLLAPSE;
+ }
+
+ colors[r].indexes[0] = rampBase;
+ colors[r].indexes[1] = rampBase + (diffSize-1);
+ colors[r].indexes[2] = rampBase + (rampSize-1);
+ }
+
+ /*
+ ** Initialize any remaining non-static entries.
+ */
+ for (i=0; i<extra; ++i) {
+ int index = numRamps*rampSize+10+i;
+ PALETTEENTRY *pe = &pPal->palPalEntry[index];
+
+ pe->peRed = (BYTE) 0;
+ pe->peGreen = (BYTE) 0;
+ pe->peBlue = (BYTE) 0;
+ pe->peFlags = PC_NOCOLLAPSE;
+ }
+ }
+
+ hPalette = CreatePalette(pPal);
+ free(pPal);
+
+ if (hPalette) {
+ SelectPalette(hDC, hPalette, FALSE);
+ RealizePalette(hDC);
+ }
+}
+
+
diff --git a/CNativeCode/OpenGL_Win32_common.h b/CNativeCode/OpenGL_Win32_common.h
new file mode 100755
index 0000000..f8c6ca4
--- /dev/null
+++ b/CNativeCode/OpenGL_Win32_common.h
@@ -0,0 +1,44 @@
+#ifndef _OPENGL_WIN32_COMMON_H
+#define _OPENGL_WIN32_COMMON_H
+
+#include "OpenGL_misc.h"
+
+#include <wingdi.h>
+
+
+// Set Pixel Format function - forward declaration
+LIBAPI void LIBAPIENTRY SetDCPixelFormat(HDC hDC, jboolean doubleBuffer,
+ jboolean stereo, jint stencilBits, jboolean offScreenRenderer,
+ jboolean verbose);
+
+LIBAPI HPALETTE LIBAPIENTRY GetOpenGLPalette(HDC hDC);
+
+LIBAPI HGLRC LIBAPIENTRY get_GC( HDC *hDC, jboolean doubleBuffer,
+ jboolean stereo, jint stencilBits, HGLRC shareWith,
+ jboolean offScreenRenderer,
+ int width, int height, HBITMAP *pix,
+ jboolean verbose);
+
+LIBAPI int LIBAPIENTRY PixelFormatDescriptorFromDc( HDC Dc,
+ PIXELFORMATDESCRIPTOR *Pfd );
+
+const char * LIBAPIENTRY GetTextualPixelFormatByHDC(HDC hdc);
+
+const char * LIBAPIENTRY GetTextualPixelFormatByPFD(
+ PIXELFORMATDESCRIPTOR *ppfd, int format);
+
+/* testX11Java does important implementation plattformspecific checks:
+ *
+ * o do fit X11-Vars in jint (because GLContext stores 'em like that)
+ */
+LIBAPI jboolean LIBAPIENTRY testWin32Java(void);
+
+LIBAPI void LIBAPIENTRY setupDIB(HDC hDCOrig, HDC hDC, HBITMAP * hBitmap,
+ int width, int height);
+
+LIBAPI void LIBAPIENTRY resizeDIB(HDC hDC, HBITMAP *hOldBitmap,
+ HBITMAP *hBitmap);
+
+LIBAPI void LIBAPIENTRY setupPalette(HDC hDC);
+
+#endif
diff --git a/CNativeCode/OpenGL_Win32_jawt.c b/CNativeCode/OpenGL_Win32_jawt.c
new file mode 100755
index 0000000..e65fbc6
--- /dev/null
+++ b/CNativeCode/OpenGL_Win32_jawt.c
@@ -0,0 +1,650 @@
+/*
+ * Original Author: Leo Chan -- 1995
+ *
+ * Adam King 1997
+ * Ported to Win32 from X
+ *
+ * This file takes care of the C implementation of finding the correct
+ * Win32 window, assigning an OpenGL graphics context to it, storing that
+ * graphics context in the java class data structure.
+ *
+ * also contains the use() and swap() functions for double buffering
+ *
+ * September 12, 1997 - Adam King
+ * - Added support for rendering directly into a Canvas ( BIG rewrite )
+ */
+
+/**
+ * Pointer Semantics of GLContext:
+ * ==============================
+
+ "displayHandle" := not used
+
+ "pData" := (JAWTDataHolder *)
+ "windowHandle" := "pData"
+
+ This holds the current state of the JAWT context !
+
+ This is used as the "not initialized" flag also !
+ It is reset to zero while Destroy Method
+
+ "pData"->dsi_win := (HDC)
+ if("offScreenRenderer" == TRUE)
+ "pData"->dsi_win contains the window handle,
+ of the last lock !
+ "pData"->dsi_win_created=0 !
+
+ "pixmapHandle" := (HBITMAP)
+ if("offScreenRenderer" == TRUE)
+ "pixmapHandle" contains the new BITMAP (by CreateDIBSection)!
+ "windowHandle" contains the new created OffScreenWindow
+ (by CreateCompatibleDC)!
+ else
+ "pixmapHandle" is unused !
+
+ "sharedGLContextNative" := (HGLRC)
+ This is the optional shared GLContext !
+
+ "glContext" := (HGLRC)
+ This is THE used GLContext !
+ */
+
+#include "OpenGL_Win32_common.h"
+
+#include "jawt_misc.h"
+
+/*
+ * Macros ..
+ */
+
+#define GET_W32_JAWT_DSI(a) \
+ ( (JAWT_Win32DrawingSurfaceInfo *) \
+ ( ( (JAWTDataHolder *)((PointerHolder)(a)) ) ->dsi_os ) \
+ )
+
+#define GET_USED_WINDOW(a) \
+ ( (HDC) \
+ ( ( (JAWTDataHolder *)((PointerHolder)(a)) ) ->dsi_win ) \
+ )
+
+static jboolean verbose = JNI_FALSE;
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_useJAWT( JNIEnv *env, jobject obj )
+{
+ (void)env;
+ (void)obj;
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj,
+ jlong thisWin )
+{
+ JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin );
+ (void)env;
+ (void)obj;
+
+ return (pData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 ;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_openOpenGLNative( JNIEnv *env, jobject obj,
+ jobject canvas)
+{
+ jboolean ret = JNI_TRUE;
+
+ jclass cls = 0;
+ jfieldID fpixmapHandle=0;
+ jfieldID foffScreenRenderer;
+ jfieldID faccumSize=0;
+ jfieldID fwindowHandle=0, fpData=0, fdoubleBuffer, fstereoView, fstencilBits;
+ jfieldID fverbose=0;
+ jfieldID fglContext=0;
+ jfieldID fshareWith=0;
+ jfieldID fcreatewinw = 0, fcreatewinh = 0;
+
+ /* these variables will be mapped in the java-object ! */
+ jboolean joffScreenRenderer=JNI_FALSE;
+ jboolean jdoubleBuffer=JNI_TRUE;
+ jboolean jstereoView=JNI_FALSE;
+ jint jstencilBits=0;
+ jint jaccumSize=0;
+ HDC theWindow;
+ HGLRC gc;
+ JAWTDataHolder * pData=0;
+ HGLRC shareWith=NULL;
+ jint jcreatewinw = 0, jcreatewinh = 0;
+ HBITMAP pix;
+
+ PIXELFORMATDESCRIPTOR pfd;
+
+ cls = (*env)->GetObjectClass(env, obj);
+ if(cls==0)
+ {
+ fprintf(stderr,"oo0.0 cls==0\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE)
+ {
+ fverbose =(*env)->GetStaticFieldID(env, cls, "gljNativeDebug", "Z");
+ if (fverbose == 0)
+ {
+ fprintf(stderr,"oo0.2 fverbose==0\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ } else {
+ verbose = (*env)->GetStaticBooleanField(env, cls, fverbose);
+ }
+ }
+
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "sizes:\n jlong=%d\n HGLRC=%d\n HDC=%d\n",
+ sizeof(jlong), sizeof(HGLRC), sizeof(HDC) );
+ fflush(stderr);
+ }
+
+ /* FIRST OF ALL CHECK IF A NATIVE POINTER OR WIN-TYPE FITS IN �jlong� */
+ ret = testWin32Java();
+
+ ret = testJavaGLTypes(verbose);
+
+ if(ret==JNI_TRUE) {
+ fpData = (*env)->GetFieldID(env, cls, "pData", "J");
+ if (fpData == 0) ret= JNI_FALSE;
+ else pData = (JAWTDataHolder *)
+ ( (PointerHolder)(*env)->GetLongField(env, obj, fpData));
+ }
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "received pData : %d\n", (int)pData);
+ }
+
+ if(ret==JNI_TRUE) {
+ fwindowHandle = (*env)->GetFieldID(env, cls, "windowHandle", "J");
+ if (fwindowHandle == 0) ret= JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ fglContext=(*env)->GetFieldID(env, cls, "glContext", "J");
+ if (fglContext == 0) ret= JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ foffScreenRenderer =
+ (*env)->GetFieldID(env, cls, "offScreenRenderer", "Z");
+ if (foffScreenRenderer == 0) ret= JNI_FALSE;
+ else joffScreenRenderer =(*env)->GetBooleanField(env, obj, foffScreenRenderer);
+ }
+
+ if(ret==JNI_TRUE) {
+ fdoubleBuffer = (*env)->GetFieldID(env, cls, "doubleBuffer", "Z");
+ if (fdoubleBuffer == 0) ret= JNI_FALSE;
+ else jdoubleBuffer =(*env)->GetBooleanField(env, obj, fdoubleBuffer);
+ }
+
+ if(ret==JNI_TRUE) {
+ fstereoView = (*env)->GetFieldID(env, cls, "stereoView", "Z");
+ if (fstereoView == 0) ret= JNI_FALSE;
+ else jstereoView =(*env)->GetBooleanField(env, obj, fstereoView);
+ }
+
+ if(ret==JNI_TRUE) {
+ fstencilBits = (*env)->GetFieldID(env, cls, "stencilBits", "I");
+ if (fstencilBits == 0) ret= JNI_FALSE;
+ else jstencilBits =(*env)->GetIntField(env, obj, fstencilBits);
+ }
+
+ if(ret==JNI_TRUE) {
+ faccumSize = (*env)->GetFieldID(env, cls, "accumSize", "I");
+ if (faccumSize == 0) ret= JNI_FALSE;
+ else jaccumSize =(*env)->GetIntField(env, obj, faccumSize);
+ }
+
+ if(ret==JNI_TRUE) {
+ fcreatewinw = (*env)->GetFieldID(env, cls, "createwinw", "I");
+ if (fcreatewinw == 0) ret= JNI_FALSE;
+ else jcreatewinw =(*env)->GetIntField(env, obj, fcreatewinw);
+ }
+
+ if(ret==JNI_TRUE) {
+ fcreatewinh = (*env)->GetFieldID(env, cls, "createwinh", "I");
+ if (fcreatewinh == 0) ret= JNI_FALSE;
+ else jcreatewinh =(*env)->GetIntField(env, obj, fcreatewinh);
+ }
+
+ if(ret==JNI_TRUE) {
+ fshareWith = (*env)->GetFieldID(env, cls, "sharedGLContextNative", "J");
+ if (fshareWith == 0) ret= JNI_FALSE;
+ else shareWith = (HGLRC)
+ ( (PointerHolder)(*env)->GetLongField(env, obj, fshareWith));
+ }
+
+ if(ret==JNI_TRUE) {
+ fpixmapHandle = (*env)->GetFieldID(env, cls, "pixmapHandle", "J");
+ if (fpixmapHandle == 0) ret= JNI_FALSE;
+ }
+
+ if(joffScreenRenderer==JNI_TRUE)
+ {
+ jdoubleBuffer = JNI_FALSE;
+ }
+
+ if(JNI_TRUE==verbose && joffScreenRenderer==JNI_TRUE)
+ {
+ fprintf(stderr,"\nGL4Java: (USING OFFSCREEN GLPIXMAP BUFFER,\n\t forced: !doubleBuffer)\n");
+ fflush(stderr);
+ }
+
+ if(joffScreenRenderer==JNI_TRUE)
+ {
+ jawt_create_offscreen(env, &pData, verbose);
+ }
+ else {
+ if(jawt_create_open(env, canvas, &pData, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: openOpen could not create&open JAWT reference!\n");
+ fflush(stderr);
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ ret=JNI_FALSE;
+ return ret;
+ }
+
+ if(jawt_lock(env, pData, JNI_TRUE, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: openOpen could not lock JAWT reference!\n");
+ fflush(stderr);
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ ret=JNI_FALSE;
+ return ret;
+ }
+ }
+
+ if(pData->result==JNI_TRUE)
+ {
+ if(joffScreenRenderer==JNI_FALSE)
+ {
+ theWindow = GET_W32_JAWT_DSI(pData)->hdc;
+ jcreatewinw = pData->dsi->bounds.width;
+ jcreatewinh = pData->dsi->bounds.height;
+ }
+ }
+
+ wglMakeCurrent(NULL, NULL);
+
+ /**
+ * with version jdk1.1.6 and later, we are able to use
+ * the java-function straight to achieve the native window
+ * handle ....
+ *
+ * this handle is saved to pData for the windows version !
+ */
+ if( theWindow == 0 && !joffScreenRenderer)
+ {
+ printf( "get_GC: Error, pData->hdc is zero\n");
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ return JNI_FALSE;
+ }
+
+ /* get the graphics context for this widget */
+ if( (gc = get_GC( &theWindow, jdoubleBuffer, jstereoView, jstencilBits,
+ shareWith, joffScreenRenderer, jcreatewinw,
+ jcreatewinh, &pix, verbose)) == 0 )
+ {
+ printf( "getGC error" );
+ return JNI_FALSE;
+ }
+
+ /* fetch the states of doubleBuffer and stereo */
+ (void) PixelFormatDescriptorFromDc( theWindow, &pfd);
+
+ jdoubleBuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER)?JNI_TRUE:JNI_FALSE;
+ if(ret==JNI_TRUE && fdoubleBuffer!=0) {
+ (*env)->SetBooleanField(env, obj, fdoubleBuffer,
+ jdoubleBuffer);
+ }
+
+ jstencilBits = (jint)(pfd.cStencilBits);
+ if(ret==JNI_TRUE && fstencilBits!=0) {
+ (*env)->SetIntField(env, obj,
+ fstencilBits, (jint)jstencilBits);
+ }
+
+ jaccumSize=(jint)(pfd.cAccumRedBits+pfd.cAccumGreenBits+pfd.cAccumBlueBits+pfd.cAccumAlphaBits);
+ if(ret==JNI_TRUE && faccumSize!=0) {
+ (*env)->SetIntField(env, obj,
+ faccumSize, (jint)jaccumSize);
+ }
+
+ jawt_close_unlock(env, pData, verbose);
+
+ if(ret==JNI_TRUE && fwindowHandle!=0) {
+ (*env)->SetLongField(env, obj, fwindowHandle,
+ (jlong)((PointerHolder)pData));
+ }
+ if(ret==JNI_TRUE && fpData!=0) {
+ (*env)->SetLongField(env, obj, fpData,
+ (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fpixmapHandle!=0) {
+ (*env)->SetLongField(env, obj, fpixmapHandle, (jlong)((PointerHolder)pix));
+ if(JNI_TRUE==verbose)
+ fprintf(stderr, "go and set pixmapHandle pix: %d; 0x%X\n",
+ (int)pix, (int)pix);
+ }
+
+ if(ret==JNI_TRUE && fglContext !=0 ) {
+ (*env)->SetLongField(env, obj, fglContext, (jlong)((PointerHolder)gc));
+ if(JNI_TRUE==verbose)
+ fprintf(stderr, "go and set gc : %d, 0x%X\n",
+ (int)gc, (int)gc);
+ }
+
+ /*
+ gl4java_bind_ext(JNI_TRUE==verbose);
+ */
+
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljMakeCurrentNative( JNIEnv *env, jobject obj,
+ jobject canvas,
+ jlong disp,
+ jlong thisWin,
+ jlong glContext)
+{
+ jboolean ret = JNI_TRUE;
+ JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin );
+
+ if( !thisWin )
+ {
+ return JNI_FALSE;
+ }
+
+ if( !glContext )
+ {
+ return JNI_FALSE;
+ }
+
+ if(jawt_open(env, canvas, pData, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: MakeCurrent could not open JAWT reference!\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return ret;
+ }
+
+ if(jawt_lock(env, pData, JNI_FALSE, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ /* this can happen:
+ if ( (pJData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 )
+
+ In this case, we need a new GLXContext ...
+
+ This has to be queried by the java class,
+ while using the native method hasJAWTSurfaceChanged !
+ */
+ if(verbose)
+ {
+ fprintf(stderr,"\nGL4Java ERROR: MakeCurrent could not lock JAWT reference!\n");
+ fflush(stderr);
+ }
+ ret=JNI_FALSE;
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return ret;
+ }
+
+ if ( ret==JNI_TRUE && !wglMakeCurrent(GET_USED_WINDOW(thisWin),
+ (HGLRC)((PointerHolder)glContext)) )
+ {
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljFreeNative( JNIEnv *env, jobject obj,
+ jobject canvas,
+ jlong disp,
+ jlong thisWin,
+ jlong glContext
+ )
+{
+ JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin );
+ (void)glContext;
+ (void)disp;
+ (void)canvas;
+
+ if ( ! wglMakeCurrent( NULL, NULL ) )
+ {
+ fprintf(stderr, "gljFree failed\n");
+ fflush(stderr);
+ return JNI_FALSE;
+ }
+
+ jawt_close_unlock(env, pData, verbose);
+
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljDestroyNative( JNIEnv *env, jobject obj,
+ jobject canvas)
+{
+ jboolean ret = JNI_TRUE;
+
+ jclass cls = 0;
+ jfieldID fpData=0;
+ jfieldID fwindowHandle=0, fpixmapHandle;
+ jfieldID fglContext=0;
+ jfieldID foffScreenRenderer;
+ jfieldID fownwind=0;
+
+ jboolean jownwind = JNI_FALSE ;
+ jboolean joffScreenRenderer=JNI_FALSE;
+ HBITMAP pix;
+ HDC thisWin;
+ HGLRC gc;
+ JAWTDataHolder * pData = NULL;
+
+ (void)canvas;
+
+ cls = (*env)->GetObjectClass(env, obj);
+ if(cls==0)
+ {
+ ret=JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ fwindowHandle = (*env)->GetFieldID(env, cls, "windowHandle", "J");
+ if (fwindowHandle == 0) ret= JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ fglContext=(*env)->GetFieldID(env, cls, "glContext", "J");
+ if (fglContext == 0) ret= JNI_FALSE;
+ else gc =(HGLRC)
+ ((PointerHolder)(*env)->GetLongField(env, obj, fglContext));
+ }
+
+
+ if(ret==JNI_TRUE) {
+ fpixmapHandle = (*env)->GetFieldID(env, cls, "pixmapHandle", "J");
+ if (fpixmapHandle == 0) ret= JNI_FALSE;
+ else pix =(HBITMAP)
+ ((PointerHolder)(*env)->GetLongField(env, obj, fpixmapHandle));
+ }
+
+ if(ret==JNI_TRUE) {
+ foffScreenRenderer =
+ (*env)->GetFieldID(env, cls, "offScreenRenderer", "Z");
+ if (foffScreenRenderer == 0) ret= JNI_FALSE;
+ else joffScreenRenderer =(*env)->GetBooleanField(env, obj, foffScreenRenderer);
+ }
+
+ if(ret==JNI_TRUE) {
+ fownwind = (*env)->GetFieldID(env, cls, "createOwnWindow", "Z");
+ if (fownwind == 0) ret= JNI_FALSE;
+ else jownwind =(*env)->GetBooleanField(env, obj, fownwind);
+ }
+
+ if(ret==JNI_TRUE) {
+ fpData = (*env)->GetFieldID(env, cls, "pData", "J");
+ if (fpData == 0) ret= JNI_FALSE;
+ else pData =(JAWTDataHolder *)
+ ( (PointerHolder) (*env)->GetLongField(env, obj, fpData) );
+ }
+
+
+ if(jawt_open(env, canvas, pData, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: gljDestroy could not open JAWT reference!\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return ret;
+ }
+
+ if(jawt_lock(env, pData, JNI_TRUE, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java: gljDestroy lock failed\n");
+ fflush(stderr);
+ }
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return JNI_FALSE;
+ }
+
+ thisWin = GET_USED_WINDOW(pData);
+
+ if(ret==JNI_TRUE)
+ {
+ if ( gc == 0 )
+ {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "gljDestroy failed, GL context is 0\n");
+ fflush(stderr);
+ }
+ ret = JNI_FALSE;
+ }
+
+ if ( ret==JNI_TRUE && ! wglMakeCurrent( NULL, NULL ) )
+ {
+ fprintf(stderr, "gljDestroy failed (free)\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ } else if( ret == JNI_TRUE) {
+ wglDeleteContext(gc);
+ }
+
+ if(joffScreenRenderer==JNI_TRUE)
+ {
+ if(pix!=0 && joffScreenRenderer==JNI_TRUE)
+ {
+ DeleteObject(pix);
+ pix=0;
+ }
+ if(thisWin!=0 &&
+ (joffScreenRenderer || jownwind) )
+ {
+ DeleteDC(thisWin);
+ thisWin=0;
+ }
+ }
+ }
+
+ if(ret==JNI_TRUE)
+ {
+ gc = 0;
+ thisWin = 0;
+ }
+
+ jawt_free_close_unlock(env, &pData, verbose);
+
+ if(ret==JNI_TRUE && fpData!=0) {
+ (*env)->SetLongField(env, obj, fpData, (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fwindowHandle!=0) {
+ (*env)->SetLongField(env, obj, fwindowHandle, (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fglContext) {
+ (*env)->SetLongField(env, obj, fglContext, (jlong)((PointerHolder)gc));
+ }
+
+
+ if(ret==JNI_TRUE && fpixmapHandle!=0) {
+ (*env)->SetLongField(env, obj, fpixmapHandle, (jlong)((PointerHolder)pix));
+ }
+
+ if(ret==JNI_TRUE && fownwind) {
+ (*env)->SetBooleanField(env, obj, fownwind, jownwind);
+ }
+
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljSwapNative( JNIEnv *env, jobject obj,
+ jlong disp,
+ jlong thisWin,
+ jlong glContext,
+ jboolean doubleBuffer
+ )
+{
+ jboolean ret = JNI_TRUE;
+
+ (void)glContext;
+ (void)disp;
+
+ if( !thisWin || GET_USED_WINDOW(thisWin)==0)
+ {
+ fprintf(stderr,"Swap does not got the window ...\n");
+ return JNI_FALSE;
+ }
+
+ if( doubleBuffer==JNI_TRUE )
+ {
+ if( SwapBuffers( GET_USED_WINDOW(thisWin) ) == FALSE )
+ {
+ /* Error in Win2000 implementation :o)
+ * printf( "Error in swap buffer!\n" );
+ */
+ return JNI_FALSE;
+ }
+ } else {
+ glFlush();
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gl4java_GLContext_gljResizeNative( JNIEnv *env, jobject obj,
+ jboolean isOwnWindow,
+ jlong disp, jlong thisWin,
+ jlong width, jlong height)
+{
+}
+
diff --git a/CNativeCode/OpenGL_X11_common.c b/CNativeCode/OpenGL_X11_common.c
new file mode 100644
index 0000000..cef4290
--- /dev/null
+++ b/CNativeCode/OpenGL_X11_common.c
@@ -0,0 +1,622 @@
+/*
+ * This file takes care of the C implementation of opening up an
+ * X window, assigning an OpenGL graphics context to it, storing that
+ * graphics context in the java class data structure.
+ *
+ * also contains the use() and swap() functions for double buffering
+ *
+ * Leo Chan -- 1995
+ *
+ * Adam King -- 1997
+ *
+ * Modified Creation window code to use the currently showing Java Frame
+ * window instead of creating a new window.
+ * ---------------
+ *
+ * Many improvements and changes are made !
+ *
+ * Sven Goethel
+ *
+ * September 1997
+ *
+ * some X stuff is also modified/debugged to run on aix ...
+ */
+
+/*
+ * need to include the JAVA internal header files for macros and function
+ * prototypes required to maipulated JAVA data structures and functions
+ *
+ * StubPreamble.h includes the structure and macro definitions neede to
+ * convert JAVA data structures into C data structures.
+ *
+ */
+
+#include "OpenGL_X11_common.h"
+
+/*
+ * Name : get_GC
+ *
+ * Parameters: win - the X window use to the OpenGL context with
+ * visual - The visual to create the context for
+ * gc - a pointer to a GLXContext structure. This is how
+ * the created context will be returned to the caller
+ *
+ * Returns : a pointer to a created GLXContext is returned through the
+ * gc argument.
+ * int - an error code: 0 means everything was fine
+ * -1 context creation failed
+ * -2 context/window association failed
+ *
+ * Purpose : create an X window Graphics context and assocaite it with
+ * the window. It returns 0 if everything was fine, -1 if the
+ * context could not be created, -2 if the context could not
+ * be associated with the window
+ */
+int LIBAPIENTRY get_GC( Display *display, Window win, XVisualInfo *visual,
+ GLXContext *gc, GLXContext gc_share)
+{
+ int trial = 2;
+
+ while(trial>0)
+ {
+ switch(trial)
+ {
+ case 2:
+ *gc = glXCreateContext( display, visual, gc_share, GL_TRUE );
+ break;
+ case 1:
+ *gc = glXCreateContext( display, visual, gc_share, GL_FALSE );
+ break;
+ }
+ trial--;
+
+ /* check if the context could be created */
+ if( *gc == NULL ) {
+ continue;
+ }
+
+ /* associated the context with the X window */
+ if( glXMakeCurrent( display, win, *gc ) == False) {
+ glXDestroyContext( display, *gc );
+ continue;
+ } else return 0;
+ }
+
+ return -2;
+}
+
+
+
+/**
+ * Description for pWin:
+ * if ownwin:
+ * input: the parent window
+ * output: the newly created window
+ * else if ! ownwin:
+ * i/o: the window itself
+ */
+VisualGC LIBAPIENTRY findVisualGlX( Display *display,
+ Window rootWin,
+ Window * pWin,
+ int width, int height,
+ jboolean doubleBuffer,
+ jboolean stereoView,
+ jboolean rgba,
+ jint stencilBits,
+ jint accumSize,
+ jboolean * pOwnWin,
+ GLXContext shareWith,
+ jboolean offscreen,
+ Pixmap *pix,
+ jboolean verbose
+ )
+{
+ Window newWin = 0;
+ int visualAttribList[32];
+ int i=0;
+ int j=0;
+ int done=0;
+ VisualGC vgc = { NULL, 0, 0 };
+ jboolean tryChooseVisual = JNI_TRUE;
+ int gc_ret = 0;
+
+ /**
+ * The Visual seeked by Function: findVisualIdByFeature !
+ */
+ XVisualInfo * visualList=NULL; /* the visual list, to be XFree-ed */
+
+ /* backup variables ... */
+ jboolean _rgba=rgba;
+ jint _stencilBits=stencilBits;
+ jint _accumSize=accumSize;
+ jboolean _stereoView=stereoView;
+ jboolean _doubleBuffer=doubleBuffer;
+
+ do {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java: seeking visual loop# %d\n", j);
+ }
+
+ i=0;
+ visualAttribList[i++] = GLX_RED_SIZE;
+ visualAttribList[i++] = 1;
+ visualAttribList[i++] = GLX_GREEN_SIZE;
+ visualAttribList[i++] = 1;
+ visualAttribList[i++] = GLX_BLUE_SIZE;
+ visualAttribList[i++] = 1;
+ visualAttribList[i++] = GLX_DEPTH_SIZE;
+ visualAttribList[i++] = 1;
+ visualAttribList[i++] = GLX_ACCUM_RED_SIZE;
+ visualAttribList[i++] = accumSize;
+ visualAttribList[i++] = GLX_ACCUM_GREEN_SIZE;
+ visualAttribList[i++] = accumSize;
+ visualAttribList[i++] = GLX_ACCUM_BLUE_SIZE;
+ visualAttribList[i++] = accumSize;
+
+ if(JNI_TRUE==rgba)
+ {
+ visualAttribList[i++] = GLX_RGBA;
+ visualAttribList[i++] = GLX_ACCUM_ALPHA_SIZE;
+ visualAttribList[i++] = accumSize;
+ }
+ if(JNI_TRUE==doubleBuffer)
+ visualAttribList[i++] = GLX_DOUBLEBUFFER;
+ if(JNI_TRUE==stereoView)
+ visualAttribList[i++] = GLX_STEREO;
+ visualAttribList[i++] = GLX_STENCIL_SIZE;
+ visualAttribList[i++] = (int)stencilBits;
+ visualAttribList[i] = None;
+
+ if(tryChooseVisual==JNI_TRUE && vgc.visual==NULL)
+ {
+ vgc.visual = glXChooseVisual( display,
+ DefaultScreen( display ),
+ visualAttribList );
+ if(JNI_TRUE==verbose)
+ {
+ if(vgc.visual!=NULL)
+ {
+ fprintf(stderr, "glXChooseVisual: test visual(ID:%d(0x%X)):\n",
+ (int) vgc.visual->visualid,
+ (int) vgc.visual->visualid);
+ printVisualInfo ( display, vgc.visual);
+ } else
+ fprintf(stderr, "glXChooseVisual: no visual\n");
+ fflush(stderr);
+ }
+ }
+
+ if(vgc.visual==NULL)
+ {
+ vgc.visual = findVisualIdByFeature( &visualList,
+ display, *pWin,
+ doubleBuffer, stereoView,
+ rgba,
+ stencilBits,
+ accumSize,
+ verbose);
+ }
+
+ if(vgc.visual==NULL)
+ {
+ vgc.visual = findVisualIdByFeature( &visualList,
+ display, *pWin,
+ doubleBuffer, stereoView,
+ rgba,
+ stencilBits>0,
+ accumSize>0, verbose);
+ }
+
+ if( *pOwnWin == JNI_TRUE && vgc.visual!=NULL)
+ {
+ newWin = createOwnOverlayWin(display,
+ rootWin,
+ *pWin /* the parent */,
+ vgc.visual, width, height);
+ }
+
+ if( offscreen==JNI_TRUE && vgc.visual!=NULL)
+ {
+ if(*pix!=0)
+ {
+ XFreePixmap(display, *pix);
+ }
+ if(vgc.visual !=NULL)
+ *pix = XCreatePixmap( display, rootWin, width, height,
+ vgc.visual->depth);
+ if(*pix!=0)
+ {
+ *pWin = glXCreateGLXPixmap( display, vgc.visual, *pix );
+ if(*pWin==0)
+ {
+ XFreePixmap(display, *pix);
+ *pix=0;
+ fprintf(stderr, "GL4Java(%d): glXCreateGLXPixmap failed\n", j);
+ fflush(stderr);
+ }
+ } else {
+ fprintf(stderr, "GL4Java(%d): XCreatePixmap failed\n", j);
+ fflush(stderr);
+ *pWin = 0;
+ }
+ if(JNI_TRUE==verbose)
+ {
+ if(*pWin!=0)
+ {
+ fprintf(stderr, "GL4Java(%d): pixmap ok\n", j);
+ fflush(stderr);
+ }
+ }
+ }
+
+ gc_ret = -100;
+
+ if( *pOwnWin == JNI_TRUE && newWin!=0 &&
+ (gc_ret=get_GC( display, newWin,
+ vgc.visual, &(vgc.gc), shareWith)) == 0
+ )
+ {
+ vgc.success=1;
+ *pWin = newWin ;
+ }
+ else if( vgc.visual!=NULL && *pOwnWin == JNI_FALSE && *pWin!=0 &&
+ (gc_ret=get_GC( display, *pWin,
+ vgc.visual, &(vgc.gc), shareWith)) == 0
+ )
+ {
+ vgc.success=1;
+ } else
+ {
+ j++; /* trial counter */
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java(%d): Visual fetching failed (gc_get=%d)\n", j, gc_ret);
+ fflush(stderr);
+ }
+
+ if(*pix!=0)
+ {
+ XFreePixmap(display, *pix);
+ *pix=0;
+ }
+
+ if(visualList!=NULL)
+ {
+ XFree(visualList);
+ visualList=NULL;
+ vgc.visual=NULL;
+ } else if(vgc.visual!=NULL)
+ {
+ XFree(vgc.visual);
+ vgc.visual=NULL;
+ }
+
+ /* Fall-Back ... */
+ if(*pOwnWin==JNI_FALSE && offscreen==JNI_FALSE) {
+ rgba=_rgba;
+ stencilBits=_stencilBits;
+ accumSize=_accumSize;
+ stereoView=_stereoView;
+ doubleBuffer=_doubleBuffer;
+ *pOwnWin=JNI_TRUE;
+ } else if(accumSize>0 && offscreen==JNI_TRUE) {
+ accumSize=0;
+ } else if(doubleBuffer==JNI_FALSE && offscreen==JNI_TRUE) {
+ doubleBuffer=JNI_TRUE;
+ } else if(stencilBits>0) {
+ stencilBits=0;
+ } else if(stereoView==JNI_TRUE) {
+ stereoView=JNI_FALSE;
+ } else if(rgba==JNI_TRUE) {
+ rgba=JNI_FALSE;
+ } else if(doubleBuffer==JNI_TRUE) {
+ doubleBuffer=JNI_FALSE;
+ } else if(tryChooseVisual==JNI_TRUE) {
+ rgba=_rgba;
+ stencilBits=_stencilBits;
+ accumSize=_accumSize;
+ stereoView=_stereoView;
+ doubleBuffer=_doubleBuffer;
+ *pOwnWin=JNI_FALSE;
+ tryChooseVisual=JNI_FALSE;
+ } else done=1;
+ }
+ } while (vgc.success==0 && done==0) ;
+
+ if(vgc.success==1 && JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "\nfindVisualGlX vi(ID:%d): \n screen %d, depth %d, class %d,\n clrmapsz %d, bitsPerRGB %d, shared with %d\n",
+ (int)vgc.visual->visualid,
+ (int)vgc.visual->screen,
+ (int)vgc.visual->depth,
+ (int)vgc.visual->class,
+ (int)vgc.visual->colormap_size,
+ (int)vgc.visual->bits_per_rgb,
+ (int)shareWith);
+ printVisualInfo ( display, vgc.visual);
+ }
+
+ return vgc;
+}
+
+
+void LIBAPIENTRY printVisualInfo ( Display *display, XVisualInfo * vi)
+{
+ int dblBuffer, stereoView, rgbaMode, stencilSize;
+ int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
+
+ fprintf(stderr, "\nvi(ID:%d(0x%X)): \n screen %d, depth %d, class %d,\n clrmapsz %d, bitsPerRGB %d\n",
+ (int) vi->visualid,
+ (int) vi->visualid,
+ (int) vi->screen,
+ (int) vi->depth,
+ (int) vi->class,
+ (int) vi->colormap_size,
+ (int) vi->bits_per_rgb );
+
+ glXGetConfig( display, vi, GLX_DOUBLEBUFFER, &dblBuffer);
+ glXGetConfig( display, vi, GLX_STEREO, &stereoView);
+ glXGetConfig( display, vi, GLX_RGBA, &rgbaMode);
+ glXGetConfig( display, vi, GLX_STENCIL_SIZE, &stencilSize);
+ glXGetConfig( display, vi, GLX_ACCUM_RED_SIZE, &accumRedSize);
+ glXGetConfig( display, vi, GLX_ACCUM_GREEN_SIZE, &accumGreenSize);
+ glXGetConfig( display, vi, GLX_ACCUM_BLUE_SIZE, &accumBlueSize);
+ glXGetConfig( display, vi, GLX_ACCUM_ALPHA_SIZE, &accumAlphaSize);
+
+ fprintf(stderr, "\t doubleBuff: %d, ", dblBuffer);
+ fprintf(stderr, " stereo: %d, ", stereoView);
+ fprintf(stderr, " rgba: %d, ", rgbaMode);
+ fprintf(stderr, " stencilSize: %d !\n", stencilSize);
+ fprintf(stderr, "\t red accum: %d, ", accumRedSize);
+ fprintf(stderr, " green accum: %d, ", accumGreenSize);
+ fprintf(stderr, " blue accum: %d, ", accumBlueSize);
+ fprintf(stderr, " alpha accum: %d !\n", accumAlphaSize);
+
+ fflush(stderr);
+}
+
+void LIBAPIENTRY printAllVisualInfo ( Display *disp, Window win, jboolean verbose)
+{
+ XVisualInfo * visualInfo=0;
+ XVisualInfo * vi=0;
+ XVisualInfo viTemplate;
+ int i, numReturns;
+ XWindowAttributes xwa;
+
+ if(XGetWindowAttributes(disp, win, &xwa) == 0)
+ {
+ fprintf(stderr, "\nERROR while fetching XWindowAttributes\n");
+ fflush(stderr);
+ return;
+ }
+
+ viTemplate.screen = DefaultScreen( disp );
+ viTemplate.class = (xwa.visual)->class ;
+ viTemplate.depth = xwa.depth;
+
+ visualInfo = XGetVisualInfo( disp, VisualScreenMask,
+ &viTemplate, &numReturns );
+
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "\nNum of Visuals : %d\n", numReturns );
+
+ for(i=0; i<numReturns; i++)
+ {
+ vi = &(visualInfo[i]);
+ printVisualInfo ( disp, vi);
+ }
+ }
+
+ XFree(visualInfo);
+}
+
+int LIBAPIENTRY testVisualInfo ( Display *display, XVisualInfo * vi,
+ int dblBuffer, int stereoView, int rgbaMode,
+ int stencilSize, int accumSize)
+{
+ int glxCfg;
+
+ glXGetConfig( display, vi, GLX_DOUBLEBUFFER, &glxCfg);
+ if(glxCfg<dblBuffer) return 0;
+
+ glXGetConfig( display, vi, GLX_STEREO, &glxCfg);
+ if(glxCfg<stereoView) return 0;
+
+ glXGetConfig( display, vi, GLX_RGBA, &glxCfg);
+ if(glxCfg<rgbaMode) return 0;
+
+ glXGetConfig( display, vi, GLX_STENCIL_SIZE, &glxCfg);
+ if(glxCfg<stencilSize) return 0;
+
+ glXGetConfig(display, vi, GLX_ACCUM_RED_SIZE, &glxCfg);
+ if(glxCfg<accumSize) return 0;
+
+ glXGetConfig(display, vi, GLX_ACCUM_GREEN_SIZE, &glxCfg);
+ if(glxCfg<accumSize) return 0;
+
+ glXGetConfig(display, vi, GLX_ACCUM_BLUE_SIZE, &glxCfg);
+ if(glxCfg<accumSize) return 0;
+
+ if(rgbaMode>0) {
+ glXGetConfig(display, vi, GLX_ACCUM_ALPHA_SIZE, &glxCfg);
+ if(glxCfg<accumSize) return 0;
+ }
+
+ return 1;
+}
+
+
+XVisualInfo * LIBAPIENTRY findVisualIdByFeature( XVisualInfo ** visualList,
+ Display *disp, Window win,
+ int dblBuffer, int stereoView, int rgbaMode,
+ int stencilSize, int accumSize,
+ jboolean verbose)
+{
+ XVisualInfo * vi=0;
+ XVisualInfo viTemplate;
+ int i, numReturns;
+ XWindowAttributes xwa;
+ int done=0;
+
+ if(XGetWindowAttributes(disp, win, &xwa) == 0)
+ {
+ fprintf(stderr, "\nERROR while fetching XWindowAttributes\n");
+ fflush(stderr);
+ return 0;
+ }
+
+ viTemplate.screen = DefaultScreen( disp );
+ viTemplate.class = (xwa.visual)->class ;
+ viTemplate.depth = xwa.depth;
+
+ *visualList = XGetVisualInfo( disp, VisualScreenMask,
+ &viTemplate, &numReturns );
+
+ for(i=0; done==0 && i<numReturns; i++)
+ {
+ vi = &((*visualList)[i]);
+ if ( testVisualInfo ( disp, vi, dblBuffer, stereoView, rgbaMode,
+ stencilSize, accumSize) )
+ {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "findVisualIdByFeature: Found matching Visual:\n");
+ printVisualInfo ( disp, vi);
+ }
+ return vi;
+ }
+ }
+
+ if(JNI_TRUE==verbose)
+ {
+ if( numReturns==0 )
+ fprintf(stderr, "findVisualIdByFeature: No available visuals. Exiting...\n" );
+ else if( i>=numReturns )
+ fprintf(stderr, "findVisualIdByFeature: No matching visual found ...\n" );
+ fflush(stderr);
+ }
+
+ XFree(*visualList);
+ *visualList=NULL;
+ return NULL;
+}
+
+
+jboolean LIBAPIENTRY testX11Java()
+{
+ jboolean ret=JNI_TRUE;
+
+ /* NON DEPENDENCE CHECKS */
+
+ /* FIRST OF ALL CHECK IF A NATIVE POINTER OR X11-TYPE FITS IN �jint� */
+
+ if( sizeof(jlong) < sizeof(Display *) )
+ {
+ fprintf(stderr,"GL4Java: (Display *) fits not in jlong\n");
+ ret = JNI_FALSE;
+ }
+
+ if( sizeof(jlong) < sizeof(GLXContext) )
+ {
+ fprintf(stderr,"GL4Java: GLXContext fits not in jlong\n");
+ ret = JNI_FALSE;
+ }
+
+ if( sizeof(jlong) < sizeof(Window) )
+ {
+ fprintf(stderr,"GL4Java: Window fits not in jlong\n");
+ ret = JNI_FALSE;
+ }
+
+ if(ret==JNI_FALSE)
+ {
+ fflush(stderr);
+ }
+
+ return ret;
+}
+
+
+int LIBAPIENTRY x11gl_myErrorHandler(Display *pDisp, XErrorEvent *p_error)
+{
+ char err_msg[80];
+
+ XGetErrorText(pDisp, p_error->error_code, err_msg, 80);
+ fprintf(stderr, "X11 Error detected.\n %s\n", err_msg);
+ fprintf(stderr, " Protocol request: %d\n", p_error->request_code);
+ fprintf(stderr, " Resource ID : 0x%x\n", (int)p_error->resourceid);
+ fprintf(stderr, " \ntrying to continue ... \n");
+ fflush(stderr);
+ return 0;
+}
+
+int LIBAPIENTRY x11gl_myIOErrorHandler(Display *pDisp)
+{
+ fprintf(stderr, "X11 I/O Error detected.\n");
+ fprintf(stderr, " \ndo not know what to do ... \n");
+ fflush(stderr);
+ return 0;
+}
+
+Window LIBAPIENTRY createOwnOverlayWin(Display *display, Window rootwini, Window parentWin,
+ XVisualInfo *visual, int width, int height)
+{
+ /*
+ //------------------------------------------------------------------------//
+ // Some Systems (SGI) wont give up the window and so we have to create a //
+ // window that fits on top of the Java Canvas. //
+ //------------------------------------------------------------------------//
+ */
+ Window window=0;
+ XSetWindowAttributes attribs ;
+
+ /*
+ //----------------------------------------------------------------------//
+ // now we have the visual with the best depth so lets make a color map //
+ // for it. we use allocnone because this is a true colour visual and //
+ // the color map is read only anyway. This must be done because we //
+ // cannot call XCreateSimpleWindow. //
+ //----------------------------------------------------------------------//
+ */
+ int cmap = XCreateColormap ( display
+ , rootwini
+ , visual->visual
+ , AllocNone
+ );
+
+ /*
+ //----------------------------------------------------------------------//
+ // Set up the window attributes. //
+ //----------------------------------------------------------------------//
+ */
+ attribs.event_mask = ExposureMask ;
+ attribs.border_pixel = BlackPixel(display, DefaultScreen(display)) ;
+ attribs.colormap = cmap ;
+ attribs.bit_gravity = SouthWestGravity ; ;
+ attribs.background_pixel = 0xFF00FFFF ;
+
+ /*
+ //----------------------------------------------------------------------//
+ // Create a window. //
+ //----------------------------------------------------------------------//
+ */
+ window = XCreateWindow( display
+ , parentWin
+ , 0
+ , 0
+ , width
+ , height
+ , 0
+ , visual->depth
+ , InputOutput
+ , visual->visual
+ , CWBitGravity | CWColormap
+ | CWBorderPixel | CWBackPixel
+ , &attribs);
+
+ return window;
+}
+
+
diff --git a/CNativeCode/OpenGL_X11_common.h b/CNativeCode/OpenGL_X11_common.h
new file mode 100644
index 0000000..2eff8e3
--- /dev/null
+++ b/CNativeCode/OpenGL_X11_common.h
@@ -0,0 +1,82 @@
+#ifndef _OPENGL_X11_COMMON_
+#define _OPENGL_X11_COMMON_
+
+ /*
+ * need to include the JAVA internal header files for macros and function
+ * prototypes required to maipulated JAVA data structures and functions
+ *
+ * StubPreamble.h includes the structure and macro definitions neede to
+ * convert JAVA data structures into C data structures.
+ *
+ */
+
+ #include "OpenGL_misc.h"
+
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+
+ #include <GL/glx.h>
+ #include <X11/Xatom.h>
+
+ typedef struct {
+ XVisualInfo * visual;
+ GLXContext gc;
+ int success; /* 1: OK, 0: ERROR */
+ } VisualGC;
+
+
+ /*
+ * prototypes for functions local to this file scope
+ */
+ LIBAPI int LIBAPIENTRY get_GC( Display *display, Window win,
+ XVisualInfo *visual,
+ GLXContext *gc, GLXContext gc_share);
+
+ LIBAPI VisualGC LIBAPIENTRY findVisualGlX( Display *display,
+ Window rootWin,
+ Window * pWin,
+ int width, int height,
+ jboolean doubleBuffer,
+ jboolean stereoView,
+ jboolean rgba,
+ jint stencilBits,
+ jint accumSize,
+ jboolean * pOwnWin,
+ GLXContext shareWith,
+ jboolean offscreen,
+ Pixmap *pix,
+ jboolean verbose
+ );
+
+ LIBAPI void LIBAPIENTRY printVisualInfo ( Display *display, XVisualInfo * vi);
+ LIBAPI void LIBAPIENTRY printAllVisualInfo ( Display *disp, Window win,
+ jboolean verbose);
+
+ LIBAPI int LIBAPIENTRY testVisualInfo ( Display *display, XVisualInfo * vi,
+ int dblBuffer, int stereoView, int rgbaMode,
+ int stencilSize, int accumSize);
+
+ LIBAPI XVisualInfo * LIBAPIENTRY findVisualIdByFeature(
+ XVisualInfo ** visualList,
+ Display *disp, Window win,
+ int dblBuffer, int stereoView, int rgbaMode,
+ int stencilSize, int accumSize,
+ jboolean verbose);
+
+ /* testX11Java does important implementation plattformspecific checks:
+ *
+ * o do fit X11-Vars in jint (because GLFrame stores 'em like that)
+ */
+ LIBAPI jboolean LIBAPIENTRY testX11Java();
+
+ LIBAPI int LIBAPIENTRY x11gl_myErrorHandler(
+ Display *pDisp, XErrorEvent *p_error);
+
+ LIBAPI int LIBAPIENTRY x11gl_myIOErrorHandler(Display *pDisp);
+
+ LIBAPI Window LIBAPIENTRY createOwnOverlayWin(
+ Display *display,
+ Window rootwini, Window parentWin,
+ XVisualInfo *visual, int width, int height);
+
+#endif
diff --git a/CNativeCode/OpenGL_X11_jawt.c b/CNativeCode/OpenGL_X11_jawt.c
new file mode 100644
index 0000000..85475ff
--- /dev/null
+++ b/CNativeCode/OpenGL_X11_jawt.c
@@ -0,0 +1,951 @@
+/*
+ * Leo Chan -- 1995
+ *
+ * This file takes care of the C implementation of opening up an
+ * X window, assigning an OpenGL graphics context to it, storing that
+ * graphics context in the java class data structure.
+ *
+ * also contains the use() and swap() functions for double buffering
+ *
+ * Adam King -- 1997
+ *
+ * Modified Creation window code to use the currently showing Java Frame
+ * window instead of creating a new window.
+ * ---------------
+ *
+ * Many improvements and changes are made !
+ *
+ * Sven Goethel
+ *
+ * September 1997
+ *
+ * some X stuff is also modified/debugged to run on aix ...
+ */
+
+/**
+ * Pointer Semantics of GLContext:
+ * ==============================
+
+ "displayHandle" := (Display *)
+
+ "pData" := (JAWTDataHolder *)
+ "windowHandle" := "pData"
+
+ This holds the current state of the JAWT context !
+
+ This is used as the "not initialized" flag also !
+ It is reset to zero while Destroy Method
+
+ "pData"->dsi_win := (Window)
+ if("offScreenRenderer" == FALSE && "createOwnWindow" == TRUE )
+ "pData"->dsi_win contains the new created Window
+ (by XCreateWindow), and
+ "pData"->dsi_win_created=1 !
+
+ else if("offScreenRenderer" == TRUE && "createOwnWindow" == FALSE )
+ "pData"->dsi_win contains the new created GLXPixmap
+ (by glXCreateGLXPixmap), and
+ "pData"->dsi_win_created=1 !
+ else
+ "pData"->dsi_win contains the window handle,
+ of the last lock !
+ "pData"->dsi_win_created=0 !
+
+ "pixmapHandle" := (Pixmap)
+ if("offScreenRenderer" == TRUE)
+ "pixmapHandle" contains the new Pixmap (by XCreatePixmap)!
+ "windowHandle" contains the new created OffScreenWindow
+ (by glXCreateGLXPixmap)!
+ else
+ "pixmapHandle" is unused !
+
+ "sharedGLContextNative" := (GLXContext)
+ This is the optional shared GLContext !
+
+ "glContext" := (GLXContext)
+ This is THE used GLContext !
+
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <jni.h>
+
+/*
+ * the next thing to include are special headers that were created by
+ * JAVAH. They include the C structure definitions for the JAVA classes
+ */
+#include "gl4java_GLContext.h"
+
+/*--------------------------------------------------------------------------
+ * here on in is just regular apple pie C
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <GL/glx.h>
+#include <X11/Xatom.h>
+
+#include <stdlib.h>
+
+#include "OpenGL_X11_common.h"
+
+#include "jawt_misc.h"
+
+/*
+ * Macros ..
+ */
+
+#define GET_X11_JAWT_DSI(a) \
+ ( (JAWT_X11DrawingSurfaceInfo *) \
+ ( ( (JAWTDataHolder *)((PointerHolder)(a)) ) ->dsi_os ) \
+ )
+
+#define GET_USED_WINDOW(a) \
+ ( (Window) \
+ ( ( (JAWTDataHolder *)((PointerHolder)(a)) ) ->dsi_win ) \
+ )
+
+#define GET_USED_DISPLAY(a) \
+ ( (Display *) \
+ ( ( (JAWTDataHolder *)((PointerHolder)(a)) ) ->dsi_display ) \
+ )
+
+/*
+ * STATIC FLAGS FOR gl4java behavior ...
+ */
+static jboolean verbose = JNI_FALSE;
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_useJAWT( JNIEnv *env, jobject obj )
+{
+ (void)env;
+ (void)obj;
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj,
+ jlong thisWin )
+{
+ JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin );
+ (void)env;
+ (void)obj;
+
+ return (pData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 ;
+}
+
+/*
+ * OpenGL_GLFrame_openOpenGL
+ *
+ * the function name is created by JAVAH to reflect the package and class
+ * names of the JAVA object that called this native code.
+ *
+ * the parameter is a handle to the OpenGL_OpenGLFrame object --
+ * the data portion
+ * followed by the method table for the class.
+ */
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_openOpenGLNative( JNIEnv *env, jobject obj,
+ jobject canvas )
+{
+ int screen = 0;
+
+ /* found matching visual and gc */
+ VisualGC vgc = { NULL, 0, 0 };
+
+ jboolean ret = JNI_TRUE;
+
+ jclass cls = 0;
+ jfieldID fpData=0, fwindowHandle=0;
+ jfieldID fdisplayHandle=0, fpixmapHandle=0;
+ jfieldID fverbose=0;
+ jfieldID fglContext=0;
+ jfieldID fstereoView=0, frgba=0, fstencilBits=0,
+ faccumSize=0, fownwind=0;
+ jfieldID fdoubleBuffer=0, foffScreenRenderer;
+
+ jfieldID fcreatewinw = 0, fcreatewinh = 0;
+ jfieldID fshareWith = 0;
+ jboolean joffScreenRenderer=JNI_FALSE;
+ jboolean jdoubleBuffer=JNI_TRUE;
+ jboolean jstereoView=JNI_FALSE;
+ jboolean jrgba=JNI_TRUE;
+ jint jstencilBits=0;
+ jint jaccumSize=0;
+ jboolean jownwind = JNI_FALSE ;
+ jint jcreatewinw = 0, jcreatewinh = 0;
+ GLXContext jshareWith = 0;
+
+ /* these variables will be mapped in the java-object ! */
+ JAWTDataHolder * pData = NULL;
+ Display * display = 0;
+ Window rootwini = 0;
+ Window theWindow = 0;
+ Pixmap pix;
+ jclass AwtComponent = (*env)->FindClass(env, "Ljava/awt/Component;");
+
+ int iValue, iValue1, iValue2, iValue3;
+
+ cls = (*env)->GetObjectClass(env, obj);
+ if(cls==0)
+ {
+ fprintf(stderr,"GL4Java ERROR: clazz not accessible\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ fverbose =(*env)->GetStaticFieldID(env, cls, "gljNativeDebug", "Z");
+ if (fverbose == 0)
+ {
+ fprintf(stderr,"GL4Java: fverbose==0\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ } else {
+ verbose = (*env)->GetStaticBooleanField(env, cls, fverbose);
+ }
+ }
+
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java: sizes:\n jint=%d\n (Display *)=%d\n GLXContext=%d\n",
+ sizeof(jint), sizeof(Display *), sizeof(GLXContext) );
+ fflush(stderr);
+ }
+
+ /* FIRST OF ALL CHECK IF A NATIVE POINTER OR X11-TYPE FITS IN �jlong� */
+ ret = testX11Java();
+ ret = testJavaGLTypes(verbose);
+
+ if(ret==JNI_TRUE) {
+ foffScreenRenderer =
+ (*env)->GetFieldID(env, cls, "offScreenRenderer", "Z");
+ if (foffScreenRenderer == 0) ret= JNI_FALSE;
+ else joffScreenRenderer =(*env)->GetBooleanField(env, obj, foffScreenRenderer);
+ }
+
+ if(ret==JNI_TRUE) {
+ fdoubleBuffer = (*env)->GetFieldID(env, cls, "doubleBuffer", "Z");
+ if (fdoubleBuffer == 0) ret= JNI_FALSE;
+ else jdoubleBuffer =(*env)->GetBooleanField(env, obj, fdoubleBuffer);
+ }
+
+ if(ret==JNI_TRUE) {
+ fstereoView = (*env)->GetFieldID(env, cls, "stereoView", "Z");
+ if (fstereoView == 0) ret= JNI_FALSE;
+ else jstereoView =(*env)->GetBooleanField(env, obj, fstereoView);
+ }
+
+ if(ret==JNI_TRUE) {
+ frgba = (*env)->GetFieldID(env, cls, "rgba", "Z");
+ if (frgba == 0) ret= JNI_FALSE;
+ else jrgba =(*env)->GetBooleanField(env, obj, frgba);
+ }
+
+ if(ret==JNI_TRUE) {
+ fstencilBits = (*env)->GetFieldID(env, cls, "stencilBits", "I");
+ if (fstencilBits == 0) ret= JNI_FALSE;
+ else jstencilBits =(*env)->GetIntField(env, obj, fstencilBits);
+ }
+
+ if(ret==JNI_TRUE) {
+ faccumSize = (*env)->GetFieldID(env, cls, "accumSize", "I");
+ if (faccumSize == 0) ret= JNI_FALSE;
+ else jaccumSize =(*env)->GetIntField(env, obj, faccumSize);
+ }
+
+ if(ret==JNI_TRUE) {
+ fcreatewinw = (*env)->GetFieldID(env, cls, "createwinw", "I");
+ if (fcreatewinw == 0) ret= JNI_FALSE;
+ else jcreatewinw =(*env)->GetIntField(env, obj, fcreatewinw);
+ }
+
+ if(ret==JNI_TRUE) {
+ fcreatewinh = (*env)->GetFieldID(env, cls, "createwinh", "I");
+ if (fcreatewinh == 0) ret= JNI_FALSE;
+ else jcreatewinh =(*env)->GetIntField(env, obj, fcreatewinh);
+ }
+
+ if(ret==JNI_TRUE) {
+ fownwind = (*env)->GetFieldID(env, cls, "createOwnWindow", "Z");
+ if (fownwind == 0) ret= JNI_FALSE;
+ else jownwind =(*env)->GetBooleanField(env, obj, fownwind);
+ }
+
+ if(ret==JNI_TRUE) {
+ fshareWith = (*env)->GetFieldID(env, cls, "sharedGLContextNative", "J");
+ if (fshareWith == 0) ret= JNI_FALSE;
+ else jshareWith = (GLXContext)
+ ( (PointerHolder) (*env)->GetLongField(env, obj, fshareWith) );
+ }
+
+ if(ret==JNI_TRUE) {
+ fpData = (*env)->GetFieldID(env, cls, "pData", "J");
+ if (fpData == 0) ret= JNI_FALSE;
+ else pData =(JAWTDataHolder *)
+ ( (PointerHolder) (*env)->GetLongField(env, obj, fpData) );
+ }
+
+ if(ret==JNI_TRUE) {
+ fwindowHandle = (*env)->GetFieldID(env, cls, "windowHandle", "J");
+ }
+
+ if(ret==JNI_TRUE) {
+ fpixmapHandle = (*env)->GetFieldID(env, cls, "pixmapHandle", "J");
+ if (fpixmapHandle == 0) ret= JNI_FALSE;
+ }
+
+ if(joffScreenRenderer==JNI_TRUE)
+ {
+ jownwind = JNI_FALSE;
+ }
+
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr,"\nGL4Java: (try to use visuals: doubleBuffer=%d, stereoView=%d, rgba=%d, stencilBits=%d, accumSize=%d, ownWindow=%d)\n)\n",
+ (int)jdoubleBuffer, (int)jstereoView, (int)jrgba, (int)jstencilBits, (int)jaccumSize,
+ (int)jownwind );
+ fflush(stderr);
+ }
+
+ if(ret==JNI_TRUE) {
+ fdisplayHandle = (*env)->GetFieldID(env, cls, "displayHandle", "J");
+ if (fdisplayHandle == 0) ret= JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ fglContext=(*env)->GetFieldID(env, cls, "glContext", "J");
+ if (fglContext == 0) ret= JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ if (canvas == 0)
+ {
+ ret= JNI_FALSE;
+ fprintf(stderr,"\nGL4Java ERROR: canvas == NULL !\n");
+ fflush(stderr);
+ } else {
+ if( (*env)->IsInstanceOf(env, canvas, AwtComponent)==JNI_FALSE )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: canvas is not instanceof java/awt/Component !\n");
+ fflush(stderr);
+ ret= JNI_FALSE;
+ }
+ }
+ }
+
+ if(joffScreenRenderer==JNI_TRUE)
+ {
+ jawt_create_offscreen(env, &pData, verbose);
+ }
+ else {
+ if(jawt_create_open(env, canvas, &pData, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: openOpen could not create&open JAWT reference!\n");
+ fflush(stderr);
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ ret=JNI_FALSE;
+ return ret;
+ }
+
+ if(jawt_lock(env, pData, JNI_TRUE, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: openOpen could not lock JAWT reference!\n");
+ fflush(stderr);
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ ret=JNI_FALSE;
+ return ret;
+ }
+ }
+
+ if(pData->result==JNI_TRUE)
+ {
+ // display = GET_X11_JAWT_DSI(pData)->display;
+
+ /* JAU: Why ? the above jawt display does not work ... :-( */
+ display = XOpenDisplay( NULL );
+ pData->dsi_display_created = 1;
+ pData->dsi_display=display;
+
+ if(display==NULL)
+ {
+ fprintf(stderr,"\nGL4Java ERROR: display of JAWT reference is NULL !\n");
+ fflush(stderr);
+ pData->result=JNI_FALSE;
+ ret=JNI_FALSE;
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ return ret;
+ }
+
+ if(joffScreenRenderer==JNI_FALSE)
+ {
+ theWindow = GET_X11_JAWT_DSI(pData)->drawable;
+ jcreatewinw = pData->dsi->bounds.width;
+ jcreatewinh = pData->dsi->bounds.height;
+ }
+ }
+
+ if(JNI_TRUE==ret && JNI_TRUE==verbose)
+ {
+ if(joffScreenRenderer==JNI_TRUE)
+ {
+ fprintf(stderr,"\nGL4Java: (USING OFFSCREEN GLPIXMAP BUFFER,\n\t forced: !ownWindow, window=NULL)\n");
+ } else {
+ fprintf(stderr,"\nGL4Java: (JAVA FOUND WINDOW HANDLE 0x%p)\n\t(FOUND VISUALID %d)\n",
+ (void *)((PointerHolder)GET_X11_JAWT_DSI(pData)->drawable),
+ (int)GET_X11_JAWT_DSI(pData)->visualID);
+ }
+ fflush(stderr);
+ }
+
+ /* Check to see if the Xserver supports OpenGL */
+ if(ret==JNI_TRUE) {
+ if( !glXQueryExtension(display, (int *) 0, (int *) 0) ) {
+ fprintf(stderr, "GL4Java ERROR: Can not query glx extension -> Server does not support OpenGL\n");
+ fflush(stderr);
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ ret = JNI_FALSE;
+ } else {
+ if (JNI_TRUE==verbose) {
+ fprintf(stdout, "GLX by %s Version %s\n",
+ glXGetClientString(display, GLX_VENDOR),
+ glXGetClientString(display, GLX_VERSION));
+ }
+ }
+ }
+
+ /* initialize the x stuff */
+ if(ret==JNI_TRUE)
+ {
+ screen = DefaultScreen( display );
+ rootwini = RootWindow(display,screen) ;
+
+ glXMakeCurrent(display, None, NULL);
+
+ vgc = findVisualGlX( display, rootwini, &theWindow,
+ (int)jcreatewinw, (int)jcreatewinh,
+ jdoubleBuffer, jstereoView, jrgba,
+ jstencilBits, jaccumSize,
+ &jownwind, jshareWith,
+ joffScreenRenderer, &pix, verbose);
+
+ if(vgc.success == 0 && jrgba==JNI_TRUE)
+ {
+ jrgba=JNI_FALSE;
+ vgc = findVisualGlX( display, rootwini, &theWindow,
+ (int)jcreatewinw, (int)jcreatewinh,
+ jdoubleBuffer, jstereoView, jrgba,
+ jstencilBits, jaccumSize,
+ &jownwind, jshareWith,
+ joffScreenRenderer, &pix, verbose);
+ }
+
+ if(vgc.success == 0)
+ {
+ fprintf(stderr,"GL4Java ERROR: GETTING GC FAILED\n");
+ fflush(stderr);
+
+ if(jownwind==JNI_TRUE && theWindow!=0)
+ XDestroyWindow( display, theWindow );
+ if(joffScreenRenderer==JNI_TRUE && pix!=0)
+ XFreePixmap(display, pix);
+ XCloseDisplay( display );
+ jawt_free_close_unlock(env, &pData, JNI_FALSE);
+ ret = JNI_FALSE;
+ } else {
+ if(jownwind==JNI_TRUE || joffScreenRenderer==JNI_TRUE)
+ {
+ pData->dsi_win=(void *)(PointerHolder)theWindow;
+ pData->dsi_win_created=1;
+ }
+
+ if(glXGetConfig( display, vgc.visual,
+ GLX_DOUBLEBUFFER, &iValue)==0)
+ {
+ if (JNI_TRUE==verbose) {
+ fprintf(stdout,"doubleBuffer: %d\n", iValue);
+ fflush(stdout);
+ }
+ jdoubleBuffer=iValue?JNI_TRUE:JNI_FALSE;
+ if(ret==JNI_TRUE && fdoubleBuffer!=0) {
+ (*env)->SetBooleanField(env, obj, fdoubleBuffer,
+ jdoubleBuffer);
+ }
+
+ } else {
+ fprintf(stderr,"GL4Java: fetching doubleBuffer state failed\n");
+ fflush(stderr);
+ }
+ if(glXGetConfig( display, vgc.visual,
+ GLX_STEREO, &iValue)==0)
+ {
+ if (JNI_TRUE==verbose) {
+ fprintf(stdout,"stereoView: %d\n", iValue);
+ fflush(stdout);
+ }
+ jstereoView=iValue?JNI_TRUE:JNI_FALSE;
+ if(ret==JNI_TRUE && fstereoView!=0) {
+ (*env)->SetBooleanField(env, obj, fstereoView,
+ jstereoView);
+ }
+
+ } else {
+ fprintf(stderr,"GL4Java: fetching stereoView state failed\n");
+ fflush(stderr);
+ }
+ if(glXGetConfig( display, vgc.visual,
+ GLX_RGBA, &iValue)==0)
+ {
+ if (JNI_TRUE==verbose) {
+ fprintf(stdout,"rgba: %d\n", iValue);
+ fflush(stdout);
+ }
+ jrgba=iValue?JNI_TRUE:JNI_FALSE;
+ if(ret==JNI_TRUE && frgba!=0) {
+ (*env)->SetBooleanField(env, obj, frgba,
+ jrgba);
+ }
+
+ } else {
+ fprintf(stderr,"GL4Java: fetching rgba state failed\n");
+ fflush(stderr);
+ }
+ if(glXGetConfig( display, vgc.visual,
+ GLX_STENCIL_SIZE, &iValue)==0)
+ {
+ if (JNI_TRUE==verbose) {
+ fprintf(stdout,"stencilBits: %d\n", iValue);
+ fflush(stdout);
+ }
+ jstencilBits=iValue;
+ if(ret==JNI_TRUE && fstencilBits!=0) {
+ (*env)->SetIntField(env, obj,
+ fstencilBits, (jint)jstencilBits);
+ }
+
+ } else {
+ fprintf(stderr,"GL4Java: fetching stencilBits state failed\n");
+ fflush(stderr);
+ }
+ if(glXGetConfig( display, vgc.visual,GLX_ACCUM_RED_SIZE, &iValue)==0 &&
+ glXGetConfig( display, vgc.visual,GLX_ACCUM_GREEN_SIZE, &iValue1)==0 &&
+ glXGetConfig( display, vgc.visual,GLX_ACCUM_BLUE_SIZE, &iValue2)==0 &&
+ glXGetConfig( display, vgc.visual,GLX_ACCUM_ALPHA_SIZE, &iValue3)==0 )
+ {
+ if (JNI_TRUE==verbose) {
+ fprintf(stdout,"accumSize(red): %d\n", iValue);
+ fprintf(stdout,"accumSize(green): %d\n", iValue1);
+ fprintf(stdout,"accumSize(blue): %d\n", iValue2);
+ fprintf(stdout,"accumSize(alpha): %d\n", iValue3);
+ fflush(stdout);
+ }
+ jaccumSize=iValue+iValue1+iValue2+iValue3;
+ if(ret==JNI_TRUE && faccumSize!=0) {
+ (*env)->SetIntField(env, obj,
+ faccumSize, (jint)jaccumSize);
+ }
+
+ } else {
+ fprintf(stderr,"GL4Java: fetching accumSize(red) state failed\n");
+ fflush(stderr);
+ }
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr,"\nGL4Java: (using visuals: doubleBuffer=%d, stereoView=%d, rgba=%d, stencilBits=%d, accumSize=%d, ownWindow=%d)\n)\n",
+ (int)jdoubleBuffer, (int)jstereoView, (int)jrgba,
+ (int)jstencilBits, (int)jaccumSize, (int)jownwind);
+ fflush(stderr);
+ }
+
+ }
+ }
+
+ /* we are now done with the visual so we should free the storage */
+
+ if(ret==JNI_TRUE)
+ {
+ XClearWindow( display, theWindow );
+ XMapWindow( display, theWindow );
+ XFlush( display );
+ }
+
+ jawt_close_unlock(env, pData, verbose);
+
+
+ if(ret==JNI_TRUE && fpData) {
+ (*env)->SetLongField(env, obj, fpData, (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fwindowHandle!=0) {
+ (*env)->SetLongField(env, obj, fwindowHandle, (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fpixmapHandle!=0) {
+ (*env)->SetLongField(env, obj, fpixmapHandle, (jlong)((PointerHolder)pix));
+ }
+
+ if(ret==JNI_TRUE && fdisplayHandle) {
+ (*env)->SetLongField(env, obj, fdisplayHandle, (jlong)((PointerHolder)display));
+ }
+
+ if(ret==JNI_TRUE && fglContext) {
+ (*env)->SetLongField(env, obj, fglContext, (jlong)((PointerHolder)vgc.gc));
+ }
+
+ if(ret==JNI_TRUE && fownwind) {
+ (*env)->SetBooleanField(env, obj, fownwind, jownwind);
+ }
+
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gl4java_GLContext_gljResizeNative( JNIEnv *env, jobject obj,
+ jboolean isOwnWindow,
+ jlong disp, jlong thisWin,
+ jint width, jint height)
+{
+ /* perform a X11 synchronise, because rendering could be done
+ * by a native Thread .... So we have to try avoid gl* reentrance
+ * on the same GL-Context
+ */
+ glXWaitGL();
+
+ if(isOwnWindow)
+ {
+ XResizeWindow(GET_USED_DISPLAY(thisWin),
+ GET_USED_WINDOW(thisWin), width, height);
+ /* if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "XResizeWindow -> %d x %d\n",
+ (int)width, (int)height);
+ fflush(stderr);
+ } */
+ }
+
+ return;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljMakeCurrentNative( JNIEnv *env, jobject obj,
+ jobject canvas,
+ jlong disp,
+ jlong thisWin,
+ jlong glContext
+ )
+{
+ jboolean ret = JNI_TRUE;
+ GLXContext ctx = NULL;
+ JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin );
+
+ if(pData==0)
+ {
+ fprintf(stderr, "GL4Java ERROR: gljUse NO JAWT Holder exist ! (pData=%p, thisWin=%lX) ...\n", pData, (long)thisWin);
+ fflush(stderr);
+ return JNI_FALSE;
+ }
+
+ if(glContext==0)
+ {
+ fprintf(stderr, "GL4Java ERROR: gljUse NO actual GC was created ...\n");
+ fflush(stderr);
+ return JNI_FALSE;
+ }
+
+ if(jawt_open(env, canvas, pData, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: MakeCurrent could not open JAWT reference!\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return ret;
+ }
+
+ if(jawt_lock(env, pData, JNI_FALSE, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ /* this can happen:
+ if ( (pJData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 )
+
+ In this case, we need a new GLXContext ...
+
+ This has to be queried by the java class,
+ while using the native method hasJAWTSurfaceChanged !
+ */
+ if(verbose)
+ {
+ fprintf(stderr,"\nGL4Java ERROR: MakeCurrent could not lock JAWT reference!\n");
+ fflush(stderr);
+ }
+ ret=JNI_FALSE;
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return ret;
+ }
+
+ ctx = glXGetCurrentContext();
+
+ if(ret==JNI_TRUE && ctx!=(GLXContext)((PointerHolder)glContext) )
+ {
+ if( !glXMakeCurrent( GET_USED_DISPLAY(thisWin),
+ GET_USED_WINDOW(thisWin),
+ (GLXContext)((PointerHolder)glContext) ) )
+ {
+ extern GLenum glGetError ( void ) ;
+ fprintf(stderr, "GL4Java: gljMakeCurrent failed with GC\n Another thread may be use it now ...\n");
+ fflush(stderr);
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ ret = JNI_FALSE;
+ }
+ }
+
+ // keep jawt locked .. for this thread till FreeNative !
+
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljFreeNative( JNIEnv *env, jobject obj,
+ jobject canvas,
+ jlong disp,
+ jlong thisWin,
+ jlong glContext
+ )
+{
+ jboolean ret = JNI_TRUE;
+ JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin );
+
+ (void)glContext;
+ (void)canvas;
+
+ if(ret==JNI_TRUE)
+ {
+ if( !glXMakeCurrent( GET_USED_DISPLAY(thisWin),
+ None, NULL))
+ {
+ fprintf(stderr, "GL4Java: gljFree failed\n");
+ fflush(stderr);
+ ret = JNI_FALSE;
+ }
+ }
+
+ jawt_close_unlock(env, pData, verbose);
+
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljIsContextCurrentNative( JNIEnv *env, jobject obj,
+ jlong glContext
+ )
+{
+ GLXContext ctx = glXGetCurrentContext();
+
+ if(ctx==(GLXContext)((PointerHolder)glContext))
+ return JNI_TRUE;
+
+ return JNI_FALSE;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljDestroyNative( JNIEnv *env, jobject obj,
+ jobject canvas )
+{
+ jclass cls = 0;
+ jfieldID fdisplayHandle=0, fwindowHandle=0, fglContext=0;
+ jfieldID fpixmapHandle=0;
+ jfieldID fpData=0;
+ jfieldID fownwind=0;
+
+ jboolean jownwind = JNI_FALSE ;
+ Display *disp=0;
+ GLXContext gc=0;
+ Window win=0;
+ JAWTDataHolder * pData = NULL;
+ Pixmap pix=0;
+
+ jboolean ret = JNI_TRUE;
+
+ cls = (*env)->GetObjectClass(env, obj);
+ if(cls==0) ret=JNI_FALSE;
+
+ if(ret==JNI_TRUE) {
+ fwindowHandle = (*env)->GetFieldID(env, cls, "windowHandle", "J");
+ }
+
+ if(ret==JNI_TRUE) {
+ fdisplayHandle = (*env)->GetFieldID(env, cls, "displayHandle", "J");
+ if (fdisplayHandle == 0) ret= JNI_FALSE;
+ }
+
+ if(ret==JNI_TRUE) {
+ fglContext=(*env)->GetFieldID(env, cls, "glContext", "J");
+ if (fglContext == 0) ret= JNI_FALSE;
+ else gc =(GLXContext)
+ ( (PointerHolder) (*env)->GetLongField(env, obj, fglContext) );
+ }
+
+ if(ret==JNI_TRUE) {
+ fpData = (*env)->GetFieldID(env, cls, "pData", "J");
+ if (fpData == 0) ret= JNI_FALSE;
+ else pData =(JAWTDataHolder *)
+ ( (PointerHolder) (*env)->GetLongField(env, obj, fpData) );
+ }
+
+ if(ret==JNI_TRUE) {
+ fpixmapHandle = (*env)->GetFieldID(env, cls, "pixmapHandle", "J");
+ if (fpixmapHandle == 0) ret= JNI_FALSE;
+ else pix = (Pixmap)
+ ( (PointerHolder) (*env)->GetLongField(env, obj, fpixmapHandle));
+ }
+
+ if(ret==JNI_TRUE) {
+ fownwind = (*env)->GetFieldID(env, cls, "createOwnWindow", "Z");
+ if (fownwind == 0) ret= JNI_FALSE;
+ else jownwind =(*env)->GetBooleanField(env, obj, fownwind);
+ }
+
+ if(ret!=JNI_TRUE)
+ {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java: gljDestroy failed, bad param's\n");
+ fflush(stderr);
+ }
+ return ret;
+ }
+
+ if(jawt_open(env, canvas, pData, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ fprintf(stderr,"\nGL4Java ERROR: gljDestroy could not open JAWT reference!\n");
+ fflush(stderr);
+ ret=JNI_FALSE;
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return ret;
+ }
+
+ if(jawt_lock(env, pData, JNI_TRUE, verbose)==JNI_FALSE ||
+ pData->result==JNI_FALSE
+ )
+ {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java: gljDestroy lock failed\n");
+ fflush(stderr);
+ }
+ jawt_close_unlock(env, pData, JNI_FALSE);
+ return JNI_FALSE;
+ }
+
+ win = GET_USED_WINDOW(pData);
+ disp = GET_USED_DISPLAY(pData);
+
+ glXWaitGL();
+
+ if(ret==JNI_TRUE)
+ {
+ if ( gc == 0 )
+ {
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stderr, "GL4Java: gljDestroy failed, GL context is 0\n");
+ fflush(stderr);
+ }
+ ret = JNI_FALSE;
+ }
+ glXMakeCurrent( disp, None, NULL );
+
+ if(ret==JNI_TRUE)
+ {
+ glXDestroyContext(disp, gc);
+ if(pix!=0)
+ {
+ if(win!=0)
+ glXDestroyGLXPixmap(disp, win);
+ win=0;
+ pData->dsi_win = NULL;
+ pData->dsi_win_created = 0;
+ XFreePixmap(disp, pix);
+ pix=0;
+ }
+ if(jownwind && win!=0)
+ {
+ XDestroyWindow(disp, win);
+ win=0;
+ pData->dsi_win = NULL;
+ pData->dsi_win_created = 0;
+ jownwind=JNI_FALSE;
+ }
+ }
+ }
+
+ jawt_free_close_unlock(env, &pData, verbose);
+
+ if(ret==JNI_TRUE)
+ {
+ gc = 0;
+ disp=0;
+ win = 0;
+ pix = 0;
+ pData=0; /* remark the class, we must reinit GL-Context ! */
+ }
+
+ if(ret==JNI_TRUE && fpixmapHandle!=0) {
+ (*env)->SetLongField(env, obj, fpixmapHandle, (jlong)((PointerHolder)pix));
+ }
+
+ if(ret==JNI_TRUE && fwindowHandle!=0) {
+ (*env)->SetLongField(env, obj, fwindowHandle, (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fdisplayHandle) {
+ (*env)->SetLongField(env, obj, fdisplayHandle, (jlong)((PointerHolder)disp));
+ }
+
+ if(ret==JNI_TRUE && fglContext) {
+ (*env)->SetLongField(env, obj, fglContext, (jlong)((PointerHolder)gc));
+ }
+
+
+ if(ret==JNI_TRUE && fpData) {
+ (*env)->SetLongField(env, obj, fpData, (jlong)((PointerHolder)pData));
+ }
+
+ if(ret==JNI_TRUE && fownwind) {
+ (*env)->SetBooleanField(env, obj, fownwind, jownwind);
+ }
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gl4java_GLContext_gljSwapNative( JNIEnv *env, jobject obj,
+ jlong disp,
+ jlong thisWin,
+ jlong glContext,
+ jboolean doubleBuffer
+ )
+{
+ (void)glContext;
+
+ if( doubleBuffer == JNI_FALSE ) {
+ /* don't double buffer */
+ glXWaitGL();
+ } else {
+ glXSwapBuffers( GET_USED_DISPLAY(thisWin),
+ GET_USED_WINDOW(thisWin) );
+ }
+
+ return JNI_TRUE;
+}
+
diff --git a/CNativeCode/jawt_misc.c b/CNativeCode/jawt_misc.c
new file mode 100644
index 0000000..25ed015
--- /dev/null
+++ b/CNativeCode/jawt_misc.c
@@ -0,0 +1,365 @@
+/*----------------------------------------------------------------------
+ * JNI routines for handle access via JAWT
+ */
+
+#include "jawt_misc.h"
+
+static JAWT _awt ;
+static jboolean _awt_init = JNI_FALSE ;
+
+jboolean LIBAPIENTRY
+jawt_create_offscreen (JNIEnv *env, JAWTDataHolder **ppJData, jboolean verbose)
+{
+ if(ppJData==NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: create offscrn failed -> para's == NULL\n");
+ fflush(stderr);
+ }
+ return JNI_FALSE;
+ }
+
+ *ppJData = calloc(1, sizeof(JAWTDataHolder));
+
+ // Get the drawing surface
+ (*ppJData)->ds = NULL;
+ (*ppJData)->dsi = NULL;
+ (*ppJData)->dsi_os = NULL;
+ (*ppJData)->dsi_win = NULL;
+ (*ppJData)->dsi_win_created = 1;
+ (*ppJData)->dsi_display = NULL;
+ (*ppJData)->dsi_display_created = 1;
+ (*ppJData)->lock = 1;
+ (*ppJData)->offScreen = 1;
+ (*ppJData)->result = JNI_TRUE;
+
+ return JNI_TRUE;
+}
+
+jboolean LIBAPIENTRY
+jawt_create_open (JNIEnv *env, jobject component,
+ JAWTDataHolder **ppJData, jboolean verbose)
+{
+ if(ppJData==NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: create failed -> para's == NULL\n");
+ fflush(stderr);
+ }
+ return JNI_FALSE;
+ }
+
+ *ppJData = calloc(1, sizeof(JAWTDataHolder));
+
+ // Get the drawing surface
+ (*ppJData)->ds = NULL;
+ (*ppJData)->dsi = NULL;
+ (*ppJData)->dsi_os = NULL;
+ (*ppJData)->dsi_win = NULL;
+ (*ppJData)->dsi_win_created = 0;
+ (*ppJData)->dsi_display = NULL;
+ (*ppJData)->dsi_display_created = 0;
+ (*ppJData)->lock = 0;
+ (*ppJData)->offScreen = 0;
+ (*ppJData)->result = JNI_TRUE;
+
+ return jawt_open(env, component, *ppJData, verbose);
+}
+
+jboolean LIBAPIENTRY
+jawt_free_close_unlock (JNIEnv *env, JAWTDataHolder **ppJData, jboolean verbose)
+{
+ jboolean res = JNI_TRUE;
+
+ if(ppJData==NULL || *ppJData==NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: free failed -> para's == NULL\n");
+ fflush(stderr);
+ }
+ return JNI_FALSE;
+ }
+
+ if( ! (*ppJData)->offScreen )
+ res = jawt_close_unlock(env, *ppJData, verbose);
+
+ free(*ppJData);
+ *ppJData=NULL;
+
+ return res;
+}
+
+jboolean LIBAPIENTRY
+jawt_open (JNIEnv *env, jobject component, JAWTDataHolder *pJData, jboolean verbose)
+{
+ if(pJData==NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: open failed -> para's == NULL\n");
+ fflush(stderr);
+ }
+ return JNI_FALSE;
+ }
+
+ if( pJData->offScreen )
+ return JNI_TRUE;
+
+ // Get the AWT
+ if(_awt_init==JNI_FALSE)
+ {
+ _awt.version = JAWT_VERSION_1_3;
+ pJData->result = JAWT_GetAWT(env, &_awt);
+ if(pJData->result==JNI_TRUE)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: _awt initialized\n");
+ fflush(stderr);
+ }
+ _awt_init=JNI_TRUE;
+ } else {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: _awt init failed\n");
+ fflush(stderr);
+ }
+ return pJData->result;
+ }
+ }
+
+ // Get the drawing surface
+ pJData->ds = _awt.GetDrawingSurface(env, component);
+ pJData->result = pJData->ds != NULL;
+
+ if(verbose && pJData->result==JNI_FALSE)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: open failed -> GetDrawingSurface()==NULL\n");
+ fflush(stderr);
+ }
+ }
+
+ return pJData->result;
+}
+
+jboolean LIBAPIENTRY
+jawt_close_unlock (JNIEnv *env, JAWTDataHolder *pJData, jboolean verbose)
+{
+ if(pJData!=NULL && pJData->offScreen )
+ return JNI_TRUE;
+
+ if(pJData==NULL || _awt_init==JNI_FALSE)
+ return JNI_FALSE;
+
+ pJData->result=jawt_unlock(env, pJData, verbose);
+
+ // Free the drawing surface
+ if(pJData->ds!=0)
+ _awt.FreeDrawingSurface(pJData->ds);
+ pJData->ds=0;
+
+ return pJData->result;
+}
+
+jboolean LIBAPIENTRY
+jawt_lock (JNIEnv *env, JAWTDataHolder *pJData, jboolean ignoreSurfaceChanged,
+ jboolean verbose)
+{
+ jthrowable exc;
+
+ if(pJData!=NULL && pJData->offScreen )
+ return JNI_TRUE;
+
+ if(pJData==NULL || _awt_init==JNI_FALSE || pJData->ds==NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: lock failed -> para's == NULL\n\t(pData==%p, _awt_init=%d, pData->ds=%p)\n",
+ pJData, _awt_init, (pJData!=NULL)?pJData->ds:NULL);
+ fflush(stderr);
+ }
+ return JNI_FALSE;
+ }
+
+ // Lock the drawing surface
+ pJData->lock = pJData->ds->Lock(pJData->ds);
+ exc = (*env)->ExceptionOccurred(env);
+ if(exc) {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: lock failed -> lock exception\n");
+ fflush(stderr);
+ }
+ pJData->result = JNI_FALSE;
+ if(verbose)
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return pJData->result;
+ }
+
+ pJData->result = (pJData->lock & JAWT_LOCK_ERROR) == 0;
+
+ if(pJData->result ==JNI_FALSE)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: lock failed -> JAWT_LOCK_ERROR\n");
+ fflush(stderr);
+ }
+ return pJData->result;
+ }
+
+ if( (pJData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 )
+ {
+ if(verbose)
+ {
+ if(ignoreSurfaceChanged==JNI_TRUE)
+ fprintf(stderr, "GL4Java-JAWT: lock JAWT_LOCK_SURFACE_CHANGED ignored\n");
+ else
+ fprintf(stderr, "GL4Java-JAWT: lock failed -> JAWT_LOCK_SURFACE_CHANGED\n");
+ fflush(stderr);
+ }
+ if(ignoreSurfaceChanged==JNI_TRUE)
+ {
+ pJData->lock = 0;
+ } else {
+ pJData->result = JNI_FALSE;
+ return pJData->result;
+ }
+ }
+
+ // Get the drawing surface info
+ pJData->dsi = pJData->ds->GetDrawingSurfaceInfo(pJData->ds);
+ exc = (*env)->ExceptionOccurred(env);
+ if(exc) {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: lock failed -> get-dsi exception\n");
+ fflush(stderr);
+ }
+ pJData->result = JNI_FALSE;
+ if(verbose)
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ pJData->dsi=0;
+ }
+
+
+ if(pJData->dsi!=NULL)
+ // Get the platform-specific drawing info
+ pJData->dsi_os = (void *) pJData->dsi->platformInfo;
+ else
+ pJData->dsi_os = 0;
+
+ if(pJData->dsi_os == NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: lock failed -> dsi->platformInfo==NULL\n");
+ fflush(stderr);
+ }
+ pJData->result = JNI_FALSE;
+ return pJData->result;
+ }
+
+ if(pJData->dsi_win_created==0)
+ {
+ pJData->dsi_win = (void *) (PointerHolder)
+ #ifdef _X11_
+ ( ((JAWT_X11DrawingSurfaceInfo *)(pJData->dsi_os))->drawable );
+ #endif
+ #ifdef macintosh
+ NULL;
+ #endif
+ #ifdef _WIN32_
+ ( ((JAWT_Win32DrawingSurfaceInfo*)(pJData->dsi_os))->hdc );
+ #endif
+ }
+
+ if(pJData->dsi_display_created==0)
+ {
+ pJData->dsi_display = (void *) (PointerHolder)
+ #ifdef _X11_
+ ( ((JAWT_X11DrawingSurfaceInfo *)(pJData->dsi_os))->display );
+ #endif
+ #ifdef macintosh
+ NULL;
+ #endif
+ #ifdef _WIN32_
+ NULL;
+ #endif
+ }
+
+ return pJData->result;
+}
+
+jboolean LIBAPIENTRY
+jawt_unlock (JNIEnv *env, JAWTDataHolder *pJData, jboolean verbose)
+{
+ jthrowable exc;
+
+ if(pJData!=NULL && pJData->offScreen )
+ return JNI_TRUE;
+
+ if(pJData==NULL || _awt_init==JNI_FALSE || pJData->ds==NULL)
+ {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: unlock failed -> para's == NULL\n\t(pData==%p, _awt_init=%d, pData->ds=%p)\n",
+ pJData, _awt_init, (pJData!=NULL)?pJData->ds:NULL);
+ fflush(stderr);
+ }
+ pJData->result=JNI_FALSE;
+ return JNI_FALSE;
+ }
+
+ pJData->result=JNI_TRUE;
+
+ if(pJData->dsi!=NULL)
+ {
+ // Free the drawing surface info
+ pJData->ds->FreeDrawingSurfaceInfo(pJData->dsi);
+ exc = (*env)->ExceptionOccurred(env);
+ if(exc) {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: unlock failed -> free-dsi exception\n");
+ fflush(stderr);
+ }
+ pJData->result = JNI_FALSE;
+ if(verbose)
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return pJData->result;
+ }
+ }
+ pJData->dsi=0;
+
+ // Unlock the drawing surface
+ pJData->ds->Unlock(pJData->ds);
+ exc = (*env)->ExceptionOccurred(env);
+ if(exc) {
+ if(verbose)
+ {
+ fprintf(stderr, "GL4Java-JAWT: unlock failed -> unlock exception\n");
+ fflush(stderr);
+ }
+ pJData->result = JNI_FALSE;
+ if(verbose)
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return pJData->result;
+ }
+
+
+ pJData->lock = 0;
+
+ return JNI_TRUE;
+}
+
+
diff --git a/CNativeCode/jawt_misc.h b/CNativeCode/jawt_misc.h
new file mode 100644
index 0000000..9befce9
--- /dev/null
+++ b/CNativeCode/jawt_misc.h
@@ -0,0 +1,84 @@
+
+#ifndef _JAWT_MISC_H
+#define _JAWT_MISC_H
+
+ #include "OpenGL_misc.h"
+
+ #include <jawt_md.h>
+ #include <assert.h>
+
+ typedef struct {
+ JAWT_DrawingSurface* ds;
+ JAWT_DrawingSurfaceInfo* dsi;
+
+ /**
+ * just the java native window handle,
+ * valid, if ds is locked !
+ * but this is just an old copy ..
+ * updated via jawt_lock !
+ */
+ void * dsi_os;
+
+ /**
+ * This is, if dsi_win_created != 0,
+ * the:
+ * - the own created child window, or
+ * - the GLXPixmap of the offscreenRendering data
+ *
+ * This ressource is created manually,
+ * so it must be destroyed manually either !
+ *
+ * Otherwise (dsi_win_created==0),
+ * this is just the backup
+ * of the dsi_os->drawable, of the last lock !
+ */
+ void * dsi_win;
+ int dsi_win_created;
+
+ /**
+ * This is, if dsi_display_created != 0,
+ * the:
+ * - the own fetched display (XopenDisplay)
+ *
+ * This ressource is fetched manually !
+ *
+ * Otherwise (dsi_display_created==0),
+ * this is just the backup
+ * of the dsi_os->display, of the last lock !
+ */
+ void * dsi_display;
+ int dsi_display_created;
+
+ jint lock;
+
+ /* this JAWTDataHolder is a NOT a holder for a true JAWT
+ * component, it is used for an offScreen drawable !
+ */
+ jint offScreen;
+
+ jboolean result;
+ } JAWTDataHolder;
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_create_offscreen (JNIEnv *env, JAWTDataHolder **ppJData,
+ jboolean verbose);
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_create_open (JNIEnv *env, jobject component, JAWTDataHolder **ppJData, jboolean verbose);
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_free_close_unlock (JNIEnv *env, JAWTDataHolder **ppJData, jboolean verbose);
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_open (JNIEnv *env, jobject component, JAWTDataHolder *pJData, jboolean verbose);
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_close_unlock (JNIEnv *env, JAWTDataHolder *pJData, jboolean verbose);
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_lock (JNIEnv *env, JAWTDataHolder *pJData, jboolean ignoreSurfaceChanged,
+ jboolean verbose);
+
+ LIBAPI jboolean LIBAPIENTRY
+ jawt_unlock (JNIEnv *env, JAWTDataHolder *pJData, jboolean verbose);
+#endif