Example #1
0
SANE_Status
sane_open (SANE_String_Const name, SANE_Handle * h)
{
  struct device *dev;

  DBG (3, "%s: '%s'\n", __FUNCTION__, name);

  if (!devlist)
    sane_get_devices (NULL, SANE_TRUE);

  if (!name || !*name) {
    /* special case of empty name: open first available device */
    for (dev = devices_head; dev; dev = dev->next) {
      if (dev->dn != -1) {
	if (sane_open (dev->sane.name, h) == SANE_STATUS_GOOD)
	  return SANE_STATUS_GOOD;
      }
    }
  } else {
    for (dev = devices_head; dev; dev = dev->next) {
      if (strcmp(name, dev->sane.name) == 0) {
	*h = dev;
	return dev->io->dev_open(dev);
      }
    }
  }

  return SANE_STATUS_INVAL;
}
Example #2
0
static PyObject *openDevice (PyObject * self, PyObject * args)
{
    _ScanDevice *rv;
    SANE_Status st;
    char *name;

    if (!PyArg_ParseTuple (args, "s", &name))
        raiseError("Invalid arguments");

    rv = newScanDeviceObject ();

    if (rv == NULL)
        return raiseError("Unable to create _ScanDevice object.");

    st = sane_open (name, &(rv->h));

    if (st != SANE_STATUS_GOOD)
    {
        Py_DECREF (rv);
        return raiseSaneError (st);
    }
    return (PyObject *) rv;
}
Example #3
0
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)));
            }
        }
    }
Example #4
0
/** Function Configs_Modify
 *  @brief   oyCMMapi8_s SANE scanner manipulation
 *
 *  @version Oyranos: 0.1.10
 *  @since   2009/01/19 (Oyranos: 0.1.10)
 *  @date    2009/08/21
 *
 *  \todo { Test }
 */
