Merge branch 'master' of ssh://repo.or.cz/srv/git/tgl
[tgl.git] / glut / glut.c
blob1a541c02a2258d7eb585ebcf807b254ea38d2c3d
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/keysym.h>
11 #include <GL/glx.h>
12 #include <GL/gl.h>
14 #include "glut.h"
17 static Display * dpy;
18 static Window win;
20 static glut_display_func display_func = NULL;
21 static glut_keyboard_func keyboard_func = NULL;
22 static glut_reshape_func reshape_func = NULL;
23 static glut_idle_func idle_func = NULL;
26 static struct glut_window main_window = {0,};
29 #define DEFAULT_WIN_WIDTH 400
30 #define DEFAULT_WIN_HEIGHT 300
35 void glutSwapBuffers(void)
37 glXSwapBuffers(dpy, win);
40 void glutInit(int *argc, char **argv)
42 (void)argc; (void)argv;
44 memset(&main_window, 0, sizeof(main_window));
47 void glutInitWindowSize(int width, int height)
49 main_window.width = width;
50 main_window.height = height;
53 void glutInitWindowPosition(int x, int y)
55 main_window.x = x;
56 main_window.y = y;
59 static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None };
61 static Bool WaitForNotify(Display *d, XEvent *e, char *arg)
63 return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
66 int glutCreateWindow(char *name)
68 XVisualInfo *vi;
69 Colormap cmap;
70 XSetWindowAttributes swa;
71 XSizeHints hint;
72 GLXContext cx;
73 XEvent event;
74 int width, height;
77 /* get a connection */
78 dpy = XOpenDisplay(NULL);
79 if (dpy == NULL) {
80 fprintf(stderr,"Could not open X display\n");
81 exit(1);
84 /* get an appropriate visual */
85 vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
86 if (vi == NULL) {
87 fprintf(stderr, "No suitable visual for glx\n");
88 exit(1);
91 /* create a GLX context */
92 cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
94 /* create a color map */
95 cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
96 vi->visual, AllocNone);
98 /* create a window */
99 width = main_window.width ? : DEFAULT_WIN_WIDTH;
100 height = main_window.height ? : DEFAULT_WIN_HEIGHT;
101 main_window.width = width;
102 main_window.height = height;
104 hint.x = main_window.x;
105 hint.y = main_window.y;
106 hint.width = width;
107 hint.height = height;
108 hint.flags = PPosition | PSize;
109 swa.colormap = cmap;
110 swa.border_pixel = 0;
111 swa.event_mask = StructureNotifyMask;
112 win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height,
113 0, vi->depth, InputOutput, vi->visual,
114 CWBorderPixel|CWColormap|CWEventMask, &swa);
115 XSetStandardProperties (dpy, win, name, name, None, NULL, 0, &hint);
117 XMapWindow(dpy, win);
118 XIfEvent(dpy, &event, WaitForNotify, (char*)win);
119 XSelectInput(dpy, win, KeyPressMask | StructureNotifyMask | ExposureMask);
121 /* connect the context to the window */
122 glXMakeCurrent(dpy, win, cx);
125 return 1; /* FIXME */
128 void glutDisplayFunc(void (*func)(void))
130 display_func = func;
133 void glutKeyboardFunc(void (*func)(unsigned char key,
134 int x, int y))
136 keyboard_func = func;
140 void glutReshapeFunc(void (*func)(int width, int height))
142 reshape_func = func;
145 void glutIdleFunc(void (*func)(void))
147 idle_func = func;
150 void glutMainLoop(void)
152 int k;
153 char buf[80];
154 XEvent xev;
155 KeySym keysym;
156 XComposeStatus status;
158 if (!reshape_func) {
159 fprintf(stderr, "No reshape_func set!\n");
160 exit(1);
162 reshape_func(main_window.width, main_window.height);
164 if (display_func)
165 display_func();
167 while (1) {
168 if (XPending(dpy) > 0) {
169 XNextEvent(dpy,&xev);
170 switch(xev.type) {
171 case KeyPress:
172 XLookupString((XKeyEvent *)&xev,buf,80,&keysym,&status);
173 switch(keysym) {
174 case XK_Up:
175 k = KEY_UP;
176 break;
177 case XK_Down:
178 k = KEY_DOWN;
179 break;
180 case XK_Left:
181 k = KEY_LEFT;
182 break;
183 case XK_Right:
184 k = KEY_RIGHT;
185 break;
186 case XK_Escape:
187 k = KEY_ESCAPE;
188 break;
189 default:
190 k = keysym;
193 keyboard_func(k, 0, 0);
194 break;
195 case ConfigureNotify:
197 int width,height;
198 width = xev.xconfigure.width;
199 height = xev.xconfigure.height;
200 glXWaitX();
201 reshape_func(width, height);
203 break;
205 } else {
206 if (idle_func)
207 idle_func();