static PyObject * SaneDev_get_option(SaneDevObject *self, PyObject *args) { SANE_Status st; const SANE_Option_Descriptor *d; PyObject *value=NULL; int n; void *v; if (!PyArg_ParseTuple(args, "i", &n)) { return NULL; } if (self->h==NULL) { PyErr_SetString(ErrorObject, "SaneDev object is closed"); return NULL; } d=sane_get_option_descriptor(self->h, n); v=malloc(d->size+1); st=sane_control_option(self->h, n, SANE_ACTION_GET_VALUE, v, NULL); if (st) { free(v); return PySane_Error(st); } switch(d->type) { case(SANE_TYPE_BOOL): case(SANE_TYPE_INT): value=Py_BuildValue("i", *( (SANE_Int*)v) ); break; case(SANE_TYPE_FIXED): value=Py_BuildValue("d", SANE_UNFIX((*((SANE_Fixed*)v))) ); break; case(SANE_TYPE_STRING): value=Py_BuildValue("s", v); break; case(SANE_TYPE_BUTTON): case(SANE_TYPE_GROUP): value=Py_BuildValue("O", Py_None); break; } free(v); return value; }
static PyObject *getOption (_ScanDevice * self, PyObject * args) { SANE_Status st; const SANE_Option_Descriptor *d; PyObject *value = NULL; int n; void *v; if (!PyArg_ParseTuple (args, "i", &n)) raiseError("Invalid arguments."); if (self->h == NULL) return raiseDeviceClosedError(); d = sane_get_option_descriptor (self->h, n); v = malloc (d->size + 1); st = sane_control_option (self->h, n, SANE_ACTION_GET_VALUE, v, NULL); if (st != SANE_STATUS_GOOD) { free (v); return raiseSaneError(st); } switch (d->type) { case (SANE_TYPE_BOOL): case (SANE_TYPE_INT): value = Py_BuildValue ("i", *((SANE_Int *) v)); break; case (SANE_TYPE_FIXED): value = Py_BuildValue ("d", SANE_UNFIX ((*((SANE_Fixed *) v)))); break; case (SANE_TYPE_STRING): value = Py_BuildValue ("s", v); break; case (SANE_TYPE_BUTTON): case (SANE_TYPE_GROUP): value = Py_BuildValue ("O", Py_None); break; } free (v); return value; }
static PyObject *setAutoOption (_ScanDevice * self, PyObject * args) { SANE_Status st; const SANE_Option_Descriptor *d; SANE_Int i; int n; if (!PyArg_ParseTuple (args, "i", &n)) raiseError("Invalid arguments."); if (self->h == NULL) return raiseDeviceClosedError(); d = sane_get_option_descriptor (self->h, n); st = sane_control_option (self->h, n, SANE_ACTION_SET_AUTO, NULL, &i); if (st != SANE_STATUS_GOOD) return raiseSaneError (st); return Py_BuildValue ("i", i); }
static PyObject * SaneDev_set_auto_option(SaneDevObject *self, PyObject *args) { SANE_Status st; const SANE_Option_Descriptor *d; SANE_Int i; int n; if (!PyArg_ParseTuple(args, "i", &n)) return NULL; if (self->h==NULL) { PyErr_SetString(ErrorObject, "SaneDev object is closed"); return NULL; } d=sane_get_option_descriptor(self->h, n); st=sane_control_option(self->h, n, SANE_ACTION_SET_AUTO, NULL, &i); if (st) {return PySane_Error(st);} return Py_BuildValue("i", i); }
bool KSaneWidget::openDevice(const QString &deviceName) { int i = 0; const SANE_Option_Descriptor *optDesc; SANE_Status status; SANE_Word numSaneOptions; SANE_Int res; KPasswordDialog *dlg; KWallet::Wallet *saneWallet; QString myFolderName = QStringLiteral("ksane"); QMap<QString, QString> wallet_entry; if (d->m_saneHandle != 0) { // this KSaneWidget already has an open device return false; } // don't bother trying to open if the device string is empty if (deviceName.isEmpty()) { return false; } // save the device name d->m_devName = deviceName; // Try to open the device status = sane_open(deviceName.toLatin1().constData(), &d->m_saneHandle); bool password_dialog_ok = true; // prepare wallet for authentication and create password dialog if (status == SANE_STATUS_ACCESS_DENIED) { saneWallet = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), winId()); if (saneWallet) { dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine | KPasswordDialog::ShowKeepPassword); if (!saneWallet->hasFolder(myFolderName)) { saneWallet->createFolder(myFolderName); } saneWallet->setFolder(myFolderName); saneWallet->readMap(deviceName, wallet_entry); if (!wallet_entry.empty() || true) { dlg->setUsername(wallet_entry[QStringLiteral("username")]); dlg->setPassword(wallet_entry[QStringLiteral("password")]); dlg->setKeepPassword(true); } } else { dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine); } dlg->setPrompt(i18n("Authentication required for resource: %1", deviceName)); } // sane_open failed due to insufficient authorization // retry opening device with user provided data assisted with kwallet records while (status == SANE_STATUS_ACCESS_DENIED) { password_dialog_ok = dlg->exec(); if (!password_dialog_ok) { delete dlg; d->m_devName.clear(); return false; //the user canceled } // add/update the device user-name and password for authentication d->m_auth->setDeviceAuth(d->m_devName, dlg->username(), dlg->password()); status = sane_open(deviceName.toLatin1().constData(), &d->m_saneHandle); // store password in wallet on successful authentication if (dlg->keepPassword() && status != SANE_STATUS_ACCESS_DENIED) { QMap<QString, QString> entry; entry[QStringLiteral("username")] = dlg->username(); entry[QStringLiteral("password")] = dlg->password(); if (saneWallet) { saneWallet->writeMap(deviceName, entry); } } } if (status != SANE_STATUS_GOOD) { qDebug() << "sane_open(\"" << deviceName << "\", &handle) failed! status = " << sane_strstatus(status); d->m_auth->clearDeviceAuth(d->m_devName); d->m_devName.clear(); return false; } // update the device list if needed to get the vendor and model info if (d->m_findDevThread->devicesList().size() == 0) { d->m_findDevThread->start(); } else { // use the "old" existing list d->devListUpdated(); // if m_vendor is not updated it means that the list needs to be updated. if (d->m_vendor.isEmpty()) { d->m_findDevThread->start(); } } // Read the options (start with option 0 the number of parameters) optDesc = sane_get_option_descriptor(d->m_saneHandle, 0); if (optDesc == 0) { d->m_auth->clearDeviceAuth(d->m_devName); d->m_devName.clear(); return false; } QVarLengthArray<char> data(optDesc->size); status = sane_control_option(d->m_saneHandle, 0, SANE_ACTION_GET_VALUE, data.data(), &res); if (status != SANE_STATUS_GOOD) { d->m_auth->clearDeviceAuth(d->m_devName); d->m_devName.clear(); return false; } numSaneOptions = *reinterpret_cast<SANE_Word *>(data.data()); // read the rest of the options for (i = 1; i < numSaneOptions; ++i) { switch (KSaneOption::optionType(sane_get_option_descriptor(d->m_saneHandle, i))) { case KSaneOption::TYPE_DETECT_FAIL: d->m_optList.append(new KSaneOption(d->m_saneHandle, i)); break; case KSaneOption::TYPE_CHECKBOX: d->m_optList.append(new KSaneOptCheckBox(d->m_saneHandle, i)); break; case KSaneOption::TYPE_SLIDER: d->m_optList.append(new KSaneOptSlider(d->m_saneHandle, i)); break; case KSaneOption::TYPE_F_SLIDER: d->m_optList.append(new KSaneOptFSlider(d->m_saneHandle, i)); break; case KSaneOption::TYPE_COMBO: d->m_optList.append(new KSaneOptCombo(d->m_saneHandle, i)); break; case KSaneOption::TYPE_ENTRY: d->m_optList.append(new KSaneOptEntry(d->m_saneHandle, i)); break; case KSaneOption::TYPE_GAMMA: d->m_optList.append(new KSaneOptGamma(d->m_saneHandle, i)); break; case KSaneOption::TYPE_BUTTON: d->m_optList.append(new KSaneOptButton(d->m_saneHandle, i)); break; } } // do the connections of the option parameters for (i = 1; i < d->m_optList.size(); ++i) { //qDebug() << d->m_optList.at(i)->name(); connect(d->m_optList.at(i), SIGNAL(optsNeedReload()), d, SLOT(optReload())); connect(d->m_optList.at(i), SIGNAL(valsNeedReload()), d, SLOT(scheduleValReload())); if (d->m_optList.at(i)->needsPolling()) { //qDebug() << d->m_optList.at(i)->name() << " needs polling"; d->m_pollList.append(d->m_optList.at(i)); KSaneOptCheckBox *buttonOption = qobject_cast<KSaneOptCheckBox *>(d->m_optList.at(i)); if (buttonOption) { connect(buttonOption, SIGNAL(buttonPressed(QString,QString,bool)), this, SIGNAL(buttonPressed(QString,QString,bool))); } } }
static PyObject * SaneDev_get_options(SaneDevObject *self, PyObject *args) { const SANE_Option_Descriptor *d; PyObject *list, *value; int i=1; if (!PyArg_ParseTuple(args, "")) return NULL; if (self->h==NULL) { PyErr_SetString(ErrorObject, "SaneDev object is closed"); return NULL; } if (!(list = PyList_New(0))) return NULL; do { d=sane_get_option_descriptor(self->h, i); if (d!=NULL) { PyObject *constraint=NULL; int j; switch (d->constraint_type) { case(SANE_CONSTRAINT_NONE): Py_INCREF(Py_None); constraint=Py_None; break; case(SANE_CONSTRAINT_RANGE): if (d->type == SANE_TYPE_INT) constraint=Py_BuildValue("iii", d->constraint.range->min, d->constraint.range->max, d->constraint.range->quant); else constraint=Py_BuildValue("ddd", SANE_UNFIX(d->constraint.range->min), SANE_UNFIX(d->constraint.range->max), SANE_UNFIX(d->constraint.range->quant)); break; case(SANE_CONSTRAINT_WORD_LIST): constraint=PyList_New(d->constraint.word_list[0]); if (d->type == SANE_TYPE_INT) for (j=1; j<=d->constraint.word_list[0]; j++) PyList_SetItem(constraint, j-1, PyInt_FromLong(d->constraint.word_list[j])); else for (j=1; j<=d->constraint.word_list[0]; j++) PyList_SetItem(constraint, j-1, PyFloat_FromDouble(SANE_UNFIX(d->constraint.word_list[j]))); break; case(SANE_CONSTRAINT_STRING_LIST): constraint=PyList_New(0); for(j=0; d->constraint.string_list[j]!=NULL; j++) PyList_Append(constraint, #if PY_MAJOR_VERSION >= 3 PyUnicode_DecodeLatin1(d->constraint.string_list[j], strlen(d->constraint.string_list[j]), NULL)); #else PyString_FromString(d->constraint.string_list[j])); #endif break; } value=Py_BuildValue("isssiiiiO", i, d->name, d->title, d->desc, d->type, d->unit, d->size, d->cap, constraint); PyList_Append(list, value); } i++; } while (d!=NULL);
static PyObject * SaneDev_set_option(SaneDevObject *self, PyObject *args) { SANE_Status st; const SANE_Option_Descriptor *d; SANE_Int i; PyObject *value; int n; void *v; if (!PyArg_ParseTuple(args, "iO", &n, &value)) return NULL; if (self->h==NULL) { PyErr_SetString(ErrorObject, "SaneDev object is closed"); return NULL; } d=sane_get_option_descriptor(self->h, n); v=malloc(d->size+1); switch(d->type) { case(SANE_TYPE_BOOL): if (!PyInt_Check(value)) { PyErr_SetString(PyExc_TypeError, "SANE_BOOL requires an integer"); free(v); return NULL; } /* fall through */ case(SANE_TYPE_INT): if (!PyInt_Check(value)) { PyErr_SetString(PyExc_TypeError, "SANE_INT requires an integer"); free(v); return NULL; } *( (SANE_Int*)v) = PyInt_AsLong(value); break; case(SANE_TYPE_FIXED): if (!PyFloat_Check(value)) { PyErr_SetString(PyExc_TypeError, "SANE_FIXED requires a floating point number"); free(v); return NULL; } *( (SANE_Fixed*)v) = SANE_FIX(PyFloat_AsDouble(value)); break; case(SANE_TYPE_STRING): if (!PyString_Check(value)) { PyErr_SetString(PyExc_TypeError, "SANE_STRING requires a string"); free(v); return NULL; } strncpy(v, PyString_AsString(value), d->size-1); ((char*)v)[d->size-1] = 0; break; case(SANE_TYPE_BUTTON): case(SANE_TYPE_GROUP): break; } st=sane_control_option(self->h, n, SANE_ACTION_SET_VALUE, v, &i); if (st) {free(v); return PySane_Error(st);} free(v); return Py_BuildValue("i", i); }
// -------------------------------------------------------------- void ControlsWindow::MessageReceived ( BMessage * msg ) { switch (msg->what) { case SET_DEVICE_MSG: { ssize_t data_size; SANE_Status status; const SANE_Device * device_info; if ( msg->FindData("device", B_RAW_TYPE, (const void **) &device_info, &data_size) != B_OK ) break; m_device_info = device_info; if ( m_device ) sane_close(m_device); m_device = NULL; ScannerOptionView * option; BView * child; child = m_panel->ChildAt(0); while ( child ) { option = dynamic_cast<ScannerOptionView *>(child); if ( option ) option->RemoveSelf(); child = child->NextSibling(); }; status = sane_open(m_device_info->name, &m_device); if ( status != SANE_STATUS_GOOD ) { fprintf (stderr, "sane_open: %s\n", sane_strstatus (status)); BAlert * alert = new BAlert("sane_open", sane_strstatus(status), "Argh"); alert->Go(); break; }; const SANE_Option_Descriptor * desc; // m_options_lv->MakeEmpty(); printf("Options for device %s:\n", m_device_info->name); int opt = 1; // skip first option (option 0 = number of options) BRect r = m_panel->Bounds(); r.top = 80; r.InsetBy(8, 8); while ( (desc = sane_get_option_descriptor(m_device, opt)) != NULL ) { if (desc->type != SANE_TYPE_GROUP) { ScannerOptionView * ov = new ScannerOptionView(r, desc->name, B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT, 0, m_device, opt); if ( ov->Build() == B_OK ) { m_panel->AddChild(ov); r.top += ov->Bounds().Height(); m_tooltip->SetText(ov, desc->desc); } else delete ov; }; BString label; if (desc->type == SANE_TYPE_GROUP) label << "-- "; label << desc->title; if (desc->type == SANE_TYPE_GROUP) label << " --"; printf(" %d: name = %s\n" " title = %s\n" " desc = %s\n" " type = %d\n" " unit = %s\n" " size = %d\n" " cap = 0x%0x\n", opt, desc->name, desc->title, desc->desc, desc->type, get_unit2(desc->unit), desc->size, desc->cap); // m_options_lv->AddItem(new BStringItem(label.String())); opt++; }; BMessage * msg; msg = new BMessage(MainWindow::DEVICE_CHANGED_MSG); msg->AddString("device_name", m_device_info->name); m_parent_window->PostMessage(msg); delete msg; break; }; case SCAN_MSG: { SANE_Handle device; device = Device(); if ( ! device ) break; if ( m_scan_thread_id != -1 ) { // already launched... m_cancel_scan = true; break; }; m_cancel_scan = false; m_scan_thread_id = spawn_thread(_ScanThread, "scan", B_NORMAL_PRIORITY, this); resume_thread(m_scan_thread_id); break; }; default: inherited::MessageReceived(msg); } }
static void* sane_idainit(FILE *fp, char *filename, unsigned int page, struct ida_image_info *info, int thumbnail) { const SANE_Option_Descriptor *opt; SANE_Int flags, count; struct sane_state *h; int rc,i,value,dpi = 0; h = malloc(sizeof(*h)); memset(h,0,sizeof(*h)); if (SANE_STATUS_GOOD != (rc = sane_init(NULL,NULL))) { fprintf(stderr,"sane_init: %s\n",sane_strstatus(rc)); goto oops; } if (SANE_STATUS_GOOD != (rc = sane_open(filename,&h->sane))) { fprintf(stderr,"sane_open: %s\n",sane_strstatus(rc)); goto oops; } /* set options */ opt = sane_get_option_descriptor(h->sane,0); rc = sane_control_option(h->sane, 0, SANE_ACTION_GET_VALUE, &count, &flags); for (i = 1; i < count; i++) { opt = sane_get_option_descriptor(h->sane,i); if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_TL_X)) { value = opt->constraint.range->min; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_TL_Y)) { value = opt->constraint.range->min; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_BR_X)) { value = opt->constraint.range->max; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_BR_Y)) { value = opt->constraint.range->max; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_PREVIEW)) { value = SANE_FALSE; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->cap & SANE_CAP_AUTOMATIC) sane_control_option(h->sane, i, SANE_ACTION_SET_AUTO, NULL, &flags); if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_RESOLUTION)) { if (sane_res) { dpi = sane_res; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &dpi, &flags); } sane_control_option(h->sane, i, SANE_ACTION_GET_VALUE, &dpi, &flags); } if (debug) dump_desc(h->sane,i,opt); } if (SANE_STATUS_GOOD != (rc = sane_start(h->sane))) { fprintf(stderr,"sane_start: %s\n",sane_strstatus(rc)); goto oops; } h->started = 1; if (SANE_STATUS_GOOD != (rc = sane_get_parameters(h->sane,&h->parm))) { fprintf(stderr,"sane_get_parameters: %s\n",sane_strstatus(rc)); goto oops; } if (h->parm.format != SANE_FRAME_GRAY && h->parm.format != SANE_FRAME_RGB) { fprintf(stderr,"sane: unsupported frame format (%d)\n",h->parm.format); goto oops; } if (h->parm.depth != 8) { fprintf(stderr,"sane: unsupported color depth (%d)\n",h->parm.depth); goto oops; } if (-1 == h->parm.lines) { fprintf(stderr,"sane: can't handle unknown image size\n"); goto oops; } info->width = h->parm.pixels_per_line; info->height = h->parm.lines; if (dpi) info->dpi = dpi; h->buf = malloc(h->parm.bytes_per_line * BUF_LINES); if (debug) fprintf(stderr,"sane: scanning %dx%d %s\n",info->width,info->height, (h->parm.format == SANE_FRAME_GRAY) ? "gray" : "color"); return h; oops: if (h->buf) free(h->buf); if (h->started) sane_cancel(h->sane); if (h->sane) sane_close(h->sane); sane_exit(); free(h); return NULL; }
extern char *internalGetScannerDetails(char *device, char *lang) { char *answer = NULL; SANE_Status status; char *deviceList = o_strdup("");; int hlp = 0, resolution = 300, minRes=50, maxRes=50, phashAvailable=0; char *resolution_s, *maxRes_s, *minRes_s; SANE_Handle *openDeviceHandle; o_log(DEBUGM, "sane_open of \"%s\"", device); status = sane_open (device, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { o_log(ERROR, "Could not open: '%s' with error: %s", device, sane_strstatus(status)); free(deviceList); return NULL; } // // Find resolution ranges // for (hlp = 0; hlp < 9999; hlp++) { const SANE_Option_Descriptor *sod; sod = sane_get_option_descriptor (openDeviceHandle, hlp); if (sod == NULL) break; // Just a placeholder if (sod->type == SANE_TYPE_GROUP || sod->name == NULL || hlp == 0) continue; if ( 0 == strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) ) { // Some kind of sliding range if (sod->constraint_type == SANE_CONSTRAINT_RANGE) { o_log(DEBUGM, "Resolution setting detected as 'range'"); // Fixed resolution if (sod->type == SANE_TYPE_FIXED) maxRes = (int)SANE_UNFIX (sod->constraint.range->max); else maxRes = sod->constraint.range->max; } // A fixed list of options else if (sod->constraint_type == SANE_CONSTRAINT_WORD_LIST) { int lastIndex = sod->constraint.word_list[0]; o_log(DEBUGM, "Resolution setting detected as 'word list': lastIndex = %d",lastIndex); // maxRes = sod->constraint.word_list[lastIndex]; // resolution list cannot be treated as low to high ordered list // remark: impl capability to select scan resolution in webInterface int n=0; maxRes = 0; for (n=1; n<=lastIndex; n++ ) { o_log(DEBUGM, "index results %d --> %d", n ,(int)sod->constraint.word_list[n]); if ( maxRes < sod->constraint.word_list[n] ) { maxRes=sod->constraint.word_list[n]; } } } break; // we've found our resolution - no need to search more } } o_log(DEBUGM, "Determined max resultion to be %d", maxRes); // Define a default if(resolution >= maxRes) resolution = maxRes; if(resolution <= minRes) resolution = minRes; o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // // What languages can we OCR for? // char *availableLangs = o_strdup(""); #ifdef CAN_OCR struct simpleLinkedList *languages = getOCRAvailableLanguages(); while (languages != NULL ) { if ( checkOCRLanguage( languages->data ) == 0 ) { o_concatf(&availableLangs, "<lang>%s</lang>", languages->data); } languages = sll_getNext(languages); } sll_destroy( languages ); #endif /* CAN_OCR */ // // Can we give the option of doing 'find simmilar'? // #ifdef CAN_PHASH phashAvailable = 1; #endif /* CAN_PHASH */ // Build Reply // resolution_s = itoa(resolution,10); maxRes_s = itoa(maxRes,10); minRes_s = itoa(minRes,10); o_concatf(&deviceList, "<Resolution><max>%s</max><min>%s</min><default>%s</default></Resolution><OCRLanguages>%s</OCRLanguages><phash>%d</phash>", maxRes_s, minRes_s, resolution_s, availableLangs, phashAvailable); free(maxRes_s); free(minRes_s); free(resolution_s); free(availableLangs); // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerDetails>%s</ScannerDetails></Response>", deviceList); free(deviceList); return answer; }
int setOptions( char *uuid, SANE_Handle *openDeviceHandle, int *request_resolution ) { int option = 0; SANE_Status status; SANE_Fixed v_f; SANE_Int v_i; SANE_Bool v_b; char *v_c; //const char *modes[] = { SANE_VALUE_SCAN_MODE_COLOR, SANE_VALUE_SCAN_MODE_GRAY, "Grayscale", NULL }; const char *modes_colour[] = { SANE_VALUE_SCAN_MODE_COLOR, "Color", SANE_VALUE_SCAN_MODE_GRAY, "Grayscale", NULL }; const char *modes_gray[] = { SANE_VALUE_SCAN_MODE_GRAY, "Grayscale", NULL }; const char *speeds[] = { "Auto", "Normal", "Fast", NULL }; const char *compression[] = { "None", NULL }; const char *sources[] = { "Auto", SANE_I18N ("Auto"), "Flatbed", SANE_I18N ("Flatbed"), "FlatBed", "Normal", SANE_I18N ("Normal"), NULL }; int testScanner = 0; char *devName = getScanParam(uuid, SCAN_PARAM_DEVNAME); if ( strstr(devName, "test") != 0 ) { testScanner = 1; } free(devName); for (option = 0; option < 9999; option++) { const SANE_Option_Descriptor *sod = sane_get_option_descriptor (openDeviceHandle, option); // No more options if (sod == NULL) break; // Just a placeholder if (sod->type == SANE_TYPE_GROUP || sod->name == NULL || option == 0) continue; log_option( option, sod ); // Validation if ( (sod->cap & SANE_CAP_SOFT_SELECT) && (sod->cap & SANE_CAP_HARD_SELECT) ) { o_log(DEBUGM, "The backend said that '%s' is both hardward and software settable! Err", sod->name); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, 0); return 0; } // we MUST set this value if ( (sod->cap & SANE_CAP_SOFT_DETECT) && ((sod->cap & SANE_CAP_INACTIVE) == 0) ) { // A hardware setting if ( sod->cap & SANE_CAP_HARD_SELECT ) { o_log(DEBUGM, "We've got no way of telling the user to set the hardward %s! Err", sod->name); } // a software setting else { int paramSetRet = 0; // Set scanning Source if ( strcmp(sod->name, SANE_NAME_SCAN_SOURCE) == 0 ) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { int i, j; int foundMatch = 0; for (i = 0; sources[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { if (strcmp (sources[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { v_c = o_strdup(sources[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } } // Set scanning mode else if ( strcmp(sod->name, SANE_NAME_SCAN_MODE ) == 0 ) { const char **modes; char *requested_mode = getScanParam(uuid, SCAN_PARAM_FORMAT ); if( 0 == strcmp( "colour", requested_mode ) ) { modes = modes_colour; } else { modes = modes_gray; } free( requested_mode ); int i, j; int foundMatch = 0; for (i = 0; modes[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { if (strcmp (modes[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { v_c = o_strdup(modes[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } else if ( strcmp(sod->name, "batch-scan" ) == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "compression") == 0 ) { int i, j; int foundMatch = 0; for (i = 0; compression[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { o_log(DEBUGM, "n list: %s", sod->constraint.string_list[j]); if (strcmp (compression[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { o_log(DEBUGM, "Attempting to set compresstion to: %s", compression[i]); v_c = o_strdup(compression[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } // Set scanning depth else if ( strcmp(sod->name, SANE_NAME_BIT_DEPTH) == 0 ) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { if( sod->type == SANE_TYPE_STRING ) { v_c = o_strdup("8"); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); } if (sod->type == SANE_TYPE_FIXED) { v_f = SANE_FIX( 8 ); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else { v_i = 8; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } } } // Set Preview mode else if ( strcmp(sod->name, SANE_NAME_PREVIEW) == 0 ) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { v_b = SANE_FALSE; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } } // Set scanning resolution else if ( strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) == 0 ) { char *request_resolution_s; request_resolution_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_RESOLUTION); *request_resolution = atoi(request_resolution_s); free(request_resolution_s); if (sod->type == SANE_TYPE_FIXED) { v_f = SANE_FIX( *request_resolution ); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if (sod->type == SANE_TYPE_INT) { int sane_resolution = *request_resolution; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &sane_resolution, ¶mSetRet); } else { int sane_resolution = *request_resolution; if( sod->constraint.range->quant != 0 ) sane_resolution = sane_resolution * sod->constraint.range->quant; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &sane_resolution, ¶mSetRet); } } else if ( strcmp(sod->name, SANE_NAME_SCAN_TL_Y) == 0 ) { v_f = sod->constraint.range->min; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_TL_X) == 0 ) { v_f = sod->constraint.range->min; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_BR_Y) == 0 ) { int pagelength; char *length_s; v_f = sod->constraint.range->max; length_s = getScanParam(uuid, SCAN_PARAM_LENGTH); pagelength = atoi(length_s); if(pagelength && pagelength >= 20 && pagelength < 100) v_f = SANE_FIX( ( SANE_UNFIX(v_f) * (double)pagelength) / 100); free(length_s); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_BR_X) == 0 ) { v_f = sod->constraint.range->max; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_BRIGHTNESS) == 0 ) { v_f = 0; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_CONTRAST) == 0 ) { v_f = 0; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_SPEED) == 0) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { int i, j; int foundMatch = 0; for (i = 0; speeds[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { if (strcmp (speeds[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { v_c = o_strdup(speeds[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } } else if ( strcmp(sod->name, "custom-gamma") == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } // For the test 'virtual scanner' else if (testScanner == 1) { if ( strcmp(sod->name, "hand-scanner" ) == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "three-pass") == 0 ){ v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "three-pass-order") == 0 ) { status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "RGB", ¶mSetRet); } else if ( strcmp(sod->name, "test-raw_imageture") == 0 ) { status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "Color pattern", ¶mSetRet); } else if ( strcmp(sod->name, "read-delay") == 0 ) { v_b = SANE_TRUE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "fuzzy-parameters") == 0 ) { v_b = SANE_TRUE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "read-delay-duration") == 0 ) { v_i = 1000; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } else if ( strcmp(sod->name, "read-limit") == 0 ) { v_b = SANE_TRUE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "read-limit-size") == 0 ) { v_i = sod->constraint.range->max; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } else if ( strcmp(sod->name, "read-return-value") == 0 ) { status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "Default", ¶mSetRet); } else if ( strcmp(sod->name, "ppl-loss") == 0 ) { v_i = 0; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } else if ( strcmp(sod->name, "invert-endianess") == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } } // not a 'well known' option else { // try setting automatically if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) o_log(DEBUGM, "Could not set authmatically", sod->name); } if( status != SANE_STATUS_GOOD ) { handleSaneErrors("Cannot set no to", sod->name, status, paramSetRet); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } if ( paramSetRet & SANE_INFO_RELOAD_OPTIONS ) { //start from the beginning again. option = 0; } } // setable option } else { o_log(DEBUGM, "The option does not need to be set."); } } // options loop return 1; }
static void OyInit_color_options(SANE_Handle device) { const SANE_Option_Descriptor *opt = NULL; SANE_Int num_options = 0; SANE_Status status; unsigned int opt_num = 0, i = 0, chars = 0; char buf[BUFSIZE]; /* We got a device, find out how many options it has */ status = sane_control_option(device, 0, SANE_ACTION_GET_VALUE, &num_options, 0); if (status != SANE_STATUS_GOOD) { fprintf(stderr, "unable to determine option count\n"); exit(1); } color_option_names = (char **)malloc(sizeof(char *) * num_options); color_option_values = (char **)malloc(sizeof(char *) * num_options); memset(color_option_names, 0, sizeof(char *) * num_options); memset(color_option_values, 0, sizeof(char *) * num_options); for (opt_num = 1; opt_num < num_options; opt_num++) { opt = sane_get_option_descriptor(device, opt_num); if (opt->cap & SANE_CAP_COLOUR) { void *val = malloc(opt->size); color_option_names[i] = (char *)malloc(strlen(opt->name) + 1); strcpy(color_option_names[i], opt->name); sane_control_option(device, opt_num, SANE_ACTION_GET_VALUE, val, 0); switch (opt->type) { case SANE_TYPE_BOOL: color_option_values[i] = *(SANE_Bool *) val ? "true" : "false"; break; case SANE_TYPE_INT: if (opt->size == (SANE_Int) sizeof(SANE_Word)) chars = sprintf(buf, "%d", *(SANE_Int *) val); /* use snprintf( ..,128,.. ) */ else chars = print_int_vec((SANE_Int *) val, opt->size, buf, BUFSIZE); color_option_values[i] = (char *)malloc(chars + 1); strcpy(color_option_values[i], buf); break; case SANE_TYPE_FIXED: chars = sprintf(buf, "%f", SANE_UNFIX(*(SANE_Fixed *) val)); color_option_values[i] = (char *)malloc(chars + 1); strcpy(color_option_values[i], buf); break; case SANE_TYPE_STRING: color_option_values[i] = (char *)malloc(strlen((char *)val) + 1); strcpy(color_option_values[i], (char *)val); break; case SANE_TYPE_BUTTON: color_option_values[i] = "button"; break; default: fprintf(stderr, "Do not know what to do with option %d\n", opt->type); exit(0); break; } i++; } } }
static PyObject *setOption (_ScanDevice * self, PyObject * args) { SANE_Status st; const SANE_Option_Descriptor *d; SANE_Int i; PyObject *value; int n; if (!PyArg_ParseTuple (args, "iO", &n, &value)) raiseError("Invalid arguments."); if (self->h == NULL) return raiseDeviceClosedError(); d = sane_get_option_descriptor (self->h, n); switch (d->type) { case (SANE_TYPE_BOOL): if (!PyInt_Check (value)) return raiseError("SANE_Bool requires an integer."); SANE_Bool b = PyInt_AsLong(value); if (b != SANE_FALSE && b > SANE_TRUE) b = SANE_TRUE; st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)&b, &i); break; case (SANE_TYPE_INT): if (!PyInt_Check (value)) return raiseError("SANE_Int requires an integer."); SANE_Int j = PyInt_AsLong (value); st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)&j, &i); break; case (SANE_TYPE_FIXED): if (!PyFloat_Check (value)) return raiseError("SANE_Fixed requires an float."); SANE_Fixed f = SANE_FIX (PyFloat_AsDouble (value)); st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)&f, &i); break; case (SANE_TYPE_STRING): if (!PyUNICODE_CHECK (value)) return raiseError("SANE_String requires a a string."); SANE_String s = malloc (d->size + 1); strncpy (s, PyUNICODE_AsBYTES (value), d->size - 1); ((SANE_String) s)[d->size - 1] = 0; st = sane_control_option (self->h, n, SANE_ACTION_SET_VALUE, (void *)s, &i); free(s); break; case (SANE_TYPE_BUTTON): case (SANE_TYPE_GROUP): break; } if (st != SANE_STATUS_GOOD) return raiseSaneError(st); return Py_BuildValue ("i", i); }
static PyObject *getOptions (_ScanDevice * self, PyObject * args) { const SANE_Option_Descriptor *d; PyObject *list, *value; int i = 1; if (!PyArg_ParseTuple (args, "")) raiseError("Invalid arguments."); if (self->h == NULL) return raiseDeviceClosedError(); if (!(list = PyList_New (0))) raiseError("Unable to allocate list."); do { d = sane_get_option_descriptor (self->h, i); if (d != NULL) { PyObject *constraint = NULL; int j; switch (d->constraint_type) { case (SANE_CONSTRAINT_NONE): Py_INCREF (Py_None); constraint = Py_None; break; case (SANE_CONSTRAINT_RANGE): if (d->type == SANE_TYPE_INT) constraint = Py_BuildValue ("iii", d->constraint.range->min, d->constraint.range->max, d->constraint.range->quant); else constraint = Py_BuildValue ("ddd", SANE_UNFIX (d-> constraint. range->min), SANE_UNFIX (d-> constraint. range->max), SANE_UNFIX (d-> constraint. range->quant)); break; case (SANE_CONSTRAINT_WORD_LIST): constraint = PyList_New (d->constraint.word_list[0]); if (d->type == SANE_TYPE_INT) for (j = 1; j <= d->constraint.word_list[0]; j++) PyList_SetItem (constraint, j - 1, PyInt_FromLong (d->constraint. word_list[j])); else for (j = 1; j <= d->constraint.word_list[0]; j++) PyList_SetItem (constraint, j - 1, PyFloat_FromDouble (SANE_UNFIX (d-> constraint. word_list[j]))); break; case (SANE_CONSTRAINT_STRING_LIST): constraint = PyList_New (0); for (j = 0; d->constraint.string_list[j] != NULL; j++) PyList_Append (constraint, PyUNICODE_FromUNICODE (d->constraint. string_list[j])); break; } value = Py_BuildValue ("isssiiiiO", i, d->name, d->title, d->desc, d->type, d->unit, d->size, d->cap, constraint); PyList_Append (list, value); } i++; } while (d != NULL); return list; }
void testsane (const char *dev_name) { int hlp, x; SANE_Status bla; SANE_Int blubb; SANE_Handle hand; SANE_Parameters pars; const SANE_Option_Descriptor *sod; const SANE_Device **device_list; char buffer[2048]; bla = sane_init (&blubb, auth_callback); fprintf (stderr, "Init : stat=%d ver=%x\nPress Enter to continue...", bla, blubb); getchar (); if (bla != SANE_STATUS_GOOD) return; bla = sane_get_devices (&device_list, SANE_FALSE); fprintf (stderr, "GetDev : stat=%s\n", sane_strstatus (bla)); if (bla != SANE_STATUS_GOOD) return; bla = sane_open (dev_name, &hand); fprintf (stderr, "Open : stat=%s hand=%p\n", sane_strstatus (bla), hand); if (bla != SANE_STATUS_GOOD) return; bla = sane_set_io_mode (hand, 0); fprintf (stderr, "SetIoMode : stat=%s\n", sane_strstatus (bla)); for (hlp = 0; hlp < 9999; hlp++) { sod = sane_get_option_descriptor (hand, hlp); if (sod == NULL) break; fprintf (stderr, "Gopt(%d) : stat=%p\n", hlp, sod); fprintf (stderr, "name : %s\n", sod->name); fprintf (stderr, "title: %s\n", sod->title); fprintf (stderr, "desc : %s\n", sod->desc); fprintf (stderr, "type : %d\n", sod->type); fprintf (stderr, "unit : %d\n", sod->unit); fprintf (stderr, "size : %d\n", sod->size); fprintf (stderr, "cap : %d\n", sod->cap); fprintf (stderr, "ctyp : %d\n", sod->constraint_type); switch (sod->constraint_type) { case SANE_CONSTRAINT_NONE: break; case SANE_CONSTRAINT_STRING_LIST: fprintf (stderr, "stringlist:\n"); break; case SANE_CONSTRAINT_WORD_LIST: fprintf (stderr, "wordlist (%d) : ", sod->constraint.word_list[0]); for (x = 1; x <= sod->constraint.word_list[0]; x++) fprintf (stderr, " %d ", sod->constraint.word_list[x]); fprintf (stderr, "\n"); break; case SANE_CONSTRAINT_RANGE: fprintf (stderr, "range: %d-%d %d \n", sod->constraint.range->min, sod->constraint.range->max, sod->constraint.range->quant); break; } } bla = sane_get_parameters (hand, &pars); fprintf (stderr, "Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d\n", sane_strstatus (bla), pars.format, pars.last_frame, pars.bytes_per_line, pars.pixels_per_line, pars.lines, pars.depth); if (bla != SANE_STATUS_GOOD) return; bla = sane_start (hand); fprintf (stderr, "Start : stat=%s\n", sane_strstatus (bla)); if (bla != SANE_STATUS_GOOD) return; do { bla = sane_read (hand, buffer, sizeof (buffer), &blubb); /*printf("Read : stat=%s len=%d\n",sane_strstatus (bla),blubb); */ if (bla != SANE_STATUS_GOOD) { if (bla == SANE_STATUS_EOF) break; return; } fwrite (buffer, 1, blubb, stdout); } while (1); sane_cancel (hand); fprintf (stderr, "Cancel.\n"); sane_close (hand); fprintf (stderr, "Close\n"); for (hlp = 0; hlp < 20; hlp++) fprintf (stderr, "STRS %d=%s\n", hlp, sane_strstatus (hlp)); fprintf (stderr, "Exit.\n"); }