fixed some signed/unsigned comparison warnings with -Wsign-compare
[reactos.git] / reactos / subsys / system / usetup / genlist.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/genlist.c
23 * PURPOSE: Generic list functions
24 * PROGRAMMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include "usetup.h"
30
31 #define NDEBUG
32 #include <debug.h>
33
34 /* FUNCTIONS ****************************************************************/
35
36 PGENERIC_LIST
37 CreateGenericList(VOID)
38 {
39 PGENERIC_LIST List;
40
41 List = (PGENERIC_LIST)RtlAllocateHeap(ProcessHeap,
42 0,
43 sizeof(GENERIC_LIST));
44 if (List == NULL)
45 return NULL;
46
47 InitializeListHead(&List->ListHead);
48
49 List->Left = 0;
50 List->Top = 0;
51 List->Right = 0;
52 List->Bottom = 0;
53
54 List->CurrentEntry = NULL;
55
56 return List;
57 }
58
59
60 VOID
61 DestroyGenericList(PGENERIC_LIST List,
62 BOOLEAN FreeUserData)
63 {
64 PGENERIC_LIST_ENTRY ListEntry;
65 PLIST_ENTRY Entry;
66
67 /* Release list entries */
68 while (!IsListEmpty (&List->ListHead))
69 {
70 Entry = RemoveHeadList (&List->ListHead);
71 ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
72
73 /* Release user data */
74 if (FreeUserData && ListEntry->UserData != NULL)
75 RtlFreeHeap (ProcessHeap, 0, &ListEntry->UserData);
76
77 /* Release list entry */
78 RtlFreeHeap (ProcessHeap, 0, ListEntry);
79 }
80
81 /* Release list head */
82 RtlFreeHeap (ProcessHeap, 0, List);
83 }
84
85
86 BOOLEAN
87 AppendGenericListEntry(PGENERIC_LIST List,
88 PCHAR Text,
89 PVOID UserData,
90 BOOLEAN Current)
91 {
92 PGENERIC_LIST_ENTRY Entry;
93
94 Entry = (PGENERIC_LIST_ENTRY)RtlAllocateHeap(ProcessHeap,
95 0,
96 sizeof(GENERIC_LIST_ENTRY) + strlen(Text));
97 if (Entry == NULL)
98 return FALSE;
99
100 strcpy (Entry->Text, Text);
101 Entry->UserData = UserData;
102
103 InsertTailList(&List->ListHead,
104 &Entry->Entry);
105
106 if (Current || List->CurrentEntry == NULL)
107 {
108 List->CurrentEntry = Entry;
109 }
110
111 return TRUE;
112 }
113
114
115 static VOID
116 DrawListFrame(PGENERIC_LIST GenericList)
117 {
118 COORD coPos;
119 ULONG Written;
120 SHORT i;
121
122 /* Draw upper left corner */
123 coPos.X = GenericList->Left;
124 coPos.Y = GenericList->Top;
125 FillConsoleOutputCharacter (0xDA, // '+',
126 1,
127 coPos,
128 &Written);
129
130 /* Draw upper edge */
131 coPos.X = GenericList->Left + 1;
132 coPos.Y = GenericList->Top;
133 FillConsoleOutputCharacter (0xC4, // '-',
134 GenericList->Right - GenericList->Left - 1,
135 coPos,
136 &Written);
137
138 /* Draw upper right corner */
139 coPos.X = GenericList->Right;
140 coPos.Y = GenericList->Top;
141 FillConsoleOutputCharacter (0xBF, // '+',
142 1,
143 coPos,
144 &Written);
145
146 /* Draw left and right edge */
147 for (i = GenericList->Top + 1; i < GenericList->Bottom; i++)
148 {
149 coPos.X = GenericList->Left;
150 coPos.Y = i;
151 FillConsoleOutputCharacter (0xB3, // '|',
152 1,
153 coPos,
154 &Written);
155
156 coPos.X = GenericList->Right;
157 FillConsoleOutputCharacter (0xB3, //'|',
158 1,
159 coPos,
160 &Written);
161 }
162
163 /* Draw lower left corner */
164 coPos.X = GenericList->Left;
165 coPos.Y = GenericList->Bottom;
166 FillConsoleOutputCharacter (0xC0, // '+',
167 1,
168 coPos,
169 &Written);
170
171 /* Draw lower edge */
172 coPos.X = GenericList->Left + 1;
173 coPos.Y = GenericList->Bottom;
174 FillConsoleOutputCharacter (0xC4, // '-',
175 GenericList->Right - GenericList->Left - 1,
176 coPos,
177 &Written);
178
179 /* Draw lower right corner */
180 coPos.X = GenericList->Right;
181 coPos.Y = GenericList->Bottom;
182 FillConsoleOutputCharacter (0xD9, // '+',
183 1,
184 coPos,
185 &Written);
186 }
187
188
189 static VOID
190 DrawListEntries(PGENERIC_LIST GenericList)
191 {
192 PGENERIC_LIST_ENTRY ListEntry;
193 PLIST_ENTRY Entry;
194 COORD coPos;
195 ULONG Written;
196 USHORT Width;
197
198 coPos.X = GenericList->Left + 1;
199 coPos.Y = GenericList->Top + 1;
200 Width = GenericList->Right - GenericList->Left - 1;
201
202 Entry = GenericList->ListHead.Flink;
203 while (Entry != &GenericList->ListHead)
204 {
205 ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
206
207 if (coPos.Y == GenericList->Bottom)
208 break;
209
210 FillConsoleOutputAttribute ((GenericList->CurrentEntry == ListEntry) ? 0x71 : 0x17,
211 Width,
212 coPos,
213 &Written);
214
215 FillConsoleOutputCharacter (' ',
216 Width,
217 coPos,
218 &Written);
219
220 coPos.X++;
221 WriteConsoleOutputCharacters (ListEntry->Text,
222 min (strlen(ListEntry->Text), (SIZE_T)Width - 2),
223 coPos);
224 coPos.X--;
225
226 coPos.Y++;
227 Entry = Entry->Flink;
228 }
229
230 while (coPos.Y < GenericList->Bottom)
231 {
232 FillConsoleOutputAttribute (0x17,
233 Width,
234 coPos,
235 &Written);
236
237 FillConsoleOutputCharacter (' ',
238 Width,
239 coPos,
240 &Written);
241 coPos.Y++;
242 }
243 }
244
245
246 VOID
247 DrawGenericList(PGENERIC_LIST List,
248 SHORT Left,
249 SHORT Top,
250 SHORT Right,
251 SHORT Bottom)
252 {
253 List->Left = Left;
254 List->Top = Top;
255 List->Right = Right;
256 List->Bottom = Bottom;
257
258 DrawListFrame(List);
259
260 if (IsListEmpty(&List->ListHead))
261 return;
262
263 DrawListEntries(List);
264 }
265
266
267 VOID
268 ScrollDownGenericList (PGENERIC_LIST List)
269 {
270 PLIST_ENTRY Entry;
271
272 if (List->CurrentEntry == NULL)
273 return;
274
275 if (List->CurrentEntry->Entry.Flink != &List->ListHead)
276 {
277 Entry = List->CurrentEntry->Entry.Flink;
278 List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
279 DrawListEntries(List);
280 }
281 }
282
283
284 VOID
285 ScrollUpGenericList (PGENERIC_LIST List)
286 {
287 PLIST_ENTRY Entry;
288
289 if (List->CurrentEntry == NULL)
290 return;
291
292 if (List->CurrentEntry->Entry.Blink != &List->ListHead)
293 {
294 Entry = List->CurrentEntry->Entry.Blink;
295 List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
296 DrawListEntries(List);
297 }
298 }
299
300
301 PGENERIC_LIST_ENTRY
302 GetGenericListEntry(PGENERIC_LIST List)
303 {
304 return List->CurrentEntry;
305 }
306
307
308 VOID
309 SaveGenericListState(PGENERIC_LIST List)
310 {
311 List->BackupEntry = List->CurrentEntry;
312 }
313
314
315 VOID
316 RestoreGenericListState(PGENERIC_LIST List)
317 {
318 List->CurrentEntry = List->BackupEntry;
319 }
320
321 /* EOF */