1 /* **************************************************************************
3 * **************************************************************************
5 * Copyright (C) 1998 Uwe Maurer - uwe_maurer@t-online.de
6 * Copyright (C) 1999 James Simmons
7 * Copyright (C) 1999 Jon Taylor
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.
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.
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.
23 * **************************************************************************
25 * - Make everything use the portable ggi_* types
31 #define GRAPHTYPE_RGB GT_16BIT
32 #define GRAPHTYPE_INDEX GT_8BIT
34 /*************************************************************************/
43 #include "GL/ggimesa.h"
48 char *__glutProgramName
= "GGI";
50 static ggi_visual_t __glut_vis
;
52 static GGIMesaContext __glut_ctx
;
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
;
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
;
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);
80 static unsigned int __glut_mode
= GLUT_RGB
| GLUT_SINGLE
| GLUT_DEPTH
;
82 static int __glut_mod_keys
= 0;
84 static int __glut_redisplay
= GL_FALSE
;
87 static int __glut_menubutton
= -1;
88 static int __glut_menuactive
= GL_FALSE
;
90 #define MAX_ENTRIES 64
94 char *label
[MAX_ENTRIES
];
95 int value
[MAX_ENTRIES
];
96 struct menu_s
* submenu
[MAX_ENTRIES
];
102 static menu_t
*mainmenu
;
103 static menu_t
*curmenu
;
104 static menu_t
*activemenu
;
106 int glut_ggi_debug
= GL_FALSE
;
108 void glut_ggiPRINT(char *format
, ...)
111 va_start(args
, format
);
112 fprintf(stderr
, "GGIGLUT: ");
113 vfprintf(stderr
, format
, args
);
117 void glut_ggiDEBUG(char *format
, ...)
122 va_start(args
, format
);
123 fprintf(stderr
, "GGIGLUT: ");
124 vfprintf(stderr
, format
, args
);
129 void glutInit(int *argc
, char **argv
)
135 #define REMOVE {for (k=i;k<*argc-1;k++) argv[k]=argv[k+1]; \
138 if (__glut_init
) return;
140 s
= getenv("GGIGLUT_DEBUG");
141 glut_ggi_debug
= (s
&& atoi(s
));
146 for (i
= 1; i
< *argc
; i
++)
148 if (strcmp(argv
[i
], "-mouse") == 0)
150 mouse_showcursor
= GL_TRUE
;
154 if (strcmp(argv
[i
], "-bpp") == 0 && (i
+ 1) < (*argc
))
156 switch(atoi(argv
[i
+ 1]))
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;
165 ggiPanic("\"%s\" bits per pixel?\n", argv
[i
+1]);
167 __glut_gt_rgb
= __glut_gt_index
= gt
;
172 if (strcmp(argv
[i
], "-size") == 0 && (i
+ 2) < (*argc
))
174 __glut_width
= atoi(argv
[i
+ 1]);
175 __glut_height
= atoi(argv
[i
+ 2]);
185 ggiPanic("ggiInit() failed!\n");
187 __glut_init
= GL_TRUE
;
192 void glutInitWindowPosition(int x
, int y
)
196 void glutInitWindowSize(int x
, int y
)
200 void glutFullScreen(void)
204 void glutInitDisplayMode(unsigned int mode
)
209 void glutInitDisplayString(const char *string
)
211 glut_ggiPRINT("glutInitDisplayString: %s\n", string
);
214 int glutCreateWindow(const char *title
)
220 { GGI_AUTO
, GGI_AUTO
},
221 { GGI_AUTO
, GGI_AUTO
},
224 { GGI_AUTO
, GGI_AUTO
}
231 glutInit(NULL
, NULL
);
233 glut_ggiPRINT("GGIGLUT: %s\n", title
);
235 rgb
= !(__glut_mode
& GLUT_INDEX
);
236 frames
= (__glut_mode
& GLUT_DOUBLE
) ? 2 : 1;
238 gt
= (rgb
) ? __glut_gt_rgb
: __glut_gt_index
;
240 __glut_ctx
= GGIMesaCreateContext();
242 if (__glut_ctx
== NULL
)
243 ggiPanic("Can't create mesa-context\n");
245 __glut_vis
= ggiOpen(NULL
);
246 if (__glut_vis
== NULL
)
248 ggiPanic("ggiOpen() failed!\n");
249 /* return GL_FALSE; */
252 ggiSetFlags(__glut_vis
, GGIFLAG_ASYNC
);
254 ggiCheckMode(__glut_vis
, &mode
);
256 err
= ggiSetMode(__glut_vis
, &mode
);
259 ggiPanic("Can't set graphic mode!\n");
260 /* return GL_FALSE; */
263 ggiGetMode(__glut_vis
, &mode
);
265 if (GGIMesaSetVisual(__glut_ctx
, __glut_vis
, rgb
, frames
> 1) < 0)
267 glut_ggiDEBUG("AAA\n");
268 ggiPanic("GGIMesaSetVisual failed!\n");
271 __glut_width
= mode
.visible
.x
;
272 __glut_height
= mode
.visible
.y
;
274 mousex
= mode
.visible
.x
/ 2;
275 mousey
= mode
.visible
.y
/ 2;
277 GGIMesaMakeCurrent(__glut_ctx
);
280 __glut_reshape(__glut_width
, __glut_height
);
285 void glutReshapeFunc(void (*func
)(int, int))
287 __glut_reshape
= func
;
288 if (__glut_vis
&& __glut_reshape
)
289 __glut_reshape(__glut_width
, __glut_height
);
292 void glutKeyboardFunc(void (*keyboard
)(unsigned char key
, int x
, int y
))
294 __glut_keyboard
= keyboard
;
297 int glutGetModifiers(void)
299 return __glut_mod_keys
;
302 void glutEntryFunc(void (*func
)(int state
))
306 void glutVisibilitFunc(void (*func
)(int state
))
310 void glutTimerFunc(unsigned int millis
, void (*func
)(int value
), int value
)
314 void glutMenuStateFunc(void (*func
)(int state
))
318 int glutGet(GLenum type
)
326 case GLUT_WINDOW_WIDTH
:
328 case GLUT_WINDOW_HEIGHT
:
329 return __glut_height
;
330 case GLUT_MENU_NUM_ITEMS
:
332 return curmenu
->num_entries
;
336 glut_ggiDEBUG("glutGet: unknown type %i\n", type
);
341 void glutSpecialFunc(void (*special
)(int key
, int x
, int y
))
343 __glut_special
=special
;
346 void glutDisplayFunc(void (*disp
)(void))
351 void glutSetColor(int index
, GLfloat red
, GLfloat green
, GLfloat blue
)
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;
363 max
= (float)((1 << GGI_COLOR_PRECISION
) - 1);
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
);
371 void glutPostRedisplay(void)
373 __glut_redisplay
= GL_TRUE
;
376 void glutPostWindowRedisplay(int win
)
378 __glut_redisplay
= GL_TRUE
;
381 void glutSwapBuffers(void)
383 GGIMesaSwapBuffers();
386 void glutIdleFunc(void (*idle
)(void))
391 static void keyboard(ggi_event
*ev
)
394 int modifer
= 0, key
= 0;
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
;
406 /* if (__glut_special && key) __glut_special(GII_KTYP(key),0,0); */
409 // __glut_keyboard(GII_UNICODE(sym), 0, 0);
410 __glut_keyboard(sym
, 0, 0);
413 static void mouseabs(ggi_event
*ev
)
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;
426 if (mousex
!=oldx
|| mousey
!=oldy
) mouse_moved
=GL_TRUE
;
429 static void mouse(ggi_event
*ev
)
434 mousex
+=ev
->pmove
.x
>>1;
435 mousey
+=ev
->pmove
.y
>>1;
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;
442 if (mousex
!=oldx
|| mousey
!=oldy
) mouse_moved
=GL_TRUE
;
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);
452 static void mousemove(void)
455 if (__glut_motion
&& mouse_down
) {
456 __glut_motion(mousex
,mousey
);
459 if (__glut_passive_motion
&& (!mouse_down
)) {
460 __glut_passive_motion(mousex
,mousey
);
463 if (__glut_menuactive
) updatemouse();
464 mouse_moved
=GL_FALSE
;
468 static void button(ggi_event
*ev
)
471 int btn
[4]={0,GLUT_LEFT_BUTTON
,GLUT_RIGHT_BUTTON
,GLUT_MIDDLE_BUTTON
};
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()) {
479 __glut_menuactive
=GL_FALSE
;
482 if (btn
[ev
->pbutton
.button
]==__glut_menubutton
) {
483 __glut_menuactive
=GL_TRUE
;
488 __glut_mouse(btn
[ev
->pbutton
.button
],state
,mousex
,mousey
);
490 if (state
==GLUT_DOWN
) {
491 mouse_down
|=(1<<(ev
->pbutton
.button
-1));
493 else mouse_down
&=~(1<<(ev
->pbutton
.button
-1));
497 void glutMainLoop(void)
500 ggi_event_mask evmask
= (emKeyPress
| emKeyRepeat
| emPtrMove
| emPtrButton
);
503 ggiSetEventMask(__glut_vis
, evmask
);
507 if (__glut_visibility
)
508 __glut_visibility(GLUT_VISIBLE
);
512 if (!__glut_menuactive
)
516 if (__glut_redisplay
&& __glut_display
)
518 __glut_redisplay
= GL_FALSE
;
525 struct timeval t
= {0, 0};
527 if (ggiEventPoll(__glut_vis
, evmask
, &t
) == 0)
530 ggiEventRead(__glut_vis
, &ev
, evmask
);
544 case evPtrButtonPress
:
545 case evPtrButtonRelease
:
554 static void showmenu()
557 ggi_color col
={0xffff,0xffff,0xffff};
559 ggiSetGCForeground(__glut_vis
,ggiMapColor(__glut_vis
,&col
));
560 ggiSetOrigin(__glut_vis
,0,0);
562 for (y
=i
=0;i
<activemenu
->num_entries
;i
++,y
+=8) {
563 ggiPuts(__glut_vis
,0,y
,activemenu
->label
[i
]);
568 static int clickmenu(void)
575 if (i
>=activemenu
->num_entries
) return GL_TRUE
;
576 if (mousex
>=8*strlen(activemenu
->label
[i
])) return GL_TRUE
;
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
];
589 activemenu
->func(activemenu
->value
[i
]);
595 static char buffer
[16*16*4];
597 static void updatemouse()
599 ggiPutBox(__glut_vis
,oldx
,oldy
,16,16,buffer
);
603 static void drawmouse()
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);
617 int glutCreateMenu(void(*func
)(int))
620 m
=malloc(sizeof(menu_t
));
621 memset(m
,0,sizeof(menu_t
));
627 static void addEntry(const char *label
,int value
,menu_t
*submenu
)
629 int i
=curmenu
->num_entries
;
630 /* printf("%i %i %s %p\n",i,value,label,submenu); */
632 curmenu
->label
[i
]=strdup(label
);
633 curmenu
->value
[i
]=value
;
634 curmenu
->submenu
[i
]=submenu
;
636 if (strlen(label
)>curmenu
->max_strlen
)
637 curmenu
->max_strlen
=strlen(label
);
638 curmenu
->num_entries
++;
642 void glutAddMenuEntry(const char *label
,int value
)
644 addEntry(label
,value
,NULL
);
647 void glutAddSubMenu(const char *label
,int submenu
)
651 if (!curmenu
) return;
652 strncpy(text
,label
,98);
654 text
[strlen(text
)+1]=0;
655 text
[strlen(text
)]='>';
657 addEntry(text
,0,(menu_t
*) submenu
);
660 void glutAttachMenu(int button
)
663 __glut_menubutton
=button
;
666 void glutDetachMenu(int button
)
670 void glutVisibilityFunc(void (*func
)(int state
))
672 __glut_visibility
=func
;
675 void glutMouseFunc(void (*mouse
)(int, int, int, int))
680 void glutMotionFunc(void (*motion
)(int,int))
682 __glut_motion
=motion
;
685 void glutPassiveMotionFunc(void (*motion
)(int,int))
687 __glut_passive_motion
=motion
;
690 void glutSetWindowTitle(const char *title
)
694 void glutSetIconTitle(const char *title
)
698 void glutChangeToMenuEntry(int item
,const char *label
,int value
)
700 if (item
>0 && item
<=curmenu
->num_entries
) {
702 free(curmenu
->label
[item
]);
703 curmenu
->label
[item
]=strdup(label
);
704 curmenu
->value
[item
]=value
;
705 curmenu
->submenu
[item
]=NULL
;
708 void glutChangeToSubMenu(int item
,const char *label
,int submenu
)
710 if (item
>0 && item
<=curmenu
->num_entries
) {
712 free(curmenu
->label
[item
]);
713 curmenu
->label
[item
]=strdup(label
);
714 curmenu
->value
[item
]=0;
715 curmenu
->submenu
[item
]=(menu_t
*)submenu
;
719 void glutDestroyMenu(int menu
)
721 menu_t
*m
=(menu_t
*)menu
;
724 for (i
=0;i
<m
->num_entries
;i
++) {
730 int glutCreateSubWindow(int win
,int x
,int y
,int w
,int h
)
735 void glutDestroyWindow(int win
)
739 int glutGetWindow(void)
744 void glutSetWindow(int win
)
748 void glutPositionWindow(int x
,int y
)
752 void glutReshapeWindow(int x
,int y
)
756 void glutPushWindow(void)
760 void glutPopWindow(void)
764 void glutIconifyWindow(void)
768 void glutShowWindow()
772 void glutHideWindow()
776 void glutSetCursor(int cursor
)
780 void glutWarpPointer(int x
,int y
)
784 void glutEstablishOverlay(void)
788 void glutRemoveOverlay(void)
792 void glutUseLayer(GLenum layer
)
796 int glutLayerGet(GLenum type
)
801 void glutPostOverlayRedisplay(void)
805 void glutPostWindowOverlayRedisplay(int w
)
809 void glutShowOverlay(void)
813 void glutHideOverlay(void)
817 int glutGetMenu(void)
822 void glutSetMenu(int menu
)
826 void glutRemoveMenuItem(int item
)
830 void glutSpaceBallMotionFunc(void (*func
)(int key
,int x
,int y
))
834 void glutSpaceBallRotateFunc(void (*func
)(int x
,int y
,int z
))
838 void glutSpaceBallButtonFunc(void (*func
)(int button
,int state
))
842 void glutCopyColormap(int win
)
846 int glutDeviceGet(GLenum param
)