Пример #1
0
static SANE_Status u12if_getCaps( U12_Device *dev )
{
	int cntr;
	int res_x = 600 ; /*dev->caps.OpticDpi.x */
	DBG( _DBG_INFO, "u12if_getCaps()\n" );

/* FIXME: set dpi_range.max, max_x & max_y on a per model base */
	dev->dpi_max_x       = 600;
	dev->dpi_max_y       = 1200;

	/* A4 devices */
	dev->max_x = 8.5     * (double)_MM_PER_INCH;
	dev->max_y = 11.6934 * (double)_MM_PER_INCH;

	/* limit the range */
	dev->dpi_range.min   = _DEF_DPI;
	dev->dpi_range.max   = dev->dpi_max_y;
	dev->dpi_range.quant = 0;
	dev->x_range.min 	 = 0;
	dev->x_range.max 	 = SANE_FIX(dev->max_x);
	dev->x_range.quant 	 = 0;
	dev->y_range.min 	 = 0;
	dev->y_range.max 	 = SANE_FIX(dev->max_y);
	dev->y_range.quant 	 = 0;

	/* calculate the size of the resolution list +
	 * one more to avoid a buffer overflow, then allocate it...
	 */
	dev->res_list = (SANE_Int *)
					calloc((((res_x * 16)-_DEF_DPI)/25+1),
						sizeof (SANE_Int));

	if (NULL == dev->res_list) {
		DBG( _DBG_ERROR, "alloc fail, resolution problem\n" );
		u12if_close(dev);
		return SANE_STATUS_INVAL;
	}

    /* build up the resolution table */
	dev->res_list_size = 0;
	for( cntr = _DEF_DPI; cntr <= (res_x*16); cntr += 25 ) {
		dev->res_list_size++;
		dev->res_list[dev->res_list_size - 1] = (SANE_Int)cntr;
	}
	
	return SANE_STATUS_GOOD;
}
Пример #2
0
static TW_UINT16 set_one_coord(const char *name, double coord)
{
    SANE_Status status;
    status = sane_option_set_fixed(activeDS.deviceHandle, name, SANE_FIX(coord), NULL);
    if (status != SANE_STATUS_GOOD)
        return sane_status_to_twcc(status);
    return TWCC_SUCCESS;
}
Пример #3
0
/*
 * options
 */
static void
st400_reset_options( ST400_Device *dev )
{
	DBG(DCODE, "st400_reset_options(%p)\n", (void *) dev);

	dev->val[OPT_NUM_OPTS]	= NUM_OPTIONS;
	dev->val[OPT_RESOLUTION]	= dev->opt[OPT_RESOLUTION].constraint.word_list[1];
	dev->val[OPT_DEPTH]		= dev->opt[OPT_DEPTH].constraint.word_list[1];
    dev->val[OPT_THRESHOLD]	= SANE_FIX(50.0);
	dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
    dev->val[OPT_TL_X]		= SANE_FIX(0.0);
	dev->val[OPT_TL_Y]		= SANE_FIX(0.0);
	dev->val[OPT_BR_X]		= SANE_FIX(0.0);
	dev->val[OPT_BR_Y]		= SANE_FIX(0.0);

	if( dev->model->dpi_list )
		dev->opt[OPT_RESOLUTION].constraint.word_list = dev->model->dpi_list;
}
Пример #4
0
scan_area_t 
model_info_max_scan_area(const void *self, const char *option, const char *mode)
{
  _model_info_t *self_ = NULL;
  scan_area_t scan_area;
  
  require (self);
  require (option);

  scan_area.width = SANE_FIX(-1);
  scan_area.height = SANE_FIX(-1);

  self_ = (_model_info_t *) self;

  if(strcmp(option, "adf") == 0 && strcmp_c(mode, "duplex") == 0){
    if(self_->adf_duplex){
      scan_area.width = SANE_FIX (self_->adf_duplex->width * MM_PER_INCH / self_->adf_duplex->base);
      scan_area.height = SANE_FIX (self_->adf_duplex->height * MM_PER_INCH / self_->adf_duplex->base);
    }
  }else {
    if(self_->dfault){
      scan_area.width = SANE_FIX (self_->dfault->width * MM_PER_INCH / self_->dfault->base);
      scan_area.height = SANE_FIX (self_->dfault->height * MM_PER_INCH / self_->dfault->base);
    }
  }

  return scan_area;
}
Пример #5
0
static void reset_options(struct device *dev)
{
  dev->val[OPT_RESOLUTION].w = 150;
  dev->val[OPT_MODE].s = string_match(scan_modes, SANE_VALUE_SCAN_MODE_COLOR);

  /* if docs loaded in adf use it as default source, flatbed oterwise */
  dev->val[OPT_SOURCE].s = UNCONST(doc_sources[(dev->doc_loaded)? 1 : 0]);

  dev->val[OPT_THRESHOLD].w = SANE_FIX(50);

  /* this is reported maximum window size, will be fixed later */
  dev->win_x_range.min = SANE_FIX(0);
  dev->win_x_range.max = SANE_FIX((double)dev->max_win_width / PNT_PER_MM);
  dev->win_x_range.quant = SANE_FIX(1);
  dev->win_y_range.min = SANE_FIX(0);
  dev->win_y_range.max = SANE_FIX((double)dev->max_win_len / PNT_PER_MM);
  dev->win_y_range.quant = SANE_FIX(1);
  dev->val[OPT_SCAN_TL_X].w = dev->win_x_range.min;
  dev->val[OPT_SCAN_TL_Y].w = dev->win_y_range.min;
  dev->val[OPT_SCAN_BR_X].w = dev->win_x_range.max;
  dev->val[OPT_SCAN_BR_Y].w = dev->win_y_range.max;
}
Пример #6
0
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdlib.h>
#include <string.h>

#include "sanemock.h"

static SANE_Device **sane_device_list = NULL;
static SANE_Virtual_Device *first_virtual_device = NULL;

static SANE_String_Const string_list[] = { SANE_I18N("First String Option"), SANE_I18N("Second String Option"), 0 };
static SANE_Int word_list_int[] = { 10, 20, 30 };
static SANE_Int word_list_fixed[] = { SANE_FIX(25.4), SANE_FIX(30.2) };
static SANE_Range range = { SANE_FIX(10.0), SANE_FIX(100.0), SANE_FIX(5.0) };

SANE_Bool is_initialized = SANE_FALSE;

