Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP : PAPPL Scan API Integration #349

Draft
wants to merge 22 commits into
base: v1.4.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ CentOS 8/Fedora 23+/RHEL 8:

sudo dnf groupinstall 'Development Tools'
sudo dnf install avahi-devel cups-devel libjpeg-turbo-devel \
libpng-devel libssl-devel libusbx-devel pam-devel zlib-devel
libpng-devel libssl-devel libusbx-devel pam-devel zlib-devel libxml2 libxml2-dev

Debian/Raspbian/Ubuntu:

sudo apt-get install build-essential libavahi-client-dev libcups2-dev \
libcupsimage2-dev libjpeg-dev libpam-dev libpng-dev libssl-dev \
libusb-1.0-0-dev zlib1g-dev
libusb-1.0-0-dev zlib1g-dev libxml2 libxml2-dev

macOS (after installing Xcode from the AppStore):

Expand All @@ -43,6 +43,7 @@ macOS (after installing Xcode from the AppStore):
brew install libpng
brew install libusb
brew install openssl@3
brew install libxml2

or download, build, and install libjpeg, libpng, libusb, and OpenSSL or LibreSSL
from source.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ are required along with the following support libraries:
- LIBUSB (1.0 or later) for USB printing support (optional)
- PAM for authentication support (optional)
- ZLIB (1.1 or later) for compression support
- LIBXML for xml parsing support

Most development happens on Intel and Apple Silicon Macs, with testing on
various Linux distributions, Windows 10+, and a [Raspberry Pi Zero W][7] to
Expand Down Expand Up @@ -111,4 +112,3 @@ This software is based loosely on the "ippeveprinter.c" code from [CUPS][12].
[10]: https://github.com/openprinting/ps-printer-app
[11]: https://hosted.weblate.org
[12]: https://openprinting.github.io/cups

12 changes: 11 additions & 1 deletion pappl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

include ../Makedefs

CFLAGS += $(shell pkg-config --cflags libxml-2.0)
LDFLAGS += $(shell pkg-config --libs libxml-2.0)

BASEOBJS = \
client.o \
Expand Down Expand Up @@ -45,6 +47,11 @@ BASEOBJS = \
printer-usb.o \
printer-webif.o \
resource.o \
scanner.o \
scanner-accessors.o\
scanner-driver.o \
scanner-escl.o \
scanner-webif.o \
snmp.o \
subscription.o \
subscription-ipp.o \
Expand Down Expand Up @@ -72,8 +79,11 @@ HEADERS = \
mainloop.h \
pappl.h \
printer.h \
scanner.h \
scanner-private.h \
subscription.h \
system.h
system.h \
system-private.h

RESOURCES = \
icon-sm.png \
Expand Down
6 changes: 6 additions & 0 deletions pappl/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,19 @@ typedef unsigned char pappl_dither_t[16][16];
// 16x16 dither array
typedef struct pappl_pr_driver_data_s pappl_pr_driver_data_t;
// Print driver data
typedef struct pappl_sc_driver_data_s pappl_sc_driver_data_t;
// Scanner driver data
typedef struct _pappl_job_s pappl_job_t;// Job object
typedef struct _pappl_loc_s pappl_loc_t;// Localization data
typedef struct pappl_pr_options_s pappl_pr_options_t;
// Combined print job options
typedef struct pappl_sc_options_s pappl_sc_options_t;
// Combined scan job options
typedef unsigned int pappl_preason_t; // Bitfield for IPP "printer-state-reasons" values
typedef struct _pappl_printer_s pappl_printer_t;
// Printer object
typedef struct _pappl_scanner_s pappl_scanner_t;
// Scanner object
typedef struct _pappl_subscription_s pappl_subscription_t;
// Subscription object
typedef struct _pappl_system_s pappl_system_t;
Expand Down
1 change: 1 addition & 0 deletions pappl/client-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct _pappl_client_s // Client data
char username[256]; // Authenticated username, if any
char language[256]; // Accept-Language value, if any
pappl_printer_t *printer; // Printer, if any
pappl_scanner_t *scanner; // Scanner, if any
pappl_job_t *job; // Job, if any
pappl_loc_t *loc; // Localization, if any
int num_files; // Number of temporary files
Expand Down
124 changes: 124 additions & 0 deletions pappl/client-webif.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,26 @@ papplClientHTMLPrinterFooter(pappl_client_t *client) // I - Client
}


