softpipe: use the polygon stipple utility module
[mesa.git] / src / glut / glx / glut_menu2.c
1
2 /* Copyright (c) Mark J. Kilgard, 1994, 1997. */
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 /* glut_menu2.c implements the little used GLUT menu calls in
9 a distinct file from glut_menu.c for slim static linking. */
10
11 /* The Win32 GLUT file win32_menu.c completely re-implements all
12 the menuing functionality implemented. This file is used only by
13 the X Window System version of GLUT. */
14
15 #ifdef __VMS
16 #include <GL/vms_x_fix.h>
17 #endif
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <errno.h>
23 #include <assert.h>
24
25 #include <X11/Xlib.h>
26
27 #include "glutint.h"
28
29 /* CENTRY */
30 /* DEPRICATED, use glutMenuStatusFunc instead. */
31 void GLUTAPIENTRY
32 glutMenuStateFunc(GLUTmenuStateCB menuStateFunc)
33 {
34 __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;
35 }
36
37 void GLUTAPIENTRY
38 glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc)
39 {
40 __glutMenuStatusFunc = menuStatusFunc;
41 }
42
43 void GLUTAPIENTRY
44 glutDestroyMenu(int menunum)
45 {
46 GLUTmenu *menu = __glutGetMenuByNum(menunum);
47 GLUTmenuItem *item, *next;
48
49 if (__glutMappedMenu)
50 __glutMenuModificationError();
51 assert(menu->id == menunum - 1);
52 XDestroySubwindows(__glutDisplay, menu->win);
53 XDestroyWindow(__glutDisplay, menu->win);
54 __glutMenuList[menunum - 1] = NULL;
55 /* free all menu entries */
56 item = menu->list;
57 while (item) {
58 assert(item->menu == menu);
59 next = item->next;
60 free(item->label);
61 free(item);
62 item = next;
63 }
64 if (__glutCurrentMenu == menu) {
65 __glutCurrentMenu = NULL;
66 }
67 free(menu);
68 }
69
70 void GLUTAPIENTRY
71 glutChangeToMenuEntry(int num, const char *label, int value)
72 {
73 GLUTmenuItem *item;
74 int i;
75
76 if (__glutMappedMenu)
77 __glutMenuModificationError();
78 i = __glutCurrentMenu->num;
79 item = __glutCurrentMenu->list;
80 while (item) {
81 if (i == num) {
82 if (item->isTrigger) {
83 /* If changing a submenu trigger to a menu entry, we
84 need to account for submenus. */
85 item->menu->submenus--;
86 }
87 free(item->label);
88 __glutSetMenuItem(item, label, value, False);
89 return;
90 }
91 i--;
92 item = item->next;
93 }
94 __glutWarning("Current menu has no %d item.", num);
95 }
96
97 void GLUTAPIENTRY
98 glutChangeToSubMenu(int num, const char *label, int menu)
99 {
100 GLUTmenuItem *item;
101 int i;
102
103 if (__glutMappedMenu)
104 __glutMenuModificationError();
105 i = __glutCurrentMenu->num;
106 item = __glutCurrentMenu->list;
107 while (item) {
108 if (i == num) {
109 if (!item->isTrigger) {
110 /* If changing a menu entry to as submenu trigger, we
111 need to account for submenus. */
112 item->menu->submenus++;
113 }
114 free(item->label);
115 __glutSetMenuItem(item, label, /* base 0 */ menu - 1, True);
116 return;
117 }
118 i--;
119 item = item->next;
120 }
121 __glutWarning("Current menu has no %d item.", num);
122 }
123
124 void GLUTAPIENTRY
125 glutRemoveMenuItem(int num)
126 {
127 GLUTmenuItem *item, **prev, *remaining;
128 int pixwidth, i;
129
130 if (__glutMappedMenu)
131 __glutMenuModificationError();
132 i = __glutCurrentMenu->num;
133 prev = &__glutCurrentMenu->list;
134 item = __glutCurrentMenu->list;
135 /* If menu item is removed, the menu's pixwidth may need to
136 be recomputed. */
137 pixwidth = 1;
138 while (item) {
139 if (i == num) {
140 /* If this menu item's pixwidth is as wide as the menu's
141 pixwidth, removing this menu item will necessitate
142 shrinking the menu's pixwidth. */
143 if (item->pixwidth >= __glutCurrentMenu->pixwidth) {
144 /* Continue recalculating menu pixwidth, first skipping
145 the removed item. */
146 remaining = item->next;
147 while (remaining) {
148 if (remaining->pixwidth > pixwidth) {
149 pixwidth = remaining->pixwidth;
150 }
151 remaining = remaining->next;
152 }
153 __glutCurrentMenu->pixwidth = pixwidth;
154 }
155 __glutCurrentMenu->num--;
156 __glutCurrentMenu->managed = False;
157
158 /* Patch up menu's item list. */
159 *prev = item->next;
160
161 free(item->label);
162 free(item);
163 return;
164 }
165 if (item->pixwidth > pixwidth) {
166 pixwidth = item->pixwidth;
167 }
168 i--;
169 prev = &item->next;
170 item = item->next;
171 }
172 __glutWarning("Current menu has no %d item.", num);
173 }
174
175 void GLUTAPIENTRY
176 glutDetachMenu(int button)
177 {
178 if (__glutMappedMenu)
179 __glutMenuModificationError();
180 if (__glutCurrentWindow->menu[button] > 0) {
181 __glutCurrentWindow->buttonUses--;
182 __glutChangeWindowEventMask(ButtonPressMask | ButtonReleaseMask,
183 __glutCurrentWindow->buttonUses > 0);
184 __glutCurrentWindow->menu[button] = 0;
185 }
186 }
187
188 /* ENDCENTRY */