/** Function Configs_FromPattern * @brief CMM_NICK oyCMMapi8_s scanner devices * * @param[in] registration a string to compare ?????? * @param[in] options read what to do from the options object * @param[out] s Return a configuration for each device found * * @version Oyranos: 0.1.10 * @since 2009/01/19 (Oyranos: 0.1.10) * @date 2009/02/09 */ int Configs_FromPattern(const char *registration, oyOptions_s * options, oyConfigs_s ** s) { oyConfig_s *device = NULL; oyConfigs_s *devices = NULL; oyOption_s *context_opt = NULL, *handle_opt = NULL, *version_opt = NULL, *name_opt = NULL; int i, num_devices, g_error = 0, status, call_sane_exit = 0; const char *device_name = 0, *command_list = 0, *command_properties = 0; const SANE_Device **device_list = NULL; int rank; oyAlloc_f allocateFunc = malloc; printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK)); rank = oyFilterRegistrationMatch(_api8.registration, registration, oyOBJECT_CMM_API8_S); command_list = oyOptions_FindString(options, "command", "list"); command_properties = oyOptions_FindString(options, "command", "properties"); device_name = oyOptions_FindString(options, "device_name", 0); /* "error handling" section */ if (rank == 0) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "Registration match Failed. Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } if (s == NULL) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "oyConfigs_s is NULL! Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } if (*s != NULL) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "Devices struct already present! Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } if (!device_name && command_properties) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "Device_name is mandatory for properties command:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } /* "help" call section */ if (oyOptions_FindString(options, "command", "help") || !options || !oyOptions_Count(options)) { /** oyMSG_WARN should make shure our message is visible. */ ConfigsFromPatternUsage((oyStruct_s *) options); return 0; } context_opt = oyOptions_Find(options, "device_context", oyNAME_PATTERN); handle_opt = oyOptions_Find(options, "device_handle", oyNAME_PATTERN); name_opt = oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN); /*Handle "driver_version" option [IN] */ check_driver_version(options, &version_opt, &call_sane_exit); devices = oyConfigs_New(0); if (command_list) { /* "list" call section */ if (device_name && /*If a user provides a device_name option,*/ !context_opt && /*and does not need the device_context data,*/ !name_opt /*or the oyNAME_NAME description*/ ) num_devices = 1; /*then we can get away without calling GetDevices()*/ else if (GetDevices(&device_list, &num_devices) != 0) { num_devices = 0; /*So that for loop will not run*/ ++g_error; } for (i = 0; i < num_devices; ++i) { int error = 0; const char *sane_name = NULL, *sane_model = NULL; if (device_list) { sane_name = device_list[i]->name; sane_model = device_list[i]->model; } else { sane_name = device_name; } /*Handle "device_name" option [IN] */ if (device_name && /*device_name is provided*/ sane_name && /*and sane_name has been retrieved*/ strcmp(device_name, sane_name) != 0) /*and they don't match,*/ continue; /*then try the next*/ device = oyConfig_FromRegistration(CMM_BASE_REG, 0); /*Handle "driver_version" option [OUT] */ if (version_opt) { oyOption_s * tmp = oyOption_Copy(version_opt, 0); oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &tmp, -1); } /*Handle "device_name" option [OUT] */ oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"), CMM_BASE_REG OY_SLASH "device_name", sane_name, OY_CREATE_NEW); /*Handle "oyNAME_NAME" option */ if (name_opt) oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"), CMM_BASE_REG OY_SLASH "oyNAME_NAME", sane_model, OY_CREATE_NEW); /*Handle "device_context" option */ /* SANE Backend protocol states that device_context is *always* returned * This is a slight variation: Only when GetDevices() is called will it be returned, * unless we call sane_exit*/ if (device_list && !call_sane_exit) { oyBlob_s *context_blob = oyBlob_New(NULL); oyOption_s *context_opt = oyOption_FromRegistration( CMM_BASE_REG OY_SLASH "device_context", 0); oyBlob_SetFromData(context_blob, (oyPointer) device_list[i], sizeof(SANE_Device), "sane"); oyOption_MoveInStruct(context_opt, (oyStruct_s **) & context_blob); oyOptions_MoveIn(*oyConfig_GetOptions(device,"data"), &context_opt, -1); } /*Handle "device_handle" option */ if (handle_opt && !call_sane_exit) { oyPointer_s *handle_ptr = NULL; SANE_Handle h; status = sane_open(sane_name, &h); if (status == SANE_STATUS_GOOD) { handle_ptr = oyPointer_New(0); oyPointer_Set(handle_ptr, "SANE", "handle", (oyPointer)h, "sane_release_handle", sane_release_handle); oyOptions_MoveInStruct(oyConfig_GetOptions(device,"data"), CMM_BASE_REG OY_SLASH "device_handle", (oyStruct_s **) &handle_ptr, OY_CREATE_NEW); } else printf(PRFX "Unable to open sane device \"%s\": %s\n", sane_name, sane_strstatus(status)); } oyConfig_SetRankMap( device, _api8.rank_map ); error = oyConfigs_MoveIn(devices, &device, -1); /*Cleanup*/ if (error) { oyConfig_Release(&device); ++g_error; } } *s = devices; } else if (command_properties) { /* "properties" call section */ const SANE_Device *device_context = NULL; SANE_Device *aux_context = NULL; SANE_Handle device_handle = NULL; /*Return a full list of scanner H/W & * SANE driver S/W color options * with the according rank map */ device = oyConfig_FromRegistration(CMM_BASE_REG, 0); /*Handle "driver_version" option [OUT] */ if (version_opt) { oyOption_s *tmp = oyOption_Copy(version_opt, 0); oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &tmp, -1); } /*1a. Get the "device_context"*/ if (!context_opt) { /*we'll have to get it ourselves*/ if (GetDevices(&device_list, &num_devices) == 0) { device_context = *device_list; while (device_context) { if(device_name && device_context->name && strcmp(device_name,device_context->name) == 0) break; device_context++; } if (!device_context) { printf(PRFX "device_name does not match any installed device.\n"); g_error++; } } else { g_error++; } } else { aux_context = (SANE_Device*)oyOption_GetData(context_opt, NULL, allocateFunc); device_context = aux_context; } /*1b. Use the "device_context"*/ if (device_context) DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device,"backend_core")); /*2a. Get the "device_handle"*/ if (!handle_opt) { status = sane_open( device_name, &device_handle ); if (status != SANE_STATUS_GOOD) { printf(PRFX "Unable to open sane device \"%s\": %s\n", device_name, sane_strstatus(status)); g_error++; } } else { oyPointer_s * oy_struct = (oyPointer_s*) oyOption_GetStruct( handle_opt, oyOBJECT_POINTER_S ); device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct); oyPointer_Release( &oy_struct ); } if (device_handle) { /*2b. Use the "device_handle"*/ ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device,"backend_core")); /*3. Set the rank map*/ oyConfig_SetRankMap( device, _api8.rank_map ); } oyConfigs_MoveIn(devices, &device, -1); /*Cleanup*/ free(aux_context); *s = devices; } else { /*unsupported, wrong or no command */ SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "No supported commands in options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK) ); ConfigsFromPatternUsage((oyStruct_s *) options); g_error = 1; } /*Global Cleanup*/ if (call_sane_exit) { printf(PRFX "sane_exit()\n"); sane_exit(); } oyOption_Release(&context_opt); oyOption_Release(&handle_opt); oyOption_Release(&version_opt); oyOption_Release(&name_opt ); printf(PRFX "Leaving %s\n", __func__); return g_error; }
/** Function oyConfigs_FromDB * @memberof oyConfigs_s * @brief Get all oyConfigs_s from DB * * @param[in] registration the filter * @param[out] configs the found configuration list * @param[in] object a optional user object * @return error * * @version Oyranos: 0.1.10 * @since 2009/01/23 (Oyranos: 0.1.10) * @date 2010/02/25 */ OYAPI int OYEXPORT oyConfigs_FromDB ( const char * registration, oyConfigs_s ** configs, oyObject_s object ) { oyConfigs_s * s = 0; oyConfig_s_ * config = 0; oyOption_s * o = 0; char ** texts = 0, ** key_set_names = 0, ** config_key_names = 0; uint32_t count = 0, * d_rank_list = 0; int error = !registration; int i, j, k, n = 0, k_n = 0; oyCMMapi8_s_ * cmm_api8 = 0; /** 0. setup Elektra */ oyExportStart_(EXPORT_PATH | EXPORT_SETTING); if(error <= 0) { /** 1. get all module names for the registration pattern */ error = oyConfigDomainList( registration, &texts, &count, &d_rank_list, 0 ); if(count) s = oyConfigs_New( 0 ); if(error <= 0 && count && texts) cmm_api8 = (oyCMMapi8_s_*) oyCMMsGetFilterApi_( 0, texts[0], oyOBJECT_CMM_API8_S ); for(i = 0; i < count; ++i) { /** 2. obtain the directory structure for configurations */ key_set_names = oyKeySetGetNames_( texts[i], &n ); if(error <= 0) for(j = 0; j < n; ++j) { /** 3. obtain all keys from one configuration directory */ config_key_names = oyKeySetGetNames_( key_set_names[j], &k_n ); config = (oyConfig_s_*)oyConfig_New( texts[i], object ); error = !config; for(k = 0; k < k_n; ++k) { /** 4. create a oyOption_s for each Elektra DB key/value pair */ if(error <= 0) o = oyOption_FromDB( config_key_names[k], object ); error = !o; if(error <= 0) error = oyOptions_Add( config->db, o, -1, 0 ); else { WARNcc1_S( (oyStruct_s*) object, "Could not generate key %s", config_key_names[k] ); break; } oyOption_Release( &o ); } /* add information about the data's origin */ oyConfig_AddDBData( (oyConfig_s*)config, "key_set_name", key_set_names[j], OY_CREATE_NEW ); /* add a rank map to allow for comparisions */ if(cmm_api8) config->rank_map = oyRankMapCopy( cmm_api8->rank_map, config->oy_->allocateFunc_ ); oyConfigs_MoveIn( s, (oyConfig_s**)&config, -1 ); } } oyStringListRelease_( &texts, count, oyDeAllocateFunc_ ); } if(configs) *configs = s; else oyConfigs_Release( &s ); oyExportEnd_(); return error; }
/** Function oyConfigs_SelectSimilars * @memberof oyConfigs_s * @brief Filter similar configs compared by a pattern * * This is a simple convenience function to select from a list existing * configurations. * * @verbatim const char * pattern[][2] = {{"device_name",0}, {"manufacturer",0}, {"model",0}, {"serial",0}, {0,0}}; oyConfigs_s * devices = 0, * filtered = 0; int error = oyConfigs_FromDB( registration, &devices, 0 ); error = oyConfigs_SelectSimilars( devices, pattern, &filtered ) * @endverbatim * * @param[in] list the list * @param[in] pattern user supplied zero terminated pattern * list; The first element is a mandadory * key to meet. The second element is the * optional value. Each * @param[out] filtered the result * @return error * * @version Oyranos: 0.1.10 * @since 2009/02/26 (Oyranos: 0.1.10) * @date 2009/02/26 */ OYAPI int OYEXPORT oyConfigs_SelectSimilars ( oyConfigs_s * list, const char * pattern[][2], oyConfigs_s ** filtered ) { int error = !list; int i,j, matches = 0, n, required = 0; oyConfigs_s * s = list, * result = 0; oyConfig_s * device = 0; const char * ct = 0; if(!s) return 0; if(s) oyCheckType__m( oyOBJECT_CONFIGS_S, return 0 ) /** 0. setup Elektra */ oyExportStart_(EXPORT_PATH | EXPORT_SETTING); result = oyConfigs_New(0); n = oyConfigs_Count( list ); for(i = 0; i < n; ++i) { device = oyConfigs_Get( list, i ); j = 0; matches = 0; required = 0; while(pattern[j][0]) { ct = oyConfig_FindString( device, pattern[j][0], 0); if(pattern[j][1]) { ++required; if(ct && strcmp(ct,pattern[j][1]) == 0) ++matches; } else { ++required; ++matches; } ++j; } if(required == matches) error = oyConfigs_MoveIn( result, &device, -1 ); oyConfig_Release( &device ); } *filtered = result; return error; }
/** Function oyConfigs_FromDeviceClass * @memberof oyConfigs_s * @brief Ask a module for device informations or other direct calls * * @param[in] device_type the device type ::oyFILTER_REG_TYPE, * defaults to OY_TYPE_STD (optional) * @param[in] device_class the device class, e.g. "monitor", * ::oyFILTER_REG_APPLICATION * @param[in] options options to pass to the module, for zero * the usage instructions are requested, * a option "device_name" can be used * as filter * @param[out] devices the devices * @param[in] object the optional object * @return 0 - good, >= 1 - error * * @verbatim // pass empty options to the module to get a usage message oyOptions_s * options = 0; int error = oyConfigs_FromDeviceClass( OY_TYPE_STD, "monitor", options, 0, 0 ); @endverbatim * * @version Oyranos: 0.1.10 * @since 2009/01/28 (Oyranos: 0.1.10) * @date 2009/01/30 */ OYAPI int OYEXPORT oyConfigs_FromDeviceClass ( const char * device_type, const char * device_class, oyOptions_s * options, oyConfigs_s ** devices, oyObject_s object ) { int error = !device_class || !device_class[0]; oyConfig_s * device = 0; oyConfigs_s * configs = 0; int i, j, j_n; uint32_t count = 0, * rank_list = 0; char ** texts = 0, * device_class_registration = 0; const char * tmp = 0, * device_name = 0; if(error > 0) { WARNc_S( "\n No device_class argument provided. Give up" ); return 0; } /** 1. obtain detailed and expensive device informations */ if(options) { options = oyOptions_Copy( options, 0 ); device_name = oyOptions_FindString( options, "device_name", 0 ); } /** 1.2.1 build a device class registration string */ if(error <= 0) { device_class_registration = oyDeviceRegistrationCreate_( device_type, device_class, device_name, device_class_registration ); error = !device_class_registration; } /** 1.2.2 get all device class module names */ if(error <= 0) error = oyConfigDomainList ( device_class_registration, &texts, &count, &rank_list, 0 ); if(devices && !*devices) *devices = oyConfigs_New( object ); /** 1.3 ask each module */ for( i = 0; i < count; ++i ) { const char * registration_domain = texts[i]; /** 1.3.1 call into module */ error = oyConfigs_FromDomain( registration_domain, options, &configs, object); if(devices && *devices) j_n = oyConfigs_Count( configs ); else j_n = 0; for( j = 0; j < j_n; ++j ) { device = oyConfigs_Get( configs, j ); if(device_name) { /** 1.3.1.1 Compare the device_name with the device_name option * and collect the matching devices. */ tmp = oyConfig_FindString( device, "device_name", 0 ); if(tmp && oyStrcmp_( tmp, device_name ) == 0) oyConfigs_MoveIn( *devices, &device, -1 ); } else /** 1.3.1.2 ... or collect all device configurations */ oyConfigs_MoveIn( *devices, &device, -1 ); oyConfig_Release( &device ); } oyConfigs_Release( &configs ); } if(devices) j_n = oyConfigs_Count( *devices ); else j_n = 0; for( j = 0; j < j_n; ++j ) { device = oyConfigs_Get( *devices, j ); /** The basic call on how to obtain the configuration is added here as * the objects name. "properties" and "list" are known. */ if(oyOptions_FindString( options, "command", "properties" ) || oyOptions_FindString( options, "oyNAME_DESCRIPTION", 0 )) oyObject_SetName( device->oy_, "properties", oyNAME_NAME ); else if(oyOptions_FindString( options, "list", 0 )) oyObject_SetName( device->oy_, "list", oyNAME_NAME ); oyConfig_Release( &device ); } oyOptions_Release( &options ); return error; }