1 /*
2  * (c) Copyright 1993, Silicon Graphics, Inc.
3  * ALL RIGHTS RESERVED
4  * Permission to use, copy, modify, and distribute this software for
5  * any purpose and without fee is hereby granted, provided that the above
6  * copyright notice appear in all copies and that both the copyright notice
7  * and this permission notice appear in supporting documentation, and that
8  * the name of Silicon Graphics, Inc. not be used in advertising
9  * or publicity pertaining to distribution of the software without specific,
10  * written prior permission.
11  *
12  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
13  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
14  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
15  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
16  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
17  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
18  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
19  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
20  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
21  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
22  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
23  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
24  *
25  * US Government Users Restricted Rights
26  * Use, duplication, or disclosure by the Government is subject to
27  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
28  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
29  * clause at DFARS 252.227-7013 and/or in similar or successor
30  * clauses in the FAR or the DOD or NASA FAR Supplement.
31  * Unpublished-- rights reserved under the copyright laws of the
32  * United States.  Contractor/manufacturer is Silicon Graphics,
33  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
34  *
35  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
36  */
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <X11/keysym.h>
42 
43 #include "battalion.h"
44 
45 #if defined(__cplusplus) || defined(c_plusplus)
46 #define class c_class
47 #endif
48 
49 
50 /******************************************************************************/
51 
52 static struct _WINDOWINFO
53     {
54     int x, y;
55     int width, height;
56     GLenum type;
57     } windInfo = { -1, -1, 100, 100, 0};
58 
59 static Display *display		= 0;
60 static XVisualInfo *visualInfo	= 0;
61 static Window window		= 0;
62 static int screen		= 0;
63 static GLXContext context	= 0;
64 
65 
66 
67 static GLenum (*KeyDownFunc)(int, GLenum)	    = NULL;
68 static GLenum (*MouseDownFunc)(int, int, GLenum)    = NULL;
69 static GLenum (*MouseUpFunc)(int, int, GLenum)	    = NULL;
70 static GLenum (*MouseMoveFunc)(int, int, GLenum)    = NULL;
71 
72 static int lastEventType = -1;
73 static Colormap colorMap;
74 
75 static float colorMaps[] = {
76     0.000000, 1.000000, 0.000000, 1.000000, 0.000000, 1.000000,
77     0.000000, 1.000000, 0.333333, 0.776471, 0.443137, 0.556863,
78     0.443137, 0.556863, 0.219608, 0.666667, 0.666667, 0.333333,
79     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333,
80     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333,
81     0.666667, 0.333333, 0.039216, 0.078431, 0.117647, 0.156863,
82     0.200000, 0.239216, 0.278431, 0.317647, 0.356863, 0.400000,
83     0.439216, 0.478431, 0.517647, 0.556863, 0.600000, 0.639216,
84     0.678431, 0.717647, 0.756863, 0.800000, 0.839216, 0.878431,
85     0.917647, 0.956863, 0.000000, 0.000000, 0.000000, 0.000000,
86     0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059,
87     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
88     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
89     0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020,
90     0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000,
91     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
92     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
93     0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059,
94     0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039,
95     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
96     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
97     0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000,
98     1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000,
99     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
100     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
101     0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039,
102     0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020,
103     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
104     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
105     1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000,
106     0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059,
107     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
108     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
109     0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020,
110     0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000,
111     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
112     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
113     0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059,
114     0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039,
115     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
116     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
117     0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000,
118     1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000,
119     1.000000, 1.000000, 0.000000, 0.000000, 1.000000, 1.000000,
120     0.333333, 0.443137, 0.776471, 0.556863, 0.443137, 0.219608,
121     0.556863, 0.666667, 0.666667, 0.333333, 0.666667, 0.333333,
122     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333,
123     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333,
124     0.039216, 0.078431, 0.117647, 0.156863, 0.200000, 0.239216,
125     0.278431, 0.317647, 0.356863, 0.400000, 0.439216, 0.478431,
126     0.517647, 0.556863, 0.600000, 0.639216, 0.678431, 0.717647,
127     0.756863, 0.800000, 0.839216, 0.878431, 0.917647, 0.956863,
128     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
129     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
130     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
131     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
132     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
133     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
134     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
135     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
136     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
137     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
138     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
139     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
140     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
141     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
142     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
143     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
144     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
145     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
146     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
147     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
148     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
149     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
150     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
151     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
152     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
153     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
154     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
155     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
156     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
157     0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451,
158     0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176,
159     0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000,
160     0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726,
161     0.854902, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000,
162     1.000000, 1.000000, 1.000000, 1.000000, 0.333333, 0.443137,
163     0.443137, 0.219608, 0.776471, 0.556863, 0.556863, 0.666667,
164     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333,
165     0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333,
166     0.666667, 0.333333, 0.666667, 0.333333, 0.039216, 0.078431,
167     0.117647, 0.156863, 0.200000, 0.239216, 0.278431, 0.317647,
168     0.356863, 0.400000, 0.439216, 0.478431, 0.517647, 0.556863,
169     0.600000, 0.639216, 0.678431, 0.717647, 0.756863, 0.800000,
170     0.839216, 0.878431, 0.917647, 0.956863, 0.000000, 0.000000,
171     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
172     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
173     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
174     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
175     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
176     0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
177     0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059,
178     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
179     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
180     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
181     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
182     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
183     0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059,
184     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
185     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
186     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
187     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
188     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
189     0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039,
190     0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020,
191     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
192     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
193     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
194     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
195     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
196     0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020,
197     0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000,
198     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
199     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
200     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
201     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
202     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
203     1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
204 };
205 
206 /******************************************************************************/
207 
tkCloseWindow(void)208 void tkCloseWindow(void)
209     {
210 
211     if (display)
212 	{
213 	glFlush();
214 	glFinish();
215 	XDestroyWindow(display, window);
216 	glXDestroyContext(display, context);
217 	XFreeColormap(display, colorMap);
218 	XFree((char *)visualInfo);
219 	display = 0;
220 
221 	KeyDownFunc	= 0;
222 	MouseDownFunc	= 0;
223 	MouseUpFunc	= 0;
224 	MouseMoveFunc	= 0;
225 
226 	lastEventType	= -1;
227 	}
228     }
229 
230 /******************************************************************************/
231 
DoNextEvent(void)232 static GLenum DoNextEvent(void)
233 {
234     XEvent current, ahead;
235     char buf[1000];
236     KeySym ks;
237     int key;
238     GLenum mask;
239     extern int paused;
240 
241     XNextEvent(display, &current);
242     switch (current.type) {
243 
244       case MappingNotify:
245 	XRefreshKeyboardMapping((XMappingEvent *)&current);
246 	lastEventType = MappingNotify;
247 
248 	return GL_FALSE;
249 
250       case UnmapNotify:
251 	paused = 1;
252 	return GL_FALSE;
253 
254       case Expose:
255 	while (XEventsQueued(current.xexpose.display, QueuedAfterReading) > 0)
256 	    {
257 	    XPeekEvent(current.xexpose.display, &ahead);
258 	    if (ahead.xexpose.window != current.xexpose.window || ahead.type != Expose)
259 		{
260 		break;
261 		}
262 	    XNextEvent(display, &current);
263 	    }
264 
265 	if (current.xexpose.count == 0)
266 	    {
267 	    reshape(windInfo.width, windInfo.height);
268 	    if (lastEventType == ConfigureNotify)
269 		{
270 		lastEventType = Expose;
271 		return GL_FALSE;
272 		}
273 	    else
274 		{
275 		lastEventType = Expose;
276 		return GL_TRUE;
277 		}
278 	    }
279 
280 	return GL_FALSE;
281 
282       case ConfigureNotify:
283 	lastEventType	= ConfigureNotify;
284 	windInfo.width	= current.xconfigure.width;
285 	windInfo.height = current.xconfigure.height;
286 	reshape(windInfo.width, windInfo.height);
287 	return GL_TRUE;
288 
289       case ButtonPress:
290 	lastEventType = ButtonPress;
291 
292 	    mask = 0;
293 	    if (current.xbutton.button == 1)
294 		{
295 		mask |= TK_LEFTBUTTON;
296 		}
297 	    if (current.xbutton.button == 2)
298 		{
299 		mask |= TK_MIDDLEBUTTON;
300 		}
301 	    if (current.xbutton.button == 3)
302 		{
303 		mask |= TK_RIGHTBUTTON;
304 		}
305 
306 	    return MouseDown(current.xbutton.x, current.xbutton.y, mask);
307 
308 
309       case ButtonRelease:
310 	lastEventType = ButtonRelease;
311 
312 	    mask = 0;
313 	    if (current.xbutton.button == 1)
314 		{
315 		mask |= TK_LEFTBUTTON;
316 		}
317 	    if (current.xbutton.button == 2)
318 		{
319 		mask |= TK_MIDDLEBUTTON;
320 		}
321 	    if (current.xbutton.button == 3)
322 		{
323 		mask |= TK_RIGHTBUTTON;
324 		}
325 
326 	    return MouseUp(current.xbutton.x, current.xbutton.y, mask);
327 
328       case KeyPress:
329 	lastEventType = KeyPress;
330 	XLookupString(&current.xkey, buf, sizeof(buf), &ks, 0);
331 	switch (ks) {
332 	  case XK_a: 		key = TK_a;		break;
333 	  case XK_A: 		key = TK_A;		break;
334 	  case XK_z: 		key = TK_z;		break;
335 	  case XK_Z: 		key = TK_Z;		break;
336 	  case XK_Control_L:	key = TK_CONTROL_L;	break;
337 	  case XK_Control_R:	key = TK_CONTROL_R;	break;
338 	  case XK_Left:		key = TK_LEFT;		break;
339 	  case XK_Up:		key = TK_UP;		break;
340 	  case XK_Right:  	key = TK_RIGHT;		break;
341 	  case XK_Down:		key = TK_DOWN;		break;
342 
343 	  case XK_I: 		key = TK_I;		break;
344 	  case XK_J: 		key = TK_J;		break;
345 	  case XK_K: 		key = TK_K;		break;
346 	  case XK_L: 		key = TK_L;		break;
347 	  case XK_i: 		key = TK_i;		break;
348 	  case XK_j: 		key = TK_j;		break;
349 	  case XK_k: 		key = TK_k;		break;
350 	  case XK_l: 		key = TK_l;		break;
351 
352 	  case XK_1: 		key = TK_1;		break;
353 	  case XK_2: 		key = TK_2;		break;
354 	  case XK_3: 		key = TK_3;		break;
355 	  case XK_4: 		key = TK_4;		break;
356 
357 	  case XK_D: 		key = TK_D;		break;
358 	  case XK_H: 		key = TK_H;		break;
359 	  case XK_M: 		key = TK_M;		break;
360 	  case XK_P: 		key = TK_P;		break;
361 	  case XK_S: 		key = TK_S;		break;
362 	  case XK_T: 		key = TK_T;		break;
363 	  case XK_d: 		key = TK_d;		break;
364 	  case XK_h: 		key = TK_h;		break;
365 	  case XK_m: 		key = TK_m;		break;
366 	  case XK_p: 		key = TK_p;		break;
367 	  case XK_s: 		key = TK_s;		break;
368 
369 	  case XK_6: 		key = TK_6;		break;
370 	  case XK_7: 		key = TK_7;		break;
371 	  case XK_8: 		key = TK_8;		break;
372 	  case XK_9: 		key = TK_9;		break;
373 	  case XK_space:	key = TK_SPACE;		break;
374 	  case XK_Escape: 	key = TK_ESCAPE;	break;
375 
376 	  case XK_q: 		key = TK_q;		break;
377 	  case XK_w: 		key = TK_w;		break;
378 
379 	  case XK_g: 		key = TK_g;		break;
380 	  case XK_G: 		key = TK_G;		break;
381 
382 	  default: 		key = GL_FALSE;		break;
383 	}
384 
385 	if (key)
386 	    {
387 	    return processKey(key, 0);
388 	    }
389 	else
390 	    {
391  	    return GL_FALSE;
392 	    }
393 
394 /*
395  * Stuff below added by Johan Hagman for ctrl key to turn weapon on
396  * rather than as a toggle for the weapon
397  */
398 
399       case KeyRelease:
400 	lastEventType = KeyPress;
401 	XLookupString(&current.xkey, buf, sizeof(buf), &ks, 0);
402 	switch (ks) {
403 	  case XK_Control_L:	key = TK_CONTROL_L;	break;
404 	  default: 		key = GL_FALSE;		break;
405 	}
406 
407 	if (key)
408 	    return processKeyRelease(key);
409 	else
410 	    return GL_FALSE;
411 
412     }
413     return GL_FALSE;
414 }
415 
416 /******************************************************************************/
417 
418 /********************************************
419 Andy's new shorter version of the tkExec
420 function to try and speed things up a bit
421 ********************************************/
tkExec(void)422 void tkExec(void)
423     {
424     while (GL_TRUE)
425 	{
426 	id();
427 
428 	while (XPending(display))
429 	    DoNextEvent();
430 	}
431     }
432 
433 
434 /******************************************************************************/
435 
tkGetMouseLoc(int * x,int * y)436 void tkGetMouseLoc(int *x, int *y)
437     {
438     int junk;
439 
440     *x = 0;
441     *y = 0;
442     XQueryPointer(display, window, (Window *)&junk, (Window *)&junk,
443 		  &junk, &junk, x, y, (unsigned int *)&junk);
444     }
445 
446 /******************************************************************************/
447 
FindVisual(GLenum type)448 static XVisualInfo *FindVisual(GLenum type)
449     {
450     int list[32];
451     int i;
452 
453     i = 0;
454 
455     list[i++] = GLX_LEVEL;
456     list[i++] = 0;
457 
458     if (TK_IS_DOUBLE(type)) {
459 	list[i++] = (int) GLX_DOUBLEBUFFER;
460     }
461 
462     if (TK_IS_RGB(type))
463 	{
464 	list[i++] = GLX_RGBA;
465 	list[i++] = GLX_RED_SIZE;
466 	list[i++] = 1;
467 	list[i++] = GLX_GREEN_SIZE;
468 	list[i++] = 1;
469 	list[i++] = GLX_BLUE_SIZE;
470 	list[i++] = 1;
471 
472 	if (TK_HAS_ALPHA(type))
473 	    {
474 	    list[i++] = GLX_ALPHA_SIZE;
475 	    list[i++] = 1;
476 	    }
477 
478 	if (TK_HAS_ACCUM(type))
479 	    {
480 	    list[i++] = GLX_ACCUM_RED_SIZE;
481 	    list[i++] = 1;
482 	    list[i++] = GLX_ACCUM_GREEN_SIZE;
483 	    list[i++] = 1;
484 	    list[i++] = GLX_ACCUM_BLUE_SIZE;
485 	    list[i++] = 1;
486 
487 	    if (TK_HAS_ALPHA(type))
488 		{
489 		list[i++] = GLX_ACCUM_ALPHA_SIZE;
490 		list[i++] = 1;
491 	    }
492 	    }
493 	}
494     else if (TK_IS_INDEX(type))
495 	{
496 	list[i++] = GLX_BUFFER_SIZE;
497 	list[i++] = 1;
498 	}
499 
500     if (TK_HAS_DEPTH(type))
501 	{
502 	list[i++] = GLX_DEPTH_SIZE;
503 	list[i++] = 1;
504 	}
505 
506     if (TK_HAS_STENCIL(type))
507 	{
508 	list[i++] = GLX_STENCIL_SIZE;
509 	list[i++] = 1;
510 	}
511 
512     list[i] = None;
513 
514     return glXChooseVisual(display, screen, (int *) list);
515     }
516 
517 /******************************************************************************/
518 
MakeVisualType(XVisualInfo * vi)519 static int MakeVisualType(XVisualInfo *vi)
520     {
521     GLenum mask;
522     int x, y, z;
523 
524     mask = 0;
525 
526     glXGetConfig(display, vi, GLX_RGBA, &x);
527 
528     if (x) {
529 	mask |= TK_RGB;
530 
531 	glXGetConfig(display, vi, GLX_ALPHA_SIZE, &x);
532 	if (x > 0)
533 	    {
534 	    mask |= TK_ALPHA;
535 	    }
536 
537 	glXGetConfig(display, vi, GLX_ACCUM_RED_SIZE, &x);
538 	glXGetConfig(display, vi, GLX_ACCUM_GREEN_SIZE, &y);
539 	glXGetConfig(display, vi, GLX_ACCUM_BLUE_SIZE, &z);
540 
541 	if (x > 0 && y > 0 && z > 0)
542 	    {
543 	    mask |= TK_ACCUM;
544 	    }
545 	}
546     else
547 	{
548 	mask |= TK_INDEX;
549 	}
550 
551     glXGetConfig(display, vi, GLX_DOUBLEBUFFER, &x);
552     if (x)
553 	{
554 	mask |= TK_DOUBLE;
555 	}
556     else
557 	{
558 	mask |= TK_SINGLE;
559 	}
560 
561     glXGetConfig(display, vi, GLX_DEPTH_SIZE, &x);
562     if (x > 0)
563 	{
564 	mask |= TK_DEPTH;
565 	}
566 
567     glXGetConfig(display, vi, GLX_STENCIL_SIZE, &x);
568     if (x > 0)
569 	{
570 	mask |= TK_STENCIL;
571 	}
572 
573     if (glXIsDirect(display, context))
574 	{
575 	mask |= TK_DIRECT;
576 	}
577     else
578 	{
579 	mask |= TK_INDIRECT;
580 	}
581 
582     return mask;
583     }
584 
585 /******************************************************************************/
586 
WaitForMapNotify(Display * d,XEvent * e,char * arg)587 static int WaitForMapNotify(Display *d, XEvent *e, char *arg)
588     {
589     Display *display;
590     char *arguments;
591 
592     display = d;
593     arguments = arg;
594 
595 	if (e->type == MapNotify && e->xmap.window == window) {
596 	    return GL_TRUE;
597 	}
598 	return GL_FALSE;
599     }
600 
601 /******************************************************************************/
602 
tkInitPosition(int x,int y,int width,int height)603 void tkInitPosition(int x, int y, int width, int height)
604     {
605     windInfo.x	    = x;
606     windInfo.y	    = y;
607     windInfo.width  = width;
608     windInfo.height = height;
609     }
610 
611 /******************************************************************************/
612 
tkInitDisplayMode(GLenum type)613 void tkInitDisplayMode(GLenum type)
614     {
615     windInfo.type = type;
616     }
617 
618 /******************************************************************************/
619 
tkInitWindow(char * title)620 GLenum tkInitWindow(char *title)
621 {
622     XSetWindowAttributes wa;
623     XSizeHints sh;
624     XEvent e;
625     int erb, evb;
626     unsigned long mask;
627 
628     if (!display)
629 	{
630 	display = XOpenDisplay(0);
631 	if (!display)
632 	    {
633 	    fprintf(stderr, "Can't connect to display!\n");
634 	    return GL_FALSE;
635 	    }
636 
637 	if (!glXQueryExtension(display, &erb, &evb))
638 	    {
639 	    fprintf(stderr, "No glx extension!\n");
640 	    return GL_FALSE;
641 	    }
642 
643 	screen = DefaultScreen(display);
644 	}
645 
646     visualInfo = FindVisual(windInfo.type);
647 
648     if (!visualInfo)
649 	{
650 	fprintf(stderr, "Window type not found!\n");
651 	return GL_FALSE;
652 	}
653 
654     context = glXCreateContext(display, visualInfo, None,
655 			       (TK_IS_DIRECT(windInfo.type)) ? GL_TRUE
656 							     : GL_FALSE);
657     if (!context)
658 	{
659 	fprintf(stderr, "Can't create a context!\n");
660 	return GL_FALSE;
661 	}
662 
663     windInfo.type = MakeVisualType(visualInfo);
664 
665     if (TK_IS_INDEX(windInfo.type))
666 	{
667 	if (visualInfo->class != StaticColor && visualInfo->class != StaticGray)
668 	    {
669 	    colorMap = XCreateColormap(display, RootWindow(display, screen),
670 				       visualInfo->visual, AllocAll);
671 	    }
672 	else
673 	    {
674 	    colorMap = XCreateColormap(display, RootWindow(display, screen),
675 				       visualInfo->visual, AllocNone);
676 	    }
677 
678 	wa.colormap = colorMap;
679 	tkSetRGBMap(256, colorMaps);
680 	wa.background_pixel = 7;
681 	wa.border_pixel = 0;
682 	}
683     else
684 	{
685 	colorMap = XCreateColormap(display, RootWindow(display, screen),
686 				   visualInfo->visual, AllocNone);
687 	wa.colormap = colorMap;
688 	tkSetRGBMap(256, colorMaps);
689 	wa.background_pixel = 0xFFFFFFFF;
690 	wa.border_pixel = 0;
691 	}
692 
693     wa.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask |
694 
695 		    KeyReleaseMask |
696 
697 		    ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
698 
699     mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
700 
701     window = XCreateWindow(display, RootWindow(display, screen), 0, 0,
702 			   windInfo.width, windInfo.height, 0,
703 			   visualInfo->depth, InputOutput, visualInfo->visual,
704 			   mask, &wa);
705 
706     if ((windInfo.x != -1) && (windInfo.y != -1))
707 	{
708 	sh.flags    = USPosition;
709 	sh.x	    = windInfo.x + 10;
710 	sh.y	    = windInfo.y + 10;
711 
712 	XSetStandardProperties(display, window, title, title, None, 0, 0, &sh);
713 	}
714     else
715 	{
716 	XSetStandardProperties(display, window, title, title, None, 0, 0, 0);
717 	}
718 
719     XMapWindow(display, window);
720     XIfEvent(display, &e, WaitForMapNotify, 0);
721 
722     XSetWMColormapWindows(display, window, &window, 1);
723 
724     if (!glXMakeCurrent(display, window, context))
725 	{
726 	fprintf(stderr, "Can't make window current drawable!\n");
727 	return GL_FALSE;
728 	}
729 
730     XFlush(display);
731 
732     return GL_TRUE;
733 }
734 
735 /******************************************************************************/
736 
Ignore(Display * parm1,XErrorEvent * parm2)737 static int Ignore(Display *parm1, XErrorEvent *parm2)
738     {
739     Display *display;
740     XErrorEvent *error;
741 
742     display = parm1;
743     error = parm2;
744 
745 	return 0;
746     }
747 
748 /******************************************************************************/
749 
tkSetRGBMap(int size,float * rgb)750 void tkSetRGBMap(int size, float *rgb)
751 {
752     XErrorHandler old_handler;
753     XColor c;
754     int rShift, gShift, bShift, max, i;
755 
756     old_handler = XSetErrorHandler(Ignore);
757 
758     switch (visualInfo->class) {
759       case DirectColor:
760 	max = (size > visualInfo->colormap_size) ? visualInfo->colormap_size
761 						 : size;
762 	for (i = 0; i < max; i++)
763 	    {
764 	    rShift = ffs((unsigned int)visualInfo->red_mask) - 1;
765 	    gShift = ffs((unsigned int)visualInfo->green_mask) - 1;
766 	    bShift = ffs((unsigned int)visualInfo->blue_mask) - 1;
767 	    c.pixel = ((i << rShift) & visualInfo->red_mask) |
768 		      ((i << gShift) & visualInfo->green_mask) |
769 		      ((i << bShift) & visualInfo->blue_mask);
770 
771 	    c.red = (unsigned short)(rgb[i] * 65535.0 + 0.5);
772 	    c.green = (unsigned short)(rgb[size+i] * 65535.0 + 0.5);
773 	    c.blue = (unsigned short)(rgb[size*2+i] * 65535.0 + 0.5);
774 
775 	    c.flags = DoRed | DoGreen | DoBlue;
776 	    XStoreColor(display, colorMap, &c);
777 	    }
778 	break;
779 
780       case GrayScale:
781       case PseudoColor:
782 	max = (size > visualInfo->colormap_size) ? visualInfo->colormap_size
783 						 : size;
784 	for (i = 0; i < max; i++) {
785 	    c.pixel = i;
786 	    c.red = (unsigned short)(rgb[i] * 65535.0 + 0.5);
787 	    c.green = (unsigned short)(rgb[size+i] *
788 				       65535.0 + 0.5);
789 	    c.blue = (unsigned short)(rgb[size*2+i] *
790 				      65535.0 + 0.5);
791 	    c.flags = DoRed | DoGreen | DoBlue;
792 	    XStoreColor(display, colorMap, &c);
793 	}
794 	break;
795     }
796 
797     XSync(display, 0);
798     XSetErrorHandler(old_handler);
799 }
800 
801 /******************************************************************************/
802 
tkSwapBuffers(void)803 void tkSwapBuffers(void)
804 {
805     if (display) {
806 	glXSwapBuffers(display, window);
807     }
808 }
809 
810 /******************************************************************************/
811 
812 /*
813  * Stuff below added by Johan Hagman for pointer
814  * grabbing in Solaris battalion
815  */
816 
unGrabPointer()817 void unGrabPointer()
818 {
819     /* Ungrab the pointer */
820     XUngrabPointer(display, CurrentTime);
821 }
822 
823 
grabPointer()824 void grabPointer()
825 {
826     /* Grab the pointer so you cannot move the  mouse out of the main
827      * window. Also set the cursor to a new cursor with no shape.
828      */
829     if (XGrabPointer(display, window, True,
830 			ButtonReleaseMask | ButtonPressMask,
831 			GrabModeAsync, GrabModeAsync, window,
832 			None, CurrentTime) != GrabSuccess)
833     {
834 	/* Error while grab - not too bad but let user know */
835 	fprintf(stderr, "Warning: Pointer grab unsuccessful.");
836     }
837 }
838 
839 /******************************************************************************/
840 
841 
842 /********************************************
843  * void tkExec(void)
844     {
845     GLenum flag;
846 
847     while (GL_TRUE)
848 	{
849 	if (IdleFunc)
850 	    {
851 	    if (IdleFunc)
852 		{
853 		(*IdleFunc)();
854 		}
855 	    flag = GL_FALSE;
856 	    while (XPending(display))
857 		{
858 		flag |= DoNextEvent();
859 		}
860 	    if (flag == GL_TRUE)
861 		{
862 		if (DisplayFunc)
863 		    {
864 		    (*DisplayFunc)();
865 		    }
866 		}
867 	    }
868 	else
869 	    {
870 	    if (DoNextEvent() == GL_TRUE)
871 		{
872 		if (DisplayFunc)
873 		    {
874 		    (*DisplayFunc)();
875 		    }
876 		}
877 	    }
878 	}
879     }
880 
881 ************************************************/
882 
883 /*
884 void tkSetOneColor(int index, float r, float g, float b)
885 {
886     XErrorHandler old_handler;
887     XColor c;
888     int rShift, gShift, bShift;
889 
890     old_handler = XSetErrorHandler(Ignore);
891 
892     switch (visualInfo->class) {
893       case DirectColor:
894 	rShift = ffs((unsigned int)visualInfo->red_mask) - 1;
895 	gShift = ffs((unsigned int)visualInfo->green_mask) - 1;
896 	bShift = ffs((unsigned int)visualInfo->blue_mask) - 1;
897 	c.pixel = ((index << rShift) & visualInfo->red_mask) |
898 		  ((index << gShift) & visualInfo->green_mask) |
899 		  ((index << bShift) & visualInfo->blue_mask);
900 	c.red = (unsigned short)(r * 65535.0 + 0.5);
901 	c.green = (unsigned short)(g * 65535.0 + 0.5);
902 	c.blue = (unsigned short)(b * 65535.0 + 0.5);
903 	c.flags = DoRed | DoGreen | DoBlue;
904 	XStoreColor(display, colorMap, &c);
905 	break;
906       case GrayScale:
907       case PseudoColor:
908 	if (index < visualInfo->colormap_size) {
909 	    c.pixel = index;
910 	    c.red = (unsigned short)(r * 65535.0 + 0.5);
911 	    c.green = (unsigned short)(g * 65535.0 + 0.5);
912 	    c.blue = (unsigned short)(b * 65535.0 + 0.5);
913 	    c.flags = DoRed | DoGreen | DoBlue;
914 	    XStoreColor(display, colorMap, &c);
915 	}
916 	break;
917     }
918 
919     XSync(display, 0);
920     XSetErrorHandler(old_handler);
921 }
922 */
923 /******************************************************************************/
924 /*
925 void tkSetFogRamp(int density, int startIndex)
926 {
927     XErrorHandler old_handler;
928     XColor c[256];
929     int rShift, gShift, bShift, intensity, fogValues, colorValues;
930     int i, j, k;
931 
932     old_handler = XSetErrorHandler(Ignore);
933 
934     switch (visualInfo->class) {
935       case DirectColor:
936 	fogValues = 1 << density;
937 	colorValues = 1 << startIndex;
938 	for (i = 0; i < colorValues; i++) {
939 	    for (j = 0; j < fogValues; j++) {
940 		k = i * fogValues + j;
941 		intensity = i * fogValues + j * colorValues;
942 		if (intensity > visualInfo->colormap_size) {
943 		    intensity = visualInfo->colormap_size;
944 		}
945 		intensity = (intensity << 8) | intensity;
946 		rShift = ffs((unsigned int)visualInfo->red_mask) - 1;
947 		gShift = ffs((unsigned int)visualInfo->green_mask) - 1;
948 		bShift = ffs((unsigned int)visualInfo->blue_mask) - 1;
949 		c[k].pixel = ((k << rShift) & visualInfo->red_mask) |
950 			     ((k << gShift) & visualInfo->green_mask) |
951 			     ((k << bShift) & visualInfo->blue_mask);
952 		c[k].red = (unsigned short)intensity;
953 		c[k].green = (unsigned short)intensity;
954 		c[k].blue = (unsigned short)intensity;
955 		c[k].flags = DoRed | DoGreen | DoBlue;
956 	    }
957 	}
958 	XStoreColors(display, colorMap, c, visualInfo->colormap_size);
959 	break;
960       case GrayScale:
961       case PseudoColor:
962 	fogValues = 1 << density;
963 	colorValues = 1 << startIndex;
964 	for (i = 0; i < colorValues; i++) {
965 	    for (j = 0; j < fogValues; j++) {
966 		k = i * fogValues + j;
967 		intensity = i * fogValues + j * colorValues;
968 		if (intensity > visualInfo->colormap_size) {
969 		    intensity = visualInfo->colormap_size;
970 		}
971 		intensity = (intensity << 8) | intensity;
972 		c[k].pixel = k;
973 		c[k].red = (unsigned short)intensity;
974 		c[k].green = (unsigned short)intensity;
975 		c[k].blue = (unsigned short)intensity;
976 		c[k].flags = DoRed | DoGreen | DoBlue;
977 	    }
978 	}
979 	XStoreColors(display, colorMap, c, visualInfo->colormap_size);
980 	break;
981     }
982 
983     XSync(display, 0);
984     XSetErrorHandler(old_handler);
985 }
986 */
987 /******************************************************************************/
988 /*
989 void tkSetGreyRamp(void)
990 {
991     XErrorHandler old_handler;
992     XColor c[256];
993     float intensity;
994     int rShift, gShift, bShift, i;
995 
996     old_handler = XSetErrorHandler(Ignore);
997 
998     switch (visualInfo->class) {
999       case DirectColor:
1000 	for (i = 0; i < visualInfo->colormap_size; i++) {
1001 	    intensity = (float)i / (float)visualInfo->colormap_size *
1002 			65535.0 + 0.5;
1003 	    rShift = ffs((unsigned int)visualInfo->red_mask) - 1;
1004 	    gShift = ffs((unsigned int)visualInfo->green_mask) - 1;
1005 	    bShift = ffs((unsigned int)visualInfo->blue_mask) - 1;
1006 	    c[i].pixel = ((i << rShift) & visualInfo->red_mask) |
1007 			 ((i << gShift) & visualInfo->green_mask) |
1008 			 ((i << bShift) & visualInfo->blue_mask);
1009 	    c[i].red = (unsigned short)intensity;
1010 	    c[i].green = (unsigned short)intensity;
1011 	    c[i].blue = (unsigned short)intensity;
1012 	    c[i].flags = DoRed | DoGreen | DoBlue;
1013 	}
1014 	XStoreColors(display, colorMap, c, visualInfo->colormap_size);
1015 	break;
1016       case GrayScale:
1017       case PseudoColor:
1018 	for (i = 0; i < visualInfo->colormap_size; i++) {
1019 	    intensity = (float)i / (float)visualInfo->colormap_size *
1020 			65535.0 + 0.5;
1021 	    c[i].pixel = i;
1022 	    c[i].red = (unsigned short)intensity;
1023 	    c[i].green = (unsigned short)intensity;
1024 	    c[i].blue = (unsigned short)intensity;
1025 	    c[i].flags = DoRed | DoGreen | DoBlue;
1026 	}
1027 	XStoreColors(display, colorMap, c, visualInfo->colormap_size);
1028 	break;
1029     }
1030 
1031     XSync(display, 0);
1032     XSetErrorHandler(old_handler);
1033 }
1034 */
1035 
1036 /*
1037       case MotionNotify:
1038 	lastEventType = MotionNotify;
1039 	if (MouseMoveFunc) {
1040 	    GLenum mask;
1041 
1042 	    mask = 0;
1043 	    if (current.xmotion.state & Button1Mask) {
1044 		mask |= TK_LEFTBUTTON;
1045 	    }
1046 	    if (current.xmotion.state & Button2Mask) {
1047 		mask |= TK_MIDDLEBUTTON;
1048 	    }
1049 	    if (current.xmotion.state & Button3Mask) {
1050 		mask |= TK_RIGHTBUTTON;
1051 	    }
1052 	    return (*MouseMoveFunc)(current.xmotion.x, current.xmotion.y, mask);
1053 	} else {
1054 	    return GL_FALSE;
1055 	}
1056 */
1057 
1058 /*
1059  float tkRGBMap[8][3] = {
1060     {
1061 	0, 0, 0
1062     },
1063     {
1064 	1, 0, 0
1065     },
1066     {
1067 	0, 1, 0
1068     },
1069     {
1070 	1, 1, 0
1071     },
1072     {
1073 	0, 0, 1
1074     },
1075     {
1076 	1, 0, 1
1077     },
1078     {
1079 	0, 1, 1
1080     },
1081     {
1082 	1, 1, 1
1083     }
1084 };
1085 
1086  */
1087 /******************************************************************************/
1088 /*
1089 void tkQuit(void)
1090 {
1091 
1092     exit(0);
1093 }
1094 */
1095 
1096  /******************************************************************************/
1097 /*
1098 void tkExposeFunc(void (*Func)(int, int))
1099 {
1100 
1101     ExposeFunc = Func;
1102 }
1103 */
1104 /******************************************************************************/
1105 /*
1106 void tkReshapeFunc(void (*Func)(int, int))
1107 {
1108 
1109     ReshapeFunc = Func;
1110 }
1111 */
1112 /******************************************************************************/
1113 /*
1114 void tkDisplayFunc(void (*Func)(void))
1115 {
1116 
1117     DisplayFunc = Func;
1118 }
1119 */
1120 /******************************************************************************/
1121 /*
1122 void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
1123 {
1124 
1125     KeyDownFunc = Func;
1126 }
1127 */
1128 /******************************************************************************/
1129 /*
1130 void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
1131 {
1132 
1133     MouseDownFunc = Func;
1134 }
1135 */
1136 /******************************************************************************/
1137 /*
1138 void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
1139 {
1140 
1141     MouseUpFunc = Func;
1142 }
1143 */
1144 /******************************************************************************/
1145 /*
1146 void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
1147 {
1148 
1149     MouseMoveFunc = Func;
1150 }
1151 */
1152 /******************************************************************************/
1153 /*
1154 void tkIdleFunc(void (*Func)(void))
1155 {
1156 
1157     IdleFunc = Func;
1158 }
1159 */
1160 /******************************************************************************/
1161 /*
1162 GLint tkGetColorMapSize(void)
1163 {
1164 
1165     if (!display) {
1166 	return 0;
1167     } else {
1168 	return visualInfo->colormap_size;
1169     }
1170 }
1171 */
1172 
1173 /******************************************************************************/
1174 /*
1175 Display *tkGetXDisplay(void)
1176     {
1177     return display;
1178     }
1179 */
1180 /******************************************************************************/
1181 /*
1182 Window tkGetXWindow(void)
1183     {
1184     return window;
1185     }
1186 */
1187 
1188 
1189 /*
1190 static void (*ExposeFunc)(int, int)		    = NULL;
1191 static void (*ReshapeFunc)(int, int)		    = NULL;
1192 static void (*DisplayFunc)(void)		    = NULL;
1193 static void (*IdleFunc)(void)			    = NULL;
1194 */
1195 
1196 
1197 
1198 
1199 /*
1200 	  case XK_0: 		key = TK_0;		break;
1201 	  case XK_5: 		key = TK_5;		break;
1202 	  case XK_B: 		key = TK_B;		break;
1203 	  case XK_C: 		key = TK_C;		break;
1204 	  case XK_E: 		key = TK_E;		break;
1205 	  case XK_F: 		key = TK_F;		break;
1206 	  case XK_G: 		key = TK_G;		break;
1207 	  case XK_N: 		key = TK_N;		break;
1208 	  case XK_O: 		key = TK_O;		break;
1209 	  case XK_Q: 		key = TK_Q;		break;
1210 	  case XK_R: 		key = TK_R;		break;
1211 	  case XK_U: 		key = TK_U;		break;
1212 	  case XK_V: 		key = TK_V;		break;
1213 	  case XK_W: 		key = TK_W;		break;
1214 	  case XK_X: 		key = TK_X;		break;
1215 	  case XK_Y: 		key = TK_Y;		break;
1216 	  case XK_b: 		key = TK_b;		break;
1217 	  case XK_c: 		key = TK_c;		break;
1218 	  case XK_e: 		key = TK_e;		break;
1219 	  case XK_f: 		key = TK_f;		break;
1220 	  case XK_g: 		key = TK_g;		break;
1221 	  case XK_n: 		key = TK_n; 		break;
1222 	  case XK_o: 		key = TK_o;		break;
1223 	  case XK_r: 		key = TK_r;		break;
1224 	  case XK_t: 		key = TK_t;		break;
1225 	  case XK_u: 		key = TK_u;		break;
1226 	  case XK_v: 		key = TK_v;		break;
1227 	  case XK_x: 		key = TK_x;		break;
1228 	  case XK_y: 		key = TK_y;		break;
1229 	  case XK_Shift_L:	key = TK_SHIFT_L;	break;
1230 	  case XK_Shift_R:	key = TK_SHIFT_R;	break;
1231 	  case XK_Return: 	key = TK_RETURN;	break;
1232 */
1233 
1234 
1235