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.6 */ 32 33 /*LINTLIBRARY*/ 34 35 #include <sys/types.h> 36 #include "private.h" 37 38 static void 39 link_col_major(MENU *m) 40 { 41 ITEM *i; 42 int n; 43 short c, r; 44 int left, up; 45 46 r = 0; 47 c = 0; 48 for (i = IthItem(m, 0), n = 0; i; i = IthItem(m, ++n)) { 49 X(i) = c; 50 Y(i) = r; 51 Left(i) = c ? IthItem(m, n-Rows(m)) : (ITEM *) NULL; 52 if (n + Rows(m) >= Nitems(m)) { 53 Right(i) = (ITEM *) NULL; 54 } else { 55 Right(i) = IthItem(m, n + Rows(m)); 56 } 57 Up(i) = r ? IthItem(m, n-1) : (ITEM *) NULL; 58 Down(i) = (r == Rows(m)-1) ? (ITEM *)0 : IthItem(m, n+1); 59 if (++r == Rows(m)) { 60 r = 0; 61 c += 1; 62 } 63 } 64 if (r) { 65 Down(IthItem(m, n-1)) = IthItem(m, n - Rows(m)); 66 } 67 68 if (Cyclic(m)) { 69 /* Set up left and right links at edge of menu */ 70 71 r = Rows(m) * (Nitems(m)/Rows(m)); 72 for (n = 0; n < Rows(m); n++) { 73 left = n + r; 74 if (left >= Nitems(m)) { 75 left -= Rows(m); 76 } 77 Left(IthItem(m, n)) = IthItem(m, left); 78 Right(IthItem(m, left)) = IthItem(m, n); 79 } 80 81 /* Setup up and down links at edge of menu */ 82 83 for (n = 0; n < Nitems(m); n += Rows(m)) { 84 up = n + Rows(m) - 1; 85 if (up >= Nitems(m)) { 86 Up(IthItem(m, n)) = IthItem(m, n-1); 87 } else { 88 Up(IthItem(m, n)) = IthItem(m, up); 89 Down(IthItem(m, up)) = IthItem(m, n); 90 } 91 } 92 } 93 } 94 95 static void 96 link_row_major(MENU *m) 97 { 98 int n; 99 short c, r; 100 ITEM *i; 101 int left, up; 102 103 r = 0; 104 c = 0; 105 for (i = IthItem(m, 0), n = 0; i; i = IthItem(m, ++n)) { 106 X(i) = c; 107 Y(i) = r; 108 Left(i) = c ? IthItem(m, n-1) : (ITEM *) NULL; 109 Right(i) = (c == Cols(m)-1 || n == Nitems(m)-1) ? (ITEM *)0 : 110 IthItem(m, n+1); 111 Up(i) = r ? IthItem(m, n-Cols(m)) : (ITEM *) NULL; 112 113 if (n+Cols(m) < Nitems(m)) { 114 Down(i) = IthItem(m, n + Cols(m)); 115 } else { 116 if (r == Rows(m)-1) { 117 /* Down is undefined if this is a complete */ 118 /* last column */ 119 Down(i) = (ITEM *) NULL; 120 } else { 121 /* Down is set to last item if the last */ 122 /* column isn't full */ 123 Down(i) = IthItem(m, Nitems(m)-1); 124 } 125 } 126 if (++c == Cols(m)) { 127 c = 0; 128 r += 1; 129 } 130 } 131 132 if (Cyclic(m)) { 133 134 /* Setup left and right links at edge of menu */ 135 136 for (n = 0; n < Nitems(m); n += Cols(m)) { 137 left = n + Cols(m) - 1; 138 if (left >= Nitems(m)) { 139 left = Nitems(m) - 1; 140 } 141 Left(IthItem(m, n)) = IthItem(m, left); 142 Right(IthItem(m, left)) = IthItem(m, n); 143 } 144 145 /* Setup up and down links at edge of menu */ 146 147 r = (Rows(m) - 1) * Cols(m); 148 for (n = 0; n < Cols(m); n++) { 149 up = n + r; 150 151 /* If there is an incomplete line below this one */ 152 /* the point to the last item in the menu. */ 153 154 if (up >= Nitems(m)) { 155 Up(IthItem(m, n)) = IthItem(m, Nitems(m)-1); 156 } else { 157 Up(IthItem(m, n)) = IthItem(m, up); 158 Down(IthItem(m, up)) = IthItem(m, n); 159 } 160 } 161 } 162 } 163 164 void 165 _link_items(MENU *m) 166 { 167 if (Items(m) && IthItem(m, 0)) { 168 ResetLink(m); 169 if (RowMajor(m)) { 170 link_row_major(m); 171 } else { 172 link_col_major(m); 173 } 174 } 175 } 176