//
// 'papplClientHTMLScannerFooter()' - Show the web interface footer for scanners.
//
// This function sends the standard web interface footer for a scanner followed
// by a trailing 0-length chunk to finish the current HTTP response. Use the
// @link papplSystemSetFooterHTML@ function to add any custom HTML needed in
// the footer.
//

void
papplClientHTMLScannerFooter(pappl_client_t *client) // I - Client
{
papplClientHTMLPuts(client,
" </div>\n"
" </div>\n"
" </div>\n");
papplClientHTMLFooter(client);
}


//
// 'papplClientHTMLPrinterHeader()' - Show the web interface header and title
// for printers.
Expand Down Expand Up @@ -1015,6 +1035,110 @@ papplClientHTMLPrinterHeader(
}


//
// 'papplClientHTMLScannerHeader()' - Show the web interface header and title
// for scanners.
//
// This function sends the standard web interface header and title for a
// scanner. If the "refresh" argument is greater than zero, the page will
// automatically reload after that many seconds.
//
// If "label" and "path_or_url" are non-`NULL` strings, an additional navigation
// link is included with the title header - this is typically used for an
// action button ("Change").
//
// Use the @link papplSystemAddLink@ function to add system-wide navigation
// links to the header. Similarly, use @link papplScannerAddLink@ to add
// scanner-specific links, which will appear in the web interface scanner if
// the system is not configured to support multiple scanners
//

// TODO : papplScannerAddLink
void
papplClientHTMLScannerHeader(
pappl_client_t *client, // I - Client
pappl_scanner_t *scanner, // I - Scanner
const char *title, // I - Title
int refresh, // I - Refresh time in seconds or 0 for none
const char *label, // I - Button label or `NULL` for none
const char *path_or_url) // I - Button path or `NULL` for none
{
const char *header; // Header text

if (!papplClientRespond(client, HTTP_STATUS_OK, NULL, "text/html", 0, 0))
return;


// Multi-queue mode not required for scanners

// Single queue mode - the function will automatically add the scanner name and localize the title...
papplClientHTMLHeader(client, title, refresh);

// Generate HTML for scanners
_papplRWLockRead(scanner);
papplClientHTMLPrintf(client,
" <div class=\"header2\">\n"
" <div class=\"row\">\n"
" <div class=\"col-12 nav\"><a class=\"btn\" href=\"%s\">%s:</a>\n", scanner->uriname, scanner->name);
_papplClientHTMLPutLinks(client, scanner->links, PAPPL_LOPTIONS_NAVIGATION);
papplClientHTMLPuts(client,
" </div>\n"
" </div>\n"
" </div>\n");
_papplRWUnlock(scanner);

// Display system version if available
if (client->system->versions[0].sversion[0])
{
papplClientHTMLPrintf(client,
" <div class=\"header2\">\n"
" <div class=\"row\">\n"
" <div class=\"col-12 nav\">\n"
" Version %s\n"
" </div>\n"
" </div>\n"
" </div>\n", client->system->versions[0].sversion);
}

papplClientHTMLPuts(client, " <div class=\"content\">\n");

if ((header = papplClientGetLocString(client, client->uri)) == client->uri)
{
size_t urilen = strlen(scanner->uriname);
// Length of scanner URI name
const char *uriptr = client->uri + urilen;
// Pointer into client URI

if (strlen(client->uri) <= urilen || !strcmp(client->uri, "/") || (header = papplClientGetLocString(client, uriptr)) == uriptr)
header = NULL;
}

if (header)
{
// Show header text
papplClientHTMLPuts(client,
" <div class=\"row\">\n"
" <div class=\"col-12\">\n");
papplClientHTMLPuts(client, header);
papplClientHTMLPuts(client,
"\n"
" </div>\n"
" </div>\n");
}

if (title)
{
papplClientHTMLPrintf(client,
" <div class=\"row\">\n"
" <div class=\"col-12\">\n"
" <h1 class=\"title\">%s", papplClientGetLocString(client, title));
if (label && path_or_url)
papplClientHTMLPrintf(client, " <a class=\"btn\" href=\"%s\">%s</a>", path_or_url, papplClientGetLocString(client, label));
papplClientHTMLPuts(client, "</h1>\n");
}
}