int Configs_Modify(oyConfigs_s * devices, oyOptions_s * options)
{
   oyOption_s *version_opt = NULL;
   oyOption_s *version_opt_dev = NULL;
   oyConfig_s *device = NULL;
   int num_devices, g_error = 0;
   int call_sane_exit = 0;
   const char *command_list = NULL,
              *command_properties = NULL;

   oyAlloc_f allocateFunc = malloc;

   printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK));

   /* "error handling" section */
   if (!devices || !oyConfigs_Count(devices)) {
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "No devices given! Options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK) );
      return 1;
   }

   /* "help" call section */
   if (oyOptions_FindString(options, "command", "help") || !options || !oyOptions_Count(options)) {
    /** oyMSG_WARN should make shure our message is visible. */
      ConfigsFromPatternUsage((oyStruct_s *) options);
      return 0;
   }

   num_devices = oyConfigs_Count(devices);
   command_list = oyOptions_FindString(options, "command", "list");
   command_properties = oyOptions_FindString(options, "command", "properties");

   /* Now we get some options [IN], and we already have some devices with
    * possibly already assigned options. Those provided through the input
    * oyOptions_s should take presedence over ::data & ::backend_core ones.
    * OTOH, all device_* options have a 1-1 relationship meaning if
    * one changes, probably all other should. So the simplest [naive] approach
    * would be to ignore all device_* options [IN] that are already in device.
    * Except from driver_version which has a special meaning.
    */

   /* Handle "driver_version" option [IN] */
   /* Check the first device to see if a positive driver_version is provided. */
   /* If not, consult the input options */
   device = oyConfigs_Get(devices, 0);
   version_opt_dev = oyConfig_Find(device, "driver_version");
   if (version_opt_dev && oyOption_GetValueInt(version_opt_dev, 0) > 0)
      call_sane_exit = 0;
   else
      check_driver_version(options, &version_opt, &call_sane_exit);
   oyConfig_Release(&device);
   oyOption_Release(&version_opt_dev);

   if (command_list) {
      /* "list" call section */
      int i;

      for (i = 0; i < num_devices; ++i) {
         const SANE_Device *device_context = NULL;
         SANE_Status status = SANE_STATUS_INVAL;
         oyOption_s *name_opt_dev = NULL,
                    *handle_opt_dev = NULL,
                    *context_opt_dev = NULL;
         const char *sane_name = NULL,
                    *sane_model = NULL;
         int error = 0;

         device = oyConfigs_Get(devices, i);

         if(oyOptions_Count(*oyConfig_GetOptions(device,"backend_core")))
           printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK));
         if(oyOptions_Count(*oyConfig_GetOptions(device,"data")))
           printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK));

         /*Ignore device without a device_name*/
         if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_name\" is missing from config object!");
            oyConfig_Release(&device);
            g_error++;
            continue;
         }

         /*Handle "driver_version" option [OUT] */
         version_opt_dev = oyConfig_Find(device, "driver_version");
         if (!version_opt_dev && version_opt)
            oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &version_opt, -1);
         oyOption_Release(&version_opt_dev);

         /*Handle "device_context" option */
         /*This is always provided by Configs_FromPattern()
          * [or should be alternatively by the user].
          * Configs_Modify() will not scan for SANE devices
          * because it takes too long*/
         context_opt_dev = oyConfig_Find(device, "device_context");
         if (!context_opt_dev) {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_context\" option is missing!");
            error = g_error = 1;
         }
         if (!error) {
            device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc);
            sane_name  = device_context->name;
            sane_model = device_context->model;
         }

         /*Handle "oyNAME_NAME" option */
         name_opt_dev = oyConfig_Find(device, "oyNAME_NAME");
         if (!error && !name_opt_dev && oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN))
            oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"),
                                  CMM_BASE_REG OY_SLASH "oyNAME_NAME",
                                  sane_model,
                                  OY_CREATE_NEW);

         /*Handle "device_handle" option */
         handle_opt_dev = oyConfig_Find(device, "device_handle");
         if (!error && !handle_opt_dev) {
            oyPointer_s *handle_ptr = NULL;
            SANE_Handle h;
            status = sane_open(sane_name, &h);
            if (status == SANE_STATUS_GOOD) {
               handle_ptr = oyPointer_New(0);
               oyPointer_Set(handle_ptr,
                            "SANE",
                            "handle",
                            (oyPointer)h,
                            "sane_release_handle",
                            sane_release_handle);
               oyOptions_MoveInStruct(oyConfig_GetOptions(device,"data"),
                                      CMM_BASE_REG OY_SLASH "device_handle",
                                      (oyStruct_s **) &handle_ptr, OY_CREATE_NEW);
            } else
               printf(PRFX "Unable to open sane device \"%s\": %s\n", sane_name, sane_strstatus(status));
         }

         /*Create static rank_map, if not already there*/
         if (!oyConfig_GetRankMap( device))
           oyConfig_SetRankMap( device, _api8.rank_map );

         /*Cleanup*/
         oyConfig_Release(&device);
         oyOption_Release(&context_opt_dev);
         oyOption_Release(&name_opt_dev);
         oyOption_Release(&handle_opt_dev);
      }
   } else if (command_properties) {
      /* "properties" call section */
      int i;

      /*Return a full list of scanner H/W &
       * SANE driver S/W color options
       * with the according rank map */

      for (i = 0; i < num_devices; ++i) {
         SANE_Device *device_context = NULL;
         SANE_Status status = SANE_STATUS_INVAL;
         SANE_Handle device_handle;
         oyOption_s *name_opt_dev = NULL,
                    *handle_opt_dev = NULL,
                    *context_opt_dev = NULL;
         oyConfig_s *device_new = NULL;
         char *device_name = NULL;

         /* All previous device properties are considered obsolete
          * and a new device is created. Basic options are moved from
          * the old to new device */
         device = oyConfigs_Get(devices, i);
         device_new = oyConfig_FromRegistration(CMM_BASE_REG, 0);

         printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK));
         printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK));

         /*Ignore device without a device_name*/
         if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_name\" is NULL, or missing from config object!");
            oyConfig_Release(&device);
            oyConfig_Release(&device_new);
            g_error++;
            continue;
         }

         /*Handle "driver_version" option [OUT] */
         if (version_opt) {
            oyOption_s *tmp = oyOption_Copy(version_opt, 0);
            oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &tmp, -1);
         }

         /* 1. Get the "device_name" from old device */
         name_opt_dev = oyConfig_Find(device, "device_name");
         device_name = oyOption_GetValueText(name_opt_dev, allocateFunc);
         oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &name_opt_dev, -1);

         /* 2. Get the "device_context" from old device */
         /* It should be there, see "list" call above */
         context_opt_dev = oyConfig_Find(device, "device_context");
         if (context_opt_dev) {
            device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc);
            if (device_context) {
               oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &context_opt_dev, -1);
            } else {
               SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                       _DBG_ARGS_, "The \"device_context\" is NULL!");
               oyOption_Release(&context_opt_dev);
               g_error++;
            }
         } else {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_context\" option is missing!");
            g_error++;
         }

         /* 3. Get the scanner H/W properties from old device */
         /* FIXME: we only recompute them, just in case they are not in old device */
         if (device_context) {
            DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device_new,"backend_core"));
         }

         /* 4. Get the "device_handle" from old device */
         /* If not there, get one from SANE */
         handle_opt_dev = oyConfig_Find(device, "device_handle");
         if (handle_opt_dev) {
           oyPointer_s * oy_struct = (oyPointer_s*)oyOption_GetStruct(
                                           handle_opt_dev, oyOBJECT_POINTER_S );
           device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct);
           oyPointer_Release( &oy_struct );
            oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &handle_opt_dev, -1);
         } else {
            printf(PRFX "Opening sane device \"%s\"..", device_name); fflush(NULL);
            status = sane_open( device_name, &device_handle );
            if (status != SANE_STATUS_GOOD)
               printf("[FAIL: %s]\n", sane_strstatus(status));
            else
               printf("[OK]\n");
         }

         if (handle_opt_dev || status == SANE_STATUS_GOOD) {
            /* Use the device_handle to get the device color options */
            ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device_new,"backend_core"));

            /*5. Set the rank map*/
            oyConfig_SetRankMap( device_new, _api8.rank_map );
         }

         /*Cleanup*/
         /* Remove old, add new device */
         oyConfig_Release(&device);
         oyConfigs_ReleaseAt(devices, i);
         oyConfigs_MoveIn(devices, &device_new, -1);

         /*If we had to open a SANE device, we'll have to close it*/
         if (status == SANE_STATUS_GOOD) {
            printf(PRFX "sane_close(%s)\n", device_name);
            sane_close(device_handle);
         }

         free(device_context);
         free(device_name);
      }
   } else {
      /*unsupported, wrong or no command */
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "No supported commands in options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK) );
      ConfigsFromPatternUsage((oyStruct_s *) options);
      g_error = 1;
   }

   /*Cleanup*/
   if (call_sane_exit) {
      printf(PRFX "sane_exit()\n");
      sane_exit();
   }

   oyOption_Release(&version_opt);

   printf(PRFX "Leaving %s\n", __func__);
   return g_error;
}
Example #5
0
/** Function Configs_FromPattern
 *  @brief   CMM_NICK oyCMMapi8_s scanner devices
 *
 *  @param[in] 	registration	a string to compare ??????
 *  @param[in]		options			read what to do from the options object
 *  @param[out]	s					Return a configuration for each device found
 *
 *  @version Oyranos: 0.1.10
 *  @since   2009/01/19 (Oyranos: 0.1.10)
 *  @date    2009/02/09
 */
