DEVINFO.C

/****************************************************************************/ 
/* */
/* Copyright (C) 1987-1996 Microsoft Corp. */
/* All Rights Reserved */
/* */
/****************************************************************************/
/****************************** Module Header *******************************
* Module Name: devinfo.c
*
* Contains routines for manipulating the linked list of known target
* devices for icons and cursors.
*
* History:
*
****************************************************************************/

#include "imagedit.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


STATICFN VOID ProcessDeviceSection(INT iType);
STATICFN BOOL ParseDeviceLine(PSTR pszLine, PINT pnColors, PINT pcx,
PINT pcy);



/************************************************************************
* InitDeviceList
*
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID InitDeviceList(VOID)
{
/*
* Allocate the standard icon devices.
*/
DeviceLinkAlloc(FT_ICON, ids(IDS_ICONDEVNAMEEGAVGA), 16, 32, 32);
DeviceLinkAlloc(FT_ICON, ids(IDS_ICONDEVNAMEMONO), 2, 32, 32);
DeviceLinkAlloc(FT_ICON, ids(IDS_ICONDEVNAMECGA), 2, 32, 16);

ProcessDeviceSection(FT_ICON);

/*
* Allocate the standard cursor devices.
*/
DeviceLinkAlloc(FT_CURSOR, ids(IDS_CURDEVNAMEVGAMONO), 2, 32, 32);
DeviceLinkAlloc(FT_CURSOR, ids(IDS_CURDEVNAMEVGACOLOR), 16, 32, 32);

ProcessDeviceSection(FT_CURSOR);
}



/************************************************************************
* ProcessDeviceSection
*
*
*
* Arguments:
*
* History:
*
************************************************************************/

STATICFN VOID ProcessDeviceSection(
INT iType)
{
PSTR pszSectionName;
CHAR szValueBuf[CCHTEXTMAX];
CHAR szKeyNameBuf[CCHTEXTMAX];
PSTR pszKeyName;
INT nColors;
INT cx;
INT cy;

if (iType == FT_ICON) {
pszSectionName = ids(IDS_ICONINISECTION);
}
else {
pszSectionName = ids(IDS_CURSORINISECTION);
}

if (!GetPrivateProfileString(pszSectionName, NULL, "",
szKeyNameBuf, sizeof(szKeyNameBuf), ids(IDS_IMAGEDITINI)))
return;

pszKeyName = szKeyNameBuf;
while (*pszKeyName) {
if (GetPrivateProfileString(pszSectionName, pszKeyName, "",
szValueBuf, sizeof(szValueBuf), ids(IDS_IMAGEDITINI))) {
if (ParseDeviceLine(szValueBuf, &nColors, &cx, &cy))
DeviceLinkAlloc(iType, pszKeyName, nColors, cx, cy);
}

pszKeyName += strlen(pszKeyName) + 1;
}
}



/************************************************************************
* ParseDeviceLine
*
*
*
* Arguments:
*
* History:
*
************************************************************************/

STATICFN BOOL ParseDeviceLine(
PSTR pszLine,
PINT pnColors,
PINT pcx,
PINT pcy)
{
static CHAR szSep[] = " ,";
PSTR pstr;

if (!(pstr = strtok(pszLine, szSep)))
return FALSE;

*pnColors = atoi(pstr);

if (!(pstr = strtok(NULL, szSep)))
return FALSE;

*pcx = atoi(pstr);

if (!(pstr = strtok(NULL, szSep)))
return FALSE;

*pcy = atoi(pstr);

return TRUE;
}



/************************************************************************
* DeviceLinkAlloc
*
* Allocates a DEVICE structure, initializes it with the given values
* and adds it to the appropriate linked list. Because these are
* specified only at init time, there is no need to ever free them.
*
* There is a special case if the image type is FT_BITMAP. Because
* there is only one type of bitmap image device at any one time,
* this routine does not really allocate a link for these. Instead,
* it uses a static structure for bitmaps. It will be set to the
* given values and a pointer to it will be returned. This means
* that for bitmaps, this function must be called every time that
* the current bitmap image changes to set up the proper values in
* the structure.
*
* Arguments:
* INT iType - Type of image. FT_* constant.
* PSTR pszName - Device name ("VGA", for example).
* INT nColors - Number of colors.
* INT cx - Width of image.
* INT cy - Height of image.
*
* History:
*
************************************************************************/