//
// 'papplClientHTMLPrintf()' - Send formatted text to the web browser client,
// escaping as needed.
Expand Down
2 changes: 2 additions & 0 deletions pappl/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ extern bool papplClientHTMLAuthorize(pappl_client_t *client) _PAPPL_PUBLIC;
extern void papplClientHTMLEscape(pappl_client_t *client, const char *s, size_t slen) _PAPPL_PUBLIC;
extern void papplClientHTMLFooter(pappl_client_t *client) _PAPPL_PUBLIC;
extern void papplClientHTMLHeader(pappl_client_t *client, const char *title, int refresh) _PAPPL_PUBLIC;
extern void papplClientHTMLScannerHeader(pappl_client_t *client, pappl_scanner_t *scanner, const char *title, int refresh, const char *label, const char *path_or_url)_PAPPL_PUBLIC;
extern void papplClientHTMLScannerFooter(pappl_client_t *client)_PAPPL_PUBLIC;
extern void papplClientHTMLPrinterFooter(pappl_client_t *client) _PAPPL_PUBLIC;
extern void papplClientHTMLPrinterHeader(pappl_client_t *client, pappl_printer_t *printer, const char *title, int refresh, const char *label, const char *path_or_url) _PAPPL_PUBLIC;
extern void papplClientHTMLPrintf(pappl_client_t *client, const char *format, ...) _PAPPL_PUBLIC _PAPPL_FORMAT(2, 3);
Expand Down
22 changes: 22 additions & 0 deletions pappl/dnssd.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,28 @@ _papplPrinterUnregisterDNSSDNoLock(
#endif // HAVE_MDNSRESPONDER
}

//
// TODO : papplScannerRegisterDNSSDNoLock - Register a scanner's DNS-SD service.
//

bool // O - `true` on success, `false` on failure
_papplScannerRegisterDNSSDNoLock(
pappl_scanner_t *scanner) // I - Scanner
{
bool ret = true; // Sample return value
return (ret);
}

//
// TODO: '_papplScannerUnregisterDNSSDNoLock()' - Unregister a scanners's DNS-SD service.
//

void
_papplScannerUnregisterDNSSDNoLock(
pappl_scanner_t *scanner) // I - Scanner
{
return ; // Sample return
}

//
// '_papplSystemRegisterDNSSDNoLock()' - Register a system's DNS-SD service.
Expand Down
1 change: 1 addition & 0 deletions pappl/job-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct _pappl_job_s // Job data
pthread_rwlock_t rwlock; // Reader/writer lock
pappl_system_t *system; // Containing system
pappl_printer_t *printer; // Containing printer
pappl_scanner_t *scanner; // Containing scanner
int job_id; // "job-id" value
const char *name, // "job-name" value
*username, // "job-originating-user-name" value
Expand Down
10 changes: 5 additions & 5 deletions pappl/job-process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ finish_job(pappl_job_t *job) // I - Job
if (job->state >= IPP_JSTATE_CANCELED && !printer->max_preserved_jobs && !job->retain_until)
_papplJobRemoveFile(job);

_papplSystemAddEventNoLock(job->system, job->printer, job, PAPPL_EVENT_JOB_COMPLETED, NULL);
_papplSystemAddEventNoLock(job->system, job->printer, NULL, job, PAPPL_EVENT_JOB_COMPLETED, NULL);

if (printer->is_stopped)
{
Expand All @@ -1102,7 +1102,7 @@ finish_job(pappl_job_t *job) // I - Job

_papplRWUnlock(job);

_papplSystemAddEventNoLock(printer->system, printer, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED, NULL);
_papplSystemAddEventNoLock(printer->system, printer, NULL, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED, NULL);

if (printer->max_preserved_jobs > 0)
_papplPrinterCleanJobsNoLock(printer);
Expand Down Expand Up @@ -1166,7 +1166,7 @@ start_job(pappl_job_t *job) // I - Job
job->processing = time(NULL);
printer->processing_job = job;

_papplSystemAddEventNoLock(printer->system, printer, job, PAPPL_EVENT_JOB_STATE_CHANGED, NULL);
_papplSystemAddEventNoLock(printer->system, printer, NULL, job, PAPPL_EVENT_JOB_STATE_CHANGED, NULL);

_papplRWUnlock(job);

Expand Down Expand Up @@ -1216,7 +1216,7 @@ start_job(pappl_job_t *job) // I - Job
job->state = IPP_JSTATE_PENDING;

_papplRWLockRead(job);
_papplSystemAddEventNoLock(job->system, job->printer, job, PAPPL_EVENT_JOB_STATE_CHANGED, NULL);
_papplSystemAddEventNoLock(job->system, job->printer, NULL, job, PAPPL_EVENT_JOB_STATE_CHANGED, NULL);
_papplRWUnlock(job);

if (printer->device)
Expand All @@ -1234,7 +1234,7 @@ start_job(pappl_job_t *job) // I - Job
ret = true;
}

