pax_global_header00006660000000000000000000000064133362434450014521gustar00rootroot0000000000000052 comment=60a003ce70463d1398ea0fa0418caa436fed69c4 cpdb-libs-1.2.0/000077500000000000000000000000001333624344500133605ustar00rootroot00000000000000cpdb-libs-1.2.0/.gitignore000066400000000000000000000006361333624344500153550ustar00rootroot00000000000000*.o *.pdf .project print_frontend pickle_test .vscode/ .gdb_history .cproject gmon.out autom4te.cache missing Makefile1 Makefile.in install-sh configure autoscan.log aclocal.m4 compile lib/backend_interface.c lib/backend_interface.h lib/frontend_interface.c lib/frontend_interface.h lib/*.so lib/*.o lib/*.la lib/*.lo ltmain.sh Makefile ar-lib config.* depcomp lib/.deps libtool lib/.libs *.pc *.tar.* cpd-library*cpdb-libs-1.2.0/LICENSE.md000066400000000000000000000020571333624344500147700ustar00rootroot00000000000000MIT License Copyright (c) 2017 Nilanjana Lodh Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cpdb-libs-1.2.0/Makefile.am000066400000000000000000000003451333624344500154160ustar00rootroot00000000000000EXTRA_DIST = demo/*.c demo/Makefile README.md AUTOMAKE_OPTIONS = foreign SUBDIRS = lib ACLOCAL_AMFLAGS = '-I m4' pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = cpdb-libs-backend.pc cpdb-libs-frontend.pc cpdb-libs-common.pc cpdb-libs-1.2.0/README.md000066400000000000000000000061321333624344500146410ustar00rootroot00000000000000# Frontend/Backend Communication Libraries for the Common Print Dialog Backends This repository hosts the code for frontend and backend libraries for the Common Printing Dialog Backends (CPDB) project. These libraries allow the CPDB frontends (the print dialogs) and backends (the modules communicating with the different .printing systems) too communicate with each other via D-Bus. The frontend library also provides some extra functionality to deal with Printers, Settings, etc. in a high level manner. ## Background The Common Printing Dialog Backends (CPDB) project of OpenPrinting is about separating the print dialogs of different GUI toolkits and applications (GTK, Qt, LibreOffice, ...) from the different print technologies (CUPS/IPP, Google Cloud Print, ...) so that they can get developed independently and so always from all applications one can print with all print technologies and changes in the print technologies get supported quickly. If one opens the print dialog, the dialog will not talk directly to CUPS, Google Cloud Print, or any other printing system. For this communication there are the backends. The dialog will find all available backend and sends commands to them, for listing all available printers, giving property/option lists for the selected printers, and printing on the selcted printer. This communication is done via D-Bus. So the backends are easily exchangeable and for getting support for a new print technology only its backend needs to get added. ## Dependencies - [CUPS](https://github.com/apple/cups/releases) : Version >= 2.2 Installing bleeding edge release from [here](https://github.com/apple/cups/releases). (Preferable!) OR `sudo apt install cups libcups2-dev` - GLIB 2.0 : `sudo apt install libglib2.0-dev` - LIBTOOL : `sudo apt install libtool` ## Build and installation $ ./autogen $ ./configure $ make $ sudo make install $ sudo ldconfig Use the sample frontend client to check that the library and the installed backends work as expected: ## Testing the library The project also includes a sample command line frontend (using the `cpdb-libs-frontend` API) that you can use to test whether the installed libraries and print backends work as expected. $ cd demo/ $ make $ ./print_frontend The list of printers from various printers should start appearing automatically. Type `help` to get the list of available commands. Make sure to stop the frontend using the `stop` command only. The library also provides support for serializing a printer. Use the `pickle-printer` command to serialize it, and run the `pickle_test` executable after that to deserialize and test it. ## Using the libraries for devloping print backends and dialogs. To develop a frontend client(Eg. a print dialog), use the `cpdb-libs-frontend` library. pkg-config support: `pkg-config --cflags --libs cpdb-libs-frontend`. Header file : `cpdb-libs-frontend.h` Similarly, to develop a print backend, you need to use the `cpdb-libs-backend` library. pkg-config support: `pkg-config --cflags --libs cpdb-libs-backend`. Header file: `cpdb-libs-backend.h` in your code. cpdb-libs-1.2.0/autogen.sh000077500000000000000000000000171333624344500153570ustar00rootroot00000000000000autoreconf -fi cpdb-libs-1.2.0/configure.ac000066400000000000000000000017761333624344500156610ustar00rootroot00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([cpdb-libs],[1.2.0],[nilanjanalodh@gmail.com],[CPDB libraries for backends and frontends], [https://github.com/OpenPrinting/cpdb-libs]) AM_INIT_AUTOMAKE([-Wall foreign]) AC_CONFIG_SRCDIR([lib/frontend_helper.h]) : ${CFLAGS=""} # Check for a C compiler AC_PROG_CC #Check for archiver AM_PROG_AR LT_INIT PKG_CHECK_MODULES([GIO],[gio-2.0]) PKG_CHECK_MODULES([GIOUNIX],[gio-unix-2.0]) PKG_CHECK_MODULES([GLIB],[glib-2.0]) # Checks for header files. AC_CHECK_HEADERS([stdlib.h string.h unistd.h cups/cups.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_MALLOC AC_CHECK_FUNCS([getcwd]) AC_CONFIG_FILES([Makefile lib/Makefile cpdb-libs-backend.pc cpdb-libs-frontend.pc cpdb-libs-common.pc]) AC_OUTPUT cpdb-libs-1.2.0/cpdb-libs-backend.pc.in000066400000000000000000000004421333624344500175350ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Cflags: -I${includedir} Requires: gio-2.0 gio-unix-2.0 glib-2.0 cpdb-libs-common Libs: -L${libdir} Name: cpdb-libs-backend Description: Common Print Dialog Backends: Library for backends Version: @VERSION@ cpdb-libs-1.2.0/cpdb-libs-common.pc.in000066400000000000000000000004541333624344500174410ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Cflags: -I${includedir} Requires: gio-2.0 gio-unix-2.0 glib-2.0 Libs: -L${libdir} -lcpdb-libs-common Name: cpdb-libs-common Description: Common Print Dialog Backends: Common parts of the libraries Version: @VERSION@ cpdb-libs-1.2.0/cpdb-libs-frontend.pc.in000066400000000000000000000004711333624344500177670ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Cflags: -I${includedir} Requires: gio-2.0 gio-unix-2.0 glib-2.0 cpdb-libs-common Libs: -L${libdir} -lcpdb-libs-frontend Name: cpdb-libs-frontend Description: Common Print Dialog Backends: Library for frontends Version: @VERSION@ cpdb-libs-1.2.0/demo/000077500000000000000000000000001333624344500143045ustar00rootroot00000000000000cpdb-libs-1.2.0/demo/Makefile000066400000000000000000000006501333624344500157450ustar00rootroot00000000000000CPD_FRONT_FLAGS=$(shell pkg-config --cflags --libs cpdb-libs-frontend) GLIB_FLAGS=$(shell pkg-config --cflags --libs gio-2.0 gio-unix-2.0 glib-2.0) .PHONY = all all: print_frontend pickle_test #compile the sample frontend print_frontend: print_frontend.c gcc -g -pg -o $@ $^ $(CPD_FRONT_FLAGS) $(GLIB_FLAGS) pickle_test: pickle_test.c gcc -g -pg -o $@ $^ $(CPD_FRONT_FLAGS) clean: rm -f print_frontend pickle_test cpdb-libs-1.2.0/demo/pickle_test.c000066400000000000000000000010371333624344500167570ustar00rootroot00000000000000#include #include int main(int argc, char **argv) { if (argc != 2) { printf("Usage : %s filepath_to_print\n", argv[0]); exit(EXIT_SUCCESS); } PrinterObj *p = resurrect_printer_from_file("/tmp/.printer-pickle"); if (p == NULL) { printf("No serialized printer found. " "You must first 'pickle' a printer using the " "'pickle-printer' command inside print_frontend\n"); exit(EXIT_FAILURE); } print_file(p, argv[1]); } cpdb-libs-1.2.0/demo/print_frontend.c000066400000000000000000000250771333624344500175160ustar00rootroot00000000000000#include #include #include #include #include void display_help(); gpointer parse_commands(gpointer user_data); FrontendObj *f; static int add_printer_callback(PrinterObj *p) { //printf("print_frontend.c : Printer %s added!\n", p->name); print_basic_options(p); } static int remove_printer_callback(PrinterObj *p) { g_message("Removed Printer %s : %s!\n", p->name, p->backend_name); } int main(int argc, char **argv) { event_callback add_cb = (event_callback)add_printer_callback; event_callback rem_cb = (event_callback)remove_printer_callback; char *dialog_bus_name = malloc(300); if (argc > 1) //this is for creating multiple instances of a dialog simultaneously f = get_new_FrontendObj(argv[1], add_cb, rem_cb); else f = get_new_FrontendObj(NULL, add_cb, rem_cb); /** Uncomment the line below if you don't want to use the previously saved settings**/ //ignore_last_saved_settings(f); g_thread_new("parse_commands_thread", parse_commands, NULL); connect_to_dbus(f); GMainLoop *loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); } gpointer parse_commands(gpointer user_data) { printf("parse_commands\n"); fflush(stdout); char buf[100]; while (1) { printf("> "); fflush(stdout); scanf("%s", buf); if (strcmp(buf, "stop") == 0) { disconnect_from_dbus(f); g_message("Stopping front end..\n"); exit(0); } else if (strcmp(buf, "refresh") == 0) { refresh_printer_list(f); g_message("Getting changes in printer list..\n"); } else if (strcmp(buf, "hide-remote-cups") == 0) { hide_remote_cups_printers(f); g_message("Hiding remote printers discovered by the cups backend..\n"); } else if (strcmp(buf, "unhide-remote-cups") == 0) { unhide_remote_cups_printers(f); g_message("Unhiding remote printers discovered by the cups backend..\n"); } else if (strcmp(buf, "hide-temporary-cups") == 0) { hide_temporary_cups_printers(f); g_message("Hiding remote printers discovered by the cups backend..\n"); } else if (strcmp(buf, "unhide-temporary-cups") == 0) { unhide_temporary_cups_printers(f); g_message("Unhiding remote printers discovered by the cups backend..\n"); } else if (strcmp(buf, "get-all-options") == 0) { char printer_id[100]; char backend_name[100]; scanf("%s%s", printer_id, backend_name); g_message("Getting all attributes ..\n"); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); if(p == NULL) continue; Options *opts = get_all_options(p); printf("Retrieved %d options.\n", opts->count); GHashTableIter iter; gpointer value; g_hash_table_iter_init(&iter, opts->table); while (g_hash_table_iter_next(&iter, NULL, &value)) { print_option(value); } } else if (strcmp(buf, "get-default") == 0) { char printer_id[100], backend_name[100], option_name[100]; scanf("%s%s%s", option_name, printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); char *ans = get_default(p, option_name); if (!ans) printf("Option %s doesn't exist.", option_name); else printf("Default : %s\n", ans); } else if (strcmp(buf, "get-setting") == 0) { char printer_id[100], backend_name[100], setting_name[100]; scanf("%s%s%s", setting_name, printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); char *ans = get_setting(p, setting_name); if (!ans) printf("Setting %s doesn't exist.\n", setting_name); else printf("Setting value : %s\n", ans); } else if (strcmp(buf, "get-current") == 0) { char printer_id[100], backend_name[100], option_name[100]; scanf("%s%s%s", option_name, printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); char *ans = get_current(p, option_name); if (!ans) printf("Option %s doesn't exist.", option_name); else printf("Current value : %s\n", ans); } else if (strcmp(buf, "add-setting") == 0) { char printer_id[100], backend_name[100], option_name[100], option_val[100]; scanf("%s %s %s %s", option_name, option_val, printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); printf("%s : %s\n", option_name, option_val); add_setting_to_printer(p, get_string_copy(option_name), get_string_copy(option_val)); } else if (strcmp(buf, "clear-setting") == 0) { char printer_id[100], backend_name[100], option_name[100]; scanf("%s%s%s", option_name, printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); clear_setting_from_printer(p, option_name); } else if (strcmp(buf, "get-state") == 0) { char printer_id[100]; char backend_name[100]; scanf("%s%s", printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); printf("%s\n", get_state(p)); } else if (strcmp(buf, "is-accepting-jobs") == 0) { char printer_id[100]; char backend_name[100]; scanf("%s%s", printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); printf("Accepting jobs ? : %d \n", is_accepting_jobs(p)); } else if (strcmp(buf, "help") == 0) { display_help(); } else if (strcmp(buf, "ping") == 0) { char printer_id[100], backend_name[100]; scanf("%s%s", printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); print_backend_call_ping_sync(p->backend_proxy, p->id, NULL, NULL); } else if (strcmp(buf, "get-default-printer") == 0) { char backend_name[100]; scanf("%s", backend_name); /** * Backend name = The last part of the backend dbus service * Eg. "CUPS" or "GCP" */ printf("%s\n", get_default_printer(f, backend_name)); } else if (strcmp(buf, "print-file") == 0) { char printer_id[100], backend_name[100], file_path[200]; scanf("%s%s%s", file_path, printer_id, backend_name); /** * Try adding some settings here .. change them and experiment */ PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); if(strcmp(backend_name, "FILE") == 0) { char final_file_path[200]; printf("Please give the final file path: "); scanf("%s", final_file_path); print_file_path(p, file_path, final_file_path); continue; } add_setting_to_printer(p, "copies", "3"); print_file(p, file_path); } else if (strcmp(buf, "get-active-jobs-count") == 0) { char printer_id[100]; char backend_name[100]; scanf("%s%s", printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); printf("%d jobs currently active.\n", get_active_jobs_count(p)); } else if (strcmp(buf, "get-all-jobs") == 0) { int active_only; scanf("%d", &active_only); Job *j; int x = get_all_jobs(f, &j, active_only); printf("Total %d jobs\n", x); int i; for (i = 0; i < x; i++) { printf("%s .. %s .. %s .. %s .. %s\n", j[i].job_id, j[i].title, j[i].printer_id, j[i].state, j[i].submitted_at); } } else if (strcmp(buf, "cancel-job") == 0) { char printer_id[100]; char backend_name[100]; char job_id[100]; scanf("%s%s%s", job_id, printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); if (cancel_job(p, job_id)) printf("Job %s has been cancelled.\n", job_id); else printf("Unable to cancel job %s\n", job_id); } else if (strcmp(buf, "pickle-printer") == 0) { char printer_id[100]; char backend_name[100]; char job_id[100]; scanf("%s%s", printer_id, backend_name); PrinterObj *p = find_PrinterObj(f, printer_id, backend_name); pickle_printer_to_file(p, "/tmp/.printer-pickle", f); } } } void display_help() { g_message("Available commands .. "); printf("%s\n", "stop"); printf("%s\n", "refresh"); printf("%s\n", "hide-remote-cups"); printf("%s\n", "unhide-remote-cups"); printf("%s\n", "hide-temporary-cups"); printf("%s\n", "unhide-temporary-cups"); //printf("%s\n", "ping "); printf("%s\n", "get-default-printer "); printf("print-file \n"); printf("get-active-jobs-count \n"); printf("get-all-jobs <0 for all jobs; 1 for only active>\n"); printf("%s\n", "get-state "); printf("%s\n", "is-accepting-jobs "); printf("%s\n", "cancel-job "); printf("get-all-options \n"); printf("%s\n", "get-default