/****************************************************************************
*
*                SciTech Nucleus Command Line Options program
*
*               Copyright (C) 1991-1998 SciTech Software, Inc.
*                            All rights reserved.
*
*  ======================================================================
*  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
*  |                                                                    |
*  |This copyrighted computer code contains proprietary technology      |
*  |owned by SciTech Software, Inc., located at 505 Wall Street,        |
*  |Chico, CA 95928 USA (http://www.scitechsoft.com).                   |
*  |                                                                    |
*  |The contents of this file are subject to the SciTech Nucleus        |
*  |License; you may *not* use this file or related software except in  |
*  |compliance with the License. You may obtain a copy of the License   |
*  |at http://www.scitechsoft.com/nucleus-license.txt                   |
*  |                                                                    |
*  |Software distributed under the License is distributed on an         |
*  |"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or      |
*  |implied. See the License for the specific language governing        |
*  |rights and limitations under the License.                           |
*  |                                                                    |
*  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
*  ======================================================================
*
* Language:     ANSI C
* Environment:  Any 32-bit protected mode environment
*
* Description:  Simple program that allows the Nucleus opt to be
*				changed from the command line.
*
****************************************************************************/

#include "nucleus/graphics.h"
#include "sdd/copyrigh.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*---------------------------- Global Variables ---------------------------*/

static GA_devCtx		*dc = NULL;
static GA_initFuncs		init;
static GA_configInfo	info;
static GA_options		opt;
static GA_globalOptions	gOpt;
GA_driverFuncs          driver;

/*----------------------------- Implementation ----------------------------*/

/****************************************************************************
REMARKS:
Display the sign on banner.
****************************************************************************/
static void banner(void)
{
	printf("GAOption - SciTech Nucleus Option Selection Program\n");
	printf("           %s\n", SCITECH_COPYRIGHT_MSG_SHORT);
	printf("\n");
}

/****************************************************************************
REMARKS:
Display the help screen.
****************************************************************************/
static void help(void)
{
	banner();
	printf("Valid commands are:\n");
	printf("\n");
    printf("  gaoption show       <global | accel> <device>\n");
    printf("  gaoption accel      [function] [on | off] <device>\n");
	printf("  gaoption accel      [none | basic | most | full] <device>\n");
	printf("  gaoption vbe        [on | off]\n");
	printf("  gaoption vga        [on | off]\n");
	printf("  gaoption noncert    [on | off]\n");
	printf("  gaoption nowcomb    [on | off]\n");
	printf("  gaoption noddc      [on | off]\n");
    printf("  gaoption agpfwrite  [on | off]\n");
	printf("  gaoption lcdusebios [auto | on | off]\n");
	printf("  gaoption agpmem     [memsize]\n");
	printf("  gaoption usesysmem  [memsize | off]\n");
	printf("  gaoption prefer16   [on | off] <device>\n");
	printf("  gaoption prefer32   [on | off] <device>\n");
#ifdef SNAP
	printf("  gaoption invert     [on | off] <device>\n");
	printf("  gaoption portrait   [on | off] <device>\n");
	printf("  gaoption flipped    [on | off] <device>\n");
	printf("  gaoption virtual    [on | off] <[xRes] [yRes] [horz count] [vert count]>\n");
	printf("  gaoption multihead  [on | off] [xRes] [yRes] [horz count] [vert count] <dev>\n");
#endif
	exit(-1);
}

/****************************************************************************
REMARKS:
Load the global device driver options.
****************************************************************************/
static void LoadGlobalOptions(void)
{
	gOpt.dwSize = sizeof(gOpt);
	GA_getGlobalOptions(&gOpt, false);
}