SANE_Status sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize) {
    if (is_initialized) {
        return SANE_STATUS_INVAL;
    }
    SANE_Device *sane_device = NULL;
    SANE_Virtual_Device* virtual_device = NULL;
    SANE_Virtual_Device* previous_virtual_device = NULL;
    *version_code = SANE_VERSION_CODE(MAJOR, MINOR, BUILD);
    sane_device_list = malloc((DEVICE_COUNT + 1) * sizeof(sane_device));
    SANE_Int i;
    for (i = 0; i < DEVICE_COUNT; i++) {
Пример #7
0
#include "leo.h"

/*--------------------------------------------------------------------------*/

/* Lists of possible scan modes. */
static SANE_String_Const scan_mode_list[] = {
  BLACK_WHITE_STR,
  GRAY_STR,
  COLOR_STR,
  NULL
};

/*--------------------------------------------------------------------------*/

/* Minimum and maximum width and length supported. */
static SANE_Range x_range = { SANE_FIX (0), SANE_FIX (8.5 * MM_PER_INCH), 0 };
static SANE_Range y_range =
  { SANE_FIX (0), SANE_FIX (11.5 * MM_PER_INCH), 0 };

/*--------------------------------------------------------------------------*/

static const SANE_Range gamma_range = {
  0,				/* minimum */
  255,				/* maximum */
  0				/* quantization */
};

/*--------------------------------------------------------------------------*/

static SANE_String_Const halftone_pattern_list[] = {
  SANE_I18N ("None"),
Пример #8
0
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);
}
Пример #9
0
/* called after option changed and in set_window */
static int fix_window(struct device *dev)
{
  double win_width_mm, win_len_mm;
  int i;
  int threshold = SANE_UNFIX(dev->val[OPT_THRESHOLD].w);

  dev->resolution = dpi_to_code(dev->val[OPT_RESOLUTION].w);
  dev->composition = scan_mode_to_code[string_match_index(scan_modes, dev->val[OPT_MODE].s)];

  if (dev->composition == MODE_LINEART ||
      dev->composition == MODE_HALFTONE) {
    dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
  } else {
    dev->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
  }
  if (threshold < 30) {
    dev->val[OPT_THRESHOLD].w = SANE_FIX(30);
  } else if (threshold > 70) {
    dev->val[OPT_THRESHOLD].w = SANE_FIX(70);
  }
  threshold = SANE_UNFIX(dev->val[OPT_THRESHOLD].w);
  dev->threshold = (threshold - 30) / 10;
  dev->val[OPT_THRESHOLD].w = SANE_FIX(dev->threshold * 10 + 30);

  dev->doc_source = doc_source_to_code[string_match_index(doc_sources, dev->val[OPT_SOURCE].s)];

  /* max window len is dependent of document source */
  if (dev->doc_source == DOC_FLATBED ||
      (dev->doc_source == DOC_AUTO && !dev->doc_loaded))
    dev->max_len = dev->max_len_fb;
  else
    dev->max_len = dev->max_len_adf;

  /* parameters */
  dev->win_y_range.max = SANE_FIX((double)dev->max_len / PNT_PER_MM);

  /* window sanity checking */
  for (i = OPT_SCAN_TL_X; i <= OPT_SCAN_BR_Y; i++) {
    if (dev->val[i].w < dev->opt[i].constraint.range->min)
      dev->val[i].w = dev->opt[i].constraint.range->min;
    if (dev->val[i].w > dev->opt[i].constraint.range->max)
      dev->val[i].w = dev->opt[i].constraint.range->max;
  }

  if (dev->val[OPT_SCAN_TL_X].w > dev->val[OPT_SCAN_BR_X].w)
    SWAP_Word(dev->val[OPT_SCAN_TL_X].w, dev->val[OPT_SCAN_BR_X].w);
  if (dev->val[OPT_SCAN_TL_Y].w > dev->val[OPT_SCAN_BR_Y].w)
    SWAP_Word(dev->val[OPT_SCAN_TL_Y].w, dev->val[OPT_SCAN_BR_Y].w);

  /* recalculate millimeters to inches */
  dev->win_off_x = SANE_UNFIX(dev->val[OPT_SCAN_TL_X].w) / MM_PER_INCH;
  dev->win_off_y = SANE_UNFIX(dev->val[OPT_SCAN_TL_Y].w) / MM_PER_INCH;

  /* calc win size in mm */
  win_width_mm = SANE_UNFIX(dev->val[OPT_SCAN_BR_X].w) -
		    SANE_UNFIX(dev->val[OPT_SCAN_TL_X].w);
  win_len_mm = SANE_UNFIX(dev->val[OPT_SCAN_BR_Y].w) -
		  SANE_UNFIX(dev->val[OPT_SCAN_TL_Y].w);
  /* convert mm to 1200 dpi points */
  dev->win_width = (int)(win_width_mm * PNT_PER_MM);
  dev->win_len = (int)(win_len_mm * PNT_PER_MM);

  /* don't scan if window is zero size */
  if (!dev->win_width || !dev->win_len) {
    /* "The scan cannot be started with the current set of options." */
    dev->state = SANE_STATUS_INVAL;
    return 0;
  }

  return 1;
}
Пример #10
0
typedef enum { optCount,
	       optGroupMode, optMode, optResolution,
#ifdef SM3600_SUPPORT_EXPOSURE
	       optBrightness, optContrast,
#endif
	       optPreview, optGrayPreview,
	       optGroupGeometry,optTLX, optTLY, optBRX, optBRY,
	       optGroupEnhancement,
	       optGammaY, optGammaR,optGammaG,optGammaB,
	       optLast } TOptionIndex;

static const SANE_String_Const aScanModes[]= {  "color", "gray", "lineart",
						"halftone", NULL };

static const SANE_Range rangeXmm = {
  SANE_FIX(0),
  SANE_FIX(220),
  SANE_FIX(0.1) };

static const SANE_Range rangeYmm = {
  SANE_FIX(0),
  SANE_FIX(300),
  SANE_FIX(0.1) };

#ifdef SM3600_SUPPORT_EXPOSURE
static const SANE_Range rangeLumi = {
  SANE_FIX(-100.0),
  SANE_FIX(100.0),
  SANE_FIX(1.0) };
#endif
Пример #11
0
int bb_open(struct ledm_session *ps)
{
  struct bb_ledm_session *pbb;
  struct device_settings *ds;
  int stat=1, i, j;

  _DBG("bb_open()\n");

  if ((ps->bb_session = create_session()) == NULL)
    goto bugout;

  pbb = ps->bb_session;

  /* Get scanner elements from device. */
  if (get_scanner_elements(ps, &pbb->elements))
  {
    goto bugout;
  }

  /* Determine supported Scan Modes. */
  ds = &pbb->elements.config.settings;
  for(i=0, j=0; i<CE_MAX; i++)
  {
    if (ds->color[i] == CE_K1)
    {
      ps->scanModeList[j] = SANE_VALUE_SCAN_MODE_LINEART;
      ps->scanModeMap[j++] = CE_K1;
    }
    if (ds->color[i] == CE_GRAY8)
    {
       ps->scanModeList[j] = SANE_VALUE_SCAN_MODE_GRAY;
       ps->scanModeMap[j++] = CE_GRAY8;
    }
    if (ds->color[i] == CE_COLOR8)
    {
      ps->scanModeList[j] = SANE_VALUE_SCAN_MODE_COLOR;
      ps->scanModeMap[j++] = CE_COLOR8;
    }
  }
   
  /* Determine scan input sources. */
  i=0;
  if (pbb->elements.config.platen.flatbed_supported)
  {
    ps->inputSourceList[i] = STR_ADF_MODE_FLATBED;
    ps->inputSourceMap[i++] = IS_PLATEN;
  }
  if (pbb->elements.config.adf.supported)
  {
    ps->inputSourceList[i] = STR_ADF_MODE_ADF;
    ps->inputSourceMap[i++] = IS_ADF;
  }
  if (pbb->elements.config.adf.duplex_supported)
  {
    ps->inputSourceList[i] = STR_TITLE_DUPLEX;
    ps->inputSourceMap[i++] = IS_ADF_DUPLEX;
  }

  /* Determine if jpeg quality factor is supported. */
  if (pbb->elements.config.settings.jpeg_quality_factor_supported)
    ps->option[LEDM_OPTION_JPEG_QUALITY].cap &= ~SANE_CAP_INACTIVE;
  else
    ps->option[LEDM_OPTION_JPEG_QUALITY].cap |= SANE_CAP_INACTIVE;


  /* Set flatbed x,y extents. */
  ps->platen_min_width = SANE_FIX(pbb->elements.config.platen.minimum_size.width/1000.0*MM_PER_INCH);
  ps->platen_min_height = SANE_FIX(pbb->elements.config.platen.minimum_size.height/1000.0*MM_PER_INCH);
  ps->platen_tlxRange.max = SANE_FIX(pbb->elements.config.platen.maximum_size.width/11.811023);
  ps->platen_brxRange.max = ps->platen_tlxRange.max;
  ps->platen_tlyRange.max = SANE_FIX(pbb->elements.config.platen.maximum_size.height/11.811023);
  ps->platen_bryRange.max = ps->platen_tlyRange.max;

  /* Set adf/duplex x,y extents. */
  ps->adf_min_width = SANE_FIX(pbb->elements.config.adf.minimum_size.width/1000.0*MM_PER_INCH);
  ps->adf_min_height = SANE_FIX(pbb->elements.config.adf.minimum_size.height/1000.0*MM_PER_INCH);
  ps->adf_tlxRange.max = SANE_FIX(pbb->elements.config.adf.maximum_size.width/11.811023);
  ps->adf_brxRange.max = ps->adf_tlxRange.max;
  ps->adf_tlyRange.max = SANE_FIX(pbb->elements.config.adf.maximum_size.height/11.811023);
  ps->adf_bryRange.max = ps->adf_tlyRange.max;

  if (pbb->elements.config.platen.flatbed_supported)
  {
      i = pbb->elements.config.platen.platen_resolution_list[0] + 1;
      while(i--)
      {
          _DBG("bb_open platen_resolution_list = %d\n",  pbb->elements.config.platen.platen_resolution_list[i]);
          ps->platen_resolutionList[i] = pbb->elements.config.platen.platen_resolution_list[i];
          ps->resolutionList[i] = pbb->elements.config.platen.platen_resolution_list[i];
      }
  }
  if (pbb->elements.config.adf.supported)
  {
     i = pbb->elements.config.adf.adf_resolution_list[0] + 1;
     while(i--)
     {
         _DBG("bb_open adf_resolution_list = %d\n", pbb->elements.config.adf.adf_resolution_list[i]);
         ps->adf_resolutionList[i] = pbb->elements.config.adf.adf_resolution_list[i]; 
         ps->resolutionList[i] = pbb->elements.config.adf.adf_resolution_list[i];
     }
  }
  stat = 0;

bugout:
  return stat;
} /* bb_open */
Пример #12
0
static const SANE_Range buffer_range = {
    1024,				/* minimum bytes */
    2048 * 1024,			/* maximum bytes */
    1024				/* quantization */
};

/* range for int value in [0-15] */
static const SANE_Range value16_range = {
    0,				/* minimum */
    15,				/* maximum */
    1				/* quantization */
};

/* range for fixed height value */
static const SANE_Range height_range = {
    SANE_FIX (0),			/* minimum */
    SANE_FIX (29.7),		/* maximum */
    0				/* no quantization : hard to do for float values ... */
};

/* list of astra models */
static const SANE_String_Const astra_models[] =
{ "610", "1220", "1600", "2000", NULL };

/* string list */
static const SANE_String_Const string_list[] =
{ "string1", "string2", "string3", "string4", NULL };

/* last device name used for attach callback */
static char *lastdevname = NULL;
Пример #13
0
/*
 * fixed option
 */
static void
fixed_option (void)
{
    SANE_Status status;
    SANEI_Config config;
    SANE_Word width, height, fixedarray[7];
    SANE_Option_Descriptor *options[3];
    void *values[3];
    int i;

    i = 0;
    options[i] =
        (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
    options[i]->name = "width";
    options[i]->title = "width";
    options[i]->type = SANE_TYPE_FIXED;
    options[i]->unit = SANE_UNIT_NONE;
    options[i]->size = sizeof (SANE_Word);
    options[i]->cap = SANE_CAP_SOFT_SELECT;
    options[i]->constraint_type = SANE_CONSTRAINT_NONE;
    values[i] = &width;
    i++;

    options[i] =
        (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
    options[i]->name = "height";
    options[i]->title = "height";
    options[i]->type = SANE_TYPE_FIXED;
    options[i]->unit = SANE_UNIT_NONE;
    options[i]->size = sizeof (SANE_Word);
    options[i]->cap = SANE_CAP_SOFT_SELECT;
    options[i]->constraint_type = SANE_CONSTRAINT_NONE;
    values[i] = &height;
    i++;

    options[i] =
        (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
    options[i]->name = "array-of-fixed";
    options[i]->title = "array of fixed";
    options[i]->type = SANE_TYPE_FIXED;
    options[i]->unit = SANE_UNIT_NONE;
    options[i]->size = sizeof (fixedarray);
    options[i]->cap = SANE_CAP_SOFT_SELECT;
    options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
    options[i]->constraint.range = &height_range;
    values[i] = fixedarray;
    i++;

    config.descriptors = options;
    config.values = values;
    config.count = i;

    /* configure and attach */
    status =
        sanei_configure_attach (CONFIG_PATH "/data/fixed.conf",
                                &config, check_config_attach);

    /* check results */
    assert (status == SANE_STATUS_GOOD);
    assert (width == SANE_FIX (21.0));
    assert (height == SANE_FIX (29.7));
    for (i = 0; i < 7; i++)
    {
        assert (fixedarray[i] == SANE_FIX (2.0 + 0.1 * ((float) i)));
    }
}
Пример #14
0
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, &paramSetRet) ) {
            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, &paramSetRet);
                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, &paramSetRet);
              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, &paramSetRet);
        }

        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, &paramSetRet);
                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, &paramSetRet) ) {
            if( sod->type == SANE_TYPE_STRING ) {
              v_c = o_strdup("8");
              status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, &paramSetRet);
              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, &paramSetRet);
            }
            else {
              v_i = 8;
              status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, &paramSetRet);
            }
          }
        }

        // Set Preview mode
        else if ( strcmp(sod->name, SANE_NAME_PREVIEW) == 0 ) {
          if ( !setDefaultScannerOption(openDeviceHandle, sod, option, &paramSetRet) ) {
            v_b = SANE_FALSE;
            status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, &paramSetRet);
          }
        }

        // 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, &paramSetRet);
          }
          else if (sod->type == SANE_TYPE_INT) {
            int sane_resolution = *request_resolution;
            status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &sane_resolution, &paramSetRet);
          }
         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, &paramSetRet);
          }
        }

        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, &paramSetRet);
        }

        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, &paramSetRet);
        }

        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, &paramSetRet);
        }

        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, &paramSetRet);
        }

        else if ( strcmp(sod->name, SANE_NAME_BRIGHTNESS) == 0 ) {
          v_f = 0;
          status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, &paramSetRet);
        }

        else if ( strcmp(sod->name, SANE_NAME_CONTRAST) == 0 ) {
          v_f = 0;
          status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, &paramSetRet);
        }

        else if ( strcmp(sod->name, SANE_NAME_SCAN_SPEED) == 0) {
          if ( !setDefaultScannerOption(openDeviceHandle, sod, option, &paramSetRet) ) {
            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, &paramSetRet);
                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, &paramSetRet);
        }

        // 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, &paramSetRet);
          }
          else if ( strcmp(sod->name, "three-pass") == 0 ){
            v_b = SANE_FALSE;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, &paramSetRet);
          }
          else if ( strcmp(sod->name, "three-pass-order") == 0 ) {
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "RGB", &paramSetRet);
          }
          else if ( strcmp(sod->name, "test-raw_imageture") == 0 ) {
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "Color pattern", &paramSetRet);
          }
          else if ( strcmp(sod->name, "read-delay") == 0 ) {
            v_b = SANE_TRUE;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, &paramSetRet);
          }
          else if ( strcmp(sod->name, "fuzzy-parameters") == 0 ) {
            v_b = SANE_TRUE;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, &paramSetRet);
          }
          else if ( strcmp(sod->name, "read-delay-duration") == 0 ) {
            v_i = 1000;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, &paramSetRet);
          }
          else if ( strcmp(sod->name, "read-limit") == 0 ) {
            v_b = SANE_TRUE;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, &paramSetRet);
          }
          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, &paramSetRet);
          }
          else if ( strcmp(sod->name, "read-return-value") == 0 ) {
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "Default", &paramSetRet);
          }
          else if ( strcmp(sod->name, "ppl-loss") == 0 ) {
            v_i = 0;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, &paramSetRet);
          }
          else if ( strcmp(sod->name, "invert-endianess") == 0 ) {
            v_b = SANE_FALSE;
            status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, &paramSetRet);
          }
        }

        // not a 'well known' option
        else {
          // try setting automatically
          if ( !setDefaultScannerOption(openDeviceHandle, sod, option, &paramSetRet) )
            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;
}
Пример #15
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *value,
                     SANE_Int * info)
{
  struct hp5590_scanner	*scanner = handle;
  
  if (!value)
    return SANE_STATUS_INVAL;

  if (!handle)
    return SANE_STATUS_INVAL;
 
  if (option >= HP5590_OPT_LAST)
    return SANE_STATUS_INVAL;

  if (action == SANE_ACTION_GET_VALUE)
    {
      if (option == HP5590_OPT_NUM)
	{
	  DBG(3, "%s: get total number of options - %u\n", __FUNCTION__, HP5590_OPT_LAST);
	  *((SANE_Int *) value) = HP5590_OPT_LAST;
	  return SANE_STATUS_GOOD;
	}
 
      if (!scanner->opts)
	return SANE_STATUS_INVAL;
      
      DBG (DBG_proc, "%s: get option '%s' value\n", __FUNCTION__, scanner->opts[option].name);

      if (option == HP5590_OPT_BR_X)
	{
	  *(SANE_Fixed *) value = SANE_FIX (scanner->br_x * 25.4);
	}

      if (option == HP5590_OPT_BR_Y)
	{
	  *(SANE_Fixed *) value = SANE_FIX (scanner->br_y * 25.4);
	}

      if (option == HP5590_OPT_TL_X)
	{
	  *(SANE_Fixed *) value = SANE_FIX ((scanner->tl_x) * 25.4);
	}

      if (option == HP5590_OPT_TL_Y)
	{
	  *(SANE_Fixed *) value = SANE_FIX (scanner->tl_y * 25.4);
	}

      if (option == HP5590_OPT_MODE)
	{
	  switch (scanner->depth) {
	    case DEPTH_BW:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_MODE_LINEART, strlen (SANE_VALUE_SCAN_MODE_LINEART));
	      break;
	    case DEPTH_GRAY:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_MODE_GRAY, strlen (SANE_VALUE_SCAN_MODE_GRAY));
	      break;
	    case DEPTH_COLOR_24:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_MODE_COLOR_24, strlen (SANE_VALUE_SCAN_MODE_COLOR_24));
	      break;
	    case DEPTH_COLOR_48:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_MODE_COLOR_48, strlen (SANE_VALUE_SCAN_MODE_COLOR_48));
	      break;
	    default:
	      return SANE_STATUS_INVAL;
	  }
	}

      if (option == HP5590_OPT_SOURCE)
	{
	  switch (scanner->source) {
	    case SOURCE_FLATBED:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_SOURCE_FLATBED, strlen (SANE_VALUE_SCAN_SOURCE_FLATBED));
	      break;
	    case SOURCE_ADF:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_SOURCE_ADF, strlen (SANE_VALUE_SCAN_SOURCE_ADF));
	      break;
	    case SOURCE_ADF_DUPLEX:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX, strlen (SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX));
	      break;
	    case SOURCE_TMA_SLIDES:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_SOURCE_TMA_SLIDES, strlen (SANE_VALUE_SCAN_SOURCE_TMA_SLIDES));
	      break;
	    case SOURCE_TMA_NEGATIVES:
	      memset (value , 0, scanner->opts[option].size);
	      memcpy (value, SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES, strlen (SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES));
	      break;
	    case SOURCE_NONE:
	    default:
	      return SANE_STATUS_INVAL;
	  }
	}

      if (option == HP5590_OPT_RESOLUTION)
	{
	  *(SANE_Int *) value = scanner->dpi;
	}

      if (option == HP5590_OPT_LAMP_TIMEOUT)
	{
	  *(SANE_Bool *) value = scanner->extend_lamp_timeout;
	}

      if (option == HP5590_OPT_WAIT_FOR_BUTTON)
	{
	  *(SANE_Bool *) value = scanner->wait_for_button;
	}

      if (option == HP5590_OPT_PREVIEW)
	{
	  *(SANE_Bool *) value = scanner->preview;
	}
    }
 
  if (action == SANE_ACTION_SET_VALUE)
    {
      if (option == HP5590_OPT_NUM)
	return SANE_STATUS_INVAL;

      if (option == HP5590_OPT_BR_X)
	{
	  float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
	  if (val <= scanner->tl_x)
	    return SANE_STATUS_GOOD;
	  scanner->br_x = val;
	  if (info)
	    *info = SANE_INFO_RELOAD_PARAMS;
	}

      if (option == HP5590_OPT_BR_Y)
	{
	  float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
	  if (val <= scanner->tl_y)
	    return SANE_STATUS_GOOD;
	  scanner->br_y = val;
	  if (info)
 	    *info = SANE_INFO_RELOAD_PARAMS;
	}

      if (option == HP5590_OPT_TL_X)
	{
	  float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
	  if (val >= scanner->br_x)
	    return SANE_STATUS_GOOD;
	  scanner->tl_x = val;
	  if (info)
 	    *info = SANE_INFO_RELOAD_PARAMS;
	}

      if (option == HP5590_OPT_TL_Y)
	{
	  float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
	  if (val >= scanner->br_y)
	    return SANE_STATUS_GOOD;
	  scanner->tl_y = val;
	  if (info)
  	    *info = SANE_INFO_RELOAD_PARAMS;
	}

      if (option == HP5590_OPT_MODE)
	{
	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_LINEART) == 0)
	    {
	      scanner->depth = DEPTH_BW;
	    }

	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_GRAY) == 0)
	    {
	      scanner->depth = DEPTH_GRAY;
	    }

	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_COLOR_24) == 0)
	    {
	      scanner->depth = DEPTH_COLOR_24;
	    }

	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_COLOR_48) == 0)
	    {
	      scanner->depth = DEPTH_COLOR_48;
	    }
	  if (info)
 	    *info = SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
	}

      if (option == HP5590_OPT_SOURCE)
	{
          range_y.max = SANE_FIX(scanner->info->max_size_y * 25.4);

	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_FLATBED) == 0)
	    {
	      scanner->source = SOURCE_FLATBED;
	      range_x.max = SANE_FIX(scanner->info->max_size_x * 25.4);
	      range_y.max = SANE_FIX(scanner->info->max_size_y * 25.4);
	      scanner->br_x = scanner->info->max_size_x;
	      scanner->br_y = scanner->info->max_size_y;
	    }
	  /* In ADF modes the device can scan up to ADF_MAX_Y_INCHES, which is usually
	   * bigger than what scanner reports back during initialization
	   */
	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_ADF) == 0)
	    {
	      scanner->source = SOURCE_ADF;
	      range_x.max = SANE_FIX(scanner->info->max_size_x * 25.4);
	      range_y.max = SANE_FIX(ADF_MAX_Y_INCHES * 25.4);
	      scanner->br_x = scanner->info->max_size_x;
	      scanner->br_y = ADF_MAX_Y_INCHES * 25.4;
	    }
	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX) == 0)
	    {
	      scanner->source = SOURCE_ADF_DUPLEX;
	      range_x.max = SANE_FIX(scanner->info->max_size_x * 25.4);
	      range_y.max = SANE_FIX(ADF_MAX_Y_INCHES * 25.4 * 2);
	      scanner->br_y = ADF_MAX_Y_INCHES * 25.4 * 2;
	      scanner->br_x = scanner->info->max_size_x;
	    }
	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_TMA_SLIDES) == 0)
	    {
	      scanner->source = SOURCE_TMA_SLIDES;
	      range_x.max = SANE_FIX(TMA_MAX_X_INCHES * 25.4);
	      range_y.max = SANE_FIX(TMA_MAX_Y_INCHES * 25.4);
	      scanner->br_x = TMA_MAX_X_INCHES * 25.4;
	      scanner->br_y = TMA_MAX_Y_INCHES * 25.4;
	    }
	  if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES) == 0)
	    {
	      scanner->source = SOURCE_TMA_NEGATIVES;
	      range_x.max = SANE_FIX(TMA_MAX_X_INCHES * 25.4);
	      range_y.max = SANE_FIX(TMA_MAX_Y_INCHES * 25.4);
	      scanner->br_x = TMA_MAX_X_INCHES * 25.4;
	      scanner->br_y = TMA_MAX_Y_INCHES * 25.4;
	    }
	  if (info)
	    *info = SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
	}

      if (option == HP5590_OPT_RESOLUTION)
	{
	  scanner->dpi = *(SANE_Int *) value;
	  if (info)
	    *info = SANE_INFO_RELOAD_PARAMS;
	}

      if (option == HP5590_OPT_LAMP_TIMEOUT)
	{
	  scanner->extend_lamp_timeout = *(SANE_Bool *) value;
	}

      if (option == HP5590_OPT_WAIT_FOR_BUTTON)
	{
	  scanner->wait_for_button = *(SANE_Bool *) value;
	}

      if (option == HP5590_OPT_PREVIEW)
	{
	  scanner->preview = *(SANE_Bool *) value;
	}
    }
   
  return SANE_STATUS_GOOD;
}
Пример #16
0
SANE_Status
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{
  struct hp5590_scanner 	*ptr;
  SANE_Option_Descriptor 	*opts;
  unsigned int 			available_sources;
  SANE_String_Const 		*sources_list;
  unsigned int 			source_idx;

  DBG (DBG_proc, "%s: device name: %s\n", __FUNCTION__, devicename);

  if (!handle)
    return SANE_STATUS_INVAL;

  /* Allow to open the first available device by specifying zero-length name */
  if (!devicename || !devicename[0]) {
    ptr = scanners_list;
  } else {
    for (ptr = scanners_list;
	 ptr && strcmp (ptr->sane.name, devicename) != 0;
	 ptr = ptr->next);
  }

  if (!ptr)
    return SANE_STATUS_INVAL;

  ptr->tl_x = 0;
  ptr->tl_y = 0;
  ptr->br_x = ptr->info->max_size_x;
  ptr->br_y = ptr->info->max_size_y;
  ptr->dpi = res_list[1];
  ptr->depth = DEPTH_BW; 
  ptr->source = SOURCE_FLATBED;
  ptr->extend_lamp_timeout = SANE_FALSE;
  ptr->wait_for_button = SANE_FALSE;
  ptr->preview = SANE_FALSE;
  ptr->quality = 4;
  ptr->image_size = 0;
  ptr->scanning = SANE_FALSE;

  *handle = ptr;

  opts = malloc (sizeof (SANE_Option_Descriptor) * HP5590_OPT_LAST);
  if (!opts)
    return SANE_STATUS_NO_MEM;

  opts[HP5590_OPT_NUM].name = SANE_NAME_NUM_OPTIONS;
  opts[HP5590_OPT_NUM].title = SANE_TITLE_NUM_OPTIONS;
  opts[HP5590_OPT_NUM].desc = SANE_DESC_NUM_OPTIONS;
  opts[HP5590_OPT_NUM].type = SANE_TYPE_INT;
  opts[HP5590_OPT_NUM].unit = SANE_UNIT_NONE;
  opts[HP5590_OPT_NUM].size = sizeof(SANE_Word);
  opts[HP5590_OPT_NUM].cap =  SANE_CAP_INACTIVE | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_NUM].constraint_type = SANE_CONSTRAINT_NONE;
  opts[HP5590_OPT_NUM].constraint.string_list = NULL;

  range_x.min = SANE_FIX(0);
  range_x.max = SANE_FIX(ptr->info->max_size_x * 25.4);
  range_x.quant = SANE_FIX(0.1);
  range_y.min = SANE_FIX(0);
  range_y.max = SANE_FIX(ptr->info->max_size_y * 25.4);
  range_y.quant = SANE_FIX(0.1);

  range_qual.min = SANE_FIX(4);
  range_qual.max = SANE_FIX(16);
  range_qual.quant = SANE_FIX(1);

  opts[HP5590_OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
  opts[HP5590_OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
  opts[HP5590_OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
  opts[HP5590_OPT_TL_X].type = SANE_TYPE_FIXED;
  opts[HP5590_OPT_TL_X].unit = SANE_UNIT_MM;
  opts[HP5590_OPT_TL_X].size = sizeof(SANE_Fixed);
  opts[HP5590_OPT_TL_X].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
  opts[HP5590_OPT_TL_X].constraint.range = &range_x;

  opts[HP5590_OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
  opts[HP5590_OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
  opts[HP5590_OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
  opts[HP5590_OPT_TL_Y].type = SANE_TYPE_FIXED;
  opts[HP5590_OPT_TL_Y].unit = SANE_UNIT_MM;
  opts[HP5590_OPT_TL_Y].size = sizeof(SANE_Fixed);
  opts[HP5590_OPT_TL_Y].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  opts[HP5590_OPT_TL_Y].constraint.range = &range_y;

  opts[HP5590_OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
  opts[HP5590_OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
  opts[HP5590_OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
  opts[HP5590_OPT_BR_X].type = SANE_TYPE_FIXED;
  opts[HP5590_OPT_BR_X].unit = SANE_UNIT_MM;
  opts[HP5590_OPT_BR_X].size = sizeof(SANE_Fixed);
  opts[HP5590_OPT_BR_X].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
  opts[HP5590_OPT_BR_X].constraint.range = &range_x;

  opts[HP5590_OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
  opts[HP5590_OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
  opts[HP5590_OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
  opts[HP5590_OPT_BR_Y].type = SANE_TYPE_FIXED;
  opts[HP5590_OPT_BR_Y].unit = SANE_UNIT_MM;
  opts[HP5590_OPT_BR_Y].size = sizeof(SANE_Fixed);
  opts[HP5590_OPT_BR_Y].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  opts[HP5590_OPT_BR_Y].constraint.range = &range_y;

  opts[HP5590_OPT_MODE].name = SANE_NAME_SCAN_MODE;
  opts[HP5590_OPT_MODE].title = SANE_TITLE_SCAN_MODE;
  opts[HP5590_OPT_MODE].desc = SANE_DESC_SCAN_MODE;
  opts[HP5590_OPT_MODE].type = SANE_TYPE_STRING;
  opts[HP5590_OPT_MODE].unit = SANE_UNIT_NONE;
  opts[HP5590_OPT_MODE].size = MAX_SCAN_MODE_VALUE_LEN;
  opts[HP5590_OPT_MODE].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  opts[HP5590_OPT_MODE].constraint.string_list = mode_list;

  available_sources = 1; /* Flatbed is always available */
  if (ptr->info->features & FEATURE_ADF)
    available_sources += 2;
  if (ptr->info->features & FEATURE_TMA)
    available_sources += 2;
  available_sources++;	/* Count terminating NULL */
  sources_list = malloc (available_sources * sizeof (SANE_String_Const));
  if (!sources_list)
    return SANE_STATUS_NO_MEM;
  source_idx = 0;
  sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_FLATBED;
  if (ptr->info->features & FEATURE_ADF)
    {
      sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_ADF;
      sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX;
    }
  if (ptr->info->features & FEATURE_TMA)
    {
      sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_TMA_SLIDES;
      sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES;
    }
  sources_list[source_idx] = NULL;

  opts[HP5590_OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
  opts[HP5590_OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
  opts[HP5590_OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
  opts[HP5590_OPT_SOURCE].type = SANE_TYPE_STRING;
  opts[HP5590_OPT_SOURCE].unit = SANE_UNIT_NONE;
  opts[HP5590_OPT_SOURCE].size = MAX_SCAN_SOURCE_VALUE_LEN;
  opts[HP5590_OPT_SOURCE].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  opts[HP5590_OPT_SOURCE].constraint.string_list = sources_list;

  opts[HP5590_OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
  opts[HP5590_OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
  opts[HP5590_OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
  opts[HP5590_OPT_RESOLUTION].type = SANE_TYPE_INT;
  opts[HP5590_OPT_RESOLUTION].unit = SANE_UNIT_DPI;
  opts[HP5590_OPT_RESOLUTION].size = sizeof(SANE_Int);
  opts[HP5590_OPT_RESOLUTION].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
  opts[HP5590_OPT_RESOLUTION].constraint.word_list = res_list;

  opts[HP5590_OPT_LAMP_TIMEOUT].name = SANE_NAME_LAMP_TIMEOUT;
  opts[HP5590_OPT_LAMP_TIMEOUT].title = SANE_TITLE_LAMP_TIMEOUT;
  opts[HP5590_OPT_LAMP_TIMEOUT].desc = SANE_DESC_LAMP_TIMEOUT;
  opts[HP5590_OPT_LAMP_TIMEOUT].type = SANE_TYPE_BOOL;
  opts[HP5590_OPT_LAMP_TIMEOUT].unit = SANE_UNIT_NONE;
  opts[HP5590_OPT_LAMP_TIMEOUT].size = sizeof(SANE_Bool);
  opts[HP5590_OPT_LAMP_TIMEOUT].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
  opts[HP5590_OPT_LAMP_TIMEOUT].constraint_type = SANE_CONSTRAINT_NONE;
  opts[HP5590_OPT_LAMP_TIMEOUT].constraint.string_list = NULL;

  opts[HP5590_OPT_WAIT_FOR_BUTTON].name = SANE_NAME_WAIT_FOR_BUTTON;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].title = SANE_TITLE_WAIT_FOR_BUTTON;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].desc = SANE_DESC_WAIT_FOR_BUTTON;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].type = SANE_TYPE_BOOL;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].unit = SANE_UNIT_NONE;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].size = sizeof(SANE_Bool);
  opts[HP5590_OPT_WAIT_FOR_BUTTON].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].constraint_type = SANE_CONSTRAINT_NONE;
  opts[HP5590_OPT_WAIT_FOR_BUTTON].constraint.string_list = NULL;

  opts[HP5590_OPT_PREVIEW].name = SANE_NAME_PREVIEW;
  opts[HP5590_OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
  opts[HP5590_OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
  opts[HP5590_OPT_PREVIEW].type = SANE_TYPE_BOOL;
  opts[HP5590_OPT_PREVIEW].unit = SANE_UNIT_NONE;
  opts[HP5590_OPT_PREVIEW].size = sizeof(SANE_Bool);
  opts[HP5590_OPT_PREVIEW].cap =  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  opts[HP5590_OPT_PREVIEW].constraint_type = SANE_CONSTRAINT_NONE;
  opts[HP5590_OPT_PREVIEW].constraint.string_list = NULL;

  ptr->opts = opts;

  return SANE_STATUS_GOOD;
}
Пример #17
0
void create_options(SANE_Virtual_Device* device) {
    SANE_Option_Descriptor* option;
    option = &device->option[ALL_OPTIONS];
    option->name = "";
    option->title = SANE_TITLE_NUM_OPTIONS;
    option->desc = SANE_DESC_NUM_OPTIONS;
    option->type = SANE_TYPE_INT;
    option->unit = SANE_UNIT_NONE;
    option->size = sizeof(SANE_Word);
    option->cap = SANE_CAP_SOFT_DETECT;
    option->constraint_type = SANE_CONSTRAINT_NONE;
    option->constraint.range = 0;
    device->value[ALL_OPTIONS].word = OPTION_COUNT;

    option = &device->option[STRING_OPTION];
    option->name = "string_test";
    option->title = SANE_I18N("String Test");
    option->desc = SANE_I18N("Test string option");
    option->type = SANE_TYPE_STRING;
    option->unit = SANE_UNIT_NONE;
    option->size = string_list_size();
    option->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
    option->constraint_type = SANE_CONSTRAINT_STRING_LIST;
    option->constraint.string_list = string_list;
    device->value[STRING_OPTION].str = malloc(option->size);
    strcpy(device->value[STRING_OPTION].str, SANE_I18N("First String Option"));

    option = &device->option[WORD_OPTION_INT];
    option->name = "word_test_integer";
    option->title = SANE_I18N("Word Test Integer");
    option->desc = SANE_I18N("Test word option with integer values");
    option->type = SANE_TYPE_INT;
    option->unit = SANE_UNIT_BIT;
    option->size = sizeof(word_list_int) / sizeof(SANE_Word);
    option->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
    option->constraint_type = SANE_CONSTRAINT_WORD_LIST;
    option->constraint.word_list = word_list_int;
    device->value[WORD_OPTION_INT].word = 20;

    option = &device->option[WORD_OPTION_FIXED];
    option->name = "word_test_fixed";
    option->title = SANE_I18N("Word Test Fixed");
    option->desc = SANE_I18N("Test word option with fixed values");
    option->type = SANE_TYPE_FIXED;
    option->unit = SANE_UNIT_MM;
    option->size = sizeof(word_list_fixed) / sizeof(SANE_Word);
    option->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
    option->constraint_type = SANE_CONSTRAINT_WORD_LIST;
    option->constraint.word_list = word_list_fixed;
    device->value[WORD_OPTION_FIXED].word = SANE_FIX(30.2);

    option = &device->option[RANGE_OPTION];
    option->name = "range_test";
    option->title = SANE_I18N("Range Test");
    option->desc = SANE_I18N("Test range option");
    option->type = SANE_TYPE_FIXED;
    option->unit = SANE_UNIT_BIT;
    option->size = sizeof(range) / sizeof(SANE_Word);
    option->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
    option->constraint_type = SANE_CONSTRAINT_RANGE;
    option->constraint.range = &range;
    device->value[RANGE_OPTION].word = SANE_FIX(15.0);

    option = &device->option[BOOL_OPTION_TRUE];
    option->name = "bool_test_true";
    option->title = SANE_I18N("Boolean Test True");
    option->desc = SANE_I18N("Test boolean true option");
    option->type = SANE_TYPE_BOOL;
    option->unit = SANE_UNIT_NONE;
    option->size = sizeof(SANE_Word);
    option->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
    option->constraint_type = SANE_CONSTRAINT_NONE;
    device->value[BOOL_OPTION_TRUE].word = SANE_TRUE;

    option = &device->option[BOOL_OPTION_FALSE];
    option->name = "bool_test_false";
    option->title = SANE_I18N("Boolean Test False");
    option->desc = SANE_I18N("Test boolean false option");
    option->type = SANE_TYPE_BOOL;
    option->unit = SANE_UNIT_NONE;
    option->size = sizeof(SANE_Word);
    option->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
    option->constraint_type = SANE_CONSTRAINT_NONE;
    device->value[BOOL_OPTION_FALSE].word = SANE_FALSE;

}
Пример #18
0
  sizeof (SANE_Word),
  0,
  SANE_CONSTRAINT_NONE,
  {NULL}
};

/* range for int constraint */
static const SANE_Range int_range = {
  3,				/* minimum */
  18,				/* maximum */
  3				/* quantization */
};

/* range for sane fixed constraint */
static const SANE_Range fixed_range = {
  SANE_FIX(1.0),		/* minimum */
  SANE_FIX(431.8),		/* maximum */
  SANE_FIX(0.01)				/* quantization */
};

static SANE_Option_Descriptor int_opt = {
  SANE_NAME_SCAN_TL_X,
  SANE_TITLE_SCAN_TL_X,
  SANE_DESC_SCAN_TL_X,
  SANE_TYPE_FIXED,
  SANE_UNIT_MM,
  sizeof (SANE_Word),
  0,
  SANE_CONSTRAINT_RANGE,
  {NULL}
};
Пример #19
0
SANE_Status
kv_control_option (PKV_DEV dev, SANE_Int option,
		   SANE_Action action, void *val, SANE_Int * info)
{
  SANE_Status status;
  SANE_Word cap;
  SANE_String_Const name;
  int i;
  SANE_Word value;

  DBG (DBG_proc, "sane_control_option: enter, option %s, action %s\n",
       go_option_name[option], action == SANE_ACTION_GET_VALUE ? "R" : "W");

  if (info)
    {
      *info = 0;
    }

  if (dev->scanning)
    {
      return SANE_STATUS_DEVICE_BUSY;
    }

  if (option < 0 || option >= OPT_NUM_OPTIONS)
    {
      return SANE_STATUS_UNSUPPORTED;
    }

  cap = dev->opt[option].cap;
  if (!SANE_OPTION_IS_ACTIVE (cap))
    {
      return SANE_STATUS_UNSUPPORTED;
    }

  name = dev->opt[option].name;
  if (!name)
    {
      name = "(no name)";
    }
  if (action == SANE_ACTION_GET_VALUE)
    {
      switch (option)
	{
	  /* word options */
	case OPT_NUM_OPTS:
	case OPT_LONGPAPER:
	case OPT_LENGTHCTL:
	case OPT_DBLFEED:
	case OPT_RESOLUTION:
	case OPT_TL_Y:
	case OPT_BR_Y:
	case OPT_TL_X:
	case OPT_BR_X:
	case OPT_BRIGHTNESS:
	case OPT_CONTRAST:
	case OPT_DUPLEX:
	case OPT_LANDSCAPE:
	case OPT_AUTOMATIC_SEPARATION:
	case OPT_INVERSE:
	case OPT_MIRROR:
	case OPT_FEED_TIMEOUT:
	case OPT_JPEG:
	case OPT_FIT_TO_PAGE:
	  *(SANE_Word *) val = dev->val[option].w;
	  DBG (DBG_error, "opt value = %d\n", *(SANE_Word *) val);
	  return SANE_STATUS_GOOD;

	  /* string options */
	case OPT_MODE:
	case OPT_FEEDER_MODE:
	case OPT_SCAN_SOURCE:
	case OPT_MANUALFEED:
	case OPT_HALFTONE_PATTERN:
	case OPT_PAPER_SIZE:
	case OPT_AUTOMATIC_THRESHOLD:
	case OPT_WHITE_LEVEL:
	case OPT_NOISE_REDUCTION:
	case OPT_IMAGE_EMPHASIS:
	case OPT_GAMMA:
	case OPT_LAMP:

	  strcpy (val, dev->val[option].s);
	  DBG (DBG_error, "opt value = %s\n", (char *) val);
	  return SANE_STATUS_GOOD;

	default:
	  return SANE_STATUS_UNSUPPORTED;
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
	{
	  DBG (DBG_error,
	       "could not set option %s, not settable\n",
	       go_option_name[option]);
	  return SANE_STATUS_INVAL;
	}

      status = sanei_constrain_value (dev->opt + option, val, info);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "could not set option, invalid value\n");
	  return status;
	}

      switch (option)
	{
	  /* Side-effect options */
	case OPT_TL_Y:
	case OPT_BR_Y:
	case OPT_RESOLUTION:
	  if (info)
	    {
	      *info |= SANE_INFO_RELOAD_PARAMS;
	    }

	  dev->val[option].w = *(SANE_Word *) val;

	  if (option == OPT_RESOLUTION)
	    {
	      if (round_to_boundry (&(dev->val[option].w),
				    dev->support_info.
				    step_resolution, 100, 600))
		{
		  if (info)
		    {
		      *info |= SANE_INFO_INEXACT;
		    }
		}
	    }
	  else if (option == OPT_TL_Y)
	    {
	      if (dev->val[option].w > dev->val[OPT_BR_Y].w)
		{
		  dev->val[option].w = dev->val[OPT_BR_Y].w;
		  if (info)
		    {
		      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
		    }
		}
	    }
	  else
	    {
	      if (dev->val[option].w < dev->val[OPT_TL_Y].w)
		{
		  dev->val[option].w = dev->val[OPT_TL_Y].w;
		  if (info)
		    {
		      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
		    }
		}
	    }

	  DBG (DBG_error,
	       "option %s, input = %d, value = %d\n",
	       go_option_name[option], (*(SANE_Word *) val),
	       dev->val[option].w);

	  return SANE_STATUS_GOOD;

	  /* The length of X must be rounded (up). */
	case OPT_TL_X:
	case OPT_BR_X:
	  {
	    SANE_Word xr = dev->val[OPT_RESOLUTION].w;
	    SANE_Word tl_x = mmToIlu (SANE_UNFIX (dev->val[OPT_TL_X].w)) * xr;
	    SANE_Word br_x = mmToIlu (SANE_UNFIX (dev->val[OPT_BR_X].w)) * xr;
	    value = mmToIlu (SANE_UNFIX (*(SANE_Word *) val)) * xr;	/* XR * W */

	    if (option == OPT_TL_X)
	      {
		SANE_Word max = KV_PIXEL_MAX * xr - KV_PIXEL_ROUND;
		if (br_x < max)
		  max = br_x;
		if (round_to_boundry (&value, KV_PIXEL_ROUND, 0, max))
		  {
		    if (info)
		      {
			*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
		      }
		  }
	      }
	    else
	      {
		if (round_to_boundry
		    (&value, KV_PIXEL_ROUND, tl_x, KV_PIXEL_MAX * xr))
		  {
		    if (info)
		      {
			*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
		      }
		  }
	      }

	    dev->val[option].w = SANE_FIX (iluToMm ((double) value / xr));

	    if (info)
	      {
		*info |= SANE_INFO_RELOAD_PARAMS;
	      }

	    DBG (DBG_error,
		 "option %s, input = %d, value = %d\n",
		 go_option_name[option], (*(SANE_Word *) val),
		 dev->val[option].w);
	    return SANE_STATUS_GOOD;
	  }
	case OPT_LANDSCAPE:
	  dev->val[option].w = *(SANE_Word *) val;
	  if (info)
	    {
	      *info |= SANE_INFO_RELOAD_PARAMS;
	    }
	  return SANE_STATUS_GOOD;

	  /* Side-effect free options */
	case OPT_CONTRAST:
	case OPT_BRIGHTNESS:
	case OPT_DUPLEX:
	case OPT_LONGPAPER:
	case OPT_LENGTHCTL:
	case OPT_DBLFEED:
	case OPT_INVERSE:
	case OPT_MIRROR:
	case OPT_AUTOMATIC_SEPARATION:
	case OPT_JPEG:
	case OPT_FIT_TO_PAGE:
	  dev->val[option].w = *(SANE_Word *) val;
	  return SANE_STATUS_GOOD;

	case OPT_FEED_TIMEOUT:
	  dev->val[option].w = *(SANE_Word *) val;
	  return CMD_set_timeout (dev, *(SANE_Word *) val);

	  /* String mode */
	case OPT_SCAN_SOURCE:
	case OPT_WHITE_LEVEL:
	case OPT_NOISE_REDUCTION:
	case OPT_IMAGE_EMPHASIS:
	case OPT_GAMMA:
	case OPT_LAMP:
	case OPT_HALFTONE_PATTERN:
	case OPT_FEEDER_MODE:
	  if (strcmp (dev->val[option].s, val) == 0)
	    return SANE_STATUS_GOOD;
	  free (dev->val[option].s);
	  dev->val[option].s = (SANE_String) strdup (val);

	  if (option == OPT_FEEDER_MODE &&
	      get_string_list_index (go_feeder_mode_list,
				     dev->val[option].s) == 1)
	    /* continuous mode */
	    {
	      free (dev->val[OPT_SCAN_SOURCE].s);
	      dev->val[OPT_SCAN_SOURCE].s = strdup (go_scan_source_list[0]);
	      dev->opt[OPT_LONGPAPER].cap &= ~SANE_CAP_INACTIVE;
	      if (info)
		*info |= SANE_INFO_RELOAD_OPTIONS;
	    }
	  else
	    {
	      dev->opt[OPT_LONGPAPER].cap |= SANE_CAP_INACTIVE;
	      if (info)
		*info |= SANE_INFO_RELOAD_OPTIONS;
	    }

	  if (option == OPT_SCAN_SOURCE &&
	      get_string_list_index (go_scan_source_list,
				     dev->val[option].s) == 1)
	    /* flatbed */
	    {
	      free (dev->val[OPT_FEEDER_MODE].s);
	      dev->val[OPT_FEEDER_MODE].s = strdup (go_feeder_mode_list[0]);
	    }

	  return SANE_STATUS_GOOD;

	case OPT_MODE:
	  if (strcmp (dev->val[option].s, val) == 0)
	    return SANE_STATUS_GOOD;
	  free (dev->val[OPT_MODE].s);
	  dev->val[OPT_MODE].s = (SANE_String) strdup (val);

	  /* Set default options for the scan modes. */
	  dev->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_AUTOMATIC_THRESHOLD].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_AUTOMATIC_SEPARATION].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_INVERSE].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_JPEG].cap &= ~SANE_CAP_INACTIVE;

	  if (strcmp (dev->val[OPT_MODE].s, go_scan_mode_list[0]) == 0)
	    /* binary */
	    {
	      dev->opt[OPT_AUTOMATIC_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_INVERSE].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_JPEG].cap |= SANE_CAP_INACTIVE;
	    }
	  else if (strcmp (dev->val[OPT_MODE].s, go_scan_mode_list[1]) == 0)
	    /* halftone */
	    {
	      dev->opt[OPT_HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_AUTOMATIC_SEPARATION].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_INVERSE].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_JPEG].cap |= SANE_CAP_INACTIVE;
	    }
	  else if (strcmp (dev->val[OPT_MODE].s, go_scan_mode_list[2]) == 0)
	    /* grayscale */
	    {
	      dev->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE;
	    }

	  if (info)
	    {
	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	    }

	  return SANE_STATUS_GOOD;

	case OPT_MANUALFEED:
	  if (strcmp (dev->val[option].s, val) == 0)
	    return SANE_STATUS_GOOD;
	  free (dev->val[option].s);
	  dev->val[option].s = (SANE_String) strdup (val);

	  if (strcmp (dev->val[option].s, go_manual_feed_list[0]) == 0)	/* off */
	    dev->opt[OPT_FEED_TIMEOUT].cap |= SANE_CAP_INACTIVE;
	  else
	    dev->opt[OPT_FEED_TIMEOUT].cap &= ~SANE_CAP_INACTIVE;
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;

	case OPT_PAPER_SIZE:
	  if (strcmp (dev->val[option].s, val) == 0)
	    return SANE_STATUS_GOOD;

	  free (dev->val[OPT_PAPER_SIZE].s);
	  dev->val[OPT_PAPER_SIZE].s = (SANE_Char *) strdup (val);

	  i = get_string_list_index (go_paper_list,
				     dev->val[OPT_PAPER_SIZE].s);
	  if (i == 0)
	    {			/*user def */
	      dev->opt[OPT_TL_X].cap &=
		dev->opt[OPT_TL_Y].cap &=
		dev->opt[OPT_BR_X].cap &=
		dev->opt[OPT_BR_Y].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_LANDSCAPE].cap |= SANE_CAP_INACTIVE;
	      dev->val[OPT_LANDSCAPE].w = 0;
	    }
	  else
	    {
	      dev->opt[OPT_TL_X].cap |=
		dev->opt[OPT_TL_Y].cap |=
		dev->opt[OPT_BR_X].cap |=
		dev->opt[OPT_BR_Y].cap |= SANE_CAP_INACTIVE;
	      if (i == 4 || i == 5 || i == 7)
		{		/*A5, A6 or B6 */
		  dev->opt[OPT_LANDSCAPE].cap &= ~SANE_CAP_INACTIVE;
		}
	      else
		{
		  dev->opt[OPT_LANDSCAPE].cap |= SANE_CAP_INACTIVE;
		  dev->val[OPT_LANDSCAPE].w = 0;
		}
	    }

	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;

	  return SANE_STATUS_GOOD;


	case OPT_AUTOMATIC_THRESHOLD:
	  if (strcmp (dev->val[option].s, val) == 0)
	    return SANE_STATUS_GOOD;

	  free (dev->val[option].s);
	  dev->val[option].s = (SANE_Char *) strdup (val);

	  /* If the threshold is not set to none, some option must
	   * disappear. */

	  dev->opt[OPT_WHITE_LEVEL].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_NOISE_REDUCTION].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_IMAGE_EMPHASIS].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_AUTOMATIC_SEPARATION].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;

	  if (strcmp (val, go_automatic_threshold_list[0]) == 0)
	    {
	      dev->opt[OPT_WHITE_LEVEL].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_NOISE_REDUCTION].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_IMAGE_EMPHASIS].cap &= ~SANE_CAP_INACTIVE;
	      dev->opt[OPT_AUTOMATIC_SEPARATION].cap &= ~SANE_CAP_INACTIVE;
	      if (strcmp (dev->val[OPT_MODE].s, go_scan_mode_list[1]) == 0)
		{
		  dev->opt[OPT_HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
		}
	    }

	  if (info)
	    {
	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	    }
	  return SANE_STATUS_GOOD;

	default:
	  return SANE_STATUS_INVAL;
	}
    }

  DBG (DBG_proc, "sane_control_option: exit, bad\n");

  return SANE_STATUS_UNSUPPORTED;
}
Пример #20
0
static SANE_Status
attach (const char *devname, Tamarack_Device **devp)
{
  char result[INQ_LEN];
  int fd;
  Tamarack_Device *dev;
  SANE_Status status;
  size_t size;
  char *mfg, *model;
  char *p;

  for (dev = first_dev; dev; dev = dev->next)
    if (strcmp (dev->sane.name, devname) == 0) {
      if (devp)
	*devp = dev;
      return SANE_STATUS_GOOD;
    }

  DBG(3, "attach: opening %s\n", devname);
  status = sanei_scsi_open (devname, &fd, sense_handler, 0);
  if (status != SANE_STATUS_GOOD) {
    DBG(1, "attach: open failed (%s)\n", sane_strstatus (status));
    return SANE_STATUS_INVAL;
  }

  DBG(3, "attach: sending INQUIRY\n");
  size = sizeof (result);
  status = sanei_scsi_cmd (fd, inquiry, sizeof (inquiry), result, &size);
  if (status != SANE_STATUS_GOOD || size != INQ_LEN) {
    DBG(1, "attach: inquiry failed (%s)\n", sane_strstatus (status));
    sanei_scsi_close (fd);
    return status;
  }

  status = wait_ready (fd);
  sanei_scsi_close (fd);
  if (status != SANE_STATUS_GOOD)
    return status;

  result[33]= '\0';
  p = strchr(result+16,' ');
  if (p) *p = '\0';
  model = strdup (result+16);

  result[16]= '\0';
  p = strchr(result+8,' ');
  if (p) *p = '\0';
  mfg = strdup (result+8);

  DBG(1, "attach: Inquiry gives mfg=%s, model=%s.\n", mfg, model);
  
  if (strcmp (mfg, "TAMARACK") != 0) {
    DBG(1, "attach: device doesn't look like a Tamarack scanner "
	   "(result[0]=%#02x)\n", result[0]);
    return SANE_STATUS_INVAL;
  }
  
  dev = malloc (sizeof (*dev));
  if (!dev)
    return SANE_STATUS_NO_MEM;
  
  memset (dev, 0, sizeof (*dev));

  dev->sane.name   = strdup (devname);
  dev->sane.vendor = "Tamarack";
  dev->sane.model  = model;
  dev->sane.type   = "flatbed scanner";

  dev->x_range.min = 0;
  dev->y_range.min = 0;
  dev->x_range.quant = 0;
  dev->y_range.quant = 0;
  dev->dpi_range.min = SANE_FIX (1);
  dev->dpi_range.quant = SANE_FIX (1);

  dev->x_range.max = SANE_FIX (8.5 * MM_PER_INCH);
  dev->y_range.max = SANE_FIX (11.0 * MM_PER_INCH);
  dev->dpi_range.max = SANE_FIX (600);

  DBG(3, "attach: found Tamarack scanner model %s (%s)\n",
      dev->sane.model, dev->sane.type);

  ++num_devices;
  dev->next = first_dev;
  first_dev = dev;

  if (devp)
    *devp = dev;
  return SANE_STATUS_GOOD;
}
Пример #21
0
#include "brother_misc.c"
#include "brother_modelinf.c"
#include "brother_scanner.c"
#include "brother_bugchk.c"
#include "brother_log.c"

