Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/common/library/callback.c')
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/common/library/callback.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/library/callback.c b/bundles/org.eclipse.swt/Eclipse SWT/common/library/callback.c
new file mode 100755
index 0000000000..565483b589
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/library/callback.c
@@ -0,0 +1,328 @@
+/**
+ * Callback implementation.
+ */
+#include "globals.h"
+#include "callback.h"
+
+/* --------------- callback functions --------------- */
+
+/* Function name from index and number of arguments */
+#define FN(index, args) fn##index##_##args
+
+/**
+ * Functions templates
+ *
+ * NOTE: If the maximum number of arguments changes (MAX_ARGS), the number
+ * of function templates has to change accordinglly.
+ */
+
+/* Function template with no arguments */
+#define FN_0(index) RETURN_TYPE FN(index, 0)() { return RETURN_CAST callback(index); }
+
+/* Function template with 1 argument */
+#define FN_1(index) RETURN_TYPE FN(index, 1)(int p1) { return RETURN_CAST callback(index, p1); }
+
+/* Function template with 2 arguments */
+#define FN_2(index) RETURN_TYPE FN(index, 2)(int p1, int p2) { return RETURN_CAST callback(index, p1, p2); }
+
+/* Function template with 3 arguments */
+#define FN_3(index) RETURN_TYPE FN(index, 3)(int p1, int p2, int p3) { return RETURN_CAST callback(index, p1, p2, p3); }
+
+/* Function template with 4 arguments */
+#define FN_4(index) RETURN_TYPE FN(index, 4)(int p1, int p2, int p3, int p4) { return RETURN_CAST callback(index, p1, p2, p3, p4); }
+
+/* Function template with 5 arguments */
+#define FN_5(index) RETURN_TYPE FN(index, 5)(int p1, int p2, int p3, int p4, int p5) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5); }
+
+/* Function template with 6 arguments */
+#define FN_6(index) RETURN_TYPE FN(index, 6)(int p1, int p2, int p3, int p4, int p5, int p6) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6); }
+
+/* Function template with 7 arguments */
+#define FN_7(index) RETURN_TYPE FN(index, 7)(int p1, int p2, int p3, int p4, int p5, int p6, int p7) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7); }
+
+/* Function template with 8 arguments */
+#define FN_8(index) RETURN_TYPE FN(index, 8)(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8); }
+
+/* Function template with 9 arguments */
+#define FN_9(index) RETURN_TYPE FN(index, 9)(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
+
+/* Function template with 10 arguments */
+#define FN_10(index) RETURN_TYPE FN(index, 10) (int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
+
+/* Function template with 11 arguments */
+#define FN_11(index) RETURN_TYPE FN(index, 11) (int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
+
+/* Function template with 12 arguments */
+#define FN_12(index) RETURN_TYPE FN(index, 12) (int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
+
+/**
+ * Define all functions with the specified number of arguments.
+ *
+ * NOTE: If the maximum number of callbacks changes (MAX_CALLBACKS),
+ * this macro has to be updated.
+ */
+#define FN_BLOCK(args) FN_##args##(0) FN_##args##(1) FN_##args##(2) FN_##args##(3) FN_##args##(4) FN_##args##(5) FN_##args##(6) FN_##args##(7) FN_##args##(8) FN_##args##(9) FN_##args##(10) FN_##args##(11) FN_##args##(12) FN_##args##(13) FN_##args##(14) FN_##args##(15) FN_##args##(16) FN_##args##(17) FN_##args##(18) FN_##args##(19) FN_##args##(20) FN_##args##(21) FN_##args##(22) FN_##args##(23) FN_##args##(24) FN_##args##(25) FN_##args##(26) FN_##args##(27) FN_##args##(28) FN_##args##(29) FN_##args##(30) FN_##args##(31) FN_##args##(32) FN_##args##(33) FN_##args##(34) FN_##args##(35) FN_##args##(36) FN_##args##(37) FN_##args##(38) FN_##args##(39) FN_##args##(40) FN_##args##(41) FN_##args##(42) FN_##args##(43) FN_##args##(44) FN_##args##(45) FN_##args##(46) FN_##args##(47) FN_##args##(48) FN_##args##(49) FN_##args##(50) FN_##args##(51) FN_##args##(52) FN_##args##(53) FN_##args##(54) FN_##args##(55) FN_##args##(56) FN_##args##(57) FN_##args##(58) FN_##args##(59) FN_##args##(60) FN_##args##(61) FN_##args##(62) FN_##args##(63) FN_##args##(64) FN_##args##(65) FN_##args##(66) FN_##args##(67) FN_##args##(68) FN_##args##(69) FN_##args##(70) FN_##args##(71) FN_##args##(72) FN_##args##(73) FN_##args##(74) FN_##args##(75) FN_##args##(76) FN_##args##(77) FN_##args##(78) FN_##args##(79) FN_##args##(80) FN_##args##(81) FN_##args##(82) FN_##args##(83) FN_##args##(84) FN_##args##(85) FN_##args##(86) FN_##args##(87) FN_##args##(88) FN_##args##(89) FN_##args##(90) FN_##args##(91) FN_##args##(92) FN_##args##(93) FN_##args##(94) FN_##args##(95) FN_##args##(96) FN_##args##(97) FN_##args##(98) FN_##args##(99) FN_##args##(100) FN_##args##(101) FN_##args##(102) FN_##args##(103) FN_##args##(104) FN_##args##(105) FN_##args##(106) FN_##args##(107) FN_##args##(108) FN_##args##(109) FN_##args##(110) FN_##args##(111) FN_##args##(112) FN_##args##(113) FN_##args##(114) FN_##args##(115) FN_##args##(116) FN_##args##(117) FN_##args##(118) FN_##args##(119) FN_##args##(120) FN_##args##(121) FN_##args##(122) FN_##args##(123) FN_##args##(124) FN_##args##(125) FN_##args##(126) FN_##args##(127)
+
+/**
+ * Define all callback functions.
+ *
+ * NOTE: If the maximum number of arguments changes (MAX_ARGS), the following
+ * has to change accordinglly.
+ */
+FN_BLOCK(0)
+FN_BLOCK(1)
+FN_BLOCK(2)
+FN_BLOCK(3)
+FN_BLOCK(4)
+FN_BLOCK(5)
+FN_BLOCK(6)
+FN_BLOCK(7)
+FN_BLOCK(8)
+FN_BLOCK(9)
+FN_BLOCK(10)
+FN_BLOCK(11)
+FN_BLOCK(12)
+
+/**
+ * Initialize the function pointers for the callback routines.
+ *
+ * NOTE: If MAX_ARGS or MAX_CALLBACKS changes, the following has to be updated.
+ */
+#define FN_A_BLOCK(args) {(int *)FN(0, args),(int *)FN(1, args),(int *)FN(2, args),(int *)FN(3, args),(int *)FN(4, args),(int *)FN(5, args),(int *)FN(6, args),(int *)FN(7, args),(int *)FN(8, args),(int *)FN(9, args),(int *)FN(10, args),(int *)FN(11, args),(int *)FN(12, args),(int *)FN(13, args),(int *)FN(14, args),(int *)FN(15, args),(int *)FN(16, args),(int *)FN(17, args),(int *)FN(18, args),(int *)FN(19, args),(int *)FN(20, args),(int *)FN(21, args),(int *)FN(22, args),(int *)FN(23, args),(int *)FN(24, args),(int *)FN(25, args),(int *)FN(26, args),(int *)FN(27, args),(int *)FN(28, args),(int *)FN(29, args),(int *)FN(30, args),(int *)FN(31, args),(int *)FN(32, args),(int *)FN(33, args),(int *)FN(34, args),(int *)FN(35, args),(int *)FN(36, args),(int *)FN(37, args),(int *)FN(38, args),(int *)FN(39, args),(int *)FN(40, args),(int *)FN(41, args),(int *)FN(42, args),(int *)FN(43, args),(int *)FN(44, args),(int *)FN(45, args),(int *)FN(46, args),(int *)FN(47, args),(int *)FN(48, args),(int *)FN(49, args),(int *)FN(50, args),(int *)FN(51, args),(int *)FN(52, args),(int *)FN(53, args),(int *)FN(54, args),(int *)FN(55, args),(int *)FN(56, args),(int *)FN(57, args),(int *)FN(58, args),(int *)FN(59, args),(int *)FN(60, args),(int *)FN(61, args),(int *)FN(62, args),(int *)FN(63, args),(int *)FN(64, args),(int *)FN(65, args),(int *)FN(66, args),(int *)FN(67, args),(int *)FN(68, args),(int *)FN(69, args),(int *)FN(70, args),(int *)FN(71, args),(int *)FN(72, args),(int *)FN(73, args),(int *)FN(74, args),(int *)FN(75, args),(int *)FN(76, args),(int *)FN(77, args),(int *)FN(78, args),(int *)FN(79, args),(int *)FN(80, args),(int *)FN(81, args),(int *)FN(82, args),(int *)FN(83, args),(int *)FN(84, args),(int *)FN(85, args),(int *)FN(86, args),(int *)FN(87, args),(int *)FN(88, args),(int *)FN(89, args),(int *)FN(90, args),(int *)FN(91, args),(int *)FN(92, args),(int *)FN(93, args),(int *)FN(94, args),(int *)FN(95, args),(int *)FN(96, args),(int *)FN(97, args),(int *)FN(98, args),(int *)FN(99, args),(int *)FN(100, args),(int *)FN(101, args),(int *)FN(102, args),(int *)FN(103, args),(int *)FN(104, args),(int *)FN(105, args),(int *)FN(106, args),(int *)FN(107, args),(int *)FN(108, args),(int *)FN(109, args),(int *)FN(110, args),(int *)FN(111, args),(int *)FN(112, args),(int *)FN(113, args),(int *)FN(114, args),(int *)FN(115, args),(int *)FN(116, args),(int *)FN(117, args),(int *)FN(118, args),(int *)FN(119, args),(int *)FN(120, args),(int *)FN(121, args),(int *)FN(122, args),(int *)FN(123, args),(int *)FN(124, args),(int *)FN(125, args),(int *)FN(126, args),(int *)FN(127, args)},
+
+int * fnx_array[MAX_ARGS+1][MAX_CALLBACKS] = {
+ FN_A_BLOCK(0)
+ FN_A_BLOCK(1)
+ FN_A_BLOCK(2)
+ FN_A_BLOCK(3)
+ FN_A_BLOCK(4)
+ FN_A_BLOCK(5)
+ FN_A_BLOCK(6)
+ FN_A_BLOCK(7)
+ FN_A_BLOCK(8)
+ FN_A_BLOCK(9)
+ FN_A_BLOCK(10)
+ FN_A_BLOCK(11)
+ FN_A_BLOCK(12)
+};
+
+
+/* --------------- callback class calls --------------- */
+
+/*
+ * Class: org_eclipse_swt_internal_Callback
+ * Method: bind
+ * Signature: (Lorg/eclipse/swt/internal/Callback;)I
+ */
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_Callback_bind
+ (JNIEnv *env, jclass that, jobject lpCallback)
+/*
+** The methodID is computed once during the bind and will be valid
+** unless the Callback class is reloaded.
+*/
+{
+ DECL_GLOB(pGlob)
+ int i;
+ jclass javaClass;
+ jobject javaObject, javaMethod, javaSignature;
+ jboolean isStatic, isArrayBased;
+ jint argCount;
+ jmethodID mid;
+ const char *methodString, *sigString;
+
+ javaClass = that;
+ if (!PGLOB(callbackCached)) {
+ PGLOB(objectID) = (*env)->GetFieldID(env,javaClass,"object","Ljava/lang/Object;");
+ PGLOB(addressID) = (*env)->GetFieldID(env,javaClass,"address","I");
+ PGLOB(methodID) = (*env)->GetFieldID(env,javaClass,"method","Ljava/lang/String;");
+ PGLOB(signatureID) = (*env)->GetFieldID(env,javaClass,"signature","Ljava/lang/String;");
+ PGLOB(isStaticID) = (*env)->GetFieldID(env,javaClass,"isStatic","Z");
+ PGLOB(argCountID) = (*env)->GetFieldID(env,javaClass,"argCount","I");
+ PGLOB(isArrayBasedID) = (*env)->GetFieldID(env,javaClass,"isArrayBased","Z");
+ PGLOB(callbackCached) = 1;
+ }
+ javaObject = (*env)->GetObjectField(env,lpCallback,PGLOB(objectID));
+ javaMethod = (*env)->GetObjectField(env,lpCallback,PGLOB(methodID));
+ javaSignature = (*env)->GetObjectField(env,lpCallback,PGLOB(signatureID));
+ isStatic = (*env)->GetBooleanField(env,lpCallback,PGLOB(isStaticID));
+ argCount = (*env)->GetIntField(env,lpCallback,PGLOB(argCountID));
+ isArrayBased = (*env)->GetBooleanField(env,lpCallback,PGLOB(isArrayBasedID));
+ methodString = (*env)->GetStringUTFChars(env, javaMethod, NULL);
+ sigString = (*env)->GetStringUTFChars(env, javaSignature, NULL);
+ if (isStatic) {
+ mid = (*env)->GetStaticMethodID(env, javaObject, methodString, sigString);
+ } else {
+ javaClass = (*env)->GetObjectClass(env,javaObject);
+ /* note that this call is reusing javaClass */
+ mid = (*env)->GetMethodID(env, javaClass, methodString, sigString);
+ }
+ (*env)->ReleaseStringUTFChars(env, javaMethod, methodString);
+ (*env)->ReleaseStringUTFChars(env, javaSignature, sigString);
+ if (PGLOB(initialized)==0) {
+ memset((void *)&PGLOB(dllCallbackInfo), 0, sizeof(PGLOB(dllCallbackInfo)));
+ PGLOB(initialized) = 1;
+ }
+ for (i=0; i<MAX_CALLBACKS; i++) {
+ if (!PGLOB(dllCallbackInfo)[i].callin) {
+ PGLOB(dllCallbackInfo)[i].callin = (*env)->NewGlobalRef(env,lpCallback);
+ PGLOB(dllCallbackInfo)[i].env = env;
+ PGLOB(dllCallbackInfo)[i].methodID = mid;
+
+ return (jint) fnx_array[argCount][i];
+ }
+ }
+ fprintf(stderr, "bind fail, no free callback slot ******* \n");
+ return 0; /* this means there was no free callback slot */
+}
+
+/*
+ * Class: org_eclipse_swt_internal_Callback
+ * Method: unbind
+ * Signature: (Lorg/eclipse/swt/internal/Callback;)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_Callback_unbind
+ (JNIEnv *env, jclass that, jobject lpCallback)
+{
+ DECL_GLOB(pGlob)
+ int i, address, argCount;
+ if (!PGLOB(callbackCached)) return;
+
+ address = (*env)->GetIntField(env,lpCallback,PGLOB(addressID));
+ argCount = (*env)->GetIntField(env,lpCallback,PGLOB(argCountID));
+
+ for (i=0; i<MAX_CALLBACKS; i++) {
+ if ((int)fnx_array[argCount][i] == address) {
+ (*env)->DeleteGlobalRef(env, PGLOB(dllCallbackInfo)[i].callin);
+ PGLOB(dllCallbackInfo)[i].callin = 0;
+ PGLOB(dllCallbackInfo)[i].env = 0;
+ PGLOB(dllCallbackInfo)[i].methodID = 0;
+ }
+ }
+}
+
+/*
+ * Indicates wheter callbacks should be fired.
+ *
+ * WARNING - This var has to be a global. Do not multidata enable it.
+ */
+static int CallbacksEnabled = 1;
+
+/*
+ * Class: org_eclipse_swt_internal_Callback
+ * Method: setEnabled
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_Callback_setEnabled
+ (JNIEnv *env, jclass that, jboolean enable)
+{
+ CallbacksEnabled = enable;
+}
+
+/*
+ * Class: org_eclipse_swt_internal_Callback
+ * Method: getEnabled
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_swt_internal_Callback_getEnabled
+ (JNIEnv *env, jclass that, jboolean enable)
+{
+ return (jboolean)CallbacksEnabled;
+}
+
+int callback(int index, ...)
+{
+ if (!CallbacksEnabled) {
+ return 0;
+ } else {
+ DECL_GLOB(pGlob)
+ jobject callback = PGLOB(dllCallbackInfo)[index].callin;
+ JNIEnv *env = PGLOB(dllCallbackInfo)[index].env;
+ jmethodID mid = PGLOB(dllCallbackInfo)[index].methodID;
+ jobject javaObject;
+ jboolean isStatic, isArrayBased;
+
+ int result = 0;
+ va_list vl;
+
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "* callback starting %d\n", PGLOB(counter)++);
+#endif
+
+ /* An exception has already occurred. Allow the stack to unwind so that
+ the exception will be thrown in Java */
+ if ((*env)->ExceptionOccurred(env)) {
+
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "************ java exception occurred\n");
+#endif
+
+ return 0;
+ }
+
+ javaObject = (*env)->GetObjectField(env,callback,PGLOB(objectID));
+ isStatic = ((*env)->GetBooleanField(env,callback,PGLOB(isStaticID))) != 0;
+ isArrayBased = ((*env)->GetBooleanField(env,callback,PGLOB(isArrayBasedID))) != 0;
+
+ va_start(vl, index);
+ if (isArrayBased) {
+ int i;
+ jint argCount = (*env)->GetIntField(env,callback,PGLOB(argCountID));
+ jintArray javaArray = (*env)->NewIntArray(env,argCount);
+ jint *elements = (*env)->GetIntArrayElements(env,javaArray,NULL);
+ for (i=0; i<argCount; i++) {
+ elements[i] = va_arg(vl, jint);
+ }
+ (*env)->ReleaseIntArrayElements(env, javaArray, elements, 0);
+ if (isStatic) {
+ result = (*env)->CallStaticIntMethod(env, javaObject, mid, javaArray);
+ } else {
+ result = (*env)->CallIntMethod(env, javaObject, mid, javaArray);
+ }
+ (*env)->DeleteLocalRef(env, javaArray);
+ } else {
+ if (isStatic) {
+ result = (*env)->CallStaticIntMethodV(env, javaObject, mid, vl);
+ } else {
+ result = (*env)->CallIntMethodV(env, javaObject, mid, vl);
+ }
+ }
+ va_end(vl);
+ /* This call may be called many times before we return to Java.
+ We have to explicitly delete local references to avoid GP's
+ in the JDK and IBM Hursley VM.
+ */
+ (*env)->DeleteLocalRef(env,javaObject);
+
+#ifdef DEBUG_CALL_PRINTS
+ fprintf(stderr, "* callback exiting %d\n", --PGLOB(counter));
+#endif
+ return result;
+ }
+}
+
+/*
+ * Class: org_eclipse_swt_internal_Callback
+ * Method: reset
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_Callback_reset
+ (JNIEnv *env, jclass that)
+{
+ DECL_GLOB(pGlob)
+ memset((void *)&PGLOB(dllCallbackInfo), 0, sizeof(PGLOB(dllCallbackInfo)));
+}
+
+/*
+ * Class: org_eclipse_swt_internal_Callback
+ * Method: getPlatform
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_eclipse_swt_internal_Callback_getPlatform
+ (JNIEnv *env, jclass that)
+{
+ return (*env)->NewStringUTF(env, PLATFORM);
+}
+
+/* ------------- callback class calls end --------------- */
+
+

Back to the top