1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright (c) 1997, by Sun Mircrosystems, Inc.
28 * All rights reserved.
29 */
30
31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.12 */
32
33 /*LINTLIBRARY*/
34
35 #include <sys/types.h>
36 #include "private.h"
37
38 void
_post_item(MENU * m,ITEM * k)39 _post_item(MENU *m, ITEM *k)
40 {
41 int foreon = FALSE;
42 int backon = FALSE;
43 int greyon = FALSE;
44 chtype c;
45 int i;
46
47 /* Display the mark region of the item */
48
49 if (!Selectable(k)) {
50 (void) wattron(Win(m), Grey(m));
51 greyon = TRUE;
52 for (i = Marklen(m); i > 0; i--) {
53 (void) waddch(Win(m), ' ');
54 }
55 } else {
56 if (Value(k) || k == Current(m)) {
57 (void) wattron(Win(m), Fore(m));
58 foreon = TRUE;
59 } else {
60 (void) wattron(Win(m), Back(m));
61 backon = TRUE;
62 }
63
64 /* Display the mark */
65 if (Value(k) || (OneValue(m) && k == Current(m))) {
66 if (Marklen(m)) {
67 (void) waddstr(Win(m), Mark(m));
68 }
69 } else {
70 for (i = Marklen(m); i > 0; i--) {
71 (void) waddch(Win(m), ' ');
72 }
73 }
74 }
75
76 /* Display the name */
77
78 (void) waddnstr(Win(m), Name(k), MaxName(m));
79 if (ShowDesc(m) && MaxDesc(m) != 0) {
80 c = Pad(m);
81 } else {
82 c = ' ';
83 }
84 for (i = MaxName(m) - NameLen(k); i > 0; i--) {
85 (void) waddch(Win(m), c);
86 }
87
88 /* Display the description */
89
90 if (ShowDesc(m) && MaxDesc(m) != 0) {
91 (void) waddch(Win(m), Pad(m));
92 if (DescriptionLen(k) != 0) {
93 (void) waddstr(Win(m), Description(k));
94 }
95 for (i = MaxDesc(m) - DescriptionLen(k); i > 0; i--) {
96 (void) waddch(Win(m), ' ');
97 }
98 }
99 if (foreon) {
100 (void) wattroff(Win(m), Fore(m));
101 }
102 if (backon) {
103 (void) wattroff(Win(m), Back(m));
104 }
105 if (greyon) {
106 (void) wattroff(Win(m), Grey(m));
107 }
108 }
109
110 void
_move_post_item(MENU * m,ITEM * k)111 _move_post_item(MENU *m, ITEM *k)
112 {
113 (void) wmove(Win(m), Y(k), X(k) * (Itemlen(m)+1));
114 _post_item(m, k);
115 }
116
117 int
unpost_menu(MENU * m)118 unpost_menu(MENU *m)
119 {
120 if (!m) {
121 return (E_BAD_ARGUMENT);
122 }
123 if (Indriver(m)) {
124 return (E_BAD_STATE);
125 }
126 if (!Posted(m)) {
127 return (E_NOT_POSTED);
128 }
129 Iterm(m);
130 Mterm(m);
131 (void) werase(US(m));
132 wsyncup(US(m));
133 (void) delwin(Sub(m));
134 Sub(m) = (WINDOW *) NULL;
135 (void) delwin(Win(m));
136 Win(m) = (WINDOW *) NULL;
137 ResetPost(m);
138 return (E_OK);
139 }
140
141 /*
142 * This routine draws the item indicated by oldcur first and then
143 * draws the item indicated by Current. This will have the affect
144 * of unselecting the first item and selecting the next.
145 */
146 void
_movecurrent(MENU * m,ITEM * oldcur)147 _movecurrent(MENU *m, ITEM *oldcur)
148 {
149 if (oldcur != Current(m)) {
150 _move_post_item(m, oldcur);
151 _move_post_item(m, Current(m));
152 }
153 }
154
155 /*
156 * Draw the entire menu into the super window
157 * This routine assumes all items have been linked and
158 * that the menu is in at least a pre-post state.
159 */
160
161 void
_draw(MENU * m)162 _draw(MENU *m)
163 {
164 int k;
165 ITEM *i, *j;
166 ITEM *si, *sj;
167
168 k = 0; /* Line number */
169 i = IthItem(m, 0);
170 si = Cyclic(m) ? i : (ITEM *) NULL;
171 do {
172 (void) wmove(Win(m), k++, 0);
173 j = i;
174 sj = Cyclic(m) ? j : (ITEM *) NULL;
175 do {
176 _post_item(m, j);
177 if ((j = Right(j)) != sj) {
178 (void) waddch(Win(m), ' ');
179 }
180 } while (j != sj);
181 } while ((i = Down(i)) != si);
182 }
183
184 int
post_menu(MENU * m)185 post_menu(MENU *m)
186 {
187 ITEM **ip;
188 int r, c; /* visible # of rows and cols */
189
190 if (!m) {
191 return (E_BAD_ARGUMENT);
192 }
193 if (Indriver(m)) {
194 return (E_BAD_STATE);
195 }
196 if (Posted(m)) {
197 return (E_POSTED);
198 }
199 /* Make sure there is at least one item present */
200 if (Items(m) && IthItem(m, 0)) {
201 getmaxyx(US(m), r, c);
202
203 /* Make sure the menu fits into the window horizontally */
204 if (c < Width(m) || r < Height(m)) {
205 return (E_NO_ROOM);
206 }
207
208 /* Create the menu window and derived windows */
209 if ((Win(m) = newwin(Rows(m), Width(m), 0, 0)) ==
210 (WINDOW *) NULL) {
211 return (E_SYSTEM_ERROR);
212 }
213
214 /*
215 * Take the minimum of the height of the menu (Height), the
216 * physical height of the window (r), and the number of rows
217 * in the menu (Rows).
218 */
219 r = min(min(r, Rows(m)), Height(m));
220
221 if ((Sub(m) = derwin(Win(m), r, Width(m), 0, 0)) ==
222 (WINDOW *) NULL) {
223 return (E_SYSTEM_ERROR);
224 }
225
226 /* If needed, link all items in the menu */
227 if (LinkNeeded(m)) {
228 _link_items(m);
229 }
230
231 SetPost(m);
232
233 /* If only one value can be set then unset all values */
234 /* to start. */
235 if (OneValue(m)) {
236 for (ip = Items(m); *ip; ip++) {
237 Value(*ip) = FALSE;
238 }
239 }
240
241 /* Go do the drawing of the menu */
242 _draw(m);
243
244 Minit(m);
245 Iinit(m);
246 _show(m); /* Display the menu */
247 return (E_OK);
248 }
249 return (E_NOT_CONNECTED);
250 }
251