Change parser to do C style () for operators: 1+2*3 == 1+(2)*3
[io/jrb1.git] / addons / OpenGL / source / IoGLUT.c
blob9ac3e7ce993d2ce7f24fdc3828f35617366c9082
1 /*#io
2 GLUT ioDoc(
3 docCopyright("Steve Dekorte", 2002)
4 docLicense("BSD revised")
5 docCategory("Graphics")
6 */
8 #include "IoGLUT.h"
10 #include "List.h"
11 #include "IoState.h"
12 #include "IoNumber.h"
13 #include "IoCFunction.h"
14 #include "IoSeq.h"
15 #include "IoList.h"
16 #include "List.h"
17 #include "IoDirectory.h"
18 #include <time.h>
20 #define DATA(self) ((IoGLUTData *)IoObject_dataPointer(self))
22 void IoGlutTimerFunc(int vv);
24 static IoGLUT *proto = NULL;
27 IoTag *IoGLUT_newTag(void *state)
29 IoTag *tag = IoTag_newWithName_("GLUT");
30 IoTag_state_(tag, state);
31 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoGLUT_rawClone);
32 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoGLUT_free);
33 IoTag_markFunc_(tag, (IoTagMarkFunc *)IoGLUT_mark);
34 return tag;
37 #define GLUTMESSAGE(name) \
38 IoMessage_newWithName_label_(state, IOSYMBOL(name), IOSYMBOL("[GLUT]"))
40 IoGLUT *IoGLUT_proto(void *state)
42 IoObject *self = IoObject_new(state);
43 /*printf("state = %p proto = %p self = %p\n", state, proto, self); */
45 proto = self;
46 IoObject_tag_(self, IoGLUT_newTag(state));
47 IoObject_setDataPointer_(self, calloc(1, sizeof(IoGLUTData)));
49 DATA(self)->coroutine = IoCoroutine_new(state);
50 //printf("GLUT coro = %p\n", DATA(self)->coroutine);
52 DATA(self)->eventTarget = NULL;
53 DATA(self)->entryMessage = GLUTMESSAGE("entry");
54 DATA(self)->displayMessage = GLUTMESSAGE("display");
55 DATA(self)->keyboardMessage = GLUTMESSAGE("keyboard");
56 DATA(self)->keyboardUpMessage = GLUTMESSAGE("keyboardUp");
57 DATA(self)->joystickMessage = GLUTMESSAGE("joystick");
58 DATA(self)->motionMessage = GLUTMESSAGE("motion");
59 DATA(self)->menuMessage = GLUTMESSAGE("menu");
60 DATA(self)->mouseMessage = GLUTMESSAGE("mouse");
61 DATA(self)->passiveMotionMessage = GLUTMESSAGE("passiveMotion");
62 DATA(self)->reshapeMessage = GLUTMESSAGE("reshape");
63 DATA(self)->specialMessage = GLUTMESSAGE("special");
64 DATA(self)->timerMessage = GLUTMESSAGE("timer");
66 DATA(self)->acceptsDropMessage = GLUTMESSAGE("acceptsDrop");
67 DATA(self)->dragMessage = GLUTMESSAGE("drag");
68 DATA(self)->dropMessage = GLUTMESSAGE("drop");
69 DATA(self)->copyMessage = GLUTMESSAGE("copy");
70 DATA(self)->pasteMessage = GLUTMESSAGE("paste");
71 DATA(self)->deleteMessage = GLUTMESSAGE("delete");
72 DATA(self)->nanoSleepPeriod = 1000000000/2;
77 //printf("GLUT coro = %p\n", (void *)DATA(self)->coroutine);
78 IoState_retain_(state, self);
79 IoState_retain_(state, DATA(self)->coroutine);
80 IoState_retain_(state, DATA(self)->displayMessage);
81 IoState_retain_(state, DATA(self)->reshapeMessage);
82 IoState_retain_(state, DATA(self)->timerMessage);
86 DATA(self)->j = IoSeq_newFloatArrayOfSize_(state, 0);
87 DATA(self)->lastJ = UArray_new();
88 UArray_setItemType_(DATA(self)->lastJ, CTYPE_float32_t);
90 IoState_registerProtoWithFunc_(state, self, IoGLUT_proto);
93 //-----------------------------
95 IoState_retain_(state, DATA(self)->j);
97 IoState_retain_(state, DATA(self)->coroutine);
98 IoState_retain_(state, DATA(self)->entryMessage);
99 IoState_retain_(state, DATA(self)->displayMessage);
100 IoState_retain_(state, DATA(self)->keyboardMessage);
101 IoState_retain_(state, DATA(self)->keyboardUpMessage);
102 IoState_retain_(state, DATA(self)->joystickMessage);
103 IoState_retain_(state, DATA(self)->menuMessage);
104 IoState_retain_(state, DATA(self)->mouseMessage);
105 IoState_retain_(state, DATA(self)->motionMessage);
106 IoState_retain_(state, DATA(self)->passiveMotionMessage);
107 IoState_retain_(state, DATA(self)->reshapeMessage);
108 IoState_retain_(state, DATA(self)->specialMessage);
109 IoState_retain_(state, DATA(self)->timerMessage);
111 IoState_retain_(state, DATA(self)->acceptsDropMessage);
112 IoState_retain_(state, DATA(self)->dragMessage);
113 IoState_retain_(state, DATA(self)->dropMessage);
114 IoState_retain_(state, DATA(self)->copyMessage);
115 IoState_retain_(state, DATA(self)->pasteMessage);
116 IoState_retain_(state, DATA(self)->deleteMessage);
118 IoGLUT_protoInit(self);
119 return self;
122 IoGLUT *IoGLUT_new(void *state)
124 return IoState_protoWithInitFunction_(state, IoGLUT_proto);
127 void IoGLUT_free(IoGLUT *self)
129 /* add code to shut down GLUT */
130 free(IoObject_dataPointer(self));
133 void IoGLUT_mark(IoGLUT *self)
135 //printf("IoGLUT_mark\n");
137 if (DATA(self)->eventTarget)
139 IoObject_shouldMark(DATA(self)->eventTarget);
142 IoObject_shouldMark(DATA(self)->j);
144 IoObject_shouldMark(DATA(self)->coroutine);
145 IoObject_shouldMark(DATA(self)->entryMessage);
146 IoObject_shouldMark(DATA(self)->displayMessage);
147 IoObject_shouldMark(DATA(self)->keyboardMessage);
148 IoObject_shouldMark(DATA(self)->keyboardUpMessage);
149 IoObject_shouldMark(DATA(self)->joystickMessage);
150 IoObject_shouldMark(DATA(self)->menuMessage);
151 IoObject_shouldMark(DATA(self)->mouseMessage);
152 IoObject_shouldMark(DATA(self)->motionMessage);
153 IoObject_shouldMark(DATA(self)->passiveMotionMessage);
154 IoObject_shouldMark(DATA(self)->reshapeMessage);
155 IoObject_shouldMark(DATA(self)->specialMessage);
156 IoObject_shouldMark(DATA(self)->timerMessage);
158 IoObject_shouldMark(DATA(self)->acceptsDropMessage);
159 IoObject_shouldMark(DATA(self)->dragMessage);
160 IoObject_shouldMark(DATA(self)->dropMessage);
161 IoObject_shouldMark(DATA(self)->copyMessage);
162 IoObject_shouldMark(DATA(self)->pasteMessage);
163 IoObject_shouldMark(DATA(self)->deleteMessage);
166 /* ----------------------------------------------------------- */
168 IoObject *IoGLUT_rawClone(IoGLUT *self)
170 return IoState_protoWithInitFunction_(IOSTATE, IoGLUT_proto);
173 /* ----------------------------------------------------------- */
175 IoObject *IoGLUT_glutInitDisplayMode(IoGLUT *self, IoObject *locals, IoMessage *m)
177 int mode = IoMessage_locals_intArgAt_(m, locals, 0);
178 glutInitDisplayMode(mode);
179 return self;
182 IoObject *IoGLUT_glutInitWindowSize(IoGLUT *self, IoObject *locals, IoMessage *m)
184 int w = IoMessage_locals_intArgAt_(m, locals, 0);
185 int h = IoMessage_locals_intArgAt_(m, locals, 1);
186 //printf("glutInitWindowSize(%i, %i)\n", w, h);
187 glutInitWindowSize(w, h);
188 return self;
191 IoObject *IoGLUT_glutInitWindowPosition(IoGLUT *self, IoObject *locals, IoMessage *m)
193 int x = IoMessage_locals_intArgAt_(m, locals, 0);
194 int y = IoMessage_locals_intArgAt_(m, locals, 1);
195 //printf("glutInitWindowPosition(%i, %i)\n", x, y);
196 glutInitWindowPosition(x, y);
197 return self;
200 void IoGlutIdleFunc(void)
202 //IoState_yield(IoObject_state(proto));
205 IoObject *IoGLUT_glutInit(IoGLUT *self, IoObject *locals, IoMessage *m)
207 IoState *state = IOSTATE;
208 int argc = state->mainArgs->argc;
209 UArray *ba = IoDirectory_CurrentWorkingDirectoryAsUArray();
210 glutInit(&argc, (char **)(state->mainArgs->argv));
211 IoDirectory_SetCurrentWorkingDirectory(UArray_asCString(ba));
212 UArray_free(ba);
214 //glutIdleFunc(IoGlutIdleFunc);
215 //glutTimerFunc((unsigned int)10, IoGlutTimerFunc, -1);
216 return self;
219 IoObject *IoGLUT_glutInitDisplayString(IoGLUT *self, IoObject *locals, IoMessage *m)
221 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
222 glutInitDisplayString(IoSeq_asCString(s));
223 return self;
226 IoObject *IoGLUT_glutCreateWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
228 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
229 int windowId = glutCreateWindow(IoSeq_asCString(s));
230 return IONUMBER(windowId);
233 IoObject *IoGLUT_glutCreateSubWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
235 int win = IoMessage_locals_intArgAt_(m, locals, 0);
236 int x = IoMessage_locals_intArgAt_(m, locals, 1);
237 int y = IoMessage_locals_intArgAt_(m, locals, 2);
238 int w = IoMessage_locals_intArgAt_(m, locals, 3);
239 int h = IoMessage_locals_intArgAt_(m, locals, 4);
240 return IONUMBER(glutCreateSubWindow(win, x, y, w, h));
243 IoObject *IoGLUT_glutSetWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
245 int win = IoMessage_locals_intArgAt_(m, locals, 0);
246 glutSetWindow(win);
247 return self;
250 IoObject *IoGLUT_glutGetWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
252 return IONUMBER(glutGetWindow());
255 IoObject *IoGLUT_glutGet(IoGLUT *self, IoObject *locals, IoMessage *m)
257 GLenum n = IoMessage_locals_intArgAt_(m, locals, 0);
258 return IONUMBER(glutGet(n));
261 IoObject *IoGLUT_glutDestroyWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
263 int win = IoMessage_locals_intArgAt_(m, locals, 0);
264 glutDestroyWindow(win);
265 return self;
268 IoObject *IoGLUT_glutPositionWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
270 int x = IoMessage_locals_intArgAt_(m, locals, 0);
271 int y = IoMessage_locals_intArgAt_(m, locals, 1);
272 glutPositionWindow(x, y);
273 return self;
276 IoObject *IoGLUT_glutReshapeWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
278 int w = IoMessage_locals_intArgAt_(m, locals, 0);
279 int h = IoMessage_locals_intArgAt_(m, locals, 1);
280 glutReshapeWindow(w, h);
281 return self;
284 IoObject *IoGLUT_glutPopWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
286 glutPopWindow(); return self;
289 IoObject *IoGLUT_glutPushWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
291 glutPushWindow();
292 return self;
295 IoObject *IoGLUT_glutShowWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
297 glutShowWindow();
298 return self;
301 IoObject *IoGLUT_glutHideWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
303 glutHideWindow();
304 return self;
307 IoObject *IoGLUT_glutIconifyWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
309 glutIconifyWindow();
310 return self;
313 IoObject *IoGLUT_glutSetWindowTitle(IoGLUT *self, IoObject *locals, IoMessage *m)
315 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
316 glutSetWindowTitle(CSTRING(s));
317 return self;
320 IoObject *IoGLUT_glutSetIconTitle(IoGLUT *self, IoObject *locals, IoMessage *m)
322 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
323 glutSetIconTitle(CSTRING(s));
324 return self;
327 IoObject *IoGLUT_glutEventTarget_(IoGLUT *self, IoObject *locals, IoMessage *m)
329 DATA(proto)->eventTarget = IOREF(IoMessage_locals_valueArgAt_(m, locals, 0));
330 return self;
333 // events
335 void IoGlutDisplayFunc(void)
337 //printf("IoGlutDisplayFunc\n");
338 IoState_pushRetainPool(IoObject_state(proto));
340 IoGLUT_tryCallback(proto, DATA(proto)->displayMessage);
342 IoState_popRetainPool(IoObject_state(proto));
345 IoObject *IoGLUT_glutDisplayFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
347 glutDisplayFunc(IoGlutDisplayFunc);
348 return self;
351 void IoGlutKeyboardFunc(unsigned char key, int xv, int yv)
353 IoState_pushRetainPool(IoObject_state(proto));
354 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 0, (int)key);
355 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 1, xv);
356 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 2, yv);
358 IoGLUT_tryCallback(proto, DATA(proto)->keyboardMessage);
360 IoState_popRetainPool(IoObject_state(proto));
363 IoObject *IoGLUT_glutKeyboardFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
365 glutKeyboardFunc(IoGlutKeyboardFunc);
366 return self;
369 void IoGlutSpecialFunc(int key, int xv, int yv)
371 IoState_pushRetainPool(IoObject_state(proto));
372 IoMessage_setCachedArg_toInt_(DATA(proto)->specialMessage, 0, (int)key);
373 IoMessage_setCachedArg_toInt_(DATA(proto)->specialMessage, 1, xv);
374 IoMessage_setCachedArg_toInt_(DATA(proto)->specialMessage, 2, yv);
376 IoGLUT_tryCallback(proto, DATA(proto)->specialMessage);
378 IoState_popRetainPool(IoObject_state(proto));
381 IoObject *IoGLUT_glutSpecialFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
383 glutSpecialFunc(IoGlutSpecialFunc);
384 return self;
387 void IoGlutKeyboardUpFunc(unsigned char key, int xv, int yv)
389 IoState_pushRetainPool(IoObject_state(proto));
390 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardUpMessage, 0, (int)key);
391 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardUpMessage, 1, xv);
392 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardUpMessage, 2, yv);
394 IoGLUT_tryCallback(proto, DATA(proto)->keyboardUpMessage);
396 IoState_popRetainPool(IoObject_state(proto));
399 IoObject *IoGLUT_glutKeyboardUpFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
401 #if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
402 glutKeyboardUpFunc(IoGlutKeyboardUpFunc);
403 return self;
404 #endif
407 IoObject *IoGLUT_glutGetModifiers(IoGLUT *self, IoObject *locals, IoMessage *m)
409 return IONUMBER(glutGetModifiers());
412 void IoGlutEntryFunc(int state)
414 IoState_pushRetainPool(IoObject_state(proto));
415 IoMessage_setCachedArg_toInt_(DATA(proto)->entryMessage, 0, state);
417 IoGLUT_tryCallback(proto, DATA(proto)->entryMessage);
419 IoState_popRetainPool(IoObject_state(proto));
422 IoObject *IoGLUT_glutEntryFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
424 glutEntryFunc(IoGlutEntryFunc); return self;
427 void IoGlutMotionFunc(int xv, int yv)
429 IoState_pushRetainPool(IoObject_state(proto));
432 IoMessage_setCachedArg_toInt_(DATA(proto)->motionMessage, 0, xv);
433 IoMessage_setCachedArg_toInt_(DATA(proto)->motionMessage, 1, yv);
435 IoGLUT_tryCallback(proto, DATA(proto)->motionMessage);
438 IoState_popRetainPool(IoObject_state(proto));
441 IoObject *IoGLUT_glutMotionFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
443 glutMotionFunc(IoGlutMotionFunc);
444 return self;
447 void IoGlutPassiveMotionFunc(int xv, int yv)
449 IoState_pushRetainPool(IoObject_state(proto));
452 IoMessage_setCachedArg_toInt_(DATA(proto)->passiveMotionMessage, 0, xv);
453 IoMessage_setCachedArg_toInt_(DATA(proto)->passiveMotionMessage, 1, yv);
455 IoGLUT_tryCallback(proto, DATA(proto)->passiveMotionMessage);
458 IoState_popRetainPool(IoObject_state(proto));
461 IoObject *IoGLUT_glutPassiveMotionFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
463 glutPassiveMotionFunc(IoGlutPassiveMotionFunc);
464 return self;
467 void IoGlutMouseFunc(int button, int state, int xv, int yv)
469 IoState_pushRetainPool(IoObject_state(proto));
472 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 0, button);
473 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 1, state);
474 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 2, xv);
475 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 3, yv);
477 IoGLUT_tryCallback(proto, DATA(proto)->mouseMessage);
480 IoState_popRetainPool(IoObject_state(proto));
483 IoObject *IoGLUT_glutMouseFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
485 glutMouseFunc(IoGlutMouseFunc);
486 return self;
489 void IoGlutReshapeFunc(int width, int height)
491 //printf("IoGlutReshapeFunc\n");
492 IoState_pushRetainPool(IoObject_state(proto));
494 IoMessage_setCachedArg_toInt_(DATA(proto)->reshapeMessage, 0, width?width:1);
495 IoMessage_setCachedArg_toInt_(DATA(proto)->reshapeMessage, 1, height?height:1);
497 IoGLUT_tryCallback(proto, DATA(proto)->reshapeMessage);
500 IoState_popRetainPool(IoObject_state(proto));
503 IoObject *IoGLUT_glutReshapeFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
505 glutReshapeFunc(IoGlutReshapeFunc);
506 return self;
509 void IoGlutTimerFunc(int vv)
511 IoState *state = IoObject_state(proto);
513 //printf("IoGlutTimerFunc\n");
515 IoState_pushRetainPool(state);
517 if (vv == -1)
519 //IoState_yield(IoObject_state(proto));
520 glutTimerFunc((unsigned int)100, IoGlutTimerFunc, -1);
522 else
524 IoObject *m = DATA(proto)->timerMessage;
525 IoMessage_setCachedArg_toInt_(m, 0, vv);
526 IoGLUT_tryCallback(proto, m);
528 IoState_popRetainPool(state);
531 IoObject *IoGLUT_glutTimerFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
533 unsigned int msecs = IoMessage_locals_longArgAt_(m, locals, 0);
534 int v = IoMessage_locals_intArgAt_(m, locals, 1);
535 //printf("IoGLUT_glutTimerFunc msecs %i v %i\n", msecs, v);
536 glutTimerFunc((unsigned int)msecs, IoGlutTimerFunc, v);
537 return self;
540 IoObject *IoGLUT_tryCallback(IoGLUT *self, IoMessage *m)
542 IoState *state = IoObject_state(proto);
543 IoObject *tryCoro = DATA(self)->coroutine;
544 IoObject *t = DATA(proto)->eventTarget;
545 IoObject *result = state->ioNil;
547 //printf("IoGLUT_tryCallback(self, %p)\n", (void *)m);
549 if (t)
551 //result = IoState_tryToPerform(state, t, t, m);
554 //IoCoroutine_try(tryCoro, t, t, m);
555 IoMessage_locals_performOn_(m, t, t);
557 if (IoCoroutine_rawException(tryCoro) != state->ioNil)
559 IoState_exception_(state, tryCoro);
562 IoCoroutine_clearStack(tryCoro);
563 return IoCoroutine_rawResult(tryCoro);
566 return result;
569 #ifdef GLUT_KEY_REPEAT_ON
570 IoObject *IoGLUT_glutIgnoreKeyRepeat(IoGLUT *self, IoObject *locals, IoMessage *m)
572 int v = IoMessage_locals_intArgAt_(m, locals, 0);
573 glutIgnoreKeyRepeat(v);
574 return self;
576 #endif
578 IoObject *IoGLUT_glutMainLoop(IoGLUT *self, IoObject *locals, IoMessage *m)
580 glutMainLoop();
581 return self;
584 IoObject *IoGLUT_glutPostRedisplay(IoGLUT *self, IoObject *locals, IoMessage *m)
586 glutPostRedisplay();
587 return self;
590 IoObject *IoGLUT_glutSwapBuffers(IoGLUT *self, IoObject *locals, IoMessage *m)
592 glutSwapBuffers();
593 return self;
596 IoObject *IoGLUT_glutSolidCone(IoGLUT *self, IoObject *locals, IoMessage *m)
598 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
599 GLdouble height = IoMessage_locals_intArgAt_(m, locals, 1);
600 GLint slices = IoMessage_locals_intArgAt_(m, locals, 2);
601 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 3);
602 glutSolidCone(radius, height, slices, stacks);
603 return self;
606 IoObject *IoGLUT_glutWireCone(IoGLUT *self, IoObject *locals, IoMessage *m)
608 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
609 GLdouble height = IoMessage_locals_intArgAt_(m, locals, 1);
610 GLint slices = IoMessage_locals_intArgAt_(m, locals, 2);
611 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 3);
612 glutWireCone(radius, height, slices, stacks);
613 return self;
616 IoObject *IoGLUT_glutSolidSphere(IoGLUT *self, IoObject *locals, IoMessage *m)
618 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
619 GLint slices = IoMessage_locals_intArgAt_(m, locals, 1);
620 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 2);
621 glutSolidSphere(radius, slices, stacks);
622 return self;
625 IoObject *IoGLUT_glutWireSphere(IoGLUT *self, IoObject *locals, IoMessage *m)
627 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
628 GLint slices = IoMessage_locals_intArgAt_(m, locals, 1);
629 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 2);
630 glutWireSphere(radius, slices, stacks);
631 return self;
634 IoObject *IoGLUT_glutSolidTorus(IoGLUT *self, IoObject *locals, IoMessage *m)
636 GLdouble innerRadius = IoMessage_locals_doubleArgAt_(m, locals, 0);
637 GLdouble outerRadius = IoMessage_locals_doubleArgAt_(m, locals, 1);
638 GLint nsides = IoMessage_locals_intArgAt_(m, locals, 2);
639 GLint rings = IoMessage_locals_intArgAt_(m, locals, 3);
640 glutSolidTorus(innerRadius, outerRadius, nsides, rings);
641 return self;
644 IoObject *IoGLUT_glutWireTorus(IoGLUT *self, IoObject *locals, IoMessage *m)
646 GLdouble innerRadius = IoMessage_locals_doubleArgAt_(m, locals, 0);
647 GLdouble outerRadius = IoMessage_locals_doubleArgAt_(m, locals, 1);
648 GLint nsides = IoMessage_locals_intArgAt_(m, locals, 2);
649 GLint rings = IoMessage_locals_intArgAt_(m, locals, 3);
650 glutWireTorus(innerRadius, outerRadius, nsides, rings);
651 return self;
654 IoObject *IoGLUT_glutSolidDodecahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
656 glutSolidDodecahedron();
657 return self;
660 IoObject *IoGLUT_glutWireDodecahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
662 glutWireDodecahedron();
663 return self;
666 IoObject *IoGLUT_glutSolidOctahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
668 glutSolidOctahedron();
669 return self;
672 IoObject *IoGLUT_glutWireOctahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
674 glutWireOctahedron();
675 return self;
678 IoObject *IoGLUT_glutSolidTetrahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
680 glutSolidTetrahedron();
681 return self;
684 IoObject *IoGLUT_glutWireTetrahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
686 glutWireTetrahedron();
687 return self;
690 IoObject *IoGLUT_glutSolidIcosahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
692 glutSolidIcosahedron();
693 return self;
696 IoObject *IoGLUT_glutWireIcosahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
698 glutWireIcosahedron();
699 return self;
702 IoObject *IoGLUT_glutSolidTeapot(IoGLUT *self, IoObject *locals, IoMessage *m)
704 GLdouble r = IoMessage_locals_doubleArgAt_(m, locals, 0);
705 glutSolidTeapot(r);
706 return self;
709 IoObject *IoGLUT_glutWireTeapot(IoGLUT *self, IoObject *locals, IoMessage *m)
711 GLdouble r = IoMessage_locals_doubleArgAt_(m, locals, 0);
712 glutWireTeapot(r);
713 return self;
716 IoObject *IoGLUT_glutSolidCube(IoGLUT *self, IoObject *locals, IoMessage *m)
718 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
719 glutSolidCube(radius);
720 return self;
723 IoObject *IoGLUT_glutWireCube(IoGLUT *self, IoObject *locals, IoMessage *m)
725 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
726 glutWireCube(radius);
727 return self;
730 IoObject *IoGLUT_glutStrokeCharacter(IoGLUT *self, IoObject *locals, IoMessage *m)
732 int fontNum = IoMessage_locals_intArgAt_(m, locals, 0);
733 char c = IoMessage_locals_intArgAt_(m, locals, 1);
734 void *font = GLUT_STROKE_ROMAN;
735 if (fontNum) font = GLUT_STROKE_MONO_ROMAN;
736 glutStrokeCharacter(font, c);
737 return self;
740 IoObject *IoGLUT_glutStrokeString(IoGLUT *self, IoObject *locals, IoMessage *m)
742 int fontNum = IoMessage_locals_intArgAt_(m, locals, 0);
743 IoSymbol *string = IoMessage_locals_seqArgAt_(m, locals, 1);
744 char *s = CSTRING(string);
745 void *font = GLUT_STROKE_ROMAN;
746 if (fontNum) font = GLUT_STROKE_MONO_ROMAN;
748 while (*s)
750 glutStrokeCharacter(font, *s);
751 s++;
754 return self;
757 /* --- GLUT game mode ----------------------------------------------------- */
759 IoObject *IoGLUT_glutFullScreen(IoGLUT *self, IoObject *locals, IoMessage *m)
761 glutFullScreen();
762 return self;
765 #ifdef GLUT_GAME_MODE_ACTIVE
767 IoObject *IoGLUT_glutEnterGameMode(IoGLUT *self, IoObject *locals, IoMessage *m)
769 glutEnterGameMode();
770 return self;
773 IoObject *IoGLUT_glutLeaveGameMode(IoGLUT *self, IoObject *locals, IoMessage *m)
775 glutLeaveGameMode();
776 return self;
779 IoObject *IoGLUT_glutWarpPointer(IoGLUT *self, IoObject *locals, IoMessage *m)
781 int x = IoMessage_locals_intArgAt_(m, locals, 0);
782 int y = IoMessage_locals_intArgAt_(m, locals, 1);
783 glutWarpPointer(x, y);
784 return self;
787 IoObject *IoGLUT_glutGameModeString(IoGLUT *self, IoObject *locals, IoMessage *m)
789 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
790 glutGameModeString(IoSeq_asCString(s));
791 return self;
794 #endif
796 IoObject *IoGLUT_glutSetCursor(IoGLUT *self, IoObject *locals, IoMessage *m)
798 int x = IoMessage_locals_intArgAt_(m, locals, 0);
799 glutSetCursor(x);
800 return self;
803 // Menus --------------------------------------------------------------------
805 void IoGlutMenuFunc(int menuId)
807 IoState_pushRetainPool(IoObject_state(proto));
810 IoMessage_setCachedArg_toInt_(DATA(proto)->menuMessage, 0, menuId);
811 IoGLUT_tryCallback(proto, DATA(proto)->menuMessage);
814 IoState_popRetainPool(IoObject_state(proto));
817 IoObject *IoGLUT_glutCreateMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
819 int menuId = glutCreateMenu(IoGlutMenuFunc);
820 return IONUMBER(menuId);
823 IoObject *IoGLUT_glutSetMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
825 int menuId = IoMessage_locals_intArgAt_(m, locals, 0);
826 glutSetMenu(menuId);
827 return self;
830 IoObject *IoGLUT_glutGetMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
832 return IONUMBER(glutGetMenu());
835 IoObject *IoGLUT_glutDestroyMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
837 int menuId = IoMessage_locals_intArgAt_(m, locals, 0);
838 glutDestroyMenu(menuId);
839 return self;
842 IoObject *IoGLUT_glutAddMenuEntry(IoGLUT *self, IoObject *locals, IoMessage *m)
844 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 0);
845 int entryId = IoMessage_locals_intArgAt_(m, locals, 1);
846 glutAddMenuEntry(CSTRING(name), entryId);
847 return self;
850 IoObject *IoGLUT_glutAddSubMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
852 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 0);
853 int entryId = IoMessage_locals_intArgAt_(m, locals, 1);
854 glutAddSubMenu(CSTRING(name), entryId);
855 return self;
858 IoObject *IoGLUT_glutChangeToMenuEntry(IoGLUT *self, IoObject *locals, IoMessage *m)
860 int entryId = IoMessage_locals_intArgAt_(m, locals, 0);
861 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 1);
862 int value = IoMessage_locals_intArgAt_(m, locals, 2);
863 glutChangeToMenuEntry(entryId, CSTRING(name), value);
864 return self;
867 // GLUT_MENU_NUM_ITEMS
869 IoObject *IoGLUT_glutChangeToSubMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
871 int entryId = IoMessage_locals_intArgAt_(m, locals, 0);
872 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 1);
873 int value = IoMessage_locals_intArgAt_(m, locals, 2);
874 glutChangeToSubMenu(entryId, CSTRING(name), value);
875 return self;
878 IoObject *IoGLUT_glutRemoveMenuItem(IoGLUT *self, IoObject *locals, IoMessage *m)
880 int entry = IoMessage_locals_intArgAt_(m, locals, 0);
881 glutRemoveMenuItem(entry);
882 return self;
885 IoObject *IoGLUT_glutAttachMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
887 int button = IoMessage_locals_intArgAt_(m, locals, 0);
888 glutAttachMenu(button);
889 return self;
892 IoObject *IoGLUT_glutDetachMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
894 int button = IoMessage_locals_intArgAt_(m, locals, 0);
895 glutAttachMenu(button);
896 return self;
899 // Joystick --------------------------------------------------------------------
901 void IoGlutJoystickFunc(unsigned int buttonMask, int x, int y, int z)
903 UArray *j = IoSeq_rawUArray(DATA(proto)->j);
904 UArray *lastJ = DATA(proto)->lastJ;
905 vec3f v = {x, y, z};
907 IoSeq_setVec3f_(DATA(proto)->j, v);
908 UArray_subtract_(lastJ, j);
910 if (DATA(proto)->lastJoystickButton != buttonMask || UArray_sumAsDouble(lastJ) != 0.0) // only send callback if a change occurs
912 //printf("sum %f\n", (float)Vector_sum(lastJ));
913 //printf("b %i %i\n", (int)buttonMask, (int)DATA(proto)->lastJoystickButton);
914 IoState_pushRetainPool(IoObject_state(proto));
917 IoMessage_setCachedArg_toInt_(DATA(proto)->joystickMessage, 0, (int)buttonMask);
918 IoMessage_setCachedArg_to_(DATA(proto)->joystickMessage, 1, DATA(proto)->j);
919 IoGLUT_tryCallback(proto, DATA(proto)->joystickMessage);
922 DATA(proto)->lastJoystickButton = buttonMask;
924 IoState_popRetainPool(IoObject_state(proto));
927 UArray_copy_(lastJ, j);
931 IoObject *IoGLUT_glutInitJoystick(IoGLUT *self, IoObject *locals, IoMessage *m)
933 IoSymbol *deviceName = IoMessage_locals_symbolArgAt_(m, locals, 0);
934 // deviceName something like /dev/input/js0
935 glutInitJoystick(IoGlutJoystickFunc, CSTRING(deviceName));
936 return self;
939 IoObject *IoGLUT_glutJoystickFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
941 int pollInterval = IoMessage_locals_intArgAt_(m, locals, 0);
942 glutJoystickFunc(IoGlutJoystickFunc, pollInterval);
943 return self;
947 /* -------------------------------------------------------------------*/
949 /* can use NULL tag since the methods don't access DATA(self) - they use DATA(proto) instead */
950 #define IOCFUNCTION_GLUT(func) IOCFUNCTION(func, NULL)
952 #include "IoGLUTconst.h"
953 #include "IoGLUTfunc.h"
955 void IoGLUT_protoInit(IoGLUT *self)
957 IoObject_setSlot_to_(self,IOSYMBOL("clone"), IOCFUNCTION_GLUT(IoObject_self));
959 /* GLUT Constants */
961 t_ioGLUT_constTable *curpos=ioGLUT_constTable;
962 while (curpos->name)
964 IoObject_setSlot_to_(self,
965 IOSYMBOL(curpos->name),
966 IONUMBER(curpos->value));
967 curpos++;
971 /* GLUT Functions */
973 t_ioGLUT_funcTable *curpos=ioGLUT_funcTable;
975 while (curpos->name)
977 IoCFunction *f = IoCFunction_newWithFunctionPointer_tag_name_(IOSTATE, curpos->func, NULL, curpos->name);
978 IoObject_setSlot_to_(self, IOSYMBOL(curpos->name), f);
979 curpos++;
984 // --- Extra In --------------------------------------------------------------
986 int IoGlutAcceptsDropFunc(
987 int x,
988 int y,
989 const char *type,
990 const unsigned char *data,
991 int dataLength)
993 int result = 0;
994 IoState *state = IoObject_state(proto);
995 IoState_pushRetainPool(state);
998 IoMessage *m = DATA(proto)->acceptsDropMessage;
999 IoSymbol *typeString = IoState_symbolWithCString_(state, (char *)type);
1000 IoSeq *dataBuffer = IoSeq_newWithData_length_(state, (unsigned char *)data, dataLength);
1002 IoMessage_setCachedArg_toInt_(m, 0, x);
1003 IoMessage_setCachedArg_toInt_(m, 1, y);
1004 IoMessage_setCachedArg_to_(m, 2, typeString);
1005 IoMessage_setCachedArg_to_(m, 3, dataBuffer);
1007 if (DATA(proto)->eventTarget)
1009 IoObject *r = IoGLUT_tryCallback(proto, m);
1011 if (r && ISNUMBER(r))
1013 result = CNUMBER(r);
1018 IoState_popRetainPool(state);
1019 return result;
1022 void IoGlutDropFunc(
1023 int x,
1024 int y,
1025 const char *type,
1026 const unsigned char *data,
1027 int dataLength)
1029 IoState *state = IoObject_state(proto);
1030 IoState_pushRetainPool(state);
1033 IoMessage *m = DATA(proto)->dropMessage;
1034 IoSymbol *typeString = IoState_symbolWithCString_(state, (char *)type);
1035 IoSeq *dataBuffer = IoSeq_newWithData_length_(state, (unsigned char *)data, dataLength);
1037 IoMessage_setCachedArg_toInt_(m, 0, x);
1038 IoMessage_setCachedArg_toInt_(m, 1, y);
1039 IoMessage_setCachedArg_to_(m, 2, typeString);
1040 IoMessage_setCachedArg_to_(m, 3, dataBuffer);
1042 IoGLUT_tryCallback(proto, m);
1045 IoState_popRetainPool(state);
1048 void IoGlutPasteFunc(
1049 const char *type,
1050 const unsigned char *data,
1051 int dataLength)
1053 IoState *state = IoObject_state(proto);
1054 IoState_pushRetainPool(state);
1057 IoMessage *m = DATA(proto)->pasteMessage;
1058 IoSymbol *typeString = IoState_symbolWithCString_(state, (char *)type);
1059 IoSeq *dataBuffer = IoSeq_newWithData_length_(state, (unsigned char *)data, dataLength);
1061 IoMessage_setCachedArg_to_(m, 0, typeString);
1062 IoMessage_setCachedArg_to_(m, 1, dataBuffer);
1064 IoGLUT_tryCallback(proto, m);
1067 IoState_popRetainPool(IoObject_state(proto));
1070 void IoGlutDeleteFunc(void)
1072 IoState *state = IoObject_state(proto);
1073 IoState_pushRetainPool(state);
1074 IoGLUT_tryCallback(proto, DATA(proto)->deleteMessage);
1075 IoState_popRetainPool(state);
1079 // --- Extra Out --------------------------------------------------------------
1081 void IoGLUT_setDragCallback_(IoGLUT *self, DragCallback *func)
1083 DATA(self)->dragCallback = func;
1086 IoObject *IoGLUT_drag(IoGLUT *self, IoObject *locals, IoMessage *m)
1088 int x = IoMessage_locals_intArgAt_(m, locals, 0);
1089 int y = IoMessage_locals_intArgAt_(m, locals, 1);
1090 IoSymbol *type = IoMessage_locals_symbolArgAt_(m, locals, 2);
1091 IoSeq *buffer = IoMessage_locals_mutableSeqArgAt_(m, locals, 3);
1093 if (DATA(self)->dragCallback)
1095 (DATA(self)->dragCallback)(DATA(self)->callbackContext,
1098 CSTRING(type),
1099 IoSeq_rawBytes(buffer),
1100 IoSeq_rawSize(buffer));
1103 return IONIL(self);
1106 void IoGLUT_setCopyCallback_(IoGLUT *self, CopyCallback *func)
1108 DATA(self)->copyCallback = func;
1111 IoObject *IoGLUT_copy(IoGLUT *self, IoObject *locals, IoMessage *m)
1113 IoSymbol *type = IoMessage_locals_symbolArgAt_(m, locals, 0);
1114 IoSeq *buffer = IoMessage_locals_mutableSeqArgAt_(m, locals, 1);
1116 if (DATA(self)->copyCallback)
1118 (DATA(self)->copyCallback)(DATA(self)->callbackContext,
1119 CSTRING(type),
1120 IoSeq_rawBytes(buffer),
1121 IoSeq_rawSize(buffer));
1124 return IONIL(self);