/* Dr Geo an interactive geometry software
* (C) Copyright Mark de Does 2003
* (C) Copyright Hilaire Fernandes 2004
* hilaire@ofset.org
*
*
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licences as by published
* by the Free Software Foundation; either version 2; or (at your option)
* any later version
*
* This program is distributed in the hope that it will entertaining,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Publis License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/************************************************************************/
/* */
/* Utility functions for printing. */
/* */
/************************************************************************/
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "drgeo_printer.h"
// #include "appUtilConfig.h"
/************************************************************************/
/* */
/* Find out what printers are available on the system. */
/* */
/* 0) Compare for qsort()ing by name. */
/* 1) BSD/Linux style. */
/* 2) AIX style. ( Thanks to Marc Selis from axi.nl ) */
/* 3) SysV/LPRng style. */
/* */
/* NOTE: Before the CUPS, all commands were tried. Now that CUPS */
/* implements them both on the same machine, the first one that */
/* returns any printers is assumed to return them all. */
/* */
/************************************************************************/
/* 0 */
static int
utilPrinterCompareNames (const void *vpd1, const void *vpd2)
{
const PrintDestination *pd1 = (const PrintDestination *) vpd1;
const PrintDestination *pd2 = (const PrintDestination *) vpd2;
return strcmp (pd1->pdPrinterName, pd2->pdPrinterName);
}
/* 2,3 */
static int
utilPrinterSetLpCommand (PrintDestination * pd, const char *name, int l)
{
pd->pdCommand = (char *) malloc (l + 12);
if (!pd->pdCommand)
{
g_printerr ("No printer command\n");
// LXDEB (l, pd->pdCommand);
return -1;
}
sprintf (pd->pdCommand, "lp -s -d '%s'", name);
pd->pdPrintKind = APPprinterPIPE;
pd->pdPrinterName = (char *) malloc (l + 1);
if (!pd->pdPrinterName)
{
g_printerr ("No printer command\n");
// LXDEB (l, pd->pdPrinterName);
return -1;
}
pd->pdCommandLength = strlen (pd->pdCommand);
pd->pdPercentCount = 0;
strcpy (pd->pdPrinterName, name);
return 0;
}
/* 1 */
static int
utilPrinterGetLprPrinters (const char *command,
int *pDefaultPrinter,
int *pPrinterCount,
PrintDestination ** pDestinations)
{
char scratch[250 + 1];
int l;
FILE *f;
int found = 0;
PrintDestination *fresh;
int count = *pPrinterCount;
const char *defaultPrinterName;
f = popen (command, "r");
if (!f)
{
return 0;
}
while (fgets (scratch, 250, f))
{
l = strlen (scratch);
if (l > 0 && scratch[l - 1] == '\n')
{
scratch[l - 1] = '\0';
}
if (scratch[0] == '\t' || scratch[l - 2] != ':')
{
continue;
}
scratch[l - 2] = '\0';
fresh = (PrintDestination *) realloc (*pDestinations,
(count +
1) * sizeof (PrintDestination));
if (!fresh)
{
g_printerr ("Cannot realloc\n");
// XDEB (fresh);
return -1;
}
*pDestinations = fresh;
fresh += count;
fresh->pdCommand = (char *) malloc (l + 23);
if (!fresh->pdCommand)
{
g_printerr ("No printer command\n");
// LXDEB (l, fresh->pdCommand);
return -1;
}
# if 0
Has the advantage that there is no maximum on the file size.
Has the disadvantage that it does not work on SuSE Linux 6.0
sprintf (fresh->pdCommand, "lpr -r -s -P '%s' '%s'", scratch, "%s");
# else
sprintf (fresh->pdCommand, "lpr -r -P '%s' '%s'", scratch, "%s");
# endif
fresh->pdPrintKind = APPprinterTMPFILE;
fresh->pdPrinterName = strdup (scratch);
if (!fresh->pdPrinterName)
{
g_printerr ("No printer command\n");
// LXDEB (l, fresh->pdPrinterName);
return -1;
}
fresh->pdCommandLength = strlen (fresh->pdCommand);
fresh->pdPercentCount = 1;
found++;
count++;
}
pclose (f);
qsort (*pDestinations, count, sizeof (PrintDestination),
utilPrinterCompareNames);
defaultPrinterName = getenv ("PRINTER");
if (defaultPrinterName)
{
PrintDestination *pd = *pDestinations;
for (l = count - found; l < count; pd++, l++)
{
if (!strcmp (defaultPrinterName, pd->pdPrinterName))
{
*pDefaultPrinter = l;
break;
}
}
}
*pPrinterCount = count;
return found;
}
/* 2 */
static int
utilPrinterGetAixPrinters (const char *command,
int *pDefaultPrinter,
int *pPrinterCount,
PrintDestination ** pDestinations)
{
char scratch[250 + 1];
int l;
FILE *f;
int found = 0;
PrintDestination *fresh;
int count = *pPrinterCount;
const char *defaultPrinterName;
f = popen (command, "r");
if (!f)
{
return 0;
}
if (fgets (scratch, 250, f) && fgets (scratch, 250, f))
{
while (fgets (scratch, 250, f))
{
char *s = strchr (scratch, ' ');
if (!s)
{
continue;
}
*s = '\0';
l = s - scratch;
fresh = (PrintDestination *) realloc (*pDestinations,
(count +
1) *
sizeof (PrintDestination));
if (!fresh)
{
g_printerr ("fresh is null\n");
//XDEB (fresh);
return -1;
}
*pDestinations = fresh;
if (utilPrinterSetLpCommand (fresh + count, scratch, l))
{
g_printerr ("Can not set printer command\n");
// LDEB (l);
return -1;
}
found++;
count++;
}
}
pclose (f);
qsort (*pDestinations, count, sizeof (PrintDestination),
utilPrinterCompareNames);
defaultPrinterName = getenv ("LPDEST");
if (defaultPrinterName)
{
PrintDestination *pd = *pDestinations;
for (l = count - found; l < count; pd++, l++)
{
if (!strcmp (defaultPrinterName, pd->pdPrinterName))
{
*pDefaultPrinter = l;
break;
}
}
}
*pPrinterCount = count;
return found;
}
/* 3 */
static int
utilPrinterGetLpPrinters (const char *command,
int *pDefaultPrinter,
int *pPrinterCount,
PrintDestination ** pDestinations)
{
char scratch[250 + 1];
int l;
FILE *f;
int found = 0;
PrintDestination *fresh;
int count = *pPrinterCount;
const char *defaultPrinterName;
/* 2 */
f = popen (command, "r");
if (!f)
{
return 0;
}
while (fgets (scratch, 250, f))
{
char *s = strchr (scratch, ' ');
if (!s)
{
continue;
}
*s = '\0';
l = s - scratch;
fresh = (PrintDestination *) realloc (*pDestinations,
(count +
1) * sizeof (PrintDestination));
if (!fresh)
{
g_printerr ("fresh is null\n");
// XDEB (fresh);
return -1;
}
*pDestinations = fresh;
if (utilPrinterSetLpCommand (fresh + count, scratch, l))
{
g_printerr ("Can not set printer command\n");
// LDEB (l);
return -1;
}
found++;
count++;
}
pclose (f);
qsort (*pDestinations, count, sizeof (PrintDestination),
utilPrinterCompareNames);
defaultPrinterName = getenv ("LPDEST");
if (defaultPrinterName)
{
PrintDestination *pd = *pDestinations;
for (l = count - found; l < count; pd++, l++)
{
if (!strcmp (defaultPrinterName, pd->pdPrinterName))
{
*pDefaultPrinter = l;
break;
}
}
}
*pPrinterCount = count;
return found;
}
int
utilPrinterGetPrinters (int *pPrinterCount,
int *pDefaultPrinter,
PrintDestination ** pDestinations,
const char *customCommand, const char *customName)
{
PrintDestination *pd = (PrintDestination *) 0;
int count = 0;
int defaultPrinter = -1;
/* 1 */
if (count == 0)
{
utilPrinterGetLprPrinters ("( lpc status ) 2>/dev/null",
&defaultPrinter, &count, &pd);
}
/* 1b */
if (count == 0)
{
utilPrinterGetLprPrinters ("( /usr/sbin/lpc status ) 2>/dev/null",
&defaultPrinter, &count, &pd);
}
/* 2 */
if (count == 0)
{
utilPrinterGetAixPrinters ("( enq -As ) 2>/dev/null",
&defaultPrinter, &count, &pd);
}
/* 3 */
if (count == 0)
{
utilPrinterGetLpPrinters ("( lpstat -a ) 2>/dev/null",
&defaultPrinter, &count, &pd);
}
if (defaultPrinter < 0 && count > 0)
{
defaultPrinter = 0;
}
if (customName || customCommand)
{
if (!customName)
{
g_printerr ("No custom\n");
// XXDEB (customName, customCommand);
}
if (!customCommand)
{
g_printerr ("No custom\n");
// XXDEB (customName, customCommand);
}
}
if (customName && customCommand)
{
const char *p;
PrintDestination *fresh;
fresh = (PrintDestination *) realloc (pd,
(count +
1) * sizeof (PrintDestination));
if (!fresh)
{
g_printerr ("fresh is null\n");
// XDEB (fresh);
return -1;
}
pd = fresh;
fresh += count;
fresh->pdCommand = strdup (customCommand);
fresh->pdPrinterName = strdup (customName);
fresh->pdCommandLength = strlen (customCommand);
fresh->pdPercentCount = 0;
p = customCommand;
while (*p)
{
if (p[0] == '%' && p[1] == 'f')
{
fresh->pdPercentCount++;
}
p++;
}
if (fresh->pdPercentCount > 0)
{
fresh->pdPrintKind = APPprinterTMPFILE;
}
else
{
fresh->pdPrintKind = APPprinterPIPE;
}
if (fresh->pdCommand && fresh->pdPrinterName)
{
defaultPrinter = count++;
}
else
{
g_printerr ("No command or printer name\n");
// XXDEB (fresh->pdCommand, fresh->pdPrinterName);
}
}
*pPrinterCount = count;
*pDefaultPrinter = defaultPrinter;
*pDestinations = pd;
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1