/* ======================================================================

Initialise SANE options

====================================================================== */

#define DEBUG_MODELINF

static const SANE_Range rangeLumi = {
  SANE_FIX(-50.0),
  SANE_FIX(50.0),
  SANE_FIX(1.0) };

#define NUM_SCANMODE (5+1)
#define NUM_RESO (10+1)
#define NUM_SCANSRC (2+1)

static SANE_String_Const * scanModeList = 0;

static SANE_Int *scanResoList = 0;

static SANE_String_Const * scanSrcList = 0;

static SANE_Range rangeXmm;
static SANE_Range rangeYmm;
Пример #22
0
SANE_Status
sanei_configure_attach (const char *config_file, SANEI_Config * config,
			SANE_Status (*attach) (SANEI_Config * config,
					       const char *devname))
{
  SANE_Char line[PATH_MAX];
  SANE_Char *token, *string;
  SANE_Int len;
  const char *lp, *lp2;
  FILE *fp;
  SANE_Status status = SANE_STATUS_GOOD;
  int i, j, count;
  void *value = NULL;
  int size=0;
  SANE_Bool found;
  SANE_Word *wa;
  SANE_Bool *ba;

  DBG (3, "sanei_configure_attach: start\n");

  /* open configuration file */
  fp = sanei_config_open (config_file);
  if (!fp)
    {
      DBG (2, "sanei_configure_attach: couldn't access %s\n", config_file);
      DBG (3, "sanei_configure_attach: exit\n");
      return SANE_STATUS_ACCESS_DENIED;
    }

  /* loop reading the configuration file, all line beginning by "option " are
   * parsed for value to store in configuration structure, other line are 
   * used are device to try to attach
   */
  while (sanei_config_read (line, PATH_MAX, fp) && status == SANE_STATUS_GOOD)
    {
      /* skip white spaces at beginning of line */
      lp = sanei_config_skip_whitespace (line);

      /* skip empty lines */
      if (*lp == 0)
	continue;

      /* skip comment line */
      if (line[0] == '#')
	continue;

      len = strlen (line);

      /* delete newline characters at end */
      if (line[len - 1] == '\n')
	line[--len] = '\0';

      lp2 = lp;

      /* to ensure maximum compatibility, we accept line like:
       * option "option_name" "option_value"
       * "option_name" "option_value" 
       * So we parse the line 2 time to find an option */
      /* check if it is an option */
      lp = sanei_config_get_string (lp, &token);
      if (strncmp (token, "option", 6) == 0)
	{
	  /* skip the "option" token */
	  free (token);
	  lp = sanei_config_get_string (lp, &token);
	}

      /* search for a matching descriptor */
      i = 0;
      found = SANE_FALSE;
      while (config!=NULL && i < config->count && !found)
	{
	  if (strcmp (config->descriptors[i]->name, token) == 0)
	    {
	      found = SANE_TRUE;
	      switch (config->descriptors[i]->type)
		{
		case SANE_TYPE_INT:
		  size=config->descriptors[i]->size;
		  value = malloc (size);
		  wa = (SANE_Word *) value;
		  count = config->descriptors[i]->size / sizeof (SANE_Word);
		  for (j = 0; j < count; j++)
		    {
		      lp = sanei_config_get_string (lp, &string);
		      if (string == NULL)
			{
			  DBG (2,
			       "sanei_configure_attach: couldn't find a string to parse");
			  return SANE_STATUS_INVAL;
			}
		      wa[j] = strtol (string, NULL, 0);
		      free (string);
		    }
		  break;
		case SANE_TYPE_BOOL:
		  size=config->descriptors[i]->size;
		  value = malloc (size);
		  ba = (SANE_Bool *) value;
		  count = config->descriptors[i]->size / sizeof (SANE_Bool);
		  for (j = 0; j < count; j++)
		    {
		      lp = sanei_config_get_string (lp, &string);
		      if (string == NULL)
			{
			  DBG (2,
			       "sanei_configure_attach: couldn't find a string to parse");
			  return SANE_STATUS_INVAL;
			}
		      if ((strcmp (string, "1") == 0)
			  || (strcmp (string, "true") == 0))
			{
			  ba[j] = SANE_TRUE;
			}
		      else
			{
			  if ((strcmp (string, "0") == 0)
			      || (strcmp (string, "false") == 0))
			    ba[j] = SANE_FALSE;
			  else
			    {
			      DBG (2,
				   "sanei_configure_attach: couldn't find a valid boolean value");
			      return SANE_STATUS_INVAL;
			    }
			}
		      free (string);
		    }
		  break;
		case SANE_TYPE_FIXED:
		  size=config->descriptors[i]->size;
		  value = malloc (size);
		  wa = (SANE_Word *) value;
		  count = config->descriptors[i]->size / sizeof (SANE_Word);
		  for (j = 0; j < count; j++)
		    {
		      lp = sanei_config_get_string (lp, &string);
		      if (string == NULL)
			{
			  DBG (2,
			       "sanei_configure_attach: couldn't find a string to parse");
			  return SANE_STATUS_INVAL;
			}
		      wa[j] = SANE_FIX(strtod (string, NULL));
		      free (string);
		    }
		  break;
		case SANE_TYPE_STRING:
		  sanei_config_get_string (lp, &string);
		  if (string == NULL)
		    {
		      DBG (2,
			   "sanei_configure_attach: couldn't find a string value to parse");
		      return SANE_STATUS_INVAL;
		    }
		  value = string;
		  size=strlen(string)+1;
		  if(size>config->descriptors[i]->size)
		  {
			  size=config->descriptors[i]->size-1;
			  string[size]=0;
		  }
		  break;
		default:
		  DBG (1,
		       "sanei_configure_attach: incorrect type %d for option %s, skipping option ...\n",
		       config->descriptors[i]->type,
		       config->descriptors[i]->name);
		}
	      
	      /* check decoded value */
	      status = sanei_check_value (config->descriptors[i], value);

	      /* if value OK, copy it in configuration struct */
	      if (status == SANE_STATUS_GOOD)
		{
		  memcpy (config->values[i], value, size);
		}
	      if (value != NULL)
		{
		  free (value);
		  value = NULL;
		}
	    }
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (1,
		   "sanei_configure_attach: failed to parse option '%s', line '%s'\n",
		   token, line);
	    }
	  i++;
	}
      free (token);

      /* not detected as an option, so we call the attach function
       * with it */
      if (!found && status == SANE_STATUS_GOOD)
	{
	  /* if not an option, try to attach */
	  /* to avoid every backend to depend on scsi and usb functions
	   * we call back the backend for attach. In turn it will call
	   * sanei_usb_attach_matching_devices, sanei_config_attach_matching_devices
	   * or other. This means 2 callback functions per backend using this 
	   * function. */
	  DBG (3, "sanei_configure_attach: trying to attach with '%s'\n",
	       lp2);
	  if(attach!=NULL)
	  	attach (config, lp2);
	}
    }

  fclose (fp);
  DBG (3, "sanei_configure_attach: exit\n");
  return status;
}
Пример #23
0