PDEVICE DeviceLinkAlloc(
INT iType,
PSTR pszName,
INT nColors,
INT cx,
INT cy)
{
static DEVICE DeviceBitmap; // Device structure for bitmaps.
PDEVICE pDevice;
PDEVICE pDeviceT;
PDEVICE *ppDeviceHead;

/*
* Currently we only support 1 and 4 plane devices.
*/
if (nColors != 2 && nColors != 16) {
Message(MSG_BADDEVICECOLORS);
return NULL;
}

/*
* There is a limit to the size of image we will edit. For icons
* and cursors, the field that carries the dimensions is a byte,
* so the size cannot be greater than 256. This is also what
* we limit bitmaps to.
*/
if (cx < 1 || cx > MAXIMAGEDIM || cy < 1 || cy > MAXIMAGEDIM) {
Message(MSG_BADDEVICESIZE, MAXIMAGEDIM);
return NULL;
}

/*
* For bitmaps, don't really allocate a link, just reuse the
* static DEVICE structure used for bitmaps.
*/
if (iType == FT_BITMAP) {
pDevice = &DeviceBitmap;
}
else {
if (!(pDevice = (PDEVICE)MyAlloc(sizeof(DEVICE))))
return NULL;

switch (iType) {
case FT_ICON:
ppDeviceHead = &gpIconDeviceHead;
gnIconDevices++;
break;

case FT_CURSOR:
ppDeviceHead = &gpCursorDeviceHead;
gnCursorDevices++;
break;
}
}

pDevice->pDeviceNext = NULL;
pDevice->iType = iType;
pDevice->nColors = nColors;
pDevice->cx = cx;
pDevice->cy = cy;

if (pszName) {
strcpy(pDevice->szName, pszName);
wsprintf(pDevice->szDesc, "%s %d-Color %dx%d", // hardcoded strings!
(LPSTR)pszName, nColors, cx, cy);
}
else {
*pDevice->szName = '\0';
wsprintf(pDevice->szDesc, "%d-Color %dx%d", nColors, cx, cy);
}

/*
* Because there is only one bitmap link, there is no need
* for a list for these, only icons and cursors.
*/
if (iType != FT_BITMAP) {
/*
* Insert the link in the specified list.
*/
if (!(*ppDeviceHead)) {
/*
* This is the first one. Start the list.
*/
*ppDeviceHead = pDevice;
}
else {
/*
* Find the end of the list and tack on the new link.
*/
for (pDeviceT = *ppDeviceHead; pDeviceT->pDeviceNext;
pDeviceT = pDeviceT->pDeviceNext)
;

pDeviceT->pDeviceNext = pDevice;
}
}

return pDevice;
}



/************************************************************************
* DeviceLinkFind
*
*
*
* Arguments:
*
* History:
*
************************************************************************/

PDEVICE DeviceLinkFind(
PDEVICE pDeviceHead,
INT nColors,
INT cx,
INT cy)
{
PDEVICE pDevice;

/*
* Search the specified list.
*/
for (pDevice = pDeviceHead; pDevice; pDevice = pDevice->pDeviceNext) {
/*
* Is this a match?
*/
if (pDevice->nColors == nColors && pDevice->cx == cx &&
pDevice->cy == cy)
break;
}

return pDevice;
}



/************************************************************************
* DeviceLinkUsed
*
* This function returns TRUE if the specified device is used in
* the current image list.
*
* Arguments:
* PDEVICE pDevice - Device to look for.
*
* History:
*
************************************************************************/

BOOL DeviceLinkUsed(
PDEVICE pDevice)
{
PIMAGEINFO pImage;

for (pImage = gpImageHead; pImage; pImage = pImage->pImageNext) {
if (pImage->pDevice == pDevice)
return TRUE;
}

return FALSE;
}