1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 1997 Geoffrey T. Dairiki
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 This file is part of a SANE backend for HP Scanners supporting
40 HP Scanner Control Language (SCL).
41 */
42
43 /* #define STUBS
44 extern int sanei_debug_hp; */
45 #define DEBUG_DECLARE_ONLY
46 #include "../include/sane/config.h"
47
48 #ifdef HAVE_UNISTD_H
49 # include <unistd.h>
50 #endif
51 #include <string.h>
52 #include <signal.h>
53 #include "../include/lassert.h"
54 #include <errno.h>
55 #include <fcntl.h>
56 #include <sys/wait.h>
57
58 #include "hp-handle.h"
59
60 #include "../include/sane/sanei_backend.h"
61 #include "../include/sane/sanei_thread.h"
62
63 #include "hp-device.h"
64 #include "hp-option.h"
65 #include "hp-accessor.h"
66 #include "hp-scsi.h"
67 #include "hp-scl.h"
68
69 struct hp_handle_s
70 {
71 HpData data;
72 HpDevice dev;
73 SANE_Parameters scan_params;
74
75 SANE_Pid reader_pid;
76 int child_forked; /* Flag if we used fork() or not */
77 size_t bytes_left;
78 int pipe_read_fd;
79 sigset_t sig_set;
80
81 sig_atomic_t cancelled;
82
83 /* These data are used by the child */
84 HpScsi scsi;
85 HpProcessData procdata;
86 int pipe_write_fd;
87 };
88
89
90 static hp_bool_t
hp_handle_isScanning(HpHandle this)91 hp_handle_isScanning (HpHandle this)
92 {
93 return this->reader_pid != 0;
94 }
95
96 /*
97 * reader thread. Used when threads are used
98 */
99 static int
reader_thread(void * data)100 reader_thread (void *data)
101 {
102 struct hp_handle_s *this = (struct hp_handle_s *) data;
103 struct SIGACTION act;
104 SANE_Status status;
105
106 DBG (1, "reader_thread: thread started\n"
107 " parameters: scsi = 0x%08lx, pipe_write_fd = %d\n",
108 (long) this->scsi, this->pipe_write_fd);
109
110 memset(&act, 0, sizeof(act));
111 sigaction(SIGTERM, &act, 0);
112
113 DBG (1, "Starting sanei_hp_scsi_pipeout()\n");
114 status = sanei_hp_scsi_pipeout (this->scsi, this->pipe_write_fd,
115 &(this->procdata));
116 DBG (1, "sanei_hp_scsi_pipeout finished with %s\n", sane_strstatus (status));
117
118 close (this->pipe_write_fd);
119 this->pipe_write_fd = -1;
120 sanei_hp_scsi_destroy (this->scsi, 0);
121 return status;
122 }
123
124 /*
125 * reader process. Used when forking child.
126 */
127 static int
reader_process(void * data)128 reader_process (void *data)
129 {
130 struct hp_handle_s *this = (struct hp_handle_s *) data;
131 struct SIGACTION sa;
132 SANE_Status status;
133
134 /* Here we are in a forked child. The thread will not come up to here. */
135 /* Forked child must close read end of pipe */
136 close (this->pipe_read_fd);
137 this->pipe_read_fd = -1;
138
139 memset(&sa, 0, sizeof(sa));
140 sa.sa_handler = SIG_DFL;
141 sigaction(SIGTERM, &sa, 0);
142 sigdelset(&(this->sig_set), SIGTERM);
143 sigprocmask(SIG_SETMASK, &(this->sig_set), 0);
144
145 /* not closing writing end of pipe gives an infinite loop on Digital UNIX */
146 status = sanei_hp_scsi_pipeout (this->scsi, this->pipe_write_fd,
147 &(this->procdata));
148 close (this->pipe_write_fd);
149 this->pipe_write_fd = -1;
150 DBG(3,"reader_process: Exiting child (%s)\n",sane_strstatus(status));
151 return (status);
152 }
153
154 static SANE_Status
hp_handle_startReader(HpHandle this,HpScsi scsi)155 hp_handle_startReader (HpHandle this, HpScsi scsi)
156 {
157 int fds[2];
158 sigset_t old_set;
159
160 assert(this->reader_pid == 0);
161 this->cancelled = 0;
162 this->pipe_write_fd = this->pipe_read_fd = -1;
163
164 if (pipe(fds))
165 return SANE_STATUS_IO_ERROR;
166
167 sigfillset(&(this->sig_set));
168 sigprocmask(SIG_BLOCK, &(this->sig_set), &old_set);
169
170 this->scsi = scsi;
171 this->pipe_write_fd = fds[1];
172 this->pipe_read_fd = fds[0];
173
174 /* Will child be forked ? */
175 this->child_forked = sanei_thread_is_forked ();
176
177 /* Start a thread or fork a child. None of them will return here. */
178 /* Returning means to be in the parent or thread/fork failed */
179 this->reader_pid = sanei_thread_begin (this->child_forked ? reader_process :
180 reader_thread, (void *) this);
181 if (this->reader_pid != 0)
182 {
183 /* Here we are in the parent */
184 sigprocmask(SIG_SETMASK, &old_set, 0);
185
186 if ( this->child_forked )
187 { /* After fork(), parent must close writing end of pipe */
188 DBG(3, "hp_handle_startReader: parent closes write end of pipe\n");
189 close (this->pipe_write_fd);
190 this->pipe_write_fd = -1;
191 }
192
193 if (!sanei_thread_is_valid (this->reader_pid))
194 {
195 if ( !this->child_forked )
196 {
197 close (this->pipe_write_fd);
198 this->pipe_write_fd = -1;
199 }
200 close (this->pipe_read_fd);
201 this->pipe_read_fd = -1;
202
203 DBG(1, "hp_handle_startReader: fork() failed\n");
204
205 return SANE_STATUS_IO_ERROR;
206 }
207
208 DBG(1, "start_reader: reader process %ld started\n", (long) this->reader_pid);
209 return SANE_STATUS_GOOD;
210 }
211
212 DBG(3, "Unexpected return from sanei_thread_begin()\n");
213 return SANE_STATUS_INVAL;
214 }
215
216 static SANE_Status
hp_handle_stopScan(HpHandle this)217 hp_handle_stopScan (HpHandle this)
218 {
219 HpScsi scsi;
220
221 this->cancelled = 0;
222 this->bytes_left = 0;
223
224 if (this->reader_pid)
225 {
226 int info;
227 DBG(3, "hp_handle_stopScan: killing child (%ld)\n", (long) this->reader_pid);
228 sanei_thread_kill (this->reader_pid);
229 sanei_thread_waitpid(this->reader_pid, &info);
230
231 DBG(1, "hp_handle_stopScan: child %s = %d\n",
232 WIFEXITED(info) ? "exited, status" : "signalled, signal",
233 WIFEXITED(info) ? WEXITSTATUS(info) : WTERMSIG(info));
234 close(this->pipe_read_fd);
235 this->reader_pid = 0;
236
237 if ( !FAILED( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name)) )
238 {
239 if (WIFSIGNALED(info))
240 {
241 /*
242 sanei_hp_scl_set(scsi, SCL_CLEAR_ERRORS, 0);
243 sanei_hp_scl_errcheck(scsi);
244 */
245 sanei_hp_scl_reset(scsi);
246 }
247 sanei_hp_scsi_destroy(scsi,0);
248 }
249 }
250 else
251 {
252 DBG(3, "hp_handle_stopScan: no pid for child\n");
253 }
254 return SANE_STATUS_GOOD;
255 }
256
257 static SANE_Status
hp_handle_uploadParameters(HpHandle this,HpScsi scsi,int * scan_depth,hp_bool_t * soft_invert,hp_bool_t * out8)258 hp_handle_uploadParameters (HpHandle this, HpScsi scsi, int *scan_depth,
259 hp_bool_t *soft_invert, hp_bool_t *out8)
260 {
261 SANE_Parameters * p = &this->scan_params;
262 int data_width;
263 enum hp_device_compat_e compat;
264
265 assert(scsi);
266
267 *soft_invert = 0;
268 *out8 = 0;
269
270 p->last_frame = SANE_TRUE;
271 /* inquire resulting size of image after setting it up */
272 RETURN_IF_FAIL( sanei_hp_scl_inquire(scsi, SCL_PIXELS_PER_LINE,
273 &p->pixels_per_line,0,0) );
274 RETURN_IF_FAIL( sanei_hp_scl_inquire(scsi, SCL_BYTES_PER_LINE,
275 &p->bytes_per_line,0,0) );
276 RETURN_IF_FAIL( sanei_hp_scl_inquire(scsi, SCL_NUMBER_OF_LINES,
277 &p->lines,0,0));
278 RETURN_IF_FAIL( sanei_hp_scl_inquire(scsi, SCL_DATA_WIDTH,
279 &data_width,0,0));
280
281 switch (sanei_hp_optset_scanmode(this->dev->options, this->data)) {
282 case HP_SCANMODE_LINEART: /* Lineart */
283 case HP_SCANMODE_HALFTONE: /* Halftone */
284 p->format = SANE_FRAME_GRAY;
285 p->depth = 1;
286 *scan_depth = 1;
287
288 /* The OfficeJets don't seem to handle SCL_INVERSE_IMAGE, so we'll
289 * have to invert in software. */
290 if ((sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD)
291 && (compat & HP_COMPAT_OJ_1150C)) {
292 *soft_invert=1;
293 }
294
295 break;
296 case HP_SCANMODE_GRAYSCALE: /* Grayscale */
297 p->format = SANE_FRAME_GRAY;
298 p->depth = (data_width > 8) ? 16 : 8;
299 *scan_depth = data_width;
300
301 /* 8 bit output forced ? */
302 if ( *scan_depth > 8 )
303 {
304 *out8 = sanei_hp_optset_output_8bit (this->dev->options, this->data);
305 DBG(1,"hp_handle_uploadParameters: out8=%d\n", (int)*out8);
306 if (*out8)
307 {
308 p->depth = 8;
309 p->bytes_per_line /= 2;
310 }
311 }
312 break;
313 case HP_SCANMODE_COLOR: /* RGB */
314 p->format = SANE_FRAME_RGB;
315 p->depth = (data_width > 24) ? 16 : 8;
316 *scan_depth = data_width / 3;
317
318 /* 8 bit output forced ? */
319 if ( *scan_depth > 8 )
320 {
321 *out8 = sanei_hp_optset_output_8bit (this->dev->options, this->data);
322 DBG(1,"hp_handle_uploadParameters: out8=%d\n", (int)*out8);
323 if (*out8)
324 {
325 p->depth = 8;
326 p->bytes_per_line /= 2;
327 }
328 }
329 /* HP PhotoSmart does not invert when depth > 8. Lets do it by software */
330 if ( (*scan_depth > 8)
331 && (sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD)
332 && (compat & HP_COMPAT_PS) )
333 *soft_invert = 1;
334 DBG(1, "hp_handle_uploadParameters: data width %d\n", data_width);
335 break;
336 default:
337 assert(!"Aack");
338 return SANE_STATUS_INVAL;
339 }
340
341 return SANE_STATUS_GOOD;
342 }
343
344
345
346 HpHandle
sanei_hp_handle_new(HpDevice dev)347 sanei_hp_handle_new (HpDevice dev)
348 {
349 HpHandle new = sanei_hp_allocz(sizeof(*new));
350
351 if (!new)
352 return 0;
353
354 if (!(new->data = sanei_hp_data_dup(dev->data)))
355 {
356 sanei_hp_free(new);
357 return 0;
358 }
359
360 new->dev = dev;
361 return new;
362 }
363
364 void
sanei_hp_handle_destroy(HpHandle this)365 sanei_hp_handle_destroy (HpHandle this)
366 {
367 HpScsi scsi=0;
368
369 DBG(3,"sanei_hp_handle_destroy: stop scan\n");
370
371 hp_handle_stopScan(this);
372
373 if (sanei_hp_scsi_new(&scsi,this->dev->sanedev.name)==SANE_STATUS_GOOD &&
374 scsi) {
375 sanei_hp_scsi_destroy(scsi,1);
376 }
377
378 sanei_hp_data_destroy(this->data);
379 sanei_hp_free(this);
380 }
381
382 const SANE_Option_Descriptor *
sanei_hp_handle_saneoption(HpHandle this,SANE_Int optnum)383 sanei_hp_handle_saneoption (HpHandle this, SANE_Int optnum)
384 {
385 if (this->cancelled)
386 {
387 DBG(1, "sanei_hp_handle_saneoption: cancelled. Stop scan\n");
388 hp_handle_stopScan(this);
389 }
390 return sanei_hp_optset_saneoption(this->dev->options, this->data, optnum);
391 }
392
393 SANE_Status
sanei_hp_handle_control(HpHandle this,SANE_Int optnum,SANE_Action action,void * valp,SANE_Int * info)394 sanei_hp_handle_control(HpHandle this, SANE_Int optnum,
395 SANE_Action action, void *valp, SANE_Int *info)
396 {
397 SANE_Status status;
398 HpScsi scsi;
399 hp_bool_t immediate;
400
401 if (this->cancelled)
402 {
403 DBG(1, "sanei_hp_handle_control: cancelled. Stop scan\n");
404 RETURN_IF_FAIL( hp_handle_stopScan(this) );
405 }
406
407 if (hp_handle_isScanning(this))
408 return SANE_STATUS_DEVICE_BUSY;
409
410 RETURN_IF_FAIL( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name) );
411
412 immediate = sanei_hp_optset_isImmediate(this->dev->options, optnum);
413
414 status = sanei_hp_optset_control(this->dev->options, this->data,
415 optnum, action, valp, info, scsi,
416 immediate);
417 sanei_hp_scsi_destroy ( scsi,0 );
418
419 return status;
420 }
421
422 SANE_Status
sanei_hp_handle_getParameters(HpHandle this,SANE_Parameters * params)423 sanei_hp_handle_getParameters (HpHandle this, SANE_Parameters *params)
424 {
425 SANE_Status status;
426
427 if (!params)
428 return SANE_STATUS_GOOD;
429
430 if (this->cancelled)
431 {
432 DBG(1, "sanei_hp_handle_getParameters: cancelled. Stop scan\n");
433 RETURN_IF_FAIL( hp_handle_stopScan(this) );
434 }
435
436 if (hp_handle_isScanning(this))
437 {
438 *params = this->scan_params;
439 return SANE_STATUS_GOOD;
440 }
441
442 status = sanei_hp_optset_guessParameters(this->dev->options,
443 this->data, params);
444 #ifdef INQUIRE_AFTER_SCAN
445 /* Photosmart: this gives the correct number of lines when doing
446 an update of the SANE parameters right after a preview */
447 if (!strcmp("C5100A", this->dev->sanedev.model)) {
448 HpScsi scsi;
449 SANE_Parameters * p = &this->scan_params;
450
451 if (!FAILED( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name) )) {
452 RETURN_IF_FAIL( sanei_hp_scl_inquire(scsi, SCL_NUMBER_OF_LINES,
453 &p->lines,0,0));
454 sanei_hp_scsi_destroy(scsi,0);
455 *params = this->scan_params;
456 }
457 }
458 #endif
459 return status;
460 }
461
462 SANE_Status
sanei_hp_handle_startScan(HpHandle this)463 sanei_hp_handle_startScan (HpHandle this)
464 {
465 SANE_Status status;
466 HpScsi scsi;
467 HpScl scl;
468 HpProcessData *procdata = &(this->procdata);
469 int adfscan;
470
471 /* FIXME: setup preview mode stuff? */
472
473 if (hp_handle_isScanning(this))
474 {
475 DBG(3,"sanei_hp_handle_startScan: Stop current scan\n");
476 RETURN_IF_FAIL( hp_handle_stopScan(this) );
477 }
478
479 RETURN_IF_FAIL( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name) );
480
481 status = sanei_hp_optset_download(this->dev->options, this->data, scsi);
482
483 if (!FAILED(status))
484 status = hp_handle_uploadParameters(this, scsi,
485 &(procdata->bits_per_channel),
486 &(procdata->invert),
487 &(procdata->out8));
488
489 if (FAILED(status))
490 {
491 sanei_hp_scsi_destroy(scsi,0);
492 return status;
493 }
494
495 procdata->mirror_vertical =
496 sanei_hp_optset_mirror_vert (this->dev->options, this->data, scsi);
497 DBG(1, "start: %s to mirror image vertically\n", procdata->mirror_vertical ?
498 "Request" : "No request" );
499
500 scl = sanei_hp_optset_scan_type (this->dev->options, this->data);
501 adfscan = (scl == SCL_ADF_SCAN);
502
503 /* For ADF scan we should check if there is paper available */
504 if ( adfscan )
505 {int adfstat = 0;
506 int can_check_paper = 0;
507 int is_flatbed = 0;
508 int minval, maxval;
509
510 /* For ADF-support, we have three different types of scanners:
511 * ScanJet, ScanJet+, IIp, 3p:
512 * scroll feed, no support for inquire paper in ADF, unload document
513 * and preload document
514 * IIc, IIcx, 3c, 4c, 6100C, 4p:
515 * flatbed, no support for preload document
516 * 5100C, 5200C, 6200C, 6300C:
517 * scroll feed.
518 * For all scroll feed types, we use the usual scan window command.
519 * For flatbed types, use a sequence of special commands.
520 */
521
522 /* Check the IIp group */
523 if ( (sanei_hp_device_support_get (this->dev->sanedev.name,
524 SCL_UNLOAD, &minval, &maxval)
525 != SANE_STATUS_GOOD )
526 && (sanei_hp_device_support_get (this->dev->sanedev.name,
527 SCL_CHANGE_DOC, &minval, &maxval)
528 != SANE_STATUS_GOOD ) )
529 {
530 DBG(3, "start: Request for ADF scan without support of unload doc\n");
531 DBG(3, " and change doc. Seems to be something like a IIp.\n");
532 DBG(3, " Use standard scan window command.\n");
533
534 scl = SCL_START_SCAN;
535 can_check_paper = 0;
536 is_flatbed = 0;
537 }
538 /*
539 else if ( sanei_hp_device_support_get (this->dev->sanedev.name,
540 SCL_PRELOAD_ADF, &minval, &maxval)
541 != SANE_STATUS_GOOD )
542 */
543 else if ( sanei_hp_is_flatbed_adf (scsi) )
544 {
545 DBG(3, "start: Request for ADF scan without support of preload doc.\n");
546 DBG(3, " Seems to be a flatbed ADF.\n");
547 DBG(3, " Use ADF scan window command.\n");
548
549 can_check_paper = 1;
550 is_flatbed = 1;
551 }
552 else
553 {
554 DBG(3, "start: Request for ADF scan with support of preload doc.\n");
555 DBG(3, " Seems to be a scroll feed ADF.\n");
556 DBG(3, " Use standard scan window command.\n");
557
558 scl = SCL_START_SCAN;
559 can_check_paper = 1;
560 is_flatbed = 0;
561 }
562
563 /* Check if the ADF is ready */
564 if ( sanei_hp_scl_inquire(scsi, SCL_ADF_READY, &adfstat, 0, 0)
565 != SANE_STATUS_GOOD )
566 {
567 DBG(1, "start: Error checking if ADF is ready\n");
568 sanei_hp_scsi_destroy(scsi,0);
569 return SANE_STATUS_UNSUPPORTED;
570 }
571
572 if ( adfstat != 1 )
573 {
574 DBG(1, "start: ADF is not ready. Finished.\n");
575 sanei_hp_scsi_destroy(scsi,0);
576 return SANE_STATUS_NO_DOCS;
577 }
578
579 /* Check paper in ADF */
580 if ( can_check_paper )
581 {
582 if ( sanei_hp_scl_inquire(scsi, SCL_ADF_BIN, &adfstat, 0, 0)
583 != SANE_STATUS_GOOD )
584 {
585 DBG(1, "start: Error checking if paper in ADF\n");
586 sanei_hp_scsi_destroy(scsi,0);
587 return SANE_STATUS_UNSUPPORTED;
588 }
589
590 if ( adfstat != 1 )
591 {
592 DBG(1, "start: No paper in ADF bin. Finished.\n");
593 sanei_hp_scsi_destroy(scsi,0);
594 return SANE_STATUS_NO_DOCS;
595 }
596
597 if ( is_flatbed )
598 {
599 if ( sanei_hp_scl_set(scsi, SCL_CHANGE_DOC, 0) != SANE_STATUS_GOOD )
600 {
601 DBG(1, "start: Error changing document\n");
602 sanei_hp_scsi_destroy(scsi,0);
603 return SANE_STATUS_UNSUPPORTED;
604 }
605 }
606 }
607 }
608
609 DBG(1, "start: %s to mirror image vertically\n", procdata->mirror_vertical ?
610 "Request" : "No request" );
611
612 this->bytes_left = ( this->scan_params.bytes_per_line
613 * this->scan_params.lines );
614
615 DBG(1, "start: %d pixels per line, %d bytes per line, %d lines high\n",
616 this->scan_params.pixels_per_line, this->scan_params.bytes_per_line,
617 this->scan_params.lines);
618 procdata->bytes_per_line = (int)this->scan_params.bytes_per_line;
619 if (procdata->out8)
620 {
621 procdata->bytes_per_line *= 2;
622 DBG(1,"(scanner will send %d bytes per line, 8 bit output forced)\n",
623 procdata->bytes_per_line);
624 }
625 procdata->lines = this->scan_params.lines;
626
627 /* Wait for front-panel button push ? */
628 status = sanei_hp_optset_start_wait(this->dev->options, this->data);
629
630 if (status) /* Wait for front button push ? Start scan in reader process */
631 {
632 procdata->startscan = scl;
633 status = SANE_STATUS_GOOD;
634 }
635 else
636 {
637 procdata->startscan = 0;
638 status = sanei_hp_scl_startScan(scsi, scl);
639 }
640
641 if (!FAILED( status ))
642 {
643 status = hp_handle_startReader(this, scsi);
644 }
645
646 /* Close SCSI-connection in forked environment */
647 if (this->child_forked)
648 sanei_hp_scsi_destroy(scsi,0);
649
650 return status;
651 }
652
653
654 SANE_Status
sanei_hp_handle_read(HpHandle this,void * buf,size_t * lengthp)655 sanei_hp_handle_read (HpHandle this, void * buf, size_t *lengthp)
656 {
657 ssize_t nread;
658 SANE_Status status;
659
660 DBG(3, "sanei_hp_handle_read: trying to read %lu bytes\n",
661 (unsigned long) *lengthp);
662
663 if (!hp_handle_isScanning(this))
664 {
665 DBG(1, "sanei_hp_handle_read: not scanning\n");
666 return SANE_STATUS_INVAL;
667 }
668
669 if (this->cancelled)
670 {
671 DBG(1, "sanei_hp_handle_read: cancelled. Stop scan\n");
672 RETURN_IF_FAIL( hp_handle_stopScan(this) );
673 return SANE_STATUS_CANCELLED;
674 }
675
676 if (*lengthp == 0)
677 return SANE_STATUS_GOOD;
678
679 if (*lengthp > this->bytes_left)
680 *lengthp = this->bytes_left;
681
682 if ((nread = read(this->pipe_read_fd, buf, *lengthp)) < 0)
683 {
684 *lengthp = 0;
685 if (errno == EAGAIN)
686 return SANE_STATUS_GOOD;
687 DBG(1, "sanei_hp_handle_read: read from pipe: %s. Stop scan\n",
688 strerror(errno));
689 hp_handle_stopScan(this);
690 return SANE_STATUS_IO_ERROR;
691 }
692
693 this->bytes_left -= (*lengthp = nread);
694
695 if (nread > 0)
696 {
697 DBG(3, "sanei_hp_handle_read: read %lu bytes\n", (unsigned long) nread);
698 return SANE_STATUS_GOOD;
699 }
700
701 DBG(1, "sanei_hp_handle_read: EOF from pipe. Stop scan\n");
702 status = this->bytes_left ? SANE_STATUS_IO_ERROR : SANE_STATUS_EOF;
703 RETURN_IF_FAIL( hp_handle_stopScan(this) );
704
705 /* Switch off lamp and check unload after scan */
706 if (status == SANE_STATUS_EOF)
707 {
708 const HpDeviceInfo *hpinfo;
709 HpScsi scsi;
710
711 if ( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name) == SANE_STATUS_GOOD )
712 {
713 hpinfo = sanei_hp_device_info_get ( this->dev->sanedev.name );
714
715 if ( hpinfo )
716 {
717 if ( hpinfo->unload_after_scan )
718 sanei_hp_scl_set(scsi, SCL_UNLOAD, 0);
719 }
720
721 sanei_hp_scsi_destroy(scsi,0);
722 }
723 }
724 return status;
725 }
726
727 void
sanei_hp_handle_cancel(HpHandle this)728 sanei_hp_handle_cancel (HpHandle this)
729 {
730 this->cancelled = 1;
731 /* The OfficeJet K series may not deliver enough data. */
732 /* Therefore the read might not return until it is interrupted. */
733 DBG(3,"sanei_hp_handle_cancel: compat flags: 0x%04x\n",
734 (int)this->dev->compat);
735 if ( (this->reader_pid)
736 && (this->dev->compat & HP_COMPAT_OJ_1150C) )
737 {
738 DBG(3,"sanei_hp_handle_cancel: send SIGTERM to child (%ld)\n",
739 (long) this->reader_pid);
740 sanei_thread_kill(this->reader_pid);
741 }
742 }
743
744 SANE_Status
sanei_hp_handle_setNonblocking(HpHandle this,hp_bool_t non_blocking)745 sanei_hp_handle_setNonblocking (HpHandle this, hp_bool_t non_blocking)
746 {
747 if (!hp_handle_isScanning(this))
748 return SANE_STATUS_INVAL;
749
750 if (this->cancelled)
751 {
752 DBG(3,"sanei_hp_handle_setNonblocking: cancelled. Stop scan\n");
753 RETURN_IF_FAIL( hp_handle_stopScan(this) );
754 return SANE_STATUS_CANCELLED;
755 }
756
757 if (fcntl(this->pipe_read_fd, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
758 return SANE_STATUS_IO_ERROR;
759
760 return SANE_STATUS_GOOD;
761 }
762
763 SANE_Status
sanei_hp_handle_getPipefd(HpHandle this,SANE_Int * fd)764 sanei_hp_handle_getPipefd (HpHandle this, SANE_Int *fd)
765 {
766 if (! hp_handle_isScanning(this))
767 return SANE_STATUS_INVAL;
768
769 if (this->cancelled)
770 {
771 DBG(3,"sanei_hp_handle_getPipefd: cancelled. Stop scan\n");
772 RETURN_IF_FAIL( hp_handle_stopScan(this) );
773 return SANE_STATUS_CANCELLED;
774 }
775
776 *fd = this->pipe_read_fd;
777 return SANE_STATUS_GOOD;
778 }
779