_papplSystemAddEventNoLock(printer->system, printer, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED, NULL);
_papplSystemAddEventNoLock(printer->system, printer, NULL, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED, NULL);

_papplRWUnlock(printer);

Expand Down
6 changes: 3 additions & 3 deletions pappl/job.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ _papplJobHoldNoLock(

if (username)
{
_papplSystemAddEventNoLock(job->system, job->printer, job, PAPPL_EVENT_JOB_STATE_CHANGED, "Job held by '%s'.", username);
_papplSystemAddEventNoLock(job->system, job->printer, NULL, job, PAPPL_EVENT_JOB_STATE_CHANGED, "Job held by '%s'.", username);
}

return (true);
Expand Down Expand Up @@ -583,7 +583,7 @@ _papplJobReleaseNoLock(
ippDeleteAttribute(job->attrs, attr);

if (username)
_papplSystemAddEventNoLock(job->system, job->printer, job, PAPPL_EVENT_JOB_STATE_CHANGED, "Job released by '%s'.", username);
_papplSystemAddEventNoLock(job->system, job->printer, NULL, job, PAPPL_EVENT_JOB_STATE_CHANGED, "Job released by '%s'.", username);
}


Expand Down Expand Up @@ -704,7 +704,7 @@ _papplJobRetainNoLock(

if (username)
{
_papplSystemAddEventNoLock(job->system, job->printer, job, PAPPL_EVENT_JOB_CONFIG_CHANGED, "Job retain set by '%s'.", username);
_papplSystemAddEventNoLock(job->system, job->printer, NULL, job, PAPPL_EVENT_JOB_CONFIG_CHANGED, "Job retain set by '%s'.", username);
}

return (true);
Expand Down
1 change: 1 addition & 0 deletions pappl/pappl-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
# include "log-private.h"
# include "mainloop-private.h"
# include "printer-private.h"
# include "scanner-private.h"
# include "system-private.h"
#endif // !_PAPPL_PAPPL_PRIVATE_H_
8 changes: 4 additions & 4 deletions pappl/printer-accessors.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ papplPrinterHoldNewJobs(
ret = true;

// Notify of the change in state...
_papplSystemAddEventNoLock(printer->system, printer, NULL, PAPPL_EVENT_PRINTER_CONFIG_CHANGED, "Holding new jobs.");
_papplSystemAddEventNoLock(printer->system, printer, NULL, NULL, PAPPL_EVENT_PRINTER_CONFIG_CHANGED, "Holding new jobs.");
}

_papplRWUnlock(printer);
Expand Down Expand Up @@ -942,7 +942,7 @@ papplPrinterPause(
else
printer->state = IPP_PSTATE_STOPPED;

_papplSystemAddEventNoLock(printer->system, printer, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED | PAPPL_EVENT_PRINTER_STOPPED, NULL);
_papplSystemAddEventNoLock(printer->system, printer, NULL, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED | PAPPL_EVENT_PRINTER_STOPPED, NULL);

_papplRWUnlock(printer);
}
Expand Down Expand Up @@ -979,7 +979,7 @@ papplPrinterReleaseHeldNewJobs(
printer->config_time = time(NULL);
ret = true;

_papplSystemAddEventNoLock(printer->system, printer, NULL, PAPPL_EVENT_PRINTER_CONFIG_CHANGED, "Releasing held new jobs.");
_papplSystemAddEventNoLock(printer->system, printer, NULL, NULL, PAPPL_EVENT_PRINTER_CONFIG_CHANGED, "Releasing held new jobs.");

for (job = (pappl_job_t *)cupsArrayGetFirst(printer->active_jobs); job; job = (pappl_job_t *)cupsArrayGetNext(printer->active_jobs))
{
Expand Down Expand Up @@ -1022,7 +1022,7 @@ papplPrinterResume(
printer->is_stopped = false;
printer->state = IPP_PSTATE_IDLE;

_papplSystemAddEventNoLock(printer->system, printer, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED, "Resumed printer.");
_papplSystemAddEventNoLock(printer->system, printer, NULL, NULL, PAPPL_EVENT_PRINTER_STATE_CHANGED, "Resumed printer.");

_papplPrinterCheckJobsNoLock(printer);

Expand Down
Loading
Loading