aboutsummaryrefslogtreecommitdiffstats
path: root/CNativeCode/GLCallbackHelperJNI.c
diff options
context:
space:
mode:
Diffstat (limited to 'CNativeCode/GLCallbackHelperJNI.c')
-rw-r--r--CNativeCode/GLCallbackHelperJNI.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/CNativeCode/GLCallbackHelperJNI.c b/CNativeCode/GLCallbackHelperJNI.c
new file mode 100644
index 0000000..2039560
--- /dev/null
+++ b/CNativeCode/GLCallbackHelperJNI.c
@@ -0,0 +1,238 @@
+
+#include "GLCallbackHelperJNI.h"
+#include "jnitools.h"
+
+#ifndef _WIN32_
+ #ifdef macintosh
+ #include <agl.h>
+ #include <string.h>
+ #else
+ #include <GL/glx.h>
+ #endif
+#endif
+
+/*
+#define DEBUG
+*/
+
+static CallbackNode * pCallbackNodeRoot = 0;
+
+void LIBAPIENTRY PrintCallbackEntry(const char *title, CallbackEntry * cbe)
+{
+ if(cbe==NULL)
+ {
+ printf("%s> NULL cbe/cbn entry\n", title);
+ return;
+ }
+
+ printf("%s> cbe entry 4 glu-obj=%ld, glx:=%ld (env=%ld, jobj=%ld)\n",
+ title, (long)(cbe->cb_obj), (long)(cbe->glx),
+ (long)(cbe->env), (long)(cbe->jobj));
+
+ printf(" which, method, argNumber, signature\n");
+ printf(" %d %s %d: %s\n",
+ cbe->which,
+ cbe->methodName,
+ cbe->argListNumber,
+ cbe->signature);
+
+ printf(" array element number\n");
+ printf(" %d %d %d %d %d\n",
+ cbe->arrayLen1,
+ cbe->arrayLen2,
+ cbe->arrayLen3,
+ cbe->arrayLen4,
+ cbe->arrayLen5);
+ fflush(NULL);
+}
+
+void LIBAPIENTRY PrintCallbackNode(const char *title, CallbackNode * cbn)
+{
+ CallbackEntry * cbe=NULL;
+ if(cbn!=NULL) cbe=cbn->this;
+ PrintCallbackEntry(title, cbe);
+}
+
+#ifdef DEBUG
+ #define DBG_PRINT_CBE(a,b) PrintCallbackEntry(a,b)
+ #define DBG_PRINT_CBN(a,b) PrintCallbackNode(a,b)
+#else
+ #define DBG_PRINT_CBE(a,b)
+ #define DBG_PRINT_CBN(a,b)
+#endif
+
+static void CleanCallbackEntry(CallbackEntry * cbe)
+{
+ DBG_PRINT_CBE("CleanCallbackEntry", cbe);
+
+ if(cbe==NULL) return;
+ (*(cbe->env))->DeleteGlobalRef(cbe->env, cbe->jobj);
+ cbe->jobj=0;
+ if(cbe->methodName!=NULL)
+ {
+ free(cbe->methodName);
+ cbe->methodName=NULL;
+ }
+ if(cbe->signature!=NULL)
+ {
+ free(cbe->signature);
+ cbe->signature=NULL;
+ }
+ cbe->argListNumber=0;
+ cbe->arrayLen1=0;
+ cbe->arrayLen2=0;
+ cbe->arrayLen3=0;
+ cbe->arrayLen4=0;
+ cbe->arrayLen5=0;
+ cbe->cb_obj=NULL;
+ cbe->which=0;
+ cbe->glx=0;
+ cbe->env=NULL;
+}
+
+CallbackNode * LIBAPIENTRY LastCallbackNode()
+{
+ CallbackNode * cbn = pCallbackNodeRoot;
+ if(cbn==NULL) return NULL;
+
+ while(cbn->next!=NULL)
+ cbn=cbn->next;
+
+ return cbn;
+}
+
+CallbackNode * LIBAPIENTRY FindNextCallbackNodeOfCbObj(void *cb_obj)
+{
+ CallbackNode * cbn = pCallbackNodeRoot;
+
+ while(cbn!=NULL && cbn->this->cb_obj!=cb_obj)
+ {
+ cbn=cbn->next;
+ }
+ return cbn;
+}
+
+CallbackNode * LIBAPIENTRY FindCallbackNode(GLenum which, jlong glx)
+{
+ CallbackNode * cbn = pCallbackNodeRoot;
+
+ #ifdef DEBUG
+ CallbackEntry * cbe = NULL;
+ printf("FindCallbackNode> which:=%d, glx:=%ld\n",
+ which, (long)glx);
+ while(cbn!=NULL)
+ {
+ cbe=cbn->this;
+ printf(" test cbe(%s %s): which:=%d, glx:=%ld\n",
+ cbe->methodName, cbe->signature,
+ cbe->which, (long)(cbe->glx));
+
+ if(cbe->which==which && cbe->glx==glx)
+ break;
+ cbn=cbn->next;
+ }
+ #else
+ while(cbn!=NULL &&
+ (cbn->this->which!=which || cbn->this->glx!=glx)
+ )
+ cbn=cbn->next;
+ #endif
+
+ return cbn;
+}
+
+CallbackEntry * LIBAPIENTRY FindCallbackEntry(GLenum which, jlong glx)
+{
+ CallbackNode * cbn = FindCallbackNode(which, glx);
+ if(cbn==NULL) return NULL;
+ return cbn->this;
+}
+
+void LIBAPIENTRY AddCallbackNode(JNIEnv * env, jobject jobj,
+ const char *methodName, const char *signature,
+ int arrayLen1, int arrayLen2, int arrayLen3,
+ int arrayLen4, int arrayLen5,
+ void *cb_obj, GLenum which, jlong glx)
+{
+ CallbackNode * cbn = NULL;
+ CallbackNode * last_cbn = NULL;
+ CallbackEntry * cbe = NULL;
+
+ cbn = FindCallbackNode (which, glx);
+ if(cbn != NULL)
+ {
+ cbe = cbn->this;
+ CleanCallbackEntry(cbe);
+ } else {
+ cbe = calloc(1, sizeof(CallbackEntry));
+ }
+
+ cbe->env=env;
+ cbe->jobj= (*env)->NewGlobalRef(env, jobj);
+ if(methodName!=NULL)
+ {
+ cbe->methodName=calloc(strlen(methodName)+1, 1);
+ strcpy(cbe->methodName, methodName);
+ }
+ if(signature!=NULL)
+ {
+ cbe->signature=calloc(strlen(signature)+1, 1);
+ strcpy(cbe->signature, signature);
+ }
+ cbe->argListNumber= jnitoolsGetArgNumber(env, signature, cbe->methodName);
+ cbe->arrayLen1=arrayLen1;
+ cbe->arrayLen2=arrayLen2;
+ cbe->arrayLen3=arrayLen3;
+ cbe->arrayLen4=arrayLen4;
+ cbe->arrayLen5=arrayLen5;
+ cbe->cb_obj=cb_obj;
+ cbe->which=which;
+ cbe->glx=glx;
+
+ if(cbn == NULL)
+ {
+ cbn = calloc(1, sizeof(CallbackNode));
+ cbn->this = cbe;
+ last_cbn = LastCallbackNode();
+ if(last_cbn==NULL)
+ pCallbackNodeRoot=cbn;
+ else {
+ last_cbn->next=cbn;
+ cbn->prev=last_cbn;
+ }
+ }
+ DBG_PRINT_CBN("AddCallbackNode", cbn);
+}
+
+void LIBAPIENTRY RemoveCallbackNodes(void *cb_obj)
+{
+ CallbackNode * cbn = NULL;
+ while ( (cbn = FindNextCallbackNodeOfCbObj(cb_obj) ) != NULL )
+ {
+ DBG_PRINT_CBN("RemoveCallbackNodes", cbn);
+ if(cbn->prev!=NULL)
+ cbn->prev->next=cbn->next;
+ else
+ pCallbackNodeRoot=cbn->next;
+ if(cbn->next!=NULL)
+ cbn->next->prev=cbn->prev;
+ CleanCallbackEntry(cbn->this);
+ free(cbn->this);
+ free(cbn);
+ }
+}
+
+jlong LIBAPIENTRY GetCurrentGLContext()
+{
+ #ifdef _WIN32_
+ return (jlong) wglGetCurrentContext();
+ #else
+ #ifdef macintosh
+ return (jlong) aglGetCurrentContext();
+ #else
+ return (jlong) glXGetCurrentContext();
+ #endif
+ #endif
+}
+
+