static const SANE_Range u8_range =
  {
      0,				/* minimum */
    255,				/* maximum */
      0				/* quantization */
  };


/* David used " 100 << SANE_FIXED_SCALE_SHIFT ". This assumes that
 * it is implemented that way. I want to hide the datatype. 
 */
static const SANE_Range percentage_range =
  {
    SANE_FIX(-100),	/* minimum */
    SANE_FIX( 100),	/* maximum */
    SANE_FIX( 1  )	/* quantization */
  };

/* David used " 100 << SANE_FIXED_SCALE_SHIFT ". This assumes that
 * it is implemented that way. I want to hide the datatype. 
 */
static const SANE_Range abs_percentage_range =
  {
    SANE_FIX( 0),	/* minimum */
    SANE_FIX( 100),	/* maximum */
    SANE_FIX( 1  )	/* quantization */
  };

Пример #24
0
static void
st400_init_options( ST400_Device *dev )
{
	static const SANE_Int depth_list[] = { 2, 1, 8 };
	static const SANE_Int dpi_list[] = { 3, 200, 300, 400 };
	static const SANE_Range thres_range = {
		SANE_FIX(0.0), SANE_FIX(100.0), SANE_FIX(0.0)
	};
	static const SANE_Range x_range = {
		SANE_FIX(0.0), SANE_FIX(ST400_MAX_X * MM_PER_INCH), SANE_FIX(0.0)
	};
	static const SANE_Range y_range = {
		SANE_FIX(0.0), SANE_FIX(ST400_MAX_Y * MM_PER_INCH), SANE_FIX(0.0)
	};

	DBG(DCODE, "st400_init_options(%p)\n", (void *)dev);

	dev->opt[OPT_NUM_OPTS].name	= SANE_NAME_NUM_OPTIONS;
	dev->opt[OPT_NUM_OPTS].title	= SANE_TITLE_NUM_OPTIONS;
	dev->opt[OPT_NUM_OPTS].desc		= SANE_DESC_NUM_OPTIONS;
	dev->opt[OPT_NUM_OPTS].type	= SANE_TYPE_INT;
	dev->opt[OPT_NUM_OPTS].unit	= SANE_UNIT_NONE;
	dev->opt[OPT_NUM_OPTS].size = sizeof(SANE_Word);
	dev->opt[OPT_NUM_OPTS].cap	= SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE;

	dev->opt[OPT_MODE_GROUP].title= "Scan Mode";
	dev->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;

	dev->opt[OPT_RESOLUTION].name	= SANE_NAME_SCAN_RESOLUTION;
	dev->opt[OPT_RESOLUTION].title= SANE_TITLE_SCAN_RESOLUTION;
	dev->opt[OPT_RESOLUTION].desc	= SANE_DESC_SCAN_RESOLUTION;
	dev->opt[OPT_RESOLUTION].type	= SANE_TYPE_INT;
	dev->opt[OPT_RESOLUTION].unit	= SANE_UNIT_DPI;
	dev->opt[OPT_RESOLUTION].size = sizeof(SANE_Word);
	dev->opt[OPT_RESOLUTION].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
	dev->opt[OPT_RESOLUTION].constraint.word_list = dpi_list;

	dev->opt[OPT_DEPTH].name	= SANE_NAME_BIT_DEPTH;
	dev->opt[OPT_DEPTH].title	= SANE_TITLE_BIT_DEPTH;
	dev->opt[OPT_DEPTH].desc	= SANE_DESC_BIT_DEPTH;
	dev->opt[OPT_DEPTH].type	= SANE_TYPE_INT;
	dev->opt[OPT_DEPTH].unit	= SANE_UNIT_BIT;
	dev->opt[OPT_DEPTH].size	= sizeof(SANE_Word);
	dev->opt[OPT_DEPTH].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
	dev->opt[OPT_DEPTH].constraint.word_list = depth_list;

	dev->opt[OPT_THRESHOLD].name	= SANE_NAME_THRESHOLD;
	dev->opt[OPT_THRESHOLD].title	= SANE_TITLE_THRESHOLD;
	dev->opt[OPT_THRESHOLD].desc	= SANE_DESC_THRESHOLD;
	dev->opt[OPT_THRESHOLD].type	= SANE_TYPE_FIXED;
	dev->opt[OPT_THRESHOLD].unit	= SANE_UNIT_PERCENT;
	dev->opt[OPT_THRESHOLD].size	= sizeof(SANE_Word);
	dev->opt[OPT_THRESHOLD].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
	dev->opt[OPT_THRESHOLD].constraint.range = &thres_range;

	dev->opt[OPT_GEOMETRY_GROUP].title= "Geometry";
	dev->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;

	dev->opt[OPT_TL_X].name	= SANE_NAME_SCAN_TL_X;
	dev->opt[OPT_TL_X].title	= SANE_TITLE_SCAN_TL_X;
	dev->opt[OPT_TL_X].desc	= SANE_DESC_SCAN_TL_X;
	dev->opt[OPT_TL_X].type	= SANE_TYPE_FIXED;
	dev->opt[OPT_TL_X].unit	= SANE_UNIT_MM;
	dev->opt[OPT_TL_X].size	= sizeof(SANE_Word);
	dev->opt[OPT_TL_X].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
	dev->opt[OPT_TL_X].constraint.range = &x_range;

	dev->opt[OPT_TL_Y].name	= SANE_NAME_SCAN_TL_Y;
	dev->opt[OPT_TL_Y].title	= SANE_TITLE_SCAN_TL_Y;
	dev->opt[OPT_TL_Y].desc	= SANE_DESC_SCAN_TL_Y;
	dev->opt[OPT_TL_Y].type	= SANE_TYPE_FIXED;
	dev->opt[OPT_TL_Y].unit	= SANE_UNIT_MM;
	dev->opt[OPT_TL_Y].size	= sizeof(SANE_Word);
	dev->opt[OPT_TL_Y].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
	dev->opt[OPT_TL_Y].constraint.range = &y_range;

	dev->opt[OPT_BR_X].name	= SANE_NAME_SCAN_BR_X;
	dev->opt[OPT_BR_X].title	= SANE_TITLE_SCAN_BR_X;
	dev->opt[OPT_BR_X].desc	= SANE_DESC_SCAN_BR_X;
	dev->opt[OPT_BR_X].type	= SANE_TYPE_FIXED;
	dev->opt[OPT_BR_X].unit	= SANE_UNIT_MM;
	dev->opt[OPT_BR_X].size	= sizeof(SANE_Word);
	dev->opt[OPT_BR_X].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
	dev->opt[OPT_BR_X].constraint.range = &x_range;

	dev->opt[OPT_BR_Y].name	= SANE_NAME_SCAN_BR_Y;
	dev->opt[OPT_BR_Y].title	= SANE_TITLE_SCAN_BR_Y;
	dev->opt[OPT_BR_Y].desc	= SANE_DESC_SCAN_BR_Y;
	dev->opt[OPT_BR_Y].type	= SANE_TYPE_FIXED;
	dev->opt[OPT_BR_Y].unit	= SANE_UNIT_MM;
	dev->opt[OPT_BR_Y].size	= sizeof(SANE_Word);
	dev->opt[OPT_BR_Y].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
	dev->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
	dev->opt[OPT_BR_Y].constraint.range = &y_range;

	st400_reset_options(dev);
}
Пример #25
0
static SANE_Status
init_options (Tamarack_Scanner *s)
{
  int i;

  memset (s->opt, 0, sizeof (s->opt));
  memset (s->val, 0, sizeof (s->val));

  for (i = 0; i < NUM_OPTIONS; ++i) {
    s->opt[i].size = sizeof (SANE_Word);
    s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  }

  s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
  s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
  s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;

  /* "Mode" group: */
  s->opt[OPT_MODE_GROUP].title = "Scan Mode";
  s->opt[OPT_MODE_GROUP].desc = "";
  s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_MODE_GROUP].cap = 0;
  s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* scan mode */
  s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
  s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
  s->opt[OPT_MODE].desc = "Select the scan mode";
  s->opt[OPT_MODE].type = SANE_TYPE_STRING;
  s->opt[OPT_MODE].size = max_string_size (mode_list);
  s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  s->opt[OPT_MODE].constraint.string_list = mode_list;
  s->val[OPT_MODE].s = strdup (mode_list[OPT_MODE_DEFAULT]);

  /* resolution */
  s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
  s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
  s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
  s->val[OPT_RESOLUTION].w = SANE_FIX (OPT_RESOLUTION_DEFAULT);

  /* preview */
  s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
  s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
  s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
  s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
  s->val[OPT_PREVIEW].w = 0;

  /* gray preview */
  s->opt[OPT_GRAY_PREVIEW].name = SANE_NAME_GRAY_PREVIEW;
  s->opt[OPT_GRAY_PREVIEW].title = SANE_TITLE_GRAY_PREVIEW;
  s->opt[OPT_GRAY_PREVIEW].desc = SANE_DESC_GRAY_PREVIEW;
  s->opt[OPT_GRAY_PREVIEW].type = SANE_TYPE_BOOL;
  s->val[OPT_GRAY_PREVIEW].w = SANE_FALSE;

  /* "Geometry" group: */
  s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
  s->opt[OPT_GEOMETRY_GROUP].desc = "";
  s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
  s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* top-left x */
  s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
  s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
  s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
  s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
  s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
  s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
  s->val[OPT_TL_X].w = 0;

  /* top-left y */
  s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
  s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
  s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
  s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
  s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
  s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
  s->val[OPT_TL_Y].w = 0;

  /* bottom-right x */
  s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
  s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
  s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
  s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
  s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
  s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
  s->val[OPT_BR_X].w = s->hw->x_range.max;

  /* bottom-right y */
  s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
  s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
  s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
  s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
  s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
  s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
  s->val[OPT_BR_Y].w = s->hw->y_range.max;

  /* "Enhancement" group: */
  s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
  s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
  s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
  s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* transparency adapter. */
  s->opt[OPT_TRANS].name = "transparency";
  s->opt[OPT_TRANS].title = "transparency";
  s->opt[OPT_TRANS].desc = "Turn on the transparency adapter.";
  s->opt[OPT_TRANS].type = SANE_TYPE_BOOL;
  s->opt[OPT_TRANS].unit = SANE_UNIT_NONE;
  s->val[OPT_TRANS].w = SANE_FALSE;

  /* brightness */
  s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
  s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
  s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS
    "  This option is active for lineart/halftone modes only.  "
    "For multibit modes (grey/color) use the gamma-table(s).";
  s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_FIXED;
  s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_PERCENT;
  s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BRIGHTNESS].constraint.range = &percentage_range;
  s->val[OPT_BRIGHTNESS].w = SANE_FIX(0);

  /* contrast */
  s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
  s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
  s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST
    "  This option is active for lineart/halftone modes only.  "
    "For multibit modes (grey/color) use the gamma-table(s).";
  s->opt[OPT_CONTRAST].type = SANE_TYPE_FIXED;
  s->opt[OPT_CONTRAST].unit = SANE_UNIT_PERCENT;
  s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_CONTRAST].constraint.range = &percentage_range;
  s->val[OPT_CONTRAST].w = SANE_FIX(0);

  /* Threshold */
  s->opt[OPT_THRESHOLD].name = "Threshold";
  s->opt[OPT_THRESHOLD].title = "Threshold";
  s->opt[OPT_THRESHOLD].desc = "Threshold: below this level is black, above is white"
    "  This option is active for bitmap modes only.  ";
  s->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED;
  s->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT;
  s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_THRESHOLD].constraint.range = &abs_percentage_range;
  s->val[OPT_THRESHOLD].w = SANE_FIX(50);
  s->opt[OPT_THRESHOLD].cap  |= SANE_CAP_INACTIVE;

