• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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