separated DOS GLUT from GLX GLUT.
[mesa.git] / src / glut / dos / window.c
1 /*
2 * DOS/DJGPP Mesa Utility Toolkit
3 * Version: 1.0
4 *
5 * Copyright (C) 2005 Daniel Borca All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * DANIEL BORCA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include <stdio.h>
27
28 #include "internal.h"
29
30
31 static GLuint swaptime, swapcount;
32
33 static DMesaVisual visual = NULL;
34
35 GLUTwindow *_glut_current, *_glut_windows[MAX_WINDOWS];
36
37
38 static void
39 clean (void)
40 {
41 int i;
42
43 for (i=1; i<=MAX_WINDOWS; i++) {
44 glutDestroyWindow(i);
45 }
46 if (visual) DMesaDestroyVisual(visual);
47
48 pc_close_stdout();
49 pc_close_stderr();
50 }
51
52
53 static GLUTwindow *
54 _glut_window (int win)
55 {
56 if (win > 0 && --win < MAX_WINDOWS) {
57 return _glut_windows[win];
58 }
59 return NULL;
60 }
61
62
63 int APIENTRY
64 glutCreateWindow (const char *title)
65 {
66 int i;
67 int m8width = (_glut_default.width + 7) & ~7;
68
69 /* We set the Visual once. This will be our desktop (graphic mode).
70 * We should do this in the `glutInit' code, but we don't have any idea
71 * about its geometry. Supposedly, when we are about to create one
72 * window, we have a slight idea about resolution.
73 */
74 if (!visual) {
75 if ((visual=DMesaCreateVisual(_glut_default.x + m8width, _glut_default.y + _glut_default.height, _glut_visual.bpp, _glut_visual.refresh,
76 _glut_default.mode & GLUT_DOUBLE,
77 !(_glut_default.mode & GLUT_INDEX),
78 (_glut_default.mode & GLUT_ALPHA ) ? _glut_visual.alpha : 0,
79 (_glut_default.mode & GLUT_DEPTH ) ? _glut_visual.depth : 0,
80 (_glut_default.mode & GLUT_STENCIL) ? _glut_visual.stencil : 0,
81 (_glut_default.mode & GLUT_ACCUM ) ? _glut_visual.accum : 0))==NULL) {
82 return 0;
83 }
84
85 DMesaGetIntegerv(DMESA_GET_SCREEN_SIZE, _glut_visual.geometry);
86 DMesaGetIntegerv(DMESA_GET_DRIVER_CAPS, &_glut_visual.flags);
87
88 /* Also hook stdio/stderr once */
89 pc_open_stdout();
90 pc_open_stderr();
91 pc_atexit(clean);
92 }
93
94 /* Search for an empty slot.
95 * Each window has its own rendering Context and its own Buffer.
96 */
97 for (i=0; i<MAX_WINDOWS; i++) {
98 if (_glut_windows[i] == NULL) {
99 DMesaContext c;
100 DMesaBuffer b;
101 GLUTwindow *w;
102
103 if ((w = (GLUTwindow *)calloc(1, sizeof(GLUTwindow))) == NULL) {
104 return 0;
105 }
106
107 /* Allocate the rendering Context. */
108 if ((c = DMesaCreateContext(visual, NULL)) == NULL) {
109 free(w);
110 return 0;
111 }
112
113 /* Allocate the Buffer (displayable area).
114 * We have to specify buffer size and position (inside the desktop).
115 */
116 if ((b = DMesaCreateBuffer(visual, _glut_default.x, _glut_default.y, m8width, _glut_default.height)) == NULL) {
117 DMesaDestroyContext(c);
118 free(w);
119 return 0;
120 }
121
122 /* Bind Buffer to Context and make the Context the current one. */
123 if (!DMesaMakeCurrent(c, b)) {
124 DMesaDestroyBuffer(b);
125 DMesaDestroyContext(c);
126 free(w);
127 return 0;
128 }
129
130 _glut_current = _glut_windows[i] = w;
131
132 w->num = ++i;
133 w->xpos = _glut_default.x;
134 w->ypos = _glut_default.y;
135 w->width = m8width;
136 w->height = _glut_default.height;
137 w->context = c;
138 w->buffer = b;
139
140 return i;
141 }
142 }
143
144 return 0;
145 }
146
147
148 int APIENTRY
149 glutCreateSubWindow (int win, int x, int y, int width, int height)
150 {
151 return GL_FALSE;
152 }
153
154
155 void APIENTRY
156 glutDestroyWindow (int win)
157 {
158 GLUTwindow *w = _glut_window(win);
159 if (w != NULL) {
160 if (w->destroy) {
161 w->destroy();
162 }
163 DMesaMakeCurrent(NULL, NULL);
164 DMesaDestroyBuffer(w->buffer);
165 DMesaDestroyContext(w->context);
166 free(w);
167 _glut_windows[win - 1] = NULL;
168 }
169 }
170
171
172 void APIENTRY
173 glutPostRedisplay (void)
174 {
175 _glut_current->redisplay = GL_TRUE;
176 }
177
178
179 void APIENTRY
180 glutSwapBuffers (void)
181 {
182 if (_glut_current->show_mouse) {
183 /* XXX scare mouse */
184 DMesaSwapBuffers(_glut_current->buffer);
185 /* XXX unscare mouse */
186 } else {
187 DMesaSwapBuffers(_glut_current->buffer);
188 }
189
190 if (_glut_fps) {
191 GLint t = glutGet(GLUT_ELAPSED_TIME);
192 swapcount++;
193 if (swaptime == 0)
194 swaptime = t;
195 else if (t - swaptime > _glut_fps) {
196 double time = 0.001 * (t - swaptime);
197 double fps = (double)swapcount / time;
198 fprintf(stderr, "GLUT: %d frames in %.2f seconds = %.2f FPS\n", swapcount, time, fps);
199 swaptime = t;
200 swapcount = 0;
201 }
202 }
203 }
204
205
206 int APIENTRY
207 glutGetWindow (void)
208 {
209 return _glut_current->num;
210 }
211
212
213 void APIENTRY
214 glutSetWindow (int win)
215 {
216 GLUTwindow *w = _glut_window(win);
217 if (w != NULL) {
218 _glut_current = w;
219 DMesaMakeCurrent(_glut_current->context, _glut_current->buffer);
220 }
221 }
222
223
224 void APIENTRY
225 glutSetWindowTitle (const char *title)
226 {
227 }
228
229
230 void APIENTRY
231 glutSetIconTitle (const char *title)
232 {
233 }
234
235
236 void APIENTRY
237 glutPositionWindow (int x, int y)
238 {
239 if (DMesaMoveBuffer(x, y)) {
240 _glut_current->xpos = x;
241 _glut_current->ypos = y;
242 }
243 }
244
245
246 void APIENTRY
247 glutReshapeWindow (int width, int height)
248 {
249 if (DMesaResizeBuffer(width, height)) {
250 _glut_current->width = width;
251 _glut_current->height = height;
252 if (_glut_current->reshape) {
253 _glut_current->reshape(width, height);
254 } else {
255 glViewport(0, 0, width, height);
256 }
257 }
258 }
259
260
261 void APIENTRY
262 glutFullScreen (void)
263 {
264 }
265
266
267 void APIENTRY
268 glutPopWindow (void)
269 {
270 }
271
272
273 void APIENTRY
274 glutPushWindow (void)
275 {
276 }
277
278
279 void APIENTRY
280 glutIconifyWindow (void)
281 {
282 }
283
284
285 void APIENTRY
286 glutShowWindow (void)
287 {
288 }
289
290
291 void APIENTRY
292 glutHideWindow (void)
293 {
294 }
295
296
297 void APIENTRY
298 glutCloseFunc (GLUTdestroyCB destroy)
299 {
300 _glut_current->destroy = destroy;
301 }
302
303
304 void APIENTRY
305 glutPostWindowRedisplay (int win)
306 {
307 GLUTwindow *w = _glut_window(win);
308 if (w != NULL) {
309 w->redisplay = GL_TRUE;
310 }
311 }
312
313
314 void * APIENTRY
315 glutGetWindowData (void)
316 {
317 return _glut_current->data;
318 }
319
320
321 void APIENTRY
322 glutSetWindowData (void *data)
323 {
324 _glut_current->data = data;
325 }