Hi,
> Is there a way for "scanimage --batch-prompt ..." to poll the button on
> the front of the scanner instead of waiting for RETURN?
>
> In gscan2pdf I can see the button sensor activate when I press the
> button (and refresh the scanner list with the button held down) but I
> can't see it in xsane or with "scanimage -A".
>
> I'm happy to start the program manually (rather than using scanbd or
> scanbuttond) but it'd be nice if I can then just load the hopper and
> press the button on the scanner for each batch.
>
> Maybe it would be better to have a scanimage option which just blocks
> until the button (chosen with command line flags?) is pressed
Please find a patch to scanimage.c attached.
This patch adds the "--sensor-trap" and "-s" options.
With no arguments this option prints the status of all the sensors as
per the "-A" option. When the name of the sensor is given as the option
argument it waits for that sensor to change state before proceeding as
normal. i.e. it scans with the supplied options unless "-n" is present,
in which case it exits with success.
I have tested this on the Fujitsu ScanSnap iX500.
With the "--sensor-trap=scan" option it waits until the button up event
on the front panel button before proceeding (provided the button is not
held down when scanimage is run).
With the "--sensor-trap=page-loaded" option it waits for a piece of
paper to be placed in the hopper before immediately scanning it.
Interestingly, if the hopper contains a piece of paper when scanimage is
invoked then it immediately scans it otherwise it waits until the page
is inserted and then scans it. I'm not sure if this will be the case for
all scanners.
There are a couple of issues that might require further attention:
I'm not sure if the signal handler initialisation is in the correct
place: If I Ctrl-C the binary whilst it is waiting for the state change
then it can't stop the scanner on the first try and aborts on the second.
I'm not sure if the indenting or function signature styles are correct.
Regards,
@ndy
--
[email protected]
http://www.ashurst.eu.org/
0x7EBA75FF
--- sane-backends-1.0.24-orig/frontend/scanimage.c 2013-08-25 22:22:58.000000000 +0100
+++ sane-backends-1.0.24/frontend/scanimage.c 2014-12-28 20:32:21.660511618 +0000
@@ -100,13 +100,14 @@ static struct option basic_options[] = {
{"accept-md5-only", no_argument, NULL, OPTION_MD5},
{"icc-profile", required_argument, NULL, 'i'},
{"dont-scan", no_argument, NULL, 'n'},
+ {"sensor-trap", optional_argument, NULL, 's'},
{0, 0, NULL, 0}
};
#define OUTPUT_PNM 0
#define OUTPUT_TIFF 1
-#define BASE_OPTSTRING "d:hi:Lf:B::nvVTAbp"
+#define BASE_OPTSTRING "d:hi:Lf:B::nvVTAbps"
#define STRIP_HEIGHT 256 /* # lines we increment image height */
static struct option *all_options;
@@ -1696,6 +1697,90 @@ static void print_options(SANE_Device *
fputc ('\n', stdout);
}
+static void print_sensors(SANE_Device * device, SANE_Int num_dev_options,
+ const char * sensor_name)
+{
+ int i, j, flag;
+ const SANE_Option_Descriptor *opt;
+
+ flag = 0;
+
+ for (i = 1; i < num_dev_options; ++i)
+ {
+ opt = 0;
+
+ /* scan area uses modified option struct */
+ for (j = 0; j < 4; ++j)
+ if (i == window[j])
+ opt = window_option + j;
+
+ if (!opt)
+ opt = sane_get_option_descriptor (device, i);
+
+ if (opt->type == SANE_TYPE_GROUP) {
+ if (strcmp (opt->name, SANE_NAME_SENSORS) == 0) {
+ flag = 1;
+ } else {
+ flag = 0;
+ }
+ }
+
+ if (flag && (!sensor_name || (strcmp(opt->name, sensor_name) == 0)))
+ print_option (device, i, opt);
+ }
+ if (num_dev_options)
+ fputc ('\n', stdout);
+}
+
+SANE_Status
+find_sensor(SANE_Device * device, SANE_Int num_dev_options,
+ const char * sensor_name,
+ SANE_Int * opt_num, const SANE_Option_Descriptor ** opt_p)
+{
+ SANE_Int dummy_opt_num = 0;
+ const SANE_Option_Descriptor *opt;
+
+ if (opt_num == 0)
+ opt_num = &dummy_opt_num;
+
+ if(opt_p == 0)
+ opt_p = &opt;
+
+ int i, j, flag;
+
+ flag = 0;
+
+ for (i = 1; i < num_dev_options; ++i)
+ {
+ opt = 0;
+
+ /* scan area uses modified option struct */
+ for (j = 0; j < 4; ++j)
+ if (i == window[j])
+ opt = window_option + j;
+
+ if (!opt)
+ opt = sane_get_option_descriptor (device, i);
+
+ if (opt->type == SANE_TYPE_GROUP) {
+ if (strcmp (opt->name, SANE_NAME_SENSORS) == 0) {
+ flag = 1;
+ } else {
+ flag = 0;
+ }
+ }
+
+ if (flag && sensor_name && (strcmp(opt->name, sensor_name) == 0))
+ {
+ *opt_p = opt;
+ *opt_num = i;
+ return SANE_STATUS_GOOD;
+ }
+ }
+
+ return SANE_STATUS_UNSUPPORTED;
+}
+
int
main (int argc, char **argv)
{
@@ -1705,6 +1790,7 @@ main (int argc, char **argv)
const char *devname = 0;
const char *defdevname = 0;
const char *format = 0;
+ const char* sensor_name = 0;
char readbuf[2];
char *readbuf2;
int batch = 0;
@@ -1712,6 +1798,7 @@ main (int argc, char **argv)
int batch_count = BATCH_COUNT_UNLIMITED;
int batch_start_at = 1;
int batch_increment = 1;
+ int sensor_trap = 0;
SANE_Status status;
char *full_optstring;
SANE_Int version_code;
@@ -1922,6 +2009,10 @@ main (int argc, char **argv)
printf ("default device is `%s'\n", defdevname);
exit (0);
}
+ case 's':
+ sensor_trap = 1;
+ sensor_name = optarg;
+ break;
case 'V':
printf ("scanimage (%s) %s; backend version %d.%d.%d\n", PACKAGE,
@@ -2210,12 +2301,6 @@ List of available devices:", prog_name);
exit (0);
}
- if (dont_scan)
- exit (0);
-
- if (output_format != OUTPUT_PNM)
- resolution_value = get_resolution ();
-
#ifdef SIGHUP
signal (SIGHUP, sighandler);
#endif
@@ -2225,6 +2310,51 @@ List of available devices:", prog_name);
signal (SIGINT, sighandler);
signal (SIGTERM, sighandler);
+ if (sensor_trap)
+ {
+ if (sensor_name)
+ {
+ SANE_Status status = SANE_STATUS_GOOD;
+ SANE_Int opt_num = 0;
+ const SANE_Option_Descriptor * opt;
+
+ status = find_sensor(device, num_dev_options, sensor_name, &opt_num, &opt);
+
+ if (status != SANE_STATUS_GOOD)
+ {
+ fprintf (stderr, "Can't find sensor %s\n", sensor_name);
+ exit (1);
+ }
+ else
+ {
+ void *orig_val = alloca (opt->size);
+ void *curr_val = alloca (opt->size);
+
+ fprintf (stderr, "Waiting for %s sensor to change state...\n",
+ sensor_name);
+
+ sane_control_option (device, opt_num, SANE_ACTION_GET_VALUE, orig_val, 0);
+
+ do
+ {
+ sane_control_option (device, opt_num, SANE_ACTION_GET_VALUE,
+ curr_val,0);
+ }
+ while (memcmp(orig_val, curr_val, opt->size) == 0);
+ }
+ }
+ else
+ {
+ print_sensors(device, num_dev_options, 0);
+ }
+ }
+
+ if (dont_scan)
+ exit (0);
+
+ if (output_format != OUTPUT_PNM)
+ resolution_value = get_resolution ();
+
if (test == 0)
{
int n = batch_start_at;
--
sane-devel mailing list: [email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel
Unsubscribe: Send mail with subject "unsubscribe your_password"
to [email protected]