1/***********************************************************
2 *      Copyright (C) 1997, Be Inc.  Copyright (C) 1999, Jake Hamby.
3 *
4 * This program is freely distributable without licensing fees
5 * and is provided without guarantee or warrantee expressed or
6 * implied. This program is -not- in the public domain.
7 *
8 *
9 *  FILE:	glutGet.cpp
10 *
11 *	DESCRIPTION:	get state information from GL
12 ***********************************************************/
13
14/***********************************************************
15 *	Headers
16 ***********************************************************/
17#include <GL/glut.h>
18#include <string.h>
19#include <Autolock.h>
20#include <Screen.h>
21
22#include "glutint.h"
23#include "glutState.h"
24
25/***********************************************************
26 *	Global variables
27 ***********************************************************/
28// rough guess, since we don't know how big the monitor really is
29const float dots_per_mm = (72/25.4);	// dots per millimeter
30
31/***********************************************************
32 *	FUNCTION:	glutGet (9.1)
33 *
34 *	DESCRIPTION:  retrieve window and GL state
35 ***********************************************************/
36int glutGet(GLenum state) {
37	switch(state) {
38	case GLUT_WINDOW_X:
39		{BAutolock winlock(gState.currentWindow->Window());	// need to lock the window
40		if (gState.currentWindow->parent)
41			return (int)gState.currentWindow->Frame().left;
42		else
43			return (int)gState.currentWindow->Window()->Frame().left;
44		}
45	case GLUT_WINDOW_Y:
46		{BAutolock winlock(gState.currentWindow->Window());
47		if (gState.currentWindow->parent)
48			return (int)gState.currentWindow->Frame().top;
49		else
50			return (int)gState.currentWindow->Window()->Frame().top;
51		}
52	case GLUT_WINDOW_WIDTH:
53		{BAutolock winlock(gState.currentWindow->Window());
54		return gState.currentWindow->m_width;
55		}
56	case GLUT_WINDOW_HEIGHT:
57		{BAutolock winlock(gState.currentWindow->Window());
58		return gState.currentWindow->m_height;
59		}
60	case GLUT_WINDOW_PARENT:
61		{BAutolock winlock(gState.currentWindow->Window());
62		if(gState.currentWindow->parent)
63			return gState.currentWindow->parent->num + 1;
64		else
65			return 0;
66		}
67	case GLUT_WINDOW_NUM_CHILDREN:
68		{BAutolock winlock(gState.currentWindow->Window());
69		int num = 0;
70		GlutWindow *children = gState.currentWindow->children;
71		while (children) {
72			num++;
73			children = children->siblings;
74		}
75		return num;
76		}
77  case GLUT_WINDOW_BUFFER_SIZE:	// best guesses
78  case GLUT_WINDOW_DEPTH_SIZE:
79        return 32;
80
81  case GLUT_WINDOW_STENCIL_SIZE:
82  case GLUT_WINDOW_RED_SIZE:		// always 24-bit color
83  case GLUT_WINDOW_GREEN_SIZE:
84  case GLUT_WINDOW_BLUE_SIZE:
85  case GLUT_WINDOW_ALPHA_SIZE:
86  case GLUT_WINDOW_ACCUM_RED_SIZE:
87  case GLUT_WINDOW_ACCUM_GREEN_SIZE:
88  case GLUT_WINDOW_ACCUM_BLUE_SIZE:
89  case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
90        return 8;
91
92  case GLUT_WINDOW_DOUBLEBUFFER:	// always double-buffered RGBA
93  case GLUT_WINDOW_RGBA:
94        return 1;
95
96  case GLUT_WINDOW_COLORMAP_SIZE:	// don't support these
97  case GLUT_WINDOW_NUM_SAMPLES:
98  case GLUT_WINDOW_STEREO:
99        return 0;
100
101 	case GLUT_WINDOW_CURSOR:
102 		return gState.currentWindow->cursor;	// don't need to lock window since it won't change
103
104	case GLUT_SCREEN_WIDTH:
105		return (int)(BScreen().Frame().Width()) + 1;
106	case GLUT_SCREEN_HEIGHT:
107		return (int)(BScreen().Frame().Height()) + 1;
108	case GLUT_SCREEN_WIDTH_MM:
109		return (int)((BScreen().Frame().Width() + 1) / dots_per_mm);
110	case GLUT_SCREEN_HEIGHT_MM:
111		return (int)((BScreen().Frame().Height() + 1) / dots_per_mm);
112	case GLUT_MENU_NUM_ITEMS:
113		return gState.currentMenu->num;
114	case GLUT_DISPLAY_MODE_POSSIBLE:
115		return __glutConvertDisplayMode(0);	// returns 1 if possible
116	case GLUT_INIT_DISPLAY_MODE:
117		return gState.displayMode;
118	case GLUT_INIT_WINDOW_X:
119		return gState.initX;
120	case GLUT_INIT_WINDOW_Y:
121		return gState.initY;
122	case GLUT_INIT_WINDOW_WIDTH:
123		return gState.initWidth;
124	case GLUT_INIT_WINDOW_HEIGHT:
125		return gState.initHeight;
126	case GLUT_ELAPSED_TIME:
127		bigtime_t elapsed, beginning, now;
128		__glutInitTime(&beginning);
129		now = system_time();
130		elapsed = now - beginning;
131		return (int) (elapsed / 1000);	// 1000 ticks in a millisecond
132	default:
133		__glutWarning("invalid glutGet parameter: %d", state);
134		return -1;
135	}
136}
137
138/***********************************************************
139 *	FUNCTION:	glutLayerGet (9.2)
140 *
141 *	DESCRIPTION:  since we don't support layers, this is easy
142 ***********************************************************/
143int glutLayerGet(GLenum info) {
144	switch(info) {
145	case GLUT_OVERLAY_POSSIBLE:
146	case GLUT_HAS_OVERLAY:
147		return 0;
148	case GLUT_LAYER_IN_USE:
149		return GLUT_NORMAL;
150	case GLUT_TRANSPARENT_INDEX:
151		return -1;
152	case GLUT_NORMAL_DAMAGED:
153		return gState.currentWindow->displayEvent;
154	case GLUT_OVERLAY_DAMAGED:
155		return -1;
156	default:
157		__glutWarning("invalid glutLayerGet param: %d", info);
158		return -1;
159	}
160}
161
162/***********************************************************
163 *	FUNCTION:	glutDeviceGet (9.3)
164 *
165 *	DESCRIPTION:  get info about I/O devices we support
166 *		easy, since BeOS only supports a keyboard and mouse now
167 ***********************************************************/
168int glutDeviceGet(GLenum info) {
169	switch(info) {
170	case GLUT_HAS_KEYBOARD:
171	case GLUT_HAS_MOUSE:
172		return 1;
173
174	case GLUT_HAS_SPACEBALL:
175	case GLUT_NUM_SPACEBALL_BUTTONS:
176	case GLUT_HAS_DIAL_AND_BUTTON_BOX:
177	case GLUT_NUM_DIALS:
178	case GLUT_NUM_BUTTON_BOX_BUTTONS:
179	case GLUT_HAS_TABLET:
180	case GLUT_NUM_TABLET_BUTTONS:
181	case GLUT_HAS_JOYSTICK:
182	case GLUT_JOYSTICK_POLL_RATE:
183	case GLUT_JOYSTICK_BUTTONS:
184	case GLUT_JOYSTICK_AXES:
185		return 0;
186
187	case GLUT_NUM_MOUSE_BUTTONS:
188	    {
189		int32 mouseButtons = 3;		// good guess
190		if(get_mouse_type(&mouseButtons) != B_OK) {
191			__glutWarning("error getting number of mouse buttons");
192		}
193		return mouseButtons;
194	    }
195
196	case GLUT_DEVICE_IGNORE_KEY_REPEAT:
197		if (gState.currentWindow)
198			return gState.currentWindow->ignoreKeyRepeat;
199 		return 0;
200
201	case GLUT_DEVICE_KEY_REPEAT:
202		return GLUT_KEY_REPEAT_DEFAULT;
203
204	default:
205		__glutWarning("invalid glutDeviceGet parameter: %d", info);
206		return -1;
207	}
208}
209
210/***********************************************************
211 *	FUNCTION:	glutGetModifiers (9.4)
212 *
213 *	DESCRIPTION:  get the modifier key state for the current window
214 ***********************************************************/
215int glutGetModifiers() {
216	if(gState.modifierKeys == (int) ~0) {
217	  __glutWarning(
218		"glutCurrentModifiers: do not call outside core input callback.");
219    return 0;
220	}
221	return gState.modifierKeys;
222}
223
224
225#ifdef __HAIKU__
226
227extern "C" {
228GLUTproc __glutGetProcAddress(const char* procName);
229}
230
231GLUTproc
232__glutGetProcAddress(const char* procName)
233{
234	if (gState.currentWindow)
235		return (GLUTproc) gState.currentWindow->GetGLProcAddress(procName);
236	return NULL;
237}
238
239#endif
240