Commit 63e8d34a authored by Jeremy White's avatar Jeremy White Committed by Alexandre Julliard

twain: Reconcile sane's long names to TWAIN's 32 byte limit.

parent 5b04c3ea
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#define NONAMELESSUNION #define NONAMELESSUNION
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT
...@@ -83,6 +84,40 @@ TW_UINT16 TWAIN_CloseDS (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -83,6 +84,40 @@ TW_UINT16 TWAIN_CloseDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
#endif #endif
} }
/* Sane returns device names that are longer than the 32 bytes allowed
by TWAIN. However, it colon separates them, and the last bit is
the most interesting. So we use the last bit, and add a signature
to ensure uniqueness */
#ifdef HAVE_SANE
static void copy_sane_short_name(const char *in, char *out, size_t outsize)
{
const char *p;
int signature = 0;
if (strlen(in) <= outsize - 1)
{
strcpy(out, in);
return;
}
for (p = in; *p; p++)
signature += *p;
p = strrchr(in, ':');
if (!p)
p = in;
else
p++;
if (strlen(p) > outsize - 7 - 1)
p += strlen(p) - (outsize - 7 - 1);
strcpy(out, p);
sprintf(out + strlen(out), "(%04X)", signature % 0x10000);
}
#endif
/* DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT */ /* DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT */
TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData) TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{ {
...@@ -109,14 +144,16 @@ TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -109,14 +144,16 @@ TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
if (device_list && device_list[0]) if (device_list && device_list[0])
{ {
pSourceIdentity->Id = DSM_sourceId ++; pSourceIdentity->Id = DSM_sourceId ++;
strcpy (pSourceIdentity->ProductName, device_list[0]->name); copy_sane_short_name(device_list[0]->name, pSourceIdentity->ProductName, sizeof(pSourceIdentity->ProductName) - 1);
strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor); TRACE("got: %s (short [%s]), %s, %s\n", device_list[0]->name, pSourceIdentity->ProductName, device_list[0]->vendor, device_list[0]->model);
strcpy (pSourceIdentity->ProductFamily, device_list[0]->model); lstrcpynA (pSourceIdentity->Manufacturer, device_list[0]->vendor, sizeof(pSourceIdentity->Manufacturer) - 1);
lstrcpynA (pSourceIdentity->ProductFamily, device_list[0]->model, sizeof(pSourceIdentity->ProductFamily) - 1);
pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR; pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR; pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
twRC = TWRC_SUCCESS; twRC = TWRC_SUCCESS;
DSM_twCC = TWCC_SUCCESS; DSM_twCC = TWCC_SUCCESS;
} }
else else
{ {
...@@ -146,11 +183,11 @@ TW_UINT16 TWAIN_IdentityGetFirst (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -146,11 +183,11 @@ TW_UINT16 TWAIN_IdentityGetFirst (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{ {
if (device_list[0]) if (device_list[0])
{ {
TRACE("got: %s, %s, %s\n", device_list[0]->name, device_list[0]->vendor, device_list[0]->model);
pSourceIdentity->Id = DSM_sourceId ++; pSourceIdentity->Id = DSM_sourceId ++;
strcpy (pSourceIdentity->ProductName, device_list[0]->name); copy_sane_short_name(device_list[0]->name, pSourceIdentity->ProductName, sizeof(pSourceIdentity->ProductName) - 1);
strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor); TRACE("got: %s (short [%s]), %s, %s\n", device_list[0]->name, pSourceIdentity->ProductName, device_list[0]->vendor, device_list[0]->model);
strcpy (pSourceIdentity->ProductFamily, device_list[0]->model); lstrcpynA (pSourceIdentity->Manufacturer, device_list[0]->vendor, sizeof(pSourceIdentity->Manufacturer) - 1);
lstrcpynA (pSourceIdentity->ProductFamily, device_list[0]->model, sizeof(pSourceIdentity->ProductFamily) - 1);
pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR; pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR; pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
...@@ -199,9 +236,10 @@ TW_UINT16 TWAIN_IdentityGetNext (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -199,9 +236,10 @@ TW_UINT16 TWAIN_IdentityGetNext (pTW_IDENTITY pOrigin, TW_MEMREF pData)
device_list[DSM_currentDevice]->model) device_list[DSM_currentDevice]->model)
{ {
pSourceIdentity->Id = DSM_sourceId ++; pSourceIdentity->Id = DSM_sourceId ++;
strcpy (pSourceIdentity->ProductName, device_list[DSM_currentDevice]->name); copy_sane_short_name(device_list[DSM_currentDevice]->name, pSourceIdentity->ProductName, sizeof(pSourceIdentity->ProductName) - 1);
strcpy (pSourceIdentity->Manufacturer, device_list[DSM_currentDevice]->vendor); TRACE("got: %s (short [%s]), %s, %s\n", device_list[DSM_currentDevice]->name, pSourceIdentity->ProductName, device_list[DSM_currentDevice]->vendor, device_list[DSM_currentDevice]->model);
strcpy (pSourceIdentity->ProductFamily, device_list[DSM_currentDevice]->model); lstrcpynA (pSourceIdentity->Manufacturer, device_list[DSM_currentDevice]->vendor, sizeof(pSourceIdentity->Manufacturer) - 1);
lstrcpynA (pSourceIdentity->ProductFamily, device_list[DSM_currentDevice]->model, sizeof(pSourceIdentity->ProductFamily) - 1);
pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR; pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR; pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
DSM_currentDevice ++; DSM_currentDevice ++;
...@@ -228,6 +266,7 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -228,6 +266,7 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
#else #else
TW_UINT16 twRC = TWRC_SUCCESS, i = 0; TW_UINT16 twRC = TWRC_SUCCESS, i = 0;
pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData; pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
TW_STR32 shortname;
activeDS *newSource; activeDS *newSource;
SANE_Status status; SANE_Status status;
...@@ -251,9 +290,11 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -251,9 +290,11 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
/* Make sure the source to be opened exists in the device list */ /* Make sure the source to be opened exists in the device list */
for (i = 0; device_list[i]; i ++) for (i = 0; device_list[i]; i ++)
{ {
if (strcmp (device_list[i]->name, pIdentity->ProductName) == 0) copy_sane_short_name(device_list[i]->name, shortname, sizeof(shortname) - 1);
if (strcmp (shortname, pIdentity->ProductName) == 0)
break; break;
} }
} }
if (device_list[i]) if (device_list[i])
...@@ -266,7 +307,7 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData) ...@@ -266,7 +307,7 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
/* Assign name and id for the opened data source */ /* Assign name and id for the opened data source */
strcpy (pIdentity->ProductName, device_list[i]->name); lstrcpynA (pIdentity->ProductName, shortname, sizeof(pIdentity->ProductName) - 1);
pIdentity->Id = DSM_sourceId ++; pIdentity->Id = DSM_sourceId ++;
/* add the data source to an internal active source list */ /* add the data source to an internal active source list */
newSource->next = activeSources; newSource->next = activeSources;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment