Tizen 2.1 base
[platform/upstream/hplip.git] / scan / scanext / scanext.c
1 /*******************************************************************
2 scanext - Python extension class for SANE
3
4 Portions (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19
20 Based on:
21 "_sane.c", part of the Python Imaging Library (PIL)
22 http://www.pythonware.com/products/pil/
23
24 Modified to work without PIL by Don Welch
25
26 (C) Copyright 2003 A.M. Kuchling.  All Rights Reserved
27 (C) Copyright 2004 A.M. Kuchling, Ralph Heinkel  All Rights Reserved
28
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of A.M. Kuchling and
34 Ralph Heinkel not be used in advertising or publicity pertaining to
35 distribution of the software without specific, written prior permission.
36
37 A.M. KUCHLING, R.H. HEINKEL DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
38 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
39 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
40 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
41 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
42 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
43 PERFORMANCE OF THIS SOFTWARE.
44
45 *******************************************************************/
46
47
48 /* _ScanDevice objects */
49
50 #include "Python.h"
51 #include "sane.h"
52 #include <sys/time.h>
53
54 static PyObject *ErrorObject;
55
56 typedef struct
57 {
58     PyObject_HEAD SANE_Handle h;
59 } _ScanDevice;
60
61 #ifdef WITH_THREAD
62 PyThreadState *_save;
63 #endif
64
65 /* Raise a SANE exception using a SANE_Status code */
66 PyObject *raiseSaneError (SANE_Status st)
67 {
68     const char *string;
69
70     if (st == SANE_STATUS_GOOD)
71     {
72         Py_INCREF (Py_None);
73         return (Py_None);
74     }
75
76     string = sane_strstatus (st);
77     //PyErr_SetString (ErrorObject, string);
78     PyErr_SetObject(ErrorObject,  PyInt_FromLong(st));
79     return NULL;
80 }
81
82 /* Raise an exception using a character string */
83 PyObject * raiseError(const char * str)
84 {
85     PyErr_SetString (ErrorObject, str);
86     return NULL;
87 }
88
89 /* Raise an exception using a character string */
90 PyObject * raiseDeviceClosedError(void)
91 {
92     return raiseError ("_ScanDevice object is closed");
93 }
94
95 static PyObject *getErrorMessage(PyObject * self, PyObject * args)
96 {
97     int st;
98
99     if (!PyArg_ParseTuple (args, "i", &st))
100         raiseError("Invalid arguments.");
101
102     return Py_BuildValue("s", sane_strstatus (st));
103 }
104
105 staticforward PyTypeObject ScanDevice_type;
106
107 #define SaneDevObject_Check(v)  ((v)->ob_type == &ScanDevice_type)
108
109 static _ScanDevice *newScanDeviceObject (void)
110 {
111     _ScanDevice *self;
112
113     self = PyObject_NEW (_ScanDevice, &ScanDevice_type);
114
115     if (self == NULL)
116         return NULL;
117
118     self->h = NULL;
119     return self;
120 }
121
122
123 /* _ScanDevice methods */
124
125 static void deAlloc (_ScanDevice * self)
126 {
127     if (self->h)
128         sane_close (self->h);
129
130     self->h = NULL;
131     PyObject_DEL (self);
132 }
133
134 static PyObject *closeScan (_ScanDevice * self, PyObject * args)
135 {
136     if (!PyArg_ParseTuple (args, ""))
137         return NULL;
138
139     if (self->h)
140         sane_close (self->h);
141
142     self->h = NULL;
143     Py_INCREF (Py_None);
144     return (Py_None);
145 }
146
147 static PyObject *getParameters (_ScanDevice * self, PyObject * args)
148 {
149     SANE_Status st;
150     SANE_Parameters p;
151     char *format_name = "unknown";
152
153     if (!PyArg_ParseTuple (args, ""))
154         raiseError("Invalid arguments.");
155
156     if (self->h == NULL)
157         return raiseDeviceClosedError();
158
159     Py_BEGIN_ALLOW_THREADS
160     st = sane_get_parameters (self->h, &p);
161     Py_END_ALLOW_THREADS
162
163     if (st != SANE_STATUS_GOOD)
164         return raiseSaneError (st);
165
166     switch (p.format)
167     {
168         case (SANE_FRAME_GRAY):
169             format_name = "gray";
170             break;
171         case (SANE_FRAME_RGB):
172             format_name = "color";
173             break;
174         case (SANE_FRAME_RED):
175             format_name = "red";
176             break;
177         case (SANE_FRAME_GREEN):
178             format_name = "green";
179             break;
180         case (SANE_FRAME_BLUE):
181             format_name = "blue";
182             break;
183     }
184
185     return Py_BuildValue ("isiiiii", p.format, format_name,
186                           p.last_frame, p.pixels_per_line,
187                           p.lines, p.depth, p.bytes_per_line);
188 }
189
190 static PyObject *startScan (_ScanDevice * self, PyObject * args)
191 {
192     SANE_Status st;
193
194     if (!PyArg_ParseTuple (args, ""))
195         raiseError("Invalid arguments.");
196
197     if (self->h == NULL)
198         return raiseDeviceClosedError();
199
200     /* sane_start can take several seconds, if the user initiates
201        a new scan, while the scan head of a flatbed scanner moves
202        back to the start position after finishing a previous scan.
203        Hence it is worth to allow threads here.
204      */
205     Py_BEGIN_ALLOW_THREADS
206     st = sane_start (self->h);
207     Py_END_ALLOW_THREADS
208
209     if (st != SANE_STATUS_GOOD &&
210         st != SANE_STATUS_EOF &&
211         st != SANE_STATUS_NO_DOCS)
212           return raiseSaneError(st);
213
214     return Py_BuildValue("i", st);
215 }
216
217 static PyObject *cancelScan (_ScanDevice * self, PyObject * args)
218 {
219     if (!PyArg_ParseTuple (args, ""))
220         raiseError("Invalid arguments.");
221
222     if (self->h == NULL)
223         return raiseDeviceClosedError();
224
225     sane_cancel (self->h);
226     Py_INCREF (Py_None);
227     return Py_None;
228 }
229
230 static PyObject *getOptions (_ScanDevice * self, PyObject * args)
231 {
232     const SANE_Option_Descriptor *d;
233     PyObject *list, *value;
234     int i = 1;
235
236     if (!PyArg_ParseTuple (args, ""))
237         raiseError("Invalid arguments.");
238
239     if (self->h == NULL)
240         return raiseDeviceClosedError();
241
242     if (!(list = PyList_New (0)))
243         raiseError("Unable to allocate list.");
244
245     do
246     {
247         d = sane_get_option_descriptor (self->h, i);
248         if (d != NULL)
249         {
250             PyObject *constraint = NULL;
251             int j;
252
253             switch (d->constraint_type)
254             {
255             case (SANE_CONSTRAINT_NONE):
256                 Py_INCREF (Py_None);
257                 constraint = Py_None;
258                 break;
259             case (SANE_CONSTRAINT_RANGE):
260                 if (d->type == SANE_TYPE_INT)
261                     constraint =
262                         Py_BuildValue ("iii", d->constraint.range->min,
263                                        d->constraint.range->max,
264                                        d->constraint.range->quant);
265                 else
266                     constraint = Py_BuildValue ("ddd",
267                                                 SANE_UNFIX (d->
268                                                             constraint.
269                                                             range->min),
270                                                 SANE_UNFIX (d->
271                                                             constraint.
272                                                             range->max),
273                                                 SANE_UNFIX (d->
274                                                             constraint.
275                                                             range->quant));
276                 break;
277             case (SANE_CONSTRAINT_WORD_LIST):
278                 constraint = PyList_New (d->constraint.word_list[0]);
279
280                 if (d->type == SANE_TYPE_INT)
281                     for (j = 1; j <= d->constraint.word_list[0]; j++)
282                         PyList_SetItem (constraint, j - 1,
283                                         PyInt_FromLong (d->constraint.
284                                                         word_list[j]));
285                 else
286                     for (j = 1; j <= d->constraint.word_list[0]; j++)
287                         PyList_SetItem (constraint, j - 1,
288                                         PyFloat_FromDouble (SANE_UNFIX
289                                                             (d->
290                                                              constraint.
291                                                              word_list[j])));
292                 break;
293             case (SANE_CONSTRAINT_STRING_LIST):
294                 constraint = PyList_New (0);
295
296                 for (j = 0; d->constraint.string_list[j] != NULL; j++)
297                     PyList_Append (constraint,
298                                    PyString_FromString (d->constraint.
299                                                         string_list[j]));
300                 break;
301             }
302             value = Py_BuildValue ("isssiiiiO", i, d->name, d->title, d->desc,
303                                    d->type, d->unit, d->size, d->cap, constraint);
304
305             PyList_Append (list, value);
306         }
307         i++;
308     }
309
310     while (d != NULL);
311     return list;
312 }
313
314 static PyObject *getOption (_ScanDevice * self, PyObject * args)
315 {
316     SANE_Status st;
317     const SANE_Option_Descriptor *d;
318     PyObject *value = NULL;
319     int n;
320     void *v;
321
322     if (!PyArg_ParseTuple (args, "i", &n))
323         raiseError("Invalid arguments.");
324
325     if (self->h == NULL)
326         return raiseDeviceClosedError();
327
328     d = sane_get_option_descriptor (self->h, n);
329     v = malloc (d->size + 1);
330     st = sane_control_option (self->h, n, SANE_ACTION_GET_VALUE, v, NULL);
331
332     if (st != SANE_STATUS_GOOD)
333     {
334         free (v);
335         return raiseSaneError(st);
336     }
337
338     switch (d->type)
339     {
340         case (SANE_TYPE_BOOL):
341         case (SANE_TYPE_INT):
342             value = Py_BuildValue ("i", *((SANE_Int *) v));
343             break;
344
345         case (SANE_TYPE_FIXED):
346             value = Py_BuildValue ("d", SANE_UNFIX ((*((SANE_Fixed *) v))));
347             break;
348
349         case (SANE_TYPE_STRING):
350             value = Py_BuildValue ("s", v);
351             break;
352
353         case (SANE_TYPE_BUTTON):
354         case (SANE_TYPE_GROUP):
355             value = Py_BuildValue ("O", Py_None);
356             break;
357     }
358
359     free (v);
360     return value;
361 }
362
363 static PyObject *setOption (_ScanDevice * self, PyObject * args)
364 {
365     SANE_Status st;
366     const SANE_Option_Descriptor *d;
367     SANE_Int i;
368     PyObject *value;
369     int n;
370
371     if (!PyArg_ParseTuple (args, "iO", &n, &value))
372         raiseError("Invalid arguments.");
373
374     if (self->h == NULL)
375         return raiseDeviceClosedError();
376
377     d = sane_get_option_descriptor (self->h, n);
378     switch (d->type)
379     {
380         case (SANE_TYPE_BOOL):
381             if (!PyInt_Check (value))
382                 return raiseError("SANE_Bool requires an integer.");
383
384             SANE_Bool b = PyInt_AsLong(value);
385
386             if (b != SANE_FALSE && b > SANE_TRUE)
387                 b = SANE_TRUE;
388
389             st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)&b, &i);
390             break;
391
392         case (SANE_TYPE_INT):
393             if (!PyInt_Check (value))
394                 return raiseError("SANE_Int requires an integer.");
395
396             SANE_Int j = PyInt_AsLong (value);
397             st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)&j, &i);
398             break;
399
400         case (SANE_TYPE_FIXED):
401             if (!PyFloat_Check (value))
402                 return raiseError("SANE_Fixed requires an float.");
403
404             SANE_Fixed f = SANE_FIX (PyFloat_AsDouble (value));
405             st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)&f, &i);
406             break;
407
408         case (SANE_TYPE_STRING):
409             if (!PyString_Check (value))
410                 return raiseError("SANE_String requires a a string.");
411
412             SANE_String s = malloc (d->size + 1);
413             strncpy (s, PyString_AsString (value), d->size - 1);
414             ((SANE_String) s)[d->size - 1] = 0;
415             st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)s, &i);
416             free(s);
417             break;
418
419         case (SANE_TYPE_BUTTON):
420         case (SANE_TYPE_GROUP):
421             break;
422     }
423
424     if (st != SANE_STATUS_GOOD)
425         return raiseSaneError(st);
426
427     return Py_BuildValue ("i", i);
428 }
429
430 static PyObject *setAutoOption (_ScanDevice * self, PyObject * args)
431 {
432     SANE_Status st;
433     const SANE_Option_Descriptor *d;
434     SANE_Int i;
435     int n;
436
437     if (!PyArg_ParseTuple (args, "i", &n))
438         raiseError("Invalid arguments.");
439
440     if (self->h == NULL)
441         return raiseDeviceClosedError();
442
443     d = sane_get_option_descriptor (self->h, n);
444     st = sane_control_option (self->h, n, SANE_ACTION_SET_AUTO, NULL, &i);
445
446     if (st != SANE_STATUS_GOOD)
447         return raiseSaneError (st);
448
449     return Py_BuildValue ("i", i);
450 }
451
452 #define MAX_READSIZE 32768
453
454 static PyObject *readScan (_ScanDevice * self, PyObject * args)
455 {
456     SANE_Status st;
457     SANE_Int len;
458     SANE_Byte buffer[MAX_READSIZE];
459     int bytes_to_read;
460
461     if (!PyArg_ParseTuple (args, "i", &bytes_to_read))
462         raiseError("Invalid arguments.");
463
464     if (bytes_to_read > MAX_READSIZE)
465         return raiseError("bytes_to_read > MAX_READSIZE");
466
467     if (self->h == NULL)
468         return raiseDeviceClosedError();
469
470     //Py_BEGIN_ALLOW_THREADS
471     Py_UNBLOCK_THREADS
472     st = sane_read (self->h, buffer, bytes_to_read, &len);
473     //Py_END_ALLOW_THREADS
474     Py_BLOCK_THREADS
475
476     if (st != SANE_STATUS_GOOD &&
477         st != SANE_STATUS_EOF &&
478         st != SANE_STATUS_NO_DOCS)
479     {
480         sane_cancel(self->h);
481         //Py_BLOCK_THREADS
482         return raiseSaneError(st);
483     }
484
485     return Py_BuildValue ("(iz#)", st, buffer, len);
486 }
487
488
489 static PyMethodDef ScanDevice_methods[] = {
490     {"getParameters", (PyCFunction) getParameters, METH_VARARGS},
491
492     {"getOptions", (PyCFunction) getOptions, METH_VARARGS},
493     {"getOption", (PyCFunction) getOption, METH_VARARGS},
494     {"setOption", (PyCFunction) setOption, METH_VARARGS},
495     {"setAutoOption", (PyCFunction) setAutoOption, METH_VARARGS},
496
497     {"startScan", (PyCFunction) startScan, METH_VARARGS},
498     {"cancelScan", (PyCFunction) cancelScan, METH_VARARGS},
499     {"readScan", (PyCFunction) readScan, METH_VARARGS},
500     {"closeScan", (PyCFunction) closeScan, METH_VARARGS},
501     {NULL, NULL}
502 };
503
504 static PyObject *getAttr (_ScanDevice * self, char *name)
505 {
506     return Py_FindMethod (ScanDevice_methods, (PyObject *) self, name);
507 }
508
509 staticforward PyTypeObject ScanDevice_type = {
510     PyObject_HEAD_INIT (&PyType_Type) 0, /*ob_size */
511     "_ScanDevice",               /*tp_name */
512     sizeof (_ScanDevice),        /*tp_basicsize */
513     0,                          /*tp_itemsize */
514     /* methods */
515     (destructor) deAlloc,       /*tp_dealloc */
516     0,                          /*tp_print */
517     (getattrfunc) getAttr,      /*tp_getattr */
518     0,                          /*tp_setattr */
519     0,                          /*tp_compare */
520     0,                          /*tp_repr */
521     0,                          /*tp_as_number */
522     0,                          /*tp_as_sequence */
523     0,                          /*tp_as_mapping */
524     0,                          /*tp_hash */
525 };
526
527 /* --------------------------------------------------------------------- */
528
529 static void auth_callback (SANE_String_Const resource,
530                        SANE_Char * username, SANE_Char * password)
531 {
532     printf("auth_callback\n");
533 }
534
535 static PyObject *init (PyObject * self, PyObject * args)
536 {
537     SANE_Status st;
538     SANE_Int version;
539
540     if (!PyArg_ParseTuple (args, ""))
541         raiseError("Invalid arguments.");
542
543     /* XXX Authorization is not yet supported */
544     st = sane_init (&version, auth_callback);
545
546     if (st != SANE_STATUS_GOOD)
547         return raiseSaneError (st);
548
549     return Py_BuildValue ("iiii", version, SANE_VERSION_MAJOR (version),
550                           SANE_VERSION_MINOR (version),
551                           SANE_VERSION_BUILD (version));
552
553 }
554
555
556
557 static PyObject *deInit (PyObject * self, PyObject * args)
558 {
559     if (!PyArg_ParseTuple (args, ""))
560         raiseError("Invalid arguments");
561
562     sane_exit ();
563     Py_INCREF (Py_None);
564     return Py_None;
565 }
566
567 static PyObject *getDevices (PyObject * self, PyObject * args)
568 {
569     const SANE_Device **device_list;
570     SANE_Status st;
571     PyObject *list;
572     int local_only=SANE_FALSE, i;
573
574     if (!PyArg_ParseTuple (args, "|i", &local_only))
575         raiseError("Invalid arguments");
576
577     st = sane_get_devices (&device_list, local_only);
578
579     if (st != SANE_STATUS_GOOD)
580         return raiseSaneError (st);
581
582     if (!(list = PyList_New (0)))
583         return raiseError("Unable to allocate device list.");
584
585     for (i=0; device_list[i]; i++)
586     {
587         PyList_Append (list, Py_BuildValue ("ssss", device_list[i]->name, device_list[i]->vendor,
588                                             device_list[i]->model, device_list[i]->type));
589     }
590
591     return list;
592 }
593
594 /* Function returning new _ScanDevice object */
595
596 static PyObject *openDevice (PyObject * self, PyObject * args)
597 {
598     _ScanDevice *rv;
599     SANE_Status st;
600     char *name;
601
602     if (!PyArg_ParseTuple (args, "s", &name))
603         raiseError("Invalid arguments");
604
605     rv = newScanDeviceObject ();
606
607     if (rv == NULL)
608         return raiseError("Unable to create _ScanDevice object.");
609
610     st = sane_open (name, &(rv->h));
611
612     if (st != SANE_STATUS_GOOD)
613     {
614         Py_DECREF (rv);
615         return raiseSaneError (st);
616     }
617     return (PyObject *) rv;
618 }
619
620 static PyObject *isOptionActive (PyObject * self, PyObject * args)
621 {
622     SANE_Int cap;
623     long lg;
624
625     if (!PyArg_ParseTuple (args, "l", &lg))
626         raiseError("Invalid arguments");
627
628     cap = lg;
629     return PyInt_FromLong (SANE_OPTION_IS_ACTIVE (cap));
630 }
631
632 static PyObject *isOptionSettable (PyObject * self, PyObject * args)
633 {
634     SANE_Int cap;
635     long lg;
636
637     if (!PyArg_ParseTuple (args, "l", &lg))
638         raiseError("Invalid arguments");
639
640     cap = lg;
641     return PyInt_FromLong (SANE_OPTION_IS_SETTABLE (cap));
642 }
643
644
645 /* List of functions defined in the module */
646
647 static PyMethodDef ScanExt_methods[] = {
648     {"init", init, METH_VARARGS},
649     {"deInit", deInit, METH_VARARGS},
650     {"getDevices", getDevices, METH_VARARGS},
651     {"openDevice", openDevice, METH_VARARGS},
652     {"isOptionActive", isOptionActive, METH_VARARGS},
653     {"isOptionSettable", isOptionSettable, METH_VARARGS},
654     {"getErrorMessage", getErrorMessage, METH_VARARGS},
655     {NULL, NULL}                /* sentinel */
656 };
657
658
659 static void insint (PyObject * d, char *name, int value)
660 {
661     PyObject *v = PyInt_FromLong ((long) value);
662
663     if (!v || PyDict_SetItemString (d, name, v))
664         Py_FatalError ("can't initialize sane module");
665
666     Py_DECREF (v);
667 }
668
669 void initscanext (void)
670 {
671     PyObject *m, *d;
672
673     /* Create the module and add the functions */
674     m = Py_InitModule ("scanext", ScanExt_methods);
675
676     /* Add some symbolic constants to the module */
677     d = PyModule_GetDict (m);
678     ErrorObject = PyString_FromString ("scanext.error");
679     PyDict_SetItemString (d, "error", ErrorObject);
680
681     insint (d, "INFO_INEXACT", SANE_INFO_INEXACT);
682     insint (d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS);
683     insint (d, "RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS);
684
685     insint (d, "FRAME_GRAY", SANE_FRAME_GRAY);
686     insint (d, "FRAME_RGB", SANE_FRAME_RGB);
687     insint (d, "FRAME_RED", SANE_FRAME_RED);
688     insint (d, "FRAME_GREEN", SANE_FRAME_GREEN);
689     insint (d, "FRAME_BLUE", SANE_FRAME_BLUE);
690
691     insint (d, "CONSTRAINT_NONE", SANE_CONSTRAINT_NONE);
692     insint (d, "CONSTRAINT_RANGE", SANE_CONSTRAINT_RANGE);
693     insint (d, "CONSTRAINT_WORD_LIST", SANE_CONSTRAINT_WORD_LIST);
694     insint (d, "CONSTRAINT_STRING_LIST", SANE_CONSTRAINT_STRING_LIST);
695
696     insint (d, "TYPE_BOOL", SANE_TYPE_BOOL);
697     insint (d, "TYPE_INT", SANE_TYPE_INT);
698     insint (d, "TYPE_FIXED", SANE_TYPE_FIXED);
699     insint (d, "TYPE_STRING", SANE_TYPE_STRING);
700     insint (d, "TYPE_BUTTON", SANE_TYPE_BUTTON);
701     insint (d, "TYPE_GROUP", SANE_TYPE_GROUP);
702
703     insint (d, "UNIT_NONE", SANE_UNIT_NONE);
704     insint (d, "UNIT_PIXEL", SANE_UNIT_PIXEL);
705     insint (d, "UNIT_BIT", SANE_UNIT_BIT);
706     insint (d, "UNIT_MM", SANE_UNIT_MM);
707     insint (d, "UNIT_DPI", SANE_UNIT_DPI);
708     insint (d, "UNIT_PERCENT", SANE_UNIT_PERCENT);
709     insint (d, "UNIT_MICROSECOND", SANE_UNIT_MICROSECOND);
710
711     insint (d, "CAP_SOFT_SELECT", SANE_CAP_SOFT_SELECT);
712     insint (d, "CAP_HARD_SELECT", SANE_CAP_HARD_SELECT);
713     insint (d, "CAP_SOFT_DETECT", SANE_CAP_SOFT_DETECT);
714     insint (d, "CAP_EMULATED", SANE_CAP_EMULATED);
715     insint (d, "CAP_AUTOMATIC", SANE_CAP_AUTOMATIC);
716     insint (d, "CAP_INACTIVE", SANE_CAP_INACTIVE);
717     insint (d, "CAP_ADVANCED", SANE_CAP_ADVANCED);
718
719     /* handy for checking array lengths: */
720     insint (d, "SANE_WORD_SIZE", sizeof (SANE_Word));
721
722     /* possible return values of set_option() */
723     insint (d, "INFO_INEXACT", SANE_INFO_INEXACT);
724     insint (d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS);
725     insint (d, "INFO_RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS);
726
727     // SANE status codes
728     insint (d, "SANE_STATUS_GOOD",  SANE_STATUS_GOOD); //Operation completed succesfully.
729     insint (d, "SANE_STATUS_UNSUPPORTED", SANE_STATUS_UNSUPPORTED); // Operation is not supported.
730     insint (d, "SANE_STATUS_CANCELLED", SANE_STATUS_CANCELLED); //Operation was cancelled.
731     insint (d, "SANE_STATUS_DEVICE_BUSY", SANE_STATUS_DEVICE_BUSY); // Device is busy---retry later.
732     insint (d, "SANE_STATUS_INVAL",  SANE_STATUS_INVAL); // Data or argument is invalid.
733     insint (d, "SANE_STATUS_EOF", SANE_STATUS_EOF);  // No more data available (end-of-file).
734     insint (d, "SANE_STATUS_JAMMED", SANE_STATUS_JAMMED); // Document feeder jammed.
735     insint (d, "SANE_STATUS_NO_DOCS", SANE_STATUS_NO_DOCS); // Document feeder out of documents.
736     insint (d, "SANE_STATUS_COVER_OPEN", SANE_STATUS_COVER_OPEN); // Scanner cover is open.
737     insint (d, "SANE_STATUS_IO_ERROR", SANE_STATUS_IO_ERROR); // Error during device I/O.
738     insint (d, "SANE_STATUS_NO_MEM", SANE_STATUS_NO_MEM); // Out of memory.
739     insint (d, "SANE_STATUS_ACCESS_DENIED", SANE_STATUS_ACCESS_DENIED);  // Access to resource has been denied.
740
741     // Maximum buffer size for read()
742     insint(d, "MAX_READSIZE", MAX_READSIZE);
743
744     /* Check for errors */
745     if (PyErr_Occurred ())
746         Py_FatalError ("can't initialize module scanext");
747
748 }