/****************************************************************************
REMARKS:
Load the Nucleus driver and intialise it.
****************************************************************************/
static void LoadDriver(
	int deviceIndex)
{
	if (!dc) {
		if ((dc = GA_loadDriver(deviceIndex,false)) == NULL)
			PM_fatalError(GA_errorMsg(GA_status()));
		init.dwSize = sizeof(init);
		if (!GA_queryFunctions(dc,GA_GET_INITFUNCS,&init))
			PM_fatalError("Unable to get device driver functions!");
		info.dwSize = sizeof(info);
		init.GetConfigInfo(&info);
		opt.dwSize = sizeof(opt);
		init.GetOptions(&opt);
		LoadGlobalOptions();

        // Turn off multi-head support if the controller itself does
        // not support multi-head modes
        if (!(dc->Attributes & gaHaveMultiHead))
            opt.bMultiHead = false;
		}
}

#ifdef SNAP
/****************************************************************************
REMARKS:
Function to enable virtual display mode. This is a simple function that
can enable any number of displays in a rectangular layout with each
display using the same resolution.
****************************************************************************/
static void EnableVirtualMode(
	int argc,
	char *argv[])
{
	int x,y,i,xRes,yRes,numX,numY;

	if (argc != 7)
		help();
	xRes = atoi(argv[3]);
	yRes = atoi(argv[4]);
	numX = atoi(argv[5]);
	numY = atoi(argv[6]);
	gOpt.virtualSize.left = gOpt.virtualSize.top = 0;
	gOpt.virtualSize.right = xRes * numX;
	gOpt.virtualSize.bottom = yRes * numY;
	memset(&gOpt.resolutions,0,sizeof(gOpt.resolutions));
	memset(&gOpt.bounds,0,sizeof(gOpt.bounds));
	for (i = x = 0; x < numX; x++) {
		for (y = 0; y < numY; y++, i++) {
			gOpt.resolutions[i].left = gOpt.resolutions[i].top = 0;
			gOpt.resolutions[i].right = xRes;
			gOpt.resolutions[i].bottom = yRes;
			gOpt.bounds[i].left = x * xRes;
			gOpt.bounds[i].top = y * yRes;
			gOpt.bounds[i].right = (x+1) * xRes;
			gOpt.bounds[i].bottom = (y+1) * yRes;
			}
		}
	gOpt.bVirtualDisplay = true;
}

/****************************************************************************
REMARKS:
Function to enable virtual display mode. This is a simple function that
can enable any number of displays in a rectangular layout with each
display using the same resolution.
****************************************************************************/
static void EnableMultiHeadMode(
	int argc,
	char *argv[])
{
	int x,y,i,xRes,yRes,numX,numY;

    if (!(dc->Attributes & gaHaveMultiHead)){
        printf("MultiHead is not supported on this driver.\n");
        exit(-1);
        }

	if (argc != 7 && argc != 8)
		help();
	xRes = atoi(argv[3]);
	yRes = atoi(argv[4]);
	numX = atoi(argv[5]);
	numY = atoi(argv[6]);
    if (numX * numY > GA_MAX_HEADS){
        printf("Requested layout exceeds maximum number of heads.\n");
        exit(-1);
        }
    else if (numX * numY < 2){
        printf("Requested heads must be greater than or equal to 2.\n");
        exit(-1);
        }
	opt.multiHeadSize.left = opt.multiHeadSize.top = 0;
	opt.multiHeadSize.right = xRes * numX;
	opt.multiHeadSize.bottom = yRes * numY;
	memset(&opt.multiHeadRes,0,sizeof(opt.multiHeadRes));
	memset(&opt.multiHeadBounds,0,sizeof(opt.multiHeadBounds));
	for (i = x = 0; x < numX; x++) {
		for (y = 0; y < numY; y++, i++) {
			opt.multiHeadRes[i].left = opt.multiHeadRes[i].top = 0;
			opt.multiHeadRes[i].right = xRes;
			opt.multiHeadRes[i].bottom = yRes;
			opt.multiHeadBounds[i].left = x * xRes;
			opt.multiHeadBounds[i].top = y * yRes;
			opt.multiHeadBounds[i].right = (x+1) * xRes;
			opt.multiHeadBounds[i].bottom = (y+1) * yRes;
			}
		}
	opt.bMultiHead = true;
}
#endif

