SANE_Status sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) { Abaton_Scanner *s = handle; DBG (FLOW_CONTROL, "Entering sane_get_parameters\n"); calc_parameters (s); if (params) *params = s->params; return SANE_STATUS_GOOD; }
SANE_Status sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) { Mustek_Usb_Scanner *s = handle; SANE_Status status; DBG (5, "sane_get_parameters: start\n"); RIE (calc_parameters (s)); if (params) *params = s->params; DBG (5, "sane_get_parameters: exit\n"); return SANE_STATUS_GOOD; }
static SANE_Status mode_update (SANE_Handle handle, char *val) { Abaton_Scanner *s = handle; if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART)) { DISABLE (OPT_BRIGHTNESS); DISABLE (OPT_CONTRAST); ENABLE (OPT_THRESHOLD); DISABLE (OPT_HALFTONE_PATTERN); } else if (!strcmp (val, SANE_VALUE_SCAN_MODE_HALFTONE)) { ENABLE (OPT_BRIGHTNESS); ENABLE (OPT_CONTRAST); DISABLE (OPT_THRESHOLD); ENABLE (OPT_HALFTONE_PATTERN); } else if (!strcmp (val, "Gray16") || !strcmp (val, "Gray256")) { ENABLE (OPT_BRIGHTNESS); ENABLE (OPT_CONTRAST); DISABLE (OPT_THRESHOLD); DISABLE (OPT_HALFTONE_PATTERN); } /* End of Gray */ else { DBG (ERROR_MESSAGE, "Invalid mode %s\n", (char *) val); return SANE_STATUS_INVAL; } calc_parameters (s); return SANE_STATUS_GOOD; }
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; }
SANE_Status sane_start (SANE_Handle handle) { Mustek_Usb_Scanner *s = handle; SANE_Status status; SANE_String val; Colormode color_mode; SANE_Word dpi, x, y, width, height; DBG (5, "sane_start: start\n"); /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ s->total_bytes = 0; s->total_lines = 0; RIE (calc_parameters (s)); if (s->width_dots <= 0) { DBG (0, "sane_start: top left x > bottom right x --- exiting\n"); return SANE_STATUS_INVAL; } if (s->height_dots <= 0) { DBG (0, "sane_start: top left y > bottom right y --- exiting\n"); return SANE_STATUS_INVAL; } val = s->val[OPT_MODE].s; if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART)) color_mode = GRAY8; else if (!strcmp (val, SANE_VALUE_SCAN_MODE_GRAY)) color_mode = GRAY8; else /* Color */ color_mode = RGB24; dpi = SANE_UNFIX (s->val[OPT_RESOLUTION].w); x = s->tl_x_dots; y = s->tl_y_dots; width = s->width_dots; height = s->height_dots; if (!s->hw->is_prepared) { RIE (usb_high_scan_prepare (s->hw)); RIE (usb_high_scan_reset (s->hw)); } RIE (usb_high_scan_set_threshold (s->hw, 128)); RIE (usb_high_scan_embed_gamma (s->hw, NULL)); RIE (usb_high_scan_suggest_parameters (s->hw, dpi, x, y, width, height, color_mode)); RIE (usb_high_scan_setup_scan (s->hw, s->hw->scan_mode, s->hw->x_dpi, s->hw->y_dpi, 0, s->hw->x, s->hw->y, s->hw->width)); DBG (3, "sane_start: wanted: dpi=%d, x=%d, y=%d, width=%d, height=%d, " "scan_mode=%d\n", dpi, x, y, width, height, color_mode); DBG (3, "sane_start: got: x_dpi=%d, y_dpi=%d, x=%d, y=%d, width=%d, " "height=%d, scan_mode=%d\n", s->hw->x_dpi, s->hw->y_dpi, s->hw->x, s->hw->y, s->hw->width, s->hw->height, s->hw->scan_mode); s->scanning = SANE_TRUE; s->read_rows = s->hw->height; s->hw->line_switch = s->hw->height; s->hw->line_offset = 0; s->hw->scan_buffer_len = 0; DBG (5, "sane_start: exit\n"); return SANE_STATUS_GOOD; }
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; }
SANE_Status sane_start (SANE_Handle handle) { Abaton_Scanner *s = handle; SANE_Status status; /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ calc_parameters (s); if (s->fd < 0) { /* this is the first (and maybe only) pass... */ status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "open: open of %s failed: %s\n", s->hw->sane.name, sane_strstatus (status)); return status; } } status = wait_ready (s->fd); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "open: wait_ready() failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = request_sense (s); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "sane_start: request_sense revealed error: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = set_window (s); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "open: set scan area command failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } s->scanning = SANE_TRUE; s->AbortedByUser = SANE_FALSE; status = start_scan (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; return SANE_STATUS_GOOD; stop_scanner_and_return: s->scanning = SANE_FALSE; s->AbortedByUser = SANE_FALSE; return status; }
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; }