changed coding style. made `glutTimerFunc' less accurate, but far more reliable.
[mesa.git] / src / glut / dos / init.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.0
4 * Copyright (C) 1995-1998 Brian Paul
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*
22 * DOS/DJGPP glut driver v1.5 for Mesa
23 *
24 * Copyright (C) 2002 - Daniel Borca
25 * Email : dborca@users.sourceforge.net
26 * Web : http://www.geocities.com/dborca
27 */
28
29
30 #include <string.h>
31
32 #include "glutint.h"
33
34 #define DEFAULT_WIDTH 300
35 #define DEFAULT_HEIGHT 300
36 #define DEFAULT_BPP 16
37
38 #define ALPHA_SIZE 8
39 #define DEPTH_SIZE 16
40 #define STENCIL_SIZE 8
41 #define ACCUM_SIZE 16
42
43
44 GLuint g_bpp = DEFAULT_BPP;
45 GLuint g_alpha = ALPHA_SIZE;
46 GLuint g_depth = DEPTH_SIZE;
47 GLuint g_stencil = STENCIL_SIZE;
48 GLuint g_accum = ACCUM_SIZE;
49 GLuint g_refresh = 0;
50 GLuint g_screen_w, g_screen_h;
51 GLint g_driver_caps;
52
53 GLuint g_fps = 0;
54
55 GLuint g_display_mode = 0;
56 int g_init_x = 0, g_init_y = 0;
57 GLuint g_init_w = DEFAULT_WIDTH, g_init_h = DEFAULT_HEIGHT;
58
59 char *__glutProgramName = NULL;
60
61
62 void APIENTRY
63 glutInit (int *argc, char **argv)
64 {
65 char *str;
66 const char *env;
67
68 if ((env = getenv("DMESA_GLUT_BPP")) != NULL) {
69 g_bpp = atoi(env);
70 }
71 if ((env = getenv("DMESA_GLUT_ALPHA")) != NULL) {
72 g_alpha = atoi(env);
73 }
74 if ((env = getenv("DMESA_GLUT_DEPTH")) != NULL) {
75 g_depth = atoi(env);
76 }
77 if ((env = getenv("DMESA_GLUT_STENCIL")) != NULL) {
78 g_stencil = atoi(env);
79 }
80 if ((env = getenv("DMESA_GLUT_ACCUM")) != NULL) {
81 g_accum = atoi(env);
82 }
83 if ((env = getenv("DMESA_GLUT_REFRESH")) != NULL) {
84 g_refresh = atoi(env);
85 }
86
87 /* Determine program name. */
88 str = strrchr(argv[0], '/');
89 if (str == NULL) {
90 str = argv[0];
91 } else {
92 str++;
93 }
94 __glutProgramName = __glutStrdup(str);
95
96 /* check if GLUT_FPS env var is set */
97 if ((env = getenv("GLUT_FPS")) != NULL) {
98 if ((g_fps = atoi(env)) <= 0) {
99 g_fps = 5000; /* 5000 milliseconds */
100 }
101 }
102
103 /* Initialize timer */
104 glutGet(GLUT_ELAPSED_TIME);
105 }
106
107
108 void APIENTRY
109 glutInitDisplayMode (unsigned int mode)
110 {
111 g_display_mode = mode;
112 }
113
114
115 void APIENTRY
116 glutInitWindowPosition (int x, int y)
117 {
118 g_init_x = x;
119 g_init_y = y;
120 }
121
122
123 void APIENTRY
124 glutInitWindowSize (int width, int height)
125 {
126 g_init_w = width;
127 g_init_h = height;
128 }
129
130
131 #define DO_REDISPLAY(w, ccin, ccout) \
132 do { \
133 if (w->redisplay && w->display) { \
134 int rv = GL_TRUE; \
135 \
136 idle = GL_FALSE; \
137 w->redisplay = GL_FALSE; \
138 \
139 /* test IN condition (whether we need to `MakeCurrent') */\
140 if (ccin) { \
141 rv = DMesaMakeCurrent(w->context, w->buffer); \
142 } \
143 \
144 /* do the display only if `MakeCurrent' didn't failed */ \
145 if (rv) { \
146 if (w->show_mouse && !(g_display_mode & GLUT_DOUBLE)) {\
147 /* XXX scare mouse */ \
148 w->display(); \
149 /* XXX unscare mouse */ \
150 } else { \
151 w->display(); \
152 } \
153 \
154 /* update OUT condition */ \
155 ccout; \
156 } \
157 } \
158 } while (0)
159
160
161 void APIENTRY
162 glutMainLoop (void)
163 {
164 int i, n;
165 GLUTwindow *w;
166 GLboolean idle;
167 static int old_mouse_x = 0;
168 static int old_mouse_y = 0;
169 static int old_mouse_b = 0;
170
171 {
172 GLint screen_size[2];
173 DMesaGetIntegerv(DMESA_GET_SCREEN_SIZE, screen_size);
174 g_screen_w = screen_size[0];
175 g_screen_h = screen_size[1];
176 DMesaGetIntegerv(DMESA_GET_DRIVER_CAPS, &g_driver_caps);
177 }
178
179 pc_install_keyb();
180 __glutInitMouse();
181
182 for (i = 0; i < MAX_WINDOWS; i++) {
183 w = g_windows[i];
184 if (w != NULL) {
185 glutSetWindow(w->num);
186 glutPostRedisplay();
187 if (w->reshape) {
188 w->reshape(w->width, w->height);
189 }
190 if (w->visibility) {
191 w->visibility(GLUT_VISIBLE);
192 }
193 }
194 }
195
196 while (GL_TRUE) {
197 idle = GL_TRUE;
198
199 n = 0;
200 for (i = 0; i < MAX_WINDOWS; i++) {
201 w = g_windows[i];
202 if ((w != NULL) && (w != g_curwin)) {
203 /* 1) redisplay `w'
204 * 2) `MakeCurrent' always
205 * 3) update number of non-default windows
206 */
207 DO_REDISPLAY(w, GL_TRUE, n++);
208 }
209 }
210 /* 1) redisplay `g_curwin'
211 * 2) `MakeCurrent' only if we previously did non-default windows
212 * 3) don't update anything
213 */
214 DO_REDISPLAY(g_curwin, n, n);
215
216 if (g_mouse) {
217 int mouse_x;
218 int mouse_y;
219 int mouse_z;
220 int mouse_b;
221
222 /* query mouse */
223 mouse_b = pc_query_mouse(&mouse_x, &mouse_y, &mouse_z);
224
225 /* relative to window coordinates */
226 g_mouse_x = mouse_x - g_curwin->xpos;
227 g_mouse_y = mouse_y - g_curwin->ypos;
228
229 /* mouse was moved? */
230 if ((mouse_x != old_mouse_x) || (mouse_y != old_mouse_y)) {
231 idle = GL_FALSE;
232 old_mouse_x = mouse_x;
233 old_mouse_y = mouse_y;
234
235 if (mouse_b) {
236 /* any button pressed */
237 if (g_curwin->motion) {
238 g_curwin->motion(g_mouse_x, g_mouse_y);
239 }
240 } else {
241 /* no button pressed */
242 if (g_curwin->passive) {
243 g_curwin->passive(g_mouse_x, g_mouse_y);
244 }
245 }
246 }
247
248 /* button state changed? */
249 if (mouse_b != old_mouse_b) {
250 GLUTmouseCB mouse_func;
251
252 if ((mouse_func = g_curwin->mouse)) {
253 if ((old_mouse_b & 1) && !(mouse_b & 1))
254 mouse_func(GLUT_LEFT_BUTTON, GLUT_UP, g_mouse_x, g_mouse_y);
255 else if (!(old_mouse_b & 1) && (mouse_b & 1))
256 mouse_func(GLUT_LEFT_BUTTON, GLUT_DOWN, g_mouse_x, g_mouse_y);
257
258 if ((old_mouse_b & 2) && !(mouse_b & 2))
259 mouse_func(GLUT_RIGHT_BUTTON, GLUT_UP, g_mouse_x, g_mouse_y);
260 else if (!(old_mouse_b & 2) && (mouse_b & 2))
261 mouse_func(GLUT_RIGHT_BUTTON, GLUT_DOWN, g_mouse_x, g_mouse_y);
262
263 if ((old_mouse_b & 4) && !(mouse_b & 4))
264 mouse_func(GLUT_MIDDLE_BUTTON, GLUT_UP, g_mouse_x, g_mouse_y);
265 else if (!(old_mouse_b & 3) && (mouse_b & 4))
266 mouse_func(GLUT_MIDDLE_BUTTON, GLUT_DOWN, g_mouse_x, g_mouse_y);
267 }
268
269 idle = GL_FALSE;
270 old_mouse_b = mouse_b;
271 }
272 }
273
274 if (pc_keypressed()) {
275 int key;
276 int glut_key;
277
278 idle = GL_FALSE;
279 key = pc_readkey();
280
281 switch (key>>16) {
282 case KEY_F1: glut_key = GLUT_KEY_F1; goto special;
283 case KEY_F2: glut_key = GLUT_KEY_F2; goto special;
284 case KEY_F3: glut_key = GLUT_KEY_F3; goto special;
285 case KEY_F4: glut_key = GLUT_KEY_F4; goto special;
286 case KEY_F5: glut_key = GLUT_KEY_F5; goto special;
287 case KEY_F6: glut_key = GLUT_KEY_F6; goto special;
288 case KEY_F7: glut_key = GLUT_KEY_F7; goto special;
289 case KEY_F8: glut_key = GLUT_KEY_F8; goto special;
290 case KEY_F9: glut_key = GLUT_KEY_F9; goto special;
291 case KEY_F10: glut_key = GLUT_KEY_F10; goto special;
292 case KEY_F11: glut_key = GLUT_KEY_F11; goto special;
293 case KEY_F12: glut_key = GLUT_KEY_F12; goto special;
294 case KEY_LEFT: glut_key = GLUT_KEY_LEFT; goto special;
295 case KEY_UP: glut_key = GLUT_KEY_UP; goto special;
296 case KEY_RIGHT: glut_key = GLUT_KEY_RIGHT; goto special;
297 case KEY_DOWN: glut_key = GLUT_KEY_DOWN; goto special;
298 case KEY_PGUP: glut_key = GLUT_KEY_PAGE_UP; goto special;
299 case KEY_PGDN: glut_key = GLUT_KEY_PAGE_DOWN; goto special;
300 case KEY_HOME: glut_key = GLUT_KEY_HOME; goto special;
301 case KEY_END: glut_key = GLUT_KEY_END; goto special;
302 case KEY_INSERT: glut_key = GLUT_KEY_INSERT; goto special;
303 special:
304 if (g_curwin->special) {
305 g_curwin->special(glut_key, g_mouse_x, g_mouse_y);
306 }
307 break;
308 default:
309 if (g_curwin->keyboard) {
310 g_curwin->keyboard(key & 0xFF, g_mouse_x, g_mouse_y);
311 }
312 }
313 }
314
315 if (idle && g_idle_func)
316 g_idle_func();
317
318 for (i = 0; i < MAX_SSHOT_CB; i++) {
319 int time = glutGet(GLUT_ELAPSED_TIME);
320 GLUTSShotCB *cb = &g_sscb[i];
321 if (cb->func && (time >= cb->time)) {
322 cb->func(cb->value);
323 cb->func = NULL;
324 }
325 }
326 }
327 }