disabled glXGetProcAddress code
[mesa.git] / src / glut / ggi / ggiglut.c
1 /* **************************************************************************
2 * ggiglut.c
3 * **************************************************************************
4 *
5 * Copyright (C) 1998 Uwe Maurer - uwe_maurer@t-online.de
6 * Copyright (C) 1999 James Simmons
7 * Copyright (C) 1999 Jon Taylor
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * **************************************************************************
24 * To-do:
25 * - Make everything use the portable ggi_* types
26 *
27 */
28
29 #define WIDTH 640
30 #define HEIGHT 480
31 #define GRAPHTYPE_RGB GT_16BIT
32 #define GRAPHTYPE_INDEX GT_8BIT
33
34 /*************************************************************************/
35
36 #include <GL/gl.h>
37 #include <GL/glu.h>
38 #include <GL/glut.h>
39 #include <malloc.h>
40 #include <stdio.h>
41 #include <stdarg.h>
42 #include <string.h>
43 #include "GL/ggimesa.h"
44
45 #include <ggi/ggi.h>
46 #include <ggi/gii.h>
47
48 char *__glutProgramName = "GGI";
49
50 static ggi_visual_t __glut_vis;
51
52 static GGIMesaContext __glut_ctx;
53
54 //static int __glut_width = WIDTH;
55 //static int __glut_height = HEIGHT;
56 //static ggi_graphtype __glut_gt_rgb = GRAPHTYPE_RGB;
57 //static ggi_graphtype __glut_gt_index = GRAPHTYPE_INDEX;
58 static int __glut_width = GGI_AUTO;
59 static int __glut_height = GGI_AUTO;
60 static ggi_graphtype __glut_gt_rgb = GT_AUTO;
61 static ggi_graphtype __glut_gt_index = GT_8BIT;
62 static int __glut_init = GL_FALSE;
63
64 static int mousex = WIDTH / 2;
65 static int mousey = HEIGHT / 2;
66 static int mouse_moved = GL_FALSE;
67 static int mouse_down = GL_FALSE;
68 static int mouse_showcursor = GL_FALSE;
69
70 static void (*__glut_reshape)(int, int);
71 static void (*__glut_display)(void);
72 static void (*__glut_idle)(void);
73 static void (*__glut_keyboard)(unsigned char, int, int);
74 static void (*__glut_special)(int, int, int);
75 static void (*__glut_mouse)(int, int, int, int);
76 static void (*__glut_motion)(int, int);
77 static void (*__glut_passive_motion)(int, int);
78 static void (*__glut_visibility)(int);
79
80 static unsigned int __glut_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
81
82 static int __glut_mod_keys = 0;
83
84 static int __glut_redisplay = GL_FALSE;
85
86 /* Menu */
87 static int __glut_menubutton = -1;
88 static int __glut_menuactive = GL_FALSE;
89
90 #define MAX_ENTRIES 64
91
92 typedef struct menu_s
93 {
94 char *label[MAX_ENTRIES];
95 int value[MAX_ENTRIES];
96 struct menu_s * submenu[MAX_ENTRIES];
97 void (*func)(int);
98 int max_strlen;
99 int num_entries;
100 } menu_t;
101
102 static menu_t *mainmenu;
103 static menu_t *curmenu;
104 static menu_t *activemenu;
105
106 int glut_ggi_debug = GL_FALSE;
107
108 void glut_ggiPRINT(char *format, ...)
109 {
110 va_list args;
111 va_start(args, format);
112 fprintf(stderr, "GGIGLUT: ");
113 vfprintf(stderr, format, args);
114 va_end(args);
115 }
116
117 void glut_ggiDEBUG(char *format, ...)
118 {
119 va_list args;
120 if (glut_ggi_debug)
121 {
122 va_start(args, format);
123 fprintf(stderr, "GGIGLUT: ");
124 vfprintf(stderr, format, args);
125 va_end(args);
126 }
127 }
128
129 void glutInit(int *argc, char **argv)
130 {
131 ggi_graphtype gt;
132 int i, k;
133 char *s;
134
135 #define REMOVE {for (k=i;k<*argc-1;k++) argv[k]=argv[k+1]; \
136 (*argc)--; i--; }
137
138 if (__glut_init) return;
139
140 s = getenv("GGIGLUT_DEBUG");
141 glut_ggi_debug = (s && atoi(s));
142
143 if (argc && argv)
144 {
145
146 for (i = 1; i < *argc; i++)
147 {
148 if (strcmp(argv[i], "-mouse") == 0)
149 {
150 mouse_showcursor = GL_TRUE;
151 REMOVE;
152 }
153 else
154 if (strcmp(argv[i], "-bpp") == 0 && (i + 1) < (*argc))
155 {
156 switch(atoi(argv[i + 1]))
157 {
158 case 4: gt = GT_4BIT; break;
159 case 8: gt = GT_8BIT; break;
160 case 15: gt = GT_15BIT; break;
161 case 16: gt = GT_16BIT; break;
162 case 24: gt = GT_24BIT; break;
163 case 32: gt = GT_32BIT; break;
164 default:
165 ggiPanic("\"%s\" bits per pixel?\n", argv[i+1]);
166 }
167 __glut_gt_rgb = __glut_gt_index = gt;
168 REMOVE;
169 REMOVE;
170 }
171 else
172 if (strcmp(argv[i], "-size") == 0 && (i + 2) < (*argc))
173 {
174 __glut_width = atoi(argv[i + 1]);
175 __glut_height = atoi(argv[i + 2]);
176 REMOVE;
177 REMOVE;
178 REMOVE;
179 }
180 }
181 }
182
183 if (ggiInit() < 0)
184 {
185 ggiPanic("ggiInit() failed!\n");
186 }
187 __glut_init = GL_TRUE;
188
189 #undef REMOVE
190 }
191
192 void glutInitWindowPosition(int x, int y)
193 {
194 }
195
196 void glutInitWindowSize(int x, int y)
197 {
198 }
199
200 void glutFullScreen(void)
201 {
202 }
203
204 void glutInitDisplayMode(unsigned int mode)
205 {
206 __glut_mode = mode;
207 }
208
209 void glutInitDisplayString(const char *string)
210 {
211 glut_ggiPRINT("glutInitDisplayString: %s\n", string);
212 }
213
214 int glutCreateWindow(const char *title)
215 {
216 ggi_graphtype gt;
217 ggi_mode mode =
218 {
219 1,
220 { GGI_AUTO, GGI_AUTO },
221 { GGI_AUTO, GGI_AUTO },
222 { 0, 0 },
223 GT_AUTO,
224 { GGI_AUTO, GGI_AUTO }
225 };
226 int frames;
227 int rgb;
228 int err;
229
230 if (!__glut_init)
231 glutInit(NULL, NULL);
232
233 glut_ggiPRINT("GGIGLUT: %s\n", title);
234
235 rgb = !(__glut_mode & GLUT_INDEX);
236 frames = (__glut_mode & GLUT_DOUBLE) ? 2 : 1;
237
238 gt = (rgb) ? __glut_gt_rgb : __glut_gt_index;
239
240 __glut_ctx = GGIMesaCreateContext();
241
242 if (__glut_ctx == NULL)
243 ggiPanic("Can't create mesa-context\n");
244
245 __glut_vis = ggiOpen(NULL);
246 if (__glut_vis == NULL)
247 {
248 ggiPanic("ggiOpen() failed!\n");
249 /* return GL_FALSE; */
250 }
251
252 ggiSetFlags(__glut_vis, GGIFLAG_ASYNC);
253
254 ggiCheckMode(__glut_vis, &mode);
255
256 err = ggiSetMode(__glut_vis, &mode);
257 if (err < 0)
258 {
259 ggiPanic("Can't set graphic mode!\n");
260 /* return GL_FALSE; */
261 }
262
263 ggiGetMode(__glut_vis, &mode);
264
265 if (GGIMesaSetVisual(__glut_ctx, __glut_vis, rgb, frames > 1) < 0)
266 {
267 glut_ggiDEBUG("AAA\n");
268 ggiPanic("GGIMesaSetVisual failed!\n");
269 }
270
271 __glut_width = mode.visible.x;
272 __glut_height = mode.visible.y;
273
274 mousex = mode.visible.x / 2;
275 mousey = mode.visible.y / 2;
276
277 GGIMesaMakeCurrent(__glut_ctx);
278
279 if (__glut_reshape)
280 __glut_reshape(__glut_width, __glut_height);
281
282 return GL_TRUE;
283 }
284
285 void glutReshapeFunc(void (*func)(int, int))
286 {
287 __glut_reshape = func;
288 if (__glut_vis && __glut_reshape)
289 __glut_reshape(__glut_width, __glut_height);
290 }
291
292 void glutKeyboardFunc(void (*keyboard)(unsigned char key, int x, int y))
293 {
294 __glut_keyboard = keyboard;
295 }
296
297 int glutGetModifiers(void)
298 {
299 return __glut_mod_keys;
300 }
301
302 void glutEntryFunc(void (*func)(int state))
303 {
304 }
305
306 void glutVisibilitFunc(void (*func)(int state))
307 {
308 }
309
310 void glutTimerFunc(unsigned int millis, void (*func)(int value), int value)
311 {
312 }
313
314 void glutMenuStateFunc(void (*func)(int state))
315 {
316 }
317
318 int glutGet(GLenum type)
319 {
320 switch(type)
321 {
322 case GLUT_WINDOW_X:
323 return 0;
324 case GLUT_WINDOW_Y:
325 return 0;
326 case GLUT_WINDOW_WIDTH:
327 return __glut_width;
328 case GLUT_WINDOW_HEIGHT:
329 return __glut_height;
330 case GLUT_MENU_NUM_ITEMS:
331 if (curmenu)
332 return curmenu->num_entries;
333 else
334 return 0;
335 default:
336 glut_ggiDEBUG("glutGet: unknown type %i\n", type);
337 }
338 return 0;
339 }
340
341 void glutSpecialFunc(void (*special)(int key, int x, int y))
342 {
343 __glut_special=special;
344 }
345
346 void glutDisplayFunc(void (*disp)(void))
347 {
348 __glut_display=disp;
349 }
350
351 void glutSetColor(int index, GLfloat red, GLfloat green, GLfloat blue)
352 {
353 ggi_color c;
354 GLfloat max;
355
356 if (red > 1.0) red = 1.0;
357 if (red < 0.0) red = 0.0;
358 if (green > 1.0) green = 1.0;
359 if (green < 0.0) green = 0.0;
360 if (blue > 1.0) blue = 1.0;
361 if (blue < 0.0) blue = 0.0;
362
363 max = (float)((1 << GGI_COLOR_PRECISION) - 1);
364
365 c.r = (int)(max * red);
366 c.g = (int)(max * green);
367 c.b = (int)(max * blue);
368 ggiSetPalette(__glut_vis, index, 1, &c);
369 }
370
371 void glutPostRedisplay(void)
372 {
373 __glut_redisplay = GL_TRUE;
374 }
375
376 void glutPostWindowRedisplay(int win)
377 {
378 __glut_redisplay = GL_TRUE;
379 }
380
381 void glutSwapBuffers(void)
382 {
383 GGIMesaSwapBuffers();
384 }
385
386 void glutIdleFunc(void (*idle)(void))
387 {
388 __glut_idle = idle;
389 }
390
391 static void keyboard(ggi_event *ev)
392 {
393 int sym;
394 int modifer = 0, key = 0;
395
396 sym = ev->key.sym;
397
398 modifer = ev->key.modifiers;
399 if (modifer == GII_KM_SHIFT)
400 __glut_mod_keys |= GLUT_ACTIVE_SHIFT;
401 if (modifer == GII_KM_CTRL)
402 __glut_mod_keys |= GLUT_ACTIVE_CTRL;
403 if (modifer == GII_KM_ALT)
404 __glut_mod_keys |= GLUT_ACTIVE_ALT;
405
406 /* if (__glut_special && key) __glut_special(GII_KTYP(key),0,0); */
407
408 if (__glut_keyboard)
409 // __glut_keyboard(GII_UNICODE(sym), 0, 0);
410 __glut_keyboard(sym, 0, 0);
411 }
412
413 static void mouseabs(ggi_event *ev)
414 {
415 int oldx=mousex;
416 int oldy=mousey;
417
418 mousex=ev->pmove.x;
419 mousey=ev->pmove.y;
420
421 if (mousex<0) mousex=0;
422 if (mousey<0) mousey=0;
423 if (mousex>=__glut_width) mousex=__glut_width-1;
424 if (mousey>=__glut_height) mousey=__glut_height-1;
425
426 if (mousex!=oldx || mousey!=oldy) mouse_moved=GL_TRUE;
427 }
428
429 static void mouse(ggi_event *ev)
430 {
431 int oldx=mousex;
432 int oldy=mousey;
433
434 mousex+=ev->pmove.x>>1;
435 mousey+=ev->pmove.y>>1;
436
437 if (mousex<0) mousex=0;
438 if (mousey<0) mousey=0;
439 if (mousex>=__glut_width) mousex=__glut_width-1;
440 if (mousey>=__glut_height) mousey=__glut_height-1;
441
442 if (mousex!=oldx || mousey!=oldy) mouse_moved=GL_TRUE;
443
444 }
445
446 /* FIXME: Prototypes belong in headers, not here! [JMT] */
447 static void showmenu(void);
448 static int clickmenu(void);
449 static void updatemouse(void);
450 static void drawmouse(void);
451
452 static void mousemove(void)
453 {
454 if (mouse_moved) {
455 if (__glut_motion && mouse_down) {
456 __glut_motion(mousex,mousey);
457 }
458
459 if (__glut_passive_motion && (!mouse_down)) {
460 __glut_passive_motion(mousex,mousey);
461 }
462
463 if (__glut_menuactive) updatemouse();
464 mouse_moved=GL_FALSE;
465 }
466 }
467
468 static void button(ggi_event *ev)
469 {
470 int i;
471 int btn[4]={0,GLUT_LEFT_BUTTON,GLUT_RIGHT_BUTTON,GLUT_MIDDLE_BUTTON};
472 mousemove();
473
474 if (ev->pbutton.button <= 3) { /* GGI can have >3 buttons ! */
475 char state = ev->any.type == evPtrButtonPress ?GLUT_DOWN:GLUT_UP;
476 if (__glut_menuactive) {
477 if (state==GLUT_UP && clickmenu()) {
478 glutPostRedisplay();
479 __glut_menuactive=GL_FALSE;
480 }
481 } else
482 if (btn[ev->pbutton.button]==__glut_menubutton) {
483 __glut_menuactive=GL_TRUE;
484 activemenu=mainmenu;
485 showmenu();
486 } else
487 if (__glut_mouse) {
488 __glut_mouse(btn[ev->pbutton.button],state,mousex,mousey);
489 }
490 if (state==GLUT_DOWN) {
491 mouse_down|=(1<<(ev->pbutton.button-1));
492 }
493 else mouse_down&=~(1<<(ev->pbutton.button-1));
494 }
495 }
496
497 void glutMainLoop(void)
498 {
499 ggi_event ev;
500 ggi_event_mask evmask = (emKeyPress | emKeyRepeat | emPtrMove | emPtrButton);
501
502
503 ggiSetEventMask(__glut_vis, evmask);
504
505 glutPostRedisplay();
506
507 if (__glut_visibility)
508 __glut_visibility(GLUT_VISIBLE);
509
510 while (1)
511 {
512 if (!__glut_menuactive)
513 {
514 if (__glut_idle)
515 __glut_idle();
516 if (__glut_redisplay && __glut_display)
517 {
518 __glut_redisplay = GL_FALSE;
519 __glut_display();
520 }
521 }
522
523 while (1)
524 {
525 struct timeval t = {0, 0};
526
527 if (ggiEventPoll(__glut_vis, evmask, &t) == 0)
528 break;
529
530 ggiEventRead(__glut_vis, &ev, evmask);
531
532 switch (ev.any.type)
533 {
534 case evKeyPress:
535 case evKeyRepeat:
536 keyboard(&ev);
537 break;
538 case evPtrAbsolute:
539 mouseabs(&ev);
540 break;
541 case evPtrRelative:
542 mouse(&ev);
543 break;
544 case evPtrButtonPress:
545 case evPtrButtonRelease:
546 button(&ev);
547 break;
548 }
549 }
550 mousemove();
551 }
552 }
553
554 static void showmenu()
555 {
556 int y,i;
557 ggi_color col={0xffff,0xffff,0xffff};
558
559 ggiSetGCForeground(__glut_vis,ggiMapColor(__glut_vis,&col));
560 ggiSetOrigin(__glut_vis,0,0);
561
562 for (y=i=0;i<activemenu->num_entries;i++,y+=8) {
563 ggiPuts(__glut_vis,0,y,activemenu->label[i]);
564 }
565 drawmouse();
566 }
567
568 static int clickmenu(void)
569 {
570 int i;
571 int w,h;
572
573 i=mousey/8;
574
575 if (i>=activemenu->num_entries) return GL_TRUE;
576 if (mousex>=8*strlen(activemenu->label[i])) return GL_TRUE;
577
578 if (activemenu->submenu[i]) {
579 ggi_color col={0,0,0};
580 ggiSetGCForeground(__glut_vis,ggiMapColor(__glut_vis,&col));
581 h=activemenu->num_entries*8;
582 w=activemenu->max_strlen*8;
583 ggiDrawBox(__glut_vis,0,0,w,h);
584 activemenu=activemenu->submenu[i];
585 showmenu();
586 return GL_FALSE;
587 }
588 curmenu=activemenu;
589 activemenu->func(activemenu->value[i]);
590 return GL_TRUE;
591 }
592
593 static int oldx=-1;
594 static int oldy=-1;
595 static char buffer[16*16*4];
596
597 static void updatemouse()
598 {
599 ggiPutBox(__glut_vis,oldx,oldy,16,16,buffer);
600 drawmouse();
601 }
602
603 static void drawmouse()
604 {
605 int x,y;
606 x=mousex-8;
607 if (x<0) x=0;
608 y=mousey-8;
609 if (y<0) y=0;
610 ggiGetBox(__glut_vis,x,y,16,16,buffer);
611 ggiDrawLine(__glut_vis,mousex-2,mousey,mousex+2,mousey);
612 ggiDrawLine(__glut_vis,mousex,mousey-2,mousex,mousey+2);
613 oldx=x;
614 oldy=y;
615 }
616
617 int glutCreateMenu(void(*func)(int))
618 {
619 menu_t *m;
620 m=malloc(sizeof(menu_t));
621 memset(m,0,sizeof(menu_t));
622 curmenu=m;
623 curmenu->func=func;
624 return (int)curmenu;
625 }
626
627 static void addEntry(const char *label,int value,menu_t *submenu)
628 {
629 int i=curmenu->num_entries;
630 /* printf("%i %i %s %p\n",i,value,label,submenu); */
631 if (i<MAX_ENTRIES) {
632 curmenu->label[i]=strdup(label);
633 curmenu->value[i]=value;
634 curmenu->submenu[i]=submenu;
635
636 if (strlen(label)>curmenu->max_strlen)
637 curmenu->max_strlen=strlen(label);
638 curmenu->num_entries++;
639 }
640 }
641
642 void glutAddMenuEntry(const char *label,int value)
643 {
644 addEntry(label,value,NULL);
645 }
646
647 void glutAddSubMenu(const char *label,int submenu)
648 {
649 char text[100];
650
651 if (!curmenu) return;
652 strncpy(text,label,98);
653 text[98]=0;
654 text[strlen(text)+1]=0;
655 text[strlen(text)]='>';
656
657 addEntry(text,0,(menu_t *) submenu);
658 }
659
660 void glutAttachMenu(int button)
661 {
662 mainmenu=curmenu;
663 __glut_menubutton=button;
664 }
665
666 void glutDetachMenu(int button)
667 {
668 }
669
670 void glutVisibilityFunc(void (*func)(int state))
671 {
672 __glut_visibility=func;
673 }
674
675 void glutMouseFunc(void (*mouse)(int, int, int, int))
676 {
677 __glut_mouse=mouse;
678 }
679
680 void glutMotionFunc(void (*motion)(int,int))
681 {
682 __glut_motion=motion;
683 }
684
685 void glutPassiveMotionFunc(void (*motion)(int,int))
686 {
687 __glut_passive_motion=motion;
688 }
689
690 void glutSetWindowTitle(const char *title)
691 {
692 }
693
694 void glutSetIconTitle(const char *title)
695 {
696 }
697
698 void glutChangeToMenuEntry(int item,const char *label,int value)
699 {
700 if (item>0 && item<=curmenu->num_entries) {
701 item--;
702 free(curmenu->label[item]);
703 curmenu->label[item]=strdup(label);
704 curmenu->value[item]=value;
705 curmenu->submenu[item]=NULL;
706 }
707 }
708 void glutChangeToSubMenu(int item,const char *label,int submenu)
709 {
710 if (item>0 && item<=curmenu->num_entries) {
711 item--;
712 free(curmenu->label[item]);
713 curmenu->label[item]=strdup(label);
714 curmenu->value[item]=0;
715 curmenu->submenu[item]=(menu_t *)submenu;
716 }
717 }
718
719 void glutDestroyMenu(int menu)
720 {
721 menu_t *m=(menu_t *)menu;
722 int i;
723
724 for (i=0;i<m->num_entries;i++) {
725 free(m->label[i]);
726 }
727 free(m);
728 }
729
730 int glutCreateSubWindow(int win,int x,int y,int w,int h)
731 {
732 return 0;
733 }
734
735 void glutDestroyWindow(int win)
736 {
737 }
738
739 int glutGetWindow(void)
740 {
741 return 0;
742 }
743
744 void glutSetWindow(int win)
745 {
746 }
747
748 void glutPositionWindow(int x,int y)
749 {
750 }
751
752 void glutReshapeWindow(int x,int y)
753 {
754 }
755
756 void glutPushWindow(void)
757 {
758 }
759
760 void glutPopWindow(void)
761 {
762 }
763
764 void glutIconifyWindow(void)
765 {
766 }
767
768 void glutShowWindow()
769 {
770 }
771
772 void glutHideWindow()
773 {
774 }
775
776 void glutSetCursor(int cursor)
777 {
778 }
779
780 void glutWarpPointer(int x,int y)
781 {
782 }
783
784 void glutEstablishOverlay(void)
785 {
786 }
787
788 void glutRemoveOverlay(void)
789 {
790 }
791
792 void glutUseLayer(GLenum layer)
793 {
794 }
795
796 int glutLayerGet(GLenum type)
797 {
798 return 0;
799 }
800
801 void glutPostOverlayRedisplay(void)
802 {
803 }
804
805 void glutPostWindowOverlayRedisplay(int w)
806 {
807 }
808
809 void glutShowOverlay(void)
810 {
811 }
812
813 void glutHideOverlay(void)
814 {
815 }
816
817 int glutGetMenu(void)
818 {
819 return 0;
820 }
821
822 void glutSetMenu(int menu)
823 {
824 }
825
826 void glutRemoveMenuItem(int item)
827 {
828 }
829
830 void glutSpaceBallMotionFunc(void (*func)(int key,int x,int y))
831 {
832 }
833
834 void glutSpaceBallRotateFunc(void (*func)(int x,int y,int z))
835 {
836 }
837
838 void glutSpaceBallButtonFunc(void (*func)(int button,int state))
839 {
840 }
841
842 void glutCopyColormap(int win)
843 {
844 }
845
846 int glutDeviceGet(GLenum param)
847 {
848 return 0;
849 }