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 /*LINTLIBRARY*/ 32 33 #include <sys/types.h> 34 #include "private.h" 35 36 void 37 _post_item(MENU *m, ITEM *k) 38 { 39 int foreon = FALSE; 40 int backon = FALSE; 41 int greyon = FALSE; 42 chtype c; 43 int i; 44 45 /* Display the mark region of the item */ 46 47 if (!Selectable(k)) { 48 (void) wattron(Win(m), Grey(m)); 49 greyon = TRUE; 50 for (i = Marklen(m); i > 0; i--) { 51 (void) waddch(Win(m), ' '); 52 } 53 } else { 54 if (Value(k) || k == Current(m)) { 55 (void) wattron(Win(m), Fore(m)); 56 foreon = TRUE; 57 } else { 58 (void) wattron(Win(m), Back(m)); 59 backon = TRUE; 60 } 61 62 /* Display the mark */ 63 if (Value(k) || (OneValue(m) && k == Current(m))) { 64 if (Marklen(m)) { 65 (void) waddstr(Win(m), Mark(m)); 66 } 67 } else { 68 for (i = Marklen(m); i > 0; i--) { 69 (void) waddch(Win(m), ' '); 70 } 71 } 72 } 73 74 /* Display the name */ 75 76 (void) waddnstr(Win(m), Name(k), MaxName(m)); 77 if (ShowDesc(m) && MaxDesc(m) != 0) { 78 c = Pad(m); 79 } else { 80 c = ' '; 81 } 82 for (i = MaxName(m) - NameLen(k); i > 0; i--) { 83 (void) waddch(Win(m), c); 84 } 85 86 /* Display the description */ 87 88 if (ShowDesc(m) && MaxDesc(m) != 0) { 89 (void) waddch(Win(m), Pad(m)); 90 if (DescriptionLen(k) != 0) { 91 (void) waddstr(Win(m), Description(k)); 92 } 93 for (i = MaxDesc(m) - DescriptionLen(k); i > 0; i--) { 94 (void) waddch(Win(m), ' '); 95 } 96 } 97 if (foreon) { 98 (void) wattroff(Win(m), Fore(m)); 99 } 100 if (backon) { 101 (void) wattroff(Win(m), Back(m)); 102 } 103 if (greyon) { 104 (void) wattroff(Win(m), Grey(m)); 105 } 106 } 107 108 void 109 _move_post_item(MENU *m, ITEM *k) 110 { 111 (void) wmove(Win(m), Y(k), X(k) * (Itemlen(m)+1)); 112 _post_item(m, k); 113 } 114 115 int 116 unpost_menu(MENU *m) 117 { 118 if (!m) { 119 return (E_BAD_ARGUMENT); 120 } 121 if (Indriver(m)) { 122 return (E_BAD_STATE); 123 } 124 if (!Posted(m)) { 125 return (E_NOT_POSTED); 126 } 127 Iterm(m); 128 Mterm(m); 129 (void) werase(US(m)); 130 wsyncup(US(m)); 131 (void) delwin(Sub(m)); 132 Sub(m) = (WINDOW *) NULL; 133 (void) delwin(Win(m)); 134 Win(m) = (WINDOW *) NULL; 135 ResetPost(m); 136 return (E_OK); 137 } 138 139 /* 140 * This routine draws the item indicated by oldcur first and then 141 * draws the item indicated by Current. This will have the affect 142 * of unselecting the first item and selecting the next. 143 */ 144 void 145 _movecurrent(MENU *m, ITEM *oldcur) 146 { 147 if (oldcur != Current(m)) { 148 _move_post_item(m, oldcur); 149 _move_post_item(m, Current(m)); 150 } 151 } 152 153 /* 154 * Draw the entire menu into the super window 155 * This routine assumes all items have been linked and 156 * that the menu is in at least a pre-post state. 157 */ 158 159 void 160 _draw(MENU *m) 161 { 162 int k; 163 ITEM *i, *j; 164 ITEM *si, *sj; 165 166 k = 0; /* Line number */ 167 i = IthItem(m, 0); 168 si = Cyclic(m) ? i : (ITEM *) NULL; 169 do { 170 (void) wmove(Win(m), k++, 0); 171 j = i; 172 sj = Cyclic(m) ? j : (ITEM *) NULL; 173 do { 174 _post_item(m, j); 175 if ((j = Right(j)) != sj) { 176 (void) waddch(Win(m), ' '); 177 } 178 } while (j != sj); 179 } while ((i = Down(i)) != si); 180 } 181 182 int 183 post_menu(MENU *m) 184 { 185 ITEM **ip; 186 int r, c; /* visible # of rows and cols */ 187 188 if (!m) { 189 return (E_BAD_ARGUMENT); 190 } 191 if (Indriver(m)) { 192 return (E_BAD_STATE); 193 } 194 if (Posted(m)) { 195 return (E_POSTED); 196 } 197 /* Make sure there is at least one item present */ 198 if (Items(m) && IthItem(m, 0)) { 199 getmaxyx(US(m), r, c); 200 201 /* Make sure the menu fits into the window horizontally */ 202 if (c < Width(m) || r < Height(m)) { 203 return (E_NO_ROOM); 204 } 205 206 /* Create the menu window and derived windows */ 207 if ((Win(m) = newwin(Rows(m), Width(m), 0, 0)) == 208 (WINDOW *) NULL) { 209 return (E_SYSTEM_ERROR); 210 } 211 212 /* 213 * Take the minimum of the height of the menu (Height), the 214 * physical height of the window (r), and the number of rows 215 * in the menu (Rows). 216 */ 217 r = min(min(r, Rows(m)), Height(m)); 218 219 if ((Sub(m) = derwin(Win(m), r, Width(m), 0, 0)) == 220 (WINDOW *) NULL) { 221 return (E_SYSTEM_ERROR); 222 } 223 224 /* If needed, link all items in the menu */ 225 if (LinkNeeded(m)) { 226 _link_items(m); 227 } 228 229 SetPost(m); 230 231 /* If only one value can be set then unset all values */ 232 /* to start. */ 233 if (OneValue(m)) { 234 for (ip = Items(m); *ip; ip++) { 235 Value(*ip) = FALSE; 236 } 237 } 238 239 /* Go do the drawing of the menu */ 240 _draw(m); 241 242 Minit(m); 243 Iinit(m); 244 _show(m); /* Display the menu */ 245 return (E_OK); 246 } 247 return (E_NOT_CONNECTED); 248 } 249