* User-defined destination (and option) support for the Common UNIX
* Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2009 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
#ifdef __APPLE__
static CFArrayRef appleCopyLocations(void);
static CFStringRef appleCopyNetwork(void);
-static char *appleGetDefault(char *name, int namesize);
static char *appleGetPaperSize(char *name, int namesize);
static CFStringRef appleGetPrinter(CFArrayRef locations, CFStringRef network,
CFIndex *locindex);
static char *cups_get_default(const char *filename, char *namebuf,
size_t namesize, const char **instance);
static int cups_get_dests(const char *filename, const char *match_name,
- const char *match_inst, int num_dests,
- cups_dest_t **dests);
+ const char *match_inst, int user_default_set,
+ int num_dests, cups_dest_t **dests);
static int cups_get_sdests(http_t *http, ipp_op_t op, const char *name,
int num_dests, cups_dest_t **dests);
static char *cups_make_string(ipp_attribute_t *attr, char *buffer,
{
int i; /* Looping var */
cups_dest_t *dest; /* Destination pointer */
- cups_dest_t *parent; /* Parent destination */
+ cups_dest_t *parent = NULL; /* Parent destination */
cups_option_t *doption, /* Current destination option */
*poption; /* Current parent option */
char filename[1024]; /* Local ~/.cups/lpoptions file */
const char *defprinter; /* Default printer */
char name[1024], /* Copy of printer name */
- *instance; /* Pointer to instance name */
+ *instance, /* Pointer to instance name */
+ *user_default; /* User default printer */
int num_reals; /* Number of real queues */
cups_dest_t *reals; /* Real queues */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
* Grab the default destination...
*/
-#ifdef __APPLE__
- if ((defprinter = appleGetDefault(name, sizeof(name))) == NULL)
-#endif /* __APPLE__ */
- defprinter = cupsGetDefault2(http);
+ if ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL)
+ defprinter = name;
+ else if ((defprinter = cupsGetDefault2(http)) != NULL)
+ {
+ strlcpy(name, defprinter, sizeof(name));
+ defprinter = name;
+ }
if (defprinter)
{
/*
- * Grab printer and instance name...
+ * Separate printer and instance name...
*/
-#ifdef __APPLE__
- if (name != defprinter)
-#endif /* __APPLE__ */
- strlcpy(name, defprinter, sizeof(name));
-
if ((instance = strchr(name, '/')) != NULL)
*instance++ = '\0';
dest->is_default = 1;
}
else
- {
- /*
- * This initialization of "instance" is unnecessary, but avoids a
- * compiler warning...
- */
-
instance = NULL;
- }
/*
* Load the /etc/cups/lpoptions and ~/.cups/lpoptions files...
*/
snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
- num_dests = cups_get_dests(filename, NULL, NULL, num_dests, dests);
+ num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL,
+ num_dests, dests);
if ((home = getenv("HOME")) != NULL)
{
if (access(filename, 0))
snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
- num_dests = cups_get_dests(filename, NULL, NULL, num_dests, dests);
+ num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL,
+ num_dests, dests);
}
/*
* The returned destination must be freed using @link cupsFreeDests@ with a
* "num_dests" value of 1.
*
- * @since CUPS 1.4@
+ * @since CUPS 1.4/Mac OS X 10.6@
*/
cups_dest_t * /* O - Destination or @code NULL@ */
char filename[1024], /* Path to lpoptions */
defname[256]; /* Default printer name */
const char *home = getenv("HOME"); /* Home directory */
+ int set_as_default = 0; /* Set returned destination as default */
ipp_op_t op = IPP_GET_PRINTER_ATTRIBUTES;
/* IPP operation to get server ops */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
if (!name)
{
- if ((name = getenv("LPDEST")) == NULL)
- if ((name = getenv("PRINTER")) != NULL && !strcmp(name, "lp"))
- name = NULL;
+ set_as_default = 1;
+ name = _cupsUserDefault(defname, sizeof(defname));
if (!name && home)
{
*/
if (!cups_get_sdests(http, op, name, 0, &dest))
- return (NULL);
+ {
+ if (op == CUPS_GET_DEFAULT)
+ return (NULL);
+
+ /*
+ * The default printer from environment variables or from a
+ * configuration file does not exist. Find out the real default.
+ */
+
+ if (!cups_get_sdests(http, CUPS_GET_DEFAULT, name, 0, &dest))
+ return (NULL);
+ }
if (instance)
dest->instance = _cupsStrAlloc(instance);
+ if (set_as_default)
+ dest->is_default = 1;
+
/*
* Then add local options...
*/
snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
- cups_get_dests(filename, name, instance, 1, &dest);
+ cups_get_dests(filename, name, instance, 1, 1, &dest);
if (home)
{
if (access(filename, 0))
snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
- cups_get_dests(filename, name, instance, 1, &dest);
+ cups_get_dests(filename, name, instance, 1, 1, &dest);
}
/*
* Merge in server defaults...
*/
- num_temps = cups_get_dests(filename, NULL, NULL, num_temps, &temps);
+ num_temps = cups_get_dests(filename, NULL, NULL, 0, num_temps, &temps);
/*
* Point to user defaults...
}
+/*
+ * '_cupsUserDefault()' - Get the user default printer from environment
+ * variables and location information.
+ */
+
+char * /* O - Default printer or NULL */
+_cupsUserDefault(char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ const char *env; /* LPDEST or PRINTER env variable */
+#ifdef __APPLE__
+ CFStringRef network; /* Network location */
+ CFArrayRef locations; /* Location array */
+ CFStringRef locprinter; /* Current printer */
+#endif /* __APPLE__ */
+
+
+ if ((env = getenv("LPDEST")) == NULL)
+ if ((env = getenv("PRINTER")) != NULL && !strcmp(env, "lp"))
+ env = NULL;
+
+ if (env)
+ {
+ strlcpy(name, env, namesize);
+ return (name);
+ }
+
+#ifdef __APPLE__
+ /*
+ * Use location-based defaults if "use last printer" is selected in the
+ * system preferences...
+ */
+
+ if (!appleUseLastPrinter())
+ {
+ DEBUG_puts("1_cupsUserDefault: Not using last printer as default...");
+ name[0] = '\0';
+ return (NULL);
+ }
+
+ /*
+ * Get the current location...
+ */
+
+ if ((network = appleCopyNetwork()) == NULL)
+ {
+ DEBUG_puts("1_cupsUserDefault: Unable to get current network...");
+ name[0] = '\0';
+ return (NULL);
+ }
+
+# ifdef DEBUG
+ CFStringGetCString(network, name, namesize, kCFStringEncodingUTF8);
+ DEBUG_printf(("2_cupsUserDefault: network=\"%s\"", name));
+# endif /* DEBUG */
+
+ /*
+ * Lookup the network in the preferences...
+ */
+
+ if ((locations = appleCopyLocations()) == NULL)
+ {
+ /*
+ * Missing or bad location array, so no location-based default...
+ */
+
+ DEBUG_puts("1_cupsUserDefault: Missing or bad location history array...");
+
+ CFRelease(network);
+
+ name[0] = '\0';
+ return (NULL);
+ }
+
+ DEBUG_printf(("2_cupsUserDefault: Got location, %d entries...",
+ (int)CFArrayGetCount(locations)));
+
+ if ((locprinter = appleGetPrinter(locations, network, NULL)) != NULL)
+ CFStringGetCString(locprinter, name, namesize, kCFStringEncodingUTF8);
+ else
+ name[0] = '\0';
+
+ CFRelease(network);
+ CFRelease(locations);
+
+ DEBUG_printf(("1_cupsUserDefault: Returning \"%s\"...", name));
+
+ return (*name ? name : NULL);
+
+#else
+ /*
+ * No location-based defaults on this platform...
+ */
+
+ name[0] = '\0';
+ return (NULL);
+#endif /* __APPLE__ */
+}
+
+
#ifdef __APPLE__
/*
* 'appleCopyLocations()' - Copy the location history array.
}
-/*
- * 'appleGetDefault()' - Get the default printer for this location.
- */
-
-static char * /* O - Name or NULL if no default */
-appleGetDefault(char *name, /* I - Name buffer */
- int namesize) /* I - Size of name buffer */
-{
- CFStringRef network; /* Network location */
- CFArrayRef locations; /* Location array */
- CFStringRef locprinter; /* Current printer */
-
-
- /*
- * Use location-based defaults if "use last printer" is selected in the
- * system preferences...
- */
-
- if (!appleUseLastPrinter())
- {
- DEBUG_puts("appleGetDefault: Not using last printer as default...");
- return (NULL);
- }
-
- /*
- * Get the current location...
- */
-
- if ((network = appleCopyNetwork()) == NULL)
- {
- DEBUG_puts("appleGetDefault: Unable to get current network...");
- return (NULL);
- }
-
-#ifdef DEBUG
- CFStringGetCString(network, name, namesize, kCFStringEncodingUTF8);
- DEBUG_printf(("appleGetDefault: network=\"%s\"\n", name));
-#endif /* DEBUG */
-
- /*
- * Lookup the network in the preferences...
- */
-
- if ((locations = appleCopyLocations()) == NULL)
- {
- /*
- * Missing or bad location array, so no location-based default...
- */
-
- DEBUG_puts("appleGetDefault: Missing or bad location history array...");
-
- CFRelease(network);
-
- return (NULL);
- }
-
- DEBUG_printf(("appleGetDefault: Got location, %d entries...\n",
- (int)CFArrayGetCount(locations)));
-
- if ((locprinter = appleGetPrinter(locations, network, NULL)) != NULL)
- CFStringGetCString(locprinter, name, namesize, kCFStringEncodingUTF8);
- else
- name[0] = '\0';
-
- CFRelease(network);
- CFRelease(locations);
-
- DEBUG_printf(("appleGetDefault: Returning \"%s\"...\n", name));
-
- return (*name ? name : NULL);
-}
-
-
/*
* 'appleGetPaperSize()' - Get the default paper size.
*/
if ((network = appleCopyNetwork()) == NULL)
{
- DEBUG_puts("appleSetDefault: Unable to get current network...");
+ DEBUG_puts("1appleSetDefault: Unable to get current network...");
return;
}
CFPreferencesSetAppValue(kLocationHistoryArrayKey, newlocations,
kPMPrintingPreferences);
CFPreferencesAppSynchronize(kPMPrintingPreferences);
+ notify_post("com.apple.printerPrefsChange");
}
if (newlocations)
*/
static int /* O - Number of destinations */
-cups_get_dests(const char *filename, /* I - File to read from */
- const char *match_name, /* I - Destination name we want */
- const char *match_inst, /* I - Instance name we want */
- int num_dests, /* I - Number of destinations */
- cups_dest_t **dests) /* IO - Destinations */
+cups_get_dests(
+ const char *filename, /* I - File to read from */
+ const char *match_name, /* I - Destination name we want */
+ const char *match_inst, /* I - Instance name we want */
+ int user_default_set, /* I - User default printer set? */
+ int num_dests, /* I - Number of destinations */
+ cups_dest_t **dests) /* IO - Destinations */
{
int i; /* Looping var */
cups_dest_t *dest; /* Current destination */
*name, /* Name of destination/option */
*instance; /* Instance of destination */
int linenum; /* Current line number */
- const char *printer; /* PRINTER or LPDEST */
- DEBUG_printf(("cups_get_dests(filename=\"%s\", match_name=\"%s\", "
- "match_inst=\"%s\", num_dests=%d, dests=%p)\n", filename,
- match_name ? match_name : "(null)",
- match_inst ? match_inst : "(null)", num_dests, dests));
+ DEBUG_printf(("7cups_get_dests(filename=\"%s\", match_name=\"%s\", "
+ "match_inst=\"%s\", user_default_set=%d, num_dests=%d, "
+ "dests=%p)", filename, match_name, match_inst,
+ user_default_set, num_dests, dests));
/*
* Try to open the file...
if ((fp = cupsFileOpen(filename, "r")) == NULL)
return (num_dests);
- /*
- * Check environment variables...
- */
-
- if ((printer = getenv("LPDEST")) == NULL)
- if ((printer = getenv("PRINTER")) != NULL)
- if (strcmp(printer, "lp") == 0)
- printer = NULL;
-
- DEBUG_printf(("cups_get_dests: printer=\"%s\"\n",
- printer ? printer : "(null)"));
-
/*
* Read each printer; each line looks like:
*
* See what type of line it is...
*/
- DEBUG_printf(("cups_get_dests: linenum=%d line=\"%s\" lineptr=\"%s\"\n",
- linenum, line, lineptr ? lineptr : "(null)"));
+ DEBUG_printf(("9cups_get_dests: linenum=%d line=\"%s\" lineptr=\"%s\"",
+ linenum, line, lineptr));
if ((strcasecmp(line, "dest") && strcasecmp(line, "default")) || !lineptr)
{
- DEBUG_puts("cups_get_dests: Not a dest or default line...");
+ DEBUG_puts("9cups_get_dests: Not a dest or default line...");
continue;
}
if (*lineptr)
*lineptr++ = '\0';
- DEBUG_printf(("cups_get_dests: name=\"%s\", instance=\"%s\"\n", name,
+ DEBUG_printf(("9cups_get_dests: name=\"%s\", instance=\"%s\"", name,
instance));
/*
}
else if (cupsGetDest(name, NULL, num_dests, *dests) == NULL)
{
- DEBUG_puts("cups_get_dests: Not found!");
+ DEBUG_puts("9cups_get_dests: Not found!");
continue;
}
else
* Out of memory!
*/
- DEBUG_puts("cups_get_dests: Out of memory!");
+ DEBUG_puts("9cups_get_dests: Out of memory!");
break;
}
}
* Set this as default if needed...
*/
- if (!printer && !strcasecmp(line, "default"))
+ if (!user_default_set && !strcasecmp(line, "default"))
{
- DEBUG_puts("cups_get_dests: Setting as default...");
+ DEBUG_puts("9cups_get_dests: Setting as default...");
for (i = 0; i < num_dests; i ++)
(*dests)[i].is_default = 0;