예제 #1
0
static PyObject *isOptionSettable (PyObject * self, PyObject * args)
{
    SANE_Int cap;
    long lg;

    if (!PyArg_ParseTuple (args, "l", &lg))
        raiseError("Invalid arguments");

    cap = lg;
    return PyInt_FromLong (SANE_OPTION_IS_SETTABLE (cap));
}
예제 #2
0
/**
 * Gets or sets an option value.
 * 
 * From the SANE spec:
 * This function is used to set or inquire the current value of option
 * number n of the device represented by handle h. The manner in which
 * the option is controlled is specified by parameter action. The
 * possible values of this parameter are described in more detail
 * below.  The value of the option is passed through argument val. It
 * is a pointer to the memory that holds the option value. The memory
 * area pointed to by v must be big enough to hold the entire option
 * value (determined by member size in the corresponding option
 * descriptor).
 * 
 * The only exception to this rule is that when setting the value of a
 * string option, the string pointed to by argument v may be shorter
 * since the backend will stop reading the option value upon
 * encountering the first NUL terminator in the string. If argument i
 * is not NULL, the value of *i will be set to provide details on how
 * well the request has been met.
 */
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
                     SANE_Action action, void *val, SANE_Int * info)
{
  struct scanner *s = (struct scanner *) handle;
  SANE_Int dummy = 0;

  /* Make sure that all those statements involving *info cannot break (better
   * than having to do "if (info) ..." everywhere!)
   */
  if (info == 0)
    info = &dummy;

  if (option >= NUM_OPTIONS) {
    DBG (5, "sane_control_option: %d too big\n", option);
    return SANE_STATUS_INVAL;
  }

  if (!SANE_OPTION_IS_ACTIVE (s->opt[option].cap)) {
    DBG (5, "sane_control_option: %d inactive\n", option);
    return SANE_STATUS_INVAL;
  }

  /*
   * SANE_ACTION_GET_VALUE: We have to find out the current setting and
   * return it in a human-readable form (often, text).
   */
  if (action == SANE_ACTION_GET_VALUE) {
      SANE_Word * val_p = (SANE_Word *) val;

      DBG (20, "sane_control_option: get value for '%s' (%d)\n", s->opt[option].name,option);

      switch (option) {

        case OPT_NUM_OPTS:
          *val_p = NUM_OPTIONS;
          return SANE_STATUS_GOOD;

        case OPT_MODE:
          if(s->mode == MODE_GRAYSCALE){
            strcpy (val, STRING_GRAYSCALE);
          }
          else if(s->mode == MODE_COLOR){
            strcpy (val, STRING_COLOR);
          }
          return SANE_STATUS_GOOD;
      }
  }
  else if (action == SANE_ACTION_SET_VALUE) {
      int tmp;
      SANE_Status status;

      DBG (20, "sane_control_option: set value for '%s' (%d)\n", s->opt[option].name,option);

      if ( s->started ) {
        DBG (5, "sane_control_option: cant set, device busy\n");
        return SANE_STATUS_DEVICE_BUSY;
      }

      if (!SANE_OPTION_IS_SETTABLE (s->opt[option].cap)) {
        DBG (5, "sane_control_option: not settable\n");
        return SANE_STATUS_INVAL;
      }

      status = sanei_constrain_value (s->opt + option, val, info);
      if (status != SANE_STATUS_GOOD) {
        DBG (5, "sane_control_option: bad value\n");
        return status;
      }

      /*
       * Note - for those options which can assume one of a list of
       * valid values, we can safely assume that they will have
       * exactly one of those values because that's what
       * sanei_constrain_value does. Hence no "else: invalid" branches
       * below.
       */
      switch (option) {
 
        /* Mode Group */
        case OPT_MODE:
          if (!strcmp (val, STRING_GRAYSCALE)) {
            tmp = MODE_GRAYSCALE;
          }
          else{
            tmp = MODE_COLOR;
          }

          if (tmp == s->mode)
              return SANE_STATUS_GOOD;

          s->mode = tmp;
          *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
          return SANE_STATUS_GOOD;

      }                       /* switch */
  }                           /* else */

  return SANE_STATUS_INVAL;
}
예제 #3
0
파일: ibm.c 프로젝트: DspaceSPI/SPIScan
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
                     SANE_Action action, void *val, SANE_Int * info)
{
  Ibm_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;
  DBG (11, ">> sane_control_option\n");

  if (info)
    *info = 0;

  if (s->scanning)
    return (SANE_STATUS_DEVICE_BUSY);
  if (option >= NUM_OPTIONS)
    return (SANE_STATUS_INVAL);

  cap = s->opt[option].cap;
  if (!SANE_OPTION_IS_ACTIVE (cap))
    return (SANE_STATUS_INVAL);

  if (action == SANE_ACTION_GET_VALUE)
    {
      DBG (11, "sane_control_option get_value\n");
      switch (option)
        {
          /* word options: */
        case OPT_X_RESOLUTION:
        case OPT_Y_RESOLUTION:
        case OPT_TL_X:
        case OPT_TL_Y:
        case OPT_BR_X:
        case OPT_BR_Y:
        case OPT_NUM_OPTS:
        case OPT_BRIGHTNESS:
        case OPT_CONTRAST:
          *(SANE_Word *) val = s->val[option].w;
          return (SANE_STATUS_GOOD);
        
          /* bool options: */
	case OPT_ADF:
          *(SANE_Bool *) val = s->val[option].b;
          return (SANE_STATUS_GOOD);

          /* string options: */
        case OPT_MODE:
	case OPT_PAPER:
          strcpy (val, s->val[option].s);
          return (SANE_STATUS_GOOD);
        }
    }
  else {
    DBG (11, "sane_control_option set_value\n");
    if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
        return (SANE_STATUS_INVAL);

      status = sanei_constrain_value (s->opt + option, val, info);
      if (status != SANE_STATUS_GOOD)
        return status;

      switch (option)
        {
          /* (mostly) side-effect-free word options: */
        case OPT_X_RESOLUTION:
        case OPT_Y_RESOLUTION:
          if (info && s->val[option].w != *(SANE_Word *) val)
            *info |= SANE_INFO_RELOAD_PARAMS;
          s->val[option].w = *(SANE_Word *) val;
          return (SANE_STATUS_GOOD);
       
	case OPT_TL_X:
        case OPT_TL_Y:
        case OPT_BR_X:
        case OPT_BR_Y:
          if (info && s->val[option].w != *(SANE_Word *) val)
            *info |= SANE_INFO_RELOAD_PARAMS;
          s->val[option].w = *(SANE_Word *) val;
	  /* resets the paper format to user defined */
	  if (strcmp(s->val[OPT_PAPER].s, paper_list[IBM_PAPER_USER_DEFINED]) != 0)
	    {
	      if (info)
		*info |= SANE_INFO_RELOAD_OPTIONS;
              if (s->val[OPT_PAPER].s)
                free (s->val[OPT_PAPER].s);
              s->val[OPT_PAPER].s = strdup (paper_list[IBM_PAPER_USER_DEFINED]);
	    }
          return (SANE_STATUS_GOOD);
	
	case OPT_NUM_OPTS:
        case OPT_BRIGHTNESS:
        case OPT_CONTRAST:
          s->val[option].w = *(SANE_Word *) val;
          return (SANE_STATUS_GOOD);

        case OPT_MODE:
          if (info && strcmp (s->val[option].s, (SANE_String) val))
            *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
          if (s->val[option].s)
            free (s->val[option].s);
          s->val[option].s = strdup (val);
          return (SANE_STATUS_GOOD);
	
	case OPT_ADF:
	  s->val[option].b = *(SANE_Bool *) val;
	  if (*(SANE_Bool *) val)
	    s->adf_state = ADF_ARMED;
          else 
	    s->adf_state = ADF_UNUSED;
	  return (SANE_STATUS_GOOD);
	
	case OPT_PAPER:
          if (info && strcmp (s->val[option].s, (SANE_String) val))
            *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
          if (s->val[option].s)
            free (s->val[option].s);
          s->val[option].s = strdup (val);
	  if (strcmp (s->val[OPT_PAPER].s, "User") != 0)
	    {
              s->val[OPT_TL_X].w = 0;
	      s->val[OPT_TL_Y].w = 0;
	    if (strcmp (s->val[OPT_PAPER].s, "A3") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_A3_W;
	        s->val[OPT_BR_Y].w = PAPER_A3_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "A4") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_A4_W;
	        s->val[OPT_BR_Y].w = PAPER_A4_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "A4R") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_A4R_W;
	        s->val[OPT_BR_Y].w = PAPER_A4R_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "A5") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_A5_W;
	        s->val[OPT_BR_Y].w = PAPER_A5_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "A5R") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_A5R_W;
	        s->val[OPT_BR_Y].w = PAPER_A5R_H;
  	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "A6") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_A6_W;
	        s->val[OPT_BR_Y].w = PAPER_A6_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "B4") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_B4_W;
	        s->val[OPT_BR_Y].w = PAPER_B4_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "Legal") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_LEGAL_W;
	        s->val[OPT_BR_Y].w = PAPER_LEGAL_H;
	      }
	    else if (strcmp (s->val[OPT_PAPER].s, "Letter") == 0)
	      {
                s->val[OPT_BR_X].w = PAPER_LETTER_W;
	        s->val[OPT_BR_Y].w = PAPER_LETTER_H;
	      }
	  }
	  return (SANE_STATUS_GOOD);
        }

    }
  }

  DBG (11, "<< sane_control_option\n");
  return (SANE_STATUS_INVAL);
}
예제 #4
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int *info)
{
  Tamarack_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;

  if (info)
    *info = 0;

  if (s->scanning)
    return SANE_STATUS_DEVICE_BUSY;

  if (option >= NUM_OPTIONS)
    return SANE_STATUS_INVAL;

  cap = s->opt[option].cap;

  if (!SANE_OPTION_IS_ACTIVE (cap))
    return SANE_STATUS_INVAL;

  if (action == SANE_ACTION_GET_VALUE) {
    switch (option) {
      /* word options: */
    case OPT_PREVIEW:
    case OPT_GRAY_PREVIEW:
    case OPT_RESOLUTION:
    case OPT_TL_X:
    case OPT_TL_Y:
    case OPT_BR_X:
    case OPT_BR_Y:
    case OPT_NUM_OPTS:
    case OPT_TRANS:
    case OPT_BRIGHTNESS:
    case OPT_CONTRAST:
    case OPT_THRESHOLD:
#if 0
    case OPT_CUSTOM_GAMMA:
#endif
      *(SANE_Word *) val = s->val[option].w;
      return SANE_STATUS_GOOD;

#if 0
      /* word-array options: */
    case OPT_GAMMA_VECTOR:
    case OPT_GAMMA_VECTOR_R:
    case OPT_GAMMA_VECTOR_G:
    case OPT_GAMMA_VECTOR_B:
      memcpy (val, s->val[option].wa, s->opt[option].size);
      return SANE_STATUS_GOOD;
#endif

      /* string options: */
    case OPT_MODE:
      strcpy (val, s->val[option].s);
      return SANE_STATUS_GOOD;
    }
  } else if (action == SANE_ACTION_SET_VALUE) {
    if (!SANE_OPTION_IS_SETTABLE (cap))
      return SANE_STATUS_INVAL;

    status = constrain_value (s, option, val, info);
    if (status != SANE_STATUS_GOOD)
      return status;
    
    switch (option)
      {
	/* (mostly) side-effect-free word options: */
      case OPT_RESOLUTION:
      case OPT_TL_X:
      case OPT_TL_Y:
      case OPT_BR_X:
      case OPT_BR_Y:
	if (info)
	  *info |= SANE_INFO_RELOAD_PARAMS;
	/* fall through */
      case OPT_PREVIEW:
      case OPT_GRAY_PREVIEW:
      case OPT_BRIGHTNESS:
      case OPT_CONTRAST:
      case OPT_THRESHOLD:
      case OPT_TRANS:
	s->val[option].w = *(SANE_Word *) val;
	return SANE_STATUS_GOOD;

#if 0
	/* side-effect-free word-array options: */
      case OPT_GAMMA_VECTOR:
      case OPT_GAMMA_VECTOR_R:
      case OPT_GAMMA_VECTOR_G:
      case OPT_GAMMA_VECTOR_B:
	memcpy (s->val[option].wa, val, s->opt[option].size);
	return SANE_STATUS_GOOD;

	/* options with side-effects: */

      case OPT_CUSTOM_GAMMA:
	w = *(SANE_Word *) val;
	if (w == s->val[OPT_CUSTOM_GAMMA].w)
	  return SANE_STATUS_GOOD;		/* no change */

	s->val[OPT_CUSTOM_GAMMA].w = w;
	if (w) {
	  s->mode = make_mode (s->val[OPT_MODE].s);

	  if (s->mode == GREYSCALE) {
	    s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
	  } else if (s->mode == TRUECOLOR) {
	    s->opt[OPT_GAMMA_VECTOR].cap   &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
	  }
	} else {
	  s->opt[OPT_GAMMA_VECTOR].cap   |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
	}
	if (info)
	  *info |= SANE_INFO_RELOAD_OPTIONS;
	return SANE_STATUS_GOOD;
#endif

      case OPT_MODE:
	{

	  if (s->val[option].s)
	    free (s->val[option].s);
	  s->val[option].s = strdup (val);

	  s->mode = make_mode (s->val[OPT_MODE].s);

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

	  s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_CONTRAST].cap   |= SANE_CAP_INACTIVE;
	  s->opt[OPT_THRESHOLD].cap  |= SANE_CAP_INACTIVE;
#if 0
	  s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
#endif


	  if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0) 
	    s->opt[OPT_THRESHOLD].cap  &= ~SANE_CAP_INACTIVE;
	  else {
	    s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_CONTRAST].cap   &= ~SANE_CAP_INACTIVE;
	  }
#if 0
	  if (!binary)
	    s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;

	  if (s->val[OPT_CUSTOM_GAMMA].w) {
	    if (strcmp (val, SANE_VALUE_SCAN_MODE_GRAY) == 0)
	      s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
	    else if (strcmp (val, SANE_VALUE_SCAN_MODE_COLOR) == 0) {
	      s->opt[OPT_GAMMA_VECTOR].cap   &= ~SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
	    }
	  }
#endif
	  return SANE_STATUS_GOOD;
	}
      }
    }
  return SANE_STATUS_INVAL;
}
예제 #5
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;
}
예제 #6
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
                     SANE_Action action, void *val, SANE_Int * info)
{
  Ricoh_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;
  DBG (11, ">> sane_control_option\n");

  if (info)
    *info = 0;

  if (s->scanning)
    return (SANE_STATUS_DEVICE_BUSY);
  if (option >= NUM_OPTIONS)
    return (SANE_STATUS_INVAL);

  cap = s->opt[option].cap;
  if (!SANE_OPTION_IS_ACTIVE (cap))
    return (SANE_STATUS_INVAL);

  if (action == SANE_ACTION_GET_VALUE)
    {
      switch (option)
        {
          /* word options: */
        case OPT_X_RESOLUTION:
        case OPT_Y_RESOLUTION:
        case OPT_TL_X:
        case OPT_TL_Y:
        case OPT_BR_X:
        case OPT_BR_Y:
        case OPT_NUM_OPTS:
        case OPT_BRIGHTNESS:
        case OPT_CONTRAST:
          *(SANE_Word *) val = s->val[option].w;
          return (SANE_STATUS_GOOD);

          /* string options: */
        case OPT_MODE:
          strcpy (val, s->val[option].s);
          return (SANE_STATUS_GOOD);
        }
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
        return (SANE_STATUS_INVAL);

      status = sanei_constrain_value (s->opt + option, val, info);
      if (status != SANE_STATUS_GOOD)
        return status;

      switch (option)
        {
          /* (mostly) side-effect-free word options: */
        case OPT_X_RESOLUTION:
        case OPT_Y_RESOLUTION:
        case OPT_TL_X:
        case OPT_TL_Y:
        case OPT_BR_X:
        case OPT_BR_Y:
          if (info && s->val[option].w != *(SANE_Word *) val)
            *info |= SANE_INFO_RELOAD_PARAMS;
          /* fall through */
        case OPT_NUM_OPTS:
        case OPT_BRIGHTNESS:
        case OPT_CONTRAST:
          s->val[option].w = *(SANE_Word *) val;
          return (SANE_STATUS_GOOD);

        case OPT_MODE:
          if (info && strcmp (s->val[option].s, (SANE_String) val))
            *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
          if (s->val[option].s)
            free (s->val[option].s);
          s->val[option].s = strdup (val);
          return (SANE_STATUS_GOOD);
        }
    }

  DBG (11, "<< sane_control_option\n");
  return (SANE_STATUS_INVAL);
}
예제 #7
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  Leo_Scanner *dev = handle;
  SANE_Status status;
  SANE_Word cap;
  int i;

  DBG (DBG_proc, "sane_control_option: enter, option %d, action %d\n",
       option, action);

  if (info)
    {
      *info = 0;
    }

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

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

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

  if (action == SANE_ACTION_GET_VALUE)
    {

      switch (option)
	{
	  /* word options */
	case OPT_NUM_OPTS:
	case OPT_RESOLUTION:
	case OPT_TL_Y:
	case OPT_BR_Y:
	case OPT_TL_X:
	case OPT_BR_X:
	case OPT_CUSTOM_GAMMA:
	case OPT_PREVIEW:
	  *(SANE_Word *) val = dev->val[option].w;
	  return SANE_STATUS_GOOD;

	  /* string options */
	case OPT_MODE:
	case OPT_HALFTONE_PATTERN:
	  strcpy (val, dev->val[option].s);
	  return SANE_STATUS_GOOD;

	  /* Gamma */
	case OPT_GAMMA_VECTOR_R:
	case OPT_GAMMA_VECTOR_G:
	case OPT_GAMMA_VECTOR_B:
	case OPT_GAMMA_VECTOR_GRAY:
	  memcpy (val, dev->val[option].wa, dev->opt[option].size);
	  return SANE_STATUS_GOOD;

	default:
	  return SANE_STATUS_INVAL;
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {

      if (!SANE_OPTION_IS_SETTABLE (cap))
	{
	  DBG (DBG_error, "could not set option, not settable\n");
	  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)
	{

	  /* Numeric side-effect options */
	case OPT_TL_Y:
	case OPT_BR_Y:
	case OPT_TL_X:
	case OPT_BR_X:
	case OPT_RESOLUTION:
	  if (info)
	    {
	      *info |= SANE_INFO_RELOAD_PARAMS;
	    }
	  dev->val[option].w = *(SANE_Word *) val;
	  return SANE_STATUS_GOOD;

	  /* Numeric side-effect free options */
	case OPT_PREVIEW:
	  dev->val[option].w = *(SANE_Word *) val;
	  return SANE_STATUS_GOOD;

	  /* String side-effect options */
	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_Char *) strdup (val);

	  dev->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_GAMMA_VECTOR_GRAY].cap |= SANE_CAP_INACTIVE;
	  dev->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;

	  if (strcmp (dev->val[OPT_MODE].s, BLACK_WHITE_STR) == 0)
	    {
	      i = get_string_list_index (halftone_pattern_list,
					 dev->val[OPT_HALFTONE_PATTERN].s);
	      if (halftone_pattern_val[i] == NULL)
		{
		  dev->scan_mode = LEO_BW;
		}
	      else
		{
		  dev->scan_mode = LEO_HALFTONE;
		}
	      dev->depth = 1;
	      dev->opt[OPT_HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
	    }
	  else if (strcmp (dev->val[OPT_MODE].s, GRAY_STR) == 0)
	    {
	      dev->scan_mode = LEO_GRAYSCALE;
	      dev->depth = 8;
	      dev->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
	      if (dev->val[OPT_CUSTOM_GAMMA].w)
		{
		  dev->opt[OPT_GAMMA_VECTOR_GRAY].cap &= ~SANE_CAP_INACTIVE;
		}
	    }
	  else if (strcmp (dev->val[OPT_MODE].s, COLOR_STR) == 0)
	    {
	      dev->scan_mode = LEO_COLOR;
	      dev->depth = 8;
	      dev->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
	      if (dev->val[OPT_CUSTOM_GAMMA].w)
		{
		  dev->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
		  dev->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
		  dev->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
		}
	    }

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

	case OPT_HALFTONE_PATTERN:
	  free (dev->val[option].s);
	  dev->val[option].s = (SANE_String) strdup (val);
	  i = get_string_list_index (halftone_pattern_list,
				     dev->val[OPT_HALFTONE_PATTERN].s);
	  if (halftone_pattern_val[i] == NULL)
	    {
	      dev->scan_mode = LEO_BW;
	    }
	  else
	    {
	      dev->scan_mode = LEO_HALFTONE;
	    }

	  return SANE_STATUS_GOOD;

	case OPT_GAMMA_VECTOR_R:
	case OPT_GAMMA_VECTOR_G:
	case OPT_GAMMA_VECTOR_B:
	case OPT_GAMMA_VECTOR_GRAY:
	  memcpy (dev->val[option].wa, val, dev->opt[option].size);
	  return SANE_STATUS_GOOD;

	case OPT_CUSTOM_GAMMA:
	  dev->val[OPT_CUSTOM_GAMMA].w = *(SANE_Word *) val;
	  if (dev->val[OPT_CUSTOM_GAMMA].w)
	    {
	      /* use custom_gamma_table */
	      if (dev->scan_mode == LEO_GRAYSCALE)
		{
		  dev->opt[OPT_GAMMA_VECTOR_GRAY].cap &= ~SANE_CAP_INACTIVE;
		}
	      else
		{
		  /* color mode */
		  dev->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
		  dev->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
		  dev->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
		}
	    }
	  else
	    {
	      dev->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	      dev->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	      dev->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
	      dev->opt[OPT_GAMMA_VECTOR_GRAY].cap |= SANE_CAP_INACTIVE;
	    }
	  if (info)
	    {
	      *info |= SANE_INFO_RELOAD_OPTIONS;
	    }
	  return SANE_STATUS_GOOD;

	default:
	  return SANE_STATUS_INVAL;
	}
    }

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

  return SANE_STATUS_UNSUPPORTED;
}
예제 #8
0
/* Control option */
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  int i;
  SANE_Status status;
  SANE_Word cap;
  struct scanner *s = (struct scanner *) handle;

  if (info)
    *info = 0;

  if (option < 0 || option >= NUM_OPTIONS)
    return SANE_STATUS_UNSUPPORTED;

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

  if (action == SANE_ACTION_GET_VALUE)
    {
      if (s->opt[option].type == SANE_TYPE_STRING)
	{
	  DBG (DBG_INFO,
	       "sane_control_option: reading opt[%d] =  %s\n",
	       option, s->val[option].s);
	  strcpy (val, s->val[option].s);
	}
      else
	{
	  *(SANE_Word *) val = s->val[option].w;
	  DBG (DBG_INFO,
	       "sane_control_option: reading opt[%d] =  %d\n",
	       option, s->val[option].w);
	}
      return SANE_STATUS_GOOD;

    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
	return SANE_STATUS_INVAL;

      status = sanei_constrain_value (s->opt + option, val, info);
      if (status != SANE_STATUS_GOOD)
	return status;

      if (s->opt[option].type == SANE_TYPE_STRING)
	{
	  if (!strcmp (val, s->val[option].s))
	    return SANE_STATUS_GOOD;
	  DBG (DBG_INFO,
	       "sane_control_option: writing opt[%d] =  %s\n",
	       option, (SANE_String_Const) val);
	}
      else
	{
	  if (*(SANE_Word *) val == s->val[option].w)
	    return SANE_STATUS_GOOD;
	  DBG (DBG_INFO,
	       "sane_control_option: writing opt[%d] =  %d\n",
	       option, *(SANE_Word *) val);
	}

      switch (option)
	{
	  /* Side-effect options */
	case RESOLUTION:
	  s->val[option].w = *(SANE_Word *) val;
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	case TL_Y:
	  if ((*(SANE_Word *) val) + MIN_LENGTH <=
	      s->val[BR_Y].w &&
	      !check_area (s, s->val[TL_X].w, *(SANE_Word *) val,
			   s->val[BR_X].w, s->val[BR_Y].w))
	    {
	      s->val[option].w = *(SANE_Word *) val;
	      if (info)
		*info |= SANE_INFO_RELOAD_PARAMS;
	    }
	  else if (info)
	    *info |= SANE_INFO_INEXACT |
	      SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;
	case BR_Y:
	  if ((*(SANE_Word *) val) >=
	      s->val[TL_Y].w + MIN_LENGTH
	      && !check_area (s, s->val[TL_X].w, s->val[TL_Y].w,
			      s->val[BR_X].w, *(SANE_Word *) val))
	    {
	      s->val[option].w = *(SANE_Word *) val;
	      if (info)
		*info |= SANE_INFO_RELOAD_PARAMS;
	    }
	  else if (info)
	    *info |= SANE_INFO_INEXACT |
	      SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	case TL_X:
	  if ((*(SANE_Word *) val) + MIN_WIDTH <=
	      s->val[BR_X].w &&
	      !check_area (s, *(SANE_Word *) val, s->val[TL_Y].w,
			   s->val[BR_X].w, s->val[BR_Y].w))
	    {
	      s->val[option].w = *(SANE_Word *) val;
	      if (info)
		*info |= SANE_INFO_RELOAD_PARAMS;
	    }
	  else if (info)
	    *info |= SANE_INFO_INEXACT |
	      SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	case BR_X:
	  if (*(SANE_Word *) val >=
	      s->val[TL_X].w + MIN_WIDTH
	      && !check_area (s, s->val[TL_X].w, s->val[TL_Y].w,
			      *(SANE_Word *) val, s->val[BR_Y].w))
	    {
	      s->val[option].w = *(SANE_Word *) val;
	      if (info)
		*info |= SANE_INFO_RELOAD_PARAMS;
	    }
	  else if (info)
	    *info |= SANE_INFO_INEXACT |
	      SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	case LANDSCAPE:
	  s->val[option].w = *(SANE_Word *) val;
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	  /* Side-effect free options */
	case CONTRAST:
	case BRIGHTNESS:
	case DUPLEX:
	case LENGTHCTL:
	case LONG_PAPER:
	case FIT_TO_PAGE:
	case THRESHOLD:
	case INVERSE:
	case COMPRESSION_PAR:
	case DFSTOP:
	case DFEED_L:
	case DFEED_C:
	case DFEED_R:
	case STOP_SKEW:
	case DESKEW:
	case MIRROR:
	case CROP:
	case TOPPOS:
	case BTMPOS:
	case RED_CHROMA:
	case BLUE_CHROMA:
	  s->val[option].w = *(SANE_Word *) val;
	  return SANE_STATUS_GOOD;

	case FEED_TIMEOUT:
	  s->val[option].w = *(SANE_Word *) val;
	  return kvs40xx_set_timeout (s, s->val[option].w);

	  /* String mode */
	case IMAGE_EMPHASIS:
	case GAMMA_CORRECTION:
	case LAMP:
	case HALFTONE_PATTERN:
	case DFEED_SENCE:
	case AUTOMATIC_THRESHOLD:
	case WHITE_LEVEL:
	case NOISE_REDUCTION:
	  strcpy (s->val[option].s, val);
	  return SANE_STATUS_GOOD;

	case SOURCE:
	  strcpy (s->val[option].s, val);
	  if (strcmp (s->val[option].s, SANE_I18N ("adf")))
	    {
	      strcpy (s->val[FEEDER_MODE].s, feeder_mode_list[0]);
	      strcpy (s->val[MANUALFEED].s, manual_feed_list[0]);
	      s->val[DUPLEX].w = SANE_FALSE;
	      s->val[DBLFEED].w = SANE_FALSE;
	      s->val[BTMPOS].w = SANE_FALSE;
	      s->val[TOPPOS].w = SANE_FALSE;
	      s->val[STOP_SKEW].w = SANE_FALSE;
	      s->val[LENGTHCTL].w = SANE_FALSE;
	      s->val[LONG_PAPER].w = SANE_FALSE;
	      s->opt[FEEDER_MODE].cap |= SANE_CAP_INACTIVE;
	      s->opt[MANUALFEED].cap |= SANE_CAP_INACTIVE;
	      s->opt[DUPLEX].cap |= SANE_CAP_INACTIVE;
	      s->opt[DBLFEED].cap |= SANE_CAP_INACTIVE;
	      s->opt[BTMPOS].cap |= SANE_CAP_INACTIVE;
	      s->opt[TOPPOS].cap |= SANE_CAP_INACTIVE;
	      s->opt[STOP_SKEW].cap |= SANE_CAP_INACTIVE;
	      s->opt[LENGTHCTL].cap |= SANE_CAP_INACTIVE;
	      s->opt[LONG_PAPER].cap |= SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[FEEDER_MODE].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[MANUALFEED].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DUPLEX].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DBLFEED].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[BTMPOS].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[TOPPOS].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[STOP_SKEW].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[LENGTHCTL].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[LONG_PAPER].cap &= ~SANE_CAP_INACTIVE;
	    }
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;

	case FEEDER_MODE:
	  strcpy (s->val[option].s, val);
	  if (strcmp (s->val[option].s, SANE_I18N ("continuous")))
	    {
	      s->opt[LONG_PAPER].cap |= SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[LONG_PAPER].cap &= ~SANE_CAP_INACTIVE;
	    }
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;

	case MODE:
	  strcpy (s->val[option].s, val);
	  if (!strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART))
	    {
	      s->opt[GAMMA_CORRECTION].cap |= SANE_CAP_INACTIVE;
	      s->opt[COMPRESSION].cap |= SANE_CAP_INACTIVE;
	      s->opt[COMPRESSION_PAR].cap |= SANE_CAP_INACTIVE;
	      s->opt[THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;

	      s->opt[AUTOMATIC_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[WHITE_LEVEL].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[NOISE_REDUCTION].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[INVERSE].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[RED_CHROMA].cap |= SANE_CAP_INACTIVE;
	      s->opt[BLUE_CHROMA].cap |= SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[COMPRESSION].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[COMPRESSION_PAR].cap &= ~SANE_CAP_INACTIVE;

	      s->opt[THRESHOLD].cap |= SANE_CAP_INACTIVE;
	      s->opt[INVERSE].cap |= SANE_CAP_INACTIVE;
	      s->opt[HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;

	      s->opt[AUTOMATIC_THRESHOLD].cap |= SANE_CAP_INACTIVE;
	      s->opt[WHITE_LEVEL].cap |= SANE_CAP_INACTIVE;
	      s->opt[NOISE_REDUCTION].cap |= SANE_CAP_INACTIVE;
	      s->opt[RED_CHROMA].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[BLUE_CHROMA].cap &= ~SANE_CAP_INACTIVE;
	    }

	  if (!strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY))
	    {
	      s->opt[INVERSE].cap &= ~SANE_CAP_INACTIVE;

	      s->opt[GAMMA_CORRECTION].cap &= ~SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[GAMMA_CORRECTION].cap |= SANE_CAP_INACTIVE;
	    }

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

	  return SANE_STATUS_GOOD;

	case MANUALFEED:
	  strcpy (s->val[option].s, val);
	  if (strcmp (s->val[option].s, manual_feed_list[0]) == 0)	/* off */
	    s->opt[FEED_TIMEOUT].cap |= SANE_CAP_INACTIVE;
	  else
	    s->opt[FEED_TIMEOUT].cap &= ~SANE_CAP_INACTIVE;
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;

	case STAPELED_DOC:
	  strcpy (s->val[option].s, val);
	  if (strcmp (s->val[option].s, stapeled_list[0]) == 0)
	    {
	      s->opt[DBLFEED].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFSTOP].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_L].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_R].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_SENCE].cap &= ~SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[DBLFEED].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFSTOP].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_L].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_C].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_R].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_SENCE].cap |= SANE_CAP_INACTIVE;
	    }
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;

	case DBLFEED:
	  s->val[option].w = *(SANE_Word *) val;
	  if (!s->val[option].b)
	    {
	      s->opt[DFSTOP].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_L].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_C].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_R].cap |= SANE_CAP_INACTIVE;
	      s->opt[DFEED_SENCE].cap |= SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[DFSTOP].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_L].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_R].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[DFEED_SENCE].cap &= ~SANE_CAP_INACTIVE;
	    }
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;

	case PAPER_SIZE:
	  strcpy (s->val[option].s, val);
	  i = str_index (paper_list, s->val[option].s);
	  if (i == 0)
	    {			/*user def */
	      s->opt[TL_X].cap &=
		s->opt[TL_Y].cap &=
		s->opt[BR_X].cap &= s->opt[BR_Y].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
	      s->val[LANDSCAPE].w = 0;
	    }
	  else
	    {
	      s->opt[TL_X].cap |=
		s->opt[TL_Y].cap |=
		s->opt[BR_X].cap |= s->opt[BR_Y].cap |= SANE_CAP_INACTIVE;
	      if ( /*i == 4 || */ i == 5 || i == 6 /*XXX*/
		  || i == 10 || i == 11)
		{		/*A4, A5, A6, B5, B6 */
		  if ((s->id == KV_S4085CL || s->id == KV_S4065CL)
		      && i == 4 && i == 10)
		    {		/*A4, B5 */
		      s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
		      s->val[LANDSCAPE].w = 0;
		    }
		  else
		    s->opt[LANDSCAPE].cap &= ~SANE_CAP_INACTIVE;
		}
	      else
		{
		  s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
		  s->val[LANDSCAPE].w = 0;
		}
	    }
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;

	  return SANE_STATUS_GOOD;

	case COMPRESSION:
	  s->val[option].w = *(SANE_Word *) val;
	  if (!s->val[option].b)
	    {
	      s->opt[COMPRESSION_PAR].cap |= SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[COMPRESSION_PAR].cap &= ~SANE_CAP_INACTIVE;
	    }
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;

	  return SANE_STATUS_GOOD;
	}
    }


  return SANE_STATUS_UNSUPPORTED;
}
예제 #9
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  Mustek_Usb_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;
  SANE_Int myinfo = 0;

  DBG (5, "sane_control_option: start: action = %s, option = %s (%d)\n",
       (action == SANE_ACTION_GET_VALUE) ? "get" :
       (action == SANE_ACTION_SET_VALUE) ? "set" :
       (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown",
       s->opt[option].name, option);

  if (info)
    *info = 0;

  if (s->scanning)
    {
      DBG (1, "sane_control_option: don't call this function while "
	   "scanning\n");
      return SANE_STATUS_DEVICE_BUSY;
    }

  if (option >= NUM_OPTIONS || option < 0)
    {
      DBG (1, "sane_control_option: option %d >= NUM_OPTIONS || option < 0\n",
	   option);
      return SANE_STATUS_INVAL;
    }

  cap = s->opt[option].cap;

  if (!SANE_OPTION_IS_ACTIVE (cap))
    {
      DBG (2, "sane_control_option: option %d is inactive\n", option);
      return SANE_STATUS_INVAL;
    }

  if (action == SANE_ACTION_GET_VALUE)
    {
      switch (option)
	{
	  /* word options: */
	case OPT_NUM_OPTS:
	case OPT_RESOLUTION:
	case OPT_PREVIEW:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	case OPT_THRESHOLD:
	case OPT_CUSTOM_GAMMA:
	  *(SANE_Word *) val = s->val[option].w;
	  break;
	  /* word-array options: */
	case OPT_GAMMA_VECTOR:
	case OPT_GAMMA_VECTOR_R:
	case OPT_GAMMA_VECTOR_G:
	case OPT_GAMMA_VECTOR_B:
	  memcpy (val, s->val[option].wa, s->opt[option].size);
	  break;
	  /* string options: */
	case OPT_MODE:
	  strcpy (val, s->val[option].s);
	  break;
	default:
	  DBG (2, "sane_control_option: can't get unknown option %d\n",
	       option);
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
	{
	  DBG (2, "sane_control_option: option %d is not settable\n", option);
	  return SANE_STATUS_INVAL;
	}

      status = sanei_constrain_value (s->opt + option, val, &myinfo);

      if (status != SANE_STATUS_GOOD)
	{
	  DBG (2, "sane_control_option: sanei_constrain_value returned %s\n",
	       sane_strstatus (status));
	  return status;
	}

      switch (option)
	{
	  /* (mostly) side-effect-free word options: */
	case OPT_RESOLUTION:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	  s->val[option].w = *(SANE_Word *) val;
	  RIE (calc_parameters (s));
	  myinfo |= SANE_INFO_RELOAD_PARAMS;
	  break;
	case OPT_THRESHOLD:
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	  /* Boolean */
	case OPT_PREVIEW:
	  s->val[option].w = *(SANE_Bool *) val;
	  break;
	  /* side-effect-free word-array options: */
	case OPT_GAMMA_VECTOR:
	case OPT_GAMMA_VECTOR_R:
	case OPT_GAMMA_VECTOR_G:
	case OPT_GAMMA_VECTOR_B:
	  memcpy (s->val[option].wa, val, s->opt[option].size);
	  check_gamma_table (s->val[option].wa);
	  break;
	case OPT_CUSTOM_GAMMA:
	  s->val[OPT_CUSTOM_GAMMA].w = *(SANE_Word *) val;
	  myinfo |= SANE_INFO_RELOAD_OPTIONS;
	  if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
	    {
	      s->red_table = s->red_gamma_table;
	      s->green_table = s->green_gamma_table;
	      s->blue_table = s->blue_gamma_table;
	      s->gray_table = s->gray_gamma_table;
	      if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
		s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
	      else if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
		{
		  s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
		}
	    }
	  else
	    {
	      s->red_table = s->linear_gamma_table;
	      s->green_table = s->linear_gamma_table;
	      s->blue_table = s->linear_gamma_table;
	      s->gray_table = s->linear_gamma_table;
	      s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
	    }
	  break;
	case OPT_MODE:
	  if (s->val[option].s)
	    free (s->val[option].s);
	  s->val[option].s = strdup (val);

	  RIE (calc_parameters (s));

	  s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;

	  if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0)
	    {
	      s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
	      if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
		{
		  s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
		}
	    }
	  myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  break;
	default:
	  DBG (2, "sane_control_option: can't set unknown option %d\n",
	       option);
	}
    }
  else
    {
      DBG (2, "sane_control_option: unknown action %d for option %d\n",
	   action, option);
      return SANE_STATUS_INVAL;
    }
  if (info)
    *info = myinfo;

  DBG (5, "sane_control_option: exit\n");
  return SANE_STATUS_GOOD;
}
예제 #10
0
SANE_Status
sane_control_option( SANE_Handle handle, SANE_Int optnum,
	SANE_Action action, void *valP, SANE_Int *infoP)
{
	ST400_Device *dev = handle;
	SANE_Status status;

	DBG(DCODE, "sane_control_option(%p, %d, %d, %p, %p)\n", (void *) handle, (int)optnum, (int)action, valP, (void *) infoP);

	if( infoP )
		*infoP = 0;

	if( !dev->status.open )
		return SANE_STATUS_INVAL;
	if( dev->status.scanning )
		return SANE_STATUS_DEVICE_BUSY;

	if( optnum < 0 || optnum >= NUM_OPTIONS )
		return SANE_STATUS_INVAL;

	switch( action ) {
		case SANE_ACTION_GET_VALUE:

			DBG(DOPT, "getting option %d (value=%d)\n", (int)optnum, (int)dev->val[optnum]);

			switch( optnum ) {
				case OPT_NUM_OPTS:
				case OPT_RESOLUTION:
				case OPT_DEPTH:
				case OPT_THRESHOLD:
				case OPT_TL_X:
				case OPT_TL_Y:
				case OPT_BR_X:
				case OPT_BR_Y:
					*(SANE_Word *)valP = dev->val[optnum];
					break;
				default:
					return SANE_STATUS_INVAL;
			}
			break;

		case SANE_ACTION_SET_VALUE:
			if( !SANE_OPTION_IS_SETTABLE(dev->opt[optnum].cap) )
				return SANE_STATUS_INVAL;
			status = sanei_constrain_value(&dev->opt[optnum], valP, infoP);
			if( status != SANE_STATUS_GOOD )
				return status;

			DBG(DOPT, "setting option %d to %d\n", (int)optnum, (int)*(SANE_Word *)valP);

			switch( optnum ) {
				case OPT_DEPTH:
					if( *(SANE_Word *)valP != 1 )
						dev->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
					else
						dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
					if( infoP )
						*infoP |= SANE_INFO_RELOAD_OPTIONS;
					/* fall through */
				case OPT_RESOLUTION:
				case OPT_TL_X:
				case OPT_TL_Y:
				case OPT_BR_X:
				case OPT_BR_Y:
					if( infoP )
						*infoP |= SANE_INFO_RELOAD_PARAMS;
					/* fall through */
				case OPT_THRESHOLD:
					dev->val[optnum] = *(SANE_Word *)valP;
					break;
				default:
					return SANE_STATUS_INVAL;
			}
			break;

		case SANE_ACTION_SET_AUTO:

			DBG(DOPT, "automatic option setting\n");

			return SANE_STATUS_UNSUPPORTED;

		default:
			return SANE_STATUS_INVAL;
	}
	return SANE_STATUS_GOOD;
}
예제 #11
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  Abaton_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;


  if (option < 0 || option >= NUM_OPTIONS)
    return SANE_STATUS_INVAL;

  if (info != NULL)
    *info = 0;

  if (s->scanning)
    return SANE_STATUS_DEVICE_BUSY;

  cap = s->opt[option].cap;

  if (!SANE_OPTION_IS_ACTIVE (cap))
    return SANE_STATUS_INVAL;

  if (action == SANE_ACTION_GET_VALUE)
    {
      switch (option)
	{
	  /* word options: */
	case OPT_NUM_OPTS:
	case OPT_X_RESOLUTION:
	case OPT_Y_RESOLUTION:
	case OPT_RESOLUTION_BIND:
	case OPT_PREVIEW:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	case OPT_BRIGHTNESS:
	case OPT_CONTRAST:
	case OPT_THRESHOLD:
	case OPT_NEGATIVE:
	case OPT_MIRROR:
	  *(SANE_Word *) val = s->val[option].w;
	  return SANE_STATUS_GOOD;

	  /* string options */

	case OPT_MODE:
	case OPT_HALFTONE_PATTERN:
	  status = sanei_constrain_value (s->opt + option, s->val[option].s,
					  info);
	  strcpy (val, s->val[option].s);	  
	  return SANE_STATUS_GOOD;
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
	return SANE_STATUS_INVAL;

      status = sanei_constrain_value (s->opt + option, val, info);

      if (status != SANE_STATUS_GOOD)
	return status;


      switch (option)
	{
	  /* resolution should be uniform for previews, or when the
	     user says so. */
	case OPT_PREVIEW:
	  s->val[option].w = *(SANE_Word *) val;
	  if (*(SANE_Word *) val) {
	    s->val[OPT_Y_RESOLUTION].w = s->val[OPT_X_RESOLUTION].w;
	    if (info)
	      *info |= SANE_INFO_RELOAD_OPTIONS;
	  }
	  /* always recalculate! */
	  calc_parameters (s);
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;
	    
	case OPT_RESOLUTION_BIND:
	  s->val[option].w = *(SANE_Word *) val;
	  if (*(SANE_Word *) val) {
	    s->val[OPT_Y_RESOLUTION].w = s->val[OPT_X_RESOLUTION].w;
	    calc_parameters (s);
	    if (info)
	      *info |= SANE_INFO_RELOAD_PARAMS |
		SANE_INFO_RELOAD_OPTIONS;
	  }
	  return SANE_STATUS_GOOD;
	  
	case OPT_X_RESOLUTION:
	  if (s->val[OPT_PREVIEW].w || s->val[OPT_RESOLUTION_BIND].w) {
	    s->val[OPT_Y_RESOLUTION].w = *(SANE_Word *)val;
	    if (info)
	      *info |= SANE_INFO_RELOAD_OPTIONS;
	  }
	  s->val[option].w = *(SANE_Word *) val;
	  calc_parameters (s);
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	case OPT_Y_RESOLUTION:
	  if (s->val[OPT_PREVIEW].w || s->val[OPT_RESOLUTION_BIND].w) {
	    s->val[OPT_X_RESOLUTION].w = *(SANE_Word *)val;
	    if (info)
	      *info |= SANE_INFO_RELOAD_OPTIONS;
	  }
	  s->val[option].w = *(SANE_Word *) val;
	  calc_parameters (s);
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	  /* these ones don't have crazy side effects */
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_Y:
	  s->val[option].w = *(SANE_Word *) val;
	  calc_parameters (s);
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;

	  /* this one is somewhat imprecise */
	case OPT_BR_X:
	  s->val[option].w = *(SANE_Word *) val;
	  calc_parameters (s);
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS
	      | SANE_INFO_INEXACT;	  
	  return SANE_STATUS_GOOD;

	  /* no side-effects whatsoever */
	case OPT_BRIGHTNESS:
	case OPT_CONTRAST:
	case OPT_THRESHOLD:
	case OPT_NEGATIVE:
	case OPT_MIRROR:

	  s->val[option].w = *(SANE_Word *) val;
	  return SANE_STATUS_GOOD;

	  /* string options */
	case OPT_HALFTONE_PATTERN:
	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS;
	  if (s->val[option].s)
	    free (s->val[option].s);
	  s->val[option].s = strdup (val);
	  return SANE_STATUS_GOOD;
	  
	case OPT_MODE:
	  status = mode_update (s, val);
	  if (status != SANE_STATUS_GOOD)
	    return status;
	  if (s->val[option].s)
	    free (s->val[option].s);
	  s->val[option].s = strdup (val);

	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  return SANE_STATUS_GOOD;
	}			/* End of switch */
    }				/* End of SET_VALUE */
  return SANE_STATUS_INVAL;
}
예제 #12
0
/*--------------------------------------------------------------------------*/
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  AS6E_Scan *s = handle;
  SANE_Status status = 0;
  SANE_Word cap;
  DBG (2, "sane_control_option\n");
  if (info)
    *info = 0;
  if (s->scanning)
    return SANE_STATUS_DEVICE_BUSY;
  if (option >= NUM_OPTIONS)
    return SANE_STATUS_INVAL;
  cap = s->options_list[option].cap;
  if (!SANE_OPTION_IS_ACTIVE (cap))
    return SANE_STATUS_INVAL;
  if (action == SANE_ACTION_GET_VALUE)
    {
      DBG (1, "sane_control_option %d, get value\n", option);
      switch (option)
	{
	  /* word options: */
	case OPT_RESOLUTION:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	case OPT_NUM_OPTS:
	case OPT_CONTRAST:
	case OPT_BRIGHTNESS:
	  *(SANE_Word *) val = s->value[option].w;
	  return (SANE_STATUS_GOOD);
	  /* string options: */
	case OPT_MODE:
	  strcpy (val, s->value[option].s);
	  return (SANE_STATUS_GOOD);
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      DBG (1, "sane_control_option %d, set value\n", option);
      if (!SANE_OPTION_IS_SETTABLE (cap))
	return (SANE_STATUS_INVAL);
/*      status = sanei_constrain_value (s->options_list[option], val, info);*/
      if (status != SANE_STATUS_GOOD)
	return (status);
      switch (option)
	{
	  /* (mostly) side-effect-free word options: */
	case OPT_RESOLUTION:
	case OPT_BR_X:
	case OPT_BR_Y:
	case OPT_TL_X:
	case OPT_TL_Y:
	  if (info && s->value[option].w != *(SANE_Word *) val)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  /* fall through */
	case OPT_NUM_OPTS:
	case OPT_CONTRAST:
	case OPT_BRIGHTNESS:
	  s->value[option].w = *(SANE_Word *) val;
	  DBG (1, "set brightness to\n");
	  return (SANE_STATUS_GOOD);
	case OPT_MODE:
	  if (s->value[option].s)
	    free (s->value[option].s);
	  s->value[option].s = strdup (val);
	  return (SANE_STATUS_GOOD);
	}
    }
  return (SANE_STATUS_INVAL);
}
예제 #13
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  V4L_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;

  if (info)
    *info = 0;

  if (option >= NUM_OPTIONS || option < 0)
    return SANE_STATUS_INVAL;

  DBG (4, "sane_control_option: %s option %d (%s)\n",
       action == SANE_ACTION_GET_VALUE ? "get" :
       action == SANE_ACTION_SET_VALUE ? "set" :
       action == SANE_ACTION_SET_AUTO ? "auto set" :
       "(unknow action with)", option,
       s->opt[option].name ? s->opt[option].name : s->opt[option].title);

  cap = s->opt[option].cap;

  if (!SANE_OPTION_IS_ACTIVE (cap))
    {
      DBG (1, "sane_control option: option is inactive\n");
      return SANE_STATUS_INVAL;
    }

  if (action == SANE_ACTION_GET_VALUE)
    {
      switch (option)
	{
	  /* word options: */
	case OPT_NUM_OPTS:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	case OPT_BRIGHTNESS:
	case OPT_HUE:
	case OPT_COLOR:
	case OPT_CONTRAST:
	case OPT_WHITE_LEVEL:
	  *(SANE_Word *) val = s->val[option].w;
	  return SANE_STATUS_GOOD;
	case OPT_CHANNEL:	/* string list options */
	case OPT_MODE:
	  strcpy (val, s->val[option].s);
	  return SANE_STATUS_GOOD;
	default:
	  DBG (1, "sane_control_option: option %d unknown\n", option);
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
	{
	  DBG (1, "sane_control_option: option is not settable\n");
	  return SANE_STATUS_INVAL;
	}
      status = sanei_constrain_value (s->opt + option, val, info);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (1, "sane_control_option: sanei_constarin_value failed: %s\n",
	       sane_strstatus (status));
	  return status;
	}
      if (option >= OPT_TL_X && option <= OPT_BR_Y)
	{
	  s->user_corner |= 1 << (option - OPT_TL_X);
	  if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window))
	    {
	      DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed "
		   "(can not get window geometry)\n");
	      return SANE_STATUS_INVAL;
	    }
	  s->window.clipcount = 0;
	  s->window.clips = 0;
	  s->window.height = parms.lines;
	  s->window.width = parms.pixels_per_line;
	}


      switch (option)
	{
	  /* (mostly) side-effect-free word options: */
	case OPT_TL_X:
	  break;
	case OPT_TL_Y:
	  break;
	case OPT_BR_X:
	  s->window.width = *(SANE_Word *) val;
	  parms.pixels_per_line = *(SANE_Word *) val;
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  break;
	case OPT_BR_Y:
	  s->window.height = *(SANE_Word *) val;
	  parms.lines = *(SANE_Word *) val;
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS;
	  break;
	case OPT_MODE:
	  if (info)
	    *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
	  s->val[option].s = strdup (val);
	  if (!s->val[option].s)
	    return SANE_STATUS_NO_MEM;
	  if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
	    s->pict.palette = VIDEO_PALETTE_GREY;
	  else
	    s->pict.palette = VIDEO_PALETTE_RGB24;
	  update_parameters (s);
	  break;
	case OPT_BRIGHTNESS:
	  s->pict.brightness = *(SANE_Word *) val *256;
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	case OPT_HUE:
	  s->pict.hue = *(SANE_Word *) val *256;
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	case OPT_COLOR:
	  s->pict.colour = *(SANE_Word *) val *256;
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	case OPT_CONTRAST:
	  s->pict.contrast = *(SANE_Word *) val *256;
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	case OPT_WHITE_LEVEL:
	  s->pict.whiteness = *(SANE_Word *) val *256;
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	case OPT_CHANNEL:
	  {
	    int i;
	    struct video_channel channel;

	    s->val[option].s = strdup (val);
	    if (!s->val[option].s)
	      return SANE_STATUS_NO_MEM;
	    for (i = 0; i < MAX_CHANNELS; i++)
	      {
		if (strcmp (s->channel[i], val) == 0)
		  {
		    channel.channel = i;
		    if (-1 == v4l1_ioctl (s->fd, VIDIOCGCHAN, &channel))
		      {
			DBG (1, "sane_open: can't ioctl VIDIOCGCHAN %s: %s\n",
			     s->devicename, strerror (errno));
			return SANE_STATUS_INVAL;
		      }
		    if (-1 == v4l1_ioctl (s->fd, VIDIOCSCHAN, &channel))
		      {
			DBG (1, "sane_open: can't ioctl VIDIOCSCHAN %s: %s\n",
			     s->devicename, strerror (errno));
			return SANE_STATUS_INVAL;
		      }
		    break;
		  }
	      }
	    return SANE_STATUS_GOOD;
	    break;
	  }
	default:
	  DBG (1, "sane_control_option: option %d unknown\n", option);
	  return SANE_STATUS_INVAL;
	}
      if (option >= OPT_TL_X && option <= OPT_BR_Y)
	{
	  if (-1 == v4l1_ioctl (s->fd, VIDIOCSWIN, &s->window))
	    {
	      DBG (1, "sane_control_option: ioctl VIDIOCSWIN failed (%s)\n",
		   strerror (errno));
	      /* return SANE_STATUS_INVAL; */
	    }
	  if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window))
	    {
	      DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed (%s)\n",
		   strerror (errno));
	      return SANE_STATUS_INVAL;
	    }
	}
      if (option >= OPT_BRIGHTNESS && option <= OPT_WHITE_LEVEL)
	{
	  if (-1 == v4l1_ioctl (s->fd, VIDIOCSPICT, &s->pict))
	    {
	      DBG (1, "sane_control_option: ioctl VIDIOCSPICT failed (%s)\n",
		   strerror (errno));
	      /* return SANE_STATUS_INVAL; */
	    }
	}
      return SANE_STATUS_GOOD;
    }
  else if (action == SANE_ACTION_SET_AUTO)
    {
      if (!(cap & SANE_CAP_AUTOMATIC))
	{
	  DBG (1, "sane_control_option: option can't be set automatically\n");
	  return SANE_STATUS_INVAL;
	}
      switch (option)
	{
	case OPT_BRIGHTNESS:
	  /* not implemented yet */
	  return SANE_STATUS_GOOD;

	default:
	  break;
	}
    }
  return SANE_STATUS_INVAL;
}