1 /*******************************************************************************
2  * Copyright (c) 2000, 2012 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 
15 /**
16  * Callback implementation.
17  */
18 #include "callback.h"
19 #include <string.h>
20 
21 #ifndef CALLBACK_NATIVE
22 #define CALLBACK_NATIVE(func) Java_org_eclipse_swt_internal_Callback_##func
23 #endif
24 
25 /* define this to print out debug statements */
26 /* #define DEBUG_CALL_PRINTS */
27 
28 /* --------------- callback globals ----------------- */
29 
30 static CALLBACK_DATA callbackData[MAX_CALLBACKS];
31 static int callbackEnabled = 1;
32 static int callbackEntryCount = 0;
33 static int initialized = 0;
34 static jint JNI_VERSION = 0;
35 
36 #ifdef DEBUG_CALL_PRINTS
37 	static int counter = 0;
38 
39 	#if   defined(COCOA)
40 		#include <objc/runtime.h>
41 	#elif defined(GTK)
42 		#include <dlfcn.h>
43 		#include <gdk/gdk.h>
44 	#endif
45 #endif
46 
47 #ifdef ATOMIC
48 #include <libkern/OSAtomic.h>
49 #define ATOMIC_INC(value) OSAtomicIncrement32(&value);
50 #define ATOMIC_DEC(value) OSAtomicDecrement32(&value);
51 #else
52 #define ATOMIC_INC(value) value++;
53 #define ATOMIC_DEC(value) value--;
54 #endif
55 
56 jlong callback(int index, ...);
57 
58 /* --------------- callback functions --------------- */
59 
60 
61 /* Function name from index and number of arguments */
62 #define FN(index, args) fn##index##_##args
63 
64 /**
65  * Functions templates
66  *
67  * NOTE: If the maximum number of arguments changes (MAX_ARGS), the number
68  *       of function templates has to change accordingly.
69  */
70 
71 /* Function template with no arguments */
72 #define FN_0(index) jlong FN(index, 0)() { return callback(index); }
73 
74 /* Function template with 1 argument */
75 #define FN_1(index) jlong FN(index, 1)(jlong p1) { return callback(index, p1); }
76 
77 /* Function template with 2 arguments */
78 #define FN_2(index) jlong FN(index, 2)(jlong p1, jlong p2) { return callback(index, p1, p2); }
79 
80 /* Function template with 3 arguments */
81 #define FN_3(index) jlong FN(index, 3)(jlong p1, jlong p2, jlong p3) { return callback(index, p1, p2, p3); }
82 
83 /* Function template with 4 arguments */
84 #define FN_4(index) jlong FN(index, 4)(jlong p1, jlong p2, jlong p3, jlong p4) { return callback(index, p1, p2, p3, p4); }
85 
86 /* Function template with 5 arguments */
87 #define FN_5(index) jlong FN(index, 5)(jlong p1, jlong p2, jlong p3, jlong p4, jlong p5) { return callback(index, p1, p2, p3, p4, p5); }
88 
89 /* Function template with 6 arguments */
90 #define FN_6(index) jlong FN(index, 6)(jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6) { return callback(index, p1, p2, p3, p4, p5, p6); }
91 
92 /* Function template with 7 arguments */
93 #define FN_7(index) jlong FN(index, 7)(jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6, jlong p7) { return callback(index, p1, p2, p3, p4, p5, p6, p7); }
94 
95 /* Function template with 8 arguments */
96 #define FN_8(index) jlong FN(index, 8)(jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6, jlong p7, jlong p8) { return callback(index, p1, p2, p3, p4, p5, p6, p7, p8); }
97 
98 /* Function template with 9 arguments */
99 #define FN_9(index) jlong FN(index, 9)(jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6, jlong p7, jlong p8, jlong p9) { return callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
100 
101 /* Function template with 10 arguments */
102 #define FN_10(index) jlong FN(index, 10) (jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6, jlong p7, jlong p8, jlong p9, jlong p10) { return callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
103 
104 /* Function template with 11 arguments */
105 #define FN_11(index) jlong FN(index, 11) (jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6, jlong p7, jlong p8, jlong p9, jlong p10, jlong p11) { return callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
106 
107 /* Function template with 12 arguments */
108 #define FN_12(index) jlong FN(index, 12) (jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6, jlong p7, jlong p8, jlong p9, jlong p10, jlong p11, jlong p12) { return callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
109 
110 /**
111  * Define all functions with the specified number of arguments.
112  *
113  * NOTE: If the maximum number of callbacks changes (MAX_CALLBACKS),
114  *       this macro has to be updated.
115  */
116 #if MAX_CALLBACKS == 16
117 #define FN_BLOCK(args) \
118 	FN_##args(0) \
119 	FN_##args(1) \
120 	FN_##args(2) \
121 	FN_##args(3) \
122 	FN_##args(4) \
123 	FN_##args(5) \
124 	FN_##args(6) \
125 	FN_##args(7) \
126 	FN_##args(8) \
127 	FN_##args(9) \
128 	FN_##args(10) \
129 	FN_##args(11) \
130 	FN_##args(12) \
131 	FN_##args(13) \
132 	FN_##args(14) \
133 	FN_##args(15)
134 #elif MAX_CALLBACKS == 128
135 #define FN_BLOCK(args) \
136 	FN_##args(0) \
137 	FN_##args(1) \
138 	FN_##args(2) \
139 	FN_##args(3) \
140 	FN_##args(4) \
141 	FN_##args(5) \
142 	FN_##args(6) \
143 	FN_##args(7) \
144 	FN_##args(8) \
145 	FN_##args(9) \
146 	FN_##args(10) \
147 	FN_##args(11) \
148 	FN_##args(12) \
149 	FN_##args(13) \
150 	FN_##args(14) \
151 	FN_##args(15) \
152 	FN_##args(16) \
153 	FN_##args(17) \
154 	FN_##args(18) \
155 	FN_##args(19) \
156 	FN_##args(20) \
157 	FN_##args(21) \
158 	FN_##args(22) \
159 	FN_##args(23) \
160 	FN_##args(24) \
161 	FN_##args(25) \
162 	FN_##args(26) \
163 	FN_##args(27) \
164 	FN_##args(28) \
165 	FN_##args(29) \
166 	FN_##args(30) \
167 	FN_##args(31) \
168 	FN_##args(32) \
169 	FN_##args(33) \
170 	FN_##args(34) \
171 	FN_##args(35) \
172 	FN_##args(36) \
173 	FN_##args(37) \
174 	FN_##args(38) \
175 	FN_##args(39) \
176 	FN_##args(40) \
177 	FN_##args(41) \
178 	FN_##args(42) \
179 	FN_##args(43) \
180 	FN_##args(44) \
181 	FN_##args(45) \
182 	FN_##args(46) \
183 	FN_##args(47) \
184 	FN_##args(48) \
185 	FN_##args(49) \
186 	FN_##args(50) \
187 	FN_##args(51) \
188 	FN_##args(52) \
189 	FN_##args(53) \
190 	FN_##args(54) \
191 	FN_##args(55) \
192 	FN_##args(56) \
193 	FN_##args(57) \
194 	FN_##args(58) \
195 	FN_##args(59) \
196 	FN_##args(60) \
197 	FN_##args(61) \
198 	FN_##args(62) \
199 	FN_##args(63) \
200 	FN_##args(64) \
201 	FN_##args(65) \
202 	FN_##args(66) \
203 	FN_##args(67) \
204 	FN_##args(68) \
205 	FN_##args(69) \
206 	FN_##args(70) \
207 	FN_##args(71) \
208 	FN_##args(72) \
209 	FN_##args(73) \
210 	FN_##args(74) \
211 	FN_##args(75) \
212 	FN_##args(76) \
213 	FN_##args(77) \
214 	FN_##args(78) \
215 	FN_##args(79) \
216 	FN_##args(80) \
217 	FN_##args(81) \
218 	FN_##args(82) \
219 	FN_##args(83) \
220 	FN_##args(84) \
221 	FN_##args(85) \
222 	FN_##args(86) \
223 	FN_##args(87) \
224 	FN_##args(88) \
225 	FN_##args(89) \
226 	FN_##args(90) \
227 	FN_##args(91) \
228 	FN_##args(92) \
229 	FN_##args(93) \
230 	FN_##args(94) \
231 	FN_##args(95) \
232 	FN_##args(96) \
233 	FN_##args(97) \
234 	FN_##args(98) \
235 	FN_##args(99) \
236 	FN_##args(100) \
237 	FN_##args(101) \
238 	FN_##args(102) \
239 	FN_##args(103) \
240 	FN_##args(104) \
241 	FN_##args(105) \
242 	FN_##args(106) \
243 	FN_##args(107) \
244 	FN_##args(108) \
245 	FN_##args(109) \
246 	FN_##args(110) \
247 	FN_##args(111) \
248 	FN_##args(112) \
249 	FN_##args(113) \
250 	FN_##args(114) \
251 	FN_##args(115) \
252 	FN_##args(116) \
253 	FN_##args(117) \
254 	FN_##args(118) \
255 	FN_##args(119) \
256 	FN_##args(120) \
257 	FN_##args(121) \
258 	FN_##args(122) \
259 	FN_##args(123) \
260 	FN_##args(124) \
261 	FN_##args(125) \
262 	FN_##args(126) \
263 	FN_##args(127)
264 #elif MAX_CALLBACKS == 256
265 #define FN_BLOCK(args) \
266 	FN_##args(0) \
267 	FN_##args(1) \
268 	FN_##args(2) \
269 	FN_##args(3) \
270 	FN_##args(4) \
271 	FN_##args(5) \
272 	FN_##args(6) \
273 	FN_##args(7) \
274 	FN_##args(8) \
275 	FN_##args(9) \
276 	FN_##args(10) \
277 	FN_##args(11) \
278 	FN_##args(12) \
279 	FN_##args(13) \
280 	FN_##args(14) \
281 	FN_##args(15) \
282 	FN_##args(16) \
283 	FN_##args(17) \
284 	FN_##args(18) \
285 	FN_##args(19) \
286 	FN_##args(20) \
287 	FN_##args(21) \
288 	FN_##args(22) \
289 	FN_##args(23) \
290 	FN_##args(24) \
291 	FN_##args(25) \
292 	FN_##args(26) \
293 	FN_##args(27) \
294 	FN_##args(28) \
295 	FN_##args(29) \
296 	FN_##args(30) \
297 	FN_##args(31) \
298 	FN_##args(32) \
299 	FN_##args(33) \
300 	FN_##args(34) \
301 	FN_##args(35) \
302 	FN_##args(36) \
303 	FN_##args(37) \
304 	FN_##args(38) \
305 	FN_##args(39) \
306 	FN_##args(40) \
307 	FN_##args(41) \
308 	FN_##args(42) \
309 	FN_##args(43) \
310 	FN_##args(44) \
311 	FN_##args(45) \
312 	FN_##args(46) \
313 	FN_##args(47) \
314 	FN_##args(48) \
315 	FN_##args(49) \
316 	FN_##args(50) \
317 	FN_##args(51) \
318 	FN_##args(52) \
319 	FN_##args(53) \
320 	FN_##args(54) \
321 	FN_##args(55) \
322 	FN_##args(56) \
323 	FN_##args(57) \
324 	FN_##args(58) \
325 	FN_##args(59) \
326 	FN_##args(60) \
327 	FN_##args(61) \
328 	FN_##args(62) \
329 	FN_##args(63) \
330 	FN_##args(64) \
331 	FN_##args(65) \
332 	FN_##args(66) \
333 	FN_##args(67) \
334 	FN_##args(68) \
335 	FN_##args(69) \
336 	FN_##args(70) \
337 	FN_##args(71) \
338 	FN_##args(72) \
339 	FN_##args(73) \
340 	FN_##args(74) \
341 	FN_##args(75) \
342 	FN_##args(76) \
343 	FN_##args(77) \
344 	FN_##args(78) \
345 	FN_##args(79) \
346 	FN_##args(80) \
347 	FN_##args(81) \
348 	FN_##args(82) \
349 	FN_##args(83) \
350 	FN_##args(84) \
351 	FN_##args(85) \
352 	FN_##args(86) \
353 	FN_##args(87) \
354 	FN_##args(88) \
355 	FN_##args(89) \
356 	FN_##args(90) \
357 	FN_##args(91) \
358 	FN_##args(92) \
359 	FN_##args(93) \
360 	FN_##args(94) \
361 	FN_##args(95) \
362 	FN_##args(96) \
363 	FN_##args(97) \
364 	FN_##args(98) \
365 	FN_##args(99) \
366 	FN_##args(100) \
367 	FN_##args(101) \
368 	FN_##args(102) \
369 	FN_##args(103) \
370 	FN_##args(104) \
371 	FN_##args(105) \
372 	FN_##args(106) \
373 	FN_##args(107) \
374 	FN_##args(108) \
375 	FN_##args(109) \
376 	FN_##args(110) \
377 	FN_##args(111) \
378 	FN_##args(112) \
379 	FN_##args(113) \
380 	FN_##args(114) \
381 	FN_##args(115) \
382 	FN_##args(116) \
383 	FN_##args(117) \
384 	FN_##args(118) \
385 	FN_##args(119) \
386 	FN_##args(120) \
387 	FN_##args(121) \
388 	FN_##args(122) \
389 	FN_##args(123) \
390 	FN_##args(124) \
391 	FN_##args(125) \
392 	FN_##args(126) \
393 	FN_##args(127) \
394 	FN_##args(128) \
395 	FN_##args(129) \
396 	FN_##args(130) \
397 	FN_##args(131) \
398 	FN_##args(132) \
399 	FN_##args(133) \
400 	FN_##args(134) \
401 	FN_##args(135) \
402 	FN_##args(136) \
403 	FN_##args(137) \
404 	FN_##args(138) \
405 	FN_##args(139) \
406 	FN_##args(140) \
407 	FN_##args(141) \
408 	FN_##args(142) \
409 	FN_##args(143) \
410 	FN_##args(144) \
411 	FN_##args(145) \
412 	FN_##args(146) \
413 	FN_##args(147) \
414 	FN_##args(148) \
415 	FN_##args(149) \
416 	FN_##args(150) \
417 	FN_##args(151) \
418 	FN_##args(152) \
419 	FN_##args(153) \
420 	FN_##args(154) \
421 	FN_##args(155) \
422 	FN_##args(156) \
423 	FN_##args(157) \
424 	FN_##args(158) \
425 	FN_##args(159) \
426 	FN_##args(160) \
427 	FN_##args(161) \
428 	FN_##args(162) \
429 	FN_##args(163) \
430 	FN_##args(164) \
431 	FN_##args(165) \
432 	FN_##args(166) \
433 	FN_##args(167) \
434 	FN_##args(168) \
435 	FN_##args(169) \
436 	FN_##args(170) \
437 	FN_##args(171) \
438 	FN_##args(172) \
439 	FN_##args(173) \
440 	FN_##args(174) \
441 	FN_##args(175) \
442 	FN_##args(176) \
443 	FN_##args(177) \
444 	FN_##args(178) \
445 	FN_##args(179) \
446 	FN_##args(180) \
447 	FN_##args(181) \
448 	FN_##args(182) \
449 	FN_##args(183) \
450 	FN_##args(184) \
451 	FN_##args(185) \
452 	FN_##args(186) \
453 	FN_##args(187) \
454 	FN_##args(188) \
455 	FN_##args(189) \
456 	FN_##args(190) \
457 	FN_##args(191) \
458 	FN_##args(192) \
459 	FN_##args(193) \
460 	FN_##args(194) \
461 	FN_##args(195) \
462 	FN_##args(196) \
463 	FN_##args(197) \
464 	FN_##args(198) \
465 	FN_##args(199) \
466 	FN_##args(200) \
467 	FN_##args(201) \
468 	FN_##args(202) \
469 	FN_##args(203) \
470 	FN_##args(204) \
471 	FN_##args(205) \
472 	FN_##args(206) \
473 	FN_##args(207) \
474 	FN_##args(208) \
475 	FN_##args(209) \
476 	FN_##args(210) \
477 	FN_##args(211) \
478 	FN_##args(212) \
479 	FN_##args(213) \
480 	FN_##args(214) \
481 	FN_##args(215) \
482 	FN_##args(216) \
483 	FN_##args(217) \
484 	FN_##args(218) \
485 	FN_##args(219) \
486 	FN_##args(220) \
487 	FN_##args(221) \
488 	FN_##args(222) \
489 	FN_##args(223) \
490 	FN_##args(224) \
491 	FN_##args(225) \
492 	FN_##args(226) \
493 	FN_##args(227) \
494 	FN_##args(228) \
495 	FN_##args(229) \
496 	FN_##args(230) \
497 	FN_##args(231) \
498 	FN_##args(232) \
499 	FN_##args(233) \
500 	FN_##args(234) \
501 	FN_##args(235) \
502 	FN_##args(236) \
503 	FN_##args(237) \
504 	FN_##args(238) \
505 	FN_##args(239) \
506 	FN_##args(240) \
507 	FN_##args(241) \
508 	FN_##args(242) \
509 	FN_##args(243) \
510 	FN_##args(244) \
511 	FN_##args(245) \
512 	FN_##args(246) \
513 	FN_##args(247) \
514 	FN_##args(248) \
515 	FN_##args(249) \
516 	FN_##args(250) \
517 	FN_##args(251) \
518 	FN_##args(252) \
519 	FN_##args(253) \
520 	FN_##args(254) \
521 	FN_##args(255)
522 #else
523 #error Invalid MAX_CALLBACKS
524 #endif /* MAX_CALLBACKS == 16 */
525 
526 /**
527  * Define all callback functions.
528  *
529  * NOTE: If the maximum number of arguments changes (MAX_ARGS), the following
530  *       has to change accordinglly.
531  */
532 FN_BLOCK(0)
533 FN_BLOCK(1)
534 FN_BLOCK(2)
535 FN_BLOCK(3)
536 FN_BLOCK(4)
537 FN_BLOCK(5)
538 FN_BLOCK(6)
539 FN_BLOCK(7)
540 FN_BLOCK(8)
541 FN_BLOCK(9)
542 FN_BLOCK(10)
543 FN_BLOCK(11)
544 FN_BLOCK(12)
545 
546 /**
547  * Initialize the function pointers for the callback routines.
548  *
549  * NOTE: If MAX_ARGS or MAX_CALLBACKS changes, the following has to be updated.
550  */
551 #if MAX_CALLBACKS == 16
552 #define FN_A_BLOCK(args) { \
553 	(jlong)FN(0, args), \
554 	(jlong)FN(1, args), \
555 	(jlong)FN(2, args), \
556 	(jlong)FN(3, args), \
557 	(jlong)FN(4, args), \
558 	(jlong)FN(5, args), \
559 	(jlong)FN(6, args), \
560 	(jlong)FN(7, args), \
561 	(jlong)FN(8, args), \
562 	(jlong)FN(9, args), \
563 	(jlong)FN(10, args), \
564 	(jlong)FN(11, args), \
565 	(jlong)FN(12, args), \
566 	(jlong)FN(13, args), \
567 	(jlong)FN(14, args), \
568 	(jlong)FN(15, args), \
569 },
570 #elif MAX_CALLBACKS == 128
571 #define FN_A_BLOCK(args) { \
572 	(jlong)FN(0, args), \
573 	(jlong)FN(1, args), \
574 	(jlong)FN(2, args), \
575 	(jlong)FN(3, args), \
576 	(jlong)FN(4, args), \
577 	(jlong)FN(5, args), \
578 	(jlong)FN(6, args), \
579 	(jlong)FN(7, args), \
580 	(jlong)FN(8, args), \
581 	(jlong)FN(9, args), \
582 	(jlong)FN(10, args), \
583 	(jlong)FN(11, args), \
584 	(jlong)FN(12, args), \
585 	(jlong)FN(13, args), \
586 	(jlong)FN(14, args), \
587 	(jlong)FN(15, args), \
588 	(jlong)FN(16, args), \
589 	(jlong)FN(17, args), \
590 	(jlong)FN(18, args), \
591 	(jlong)FN(19, args), \
592 	(jlong)FN(20, args), \
593 	(jlong)FN(21, args), \
594 	(jlong)FN(22, args), \
595 	(jlong)FN(23, args), \
596 	(jlong)FN(24, args), \
597 	(jlong)FN(25, args), \
598 	(jlong)FN(26, args), \
599 	(jlong)FN(27, args), \
600 	(jlong)FN(28, args), \
601 	(jlong)FN(29, args), \
602 	(jlong)FN(30, args), \
603 	(jlong)FN(31, args), \
604 	(jlong)FN(32, args), \
605 	(jlong)FN(33, args), \
606 	(jlong)FN(34, args), \
607 	(jlong)FN(35, args), \
608 	(jlong)FN(36, args), \
609 	(jlong)FN(37, args), \
610 	(jlong)FN(38, args), \
611 	(jlong)FN(39, args), \
612 	(jlong)FN(40, args), \
613 	(jlong)FN(41, args), \
614 	(jlong)FN(42, args), \
615 	(jlong)FN(43, args), \
616 	(jlong)FN(44, args), \
617 	(jlong)FN(45, args), \
618 	(jlong)FN(46, args), \
619 	(jlong)FN(47, args), \
620 	(jlong)FN(48, args), \
621 	(jlong)FN(49, args), \
622 	(jlong)FN(50, args), \
623 	(jlong)FN(51, args), \
624 	(jlong)FN(52, args), \
625 	(jlong)FN(53, args), \
626 	(jlong)FN(54, args), \
627 	(jlong)FN(55, args), \
628 	(jlong)FN(56, args), \
629 	(jlong)FN(57, args), \
630 	(jlong)FN(58, args), \
631 	(jlong)FN(59, args), \
632 	(jlong)FN(60, args), \
633 	(jlong)FN(61, args), \
634 	(jlong)FN(62, args), \
635 	(jlong)FN(63, args), \
636 	(jlong)FN(64, args), \
637 	(jlong)FN(65, args), \
638 	(jlong)FN(66, args), \
639 	(jlong)FN(67, args), \
640 	(jlong)FN(68, args), \
641 	(jlong)FN(69, args), \
642 	(jlong)FN(70, args), \
643 	(jlong)FN(71, args), \
644 	(jlong)FN(72, args), \
645 	(jlong)FN(73, args), \
646 	(jlong)FN(74, args), \
647 	(jlong)FN(75, args), \
648 	(jlong)FN(76, args), \
649 	(jlong)FN(77, args), \
650 	(jlong)FN(78, args), \
651 	(jlong)FN(79, args), \
652 	(jlong)FN(80, args), \
653 	(jlong)FN(81, args), \
654 	(jlong)FN(82, args), \
655 	(jlong)FN(83, args), \
656 	(jlong)FN(84, args), \
657 	(jlong)FN(85, args), \
658 	(jlong)FN(86, args), \
659 	(jlong)FN(87, args), \
660 	(jlong)FN(88, args), \
661 	(jlong)FN(89, args), \
662 	(jlong)FN(90, args), \
663 	(jlong)FN(91, args), \
664 	(jlong)FN(92, args), \
665 	(jlong)FN(93, args), \
666 	(jlong)FN(94, args), \
667 	(jlong)FN(95, args), \
668 	(jlong)FN(96, args), \
669 	(jlong)FN(97, args), \
670 	(jlong)FN(98, args), \
671 	(jlong)FN(99, args), \
672 	(jlong)FN(100, args), \
673 	(jlong)FN(101, args), \
674 	(jlong)FN(102, args), \
675 	(jlong)FN(103, args), \
676 	(jlong)FN(104, args), \
677 	(jlong)FN(105, args), \
678 	(jlong)FN(106, args), \
679 	(jlong)FN(107, args), \
680 	(jlong)FN(108, args), \
681 	(jlong)FN(109, args), \
682 	(jlong)FN(110, args), \
683 	(jlong)FN(111, args), \
684 	(jlong)FN(112, args), \
685 	(jlong)FN(113, args), \
686 	(jlong)FN(114, args), \
687 	(jlong)FN(115, args), \
688 	(jlong)FN(116, args), \
689 	(jlong)FN(117, args), \
690 	(jlong)FN(118, args), \
691 	(jlong)FN(119, args), \
692 	(jlong)FN(120, args), \
693 	(jlong)FN(121, args), \
694 	(jlong)FN(122, args), \
695 	(jlong)FN(123, args), \
696 	(jlong)FN(124, args), \
697 	(jlong)FN(125, args), \
698 	(jlong)FN(126, args), \
699 	(jlong)FN(127, args), \
700 },
701 #elif MAX_CALLBACKS == 256
702 #define FN_A_BLOCK(args) { \
703 	(jlong)FN(0, args), \
704 	(jlong)FN(1, args), \
705 	(jlong)FN(2, args), \
706 	(jlong)FN(3, args), \
707 	(jlong)FN(4, args), \
708 	(jlong)FN(5, args), \
709 	(jlong)FN(6, args), \
710 	(jlong)FN(7, args), \
711 	(jlong)FN(8, args), \
712 	(jlong)FN(9, args), \
713 	(jlong)FN(10, args), \
714 	(jlong)FN(11, args), \
715 	(jlong)FN(12, args), \
716 	(jlong)FN(13, args), \
717 	(jlong)FN(14, args), \
718 	(jlong)FN(15, args), \
719 	(jlong)FN(16, args), \
720 	(jlong)FN(17, args), \
721 	(jlong)FN(18, args), \
722 	(jlong)FN(19, args), \
723 	(jlong)FN(20, args), \
724 	(jlong)FN(21, args), \
725 	(jlong)FN(22, args), \
726 	(jlong)FN(23, args), \
727 	(jlong)FN(24, args), \
728 	(jlong)FN(25, args), \
729 	(jlong)FN(26, args), \
730 	(jlong)FN(27, args), \
731 	(jlong)FN(28, args), \
732 	(jlong)FN(29, args), \
733 	(jlong)FN(30, args), \
734 	(jlong)FN(31, args), \
735 	(jlong)FN(32, args), \
736 	(jlong)FN(33, args), \
737 	(jlong)FN(34, args), \
738 	(jlong)FN(35, args), \
739 	(jlong)FN(36, args), \
740 	(jlong)FN(37, args), \
741 	(jlong)FN(38, args), \
742 	(jlong)FN(39, args), \
743 	(jlong)FN(40, args), \
744 	(jlong)FN(41, args), \
745 	(jlong)FN(42, args), \
746 	(jlong)FN(43, args), \
747 	(jlong)FN(44, args), \
748 	(jlong)FN(45, args), \
749 	(jlong)FN(46, args), \
750 	(jlong)FN(47, args), \
751 	(jlong)FN(48, args), \
752 	(jlong)FN(49, args), \
753 	(jlong)FN(50, args), \
754 	(jlong)FN(51, args), \
755 	(jlong)FN(52, args), \
756 	(jlong)FN(53, args), \
757 	(jlong)FN(54, args), \
758 	(jlong)FN(55, args), \
759 	(jlong)FN(56, args), \
760 	(jlong)FN(57, args), \
761 	(jlong)FN(58, args), \
762 	(jlong)FN(59, args), \
763 	(jlong)FN(60, args), \
764 	(jlong)FN(61, args), \
765 	(jlong)FN(62, args), \
766 	(jlong)FN(63, args), \
767 	(jlong)FN(64, args), \
768 	(jlong)FN(65, args), \
769 	(jlong)FN(66, args), \
770 	(jlong)FN(67, args), \
771 	(jlong)FN(68, args), \
772 	(jlong)FN(69, args), \
773 	(jlong)FN(70, args), \
774 	(jlong)FN(71, args), \
775 	(jlong)FN(72, args), \
776 	(jlong)FN(73, args), \
777 	(jlong)FN(74, args), \
778 	(jlong)FN(75, args), \
779 	(jlong)FN(76, args), \
780 	(jlong)FN(77, args), \
781 	(jlong)FN(78, args), \
782 	(jlong)FN(79, args), \
783 	(jlong)FN(80, args), \
784 	(jlong)FN(81, args), \
785 	(jlong)FN(82, args), \
786 	(jlong)FN(83, args), \
787 	(jlong)FN(84, args), \
788 	(jlong)FN(85, args), \
789 	(jlong)FN(86, args), \
790 	(jlong)FN(87, args), \
791 	(jlong)FN(88, args), \
792 	(jlong)FN(89, args), \
793 	(jlong)FN(90, args), \
794 	(jlong)FN(91, args), \
795 	(jlong)FN(92, args), \
796 	(jlong)FN(93, args), \
797 	(jlong)FN(94, args), \
798 	(jlong)FN(95, args), \
799 	(jlong)FN(96, args), \
800 	(jlong)FN(97, args), \
801 	(jlong)FN(98, args), \
802 	(jlong)FN(99, args), \
803 	(jlong)FN(100, args), \
804 	(jlong)FN(101, args), \
805 	(jlong)FN(102, args), \
806 	(jlong)FN(103, args), \
807 	(jlong)FN(104, args), \
808 	(jlong)FN(105, args), \
809 	(jlong)FN(106, args), \
810 	(jlong)FN(107, args), \
811 	(jlong)FN(108, args), \
812 	(jlong)FN(109, args), \
813 	(jlong)FN(110, args), \
814 	(jlong)FN(111, args), \
815 	(jlong)FN(112, args), \
816 	(jlong)FN(113, args), \
817 	(jlong)FN(114, args), \
818 	(jlong)FN(115, args), \
819 	(jlong)FN(116, args), \
820 	(jlong)FN(117, args), \
821 	(jlong)FN(118, args), \
822 	(jlong)FN(119, args), \
823 	(jlong)FN(120, args), \
824 	(jlong)FN(121, args), \
825 	(jlong)FN(122, args), \
826 	(jlong)FN(123, args), \
827 	(jlong)FN(124, args), \
828 	(jlong)FN(125, args), \
829 	(jlong)FN(126, args), \
830 	(jlong)FN(127, args), \
831 	(jlong)FN(128, args), \
832 	(jlong)FN(129, args), \
833 	(jlong)FN(130, args), \
834 	(jlong)FN(131, args), \
835 	(jlong)FN(132, args), \
836 	(jlong)FN(133, args), \
837 	(jlong)FN(134, args), \
838 	(jlong)FN(135, args), \
839 	(jlong)FN(136, args), \
840 	(jlong)FN(137, args), \
841 	(jlong)FN(138, args), \
842 	(jlong)FN(139, args), \
843 	(jlong)FN(140, args), \
844 	(jlong)FN(141, args), \
845 	(jlong)FN(142, args), \
846 	(jlong)FN(143, args), \
847 	(jlong)FN(144, args), \
848 	(jlong)FN(145, args), \
849 	(jlong)FN(146, args), \
850 	(jlong)FN(147, args), \
851 	(jlong)FN(148, args), \
852 	(jlong)FN(149, args), \
853 	(jlong)FN(150, args), \
854 	(jlong)FN(151, args), \
855 	(jlong)FN(152, args), \
856 	(jlong)FN(153, args), \
857 	(jlong)FN(154, args), \
858 	(jlong)FN(155, args), \
859 	(jlong)FN(156, args), \
860 	(jlong)FN(157, args), \
861 	(jlong)FN(158, args), \
862 	(jlong)FN(159, args), \
863 	(jlong)FN(160, args), \
864 	(jlong)FN(161, args), \
865 	(jlong)FN(162, args), \
866 	(jlong)FN(163, args), \
867 	(jlong)FN(164, args), \
868 	(jlong)FN(165, args), \
869 	(jlong)FN(166, args), \
870 	(jlong)FN(167, args), \
871 	(jlong)FN(168, args), \
872 	(jlong)FN(169, args), \
873 	(jlong)FN(170, args), \
874 	(jlong)FN(171, args), \
875 	(jlong)FN(172, args), \
876 	(jlong)FN(173, args), \
877 	(jlong)FN(174, args), \
878 	(jlong)FN(175, args), \
879 	(jlong)FN(176, args), \
880 	(jlong)FN(177, args), \
881 	(jlong)FN(178, args), \
882 	(jlong)FN(179, args), \
883 	(jlong)FN(180, args), \
884 	(jlong)FN(181, args), \
885 	(jlong)FN(182, args), \
886 	(jlong)FN(183, args), \
887 	(jlong)FN(184, args), \
888 	(jlong)FN(185, args), \
889 	(jlong)FN(186, args), \
890 	(jlong)FN(187, args), \
891 	(jlong)FN(188, args), \
892 	(jlong)FN(189, args), \
893 	(jlong)FN(190, args), \
894 	(jlong)FN(191, args), \
895 	(jlong)FN(192, args), \
896 	(jlong)FN(193, args), \
897 	(jlong)FN(194, args), \
898 	(jlong)FN(195, args), \
899 	(jlong)FN(196, args), \
900 	(jlong)FN(197, args), \
901 	(jlong)FN(198, args), \
902 	(jlong)FN(199, args), \
903 	(jlong)FN(200, args), \
904 	(jlong)FN(201, args), \
905 	(jlong)FN(202, args), \
906 	(jlong)FN(203, args), \
907 	(jlong)FN(204, args), \
908 	(jlong)FN(205, args), \
909 	(jlong)FN(206, args), \
910 	(jlong)FN(207, args), \
911 	(jlong)FN(208, args), \
912 	(jlong)FN(209, args), \
913 	(jlong)FN(210, args), \
914 	(jlong)FN(211, args), \
915 	(jlong)FN(212, args), \
916 	(jlong)FN(213, args), \
917 	(jlong)FN(214, args), \
918 	(jlong)FN(215, args), \
919 	(jlong)FN(216, args), \
920 	(jlong)FN(217, args), \
921 	(jlong)FN(218, args), \
922 	(jlong)FN(219, args), \
923 	(jlong)FN(220, args), \
924 	(jlong)FN(221, args), \
925 	(jlong)FN(222, args), \
926 	(jlong)FN(223, args), \
927 	(jlong)FN(224, args), \
928 	(jlong)FN(225, args), \
929 	(jlong)FN(226, args), \
930 	(jlong)FN(227, args), \
931 	(jlong)FN(228, args), \
932 	(jlong)FN(229, args), \
933 	(jlong)FN(230, args), \
934 	(jlong)FN(231, args), \
935 	(jlong)FN(232, args), \
936 	(jlong)FN(233, args), \
937 	(jlong)FN(234, args), \
938 	(jlong)FN(235, args), \
939 	(jlong)FN(236, args), \
940 	(jlong)FN(237, args), \
941 	(jlong)FN(238, args), \
942 	(jlong)FN(239, args), \
943 	(jlong)FN(240, args), \
944 	(jlong)FN(241, args), \
945 	(jlong)FN(242, args), \
946 	(jlong)FN(243, args), \
947 	(jlong)FN(244, args), \
948 	(jlong)FN(245, args), \
949 	(jlong)FN(246, args), \
950 	(jlong)FN(247, args), \
951 	(jlong)FN(248, args), \
952 	(jlong)FN(249, args), \
953 	(jlong)FN(250, args), \
954 	(jlong)FN(251, args), \
955 	(jlong)FN(252, args), \
956 	(jlong)FN(253, args), \
957 	(jlong)FN(254, args), \
958 	(jlong)FN(255, args), \
959 },
960 #else
961 #error Invalid MAX_CALLBACKS
962 #endif /* MAX_CALLBACKS == 16 */
963 
964 jlong fnx_array[MAX_ARGS+1][MAX_CALLBACKS] = {
965 	FN_A_BLOCK(0)
966 	FN_A_BLOCK(1)
967 	FN_A_BLOCK(2)
968 	FN_A_BLOCK(3)
969 	FN_A_BLOCK(4)
970 	FN_A_BLOCK(5)
971 	FN_A_BLOCK(6)
972 	FN_A_BLOCK(7)
973 	FN_A_BLOCK(8)
974 	FN_A_BLOCK(9)
975 	FN_A_BLOCK(10)
976 	FN_A_BLOCK(11)
977 	FN_A_BLOCK(12)
978 };
979 
980 /* --------------- callback class calls --------------- */
981 
CALLBACK_NATIVE(bind)982 JNIEXPORT jlong JNICALL CALLBACK_NATIVE(bind)
983   (JNIEnv *env, jclass that, jobject callbackObject, jobject object, jstring method, jstring signature, jint argCount, jboolean isStatic, jboolean isArrayBased, jlong errorResult)
984 {
985 	int i;
986 	jmethodID mid = NULL;
987 	jclass javaClass = that;
988 	const char *methodString = NULL, *sigString = NULL;
989 	jlong result = 0;
990 	if (JNI_VERSION == 0) JNI_VERSION = (*env)->GetVersion(env);
991 	if (!initialized) {
992 		memset(&callbackData, 0, sizeof(callbackData));
993 		initialized = 1;
994 	}
995 	if (method) methodString = (const char *) (*env)->GetStringUTFChars(env, method, NULL);
996 	if (signature) sigString = (const char *) (*env)->GetStringUTFChars(env, signature, NULL);
997 	if (object && methodString && sigString) {
998 		if (isStatic) {
999 			mid = (*env)->GetStaticMethodID(env, object, methodString, sigString);
1000 		} else {
1001 			javaClass = (*env)->GetObjectClass(env, object);
1002 			mid = (*env)->GetMethodID(env, javaClass, methodString, sigString);
1003 		}
1004 	}
1005 	if (mid == 0) goto fail;
1006 	for (i=0; i<MAX_CALLBACKS; i++) {
1007 		if (!callbackData[i].callback) {
1008 			if ((callbackData[i].callback = (*env)->NewGlobalRef(env, callbackObject)) == NULL) goto fail;
1009 			if ((callbackData[i].object = (*env)->NewGlobalRef(env, object)) == NULL) goto fail;
1010 			callbackData[i].isStatic = isStatic;
1011 			callbackData[i].isArrayBased = isArrayBased;
1012 			callbackData[i].argCount = argCount;
1013 			callbackData[i].errorResult = errorResult;
1014 			callbackData[i].methodID = mid;
1015 
1016 			#ifdef DEBUG_CALL_PRINTS
1017 				#if   defined(COCOA)
1018 					callbackData[i].arg_Selector = -1;
1019 
1020 					if (!strcmp(methodString, "applicationProc") ||
1021 						!strcmp(methodString, "dragSourceProc") ||
1022 						!strcmp(methodString, "windowProc") ||
1023 						!strcmp(methodString, "dialogProc"))
1024 					{
1025 						callbackData[i].arg_Selector = 1;
1026 					}
1027 				#elif defined(GTK)
1028 					callbackData[i].arg_GObject = -1;
1029 					callbackData[i].arg_GdkEvent = -1;
1030 					callbackData[i].arg_SwtSignalID = -1;
1031 
1032 					if (!strcmp(methodString, "windowProc")) {
1033 						callbackData[i].arg_GObject = 0;
1034 						callbackData[i].arg_SwtSignalID = argCount - 1;
1035 					}
1036 
1037 					if (!strcmp(methodString, "eventProc")) {
1038 						callbackData[i].arg_GdkEvent = 0;
1039 					}
1040 				#endif
1041 
1042 				fprintf(stderr, "SWT-JNI: Registered callback[%02d] = %s%s\n", i, methodString, sigString);
1043 				fflush(stderr);
1044 			#endif
1045 
1046 			result = (jlong) fnx_array[argCount][i];
1047 			break;
1048 		}
1049 	}
1050 
1051 fail:
1052 	if (method && methodString) (*env)->ReleaseStringUTFChars(env, method, methodString);
1053 	if (signature && sigString) (*env)->ReleaseStringUTFChars(env, signature, sigString);
1054 	return result;
1055 }
1056 
CALLBACK_NATIVE(unbind)1057 JNIEXPORT void JNICALL CALLBACK_NATIVE(unbind)
1058   (JNIEnv *env, jclass that, jobject callback)
1059 {
1060 	int i;
1061 	for (i=0; i<MAX_CALLBACKS; i++) {
1062 		if (callbackData[i].callback != NULL && (*env)->IsSameObject(env, callback, callbackData[i].callback)) {
1063 			if (callbackData[i].callback != NULL) (*env)->DeleteGlobalRef(env, callbackData[i].callback);
1064 			if (callbackData[i].object != NULL) (*env)->DeleteGlobalRef(env, callbackData[i].object);
1065 			memset(&callbackData[i], 0, sizeof(CALLBACK_DATA));
1066 		}
1067 	}
1068 }
1069 
CALLBACK_NATIVE(getEnabled)1070 JNIEXPORT jboolean JNICALL CALLBACK_NATIVE(getEnabled)
1071   (JNIEnv *env, jclass that)
1072 {
1073 	return (jboolean)callbackEnabled;
1074 }
1075 
CALLBACK_NATIVE(getEntryCount)1076 JNIEXPORT jint JNICALL CALLBACK_NATIVE(getEntryCount)
1077   (JNIEnv *env, jclass that)
1078 {
1079 	return (jint)callbackEntryCount;
1080 }
1081 
CALLBACK_NATIVE(setEnabled)1082 JNIEXPORT void JNICALL CALLBACK_NATIVE(setEnabled)
1083   (JNIEnv *env, jclass that, jboolean enable)
1084 {
1085 	callbackEnabled = enable;
1086 }
1087 
CALLBACK_NATIVE(reset)1088 JNIEXPORT void JNICALL CALLBACK_NATIVE(reset)
1089   (JNIEnv *env, jclass that)
1090 {
1091 	memset((void *)&callbackData, 0, sizeof(callbackData));
1092 }
1093 
1094 #if (defined(DEBUG_CALL_PRINTS) && defined(GTK))
glibTypeNameFromInstance(void * object)1095 const char* glibTypeNameFromInstance(void* object) {
1096 	static int isInitialized = 0;
1097 	static const char* (*g_type_name_from_instance)(void*) = 0;
1098 
1099 	if (!isInitialized) {
1100 		/* Do not dlclose(gobjectHandle); we're going to continue using the library */
1101 		void* gobjectHandle = dlopen("libgobject-2.0.so.0", RTLD_LAZY);
1102 
1103 		if (gobjectHandle)
1104 			g_type_name_from_instance = dlsym(gobjectHandle, "g_type_name_from_instance");
1105 
1106 		isInitialized = 1;
1107 	}
1108 
1109 	if (!g_type_name_from_instance)
1110 		return "<No glib>";
1111 
1112 	return g_type_name_from_instance(object);
1113 }
1114 
swtSignalNameFromId(int id)1115 const char* swtSignalNameFromId(int id) {
1116 	/* Adapted from constants in org.eclipse.swt.widgets.Widget */
1117 	switch (id) {
1118 		case 1:   return "ACTIVATE";
1119 		case 2:   return "BUTTON_PRESS_EVENT";
1120 		case 3:   return "BUTTON_PRESS_EVENT_INVERSE";
1121 		case 4:   return "BUTTON_RELEASE_EVENT";
1122 		case 5:   return "BUTTON_RELEASE_EVENT_INVERSE";
1123 		case 6:   return "CHANGED";
1124 		case 7:   return "CHANGE_VALUE";
1125 		case 8:   return "CLICKED";
1126 		case 9:   return "COMMIT";
1127 		case 10:  return "CONFIGURE_EVENT";
1128 		case 11:  return "DELETE_EVENT";
1129 		case 12:  return "DELETE_RANGE";
1130 		case 13:  return "DELETE_TEXT";
1131 		case 14:  return "ENTER_NOTIFY_EVENT";
1132 		case 15:  return "EVENT";
1133 		case 16:  return "EVENT_AFTER";
1134 		case 17:  return "EXPAND_COLLAPSE_CURSOR_ROW";
1135 		case 18:  return "EXPOSE_EVENT";
1136 		case 19:  return "EXPOSE_EVENT_INVERSE";
1137 		case 20:  return "FOCUS";
1138 		case 21:  return "FOCUS_IN_EVENT";
1139 		case 22:  return "FOCUS_OUT_EVENT";
1140 		case 23:  return "GRAB_FOCUS";
1141 		case 24:  return "HIDE";
1142 		case 25:  return "INPUT";
1143 		case 26:  return "INSERT_TEXT";
1144 		case 27:  return "KEY_PRESS_EVENT";
1145 		case 28:  return "KEY_RELEASE_EVENT";
1146 		case 29:  return "LEAVE_NOTIFY_EVENT";
1147 		case 30:  return "MAP";
1148 		case 31:  return "MAP_EVENT";
1149 		case 32:  return "MNEMONIC_ACTIVATE";
1150 		case 33:  return "MOTION_NOTIFY_EVENT";
1151 		case 34:  return "MOTION_NOTIFY_EVENT_INVERSE";
1152 		case 35:  return "MOVE_FOCUS";
1153 		case 36:  return "OUTPUT";
1154 		case 37:  return "POPULATE_POPUP";
1155 		case 38:  return "POPUP_MENU";
1156 		case 39:  return "PREEDIT_CHANGED";
1157 		case 40:  return "REALIZE";
1158 		case 41:  return "ROW_ACTIVATED";
1159 		case 42:  return "SCROLL_CHILD";
1160 		case 43:  return "SCROLL_EVENT";
1161 		case 44:  return "SELECT";
1162 		case 45:  return "SHOW";
1163 		case 46:  return "SHOW_HELP";
1164 		case 47:  return "SIZE_ALLOCATE";
1165 		case 48:  return "STYLE_UPDATED";
1166 		case 49:  return "SWITCH_PAGE";
1167 		case 50:  return "TEST_COLLAPSE_ROW";
1168 		case 51:  return "TEST_EXPAND_ROW";
1169 		case 52:  return "TEXT_BUFFER_INSERT_TEXT";
1170 		case 53:  return "TOGGLED";
1171 		case 54:  return "UNMAP";
1172 		case 55:  return "UNMAP_EVENT";
1173 		case 56:  return "UNREALIZE";
1174 		case 57:  return "VALUE_CHANGED";
1175 		case 59:  return "WINDOW_STATE_EVENT";
1176 		case 60:  return "ACTIVATE_INVERSE";
1177 		case 61:  return "DAY_SELECTED";
1178 		case 62:  return "MONTH_CHANGED";
1179 		case 63:  return "STATUS_ICON_POPUP_MENU";
1180 		case 64:  return "ROW_INSERTED";
1181 		case 65:  return "ROW_DELETED";
1182 		case 66:  return "DAY_SELECTED_DOUBLE_CLICK";
1183 		case 67:  return "ICON_RELEASE";
1184 		case 68:  return "SELECTION_DONE";
1185 		case 69:  return "START_INTERACTIVE_SEARCH";
1186 		case 70:  return "BACKSPACE";
1187 		case 71:  return "BACKSPACE_INVERSE";
1188 		case 72:  return "COPY_CLIPBOARD";
1189 		case 73:  return "COPY_CLIPBOARD_INVERSE";
1190 		case 74:  return "CUT_CLIPBOARD";
1191 		case 75:  return "CUT_CLIPBOARD_INVERSE";
1192 		case 76:  return "PASTE_CLIPBOARD";
1193 		case 77:  return "PASTE_CLIPBOARD_INVERSE";
1194 		case 78:  return "DELETE_FROM_CURSOR";
1195 		case 79:  return "DELETE_FROM_CURSOR_INVERSE";
1196 		case 80:  return "MOVE_CURSOR";
1197 		case 81:  return "MOVE_CURSOR_INVERSE";
1198 		case 82:  return "DIRECTION_CHANGED";
1199 		case 83:  return "CREATE_MENU_PROXY";
1200 		case 84:  return "ROW_HAS_CHILD_TOGGLED";
1201 		case 85:  return "POPPED_UP";
1202 		case 86:  return "FOCUS_IN";
1203 		case 87:  return "FOCUS_OUT";
1204 		case 88:  return "IM_UPDATE";
1205 		case 89:  return "KEY_PRESSED";
1206 		case 90:  return "KEY_RELEASED";
1207 		case 91:  return "DECELERATE";
1208 		case 92:  return "SCROLL";
1209 		case 93:  return "SCROLL_BEGIN";
1210 		case 94:  return "SCROLL_END";
1211 		case 95:  return "ENTER";
1212 		case 96:  return "LEAVE";
1213 		case 97:  return "MOTION";
1214 		case 98:  return "MOTION_INVERSE";
1215 		case 99:  return "CLOSE_REQUEST";
1216 		case 100: return "GESTURE_PRESSED";
1217 		case 101: return "GESTURE_RELEASED";
1218 		case 102: return "NOTIFY_STATE";
1219 		case 103: return "SIZE_ALLOCATE_GTK4";
1220 		case 104: return "DPI_CHANGED";
1221 	}
1222 
1223 	return 0;
1224 }
1225 #endif
1226 
callback(int index,...)1227 jlong callback(int index, ...)
1228 {
1229 	if (!callbackEnabled) return 0;
1230 
1231 	{
1232 	JNIEnv *env = NULL;
1233 	jmethodID mid = callbackData[index].methodID;
1234 	jobject object = callbackData[index].object;
1235 	jboolean isStatic = callbackData[index].isStatic;
1236 	jboolean isArrayBased = callbackData[index].isArrayBased;
1237 	jint argCount = callbackData[index].argCount;
1238 	jlong result = callbackData[index].errorResult;
1239 	jthrowable ex;
1240 	int detach = 0;
1241 	va_list vl;
1242 
1243 	va_start(vl, index);
1244 
1245 #ifdef DEBUG_CALL_PRINTS
1246 	{
1247 		va_list vaCopy;
1248 		va_copy(vaCopy, vl);
1249 
1250 		counter++;
1251 		fprintf(stderr, "SWT-JNI:%*scallback[%d](", counter, "", index);
1252 		for (int i=0; i<argCount; i++) {
1253 			void* arg = va_arg(vaCopy, void*);
1254 			int isPrinted = 0;
1255 
1256 			#ifdef COCOA
1257 				if (!isPrinted && (i == callbackData[index].arg_Selector)) {
1258 					fprintf(stderr, "%s ", sel_getName(arg));
1259 					isPrinted = 1;
1260 				}
1261 			#elif defined(GTK)
1262 				if (!isPrinted && (i == callbackData[index].arg_GObject)) {
1263 					fprintf(stderr, "%p [%s] ", arg, glibTypeNameFromInstance(arg));
1264 					isPrinted = 1;
1265 				}
1266 
1267 				if (!isPrinted && (i == callbackData[index].arg_GdkEvent)) {
1268 					const GdkEventAny* event = (const GdkEventAny*)arg;
1269 					fprintf(stderr,
1270 						"%p [GdkEvent type=%d window=%p [%s]] ",
1271 						event,
1272 						event->type,
1273 						event->window,
1274 						glibTypeNameFromInstance(event->window)
1275 					);
1276 
1277 					isPrinted = 1;
1278 				}
1279 
1280 				if (!isPrinted && (i == callbackData[index].arg_SwtSignalID)) {
1281 					int signalID = (int)(long long)arg;
1282 					const char* signalName = swtSignalNameFromId(signalID);
1283 					if (signalName)
1284 						fprintf(stderr, "%s ", signalName);
1285 					else
1286 						fprintf(stderr, "%d ", signalID);
1287 					isPrinted = 1;
1288 				}
1289 			#endif
1290 
1291 			if (!isPrinted)
1292 				fprintf(stderr, "%p ", arg);
1293 		}
1294 		fprintf(stderr, ") {\n");
1295 
1296 		fflush(stderr);
1297 		va_end(vaCopy);
1298 	}
1299 #endif
1300 
1301 #ifdef JNI_VERSION_1_2
1302 	if (IS_JNI_1_2) {
1303 		(*JVM)->GetEnv(JVM, (void **)&env, JNI_VERSION_1_2);
1304 	}
1305 #endif
1306 
1307 #ifdef JNI_VERSION_1_4
1308 	if (env == NULL) {
1309 		if (JNI_VERSION >= JNI_VERSION_1_4) {
1310 			(*JVM)->AttachCurrentThreadAsDaemon(JVM, (void **)&env, NULL);
1311 		}
1312 	}
1313 #endif
1314 
1315 	if (env == NULL) {
1316 		(*JVM)->AttachCurrentThread(JVM, (void **)&env, NULL);
1317 		if (IS_JNI_1_2) detach = 1;
1318 	}
1319 
1320 	/* If the current thread is not attached to the VM, it is not possible to call into the VM */
1321 	if (env == NULL) {
1322 #ifdef DEBUG_CALL_PRINTS
1323 		fprintf(stderr, "SWT-JNI:%*s ERROR(%d): (env == NULL)\n", counter, "", __LINE__);
1324 		fflush(stderr);
1325 #endif
1326 		goto noEnv;
1327 	}
1328 
1329 	/* If an exception has occurred in previous callbacks do not call into the VM. */
1330 	if ((ex = (*env)->ExceptionOccurred(env))) {
1331 #ifdef DEBUG_CALL_PRINTS
1332 		fprintf(stderr, "SWT-JNI:%*s ERROR(%d): (*env)->ExceptionOccurred()\n", counter, "", __LINE__);
1333 		fflush(stderr);
1334 #endif
1335 		(*env)->DeleteLocalRef(env, ex);
1336 		goto done;
1337 	}
1338 
1339 	/* Call into the VM. */
1340 	ATOMIC_INC(callbackEntryCount);
1341 
1342 	if (isArrayBased) {
1343 		int i;
1344 		jlongArray argsArray = (*env)->NewLongArray(env, argCount);
1345 		if (argsArray != NULL) {
1346 			jlong *elements = (*env)->GetLongArrayElements(env, argsArray, NULL);
1347 			if (elements != NULL) {
1348 				for (i=0; i<argCount; i++) {
1349 					elements[i] = va_arg(vl, jlong);
1350 				}
1351 				(*env)->ReleaseLongArrayElements(env, argsArray, elements, 0);
1352 				if (isStatic) {
1353 					result = (*env)->CallStaticLongMethod(env, object, mid, argsArray);
1354 				} else {
1355 					result = (*env)->CallLongMethod(env, object, mid, argsArray);
1356 				}
1357 			}
1358 			/*
1359 			* This function may be called many times before returning to Java,
1360 			* explicitly delete local references to avoid GP's in certain VMs.
1361 			*/
1362 			(*env)->DeleteLocalRef(env, argsArray);
1363 		}
1364 	} else {
1365 		if (isStatic) {
1366 			result = (*env)->CallStaticLongMethodV(env, object, mid, vl);
1367 		} else {
1368 			result = (*env)->CallLongMethodV(env, object, mid, vl);
1369 		}
1370 	}
1371 	ATOMIC_DEC(callbackEntryCount);
1372 
1373 done:
1374 	va_end(vl);
1375 
1376 	/* If an exception has occurred in Java, return the error result. */
1377 	if ((ex = (*env)->ExceptionOccurred(env))) {
1378 		(*env)->DeleteLocalRef(env, ex);
1379 #ifdef DEBUG_CALL_PRINTS
1380 		fprintf(stderr, "SWT-JNI:%*s ERROR(%d): (*env)->ExceptionOccurred()\n", counter, "", __LINE__);
1381 		fflush(stderr);
1382 
1383 		/*
1384 		 * WARNING: ExceptionDescribe() also clears exception as if it never happened.
1385 		 * Don't do this because it changes the behavior of debugged program significantly.
1386 		 * (*env)->ExceptionDescribe(env);
1387 		 */
1388 #endif
1389 		result = callbackData[index].errorResult;
1390 	}
1391 
1392 	if (detach) {
1393 		(*JVM)->DetachCurrentThread(JVM);
1394 		env = NULL;
1395 	}
1396 
1397 noEnv:
1398 
1399 #ifdef DEBUG_CALL_PRINTS
1400 	fprintf(stderr, "SWT-JNI:%*s} ret=%p\n", counter, "", (void*)result);
1401 	fflush(stderr);
1402 	counter--;
1403 #endif
1404 
1405 	return result;
1406 	}
1407 }
1408 
1409 /* ------------- callback class calls end --------------- */
1410