Merge branch 'master' into gallium-0.2
[mesa.git] / src / glut / dos / loop.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 <string.h>
27
28 #include <GL/glut.h>
29 #include "GL/dmesa.h"
30
31 #include "PC_HW/pc_hw.h"
32 #include "internal.h"
33
34
35 static int looping = 0;
36
37
38 #define DO_REDISPLAY(w, ccin, ccout) \
39 do { \
40 if (w->redisplay && w->display) { \
41 int rv = GL_TRUE; \
42 \
43 idle = GL_FALSE; \
44 w->redisplay = GL_FALSE; \
45 \
46 /* test IN condition (whether we need to `MakeCurrent') */\
47 if (ccin) { \
48 rv = DMesaMakeCurrent(w->context, w->buffer); \
49 } \
50 \
51 /* do the display only if `MakeCurrent' didn't failed */ \
52 if (rv) { \
53 if (w->show_mouse && !(_glut_default.mode & GLUT_DOUBLE)) {\
54 /* XXX scare mouse */ \
55 w->display(); \
56 /* XXX unscare mouse */ \
57 } else { \
58 w->display(); \
59 } \
60 \
61 /* update OUT condition */ \
62 ccout; \
63 } \
64 } \
65 } while (0)
66
67
68 void APIENTRY
69 glutMainLoopEvent (void)
70 {
71 int i, n;
72 GLUTwindow *w;
73 GLboolean idle;
74 static int old_mouse_x = 0;
75 static int old_mouse_y = 0;
76 static int old_mouse_b = 0;
77
78 static GLboolean virgin = GL_TRUE;
79 if (virgin) {
80 pc_install_keyb();
81 _glut_mouse_init();
82
83 for (i = 0; i < MAX_WINDOWS; i++) {
84 w = _glut_windows[i];
85 if (w != NULL) {
86 glutSetWindow(w->num);
87 glutPostRedisplay();
88 if (w->reshape) {
89 w->reshape(w->width, w->height);
90 }
91 if (w->visibility) {
92 w->visibility(GLUT_VISIBLE);
93 }
94 }
95 }
96 virgin = GL_FALSE;
97 }
98
99 idle = GL_TRUE;
100
101 n = 0;
102 for (i = 0; i < MAX_WINDOWS; i++) {
103 w = _glut_windows[i];
104 if ((w != NULL) && (w != _glut_current)) {
105 /* 1) redisplay `w'
106 * 2) `MakeCurrent' always
107 * 3) update number of non-default windows
108 */
109 DO_REDISPLAY(w, GL_TRUE, n++);
110 }
111 }
112 /* 1) redisplay `_glut_current'
113 * 2) `MakeCurrent' only if we previously did non-default windows
114 * 3) don't update anything
115 */
116 DO_REDISPLAY(_glut_current, n, n);
117
118 if (_glut_mouse) {
119 int mouse_x;
120 int mouse_y;
121 int mouse_z;
122 int mouse_b;
123
124 /* query mouse */
125 mouse_b = pc_query_mouse(&mouse_x, &mouse_y, &mouse_z);
126
127 /* relative to window coordinates */
128 _glut_mouse_x = mouse_x - _glut_current->xpos;
129 _glut_mouse_y = mouse_y - _glut_current->ypos;
130
131 /* mouse was moved? */
132 if ((mouse_x != old_mouse_x) || (mouse_y != old_mouse_y)) {
133 idle = GL_FALSE;
134 old_mouse_x = mouse_x;
135 old_mouse_y = mouse_y;
136
137 if (mouse_b) {
138 /* any button pressed */
139 if (_glut_current->motion) {
140 _glut_current->motion(_glut_mouse_x, _glut_mouse_y);
141 }
142 } else {
143 /* no button pressed */
144 if (_glut_current->passive) {
145 _glut_current->passive(_glut_mouse_x, _glut_mouse_y);
146 }
147 }
148 }
149
150 /* button state changed? */
151 if (mouse_b != old_mouse_b) {
152 GLUTmouseCB mouse_func;
153
154 if ((mouse_func = _glut_current->mouse)) {
155 if ((old_mouse_b & 1) && !(mouse_b & 1))
156 mouse_func(GLUT_LEFT_BUTTON, GLUT_UP, _glut_mouse_x, _glut_mouse_y);
157 else if (!(old_mouse_b & 1) && (mouse_b & 1))
158 mouse_func(GLUT_LEFT_BUTTON, GLUT_DOWN, _glut_mouse_x, _glut_mouse_y);
159
160 if ((old_mouse_b & 2) && !(mouse_b & 2))
161 mouse_func(GLUT_RIGHT_BUTTON, GLUT_UP, _glut_mouse_x, _glut_mouse_y);
162 else if (!(old_mouse_b & 2) && (mouse_b & 2))
163 mouse_func(GLUT_RIGHT_BUTTON, GLUT_DOWN, _glut_mouse_x, _glut_mouse_y);
164
165 if ((old_mouse_b & 4) && !(mouse_b & 4))
166 mouse_func(GLUT_MIDDLE_BUTTON, GLUT_UP, _glut_mouse_x, _glut_mouse_y);
167 else if (!(old_mouse_b & 3) && (mouse_b & 4))
168 mouse_func(GLUT_MIDDLE_BUTTON, GLUT_DOWN, _glut_mouse_x, _glut_mouse_y);
169 }
170
171 idle = GL_FALSE;
172 old_mouse_b = mouse_b;
173 }
174 }
175
176 if (pc_keypressed()) {
177 int key;
178 int glut_key;
179
180 idle = GL_FALSE;
181 key = pc_readkey();
182
183 switch (key>>16) {
184 case KEY_F1: glut_key = GLUT_KEY_F1; goto special;
185 case KEY_F2: glut_key = GLUT_KEY_F2; goto special;
186 case KEY_F3: glut_key = GLUT_KEY_F3; goto special;
187 case KEY_F4: glut_key = GLUT_KEY_F4; goto special;
188 case KEY_F5: glut_key = GLUT_KEY_F5; goto special;
189 case KEY_F6: glut_key = GLUT_KEY_F6; goto special;
190 case KEY_F7: glut_key = GLUT_KEY_F7; goto special;
191 case KEY_F8: glut_key = GLUT_KEY_F8; goto special;
192 case KEY_F9: glut_key = GLUT_KEY_F9; goto special;
193 case KEY_F10: glut_key = GLUT_KEY_F10; goto special;
194 case KEY_F11: glut_key = GLUT_KEY_F11; goto special;
195 case KEY_F12: glut_key = GLUT_KEY_F12; goto special;
196 case KEY_LEFT: glut_key = GLUT_KEY_LEFT; goto special;
197 case KEY_UP: glut_key = GLUT_KEY_UP; goto special;
198 case KEY_RIGHT: glut_key = GLUT_KEY_RIGHT; goto special;
199 case KEY_DOWN: glut_key = GLUT_KEY_DOWN; goto special;
200 case KEY_PGUP: glut_key = GLUT_KEY_PAGE_UP; goto special;
201 case KEY_PGDN: glut_key = GLUT_KEY_PAGE_DOWN; goto special;
202 case KEY_HOME: glut_key = GLUT_KEY_HOME; goto special;
203 case KEY_END: glut_key = GLUT_KEY_END; goto special;
204 case KEY_INSERT: glut_key = GLUT_KEY_INSERT; goto special;
205 special:
206 if (_glut_current->special) {
207 _glut_current->special(glut_key, _glut_mouse_x, _glut_mouse_y);
208 }
209 break;
210 default:
211 if (_glut_current->keyboard) {
212 _glut_current->keyboard(key & 0xFF, _glut_mouse_x, _glut_mouse_y);
213 }
214 }
215 }
216
217 if (idle && _glut_idle_func)
218 _glut_idle_func();
219
220 for (i = 0; i < MAX_TIMER_CB; i++) {
221 int time = glutGet(GLUT_ELAPSED_TIME);
222 GLUTSShotCB *cb = &_glut_timer_cb[i];
223 if (cb->func && (time >= cb->time)) {
224 cb->func(cb->value);
225 cb->func = NULL;
226 }
227 }
228 }
229
230
231 void APIENTRY
232 glutMainLoop (void)
233 {
234 looping++;
235 while (looping) {
236 glutMainLoopEvent();
237 }
238 }
239
240
241 void APIENTRY
242 glutLeaveMainLoop (void)
243 {
244 looping--;
245 }