增加打印机相关接口
This commit is contained in:
parent
a4bf694cf2
commit
ffbf9190b6
|
@ -19,7 +19,8 @@ Build-Depends: debhelper-compat (= 12),
|
|||
libudev-dev,
|
||||
libopencv-dev,
|
||||
libarchive-dev,
|
||||
libtesseract-dev
|
||||
libtesseract-dev,
|
||||
libcups2-dev,
|
||||
Standards-Version: 4.4.1
|
||||
Homepage: http://gitlab2.kylin.com/kysdk/kysdk-system
|
||||
|
||||
|
@ -172,7 +173,8 @@ Depends: ${shlibs:Depends},
|
|||
libkysdk-log(>=1.2.0),
|
||||
libkysdk-config(>=1.2.0),
|
||||
systemd,
|
||||
libkysdk-systemcommon
|
||||
libkysdk-systemcommon,
|
||||
cups
|
||||
Multi-Arch: same
|
||||
Description: 硬件信息获取库
|
||||
|
||||
|
@ -184,7 +186,8 @@ Depends: ${shlibs:Depends},
|
|||
libkysdk-hardware,
|
||||
libkysdk-log-dev(>=1.2.0),
|
||||
libkysdk-config-dev(>=1.2.0),
|
||||
libsystemd-dev
|
||||
libsystemd-dev,
|
||||
libcups2-dev
|
||||
Multi-Arch: same
|
||||
Description: 硬件信息获取库 - 开发库
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
usr/include/kysdk/kysdk-system/libkync.h
|
||||
usr/include/kysdk/kysdk-system/libkycpu.h
|
||||
usr/include/kysdk/kysdk-system/libkyprinter.h
|
||||
development-files/kysdk-hardware.pc usr/share/pkgconfig/
|
|
@ -4,9 +4,12 @@ add_library(kyhw SHARED ${SOURCESCODE})
|
|||
set_target_properties(kyhw PROPERTIES VERSION 1.2.0 SOVERSION 1)
|
||||
add_executable(kync-test test/kync-test.c)
|
||||
add_executable(kycpu-test test/kycpu-test.c)
|
||||
target_link_libraries(kyhw kylog kyconf pthread systemd)
|
||||
add_executable(kyprinter-test test/kyprinter-test.c)
|
||||
# 额外链接的库在这一行
|
||||
target_link_libraries(kyhw kylog kyconf pthread systemd cups)
|
||||
target_link_libraries(kync-test kyhw)
|
||||
target_link_libraries(kycpu-test kyhw)
|
||||
target_link_libraries(kyprinter-test kyhw)
|
||||
|
||||
install(TARGETS kyhw
|
||||
DESTINATION lib/kysdk/kysdk-system)
|
||||
|
@ -15,4 +18,7 @@ install(FILES libkync.h
|
|||
DESTINATION include/kysdk/kysdk-system)
|
||||
|
||||
install(FILES libkycpu.h
|
||||
DESTINATION include/kysdk/kysdk-system)
|
||||
|
||||
install(FILES libkyprinter.h
|
||||
DESTINATION include/kysdk/kysdk-system)
|
|
@ -0,0 +1,325 @@
|
|||
#include "libkyprinter.h"
|
||||
#include <errno.h>
|
||||
#include <libkylog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <syslog.h>
|
||||
#include <cups/cups.h>
|
||||
#include <cups/adminutil.h>
|
||||
#include <cups/ipp.h>
|
||||
#include <cups/ppd.h>
|
||||
|
||||
#define _IPP_PRIVATE_STRUCTURES 1
|
||||
|
||||
cups_option_t *cups_options; // cups设置
|
||||
int num_options; // cups设置
|
||||
|
||||
char **kdk_printer_get_list()
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
cups_dest_t *dests = NULL;
|
||||
int num_dests = 0;
|
||||
int i = 0;
|
||||
char **printers = NULL;
|
||||
|
||||
num_dests = cupsGetDests(&dests);
|
||||
if (num_dests == 0 &&
|
||||
(cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
||||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED))
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr, "Printer: Error - add '/version=1.1' to server name.");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < num_dests; i++)
|
||||
{
|
||||
printf("[%s] printer name is %s \n", __FUNCTION__, dests[i].name);
|
||||
char **tmp = realloc(printers, sizeof(char *) * i);
|
||||
printers = tmp;
|
||||
printers[i] = malloc(sizeof(char) * (strlen(dests[i].name) + 1));
|
||||
strcpy(printers[i], dests[i].name);
|
||||
}
|
||||
char **tmp = realloc(printers, sizeof(char *) * (i + 1));
|
||||
printers = tmp;
|
||||
printers[i] = NULL;
|
||||
cupsFreeDests(num_dests, dests);
|
||||
return printers;
|
||||
}
|
||||
|
||||
int kdk_printer_remove_options()
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
if (num_options != 0 && cups_options != NULL)
|
||||
{
|
||||
cupsFreeOptions(num_options, cups_options);
|
||||
num_options = 0;
|
||||
cups_options = NULL;
|
||||
}
|
||||
printf("[%s] num_options = %d\n", __FUNCTION__, num_options);
|
||||
return 0;
|
||||
}
|
||||
//"two-sided-long-edge","two-sided-short-edge",one-sided
|
||||
void kdk_printer_set_options(int number_up,
|
||||
const char *media,
|
||||
const char *number_up_layout, const char *sides)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
kdk_printer_remove_options();
|
||||
cups_options = NULL;
|
||||
num_options = 0;
|
||||
|
||||
char NumberUp[2] = {0};
|
||||
|
||||
snprintf(NumberUp, 2, "%d", number_up);
|
||||
/* cups options */
|
||||
num_options = cupsAddOption("number-up", NumberUp, num_options, &cups_options);
|
||||
|
||||
num_options = cupsAddOption("media", media, num_options, &cups_options);
|
||||
|
||||
num_options = cupsAddOption("number-up-layout", number_up_layout, num_options, &cups_options);
|
||||
|
||||
num_options = cupsAddOption("sides", sides, num_options, &cups_options);
|
||||
}
|
||||
|
||||
int kdk_printer_print_file(const char *printername, char *filepath)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
printf("[%s] printer_name: %s, file_path: %s\n", __FUNCTION__,
|
||||
printername,
|
||||
filepath);
|
||||
|
||||
int jobid = cupsPrintFile(printername, filepath, "Print report", num_options, cups_options);
|
||||
//注意:这里没有设置格式的话会直接用默认格式,一般默认格式是单页打印
|
||||
// printf("[%s] num_options = %d,name = %s,value = %s",
|
||||
// __FUNCTION__,num_options,cups_options->name,cups_options->value);
|
||||
return jobid;
|
||||
}
|
||||
|
||||
int kdk_printer_cancel_all_jobs(const char *printername)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
int ret = cupsCancelJob(printername, CUPS_JOBID_ALL); // 1=success 0=fail
|
||||
if (ret == 0)
|
||||
{
|
||||
printf(LOG_ERR, "%s ,job_id = CUPS_JOBID_ALL, find err = %s ", __FUNCTION__, cupsLastErrorString());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int /* O - 1 on match, 0 on no match */
|
||||
match_list(const char *list, /* I - List of names */
|
||||
const char *name) /* I - Name to find */
|
||||
{
|
||||
const char *nameptr; /* Pointer into name */
|
||||
/*
|
||||
* An empty list always matches...
|
||||
*/
|
||||
|
||||
if (!list || !*list)
|
||||
return (1);
|
||||
if (!name)
|
||||
return (0);
|
||||
while (*list)
|
||||
{
|
||||
/*
|
||||
* Skip leading whitespace and commas...
|
||||
*/
|
||||
while (isspace(*list & 255) || *list == ',')
|
||||
list++;
|
||||
if (!*list)
|
||||
break;
|
||||
/*
|
||||
* Compare names...
|
||||
*/
|
||||
for (nameptr = name;
|
||||
*nameptr && *list && tolower(*nameptr & 255) == tolower(*list & 255);
|
||||
nameptr++, list++)
|
||||
;
|
||||
if (!*nameptr && (!*list || *list == ',' || isspace(*list & 255)))
|
||||
return (1);
|
||||
while (*list && !isspace(*list & 255) && *list != ',')
|
||||
list++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int /* O - 0 on success, 1 on fail */
|
||||
_show_printer_state(const char *printers /* I - Destinations */
|
||||
// char* buf, /* I - Number of user-defined dests */
|
||||
) /* I - User-defined destinations */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
time_t ptime; /* Printer state time */
|
||||
|
||||
const char *printer, /* Printer name */
|
||||
*device; /* Printer device URI */
|
||||
ipp_pstate_t pstate;
|
||||
int state_code = 0;
|
||||
static const char *pattrs[] = /* Attributes we need for printers... */
|
||||
{
|
||||
"printer-name",
|
||||
"printer-state"};
|
||||
|
||||
#ifdef PRT_DEBUG
|
||||
printf(("show_devices(printers=\"%s\")\n", printers));
|
||||
#endif
|
||||
if (printers != NULL && !strcmp(printers, "all"))
|
||||
printers = NULL;
|
||||
|
||||
/*
|
||||
* Build a CUPS_GET_PRINTERS request, which requires the following
|
||||
* attributes:
|
||||
*
|
||||
* attributes-charset
|
||||
* attributes-natural-language
|
||||
* requested-attributes
|
||||
* requesting-user-name
|
||||
*/
|
||||
|
||||
request = ippNewRequest(CUPS_GET_PRINTERS);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
|
||||
NULL, pattrs);
|
||||
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
|
||||
NULL, cupsUser());
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/");
|
||||
|
||||
if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
||||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr,
|
||||
"%s: Error - add '/version=1.1' to server name.",
|
||||
"lpstat");
|
||||
#endif
|
||||
ippDelete(response);
|
||||
return (1);
|
||||
}
|
||||
else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
|
||||
#endif
|
||||
ippDelete(response);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (response)
|
||||
{
|
||||
/*
|
||||
* Loop through the printers returned in the list and display
|
||||
* their devices...
|
||||
*/
|
||||
attr = ippFirstAttribute(response);
|
||||
for (; attr != NULL; attr = ippNextAttribute(response))
|
||||
{
|
||||
/*
|
||||
* Skip leading attributes until we hit a job...
|
||||
*/
|
||||
|
||||
while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
|
||||
attr = ippNextAttribute(response);
|
||||
|
||||
if (attr == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Pull the needed attributes from this job...
|
||||
*/
|
||||
printer = NULL;
|
||||
pstate = IPP_PRINTER_IDLE;
|
||||
while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER)
|
||||
{
|
||||
const char *attr_name = ippGetName(attr);
|
||||
ipp_tag_t value_tag = ippGetValueTag(attr);
|
||||
if (!strcmp(attr_name, "printer-name") &&
|
||||
value_tag == IPP_TAG_NAME)
|
||||
printer = ippGetString(attr, 0, NULL);
|
||||
else if (!strcmp(attr_name, "printer-state") &&
|
||||
value_tag == IPP_TAG_ENUM)
|
||||
{
|
||||
pstate = (ipp_pstate_t)ippGetInteger(attr, 0);
|
||||
// printf("statecode: %d\n",ippGetInteger(attr,0));
|
||||
}
|
||||
|
||||
attr = ippNextAttribute(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have everything needed...
|
||||
*/
|
||||
|
||||
if (printer == NULL)
|
||||
{
|
||||
if (attr == NULL)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (match_list(printers, printer))
|
||||
{
|
||||
switch (pstate)
|
||||
{
|
||||
case IPP_PRINTER_IDLE:
|
||||
state_code = CUPS_PRINTER_STATE_IDLE;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_IDLE);
|
||||
break;
|
||||
case IPP_PRINTER_PROCESSING:
|
||||
state_code = CUPS_PRINTER_STATE_PROCESSING;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_PROCESSING);
|
||||
break;
|
||||
case IPP_PRINTER_STOPPED:
|
||||
state_code = CUPS_PRINTER_STATE_STOPPED;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_STOPPED);
|
||||
break;
|
||||
case IPP_PRINTER_BUSY:
|
||||
state_code = CUPS_PRINTER_STATE_PROCESSING;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_PROCESSING);
|
||||
break;
|
||||
default:
|
||||
state_code = CUPS_PRINTER_STATE_STOPPED;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_STOPPED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attr == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
return state_code;
|
||||
}
|
||||
|
||||
int kdk_printer_get_status(const char *printername)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
http_t *http; /* Connection to server */
|
||||
int ret;
|
||||
if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
|
||||
cupsEncryption())) != NULL)
|
||||
{
|
||||
httpClose(http);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
return _show_printer_state(printername);
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#ifndef KDK_SYSTEM_HW_NWCARD_H__
|
||||
#define KDK_SYSTEM_HW_NWCARD_H__
|
||||
|
||||
#define CUPS_PRINTER_STATE_BUSY 6 //"Busy"
|
||||
#define CUPS_PRINTER_STATE_STOPPED 4 //"Stop"
|
||||
#define CUPS_PRINTER_STATE_IDLE 2 //"Idle"
|
||||
#define CUPS_PRINTER_STATE_PROCESSING 3 //"Processing"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 获取系统中所有的打印机
|
||||
*
|
||||
* @return char** 网卡名称列表,由NULL字符串表示结尾;由alloc生成,需要被kdk_printer_freeall回收;若获取出错,返回NULL;
|
||||
*/
|
||||
extern char** kdk_printer_get_list();
|
||||
|
||||
/**
|
||||
* @brief 设置打印参数,每次设置会清除之前设置打印参数,这个设置是全局设置,设置了之后所有打印机都会用这个参数进行打印
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
* @param number_up cups属性,一张纸打印几页,如2 4等
|
||||
* @param media cups属性,纸张类型,如A4
|
||||
* @param number_up_layout cups属性,如lrtb
|
||||
* @param sides cups属性,单面如one-sided,双面如two-sided-long-edge(长边翻转),two-sided-short-edge(短边翻转)
|
||||
*
|
||||
* @return 无
|
||||
*/
|
||||
extern void kdk_printer_set_options(int number_up,const char *media,const char *number_up_layout,const char *sides);
|
||||
|
||||
/**
|
||||
* @brief 打印文件
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
* @param filepath 文件绝对路径
|
||||
*
|
||||
* @return 打印作业的id
|
||||
*
|
||||
* @notice 虽然支持多种格式的打印,但是打印除pdf之外的格式打印的效果都不够好,建议打印pdf格式的文件
|
||||
*/
|
||||
extern int kdk_printer_print_file(const char *printername, char *filepath);
|
||||
|
||||
/**
|
||||
* @brief 清除某个打印机的所有打印队列
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
*
|
||||
*
|
||||
* @return 成功返回0,失败返回-1
|
||||
*/
|
||||
extern int kdk_printer_cancel_all_jobs(const char *printername);
|
||||
|
||||
/**
|
||||
* @brief 获取当前打印机状态
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
*
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
extern int kdk_printer_get_status(const char *printername);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,29 @@
|
|||
#include "../libkyprinter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int index = 0;
|
||||
//获取打印机列表
|
||||
char **printers = kdk_printer_get_list();
|
||||
while (printers[index])
|
||||
{
|
||||
printf("%zd: %s\n", index + 1, printers[index]);
|
||||
if (kdk_printer_get_status(printers[index]) == CUPS_PRINTER_STATE_IDLE)
|
||||
{
|
||||
//取消当前打印机所有打印任务
|
||||
kdk_printer_cancel_all_jobs(printers[index]);
|
||||
//设置打印参数(这个参数所有打印机共用)
|
||||
kdk_printer_set_options(2, "A4", "lrtb", "two-sided-long-edge");
|
||||
//打印
|
||||
int job_id = kdk_printer_print_file(printers[index], "/etc/apt/sources.list");
|
||||
if (job_id == 0)
|
||||
{
|
||||
printf("[%s] create print job fail\n", __FUNCTION__);
|
||||
}
|
||||
printf("[%s] The jobs_id = %d\n", __FUNCTION__, job_id);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue