ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

genlist.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS kernel
00003  *  Copyright (C) 2004 ReactOS Team
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License along
00016  *  with this program; if not, write to the Free Software Foundation, Inc.,
00017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 /* COPYRIGHT:       See COPYING in the top level directory
00020  * PROJECT:         ReactOS text-mode setup
00021  * FILE:            subsys/system/usetup/genlist.c
00022  * PURPOSE:         Generic list functions
00023  * PROGRAMMER:      Eric Kohl
00024  *                  Christoph von Wittich <christoph at reactos.org>
00025  */
00026 
00027 /* INCLUDES *****************************************************************/
00028 
00029 #include "usetup.h"
00030 
00031 #define NDEBUG
00032 #include <debug.h>
00033 
00034 /* FUNCTIONS ****************************************************************/
00035 
00036 typedef struct _GENERIC_LIST_ENTRY
00037 {
00038     LIST_ENTRY Entry;
00039     PGENERIC_LIST List;
00040     PVOID UserData;
00041     CHAR Text[1];
00042 } GENERIC_LIST_ENTRY;
00043 
00044 
00045 typedef struct _GENERIC_LIST
00046 {
00047     LIST_ENTRY ListHead;
00048 
00049     PLIST_ENTRY FirstShown;
00050     PLIST_ENTRY LastShown;
00051     SHORT Left;
00052     SHORT Top;
00053     SHORT Right;
00054     SHORT Bottom;
00055     BOOL Redraw;
00056 
00057     PGENERIC_LIST_ENTRY CurrentEntry;
00058     PGENERIC_LIST_ENTRY BackupEntry;
00059 } GENERIC_LIST;
00060 
00061 PGENERIC_LIST
00062 CreateGenericList(VOID)
00063 {
00064     PGENERIC_LIST List;
00065 
00066     List = (PGENERIC_LIST)RtlAllocateHeap(ProcessHeap,
00067                                           0,
00068                                           sizeof(GENERIC_LIST));
00069     if (List == NULL)
00070         return NULL;
00071 
00072     InitializeListHead(&List->ListHead);
00073 
00074     List->Left = 0;
00075     List->Top = 0;
00076     List->Right = 0;
00077     List->Bottom = 0;
00078     List->Redraw = TRUE;
00079 
00080     List->CurrentEntry = NULL;
00081 
00082     return List;
00083 }
00084 
00085 
00086 VOID
00087 DestroyGenericList(PGENERIC_LIST List,
00088                    BOOLEAN FreeUserData)
00089 {
00090     PGENERIC_LIST_ENTRY ListEntry;
00091     PLIST_ENTRY Entry;
00092 
00093     /* Release list entries */
00094     while (!IsListEmpty (&List->ListHead))
00095     {
00096         Entry = RemoveHeadList (&List->ListHead);
00097         ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
00098 
00099         /* Release user data */
00100         if (FreeUserData && ListEntry->UserData != NULL)
00101             RtlFreeHeap (ProcessHeap, 0, ListEntry->UserData);
00102 
00103         /* Release list entry */
00104         RtlFreeHeap (ProcessHeap, 0, ListEntry);
00105     }
00106 
00107     /* Release list head */
00108     RtlFreeHeap (ProcessHeap, 0, List);
00109 }
00110 
00111 
00112 BOOLEAN
00113 AppendGenericListEntry(PGENERIC_LIST List,
00114                      PCHAR Text,
00115                      PVOID UserData,
00116                      BOOLEAN Current)
00117 {
00118     PGENERIC_LIST_ENTRY Entry;
00119 
00120     Entry = (PGENERIC_LIST_ENTRY)RtlAllocateHeap(ProcessHeap,
00121                                                  0,
00122                                                  sizeof(GENERIC_LIST_ENTRY) + strlen(Text));
00123     if (Entry == NULL)
00124         return FALSE;
00125 
00126     strcpy (Entry->Text, Text);
00127     Entry->List = List;
00128     Entry->UserData = UserData;
00129 
00130     InsertTailList(&List->ListHead,
00131                    &Entry->Entry);
00132 
00133     if (Current || List->CurrentEntry == NULL)
00134     {
00135         List->CurrentEntry = Entry;
00136     }
00137 
00138     return TRUE;
00139 }
00140 
00141 
00142 static VOID
00143 DrawListFrame(PGENERIC_LIST GenericList)
00144 {
00145     COORD coPos;
00146     DWORD Written;
00147     SHORT i;
00148 
00149     /* Draw upper left corner */
00150     coPos.X = GenericList->Left;
00151     coPos.Y = GenericList->Top;
00152     FillConsoleOutputCharacterA (StdOutput,
00153                                  0xDA, // '+',
00154                                  1,
00155                                  coPos,
00156                                  &Written);
00157 
00158     /* Draw upper edge */
00159     coPos.X = GenericList->Left + 1;
00160     coPos.Y = GenericList->Top;
00161     FillConsoleOutputCharacterA (StdOutput,
00162                                  0xC4, // '-',
00163                                  GenericList->Right - GenericList->Left - 1,
00164                                  coPos,
00165                                  &Written);
00166 
00167     /* Draw upper right corner */
00168     coPos.X = GenericList->Right;
00169     coPos.Y = GenericList->Top;
00170     FillConsoleOutputCharacterA (StdOutput,
00171                                  0xBF, // '+',
00172                                  1,
00173                                  coPos,
00174                                  &Written);
00175 
00176     /* Draw left and right edge */
00177     for (i = GenericList->Top + 1; i < GenericList->Bottom; i++)
00178     {
00179         coPos.X = GenericList->Left;
00180         coPos.Y = i;
00181         FillConsoleOutputCharacterA (StdOutput,
00182                                      0xB3, // '|',
00183                                      1,
00184                                      coPos,
00185                                      &Written);
00186 
00187         coPos.X = GenericList->Right;
00188         FillConsoleOutputCharacterA (StdOutput,
00189                                      0xB3, //'|',
00190                                      1,
00191                                      coPos,
00192                                      &Written);
00193     }
00194 
00195     /* Draw lower left corner */
00196     coPos.X = GenericList->Left;
00197     coPos.Y = GenericList->Bottom;
00198     FillConsoleOutputCharacterA (StdOutput,
00199                                  0xC0, // '+',
00200                                  1,
00201                                  coPos,
00202                                  &Written);
00203 
00204     /* Draw lower edge */
00205     coPos.X = GenericList->Left + 1;
00206     coPos.Y = GenericList->Bottom;
00207     FillConsoleOutputCharacterA (StdOutput,
00208                                  0xC4, // '-',
00209                                  GenericList->Right - GenericList->Left - 1,
00210                                  coPos,
00211                                  &Written);
00212 
00213     /* Draw lower right corner */
00214     coPos.X = GenericList->Right;
00215     coPos.Y = GenericList->Bottom;
00216     FillConsoleOutputCharacterA (StdOutput,
00217                                  0xD9, // '+',
00218                                  1,
00219                                  coPos,
00220                                  &Written);
00221 }
00222 
00223 
00224 static VOID
00225 DrawListEntries(PGENERIC_LIST GenericList)
00226 {
00227     PGENERIC_LIST_ENTRY ListEntry;
00228     PLIST_ENTRY Entry;
00229     COORD coPos;
00230     DWORD Written;
00231     USHORT Width;
00232 
00233     coPos.X = GenericList->Left + 1;
00234     coPos.Y = GenericList->Top + 1;
00235     Width = GenericList->Right - GenericList->Left - 1;
00236 
00237     Entry = GenericList->FirstShown;
00238     while (Entry != &GenericList->ListHead)
00239     {
00240         ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
00241 
00242         if (coPos.Y == GenericList->Bottom)
00243             break;
00244         GenericList->LastShown = Entry;
00245 
00246         FillConsoleOutputAttribute (StdOutput,
00247                                     (GenericList->CurrentEntry == ListEntry) ?
00248                                     FOREGROUND_BLUE | BACKGROUND_WHITE :
00249                                     FOREGROUND_WHITE | BACKGROUND_BLUE,
00250                                     Width,
00251                                     coPos,
00252                                     &Written);
00253 
00254         FillConsoleOutputCharacterA (StdOutput,
00255                                      ' ',
00256                                      Width,
00257                                      coPos,
00258                                      &Written);
00259 
00260         coPos.X++;
00261         WriteConsoleOutputCharacterA (StdOutput,
00262                                       ListEntry->Text,
00263                                       min (strlen(ListEntry->Text), (SIZE_T)Width - 2),
00264                                       coPos,
00265                                       &Written);
00266         coPos.X--;
00267 
00268         coPos.Y++;
00269         Entry = Entry->Flink;
00270     }
00271 
00272     while (coPos.Y < GenericList->Bottom)
00273     {
00274         FillConsoleOutputAttribute (StdOutput,
00275                                     FOREGROUND_WHITE | BACKGROUND_BLUE,
00276                                     Width,
00277                                     coPos,
00278                                     &Written);
00279 
00280         FillConsoleOutputCharacterA (StdOutput,
00281                                      ' ',
00282                                      Width,
00283                                      coPos,
00284                                      &Written);
00285         coPos.Y++;
00286     }
00287 }
00288 
00289 static VOID
00290 DrawScrollBarGenericList(PGENERIC_LIST GenericList)
00291 {
00292     COORD coPos;
00293     DWORD Written;
00294 
00295     coPos.X = GenericList->Right + 1;
00296     coPos.Y = GenericList->Top;
00297 
00298     if (GenericList->FirstShown != GenericList->ListHead.Flink)
00299     {
00300         FillConsoleOutputCharacterA (StdOutput,
00301                                      '\x18',
00302                                      1,
00303                                      coPos,
00304                                      &Written);
00305     }
00306     else
00307     {
00308         FillConsoleOutputCharacterA (StdOutput,
00309                                      ' ',
00310                                      1,
00311                                      coPos,
00312                                      &Written);
00313     }
00314 
00315     coPos.Y = GenericList->Bottom;
00316     if (GenericList->LastShown != GenericList->ListHead.Blink)
00317     {
00318         FillConsoleOutputCharacterA (StdOutput,
00319                                      '\x19',
00320                                      1,
00321                                      coPos,
00322                                      &Written);
00323     }
00324     else
00325     {
00326         FillConsoleOutputCharacterA (StdOutput,
00327                                      ' ',
00328                                      1,
00329                                      coPos,
00330                                      &Written);
00331     }
00332 }
00333 
00334 VOID
00335 DrawGenericList(PGENERIC_LIST List,
00336                 SHORT Left,
00337                 SHORT Top,
00338                 SHORT Right,
00339                 SHORT Bottom)
00340 {
00341     List->FirstShown = List->ListHead.Flink;
00342     List->Left = Left;
00343     List->Top = Top;
00344     List->Right = Right;
00345     List->Bottom = Bottom;
00346 
00347     DrawListFrame(List);
00348 
00349     if (IsListEmpty(&List->ListHead))
00350         return;
00351 
00352     DrawListEntries(List);
00353     DrawScrollBarGenericList(List);
00354 }
00355 
00356 VOID
00357 ScrollPageDownGenericList (PGENERIC_LIST List)
00358 {
00359     SHORT i;
00360 
00361     /* Suspend auto-redraw */
00362     List->Redraw = FALSE;
00363 
00364     for (i = List->Top + 1; i < List->Bottom - 1; i++)
00365     {
00366         ScrollDownGenericList (List);
00367     }
00368 
00369     /* Update user interface */
00370     DrawListEntries(List);
00371     DrawScrollBarGenericList(List);
00372 
00373     /* Re enable auto-redraw */
00374     List->Redraw = TRUE;
00375 }
00376 
00377 VOID
00378 ScrollPageUpGenericList (PGENERIC_LIST List)
00379 {
00380     SHORT i;
00381 
00382     /* Suspend auto-redraw */
00383     List->Redraw = FALSE;
00384 
00385     for (i = List->Bottom - 1; i > List->Top + 1; i--)
00386     {
00387          ScrollUpGenericList (List);
00388     }
00389 
00390     /* Update user interface */
00391     DrawListEntries(List);
00392     DrawScrollBarGenericList(List);
00393 
00394     /* Re enable auto-redraw */
00395     List->Redraw = TRUE;
00396 }
00397 
00398 VOID
00399 ScrollDownGenericList (PGENERIC_LIST List)
00400 {
00401     PLIST_ENTRY Entry;
00402 
00403     if (List->CurrentEntry == NULL)
00404         return;
00405 
00406     if (List->CurrentEntry->Entry.Flink != &List->ListHead)
00407     {
00408         Entry = List->CurrentEntry->Entry.Flink;
00409         if (List->LastShown == &List->CurrentEntry->Entry)
00410         {
00411             List->FirstShown = List->FirstShown->Flink;
00412             List->LastShown = List->LastShown->Flink;
00413         }
00414         List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
00415 
00416         if (List->Redraw)
00417         {
00418             DrawListEntries(List);
00419             DrawScrollBarGenericList(List);
00420         }
00421     }
00422 }
00423 
00424 
00425 VOID
00426 ScrollToPositionGenericList (PGENERIC_LIST List, ULONG uIndex)
00427 {
00428     PLIST_ENTRY Entry;
00429     ULONG uCount = 0;
00430 
00431     if (List->CurrentEntry == NULL || uIndex == 0)
00432         return;
00433 
00434     do
00435     {
00436         if (List->CurrentEntry->Entry.Flink != &List->ListHead)
00437         {
00438             Entry = List->CurrentEntry->Entry.Flink;
00439             if (List->LastShown == &List->CurrentEntry->Entry)
00440             {
00441                 List->FirstShown = List->FirstShown->Flink;
00442                 List->LastShown = List->LastShown->Flink;
00443             }
00444             List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
00445         }
00446         uCount++;
00447     }
00448     while (uIndex != uCount);
00449 
00450     if (List->Redraw)
00451     {
00452         DrawListEntries(List);
00453         DrawScrollBarGenericList(List);
00454     }
00455 }
00456 
00457 
00458 VOID
00459 ScrollUpGenericList (PGENERIC_LIST List)
00460 {
00461     PLIST_ENTRY Entry;
00462 
00463     if (List->CurrentEntry == NULL)
00464         return;
00465 
00466     if (List->CurrentEntry->Entry.Blink != &List->ListHead)
00467     {
00468         Entry = List->CurrentEntry->Entry.Blink;
00469         if (List->FirstShown == &List->CurrentEntry->Entry)
00470         {
00471             List->FirstShown = List->FirstShown->Blink;
00472             List->LastShown = List->LastShown->Blink;
00473         }
00474         List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry);
00475 
00476         if (List->Redraw)
00477         {
00478             DrawListEntries(List);
00479             DrawScrollBarGenericList(List);
00480         }
00481     }
00482 }
00483 
00484 
00485 VOID
00486 SetCurrentListEntry(PGENERIC_LIST List, PGENERIC_LIST_ENTRY Entry)
00487 {
00488     if (Entry->List != List)
00489         return;
00490     List->CurrentEntry = Entry;
00491 }
00492 
00493 
00494 PGENERIC_LIST_ENTRY
00495 GetCurrentListEntry(PGENERIC_LIST List)
00496 {
00497     return List->CurrentEntry;
00498 }
00499 
00500 
00501 PGENERIC_LIST_ENTRY
00502 GetFirstListEntry(PGENERIC_LIST List)
00503 {
00504     PLIST_ENTRY Entry = List->ListHead.Flink;
00505 
00506     if (Entry == &List->ListHead)
00507         return NULL;
00508     return CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
00509 }
00510 
00511 
00512 PGENERIC_LIST_ENTRY
00513 GetNextListEntry(PGENERIC_LIST_ENTRY Entry)
00514 {
00515     PLIST_ENTRY Next = Entry->Entry.Flink;
00516 
00517     if (Next == &Entry->List->ListHead)
00518         return NULL;
00519     return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry);
00520 }
00521 
00522 
00523 PVOID
00524 GetListEntryUserData(PGENERIC_LIST_ENTRY List)
00525 {
00526     return List->UserData;
00527 }
00528 
00529 
00530 LPCSTR
00531 GetListEntryText(PGENERIC_LIST_ENTRY List)
00532 {
00533     return List->Text;
00534 }
00535 
00536 
00537 VOID
00538 GenericListKeyPress (PGENERIC_LIST GenericList, CHAR AsciChar)
00539 {
00540     PGENERIC_LIST_ENTRY ListEntry;
00541     PGENERIC_LIST_ENTRY OldListEntry;
00542     BOOLEAN Flag = FALSE;
00543 
00544     ListEntry = GenericList->CurrentEntry;
00545     OldListEntry = GenericList->CurrentEntry;
00546 
00547     GenericList->Redraw = FALSE;
00548 
00549     if ((strlen(ListEntry->Text) > 0) && (tolower(ListEntry->Text[0]) == AsciChar) &&
00550          (GenericList->CurrentEntry->Entry.Flink != &GenericList->ListHead))
00551     {
00552         ScrollDownGenericList(GenericList);
00553         ListEntry = GenericList->CurrentEntry;
00554 
00555         if ((strlen(ListEntry->Text) > 0) && (tolower(ListEntry->Text[0]) == AsciChar))
00556             goto End;
00557     }
00558 
00559     while (GenericList->CurrentEntry->Entry.Blink != &GenericList->ListHead)
00560         ScrollUpGenericList(GenericList);
00561 
00562     ListEntry = GenericList->CurrentEntry;
00563 
00564     for (;;)
00565     {
00566         if ((strlen(ListEntry->Text) > 0) && (tolower(ListEntry->Text[0]) == AsciChar))
00567         {
00568             Flag = TRUE;
00569             break;
00570         }
00571 
00572         if (GenericList->CurrentEntry->Entry.Flink == &GenericList->ListHead)
00573             break;
00574 
00575         ScrollDownGenericList(GenericList);
00576         ListEntry = GenericList->CurrentEntry;
00577     }
00578 
00579     if (!Flag)
00580     {
00581         while (GenericList->CurrentEntry->Entry.Blink != &GenericList->ListHead)
00582         {
00583             if (GenericList->CurrentEntry != OldListEntry)
00584                 ScrollUpGenericList(GenericList);
00585             else
00586                 break;
00587         }
00588     }
00589 End:
00590     DrawListEntries(GenericList);
00591     DrawScrollBarGenericList(GenericList);
00592 
00593     GenericList->Redraw = TRUE;
00594 }
00595 
00596 
00597 VOID
00598 SaveGenericListState(PGENERIC_LIST List)
00599 {
00600     List->BackupEntry = List->CurrentEntry;
00601 }
00602 
00603 
00604 VOID
00605 RestoreGenericListState(PGENERIC_LIST List)
00606 {
00607     List->CurrentEntry = List->BackupEntry;
00608 }
00609 
00610 /* EOF */

Generated on Mon May 28 2012 04:17:51 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.