Addons updated to new doc format
[io.git] / addons / OpenGL / source / IoGLUT.c
blobf9a3fb7378c772f53929ea1d6619c33834d601e5
2 //metadoc GLUT copyright Steve Dekorte 2002
3 //metadoc GLUT license BSD revised
4 //metadoc GLUT category Graphics
6 #include "IoGLUT.h"
8 #include "List.h"
9 #include "IoState.h"
10 #include "IoNumber.h"
11 #include "IoCFunction.h"
12 #include "IoSeq.h"
13 #include "IoList.h"
14 #include "List.h"
15 #include "IoDirectory.h"
16 #include <time.h>
18 #define DATA(self) ((IoGLUTData *)IoObject_dataPointer(self))
20 void IoGlutTimerFunc(int vv);
22 static IoGLUT *proto = NULL;
25 IoTag *IoGLUT_newTag(void *state)
27 IoTag *tag = IoTag_newWithName_("GLUT");
28 IoTag_state_(tag, state);
29 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoGLUT_rawClone);
30 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoGLUT_free);
31 IoTag_markFunc_(tag, (IoTagMarkFunc *)IoGLUT_mark);
32 return tag;
35 #define GLUTMESSAGE(name) \
36 IoMessage_newWithName_label_(state, IOSYMBOL(name), IOSYMBOL("[GLUT]"))
38 IoGLUT *IoGLUT_proto(void *state)
40 IoObject *self = IoObject_new(state);
41 /*printf("state = %p proto = %p self = %p\n", state, proto, self); */
43 proto = self;
44 IoObject_tag_(self, IoGLUT_newTag(state));
45 IoObject_setDataPointer_(self, calloc(1, sizeof(IoGLUTData)));
47 DATA(self)->coroutine = IoCoroutine_new(state);
48 //printf("GLUT coro = %p\n", DATA(self)->coroutine);
50 DATA(self)->eventTarget = NULL;
51 DATA(self)->entryMessage = GLUTMESSAGE("entry");
52 DATA(self)->displayMessage = GLUTMESSAGE("display");
53 DATA(self)->keyboardMessage = GLUTMESSAGE("keyboard");
54 DATA(self)->keyboardUpMessage = GLUTMESSAGE("keyboardUp");
55 DATA(self)->joystickMessage = GLUTMESSAGE("joystick");
56 DATA(self)->motionMessage = GLUTMESSAGE("motion");
57 DATA(self)->menuMessage = GLUTMESSAGE("menu");
58 DATA(self)->mouseMessage = GLUTMESSAGE("mouse");
59 DATA(self)->passiveMotionMessage = GLUTMESSAGE("passiveMotion");
60 DATA(self)->reshapeMessage = GLUTMESSAGE("reshape");
61 DATA(self)->specialMessage = GLUTMESSAGE("special");
62 DATA(self)->specialUpMessage = GLUTMESSAGE("specialUp");
63 DATA(self)->timerMessage = GLUTMESSAGE("timer");
65 DATA(self)->acceptsDropMessage = GLUTMESSAGE("acceptsDrop");
66 DATA(self)->dragMessage = GLUTMESSAGE("drag");
67 DATA(self)->dropMessage = GLUTMESSAGE("drop");
68 DATA(self)->copyMessage = GLUTMESSAGE("copy");
69 DATA(self)->pasteMessage = GLUTMESSAGE("paste");
70 DATA(self)->deleteMessage = GLUTMESSAGE("delete");
71 DATA(self)->nanoSleepPeriod = 1000000000/2;
76 //printf("GLUT coro = %p\n", (void *)DATA(self)->coroutine);
77 IoState_retain_(state, self);
78 IoState_retain_(state, DATA(self)->coroutine);
79 IoState_retain_(state, DATA(self)->displayMessage);
80 IoState_retain_(state, DATA(self)->reshapeMessage);
81 IoState_retain_(state, DATA(self)->timerMessage);
85 DATA(self)->j = IoSeq_newFloatArrayOfSize_(state, 0);
86 DATA(self)->lastJ = UArray_new();
87 UArray_setItemType_(DATA(self)->lastJ, CTYPE_float32_t);
89 IoState_registerProtoWithFunc_(state, self, IoGLUT_proto);
92 //-----------------------------
94 IoState_retain_(state, DATA(self)->j);
96 IoState_retain_(state, DATA(self)->coroutine);
97 IoState_retain_(state, DATA(self)->entryMessage);
98 IoState_retain_(state, DATA(self)->displayMessage);
99 IoState_retain_(state, DATA(self)->keyboardMessage);
100 IoState_retain_(state, DATA(self)->keyboardUpMessage);
101 IoState_retain_(state, DATA(self)->joystickMessage);
102 IoState_retain_(state, DATA(self)->menuMessage);
103 IoState_retain_(state, DATA(self)->mouseMessage);
104 IoState_retain_(state, DATA(self)->motionMessage);
105 IoState_retain_(state, DATA(self)->passiveMotionMessage);
106 IoState_retain_(state, DATA(self)->reshapeMessage);
107 IoState_retain_(state, DATA(self)->specialMessage);
108 IoState_retain_(state, DATA(self)->specialUpMessage);
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)->specialUpMessage);
157 IoObject_shouldMark(DATA(self)->timerMessage);
159 IoObject_shouldMark(DATA(self)->acceptsDropMessage);
160 IoObject_shouldMark(DATA(self)->dragMessage);
161 IoObject_shouldMark(DATA(self)->dropMessage);
162 IoObject_shouldMark(DATA(self)->copyMessage);
163 IoObject_shouldMark(DATA(self)->pasteMessage);
164 IoObject_shouldMark(DATA(self)->deleteMessage);
167 /* ----------------------------------------------------------- */
169 IoObject *IoGLUT_rawClone(IoGLUT *self)
171 return IoState_protoWithInitFunction_(IOSTATE, IoGLUT_proto);
174 /* ----------------------------------------------------------- */
176 IoObject *IoGLUT_glutInitDisplayMode(IoGLUT *self, IoObject *locals, IoMessage *m)
178 int mode = IoMessage_locals_intArgAt_(m, locals, 0);
179 glutInitDisplayMode(mode);
180 return self;
183 IoObject *IoGLUT_glutInitWindowSize(IoGLUT *self, IoObject *locals, IoMessage *m)
185 int w = IoMessage_locals_intArgAt_(m, locals, 0);
186 int h = IoMessage_locals_intArgAt_(m, locals, 1);
187 //printf("glutInitWindowSize(%i, %i)\n", w, h);
188 glutInitWindowSize(w, h);
189 return self;
192 IoObject *IoGLUT_glutInitWindowPosition(IoGLUT *self, IoObject *locals, IoMessage *m)
194 int x = IoMessage_locals_intArgAt_(m, locals, 0);
195 int y = IoMessage_locals_intArgAt_(m, locals, 1);
196 //printf("glutInitWindowPosition(%i, %i)\n", x, y);
197 glutInitWindowPosition(x, y);
198 return self;
201 void IoGlutIdleFunc(void)
203 //IoState_yield(IoObject_state(proto));
206 IoObject *IoGLUT_glutInit(IoGLUT *self, IoObject *locals, IoMessage *m)
208 IoState *state = IOSTATE;
209 int argc = state->mainArgs->argc;
210 UArray *ba = IoDirectory_CurrentWorkingDirectoryAsUArray();
211 glutInit(&argc, (char **)(state->mainArgs->argv));
212 IoDirectory_SetCurrentWorkingDirectory(UArray_asCString(ba));
213 UArray_free(ba);
215 //glutIdleFunc(IoGlutIdleFunc);
216 //glutTimerFunc((unsigned int)10, IoGlutTimerFunc, -1);
217 return self;
220 IoObject *IoGLUT_glutInitDisplayString(IoGLUT *self, IoObject *locals, IoMessage *m)
222 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
223 glutInitDisplayString(IoSeq_asCString(s));
224 return self;
227 IoObject *IoGLUT_glutCreateWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
229 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
230 int windowId = glutCreateWindow(IoSeq_asCString(s));
231 return IONUMBER(windowId);
234 IoObject *IoGLUT_glutCreateSubWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
236 int win = IoMessage_locals_intArgAt_(m, locals, 0);
237 int x = IoMessage_locals_intArgAt_(m, locals, 1);
238 int y = IoMessage_locals_intArgAt_(m, locals, 2);
239 int w = IoMessage_locals_intArgAt_(m, locals, 3);
240 int h = IoMessage_locals_intArgAt_(m, locals, 4);
241 return IONUMBER(glutCreateSubWindow(win, x, y, w, h));
244 IoObject *IoGLUT_glutSetWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
246 int win = IoMessage_locals_intArgAt_(m, locals, 0);
247 glutSetWindow(win);
248 return self;
251 IoObject *IoGLUT_glutGetWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
253 return IONUMBER(glutGetWindow());
256 IoObject *IoGLUT_glutGet(IoGLUT *self, IoObject *locals, IoMessage *m)
258 GLenum n = IoMessage_locals_intArgAt_(m, locals, 0);
259 return IONUMBER(glutGet(n));
262 IoObject *IoGLUT_glutDestroyWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
264 int win = IoMessage_locals_intArgAt_(m, locals, 0);
265 glutDestroyWindow(win);
266 return self;
269 IoObject *IoGLUT_glutPositionWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
271 int x = IoMessage_locals_intArgAt_(m, locals, 0);
272 int y = IoMessage_locals_intArgAt_(m, locals, 1);
273 glutPositionWindow(x, y);
274 return self;
277 IoObject *IoGLUT_glutReshapeWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
279 int w = IoMessage_locals_intArgAt_(m, locals, 0);
280 int h = IoMessage_locals_intArgAt_(m, locals, 1);
281 glutReshapeWindow(w, h);
282 return self;
285 IoObject *IoGLUT_glutPopWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
287 glutPopWindow(); return self;
290 IoObject *IoGLUT_glutPushWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
292 glutPushWindow();
293 return self;
296 IoObject *IoGLUT_glutShowWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
298 glutShowWindow();
299 return self;
302 IoObject *IoGLUT_glutHideWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
304 glutHideWindow();
305 return self;
308 IoObject *IoGLUT_glutIconifyWindow(IoGLUT *self, IoObject *locals, IoMessage *m)
310 glutIconifyWindow();
311 return self;
314 IoObject *IoGLUT_glutSetWindowTitle(IoGLUT *self, IoObject *locals, IoMessage *m)
316 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
317 glutSetWindowTitle(CSTRING(s));
318 return self;
321 IoObject *IoGLUT_glutSetIconTitle(IoGLUT *self, IoObject *locals, IoMessage *m)
323 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
324 glutSetIconTitle(CSTRING(s));
325 return self;
328 IoObject *IoGLUT_glutEventTarget_(IoGLUT *self, IoObject *locals, IoMessage *m)
330 DATA(proto)->eventTarget = IOREF(IoMessage_locals_valueArgAt_(m, locals, 0));
331 return self;
334 // events
336 void IoGlutDisplayFunc(void)
338 //printf("IoGlutDisplayFunc\n");
339 IoState_pushRetainPool(IoObject_state(proto));
341 IoGLUT_tryCallback(proto, DATA(proto)->displayMessage);
343 IoState_popRetainPool(IoObject_state(proto));
346 IoObject *IoGLUT_glutDisplayFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
348 glutDisplayFunc(IoGlutDisplayFunc);
349 return self;
352 void IoGlutKeyboardFunc(unsigned char key, int xv, int yv)
354 IoState_pushRetainPool(IoObject_state(proto));
355 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 0, (int)key);
356 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 1, xv);
357 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 2, yv);
359 IoGLUT_tryCallback(proto, DATA(proto)->keyboardMessage);
361 IoState_popRetainPool(IoObject_state(proto));
364 IoObject *IoGLUT_glutKeyboardFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
366 glutKeyboardFunc(IoGlutKeyboardFunc);
367 return self;
370 void IoGlutSpecialFunc(int key, int xv, int yv)
372 IoState_pushRetainPool(IoObject_state(proto));
373 IoMessage_setCachedArg_toInt_(DATA(proto)->specialMessage, 0, (int)key);
374 IoMessage_setCachedArg_toInt_(DATA(proto)->specialMessage, 1, xv);
375 IoMessage_setCachedArg_toInt_(DATA(proto)->specialMessage, 2, yv);
377 IoGLUT_tryCallback(proto, DATA(proto)->specialMessage);
379 IoState_popRetainPool(IoObject_state(proto));
382 IoObject *IoGLUT_glutSpecialFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
384 glutSpecialFunc(IoGlutSpecialFunc);
385 return self;
388 void IoGlutKeyboardUpFunc(unsigned char key, int xv, int yv)
390 IoState_pushRetainPool(IoObject_state(proto));
391 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardUpMessage, 0, (int)key);
392 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardUpMessage, 1, xv);
393 IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardUpMessage, 2, yv);
395 IoGLUT_tryCallback(proto, DATA(proto)->keyboardUpMessage);
397 IoState_popRetainPool(IoObject_state(proto));
400 IoObject *IoGLUT_glutKeyboardUpFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
402 #if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
403 glutKeyboardUpFunc(IoGlutKeyboardUpFunc);
404 return self;
405 #endif
408 void IoGlutSpecialUpFunc(int key, int xv, int yv)
410 IoState_pushRetainPool(IoObject_state(proto));
411 IoMessage_setCachedArg_toInt_(DATA(proto)->specialUpMessage, 0, (int)key);
412 IoMessage_setCachedArg_toInt_(DATA(proto)->specialUpMessage, 1, xv);
413 IoMessage_setCachedArg_toInt_(DATA(proto)->specialUpMessage, 2, yv);
415 IoGLUT_tryCallback(proto, DATA(proto)->specialUpMessage);
417 IoState_popRetainPool(IoObject_state(proto));
420 IoObject *IoGLUT_glutSpecialUpFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
422 #if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
423 glutSpecialUpFunc(IoGlutSpecialUpFunc);
424 return self;
425 #endif
428 IoObject *IoGLUT_glutGetModifiers(IoGLUT *self, IoObject *locals, IoMessage *m)
430 return IONUMBER(glutGetModifiers());
433 void IoGlutEntryFunc(int state)
435 IoState_pushRetainPool(IoObject_state(proto));
436 IoMessage_setCachedArg_toInt_(DATA(proto)->entryMessage, 0, state);
438 IoGLUT_tryCallback(proto, DATA(proto)->entryMessage);
440 IoState_popRetainPool(IoObject_state(proto));
443 IoObject *IoGLUT_glutEntryFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
445 glutEntryFunc(IoGlutEntryFunc); return self;
448 void IoGlutMotionFunc(int xv, int yv)
450 IoState_pushRetainPool(IoObject_state(proto));
453 IoMessage_setCachedArg_toInt_(DATA(proto)->motionMessage, 0, xv);
454 IoMessage_setCachedArg_toInt_(DATA(proto)->motionMessage, 1, yv);
456 IoGLUT_tryCallback(proto, DATA(proto)->motionMessage);
459 IoState_popRetainPool(IoObject_state(proto));
462 IoObject *IoGLUT_glutMotionFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
464 glutMotionFunc(IoGlutMotionFunc);
465 return self;
468 void IoGlutPassiveMotionFunc(int xv, int yv)
470 IoState_pushRetainPool(IoObject_state(proto));
473 IoMessage_setCachedArg_toInt_(DATA(proto)->passiveMotionMessage, 0, xv);
474 IoMessage_setCachedArg_toInt_(DATA(proto)->passiveMotionMessage, 1, yv);
476 IoGLUT_tryCallback(proto, DATA(proto)->passiveMotionMessage);
479 IoState_popRetainPool(IoObject_state(proto));
482 IoObject *IoGLUT_glutPassiveMotionFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
484 glutPassiveMotionFunc(IoGlutPassiveMotionFunc);
485 return self;
488 void IoGlutMouseFunc(int button, int state, int xv, int yv)
490 IoState_pushRetainPool(IoObject_state(proto));
493 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 0, button);
494 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 1, state);
495 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 2, xv);
496 IoMessage_setCachedArg_toInt_(DATA(proto)->mouseMessage, 3, yv);
498 IoGLUT_tryCallback(proto, DATA(proto)->mouseMessage);
501 IoState_popRetainPool(IoObject_state(proto));
504 IoObject *IoGLUT_glutMouseFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
506 glutMouseFunc(IoGlutMouseFunc);
507 return self;
510 void IoGlutReshapeFunc(int width, int height)
512 //printf("IoGlutReshapeFunc\n");
513 IoState_pushRetainPool(IoObject_state(proto));
515 IoMessage_setCachedArg_toInt_(DATA(proto)->reshapeMessage, 0, width?width:1);
516 IoMessage_setCachedArg_toInt_(DATA(proto)->reshapeMessage, 1, height?height:1);
518 IoGLUT_tryCallback(proto, DATA(proto)->reshapeMessage);
521 IoState_popRetainPool(IoObject_state(proto));
524 IoObject *IoGLUT_glutReshapeFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
526 glutReshapeFunc(IoGlutReshapeFunc);
527 return self;
530 void IoGlutTimerFunc(int vv)
532 IoState *state = IoObject_state(proto);
534 //printf("IoGlutTimerFunc\n");
536 IoState_pushRetainPool(state);
538 if (vv == -1)
540 //IoState_yield(IoObject_state(proto));
541 glutTimerFunc((unsigned int)100, IoGlutTimerFunc, -1);
543 else
545 IoObject *m = DATA(proto)->timerMessage;
546 IoMessage_setCachedArg_toInt_(m, 0, vv);
547 IoGLUT_tryCallback(proto, m);
549 IoState_popRetainPool(state);
552 IoObject *IoGLUT_glutTimerFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
554 unsigned int msecs = IoMessage_locals_longArgAt_(m, locals, 0);
555 int v = IoMessage_locals_intArgAt_(m, locals, 1);
556 //printf("IoGLUT_glutTimerFunc msecs %i v %i\n", msecs, v);
557 glutTimerFunc((unsigned int)msecs, IoGlutTimerFunc, v);
558 return self;
561 IoObject *IoGLUT_tryCallback(IoGLUT *self, IoMessage *m)
563 IoState *state = IoObject_state(proto);
564 IoObject *tryCoro = DATA(self)->coroutine;
565 IoObject *t = DATA(proto)->eventTarget;
566 IoObject *result = state->ioNil;
568 //printf("IoGLUT_tryCallback(self, %p)\n", (void *)m);
570 if (t)
572 //result = IoState_tryToPerform(state, t, t, m);
575 //IoCoroutine_try(tryCoro, t, t, m);
576 IoMessage_locals_performOn_(m, t, t);
578 if (IoCoroutine_rawException(tryCoro) != state->ioNil)
580 IoState_exception_(state, tryCoro);
583 IoCoroutine_clearStack(tryCoro);
584 return IoCoroutine_rawResult(tryCoro);
587 return result;
590 #ifdef GLUT_KEY_REPEAT_ON
591 IoObject *IoGLUT_glutIgnoreKeyRepeat(IoGLUT *self, IoObject *locals, IoMessage *m)
593 int v = IoMessage_locals_intArgAt_(m, locals, 0);
594 glutIgnoreKeyRepeat(v);
595 return self;
597 #endif
599 IoObject *IoGLUT_glutMainLoop(IoGLUT *self, IoObject *locals, IoMessage *m)
601 glutMainLoop();
602 return self;
605 IoObject *IoGLUT_glutPostRedisplay(IoGLUT *self, IoObject *locals, IoMessage *m)
607 glutPostRedisplay();
608 return self;
611 IoObject *IoGLUT_glutSwapBuffers(IoGLUT *self, IoObject *locals, IoMessage *m)
613 glutSwapBuffers();
614 return self;
617 IoObject *IoGLUT_glutSolidCone(IoGLUT *self, IoObject *locals, IoMessage *m)
619 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
620 GLdouble height = IoMessage_locals_intArgAt_(m, locals, 1);
621 GLint slices = IoMessage_locals_intArgAt_(m, locals, 2);
622 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 3);
623 glutSolidCone(radius, height, slices, stacks);
624 return self;
627 IoObject *IoGLUT_glutWireCone(IoGLUT *self, IoObject *locals, IoMessage *m)
629 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
630 GLdouble height = IoMessage_locals_intArgAt_(m, locals, 1);
631 GLint slices = IoMessage_locals_intArgAt_(m, locals, 2);
632 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 3);
633 glutWireCone(radius, height, slices, stacks);
634 return self;
637 IoObject *IoGLUT_glutSolidSphere(IoGLUT *self, IoObject *locals, IoMessage *m)
639 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
640 GLint slices = IoMessage_locals_intArgAt_(m, locals, 1);
641 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 2);
642 glutSolidSphere(radius, slices, stacks);
643 return self;
646 IoObject *IoGLUT_glutWireSphere(IoGLUT *self, IoObject *locals, IoMessage *m)
648 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
649 GLint slices = IoMessage_locals_intArgAt_(m, locals, 1);
650 GLint stacks = IoMessage_locals_intArgAt_(m, locals, 2);
651 glutWireSphere(radius, slices, stacks);
652 return self;
655 IoObject *IoGLUT_glutSolidTorus(IoGLUT *self, IoObject *locals, IoMessage *m)
657 GLdouble innerRadius = IoMessage_locals_doubleArgAt_(m, locals, 0);
658 GLdouble outerRadius = IoMessage_locals_doubleArgAt_(m, locals, 1);
659 GLint nsides = IoMessage_locals_intArgAt_(m, locals, 2);
660 GLint rings = IoMessage_locals_intArgAt_(m, locals, 3);
661 glutSolidTorus(innerRadius, outerRadius, nsides, rings);
662 return self;
665 IoObject *IoGLUT_glutWireTorus(IoGLUT *self, IoObject *locals, IoMessage *m)
667 GLdouble innerRadius = IoMessage_locals_doubleArgAt_(m, locals, 0);
668 GLdouble outerRadius = IoMessage_locals_doubleArgAt_(m, locals, 1);
669 GLint nsides = IoMessage_locals_intArgAt_(m, locals, 2);
670 GLint rings = IoMessage_locals_intArgAt_(m, locals, 3);
671 glutWireTorus(innerRadius, outerRadius, nsides, rings);
672 return self;
675 IoObject *IoGLUT_glutSolidDodecahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
677 glutSolidDodecahedron();
678 return self;
681 IoObject *IoGLUT_glutWireDodecahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
683 glutWireDodecahedron();
684 return self;
687 IoObject *IoGLUT_glutSolidOctahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
689 glutSolidOctahedron();
690 return self;
693 IoObject *IoGLUT_glutWireOctahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
695 glutWireOctahedron();
696 return self;
699 IoObject *IoGLUT_glutSolidTetrahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
701 glutSolidTetrahedron();
702 return self;
705 IoObject *IoGLUT_glutWireTetrahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
707 glutWireTetrahedron();
708 return self;
711 IoObject *IoGLUT_glutSolidIcosahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
713 glutSolidIcosahedron();
714 return self;
717 IoObject *IoGLUT_glutWireIcosahedron(IoGLUT *self, IoObject *locals, IoMessage *m)
719 glutWireIcosahedron();
720 return self;
723 IoObject *IoGLUT_glutSolidTeapot(IoGLUT *self, IoObject *locals, IoMessage *m)
725 GLdouble r = IoMessage_locals_doubleArgAt_(m, locals, 0);
726 glutSolidTeapot(r);
727 return self;
730 IoObject *IoGLUT_glutWireTeapot(IoGLUT *self, IoObject *locals, IoMessage *m)
732 GLdouble r = IoMessage_locals_doubleArgAt_(m, locals, 0);
733 glutWireTeapot(r);
734 return self;
737 IoObject *IoGLUT_glutSolidCube(IoGLUT *self, IoObject *locals, IoMessage *m)
739 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
740 glutSolidCube(radius);
741 return self;
744 IoObject *IoGLUT_glutWireCube(IoGLUT *self, IoObject *locals, IoMessage *m)
746 GLdouble radius = IoMessage_locals_doubleArgAt_(m, locals, 0);
747 glutWireCube(radius);
748 return self;
751 IoObject *IoGLUT_glutStrokeCharacter(IoGLUT *self, IoObject *locals, IoMessage *m)
753 int fontNum = IoMessage_locals_intArgAt_(m, locals, 0);
754 char c = IoMessage_locals_intArgAt_(m, locals, 1);
755 void *font = GLUT_STROKE_ROMAN;
756 if (fontNum) font = GLUT_STROKE_MONO_ROMAN;
757 glutStrokeCharacter(font, c);
758 return self;
761 IoObject *IoGLUT_glutStrokeString(IoGLUT *self, IoObject *locals, IoMessage *m)
763 int fontNum = IoMessage_locals_intArgAt_(m, locals, 0);
764 IoSymbol *string = IoMessage_locals_seqArgAt_(m, locals, 1);
765 char *s = CSTRING(string);
766 void *font = GLUT_STROKE_ROMAN;
767 if (fontNum) font = GLUT_STROKE_MONO_ROMAN;
769 while (*s)
771 glutStrokeCharacter(font, *s);
772 s++;
775 return self;
778 /* --- GLUT game mode ----------------------------------------------------- */
780 IoObject *IoGLUT_glutFullScreen(IoGLUT *self, IoObject *locals, IoMessage *m)
782 glutFullScreen();
783 return self;
786 #ifdef GLUT_GAME_MODE_ACTIVE
788 IoObject *IoGLUT_glutEnterGameMode(IoGLUT *self, IoObject *locals, IoMessage *m)
790 glutEnterGameMode();
791 return self;
794 IoObject *IoGLUT_glutLeaveGameMode(IoGLUT *self, IoObject *locals, IoMessage *m)
796 glutLeaveGameMode();
797 return self;
800 IoObject *IoGLUT_glutWarpPointer(IoGLUT *self, IoObject *locals, IoMessage *m)
802 int x = IoMessage_locals_intArgAt_(m, locals, 0);
803 int y = IoMessage_locals_intArgAt_(m, locals, 1);
804 glutWarpPointer(x, y);
805 return self;
808 IoObject *IoGLUT_glutGameModeString(IoGLUT *self, IoObject *locals, IoMessage *m)
810 IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
811 glutGameModeString(IoSeq_asCString(s));
812 return self;
815 #endif
817 IoObject *IoGLUT_glutSetCursor(IoGLUT *self, IoObject *locals, IoMessage *m)
819 int x = IoMessage_locals_intArgAt_(m, locals, 0);
820 glutSetCursor(x);
821 return self;
824 // Menus --------------------------------------------------------------------
826 void IoGlutMenuFunc(int menuId)
828 IoState_pushRetainPool(IoObject_state(proto));
831 IoMessage_setCachedArg_toInt_(DATA(proto)->menuMessage, 0, menuId);
832 IoGLUT_tryCallback(proto, DATA(proto)->menuMessage);
835 IoState_popRetainPool(IoObject_state(proto));
838 IoObject *IoGLUT_glutCreateMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
840 int menuId = glutCreateMenu(IoGlutMenuFunc);
841 return IONUMBER(menuId);
844 IoObject *IoGLUT_glutSetMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
846 int menuId = IoMessage_locals_intArgAt_(m, locals, 0);
847 glutSetMenu(menuId);
848 return self;
851 IoObject *IoGLUT_glutGetMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
853 return IONUMBER(glutGetMenu());
856 IoObject *IoGLUT_glutDestroyMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
858 int menuId = IoMessage_locals_intArgAt_(m, locals, 0);
859 glutDestroyMenu(menuId);
860 return self;
863 IoObject *IoGLUT_glutAddMenuEntry(IoGLUT *self, IoObject *locals, IoMessage *m)
865 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 0);
866 int entryId = IoMessage_locals_intArgAt_(m, locals, 1);
867 glutAddMenuEntry(CSTRING(name), entryId);
868 return self;
871 IoObject *IoGLUT_glutAddSubMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
873 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 0);
874 int entryId = IoMessage_locals_intArgAt_(m, locals, 1);
875 glutAddSubMenu(CSTRING(name), entryId);
876 return self;
879 IoObject *IoGLUT_glutChangeToMenuEntry(IoGLUT *self, IoObject *locals, IoMessage *m)
881 int entryId = IoMessage_locals_intArgAt_(m, locals, 0);
882 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 1);
883 int value = IoMessage_locals_intArgAt_(m, locals, 2);
884 glutChangeToMenuEntry(entryId, CSTRING(name), value);
885 return self;
888 // GLUT_MENU_NUM_ITEMS
890 IoObject *IoGLUT_glutChangeToSubMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
892 int entryId = IoMessage_locals_intArgAt_(m, locals, 0);
893 IoSymbol *name = IoMessage_locals_symbolArgAt_(m, locals, 1);
894 int value = IoMessage_locals_intArgAt_(m, locals, 2);
895 glutChangeToSubMenu(entryId, CSTRING(name), value);
896 return self;
899 IoObject *IoGLUT_glutRemoveMenuItem(IoGLUT *self, IoObject *locals, IoMessage *m)
901 int entry = IoMessage_locals_intArgAt_(m, locals, 0);
902 glutRemoveMenuItem(entry);
903 return self;
906 IoObject *IoGLUT_glutAttachMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
908 int button = IoMessage_locals_intArgAt_(m, locals, 0);
909 glutAttachMenu(button);
910 return self;
913 IoObject *IoGLUT_glutDetachMenu(IoGLUT *self, IoObject *locals, IoMessage *m)
915 int button = IoMessage_locals_intArgAt_(m, locals, 0);
916 glutAttachMenu(button);
917 return self;
920 // Joystick --------------------------------------------------------------------
922 void IoGlutJoystickFunc(unsigned int buttonMask, int x, int y, int z)
924 UArray *j = IoSeq_rawUArray(DATA(proto)->j);
925 UArray *lastJ = DATA(proto)->lastJ;
926 vec3f v = (vec3f){x, y, z};
928 IoSeq_setVec3f_(DATA(proto)->j, v);
929 UArray_subtract_(lastJ, j);
931 if (DATA(proto)->lastJoystickButton != buttonMask || UArray_sumAsDouble(lastJ) != 0.0) // only send callback if a change occurs
933 //printf("sum %f\n", (float)Vector_sum(lastJ));
934 //printf("b %i %i\n", (int)buttonMask, (int)DATA(proto)->lastJoystickButton);
935 IoState_pushRetainPool(IoObject_state(proto));
938 IoMessage_setCachedArg_toInt_(DATA(proto)->joystickMessage, 0, (int)buttonMask);
939 IoMessage_setCachedArg_to_(DATA(proto)->joystickMessage, 1, DATA(proto)->j);
940 IoGLUT_tryCallback(proto, DATA(proto)->joystickMessage);
943 DATA(proto)->lastJoystickButton = buttonMask;
945 IoState_popRetainPool(IoObject_state(proto));
948 UArray_copy_(lastJ, j);
952 IoObject *IoGLUT_glutInitJoystick(IoGLUT *self, IoObject *locals, IoMessage *m)
954 IoSymbol *deviceName = IoMessage_locals_symbolArgAt_(m, locals, 0);
955 // deviceName something like /dev/input/js0
956 glutInitJoystick(IoGlutJoystickFunc, CSTRING(deviceName));
957 return self;
960 IoObject *IoGLUT_glutJoystickFunc(IoGLUT *self, IoObject *locals, IoMessage *m)
962 int pollInterval = IoMessage_locals_intArgAt_(m, locals, 0);
963 glutJoystickFunc(IoGlutJoystickFunc, pollInterval);
964 return self;
968 /* -------------------------------------------------------------------*/
970 /* can use NULL tag since the methods don't access DATA(self) - they use DATA(proto) instead */
971 #define IOCFUNCTION_GLUT(func) IOCFUNCTION(func, NULL)
973 #include "IoGLUTconst.h"
974 #include "IoGLUTfunc.h"
976 void IoGLUT_protoInit(IoGLUT *self)
978 IoObject_setSlot_to_(self,IOSYMBOL("clone"), IOCFUNCTION_GLUT(IoObject_self));
980 /* GLUT Constants */
982 t_ioGLUT_constTable *curpos=ioGLUT_constTable;
983 while (curpos->name)
985 IoObject_setSlot_to_(self,
986 IOSYMBOL(curpos->name),
987 IONUMBER(curpos->value));
988 curpos++;
992 /* GLUT Functions */
994 t_ioGLUT_funcTable *curpos=ioGLUT_funcTable;
996 while (curpos->name)
998 IoCFunction *f = IoCFunction_newWithFunctionPointer_tag_name_(IOSTATE, curpos->func, NULL, curpos->name);
999 IoObject_setSlot_to_(self, IOSYMBOL(curpos->name), f);
1000 curpos++;
1005 // --- Extra In --------------------------------------------------------------
1007 int IoGlutAcceptsDropFunc(
1008 int x,
1009 int y,
1010 const char *type,
1011 const unsigned char *data,
1012 int dataLength)
1014 int result = 0;
1015 IoState *state = IoObject_state(proto);
1016 IoState_pushRetainPool(state);
1019 IoMessage *m = DATA(proto)->acceptsDropMessage;
1020 IoSymbol *typeString = IoState_symbolWithCString_(state, (char *)type);
1021 IoSeq *dataBuffer = IoSeq_newWithData_length_(state, (unsigned char *)data, dataLength);
1023 IoMessage_setCachedArg_toInt_(m, 0, x);
1024 IoMessage_setCachedArg_toInt_(m, 1, y);
1025 IoMessage_setCachedArg_to_(m, 2, typeString);
1026 IoMessage_setCachedArg_to_(m, 3, dataBuffer);
1028 if (DATA(proto)->eventTarget)
1030 IoObject *r = IoGLUT_tryCallback(proto, m);
1032 if (r && ISNUMBER(r))
1034 result = CNUMBER(r);
1039 IoState_popRetainPool(state);
1040 return result;
1043 void IoGlutDropFunc(
1044 int x,
1045 int y,
1046 const char *type,
1047 const unsigned char *data,
1048 int dataLength)
1050 IoState *state = IoObject_state(proto);
1051 IoState_pushRetainPool(state);
1054 IoMessage *m = DATA(proto)->dropMessage;
1055 IoSymbol *typeString = IoState_symbolWithCString_(state, (char *)type);
1056 IoSeq *dataBuffer = IoSeq_newWithData_length_(state, (unsigned char *)data, dataLength);
1058 IoMessage_setCachedArg_toInt_(m, 0, x);
1059 IoMessage_setCachedArg_toInt_(m, 1, y);
1060 IoMessage_setCachedArg_to_(m, 2, typeString);
1061 IoMessage_setCachedArg_to_(m, 3, dataBuffer);
1063 IoGLUT_tryCallback(proto, m);
1066 IoState_popRetainPool(state);
1069 void IoGlutPasteFunc(
1070 const char *type,
1071 const unsigned char *data,
1072 int dataLength)
1074 IoState *state = IoObject_state(proto);
1075 IoState_pushRetainPool(state);
1078 IoMessage *m = DATA(proto)->pasteMessage;
1079 IoSymbol *typeString = IoState_symbolWithCString_(state, (char *)type);
1080 IoSeq *dataBuffer = IoSeq_newWithData_length_(state, (unsigned char *)data, dataLength);
1082 IoMessage_setCachedArg_to_(m, 0, typeString);
1083 IoMessage_setCachedArg_to_(m, 1, dataBuffer);
1085 IoGLUT_tryCallback(proto, m);
1088 IoState_popRetainPool(IoObject_state(proto));
1091 void IoGlutDeleteFunc(void)
1093 IoState *state = IoObject_state(proto);
1094 IoState_pushRetainPool(state);
1095 IoGLUT_tryCallback(proto, DATA(proto)->deleteMessage);
1096 IoState_popRetainPool(state);
1100 // --- Extra Out --------------------------------------------------------------
1102 void IoGLUT_setDragCallback_(IoGLUT *self, DragCallback *func)
1104 DATA(self)->dragCallback = func;
1107 IoObject *IoGLUT_drag(IoGLUT *self, IoObject *locals, IoMessage *m)
1109 int x = IoMessage_locals_intArgAt_(m, locals, 0);
1110 int y = IoMessage_locals_intArgAt_(m, locals, 1);
1111 IoSymbol *type = IoMessage_locals_symbolArgAt_(m, locals, 2);
1112 IoSeq *buffer = IoMessage_locals_mutableSeqArgAt_(m, locals, 3);
1114 if (DATA(self)->dragCallback)
1116 (DATA(self)->dragCallback)(DATA(self)->callbackContext,
1119 CSTRING(type),
1120 IoSeq_rawBytes(buffer),
1121 IoSeq_rawSize(buffer));
1124 return IONIL(self);
1127 void IoGLUT_setCopyCallback_(IoGLUT *self, CopyCallback *func)
1129 DATA(self)->copyCallback = func;
1132 IoObject *IoGLUT_copy(IoGLUT *self, IoObject *locals, IoMessage *m)
1134 IoSymbol *type = IoMessage_locals_symbolArgAt_(m, locals, 0);
1135 IoSeq *buffer = IoMessage_locals_mutableSeqArgAt_(m, locals, 1);
1137 if (DATA(self)->copyCallback)
1139 (DATA(self)->copyCallback)(DATA(self)->callbackContext,
1140 CSTRING(type),
1141 IoSeq_rawBytes(buffer),
1142 IoSeq_rawSize(buffer));
1145 return IONIL(self);