#if 0
  /* custom-gamma table */
  s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
  s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
  s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;

  /* grayscale gamma vector */
  s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR].wa = &s->gamma_table[0][0];

  /* red gamma vector */
  s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[1][0];

  /* green gamma vector */
  s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[2][0];

  /* blue gamma vector */
  s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0];
#endif
  return SANE_STATUS_GOOD;
}
Пример #26
0
static SANE_Status
calc_parameters (Mustek_Usb_Scanner * s)
{
  SANE_String val;
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Int max_x, max_y;

  DBG (5, "calc_parameters: start\n");
  val = s->val[OPT_MODE].s;

  s->params.last_frame = SANE_TRUE;

  if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
    {
      s->params.format = SANE_FRAME_GRAY;
      s->params.depth = 1;
      s->bpp = 1;
      s->channels = 1;
    }
  else if (!strcmp (val, SANE_VALUE_SCAN_MODE_GRAY))
    {
      s->params.format = SANE_FRAME_GRAY;
      s->params.depth = 8;
      s->bpp = 8;
      s->channels = 1;
    }
  else if (!strcmp (val, SANE_VALUE_SCAN_MODE_COLOR))
    {
      s->params.format = SANE_FRAME_RGB;
      s->params.depth = 8;
      s->bpp = 24;
      s->channels = 3;
    }
  else
    {
      DBG (1, "calc_parameters: invalid mode %s\n", (SANE_Char *) val);
      status = SANE_STATUS_INVAL;
    }

  s->tl_x = SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH;
  s->tl_y = SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH;
  s->width = SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH - s->tl_x;
  s->height = SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH - s->tl_y;

  if (s->width < 0)
    {
      DBG (1, "calc_parameters: warning: tl_x > br_x\n");
    }
  if (s->height < 0)
    {
      DBG (1, "calc_parameters: warning: tl_y > br_y\n");
    }
  max_x = s->hw->max_width * SANE_UNFIX (s->val[OPT_RESOLUTION].w) / 300;
  max_y = s->hw->max_height * SANE_UNFIX (s->val[OPT_RESOLUTION].w) / 300;

  s->tl_x_dots = s->tl_x * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
  s->width_dots = s->width * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
  s->tl_y_dots = s->tl_y * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
  s->height_dots = s->height * SANE_UNFIX (s->val[OPT_RESOLUTION].w);

  if (s->width_dots > max_x)
    s->width_dots = max_x;
  if (s->height_dots > max_y)
    s->height_dots = max_y;
  if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
    {
      s->width_dots = (s->width_dots / 8) * 8;
      if (s->width_dots == 0)
	s->width_dots = 8;
    }
  if (s->tl_x_dots < 0)
    s->tl_x_dots = 0;
  if (s->tl_y_dots < 0)
    s->tl_y_dots = 0;
  if (s->tl_x_dots + s->width_dots > max_x)
    s->tl_x_dots = max_x - s->width_dots;
  if (s->tl_y_dots + s->height_dots > max_y)
    s->tl_y_dots = max_y - s->height_dots;

  s->val[OPT_TL_X].w = SANE_FIX (s->tl_x * MM_PER_INCH);
  s->val[OPT_TL_Y].w = SANE_FIX (s->tl_y * MM_PER_INCH);
  s->val[OPT_BR_X].w = SANE_FIX ((s->tl_x + s->width) * MM_PER_INCH);
  s->val[OPT_BR_Y].w = SANE_FIX ((s->tl_y + s->height) * MM_PER_INCH);

  s->params.pixels_per_line = s->width_dots;
  if (s->params.pixels_per_line < 0)
    s->params.pixels_per_line = 0;
  s->params.lines = s->height_dots;
  if (s->params.lines < 0)
    s->params.lines = 0;
  s->params.bytes_per_line = s->params.pixels_per_line * s->params.depth / 8
    * s->channels;

  DBG (4, "calc_parameters: format=%d\n", s->params.format);
  DBG (4, "calc_parameters: last frame=%d\n", s->params.last_frame);
  DBG (4, "calc_parameters: lines=%d\n", s->params.lines);
  DBG (4, "calc_parameters: pixels per line=%d\n", s->params.pixels_per_line);
  DBG (4, "calc_parameters: bytes per line=%d\n", s->params.bytes_per_line);
  DBG (4, "calc_parameters: Pixels %dx%dx%d\n",
       s->params.pixels_per_line, s->params.lines, 1 << s->params.depth);

  DBG (5, "calc_parameters: exit\n");
  return status;
}
Пример #27
0
      break;
    case SANE_ACTION_SET_VALUE:
      optionAGainValue = *(SANE_Int *) value;
      *info |= SANE_INFO_RELOAD_PARAMS;
      break;
    case SANE_ACTION_GET_VALUE:
      *(SANE_Int *) value = optionAGainValue;
      break;
    }
  return SANE_STATUS_GOOD;
}

