pike.git / src / modules / SANE / sane.c

version» Context lines:

pike.git/src/modules/SANE/sane.c:1: + /* + || This file is part of Pike. For copyright information see COPYRIGHT. + || Pike is distributed under GPL, LGPL and MPL. See the file COPYING + || for more information. + */ +    #include "config.h"    - #if defined(HAVE_SANE_SANE_H) || defined(HAVE_SANE_H) + #if (defined(HAVE_SANE_SANE_H) || defined(HAVE_SANE_H)) && defined(HAVE_LIBSANE)   #ifdef HAVE_SANE_SANE_H   #include <sane/sane.h> - #else - #ifdef HAVE_SANE_H + #elif defined(HAVE_SANE_H)   #include <sane.h>   #endif - #endif +    #include <stdio.h>      #include "global.h"   #include "stralloc.h"   #include "pike_macros.h"   #include "object.h"   #include "constants.h"   #include "interpret.h"   #include "svalue.h"   #include "threads.h"
pike.git/src/modules/SANE/sane.c:22:   #include "pike_error.h"   #include "mapping.h"   #include "multiset.h"   #include "backend.h"   #include "operators.h"   #include "module_support.h"   #include "builtin_functions.h"      #include "../Image/image.h"    - /* must be included last */ - #include "module_magic.h" +     - RCSID("$Id: sane.c,v 1.9 2001/07/21 00:54:31 nilsson Exp $"); + #define sp Pike_sp    - /* - **! module SANE - **! - **! This module enables access to the SANE (Scanner Access Now Easy) - **! library from pike - **! - **! note - **! $Id: sane.c,v 1.9 2001/07/21 00:54:31 nilsson Exp $ + /*! @module SANE +  *! +  *! This module enables access to the SANE (Scanner Access Now Easy) +  *! library from pike   */      static int sane_is_inited;      struct scanner   {    SANE_Handle h;   };      static void init_sane()
pike.git/src/modules/SANE/sane.c:61:   static void push_device( SANE_Device *d )   {    push_text( "name" ); push_text( d->name );    push_text( "vendor" ); push_text( d->vendor );    push_text( "model" ); push_text( d->model );    push_text( "type" ); push_text( d->type );    f_aggregate_mapping( 8 );   }       - /* - **! method array(mapping) list-scanners() - **! - **! Returns an array with all available scanners. - **! - **! Example: - **! <pre> - **! Pike v0.7 release 120 running Hilfe v2.0 (Incremental Pike Frontend) - **! > SANE.list_scanners(); - **! Result: ({ - **! ([ - **! "model":"Astra 1220S ", - **! "name":"umax:/dev/scg1f", - **! "type":"flatbed scanner", - **! "vendor":"UMAX " - **! ]), - **! ([ - **! "model":"Astra 1220S ", - **! "name":"net:lain.idonex.se:umax:/dev/scg1f", - **! "type":"flatbed scanner", - **! "vendor":"UMAX " - **! ]) - **! }) - **! - **! </pre> + /*! @decl array(mapping) list_scanners() +  *! +  *! Returns an array with all available scanners. +  *! +  *! @example +  *! Pike v0.7 release 120 running Hilfe v2.0 (Incremental Pike Frontend) +  *! > SANE.list_scanners(); +  *! Result: ({ +  *! ([ +  *! "model":"Astra 1220S ", +  *! "name":"umax:/dev/scg1f", +  *! "type":"flatbed scanner", +  *! "vendor":"UMAX " +  *! ]), +  *! ([ +  *! "model":"Astra 1220S ", +  *! "name":"net:lain.idonex.se:umax:/dev/scg1f", +  *! "type":"flatbed scanner", +  *! "vendor":"UMAX " +  *! ]) +  *! })   */   static void f_list_scanners( INT32 args )   {    SANE_Device **devices;    int i = 0;       if( !sane_is_inited ) init_sane();    switch( sane_get_devices( (void *)&devices, 0 ) )    {    case 0:
pike.git/src/modules/SANE/sane.c:199:    push_text( "list" );    for( i = 0; o->constraint.string_list[i]; i++ )    push_text( o->constraint.string_list[i] );    f_aggregate( i );    f_aggregate_mapping( 4 );    break;    }    f_aggregate_mapping( sp - osp );   }    - /* - **! class Scanner - **! Scanner s = Scanner( scanner name ) + /*! @class Scanner    */ -  +  + /*! @decl void create(string name) +  */   static void f_scanner_create( INT32 args )   {    char *name;    if(!sane_is_inited) init_sane();    get_all_args( "create", args, "%s", &name );       if( sane_open( name, &THIS->h ) )    Pike_error("Failed to open scanner \"%s\"\n", name );   }    - /* - **! method array(mapping) list_options() + /*! @decl array(mapping) list_options() +  *! +  *! This method returns an array where every element is a +  *! mapping, layed out as follows. +  *! +  *! @mapping +  *! @member string "name" +  *! +  *! @member string "title" +  *! +  *! @member string "desc" +  *! +  *! @member string "type" +  *! @string +  *! @value "boolean" +  *! @value "int" +  *! @value "float" +  *! @value "string" +  *! @value "button" +  *! @value "group" +  *! @endstring +  *! @member string "unit" +  *! @string +  *! @value "none" +  *! @value "pixel" +  *! @value "bit" +  *! @value "mm" +  *! @value "dpi" +  *! @value "percent" +  *! @value "microsend" +  *! @endstring +  *! @member int "size" +  *! +  *! @member multiset "cap" +  *! @multiset +  *! @index "soft_select" +  *! @index "hard_select" +  *! @index "emulate" +  *! @index "automatic" +  *! @index "inactive" +  *! @index "advanced" +  *! @endmultiset +  *! @member int(0..0)|mapping "constraint" +  *! Constraints can be of three different types; range, word list or string +  *! list. Constraint contains 0 if there are no constraints. +  *! +  *! @mapping range +  *! @member string "type" +  *! Contains the value "range". +  *! @member int "max" +  *! @member int "min" +  *! @member int "quant" +  *! @endmapping +  *! +  *! @mapping "word list" +  *! @member string "type" +  *! Contains the value "list". +  *! @member array(float|int) "list" +  *! @endmapping +  *! +  *! @mapping "string list" +  *! @member string "type" +  *! Contains the value "list". +  *! @member array(string) "list" +  *! @endmapping +  *! @endmapping   */   static void f_scanner_list_options( INT32 args )   {    int i, n;    const SANE_Option_Descriptor *d;    pop_n_elems( args );       for( i = 1; (d = sane_get_option_descriptor( THIS->h, i) ); i++ )    push_option_descriptor( d );    f_aggregate( i-1 );
pike.git/src/modules/SANE/sane.c:241:    for( i = 1; (d = sane_get_option_descriptor( THIS->h, i ) ); i++ )    if(d->name && !strcmp( d->name, name ) )    {    *p = d;    return i;    }    Pike_error("No such option: %s\n", name );   }       - /* - **! method void set_option( string name, mixed new_value ) - **! method void set_option( string name ) - **! If no value is specified, the option is set to it's default value + /*! @decl void set_option( string name, mixed new_value ) +  *! @decl void set_option( string name ) +  *! If no value is specified, the option is set to it's default value    */   static void f_scanner_set_option( INT32 args )   {    char *name;    int no;    INT_TYPE int_value;    FLOAT_TYPE float_value;    SANE_Int tmp;    const SANE_Option_Descriptor *d;    get_all_args( "set_option", args, "%s", &name );       no = find_option( name, &d );    if( args > 1 )    {    switch( d->type )    {    case SANE_TYPE_BOOL:    case SANE_TYPE_INT:    case SANE_TYPE_BUTTON: -  sp++;get_all_args( "set_option", args, "%D", &int_value );sp--; +  sp++;get_all_args( "set_option", args, "%I", &int_value );sp--;    sane_control_option( THIS->h, no, SANE_ACTION_SET_VALUE,    &int_value, &tmp );    break;    case SANE_TYPE_FIXED:    sp++;get_all_args( "set_option", args, "%F", &float_value );sp--;    int_value = SANE_FIX(((double)float_value));    sane_control_option( THIS->h, no, SANE_ACTION_SET_VALUE,    &int_value, &tmp );    break;    case SANE_TYPE_STRING:
pike.git/src/modules/SANE/sane.c:290:    }    } else {    int_value = 1;    sane_control_option( THIS->h, no, SANE_ACTION_SET_AUTO, &int_value, &tmp );    }    pop_n_elems( args );    push_int( 0 );   }       - /* - **! method mixed get_option( string name ) + /*! @decl mixed get_option( string name )   */   static void f_scanner_get_option( INT32 args )   {    char *name;    int no;    SANE_Int int_value;    float f;    SANE_Int tmp;    const SANE_Option_Descriptor *d;    get_all_args( "get_option", args, "%s", &name );
pike.git/src/modules/SANE/sane.c:331:    case SANE_TYPE_STRING:    sane_control_option( THIS->h, no, SANE_ACTION_GET_VALUE,    &name, &tmp );    pop_n_elems( args );    push_text( name );    case SANE_TYPE_GROUP:    break;    }   }    - /* - **! method mapping(string:int) get_parameters() + /*! @decl mapping(string:int) get_parameters() +  *! +  *! @returns +  *! @mapping +  *! @member int "format" +  *! @member int "last_frame" +  *! @member int "lines" +  *! @member int "depth" +  *! @member int "pixels_per_line" +  *! @member int "bytes_per_line" +  *! @endmapping   */   static void f_scanner_get_parameters( INT32 args )   {    SANE_Parameters p;    pop_n_elems( args );    sane_get_parameters( THIS->h, &p );    push_text( "format" ); push_int( p.format );    push_text( "last_frame" ); push_int( p.last_frame );    push_text( "lines" ); push_int( p.lines );    push_text( "depth" ); push_int( p.depth );
pike.git/src/modules/SANE/sane.c:358:      static struct program *image_program;      static void get_grey_frame( SANE_Handle h, SANE_Parameters *p, char *data )   {    char buffer[8000];    int nbytes = p->lines * p->bytes_per_line, amnt_read;    while( nbytes )    {    char *pp = buffer; -  if( sane_read( h, buffer, MINIMUM(8000,nbytes), &amnt_read ) ) +  if( sane_read( h, (unsigned char *)buffer, MINIMUM(8000,nbytes), +  &amnt_read ) )    return;    while( amnt_read-- && nbytes--)    {    *(data++) = *(pp);    *(data++) = *(pp);    *(data++) = *(pp++);    }    }   }      static void get_rgb_frame( SANE_Handle h, SANE_Parameters *p, char *data )   {    char buffer[8000];    int nbytes = p->lines * p->bytes_per_line, amnt_read;    while( nbytes )    {    char *pp = buffer; -  if( sane_read( h, buffer, MINIMUM(8000,nbytes), &amnt_read ) ) +  if( sane_read( h, (unsigned char *)buffer, MINIMUM(8000,nbytes), +  &amnt_read ) )    return;    while( amnt_read-- && nbytes--)    *(data++) = *(pp++);    }   }      static void get_comp_frame( SANE_Handle h, SANE_Parameters *p, char *data )   {    char buffer[8000];    int nbytes = p->lines * p->bytes_per_line, amnt_read;
pike.git/src/modules/SANE/sane.c:413:    {    push_text( "Image.Image" );    APPLY_MASTER( "resolv", 1 );    image_program = program_from_svalue( sp - 1 );    sp--;/* Do not free image program.. */    }    if( !image_program )    Pike_error("No Image.Image?!\n");   }    - /* - **! method Image.Image simple_scan() + /*! @decl Image.Image simple_scan()   */   static void f_scanner_simple_scan( INT32 args )   {    SANE_Parameters p;    SANE_Handle h = THIS->h;    struct object *o;    rgb_group *r;          assert_image_program();
pike.git/src/modules/SANE/sane.c:468:    get_comp_frame( h, &p, ((char *)r)+2 );    break;    }    }    while( !p.last_frame );       THREADS_DISALLOW();    push_object( o );   }    - /* - **! method void row_scan(function(Image.Image,int,Scanner:void) callback) + /*! @decl void row_scan(function(Image.Image,int,Scanner:void) callback)   */   static void f_scanner_row_scan( INT32 args )   {    SANE_Parameters p;    SANE_Handle h = THIS->h;    struct svalue *s;    struct object *o;    rgb_group *r, or;    int i, nr;   
pike.git/src/modules/SANE/sane.c:613:    {    set_read_callback( fd, 0, 0 );    free_object( c->o );    free_object( c->t );    free_svalue( &c->callback );    free( c->buffer );    free( c );    }   }    - /* - **! method void nonblocking_row_scan(function(Image.Image,int,Scanner,int:void) callback) + /*! @decl void nonblocking_row_scan(function(Image.Image,int,Scanner,int:void) callback)   */   static void f_scanner_nonblocking_row_scan( INT32 args )   {    SANE_Parameters p;    SANE_Handle h = THIS->h;    struct svalue *s;    int fd;    struct row_scan_struct *rsp;       if( sane_start( THIS->h ) ) Pike_error("Start failed\n");
pike.git/src/modules/SANE/sane.c:647:    break;    }       assert_image_program();       rsp = malloc( sizeof(struct row_scan_struct) );    push_int( p.pixels_per_line );    push_int( 1 );    rsp->o = clone_object( image_program, 2 );    rsp->t = Pike_fp->current_object; -  Pike_fp->current_object->refs++; +  add_ref(Pike_fp->current_object);    rsp->r = ((struct image *)rsp->o->storage)->img;    rsp->h = THIS->h;    rsp->p = p;    rsp->buffer = malloc( p.bytes_per_line );    rsp->current_row = 0;    rsp->bufferpos = 0;    rsp->callback = sp[-1];    rsp->nonblocking = !sane_set_io_mode( THIS->h, 1 );    sp--;       if( sane_get_select_fd( THIS->h, &fd ) )    {    free_object( rsp->o );    free_object( rsp->t );    free( rsp->buffer );    free( rsp );    Pike_error("Failed to get select fd for scanning device!\n");    } -  set_read_callback( fd, nonblocking_row_scan_callback, (void*)rsp ); +  set_read_callback( fd, (file_callback)nonblocking_row_scan_callback, +  (void*)rsp );    push_int( 0 );   }    -  + /*! @decl void cancel_scan() +  */   static void f_scanner_cancel_scan( INT32 args )   {    sane_cancel( THIS->h );   }    -  + /*! @endclass +  */ +  + /*! @decl constant FrameGray +  *! @decl constant FrameRGB +  *! @decl constant FrameRed +  *! @decl constant FrameGreen +  *! @decl constant FrameBlue +  */ +  + /*! @endmodule +  */ +    static void init_scanner_struct( struct object *p )   {    THIS->h = 0;   }      static void exit_scanner_struct( struct object *p )   {    if( THIS->h )    sane_close( THIS->h );   }    - void pike_module_init() + PIKE_MODULE_INIT   {    struct program *p; -  add_function( "list_scanners", f_list_scanners, -  "function(void:array(mapping))", 0 ); +  ADD_FUNCTION( "list_scanners", f_list_scanners, +  tFunc(tNone,tArr(tMapping)), 0 );       add_integer_constant( "FrameGray", SANE_FRAME_GRAY,0 );    add_integer_constant( "FrameRGB", SANE_FRAME_RGB,0 );    add_integer_constant( "FrameRed", SANE_FRAME_RED,0 );    add_integer_constant( "FrameGreen",SANE_FRAME_GREEN,0 );    add_integer_constant( "FrameBlue", SANE_FRAME_BLUE,0 );          start_new_program();    ADD_STORAGE( struct scanner ); -  add_function( "get_option", f_scanner_get_option, -  "function(string:mixed)", 0 ); -  add_function( "set_option", f_scanner_set_option, -  "function(string,void|mixed:void)", 0 ); -  add_function( "list_options", f_scanner_list_options, -  "function(void:array(mapping(string:mixed)))", 0 ); +  ADD_FUNCTION( "get_option", f_scanner_get_option, tFunc(tStr, tMix), 0 ); +  ADD_FUNCTION( "set_option", f_scanner_set_option, +  tFunc(tStr tOr(tVoid, tMix), tVoid), 0 ); +  ADD_FUNCTION( "list_options", f_scanner_list_options, +  tFunc(tNone, tArr(tMap(tStr, tMix))), 0 );    -  add_function( "simple_scan", f_scanner_simple_scan, -  "function(void:object)", 0 ); +  ADD_FUNCTION( "simple_scan", f_scanner_simple_scan, tFunc(tNone, tObj), 0 );    -  add_function( "row_scan", f_scanner_row_scan, -  "function(function(object,int,object:void):void)", 0 ); +  ADD_FUNCTION( "row_scan", f_scanner_row_scan, +  tFunc(tFunc(tObj tInt tObj,tVoid),tVoid), 0 );    -  add_function( "nonblocking_row_scan", f_scanner_nonblocking_row_scan, -  "function(function(object,int,object,int:void):void)", 0 ); +  ADD_FUNCTION( "nonblocking_row_scan", f_scanner_nonblocking_row_scan, +  tFunc(tFunc(tObj tInt tObj tInt,tVoid),tVoid), 0 );    -  add_function( "cancel_scan", f_scanner_cancel_scan, -  "function(void:object)", 0 ); +  ADD_FUNCTION( "cancel_scan", f_scanner_cancel_scan, tFunc(tNone, tObj), 0 );    -  add_function( "get_parameters", f_scanner_get_parameters, -  "function(void:mapping)", 0 ); +  ADD_FUNCTION( "get_parameters", f_scanner_get_parameters, +  tFunc(tNone, tMapping), 0 );    -  add_function( "create", f_scanner_create, -  "function(string:void)", ID_STATIC ); +  ADD_FUNCTION( "create", f_scanner_create, tFunc(tStr, tVoid), ID_PROTECTED );       set_init_callback(init_scanner_struct);    set_exit_callback(exit_scanner_struct);       add_program_constant( "Scanner", (p=end_program( ) ), 0 );    free_program( p );   }    - void pike_module_exit() + PIKE_MODULE_EXIT   {    if( sane_is_inited )    sane_exit();    if( image_program )    free_program( image_program );   }      #else - #include "module_magic.h" - void pike_module_init() {} - void pike_module_exit() {} + #include "program.h" + #include "module.h" + #include "module_support.h" + PIKE_MODULE_INIT { +  if(!TEST_COMPAT(7,6)) +  HIDE_MODULE(); + } + PIKE_MODULE_EXIT {}   #endif