From ba164358dba830e3fa664ecd8f9fdadbc1feb384 Mon Sep 17 00:00:00 2001 From: Pierre Willenbrock Date: Fri, 16 Jan 2009 15:31:10 +0000 Subject: [PATCH] Add support for buttons on Canon LiDE 35/40/50. --- ChangeLog | 6 +++ backend/genesys.c | 82 +++++++++++++++++++++++++++++++++++++-- backend/genesys.h | 10 +++++ backend/genesys_devices.c | 11 +++++- backend/genesys_gl646.c | 15 ++++++- backend/genesys_gl841.c | 29 +++++++++++++- backend/genesys_low.h | 18 ++++++++- 7 files changed, 163 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9c36c4fc..0a3ef2133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-01-16 Pierre Willenbrock + * backend/genesys.c, backend/genesys.h, backend/genesys_devices.c, + backend/genesys_gl646.c, backend/genesys_gl841.c, + backend/genesys_low.h: Add support for buttons on + Canon LiDE 35/40/50. + 2009-01-15 Nicolas Martin * doc/sane-pixma.man, doc/descriptions/pixma.desc, pixma_mp150.c, AUTHORS: diff --git a/backend/genesys.c b/backend/genesys.c index 9e5d64cd0..38f016993 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -3,7 +3,7 @@ Copyright (C) 2003, 2004 Henning Meier-Geinitz Copyright (C) 2004, 2005 Gerhard Jaeger Copyright (C) 2004, 2008 Stéphane Voltz - Copyright (C) 2005, 2006 Pierre Willenbrock + Copyright (C) 2005-2009 Pierre Willenbrock Copyright (C) 2006 Laurent Charpentier Copyright (C) 2007 Luke @@ -4834,7 +4834,7 @@ init_options (Genesys_Scanner * s) /* currently, there are only gamma table options in this group, * so if the scanner doesn't support gamma table, disable the * whole group */ - if (!(s->dev->model->flags & GENESYS_FLAG_CUSTOM_GAMMA)) + if (!(model->flags & GENESYS_FLAG_CUSTOM_GAMMA)) { s->opt[OPT_ENHANCEMENT_GROUP].cap |= SANE_CAP_INACTIVE; s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE; @@ -4898,6 +4898,73 @@ init_options (Genesys_Scanner * s) s->opt[OPT_LAMP_OFF_TIME].constraint.range = &time_range; s->val[OPT_LAMP_OFF_TIME].w = 15; /* 15 minutes */ + s->opt[OPT_SENSOR_GROUP].name = SANE_NAME_SENSORS; + s->opt[OPT_SENSOR_GROUP].title = SANE_TITLE_SENSORS; + s->opt[OPT_SENSOR_GROUP].desc = SANE_DESC_SENSORS; + s->opt[OPT_SENSOR_GROUP].type = SANE_TYPE_GROUP; + s->opt[OPT_SENSOR_GROUP].constraint_type = SANE_CONSTRAINT_NONE; + + s->opt[OPT_SCAN_SW].name = SANE_NAME_SCAN; + s->opt[OPT_SCAN_SW].title = SANE_TITLE_SCAN; + s->opt[OPT_SCAN_SW].desc = SANE_DESC_SCAN; + s->opt[OPT_SCAN_SW].type = SANE_TYPE_BOOL; + s->opt[OPT_SCAN_SW].unit = SANE_UNIT_NONE; + if (model->flags & GENESYS_FLAG_SCAN_SW) + s->opt[OPT_SCAN_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + else + s->opt[OPT_SCAN_SW].cap = SANE_CAP_INACTIVE; + s->val[OPT_SCAN_SW].b = 0; + s->last_val[OPT_SCAN_SW].b = 0; + + /* SANE_NAME_FILE is not for buttons */ + s->opt[OPT_FILE_SW].name = "file"; + s->opt[OPT_FILE_SW].title = "File button"; + s->opt[OPT_FILE_SW].desc = "File button"; + s->opt[OPT_FILE_SW].type = SANE_TYPE_BOOL; + s->opt[OPT_FILE_SW].unit = SANE_UNIT_NONE; + if (model->flags & GENESYS_FLAG_FILE_SW) + s->opt[OPT_FILE_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + else + s->opt[OPT_FILE_SW].cap = SANE_CAP_INACTIVE; + s->val[OPT_FILE_SW].b = 0; + s->last_val[OPT_FILE_SW].b = 0; + + s->opt[OPT_EMAIL_SW].name = SANE_NAME_EMAIL; + s->opt[OPT_EMAIL_SW].title = SANE_TITLE_EMAIL; + s->opt[OPT_EMAIL_SW].desc = SANE_DESC_EMAIL; + s->opt[OPT_EMAIL_SW].type = SANE_TYPE_BOOL; + s->opt[OPT_EMAIL_SW].unit = SANE_UNIT_NONE; + if (model->flags & GENESYS_FLAG_EMAIL_SW) + s->opt[OPT_EMAIL_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + else + s->opt[OPT_EMAIL_SW].cap = SANE_CAP_INACTIVE; + s->val[OPT_EMAIL_SW].b = 0; + s->last_val[OPT_EMAIL_SW].b = 0; + + s->opt[OPT_COPY_SW].name = SANE_NAME_COPY; + s->opt[OPT_COPY_SW].title = SANE_TITLE_COPY; + s->opt[OPT_COPY_SW].desc = SANE_DESC_COPY; + s->opt[OPT_COPY_SW].type = SANE_TYPE_BOOL; + s->opt[OPT_COPY_SW].unit = SANE_UNIT_NONE; + if (model->flags & GENESYS_FLAG_COPY_SW) + s->opt[OPT_COPY_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + else + s->opt[OPT_COPY_SW].cap = SANE_CAP_INACTIVE; + s->val[OPT_COPY_SW].b = 0; + s->last_val[OPT_COPY_SW].b = 0; + + s->opt[OPT_PAGE_LOADED_SW].name = SANE_NAME_PAGE_LOADED; + s->opt[OPT_PAGE_LOADED_SW].title = SANE_TITLE_PAGE_LOADED; + s->opt[OPT_PAGE_LOADED_SW].desc = SANE_DESC_PAGE_LOADED; + s->opt[OPT_PAGE_LOADED_SW].type = SANE_TYPE_BOOL; + s->opt[OPT_PAGE_LOADED_SW].unit = SANE_UNIT_NONE; + if (model->flags & GENESYS_FLAG_PAGE_LOADED_SW) + s->opt[OPT_PAGE_LOADED_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + else + s->opt[OPT_PAGE_LOADED_SW].cap = SANE_CAP_INACTIVE; + s->val[OPT_PAGE_LOADED_SW].b = 0; + s->last_val[OPT_PAGE_LOADED_SW].b = 0; + RIE (calc_parameters (s)); DBG (DBG_proc, "init_options: exit\n"); @@ -5357,6 +5424,7 @@ get_option_value (Genesys_Scanner * s, int option, void *val) unsigned int i; SANE_Word *table; u_int16_t *gamma; + SANE_Status status = SANE_STATUS_GOOD; switch (option) { @@ -5422,11 +5490,19 @@ get_option_value (Genesys_Scanner * s, int option, void *val) table[i] = s->dev->sensor.blue_gamma_table[i]; } break; + /* buttons */ + case OPT_SCAN_SW: + case OPT_FILE_SW: + case OPT_EMAIL_SW: + case OPT_COPY_SW: + RIE(s->dev->model->cmd_set->update_hardware_sensors(s,option)); + s->last_val[option].b = *(SANE_Bool *) val = s->val[option].b; + break; default: DBG (DBG_warn, "get_option_value: can't get unknown option %d\n", option); } - return SANE_STATUS_GOOD; + return status; } /* sets an option , called by sane_control_option */ diff --git a/backend/genesys.h b/backend/genesys.h index 01e178e86..d93c13049 100644 --- a/backend/genesys.h +++ b/backend/genesys.h @@ -3,6 +3,7 @@ Copyright (C) 2003, 2004 Henning Meier-Geinitz Copyright (C) 2005 Stephane Voltz Copyright (C) 2006 Laurent Charpentier + Copyright (C) 2009 Pierre Willenbrock This file is part of the SANE package. @@ -94,6 +95,14 @@ enum Genesys_Option OPT_THRESHOLD, OPT_DISABLE_INTERPOLATION, OPT_COLOR_FILTER, + + OPT_SENSOR_GROUP, + OPT_SCAN_SW, + OPT_FILE_SW, + OPT_EMAIL_SW, + OPT_COPY_SW, + OPT_PAGE_LOADED_SW, + /* must come last: */ NUM_OPTIONS }; @@ -110,6 +119,7 @@ typedef struct Genesys_Scanner SANE_Bool scanning; /**< We are currently scanning */ SANE_Option_Descriptor opt[NUM_OPTIONS]; /**< Option descriptors */ Option_Value val[NUM_OPTIONS]; /**< Option values */ + Option_Value last_val[NUM_OPTIONS]; /**< Option values as read by the frontend. used for sensors. */ SANE_Parameters params; /**< SANE Parameters */ SANE_Int bpp_list[5]; /**< */ } Genesys_Scanner; diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index 4593402ef..b50d414d8 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -4,7 +4,7 @@ Copyright (C) 2003-2005 Henning Meier-Geinitz Copyright (C) 2004, 2005 Gerhard Jaeger Copyright (C) 2004-2007 Stephane Voltz - Copyright (C) 2005 Pierre Willenbrock + Copyright (C) 2005-2009 Pierre Willenbrock Copyright (C) 2007 Luke This file is part of the SANE package. @@ -475,7 +475,14 @@ static Genesys_Model canon_lide_50_model = { DAC_CANONLIDE35, GPO_CANONLIDE35, MOTOR_CANONLIDE35, - GENESYS_FLAG_LAZY_INIT | GENESYS_FLAG_SKIP_WARMUP | GENESYS_FLAG_OFFSET_CALIBRATION | GENESYS_FLAG_DARK_WHITE_CALIBRATION, /* Which flags are needed for this scanner? */ + GENESYS_FLAG_LAZY_INIT | /* Which flags are needed for this scanner? */ + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_WHITE_CALIBRATION | + GENESYS_FLAG_SCAN_SW | + GENESYS_FLAG_FILE_SW | + GENESYS_FLAG_EMAIL_SW | + GENESYS_FLAG_COPY_SW, 280, 400 }; diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index b29672f9c..67a2aa53a 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -4,7 +4,7 @@ Copyright (C) 2003, 2004 Henning Meier-Geinitz Copyright (C) 2004 Gerhard Jaeger Copyright (C) 2004 - 2008 Stéphane Voltz - Copyright (C) 2005, 2006 Pierre Willenbrock + Copyright (C) 2005 - 2009 Pierre Willenbrock Copyright (C) 2007 Luke This file is part of the SANE package. @@ -4529,6 +4529,17 @@ gl646_init (Genesys_Device * dev) return SANE_STATUS_GOOD; } +static SANE_Status +gl646_update_hardware_sensors (Genesys_Scanner * s, SANE_Int option) +{ + /* do what is needed to get a new set of events, but try to not lose + any of them. + */ + SANE_Status status = SANE_STATUS_GOOD; + + return status; +} + /** the gl646 command set */ static Genesys_Command_Set gl646_cmd_set = { "gl646-generic", /* the name of this set */ @@ -4572,6 +4583,8 @@ static Genesys_Command_Set gl646_cmd_set = { gl646_bulk_write_register, gl646_bulk_write_data, gl646_bulk_read_data, + + gl646_update_hardware_sensors, }; SANE_Status diff --git a/backend/genesys_gl841.c b/backend/genesys_gl841.c index eddf92701..5d81f35bd 100644 --- a/backend/genesys_gl841.c +++ b/backend/genesys_gl841.c @@ -5,7 +5,7 @@ Copyright (C) 2004 Gerhard Jaeger Copyright (C) 2004, 2005 Stephane Voltz Copyright (C) 2005 Philipp Schmid - Copyright (C) 2005, 2006 Pierre Willenbrock + Copyright (C) 2005 - 2009 Pierre Willenbrock Copyright (C) 2006 Laurent Charpentier @@ -5270,6 +5270,31 @@ gl841_init (Genesys_Device * dev) return SANE_STATUS_GOOD; } +static SANE_Status +gl841_update_hardware_sensors (Genesys_Scanner * s, SANE_Int option) +{ + /* do what is needed to get a new set of events, but try to not lose + any of them. + */ + SANE_Status status = SANE_STATUS_GOOD; + u_int8_t val; + + if (s->dev->model->gpo_type == GPO_CANONLIDE35) + { + RIE(sanei_genesys_read_register(s->dev, 0x6d, &val)); + + if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b) + s->val[OPT_SCAN_SW].b = (val & 0x01) == 0; + if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b) + s->val[OPT_FILE_SW].b = (val & 0x02) == 0; + if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b) + s->val[OPT_EMAIL_SW].b = (val & 0x04) == 0; + if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b) + s->val[OPT_COPY_SW].b = (val & 0x08) == 0; + } + + return status; +} /** the gl841 command set */ static Genesys_Command_Set gl841_cmd_set = { @@ -5315,6 +5340,8 @@ static Genesys_Command_Set gl841_cmd_set = { gl841_bulk_write_register, gl841_bulk_write_data, gl841_bulk_read_data, + + gl841_update_hardware_sensors, }; SANE_Status diff --git a/backend/genesys_low.h b/backend/genesys_low.h index 8ce295e88..1c72e4f5d 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -4,7 +4,7 @@ Copyright (C) 2003, 2004 Henning Meier-Geinitz Copyright (C) 2004, 2005 Gerhard Jaeger Copyright (C) 2004, 2005 Stephane Voltz - Copyright (C) 2005 Pierre Willenbrock + Copyright (C) 2005 - 2009 Pierre Willenbrock Copyright (C) 2006 Laurent Charpentier Parts of the structs have been taken from the gt68xx backend by Sergey Vlasov et al. @@ -97,6 +97,12 @@ #define GENESYS_FLAG_DARK_WHITE_CALIBRATION (1 << 12) /*yet another calibration method. does white and dark shading in one run, depending on a black and a white strip*/ #define GENESYS_FLAG_CUSTOM_GAMMA (1 << 13) /* allow custom gamma tables */ +#define GENESYS_FLAG_SCAN_SW (1 << 14) /* scanner has SCAN button */ +#define GENESYS_FLAG_FILE_SW (1 << 15) /* scanner has FILE button */ +#define GENESYS_FLAG_COPY_SW (1 << 16) /* scanner has COPY button */ +#define GENESYS_FLAG_EMAIL_SW (1 << 17) /* scanner has EMAIL button */ +#define GENESYS_FLAG_PAGE_LOADED_SW (1 << 18) /* scanner has paper in detection */ + /* USB control message values */ #define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN) #define REQUEST_TYPE_OUT (USB_TYPE_VENDOR | USB_DIR_OUT) @@ -326,6 +332,7 @@ typedef struct Genesys_Command_Set SANE_Status (*park_head) (Genesys_Device * dev, Genesys_Register_Set * reg, SANE_Bool wait_until_home); + SANE_Status (*bulk_write_register) (Genesys_Device * dev, Genesys_Register_Set * reg, size_t elems); @@ -335,6 +342,15 @@ typedef struct Genesys_Command_Set SANE_Status (*bulk_read_data) (Genesys_Device * dev, u_int8_t addr, u_int8_t * data, size_t len); + /* Updates hardware sensor information in Genesys_Scanner.val[]. + If possible, just get information for given option. + The sensor state in Genesys_Scanner.val[] should be merged with the + new sensor state, using the information that was last read by the frontend + in Genesys_Scanner.last_val[], in such a way that a button up/down + relative to Genesys_Scanner.last_val[] is not lost. + */ + SANE_Status (*update_hardware_sensors) (Genesys_Device * dev, + SANE_Int option); } Genesys_Command_Set; typedef struct Genesys_Model