13860cbe1cafb88d70097bdfb8d84cc0029f1738esrs/*
23860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    Implementation of GPTData class derivative with curses-based text-mode
33860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    interaction
4e3ee733ff8690af7568dac665bc20ecf869dea1dRoderick W. Smith *    Copyright (C) 2011-2013 Roderick W. Smith
5d1b11e8305621d73ff675af940e7f1f28b639b0dsrs *
63860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    This program is free software; you can redistribute it and/or modify
73860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    it under the terms of the GNU General Public License as published by
83860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    the Free Software Foundation; either version 2 of the License, or
93860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    (at your option) any later version.
10d1b11e8305621d73ff675af940e7f1f28b639b0dsrs *
113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    This program is distributed in the hope that it will be useful,
123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    but WITHOUT ANY WARRANTY; without even the implied warranty of
133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    GNU General Public License for more details.
15d1b11e8305621d73ff675af940e7f1f28b639b0dsrs *
163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    You should have received a copy of the GNU General Public License along
173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    with this program; if not, write to the Free Software Foundation, Inc.,
183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19d1b11e8305621d73ff675af940e7f1f28b639b0dsrs *
203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs */
213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#include <iostream>
233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#include <string>
243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#include <sstream>
253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#include <ncurses.h>
263860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#include "gptcurses.h"
273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#include "support.h"
283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
293860cbe1cafb88d70097bdfb8d84cc0029f1738esrsusing namespace std;
303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// # of lines to reserve for general information and headers (RESERVED_TOP)
323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// and for options and messages (RESERVED_BOTTOM)
333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#define RESERVED_TOP 7
343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs#define RESERVED_BOTTOM 5
353860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
363860cbe1cafb88d70097bdfb8d84cc0029f1738esrsint GPTDataCurses::numInstances = 0;
373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
383860cbe1cafb88d70097bdfb8d84cc0029f1738esrsGPTDataCurses::GPTDataCurses(void) {
393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (numInstances > 0) {
403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      refresh();
413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } else {
4284aaff6b9cf3b802c621781cf9acd006aa5a3e66Roderick W. Smith      setlocale( LC_ALL , "" );
433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      initscr();
443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      cbreak();
453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      noecho();
463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      intrflush(stdscr, false);
473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      keypad(stdscr, true);
483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      nonl();
493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      numInstances++;
503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if/else
513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   firstSpace = NULL;
523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   lastSpace = NULL;
533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   currentSpace = NULL;
543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   currentSpaceNum = -1;
553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   whichOptions = ""; // current set of options
563860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   currentKey = 'b'; // currently selected option
571eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith   displayType = USE_CURSES;
583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses constructor
593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
603860cbe1cafb88d70097bdfb8d84cc0029f1738esrsGPTDataCurses::~GPTDataCurses(void) {
613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   numInstances--;
623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if ((numInstances == 0) && !isendwin())
633860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      endwin();
643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses destructor
653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs/************************************************
673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                              *
683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs * Functions relating to Spaces data structures *
693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                              *
703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs ************************************************/
713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
723860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::EmptySpaces(void) {
733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   Space *trash;
743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while (firstSpace != NULL) {
763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      trash = firstSpace;
773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      firstSpace = firstSpace->nextSpace;
783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      delete trash;
793860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
803860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   numSpaces = 0;
813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   lastSpace = NULL;
823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::EmptySpaces()
833860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Create Spaces from partitions. Does NOT creates Spaces to represent
853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// unpartitioned space on the disk.
863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Returns the number of Spaces created.
873860cbe1cafb88d70097bdfb8d84cc0029f1738esrsint GPTDataCurses::MakeSpacesFromParts(void) {
883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   uint i;
893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   Space *tempSpace;
903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   EmptySpaces();
923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   for (i = 0; i < numParts; i++) {
933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (partitions[i].IsUsed()) {
943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         tempSpace = new Space;
953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         tempSpace->firstLBA = partitions[i].GetFirstLBA();
963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         tempSpace->lastLBA = partitions[i].GetLastLBA();
973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         tempSpace->origPart = &partitions[i];
983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         tempSpace->partNum = (int) i;
993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         LinkToEnd(tempSpace);
1003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // if
1013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // for
1023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   return numSpaces;
1033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::MakeSpacesFromParts()
1043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Add a single empty Space to the current Spaces linked list and sort the result....
1063860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::AddEmptySpace(uint64_t firstLBA, uint64_t lastLBA) {
1073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   Space *tempSpace;
1083860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   tempSpace = new Space;
1103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   tempSpace->firstLBA = firstLBA;
1113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   tempSpace->lastLBA = lastLBA;
1123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   tempSpace->origPart = &emptySpace;
1133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   tempSpace->partNum = -1;
1143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   LinkToEnd(tempSpace);
1153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   SortSpaces();
1163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::AddEmptySpace();
1173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Add Spaces to represent the unallocated parts of the partition table.
1193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Returns the number of Spaces added.
1203860cbe1cafb88d70097bdfb8d84cc0029f1738esrsint GPTDataCurses::AddEmptySpaces(void) {
1213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int numAdded = 0;
1223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   Space *current;
1233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   SortSpaces();
1253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (firstSpace == NULL) {
1263860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      AddEmptySpace(GetFirstUsableLBA(), GetLastUsableLBA());
1273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      numAdded++;
1283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } else {
1293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      current = firstSpace;
1303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      while ((current != NULL) /* && (current->partNum != -1) */ ) {
1313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if ((current == firstSpace) && (current->firstLBA > GetFirstUsableLBA())) {
1323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            AddEmptySpace(GetFirstUsableLBA(), current->firstLBA - 1);
1333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            numAdded++;
1343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } // if
1353860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if ((current == lastSpace) && (current->lastLBA < GetLastUsableLBA())) {
1363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            AddEmptySpace(current->lastLBA + 1, GetLastUsableLBA());
1373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            numAdded++;
1383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } // if
1393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if ((current->prevSpace != NULL) && (current->prevSpace->lastLBA < (current->firstLBA - 1))) {
1403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            AddEmptySpace(current->prevSpace->lastLBA + 1, current->firstLBA - 1);
1413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            numAdded++;
1423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } // if
1433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         current = current->nextSpace;
1443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // while
1453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if/else
1463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   return numAdded;
1473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::AddEmptySpaces()
1483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Remove the specified Space from the linked list and set its previous and
1503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// next pointers to NULL.
1513860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::UnlinkSpace(Space *theSpace) {
1523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (theSpace != NULL) {
1533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (theSpace->prevSpace != NULL)
1543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         theSpace->prevSpace->nextSpace = theSpace->nextSpace;
1553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (theSpace->nextSpace != NULL)
1563860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         theSpace->nextSpace->prevSpace = theSpace->prevSpace;
1573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (theSpace == firstSpace)
1583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         firstSpace = theSpace->nextSpace;
1593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (theSpace == lastSpace)
1603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         lastSpace = theSpace->prevSpace;
1613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      theSpace->nextSpace = NULL;
1623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      theSpace->prevSpace = NULL;
1633860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      numSpaces--;
1643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
1653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::UnlinkSpace
1663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Link theSpace to the end of the current linked list.
1683860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::LinkToEnd(Space *theSpace) {
1693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (lastSpace == NULL) {
1703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      firstSpace = lastSpace = theSpace;
1713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      theSpace->nextSpace = NULL;
1723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      theSpace->prevSpace = NULL;
1733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } else {
1743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      theSpace->prevSpace = lastSpace;
1753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      theSpace->nextSpace = NULL;
1763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      lastSpace->nextSpace = theSpace;
1773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      lastSpace = theSpace;
1783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if/else
1793860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   numSpaces++;
1803860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::LinkToEnd()
1813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Sort spaces into ascending order by on-disk position.
1833860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::SortSpaces(void) {
1843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   Space *oldFirst, *oldLast, *earliest = NULL, *current = NULL;
1853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
1863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   oldFirst = firstSpace;
1873860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   oldLast = lastSpace;
1883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   firstSpace = lastSpace = NULL;
1893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while (oldFirst != NULL) {
1903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      current = earliest = oldFirst;
1913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      while (current != NULL) {
1923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (current->firstLBA < earliest->firstLBA)
1933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            earliest = current;
1943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         current = current->nextSpace;
1953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // while
1963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (oldFirst == earliest)
1973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         oldFirst = earliest->nextSpace;
1983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (oldLast == earliest)
1993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         oldLast = earliest->prevSpace;
2003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      UnlinkSpace(earliest);
2013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      LinkToEnd(earliest);
2023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // while
2033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::SortSpaces()
2043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
2053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Identify the spaces on the disk, a "space" being defined as a partition
2063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// or an empty gap between, before, or after partitions. The spaces are
2073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// presented to users in the main menu display.
2083860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::IdentifySpaces(void) {
2093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   MakeSpacesFromParts();
2103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   AddEmptySpaces();
2113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::IdentifySpaces()
2123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
2133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs/**************************
2143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                        *
2153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs * Data display functions *
2163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                        *
2173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs **************************/
2183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
2193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Display a single Space on line # lineNum.
2203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Returns a pointer to the space being displayed
2213860cbe1cafb88d70097bdfb8d84cc0029f1738esrsSpace* GPTDataCurses::ShowSpace(int spaceNum, int lineNum) {
2223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   Space *space;
2233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int i = 0;
2240741fa21ac6cb477891ef15f269c8c8f36cac7c6srs#ifdef USE_UTF16
2253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char temp[40];
2260741fa21ac6cb477891ef15f269c8c8f36cac7c6srs#endif
2273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
2283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   space = firstSpace;
2293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while ((space != NULL) && (i < spaceNum)) {
2303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      space = space->nextSpace;
2313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      i++;
2323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // while
2333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if ((space != NULL) && (lineNum < (LINES - 5))) {
2343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      ClearLine(lineNum);
2353860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (space->partNum == -1) { // space is empty
2363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(lineNum, 12);
2373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw(BytesToIeee((space->lastLBA - space->firstLBA + 1), blockSize).c_str());
2383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(lineNum, 24);
2393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw("free space");
2403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } else { // space holds a partition
2413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(lineNum, 3);
2423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw("%d", space->partNum + 1);
2433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(lineNum, 12);
2443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw(BytesToIeee((space->lastLBA - space->firstLBA + 1), blockSize).c_str());
2453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(lineNum, 24);
2463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw(space->origPart->GetTypeName().c_str());
2473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(lineNum, 50);
2483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         #ifdef USE_UTF16
2493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         space->origPart->GetDescription().extract(0, 39, temp, 39);
2503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw(temp);
2513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         #else
2523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw(space->origPart->GetDescription().c_str());
2533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         #endif
2543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // if/else
2553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
2563860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   return space;
2573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::ShowSpace
2583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
2593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Display the partitions, being sure that the space #selected is displayed
2603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// and highlighting that space.
2613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Returns the number of the space being shown (should be selected, but will
2623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// be -1 if something weird happens)
2633860cbe1cafb88d70097bdfb8d84cc0029f1738esrsint GPTDataCurses::DisplayParts(int selected) {
2643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int lineNum = 5, i = 0, retval = -1, numToShow, pageNum;
2653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   string theLine;
2663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
2673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(lineNum++, 0);
2683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   theLine = "Part. #     Size        Partition Type            Partition Name";
2693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw(theLine.c_str());
2703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(lineNum++, 0);
2713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   theLine = "----------------------------------------------------------------";
2723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw(theLine.c_str());
2733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   numToShow = LINES - RESERVED_TOP - RESERVED_BOTTOM;
2743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   pageNum = selected / numToShow;
2753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   for (i = pageNum * numToShow; i <= (pageNum + 1) * numToShow - 1; i++) {
2763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (i < numSpaces) { // real space; show it
2773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (i == selected) {
2783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            currentSpaceNum = i;
2791eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith            if (displayType == USE_CURSES) {
2801eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith               attron(A_REVERSE);
2811eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith               currentSpace = ShowSpace(i, lineNum++);
2821eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith               attroff(A_REVERSE);
2831eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith            } else {
2841eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith               currentSpace = ShowSpace(i, lineNum);
2851eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith               move(lineNum++, 0);
2861eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith               printw(">");
2871eea9b0b51367472ce12efb59b0018c0ac96a463Roderick W. Smith            }
2883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            DisplayOptions(i);
2893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            retval = selected;
2903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } else {
2913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ShowSpace(i, lineNum++);
2923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         }
2933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } else { // blank in display
2943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         ClearLine(lineNum++);
2953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // if/else
2963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // for
2973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   refresh();
2983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   return retval;
2993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::DisplayParts()
3003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs/**********************************************
3023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                            *
3033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs * Functions corresponding to main menu items *
3043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                            *
3053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs **********************************************/
3063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Delete the specified partition and re-detect partitions and spaces....
3083860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::DeletePartition(int partNum) {
3093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (!GPTData::DeletePartition(partNum))
3103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      Report("Could not delete partition!");
3113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   IdentifySpaces();
3123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (currentSpaceNum >= numSpaces) {
3133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentSpaceNum = numSpaces - 1;
3143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentSpace = lastSpace;
3153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
3163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::DeletePartition()
3173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Displays information on the specified partition
3193860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::ShowInfo(int partNum) {
3203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   uint64_t size;
3210741fa21ac6cb477891ef15f269c8c8f36cac7c6srs#ifdef USE_UTF16
32284aaff6b9cf3b802c621781cf9acd006aa5a3e66Roderick W. Smith   char temp[NAME_SIZE + 1];
3230741fa21ac6cb477891ef15f269c8c8f36cac7c6srs#endif
3243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clear();
3263860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(2, (COLS - 29) / 2);
3273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Information for partition #%d\n\n", partNum + 1);
3283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Partition GUID code: %s (%s)\n", partitions[partNum].GetType().AsString().c_str(),
3293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs          partitions[partNum].GetTypeName().c_str());
3303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Partition unique GUID: %s\n", partitions[partNum].GetUniqueGUID().AsString().c_str());
3313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("First sector: %lld (at %s)\n", partitions[partNum].GetFirstLBA(),
3323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs          BytesToIeee(partitions[partNum].GetFirstLBA(), blockSize).c_str());
3333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Last sector: %lld (at %s)\n", partitions[partNum].GetLastLBA(),
3343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs          BytesToIeee(partitions[partNum].GetLastLBA(), blockSize).c_str());
335bdbab02f71097593c879a552951d73969305d0aeAurimas Liutikas   size = partitions[partNum].GetLastLBA() - partitions[partNum].GetFirstLBA();
3363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Partition size: %lld sectors (%s)\n", size, BytesToIeee(size, blockSize).c_str());
3373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Attribute flags: %016x\n", partitions[partNum].GetAttributes().GetAttributes());
3383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   #ifdef USE_UTF16
33984aaff6b9cf3b802c621781cf9acd006aa5a3e66Roderick W. Smith   partitions[partNum].GetDescription().extract(0, NAME_SIZE , temp, NAME_SIZE );
3403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Partition name: '%s'\n", temp);
3413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   #else
3423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Partition name: '%s'\n", partitions[partNum].GetDescription().c_str());
3433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   #endif
3443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   PromptToContinue();
3453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::ShowInfo()
3463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Prompt for and change a partition's name....
3483860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::ChangeName(int partNum) {
34984aaff6b9cf3b802c621781cf9acd006aa5a3e66Roderick W. Smith   char temp[NAME_SIZE + 1];
3503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (ValidPartNum(partNum)) {
3523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 4, 0);
3533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      clrtobot();
3543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 4, 0);
3553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      #ifdef USE_UTF16
35684aaff6b9cf3b802c621781cf9acd006aa5a3e66Roderick W. Smith      partitions[partNum].GetDescription().extract(0, NAME_SIZE , temp, NAME_SIZE );
3573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Current partition name is '%s'\n", temp);
3583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      #else
3593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Current partition name is '%s'\n", partitions[partNum].GetDescription().c_str());
3603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      #endif
3613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Enter new partition name, or <Enter> to use the current name:\n");
3623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      echo();
36384aaff6b9cf3b802c621781cf9acd006aa5a3e66Roderick W. Smith      getnstr(temp, NAME_SIZE );
3643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      partitions[partNum].SetName((string) temp);
3653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      noecho();
3663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
3673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::ChangeName()
3683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Change the partition's type code....
3703860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::ChangeType(int partNum) {
3713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char temp[80] = "L\0";
3723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   PartType tempType;
3733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   echo();
3753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   do {
3763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 4, 0);
3773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      clrtobot();
3783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 4, 0);
3793860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Current type is %04x (%s)\n", partitions[partNum].GetType().GetHexType(), partitions[partNum].GetTypeName().c_str());
3803860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Hex code or GUID (L to show codes, Enter = %04x): ", partitions[partNum].GetType().GetHexType());
3813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      getnstr(temp, 79);
3823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if ((temp[0] == 'L') || (temp[0] == 'l')) {
3833860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         ShowTypes();
3843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } else {
3853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (temp[0] == '\0')
3863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            tempType = partitions[partNum].GetType().GetHexType();
3873860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         tempType = temp;
3883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         partitions[partNum].SetType(tempType);
3893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // if
3903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } while ((temp[0] == 'L') || (temp[0] == 'l') || (partitions[partNum].GetType() == (GUIDData) "0x0000"));
3913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   noecho();
3923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::ChangeType
3933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Sets the partition alignment value
3953860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::SetAlignment(void) {
3963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int alignment;
3973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
3983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 4, 0);
3993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clrtobot();
4003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Current partition alignment, in sectors, is %d.", GetAlignment());
4013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   do {
4023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 3, 0);
4033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Type new alignment value, in sectors: ");
4043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      echo();
4053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      scanw("%d", &alignment);
4063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      noecho();
4073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } while ((alignment == 0) || (alignment > MAX_ALIGNMENT));
4083860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   GPTData::SetAlignment(alignment);
4093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::SetAlignment()
4103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Verify the data structures. Note that this function leaves curses mode and
4123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// relies on the underlying GPTData::Verify() function to report on problems
4133860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::Verify(void) {
4143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char junk;
4153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   def_prog_mode();
4173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   endwin();
4183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   GPTData::Verify();
4193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   cout << "\nPress the <Enter> key to continue: ";
4203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   cin.get(junk);
4213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   reset_prog_mode();
4223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   refresh();
4233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::Verify()
4243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Create a new partition in the space pointed to by currentSpace.
4263860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::MakeNewPart(void) {
4273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   uint64_t size, newFirstLBA = 0, newLastLBA = 0;
4283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int partNum;
4293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char inLine[80];
4303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 4, 0);
4323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clrtobot();
4333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while ((newFirstLBA < currentSpace->firstLBA) || (newFirstLBA > currentSpace->lastLBA)) {
4343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      newFirstLBA = currentSpace->firstLBA;
4353860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 4, 0);
4363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      clrtoeol();
4373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      newFirstLBA = currentSpace->firstLBA;
4383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      Align(&newFirstLBA);
4393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("First sector (%lld-%lld, default = %lld): ", newFirstLBA, currentSpace->lastLBA, newFirstLBA);
4403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      echo();
4413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      getnstr(inLine, 79);
4423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      noecho();
4433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      newFirstLBA = IeeeToInt(inLine, blockSize, currentSpace->firstLBA, currentSpace->lastLBA, newFirstLBA);
4443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      Align(&newFirstLBA);
4453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // while
4463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   size = currentSpace->lastLBA - newFirstLBA + 1;
4473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while ((newLastLBA > currentSpace->lastLBA) || (newLastLBA < newFirstLBA)) {
4483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 3, 0);
4493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      clrtoeol();
4503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Size in sectors or {KMGTP} (default = %lld): ", size);
4513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      echo();
4523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      getnstr(inLine, 79);
4533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      noecho();
4543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      newLastLBA = newFirstLBA + IeeeToInt(inLine, blockSize, 1, size, size) - 1;
4553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // while
4563860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   partNum = FindFirstFreePart();
4573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (CreatePartition(partNum, newFirstLBA, newLastLBA)) { // created OK; set type code & name....
4583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      ChangeType(partNum);
4593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      ChangeName(partNum);
4603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } else {
4613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      Report("Error creating partition!");
4623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if/else
4633860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::MakeNewPart()
4643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Prompt user for permission to save data and, if it's given, do so!
4663860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::SaveData(void) {
4673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   string answer = "";
4683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char inLine[80];
4693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 4, 0);
4713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clrtobot();
4723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move (LINES - 2, 14);
4733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Warning!! This may destroy data on your disk!");
4743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   echo();
4753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while ((answer != "yes") && (answer != "no")) {
4763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move (LINES - 4, 2);
4773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("Are you sure you want to write the partition table to disk? (yes or no): ");
4783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      getnstr(inLine, 79);
4793860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      answer = inLine;
4803860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if ((answer != "yes") && (answer != "no")) {
4813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(LINES - 2, 0);
4823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         clrtoeol();
4833860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(LINES - 2, 14);
4843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         printw("Please enter 'yes' or 'no'");
4853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // if
4863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // while()
4873860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   noecho();
4883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (answer == "yes") {
4893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (SaveGPTData(1)) {
4903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (!myDisk.DiskSync())
4913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            Report("The kernel may be using the old partition table. Reboot to use the new\npartition table!");
4923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } else {
4933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         Report("Problem saving data! Your partition table may be damaged!");
4943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      }
4953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   }
4963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::SaveData()
4973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
4983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Back up the partition table, prompting user for a filename....
4993860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::Backup(void) {
5003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char inLine[80];
5013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   ClearBottom();
5033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 3, 0);
5043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Enter backup filename to save: ");
5053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   echo();
5063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   getnstr(inLine, 79);
5073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   noecho();
5083860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   SaveGPTBackup(inLine);
5093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::Backup()
5103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Load a GPT backup from a file
5123860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::LoadBackup(void) {
5133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char inLine[80];
5143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   ClearBottom();
5163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 3, 0);
5173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Enter backup filename to load: ");
5183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   echo();
5193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   getnstr(inLine, 79);
5203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   noecho();
5213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (!LoadGPTBackup(inLine))
5223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      Report("Restoration failed!");
5233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   IdentifySpaces();
5243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::LoadBackup()
5253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5263860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Display some basic help information
5273860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::ShowHelp(void) {
5283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int i = 0;
5293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clear();
5313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(0, (COLS - 22) / 2);
5323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Help screen for cgdisk");
5333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(2, 0);
5343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("This is cgdisk, a curses-based disk partitioning program. You can use it\n");
5353860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("to create, delete, and modify partitions on your hard disk.\n\n");
5363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   attron(A_BOLD);
5373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Use cgdisk only on GUID Partition Table (GPT) disks!\n");
5383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   attroff(A_BOLD);
5393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Use cfdisk on Master Boot Record (MBR) disks.\n\n");
5403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Command      Meaning\n");
5413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("-------      -------\n");
5423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   while (menuMain[i].key != 0) {
5433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw("   %c         %s\n", menuMain[i].key, menuMain[i].desc.c_str());
5443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      i++;
5453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // while()
5463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   PromptToContinue();
5473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::ShowHelp()
5483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs/************************************
5503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                  *
5513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs * User input and menuing functions *
5523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                  *
5533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs ************************************/
5543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Change the currently-selected space....
5563860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::ChangeSpaceSelection(int delta) {
5573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (currentSpace != NULL) {
5583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      while ((delta > 0) && (currentSpace->nextSpace != NULL)) {
5593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         currentSpace = currentSpace->nextSpace;
5603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         delta--;
5613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         currentSpaceNum++;
5623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // while
5633860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      while ((delta < 0) && (currentSpace->prevSpace != NULL)) {
5643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         currentSpace = currentSpace->prevSpace;
5653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         delta++;
5663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         currentSpaceNum--;
5673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // while
5683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
5693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   // Below will hopefully never be true; bad counting error (bug), so reset to
5703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   // the first Space as a failsafe....
5713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (DisplayParts(currentSpaceNum) != currentSpaceNum) {
5723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentSpaceNum = 0;
5733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentSpace = firstSpace;
5743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      DisplayParts(currentSpaceNum);
5753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
5763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses
5773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Move option selection left or right....
5793860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::MoveSelection(int delta) {
5803860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int newKeyNum;
5813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   // Begin with a sanity check to ensure a valid key is selected....
5833860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (whichOptions.find(currentKey) == string::npos)
5843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentKey = 'n';
5853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   newKeyNum = whichOptions.find(currentKey);
5863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   newKeyNum += delta;
5873860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (newKeyNum < 0)
5883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      newKeyNum = whichOptions.length() - 1;
5893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   newKeyNum %= whichOptions.length();
5903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   currentKey = whichOptions[newKeyNum];
5913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   DisplayOptions(currentKey);
5923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::MoveSelection()
5933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
5943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Show user's options. Refers to currentSpace to determine which options to show.
5953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Highlights the option with the key selectedKey; or a default if that's invalid.
5963860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::DisplayOptions(char selectedKey) {
5973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   uint i, j = 0, firstLine, numPerLine;
5983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   string optionName, optionDesc = "";
5993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
6003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (currentSpace != NULL) {
6013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (currentSpace->partNum == -1) { // empty space is selected
6023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         whichOptions = EMPTY_SPACE_OPTIONS;
6033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (whichOptions.find(selectedKey) == string::npos)
6043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            selectedKey = 'n';
6053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } else { // a partition is selected
6063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         whichOptions = PARTITION_OPTIONS;
6073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (whichOptions.find(selectedKey) == string::npos)
6083860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            selectedKey = 't';
6093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // if/else
6103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
6113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      firstLine = LINES - 4;
6123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      numPerLine = (COLS - 8) / 12;
6133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      ClearBottom();
6143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(firstLine, 0);
6153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      for (i = 0; i < whichOptions.length(); i++) {
6163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         optionName = "";
6173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         for (j = 0; menuMain[j].key; j++) {
6183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            if (menuMain[j].key == whichOptions[i]) {
6193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs               optionName = menuMain[j].name;
6203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs               if (whichOptions[i] == selectedKey)
6213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs                  optionDesc = menuMain[j].desc;
6223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            } // if
6233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } // for
6243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         move(firstLine + i / numPerLine, (i % numPerLine) * 12 + 4);
6253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (whichOptions[i] == selectedKey) {
6263860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            attron(A_REVERSE);
6273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            printw("[ %s ]", optionName.c_str());
6283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            attroff(A_REVERSE);
6293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } else {
6303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            printw("[ %s ]", optionName.c_str());
6313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } // if/else
6323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // for
6333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      move(LINES - 1, (COLS - optionDesc.length()) / 2);
6343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      printw(optionDesc.c_str());
6353860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentKey = selectedKey;
6363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if
6373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::DisplayOptions()
6383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
6393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Accept user input and process it. Returns when the program should terminate.
6403860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::AcceptInput() {
6413860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int inputKey, exitNow = 0;
6423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
6433860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   do {
6443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      refresh();
6453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      inputKey = getch();
6463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      switch (inputKey) {
6473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case KEY_UP:
6483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ChangeSpaceSelection(-1);
6493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case KEY_DOWN:
6513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ChangeSpaceSelection(+1);
6523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case 339: // page up key
6543860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ChangeSpaceSelection(RESERVED_TOP + RESERVED_BOTTOM - LINES);
6553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6563860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case 338: // page down key
6573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ChangeSpaceSelection(LINES - RESERVED_TOP - RESERVED_BOTTOM);
6583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case KEY_LEFT:
6603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            MoveSelection(-1);
6613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case KEY_RIGHT:
6633860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            MoveSelection(+1);
6643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case KEY_ENTER: case 13:
6663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            exitNow = Dispatch(currentKey);
6673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         case 27: // escape key
6693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            exitNow = 1;
6703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         default:
6723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            exitNow = Dispatch(inputKey);
6733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            break;
6743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      } // switch()
6753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } while (!exitNow);
6763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::AcceptInput()
6773860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
6783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Operation has been selected, so do it. Returns 1 if the program should
6793860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// terminate on return from this program, 0 otherwise.
6803860cbe1cafb88d70097bdfb8d84cc0029f1738esrsint GPTDataCurses::Dispatch(char operation) {
6813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   int exitNow = 0;
6823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
6833860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   switch (operation) {
6843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'a': case 'A':
6853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         SetAlignment();
6863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
6873860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'b': case 'B':
6883860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         Backup();
6893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
6903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'd': case 'D':
6913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (ValidPartNum(currentSpace->partNum))
6923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            DeletePartition(currentSpace->partNum);
6933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
6943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'h': case 'H':
6953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         ShowHelp();
6963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
6973860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'i': case 'I':
6983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (ValidPartNum(currentSpace->partNum))
6993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ShowInfo(currentSpace->partNum);
7003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'l': case 'L':
7023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         LoadBackup();
7033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'm': case 'M':
7053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (ValidPartNum(currentSpace->partNum))
7063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ChangeName(currentSpace->partNum);
7073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7083860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'n': case 'N':
7093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (currentSpace->partNum < 0) {
7103860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            MakeNewPart();
7113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            IdentifySpaces();
7123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         } // if
7133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'q': case 'Q':
7153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         exitNow = 1;
7163860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 't': case 'T':
7183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         if (ValidPartNum(currentSpace->partNum))
7193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs            ChangeType(currentSpace->partNum);
7203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'v': case 'V':
7223860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         Verify();
7233860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7243860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      case 'w': case 'W':
7253860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         SaveData();
7263860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7273860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      default:
7283860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         break;
7293860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // switch()
7303860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   DrawMenu();
7313860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   return exitNow;
7323860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::Dispatch()
7333860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7343860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Draws the main menu
7353860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid GPTDataCurses::DrawMenu(void) {
7363860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   string title="cgdisk ";
7373860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   title += GPTFDISK_VERSION;
7383860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   string drive="Disk Drive: ";
7393860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   drive += device;
7403860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   ostringstream size;
741e3ee733ff8690af7568dac665bc20ecf869dea1dRoderick W. Smith
7423860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   size << "Size: " << diskSize << ", " << BytesToIeee(diskSize, blockSize);
743e3ee733ff8690af7568dac665bc20ecf869dea1dRoderick W. Smith
7443860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clear();
7453860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(0, (COLS - title.length()) / 2);
7463860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw(title.c_str());
7473860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(2, (COLS - drive.length()) / 2);
7483860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw(drive.c_str());
7493860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(3, (COLS - size.str().length()) / 2);
7503860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw(size.str().c_str());
7513860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   DisplayParts(currentSpaceNum);
7523860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // DrawMenu
7533860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7543860cbe1cafb88d70097bdfb8d84cc0029f1738esrsint GPTDataCurses::MainMenu(void) {
7553860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   if (((LINES - RESERVED_TOP - RESERVED_BOTTOM) < 2) || (COLS < 80)) {
7563860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      Report("Display is too small; it must be at least 80 x 14 characters!");
7573860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } else {
7583860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      if (GPTData::Verify() > 0)
7593860cbe1cafb88d70097bdfb8d84cc0029f1738esrs         Report("Warning! Problems found on disk! Use the Verify function to learn more.\n"
7603860cbe1cafb88d70097bdfb8d84cc0029f1738esrs                "Using gdisk or some other program may be necessary to repair the problems.");
7613860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      IdentifySpaces();
7623860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      currentSpaceNum = 0;
7633860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      DrawMenu();
7643860cbe1cafb88d70097bdfb8d84cc0029f1738esrs      AcceptInput();
7653860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   } // if/else
7663860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   endwin();
7673860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   return 0;
7683860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // GPTDataCurses::MainMenu
7693860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7703860cbe1cafb88d70097bdfb8d84cc0029f1738esrs/***********************************************************
7713860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                                         *
7723860cbe1cafb88d70097bdfb8d84cc0029f1738esrs * Non-class support functions (mostly related to ncurses) *
7733860cbe1cafb88d70097bdfb8d84cc0029f1738esrs *                                                         *
7743860cbe1cafb88d70097bdfb8d84cc0029f1738esrs ***********************************************************/
7753860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7763860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Clears the specified line of all data....
7773860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid ClearLine(int lineNum) {
7783860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(lineNum, 0);
7793860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clrtoeol();
7803860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // ClearLine()
7813860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7823860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Clear the last few lines of the display
7833860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid ClearBottom(void) {
7843860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - RESERVED_BOTTOM, 0);
7853860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clrtobot();
7863860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // ClearBottom()
7873860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7883860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid PromptToContinue(void) {
7893860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   ClearBottom();
7903860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 2, (COLS - 29) / 2);
7913860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Press any key to continue....");
7923860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   cbreak();
7933860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   getch();
7943860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // PromptToContinue()
7953860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
7963860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Display one line of text on the screen and prompt to press any key to continue.
7973860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid Report(string theText) {
7983860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   clear();
7993860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(0, 0);
8003860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw(theText.c_str());
8013860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   move(LINES - 2, (COLS - 29) / 2);
8023860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   printw("Press any key to continue....");
8033860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   cbreak();
8043860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   getch();
8053860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // Report()
8063860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
8073860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// Displays all the partition type codes and then prompts to continue....
8083860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// NOTE: This function temporarily exits curses mode as a matter of
8093860cbe1cafb88d70097bdfb8d84cc0029f1738esrs// convenience.
8103860cbe1cafb88d70097bdfb8d84cc0029f1738esrsvoid ShowTypes(void) {
8113860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   PartType tempType;
8123860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   char junk;
8133860cbe1cafb88d70097bdfb8d84cc0029f1738esrs
8143860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   def_prog_mode();
8153860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   endwin();
816e3ee733ff8690af7568dac665bc20ecf869dea1dRoderick W. Smith   tempType.ShowAllTypes(LINES - 3);
8173860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   cout << "\nPress the <Enter> key to continue: ";
8183860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   cin.get(junk);
8193860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   reset_prog_mode();
8203860cbe1cafb88d70097bdfb8d84cc0029f1738esrs   refresh();
8213860cbe1cafb88d70097bdfb8d84cc0029f1738esrs} // ShowTypes()
822