diff options
Diffstat (limited to 'Xprint/Init.c')
-rw-r--r-- | Xprint/Init.c | 387 |
1 files changed, 298 insertions, 89 deletions
diff --git a/Xprint/Init.c b/Xprint/Init.c index 0deafda7c..cd16847ee 100644 --- a/Xprint/Init.c +++ b/Xprint/Init.c @@ -2,11 +2,12 @@ /* (c) Copyright 1996 Hewlett-Packard Company (c) Copyright 1996 International Business Machines Corp. -(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996-2004 Sun Microsystems, Inc. (c) Copyright 1996 Novell, Inc. (c) Copyright 1996 Digital Equipment Corp. (c) Copyright 1996 Fujitsu Limited (c) Copyright 1996 Hitachi, Ltd. +(c) Copyright 2003-2004 Roland Mainz <roland.mainz@nrubsig.org> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -50,7 +51,6 @@ copyright holders. ** ********************************************************* ** ********************************************************************/ -/* $XFree86: xc/programs/Xserver/Xprint/Init.c,v 1.14tsi Exp $ */ #include <unistd.h> #include <stdlib.h> @@ -91,6 +91,7 @@ typedef char *XPointer; #include "attributes.h" #include "os.h" +#include "spooler.h" static void GenericScreenInit( int index, @@ -116,57 +117,6 @@ static Bool InitPrintDrivers( #define MODELDIRNAME "/models" #define FONTDIRNAME "/fonts" -/* - * The string LIST_QUEUES is fed to a shell to generate an ordered - * list of available printers on the system. These string definitions - * are taken from the file PrintSubSys.C within the code for the - * dtprintinfo program. - */ -#ifdef AIXV4 -const char *LIST_QUEUES = "lsallq | grep -v '^bsh$' | sort"; -#else -#ifdef hpux -const char *LIST_QUEUES = "LANG=C lpstat -v | " - "awk '" - " $2 == \"for\" " - " { " - " x = match($3, /:/); " - " print substr($3, 1, x-1)" - " }' | sort"; -#else -#ifdef __osf__ - const char *LIST_QUEUES = "LANG=C lpstat -v | " - "nawk '" - " $2 == \"for\" " - " { print $4 }' " - " | sort"; -#else -#ifdef __uxp__ -const char *LIST_QUEUES = "LANG=C lpstat -v | " - "nawk '" - " $4 == \"for\" " - " { " - " x = match($5, /:/); " - " print substr($5, 1, x-1)" - " }' | sort"; -#else -#if defined(CSRG_BASED) || defined(linux) || defined(ISC) || defined(__GNUC__) -const char *LIST_QUEUES = "LANG=C lpc status | grep -v '^\t' | " - "sed -e /:/s/// | sort"; -#else -const char *LIST_QUEUES = "LANG=C lpstat -v | " - "nawk '" - " $2 == \"for\" " - " { " - " x = match($3, /:/); " - " print substr($3, 1, x-1)" - " }' | sort"; -#endif -#endif -#endif -#endif -#endif - #ifdef XPRASTERDDX static @@ -183,9 +133,9 @@ PixmapFormatRec RasterPixmapFormats[] = { static PixmapFormatRec ColorPclPixmapFormats[] = { - { 1, 1, BITMAP_SCANLINE_PAD }, - { 8, 8, BITMAP_SCANLINE_PAD }, - { 24,32, BITMAP_SCANLINE_PAD } + { 1, 1, BITMAP_SCANLINE_PAD }, + { 8, 8, BITMAP_SCANLINE_PAD }, + { 24, 32, BITMAP_SCANLINE_PAD } }; #define NUMCPCLFORMATS (sizeof ColorPclPixmapFormats)/(sizeof ColorPclPixmapFormats[0]) @@ -211,9 +161,9 @@ PixmapFormatRec MonoPclPixmapFormats[] = { static PixmapFormatRec PSPixmapFormats[] = { - { 1, 1, BITMAP_SCANLINE_PAD }, - { 8, 8, BITMAP_SCANLINE_PAD }, - { 24,32, BITMAP_SCANLINE_PAD } + { 1, 1, BITMAP_SCANLINE_PAD }, + { 8, 8, BITMAP_SCANLINE_PAD }, + { 24, 32, BITMAP_SCANLINE_PAD } }; #define NUMPSFORMATS (sizeof PSPixmapFormats)/(sizeof PSPixmapFormats[0]) @@ -296,6 +246,7 @@ typedef struct _printerDbEntry { char *qualifier; int screenNum; char *driverName; + char *desc; } PrinterDbEntry, *PrinterDbPtr; static PrinterDbPtr printerDb = (PrinterDbPtr)NULL; @@ -325,10 +276,82 @@ typedef struct _driverMapping { int screenNum; } DriverMapEntry, *DriverMapPtr; +static const char configFilePath[] = +"/etc/dt/config/print:/usr/dt/config/print"; + +static const char printServerConfigDir[] = "XPSERVERCONFIGDIR"; + +static int printScreenPrivIndex, + printWindowPrivIndex, + printGCPrivIndex; +static unsigned long printGeneration = 0; static char *configFileName = (char *)NULL; static Bool freeDefaultFontPath = FALSE; static char *origFontPath = (char *)NULL; +static Bool xprintInitGlobalsCalled = FALSE; +/* + * This function is responsible for doing initalisation of any global + * variables at an very early point of server startup (even before + * |ProcessCommandLine()|. + */ +void XprintInitGlobals(void) +{ + extern char dispatchExceptionAtReset; /* defined in Xserver/dix/dispatch.c */ + + xprintInitGlobalsCalled = TRUE; + +#ifdef SMART_SCHEDULE + /* Somehow the XF86 "smart scheduler" completely kills the Xprint DDX + * (see http://xprint.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=467 + * ("Xfree86's "smart scheduler" breaks Xprt") */ + SmartScheduleDisable = TRUE; +#endif /* SMART_SCHEDULE */ + + /* Disable internal screensaver for Xprint (workaround for + * http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=567 ("Xorg + * Xprt starts to consume 100% CPU when being idle for some time")) */ + defaultScreenSaverTime = 0; + + /* Ensure that the maximum request size for the BIGREQUESTS extension + * is at least 8MB (see + * http://xprint.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=622 - "RFE: + * Xprt's default BIGREQUESTS extension buffer size should be 8MB") + */ + maxBigRequestSize = (8*1048576)-1; + + /* Xprt should not reset by default when the last client exists + * (default for Xprt is |0|, video Xservers use |DE_RESET|) */ + dispatchExceptionAtReset = 0; +} + +/* + * XprintUseMsg() prints usage for the Xprint-specific options + */ +void XprintUseMsg() +{ + XpSpoolerTypePtr curr = xpstm; + + /* Option '-XpFile' */ + 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"); + + /* Option '-XpSpoolerType' */ + 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); +} + /* * XprintOptions checks argv[i] to see if it is our command line * option specifying a configuration file name. It returns the index @@ -340,6 +363,7 @@ XprintOptions( char **argv, int i) { + extern void ddxUseMsg(); if(strcmp(argv[i], "-XpFile") == 0) { if ((i + 1) >= argc) { @@ -349,8 +373,19 @@ XprintOptions( 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; + } } /************************************************************ @@ -417,19 +452,21 @@ FreePrinterDb(void) { PrinterDbPtr pCurEntry, pNextEntry; - for(pCurEntry = printerDb, pNextEntry = 0; + 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); /* * We don't free the driver name, because it's expected to simply * be a pointer into the xrm database. */ xfree(pCurEntry); } - printerDb = 0; + printerDb = (PrinterDbPtr)NULL; } /* @@ -439,12 +476,13 @@ FreePrinterDb(void) * XXX AddPrinterDbName needs to check for (and not add) duplicate names. */ static Bool -AddPrinterDbName(char *name) +AddPrinterDbName(char *name, char *desc) { PrinterDbPtr pEntry = (PrinterDbPtr)xalloc(sizeof(PrinterDbEntry)); if(pEntry == (PrinterDbPtr)NULL) return FALSE; - pEntry->name = strdup(name); + pEntry->name = (name != NULL) ? strdup(name) : NULL; + pEntry->desc = (desc != NULL) ? strdup(desc) : NULL; pEntry->qualifier = (char *)NULL; if(printerDb == (PrinterDbPtr)NULL) @@ -460,20 +498,45 @@ AddPrinterDbName(char *name) return TRUE; } -static void +static int AugmentPrinterDb(const char *command) { FILE *fp; char name[256]; + int num_printers = 0; /* Number of printers we found */ + size_t namelen; + char *desc = NULL; fp = popen(command, "r"); /* XXX is a 256 character limit overly restrictive for printer names? */ - while(fgets(name, 256, fp) != (char *)NULL && strlen(name)) + while(fgets(name, 256, fp) != (char *)NULL && (namelen=strlen(name))) { - name[strlen(name) - 1] = (char)'\0'; /* strip the \n */ - AddPrinterDbName(name); + char *option = name; + + name[namelen-1] = (char)'\0'; /* strip the \n */ + +#define XP_DESCRIPTOR "xp-printerattr.descriptor=" +#define XP_DESCRIPTOR_LEN (sizeof(XP_DESCRIPTOR)-1) + while (option = strchr(option, '\t')) { + option++; /* Skip the '\t' */ + if (!strncmp(option, XP_DESCRIPTOR, XP_DESCRIPTOR_LEN)) { + *(option-1) = '\0'; /* Kill the '\t' (only if we found a valid option) */ + option += XP_DESCRIPTOR_LEN; + if (*option != '\0') { + desc = option; + } + } + else + { + /* Unknown option */ + ErrorF("AugmentPrinterDb: Unknown option '%s'\n", option); + } + } + AddPrinterDbName(name, desc); + num_printers++; } pclose(fp); + return num_printers; } /* @@ -592,7 +655,7 @@ StoreDriverNames(void) "xp-ddx-identifier"); if(pEntry->driverName == (char *)NULL || strlen(pEntry->driverName) == 0 || - GetInitFunc(pEntry->driverName) == 0) + GetInitFunc(pEntry->driverName) == (Bool(*)())NULL) { if (pEntry->driverName && (strlen(pEntry->driverName) != 0)) { ErrorF("Xp Extension: Can't load driver %s\n", @@ -609,6 +672,29 @@ StoreDriverNames(void) } } +/* + * StoreDescriptors - queries the attribute store for the descriptor. + * if the descriptor is not in the attribute database, then the descriptor + * from the printerDb is store in the attribute store for the printer. + */ +static void +StoreDescriptors() +{ + 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, @@ -650,7 +736,7 @@ GetConfigFileName(void) /* * Check for a LANG-specific file. */ - if ((dirName = XpGetConfigDir(TRUE)) != 0) + if(dirName = XpGetConfigDir(TRUE)) { filePath = (char *)xalloc(strlen(dirName) + strlen(XPRINTERSFILENAME) + 2); @@ -669,7 +755,7 @@ GetConfigFileName(void) xfree(filePath); } - if ((dirName = XpGetConfigDir(FALSE)) != 0) + if(dirName = XpGetConfigDir(FALSE)) { filePath = (char *)xalloc(strlen(dirName) + strlen(XPRINTERSFILENAME) + 2); @@ -701,6 +787,7 @@ GetConfigFileName(void) static PrinterDbPtr BuildPrinterDb(void) { + char *printerList, *augmentCmd = (char *)NULL; Bool defaultAugment = TRUE, freeConfigFileName; if(configFileName && access(configFileName, R_OK) != 0) @@ -727,9 +814,9 @@ BuildPrinterDb(void) { while((tok = strtok((char *)NULL, " \t")) != (char *)NULL) { - if ((ptr = MbStrchr(tok, '\012')) != 0) + if(ptr = MbStrchr(tok, '\012')) *ptr = (char)'\0'; - AddPrinterDbName(tok); + AddPrinterDbName(tok, NULL); } } else if(strcmp(tok, "Map") == 0) @@ -768,7 +855,43 @@ BuildPrinterDb(void) if(defaultAugment == TRUE) { - AugmentPrinterDb(LIST_QUEUES); + XpSpoolerTypePtr curr_spooler_type; /* spooler we are currently probing for queues */ + int num_printers_found; /* number of printers found by |AugmentPrinterDb()| */ + char *tok_lasts; /* strtok_r() position token */ + char *spnamelist; /* list of spooler names, seperated by ":" */ + char *spname; /* spooler name */ + + spnamelist = strdup(XpGetSpoolerTypeNameList()); /* strtok_r() modifies string so dup' it first */ + + 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); + /* Did we found a spooler which works ? */ + if(num_printers_found > 0) + { + spooler_type = curr_spooler_type; +#ifdef DEBUG_gisburn + fprintf(stderr, "BuildPrinterDb: using '%s'.\n", spooler_type->name); +#endif /* DEBUG_gisburn */ + break; + } + } + + free(spnamelist); } MergeNameMap(); @@ -782,6 +905,7 @@ BuildPrinterDb(void) * in the printerDb */ StoreDriverNames(); + StoreDescriptors(); if(freeConfigFileName) { @@ -951,7 +1075,7 @@ FindFontDir( return (char *)NULL; configDir = XpGetConfigDir(TRUE); - if ((fontDir = ValidateFontDir(configDir, modelName)) != 0) + if(fontDir = ValidateFontDir(configDir, modelName)) { xfree(configDir); return fontDir; @@ -1013,8 +1137,8 @@ AddToFontPath( static void AugmentFontPath(void) { - char *modelID, **allIDs = (char **)NULL; - PrinterDbPtr pDbEntry; + char *newPath, *modelID, **allIDs = (char **)NULL; + PrinterDbPtr pDb, pDbEntry; int numModels, i; if(!origFontPath) @@ -1072,7 +1196,7 @@ AugmentFontPath(void) for(i = 0; allIDs != (char **)NULL && allIDs[i] != (char *)NULL; i ++) { char *fontDir; - if ((fontDir = FindFontDir(allIDs[i])) != 0) + if(fontDir = FindFontDir(allIDs[i])) { AddToFontPath(fontDir); xfree(fontDir); @@ -1162,7 +1286,7 @@ XpClientIsPrintClient( * fpe->name. */ if(fpe->name_length < PATH_PREFIX_LEN || - (strlen(fontDir) != (unsigned)(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)) { @@ -1235,6 +1359,38 @@ PrinterInitOutput( char **driverNames; char *configDir; + /* This should NEVER happen, but... */ + if( !xprintInitGlobalsCalled ) + { + FatalError("Internal error: XprintInitGlobals() not called."); + } +#ifdef SMART_SCHEDULE + /* |XprintInitGlobals| should have set |SmartScheduleDisable| to + * |TRUE| - if not we will trigger this safeguard. */ + if( SmartScheduleDisable != TRUE ) + { + FatalError("Internal error: XF86 smart scheduler incompatible to Xprint DDX."); + } +#endif /* SMART_SCHEDULE */ + /* Safeguard for + * http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=567 ("Xorg + * Xprt starts to consume 100% CPU when being idle for some time") + * |XprintInitGlobals| should have set |defaultScreenSaverTime| to + * |0| - if not we will trigger this trap. */ + if( defaultScreenSaverTime != 0 ) + { + FatalError("Internal screen saver must be OFF for printing."); + } + + /* Print a warnung when the maximum request size of the BIGREQUESTS + * extension is smaller than 8MB (see + * http://xprint.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=622) + */ + if (maxBigRequestSize < (8*1048576)-1) { + ErrorF("Xp Extension: BIGREQUESTS max. request is currently %ld bytes " + ", recommemded minimum for Xprint is 8MB.\n", (long)maxBigRequestSize); + } + /* * this little test is just a warning at startup to make sure * that the config directory exists. @@ -1254,10 +1410,9 @@ PrinterInitOutput( xfree(configDir); } else { - ErrorF("Xp Extension: could not find config dir %s\n", - configDir ? configDir : XPRINTDIR); - - if (configDir) xfree(configDir); + /* Refuse to start when we do not have our config dir... */ + FatalError("Xp Extension: could not find config dir %s\n", + configDir ? configDir : XPRINTDIR); } if(printerDb != (PrinterDbPtr)NULL) @@ -1414,7 +1569,7 @@ InitPrintDrivers( } if(callInit == TRUE) { - pBFunc initFunc; + Bool (*initFunc)(); initFunc = GetInitFunc(pDb->driverName); if(initFunc(index, pScreen, argc, argv) == FALSE) { @@ -1451,9 +1606,10 @@ GenericScreenInit( int argc, char **argv) { + int i; float fWidth, fHeight, maxWidth, maxHeight; unsigned short width, height; - PrinterDbPtr pDb; + PrinterDbPtr pDb, pDb2; int res, maxRes; /* @@ -1477,6 +1633,7 @@ GenericScreenInit( { if(pDb->screenNum == index) { + XpValidatePoolsRec *pValRec; pVFunc dimensionsFunc; @@ -1506,6 +1663,57 @@ GenericScreenInit( } /* + * QualifyName - takes an unqualified file name such as X6printers and + * a colon-separated list of directory path names such as + * /etc/opt/dt:/opt/dt/config. + * + * Returns a fully qualified file path name such as /etc/opt/dt/X6printers. + * The returned value is malloc'd, and the caller is responsible for + * freeing the associated memory. + */ +static char * +QualifyName(fileName, searchPath) + 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); + + /* see if we can read from the file */ + if((pFile = fopen(chance, "r")) != (FILE *)NULL) + { + fclose(pFile); + /* ... restore the colon, .... */ + if (nextPath) + *nextPath = ':'; + + return chance; + } + + xfree(chance); + + if (nextPath == NULL) /* End of path list? */ + break; + + /* try the next path */ + curPath = nextPath + 1; + } + return NULL; +} + +/* * FillPrinterListEntry fills in a single XpDiListEntry element with data * derived from the supplied PrinterDbPtr element. * @@ -1548,12 +1756,11 @@ GetPrinterListInfo( int localeLen, char *locale) { - PrinterDbPtr pDb; + PrinterDbPtr pDb, pDb2; for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next) { - if (strlen(pDb->name) == (unsigned)nameLen - && !strncmp(pDb->name, name, nameLen)) + if(strlen(pDb->name) == nameLen && !strncmp(pDb->name, name, nameLen)) { FillPrinterListEntry(pEntry, pDb, localeLen, locale); return TRUE; @@ -1598,7 +1805,7 @@ XpDiGetPrinterList( if(!nameLen || name == (char *)NULL) { int i; - PrinterDbPtr pDb; + PrinterDbPtr pDb, pDb2; for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL; pDb = pDb->next, i++) @@ -1648,11 +1855,12 @@ WindowPtr XpDiValidatePrinter(char *printerName, int printerNameLen) { PrinterDbPtr pCurEntry; + WindowPtr pWin; for(pCurEntry = printerDb; pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next) { - if(strlen(pCurEntry->name) == (unsigned)printerNameLen && + if(strlen(pCurEntry->name) == printerNameLen && !strncmp(pCurEntry->name, printerName, printerNameLen)) return WindowTable[pCurEntry->screenNum]; } @@ -1680,3 +1888,4 @@ XpDiGetDriverName(int index, char *printerName) return (char *)NULL; /* XXX Should we supply a default driverName? */ } + |