/****************************************************************************
REMARKS:
Function to enable the hardware acceleration features of the drivers
depending on a sliding scale.
****************************************************************************/
static void SetHardwareAccel(
	int argc,
	char *argv[])
{
        ibool   enable;

        if (argc < 3 || argc > 5) help();
        if (stricmp(argv[2],"full") == 0) {
        opt.bHardwareCursor         = true;
        opt.bHardwareColorCursor    = true;
        opt.bHardwareVideo          = true;
        opt.bHardwareAccel2D        = true;
		opt.bHardwareAccel3D        = true;
		opt.bMonoPattern            = true;
		opt.bTransMonoPattern       = true;
		opt.bColorPattern           = true;
		opt.bTransColorPattern      = true;
		opt.bSysMem                 = true;
		opt.bLinear                 = true;
		opt.bBusMaster              = true;
		opt.bDrawScanList           = true;
		opt.bDrawEllipseList        = true;
		opt.bDrawFatEllipseList     = true;
		opt.bDrawRect               = true;
		opt.bDrawRectLin            = true;
		opt.bDrawTrap               = true;
		opt.bDrawLine               = true;
		opt.bDrawStippleLine        = true;
		opt.bPutMonoImage           = true;
		opt.bClipMonoImage          = true;
		opt.bBitBlt                 = true;
		opt.bBitBltPatt             = true;
		opt.bBitBltColorPatt        = true;
		opt.bSrcTransBlt            = true;
		opt.bDstTransBlt            = true;
		opt.bStretchBlt             = true;
		opt.bConvertBlt             = true;
		opt.bStretchConvertBlt      = true;
		opt.bBitBltFx               = true;
		opt.bGetBitmap              = true;
                opt.accelType               = gaAccelType_Full;
		}
	else if (stricmp(argv[2],"most") == 0) {
        opt.bHardwareCursor         = false;
        opt.bHardwareColorCursor    = false;
        opt.bHardwareVideo          = true;
        opt.bHardwareAccel2D        = true;
		opt.bHardwareAccel3D        = true;
		opt.bMonoPattern            = true;
		opt.bTransMonoPattern       = true;
		opt.bColorPattern           = true;
		opt.bTransColorPattern      = true;
		opt.bSysMem                 = true;
		opt.bLinear                 = true;
		opt.bBusMaster              = true;
		opt.bDrawScanList           = true;
		opt.bDrawEllipseList        = true;
		opt.bDrawFatEllipseList     = true;
		opt.bDrawRect               = true;
		opt.bDrawRectLin            = true;
		opt.bDrawTrap               = true;
		opt.bDrawLine               = true;
		opt.bDrawStippleLine        = true;
		opt.bPutMonoImage           = true;
		opt.bClipMonoImage          = true;
		opt.bBitBlt                 = true;
		opt.bBitBltPatt             = true;
		opt.bBitBltColorPatt        = true;
		opt.bSrcTransBlt            = true;
		opt.bDstTransBlt            = true;
		opt.bStretchBlt             = true;
		opt.bConvertBlt             = true;
		opt.bStretchConvertBlt      = true;
		opt.bBitBltFx               = true;
		opt.bGetBitmap              = true;
                opt.accelType               = gaAccelType_Most;
		}
	else if (stricmp(argv[2],"basic") == 0) {
        opt.bHardwareCursor         = false;
        opt.bHardwareColorCursor    = false;
        opt.bHardwareVideo          = false;
        opt.bHardwareAccel2D        = true;
		opt.bHardwareAccel3D        = false;
		opt.bMonoPattern            = true;
		opt.bTransMonoPattern       = true;
		opt.bColorPattern           = true;
		opt.bTransColorPattern      = true;
		opt.bSysMem                 = false;
		opt.bLinear                 = false;
		opt.bBusMaster              = false;
		opt.bDrawScanList           = true;
		opt.bDrawEllipseList        = true;
		opt.bDrawFatEllipseList     = true;
		opt.bDrawRect               = true;
		opt.bDrawRectLin            = false;
		opt.bDrawTrap               = true;
		opt.bDrawLine               = false;
		opt.bDrawStippleLine        = false;
		opt.bPutMonoImage           = false;
		opt.bClipMonoImage          = false;
		opt.bBitBlt                 = true;
		opt.bBitBltPatt             = false;
		opt.bBitBltColorPatt        = false;
		opt.bSrcTransBlt            = false;
		opt.bDstTransBlt            = false;
		opt.bStretchBlt             = false;
		opt.bConvertBlt             = false;
		opt.bStretchConvertBlt      = false;
		opt.bBitBltFx               = false;
		opt.bGetBitmap              = false;
                opt.accelType               = gaAccelType_Basic;
		}
	else if (stricmp(argv[2],"none") == 0) {
        opt.bHardwareCursor         = false;
        opt.bHardwareColorCursor    = false;
        opt.bHardwareVideo          = false;
        opt.bHardwareAccel2D        = false;
		opt.bHardwareAccel3D        = false;
		opt.bMonoPattern            = false;
		opt.bTransMonoPattern       = false;
		opt.bColorPattern           = false;
		opt.bTransColorPattern      = false;
		opt.bSysMem                 = false;
		opt.bLinear                 = false;
		opt.bBusMaster              = false;
		opt.bDrawScanList           = false;
		opt.bDrawEllipseList        = false;
		opt.bDrawFatEllipseList     = false;
		opt.bDrawRect               = false;
		opt.bDrawRectLin            = false;
		opt.bDrawTrap               = false;
		opt.bDrawLine               = false;
		opt.bDrawStippleLine        = false;
		opt.bPutMonoImage           = false;
		opt.bClipMonoImage          = false;
		opt.bBitBlt                 = false;
		opt.bBitBltPatt             = false;
		opt.bBitBltColorPatt        = false;
		opt.bSrcTransBlt            = false;
		opt.bDstTransBlt            = false;
		opt.bStretchBlt             = false;
		opt.bConvertBlt             = false;
		opt.bStretchConvertBlt      = false;
		opt.bBitBltFx               = false;
		opt.bGetBitmap              = false;
        opt.accelType               = gaAccelType_None;
		}
    else {
        if (argc < 4) help();
        enable = stricmp(argv[3],"on") == 0;

        if (stricmp(argv[2],"HardwareCursor") == 0)
            opt.bHardwareCursor         = enable;
        else if (stricmp(argv[2],"HardwareColorCursor") == 0)
            opt.bHardwareColorCursor    = enable;
        else if (stricmp(argv[2],"HardwareVideo") == 0)
            opt.bHardwareVideo          = enable;
        else if (stricmp(argv[2],"HardwareAccel2D") == 0)
            opt.bHardwareAccel2D        = enable;
        else if (stricmp(argv[2],"HardwareAccel3D") == 0)
            opt.bHardwareAccel3D        = enable;
        else if (stricmp(argv[2],"MonoPattern") == 0)
            opt.bMonoPattern            = enable;
        else if (stricmp(argv[2],"TransMonoPattern") == 0)
            opt.bTransMonoPattern       = enable;
        else if (stricmp(argv[2],"ColorPattern") == 0)
            opt.bColorPattern           = enable;
        else if (stricmp(argv[2],"TransColorPattern") == 0)
            opt.bTransColorPattern      = enable;
        else if (stricmp(argv[2],"SysMem") == 0)
            opt.bSysMem                 = enable;
        else if (stricmp(argv[2],"Linear") == 0)
            opt.bLinear                 = enable;
        else if (stricmp(argv[2],"BusMaster") == 0)
            opt.bBusMaster              = enable;
        else if (stricmp(argv[2],"DrawScanList") == 0)
            opt.bDrawScanList           = enable;
        else if (stricmp(argv[2],"DrawEllipseList") == 0)
            opt.bDrawEllipseList        = enable;
        else if (stricmp(argv[2],"DrawFatEllipseList") == 0)
            opt.bDrawFatEllipseList     = enable;
        else if (stricmp(argv[2],"DrawRect") == 0)
            opt.bDrawRect               = enable;
        else if (stricmp(argv[2],"DrawRectLin") == 0)
            opt.bDrawRectLin            = enable;
        else if (stricmp(argv[2],"DrawTrap") == 0)
            opt.bDrawTrap               = enable;
        else if (stricmp(argv[2],"DrawLine") == 0)
            opt.bDrawLine               = enable;
        else if (stricmp(argv[2],"DrawStippleLine") == 0)
            opt.bDrawStippleLine        = enable;
        else if (stricmp(argv[2],"PutMonoImage") == 0)
            opt.bPutMonoImage           = enable;
        else if (stricmp(argv[2],"ClipMonoImage") == 0)
            opt.bClipMonoImage          = enable;
        else if (stricmp(argv[2],"BitBlt") == 0)
            opt.bBitBlt                 = enable;
        else if (stricmp(argv[2],"BitBltPatt") == 0)
            opt.bBitBltPatt             = enable;
        else if (stricmp(argv[2],"BitBltColorPatt") == 0)
            opt.bBitBltColorPatt        = enable;
        else if (stricmp(argv[2],"SrcTransBlt") == 0)
            opt.bSrcTransBlt            = enable;
        else if (stricmp(argv[2],"DstTransBlt") == 0)
            opt.bDstTransBlt            = enable;
        else if (stricmp(argv[2],"StretchBlt") == 0)
            opt.bStretchBlt             = enable;
        else if (stricmp(argv[2],"ConvertBlt") == 0)
            opt.bConvertBlt             = enable;
        else if (stricmp(argv[2],"StretchConvertBlt") == 0)
            opt.bStretchConvertBlt      = enable;
        else if (stricmp(argv[2],"BitBltFx") == 0)
            opt.bBitBltFx               = enable;
        else if (stricmp(argv[2],"GetBitmap") == 0)
            opt.bGetBitmap              = enable;
        else
            help();
        opt.accelType               = gaAccelType_Custom;
        }
}

