From f36d363033840c84c76bf5285a252846aa9a7e96 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 13 Feb 2001 05:39:47 +0000 Subject: JAWT Support JDK >=1.3 --- CNativeCode/OpenGL_Win32_common.c | 655 ++++++++++++++++++++++++++ CNativeCode/OpenGL_Win32_common.h | 44 ++ CNativeCode/OpenGL_Win32_jawt.c | 650 ++++++++++++++++++++++++++ CNativeCode/OpenGL_X11_common.c | 622 +++++++++++++++++++++++++ CNativeCode/OpenGL_X11_common.h | 82 ++++ CNativeCode/OpenGL_X11_jawt.c | 951 ++++++++++++++++++++++++++++++++++++++ CNativeCode/jawt_misc.c | 365 +++++++++++++++ CNativeCode/jawt_misc.h | 84 ++++ 8 files changed, 3453 insertions(+) create mode 100755 CNativeCode/OpenGL_Win32_common.c create mode 100755 CNativeCode/OpenGL_Win32_common.h create mode 100755 CNativeCode/OpenGL_Win32_jawt.c create mode 100644 CNativeCode/OpenGL_X11_common.c create mode 100644 CNativeCode/OpenGL_X11_common.h create mode 100644 CNativeCode/OpenGL_X11_jawt.c create mode 100644 CNativeCode/jawt_misc.c create mode 100644 CNativeCode/jawt_misc.h (limited to 'CNativeCode') 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; ipalPalEntry[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; rpalPalEntry[rampBase]; + int diffSize = (int) (rampSize * colors[r].ratio); + int specSize = rampSize - diffSize; + + for (i=0; ipalPalEntry[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 + + +// 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; i0) { + glXGetConfig(display, vi, GLX_ACCUM_ALPHA_SIZE, &glxCfg); + if(glxCfgclass ; + viTemplate.depth = xwa.depth; + + *visualList = XGetVisualInfo( disp, VisualScreenMask, + &viTemplate, &numReturns ); + + for(i=0; done==0 && 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 + #include + + #include + #include + + 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 +#include +#include + +/* + * 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 +#include + +#include +#include + +#include + +#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 + #include + + 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 -- cgit v1.2.3