1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci This file is part of the SANE package. 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 6141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 7141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 8141cc406Sopenharmony_ci License, or (at your option) any later version. 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 11141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13141cc406Sopenharmony_ci General Public License for more details. 14141cc406Sopenharmony_ci 15141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 16141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 19141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 22141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 23141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 24141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 25141cc406Sopenharmony_ci account of linking the SANE library code into it. 26141cc406Sopenharmony_ci 27141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 28141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 29141cc406Sopenharmony_ci License. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 32141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 33141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 36141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 37141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 38141cc406Sopenharmony_ci*/ 39141cc406Sopenharmony_ci 40141cc406Sopenharmony_ci/* 41141cc406Sopenharmony_ci This file implements a SANE backend for the Ibm 2456 flatbed scanner, 42141cc406Sopenharmony_ci written by mf <massifr@tiscalinet.it>. It derives from the backend for 43141cc406Sopenharmony_ci Ricoh flatbed scanners written by Feico W. Dillema. 44141cc406Sopenharmony_ci 45141cc406Sopenharmony_ci Currently maintained by Henning Meier-Geinitz <henning@meier-geinitz.de>. 46141cc406Sopenharmony_ci*/ 47141cc406Sopenharmony_ci 48141cc406Sopenharmony_ci#define BUILD 5 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci#include "../include/sane/config.h" 51141cc406Sopenharmony_ci 52141cc406Sopenharmony_ci#include <limits.h> 53141cc406Sopenharmony_ci#include <stdlib.h> 54141cc406Sopenharmony_ci#include <stdarg.h> 55141cc406Sopenharmony_ci#include <string.h> 56141cc406Sopenharmony_ci#include <sys/time.h> 57141cc406Sopenharmony_ci#include <unistd.h> 58141cc406Sopenharmony_ci#include <ctype.h> 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_ci#include "../include/sane/sane.h" 61141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 62141cc406Sopenharmony_ci#include "../include/sane/sanei_scsi.h" 63141cc406Sopenharmony_ci 64141cc406Sopenharmony_ci#define BACKEND_NAME ibm 65141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci#ifndef PATH_MAX 68141cc406Sopenharmony_ci# define PATH_MAX 1024 69141cc406Sopenharmony_ci#endif 70141cc406Sopenharmony_ci 71141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 72141cc406Sopenharmony_ci#define IBM_CONFIG_FILE "ibm.conf" 73141cc406Sopenharmony_ci 74141cc406Sopenharmony_ci#include "ibm.h" 75141cc406Sopenharmony_ci#include "ibm-scsi.c" 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_ci#define MAX(a,b) ((a) > (b) ? (a) : (b)) 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_cistatic int num_devices = 0; 80141cc406Sopenharmony_cistatic Ibm_Device *first_dev = NULL; 81141cc406Sopenharmony_cistatic Ibm_Scanner *first_handle = NULL; 82141cc406Sopenharmony_ci/* static int is50 = 0; */ 83141cc406Sopenharmony_ci 84141cc406Sopenharmony_ci 85141cc406Sopenharmony_cistatic size_t 86141cc406Sopenharmony_cimax_string_size (const SANE_String_Const strings[]) 87141cc406Sopenharmony_ci{ 88141cc406Sopenharmony_ci size_t size, max_size = 0; 89141cc406Sopenharmony_ci int i; 90141cc406Sopenharmony_ci DBG (11, ">> max_string_size\n"); 91141cc406Sopenharmony_ci 92141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 93141cc406Sopenharmony_ci { 94141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 95141cc406Sopenharmony_ci if (size > max_size) 96141cc406Sopenharmony_ci max_size = size; 97141cc406Sopenharmony_ci } 98141cc406Sopenharmony_ci 99141cc406Sopenharmony_ci DBG (11, "<< max_string_size\n"); 100141cc406Sopenharmony_ci return max_size; 101141cc406Sopenharmony_ci} 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_cistatic SANE_Status 104141cc406Sopenharmony_ciattach (const char *devnam, Ibm_Device ** devp) 105141cc406Sopenharmony_ci{ 106141cc406Sopenharmony_ci SANE_Status status; 107141cc406Sopenharmony_ci Ibm_Device *dev; 108141cc406Sopenharmony_ci 109141cc406Sopenharmony_ci int fd; 110141cc406Sopenharmony_ci struct inquiry_data ibuf; 111141cc406Sopenharmony_ci struct measurements_units_page mup; 112141cc406Sopenharmony_ci struct ibm_window_data wbuf; 113141cc406Sopenharmony_ci size_t buf_size; 114141cc406Sopenharmony_ci char *str; 115141cc406Sopenharmony_ci DBG (11, ">> attach\n"); 116141cc406Sopenharmony_ci 117141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 118141cc406Sopenharmony_ci { 119141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devnam) == 0) 120141cc406Sopenharmony_ci { 121141cc406Sopenharmony_ci if (devp) 122141cc406Sopenharmony_ci *devp = dev; 123141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 124141cc406Sopenharmony_ci } 125141cc406Sopenharmony_ci } 126141cc406Sopenharmony_ci 127141cc406Sopenharmony_ci DBG (3, "attach: opening %s\n", devnam); 128141cc406Sopenharmony_ci status = sanei_scsi_open (devnam, &fd, NULL, NULL); 129141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 130141cc406Sopenharmony_ci { 131141cc406Sopenharmony_ci DBG (1, "attach: open failed: %s\n", sane_strstatus (status)); 132141cc406Sopenharmony_ci return (status); 133141cc406Sopenharmony_ci } 134141cc406Sopenharmony_ci 135141cc406Sopenharmony_ci DBG (3, "attach: sending INQUIRY\n"); 136141cc406Sopenharmony_ci memset (&ibuf, 0, sizeof (ibuf)); 137141cc406Sopenharmony_ci buf_size = sizeof(ibuf); 138141cc406Sopenharmony_ci/* next line by mf */ 139141cc406Sopenharmony_ci ibuf.byte2 = 2; 140141cc406Sopenharmony_ci status = inquiry (fd, &ibuf, &buf_size); 141141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 142141cc406Sopenharmony_ci { 143141cc406Sopenharmony_ci DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status)); 144141cc406Sopenharmony_ci sanei_scsi_close (fd); 145141cc406Sopenharmony_ci return (status); 146141cc406Sopenharmony_ci } 147141cc406Sopenharmony_ci 148141cc406Sopenharmony_ci if (ibuf.devtype != 6) 149141cc406Sopenharmony_ci { 150141cc406Sopenharmony_ci DBG (1, "attach: device \"%s\" is not a scanner\n", devnam); 151141cc406Sopenharmony_ci sanei_scsi_close (fd); 152141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 153141cc406Sopenharmony_ci } 154141cc406Sopenharmony_ci 155141cc406Sopenharmony_ci if (!( 156141cc406Sopenharmony_ci (strncmp ((char *)ibuf.vendor, "IBM", 3) ==0 157141cc406Sopenharmony_ci && strncmp ((char *)ibuf.product, "2456", 4) == 0) 158141cc406Sopenharmony_ci || (strncmp ((char *)ibuf.vendor, "RICOH", 5) == 0 159141cc406Sopenharmony_ci && strncmp ((char *)ibuf.product, "IS420", 5) == 0) 160141cc406Sopenharmony_ci || (strncmp ((char *)ibuf.vendor, "RICOH", 5) == 0 161141cc406Sopenharmony_ci && strncmp ((char *)ibuf.product, "IS410", 5) == 0) 162141cc406Sopenharmony_ci || (strncmp ((char *)ibuf.vendor, "RICOH", 5) == 0 163141cc406Sopenharmony_ci && strncmp ((char *)ibuf.product, "IS430", 5) == 0) 164141cc406Sopenharmony_ci )) 165141cc406Sopenharmony_ci { 166141cc406Sopenharmony_ci DBG (1, "attach: device \"%s\" doesn't look like a scanner I know\n", 167141cc406Sopenharmony_ci devnam); 168141cc406Sopenharmony_ci sanei_scsi_close (fd); 169141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 170141cc406Sopenharmony_ci } 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ci DBG (3, "attach: sending TEST_UNIT_READY\n"); 173141cc406Sopenharmony_ci status = test_unit_ready (fd); 174141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 175141cc406Sopenharmony_ci { 176141cc406Sopenharmony_ci DBG (1, "attach: test unit ready failed (%s)\n", 177141cc406Sopenharmony_ci sane_strstatus (status)); 178141cc406Sopenharmony_ci sanei_scsi_close (fd); 179141cc406Sopenharmony_ci return (status); 180141cc406Sopenharmony_ci } 181141cc406Sopenharmony_ci /* 182141cc406Sopenharmony_ci * Causes a problem with RICOH IS420 183141cc406Sopenharmony_ci * Ignore this function ... seems to work ok 184141cc406Sopenharmony_ci * Suggested to George Murphy george@topfloor.ie by henning 185141cc406Sopenharmony_ci */ 186141cc406Sopenharmony_ci if (strncmp((char *)ibuf.vendor, "RICOH", 5) != 0 187141cc406Sopenharmony_ci && strncmp((char *)ibuf.product, "IS420", 5) != 0) 188141cc406Sopenharmony_ci { 189141cc406Sopenharmony_ci DBG (3, "attach: sending OBJECT POSITION\n"); 190141cc406Sopenharmony_ci status = object_position (fd, OBJECT_POSITION_UNLOAD); 191141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 192141cc406Sopenharmony_ci { 193141cc406Sopenharmony_ci DBG (1, "attach: OBJECT POSITION failed\n"); 194141cc406Sopenharmony_ci sanei_scsi_close (fd); 195141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 196141cc406Sopenharmony_ci } 197141cc406Sopenharmony_ci } 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_ci memset (&mup, 0, sizeof (mup)); 200141cc406Sopenharmony_ci mup.page_code = MEASUREMENTS_PAGE; 201141cc406Sopenharmony_ci mup.parameter_length = 0x06; 202141cc406Sopenharmony_ci mup.bmu = INCHES; 203141cc406Sopenharmony_ci mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff; 204141cc406Sopenharmony_ci mup.mud[1] = (DEFAULT_MUD & 0xff); 205141cc406Sopenharmony_ci 206141cc406Sopenharmony_ci#if 0 207141cc406Sopenharmony_ci DBG (3, "attach: sending MODE SELECT\n"); 208141cc406Sopenharmony_ci status = mode_select (fd, (struct mode_pages *) &mup); 209141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 210141cc406Sopenharmony_ci { 211141cc406Sopenharmony_ci DBG (1, "attach: MODE_SELECT failed\n"); 212141cc406Sopenharmony_ci sanei_scsi_close (fd); 213141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 214141cc406Sopenharmony_ci } 215141cc406Sopenharmony_ci#endif 216141cc406Sopenharmony_ci 217141cc406Sopenharmony_ci#if 0 218141cc406Sopenharmony_ci DBG (3, "attach: sending MODE SENSE\n"); 219141cc406Sopenharmony_ci memset (&mup, 0, sizeof (mup)); 220141cc406Sopenharmony_ci status = mode_sense (fd, (struct mode_pages *) &mup, PC_CURRENT | MEASUREMENTS_PAGE); 221141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 222141cc406Sopenharmony_ci { 223141cc406Sopenharmony_ci DBG (1, "attach: MODE_SENSE failed\n"); 224141cc406Sopenharmony_ci sanei_scsi_close (fd); 225141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 226141cc406Sopenharmony_ci } 227141cc406Sopenharmony_ci#endif 228141cc406Sopenharmony_ci 229141cc406Sopenharmony_ci DBG (3, "attach: sending GET WINDOW\n"); 230141cc406Sopenharmony_ci memset (&wbuf, 0, sizeof (wbuf)); 231141cc406Sopenharmony_ci status = get_window (fd, &wbuf); 232141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 233141cc406Sopenharmony_ci { 234141cc406Sopenharmony_ci DBG (1, "attach: GET_WINDOW failed %d\n", status); 235141cc406Sopenharmony_ci sanei_scsi_close (fd); 236141cc406Sopenharmony_ci DBG (11, "<< attach\n"); 237141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 238141cc406Sopenharmony_ci } 239141cc406Sopenharmony_ci 240141cc406Sopenharmony_ci sanei_scsi_close (fd); 241141cc406Sopenharmony_ci 242141cc406Sopenharmony_ci dev = malloc (sizeof (*dev)); 243141cc406Sopenharmony_ci if (!dev) 244141cc406Sopenharmony_ci return (SANE_STATUS_NO_MEM); 245141cc406Sopenharmony_ci memset (dev, 0, sizeof (*dev)); 246141cc406Sopenharmony_ci 247141cc406Sopenharmony_ci dev->sane.name = strdup (devnam); 248141cc406Sopenharmony_ci dev->sane.vendor = "IBM"; 249141cc406Sopenharmony_ci 250141cc406Sopenharmony_ci size_t prod_rev_size = sizeof(ibuf.product) + sizeof(ibuf.revision) + 1; 251141cc406Sopenharmony_ci str = malloc (prod_rev_size); 252141cc406Sopenharmony_ci if (str) 253141cc406Sopenharmony_ci { 254141cc406Sopenharmony_ci snprintf (str, prod_rev_size, "%.*s%.*s", 255141cc406Sopenharmony_ci (int) sizeof(ibuf.product), (const char *) ibuf.product, 256141cc406Sopenharmony_ci (int) sizeof(ibuf.revision), (const char *) ibuf.revision); 257141cc406Sopenharmony_ci } 258141cc406Sopenharmony_ci dev->sane.model = str; 259141cc406Sopenharmony_ci dev->sane.type = "flatbed scanner"; 260141cc406Sopenharmony_ci 261141cc406Sopenharmony_ci DBG (5, "dev->sane.name = %s\n", dev->sane.name); 262141cc406Sopenharmony_ci DBG (5, "dev->sane.vendor = %s\n", dev->sane.vendor); 263141cc406Sopenharmony_ci DBG (5, "dev->sane.model = %s\n", dev->sane.model); 264141cc406Sopenharmony_ci DBG (5, "dev->sane.type = %s\n", dev->sane.type); 265141cc406Sopenharmony_ci 266141cc406Sopenharmony_ci dev->info.xres_default = _2btol(wbuf.x_res); 267141cc406Sopenharmony_ci dev->info.yres_default = _2btol(wbuf.y_res); 268141cc406Sopenharmony_ci dev->info.image_mode_default = wbuf.image_comp; 269141cc406Sopenharmony_ci 270141cc406Sopenharmony_ci /* if you throw the MRIF bit the brightness control reverses too */ 271141cc406Sopenharmony_ci /* so I reverse the reversal in software for symmetry's sake */ 272141cc406Sopenharmony_ci /* I should make this into an option */ 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci if (wbuf.image_comp == IBM_GRAYSCALE || wbuf.image_comp == IBM_DITHERED_MONOCHROME) 275141cc406Sopenharmony_ci { 276141cc406Sopenharmony_ci dev->info.brightness_default = 256 - wbuf.brightness; 277141cc406Sopenharmony_ci/* 278141cc406Sopenharmony_ci if (is50) 279141cc406Sopenharmony_ci dev->info.contrast_default = wbuf.contrast; 280141cc406Sopenharmony_ci else 281141cc406Sopenharmony_ci*/ 282141cc406Sopenharmony_ci dev->info.contrast_default = 256 - wbuf.contrast; 283141cc406Sopenharmony_ci } 284141cc406Sopenharmony_ci else /* wbuf.image_comp == IBM_BINARY_MONOCHROME */ 285141cc406Sopenharmony_ci { 286141cc406Sopenharmony_ci dev->info.brightness_default = wbuf.brightness; 287141cc406Sopenharmony_ci dev->info.contrast_default = wbuf.contrast; 288141cc406Sopenharmony_ci } 289141cc406Sopenharmony_ci 290141cc406Sopenharmony_ci/* da rivedere 291141cc406Sopenharmony_ci dev->info.adf_default = wbuf.adf_state; 292141cc406Sopenharmony_ci*/ 293141cc406Sopenharmony_ci dev->info.adf_default = ADF_UNUSED; 294141cc406Sopenharmony_ci dev->info.adf_default = IBM_PAPER_USER_DEFINED; 295141cc406Sopenharmony_ci 296141cc406Sopenharmony_ci#if 1 297141cc406Sopenharmony_ci dev->info.bmu = mup.bmu; 298141cc406Sopenharmony_ci dev->info.mud = _2btol(mup.mud); 299141cc406Sopenharmony_ci if (dev->info.mud == 0) { 300141cc406Sopenharmony_ci /* The Ricoh says it uses points as default Basic Measurement Unit */ 301141cc406Sopenharmony_ci /* but gives a Measurement Unit Divisor of zero */ 302141cc406Sopenharmony_ci /* So, we set it to the default (SCSI-standard) of 1200 */ 303141cc406Sopenharmony_ci /* with BMU in inches, i.e. 1200 points equal 1 inch */ 304141cc406Sopenharmony_ci dev->info.bmu = INCHES; 305141cc406Sopenharmony_ci dev->info.mud = DEFAULT_MUD; 306141cc406Sopenharmony_ci } 307141cc406Sopenharmony_ci#else 308141cc406Sopenharmony_ci dev->info.bmu = INCHES; 309141cc406Sopenharmony_ci dev->info.mud = DEFAULT_MUD; 310141cc406Sopenharmony_ci#endif 311141cc406Sopenharmony_ci 312141cc406Sopenharmony_ci DBG (5, "xres_default=%d\n", dev->info.xres_default); 313141cc406Sopenharmony_ci DBG (5, "xres_range.max=%d\n", dev->info.xres_range.max); 314141cc406Sopenharmony_ci DBG (5, "xres_range.min=%d\n", dev->info.xres_range.min); 315141cc406Sopenharmony_ci 316141cc406Sopenharmony_ci DBG (5, "yres_default=%d\n", dev->info.yres_default); 317141cc406Sopenharmony_ci DBG (5, "yres_range.max=%d\n", dev->info.yres_range.max); 318141cc406Sopenharmony_ci DBG (5, "yres_range.min=%d\n", dev->info.yres_range.min); 319141cc406Sopenharmony_ci 320141cc406Sopenharmony_ci DBG (5, "x_range.max=%d\n", dev->info.x_range.max); 321141cc406Sopenharmony_ci DBG (5, "y_range.max=%d\n", dev->info.y_range.max); 322141cc406Sopenharmony_ci 323141cc406Sopenharmony_ci DBG (5, "image_mode=%d\n", dev->info.image_mode_default); 324141cc406Sopenharmony_ci 325141cc406Sopenharmony_ci DBG (5, "brightness=%d\n", dev->info.brightness_default); 326141cc406Sopenharmony_ci DBG (5, "contrast=%d\n", dev->info.contrast_default); 327141cc406Sopenharmony_ci 328141cc406Sopenharmony_ci DBG (5, "adf_state=%d\n", dev->info.adf_default); 329141cc406Sopenharmony_ci 330141cc406Sopenharmony_ci DBG (5, "bmu=%d\n", dev->info.bmu); 331141cc406Sopenharmony_ci DBG (5, "mud=%d\n", dev->info.mud); 332141cc406Sopenharmony_ci 333141cc406Sopenharmony_ci ++num_devices; 334141cc406Sopenharmony_ci dev->next = first_dev; 335141cc406Sopenharmony_ci first_dev = dev; 336141cc406Sopenharmony_ci 337141cc406Sopenharmony_ci if (devp) 338141cc406Sopenharmony_ci *devp = dev; 339141cc406Sopenharmony_ci 340141cc406Sopenharmony_ci DBG (11, "<< attach\n"); 341141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 342141cc406Sopenharmony_ci} 343141cc406Sopenharmony_ci 344141cc406Sopenharmony_cistatic SANE_Status 345141cc406Sopenharmony_ciattach_one(const char *devnam) 346141cc406Sopenharmony_ci{ 347141cc406Sopenharmony_ci attach (devnam, NULL); 348141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 349141cc406Sopenharmony_ci} 350141cc406Sopenharmony_ci 351141cc406Sopenharmony_cistatic SANE_Status 352141cc406Sopenharmony_ciinit_options (Ibm_Scanner * s) 353141cc406Sopenharmony_ci{ 354141cc406Sopenharmony_ci int i; 355141cc406Sopenharmony_ci DBG (11, ">> init_options\n"); 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci memset (s->opt, 0, sizeof (s->opt)); 358141cc406Sopenharmony_ci memset (s->val, 0, sizeof (s->val)); 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci for (i = 0; i < NUM_OPTIONS; ++i) 361141cc406Sopenharmony_ci { 362141cc406Sopenharmony_ci s->opt[i].size = sizeof (SANE_Word); 363141cc406Sopenharmony_ci s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 364141cc406Sopenharmony_ci } 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 367141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 368141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 369141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 370141cc406Sopenharmony_ci s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 371141cc406Sopenharmony_ci 372141cc406Sopenharmony_ci /* "Mode" group: */ 373141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].title = "Scan Mode"; 374141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].desc = ""; 375141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 376141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].cap = 0; 377141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 378141cc406Sopenharmony_ci 379141cc406Sopenharmony_ci /* scan mode */ 380141cc406Sopenharmony_ci s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 381141cc406Sopenharmony_ci s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 382141cc406Sopenharmony_ci s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 383141cc406Sopenharmony_ci s->opt[OPT_MODE].type = SANE_TYPE_STRING; 384141cc406Sopenharmony_ci s->opt[OPT_MODE].size = max_string_size (mode_list); 385141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 386141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = mode_list; 387141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup (mode_list[s->hw->info.image_mode_default]); 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci /* x resolution */ 390141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].name = "X" SANE_NAME_SCAN_RESOLUTION; 391141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].title = "X " SANE_TITLE_SCAN_RESOLUTION; 392141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 393141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].type = SANE_TYPE_INT; 394141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI; 395141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 396141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint.range = &ibm2456_res_range; 397141cc406Sopenharmony_ci s->val[OPT_X_RESOLUTION].w = s->hw->info.xres_default; 398141cc406Sopenharmony_ci/* 399141cc406Sopenharmony_ci if (is50) 400141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint.range = &is50_res_range; 401141cc406Sopenharmony_ci else 402141cc406Sopenharmony_ci*/ 403141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint.range = &ibm2456_res_range; 404141cc406Sopenharmony_ci 405141cc406Sopenharmony_ci /* y resolution */ 406141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].name = "Y" SANE_NAME_SCAN_RESOLUTION; 407141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].title = "Y " SANE_TITLE_SCAN_RESOLUTION; 408141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 409141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].type = SANE_TYPE_INT; 410141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI; 411141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 412141cc406Sopenharmony_ci s->val[OPT_Y_RESOLUTION].w = s->hw->info.yres_default; 413141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].constraint.range = &ibm2456_res_range; 414141cc406Sopenharmony_ci 415141cc406Sopenharmony_ci /* adf */ 416141cc406Sopenharmony_ci s->opt[OPT_ADF].name = "adf"; 417141cc406Sopenharmony_ci s->opt[OPT_ADF].title = "Use ADF"; 418141cc406Sopenharmony_ci s->opt[OPT_ADF].desc = "Uses the automatic document feeder."; 419141cc406Sopenharmony_ci s->opt[OPT_ADF].type = SANE_TYPE_BOOL; 420141cc406Sopenharmony_ci s->opt[OPT_ADF].unit = SANE_UNIT_NONE; 421141cc406Sopenharmony_ci s->opt[OPT_ADF].constraint_type = SANE_CONSTRAINT_NONE; 422141cc406Sopenharmony_ci s->val[OPT_ADF].b = s->hw->info.adf_default; 423141cc406Sopenharmony_ci 424141cc406Sopenharmony_ci /* "Geometry" group: */ 425141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 426141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].desc = ""; 427141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 428141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 429141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 430141cc406Sopenharmony_ci 431141cc406Sopenharmony_ci /* paper */ 432141cc406Sopenharmony_ci s->opt[OPT_PAPER].name = "paper"; 433141cc406Sopenharmony_ci s->opt[OPT_PAPER].title = "Paper format"; 434141cc406Sopenharmony_ci s->opt[OPT_PAPER].desc = "Sets the paper format."; 435141cc406Sopenharmony_ci s->opt[OPT_PAPER].type = SANE_TYPE_STRING; 436141cc406Sopenharmony_ci s->opt[OPT_PAPER].size = max_string_size (paper_list); 437141cc406Sopenharmony_ci s->opt[OPT_PAPER].constraint_type = SANE_CONSTRAINT_STRING_LIST; 438141cc406Sopenharmony_ci s->opt[OPT_PAPER].constraint.string_list = paper_list; 439141cc406Sopenharmony_ci s->val[OPT_PAPER].s = strdup (paper_list[s->hw->info.paper_default]); 440141cc406Sopenharmony_ci 441141cc406Sopenharmony_ci /* top-left x */ 442141cc406Sopenharmony_ci s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 443141cc406Sopenharmony_ci s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 444141cc406Sopenharmony_ci s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 445141cc406Sopenharmony_ci s->opt[OPT_TL_X].type = SANE_TYPE_INT; 446141cc406Sopenharmony_ci s->opt[OPT_TL_X].unit = SANE_UNIT_PIXEL; 447141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 448141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint.range = &default_x_range; 449141cc406Sopenharmony_ci s->val[OPT_TL_X].w = 0; 450141cc406Sopenharmony_ci 451141cc406Sopenharmony_ci /* top-left y */ 452141cc406Sopenharmony_ci s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 453141cc406Sopenharmony_ci s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 454141cc406Sopenharmony_ci s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 455141cc406Sopenharmony_ci s->opt[OPT_TL_Y].type = SANE_TYPE_INT; 456141cc406Sopenharmony_ci s->opt[OPT_TL_Y].unit = SANE_UNIT_PIXEL; 457141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 458141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint.range = &default_y_range; 459141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = 0; 460141cc406Sopenharmony_ci 461141cc406Sopenharmony_ci /* bottom-right x */ 462141cc406Sopenharmony_ci s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 463141cc406Sopenharmony_ci s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 464141cc406Sopenharmony_ci s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 465141cc406Sopenharmony_ci s->opt[OPT_BR_X].type = SANE_TYPE_INT; 466141cc406Sopenharmony_ci s->opt[OPT_BR_X].unit = SANE_UNIT_PIXEL; 467141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 468141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint.range = &default_x_range; 469141cc406Sopenharmony_ci s->val[OPT_BR_X].w = default_x_range.max; 470141cc406Sopenharmony_ci 471141cc406Sopenharmony_ci /* bottom-right y */ 472141cc406Sopenharmony_ci s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 473141cc406Sopenharmony_ci s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 474141cc406Sopenharmony_ci s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 475141cc406Sopenharmony_ci s->opt[OPT_BR_Y].type = SANE_TYPE_INT; 476141cc406Sopenharmony_ci s->opt[OPT_BR_Y].unit = SANE_UNIT_PIXEL; 477141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 478141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint.range = &default_y_range; 479141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = default_y_range.max; 480141cc406Sopenharmony_ci 481141cc406Sopenharmony_ci /* "Enhancement" group: */ 482141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 483141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 484141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 485141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 486141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 487141cc406Sopenharmony_ci 488141cc406Sopenharmony_ci /* brightness */ 489141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS; 490141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS; 491141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS; 492141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT; 493141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE; 494141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE; 495141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].constraint.range = &u8_range; 496141cc406Sopenharmony_ci s->val[OPT_BRIGHTNESS].w = s->hw->info.brightness_default; 497141cc406Sopenharmony_ci 498141cc406Sopenharmony_ci /* contrast */ 499141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST; 500141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST; 501141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST; 502141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].type = SANE_TYPE_INT; 503141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE; 504141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE; 505141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].constraint.range = &u8_range; 506141cc406Sopenharmony_ci s->val[OPT_CONTRAST].w = s->hw->info.contrast_default; 507141cc406Sopenharmony_ci 508141cc406Sopenharmony_ci DBG (11, "<< init_options\n"); 509141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 510141cc406Sopenharmony_ci} 511141cc406Sopenharmony_ci 512141cc406Sopenharmony_cistatic SANE_Status 513141cc406Sopenharmony_cido_cancel (Ibm_Scanner * s) 514141cc406Sopenharmony_ci{ 515141cc406Sopenharmony_ci SANE_Status status; 516141cc406Sopenharmony_ci DBG (11, ">> do_cancel\n"); 517141cc406Sopenharmony_ci 518141cc406Sopenharmony_ci DBG (3, "cancel: sending OBJECT POSITION\n"); 519141cc406Sopenharmony_ci status = object_position (s->fd, OBJECT_POSITION_UNLOAD); 520141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 521141cc406Sopenharmony_ci { 522141cc406Sopenharmony_ci DBG (1, "cancel: OBJECT POSITION failed\n"); 523141cc406Sopenharmony_ci } 524141cc406Sopenharmony_ci 525141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 526141cc406Sopenharmony_ci 527141cc406Sopenharmony_ci if (s->fd >= 0) 528141cc406Sopenharmony_ci { 529141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 530141cc406Sopenharmony_ci s->fd = -1; 531141cc406Sopenharmony_ci } 532141cc406Sopenharmony_ci 533141cc406Sopenharmony_ci DBG (11, "<< do_cancel\n"); 534141cc406Sopenharmony_ci return (SANE_STATUS_CANCELLED); 535141cc406Sopenharmony_ci} 536141cc406Sopenharmony_ci 537141cc406Sopenharmony_ciSANE_Status 538141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 539141cc406Sopenharmony_ci{ 540141cc406Sopenharmony_ci char devnam[PATH_MAX] = "/dev/scanner"; 541141cc406Sopenharmony_ci FILE *fp; 542141cc406Sopenharmony_ci 543141cc406Sopenharmony_ci DBG_INIT (); 544141cc406Sopenharmony_ci DBG (11, ">> sane_init (authorize %s null)\n", (authorize) ? "!=" : "=="); 545141cc406Sopenharmony_ci 546141cc406Sopenharmony_ci#if defined PACKAGE && defined VERSION 547141cc406Sopenharmony_ci DBG (2, "sane_init: ibm backend version %d.%d-%d (" 548141cc406Sopenharmony_ci PACKAGE " " VERSION ")\n", SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 549141cc406Sopenharmony_ci#endif 550141cc406Sopenharmony_ci 551141cc406Sopenharmony_ci if (version_code) 552141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0); 553141cc406Sopenharmony_ci 554141cc406Sopenharmony_ci fp = sanei_config_open(IBM_CONFIG_FILE); 555141cc406Sopenharmony_ci if (fp) 556141cc406Sopenharmony_ci { 557141cc406Sopenharmony_ci char line[PATH_MAX], *lp; 558141cc406Sopenharmony_ci size_t len; 559141cc406Sopenharmony_ci 560141cc406Sopenharmony_ci /* read config file */ 561141cc406Sopenharmony_ci while (sanei_config_read (line, sizeof (line), fp)) 562141cc406Sopenharmony_ci { 563141cc406Sopenharmony_ci if (line[0] == '#') /* ignore line comments */ 564141cc406Sopenharmony_ci continue; 565141cc406Sopenharmony_ci len = strlen (line); 566141cc406Sopenharmony_ci 567141cc406Sopenharmony_ci if (!len) 568141cc406Sopenharmony_ci continue; /* ignore empty lines */ 569141cc406Sopenharmony_ci 570141cc406Sopenharmony_ci /* skip white space: */ 571141cc406Sopenharmony_ci for (lp = line; isspace(*lp); ++lp) 572141cc406Sopenharmony_ci ; 573141cc406Sopenharmony_ci strcpy (devnam, lp); 574141cc406Sopenharmony_ci } 575141cc406Sopenharmony_ci fclose (fp); 576141cc406Sopenharmony_ci } 577141cc406Sopenharmony_ci sanei_config_attach_matching_devices (devnam, attach_one); 578141cc406Sopenharmony_ci DBG (11, "<< sane_init\n"); 579141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 580141cc406Sopenharmony_ci} 581141cc406Sopenharmony_ci 582141cc406Sopenharmony_civoid 583141cc406Sopenharmony_cisane_exit (void) 584141cc406Sopenharmony_ci{ 585141cc406Sopenharmony_ci Ibm_Device *dev, *next; 586141cc406Sopenharmony_ci DBG (11, ">> sane_exit\n"); 587141cc406Sopenharmony_ci 588141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = next) 589141cc406Sopenharmony_ci { 590141cc406Sopenharmony_ci next = dev->next; 591141cc406Sopenharmony_ci free ((void *) dev->sane.name); 592141cc406Sopenharmony_ci free ((void *) dev->sane.model); 593141cc406Sopenharmony_ci free (dev); 594141cc406Sopenharmony_ci } 595141cc406Sopenharmony_ci 596141cc406Sopenharmony_ci DBG (11, "<< sane_exit\n"); 597141cc406Sopenharmony_ci} 598141cc406Sopenharmony_ci 599141cc406Sopenharmony_ciSANE_Status 600141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 601141cc406Sopenharmony_ci{ 602141cc406Sopenharmony_ci static const SANE_Device **devlist = 0; 603141cc406Sopenharmony_ci Ibm_Device *dev; 604141cc406Sopenharmony_ci int i; 605141cc406Sopenharmony_ci DBG (11, ">> sane_get_devices (local_only = %d)\n", local_only); 606141cc406Sopenharmony_ci 607141cc406Sopenharmony_ci if (devlist) 608141cc406Sopenharmony_ci free (devlist); 609141cc406Sopenharmony_ci devlist = malloc ((num_devices + 1) * sizeof (devlist[0])); 610141cc406Sopenharmony_ci if (!devlist) 611141cc406Sopenharmony_ci return (SANE_STATUS_NO_MEM); 612141cc406Sopenharmony_ci 613141cc406Sopenharmony_ci i = 0; 614141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 615141cc406Sopenharmony_ci devlist[i++] = &dev->sane; 616141cc406Sopenharmony_ci devlist[i++] = 0; 617141cc406Sopenharmony_ci 618141cc406Sopenharmony_ci *device_list = devlist; 619141cc406Sopenharmony_ci 620141cc406Sopenharmony_ci DBG (11, "<< sane_get_devices\n"); 621141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 622141cc406Sopenharmony_ci} 623141cc406Sopenharmony_ci 624141cc406Sopenharmony_ciSANE_Status 625141cc406Sopenharmony_cisane_open (SANE_String_Const devnam, SANE_Handle * handle) 626141cc406Sopenharmony_ci{ 627141cc406Sopenharmony_ci SANE_Status status; 628141cc406Sopenharmony_ci Ibm_Device *dev; 629141cc406Sopenharmony_ci Ibm_Scanner *s; 630141cc406Sopenharmony_ci DBG (11, ">> sane_open\n"); 631141cc406Sopenharmony_ci 632141cc406Sopenharmony_ci if (devnam[0] == '\0') 633141cc406Sopenharmony_ci { 634141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 635141cc406Sopenharmony_ci { 636141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devnam) == 0) 637141cc406Sopenharmony_ci break; 638141cc406Sopenharmony_ci } 639141cc406Sopenharmony_ci 640141cc406Sopenharmony_ci if (!dev) 641141cc406Sopenharmony_ci { 642141cc406Sopenharmony_ci status = attach (devnam, &dev); 643141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 644141cc406Sopenharmony_ci return (status); 645141cc406Sopenharmony_ci } 646141cc406Sopenharmony_ci } 647141cc406Sopenharmony_ci else 648141cc406Sopenharmony_ci { 649141cc406Sopenharmony_ci dev = first_dev; 650141cc406Sopenharmony_ci } 651141cc406Sopenharmony_ci 652141cc406Sopenharmony_ci if (!dev) 653141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 654141cc406Sopenharmony_ci 655141cc406Sopenharmony_ci s = malloc (sizeof (*s)); 656141cc406Sopenharmony_ci if (!s) 657141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 658141cc406Sopenharmony_ci memset (s, 0, sizeof (*s)); 659141cc406Sopenharmony_ci 660141cc406Sopenharmony_ci s->fd = -1; 661141cc406Sopenharmony_ci s->hw = dev; 662141cc406Sopenharmony_ci 663141cc406Sopenharmony_ci init_options (s); 664141cc406Sopenharmony_ci 665141cc406Sopenharmony_ci s->next = first_handle; 666141cc406Sopenharmony_ci first_handle = s; 667141cc406Sopenharmony_ci 668141cc406Sopenharmony_ci *handle = s; 669141cc406Sopenharmony_ci 670141cc406Sopenharmony_ci DBG (11, "<< sane_open\n"); 671141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 672141cc406Sopenharmony_ci} 673141cc406Sopenharmony_ci 674141cc406Sopenharmony_civoid 675141cc406Sopenharmony_cisane_close (SANE_Handle handle) 676141cc406Sopenharmony_ci{ 677141cc406Sopenharmony_ci Ibm_Scanner *s = (Ibm_Scanner *) handle; 678141cc406Sopenharmony_ci DBG (11, ">> sane_close\n"); 679141cc406Sopenharmony_ci 680141cc406Sopenharmony_ci if (s->fd != -1) 681141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 682141cc406Sopenharmony_ci free (s); 683141cc406Sopenharmony_ci 684141cc406Sopenharmony_ci DBG (11, ">> sane_close\n"); 685141cc406Sopenharmony_ci} 686141cc406Sopenharmony_ci 687141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 688141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 689141cc406Sopenharmony_ci{ 690141cc406Sopenharmony_ci Ibm_Scanner *s = handle; 691141cc406Sopenharmony_ci DBG (11, ">> sane_get_option_descriptor\n"); 692141cc406Sopenharmony_ci 693141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 694141cc406Sopenharmony_ci return (0); 695141cc406Sopenharmony_ci 696141cc406Sopenharmony_ci DBG (11, "<< sane_get_option_descriptor\n"); 697141cc406Sopenharmony_ci return (s->opt + option); 698141cc406Sopenharmony_ci} 699141cc406Sopenharmony_ci 700141cc406Sopenharmony_ciSANE_Status 701141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, 702141cc406Sopenharmony_ci SANE_Action action, void *val, SANE_Int * info) 703141cc406Sopenharmony_ci{ 704141cc406Sopenharmony_ci Ibm_Scanner *s = handle; 705141cc406Sopenharmony_ci SANE_Status status; 706141cc406Sopenharmony_ci SANE_Word cap; 707141cc406Sopenharmony_ci DBG (11, ">> sane_control_option\n"); 708141cc406Sopenharmony_ci 709141cc406Sopenharmony_ci if (info) 710141cc406Sopenharmony_ci *info = 0; 711141cc406Sopenharmony_ci 712141cc406Sopenharmony_ci if (s->scanning) 713141cc406Sopenharmony_ci return (SANE_STATUS_DEVICE_BUSY); 714141cc406Sopenharmony_ci if (option >= NUM_OPTIONS) 715141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 716141cc406Sopenharmony_ci 717141cc406Sopenharmony_ci cap = s->opt[option].cap; 718141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (cap)) 719141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 720141cc406Sopenharmony_ci 721141cc406Sopenharmony_ci if (action == SANE_ACTION_GET_VALUE) 722141cc406Sopenharmony_ci { 723141cc406Sopenharmony_ci DBG (11, "sane_control_option get_value\n"); 724141cc406Sopenharmony_ci switch (option) 725141cc406Sopenharmony_ci { 726141cc406Sopenharmony_ci /* word options: */ 727141cc406Sopenharmony_ci case OPT_X_RESOLUTION: 728141cc406Sopenharmony_ci case OPT_Y_RESOLUTION: 729141cc406Sopenharmony_ci case OPT_TL_X: 730141cc406Sopenharmony_ci case OPT_TL_Y: 731141cc406Sopenharmony_ci case OPT_BR_X: 732141cc406Sopenharmony_ci case OPT_BR_Y: 733141cc406Sopenharmony_ci case OPT_NUM_OPTS: 734141cc406Sopenharmony_ci case OPT_BRIGHTNESS: 735141cc406Sopenharmony_ci case OPT_CONTRAST: 736141cc406Sopenharmony_ci *(SANE_Word *) val = s->val[option].w; 737141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 738141cc406Sopenharmony_ci 739141cc406Sopenharmony_ci /* bool options: */ 740141cc406Sopenharmony_ci case OPT_ADF: 741141cc406Sopenharmony_ci *(SANE_Bool *) val = s->val[option].b; 742141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 743141cc406Sopenharmony_ci 744141cc406Sopenharmony_ci /* string options: */ 745141cc406Sopenharmony_ci case OPT_MODE: 746141cc406Sopenharmony_ci case OPT_PAPER: 747141cc406Sopenharmony_ci strcpy (val, s->val[option].s); 748141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 749141cc406Sopenharmony_ci } 750141cc406Sopenharmony_ci } 751141cc406Sopenharmony_ci else { 752141cc406Sopenharmony_ci DBG (11, "sane_control_option set_value\n"); 753141cc406Sopenharmony_ci if (action == SANE_ACTION_SET_VALUE) 754141cc406Sopenharmony_ci { 755141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (cap)) 756141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 757141cc406Sopenharmony_ci 758141cc406Sopenharmony_ci status = sanei_constrain_value (s->opt + option, val, info); 759141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 760141cc406Sopenharmony_ci return status; 761141cc406Sopenharmony_ci 762141cc406Sopenharmony_ci switch (option) 763141cc406Sopenharmony_ci { 764141cc406Sopenharmony_ci /* (mostly) side-effect-free word options: */ 765141cc406Sopenharmony_ci case OPT_X_RESOLUTION: 766141cc406Sopenharmony_ci case OPT_Y_RESOLUTION: 767141cc406Sopenharmony_ci if (info && s->val[option].w != *(SANE_Word *) val) 768141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 769141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 770141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 771141cc406Sopenharmony_ci 772141cc406Sopenharmony_ci case OPT_TL_X: 773141cc406Sopenharmony_ci case OPT_TL_Y: 774141cc406Sopenharmony_ci case OPT_BR_X: 775141cc406Sopenharmony_ci case OPT_BR_Y: 776141cc406Sopenharmony_ci if (info && s->val[option].w != *(SANE_Word *) val) 777141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 778141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 779141cc406Sopenharmony_ci /* resets the paper format to user defined */ 780141cc406Sopenharmony_ci if (strcmp(s->val[OPT_PAPER].s, paper_list[IBM_PAPER_USER_DEFINED]) != 0) 781141cc406Sopenharmony_ci { 782141cc406Sopenharmony_ci if (info) 783141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 784141cc406Sopenharmony_ci if (s->val[OPT_PAPER].s) 785141cc406Sopenharmony_ci free (s->val[OPT_PAPER].s); 786141cc406Sopenharmony_ci s->val[OPT_PAPER].s = strdup (paper_list[IBM_PAPER_USER_DEFINED]); 787141cc406Sopenharmony_ci } 788141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 789141cc406Sopenharmony_ci 790141cc406Sopenharmony_ci case OPT_NUM_OPTS: 791141cc406Sopenharmony_ci case OPT_BRIGHTNESS: 792141cc406Sopenharmony_ci case OPT_CONTRAST: 793141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 794141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 795141cc406Sopenharmony_ci 796141cc406Sopenharmony_ci case OPT_MODE: 797141cc406Sopenharmony_ci if (info && strcmp (s->val[option].s, (SANE_String) val)) 798141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 799141cc406Sopenharmony_ci if (s->val[option].s) 800141cc406Sopenharmony_ci free (s->val[option].s); 801141cc406Sopenharmony_ci s->val[option].s = strdup (val); 802141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 803141cc406Sopenharmony_ci 804141cc406Sopenharmony_ci case OPT_ADF: 805141cc406Sopenharmony_ci s->val[option].b = *(SANE_Bool *) val; 806141cc406Sopenharmony_ci if (*(SANE_Bool *) val) 807141cc406Sopenharmony_ci s->adf_state = ADF_ARMED; 808141cc406Sopenharmony_ci else 809141cc406Sopenharmony_ci s->adf_state = ADF_UNUSED; 810141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 811141cc406Sopenharmony_ci 812141cc406Sopenharmony_ci case OPT_PAPER: 813141cc406Sopenharmony_ci if (info && strcmp (s->val[option].s, (SANE_String) val)) 814141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 815141cc406Sopenharmony_ci if (s->val[option].s) 816141cc406Sopenharmony_ci free (s->val[option].s); 817141cc406Sopenharmony_ci s->val[option].s = strdup (val); 818141cc406Sopenharmony_ci if (strcmp (s->val[OPT_PAPER].s, "User") != 0) 819141cc406Sopenharmony_ci { 820141cc406Sopenharmony_ci s->val[OPT_TL_X].w = 0; 821141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = 0; 822141cc406Sopenharmony_ci if (strcmp (s->val[OPT_PAPER].s, "A3") == 0) 823141cc406Sopenharmony_ci { 824141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_A3_W; 825141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_A3_H; 826141cc406Sopenharmony_ci } 827141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "A4") == 0) 828141cc406Sopenharmony_ci { 829141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_A4_W; 830141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_A4_H; 831141cc406Sopenharmony_ci } 832141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "A4R") == 0) 833141cc406Sopenharmony_ci { 834141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_A4R_W; 835141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_A4R_H; 836141cc406Sopenharmony_ci } 837141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "A5") == 0) 838141cc406Sopenharmony_ci { 839141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_A5_W; 840141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_A5_H; 841141cc406Sopenharmony_ci } 842141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "A5R") == 0) 843141cc406Sopenharmony_ci { 844141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_A5R_W; 845141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_A5R_H; 846141cc406Sopenharmony_ci } 847141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "A6") == 0) 848141cc406Sopenharmony_ci { 849141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_A6_W; 850141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_A6_H; 851141cc406Sopenharmony_ci } 852141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "B4") == 0) 853141cc406Sopenharmony_ci { 854141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_B4_W; 855141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_B4_H; 856141cc406Sopenharmony_ci } 857141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "Legal") == 0) 858141cc406Sopenharmony_ci { 859141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_LEGAL_W; 860141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_LEGAL_H; 861141cc406Sopenharmony_ci } 862141cc406Sopenharmony_ci else if (strcmp (s->val[OPT_PAPER].s, "Letter") == 0) 863141cc406Sopenharmony_ci { 864141cc406Sopenharmony_ci s->val[OPT_BR_X].w = PAPER_LETTER_W; 865141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = PAPER_LETTER_H; 866141cc406Sopenharmony_ci } 867141cc406Sopenharmony_ci } 868141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 869141cc406Sopenharmony_ci } 870141cc406Sopenharmony_ci 871141cc406Sopenharmony_ci } 872141cc406Sopenharmony_ci } 873141cc406Sopenharmony_ci 874141cc406Sopenharmony_ci DBG (11, "<< sane_control_option\n"); 875141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 876141cc406Sopenharmony_ci} 877141cc406Sopenharmony_ci 878141cc406Sopenharmony_ciSANE_Status 879141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 880141cc406Sopenharmony_ci{ 881141cc406Sopenharmony_ci Ibm_Scanner *s = handle; 882141cc406Sopenharmony_ci DBG (11, ">> sane_get_parameters\n"); 883141cc406Sopenharmony_ci 884141cc406Sopenharmony_ci if (!s->scanning) 885141cc406Sopenharmony_ci { 886141cc406Sopenharmony_ci int width, length, xres, yres; 887141cc406Sopenharmony_ci const char *mode; 888141cc406Sopenharmony_ci 889141cc406Sopenharmony_ci memset (&s->params, 0, sizeof (s->params)); 890141cc406Sopenharmony_ci 891141cc406Sopenharmony_ci width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w; 892141cc406Sopenharmony_ci length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w; 893141cc406Sopenharmony_ci xres = s->val[OPT_X_RESOLUTION].w; 894141cc406Sopenharmony_ci yres = s->val[OPT_Y_RESOLUTION].w; 895141cc406Sopenharmony_ci 896141cc406Sopenharmony_ci /* make best-effort guess at what parameters will look like once 897141cc406Sopenharmony_ci scanning starts. */ 898141cc406Sopenharmony_ci if (xres > 0 && yres > 0 && width > 0 && length > 0) 899141cc406Sopenharmony_ci { 900141cc406Sopenharmony_ci s->params.pixels_per_line = width * xres / s->hw->info.mud; 901141cc406Sopenharmony_ci s->params.lines = length * yres / s->hw->info.mud; 902141cc406Sopenharmony_ci } 903141cc406Sopenharmony_ci 904141cc406Sopenharmony_ci mode = s->val[OPT_MODE].s; 905141cc406Sopenharmony_ci if ((strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0) || 906141cc406Sopenharmony_ci (strcmp (mode, SANE_VALUE_SCAN_MODE_HALFTONE)) == 0) 907141cc406Sopenharmony_ci { 908141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 909141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line / 8; 910141cc406Sopenharmony_ci /* the Ibm truncates to the byte boundary, so: chop! */ 911141cc406Sopenharmony_ci s->params.pixels_per_line = s->params.bytes_per_line * 8; 912141cc406Sopenharmony_ci s->params.depth = 1; 913141cc406Sopenharmony_ci } 914141cc406Sopenharmony_ci else /* if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0) */ 915141cc406Sopenharmony_ci { 916141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 917141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line; 918141cc406Sopenharmony_ci s->params.depth = 8; 919141cc406Sopenharmony_ci } 920141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 921141cc406Sopenharmony_ci } 922141cc406Sopenharmony_ci else 923141cc406Sopenharmony_ci DBG (5, "sane_get_parameters: scanning, so can't get params\n"); 924141cc406Sopenharmony_ci 925141cc406Sopenharmony_ci if (params) 926141cc406Sopenharmony_ci *params = s->params; 927141cc406Sopenharmony_ci 928141cc406Sopenharmony_ci DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, " 929141cc406Sopenharmony_ci "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line, 930141cc406Sopenharmony_ci s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w); 931141cc406Sopenharmony_ci 932141cc406Sopenharmony_ci DBG (11, "<< sane_get_parameters\n"); 933141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 934141cc406Sopenharmony_ci} 935141cc406Sopenharmony_ci 936141cc406Sopenharmony_ci 937141cc406Sopenharmony_ciSANE_Status 938141cc406Sopenharmony_cisane_start (SANE_Handle handle) 939141cc406Sopenharmony_ci{ 940141cc406Sopenharmony_ci char *mode_str; 941141cc406Sopenharmony_ci Ibm_Scanner *s = handle; 942141cc406Sopenharmony_ci SANE_Status status; 943141cc406Sopenharmony_ci struct ibm_window_data wbuf; 944141cc406Sopenharmony_ci struct measurements_units_page mup; 945141cc406Sopenharmony_ci 946141cc406Sopenharmony_ci DBG (11, ">> sane_start\n"); 947141cc406Sopenharmony_ci 948141cc406Sopenharmony_ci /* First make sure we have a current parameter set. Some of the 949141cc406Sopenharmony_ci parameters will be overwritten below, but that's OK. */ 950141cc406Sopenharmony_ci status = sane_get_parameters (s, 0); 951141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 952141cc406Sopenharmony_ci return status; 953141cc406Sopenharmony_ci 954141cc406Sopenharmony_ci status = sanei_scsi_open (s->hw->sane.name, &s->fd, 0, 0); 955141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 956141cc406Sopenharmony_ci { 957141cc406Sopenharmony_ci DBG (1, "open of %s failed: %s\n", 958141cc406Sopenharmony_ci s->hw->sane.name, sane_strstatus (status)); 959141cc406Sopenharmony_ci return (status); 960141cc406Sopenharmony_ci } 961141cc406Sopenharmony_ci 962141cc406Sopenharmony_ci mode_str = s->val[OPT_MODE].s; 963141cc406Sopenharmony_ci s->xres = s->val[OPT_X_RESOLUTION].w; 964141cc406Sopenharmony_ci s->yres = s->val[OPT_Y_RESOLUTION].w; 965141cc406Sopenharmony_ci s->ulx = s->val[OPT_TL_X].w; 966141cc406Sopenharmony_ci s->uly = s->val[OPT_TL_Y].w; 967141cc406Sopenharmony_ci s->width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w; 968141cc406Sopenharmony_ci s->length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w; 969141cc406Sopenharmony_ci s->brightness = s->val[OPT_BRIGHTNESS].w; 970141cc406Sopenharmony_ci s->contrast = s->val[OPT_CONTRAST].w; 971141cc406Sopenharmony_ci s->bpp = s->params.depth; 972141cc406Sopenharmony_ci if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART) == 0) 973141cc406Sopenharmony_ci { 974141cc406Sopenharmony_ci s->image_composition = IBM_BINARY_MONOCHROME; 975141cc406Sopenharmony_ci } 976141cc406Sopenharmony_ci else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE) == 0) 977141cc406Sopenharmony_ci { 978141cc406Sopenharmony_ci s->image_composition = IBM_DITHERED_MONOCHROME; 979141cc406Sopenharmony_ci } 980141cc406Sopenharmony_ci else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY) == 0) 981141cc406Sopenharmony_ci { 982141cc406Sopenharmony_ci s->image_composition = IBM_GRAYSCALE; 983141cc406Sopenharmony_ci } 984141cc406Sopenharmony_ci 985141cc406Sopenharmony_ci memset (&wbuf, 0, sizeof (wbuf)); 986141cc406Sopenharmony_ci/* next line commented out by mf */ 987141cc406Sopenharmony_ci/* _lto2b(sizeof(wbuf) - 8, wbuf.len); */ 988141cc406Sopenharmony_ci/* next line by mf */ 989141cc406Sopenharmony_ci _lto2b(IBM_WINDOW_DATA_SIZE, wbuf.len); /* size=320 */ 990141cc406Sopenharmony_ci _lto2b(s->xres, wbuf.x_res); 991141cc406Sopenharmony_ci _lto2b(s->yres, wbuf.y_res); 992141cc406Sopenharmony_ci _lto4b(s->ulx, wbuf.x_org); 993141cc406Sopenharmony_ci _lto4b(s->uly, wbuf.y_org); 994141cc406Sopenharmony_ci _lto4b(s->width, wbuf.width); 995141cc406Sopenharmony_ci _lto4b(s->length, wbuf.length); 996141cc406Sopenharmony_ci 997141cc406Sopenharmony_ci wbuf.image_comp = s->image_composition; 998141cc406Sopenharmony_ci /* if you throw the MRIF bit the brightness control reverses too */ 999141cc406Sopenharmony_ci /* so I reverse the reversal in software for symmetry's sake */ 1000141cc406Sopenharmony_ci if (wbuf.image_comp == IBM_GRAYSCALE || wbuf.image_comp == IBM_DITHERED_MONOCHROME) 1001141cc406Sopenharmony_ci { 1002141cc406Sopenharmony_ci if (wbuf.image_comp == IBM_GRAYSCALE) 1003141cc406Sopenharmony_ci wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x80; /* it was 0x90 */ 1004141cc406Sopenharmony_ci if (wbuf.image_comp == IBM_DITHERED_MONOCHROME) 1005141cc406Sopenharmony_ci wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x10; 1006141cc406Sopenharmony_ci wbuf.brightness = 256 - (SANE_Byte) s->brightness; 1007141cc406Sopenharmony_ci/* 1008141cc406Sopenharmony_ci if (is50) 1009141cc406Sopenharmony_ci wbuf.contrast = (SANE_Byte) s->contrast; 1010141cc406Sopenharmony_ci else 1011141cc406Sopenharmony_ci*/ 1012141cc406Sopenharmony_ci wbuf.contrast = 256 - (SANE_Byte) s->contrast; 1013141cc406Sopenharmony_ci } 1014141cc406Sopenharmony_ci else /* wbuf.image_comp == IBM_BINARY_MONOCHROME */ 1015141cc406Sopenharmony_ci { 1016141cc406Sopenharmony_ci wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x00; 1017141cc406Sopenharmony_ci wbuf.brightness = (SANE_Byte) s->brightness; 1018141cc406Sopenharmony_ci wbuf.contrast = (SANE_Byte) s->contrast; 1019141cc406Sopenharmony_ci } 1020141cc406Sopenharmony_ci 1021141cc406Sopenharmony_ci wbuf.threshold = 0; 1022141cc406Sopenharmony_ci wbuf.bits_per_pixel = s->bpp; 1023141cc406Sopenharmony_ci 1024141cc406Sopenharmony_ci wbuf.halftone_code = 2; /* diithering */ 1025141cc406Sopenharmony_ci wbuf.halftone_id = 0x0A; /* 8x8 Bayer pattenr */ 1026141cc406Sopenharmony_ci wbuf.pad_type = 3; 1027141cc406Sopenharmony_ci wbuf.bit_ordering[0] = 0; 1028141cc406Sopenharmony_ci wbuf.bit_ordering[1] = 7; /* modified by mf (it was 3) */ 1029141cc406Sopenharmony_ci 1030141cc406Sopenharmony_ci DBG (5, "xres=%d\n", _2btol(wbuf.x_res)); 1031141cc406Sopenharmony_ci DBG (5, "yres=%d\n", _2btol(wbuf.y_res)); 1032141cc406Sopenharmony_ci DBG (5, "ulx=%d\n", _4btol(wbuf.x_org)); 1033141cc406Sopenharmony_ci DBG (5, "uly=%d\n", _4btol(wbuf.y_org)); 1034141cc406Sopenharmony_ci DBG (5, "width=%d\n", _4btol(wbuf.width)); 1035141cc406Sopenharmony_ci DBG (5, "length=%d\n", _4btol(wbuf.length)); 1036141cc406Sopenharmony_ci DBG (5, "image_comp=%d\n", wbuf.image_comp); 1037141cc406Sopenharmony_ci 1038141cc406Sopenharmony_ci DBG (11, "sane_start: sending SET WINDOW\n"); 1039141cc406Sopenharmony_ci status = set_window (s->fd, &wbuf); 1040141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1041141cc406Sopenharmony_ci { 1042141cc406Sopenharmony_ci DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status)); 1043141cc406Sopenharmony_ci return (status); 1044141cc406Sopenharmony_ci } 1045141cc406Sopenharmony_ci 1046141cc406Sopenharmony_ci DBG (11, "sane_start: sending GET WINDOW\n"); 1047141cc406Sopenharmony_ci memset (&wbuf, 0, sizeof (wbuf)); 1048141cc406Sopenharmony_ci status = get_window (s->fd, &wbuf); 1049141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1050141cc406Sopenharmony_ci { 1051141cc406Sopenharmony_ci DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status)); 1052141cc406Sopenharmony_ci return (status); 1053141cc406Sopenharmony_ci } 1054141cc406Sopenharmony_ci DBG (5, "xres=%d\n", _2btol(wbuf.x_res)); 1055141cc406Sopenharmony_ci DBG (5, "yres=%d\n", _2btol(wbuf.y_res)); 1056141cc406Sopenharmony_ci DBG (5, "ulx=%d\n", _4btol(wbuf.x_org)); 1057141cc406Sopenharmony_ci DBG (5, "uly=%d\n", _4btol(wbuf.y_org)); 1058141cc406Sopenharmony_ci DBG (5, "width=%d\n", _4btol(wbuf.width)); 1059141cc406Sopenharmony_ci DBG (5, "length=%d\n", _4btol(wbuf.length)); 1060141cc406Sopenharmony_ci DBG (5, "image_comp=%d\n", wbuf.image_comp); 1061141cc406Sopenharmony_ci 1062141cc406Sopenharmony_ci DBG (11, "sane_start: sending MODE SELECT\n"); 1063141cc406Sopenharmony_ci memset (&mup, 0, sizeof (mup)); 1064141cc406Sopenharmony_ci mup.page_code = MEASUREMENTS_PAGE; 1065141cc406Sopenharmony_ci mup.parameter_length = 0x06; 1066141cc406Sopenharmony_ci mup.bmu = INCHES; 1067141cc406Sopenharmony_ci mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff; 1068141cc406Sopenharmony_ci mup.mud[1] = (DEFAULT_MUD & 0xff); 1069141cc406Sopenharmony_ci/* next lines by mf */ 1070141cc406Sopenharmony_ci mup.adf_page_code = 0x26; 1071141cc406Sopenharmony_ci mup.adf_parameter_length = 6; 1072141cc406Sopenharmony_ci if (s->adf_state == ADF_ARMED) 1073141cc406Sopenharmony_ci mup.adf_control = 1; 1074141cc406Sopenharmony_ci else 1075141cc406Sopenharmony_ci mup.adf_control = 0; 1076141cc406Sopenharmony_ci/* end lines by mf */ 1077141cc406Sopenharmony_ci 1078141cc406Sopenharmony_ci status = mode_select (s->fd, (struct mode_pages *) &mup); 1079141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1080141cc406Sopenharmony_ci { 1081141cc406Sopenharmony_ci DBG (1, "attach: MODE_SELECT failed\n"); 1082141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 1083141cc406Sopenharmony_ci } 1084141cc406Sopenharmony_ci 1085141cc406Sopenharmony_ci status = trigger_scan (s->fd); 1086141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1087141cc406Sopenharmony_ci { 1088141cc406Sopenharmony_ci DBG (1, "start of scan failed: %s\n", sane_strstatus (status)); 1089141cc406Sopenharmony_ci /* next line introduced not to freeze xscanimage */ 1090141cc406Sopenharmony_ci do_cancel(s); 1091141cc406Sopenharmony_ci return status; 1092141cc406Sopenharmony_ci } 1093141cc406Sopenharmony_ci 1094141cc406Sopenharmony_ci /* Wait for scanner to become ready to transmit data */ 1095141cc406Sopenharmony_ci status = ibm_wait_ready (s); 1096141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1097141cc406Sopenharmony_ci { 1098141cc406Sopenharmony_ci DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status)); 1099141cc406Sopenharmony_ci return (status); 1100141cc406Sopenharmony_ci } 1101141cc406Sopenharmony_ci 1102141cc406Sopenharmony_ci s->bytes_to_read = s->params.bytes_per_line * s->params.lines; 1103141cc406Sopenharmony_ci 1104141cc406Sopenharmony_ci DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, " 1105141cc406Sopenharmony_ci "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line, 1106141cc406Sopenharmony_ci s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w); 1107141cc406Sopenharmony_ci 1108141cc406Sopenharmony_ci s->scanning = SANE_TRUE; 1109141cc406Sopenharmony_ci 1110141cc406Sopenharmony_ci DBG (11, "<< sane_start\n"); 1111141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 1112141cc406Sopenharmony_ci} 1113141cc406Sopenharmony_ci 1114141cc406Sopenharmony_ciSANE_Status 1115141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 1116141cc406Sopenharmony_ci SANE_Int * len) 1117141cc406Sopenharmony_ci{ 1118141cc406Sopenharmony_ci Ibm_Scanner *s = handle; 1119141cc406Sopenharmony_ci SANE_Status status; 1120141cc406Sopenharmony_ci size_t nread; 1121141cc406Sopenharmony_ci DBG (11, ">> sane_read\n"); 1122141cc406Sopenharmony_ci 1123141cc406Sopenharmony_ci *len = 0; 1124141cc406Sopenharmony_ci 1125141cc406Sopenharmony_ci DBG (11, "sane_read: bytes left to read: %ld\n", (u_long) s->bytes_to_read); 1126141cc406Sopenharmony_ci 1127141cc406Sopenharmony_ci if (s->bytes_to_read == 0) 1128141cc406Sopenharmony_ci { 1129141cc406Sopenharmony_ci do_cancel (s); 1130141cc406Sopenharmony_ci return (SANE_STATUS_EOF); 1131141cc406Sopenharmony_ci } 1132141cc406Sopenharmony_ci 1133141cc406Sopenharmony_ci if (!s->scanning) { 1134141cc406Sopenharmony_ci DBG (11, "sane_read: scanning is false!\n"); 1135141cc406Sopenharmony_ci return (do_cancel (s)); 1136141cc406Sopenharmony_ci } 1137141cc406Sopenharmony_ci 1138141cc406Sopenharmony_ci nread = max_len; 1139141cc406Sopenharmony_ci if (nread > s->bytes_to_read) 1140141cc406Sopenharmony_ci nread = s->bytes_to_read; 1141141cc406Sopenharmony_ci 1142141cc406Sopenharmony_ci DBG (11, "sane_read: read %ld bytes\n", (u_long) nread); 1143141cc406Sopenharmony_ci status = read_data (s->fd, buf, &nread); 1144141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1145141cc406Sopenharmony_ci { 1146141cc406Sopenharmony_ci DBG (11, "sane_read: read error\n"); 1147141cc406Sopenharmony_ci do_cancel (s); 1148141cc406Sopenharmony_ci return (SANE_STATUS_IO_ERROR); 1149141cc406Sopenharmony_ci } 1150141cc406Sopenharmony_ci *len = nread; 1151141cc406Sopenharmony_ci s->bytes_to_read -= nread; 1152141cc406Sopenharmony_ci 1153141cc406Sopenharmony_ci DBG (11, "<< sane_read\n"); 1154141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 1155141cc406Sopenharmony_ci} 1156141cc406Sopenharmony_ci 1157141cc406Sopenharmony_civoid 1158141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 1159141cc406Sopenharmony_ci{ 1160141cc406Sopenharmony_ci Ibm_Scanner *s = handle; 1161141cc406Sopenharmony_ci DBG (11, ">> sane_cancel\n"); 1162141cc406Sopenharmony_ci 1163141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 1164141cc406Sopenharmony_ci 1165141cc406Sopenharmony_ci DBG (11, "<< sane_cancel\n"); 1166141cc406Sopenharmony_ci} 1167141cc406Sopenharmony_ci 1168141cc406Sopenharmony_ciSANE_Status 1169141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 1170141cc406Sopenharmony_ci{ 1171141cc406Sopenharmony_ci DBG (5, ">> sane_set_io_mode (handle = %p, non_blocking = %d)\n", 1172141cc406Sopenharmony_ci handle, non_blocking); 1173141cc406Sopenharmony_ci DBG (5, "<< sane_set_io_mode\n"); 1174141cc406Sopenharmony_ci 1175141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1176141cc406Sopenharmony_ci} 1177141cc406Sopenharmony_ci 1178141cc406Sopenharmony_ciSANE_Status 1179141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 1180141cc406Sopenharmony_ci{ 1181141cc406Sopenharmony_ci DBG (5, ">> sane_get_select_fd (handle = %p, fd = %p)\n", 1182141cc406Sopenharmony_ci handle, (void *) fd); 1183141cc406Sopenharmony_ci DBG (5, "<< sane_get_select_fd\n"); 1184141cc406Sopenharmony_ci 1185141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1186141cc406Sopenharmony_ci} 1187