/** @func oyraFilterPlug_ImageOutputPPMWrite * @brief implement oyCMMFilter_GetNext_f() * * @version Oyranos: 0.3.1 * @since 2008/10/07 (Oyranos: 0.1.8) * @date 2011/05/12 */ int oyraFilterPlug_ImageOutputPPMWrite ( oyFilterPlug_s * requestor_plug, oyPixelAccess_s * ticket ) { oyFilterSocket_s * socket; oyFilterNode_s * node = 0; oyOptions_s * node_opts = 0; int result = 0; const char * filename = 0; FILE * fp = 0; socket = oyFilterPlug_GetSocket( requestor_plug ); node = oyFilterSocket_GetNode( socket ); node_opts = oyFilterNode_GetOptions( node, 0 ); /* to reuse the requestor_plug is a exception for the starting request */ if(node) result = oyFilterNode_Run( node, requestor_plug, ticket ); else result = 1; if(result <= 0) filename = oyOptions_FindString( node_opts, "filename", 0 ); if(filename) fp = fopen( filename, "wb" ); if(fp) { oyImage_s *image_output = (oyImage_s*)oyFilterSocket_GetData( socket ); const char * comment = oyOptions_FindString( node_opts, "comment", NULL ); fclose (fp); fp = 0; result = oyImage_WritePPM( image_output, filename, comment ? comment : oyFilterNode_GetRelatives( node ) ); } return result; }
oyOptions_s* oyraFilter_ImageOutputPPMValidateOptions ( oyFilterCore_s * filter, oyOptions_s * validate, int statical OY_UNUSED, uint32_t * result ) { uint32_t error = !filter; #if 0 oyDATATYPE_e data_type = 0; int planar, channels; oyImage_s * image = 0; if(!error) filter = node->filter; if(!error) error = filter->type_ != oyOBJECT_FILTER_S; if(!error) { if(filter->image_ && filter->image_->layout_) { data_type = oyToDataType_m( filter->image_->layout_[0] ); if(!(data_type == oyUINT8 || data_type == oyUINT16 || data_type == oyFLOAT || data_type == oyDOUBLE )) error = 1; planar = oyToPlanar_m( filter->image_->layout_[0] ); if(!error && planar) error = 1; channels = oyToChannels_m( filter->image_->layout_[0] ); if(!error && channels > 4) error = 1; } } #endif if(!error) error = !oyOptions_FindString( validate, "filename", 0 ); *result = error; return 0; }
int oyDisplayColorServerIsActive( ) { int color_server_active = 0; /* A XCM color server expects local white point adjustment and effect. */ oyOptions_s * result_opts = oyOptions_New(NULL); oyOptions_Handle( "//" OY_TYPE_STD "/color_server_active", result_opts,"color_server_active.source_data", &result_opts ); color_server_active = oyOptions_FindString( result_opts, "color_server_active", "1" ) != NULL; oyOptions_Release( &result_opts ); if(oy_debug && color_server_active) oyMessageFunc_p( oyMSG_DBG, NULL, OY_DBG_FORMAT_ "color_server_active=%d", OY_DBG_ARGS_, color_server_active ); return color_server_active; }
/** Function Configs_Modify * @brief oyCMMapi8_s SANE scanner manipulation * * @version Oyranos: 0.1.10 * @since 2009/01/19 (Oyranos: 0.1.10) * @date 2009/08/21 * * \todo { Test } */ int Configs_Modify(oyConfigs_s * devices, oyOptions_s * options) { oyOption_s *version_opt = NULL; oyOption_s *version_opt_dev = NULL; oyConfig_s *device = NULL; int num_devices, g_error = 0; int call_sane_exit = 0; const char *command_list = NULL, *command_properties = NULL; oyAlloc_f allocateFunc = malloc; printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK)); /* "error handling" section */ if (!devices || !oyConfigs_Count(devices)) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "No devices given! Options:\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; } num_devices = oyConfigs_Count(devices); command_list = oyOptions_FindString(options, "command", "list"); command_properties = oyOptions_FindString(options, "command", "properties"); /* Now we get some options [IN], and we already have some devices with * possibly already assigned options. Those provided through the input * oyOptions_s should take presedence over ::data & ::backend_core ones. * OTOH, all device_* options have a 1-1 relationship meaning if * one changes, probably all other should. So the simplest [naive] approach * would be to ignore all device_* options [IN] that are already in device. * Except from driver_version which has a special meaning. */ /* Handle "driver_version" option [IN] */ /* Check the first device to see if a positive driver_version is provided. */ /* If not, consult the input options */ device = oyConfigs_Get(devices, 0); version_opt_dev = oyConfig_Find(device, "driver_version"); if (version_opt_dev && oyOption_GetValueInt(version_opt_dev, 0) > 0) call_sane_exit = 0; else check_driver_version(options, &version_opt, &call_sane_exit); oyConfig_Release(&device); oyOption_Release(&version_opt_dev); if (command_list) { /* "list" call section */ int i; for (i = 0; i < num_devices; ++i) { const SANE_Device *device_context = NULL; SANE_Status status = SANE_STATUS_INVAL; oyOption_s *name_opt_dev = NULL, *handle_opt_dev = NULL, *context_opt_dev = NULL; const char *sane_name = NULL, *sane_model = NULL; int error = 0; device = oyConfigs_Get(devices, i); if(oyOptions_Count(*oyConfig_GetOptions(device,"backend_core"))) printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK)); if(oyOptions_Count(*oyConfig_GetOptions(device,"data"))) printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK)); /*Ignore device without a device_name*/ if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_name\" is missing from config object!"); oyConfig_Release(&device); g_error++; continue; } /*Handle "driver_version" option [OUT] */ version_opt_dev = oyConfig_Find(device, "driver_version"); if (!version_opt_dev && version_opt) oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &version_opt, -1); oyOption_Release(&version_opt_dev); /*Handle "device_context" option */ /*This is always provided by Configs_FromPattern() * [or should be alternatively by the user]. * Configs_Modify() will not scan for SANE devices * because it takes too long*/ context_opt_dev = oyConfig_Find(device, "device_context"); if (!context_opt_dev) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_context\" option is missing!"); error = g_error = 1; } if (!error) { device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc); sane_name = device_context->name; sane_model = device_context->model; } /*Handle "oyNAME_NAME" option */ name_opt_dev = oyConfig_Find(device, "oyNAME_NAME"); if (!error && !name_opt_dev && oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN)) oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"), CMM_BASE_REG OY_SLASH "oyNAME_NAME", sane_model, OY_CREATE_NEW); /*Handle "device_handle" option */ handle_opt_dev = oyConfig_Find(device, "device_handle"); if (!error && !handle_opt_dev) { 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)); } /*Create static rank_map, if not already there*/ if (!oyConfig_GetRankMap( device)) oyConfig_SetRankMap( device, _api8.rank_map ); /*Cleanup*/ oyConfig_Release(&device); oyOption_Release(&context_opt_dev); oyOption_Release(&name_opt_dev); oyOption_Release(&handle_opt_dev); } } else if (command_properties) { /* "properties" call section */ int i; /*Return a full list of scanner H/W & * SANE driver S/W color options * with the according rank map */ for (i = 0; i < num_devices; ++i) { SANE_Device *device_context = NULL; SANE_Status status = SANE_STATUS_INVAL; SANE_Handle device_handle; oyOption_s *name_opt_dev = NULL, *handle_opt_dev = NULL, *context_opt_dev = NULL; oyConfig_s *device_new = NULL; char *device_name = NULL; /* All previous device properties are considered obsolete * and a new device is created. Basic options are moved from * the old to new device */ device = oyConfigs_Get(devices, i); device_new = oyConfig_FromRegistration(CMM_BASE_REG, 0); printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK)); printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK)); /*Ignore device without a device_name*/ if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_name\" is NULL, or missing from config object!"); oyConfig_Release(&device); oyConfig_Release(&device_new); g_error++; continue; } /*Handle "driver_version" option [OUT] */ if (version_opt) { oyOption_s *tmp = oyOption_Copy(version_opt, 0); oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &tmp, -1); } /* 1. Get the "device_name" from old device */ name_opt_dev = oyConfig_Find(device, "device_name"); device_name = oyOption_GetValueText(name_opt_dev, allocateFunc); oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &name_opt_dev, -1); /* 2. Get the "device_context" from old device */ /* It should be there, see "list" call above */ context_opt_dev = oyConfig_Find(device, "device_context"); if (context_opt_dev) { device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc); if (device_context) { oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &context_opt_dev, -1); } else { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_context\" is NULL!"); oyOption_Release(&context_opt_dev); g_error++; } } else { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_context\" option is missing!"); g_error++; } /* 3. Get the scanner H/W properties from old device */ /* FIXME: we only recompute them, just in case they are not in old device */ if (device_context) { DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device_new,"backend_core")); } /* 4. Get the "device_handle" from old device */ /* If not there, get one from SANE */ handle_opt_dev = oyConfig_Find(device, "device_handle"); if (handle_opt_dev) { oyPointer_s * oy_struct = (oyPointer_s*)oyOption_GetStruct( handle_opt_dev, oyOBJECT_POINTER_S ); device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct); oyPointer_Release( &oy_struct ); oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &handle_opt_dev, -1); } else { printf(PRFX "Opening sane device \"%s\"..", device_name); fflush(NULL); status = sane_open( device_name, &device_handle ); if (status != SANE_STATUS_GOOD) printf("[FAIL: %s]\n", sane_strstatus(status)); else printf("[OK]\n"); } if (handle_opt_dev || status == SANE_STATUS_GOOD) { /* Use the device_handle to get the device color options */ ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device_new,"backend_core")); /*5. Set the rank map*/ oyConfig_SetRankMap( device_new, _api8.rank_map ); } /*Cleanup*/ /* Remove old, add new device */ oyConfig_Release(&device); oyConfigs_ReleaseAt(devices, i); oyConfigs_MoveIn(devices, &device_new, -1); /*If we had to open a SANE device, we'll have to close it*/ if (status == SANE_STATUS_GOOD) { printf(PRFX "sane_close(%s)\n", device_name); sane_close(device_handle); } free(device_context); free(device_name); } } 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; } /*Cleanup*/ if (call_sane_exit) { printf(PRFX "sane_exit()\n"); sane_exit(); } oyOption_Release(&version_opt); printf(PRFX "Leaving %s\n", __func__); return g_error; }
/** 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; }
int updateOutputConfiguration( Display * display ) { int error = 0, i, n, update = 0; oyOptions_s * options = 0; oyConfigs_s * devices = 0; oyConfig_s * device = 0, * old_device = 0; /* allow Oyranos to see modifications made to the compiz Xlib context */ XFlush( display ); /* obtain device informations, including geometry and ICC profiles from the according Oyranos module */ error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command", "list", OY_CREATE_NEW ); if(error) WARNc2_S("%s %d", _("found issues"),error); error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/device_rectangle", "true", OY_CREATE_NEW ); if(error) WARNc2_S("%s %d", _("found issues"),error); error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/edid", "refresh", OY_CREATE_NEW ); error = oyDevicesGet( OY_TYPE_STD, "monitor", options, &devices ); if(error) WARNc2_S("%s %d", _("found issues"),error); n = oyOptions_Count( options ); oyOptions_Release( &options ); n = oyConfigs_Count( devices ); /* find out if monitors have changed at all * care only about EDID's and enumeration, no dimension */ if(n != oyConfigs_Count( old_devices )) update = 1; else for(i = 0; i < n; ++i) { const char * edid, * old_edid; device = oyConfigs_Get( devices, i ); old_device = oyConfigs_Get( old_devices, i ); edid = oyOptions_FindString( *oyConfig_GetOptions(device,"backend_core"),"EDID",0 ); old_edid = oyOptions_FindString( *oyConfig_GetOptions(old_device,"backend_core"),"EDID",0 ); if(edid && old_edid && strcmp(edid,old_edid)==0) update = 0; else update = 1; oyConfig_Release( &device ); oyConfig_Release( &old_device ); if(update) break; } if(!update) goto clean_update; cleanDisplay( display, n ); for(i = 0; i < n; ++i) { device = oyConfigs_Get( devices, i ); error = getDeviceProfile( display, device, i ); if(error) WARNc2_S("%s %d", _("found issues"),error); oyConfig_Release( &device ); } clean_update: oyConfigs_Release( &old_devices ); old_devices = devices; return 0; }
/** 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; }
/** @brief create_profile.white_point_adjust.bradford * * The profile will be generated in many different shades, which will explode * conversion cache. */ int oyProfileAddWhitePointEffect( oyProfile_s * monitor_profile, oyOptions_s ** module_options ) { oyProfile_s * wtpt = NULL; double src_XYZ[3] = {0.0, 0.0, 0.0}, dst_XYZ[3] = {0.0, 0.0, 0.0}, scale = 1.0; int error = oyProfile_GetWhitePoint( monitor_profile, src_XYZ ); int32_t display_white_point = oyGetBehaviour( oyBEHAVIOUR_DISPLAY_WHITE_POINT ); oyOptions_s * result_opts = NULL, * opts = NULL; const char * desc = NULL; if(*module_options) { const char * value = oyOptions_FindString( *module_options, "display_white_point", 0 ); if(value) { int c = atoi( value ); if(c >= 0) display_white_point = c; } } if(!display_white_point) return 0; if(!error) error = oyGetDisplayWhitePoint( display_white_point, dst_XYZ ); if(isnan(dst_XYZ[0])) error = 1; if(error) { oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "automatic display_white_point: not readable", OY_DBG_ARGS_); return error; } desc = oyProfile_GetText( monitor_profile, oyNAME_DESCRIPTION ); error = oyOptions_SetFromString( &opts, "//" OY_TYPE_STD "/src_name", desc, OY_CREATE_NEW ); if(error) return error; DBG_S_( oyPrintTime() ); { int current = -1, choices = 0; const char ** choices_string_list = NULL; uint32_t flags = 0; #ifdef HAVE_LOCALE_H char * old_loc = strdup(setlocale(LC_ALL,NULL)); setlocale(LC_ALL,"C"); #endif error = oyOptionChoicesGet2( oyWIDGET_DISPLAY_WHITE_POINT, flags, oyNAME_NAME, &choices, &choices_string_list, ¤t ); if(error > 0) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "oyOptionChoicesGet2 failed %d", OY_DBG_ARGS_, error); #ifdef HAVE_LOCALE_H setlocale(LC_ALL,old_loc); if(old_loc) { free(old_loc); } old_loc = NULL; #endif if(current > 0 && current < choices && choices_string_list) { if(current == 1) /* automatic */ { double temperature = oyGetTemperature(-1); char k[12]; sprintf(k, "%dK", (int)temperature); oyOptions_SetFromString( &opts, "//" OY_TYPE_STD "/illu_name", k, OY_CREATE_NEW ); if(temperature <= 0.1) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "automatic display_white_point: [%g %g %g] %s", OY_DBG_ARGS_, dst_XYZ[0], dst_XYZ[1], dst_XYZ[2], k); } else oyOptions_SetFromString( &opts, "//" OY_TYPE_STD "/illu_name", choices_string_list[current], OY_CREATE_NEW ); if(oy_debug) oyMessageFunc_p( oyMSG_DBG,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "illu_name: %s", OY_DBG_ARGS_, oyOptions_FindString( opts, "illu_name", 0) ); } oyOptionChoicesFree( oyWIDGET_DISPLAY_WHITE_POINT, &choices_string_list, choices ); } if(oy_debug) oyMessageFunc_p( oyMSG_WARN, NULL, OY_DBG_FORMAT_ "src_name: %s -> illu_name: %s", OY_DBG_ARGS_, oyOptions_FindString(opts, "src_name", 0), oyOptions_FindString(opts, "illu_name", 0) ); oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/src_iccXYZ", src_XYZ[0], 0, OY_CREATE_NEW ); oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/src_iccXYZ", src_XYZ[1], 1, OY_CREATE_NEW ); oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/src_iccXYZ", src_XYZ[2], 2, OY_CREATE_NEW ); oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/illu_iccXYZ", dst_XYZ[0], 0, OY_CREATE_NEW ); oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/illu_iccXYZ", dst_XYZ[1], 1, OY_CREATE_NEW ); oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/illu_iccXYZ", dst_XYZ[2], 2, OY_CREATE_NEW ); /* cache the display white point abstract profile */ error = oyOptions_Handle( "//" OY_TYPE_STD "/create_profile.white_point_adjust.bradford", opts, "create_profile.white_point_adjust.bradford.file_name", &result_opts ); DBG_S_( oyPrintTime() ); if(error > 0) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "oyOptions_Handle(white_point_adjust.bradford.file_name) failed %d", OY_DBG_ARGS_, error); /* write cache profile for slightly better speed and useful for debugging */ if(error == 0) { const char * file_name = oyOptions_FindString( result_opts, "file_name", 0 ); char * cache_path = oyGetInstallPath( oyPATH_CACHE, oySCOPE_USER, oyAllocateFunc_ ), *t; if(strstr( cache_path, "device_link") != NULL) { t = strstr( cache_path, "device_link"); t[0] = '\000'; oyStringAddPrintf( &cache_path, 0,0, "white_point_adjust/%s.icc", file_name ); } if(oyIsFile_(cache_path)) { if(oy_debug) oyMessageFunc_p( oyMSG_DBG,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "found file_name: %s -> %s\n", OY_DBG_ARGS_, file_name, cache_path ); wtpt = oyProfile_FromFile( cache_path, 0,0 ); DBG_S_( oyPrintTime() ); } } if(!error && wtpt) { oyOptions_MoveInStruct( module_options, OY_STD "/icc_color/display.icc_profile.abstract.white_point.automatic.oy-monitor", (oyStruct_s**) &wtpt, OY_CREATE_NEW ); oyOptions_Release( &result_opts ); oyOptions_Release( &opts ); return error; } if(!error && !wtpt) { /* detect scaling factor * - convert monitor device RGB to XYZ, * - apply white point adaption matrix, * - convert back to monitor device RGB and * - again to XYZ to detect clipping and * - use that information for scaling inside the white point effect profile */ oyProfile_s * xyz_profile = oyProfile_FromStd( oyASSUMED_XYZ, 0, 0 ); float rgb[9] = {1,0,0, 0,1,0, 0,0,1}, xyz[9] = {0,0,0, 0,0,0, 0,0,0}; oyDATATYPE_e buf_type = oyFLOAT; oyConversion_s * cc_moni2xyz = oyConversion_CreateBasicPixelsFromBuffers( monitor_profile, rgb, oyDataType_m(buf_type), xyz_profile, xyz, oyDataType_m(buf_type), 0, 3 ); oyConversion_s * cc_xyz2moni = oyConversion_CreateBasicPixelsFromBuffers( xyz_profile, xyz, oyDataType_m(buf_type), monitor_profile, rgb, oyDataType_m(buf_type), 0, 3 ); oyMAT3 wtpt_adapt; oyCIEXYZ srcWtpt = {src_XYZ[0], src_XYZ[1], src_XYZ[2]}, dstIllu = {dst_XYZ[0], dst_XYZ[1], dst_XYZ[2]}; error = !oyAdaptationMatrix( &wtpt_adapt, NULL, &srcWtpt, &dstIllu ); int i,j; for(j = 0; j < 100; ++j) { oyConversion_RunPixels( cc_moni2xyz, 0 ); if(oy_debug) oyMessageFunc_p( oyMSG_DBG,(oyStruct_s*)cc_moni2xyz, OY_DBG_FORMAT_ "rgb->xyz:\nR[%g %g %g] G[%g %g %g] B[%g %g %g]", OY_DBG_ARGS_, xyz[0], xyz[1], xyz[2], xyz[3], xyz[4], xyz[5], xyz[6], xyz[7], xyz[8]); oyVEC3 rXYZ, srcXYZ[3] = { {{xyz[0], xyz[1], xyz[2]}}, {{xyz[3], xyz[4], xyz[5]}}, {{xyz[6], xyz[7], xyz[8]}} }; oyMAT3 wtpt_adapt_scaled, scale_mat = {{ {{scale,0,0}}, {{0,scale,0}}, {{0,0,scale}} }}; oyMAT3per( &wtpt_adapt_scaled, &wtpt_adapt, &scale_mat ); oyMAT3eval( &rXYZ, &wtpt_adapt_scaled, &srcXYZ[0] ); for(i = 0; i < 3; ++i) xyz[0+i] = rXYZ.n[i]; oyMAT3eval( &rXYZ, &wtpt_adapt_scaled, &srcXYZ[1] ); for(i = 0; i < 3; ++i) xyz[3+i] = rXYZ.n[i]; oyMAT3eval( &rXYZ, &wtpt_adapt_scaled, &srcXYZ[2] ); for(i = 0; i < 3; ++i) xyz[6+i] = rXYZ.n[i]; if(oy_debug) oyMessageFunc_p( oyMSG_DBG,(oyStruct_s*)cc_moni2xyz, OY_DBG_FORMAT_ "srcWtpt->Illu:\nR[%g %g %g] G[%g %g %g] B[%g %g %g]", OY_DBG_ARGS_, xyz[0], xyz[1], xyz[2], xyz[3], xyz[4], xyz[5], xyz[6], xyz[7], xyz[8]); oyConversion_RunPixels( cc_xyz2moni, 0 ); if(oy_debug) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)cc_moni2xyz, OY_DBG_FORMAT_ "xyz->rgb:\nR[%g %g %g] G[%g %g %g] B[%g %g %g] %g", OY_DBG_ARGS_, rgb[0], rgb[1], rgb[2], rgb[3], rgb[4], rgb[5], rgb[6], rgb[7], rgb[8], scale); if(rgb[0+0] < 0.99 && rgb[3+1] < 0.99 && rgb[6+2] < 0.99) { if(scale < 1.00) scale += 0.01; break; } scale -= 0.01; } } oyMessageFunc_p( /*error ?*/ oyMSG_WARN/*:oyMSG_DBG*/,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "%s display_white_point: %d [%g %g %g] -> [%g %g %g] * %g %d", OY_DBG_ARGS_, desc, display_white_point, src_XYZ[0], src_XYZ[1], src_XYZ[2], dst_XYZ[0], dst_XYZ[1], dst_XYZ[2], scale, error); if(error > 0) return error; /* write cache profile for slightly better speed and useful for debugging */ if(error == 0) { const char * file_name = oyOptions_FindString( result_opts, "file_name", 0 ); char * cache_path = oyGetInstallPath( oyPATH_CACHE, oySCOPE_USER, oyAllocateFunc_ ), *t; if(strstr( cache_path, "device_link") != NULL) { t = strstr( cache_path, "device_link"); t[0] = '\000'; oyStringAddPrintf( &cache_path, 0,0, "white_point_adjust/%s.icc", file_name ); } { error = oyOptions_SetFromDouble( &opts, "//" OY_TYPE_STD "/scale", scale, 0, OY_CREATE_NEW ); if(oy_debug) oyMessageFunc_p( oyMSG_DBG,(oyStruct_s*)monitor_profile, OY_DBG_FORMAT_ "creating file_name: %s -> %s\n", OY_DBG_ARGS_, file_name, cache_path ); error = oyOptions_Handle( "//" OY_TYPE_STD "/create_profile.white_point_adjust.bradford", opts, "create_profile.white_point_adjust.bradford", &result_opts ); wtpt = (oyProfile_s*) oyOptions_GetType( result_opts, -1, "icc_profile", oyOBJECT_PROFILE_S ); error = !wtpt; if(!error) oyProfile_ToFile_( (oyProfile_s_*) wtpt, cache_path ); DBG_S_( oyPrintTime() ); } } error = !wtpt; if(error == 0) oyOptions_MoveInStruct( module_options, OY_STD "/icc_color/display.icc_profile.abstract.white_point.automatic.oy-monitor", (oyStruct_s**) &wtpt, OY_CREATE_NEW ); oyOptions_Release( &result_opts ); oyOptions_Release( &opts ); return error; }
/** Function oyDrawScreenImage * @brief generate a Oyranos image from a given context for display * * The function asks the 'oydi' node to provide parameters to render a * oyImage_s from a prepared oyConversion_s context. * * @param[in] context the Oyranos graph * @param[in,out] ticket rendering context for tracking * rectangles * @param[in] display_rectangle absolute coordinates of visible image * in relation to display * @param[in,out] old_display_rectangle * rembering of display_rectangle + @param[in,out] old_roi_rectangle remembering of ticket's ROI (optional) * @param[in] system_type the system dependent type specification * - "X11" is well supported * - "oy-test" for internal tests * @param[in] data_type_request oyUINT8 or oyUINT16 * @param[in] display the system display with system_type: * - "X11": a Display object * @param[in] window the system window with system_type: * - "X11": a Window ID * @param[in] dirty explicite redraw * @param[out] image the image from graph to display * @return 0 - success, -1 - issue, >= 1 - error * * @version Oyranos: 0.9.6 * @date 2016/09/22 * @since 2010/09/05 (Oyranos: 0.1.11) */ int oyDrawScreenImage ( oyConversion_s * context, oyPixelAccess_s * ticket, oyRectangle_s * display_rectangle, oyRectangle_s * old_display_rectangle, oyRectangle_s * old_roi_rectangle, const char * system_type, oyDATATYPE_e data_type_request, void * display, void * window, int dirty, oyImage_s * image ) { int result = 0; if(context) { double X,Y,W,H; int channels = 0; oyFilterNode_s * node_out = 0; oyRectangle_s * disp_rectangle = 0, * ticket_roi = 0; oyOptions_s * image_tags = 0; oyDATATYPE_e data_type = oyUINT8; oyPixel_t pt = 0; oyRectangle_GetGeo( display_rectangle, &X, &Y, &W, &H ); if(!image) return 1; if( W <= 0 || H <= 0) return -1; image_tags = oyImage_GetTags( image ); if(window && strcmp("X11", system_type) == 0) { #if defined(XCM_HAVE_X11) /* add X11 window and display identifiers to output image */ oyOption_s * o = 0; Display *disp = (Display*) display; Window w = (Window) window; int count = oyOptions_CountType( image_tags, "//" OY_TYPE_STD "/display/window_id", oyOBJECT_BLOB_S ); if(!count && w) { oyBlob_s * win_id = oyBlob_New(0), * display_id = oyBlob_New(0); if(win_id) { oyBlob_SetFromStatic( win_id, (oyPointer)w, 0, 0 ); o = oyOption_FromRegistration( "//" OY_TYPE_STD "/display/window_id", 0 ); oyOption_MoveInStruct( o, (oyStruct_s**)&win_id ); oyOptions_MoveIn( image_tags, &o, -1 ); oyBlob_SetFromStatic( display_id, (oyPointer)disp, 0, 0 ); o = oyOption_FromRegistration( "//" OY_TYPE_STD "/display/display_id", 0 ); oyOption_MoveInStruct( o, (oyStruct_s**)&display_id ); oyOptions_MoveIn( image_tags, &o, -1 ); oyOptions_SetFromText( &image_tags, "//" OY_TYPE_STD "/display/display_name", DisplayString(disp), OY_CREATE_NEW ); } else printf("%s:%d WARNING: no X11 Window obtained or\n" " no oyBlob_s allocateable\n", __FILE__,__LINE__); } #endif } else if(strcmp("oy-test", system_type) == 0) oyOptions_SetFromText( &image_tags, "//" OY_TYPE_STD "/display/display_name", system_type, OY_CREATE_NEW ); /* check if the actual data can be displayed */ pt = oyImage_GetPixelLayout( image, oyLAYOUT ); data_type = oyToDataType_m( pt ); channels = oyToChannels_m( pt ); if(pt != 0 && ((channels != 4 && channels != 3) || data_type != data_type_request)) { printf( "%s:%d WARNING: wrong image data format: %s\n%s\n" "need 4 or 3 channels with %s\n", __FILE__,__LINE__, oyOptions_FindString( image_tags, "filename", 0 ), image ? oyObject_GetName( image->oy_, oyNAME_NICK ) : "", oyDataTypeToText( data_type_request ) ); return 1; } /* Inform about the images display coverage. */ disp_rectangle = (oyRectangle_s*) oyOptions_GetType( image_tags, -1, "display_rectangle", oyOBJECT_RECTANGLE_S ); oyRectangle_SetGeo( disp_rectangle, X,Y,W,H ); node_out = oyConversion_GetNode( context, OY_OUTPUT ); ticket_roi = oyPixelAccess_GetArrayROI( ticket ); /* decide wether to refresh the cached rectangle of our static image */ if( node_out && /* Did the window area move? */ ((!oyRectangle_IsEqual( disp_rectangle, old_display_rectangle ) || /* Something explicite to update? */ (old_roi_rectangle && !oyRectangle_IsEqual( ticket_roi, old_roi_rectangle ))|| /* Did the image move? */ oyPixelAccess_GetStart( ticket,0 ) != oyPixelAccess_GetOldStart( ticket,0 ) || oyPixelAccess_GetStart( ticket,1 ) != oyPixelAccess_GetOldStart( ticket,1 )) || dirty > 0)) { #ifdef DEBUG_ printf( "%s:%d new display rectangle: %s +%d+%d\n", __FILE__,__LINE__, oyRectangle_Show(disp_rectangle), X, Y ), #endif /* convert the image data */ oyConversion_RunPixels( context, ticket ); if(oy_debug && getenv("OY_DEBUG_WRITE")) { oyImage_s * out = oyConversion_GetImage( context, OY_OUTPUT ); oyImage_WritePPM( out, "debug_image_out.ppm", "image_display output image"); oyImage_Release( &out ); } /* remember the old rectangle */ oyRectangle_SetByRectangle( old_display_rectangle, disp_rectangle ); oyRectangle_SetByRectangle( old_roi_rectangle, ticket_roi ); oyPixelAccess_SetOldStart(ticket,0, oyPixelAccess_GetStart(ticket,0)); oyPixelAccess_SetOldStart(ticket,1, oyPixelAccess_GetStart(ticket,1)); } else result = -1; oyFilterNode_Release( &node_out ); oyOptions_Release( &image_tags ); oyRectangle_Release( &disp_rectangle ); oyRectangle_Release( &ticket_roi ); } if(oy_debug >= 4) fprintf( stderr, "%s:%d %s() result: %d\n", strrchr(__FILE__,'/'),__LINE__,__func__, result ); return result; }