Skip to content

Commit 28f7e86

Browse files
Add the support of cpdb-libs for groups and translations
- Using general message string catalogs from CUPS and also message string catalogs from individual print queues. - Message catalog management done by libcupsfilters 2.x, via the `cfCatalog...()` API functions (`catalog.h`). - Option group support - Log messages handled by frontend library
1 parent fbd571f commit 28f7e86

File tree

5 files changed

+185
-11
lines changed

5 files changed

+185
-11
lines changed

configure.ac

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ AC_PROG_CC
1414

1515
# Checks for backend library
1616
PKG_CHECK_MODULES([CPDB],[cpdb >= 2])
17+
PKG_CHECK_MODULES([LIBCUPSFILTERS], [libcupsfilters >= 2])
1718
PKG_CHECK_MODULES([GIO],[gio-2.0])
1819
PKG_CHECK_MODULES([GIOUNIX],[gio-unix-2.0])
1920
PKG_CHECK_MODULES([GLIB],[glib-2.0])
2021

2122
# Checks for header files.
22-
AC_CHECK_HEADERS([stdlib.h string.h cups/cups.h])
23+
AC_CHECK_HEADERS([stdlib.h string.h cups/cups.h cupsfilters/catalog.h])
2324

2425
# Checks for typedefs, structures, and compiler characteristics.
2526
AC_TYPE_SIZE_T

src/Makefile.am

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ backenddir = $(CPDB_BACKEND_DIR)
22
backend_PROGRAMS = cups
33
cups_SOURCES = print_backend_cups.c backend_helper.c backend_helper.h
44
cups_CPPFLAGS = $(CPDB_CFLAGS)
5+
cups_CPPFLAGS += $(LIBCUPSFILTERS_CFLAGS)
56
cups_CPPFLAGS += $(GLIB_CFLAGS)
67
cups_CPPFLAGS += $(GIO_CFLAGS)
78
cups_CPPFLAGS += $(GIOUNIX_CFLAGS)
89

9-
cups_LDADD = $(CPDB_LIBS)
10-
cups_LDADD += -lcups -lpthread -lm -lcrypt
10+
cups_LDADD = -lcups -lpthread -lm -lcrypt
11+
cups_LDADD += $(CPDB_LIBS)
12+
cups_LDADD += $(LIBCUPSFILTERS_LIBS)
1113
cups_LDADD += $(GLIB_LIBS)
1214
cups_LDADD += $(GIO_LIBS)
1315
cups_LDADD += $(GIOUNIX_LIBS)

src/backend_helper.c

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -584,13 +584,16 @@ void unpack_option_array(GVariant *var, int num_options, Option **options)
584584
}
585585
GVariant *pack_option(const Option *opt)
586586
{
587-
GVariant **t = g_new(GVariant *, 4);
587+
char *group_name = cpdbGetGroup(opt->option_name);
588+
GVariant **t = g_new(GVariant *, 5);
588589
t[0] = g_variant_new_string(opt->option_name);
589-
t[1] = g_variant_new_string(opt->default_value); //("s", cpdbGetStringCopy(opt->default_value));
590-
t[2] = g_variant_new_int32(opt->num_supported);
591-
t[3] = cpdbPackStringArray(opt->num_supported, opt->supported_values);
592-
GVariant *tuple_variant = g_variant_new_tuple(t, 4);
590+
t[1] = g_variant_new_string(group_name);
591+
t[2] = g_variant_new_string(opt->default_value);
592+
t[3] = g_variant_new_int32(opt->num_supported);
593+
t[4] = cpdbPackStringArray(opt->num_supported, opt->supported_values);
594+
GVariant *tuple_variant = g_variant_new_tuple(t, 5);
593595
g_free(t);
596+
free(group_name);
594597
return tuple_variant;
595598
}
596599
GVariant *pack_media(const Media *media)
@@ -1594,6 +1597,97 @@ void print_job(cups_job_t *j)
15941597
printf("state : %s\n", state);
15951598
}
15961599

