コード例 #1
0
ファイル: scanner.c プロジェクト: skm42/opendias
extern const char *get_status_string (SANE_Status status) {
    struct {
        SANE_Status status;
        const char *name;
    } status_names[] = {
        { SANE_STATUS_GOOD,          "SANE_STATUS_GOOD"},
        { SANE_STATUS_UNSUPPORTED,   "SANE_STATUS_UNSUPPORTED"},
        { SANE_STATUS_CANCELLED,     "SANE_STATUS_CANCELLED"},
        { SANE_STATUS_DEVICE_BUSY,   "SANE_STATUS_DEVICE_BUSY"},
        { SANE_STATUS_INVAL,         "SANE_STATUS_INVAL"},
        { SANE_STATUS_EOF,           "SANE_STATUS_EOF"},
        { SANE_STATUS_JAMMED,        "SANE_STATUS_JAMMED"},
        { SANE_STATUS_NO_DOCS,       "SANE_STATUS_NO_DOCS"},
        { SANE_STATUS_COVER_OPEN,    "SANE_STATUS_COVER_OPEN"},
        { SANE_STATUS_IO_ERROR,      "SANE_STATUS_IO_ERROR"},
        { SANE_STATUS_NO_MEM,        "SANE_STATUS_NO_MEM"},
        { SANE_STATUS_ACCESS_DENIED, "SANE_STATUS_ACCESS_DENIED"},
        { -1,                        NULL}
    };
    static char *unknown_string = NULL;
    int i;

    for (i = 0; status_names[i].name != NULL && status_names[i].status != status; i++);

    if (status_names[i].name == NULL) {
        free (unknown_string);
        unknown_string = o_strdup("");
        o_concatf (&unknown_string, "SANE_ACTION(%d)", status);
        return unknown_string; /* Note result is undefined on second call to this function */
    }

    return status_names[i].name;
}
コード例 #2
0
ファイル: scanner.c プロジェクト: skm42/opendias
extern const char *get_action_string (SANE_Action action) {
    struct {
        SANE_Action action;
        const char *name;
    } action_names[] = {
        { SANE_ACTION_GET_VALUE, "SANE_ACTION_GET_VALUE" },
        { SANE_ACTION_SET_VALUE, "SANE_ACTION_SET_VALUE" },
        { SANE_ACTION_SET_AUTO,  "SANE_ACTION_SET_AUTO" },
        { -1,                    NULL}
    };
    static char *unknown_string = NULL;
    int i;

    for (i = 0; action_names[i].name != NULL && action_names[i].action != action; i++);

    if (action_names[i].name == NULL) {
        free (unknown_string);
        unknown_string = o_strdup("");
        o_concatf (&unknown_string, "SANE_ACTION(%d)", action);
        return unknown_string; /* Note result is undefined on second call to this function */
    }

    return action_names[i].name;
}
コード例 #3
0
ファイル: scan.c プロジェクト: Rventric/opendias
extern char *internalGetScannerDetails(char *device, char *lang) {

  char *answer = NULL;
  SANE_Status status;
  char *deviceList = o_strdup("");; 
  int hlp = 0, resolution = 300, minRes=50, maxRes=50, phashAvailable=0;
  char *resolution_s, *maxRes_s, *minRes_s;
  SANE_Handle *openDeviceHandle;

  o_log(DEBUGM, "sane_open of \"%s\"", device);
  status = sane_open (device, (SANE_Handle)&openDeviceHandle);
  if(status != SANE_STATUS_GOOD) {
    o_log(ERROR, "Could not open: '%s' with error: %s", device, sane_strstatus(status));
    free(deviceList);
    return NULL;
  }


  //
  // Find resolution ranges
  //
  for (hlp = 0; hlp < 9999; hlp++) {

    const SANE_Option_Descriptor *sod;

    sod = sane_get_option_descriptor (openDeviceHandle, hlp);
    if (sod == NULL)
      break;

    // Just a placeholder
    if (sod->type == SANE_TYPE_GROUP
    || sod->name == NULL
    || hlp == 0)
      continue;

    if ( 0 == strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) ) {

      // Some kind of sliding range
      if (sod->constraint_type == SANE_CONSTRAINT_RANGE) {
        o_log(DEBUGM, "Resolution setting detected as 'range'");

        // Fixed resolution
        if (sod->type == SANE_TYPE_FIXED)
          maxRes = (int)SANE_UNFIX (sod->constraint.range->max);
        else
          maxRes = sod->constraint.range->max;
      }

      // A fixed list of options
      else if (sod->constraint_type == SANE_CONSTRAINT_WORD_LIST) {
        int lastIndex = sod->constraint.word_list[0];
        o_log(DEBUGM, "Resolution setting detected as 'word list': lastIndex = %d",lastIndex);

        // maxRes = sod->constraint.word_list[lastIndex];
        // resolution list cannot be treated as low to high ordered list 
        // remark: impl capability to select scan resolution in webInterface
        int n=0;
        maxRes = 0;
        for (n=1; n<=lastIndex; n++ ) {
          o_log(DEBUGM, "index results %d --> %d", n ,(int)sod->constraint.word_list[n]);
          if ( maxRes < sod->constraint.word_list[n] ) {
            maxRes=sod->constraint.word_list[n];
          }
        }

      }

      break; // we've found our resolution - no need to search more
    }
  }
  o_log(DEBUGM, "Determined max resultion to be %d", maxRes);


  // Define a default
  if(resolution >= maxRes)
    resolution = maxRes;
  if(resolution <= minRes)
    resolution = minRes;

  o_log(DEBUGM, "sane_cancel");
  sane_cancel(openDeviceHandle);

  o_log(DEBUGM, "sane_close");
  sane_close(openDeviceHandle);



  //
  // What languages can we OCR for?
  //
  char *availableLangs = o_strdup("");
