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 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 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 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 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 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 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