#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <locale.h>
#ifdef __hpux
#include <sys/sysmacros.h>
#endif
#include <X11/X.h>
#define NEED_EVENTS 1
#include <X11/Xproto.h>
#include <servermd.h>
#include "screenint.h"
#include "input.h"
#include "cursor.h"
#include "misc.h"
#include "windowstr.h"
#include "inputstr.h"
#include "gcstruct.h"
#include <X11/fonts/fontstruct.h>
#include "errno.h"
typedef char *XPointer;
#define HAVE_XPointer 1
#define Status int
#include <X11/Xresource.h>
#include "DiPrint.h"
#include "attributes.h"
#include "os.h"
#include "spooler.h"
static void GenericScreenInit(
int index,
ScreenPtr pScreen,
int argc,
char **argv);
static Bool InitPrintDrivers(
int index,
ScreenPtr pScreen,
int argc,
char **argv);
#define XNPRINTERSFILEPREFIX "/X"
#define XNPRINTERSFILESUFFIX "printers"
#define XPRINTERSFILENAME "Xprinters"
#define MODELDIRNAME "/models"
#define FONTDIRNAME "/fonts"
#ifdef XPRASTERDDX
static
PixmapFormatRec RasterPixmapFormats[] = {
{ 1, 1, BITMAP_SCANLINE_PAD }
};
#define NUMRASTFORMATS (sizeof RasterPixmapFormats)/(sizeof RasterPixmapFormats[0])
#include "raster/Raster.h"
#endif
#ifdef XPPCLDDX
static
PixmapFormatRec ColorPclPixmapFormats[] = {
{ 1, 1, BITMAP_SCANLINE_PAD },
{ 8, 8, BITMAP_SCANLINE_PAD },
{ 24, 32, BITMAP_SCANLINE_PAD }
};
#define NUMCPCLFORMATS (sizeof ColorPclPixmapFormats)/(sizeof ColorPclPixmapFormats[0])
#endif
#ifdef XPMONOPCLDDX
static
PixmapFormatRec MonoPclPixmapFormats[] = {
{ 1, 1, BITMAP_SCANLINE_PAD }
};
#define NUMMPCLFORMATS (sizeof MonoPclPixmapFormats)/(sizeof MonoPclPixmapFormats[0])
#endif
#if defined(XPPCLDDX) || defined(XPMONOPCLDDX)
#include "pcl/Pcl.h"
#endif
#ifdef XPPSDDX
static
PixmapFormatRec PSPixmapFormats[] = {
{ 1, 1, BITMAP_SCANLINE_PAD },
{ 8, 8, BITMAP_SCANLINE_PAD },
{ 12, 16, BITMAP_SCANLINE_PAD },
{ 14, 16, BITMAP_SCANLINE_PAD },
{ 16, 16, BITMAP_SCANLINE_PAD },
{ 24, 32, BITMAP_SCANLINE_PAD }
};
#define NUMPSFORMATS (sizeof PSPixmapFormats)/(sizeof PSPixmapFormats[0])
#include "ps/Ps.h"
#endif
typedef struct _driverInitRec {
char *driverName;
pBFunc initFunc;
XpValidatePoolsRec *pValRec;
pVFunc dimensionsFunc;
PixmapFormatRec *pFmts;
int numFmts;
} driverInitRec;
static driverInitRec driverInits[] = {
#ifdef XPRASTERDDX
{
"XP-RASTER",
InitializeRasterDriver,
&RasterValidatePoolsRec,
(pVFunc) NULL,
RasterPixmapFormats,
NUMRASTFORMATS
},
#endif
#ifdef XPPCLDDX
{
"XP-PCL-COLOR",
InitializeColorPclDriver,
&PclValidatePoolsRec,
(pVFunc) NULL,
ColorPclPixmapFormats,
NUMCPCLFORMATS
},
#endif
#ifdef XPMONOPCLDDX
{
"XP-PCL-MONO",
InitializeMonoPclDriver,
&PclValidatePoolsRec,
(pVFunc) NULL,
MonoPclPixmapFormats,
NUMMPCLFORMATS
},
#endif
#ifdef XPPSDDX
{
"XP-POSTSCRIPT",
InitializePsDriver,
&PsValidatePoolsRec,
(pVFunc) NULL,
PSPixmapFormats,
NUMPSFORMATS
},
#endif
};
typedef struct _printerDbEntry {
struct _printerDbEntry *next;
char *name;
char *qualifier;
int screenNum;
char *driverName;
char *desc;
} PrinterDbEntry, *PrinterDbPtr;
static PrinterDbPtr printerDb = (PrinterDbPtr)NULL;
typedef struct _nameMapEntry {
struct _nameMapEntry *next;
char *name;
char *qualifier;
} NameMapEntry, *NameMapPtr;
static NameMapPtr nameMap = (NameMapPtr)NULL;
typedef struct _driverMapping {
struct _driverMapping *next;
char *driverName;
int screenNum;
} DriverMapEntry, *DriverMapPtr;
static const char configFilePath[] =
"/etc/dt/config/print:/usr/dt/config/print";
static const char printServerConfigDir[] = "XPSERVERCONFIGDIR";
static char *configFileName = (char *)NULL;
static Bool freeDefaultFontPath = FALSE;
static char *origFontPath = (char *)NULL;
static Bool xprintInitGlobalsCalled = FALSE;
void PrinterInitGlobals(void)
{
xprintInitGlobalsCalled = TRUE;
#ifdef DAMAGE
noDamageExtension = TRUE;
#endif
#ifdef SMART_SCHEDULE
SmartScheduleDisable = TRUE;
#endif
defaultScreenSaverTime = 0;
maxBigRequestSize = (8*1048576)-1;
dispatchExceptionAtReset = 0;
}
void PrinterUseMsg(void)
{
XpSpoolerTypePtr curr = xpstm;
ErrorF("-XpFile file specifies an alternate `Xprinters' file, rather\n");
ErrorF(" than the default one (e.g.\n");
ErrorF(" `${XPCONFIGDIR}/${LANG}/print/Xprinters') or\n");
ErrorF(" `${XPCONFIGDIR}/C/print/Xprinters'.\n");
ErrorF("-XpSpoolerType string specifies a spooler type.\n");
ErrorF(" Supported values are:\n");
while( curr->name != NULL )
{
ErrorF(" - '%s'\n", curr->name);
curr++;
}
ErrorF(" (multiple values can be specified, seperated by ':',\n");
ErrorF(" the first active spooler will be chosen).\n");
ErrorF(" default is '%s'.\n", XPDEFAULTSPOOLERNAMELIST);
}
int
PrinterOptions(
int argc,
char **argv,
int i)
{
if(strcmp(argv[i], "-XpFile") == 0)
{
if ((i + 1) >= argc) {
ddxUseMsg ();
return i + 2;
}
configFileName = argv[i + 1];
return i + 2;
}
else if(strcmp(argv[i], "-XpSpoolerType") == 0)
{
if ((i + 1) >= argc) {
ddxUseMsg ();
return i + 2;
}
XpSetSpoolerTypeNameList(argv[i + 1]);
return i + 2;
}
else
{
return i;
}
}
static pBFunc GetInitFunc(char *driverName)
{
driverInitRec *pInitRec;
int numDrivers = sizeof(driverInits)/sizeof(driverInitRec);
int i;
for(pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++)
{
if( !strcmp( driverName, pInitRec->driverName ) )
return pInitRec->initFunc;
}
return 0;
}
static void
GetDimFuncAndRec(
char *driverName,
XpValidatePoolsRec **pValRec,
pVFunc *dimensionsFunc)
{
driverInitRec *pInitRec;
int numDrivers = sizeof(driverInits)/sizeof(driverInitRec);
int i;
for(pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++)
{
if( !strcmp( driverName, pInitRec->driverName ) )
{
*dimensionsFunc = pInitRec->dimensionsFunc;
*pValRec = pInitRec->pValRec;
return ;
}
}
*dimensionsFunc = 0;
*pValRec = 0;
return;
}
static void
FreePrinterDb(void)
{
PrinterDbPtr pCurEntry, pNextEntry;
for(pCurEntry = printerDb, pNextEntry = (PrinterDbPtr)NULL;
pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pNextEntry)
{
pNextEntry = pCurEntry->next;
if(pCurEntry->name != (char *)NULL)
xfree(pCurEntry->name);
if(pCurEntry->desc != (char *)NULL)
xfree(pCurEntry->desc);
xfree(pCurEntry);
}
printerDb = (PrinterDbPtr)NULL;
}
static Bool
AddPrinterDbName(char *name, char *desc)
{
PrinterDbPtr pEntry = (PrinterDbPtr)xalloc(sizeof(PrinterDbEntry));
if(pEntry == (PrinterDbPtr)NULL) return FALSE;
pEntry->name = (name != NULL) ? strdup(name) : NULL;
pEntry->desc = (desc != NULL) ? strdup(desc) : NULL;
pEntry->qualifier = (char *)NULL;
if(printerDb == (PrinterDbPtr)NULL)
{
pEntry->next = (PrinterDbPtr)NULL;
printerDb = pEntry;
}
else
{
pEntry->next = printerDb;
printerDb = pEntry;
}
return TRUE;
}
static int
AugmentPrinterDb(const char *command)
{
FILE *fp;
char name[256];
int num_printers = 0;
size_t namelen;
char *desc = NULL;
fp = popen(command, "r");
while(fgets(name, 256, fp) != (char *)NULL && (namelen=strlen(name)))
{
char *option = name;
name[namelen-1] = (char)'\0';
#define XP_DESCRIPTOR "xp-printerattr.descriptor="
#define XP_DESCRIPTOR_LEN (sizeof(XP_DESCRIPTOR)-1)
while ((option = strchr(option, '\t'))) {
option++;
if (!strncmp(option, XP_DESCRIPTOR, XP_DESCRIPTOR_LEN)) {
*(option-1) = '\0';
option += XP_DESCRIPTOR_LEN;
if (*option != '\0') {
desc = option;
}
}
else
{
ErrorF("AugmentPrinterDb: Unknown option '%s'\n", option);
}
}
AddPrinterDbName(name, desc);
num_printers++;
}
pclose(fp);
return num_printers;
}
static void
FreeNameMap(void)
{
NameMapPtr pEntry, pTmp;
for(pEntry = nameMap, pTmp = (NameMapPtr)NULL;
pEntry != (NameMapPtr)NULL;
pEntry = pTmp)
{
if(pEntry->name != (char *)NULL)
xfree(pEntry->name);
if(pEntry->qualifier != (char *)NULL)
xfree(pEntry->qualifier);
pTmp = pEntry->next;
xfree(pEntry);
}
nameMap = (NameMapPtr)NULL;
}
static Bool
AddNameMap(char *name, char *qualifier)
{
NameMapPtr pEntry;
if((pEntry = (NameMapPtr)xalloc(sizeof(NameMapEntry))) == (NameMapPtr)NULL)
return FALSE;
pEntry->name = name;
pEntry->qualifier = qualifier;
pEntry->next = nameMap;
nameMap = pEntry;
return TRUE;
}
static void
MergeNameMap(void)
{
NameMapPtr pMap;
PrinterDbPtr pDb;
for(pMap = nameMap; pMap != (NameMapPtr)NULL; pMap = pMap->next)
{
for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
{
if(!strcmp(pMap->name, pDb->name))
{
pDb->qualifier = pMap->qualifier;
pMap->qualifier = (char *)NULL;
}
}
}
}
static void
CreatePrinterAttrs(void)
{
PrinterDbPtr pDb;
for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
{
XpBuildAttributeStore(pDb->name, (pDb->qualifier)?
pDb->qualifier : pDb->name);
}
}
#ifdef XPPSDDX
#define defaultDriver "XP-POSTSCRIPT"
#else
#ifdef XPPCLDDX
#define defaultDriver "XP-PCL-COLOR"
#else
#ifdef XPMONOPCLDDX
#define defaultDriver "XP-PCL-MONO"
#else
#define defaultDriver "XP-RASTER"
#endif
#endif
#endif
static void
StoreDriverNames(void)
{
PrinterDbPtr pEntry;
for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL;
pEntry = pEntry->next)
{
pEntry->driverName = (char*)XpGetPrinterAttribute(pEntry->name,
"xp-ddx-identifier");
if(pEntry->driverName == (char *)NULL ||
strlen(pEntry->driverName) == 0 ||
GetInitFunc(pEntry->driverName) == (Bool(*)())NULL)
{
if (pEntry->driverName && (strlen(pEntry->driverName) != 0)) {
ErrorF("Xp Extension: Can't load driver %s\n",
pEntry->driverName);
ErrorF(" init function missing\n");
}
pEntry->driverName = defaultDriver;
XpAddPrinterAttribute(pEntry->name,
(pEntry->qualifier != (char *)NULL)?
pEntry->qualifier : pEntry->name,
"*xp-ddx-identifier", pEntry->driverName);
}
}
}
static void
StoreDescriptors(void)
{
PrinterDbPtr pEntry;
for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL;
pEntry = pEntry->next)
{
if (pEntry->desc != NULL)
{
XpAddPrinterAttribute(pEntry->name,
(pEntry->qualifier != (char *)NULL)?
pEntry->qualifier : pEntry->name,
"*descriptor", pEntry->desc);
}
}
}
static char *
MbStrchr(
char *str,
int ch)
{
size_t mbCurMax = MB_CUR_MAX;
wchar_t targetChar, curChar;
char tmpChar;
int i, numBytes, byteLen;
if(mbCurMax <= 1) return strchr(str, ch);
tmpChar = (char)ch;
mbtowc(&targetChar, &tmpChar, mbCurMax);
for(i = 0, numBytes = 0, byteLen = strlen(str); i < byteLen; i += numBytes)
{
numBytes = mbtowc(&curChar, &str[i], mbCurMax);
if(curChar == targetChar) return &str[i];
}
return (char *)NULL;
}
static char *
GetConfigFileName(void)
{
char *dirName, *filePath;
if((dirName = XpGetConfigDir(TRUE)))
{
filePath = (char *)xalloc(strlen(dirName) +
strlen(XPRINTERSFILENAME) + 2);
if(filePath == (char *)NULL)
{
xfree(dirName);
return (char *)NULL;
}
sprintf(filePath, "%s/%s", dirName, XPRINTERSFILENAME);
xfree(dirName);
if(access(filePath, R_OK) == 0)
return filePath;
xfree(filePath);
}
if((dirName = XpGetConfigDir(FALSE)))
{
filePath = (char *)xalloc(strlen(dirName) +
strlen(XPRINTERSFILENAME) + 2);
if(filePath == (char *)NULL)
{
xfree(dirName);
return (char *)NULL;
}
sprintf(filePath, "%s/%s", dirName, XPRINTERSFILENAME);
xfree(dirName);
if(access(filePath, R_OK) == 0)
return filePath;
xfree(filePath);
}
return (char *)NULL;
}
static PrinterDbPtr
BuildPrinterDb(void)
{
Bool defaultAugment = TRUE, freeConfigFileName;
if(configFileName && access(configFileName, R_OK) != 0)
{
ErrorF("Xp Extension: Can't open file %s\n", configFileName);
}
if(!configFileName && (configFileName = GetConfigFileName()))
freeConfigFileName = TRUE;
else
freeConfigFileName = FALSE;
if(configFileName != (char *)NULL && access(configFileName, R_OK) == 0)
{
char line[256];
FILE *fp = fopen(configFileName, "r");
while(fgets(line, 256, fp) != (char *)NULL)
{
char *tok, *ptr;
if((tok = strtok(line, " \t\012")) != (char *)NULL)
{
if(tok[0] == (char)'#') continue;
if(strcmp(tok, "Printer") == 0)
{
while((tok = strtok((char *)NULL, " \t")) != (char *)NULL)
{
if((ptr = MbStrchr(tok, '\012')))
*ptr = (char)'\0';
AddPrinterDbName(tok, NULL);
}
}
else if(strcmp(tok, "Map") == 0)
{
char *name, *qualifier;
if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL)
continue;
name = strdup(tok);
if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL)
{
xfree(name);
continue;
}
qualifier = strdup(tok);
AddNameMap(name, qualifier);
}
else if(strcmp(tok, "Augment_Printer_List") == 0)
{
if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL)
continue;
if(strcmp(tok, "%default%") == 0)
continue;
defaultAugment = FALSE;
if(strcmp(tok, "%none%") == 0)
continue;
AugmentPrinterDb(tok);
}
else
break;
}
}
fclose(fp);
}
if(defaultAugment == TRUE)
{
XpSpoolerTypePtr curr_spooler_type;
int num_printers_found;
char *tok_lasts;
char *spnamelist;
char *spname;
spnamelist = strdup(XpGetSpoolerTypeNameList());
for( spname = strtok_r(spnamelist, ":", &tok_lasts) ;
spname != NULL ;
spname = strtok_r(NULL, ":", &tok_lasts) )
{
curr_spooler_type = XpSpoolerNameToXpSpoolerType(spname);
if(!curr_spooler_type)
{
FatalError("BuildPrinterDb: No spooler type entry found for '%s'.\n", spname);
}
if(curr_spooler_type->list_queues_command == NULL ||
strlen(curr_spooler_type->list_queues_command) == 0)
{
continue;
}
num_printers_found = AugmentPrinterDb(curr_spooler_type->list_queues_command);
if(num_printers_found > 0)
{
spooler_type = curr_spooler_type;
#ifdef DEBUG_gisburn
fprintf(stderr, "BuildPrinterDb: using '%s'.\n", spooler_type->name);
#endif
break;
}
}
free(spnamelist);
}
MergeNameMap();
FreeNameMap();
CreatePrinterAttrs();
StoreDriverNames();
StoreDescriptors();
if(freeConfigFileName)
{
xfree(configFileName);
configFileName = (char *)NULL;
}
return printerDb;
}
static void
FreeDriverMap(DriverMapPtr driverMap)
{
DriverMapPtr pCurEntry, pNextEntry;
for(pCurEntry = driverMap, pNextEntry = (DriverMapPtr)NULL;
pCurEntry != (DriverMapPtr)NULL; pCurEntry = pNextEntry)
{
pNextEntry = pCurEntry->next;
if(pCurEntry->driverName != (char *)NULL)
xfree(pCurEntry->driverName);
xfree(pCurEntry);
}
}
int
XpRehashPrinterList(void)
{
PrinterDbPtr pEntry, pPrev;
DriverMapPtr driverMap = (DriverMapPtr)NULL, pDrvEnt;
int result;
for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL; pEntry = pEntry->next)
{
for(pDrvEnt = driverMap; pDrvEnt != (DriverMapPtr)NULL;
pDrvEnt = pDrvEnt->next)
{
if(!strcmp(pEntry->driverName, pDrvEnt->driverName))
break;
}
if(pDrvEnt != (DriverMapPtr)NULL)
continue;
if((pDrvEnt = (DriverMapPtr)xalloc(sizeof(DriverMapEntry))) ==
(DriverMapPtr)NULL)
{
FreeDriverMap(driverMap);
return BadAlloc;
}
pDrvEnt->driverName = strdup(pEntry->driverName);
pDrvEnt->screenNum = pEntry->screenNum;
pDrvEnt->next = driverMap;
driverMap = pDrvEnt;
}
FreePrinterDb();
if((result = XpRehashAttributes()) != Success)
return result;
if(BuildPrinterDb() == (PrinterDbPtr)NULL)
return BadAlloc;
for(pEntry = printerDb, pPrev = (PrinterDbPtr)NULL;
pEntry != (PrinterDbPtr)NULL; pEntry = pEntry->next)
{
for(pDrvEnt = driverMap; pDrvEnt != (DriverMapPtr)NULL;
pDrvEnt = pDrvEnt->next)
{
if(!strcmp(printerDb->driverName, pDrvEnt->driverName))
break;
}
if(pDrvEnt != (DriverMapPtr)NULL)
{
pEntry->screenNum = pDrvEnt->screenNum;
pPrev = pEntry;
}
else {
if(pPrev)
pPrev->next = pEntry->next;
else
pPrev = pEntry->next;
if(pEntry->name != (char *)NULL)
xfree(pEntry->name);
xfree(pEntry);
pEntry = pPrev;
}
}
FreeDriverMap(driverMap);
return Success;
}
static char *
ValidateFontDir(
char *configDir,
char *modelName)
{
char *pathName;
if(!configDir || !modelName)
return (char *)NULL;
pathName = (char *)xalloc(strlen(configDir) + strlen(MODELDIRNAME) +
strlen(modelName) + strlen(FONTDIRNAME) +
strlen("fonts.dir") + 5);
if(!pathName)
return (char *)NULL;
sprintf(pathName, "%s/%s/%s/%s/%s", configDir, MODELDIRNAME, modelName,
FONTDIRNAME, "fonts.dir");
if(access(pathName, R_OK) != 0)
{
xfree(pathName);
return (char *)NULL;
}
pathName[strlen(pathName) - 9] = (char)'\0';
return pathName;
}
static char *
FindFontDir(
char *modelName)
{
char *configDir, *fontDir;
if(!modelName || !strlen(modelName))
return (char *)NULL;
configDir = XpGetConfigDir(TRUE);
if((fontDir = ValidateFontDir(configDir, modelName)))
{
xfree(configDir);
return fontDir;
}
if(configDir)
xfree(configDir);
configDir = XpGetConfigDir(FALSE);
fontDir = ValidateFontDir(configDir, modelName);
xfree(configDir);
return fontDir;
}
static char PATH_PREFIX[] = "PRINTER:";
static int PATH_PREFIX_LEN = sizeof(PATH_PREFIX) - 1;
static void
AddToFontPath(
char *pathName)
{
char *newPath;
Bool freeOldPath;
if(defaultFontPath == origFontPath)
freeOldPath = FALSE;
else
freeOldPath = TRUE;
newPath = (char *)xalloc(strlen(defaultFontPath) + strlen(pathName) +
PATH_PREFIX_LEN + 2);
sprintf(newPath, "%s%s,%s", PATH_PREFIX, pathName, defaultFontPath);
if(freeOldPath)
xfree(defaultFontPath);
defaultFontPath = newPath;
return;
}
static void
AugmentFontPath(void)
{
char *modelID, **allIDs = (char **)NULL;
PrinterDbPtr pDbEntry;
int numModels, i;
if(!origFontPath)
origFontPath = defaultFontPath;
if(freeDefaultFontPath)
{
xfree(defaultFontPath);
defaultFontPath = origFontPath;
freeDefaultFontPath = FALSE;
}
for(pDbEntry = printerDb, numModels = 0;
pDbEntry != (PrinterDbPtr)NULL;
pDbEntry = pDbEntry->next)
{
modelID =
(char*)XpGetPrinterAttribute(pDbEntry->name,
"xp-model-identifier");
if(modelID && strlen(modelID) != 0)
{
for(i = 0; i < numModels; i++)
{
if(!strcmp(modelID, allIDs[i]))
{
modelID = (char *)NULL;
break;
}
}
}
if(modelID && strlen(modelID) != 0)
{
allIDs = (char **)xrealloc(allIDs, (numModels+2) * sizeof(char *));
if(allIDs == (char **)NULL)
return;
allIDs[numModels] = modelID;
allIDs[numModels + 1] = (char *)NULL;
numModels++;
}
}
for(i = 0; allIDs != (char **)NULL && allIDs[i] != (char *)NULL; i ++)
{
char *fontDir;
if((fontDir = FindFontDir(allIDs[i])))
{
AddToFontPath(fontDir);
xfree(fontDir);
freeDefaultFontPath = TRUE;
}
}
if(allIDs)
xfree(allIDs);
return;
}
Bool
XpClientIsBitmapClient(
ClientPtr client)
{
XpContextPtr pContext;
char *mode;
if(!(pContext = XpContextOfClient(client)))
return TRUE;
mode = XpGetOneAttribute(pContext, XPPageAttr, "xp-listfonts-modes");
if(!mode || !strlen(mode))
{
mode = XpGetOneAttribute(pContext, XPDocAttr, "xp-listfonts-modes");
if(!mode || !strlen(mode))
return TRUE;
}
if(!strstr(mode, "xp-list-glyph-fonts"))
return FALSE;
return TRUE;
}
Bool
XpClientIsPrintClient(
ClientPtr client,
FontPathElementPtr fpe)
{
XpContextPtr pContext;
char *mode;
char *modelID, *fontDir;
if(!(pContext = XpContextOfClient(client)))
return FALSE;
mode = XpGetOneAttribute(pContext, XPPageAttr, "xp-listfonts-modes");
if(!mode || !strlen(mode))
{
mode = XpGetOneAttribute(pContext, XPDocAttr, "xp-listfonts-modes");
}
if(mode && strlen(mode))
{
if(!strstr(mode, "xp-list-internal-printer-fonts"))
return FALSE;
}
if (!fpe)
return TRUE;
modelID = XpGetOneAttribute(pContext, XPPrinterAttr, "xp-model-identifier");
if(!modelID || !strlen(modelID))
return FALSE;
if(!(fontDir = FindFontDir(modelID)))
return FALSE;
if(fpe->name_length < PATH_PREFIX_LEN ||
(strlen(fontDir) != (fpe->name_length - PATH_PREFIX_LEN)) ||
strncmp(fontDir, fpe->name + PATH_PREFIX_LEN,
fpe->name_length - PATH_PREFIX_LEN))
{
xfree(fontDir);
return FALSE;
}
xfree(fontDir);
return TRUE;
}
static void
AddFormats(ScreenInfo *pScreenInfo, char *driverName)
{
int i, j;
driverInitRec *pInitRec;
int numDrivers = sizeof(driverInits)/sizeof(driverInitRec);
PixmapFormatRec *formats;
int numfmts;
for (pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++)
{
if ( !strcmp( driverName, pInitRec->driverName ) )
break;
}
if (i >= numDrivers)
return;
formats = pInitRec->pFmts;
numfmts = pInitRec->numFmts;
for (i = 0; i < numfmts && pScreenInfo->numPixmapFormats < MAXFORMATS; i++)
{
for (j = 0; j < pScreenInfo->numPixmapFormats; j++) {
if (pScreenInfo->formats[j].depth == formats[i].depth &&
pScreenInfo->formats[j].bitsPerPixel == formats[i].bitsPerPixel &&
pScreenInfo->formats[j].scanlinePad == formats[i].scanlinePad)
break;
}
if (j == pScreenInfo->numPixmapFormats) {
pScreenInfo->formats[j] = formats[i];
pScreenInfo->numPixmapFormats++;
}
}
}
void
PrinterInitOutput(
ScreenInfo *pScreenInfo,
int argc,
char **argv)
{
PrinterDbPtr pDb, pDbEntry;
int driverCount = 0, i;
char **driverNames;
char *configDir;
if( !xprintInitGlobalsCalled )
{
FatalError("Internal error: PrinterInitGlobals() not called.");
}
#ifdef SMART_SCHEDULE
if( SmartScheduleDisable != TRUE )
{
FatalError("Internal error: XF86 smart scheduler incompatible to Xprint DDX.");
}
#endif
if( defaultScreenSaverTime != 0 )
{
FatalError("Internal screen saver must be OFF for printing.");
}
if (maxBigRequestSize < (8*1048576)-1) {
ErrorF("Xp Extension: BIGREQUESTS max. request is currently %ld bytes "
", recommemded minimum for Xprint is 8MB.\n", (long)maxBigRequestSize);
}
if (((configDir = XpGetConfigDir(TRUE)) != NULL) &&
(access(configDir, F_OK) == 0))
{
xfree(configDir);
}
else if (((configDir = XpGetConfigDir(FALSE)) != NULL) &&
(access(configDir, F_OK) == 0))
{
xfree(configDir);
}
else {
FatalError("Xp Extension: could not find config dir %s\n",
configDir ? configDir : XPRINTDIR);
}
if(printerDb != (PrinterDbPtr)NULL)
FreePrinterDb();
if((pDb = BuildPrinterDb()) == (PrinterDbPtr)NULL) return;
for(pDbEntry = pDb, driverCount = 0; pDbEntry != (PrinterDbPtr)NULL;
pDbEntry = pDbEntry->next, driverCount++)
;
driverNames = (char **)xalloc(sizeof(char *) * driverCount);
pDb->screenNum = screenInfo.numScreens;
driverNames[0] = pDb->driverName;
driverCount = 1;
AddFormats(pScreenInfo, pDb->driverName);
for(pDbEntry = pDb; pDbEntry != (PrinterDbPtr)NULL;
pDbEntry = pDbEntry->next)
{
Bool foundMatch;
for(i = 0, foundMatch = FALSE; i < driverCount; i++)
{
if(!strcmp(driverNames[i], pDbEntry->driverName))
{
foundMatch = TRUE;
pDbEntry->screenNum = screenInfo.numScreens + i;
break;
}
}
if(foundMatch == FALSE)
{
driverNames[driverCount] = pDbEntry->driverName;
pDbEntry->screenNum = screenInfo.numScreens + driverCount;
AddFormats(pScreenInfo, pDbEntry->driverName);
driverCount++;
}
}
for(i = 0; i < driverCount; i++)
{
int curScreen = screenInfo.numScreens;
if(AddScreen(InitPrintDrivers, argc, argv) < 0)
{
PrinterDbPtr pPrev;
ErrorF("Xp Extension: Could not add screen for driver %s\n",
driverNames[i]);
for(pPrev = pDbEntry = printerDb; pDbEntry != (PrinterDbPtr)NULL;
pDbEntry = pDbEntry->next)
{
if(pDbEntry->screenNum == curScreen)
{
if(pPrev == printerDb)
{
printerDb = pDbEntry->next;
pPrev = printerDb;
}
else
pPrev->next = pDbEntry->next;
xfree(pDbEntry->name);
xfree(pDbEntry);
pDbEntry = pPrev;
}
else
{
if(pDbEntry->screenNum > curScreen)
pDbEntry->screenNum--;
pPrev = pDbEntry;
}
}
}
}
xfree(driverNames);
AugmentFontPath();
if(pScreenInfo->numScreens > MAXSCREENS)
{
ErrorF("The number of printer screens requested ");
ErrorF("exceeds the allowable limit of %d screens.\n", MAXSCREENS);
ErrorF("Please reduce the number of requested printers in your ");
ErrorF("\nX%sprinters file.", display);
ErrorF("Server exiting...\n");
exit(-1);
}
}
static Bool
InitPrintDrivers(
int index,
ScreenPtr pScreen,
int argc,
char **argv)
{
PrinterDbPtr pDb, pDb2;
GenericScreenInit(index, pScreen, argc, argv);
for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
{
if(pDb->screenNum == index)
{
Bool callInit = TRUE;
for(pDb2 = printerDb; pDb2 != pDb; pDb2 = pDb2->next)
{
if(!strcmp(pDb->driverName, pDb2->driverName))
{
callInit = FALSE;
break;
}
}
if(callInit == TRUE)
{
Bool (*initFunc)(BFuncArgs);
initFunc = GetInitFunc(pDb->driverName);
if(initFunc(index, pScreen, argc, argv) == FALSE)
{
}
}
}
}
return TRUE;
}
void
_XpVoidNoop(void)
{
return;
}
Bool
_XpBoolNoop(void)
{
return TRUE;
}
static void
GenericScreenInit(
int index,
ScreenPtr pScreen,
int argc,
char **argv)
{
float fWidth, fHeight, maxWidth, maxHeight;
unsigned short width, height;
PrinterDbPtr pDb;
int res, maxRes;
pScreen->DisplayCursor = (DisplayCursorProcPtr)_XpBoolNoop;
pScreen->RealizeCursor = (RealizeCursorProcPtr)_XpBoolNoop;
pScreen->UnrealizeCursor = (UnrealizeCursorProcPtr)_XpBoolNoop;
pScreen->SetCursorPosition = (SetCursorPositionProcPtr)_XpBoolNoop;
pScreen->ConstrainCursor = (ConstrainCursorProcPtr)_XpVoidNoop;
pScreen->CursorLimits = (CursorLimitsProcPtr)_XpVoidNoop;
pScreen->RecolorCursor = (RecolorCursorProcPtr)_XpVoidNoop;
maxRes = 0;
maxWidth = maxHeight = 0.0;
for( pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
{
if(pDb->screenNum == index)
{
XpValidatePoolsRec *pValRec;
pVFunc dimensionsFunc;
GetDimFuncAndRec(pDb->driverName, &pValRec, &dimensionsFunc);
if(dimensionsFunc != (pVFunc)NULL)
dimensionsFunc(pDb->name, pValRec, &fWidth, &fHeight, &res);
else
XpGetMaxWidthHeightRes(pDb->name, pValRec, &fWidth,
&fHeight, &res);
if( res > maxRes )
maxRes = res;
if( fWidth > maxWidth )
maxWidth = fWidth;
if( fHeight > maxHeight )
maxHeight = fHeight;
}
}
width = (unsigned short) (maxWidth * maxRes / 25.4);
height = (unsigned short) (maxHeight * maxRes / 25.4);
pScreen->width = pScreen->height = ( width > height ) ? width :
height;
pScreen->mmWidth = pScreen->mmHeight = ( maxWidth > maxHeight ) ?
(unsigned short)(maxWidth + 0.5) :
(unsigned short)(maxHeight + 0.5);
}
#if 0
static char *
QualifyName(char *fileName, char *searchPath)
{
char * curPath = searchPath;
char * nextPath;
char * chance;
FILE *pFile;
if (fileName == NULL || searchPath == NULL)
return NULL;
while (1) {
if ((nextPath = strchr(curPath, ':')) != NULL)
*nextPath = 0;
chance = (char *)xalloc(strlen(curPath) + strlen(fileName) + 2);
sprintf(chance,"%s/%s",curPath,fileName);
if((pFile = fopen(chance, "r")) != (FILE *)NULL)
{
fclose(pFile);
if (nextPath)
*nextPath = ':';
return chance;
}
xfree(chance);
if (nextPath == NULL)
break;
curPath = nextPath + 1;
}
return NULL;
}
#endif
static void
FillPrinterListEntry(
XpDiListEntry *pEntry,
PrinterDbPtr pDb,
int localeLen,
char *locale)
{
static char *localeStr = (char *)NULL;
if(localeStr == (char *)NULL)
localeStr = strdup(setlocale(LC_ALL, (const char *)NULL));
pEntry->name = pDb->name;
pEntry->description =
(char*)XpGetPrinterAttribute(pDb->name, "descriptor");
pEntry->localeName = localeStr;
pEntry->rootWinId = WindowTable[pDb->screenNum]->drawable.id;
}
static Bool
GetPrinterListInfo(
XpDiListEntry *pEntry,
int nameLen,
char *name,
int localeLen,
char *locale)
{
PrinterDbPtr pDb;
for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
{
if(strlen(pDb->name) == nameLen && !strncmp(pDb->name, name, nameLen))
{
FillPrinterListEntry(pEntry, pDb, localeLen, locale);
return TRUE;
}
}
return FALSE;
}
void
XpDiFreePrinterList(XpDiListEntry **list)
{
int i;
for(i = 0; list[i] != (XpDiListEntry *)NULL; i++)
xfree(list[i]);
xfree(list);
}
XpDiListEntry **
XpDiGetPrinterList(
int nameLen,
char *name,
int localeLen,
char *locale)
{
XpDiListEntry **pList;
if(!nameLen || name == (char *)NULL)
{
int i;
PrinterDbPtr pDb;
for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL;
pDb = pDb->next, i++)
;
if((pList = (XpDiListEntry **)xalloc((i+1) * sizeof(XpDiListEntry *)))
== (XpDiListEntry **)NULL)
return pList;
pList[i] = (XpDiListEntry *)NULL;
for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL;
pDb = pDb->next, i++)
{
if((pList[i] = (XpDiListEntry *)xalloc(sizeof(XpDiListEntry)))==
(XpDiListEntry *)NULL)
{
XpDiFreePrinterList(pList);
return (XpDiListEntry **)NULL;
}
FillPrinterListEntry(pList[i], pDb, localeLen, locale);
}
}
else
{
if((pList = (XpDiListEntry **)xalloc(2 * sizeof(XpDiListEntry *))) ==
(XpDiListEntry **)NULL)
return pList;
if((pList[0] = (XpDiListEntry *)xalloc(sizeof(XpDiListEntry))) ==
(XpDiListEntry *)NULL)
{
xfree(pList);
return (XpDiListEntry **)NULL;
}
pList[1] = (XpDiListEntry *)NULL;
if(GetPrinterListInfo(pList[0], nameLen, name, localeLen, locale) ==
FALSE)
{
xfree(pList[0]);
pList[0] = (XpDiListEntry *)NULL;
}
}
return pList;
}
WindowPtr
XpDiValidatePrinter(char *printerName, int printerNameLen)
{
PrinterDbPtr pCurEntry;
for(pCurEntry = printerDb;
pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next)
{
if(strlen(pCurEntry->name) == printerNameLen &&
!strncmp(pCurEntry->name, printerName, printerNameLen))
return WindowTable[pCurEntry->screenNum];
}
return (WindowPtr)NULL;
}
char *
XpDiGetDriverName(int index, char *printerName)
{
PrinterDbPtr pCurEntry;
for(pCurEntry = printerDb;
pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next)
{
if(pCurEntry->screenNum == index &&
!strcmp(pCurEntry->name, printerName))
return pCurEntry->driverName;
}
return (char *)NULL;
}