opengl 0.7.0-x86-mingw32 → 0.8.0.pre1-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,845 @@
1
+ #include "common.h"
2
+
3
+ /* HACK experimental API */
4
+ void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
5
+
6
+ static ID call_id; /* 'call' method id */
7
+ static VALUE idle_func = Qnil;
8
+ static VALUE joystick_func = Qnil;
9
+ static VALUE menustate_func = Qnil;
10
+ static VALUE menustatus_func = Qnil;
11
+ static VALUE timer_func = Qnil;
12
+
13
+ typedef void *(*gvl_call)(void *);
14
+
15
+ struct callback_args {
16
+ union {
17
+ int button;
18
+ int dial;
19
+ int special;
20
+ int state;
21
+ int value;
22
+ int width;
23
+ int x;
24
+ unsigned char key;
25
+ unsigned int button_mask;
26
+ } arg0;
27
+ union {
28
+ int height;
29
+ int state;
30
+ int value;
31
+ int x;
32
+ int y;
33
+ } arg1;
34
+ union {
35
+ int x;
36
+ int y;
37
+ int z;
38
+ } arg2;
39
+ union {
40
+ int y;
41
+ int z;
42
+ } arg3;
43
+ } ;
44
+
45
+ static struct callback_args *
46
+ alloc_callback_args(void) {
47
+ struct callback_args *args;
48
+ args = (struct callback_args *)malloc(sizeof(struct callback_args));
49
+
50
+ if (args == NULL) {
51
+ fprintf(stderr, "[BUG] out of memory in opengl callback");
52
+ abort();
53
+ }
54
+
55
+ return args;
56
+ }
57
+
58
+ /*
59
+ * macros for registering callbacks -
60
+ *
61
+ * most GLUT callback functions are part of specific window state, so
62
+ * the same callback may have different functions for each GLUT window
63
+ *
64
+ * callbacks that are not tied to specific window (idle,timer,menustate) are
65
+ * registered manually
66
+ */
67
+
68
+ #define WINDOW_CALLBACK_SETUP(_funcname) \
69
+ static VALUE _funcname = Qnil; \
70
+ static VALUE \
71
+ glut_ ## _funcname(VALUE self, VALUE callback) \
72
+ { \
73
+ int win = glutGetWindow(); \
74
+ \
75
+ if (win == 0) { \
76
+ rb_raise(rb_eRuntimeError, "glut%s needs current window", #_funcname); \
77
+ } \
78
+ \
79
+ callback = rb_glut_check_callback(self, callback); \
80
+ \
81
+ rb_ary_store(_funcname, win, callback); \
82
+ \
83
+ if (NIL_P(callback)) \
84
+ glut##_funcname(NULL); \
85
+ else \
86
+ glut##_funcname(&glut_##_funcname##Callback0); \
87
+ \
88
+ return Qnil; \
89
+ }
90
+
91
+ #define WINDOW_CALLBACK_DEFINE(module, _funcname) \
92
+ rb_define_module_function(module, "glut"#_funcname, glut_##_funcname, 1); \
93
+ rb_global_variable(&_funcname); \
94
+ _funcname = rb_ary_new()
95
+
96
+ static void GLUTCALLBACK glut_DisplayFuncCallback0(void);
97
+ static void GLUTCALLBACK glut_ReshapeFuncCallback0(int, int);
98
+ static void GLUTCALLBACK glut_KeyboardFuncCallback0(unsigned char, int, int);
99
+ static void GLUTCALLBACK glut_MouseFuncCallback0(int, int, int, int);
100
+ static void GLUTCALLBACK glut_MotionFuncCallback0(int, int);
101
+ static void GLUTCALLBACK glut_PassiveMotionFuncCallback0(int, int);
102
+ static void GLUTCALLBACK glut_EntryFuncCallback0(int);
103
+ static void GLUTCALLBACK glut_VisibilityFuncCallback0(int);
104
+ static void GLUTCALLBACK glut_SpecialFuncCallback0(int, int, int);
105
+ static void GLUTCALLBACK glut_SpaceballMotionFuncCallback0(int, int, int);
106
+ static void GLUTCALLBACK glut_SpaceballRotateFuncCallback0(int, int, int);
107
+ static void GLUTCALLBACK glut_SpaceballButtonFuncCallback0(int, int);
108
+ static void GLUTCALLBACK glut_ButtonBoxFuncCallback0(int, int);
109
+ static void GLUTCALLBACK glut_DialsFuncCallback0(int, int);
110
+ static void GLUTCALLBACK glut_TabletMotionFuncCallback0(int, int);
111
+ static void GLUTCALLBACK glut_TabletButtonFuncCallback0(int, int, int, int);
112
+ static void GLUTCALLBACK glut_OverlayDisplayFuncCallback0(void);
113
+ static void GLUTCALLBACK glut_WindowStatusFuncCallback0(int);
114
+ static void GLUTCALLBACK glut_JoystickFuncCallback0(unsigned int, int, int, int);
115
+ static void GLUTCALLBACK glut_KeyboardUpFuncCallback0(unsigned char, int, int);
116
+ static void GLUTCALLBACK glut_SpecialUpFuncCallback0(int, int, int);
117
+
118
+ WINDOW_CALLBACK_SETUP(DisplayFunc)
119
+ WINDOW_CALLBACK_SETUP(ReshapeFunc)
120
+ WINDOW_CALLBACK_SETUP(KeyboardFunc)
121
+ WINDOW_CALLBACK_SETUP(MouseFunc)
122
+ WINDOW_CALLBACK_SETUP(MotionFunc)
123
+ WINDOW_CALLBACK_SETUP(PassiveMotionFunc)
124
+ WINDOW_CALLBACK_SETUP(EntryFunc)
125
+ WINDOW_CALLBACK_SETUP(VisibilityFunc)
126
+ WINDOW_CALLBACK_SETUP(SpecialFunc)
127
+ WINDOW_CALLBACK_SETUP(SpaceballMotionFunc)
128
+ WINDOW_CALLBACK_SETUP(SpaceballRotateFunc)
129
+ WINDOW_CALLBACK_SETUP(SpaceballButtonFunc)
130
+ WINDOW_CALLBACK_SETUP(ButtonBoxFunc)
131
+ WINDOW_CALLBACK_SETUP(DialsFunc)
132
+ WINDOW_CALLBACK_SETUP(TabletMotionFunc)
133
+ WINDOW_CALLBACK_SETUP(TabletButtonFunc)
134
+ WINDOW_CALLBACK_SETUP(OverlayDisplayFunc)
135
+ WINDOW_CALLBACK_SETUP(WindowStatusFunc)
136
+ WINDOW_CALLBACK_SETUP(KeyboardUpFunc)
137
+ WINDOW_CALLBACK_SETUP(SpecialUpFunc)
138
+
139
+ GLUT_SIMPLE_FUNCTION(ForceJoystickFunc)
140
+
141
+ static void *
142
+ glut_DisplayFuncCallback(void *ignored) {
143
+ VALUE func;
144
+
145
+ func = rb_ary_entry(DisplayFunc, glutGetWindow());
146
+
147
+ if (!NIL_P(func))
148
+ rb_funcall(func, call_id, 0);
149
+
150
+ return NULL;
151
+ }
152
+
153
+ static void GLUTCALLBACK
154
+ glut_DisplayFuncCallback0(void) {
155
+ rb_thread_call_with_gvl(glut_DisplayFuncCallback, NULL);
156
+ }
157
+
158
+ static void *
159
+ glut_ReshapeFuncCallback(struct callback_args *args) {
160
+ VALUE func = rb_ary_entry(ReshapeFunc, glutGetWindow());
161
+ VALUE width = INT2FIX(args->arg0.width);
162
+ VALUE height = INT2FIX(args->arg1.height);
163
+
164
+ if (!NIL_P(func))
165
+ rb_funcall(func, call_id, 2, width, height);
166
+
167
+ return NULL;
168
+ }
169
+
170
+ static void GLUTCALLBACK
171
+ glut_ReshapeFuncCallback0(int width, int height) {
172
+ struct callback_args *args = alloc_callback_args();
173
+
174
+ args->arg0.width = width;
175
+ args->arg1.height = height;
176
+
177
+ rb_thread_call_with_gvl((gvl_call)glut_ReshapeFuncCallback, args);
178
+
179
+ free(args);
180
+ }
181
+
182
+ static void *
183
+ glut_KeyboardFuncCallback(struct callback_args *args) {
184
+ VALUE func = rb_ary_entry(KeyboardFunc, glutGetWindow());
185
+ #if HAVE_SINGLE_BYTE_STRINGS
186
+ VALUE key = rb_str_new((char *)&args->arg0.key, 1);
187
+ #else
188
+ VALUE key = UINT2FIX((unsigned char)args->arg0.key);
189
+ #endif
190
+ VALUE x = INT2FIX(args->arg1.x);
191
+ VALUE y = INT2FIX(args->arg2.y);
192
+
193
+ if (!NIL_P(func))
194
+ rb_funcall(func, call_id, 3, key, x, y);
195
+
196
+ return NULL;
197
+ }
198
+
199
+ static void GLUTCALLBACK
200
+ glut_KeyboardFuncCallback0(unsigned char key, int x, int y) {
201
+ struct callback_args *args = alloc_callback_args();
202
+
203
+ args->arg0.key = key;
204
+ args->arg1.x = x;
205
+ args->arg2.y = y;
206
+
207
+ rb_thread_call_with_gvl((gvl_call)glut_KeyboardFuncCallback, args);
208
+
209
+ free(args);
210
+ }
211
+
212
+ static void *
213
+ glut_KeyboardUpFuncCallback(struct callback_args *args) {
214
+ VALUE func = rb_ary_entry(KeyboardUpFunc, glutGetWindow());
215
+ #if HAVE_SINGLE_BYTE_STRINGS
216
+ VALUE key = rb_str_new((char *)args->arg0.key, 1);
217
+ #else
218
+ VALUE key = UINT2FIX((unsigned char)args->arg0.key);
219
+ #endif
220
+ VALUE x = INT2FIX((int)args->arg1.x);
221
+ VALUE y = INT2FIX((int)args->arg2.y);
222
+
223
+ if (!NIL_P(func))
224
+ rb_funcall(func, call_id, 3, key, x, y);
225
+
226
+ return NULL;
227
+ }
228
+
229
+ static void GLUTCALLBACK
230
+ glut_KeyboardUpFuncCallback0(unsigned char key, int x, int y) {
231
+ struct callback_args *args = alloc_callback_args();
232
+
233
+ args->arg0.key = key;
234
+ args->arg1.x = x;
235
+ args->arg2.y = y;
236
+
237
+ rb_thread_call_with_gvl((gvl_call)glut_KeyboardUpFuncCallback, args);
238
+
239
+ free(args);
240
+ }
241
+
242
+ static void *
243
+ glut_MouseFuncCallback(struct callback_args *args) {
244
+ VALUE func = rb_ary_entry(MouseFunc, glutGetWindow());
245
+
246
+ VALUE button = INT2FIX(args->arg0.button);
247
+ VALUE state = INT2FIX(args->arg1.state);
248
+ VALUE x = INT2FIX(args->arg2.x);
249
+ VALUE y = INT2FIX(args->arg3.y);
250
+
251
+ if (!NIL_P(func))
252
+ rb_funcall(func, call_id, 4, button, state, x, y);
253
+
254
+ return NULL;
255
+ }
256
+
257
+ static void GLUTCALLBACK
258
+ glut_MouseFuncCallback0(int button, int state, int x, int y) {
259
+ struct callback_args *args = alloc_callback_args();
260
+
261
+ args->arg0.button = button;
262
+ args->arg1.state = state;
263
+ args->arg2.x = x;
264
+ args->arg3.y = y;
265
+
266
+ rb_thread_call_with_gvl((gvl_call)glut_MouseFuncCallback, args);
267
+
268
+ free(args);
269
+ }
270
+
271
+ static void *
272
+ glut_MotionFuncCallback(struct callback_args *args) {
273
+ VALUE func = rb_ary_entry(MotionFunc, glutGetWindow());
274
+ VALUE x = INT2FIX(args->arg0.x);
275
+ VALUE y = INT2FIX(args->arg1.y);
276
+
277
+ if (!NIL_P(func))
278
+ rb_funcall(func, call_id, 2, x, y);
279
+
280
+ return NULL;
281
+ }
282
+
283
+ static void GLUTCALLBACK
284
+ glut_MotionFuncCallback0(int x, int y) {
285
+ struct callback_args *args = alloc_callback_args();
286
+
287
+ args->arg0.x = x;
288
+ args->arg1.y = y;
289
+
290
+ rb_thread_call_with_gvl((gvl_call)glut_MotionFuncCallback, args);
291
+
292
+ free(args);
293
+ }
294
+
295
+ static void *
296
+ glut_PassiveMotionFuncCallback(struct callback_args *args) {
297
+ VALUE func = rb_ary_entry(PassiveMotionFunc, glutGetWindow());
298
+ VALUE x = INT2FIX(args->arg0.x);
299
+ VALUE y = INT2FIX(args->arg1.y);
300
+
301
+ if (!NIL_P(func))
302
+ rb_funcall(func, call_id, 2, x, y);
303
+
304
+ return NULL;
305
+ }
306
+
307
+ static void GLUTCALLBACK
308
+ glut_PassiveMotionFuncCallback0(int x, int y) {
309
+ struct callback_args *args = alloc_callback_args();
310
+
311
+ args->arg0.x = x;
312
+ args->arg1.y = y;
313
+
314
+ rb_thread_call_with_gvl((gvl_call)glut_PassiveMotionFuncCallback, args);
315
+
316
+ free(args);
317
+ }
318
+
319
+ static void *
320
+ glut_EntryFuncCallback(struct callback_args *args) {
321
+ VALUE func = rb_ary_entry(EntryFunc, glutGetWindow());
322
+ VALUE state = INT2NUM(args->arg0.state);
323
+
324
+ if (!NIL_P(func))
325
+ rb_funcall(func, call_id, 1, state);
326
+
327
+ return NULL;
328
+ }
329
+
330
+ static void GLUTCALLBACK
331
+ glut_EntryFuncCallback0(int state) {
332
+ struct callback_args *args = alloc_callback_args();
333
+
334
+ args->arg0.state = state;
335
+
336
+ rb_thread_call_with_gvl((gvl_call)glut_EntryFuncCallback, args);
337
+
338
+ free(args);
339
+ }
340
+
341
+ static void *
342
+ glut_VisibilityFuncCallback(struct callback_args *args) {
343
+ VALUE func = rb_ary_entry(VisibilityFunc, glutGetWindow());
344
+ VALUE state = INT2NUM(args->arg0.state);
345
+
346
+ if (!NIL_P(func))
347
+ rb_funcall(func, call_id, 1, state);
348
+
349
+ return NULL;
350
+ }
351
+
352
+ static void GLUTCALLBACK
353
+ glut_VisibilityFuncCallback0(int state) {
354
+ struct callback_args *args = alloc_callback_args();
355
+
356
+ args->arg0.state = state;
357
+
358
+ rb_thread_call_with_gvl((gvl_call)glut_VisibilityFuncCallback, args);
359
+
360
+ free(args);
361
+ }
362
+
363
+ static void *
364
+ glut_IdleFuncCallback(void *ignored) {
365
+ if (!NIL_P(idle_func))
366
+ rb_funcall(idle_func, call_id, 0);
367
+
368
+ return NULL;
369
+ }
370
+
371
+ static void GLUTCALLBACK
372
+ glut_IdleFuncCallback0(void) {
373
+ rb_thread_call_with_gvl((gvl_call)glut_IdleFuncCallback, NULL);
374
+ }
375
+
376
+ static void *
377
+ glut_TimerFuncCallback(struct callback_args *args) {
378
+ VALUE value = INT2NUM(args->arg0.value);
379
+
380
+ if (!NIL_P(timer_func))
381
+ rb_funcall(timer_func, call_id, 1, value);
382
+
383
+ return NULL;
384
+ }
385
+
386
+ static void GLUTCALLBACK
387
+ glut_TimerFuncCallback0(int value) {
388
+ struct callback_args *args = alloc_callback_args();
389
+
390
+ args->arg0.value = value;
391
+
392
+ rb_thread_call_with_gvl((gvl_call)glut_TimerFuncCallback, args);
393
+
394
+ free(args);
395
+ }
396
+
397
+ static void *
398
+ glut_MenuStateFuncCallback(struct callback_args *args) {
399
+ VALUE state = INT2NUM(args->arg0.state);
400
+
401
+ if (!NIL_P(menustate_func))
402
+ rb_funcall(menustate_func, call_id, 1, state);
403
+
404
+ return NULL;
405
+ }
406
+
407
+ static void GLUTCALLBACK
408
+ glut_MenuStateFuncCallback0(int state) {
409
+ struct callback_args *args = alloc_callback_args();
410
+
411
+ args->arg0.state = state;
412
+
413
+ rb_thread_call_with_gvl((gvl_call)glut_MenuStateFuncCallback, args);
414
+
415
+ free(args);
416
+ }
417
+
418
+ static void *
419
+ glut_MenuStatusFuncCallback(struct callback_args *args) {
420
+ VALUE state = INT2NUM(args->arg0.state);
421
+ VALUE x = INT2NUM(args->arg1.x);
422
+ VALUE y = INT2NUM(args->arg2.y);
423
+
424
+ if (!NIL_P(menustatus_func))
425
+ rb_funcall(menustatus_func, call_id, 3, state, x, y);
426
+
427
+ return NULL;
428
+ }
429
+
430
+ static void GLUTCALLBACK
431
+ glut_MenuStatusFuncCallback0(int state, int x, int y) {
432
+ struct callback_args *args = alloc_callback_args();
433
+
434
+ args->arg0.state = state;
435
+ args->arg1.x = x;
436
+ args->arg2.y = y;
437
+
438
+ rb_thread_call_with_gvl((gvl_call)glut_MenuStatusFuncCallback, args);
439
+
440
+ free(args);
441
+ }
442
+
443
+ static void *
444
+ glut_SpecialFuncCallback(struct callback_args *args) {
445
+ VALUE func = rb_ary_entry(SpecialFunc, glutGetWindow());
446
+ VALUE key = INT2NUM(args->arg0.key);
447
+ VALUE x = INT2NUM(args->arg1.x);
448
+ VALUE y = INT2NUM(args->arg2.y);
449
+
450
+ if (!NIL_P(func))
451
+ rb_funcall(func, call_id, 3, key, x, y);
452
+
453
+ return NULL;
454
+ }
455
+
456
+ static void GLUTCALLBACK
457
+ glut_SpecialFuncCallback0(int key, int x, int y) {
458
+ struct callback_args *args = alloc_callback_args();
459
+
460
+ args->arg0.key = key;
461
+ args->arg1.x = x;
462
+ args->arg2.y = y;
463
+
464
+ rb_thread_call_with_gvl((gvl_call)glut_SpecialFuncCallback, args);
465
+
466
+ free(args);
467
+ }
468
+
469
+ static void *
470
+ glut_SpecialUpFuncCallback(struct callback_args *args) {
471
+ VALUE func = rb_ary_entry(SpecialUpFunc, glutGetWindow());
472
+ VALUE key = INT2NUM(args->arg0.key);
473
+ VALUE x = INT2NUM(args->arg1.x);
474
+ VALUE y = INT2NUM(args->arg2.y);
475
+
476
+ if (!NIL_P(func))
477
+ rb_funcall(func, call_id, 3, key, x, y);
478
+
479
+ return NULL;
480
+ }
481
+
482
+ static void GLUTCALLBACK
483
+ glut_SpecialUpFuncCallback0(int key, int x, int y) {
484
+ struct callback_args *args = alloc_callback_args();
485
+
486
+ args->arg0.key = key;
487
+ args->arg1.x = x;
488
+ args->arg2.y = y;
489
+
490
+ rb_thread_call_with_gvl((gvl_call)glut_SpecialUpFuncCallback, args);
491
+
492
+ free(args);
493
+ }
494
+
495
+ static void *
496
+ glut_SpaceballMotionFuncCallback(struct callback_args *args) {
497
+ VALUE func = rb_ary_entry(SpaceballMotionFunc, glutGetWindow());
498
+ VALUE x = INT2NUM(args->arg0.x);
499
+ VALUE y = INT2NUM(args->arg1.y);
500
+ VALUE z = INT2NUM(args->arg2.z);
501
+
502
+ if (!NIL_P(func))
503
+ rb_funcall(func, call_id, 3, x, y, z);
504
+
505
+ return NULL;
506
+ }
507
+
508
+ static void GLUTCALLBACK
509
+ glut_SpaceballMotionFuncCallback0(int x, int y, int z) {
510
+ struct callback_args *args = alloc_callback_args();
511
+
512
+ args->arg0.x = x;
513
+ args->arg1.y = y;
514
+ args->arg2.z = z;
515
+
516
+ rb_thread_call_with_gvl((gvl_call)glut_SpaceballMotionFuncCallback, args);
517
+
518
+ free(args);
519
+ }
520
+
521
+ static void *
522
+ glut_SpaceballRotateFuncCallback(struct callback_args *args) {
523
+ VALUE func = rb_ary_entry(SpaceballRotateFunc, glutGetWindow());
524
+ VALUE x = INT2NUM(args->arg0.x);
525
+ VALUE y = INT2NUM(args->arg1.y);
526
+ VALUE z = INT2NUM(args->arg2.z);
527
+
528
+ if (!NIL_P(func))
529
+ rb_funcall(func, call_id, 3, x, y, z);
530
+
531
+ return NULL;
532
+ }
533
+
534
+ static void GLUTCALLBACK
535
+ glut_SpaceballRotateFuncCallback0(int x, int y, int z) {
536
+ struct callback_args *args = alloc_callback_args();
537
+
538
+ args->arg0.x = x;
539
+ args->arg1.y = y;
540
+ args->arg2.z = z;
541
+
542
+ rb_thread_call_with_gvl((gvl_call)glut_SpaceballRotateFuncCallback, args);
543
+
544
+ free(args);
545
+ }
546
+
547
+ static void *
548
+ glut_SpaceballButtonFuncCallback(struct callback_args *args) {
549
+ VALUE func = rb_ary_entry(SpaceballButtonFunc, glutGetWindow());
550
+ VALUE button = INT2NUM(args->arg0.button);
551
+ VALUE state = INT2NUM(args->arg1.state);
552
+
553
+ if (!NIL_P(func))
554
+ rb_funcall(func, call_id, 2, button, state);
555
+
556
+ return NULL;
557
+ }
558
+
559
+ static void GLUTCALLBACK
560
+ glut_SpaceballButtonFuncCallback0(int button, int state) {
561
+ struct callback_args *args = alloc_callback_args();
562
+
563
+ args->arg0.button = button;
564
+ args->arg1.state = state;
565
+
566
+ rb_thread_call_with_gvl((gvl_call)glut_SpaceballButtonFuncCallback, args);
567
+
568
+ free(args);
569
+ }
570
+
571
+ static void *
572
+ glut_ButtonBoxFuncCallback(struct callback_args *args) {
573
+ VALUE func = rb_ary_entry(ButtonBoxFunc, glutGetWindow());
574
+ VALUE button = INT2NUM(args->arg0.button);
575
+ VALUE state = INT2NUM(args->arg1.state);
576
+
577
+ if (!NIL_P(func))
578
+ rb_funcall(func, call_id, 2, button, state);
579
+
580
+ return NULL;
581
+ }
582
+
583
+ static void GLUTCALLBACK
584
+ glut_ButtonBoxFuncCallback0(int button, int state) {
585
+ struct callback_args *args = alloc_callback_args();
586
+
587
+ args->arg0.button = button;
588
+ args->arg1.state = state;
589
+
590
+ rb_thread_call_with_gvl((gvl_call)glut_ButtonBoxFuncCallback, args);
591
+
592
+ free(args);
593
+ }
594
+
595
+ static void *
596
+ glut_DialsFuncCallback(struct callback_args *args) {
597
+ VALUE func = rb_ary_entry(DialsFunc, glutGetWindow());
598
+ VALUE dial = INT2NUM(args->arg0.dial);
599
+ VALUE value = INT2NUM(args->arg1.value);
600
+
601
+ if (!NIL_P(func))
602
+ rb_funcall(func, call_id, 2, dial, value);
603
+
604
+ return NULL;
605
+ }
606
+
607
+ static void GLUTCALLBACK
608
+ glut_DialsFuncCallback0(int dial, int value) {
609
+ struct callback_args *args = alloc_callback_args();
610
+
611
+ args->arg0.dial = dial;
612
+ args->arg1.value = value;
613
+
614
+ rb_thread_call_with_gvl((gvl_call)glut_DialsFuncCallback, args);
615
+
616
+ free(args);
617
+ }
618
+
619
+ static void *
620
+ glut_TabletMotionFuncCallback(struct callback_args *args) {
621
+ VALUE func = rb_ary_entry(TabletMotionFunc, glutGetWindow());
622
+ VALUE x = INT2NUM(args->arg0.x);
623
+ VALUE y = INT2NUM(args->arg1.y);
624
+
625
+ if (!NIL_P(func))
626
+ rb_funcall(func, call_id, 2, x, y);
627
+
628
+ return NULL;
629
+ }
630
+
631
+ static void GLUTCALLBACK
632
+ glut_TabletMotionFuncCallback0(int x, int y) {
633
+ struct callback_args *args = alloc_callback_args();
634
+
635
+ args->arg0.x = x;
636
+ args->arg1.y = y;
637
+
638
+ rb_thread_call_with_gvl((gvl_call)glut_TabletMotionFuncCallback, args);
639
+
640
+ free(args);
641
+ }
642
+
643
+ static void *
644
+ glut_TabletButtonFuncCallback(struct callback_args *args) {
645
+ VALUE func = rb_ary_entry(TabletButtonFunc, glutGetWindow());
646
+ VALUE button = INT2NUM(args->arg0.button);
647
+ VALUE state = INT2NUM(args->arg1.state);
648
+ VALUE x = INT2NUM(args->arg2.x);
649
+ VALUE y = INT2NUM(args->arg3.y);
650
+
651
+ if (!NIL_P(func))
652
+ rb_funcall(func, call_id, 4, button, state, x, y);
653
+
654
+ return NULL;
655
+ }
656
+
657
+ static void GLUTCALLBACK
658
+ glut_TabletButtonFuncCallback0(int button, int state, int x, int y) {
659
+ struct callback_args *args = alloc_callback_args();
660
+
661
+ args->arg0.button = button;
662
+ args->arg1.state = state;
663
+ args->arg2.x = x;
664
+ args->arg3.y = y;
665
+
666
+ rb_thread_call_with_gvl((gvl_call)glut_TabletButtonFuncCallback, args);
667
+
668
+ free(args);
669
+ }
670
+
671
+ static void *
672
+ glut_OverlayDisplayFuncCallback(void) {
673
+ VALUE func = rb_ary_entry(OverlayDisplayFunc, glutGetWindow());
674
+
675
+ if (!NIL_P(func))
676
+ rb_funcall(func, call_id, 0);
677
+
678
+ return NULL;
679
+ }
680
+
681
+ static void GLUTCALLBACK
682
+ glut_OverlayDisplayFuncCallback0(void) {
683
+ rb_thread_call_with_gvl((gvl_call)glut_OverlayDisplayFuncCallback, NULL);
684
+ }
685
+
686
+ static void *
687
+ glut_WindowStatusFuncCallback(struct callback_args *args) {
688
+ VALUE func = rb_ary_entry(WindowStatusFunc, glutGetWindow());
689
+ VALUE state = INT2NUM(args->arg0.state);
690
+
691
+ if (!NIL_P(func))
692
+ rb_funcall(func, call_id, 1, state);
693
+
694
+ return NULL;
695
+ }
696
+
697
+ static void GLUTCALLBACK
698
+ glut_WindowStatusFuncCallback0(int state) {
699
+ struct callback_args *args = alloc_callback_args();
700
+
701
+ args->arg0.state = state;
702
+
703
+ rb_thread_call_with_gvl((gvl_call)glut_WindowStatusFuncCallback, args);
704
+
705
+ free(args);
706
+ }
707
+
708
+ static void *
709
+ glut_JoystickFuncCallback(struct callback_args *args) {
710
+ VALUE func = rb_ary_entry(joystick_func, glutGetWindow());
711
+ VALUE button_mask = UINT2NUM(args->arg0.button_mask);
712
+ VALUE x = INT2NUM(args->arg1.x);
713
+ VALUE y = INT2NUM(args->arg2.y);
714
+ VALUE z = INT2NUM(args->arg3.z);
715
+
716
+ if (!NIL_P(func))
717
+ rb_funcall(func, call_id, 4, button_mask, x, y, z);
718
+
719
+ return NULL;
720
+ }
721
+
722
+ static void GLUTCALLBACK
723
+ glut_JoystickFuncCallback0(unsigned int button_mask, int x, int y, int z) {
724
+ struct callback_args *args = alloc_callback_args();
725
+
726
+ args->arg0.button_mask = button_mask;
727
+ args->arg1.x = x;
728
+ args->arg2.y = y;
729
+ args->arg3.z = z;
730
+
731
+ rb_thread_call_with_gvl((gvl_call)glut_JoystickFuncCallback, args);
732
+
733
+ free(args);
734
+ }
735
+
736
+ static VALUE
737
+ glut_JoystickFunc(VALUE self, VALUE callback, VALUE _poll_interval) {
738
+ int win = glutGetWindow();
739
+ int poll_interval = NUM2INT(_poll_interval);
740
+
741
+ if (win == 0)
742
+ rb_raise(rb_eRuntimeError, "glutJoystickFunc needs current window");
743
+
744
+ callback = rb_glut_check_callback(self, callback);
745
+
746
+ rb_ary_store(joystick_func, win, callback);
747
+
748
+ if (NIL_P(callback))
749
+ glutJoystickFunc(NULL, -1);
750
+ else
751
+ glutJoystickFunc(glut_JoystickFuncCallback0, poll_interval);
752
+
753
+ return Qnil;
754
+ }
755
+
756
+ static VALUE
757
+ glut_IdleFunc(VALUE self, VALUE callback) {
758
+ callback = rb_glut_check_callback(self, callback);
759
+
760
+ idle_func = callback;
761
+
762
+ if (NIL_P(callback))
763
+ glutIdleFunc(NULL);
764
+ else
765
+ glutIdleFunc(glut_IdleFuncCallback0);
766
+
767
+ return Qnil;
768
+ }
769
+
770
+ static VALUE
771
+ glut_MenuStateFunc(VALUE self, VALUE callback) {
772
+ menustate_func = rb_glut_check_callback(self, callback);
773
+
774
+ if (NIL_P(menustate_func))
775
+ glutMenuStateFunc(NULL);
776
+ else
777
+ glutMenuStateFunc(glut_MenuStateFuncCallback0);
778
+
779
+ return Qnil;
780
+ }
781
+
782
+ static VALUE
783
+ glut_MenuStatusFunc(VALUE self, VALUE callback) {
784
+ menustatus_func = rb_glut_check_callback(self, callback);
785
+
786
+ if (NIL_P(menustatus_func))
787
+ glutMenuStatusFunc(NULL);
788
+ else
789
+ glutMenuStatusFunc(glut_MenuStatusFuncCallback0);
790
+
791
+ return Qnil;
792
+ }
793
+
794
+ static VALUE
795
+ glut_TimerFunc(VALUE self, VALUE _msec, VALUE callback, VALUE _value) {
796
+ unsigned int msec = NUM2UINT(_msec);
797
+ int value = NUM2INT(_value);
798
+
799
+ timer_func = rb_glut_check_callback(self, callback);
800
+
801
+ glutTimerFunc(msec, glut_TimerFuncCallback0, value);
802
+
803
+ return Qnil;
804
+ }
805
+
806
+ void Init_glut_callbacks() {
807
+ VALUE mGlut = rb_path2class("Glut");
808
+
809
+ call_id = rb_intern("call");
810
+ joystick_func = rb_ary_new();
811
+
812
+ rb_global_variable(&joystick_func);
813
+ rb_gc_register_address(&idle_func);
814
+ rb_gc_register_address(&timer_func);
815
+ rb_gc_register_address(&menustate_func);
816
+
817
+ rb_define_module_function(mGlut, "glutJoystickFunc", glut_JoystickFunc, 2);
818
+ rb_define_module_function(mGlut, "glutForceJoystickFunc", glut_ForceJoystickFunc, 0);
819
+ rb_define_module_function(mGlut, "glutIdleFunc", glut_IdleFunc, 1);
820
+ rb_define_module_function(mGlut, "glutMenuStateFunc", glut_MenuStateFunc, 1);
821
+ rb_define_module_function(mGlut, "glutMenuStatusFunc", glut_MenuStatusFunc, 1);
822
+ rb_define_module_function(mGlut, "glutTimerFunc", glut_TimerFunc, 3);
823
+
824
+ WINDOW_CALLBACK_DEFINE(mGlut, ButtonBoxFunc);
825
+ WINDOW_CALLBACK_DEFINE(mGlut, DialsFunc);
826
+ WINDOW_CALLBACK_DEFINE(mGlut, DisplayFunc);
827
+ WINDOW_CALLBACK_DEFINE(mGlut, EntryFunc);
828
+ WINDOW_CALLBACK_DEFINE(mGlut, KeyboardFunc);
829
+ WINDOW_CALLBACK_DEFINE(mGlut, KeyboardUpFunc);
830
+ WINDOW_CALLBACK_DEFINE(mGlut, MotionFunc);
831
+ WINDOW_CALLBACK_DEFINE(mGlut, MouseFunc);
832
+ WINDOW_CALLBACK_DEFINE(mGlut, OverlayDisplayFunc);
833
+ WINDOW_CALLBACK_DEFINE(mGlut, PassiveMotionFunc);
834
+ WINDOW_CALLBACK_DEFINE(mGlut, ReshapeFunc);
835
+ WINDOW_CALLBACK_DEFINE(mGlut, SpaceballButtonFunc);
836
+ WINDOW_CALLBACK_DEFINE(mGlut, SpaceballMotionFunc);
837
+ WINDOW_CALLBACK_DEFINE(mGlut, SpaceballRotateFunc);
838
+ WINDOW_CALLBACK_DEFINE(mGlut, SpecialFunc);
839
+ WINDOW_CALLBACK_DEFINE(mGlut, SpecialUpFunc);
840
+ WINDOW_CALLBACK_DEFINE(mGlut, TabletButtonFunc);
841
+ WINDOW_CALLBACK_DEFINE(mGlut, TabletMotionFunc);
842
+ WINDOW_CALLBACK_DEFINE(mGlut, VisibilityFunc);
843
+ WINDOW_CALLBACK_DEFINE(mGlut, WindowStatusFunc);
844
+ }
845
+