/****************************************************************************
REMARKS:
Returns the LCDUseBIOS setting.
****************************************************************************/
static const char *GetLCDMode(void)
{
	switch (gOpt.bLCDUseBIOS) {
		case gaLCDUseBIOS_Off:	return "Off";
		case gaLCDUseBIOS_Auto:	return "Auto";
		case gaLCDUseBIOS_On:	return "On";
		}
	return "Unknown!";
}

/****************************************************************************
REMARKS:
Returns the AGP shared memory size
****************************************************************************/
static const char *GetAGPMemSize(void)
{
	static char buf[20];
	sprintf(buf,"%d Kb", gOpt.dwSharedAGPMemSize);
	return buf;
}

/****************************************************************************
REMARKS:
Returns the hardware acceleration type.
****************************************************************************/
static const char *GetSysMemMode(void)
{
	static char buf[20];

	if (gOpt.bUseMemoryDriver) {
		sprintf(buf,"On (%d Kb)", gOpt.wSysMemSize);
		return buf;
		}
	return "Off";
}

/****************************************************************************
REMARKS:
Show the current settings for the device.
****************************************************************************/
static void ShowGlobalSettings(void)
{
	LoadGlobalOptions();
	printf(
		"Global options for all devices:\n\n"
		"  Force VBE Fallback ...... %s\n"
		"  Force VGA Fallback ...... %s\n"
		"  Allow non-certified ..... %s\n"
		"  Disable write combining . %s\n"
		"  Use BIOS for LCD panel... %s\n"
		"  Shared AGP memory size... %s\n"
		"  Use system memory driver. %s\n"
        "  Disable DDC detection.... %s\n"
        "  Enable AGP FastWrite..... %s\n",
        gOpt.bVBEOnly           ? "On" : "Off",
		gOpt.bVGAOnly           ? "On" : "Off",
		gOpt.bAllowNonCertified ? "On" : "Off",
		gOpt.bNoWriteCombine    ? "On" : "Off",
		GetLCDMode(),
		GetAGPMemSize(),		
		GetSysMemMode(),
        gOpt.bNoDDCDetect    ? "On" : "Off",
        gOpt.bAGPFastWrite   ? "On" : "Off");
#ifdef SNAP
    {
	int	i;

	if (gOpt.bVirtualDisplay) {
		printf("  Virtual Display.......... Yes\n");
		for (i = 0; i < GA_MAX_VIRTUAL_DISPLAYS; i++) {
			if (gOpt.bounds[i].right == 0)
				break;
			printf("    %2d: %4d x %4d (%4d,%4d,%4d,%4d)\n",
				i,
				gOpt.resolutions[i].right,
				gOpt.resolutions[i].bottom,
				gOpt.bounds[i].left,
				gOpt.bounds[i].top,
				gOpt.bounds[i].right,
				gOpt.bounds[i].bottom);
			}
		}
	else
		printf("  Virtual Display.......... Off\n");
    }
#endif
}

