disabled glXGetProcAddress code
[mesa.git] / src / glut / beos / glutMenu.cpp
1 /***********************************************************
2 * Copyright (C) 1997, Be Inc. All rights reserved.
3 *
4 * FILE: glutMenu.cpp
5 *
6 * DESCRIPTION: code for popup menu handling
7 ***********************************************************/
8
9 /***********************************************************
10 * Headers
11 ***********************************************************/
12 #include <GL/glut.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "glutint.h"
16 #include "glutState.h"
17
18 /***********************************************************
19 * Private variables
20 ***********************************************************/
21 static GlutMenu **menuList = 0;
22 static int menuListSize = 0;
23
24 /***********************************************************
25 * FUNCTION: getUnusedMenuSlot
26 *
27 * DESCRIPTION: helper function to get a new menu slot
28 ***********************************************************/
29 GlutMenu *__glutGetMenuByNum(int menunum)
30 {
31 if (menunum < 1 || menunum > menuListSize) {
32 return NULL;
33 }
34 return menuList[menunum - 1];
35 }
36
37 /***********************************************************
38 * FUNCTION: getUnusedMenuSlot
39 *
40 * DESCRIPTION: helper function to get a new menu slot
41 ***********************************************************/
42 static int
43 getUnusedMenuSlot(void)
44 {
45 int i;
46
47 /* Look for allocated, unused slot. */
48 for (i = 0; i < menuListSize; i++) {
49 if (!menuList[i]) {
50 return i;
51 }
52 }
53 /* Allocate a new slot. */
54 menuListSize++;
55 menuList = (GlutMenu **)
56 realloc(menuList, menuListSize * sizeof(GlutMenu *));
57 if (!menuList)
58 __glutFatalError("out of memory.");
59 menuList[menuListSize - 1] = NULL;
60 return menuListSize - 1;
61 }
62
63 /***********************************************************
64 * FUNCTION: glutCreateMenu (6.1)
65 *
66 * DESCRIPTION: create a new menu
67 ***********************************************************/
68 int APIENTRY
69 glutCreateMenu(GLUTselectCB selectFunc)
70 {
71 GlutMenu *menu;
72 int menuid;
73
74 menuid = getUnusedMenuSlot();
75 menu = new GlutMenu(menuid, selectFunc); // constructor sets up members
76 menuList[menuid] = menu;
77 gState.currentMenu = menu;
78 return menuid + 1;
79 }
80
81 /***********************************************************
82 * FUNCTION: glutSetMenu (6.2)
83 * glutGetMenu
84 *
85 * DESCRIPTION: set and get the current menu
86 ***********************************************************/
87 int APIENTRY
88 glutGetMenu(void)
89 {
90 if (gState.currentMenu) {
91 return gState.currentMenu->id + 1;
92 } else {
93 return 0;
94 }
95 }
96
97 void APIENTRY
98 glutSetMenu(int menuid)
99 {
100 GlutMenu *menu;
101
102 if (menuid < 1 || menuid > menuListSize) {
103 __glutWarning("glutSetMenu attempted on bogus menu.");
104 return;
105 }
106 menu = menuList[menuid - 1];
107 if (!menu) {
108 __glutWarning("glutSetMenu attempted on bogus menu.");
109 return;
110 }
111 gState.currentMenu = menu;
112 }
113
114 /***********************************************************
115 * FUNCTION: glutDestroyMenu (6.3)
116 *
117 * DESCRIPTION: destroy the specified menu
118 ***********************************************************/
119 void APIENTRY
120 glutDestroyMenu(int menunum)
121 {
122 GlutMenu *menu = __glutGetMenuByNum(menunum);
123 menuList[menunum - 1] = 0;
124 if (gState.currentMenu == menu) {
125 gState.currentMenu = 0;
126 }
127 delete menu;
128 }
129
130 /***********************************************************
131 * FUNCTION: glutAddMenuEntry (6.4)
132 *
133 * DESCRIPTION: add a new menu item
134 ***********************************************************/
135 void
136 glutAddMenuEntry(const char *label, int value)
137 {
138 new GlutMenuItem(gState.currentMenu, false, value, label);
139 }
140
141 /***********************************************************
142 * FUNCTION: glutAddSubMenu (6.5)
143 *
144 * DESCRIPTION: add a new submenu
145 ***********************************************************/
146 void
147 glutAddSubMenu(const char *label, int menu)
148 {
149 new GlutMenuItem(gState.currentMenu, true, menu-1, label);
150 }
151
152 /***********************************************************
153 * FUNCTION: glutChangeToMenuEntry (6.6)
154 *
155 * DESCRIPTION: change menuitem into a menu entry
156 ***********************************************************/
157 void
158 glutChangeToMenuEntry(int num, const char *label, int value)
159 {
160 GlutMenuItem *item;
161 int i;
162
163 i = gState.currentMenu->num;
164 item = gState.currentMenu->list;
165 while (item) {
166 if (i == num) {
167 free(item->label);
168 item->label = strdup(label);
169 item->isTrigger = false;
170 item->value = value;
171 return;
172 }
173 i--;
174 item = item->next;
175 }
176 __glutWarning("Current menu has no %d item.", num);
177 }
178
179 /***********************************************************
180 * FUNCTION: glutChangeToSubMenu (6.7)
181 *
182 * DESCRIPTION: change menuitem into a submenu
183 ***********************************************************/
184 void
185 glutChangeToSubMenu(int num, const char *label, int menu)
186 {
187 GlutMenuItem *item;
188 int i;
189
190 i = gState.currentMenu->num;
191 item = gState.currentMenu->list;
192 while (item) {
193 if (i == num) {
194 free(item->label);
195 item->label = strdup(label);
196 item->isTrigger = true;
197 item->value = menu-1;
198 return;
199 }
200 i--;
201 item = item->next;
202 }
203 __glutWarning("Current menu has no %d item.", num);
204 }
205
206 /***********************************************************
207 * FUNCTION: glutRemoveMenuItem (6.8)
208 *
209 * DESCRIPTION: remove a menu item
210 ***********************************************************/
211 void
212 glutRemoveMenuItem(int num)
213 {
214 GlutMenuItem *item, **prev;
215 int i;
216
217 i = gState.currentMenu->num;
218 prev = &gState.currentMenu->list;
219 item = gState.currentMenu->list;
220
221 while (item) {
222 if (i == num) {
223 gState.currentMenu->num--;
224
225 /* Patch up menu's item list. */
226 *prev = item->next;
227
228 free(item->label);
229 delete item;
230 return;
231 }
232 i--;
233 prev = &item->next;
234 item = item->next;
235 }
236 __glutWarning("Current menu has no %d item.", num);
237 }
238
239 /***********************************************************
240 * FUNCTION: glutAttachMenu (6.9)
241 * glutDetachMenu
242 *
243 * DESCRIPTION: attach and detach menu from view
244 ***********************************************************/
245 void
246 glutAttachMenu(int button)
247 {
248 gState.currentWindow->menu[button] = gState.currentMenu->id + 1;
249 }
250
251 void
252 glutDetachMenu(int button)
253 {
254 gState.currentWindow->menu[button] = 0;
255 }
256
257 /***********************************************************
258 * CLASS: GlutMenu
259 *
260 * FUNCTION: CreateBMenu
261 *
262 * DESCRIPTION: construct a BPopupMenu for this menu
263 ***********************************************************/
264 BMenu *GlutMenu::CreateBMenu(bool toplevel) {
265 BMenu *bpopup;
266 if(toplevel) {
267 bpopup = new GlutPopUp(id+1);
268 } else {
269 bpopup = new BMenu("");
270 }
271 GlutMenuItem *item = list;
272 while (item) {
273 GlutBMenuItem *bitem;
274 if(item->isTrigger) {
275 // recursively call CreateBMenu
276 bitem = new GlutBMenuItem(menuList[item->value]->CreateBMenu(false));
277 bitem->SetLabel(item->label);
278 bitem->menu = 0; // real menu items start at 1
279 bitem->value = 0;
280 } else {
281 bitem = new GlutBMenuItem(item->label);
282 bitem->menu = id + 1;
283 bitem->value = item->value;
284 }
285 bpopup->AddItem(bitem, 0);
286 item = item->next;
287 }
288 return bpopup;
289 }
290
291 /***********************************************************
292 * CLASS: GlutMenu
293 *
294 * FUNCTION: (destructor)
295 *
296 * DESCRIPTION: destroy the menu and its items (but not submenus!)
297 ***********************************************************/
298 GlutMenu::~GlutMenu() {
299 while (list) {
300 GlutMenuItem *next = list->next;
301 delete list;
302 list = next;
303 }
304 }
305
306 /***********************************************************
307 * CLASS: GlutMenuItem
308 *
309 * FUNCTION: (constructor)
310 *
311 * DESCRIPTION: construct the new menu item and add to parent
312 ***********************************************************/
313 GlutMenuItem::GlutMenuItem(GlutMenu *n_menu, bool n_trig, int n_value, const char *n_label)
314 {
315 menu = n_menu;
316 isTrigger = n_trig;
317 value = n_value;
318 label = strdup(n_label);
319 next = menu->list;
320 menu->list = this;
321 menu->num++;
322 }