1600+
char *get_option_translation(PrinterCUPS *p,
1601+
const char *option_name,
1602+
const char *locale)
1603+
{
1604+
char *copy;
1605+
const char *uri, *translation;
1606+
static const char *const req_attrs[] = {"printer-strings-uri"};
1607+
ipp_attribute_t *attr;
1608+
ipp_t *request, *response;
1609+
cups_array_t *opts_catalog, *printer_opts_catalog;
1610+
1611+
ensure_printer_connection(p);
1612+
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
1613+
uri = cupsGetOption("printer-uri-supported",
1614+
p->dest->num_options,
1615+
p->dest->options);
1616+
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1617+
"printer-uri", NULL, uri);
1618+
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1619+
"requested-attributes", 1, NULL, req_attrs);
1620+
response = cupsDoRequest(p->http, request, "/");
1621+
if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
1622+
{
1623+
/* request failed */
1624+
printf("Request failed: %s\n", cupsLastErrorString());
1625+
return cpdbGetStringCopy(option_name);
1626+
}
1627+
1628+
opts_catalog = cfCatalogOptionArrayNew();
1629+
cfCatalogLoad(NULL, locale, opts_catalog);
1630+
if ((attr = ippFindAttribute(response, "printer-strings-uri",
1631+
IPP_TAG_URI)) != NULL)
1632+
{
1633+
printer_opts_catalog = cfCatalogOptionArrayNew();
1634+
cfCatalogLoad(ippGetString(attr, 0, NULL), NULL, printer_opts_catalog);
1635+
}
1636+
1637+
translation = cfCatalogLookUpOption((char *)option_name,
1638+
opts_catalog, printer_opts_catalog);
1639+
copy = cpdbGetStringCopy(translation);
1640+
cupsArrayDelete(opts_catalog);
1641+
cupsArrayDelete(printer_opts_catalog);
1642+
return copy;
1643+
}
1644+
1645+
char *get_choice_translation(PrinterCUPS *p,
1646+
const char *option_name,
1647+
const char *choice_name,
1648+
const char *locale)
1649+
{
1650+
char *copy;
1651+
const char *uri, *translation;
1652+
static const char *const req_attrs[] = {"printer-strings-uri"};
1653+
ipp_attribute_t *attr;
1654+
ipp_t *request, *response;
1655+
cups_array_t *opts_catalog, *printer_opts_catalog;
1656+
1657+
ensure_printer_connection(p);
1658+
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
1659+
uri = cupsGetOption("printer-uri-supported",
1660+
p->dest->num_options,
1661+
p->dest->options);
1662+
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1663+
"printer-uri", NULL, uri);
1664+
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1665+
"requested-attributes", 1, NULL, req_attrs);
1666+
response = cupsDoRequest(p->http, request, "/");
1667+
if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
1668+
{
1669+
/* request failed */
1670+
printf("Request failed: %s\n", cupsLastErrorString());
1671+
return cpdbGetStringCopy(choice_name);
1672+
}
1673+
1674+
opts_catalog = cfCatalogOptionArrayNew();
1675+
cfCatalogLoad(NULL, locale, opts_catalog);
1676+
if ((attr = ippFindAttribute(response, "printer-strings-uri",
1677+
IPP_TAG_URI)) != NULL)
1678+
{
1679+
printer_opts_catalog = cfCatalogOptionArrayNew();
1680+
cfCatalogLoad(ippGetString(attr, 0, NULL), NULL, printer_opts_catalog);
1681+
}
1682+
1683+
translation = cfCatalogLookUpChoice((char *)choice_name, (char *)option_name,
1684+
opts_catalog, printer_opts_catalog);
1685+
copy = cpdbGetStringCopy(translation);
1686+
cupsArrayDelete(opts_catalog);
1687+
cupsArrayDelete(printer_opts_catalog);
1688+
return copy;
1689+
}
1690+
15971691
char *get_human_readable_option_name(const char *option_name)
15981692
{
15991693
if (strcmp("page-set", option_name) == 0)

src/backend_helper.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
#include <stdlib.h>
66
#include <glib.h>
77
#include <string.h>
8+
89
#include <cups/cups.h>
910
#include <cups/ppd.h>
10-
#include <cpdb/cpdb.h>
11+
#include <cupsfilters/catalog.h>
12+
13+
#include <cpdb/backend.h>
1114

1215
#define INFO 3
1316
#define WARN 2
@@ -201,6 +204,18 @@ int print_file(PrinterCUPS *p, const char *file_path, int num_settings, GVariant
201204
int get_active_jobs_count(PrinterCUPS *p);
202205
gboolean cancel_job(PrinterCUPS *p, int jobid);
203206

207+
/**
208+
* Get translation of choice name for a given locale
209+
*/
210+
char *get_option_translation(PrinterCUPS *p, const char *option_name,
211+
const char *locale);
212+
213+
/**
214+
* Get translation of option name for a given locale
215+
*/
216+
char *get_choice_translation(PrinterCUPS *p, const char *option_name,
217+
const char *choice_name, const char *locale);
218+
204219
/**
205220
* Get human readable names of the options.
206221
*/

src/print_backend_cups.c

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
#include <stdlib.h>
33
#include <glib.h>
44
#include <string.h>
5+
56
#include <cups/cups.h>
6-
#include <cpdb/cpdb.h>
7+
8+
#include <cpdb/backend.h>
79
#include "backend_helper.h"
810

911
#define _CUPS_NO_DEPRECATED 1
@@ -27,6 +29,7 @@ int main()
2729
int p = ippPort();
2830

2931
b = get_new_BackendObj();
32+
cpdbInit();
3033
acquire_session_bus_name(BUS_NAME);
3134
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
3235
g_main_loop_run(loop);
@@ -244,6 +247,53 @@ static gboolean on_handle_get_printer_state(PrintBackend *interface,
244247
return TRUE;
245248
}
246249

250+
static gboolean on_handle_get_option_translation(PrintBackend *interface,
251+
GDBusMethodInvocation *invocation,
252+
const gchar *printer_name,
253+
const gchar *option_name,
254+
const gchar *locale,
255+
gpointer user_data)
256+
{
257+
const char *dialog_name = g_dbus_method_invocation_get_sender(invocation); /// potential risk
258+
PrinterCUPS *p = get_printer_by_name(b, dialog_name, printer_name);
259+
char *translation = get_option_translation(p, option_name, locale);
260+
if (translation == NULL)
261+
translation = cpdbGetStringCopy(option_name);
262+
print_backend_complete_get_option_translation(interface, invocation, translation);
263+
return TRUE;
264+
}
265+
266+
static gboolean on_handle_get_choice_translation(PrintBackend *interface,
267+
GDBusMethodInvocation *invocation,
268+
const gchar *printer_name,
269+
const gchar *option_name,
270+
const gchar *choice_name,
271+
const gchar *locale,
272+
gpointer user_data)
273+
{
274+
const char *dialog_name = g_dbus_method_invocation_get_sender(invocation); /// potential risk
275+
PrinterCUPS *p = get_printer_by_name(b, dialog_name, printer_name);
276+
char *translation = get_choice_translation(p, option_name,
277+
choice_name, locale);
278+
if (translation == NULL)
279+
translation = cpdbGetStringCopy(choice_name);
280+
print_backend_complete_get_choice_translation(interface, invocation, translation);
281+
return TRUE;
282+
}
283+
284+
static gboolean on_handle_get_group_translation(PrintBackend *interface,
285+
GDBusMethodInvocation *invocation,
286+
const gchar *printer_name,
287+
const gchar *group_name,
288+
const gchar *locale,
289+
gpointer user_data)
290+
{
291+
char *translation = cpdbGetGroupTranslation2(group_name, locale);
292+
print_backend_complete_get_group_translation(interface, invocation, translation);
293+
free(translation);
294+
return TRUE;
295+
}
296+
247297
static gboolean on_handle_get_human_readable_option_name(PrintBackend *interface,
248298
GDBusMethodInvocation *invocation,
249299
const gchar *option_name,
@@ -336,7 +386,7 @@ static gboolean on_handle_get_all_options(PrintBackend *interface,
336386
int count = get_all_options(p, &options);
337387
count = add_media_to_options(p, medias, media_count, &options, count);
338388
GVariant *variant;
339-
builder = g_variant_builder_new(G_VARIANT_TYPE("a(ssia(s))"));
389+
builder = g_variant_builder_new(G_VARIANT_TYPE("a(sssia(s))"));
340390

341391
for (int i = 0; i < count; i++)
342392
{
@@ -473,6 +523,18 @@ void connect_to_signals()
473523
"handle-replace", //signal name
474524
G_CALLBACK(on_handle_replace), //callback
475525
NULL);
526+
g_signal_connect(skeleton, //instance
527+
"handle-get-option-translation", //signal name
528+
G_CALLBACK(on_handle_get_option_translation), //callback
529+
NULL);
530+
g_signal_connect(skeleton, //instance
531+
"handle-get-choice-translation", //signal name
532+
G_CALLBACK(on_handle_get_choice_translation), //callback
533+
NULL);
534+
g_signal_connect(skeleton, //instance
535+
"handle-get-group-translation", //signal name
536+
G_CALLBACK(on_handle_get_group_translation), //callback
537+
NULL);
476538
g_signal_connect(skeleton, //instance
477539
"handle-get-human-readable-option-name", //signal name
478540
G_CALLBACK(on_handle_get_human_readable_option_name), //callback

0 commit comments

Comments
 (0)