summaryrefslogtreecommitdiff
path: root/backend/escl/escl_capabilities.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2022-02-01 15:26:02 +0100
committerJörg Frings-Fürst <debian@jff.email>2022-02-01 15:26:02 +0100
commit5de81480e84023d91763d89e4523de88df42c194 (patch)
treecb83e4c8216cf0e8bcaa17a6f2cb64cf4d7f469a /backend/escl/escl_capabilities.c
parent97e55bdc5cdf59304af739e65f416320bcbcf599 (diff)
parent8e5d399808d2270ae9d56c96560a021e594d18a4 (diff)
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'backend/escl/escl_capabilities.c')
-rw-r--r--backend/escl/escl_capabilities.c111
1 files changed, 106 insertions, 5 deletions
diff --git a/backend/escl/escl_capabilities.c b/backend/escl/escl_capabilities.c
index db194f9..7422896 100644
--- a/backend/escl/escl_capabilities.c
+++ b/backend/escl/escl_capabilities.c
@@ -40,6 +40,25 @@ struct cap
size_t size;
};
+static size_t
+header_callback(void *str, size_t size, size_t nmemb, void *userp)
+{
+ struct cap *header = (struct cap *)userp;
+ size_t realsize = size * nmemb;
+ char *content = realloc(header->memory, header->size + realsize + 1);
+
+ if (content == NULL) {
+ DBG( 1, "Not enough memory (realloc returned NULL)\n");
+ return (0);
+ }
+ header->memory = content;
+ memcpy(&(header->memory[header->size]), str, realsize);
+ header->size = header->size + realsize;
+ header->memory[header->size] = 0;
+ return (realsize);
+}
+
+
/**
* \fn static SANE_String_Const convert_elements(SANE_String_Const str)
* \brief Function that converts the 'color modes' of the scanner (color/gray) to be understood by SANE.
@@ -182,10 +201,10 @@ find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)
{
const char *name = (const char *)node->name;
if (strcmp(name, "ColorMode") == 0) {
- const char *color = (SANE_String_Const)xmlNodeGetContent(node);
- if (type == PLATEN || strcmp(color, "BlackAndWhite1"))
+ const char *color = (SANE_String_Const)xmlNodeGetContent(node);
+ if (type == PLATEN || strcmp(color, "BlackAndWhite1"))
scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, &scanner->caps[type].ColorModesSize, (SANE_String_Const)xmlNodeGetContent(node), 1);
- }
+ }
else if (strcmp(name, "ContentType") == 0)
scanner->caps[type].ContentTypes = char_to_array(scanner->caps[type].ContentTypes, &scanner->caps[type].ContentTypesSize, (SANE_String_Const)xmlNodeGetContent(node), 0);
else if (strcmp(name, "DocumentFormat") == 0)
@@ -385,6 +404,16 @@ find_true_variables(xmlNode *node, capabilities_t *scanner, int type)
return (0);
}
+static char*
+replace_char(char* str, char find, char replace){
+ char *current_pos = strchr(str,find);
+ while (current_pos) {
+ *current_pos = replace;
+ current_pos = strchr(current_pos,find);
+ }
+ return str;
+}
+
/**
* \fn static int print_xml_c(xmlNode *node, capabilities_t *scanner)
* \brief Function that browses the xml file, node by node.
@@ -454,6 +483,37 @@ _reduce_color_modes(capabilities_t *scanner)
}
}
+static void
+_delete_pdf(capabilities_t *scanner)
+{
+ int type = 0;
+ for (type = 0; type < 3; type++) {
+ if (scanner->caps[type].ColorModesSize) {
+ if (scanner->caps[type].default_format) {
+ scanner->caps[type].have_pdf = -1;
+ if (!strcmp(scanner->caps[type].default_format, "application/pdf")) {
+ free(scanner->caps[type].default_format);
+ if (scanner->caps[type].have_tiff > -1)
+ scanner->caps[type].default_format = strdup("image/tiff");
+ else if (scanner->caps[type].have_png > -1)
+ scanner->caps[type].default_format = strdup("image/png");
+ else if (scanner->caps[type].have_jpeg > -1)
+ scanner->caps[type].default_format = strdup("image/jpeg");
+ }
+ free(scanner->caps[type].ColorModes);
+ scanner->caps[type].ColorModes = NULL;
+ scanner->caps[type].ColorModesSize = 0;
+ scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes,
+ &scanner->caps[type].ColorModesSize,
+ (SANE_String_Const)SANE_VALUE_SCAN_MODE_GRAY, 0);
+ scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes,
+ &scanner->caps[type].ColorModesSize,
+ (SANE_String_Const)SANE_VALUE_SCAN_MODE_COLOR, 0);
+ }
+ }
+ }
+}
+
/**
* \fn capabilities_t *escl_capabilities(const ESCL_Device *device, SANE_Status *status)
* \brief Function that finally recovers all the capabilities of the scanner, using curl.
@@ -463,15 +523,17 @@ _reduce_color_modes(capabilities_t *scanner)
* \return scanner (the structure that stocks all the capabilities elements)
*/
capabilities_t *
-escl_capabilities(ESCL_Device *device, SANE_Status *status)
+escl_capabilities(ESCL_Device *device, char *blacklist, SANE_Status *status)
{
capabilities_t *scanner = (capabilities_t*)calloc(1, sizeof(capabilities_t));
CURL *curl_handle = NULL;
struct cap *var = NULL;
+ struct cap *header = NULL;
xmlDoc *data = NULL;
xmlNode *node = NULL;
int i = 0;
const char *scanner_capabilities = "/eSCL/ScannerCapabilities";
+ SANE_Bool use_pdf = SANE_TRUE;
*status = SANE_STATUS_GOOD;
if (device == NULL)
@@ -481,11 +543,22 @@ escl_capabilities(ESCL_Device *device, SANE_Status *status)
*status = SANE_STATUS_NO_MEM;
var->memory = malloc(1);
var->size = 0;
+ header = (struct cap *)calloc(1, sizeof(struct cap));
+ if (header == NULL)
+ *status = SANE_STATUS_NO_MEM;
+ header->memory = malloc(1);
+ header->size = 0;
curl_handle = curl_easy_init();
escl_curl_url(curl_handle, device, scanner_capabilities);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_c);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var);
+ curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback);
+ curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)header);
+ curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
CURLcode res = curl_easy_perform(curl_handle);
+ if (res == CURLE_OK)
+ DBG( 1, "Create NewJob : the scanner header responded : [%s]\n", header->memory);
if (res != CURLE_OK) {
DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
*status = SANE_STATUS_INVAL;
@@ -503,18 +576,46 @@ escl_capabilities(ESCL_Device *device, SANE_Status *status)
goto clean;
}
+ if (device->hack &&
+ header &&
+ header->memory &&
+ strstr(header->memory, "Server: HP_Compact_Server"))
+ device->hack = curl_slist_append(NULL, "Host: localhost");
+
scanner->source = 0;
scanner->Sources = (SANE_String_Const *)malloc(sizeof(SANE_String_Const) * 4);
for (i = 0; i < 4; i++)
scanner->Sources[i] = NULL;
print_xml_c(node, device, scanner, -1);
- _reduce_color_modes(scanner);
+ DBG (3, "1-blacklist_pdf: %s\n", (use_pdf ? "TRUE" : "FALSE") );
+ if (device->model_name != NULL) {
+ if (strcasestr(device->model_name, "MFC-J985DW")) {
+ DBG (3, "blacklist_pdf: device not support PDF\n");
+ use_pdf = SANE_FALSE;
+ }
+ else if (blacklist) {
+ char *model = strdup(device->model_name);
+ replace_char(model, ' ', '_');
+ if (strcasestr(blacklist, model)) {
+ use_pdf = SANE_FALSE;
+ }
+ free(model);
+ }
+ }
+ DBG (3, "1-blacklist_pdf: %s\n", (use_pdf ? "TRUE" : "FALSE") );
+ if (use_pdf)
+ _reduce_color_modes(scanner);
+ else
+ _delete_pdf(scanner);
clean:
xmlFreeDoc(data);
clean_data:
xmlCleanupParser();
xmlMemoryDump();
curl_easy_cleanup(curl_handle);
+ if (header)
+ free(header->memory);
+ free(header);
if (var)
free(var->memory);
free(var);