1/* sane - Scanner Access Now Easy. 2 Copyright (C) 1999 Juergen G. Schimmer 3 Updates and bugfixes (C) 2002 - 2004 Henning Meier-Geinitz 4 5 This file is part of the SANE package. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the 10 License, or (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. 19 20 As a special exception, the authors of SANE give permission for 21 additional uses of the libraries contained in this release of SANE. 22 23 The exception is that, if you link a SANE library with other files 24 to produce an executable, this does not by itself cause the 25 resulting executable to be covered by the GNU General Public 26 License. Your use of that executable is in no way restricted on 27 account of linking the SANE library code into it. 28 29 This exception does not, however, invalidate any other reasons why 30 the executable file might be covered by the GNU General Public 31 License. 32 33 If you submit changes to SANE to the maintainers to be included in 34 a subsequent release, you agree by submitting the changes that 35 those changes may be distributed with this exception intact. 36 37 If you write modifications of your own for SANE, it is your choice 38 whether to permit this exception to apply to your modifications. 39 If you do not wish that, delete this exception notice. 40 41 This file implements a SANE backend for v4l-Devices. 42*/ 43 44#define BUILD 5 45 46#include "../include/sane/config.h" 47 48#include <assert.h> 49#include <ctype.h> 50#include <errno.h> 51#include <fcntl.h> 52#include <limits.h> 53#include <math.h> 54#include <setjmp.h> 55#include <signal.h> 56#include <stdio.h> 57#include <stdlib.h> 58#include <string.h> 59#include <sys/types.h> 60#include <sys/wait.h> 61#include <unistd.h> 62#include <sys/mman.h> 63 64#include <unistd.h> 65#include <sys/time.h> 66#include <sys/stat.h> 67 68#include "../include/sane/sane.h" 69#include "../include/sane/sanei.h" 70#include "../include/sane/saneopts.h" 71 72#include <sys/ioctl.h> 73 74#define BACKEND_NAME v4l 75#include "../include/sane/sanei_backend.h" 76 77#ifndef PATH_MAX 78# define PATH_MAX 1024 79#endif 80 81#include "../include/sane/sanei_config.h" 82#define V4L_CONFIG_FILE "v4l.conf" 83 84#include <libv4l1.h> 85#include "v4l.h" 86 87static const SANE_Device **devlist = NULL; 88static int num_devices; 89static V4L_Device *first_dev; 90static V4L_Scanner *first_handle; 91static char *buffer; 92 93static const SANE_String_Const mode_list[] = { 94 SANE_VALUE_SCAN_MODE_GRAY, SANE_VALUE_SCAN_MODE_COLOR, 95 0 96}; 97 98static const SANE_Range u8_range = { 99 /* min, max, quantization */ 100 0, 255, 0 101}; 102 103static SANE_Range x_range = { 0, 338, 2 }; 104 105static SANE_Range odd_x_range = { 1, 339, 2 }; 106 107static SANE_Range y_range = { 0, 249, 1 }; 108 109static SANE_Range odd_y_range = { 1, 250, 1 }; 110 111 112static SANE_Parameters parms = { 113 SANE_FRAME_RGB, 114 1, /* 1 = Last Frame , 0 = More Frames to come */ 115 0, /* Number of bytes returned per scan line: */ 116 0, /* Number of pixels per scan line. */ 117 0, /* Number of lines for the current scan. */ 118 8, /* Number of bits per sample. */ 119}; 120 121static SANE_Status 122attach (const char *devname, V4L_Device ** devp) 123{ 124 V4L_Device *dev; 125 static int v4lfd; 126 static struct video_capability capability; 127 128 errno = 0; 129 130 for (dev = first_dev; dev; dev = dev->next) 131 if (strcmp (dev->sane.name, devname) == 0) 132 { 133 if (devp) 134 *devp = dev; 135 DBG (5, "attach: device %s is already known\n", devname); 136 return SANE_STATUS_GOOD; 137 } 138 139 DBG (3, "attach: trying to open %s\n", devname); 140 v4lfd = v4l1_open (devname, O_RDWR); 141 if (v4lfd != -1) 142 { 143 if (v4l1_ioctl (v4lfd, VIDIOCGCAP, &capability) == -1) 144 { 145 DBG (1, 146 "attach: ioctl (%d, VIDIOCGCAP,..) failed on `%s': %s\n", 147 v4lfd, devname, strerror (errno)); 148 v4l1_close (v4lfd); 149 return SANE_STATUS_INVAL; 150 } 151 if (!(VID_TYPE_CAPTURE & capability.type)) 152 { 153 DBG (1, "attach: device %s can't capture to memory -- exiting\n", 154 devname); 155 v4l1_close (v4lfd); 156 return SANE_STATUS_UNSUPPORTED; 157 } 158 DBG (2, "attach: found videodev `%s' on `%s'\n", capability.name, 159 devname); 160 v4l1_close (v4lfd); 161 } 162 else 163 { 164 DBG (1, "attach: failed to open device `%s': %s\n", devname, 165 strerror (errno)); 166 return SANE_STATUS_INVAL; 167 } 168 169 dev = malloc (sizeof (*dev)); 170 if (!dev) 171 return SANE_STATUS_NO_MEM; 172 173 memset (dev, 0, sizeof (*dev)); 174 175 dev->sane.name = strdup (devname); 176 if (!dev->sane.name) 177 return SANE_STATUS_NO_MEM; 178 dev->sane.vendor = "Noname"; 179 dev->sane.model = strdup (capability.name); 180 if (!dev->sane.model) 181 return SANE_STATUS_NO_MEM; 182 dev->sane.type = "virtual device"; 183 184 ++num_devices; 185 dev->next = first_dev; 186 first_dev = dev; 187 188 if (devp) 189 *devp = dev; 190 return SANE_STATUS_GOOD; 191} 192 193static void 194update_parameters (V4L_Scanner * s) 195{ 196 /* ??? should be per-device */ 197 x_range.min = 0; 198 x_range.max = s->capability.maxwidth - s->capability.minwidth; 199 x_range.quant = 1; 200 201 y_range.min = 0; 202 y_range.max = s->capability.maxheight - s->capability.minheight; 203 y_range.quant = 1; 204 205 odd_x_range.min = s->capability.minwidth; 206 odd_x_range.max = s->capability.maxwidth; 207 if (odd_x_range.max > 767) 208 { 209 odd_x_range.max = 767; 210 x_range.max = 767 - s->capability.minwidth; 211 }; 212 odd_x_range.quant = 1; 213 214 odd_y_range.min = s->capability.minheight; 215 odd_y_range.max = s->capability.maxheight; 216 if (odd_y_range.max > 511) 217 { 218 odd_y_range.max = 511; 219 y_range.max = 511 - s->capability.minheight; 220 }; 221 odd_y_range.quant = 1; 222 223 parms.lines = s->window.height; 224 parms.pixels_per_line = s->window.width; 225 226 switch (s->pict.palette) 227 { 228 case VIDEO_PALETTE_GREY: /* Linear greyscale */ 229 { 230 parms.format = SANE_FRAME_GRAY; 231 parms.depth = 8; 232 parms.bytes_per_line = s->window.width; 233 break; 234 } 235 case VIDEO_PALETTE_RGB24: /* 24bit RGB */ 236 { 237 parms.format = SANE_FRAME_RGB; 238 parms.depth = 8; 239 parms.bytes_per_line = s->window.width * 3; 240 break; 241 } 242 default: 243 { 244 parms.format = SANE_FRAME_GRAY; 245 parms.bytes_per_line = s->window.width; 246 break; 247 } 248 } 249} 250 251static SANE_Status 252init_options (V4L_Scanner * s) 253{ 254 int i; 255 256 memset (s->opt, 0, sizeof (s->opt)); 257 memset (s->val, 0, sizeof (s->val)); 258 259 for (i = 0; i < NUM_OPTIONS; ++i) 260 { 261 s->opt[i].size = sizeof (SANE_Word); 262 s->opt[i].cap = (SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT); 263 } 264 265 /* Number of options */ 266 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 267 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 268 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 269 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 270 s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 271 272 /* "Mode" group: */ 273 s->opt[OPT_MODE_GROUP].title = "Scan Mode"; 274 s->opt[OPT_MODE_GROUP].desc = ""; 275 s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 276 s->opt[OPT_MODE_GROUP].cap = 0; 277 s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 278 279 /* mode */ 280 s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 281 s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 282 s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 283 s->opt[OPT_MODE].type = SANE_TYPE_STRING; 284 s->opt[OPT_MODE].unit = SANE_UNIT_NONE; 285 s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 286 s->opt[OPT_MODE].constraint.string_list = mode_list; 287 s->val[OPT_MODE].s = strdup (mode_list[0]); 288 if (!s->val[OPT_MODE].s) 289 return SANE_STATUS_NO_MEM; 290 s->opt[OPT_MODE].size = 1; /* '\0' */ 291 for (i = 0; mode_list[i] != 0; ++i) 292 { 293 int len = strlen(mode_list[i]) + 1; 294 if (s->opt[OPT_MODE].size < len) 295 s->opt[OPT_MODE].size = len; 296 } 297 298 /* channel */ 299 s->opt[OPT_CHANNEL].name = "channel"; 300 s->opt[OPT_CHANNEL].title = "Channel"; 301 s->opt[OPT_CHANNEL].desc = 302 "Selects the channel of the v4l device (e.g. television " "or video-in."; 303 s->opt[OPT_CHANNEL].type = SANE_TYPE_STRING; 304 s->opt[OPT_CHANNEL].unit = SANE_UNIT_NONE; 305 s->opt[OPT_CHANNEL].constraint_type = SANE_CONSTRAINT_STRING_LIST; 306 s->opt[OPT_CHANNEL].constraint.string_list = s->channel; 307 s->val[OPT_CHANNEL].s = strdup (s->channel[0]); 308 if (!s->val[OPT_CHANNEL].s) 309 return SANE_STATUS_NO_MEM; 310 if (s->channel[0] == 0 || s->channel[1] == 0) 311 s->opt[OPT_CHANNEL].cap |= SANE_CAP_INACTIVE; 312 s->opt[OPT_CHANNEL].size = 1; /* '\0' */ 313 for (i = 0; s->channel[i] != 0; ++i) 314 { 315 int len = strlen(s->channel[i]) + 1; 316 if (s->opt[OPT_CHANNEL].size < len) 317 s->opt[OPT_CHANNEL].size = len; 318 } 319 320 /* "Geometry" group: */ 321 s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 322 s->opt[OPT_GEOMETRY_GROUP].desc = ""; 323 s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 324 s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 325 s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 326 327/* top-left x *//* ??? first check if window is settable at all */ 328 s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 329 s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 330 s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 331 s->opt[OPT_TL_X].type = SANE_TYPE_INT; 332 s->opt[OPT_TL_X].unit = SANE_UNIT_PIXEL; 333 s->opt[OPT_TL_X].cap |= SANE_CAP_INACTIVE; 334 s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 335 s->opt[OPT_TL_X].constraint.range = &x_range; 336 s->val[OPT_TL_X].w = 0; 337 338 /* top-left y */ 339 s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 340 s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 341 s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 342 s->opt[OPT_TL_Y].type = SANE_TYPE_INT; 343 s->opt[OPT_TL_Y].unit = SANE_UNIT_PIXEL; 344 s->opt[OPT_TL_Y].cap |= SANE_CAP_INACTIVE; 345 s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 346 s->opt[OPT_TL_Y].constraint.range = &y_range; 347 s->val[OPT_TL_Y].w = 0; 348 349 /* bottom-right x */ 350 s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 351 s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 352 s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 353 s->opt[OPT_BR_X].type = SANE_TYPE_INT; 354 s->opt[OPT_BR_X].unit = SANE_UNIT_PIXEL; 355 s->opt[OPT_BR_X].cap |= SANE_CAP_INACTIVE; 356 s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 357 s->opt[OPT_BR_X].constraint.range = &odd_x_range; 358 s->val[OPT_BR_X].w = s->capability.maxwidth; 359 if (s->val[OPT_BR_X].w > 767) 360 s->val[OPT_BR_X].w = 767; 361 362 /* bottom-right y */ 363 s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 364 s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 365 s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 366 s->opt[OPT_BR_Y].type = SANE_TYPE_INT; 367 s->opt[OPT_BR_Y].unit = SANE_UNIT_PIXEL; 368 s->opt[OPT_BR_Y].cap |= SANE_CAP_INACTIVE; 369 s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 370 s->opt[OPT_BR_Y].constraint.range = &odd_y_range; 371 s->val[OPT_BR_Y].w = s->capability.maxheight; 372 if (s->val[OPT_BR_Y].w > 511) 373 s->val[OPT_BR_Y].w = 511; 374 375 /* "Enhancement" group: */ 376 s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 377 s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 378 s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 379 s->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 380 s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 381 382 /* brightness */ 383 s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS; 384 s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS; 385 s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS; 386 s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT; 387 s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE; 388 s->opt[OPT_BRIGHTNESS].constraint.range = &u8_range; 389 s->val[OPT_BRIGHTNESS].w = s->pict.brightness / 256; 390 391 /* hue */ 392 s->opt[OPT_HUE].name = SANE_NAME_HUE; 393 s->opt[OPT_HUE].title = SANE_TITLE_HUE; 394 s->opt[OPT_HUE].desc = SANE_DESC_HUE; 395 s->opt[OPT_HUE].type = SANE_TYPE_INT; 396 s->opt[OPT_HUE].constraint_type = SANE_CONSTRAINT_RANGE; 397 s->opt[OPT_HUE].constraint.range = &u8_range; 398 s->val[OPT_HUE].w = s->pict.hue / 256; 399 400 /* colour */ 401 s->opt[OPT_COLOR].name = "color"; 402 s->opt[OPT_COLOR].title = "Picture color"; 403 s->opt[OPT_COLOR].desc = "Sets the picture's color."; 404 s->opt[OPT_COLOR].type = SANE_TYPE_INT; 405 s->opt[OPT_COLOR].constraint_type = SANE_CONSTRAINT_RANGE; 406 s->opt[OPT_COLOR].constraint.range = &u8_range; 407 s->val[OPT_COLOR].w = s->pict.colour / 256; 408 409 /* contrast */ 410 s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST; 411 s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST; 412 s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST; 413 s->opt[OPT_CONTRAST].type = SANE_TYPE_INT; 414 s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE; 415 s->opt[OPT_CONTRAST].constraint.range = &u8_range; 416 s->val[OPT_CONTRAST].w = s->pict.contrast / 256; 417 418 /* whiteness */ 419 s->opt[OPT_WHITE_LEVEL].name = SANE_NAME_WHITE_LEVEL; 420 s->opt[OPT_WHITE_LEVEL].title = SANE_TITLE_WHITE_LEVEL; 421 s->opt[OPT_WHITE_LEVEL].desc = SANE_DESC_WHITE_LEVEL; 422 s->opt[OPT_WHITE_LEVEL].type = SANE_TYPE_INT; 423 s->opt[OPT_WHITE_LEVEL].constraint_type = SANE_CONSTRAINT_RANGE; 424 s->opt[OPT_WHITE_LEVEL].constraint.range = &u8_range; 425 s->val[OPT_WHITE_LEVEL].w = s->pict.whiteness / 256; 426 427 return SANE_STATUS_GOOD; 428} 429 430SANE_Status 431sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 432{ 433 char dev_name[PATH_MAX], *str; 434 size_t len; 435 FILE *fp; 436 437 (void) authorize; /* stop gcc from complaining */ 438 DBG_INIT (); 439 440 DBG (2, "SANE v4l backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR, 441 SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); 442 443 if (version_code) 444 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 445 446 fp = sanei_config_open (V4L_CONFIG_FILE); 447 if (!fp) 448 { 449 DBG (2, 450 "sane_init: file `%s' not accessible (%s), trying /dev/video0\n", 451 V4L_CONFIG_FILE, strerror (errno)); 452 453 return attach ("/dev/video0", 0); 454 } 455 456 while (sanei_config_read (dev_name, sizeof (dev_name), fp)) 457 { 458 if (dev_name[0] == '#') /* ignore line comments */ 459 continue; 460 len = strlen (dev_name); 461 462 if (!len) 463 continue; /* ignore empty lines */ 464 465 /* Remove trailing space and trailing comments */ 466 for (str = dev_name; *str && !isspace (*str) && *str != '#'; ++str); 467 attach (dev_name, 0); 468 } 469 fclose (fp); 470 return SANE_STATUS_GOOD; 471} 472 473void 474sane_exit (void) 475{ 476 V4L_Device *dev, *next; 477 478 for (dev = first_dev; dev; dev = next) 479 { 480 next = dev->next; 481 free ((void *) dev->sane.name); 482 free ((void *) dev->sane.model); 483 free (dev); 484 } 485 486 if (NULL != devlist) 487 { 488 free (devlist); 489 devlist = NULL; 490 } 491 DBG (5, "sane_exit: all devices freed\n"); 492} 493 494SANE_Status 495sane_get_devices (const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only) 496{ 497 V4L_Device *dev; 498 int i; 499 500 DBG (5, "sane_get_devices\n"); 501 502 if (devlist) 503 free (devlist); 504 505 devlist = malloc ((num_devices + 1) * sizeof (devlist[0])); 506 if (!devlist) 507 return SANE_STATUS_NO_MEM; 508 509 i = 0; 510 for (dev = first_dev; i < num_devices; dev = dev->next) 511 devlist[i++] = &dev->sane; 512 devlist[i++] = 0; 513 514 *device_list = devlist; 515 return SANE_STATUS_GOOD; 516} 517 518SANE_Status 519sane_open (SANE_String_Const devname, SANE_Handle * handle) 520{ 521 V4L_Device *dev; 522 V4L_Scanner *s; 523 static int v4lfd; 524 int i; 525 struct video_channel channel; 526 SANE_Status status; 527 int max_channels = MAX_CHANNELS; 528 529 if (!devname) 530 { 531 DBG (1, "sane_open: devname == 0\n"); 532 return SANE_STATUS_INVAL; 533 } 534 535 for (dev = first_dev; dev; dev = dev->next) 536 if (strcmp (dev->sane.name, devname) == 0) 537 { 538 DBG (5, "sane_open: device %s found in devlist\n", devname); 539 break; 540 } 541 if (!devname[0]) 542 dev = first_dev; 543 if (!dev) 544 { 545 DBG (1, "sane_open: device %s doesn't seem to be a v4l " 546 "device\n", devname); 547 return SANE_STATUS_INVAL; 548 } 549 550 v4lfd = v4l1_open (devname, O_RDWR); 551 if (v4lfd == -1) 552 { 553 DBG (1, "sane_open: can't open %s (%s)\n", devname, strerror (errno)); 554 return SANE_STATUS_INVAL; 555 } 556 s = malloc (sizeof (*s)); 557 if (!s) 558 return SANE_STATUS_NO_MEM; 559 memset (s, 0, sizeof (*s)); 560 s->user_corner = 0; /* ??? */ 561 s->devicename = devname; 562 s->fd = v4lfd; 563 564 if (v4l1_ioctl (s->fd, VIDIOCGCAP, &s->capability) == -1) 565 { 566 DBG (1, "sane_open: ioctl (%d, VIDIOCGCAP,..) failed on `%s': %s\n", 567 s->fd, devname, strerror (errno)); 568 v4l1_close (s->fd); 569 return SANE_STATUS_INVAL; 570 } 571 572 DBG (5, "sane_open: %d channels, %d audio devices\n", 573 s->capability.channels, s->capability.audios); 574 DBG (5, "sane_open: minwidth=%d, minheight=%d, maxwidth=%d, " 575 "maxheight=%d\n", s->capability.minwidth, s->capability.minheight, 576 s->capability.maxwidth, s->capability.maxheight); 577 if (VID_TYPE_CAPTURE & s->capability.type) 578 DBG (5, "sane_open: V4L device can capture to memory\n"); 579 if (VID_TYPE_TUNER & s->capability.type) 580 DBG (5, "sane_open: V4L device has a tuner of some form\n"); 581 if (VID_TYPE_TELETEXT & s->capability.type) 582 DBG (5, "sane_open: V4L device supports teletext\n"); 583 if (VID_TYPE_OVERLAY & s->capability.type) 584 DBG (5, "sane_open: V4L device can overlay its image onto the frame " 585 "buffer\n"); 586 if (VID_TYPE_CHROMAKEY & s->capability.type) 587 DBG (5, "sane_open: V4L device uses chromakey on overlay\n"); 588 if (VID_TYPE_CLIPPING & s->capability.type) 589 DBG (5, "sane_open: V4L device supports overlay clipping\n"); 590 if (VID_TYPE_FRAMERAM & s->capability.type) 591 DBG (5, "sane_open: V4L device overwrites frame buffer memory\n"); 592 if (VID_TYPE_SCALES & s->capability.type) 593 DBG (5, "sane_open: V4L device supports hardware scaling\n"); 594 if (VID_TYPE_MONOCHROME & s->capability.type) 595 DBG (5, "sane_open: V4L device is grey scale only\n"); 596 if (VID_TYPE_SUBCAPTURE & s->capability.type) 597 DBG (5, "sane_open: V4L device can capture parts of the image\n"); 598 599 if (s->capability.channels < max_channels) 600 max_channels = s->capability.channels; 601 for (i = 0; i < max_channels; i++) 602 { 603 channel.channel = i; 604 if (-1 == v4l1_ioctl (v4lfd, VIDIOCGCHAN, &channel)) 605 { 606 DBG (1, "sane_open: can't ioctl VIDIOCGCHAN %s: %s\n", devname, 607 strerror (errno)); 608 return SANE_STATUS_INVAL; 609 } 610 DBG (5, "sane_open: channel %d (%s), tuners=%d, flags=0x%x, " 611 "type=%d, norm=%d\n", channel.channel, channel.name, 612 channel.tuners, channel.flags, channel.type, channel.norm); 613 if (VIDEO_VC_TUNER & channel.flags) 614 DBG (5, "sane_open: channel has tuner(s)\n"); 615 if (VIDEO_VC_AUDIO & channel.flags) 616 DBG (5, "sane_open: channel has audio\n"); 617 if (VIDEO_TYPE_TV == channel.type) 618 DBG (5, "sane_open: input is TV input\n"); 619 if (VIDEO_TYPE_CAMERA == channel.type) 620 DBG (5, "sane_open: input is camera input\n"); 621 s->channel[i] = strdup (channel.name); 622 if (!s->channel[i]) 623 return SANE_STATUS_NO_MEM; 624 } 625 s->channel[i] = 0; 626 if (-1 == v4l1_ioctl (v4lfd, VIDIOCGPICT, &s->pict)) 627 { 628 DBG (1, "sane_open: can't ioctl VIDIOCGPICT %s: %s\n", devname, 629 strerror (errno)); 630 return SANE_STATUS_INVAL; 631 } 632 DBG (5, "sane_open: brightness=%d, hue=%d, colour=%d, contrast=%d\n", 633 s->pict.brightness, s->pict.hue, s->pict.colour, s->pict.contrast); 634 DBG (5, "sane_open: whiteness=%d, depth=%d, palette=%d\n", 635 s->pict.whiteness, s->pict.depth, s->pict.palette); 636 637 /* ??? */ 638 s->pict.palette = VIDEO_PALETTE_GREY; 639 if (-1 == v4l1_ioctl (s->fd, VIDIOCSPICT, &s->pict)) 640 { 641 DBG (1, "sane_open: ioctl VIDIOCSPICT failed (%s)\n", strerror (errno)); 642 } 643 644 if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window)) 645 { 646 DBG (1, "sane_open: can't ioctl VIDIOCGWIN %s: %s\n", devname, 647 strerror (errno)); 648 return SANE_STATUS_INVAL; 649 } 650 DBG (5, "sane_open: x=%d, y=%d, width=%d, height=%d\n", 651 s->window.x, s->window.y, s->window.width, s->window.height); 652 653 /* already done in sane_start 654 if (-1 == v4l1_ioctl (v4lfd, VIDIOCGMBUF, &mbuf)) 655 DBG (1, "sane_open: can't ioctl VIDIOCGMBUF (no Fbuffer?)\n"); 656 */ 657 658 status = init_options (s); 659 if (status != SANE_STATUS_GOOD) 660 return status; 661 update_parameters (s); 662 663 /* insert newly opened handle into list of open handles: */ 664 s->next = first_handle; 665 first_handle = s; 666 667 *handle = s; 668 669 return SANE_STATUS_GOOD; 670} 671 672void 673sane_close (SANE_Handle handle) 674{ 675 V4L_Scanner *prev, *s; 676 677 DBG (2, "sane_close: trying to close handle %p\n", (void *) handle); 678 /* remove handle from list of open handles: */ 679 prev = 0; 680 for (s = first_handle; s; s = s->next) 681 { 682 if (s == handle) 683 break; 684 prev = s; 685 } 686 if (!s) 687 { 688 DBG (1, "sane_close: bad handle %p\n", handle); 689 return; /* oops, not a handle we know about */ 690 } 691 if (prev) 692 prev->next = s->next; 693 else 694 first_handle = s->next; 695 696 if (s->scanning) 697 sane_cancel (handle); 698 v4l1_close (s->fd); 699 free (s); 700} 701 702const SANE_Option_Descriptor * 703sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 704{ 705 V4L_Scanner *s = handle; 706 707 if ((unsigned) option >= NUM_OPTIONS || option < 0) 708 return 0; 709 DBG (4, "sane_get_option_descriptor: option %d (%s)\n", option, 710 s->opt[option].name ? s->opt[option].name : s->opt[option].title); 711 return s->opt + option; 712} 713 714SANE_Status 715sane_control_option (SANE_Handle handle, SANE_Int option, 716 SANE_Action action, void *val, SANE_Int * info) 717{ 718 V4L_Scanner *s = handle; 719 SANE_Status status; 720 SANE_Word cap; 721 722 if (info) 723 *info = 0; 724 725 if (option >= NUM_OPTIONS || option < 0) 726 return SANE_STATUS_INVAL; 727 728 DBG (4, "sane_control_option: %s option %d (%s)\n", 729 action == SANE_ACTION_GET_VALUE ? "get" : 730 action == SANE_ACTION_SET_VALUE ? "set" : 731 action == SANE_ACTION_SET_AUTO ? "auto set" : 732 "(unknown action with)", option, 733 s->opt[option].name ? s->opt[option].name : s->opt[option].title); 734 735 cap = s->opt[option].cap; 736 737 if (!SANE_OPTION_IS_ACTIVE (cap)) 738 { 739 DBG (1, "sane_control option: option is inactive\n"); 740 return SANE_STATUS_INVAL; 741 } 742 743 if (action == SANE_ACTION_GET_VALUE) 744 { 745 switch (option) 746 { 747 /* word options: */ 748 case OPT_NUM_OPTS: 749 case OPT_TL_X: 750 case OPT_TL_Y: 751 case OPT_BR_X: 752 case OPT_BR_Y: 753 case OPT_BRIGHTNESS: 754 case OPT_HUE: 755 case OPT_COLOR: 756 case OPT_CONTRAST: 757 case OPT_WHITE_LEVEL: 758 *(SANE_Word *) val = s->val[option].w; 759 return SANE_STATUS_GOOD; 760 case OPT_CHANNEL: /* string list options */ 761 case OPT_MODE: 762 strcpy (val, s->val[option].s); 763 return SANE_STATUS_GOOD; 764 default: 765 DBG (1, "sane_control_option: option %d unknown\n", option); 766 } 767 } 768 else if (action == SANE_ACTION_SET_VALUE) 769 { 770 if (!SANE_OPTION_IS_SETTABLE (cap)) 771 { 772 DBG (1, "sane_control_option: option is not settable\n"); 773 return SANE_STATUS_INVAL; 774 } 775 status = sanei_constrain_value (s->opt + option, val, info); 776 if (status != SANE_STATUS_GOOD) 777 { 778 DBG (1, "sane_control_option: sanei_constarin_value failed: %s\n", 779 sane_strstatus (status)); 780 return status; 781 } 782 if (option >= OPT_TL_X && option <= OPT_BR_Y) 783 { 784 s->user_corner |= 1 << (option - OPT_TL_X); 785 if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window)) 786 { 787 DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed " 788 "(can not get window geometry)\n"); 789 return SANE_STATUS_INVAL; 790 } 791 s->window.clipcount = 0; 792 s->window.clips = 0; 793 s->window.height = parms.lines; 794 s->window.width = parms.pixels_per_line; 795 } 796 797 798 switch (option) 799 { 800 /* (mostly) side-effect-free word options: */ 801 case OPT_TL_X: 802 break; 803 case OPT_TL_Y: 804 break; 805 case OPT_BR_X: 806 s->window.width = *(SANE_Word *) val; 807 parms.pixels_per_line = *(SANE_Word *) val; 808 if (info) 809 *info |= SANE_INFO_RELOAD_PARAMS; 810 break; 811 case OPT_BR_Y: 812 s->window.height = *(SANE_Word *) val; 813 parms.lines = *(SANE_Word *) val; 814 if (info) 815 *info |= SANE_INFO_RELOAD_PARAMS; 816 break; 817 case OPT_MODE: 818 if (info) 819 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 820 s->val[option].s = strdup (val); 821 if (!s->val[option].s) 822 return SANE_STATUS_NO_MEM; 823 if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY) == 0) 824 s->pict.palette = VIDEO_PALETTE_GREY; 825 else 826 s->pict.palette = VIDEO_PALETTE_RGB24; 827 update_parameters (s); 828 break; 829 case OPT_BRIGHTNESS: 830 s->pict.brightness = *(SANE_Word *) val *256; 831 s->val[option].w = *(SANE_Word *) val; 832 break; 833 case OPT_HUE: 834 s->pict.hue = *(SANE_Word *) val *256; 835 s->val[option].w = *(SANE_Word *) val; 836 break; 837 case OPT_COLOR: 838 s->pict.colour = *(SANE_Word *) val *256; 839 s->val[option].w = *(SANE_Word *) val; 840 break; 841 case OPT_CONTRAST: 842 s->pict.contrast = *(SANE_Word *) val *256; 843 s->val[option].w = *(SANE_Word *) val; 844 break; 845 case OPT_WHITE_LEVEL: 846 s->pict.whiteness = *(SANE_Word *) val *256; 847 s->val[option].w = *(SANE_Word *) val; 848 break; 849 case OPT_CHANNEL: 850 { 851 int i; 852 struct video_channel channel; 853 854 s->val[option].s = strdup (val); 855 if (!s->val[option].s) 856 return SANE_STATUS_NO_MEM; 857 for (i = 0; i < MAX_CHANNELS; i++) 858 { 859 if (strcmp (s->channel[i], val) == 0) 860 { 861 channel.channel = i; 862 if (-1 == v4l1_ioctl (s->fd, VIDIOCGCHAN, &channel)) 863 { 864 DBG (1, "sane_open: can't ioctl VIDIOCGCHAN %s: %s\n", 865 s->devicename, strerror (errno)); 866 return SANE_STATUS_INVAL; 867 } 868 if (-1 == v4l1_ioctl (s->fd, VIDIOCSCHAN, &channel)) 869 { 870 DBG (1, "sane_open: can't ioctl VIDIOCSCHAN %s: %s\n", 871 s->devicename, strerror (errno)); 872 return SANE_STATUS_INVAL; 873 } 874 break; 875 } 876 } 877 return SANE_STATUS_GOOD; 878 break; 879 } 880 default: 881 DBG (1, "sane_control_option: option %d unknown\n", option); 882 return SANE_STATUS_INVAL; 883 } 884 if (option >= OPT_TL_X && option <= OPT_BR_Y) 885 { 886 if (-1 == v4l1_ioctl (s->fd, VIDIOCSWIN, &s->window)) 887 { 888 DBG (1, "sane_control_option: ioctl VIDIOCSWIN failed (%s)\n", 889 strerror (errno)); 890 /* return SANE_STATUS_INVAL; */ 891 } 892 if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window)) 893 { 894 DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed (%s)\n", 895 strerror (errno)); 896 return SANE_STATUS_INVAL; 897 } 898 } 899 if (option >= OPT_BRIGHTNESS && option <= OPT_WHITE_LEVEL) 900 { 901 if (-1 == v4l1_ioctl (s->fd, VIDIOCSPICT, &s->pict)) 902 { 903 DBG (1, "sane_control_option: ioctl VIDIOCSPICT failed (%s)\n", 904 strerror (errno)); 905 /* return SANE_STATUS_INVAL; */ 906 } 907 } 908 return SANE_STATUS_GOOD; 909 } 910 else if (action == SANE_ACTION_SET_AUTO) 911 { 912 if (!(cap & SANE_CAP_AUTOMATIC)) 913 { 914 DBG (1, "sane_control_option: option can't be set automatically\n"); 915 return SANE_STATUS_INVAL; 916 } 917 switch (option) 918 { 919 case OPT_BRIGHTNESS: 920 /* not implemented yet */ 921 return SANE_STATUS_GOOD; 922 923 default: 924 break; 925 } 926 } 927 return SANE_STATUS_INVAL; 928} 929 930SANE_Status 931sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 932{ 933 V4L_Scanner *s = handle; 934 935 DBG (4, "sane_get_parameters\n"); 936 update_parameters (s); 937 if (params == 0) 938 { 939 DBG (1, "sane_get_parameters: params == 0\n"); 940 return SANE_STATUS_INVAL; 941 } 942 if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window)) 943 { 944 DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed " 945 "(can not get window geometry)\n"); 946 return SANE_STATUS_INVAL; 947 } 948 parms.pixels_per_line = s->window.width; 949 parms.bytes_per_line = s->window.width; 950 if (parms.format == SANE_FRAME_RGB) 951 parms.bytes_per_line = s->window.width * 3; 952 parms.lines = s->window.height; 953 *params = parms; 954 return SANE_STATUS_GOOD; 955 956} 957 958SANE_Status 959sane_start (SANE_Handle handle) 960{ 961 int len; 962 V4L_Scanner *s; 963 char data; 964 965 DBG (2, "sane_start\n"); 966 for (s = first_handle; s; s = s->next) 967 { 968 if (s == handle) 969 break; 970 } 971 if (!s) 972 { 973 DBG (1, "sane_start: bad handle %p\n", handle); 974 return SANE_STATUS_INVAL; /* oops, not a handle we know about */ 975 } 976 len = v4l1_ioctl (s->fd, VIDIOCGCAP, &s->capability); 977 if (-1 == len) 978 { 979 DBG (1, "sane_start: can not get capabilities\n"); 980 return SANE_STATUS_INVAL; 981 } 982 s->buffercount = 0; 983 if (-1 == v4l1_ioctl (s->fd, VIDIOCGMBUF, &s->mbuf)) 984 { 985 s->is_mmap = SANE_FALSE; 986 buffer = 987 malloc (s->capability.maxwidth * s->capability.maxheight * 988 s->pict.depth); 989 if (0 == buffer) 990 return SANE_STATUS_NO_MEM; 991 DBG (3, "sane_start: V4L trying to read frame\n"); 992 len = v4l1_read (s->fd, buffer, parms.bytes_per_line * parms.lines); 993 DBG (3, "sane_start: %d bytes read\n", len); 994 } 995 else 996 { 997 int loop; 998 s->is_mmap = SANE_TRUE; 999 DBG (3, 1000 "sane_start: mmap frame, buffersize: %d bytes, buffers: %d, offset 0 %d\n", 1001 s->mbuf.size, s->mbuf.frames, s->mbuf.offsets[0]); 1002 buffer = 1003 v4l1_mmap (0, s->mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, 0); 1004 if (buffer == (void *)-1) 1005 { 1006 DBG (1, "sane_start: mmap failed: %s\n", strerror (errno)); 1007 buffer = NULL; 1008 return SANE_STATUS_IO_ERROR; 1009 } 1010 DBG (3, "sane_start: mmapped frame, capture 1 pict into %p\n", (void *) buffer); 1011 s->mmap.frame = 0; 1012 s->mmap.width = s->window.width; 1013 /* s->mmap.width = parms.pixels_per_line; ??? huh? */ 1014 s->mmap.height = s->window.height; 1015 /* s->mmap.height = parms.lines; ??? huh? */ 1016 s->mmap.format = s->pict.palette; 1017 DBG (2, "sane_start: mmapped frame %d x %d with palette %d\n", 1018 s->mmap.width, s->mmap.height, s->mmap.format); 1019 1020 /* We need to loop here to empty the read buffers, so we don't 1021 get a stale image */ 1022 for (loop = 0; loop <= s->mbuf.frames; loop++) 1023 { 1024 len = v4l1_ioctl (s->fd, VIDIOCMCAPTURE, &s->mmap); 1025 if (len == -1) 1026 { 1027 DBG (1, "sane_start: ioctl VIDIOCMCAPTURE failed: %s\n", 1028 strerror (errno)); 1029 return SANE_STATUS_INVAL; 1030 } 1031 DBG (3, "sane_start: waiting for frame %x, loop %d\n", s->mmap.frame, loop); 1032 len = v4l1_ioctl (s->fd, VIDIOCSYNC, &(s->mmap.frame)); 1033 if (-1 == len) 1034 { 1035 DBG (1, "sane_start: call to ioctl(%d, VIDIOCSYNC, ..) failed\n", 1036 s->fd); 1037 return SANE_STATUS_INVAL; 1038 } 1039 } 1040 DBG (3, "sane_start: frame %x done\n", s->mmap.frame); 1041 } 1042 1043 /* v4l1 actually returns BGR when we ask for RGB, so convert it */ 1044 if (s->pict.palette == VIDEO_PALETTE_RGB24) 1045 { 1046 uint32_t loop; 1047 DBG (3, "sane_start: converting from BGR to RGB\n"); 1048 for (loop = 0; loop < (s->window.width * s->window.height * 3); loop += 3) 1049 { 1050 data = *(buffer + loop); 1051 *(buffer + loop) = *(buffer + loop + 2); 1052 *(buffer + loop + 2) = data; 1053 } 1054 } 1055 1056 DBG (3, "sane_start: done\n"); 1057 return SANE_STATUS_GOOD; 1058} 1059 1060SANE_Status 1061sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 1062 SANE_Int * lenp) 1063{ 1064 int i, min; 1065 V4L_Scanner *s = handle; 1066 1067 DBG (4, "sane_read: max_len = %d\n", max_len); 1068 if (!lenp) 1069 { 1070 DBG (1, "sane_read: lenp == 0\n"); 1071 return SANE_STATUS_INVAL; 1072 } 1073 if ((s->buffercount + 1) > (parms.lines * parms.bytes_per_line)) 1074 { 1075 *lenp = 0; 1076 return SANE_STATUS_EOF; 1077 }; 1078 min = parms.lines * parms.bytes_per_line; 1079 if (min > (max_len + s->buffercount)) 1080 min = (max_len + s->buffercount); 1081 if (s->is_mmap == SANE_FALSE) 1082 { 1083 for (i = s->buffercount; i < (min + 0); i++) 1084 { 1085 *(buf + i - s->buffercount) = *(buffer + i); 1086 }; 1087 *lenp = (parms.lines * parms.bytes_per_line - s->buffercount); 1088 if (max_len < *lenp) 1089 *lenp = max_len; 1090 DBG (3, "sane_read: transferred %d bytes (from %d to %d)\n", *lenp, 1091 s->buffercount, i); 1092 s->buffercount = i; 1093 } 1094 else 1095 { 1096 for (i = s->buffercount; i < (min + 0); i++) 1097 { 1098 *(buf + i - s->buffercount) = *(buffer + i); 1099 }; 1100 *lenp = (parms.lines * parms.bytes_per_line - s->buffercount); 1101 if ((i - s->buffercount) < *lenp) 1102 *lenp = (i - s->buffercount); 1103 DBG (3, "sane_read: transferred %d bytes (from %d to %d)\n", *lenp, 1104 s->buffercount, i); 1105 s->buffercount = i; 1106 } 1107 return SANE_STATUS_GOOD; 1108} 1109 1110void 1111sane_cancel (SANE_Handle handle) 1112{ 1113 V4L_Scanner *s = handle; 1114 1115 DBG (2, "sane_cancel\n"); 1116 1117 /* ??? buffer isn't checked in sane_read? */ 1118 if (buffer) 1119 { 1120 if (s->is_mmap) 1121 v4l1_munmap(buffer, s->mbuf.size); 1122 else 1123 free (buffer); 1124 1125 buffer = NULL; 1126 } 1127} 1128 1129 1130SANE_Status 1131sane_set_io_mode (SANE_Handle __sane_unused__ handle, SANE_Bool non_blocking) 1132{ 1133 if (non_blocking == SANE_FALSE) 1134 return SANE_STATUS_GOOD; 1135 return SANE_STATUS_UNSUPPORTED; 1136} 1137 1138SANE_Status 1139sane_get_select_fd (SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ * fd) 1140{ 1141 return SANE_STATUS_UNSUPPORTED; 1142} 1143