/*-----------------------------------------------------------------*/

/* Scanner gamma setting */
static SANE_Fixed optionGammaValue = SANE_FIX (1.6);

static SANE_Option_Descriptor optionGammaDescriptor = {
  "gamma",
  SANE_I18N ("Gamma Correction"),
  SANE_I18N ("Selects the gamma corrected transfer curve"),
  SANE_TYPE_FIXED,
  SANE_UNIT_NONE,
  sizeof (SANE_Int),
  SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED,
  SANE_CONSTRAINT_NONE,
  {NULL}
};


static SANE_Status
Пример #28
0
static SANE_Status
init_options (Mustek_Usb_Scanner * s)
{
  SANE_Int option;
  SANE_Status status;

  DBG (5, "init_options: start\n");

  memset (s->opt, 0, sizeof (s->opt));
  memset (s->val, 0, sizeof (s->val));

  for (option = 0; option < NUM_OPTIONS; ++option)
    {
      s->opt[option].size = sizeof (SANE_Word);
      s->opt[option].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
    }
  s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
  s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
  s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;

  /* "Mode" group: */
  s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode");
  s->opt[OPT_MODE_GROUP].desc = "";
  s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_MODE_GROUP].size = 0;
  s->opt[OPT_MODE_GROUP].cap = 0;
  s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* scan mode */
  mode_list[0] = SANE_VALUE_SCAN_MODE_COLOR;
  mode_list[1] = SANE_VALUE_SCAN_MODE_GRAY;
  mode_list[2] = SANE_VALUE_SCAN_MODE_LINEART;
  mode_list[3] = NULL;

  s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
  s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
  s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
  s->opt[OPT_MODE].type = SANE_TYPE_STRING;
  s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  s->opt[OPT_MODE].size = max_string_size (mode_list);
  s->opt[OPT_MODE].constraint.string_list = mode_list;
  s->val[OPT_MODE].s = strdup (mode_list[1]);

  /* resolution */
  s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
  s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
  s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
  s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
  if (s->hw->chip->scanner_type == MT_600CU)
    s->hw->dpi_range.max = SANE_FIX (600);
  else
    s->hw->dpi_range.max = SANE_FIX (1200);

  /* preview */
  s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
  s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
  s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
  s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
  s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
  s->val[OPT_PREVIEW].w = SANE_FALSE;

  /* "Geometry" group: */
  s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry");
  s->opt[OPT_GEOMETRY_GROUP].desc = "";
  s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
  s->opt[OPT_GEOMETRY_GROUP].size = 0;
  s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* top-left x */
  s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
  s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
  s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
  s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
  s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
  s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
  s->val[OPT_TL_X].w = 0;

  /* top-left y */
  s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
  s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
  s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
  s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
  s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
  s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
  s->val[OPT_TL_Y].w = 0;

  /* bottom-right x */
  s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
  s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
  s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
  s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
  s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
  s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
  s->val[OPT_BR_X].w = s->hw->x_range.max;

  /* bottom-right y */
  s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
  s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
  s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
  s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
  s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
  s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
  s->val[OPT_BR_Y].w = s->hw->y_range.max;

  /* "Enhancement" group: */
  s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
  s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
  s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
  s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
  s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* threshold */
  s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
  s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
  s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
  s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
  s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
  s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
  s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
  s->val[OPT_THRESHOLD].w = 128;

  /* custom-gamma table */
  s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
  s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;

  /* gray gamma vector */
  s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR].wa = &s->gray_gamma_table[0];

  /* red gamma vector */
  s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_R].wa = &s->red_gamma_table[0];

  /* green gamma vector */
  s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_G].wa = &s->green_gamma_table[0];

  /* blue gamma vector */
  s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_B].wa = &s->blue_gamma_table[0];

  RIE (calc_parameters (s));

  DBG (5, "init_options: exit\n");
  return SANE_STATUS_GOOD;
}
Пример #29
0
static SANE_Status
attach (SANE_String_Const devname, Mustek_Usb_Device ** devp,
	SANE_Bool may_wait)
{
  Mustek_Usb_Device *dev;
  SANE_Status status;
  Mustek_Type scanner_type;
  SANE_Int fd;

  DBG (5, "attach: start: devp %s NULL, may_wait = %d\n", devp ? "!=" : "==",
       may_wait);
  if (!devname)
    {
      DBG (1, "attach: devname == NULL\n");
      return SANE_STATUS_INVAL;
    }

  for (dev = first_dev; dev; dev = dev->next)
    if (strcmp (dev->sane.name, devname) == 0)
      {
	if (devp)
	  *devp = dev;
	DBG (4, "attach: device `%s' was already in device list\n", devname);
	return SANE_STATUS_GOOD;
      }

  DBG (4, "attach: trying to open device `%s'\n", devname);
  status = sanei_usb_open (devname, &fd);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (3, "attach: couldn't open device `%s': %s\n", devname,
	   sane_strstatus (status));
      return status;
    }
  DBG (4, "attach: device `%s' successfully opened\n", devname);

  /* try to identify model */
  DBG (4, "attach: trying to identify device `%s'\n", devname);
  status = usb_low_identify_scanner (fd, &scanner_type);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (1, "attach: device `%s' doesn't look like a supported scanner\n",
	   devname);
      sanei_usb_close (fd);
      return status;
    }
  sanei_usb_close (fd);
  if (scanner_type == MT_UNKNOWN)
    {
      DBG (3, "attach: warning: couldn't identify device `%s', must set "
	   "type manually\n", devname);
    }

  dev = malloc (sizeof (Mustek_Usb_Device));
  if (!dev)
    {
      DBG (1, "attach: couldn't malloc Mustek_Usb_Device\n");
      return SANE_STATUS_NO_MEM;
    }

  memset (dev, 0, sizeof (*dev));
  dev->name = strdup (devname);
  dev->sane.name = (SANE_String_Const) dev->name;
  dev->sane.vendor = "Mustek";
  switch (scanner_type)
    {
    case MT_1200CU:
      dev->sane.model = "1200 CU";
      break;
    case MT_1200CU_PLUS:
      dev->sane.model = "1200 CU Plus";
      break;
    case MT_1200USB:
      dev->sane.model = "1200 USB (unsupported)";
      break;
    case MT_1200UB:
      dev->sane.model = "1200 UB";
      break;
    case MT_600CU:
      dev->sane.model = "600 CU";
      break;
    case MT_600USB:
      dev->sane.model = "600 USB (unsupported)";
      break;
    default:
      dev->sane.model = "(unidentified)";
      break;
    }
  dev->sane.type = "flatbed scanner";

  dev->x_range.min = 0;
  dev->x_range.max = SANE_FIX (8.4 * MM_PER_INCH);
  dev->x_range.quant = 0;

  dev->y_range.min = 0;
  dev->y_range.max = SANE_FIX (11.7 * MM_PER_INCH);
  dev->y_range.quant = 0;

  dev->max_height = 11.7 * 300;
  dev->max_width = 8.4 * 300;
  dev->dpi_range.min = SANE_FIX (50);
  dev->dpi_range.max = SANE_FIX (600);
  dev->dpi_range.quant = SANE_FIX (1);

  status = usb_high_scan_init (dev);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (1, "attach: usb_high_scan_init returned status: %s\n",
	   sane_strstatus (status));
      free (dev);
      return status;
    }
  dev->chip->scanner_type = scanner_type;
  dev->chip->max_block_size = max_block_size;

  DBG (2, "attach: found %s %s %s at %s\n", dev->sane.vendor, dev->sane.type,
       dev->sane.model, dev->sane.name);
  ++num_devices;
  dev->next = first_dev;
  first_dev = dev;

  if (devp)
    *devp = dev;

  DBG (5, "attach: exit\n");
  return SANE_STATUS_GOOD;
}
Пример #30
0
};

static SANE_String_Const scan_modes[] = {
  SANE_VALUE_SCAN_MODE_LINEART,
  SANE_VALUE_SCAN_MODE_HALFTONE,
  SANE_VALUE_SCAN_MODE_GRAY,
  SANE_VALUE_SCAN_MODE_COLOR,
  NULL
};

static int scan_mode_to_code[] = {
  0x00, 0x01, 0x03, 0x05
};

static SANE_Range threshold = {
  SANE_FIX(30), SANE_FIX(70), SANE_FIX(10)
};

static void reset_options(struct device *dev)
{
  dev->val[OPT_RESOLUTION].w = 150;
  dev->val[OPT_MODE].s = string_match(scan_modes, SANE_VALUE_SCAN_MODE_COLOR);

  /* if docs loaded in adf use it as default source, flatbed oterwise */
  dev->val[OPT_SOURCE].s = UNCONST(doc_sources[(dev->doc_loaded)? 1 : 0]);

  dev->val[OPT_THRESHOLD].w = SANE_FIX(50);

  /* this is reported maximum window size, will be fixed later */
  dev->win_x_range.min = SANE_FIX(0);
  dev->win_x_range.max = SANE_FIX((double)dev->max_win_width / PNT_PER_MM);