int Configs_FromPattern(const char *registration, oyOptions_s * options, oyConfigs_s ** s)
{
   oyConfig_s *device = NULL;
   oyConfigs_s *devices = NULL;
   oyOption_s *context_opt = NULL,
              *handle_opt = NULL,
              *version_opt = NULL,
              *name_opt = NULL;
   int i, num_devices, g_error = 0, status, call_sane_exit = 0;
   const char *device_name = 0, *command_list = 0, *command_properties = 0;
   const SANE_Device **device_list = NULL;
   int rank;
   oyAlloc_f allocateFunc = malloc;

   printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK));

   rank = oyFilterRegistrationMatch(_api8.registration, registration,
                                        oyOBJECT_CMM_API8_S);
   command_list = oyOptions_FindString(options, "command", "list");
   command_properties = oyOptions_FindString(options, "command", "properties");
   device_name = oyOptions_FindString(options, "device_name", 0);

   /* "error handling" section */
   if (rank == 0) {
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "Registration match Failed. Options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK));
      return 1;
   }
   if (s == NULL) {
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "oyConfigs_s is NULL! Options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK));
      return 1;
   }
   if (*s != NULL) {
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "Devices struct already present! Options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK));
      return 1;
   }

   if (!device_name && command_properties) {
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "Device_name is mandatory for properties command:\n%s",
              _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK));
      return 1;
   }

   /* "help" call section */
   if (oyOptions_FindString(options, "command", "help") || !options || !oyOptions_Count(options)) {
    /** oyMSG_WARN should make shure our message is visible. */
      ConfigsFromPatternUsage((oyStruct_s *) options);
      return 0;
   }

   context_opt = oyOptions_Find(options, "device_context", oyNAME_PATTERN);
   handle_opt = oyOptions_Find(options, "device_handle", oyNAME_PATTERN);
   name_opt = oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN);

   /*Handle "driver_version" option [IN] */
   check_driver_version(options, &version_opt, &call_sane_exit);

   devices = oyConfigs_New(0);
   if (command_list) {
      /* "list" call section */

      if (device_name &&   /*If a user provides a device_name option,*/
          !context_opt &&  /*and does not need the device_context data,*/
          !name_opt        /*or the oyNAME_NAME description*/
         )
         num_devices = 1;  /*then we can get away without calling GetDevices()*/
      else if (GetDevices(&device_list, &num_devices) != 0) {
         num_devices = 0; /*So that for loop will not run*/
         ++g_error;
      }

      for (i = 0; i < num_devices; ++i) {
         int error = 0;
         const char *sane_name = NULL,
                    *sane_model = NULL;

         if (device_list) {
            sane_name = device_list[i]->name;
            sane_model = device_list[i]->model;
         } else {
            sane_name = device_name;
         }

         /*Handle "device_name" option [IN] */
         if (device_name &&                        /*device_name is provided*/
             sane_name &&                          /*and sane_name has been retrieved*/
             strcmp(device_name, sane_name) != 0)  /*and they don't match,*/
            continue;                              /*then try the next*/

         device = oyConfig_FromRegistration(CMM_BASE_REG, 0);

         /*Handle "driver_version" option [OUT] */
         if (version_opt) {
            oyOption_s * tmp = oyOption_Copy(version_opt, 0);
            oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &tmp, -1);
         }

         /*Handle "device_name" option [OUT] */
         oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"),
                               CMM_BASE_REG OY_SLASH "device_name",
                               sane_name,
                               OY_CREATE_NEW);

         /*Handle "oyNAME_NAME" option */
         if (name_opt)
            oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"),
                                  CMM_BASE_REG OY_SLASH "oyNAME_NAME",
                                  sane_model,
                                  OY_CREATE_NEW);

         /*Handle "device_context" option */
         /* SANE Backend protocol states that device_context is *always* returned
          * This is a slight variation: Only when GetDevices() is called will it be returned,
          * unless we call sane_exit*/
         if (device_list && !call_sane_exit) {
            oyBlob_s *context_blob = oyBlob_New(NULL);
            oyOption_s *context_opt = oyOption_FromRegistration(
                                     CMM_BASE_REG OY_SLASH "device_context", 0);

            oyBlob_SetFromData(context_blob, (oyPointer) device_list[i], sizeof(SANE_Device), "sane");
            oyOption_MoveInStruct(context_opt, (oyStruct_s **) & context_blob);
            oyOptions_MoveIn(*oyConfig_GetOptions(device,"data"), &context_opt, -1);
         }

         /*Handle "device_handle" option */
         if (handle_opt && !call_sane_exit) {
            oyPointer_s *handle_ptr = NULL;
            SANE_Handle h;
            status = sane_open(sane_name, &h);
            if (status == SANE_STATUS_GOOD) {
               handle_ptr = oyPointer_New(0);
               oyPointer_Set(handle_ptr,
                            "SANE",
                            "handle",
                            (oyPointer)h,
                            "sane_release_handle",
                            sane_release_handle);
               oyOptions_MoveInStruct(oyConfig_GetOptions(device,"data"),
                                      CMM_BASE_REG OY_SLASH "device_handle",
                                      (oyStruct_s **) &handle_ptr, OY_CREATE_NEW);
            } else
               printf(PRFX "Unable to open sane device \"%s\": %s\n", sane_name, sane_strstatus(status));
         }

         oyConfig_SetRankMap( device, _api8.rank_map );

         error = oyConfigs_MoveIn(devices, &device, -1);

         /*Cleanup*/
         if (error) {
            oyConfig_Release(&device);
            ++g_error;
         }
      }

      *s = devices;
   } else if (command_properties) {
      /* "properties" call section */
      const SANE_Device *device_context = NULL;
      SANE_Device *aux_context = NULL;
      SANE_Handle device_handle = NULL;

      /*Return a full list of scanner H/W &
       * SANE driver S/W color options
       * with the according rank map */

      device = oyConfig_FromRegistration(CMM_BASE_REG, 0);

      /*Handle "driver_version" option [OUT] */
      if (version_opt) {
         oyOption_s *tmp = oyOption_Copy(version_opt, 0);
         oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &tmp, -1);
      }

      /*1a. Get the "device_context"*/
      if (!context_opt) { /*we'll have to get it ourselves*/
         if (GetDevices(&device_list, &num_devices) == 0) {
            device_context = *device_list;
            while (device_context) {
               if(device_name && device_context->name &&
                  strcmp(device_name,device_context->name) == 0)
                  break;
               device_context++;
            }
            if (!device_context) {
               printf(PRFX "device_name does not match any installed device.\n");
               g_error++;
            }
         } else {
            g_error++;
         }
      } else {
         aux_context = (SANE_Device*)oyOption_GetData(context_opt, NULL, allocateFunc);
         device_context = aux_context;
      }

      /*1b. Use the "device_context"*/
      if (device_context)
         DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device,"backend_core"));

      /*2a. Get the "device_handle"*/
      if (!handle_opt) {
         status = sane_open( device_name, &device_handle );
         if (status != SANE_STATUS_GOOD) {
            printf(PRFX "Unable to open sane device \"%s\": %s\n", device_name, sane_strstatus(status));
            g_error++;
         }
      } else {
        oyPointer_s * oy_struct = (oyPointer_s*) oyOption_GetStruct( handle_opt,
                                                           oyOBJECT_POINTER_S );
        device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct);
        oyPointer_Release( &oy_struct );
      }

      if (device_handle) {
         /*2b. Use the "device_handle"*/
         ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device,"backend_core"));

         /*3. Set the rank map*/
         oyConfig_SetRankMap( device, _api8.rank_map );
      }
      oyConfigs_MoveIn(devices, &device, -1);

      /*Cleanup*/
      free(aux_context);

      *s = devices;
   } else {
      /*unsupported, wrong or no command */
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "No supported commands in options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK) );
      ConfigsFromPatternUsage((oyStruct_s *) options);
      g_error = 1;
   }

   /*Global Cleanup*/
   if (call_sane_exit) {
      printf(PRFX "sane_exit()\n");
      sane_exit();
   }

   oyOption_Release(&context_opt);
   oyOption_Release(&handle_opt);
   oyOption_Release(&version_opt);
   oyOption_Release(&name_opt );

   printf(PRFX "Leaving %s\n", __func__);
   return g_error;
}
Example #6
0
// --------------------------------------------------------------
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);
	}
}
Example #7
0
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;
}
Example #8
0
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;

}
Example #9
0
char *internalDoScanningOperation(char *uuid, char *lang) {

  int request_resolution = 0;
  int docid;
  int current_page = 0;
  int total_requested_pages;
  double totbytes = 0;
  SANE_Status status;
  SANE_Handle *openDeviceHandle;
  SANE_Byte *raw_image;
  SANE_Parameters pars;
  char *docid_s;
  char *total_requested_pages_s;
  char *devName;
  char *outFilename;
  char *raw_image_format;
  char *header;

  o_log(DEBUGM, "doScanningOperation: sane initialized uuid(%s)",(char *)uuid);
  updateScanProgress(uuid, SCAN_WAITING_ON_SCANNER, 0);

  // Open the device
  devName = getScanParam(uuid, SCAN_PARAM_DEVNAME);
  o_log(DEBUGM, "sane_open of \"%s\"",devName);
  status = sane_open ((SANE_String_Const) devName, (SANE_Handle)&openDeviceHandle);
  if(status != SANE_STATUS_GOOD) {
    handleSaneErrors("Cannot open device ", devName, status, 0);
    updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status);
    free(devName);
    return 0;
  }
  free(devName);

  /* ========================================================== */
  if ( ! setOptions( (char *)uuid, openDeviceHandle, &request_resolution ) )
    return 0;
  o_log(DEBUGM, "sane_start: setOptions returned request_resolution %d\n",request_resolution);

  int timeout = 5;
  while( 0 < timeout ) {
    status = sane_start (openDeviceHandle);
    if(status == SANE_STATUS_GOOD) {  
      break;
    }
    else {
      if(status == SANE_STATUS_DEVICE_BUSY ) {  
        // BUSY signal could be the scanner just having a 
        // bit of lag - specially network connected devices
        timeout--;
        if ( timeout == 0 ) {
          handleSaneErrors("Cannot start scanning", "even after trying several time", status, 0);
          updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status);
          return 0;
        }
        else {
          o_log(WARNING, "Device reports not ready to 'start', waiting 500ms. Will try another %d times", timeout);
          usleep(500 * 1000); // 500ms or 0.5sec
        }
      }
      else {
        handleSaneErrors("Cannot start scanning", "", status, 0);
        updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status);
        return 0;
      }
    }
  }

  // Get scanning params (from the scanner)
  if( request_resolution == 0 ) {
    o_log(DEBUGM, "Resolution did not get set in scanner setup.");
    updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10004);
    return 0;
  }

  o_log(DEBUGM, "Get scanning params");
  status = sane_get_parameters (openDeviceHandle, &pars);
  o_log(INFORMATION, "Scanner Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d",
    sane_strstatus (status),
    pars.format, pars.last_frame,
    pars.bytes_per_line, pars.pixels_per_line,
    pars.lines, pars.depth);

  switch (pars.format) {
    case SANE_FRAME_GRAY:
      o_log(DEBUGM, "Expecting Gray data (1 channel only).");
      raw_image_format = o_strdup( "P5" );
      break;
    case SANE_FRAME_RGB:
      o_log(DEBUGM, "Expecting RGB data (3 channels).");
      raw_image_format = o_strdup( "P6" );
      break;
    default:
      o_log(DEBUGM, "backend returns three frames speratly. We do not currently support this.");
      updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10003);
      return 0;
      break;
  }
  
  header = o_printf ("%s\n# SANE data follows\n%d %d\n%d\n", 
    raw_image_format, pars.pixels_per_line, pars.lines,
    (pars.depth <= 8) ? 255 : 65535);
  free( raw_image_format );


  // Save Record
  //
  docid_s = getScanParam(uuid, SCAN_PARAM_DOCID);
  total_requested_pages_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_PAGES);
  total_requested_pages = atoi(total_requested_pages_s);
  free(total_requested_pages_s);
  if( docid_s == NULL ) {
    o_log(DEBUGM, "Saving record");
    updateScanProgress(uuid, SCAN_DB_WORKING, 0);

    docid_s = addNewScannedDoc(pars.lines, pars.pixels_per_line, request_resolution, total_requested_pages); 
    setScanParam(uuid, SCAN_PARAM_DOCID, docid_s);
    setScanParam(uuid, SCAN_PARAM_ON_PAGE, "1");
    current_page = 1;
  }
  else {
    char *current_page_s = getScanParam(uuid, SCAN_PARAM_ON_PAGE);
    current_page = atoi(current_page_s);
    free(current_page_s);

    current_page++;

    current_page_s = itoa(current_page, 10);
    setScanParam(uuid, SCAN_PARAM_ON_PAGE, current_page_s);
    free(current_page_s);
  }
  docid = atoi(docid_s);
  free(docid_s);

  totbytes = (double)((pars.bytes_per_line * pars.lines));

  /* ========================================================== */
  raw_image = collectData( (char *)uuid, openDeviceHandle, totbytes, pars.bytes_per_line, header );
  o_log(INFORMATION, "Scanning done.");

  o_log(DEBUGM, "sane_cancel");
  sane_cancel(openDeviceHandle);

  o_log(DEBUGM, "sane_close");
  sane_close(openDeviceHandle);


  // Convert Raw into JPEG
  //
  updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 0);
  PIX *pix;
  if ( ( pix = pixReadMem( raw_image, (pars.bytes_per_line*pars.lines)+strlen(header) ) ) == NULL) {
    o_log(ERROR, "Could not load the image data into a PIX");
  }
  updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 55);
  o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", pixGetDepth(pix));
  free(raw_image);
  free(header);

  outFilename = o_printf("%s/scans/%d_%d.jpg", BASE_DIR, docid, current_page);
  pixWrite(outFilename, pix, IFF_JFIF_JPEG);
  free(outFilename);
  updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 100);
  o_log(INFORMATION, "Conversion process: Complete");




  // Do OCR - on this page
  // - OCR libs just wants the raw data and not the image header
  ocrImage( uuid, docid, current_page, request_resolution, pix, lang );


#ifdef CAN_PHASH
  // Calulate the pHash, so we can compare images later
  if( current_page == 1 ) {
    updateScanProgress(uuid, SCAN_CALULATING_PHASH, 0);
    unsigned long long hash = getImagePhash_px( pix );
    savePhash( docid, hash );
  }
#endif /* CAN_PHASH */
  pixDestroy( &pix );


  // cleaup && What should we do next
  //
  o_log(DEBUGM, "mostly done.");
  if(current_page >= total_requested_pages)
    updateScanProgress(uuid, SCAN_FINISHED, docid);
  else
    updateScanProgress(uuid, SCAN_WAITING_ON_NEW_PAGE, ++current_page);

  o_log(DEBUGM, "Page scan done.");

  return o_strdup("OK"); 
}
Example #10
0
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");
}