/****************************************************************************
REMARKS:
Returns the hardware acceleration type.
****************************************************************************/
static const char *GetHardwareAccelType(void)
{
	switch (opt.accelType) {
        case gaAccelType_Custom: return "Custom";
        case gaAccelType_Full:   return "Full";
        case gaAccelType_Most:   return "Most";
        case gaAccelType_Basic:  return "Basic";
        case gaAccelType_None:   return "None";
		}
	return "Unknown!";
}

/****************************************************************************
REMARKS:
Show the current acceleration settings for the device.
****************************************************************************/
static void ShowAccelSettings(
	int deviceIndex)
{
	LoadDriver(deviceIndex);
	printf(
        "Acceleration Settings for %s %s (device %d):\n\n"
        "  HardwareCursor        : %s\n"
        "  HardwareColorCursor   : %s\n"
        "  HardwareVideo         : %s\n"
        "  HardwareAccel2D       : %s\n"
        "  HardwareAccel3D       : %s\n"
        "  MonoPattern           : %s\n"
        "  TransMonoPattern      : %s\n"
        "  ColorPattern          : %s\n"
        "  TransColorPattern     : %s\n"
        "  SysMem                : %s\n"
        "  Linear                : %s\n"
        "  BusMaster             : %s\n"
        "  DrawScanList          : %s\n"
        "  DrawEllipseList       : %s\n"
        "  DrawFatEllipseList    : %s\n"
        "  DrawRect              : %s\n"
        "  DrawRectLin           : %s\n"
        "  DrawTrap              : %s\n"
        "  DrawLine              : %s\n"
        "  DrawStippleLine       : %s\n"
        "  PutMonoImage          : %s\n"
        "  ClipMonoImage         : %s\n"
        "  BitBlt                : %s\n"
        "  BitBltPatt            : %s\n"
        "  BitBltColorPatt       : %s\n"
        "  SrcTransBlt           : %s\n"
        "  DstTransBlt           : %s\n"
        "  StretchBlt            : %s\n"
        "  ConvertBlt            : %s\n"
        "  StretchConvertBlt     : %s\n"
        "  BitBltFx              : %s\n"
        "  GetBitmap             : %s\n"
        "  Hardware acceleration : %s\n\n",
		info.ManufacturerName, info.ChipsetName,
		deviceIndex,
        opt.bHardwareCursor         ? "On" : "Off",
        opt.bHardwareColorCursor    ? "On" : "Off",
        opt.bHardwareVideo          ? "On" : "Off",
        opt.bHardwareAccel2D        ? "On" : "Off",
        opt.bHardwareAccel3D        ? "On" : "Off",
        opt.bMonoPattern            ? "On" : "Off",
        opt.bTransMonoPattern       ? "On" : "Off",
        opt.bColorPattern           ? "On" : "Off",
        opt.bTransColorPattern      ? "On" : "Off",
        opt.bSysMem                 ? "On" : "Off",
        opt.bLinear                 ? "On" : "Off",
        opt.bBusMaster              ? "On" : "Off",
        opt.bDrawScanList           ? "On" : "Off",
        opt.bDrawEllipseList        ? "On" : "Off",
        opt.bDrawFatEllipseList     ? "On" : "Off",
        opt.bDrawRect               ? "On" : "Off",
        opt.bDrawRectLin            ? "On" : "Off",
        opt.bDrawTrap               ? "On" : "Off",
        opt.bDrawLine               ? "On" : "Off",
        opt.bDrawStippleLine        ? "On" : "Off",
        opt.bPutMonoImage           ? "On" : "Off",
        opt.bClipMonoImage          ? "On" : "Off",
        opt.bBitBlt                 ? "On" : "Off",
        opt.bBitBltPatt             ? "On" : "Off",
        opt.bBitBltColorPatt        ? "On" : "Off",
        opt.bSrcTransBlt            ? "On" : "Off",
        opt.bDstTransBlt            ? "On" : "Off",
        opt.bStretchBlt             ? "On" : "Off",
        opt.bConvertBlt             ? "On" : "Off",
        opt.bStretchConvertBlt      ? "On" : "Off",
        opt.bBitBltFx               ? "On" : "Off",
        opt.bGetBitmap              ? "On" : "Off",
        GetHardwareAccelType());
}