#ifdef CAN_OCR
  struct simpleLinkedList *languages = getOCRAvailableLanguages();
  while (languages != NULL ) {
    if ( checkOCRLanguage( languages->data ) == 0 ) {
      o_concatf(&availableLangs, "<lang>%s</lang>", languages->data);
    }
    languages = sll_getNext(languages);
  }
  sll_destroy( languages );
#endif /* CAN_OCR */


  //
  // Can we give the option of doing 'find simmilar'?
  //
#ifdef CAN_PHASH
  phashAvailable = 1;
#endif /* CAN_PHASH */

  // Build Reply
  //
  resolution_s = itoa(resolution,10);
  maxRes_s = itoa(maxRes,10);
  minRes_s = itoa(minRes,10);

  o_concatf(&deviceList, "<Resolution><max>%s</max><min>%s</min><default>%s</default></Resolution><OCRLanguages>%s</OCRLanguages><phash>%d</phash>", maxRes_s, minRes_s, resolution_s, availableLangs, phashAvailable);

  free(maxRes_s);
  free(minRes_s);
  free(resolution_s);
  free(availableLangs);

  // The escaped string placeholder will be interprited in the sane dispatcher client
  answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerDetails>%s</ScannerDetails></Response>", deviceList);
  free(deviceList);

  return answer;

}
コード例 #4
0
ファイル: scanner.c プロジェクト: skm42/opendias
extern void log_option (SANE_Int index, const SANE_Option_Descriptor *option) {
    char *string;
    SANE_Word i;
    SANE_Int cap;
    
    string = o_strdup("");
    o_concatf (&string, "Option %d:", index);
    
    if (option->name)    
        o_concatf (&string, " name='%s'", option->name);
    
    if (option->title)
        o_concatf (&string, " title='%s'", option->title);

    switch (option->type) {
    case SANE_TYPE_BOOL:
        conCat(&string, " type=bool");
        break;
    case SANE_TYPE_INT:
        conCat(&string, " type=int");
        break;
    case SANE_TYPE_FIXED:
        conCat(&string, " type=fixed");        
        break;
    case SANE_TYPE_STRING:
        conCat(&string, " type=string");        
        break;
    case SANE_TYPE_BUTTON:
        conCat(&string, " type=button");        
        break;
    case SANE_TYPE_GROUP:
        conCat(&string, " type=group");
        break;
    default:
        o_concatf (&string, " type=%d", option->type);
        break;
    }
    
    o_concatf (&string, " size=%d", option->size);

    switch (option->unit) {
    case SANE_UNIT_NONE:
        break;
    case SANE_UNIT_PIXEL:
        conCat(&string, " unit=pixels");
        break;
    case SANE_UNIT_BIT:
        conCat(&string, " unit=bits");
        break;
    case SANE_UNIT_MM:
        conCat(&string, " unit=mm");
        break;
    case SANE_UNIT_DPI:
        conCat(&string, " unit=dpi");
        break;
    case SANE_UNIT_PERCENT:
        conCat(&string, " unit=percent");
        break;
    case SANE_UNIT_MICROSECOND:
        conCat(&string, " unit=microseconds");
        break;
    default:
        o_concatf (&string, " unit=%d", option->unit);
        break;
    }

    switch (option->constraint_type) {
    case SANE_CONSTRAINT_RANGE:
        if (option->type == SANE_TYPE_FIXED)
            o_concatf (&string, " min=%f, max=%f, quant=%d",
                                    SANE_UNFIX (option->constraint.range->min), SANE_UNFIX (option->constraint.range->max),
                                    option->constraint.range->quant);
        else
            o_concatf (&string, " min=%d, max=%d, quant=%d",
                                    option->constraint.range->min, option->constraint.range->max,
                                    option->constraint.range->quant);
        break;
    case SANE_CONSTRAINT_WORD_LIST:
        conCat(&string, " values=[");
        for (i = 0; i < option->constraint.word_list[0]; i++) {
            if (i != 0)
                conCat(&string, ", ");
            if (option->type == SANE_TYPE_INT)
                o_concatf (&string, "%d", option->constraint.word_list[i+1]);
            else
                o_concatf (&string, "%f", SANE_UNFIX (option->constraint.word_list[i+1]));
        }
        conCat(&string, "]");
        break;
    case SANE_CONSTRAINT_STRING_LIST:
        conCat(&string, " values=[");
        for (i = 0; option->constraint.string_list[i]; i++) {
            if (i != 0)
                conCat(&string, ", ");
            o_concatf (&string, "\"%s\"", option->constraint.string_list[i]);
        }
        conCat(&string, "]");
        break;
    default:
        break;
    }
    
    cap = option->cap;
    if (cap) {
        struct {
            SANE_Int cap;
            const char *name;
        } caps[] = {
            { SANE_CAP_SOFT_SELECT,     "soft-select"},
            { SANE_CAP_HARD_SELECT,     "hard-select"},
            { SANE_CAP_SOFT_DETECT,     "soft-detect"},
            { SANE_CAP_EMULATED,        "emulated"},
            { SANE_CAP_AUTOMATIC,       "automatic"},
            { SANE_CAP_INACTIVE,        "inactive"},
            { SANE_CAP_ADVANCED,        "advanced"},
            { 0,                        NULL}
        };
        int i, n = 0;
        
        conCat(&string, " cap=");
        for (i = 0; caps[i].cap > 0; i++) {
            if (cap & caps[i].cap) {
                cap &= ~caps[i].cap;
                if (n != 0)
                    conCat(&string, ",");
                conCat(&string, caps[i].name);
                n++;
            }
        }
        /* Unknown capabilities */
        if (cap) {
            if (n != 0)
                conCat(&string, ",");
            o_concatf (&string, "%x", cap);
        }
    }

    o_log(DEBUGM, "%s", string);
    free(string);

//    if (option->desc)
//      o_log(DEBUGM, "  Description: %s", option->desc);
}
コード例 #5
0
ファイル: scan.c プロジェクト: Rventric/opendias
extern char *internalGetScannerList(char *lang) {
  char *answer = NULL;
  SANE_Status status;
  const SANE_Device **SANE_device_list;
  int scanOK = SANE_FALSE;
  char *deviceList; 

  status = sane_get_devices (&SANE_device_list, SANE_TRUE);
  if(status == SANE_STATUS_GOOD) {
    if (SANE_device_list && SANE_device_list[0]) {
      scanOK = SANE_TRUE;
      o_log(DEBUGM, "device(s) found");
    }
    else {
      o_log(INFORMATION, "No devices found");
    }
  }
  else {
    o_log(WARNING, "Checking for devices failed");
  }

  if(scanOK == SANE_TRUE) {

    int i = 0;

    char *replyTemplate; 
    replyTemplate = o_strdup("<Device><vendor>%s</vendor><model>%s</model><type>%s</type><name>%s</name><host>%s</host></Device>");
    deviceList = o_strdup("");

    for (i=0 ; SANE_device_list[i] ; i++) {

      char *vendor, *model, *type, *name;
      char *scannerHost;

      vendor = o_strdup(SANE_device_list[i]->vendor);
      model = o_strdup(SANE_device_list[i]->model);
      type = o_strdup(SANE_device_list[i]->type);
      name = o_strdup(SANE_device_list[i]->name);
      propper(vendor);
      propper(model);
      propper(type);

      // Find location of the device
      if ( name && name == strstr(name, "net:") ) {

        struct sockaddr_in sa;
        char *ipandmore, *ip;
        char host[NI_MAXHOST];
        char service[NI_MAXSERV];
        int len;

        // Ignore the 'net:' part
        ipandmore = name + 4;

        // Find the length of the address part
        len = strstr(ipandmore, ":") - ipandmore;

        // Load 'ip' with the network addres
        ip = malloc(1+(size_t)len);
        (void) strncpy(ip,ipandmore,(size_t)len);
        ip[len] = '\0';

        // Convert into an inet address
        memset(&sa, 0, sizeof(sa));
        sa.sin_family = AF_INET;
        sa.sin_addr.s_addr = inet_addr( ip );

        // Lookup hostname from address
        o_log(DEBUGM, "Going to lookup: %s", ip);
        if ( getnameinfo((struct sockaddr *)&sa, sizeof sa, host, sizeof host, service, sizeof service, NI_NAMEREQD) == 0 ) {
          o_log(DEBUGM, "found host: %s", host);
          scannerHost = o_strdup(host);
        } 
        else {
          o_log(DEBUGM, "Could not get hostname");
          scannerHost = o_strdup(ip);
        }

        // Clean up
        free(ip);
      }
      else {
        scannerHost = o_strdup( getString("LOCAL_opendias_server", lang) );
      }

      // Build Reply
      //
      o_concatf(&deviceList, replyTemplate, vendor, model, type, name, scannerHost);

      free(vendor);
      free(model);
      free(type);
      free(name);
      free(scannerHost);
    }

    free(replyTemplate);
    if(deviceList) {
      // The escaped string placeholder will be interprited in the sane dispatcher client
      answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%%s><Devices>%s</Devices></ScannerList></Response>", deviceList);
      free(deviceList);
    }
    else {
      // No devices
      // The escaped string placeholder will be interprited in the sane dispatcher client
      answer = o_strdup( "<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%s></ScannerList></Response>");
    }
  }

  else {
    // sane failed.
    // The escaped string placeholder will be interprited in the sane dispatcher client
    answer = o_strdup( "<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%s></ScannerList></Response>");
  }

  return answer;

}