/****************************************************************************
REMARKS:
Show the current settings for the device.
****************************************************************************/
static void ShowSettings(
	int deviceIndex)
{
	LoadDriver(deviceIndex);
	printf(
		"Options for %s %s (device %d):\n\n"
		"  Invert .................. %s\n"
		"  Portrait ................ %s\n"
		"  Flipped ................. %s\n"
		"  Prefer 16 bit per pixel.. %s\n"
		"  Prefer 32 bit per pixel.. %s\n"
		"  Hardware acceleration.... %s\n",
		info.ManufacturerName, info.ChipsetName,
		deviceIndex,
		opt.bInvertColors 	    ? "On" : "Off",
		opt.bPortrait     	    ? "On" : "Off",
		opt.bFlipped      	    ? "On" : "Off",
		opt.bPrefer16bpp		? "On" : "Off",
		opt.bPrefer32bpp		? "On" : "Off",
		GetHardwareAccelType());
#ifdef SNAP
    {
    int i;

    if (opt.bMultiHead) {
		printf("  Multi Head Display....... Yes\n");
		for (i = 0; i < GA_MAX_HEADS; i++) {
			if (opt.multiHeadBounds[i].right == 0)
				break;
			printf("    %2d: %4d x %4d (%4d,%4d,%4d,%4d)\n",
				i,
				opt.multiHeadRes[i].right,
				opt.multiHeadRes[i].bottom,
				opt.multiHeadBounds[i].left,
				opt.multiHeadBounds[i].top,
				opt.multiHeadBounds[i].right,
				opt.multiHeadBounds[i].bottom);
			}
		}
	else
		printf("  Multi Head Display....... Off\n");
    }
#endif
    printf("\n");
}

/****************************************************************************
REMARKS:
Main program entry point
****************************************************************************/
int main(
	int argc,
	char *argv[])
{
	/* Now handle the query */
	if (argc >= 2 && stricmp(argv[1],"show") == 0) {
		if (argc == 2) {
			ShowSettings(0);
			ShowGlobalSettings();
			}
		else if (tolower(argv[2][0]) == 'g')
			ShowGlobalSettings();
        else if (tolower(argv[2][0]) == 'a') {
            int device = (argc == 3) ? 0 : atoi(argv[3]);
            ShowAccelSettings(device);
            }
		else {
			ShowSettings(atoi(argv[2]));
			ShowGlobalSettings();
			}
		}
	else if (argc >= 3) {
        int     device;
		ibool 	enable = stricmp(argv[2],"on") == 0;

		LoadGlobalOptions();
		if (stricmp(argv[1],"vbe") == 0)
			gOpt.bVBEOnly = enable;
		else if (stricmp(argv[1],"vga") == 0)
			gOpt.bVGAOnly = enable;
		else if (stricmp(argv[1],"noncert") == 0)
			gOpt.bAllowNonCertified = enable;
		else if (stricmp(argv[1],"nowcomb") == 0)
			gOpt.bNoWriteCombine = enable;
		else if (stricmp(argv[1],"noddc") == 0)
			gOpt.bNoDDCDetect = enable;
        else if (stricmp(argv[1],"agpfwrite") == 0)
            gOpt.bAGPFastWrite = enable;
#ifdef SNAP
		else if (stricmp(argv[1],"virtual") == 0) {
			if (enable)
				EnableVirtualMode(argc,argv);
			else
				gOpt.bVirtualDisplay = false;
			}
#endif
		else if (stricmp(argv[1],"lcdusebios") == 0) {
			if (stricmp(argv[2],"auto") == 0)
				gOpt.bLCDUseBIOS = gaLCDUseBIOS_Auto;
			else if (enable)
				gOpt.bLCDUseBIOS = gaLCDUseBIOS_On;
			else
				gOpt.bLCDUseBIOS = gaLCDUseBIOS_Off;
			}
		else if (stricmp(argv[1],"agpmem") == 0) {
			gOpt.dwSharedAGPMemSize = atoi(argv[2]);
            if (gOpt.dwSharedAGPMemSize < 512 || gOpt.dwSharedAGPMemSize > 65536)
                gOpt.dwSharedAGPMemSize = 0;
			}
		else if (stricmp(argv[1],"usesysmem") == 0) {
			gOpt.bUseMemoryDriver = (stricmp(argv[2],"off") != 0);
			gOpt.wSysMemSize = atoi(argv[2]);
			}
		else {
			if (stricmp(argv[1],"accel") == 0) {
                /* Device parameter is always last, and if it is not present
                 * then the device should be zero which is what atoi()
                 * returns for non-number values.
                 */
                device = atoi(argv[argc-1]);
                }
    		else if (stricmp(argv[1],"multihead") == 0) {
                if (argc == 8)
                    device = atoi(argv[7]);
                else
                    device = 0;
                }
            else
                device = (argc == 3) ? 0 : atoi(argv[3]);
			LoadDriver(device);
			if (stricmp(argv[1],"invert") == 0)
				opt.bInvertColors = enable;
			else if (stricmp(argv[1],"portrait") == 0)
				opt.bPortrait = enable;
			else if (stricmp(argv[1],"flipped") == 0)
				opt.bFlipped = enable;
			else if (stricmp(argv[1],"prefer16") == 0)
				opt.bPrefer16bpp = enable;
			else if (stricmp(argv[1],"prefer32") == 0)
				opt.bPrefer32bpp = enable;
			else if (stricmp(argv[1],"accel") == 0)
				SetHardwareAccel(argc,argv);
#ifdef SNAP
    		else if (stricmp(argv[1],"multihead") == 0) {
    			if (enable)
                    EnableMultiHeadMode(argc,argv);
                else
    				opt.bMultiHead = false;
    			}
#endif
			init.SetOptions(&opt);
			GA_saveOptions(dc,&opt);
			ShowSettings(device);
			}
		GA_setGlobalOptions(&gOpt);
		GA_saveGlobalOptions(&gOpt);
		ShowGlobalSettings();
		}
	else
		help();
	if (dc)
		GA_unloadDriver(dc);
	return 0;
}

