* [sources]: add oyProfile_Install()
[oyranos.git] / API_generated / oyranos_devices.c
1 /** @file oyranos_devices.c
2
3    [Template file inheritance graph]
4    +-- oyranos_devices.template.c
5
6  *  Oyranos is an open source Colour Management System
7  *
8  *  @par Copyright:
9  *            2004-2012 (C) Kai-Uwe Behrmann
10  *
11  *  @author   Kai-Uwe Behrmann <ku.b@gmx.de>
12  *  @par License:
13  *            new BSD - see: http://www.opensource.org/licenses/bsd-license.php
14  *  @date     2012/11/15
15  */
16
17
18 #include <string.h>
19
20 #include "oyCMMapi6_s.h"
21 #include "oyCMMapiFilters_s.h"
22 #include "oyCMMapi9_s_.h"
23 #include "oyFilterCore_s_.h"
24 #include "oyFilterNode_s_.h"
25 #include "oyFilterNodes_s.h"
26
27 #include <oyranos_helper.h>
28 #include <oyranos_icc.h>
29
30 #include "oyranos_devices.h"
31 #include "oyranos_devices_internal.h"
32 #include "oyranos_object_internal.h"
33 #include "oyConfig_s_.h"
34 #include "oyOption_s_.h"
35 #include "oyOptions_s_.h"
36 #include "oyProfiles_s.h"
37
38 #include "oyjl/oyjl_tree.h"
39
40
41 /** \addtogroup devices_handling Device API
42  *
43  *  Devices are a special form of configurations. Their access is grouped
44  *  for effective performance. Known devices are queried with
45  *  oyDevicesGet(). oyConfigDomainList() provides a list of known device
46  *  modules.
47  *  A single device can be obtained by oyDeviceGet(). The \a
48  *  device_type argument defaults to OY_TYPE_STD and can be omitted for this
49  *  group. The \a device_class argument specifies a subgroup, e.g. 
50  *  "monitor".
51  *
52  *  All other functions return a handle to the device. With this handle it is
53  *  possible to get informations (oyDeviceGetInfo()), query it's current,
54  *  possibly remote profile (oyDeviceAskProfile2()) or typical used get a 
55  *  profile with fallbacks including the DB through (oyDeviceGetProfile()), 
56  *  set the profile persistent (oyDeviceSetProfile()) or query the persistent
57  *  stored profile (oyDeviceProfileFromDB()).
58  *
59  *  @{
60  */
61
62
63
64 /** Function oyDevicesGet
65  *  @brief   get all devices matching to a device class and type
66  *
67  *  @verbatim
68     // "list" all monitors
69     oyConfigs_s * monitors = 0;
70     int error = oyDevicesGet( 0, "monitor", 0, &monitors );
71     // see how many are included
72     int n = oyConfigs_Count( monitors );
73     // release them
74     oyConfigs_Release( &monitors );
75     @endverbatim
76  *
77  *  For obtaining expensive "properties" informations at once, add the according
78  *  option.
79  *  @verbatim
80     // get all monitors the expensive way
81     oyConfigs_s * monitors = 0;
82     oyOptions_s * options = oyOptions_New( 0 );
83     int error = 0;
84
85     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
86                                    "properties", OY_CREATE_NEW );
87     error = oyDevicesGet( 0, "monitor", 0, &monitors );
88     oyOptions_Release( &options );
89
90     // see how many are included
91     int n = oyConfigs_Count( monitors );
92
93     // release them
94     oyConfigs_Release( &monitors );
95     @endverbatim
96  *
97  *  @param[in]     device_type         the device type ::oyFILTER_REG_TYPE,
98  *                                     defaults to OY_TYPE_STD (optional)
99  *  @param[in]     device_class        the device class, e.g. "monitor",
100  *                                     ::oyFILTER_REG_APPLICATION
101  *  @param[in]     options             options for the device
102  *  @param[out]    devices             the found devices
103  *  @return                            0 - good, >= 1 - error, <= -1 unknown
104  *
105  *  @version Oyranos: 0.1.10
106  *  @since   2009/02/02 (Oyranos: 0.1.10)
107  *  @date    2009/02/02
108  */
109 OYAPI int  OYEXPORT
110            oyDevicesGet              ( const char        * device_type,
111                                        const char        * device_class,
112                                        oyOptions_s       * options,
113                                        oyConfigs_s      ** devices )
114 {
115   int error = !device_class || !device_class[0];
116   static char * num = 0;
117
118   if(error > 0)
119   {
120     WARNc_S( "Argument(s) incorrect. Giving up" );
121     return error;
122   }
123
124   if(!num)
125     oyAllocHelper_m_( num, char, 80, 0, error = 1; return error );
126
127   /** 1. obtain detailed and expensive device informations */
128
129   if(!options)
130   {
131     options = oyOptions_New( 0 );
132     /** 1.1 add "list" call to module arguments */
133     error = oyOptions_SetDeviceTextKey_( (oyOptions_s_*)options, device_type,
134                                              device_class,
135                                              "command", "list" );
136   }
137
138   /** 1.2 ask each module */
139   if(error <= 0)
140     error = oyConfigs_FromDeviceClass( device_type, device_class,
141                                            options, devices, 0 );
142
143
144   return error;
145 }
146
147 /** Function oyDeviceGet
148  *  @brief   ask a module for device informations or other direct calls
149  *
150  *  @verbatim
151     oyConfig_s * device = 0;
152     int error = oyDeviceGet( 0, "monitor", ":0.0", 0, &device );
153     oyConfig_Release( &device );
154     @endverbatim
155  *
156  *  @verbatim
157     // pass empty options to the module to get a usage message
158     oyOptions_s * options = oyOptions_New( 0 );
159     oyDeviceGet( OY_TYPE_STD, "monitor", ":0.0", options, 0 );
160     @endverbatim
161  *
162  *  @param[in]     device_type         the device type, e.g. OY_TYPE_STD,
163  *                                     defaults to OY_TYPE_STD (optional)
164  *  @param[in]     device_class        registration ::oyFILTER_REG_APPLICATION
165  *                                     part, e.g. "monitor", mandatory
166  *  @param[in]     device_name         the device name as returned by
167  *                                     oyConfigs_FromPattern_f, mandatory,
168                                        ::oyFILTER_REG_OPTION
169  *  @param[in]     options             options to pass to the module, for zero
170  *                                     the verbose and expensive "properties"
171  *                                     call is assumed
172  *  @param[out]    device              the returned device
173  *  @return                            error
174  *
175  *  @version Oyranos: 0.1.10
176  *  @since   2009/01/28 (Oyranos: 0.1.10)
177  *  @date    2009/02/09
178  */
179 OYAPI int  OYEXPORT
180            oyDeviceGet               ( const char        * device_type,
181                                        const char        * device_class,
182                                        const char        * device_name,
183                                        oyOptions_s       * options,
184                                        oyConfig_s       ** device )
185 {
186   int error = !device_name || !device_name[0] ||
187               !device_class || !device_class[0];
188   oyConfigs_s * devices = 0;
189   oyConfig_s * s = 0;
190
191   if(error > 0)
192   {
193     WARNc2_S( "No device_name/device_class argument provided. Give up: %s/%s",
194               oyNoEmptyString_m_(device_name),
195               oyNoEmptyString_m_(device_class) );
196     return 0;
197   }
198
199   /** 1. obtain basic device informations */
200
201   if(!options)
202   {
203     options = oyOptions_New( 0 );
204     error = !options;
205     /** 1.1 add "list" call to module arguments */
206     if(error <= 0)
207     error = oyOptions_SetDeviceTextKey_( (oyOptions_s_*)options, device_type,
208                                              device_class,
209                                              "command", "list" );
210   }
211
212   /** 1.1.2 set device filter */
213   if(error <= 0)
214     error = oyOptions_SetDeviceTextKey_( (oyOptions_s_*)options, device_type,
215                                              device_class,
216                                              "device_name",device_name);
217
218   /** 2. get the device */
219   error = oyConfigs_FromDeviceClass( device_type, device_class,
220                                          options, &devices, 0 );
221
222   s = oyConfigs_Get( devices, 0 );
223
224   oyConfigs_Release( &devices );
225
226
227   /** 3. check for success of device detection */
228   error = !s;
229   if(error)
230     DBG_NUM2_S( "%s: \"%s\"", _("Could not open device"), device_name );
231
232   if(device)
233     *device = s;
234   else
235     oyConfig_Release( &s );
236
237   return error;
238 }
239
240 /** Function oyDeviceBackendCall
241  *  @brief   get device answere from options
242  *
243  *  @param[in]     device          the device
244  *  @param[in]     options             options for the device
245  *  @return                            error
246  *
247  *  @version Oyranos: 0.1.10
248  *  @since   2009/02/02 (Oyranos: 0.1.10)
249  *  @date    2009/08/25
250  */
251 OYAPI int  OYEXPORT
252                oyDeviceBackendCall   ( oyConfig_s        * device,
253                                        oyOptions_s       * options )
254 {
255   int error = !device,
256       l_error = 0;
257   oyConfigs_s * devices = 0;
258   oyConfig_s * s = device;
259   int new_options = 0;
260
261   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
262
263   if(!options)
264   {
265     /** 1. obtain detailed and expensive device informations for a
266      *     zero options argument through the "properties" command. */
267     options = oyOptions_New( 0 );
268     l_error = !options; OY_ERR
269     /** 1.1 add "properties" call to module arguments */
270     if(error <= 0)
271     l_error = oyOptions_SetRegistrationTextKey_( oyOptionsPriv_m(options),
272                                                  oyConfigPriv_m(device)->registration,
273                                                  "command", "properties" ); OY_ERR
274     new_options = 1;
275   }
276
277   devices = oyConfigs_New( 0 );
278   error = !devices;
279   
280   if(error <= 0)
281   {
282     /* Keep a reference to config as devices will later be released. */
283     s = oyConfig_Copy( device, 0 );
284
285     oyConfigs_MoveIn( devices, &device, -1 );
286   }
287
288   /** 3. talk to the module */
289   l_error = oyConfigs_Modify( devices, options ); OY_ERR
290
291   oyConfigs_Release( &devices );
292   if(new_options)
293     oyOptions_Release( &options );
294
295   return error;
296 }
297
298 icProfileClassSignature oyDeviceSigGet(oyConfig_s        * device )
299 {
300   icProfileClassSignature deviceSignature = 0;
301   if(oyFilterRegistrationMatch( oyConfigPriv_m(device)->registration, "monitor", 0 ))
302     deviceSignature = icSigDisplayClass;
303   else if(oyFilterRegistrationMatch( oyConfigPriv_m(device)->registration, "scanner", 0 ))
304     deviceSignature = icSigInputClass;
305   else if(oyFilterRegistrationMatch( oyConfigPriv_m(device)->registration, "raw-image", 0 ))
306     deviceSignature = icSigInputClass;
307   else if(oyFilterRegistrationMatch( oyConfigPriv_m(device)->registration, "printer", 0 ))
308     deviceSignature = icSigOutputClass;
309
310   return deviceSignature;
311 }
312
313 /** Function oyDeviceSetup
314  *  @brief   activate the device using the stored configuration
315  *
316  *  @param[in]     device              the device
317  *  @return                            error
318  *
319  *  @version Oyranos: 0.1.10
320  *  @since   2009/01/30 (Oyranos: 0.1.10)
321  *  @date    2009/02/07
322  */
323 OYAPI int  OYEXPORT
324          oyDeviceSetup               ( oyConfig_s        * device )
325 {
326   int error = !device;
327   oyOptions_s * options = 0;
328   oyProfile_s * p = 0;
329   char * profile_name = 0,
330        * profile_name_temp = 0;
331   const char * device_name = 0;
332   oyConfig_s * s = device;
333   oyOption_s * o;
334
335   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
336
337   {
338     /* 1. ask for the profile the device is setup with */
339     error = oyDeviceAskProfile2( device, 0, &p );
340     if(p)
341     {
342       oyProfile_Release( &p );
343       /** We ignore a device, which already has its profile setup. */
344       return error;
345     }
346
347     /* 2. query the full device information */
348     error = oyDeviceProfileFromDB( device, &profile_name, 0 );
349
350     /* 2.1 select best match to device from installed profiles */
351     if(!profile_name)
352     {
353       int size;
354       oyProfile_s * profile = 0;
355       oyProfiles_s * patterns = 0, * iccs = 0;
356       icProfileClassSignature device_signature = oyDeviceSigGet(device);
357       int32_t * rank_list = 0;
358       double clck;
359
360       profile = oyProfile_FromSignature( device_signature, oySIGNATURE_CLASS, 0 );
361       patterns = oyProfiles_New( 0 );
362       oyProfiles_MoveIn( patterns, &profile, -1 );
363
364       clck = oyClock();
365       iccs = oyProfiles_Create( patterns, 0 );
366       clck = oyClock() - clck;
367       DBG_NUM1_S("oyProfiles_Create(): %g", clck/1000000.0 );
368       oyProfiles_Release( &patterns );
369
370       size = oyProfiles_Count(iccs);
371       oyAllocHelper_m_( rank_list, int32_t, oyProfiles_Count(iccs), 0, error = 1; return error );
372       if(error <= 0)
373       {
374         clck = oyClock();
375         oyProfiles_DeviceRank( iccs, device, rank_list );
376         clck = oyClock() - clck;
377         DBG_NUM1_S("oyProfiles_DeviceRank(): %g", clck/1000000.0 );
378       }
379       if(error <= 0 && size && rank_list[0] > 0)
380       {
381         p = oyProfiles_Get( iccs, 0 );
382         profile_name = oyStringCopy_( oyProfile_GetFileName(p, -1),
383                                       oyAllocateFunc_ );
384         WARNc1_S( "implicitely selected %s", oyNoEmptyString_m_(profile_name) );
385         if(oy_debug > 1)
386         {
387           int i, n = oyProfiles_Count( iccs );
388           const char * fn;
389           oyProfile_Release( &p );
390           for(i = 0; i < n; ++i)
391           {
392             p = oyProfiles_Get( iccs, i );
393             fn = oyProfile_GetFileName(p, -1);
394             if(rank_list[i])
395               DBG_NUM2_S("%d: %s", rank_list[i], fn);
396           }
397         }
398         oyFree_m_( rank_list );
399       }
400
401       oyProfile_Release( &p );
402       oyProfiles_Release( &iccs );
403     }
404
405
406     if(!profile_name)
407     {
408       oyOptions_s * fallback = oyOptions_New( 0 );
409       error = oyOptions_SetRegistrationTextKey_( oyOptionsPriv_m(fallback),
410                                                  oyConfigPriv_m(device)->registration,
411                                                  "icc_profile.fallback","true");
412       /* 2.2.1 try fallback for rescue */
413       error = oyDeviceAskProfile2( device, fallback, &p );
414       oyOptions_Release( &fallback );
415       if(p)
416       {
417         profile_name = oyStringCopy_( oyProfile_GetFileName(p, -1),
418                                       oyAllocateFunc_ );
419         if(!profile_name)
420         {
421           oyOptions_s * opts = 0;
422           oyOptions_SetFromText( &opts, "////device", "1", OY_CREATE_NEW );
423           error = oyProfile_Install( p, opts );
424           oyOptions_Release( &opts );
425           if(!error)
426             profile_name = oyStringCopy_( oyProfile_GetText(p, oyNAME_DESCRIPTION),
427                                       oyAllocateFunc_ );
428           else
429           {
430             char * data = 0;
431             size_t size = 0;
432             data = oyProfile_GetMem( p, &size, 0, oyAllocateFunc_ );
433             error = oyWriteMemToFile2_( "oyranos_tmp.icc", data, size,
434                                         OY_FILE_NAME_SEARCH | OY_FILE_TEMP_DIR,
435                                         &profile_name_temp, oyAllocateFunc_ );
436           }
437
438           if(profile_name_temp)
439             profile_name = profile_name_temp;
440           else if( !profile_name )
441           {
442             error = 1;
443             WARNc2_S("%s: \"%s\"(oyranos_tmp.icc)",_("Could not write to file"),
444                       oyNoEmptyString_m_(profile_name_temp) );
445           }
446         }
447       }
448
449       if(!profile_name)
450         return error;
451     }
452
453     /* 2.3 get device_name */
454     device_name = oyConfig_FindString( device, "device_name", 0);
455
456     /* 3. setup the device through the module */
457     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
458                                    "setup", OY_CREATE_NEW );
459     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/device_name",
460                                    device_name, OY_CREATE_NEW );
461     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/profile_name",
462                                    profile_name, OY_CREATE_NEW );
463     /* 3.1 send the query to a module */
464     error = oyDeviceBackendCall( device, options );
465
466     /* 3.2 check if the module has used that profile and complete do that if needed */
467     if(!oyConfig_Has( device, "icc_profile" ))
468     {
469       int has = 0;
470 #define OY_DOMAIN OY_TOP_SHARED OY_SLASH OY_DOMAIN_INTERNAL OY_SLASH OY_TYPE_STD
471       o = oyOption_FromRegistration( OY_DOMAIN OY_SLASH "icc_profile", 0 );
472
473       p = oyProfile_FromFile( profile_name, 0,0 );
474
475       if(p)
476       {
477         has = 1;
478         error = oyOption_StructMoveIn( o, (oyStruct_s**) &p );
479       }
480       else
481       /** Warn on not found profile. */
482       {
483         oyMessageFunc_p( oyMSG_ERROR,(oyStruct_s*)device,
484                        OY_DBG_FORMAT_"\n\t%s: \"%s\"\n\t%s\n", OY_DBG_ARGS_,
485                 _("Could not open ICC profile"), profile_name,
486                 _("install in the OpenIccDirectory icc path") );
487       }
488
489       if(has)
490         oyOptions_Set( oyConfigPriv_m(device)->data, o, -1, 0 );
491       oyOption_Release( &o );
492       oyProfile_Release( &p );
493     }
494
495     if(profile_name_temp)
496       oyRemoveFile_( profile_name_temp );
497     profile_name_temp = 0;
498     oyOptions_Release( &options );
499     if(profile_name)
500       oyFree_m_( profile_name );
501   }
502
503   return error;
504 }
505
506 /** Function oyDeviceUnset
507  *  @brief   unset the device profile
508  *
509  *  The function solely calls \a unset in the module, e.g. unset graphic card
510  *  luts and server stored profile. So pretty all device/server side 
511  *  informatin should go away. \n
512  *
513  *  @param         device          the device
514  *  @return                            error
515  *
516  *  @version Oyranos: 0.1.10
517  *  @since   2009/02/12 (Oyranos: 0.1.10)
518  *  @date    2009/02/12
519  */
520 int      oyDeviceUnset               ( oyConfig_s        * device )
521 {
522   int error = !device;
523   oyOptions_s * options = 0;
524   char * profile_name = 0;
525   const char * device_name = 0;
526   oyConfig_s * s = device;
527
528   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
529
530   {
531     /* 1. query the full device information */
532     error = oyDeviceProfileFromDB( device, &profile_name, 0 );
533
534     /* 1.1 get device_name */
535     device_name = oyConfig_FindString( device, "device_name", 0);
536
537     /* 2. unset the device through the module */
538     /** 2.1 set a general request */
539     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
540                                    "unset", OY_CREATE_NEW );
541     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/device_name",
542                                    device_name, OY_CREATE_NEW );
543
544     /** 2.2 send the query to a module */
545     error = oyConfigs_FromDomain( oyConfigPriv_m(device)->registration, options, 0, 0 );
546
547     oyOptions_Release( &options );
548     /* 3.1 send the query to a module */
549     error = oyDeviceBackendCall( device, options );
550
551     oyOptions_Release( &options );
552     if(profile_name)
553       oyFree_m_( profile_name );
554   }
555
556   return error;
557 }
558
559 /** Function oyDeviceGetInfo
560  *  @brief   get all devices matching to a device class and type
561  *
562  *  @verbatim
563     // print all properties
564     int error = oyDeviceGetInfo( device, oyNAME_DESCRIPTION, 0, &text,
565                                      malloc );
566     char * list = text, * tmp = 0, * line = malloc(128);
567     int even = 1;
568
569         tmp = list;
570         while(list && list[0])
571         {
572           snprintf( line, 128, "%s", list );
573           if(strchr( line, '\n' ))
574           {
575             tmp = strchr( line, '\n' );
576             tmp[0] = 0;
577           }
578           if(even)
579             printf( "%s\n", line );
580           else
581             printf( "  %s\n", line );
582           list = strchr( list, '\n' );
583           if(list) ++list;
584           even = !even;
585         }
586
587     if(line) free(line);
588     if(text) free(text);
589     @endverbatim
590  *
591  *  To obtain a certain single pice of information you do not need 
592  *  oyDeviceGetInfo. See the following example:
593  *  @verbatim
594     char * device_name = ":0.0"; // a typical device
595     char * text = 0;
596     oyConfig_s * device = 0;
597     oyOptions_s * options = 0;
598     int error = 0;
599
600     // tell the module with the "properties" call to add all informations
601     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD
602                                    "/config/command",
603                                    "properties", OY_CREATE_NEW );
604
605     oyDeviceGet( OY_TYPE_STD, "monitor", device_name, options, &device );
606     text = oyConfig_FindString( device, "manufacturer", 0 );
607     @endverbatim
608  *
609  *  @param[in]     device          the device
610  *  @param[in]     type                influences the info_text output
611  *                                     - oyNAME_NAME - a short one line text,
612  *                                     - oyNAME_NICK - one word,
613  *                                     - oyNAME_DESCRIPTION - expensive text,
614  *                                     even lines contain the property key name,
615  *                                     odd lines contain the value,
616  *                                     lines are separated by newline '\\n'
617  *  @param[in]     options             defaults to command=properties
618  *  @param[out]    info_text           the text
619  *  @param[in]     allocateFunc        the user allocator for info_text
620  *  @return                            0 - good, 1 >= error, -1 <= issue(s)
621  *
622  *  @version Oyranos: 0.1.10
623  *  @since   2009/02/02 (Oyranos: 0.1.10)
624  *  @date    2009/03/27
625  */
626 OYAPI int  OYEXPORT
627            oyDeviceGetInfo           ( oyConfig_s        * device,
628                                        oyNAME_e            type,
629                                        oyOptions_s       * options,
630                                        char             ** info_text,
631                                        oyAlloc_f           allocateFunc )
632 {
633   int error = !device || !info_text;
634   oyConfig_s_ * device_ = (oyConfig_s_*)device;
635   oyOption_s * o = 0;
636   oyConfig_s * config = 0;
637   const char * tmp = 0;
638   static char * num = 0;
639   char * text = 0, * t = 0;
640   int i, n,
641       own_options = 0;
642   oyConfig_s * s = device;
643
644   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
645
646   if(error > 0)
647   {
648     WARNc_S( "Argument(s) incorrect. Giving up" );
649     return error;
650   }
651
652   if(!allocateFunc)
653     allocateFunc = oyAllocateFunc_;
654
655   if(!options)
656     own_options = 1;
657
658   if(type == oyNAME_NICK)
659   {
660     tmp = oyOptions_FindString( device_->backend_core,"device_name", 0 );
661     *info_text = oyStringCopy_( tmp, allocateFunc );
662     return error;
663   }
664
665   if(type == oyNAME_DESCRIPTION)
666   {
667     /* get expensive infos */
668     if(oyOptions_Count( device_->backend_core ) < 2)
669     {
670       error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
671                                      "properties", OY_CREATE_NEW );
672
673       if(error <= 0)
674         error = oyDeviceBackendCall( device, options );
675     }
676
677     if(error <= 0)
678     {
679       n = oyOptions_Count( device_->backend_core );
680       for( i = 0; i < n; ++i )
681       {
682         o = oyOptions_Get( device_->backend_core, i );
683         
684         STRING_ADD( text, oyStrrchr_( oyOption_GetRegistration(o),
685                           OY_SLASH_C ) + 1 );
686         STRING_ADD( text, ":\n" );
687         t = oyOption_GetValueText(o,oyAllocateFunc_);
688         if(t)
689         {
690           STRING_ADD( text, t );
691           oyDeAllocateFunc_(t); t = 0;
692         }
693         STRING_ADD( text, "\n" );
694
695         oyOption_Release( &o );
696       }
697     }
698     *info_text = oyStringCopy_( text, allocateFunc );
699     oyFree_m_(text);
700     return error;
701   }
702
703
704   if(!num)
705     oyAllocHelper_m_( num, char, 80, 0, error = 1; return error );
706
707   if(!options)
708   {
709     options = oyOptions_New( 0 );
710
711     error = !options;
712   }
713
714   if(error <= 0)
715   {
716     /* add "list" call to module arguments */
717     error = oyOptions_SetRegistrationTextKey_( (oyOptions_s_*)options,
718                                                device_->registration,
719                                                "command", "list" );
720   }
721
722   if(error <= 0)
723   {
724     if(type == oyNAME_NAME)
725     error = oyOptions_SetRegistrationTextKey_( (oyOptions_s_*)options,
726                                                device_->registration,
727                                                "oyNAME_NAME", "true" );
728   }
729
730
731   /** 1.2 ask each module */
732   if(error <= 0)
733     error = oyDeviceBackendCall( device, options );
734
735   if(error <= 0 && device_->backend_core)
736   {
737     /** 1.2.1 add device_name to the string list */
738     if(type == oyNAME_NICK)
739       tmp = oyOptions_FindString( device_->backend_core,"device_name",0);
740     else if(type == oyNAME_NAME)
741       tmp = oyOptions_FindString( device_->data, "oyNAME_NAME", 0 );
742     else if(type == oyNAME_DESCRIPTION)
743       tmp = oyOptions_FindString( device_->data, "oyNAME_DESCRIPTION", 0 );
744   }
745
746   *info_text = oyStringCopy_( tmp, allocateFunc );
747
748   if(own_options)
749     oyOptions_Release( &options );
750   oyConfig_Release( &config );
751
752   return error;
753 }
754
755 /** Function oyDeviceGetProfile
756  *  @brief   order a device profile
757  *
758  *  This function is designed to satisfy most users as it tries to deliver
759  *  a profile all the time. 
760  *  Following code can almost allways expect some profile to go with.
761  *  It tries hard to get a current profile or set the system up and retry or
762  *  get at least one basic profile.
763  *
764  *  For a basic and thus weaker call to the device use
765  *  oyDeviceAskProfile2() instead.
766  *
767  *  @param         device              the device
768  *  @param         options             options passed to the backend
769  *  @param         profile             the device's ICC profile
770  *  @return                            error
771  *
772  *  @version Oyranos: 0.1.10
773  *  @since   2009/02/08 (Oyranos: 0.1.10)
774  *  @date    2009/02/09
775  */
776 OYAPI int  OYEXPORT
777            oyDeviceGetProfile        ( oyConfig_s        * device,
778                                        oyOptions_s       * options,
779                                        oyProfile_s      ** profile )
780 {
781   int error = !device,
782       l_error = 0;
783   oyConfig_s * s = device;
784
785   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
786
787
788   l_error = oyDeviceAskProfile2( device, options, profile ); OY_ERR
789
790   /** This function does a device setup in case no profile is delivered
791    *  by the according module. */
792   if(error != 0 && !*profile)
793     error = oyDeviceSetup( device );
794
795   if(error <= 0) 
796     l_error = oyDeviceAskProfile2( device, options, profile ); OY_ERR
797
798   /** As a last means oyASSUMED_WEB is delivered. */
799   if(!*profile)
800   {
801     *profile = oyProfile_FromStd( oyASSUMED_WEB, 0 );
802     if(error == 0)
803       error = -1;
804   }
805
806   return error;
807 }
808
809 /** Function oyDeviceAskProfile2
810  *  @brief   ask for the device profile
811  *
812  *  Ask for a profile associated with the device. A device capable to
813  *  hold a profile. Only the held profile will be checked and returned.
814  *  In case this profile is not found a "icc_profile" of oyVAL_STRUCT should be
815  *  included.
816  *
817  *  The device might not be able to hold a profile, then just the DB profile
818  *  will be returned from here without an issue. For interessted users, the
819  *  source of the profile keeps transparent, as it can be checked if the
820  *  device contains a "icc_profile" option which contains a oyProfile_s object.
821  *
822  *  @param[in]     device              the device
823  *  @param[in]     options             additional options
824  *  @param[out]    profile             the device's ICC profile
825  *  @return                            0 - good, 1 >= error, -1 <= issue(s)
826  *
827  *  @version Oyranos: 0.1.10
828  *  @since   2009/02/10 (Oyranos: 0.1.10)
829  *  @date    2009/12/10
830  */
831 OYAPI int  OYEXPORT
832            oyDeviceAskProfile2       ( oyConfig_s        * device,
833                                        oyOptions_s       * options,
834                                        oyProfile_s      ** profile )
835 {
836   int error = !device;
837   oyOption_s * o = 0;
838   oyConfig_s * s = device;
839   int own_options = 0;
840   oyProfile_s * p = 0;
841
842   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
843
844
845   if(!options)
846   {
847     options = oyOptions_New( 0 );
848     own_options = 1;
849     error = !options;
850   }
851
852   if(error <= 0)
853   {
854     /* add "list" call to module arguments */
855     error = oyOptions_SetRegistrationTextKey_( (oyOptions_s_*)options,
856                                                oyConfigPriv_m(device)->registration,
857                                                "command", "list" );
858   }
859
860   if(error <= 0)
861   {
862     error = oyOptions_SetRegistrationTextKey_( (oyOptions_s_*)options,
863                                                  oyConfigPriv_m(device)->registration,
864                                                  "icc_profile", "true" );
865   }
866
867   if(error <= 0)
868     error = oyDeviceBackendCall( device, options );
869
870   /* The backend shows with the existence of the "icc_profile" response that it
871    * can handle device profiles through the driver. */
872   if(error <= 0)
873     o = oyConfig_Find( device, "icc_profile" );
874
875   p = (oyProfile_s*) oyOption_GetStruct( o, oyOBJECT_PROFILE_S );
876   if(oyProfile_GetSignature( p, oySIGNATURE_MAGIC ) == icMagicNumber)
877     *profile = p;
878   else if(!error)
879     error = -1;
880   p = 0;
881
882   /* The backend can not handle device driver profiles. Switch back to DB. */
883   if(error <= 0 && !(*profile) && !o)
884   {
885     char * profile_name = 0;
886     oyDeviceProfileFromDB( device, &profile_name, 0 );
887     if(profile_name)
888     {
889       *profile = oyProfile_FromFile( profile_name, 0,0 );
890       oyDeAllocateFunc_( profile_name );
891     }
892   }
893
894   if(own_options)
895     oyOptions_Release( &options );
896   oyOption_Release( &o );
897
898   return error;
899 }
900
901 /** Function oyDeviceSetProfile
902  *  @brief   set the device profile
903  *
904  *  The function will lookup the monitor in the Oyranos device database
905  *  and stores the given profile there.
906  *
907  *  To set a new profile und update the device please call the following
908  *  sequence:
909  *  @verbatim
910     // store new settings in the Oyranos data base
911     oyDeviceSetProfile( device, profile );
912     // remove any device entries
913     oyDeviceUnset( device );
914     // update the device from the newly added Oyranos data base settings
915     oyDeviceSetup( device );
916     @endverbatim
917  *
918  *  @param         device              the device
919  *  @param         profile_name        the device's ICC profile or zero to
920  *                                     unset
921  *  @return                            error
922  *
923  *  @version Oyranos: 0.1.10
924  *  @since   2009/02/07 (Oyranos: 0.1.10)
925  *  @date    2009/02/12
926  */
927 int      oyDeviceSetProfile          ( oyConfig_s        * device,
928                                        const char        * profile_name )
929 {
930   int error = !device || !profile_name || !profile_name[0];
931   oyOption_s * od = 0;
932   oyOptions_s * options = 0;
933   oyConfigs_s * configs = 0;
934   oyConfig_s * config = 0,
935              * device_tmp = 0;
936   oyProfile_s * p = 0;
937   int i, j, n, j_n, equal;
938   char * d_opt = 0;
939   const char * device_name = 0,
940              * o_val = 0,
941              * d_val = 0;
942   oyConfig_s * s = device;
943
944   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
945
946   if(error > 0)
947   {
948     WARNc1_S( "No profile argument provided. Give up. %s",
949               oyNoEmptyString_m_(profile_name) );
950     return error;
951   }
952
953
954   /** 1. obtain detailed and expensive device informations */
955   if(oyOptions_Count( oyConfigPriv_m(device)->backend_core ) < 2)
956   { 
957     /** 1.1 add "properties" call to module arguments */
958     error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
959                                    "properties", OY_CREATE_NEW );
960
961     /** 1.2 get monitor device */
962     if(error <= 0)
963       error = oyDeviceBackendCall( device, options );
964
965     oyOptions_Release( &options );
966   }
967
968   if(error <= 0)
969     error = !oyOptions_Count( oyConfigPriv_m(device)->backend_core );
970
971   if(error <= 0)
972   {
973     device_name = oyConfig_FindString( device, "device_name", 0);
974     error = !device_name;
975   }
976
977   /** 2. check for success of device detection */
978   if(error)
979   {
980     WARNc2_S( "%s: \"%s\"", _("Could not open device"), device_name );
981     goto cleanup;
982   }
983
984   /** 3 load profile from file name argument */
985   p = oyProfile_FromFile( profile_name, 0, 0 );
986
987   /** 3.1 check for success of profile loading */
988   error = !p;
989   if(error)
990   {
991     WARNc2_S( "%s: \"%s\"", _("Could not open profile"), profile_name );
992     goto cleanup;
993   }
994
995   /** 4. Now remove all those DB configurations fully matching the selected
996    *     device.  */
997   if(error <= 0)
998   {
999     /** 4.1 get stored DB's configurations */
1000     error = oyConfigs_FromDB( oyConfigPriv_m(device)->registration, &configs, 0 );
1001
1002     n = oyConfigs_Count( configs );
1003     for( i = 0; i < n; ++i )
1004     {
1005       config = oyConfigs_Get( configs, i );
1006
1007       equal = 0;
1008
1009       j_n = oyOptions_Count( oyConfigPriv_m(device)->backend_core );
1010       for(j = 0; j < j_n; ++j)
1011       {
1012         od = oyOptions_Get( oyConfigPriv_m(device)->backend_core, j );
1013         d_opt = oyFilterRegistrationToText( oyOption_GetRegistration(od),
1014                                             oyFILTER_REG_MAX, 0 );
1015         d_val = oyConfig_FindString( device, d_opt, 0 );
1016
1017         o_val = oyConfig_FindString( config, d_opt, 0 );
1018
1019         /** 4.1.1 compare if each device key matches to one configuration
1020          *          key */
1021         if( (d_val && o_val &&
1022              oyStrcmp_( d_val, o_val ) == 0 ) ||
1023             (!d_val && !o_val) )
1024           ++equal;
1025         else
1026           if(oyStrcmp_( d_opt, "profile_name") == 0)
1027             ++equal;
1028
1029         oyOption_Release( &od );
1030         oyFree_m_( d_opt );
1031       }
1032
1033       /** 4.1.2 if the 4.1.1 condition is true remove the configuration */
1034       if(equal == j_n)
1035         oyConfig_EraseFromDB( config );
1036
1037       oyConfig_Release( &config );
1038     }
1039     oyConfigs_Release( &configs );
1040   }
1041
1042   /** 5. save the new configuration with a associated profile \n
1043    *  5.1 add the profile simply to the device configuration */
1044   if(error <= 0)
1045   {
1046     error = oyConfig_ClearDBData( device );
1047     error = oyConfig_AddDBData( device, "profile_name", profile_name,
1048                                 OY_CREATE_NEW );
1049   }
1050
1051   /** 5.2 save the configuration to DB (Elektra) */
1052   if(error <= 0)
1053     error = oyConfig_SaveToDB( device );
1054   /** 5.3 reload the DB part */
1055   if(error <= 0)
1056     error = oyConfig_GetDB( device, 0 );
1057
1058   cleanup:
1059   oyConfig_Release( &device_tmp );
1060
1061   return error;
1062 }
1063
1064 /** Function oyDeviceProfileFromDB
1065  *  @brief   look up a profile of a device from DB
1066  *
1067  *  The function asks the module for a detailed and possible expensive list
1068  *  of device information and tries to find a matching configuration in the
1069  *  DB. The device informations are the same as for saving to DB.
1070  *
1071  *  @param[in]     device          a device
1072  *  @param[in]     profile_name        profile's name in DB
1073  *  @param[in]     allocateFunc        user allocator
1074  *  @return                            error
1075  *
1076  *  @version Oyranos: 0.1.10
1077  *  @since   2009/01/21 (Oyranos: 0.1.10)
1078  *  @date    2009/02/09
1079  */
1080 OYAPI int OYEXPORT oyDeviceProfileFromDB
1081                                      ( oyConfig_s        * device,
1082                                        char             ** profile_name,
1083                                        oyAlloc_f           allocateFunc )
1084 {
1085   oyOption_s * o = 0;
1086   oyOptions_s * options = 0;
1087   int error = !device || !profile_name;
1088   const char * device_name = 0;
1089   char * tmp = 0, * tmp2 = 0;
1090   int32_t rank_value = 0;
1091   oyConfig_s * s = device;
1092
1093   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
1094
1095   if(!allocateFunc)
1096     allocateFunc = oyAllocateFunc_;
1097
1098   if(error <= 0)
1099   {
1100     o = oyConfig_Find( device, "profile_name" );
1101     device_name = oyConfig_FindString( device, "device_name", 0);
1102
1103     /* 1. obtain detailed and expensive device informations */
1104     if( !oyConfig_FindString(s,"manufacturer",0) ||
1105         !oyConfig_FindString(s,"model",0) )
1106     { 
1107       /* 1.1 add "properties" call to module arguments */
1108       error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
1109                                      "properties", OY_CREATE_NEW );
1110       error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/device_name",
1111                                      device_name, OY_CREATE_NEW );
1112
1113       device_name = 0;
1114
1115       /* 1.2 get device */
1116       if(error <= 0)
1117         error = oyDeviceBackendCall( device, options );
1118
1119       oyOptions_Release( &options );
1120
1121       /* renew outdated string */
1122       o = oyConfig_Find( device, "profile_name" );
1123       device_name = oyConfig_FindString( device, "device_name", 0);
1124       oyOption_Release( &o );
1125     }
1126
1127     if(!o)
1128     {
1129       error = oyConfig_GetDB( device, &rank_value );
1130       o = oyConfig_Find( device, "profile_name" );
1131     }
1132
1133     if(!o)
1134     {
1135       o = oyOptions_Get( oyConfigPriv_m(device)->db, 0 );
1136       if(o)
1137         tmp = oyStringCopy_(oyOption_GetRegistration(o), oyAllocateFunc_);
1138       if(tmp && oyStrrchr_( tmp, OY_SLASH_C))
1139       {
1140         tmp2 = oyStrrchr_( tmp, OY_SLASH_C);
1141         tmp2[0] = 0;
1142       }
1143       WARNc3_S( "\n Could not get a \"profile_name\" from %s\n"
1144                 " registration: \"%s\" rank: %d", 
1145                 oyNoEmptyString_m_(device_name), oyNoEmptyString_m_(tmp),
1146                 (int)rank_value )
1147       if(tmp)
1148         oyFree_m_(tmp); tmp2 = 0;
1149       oyOption_Release( &o );
1150       error = -1;
1151     } else if(!oyOption_GetValueString(o,0))
1152     {
1153       WARNc1_S( "Could not get \"profile_name\" data from %s", 
1154                 oyNoEmptyString_m_(device_name) )
1155       error = -1;
1156     } else
1157       *profile_name = oyOption_GetValueText( o, allocateFunc );
1158
1159   } else
1160     WARNc_S( "missed argument(s)" );
1161
1162   return error;
1163 }
1164
1165 /** Function oyDeviceSelectSimiliar
1166  *  @brief   get similiar devices by a pattern from a list
1167  *
1168  *  The function takes a device and tries to find exact matches, which can be
1169  *  considered as belonging to the same device. The comparision can be 
1170  *  influenced by the flags.
1171  *  The option "profile_name" is ignored during the comparision.
1172  *
1173  *  @param[in]     pattern             Pass a device used as reference. String
1174  *                                     options of this object are compared to
1175  *                                     the objects in the heap argument
1176  *                                     depending on the flags argument.
1177  *                                     "profile_name" and other
1178  *                                     options from heap objects are ignored.
1179  *  @param[in]     heap                a list of device objects
1180  *  @param[in]     flags               - 0 yields exact match
1181  *                                     - 1 compare manufacturer model and serial
1182  *                                     - 2 compare only manufacturer and model
1183  *                                     - 4 compare only device_name
1184  *  @param[out]    matched_devices     the devices selected from heap
1185  *  @return                            error
1186  *
1187  *  @version Oyranos: 0.1.10
1188  *  @since   2009/08/27 (Oyranos: 0.1.10)
1189  *  @date    2009/08/27
1190  */
1191 OYAPI int OYEXPORT oyDeviceSelectSimiliar
1192                                      ( oyConfig_s        * pattern,
1193                                        oyConfigs_s       * heap,
1194                                        uint32_t            flags,
1195                                        oyConfigs_s      ** matched_devices )
1196 {
1197   oyOption_s * odh = 0,
1198              * od = 0;
1199   int error  = !pattern || !matched_devices;
1200   char * od_key = 0;
1201   const char * od_val = 0,
1202              * odh_val = 0;
1203   oyConfig_s * s = pattern,
1204              * dh = 0;
1205   oyConfigs_s * matched = 0;
1206   int i,j,n,j_n;
1207   int match = 1;
1208
1209   oyCheckType__m( oyOBJECT_CONFIG_S, return 1 )
1210
1211   if(error <= 0)
1212   {
1213     n = oyConfigs_Count( heap );
1214
1215     /* Make shure the pattern has as well manufacturer, model included.
1216      * If not try a "properties" command. */
1217     if((flags == 0 || flags == 1 || flags == 2) &&
1218        (!oyConfig_FindString(s,"manufacturer",0) ||
1219         !oyConfig_FindString(s,"model",0)))
1220     {
1221       oyOptions_s * options = 0;
1222       error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "/config/command",
1223                                    "properties", OY_CREATE_NEW );
1224       oyDeviceBackendCall( s, options );
1225       oyOptions_Release( &options );
1226     }
1227
1228     if((flags == 1 || flags == 2) &&
1229        (!oyConfig_FindString(s,"manufacturer",0) ||
1230         !oyConfig_FindString(s,"model",0)))
1231     {
1232       return 0;
1233     }
1234
1235     matched = oyConfigs_New( 0 );
1236
1237     for(i = 0; i < n; ++i)
1238     {
1239       match = 0;
1240       dh = oyConfigs_Get( heap, i );
1241
1242       j_n = oyConfig_Count( pattern );
1243       for(j = 0; j < j_n; ++j)
1244       {
1245         match = 1;
1246         od = oyConfig_Get( pattern, j );
1247         od_key = oyFilterRegistrationToText( oyOption_GetRegistration(od),
1248                                              oyFILTER_REG_MAX, 0);
1249
1250         od_val = oyOption_GetValueString( od, 0 );
1251         if(!od_val)
1252           /* ignore non text options */
1253           continue;
1254
1255         /* handle selective flags */
1256         if(flags == 4 &&
1257            oyStrcmp_(od_key,"device_name") != 0
1258           )
1259           continue;
1260         else
1261         if(flags == 2 &&
1262            oyStrcmp_(od_key,"manufacturer") != 0 &&
1263            oyStrcmp_(od_key,"model") != 0
1264           )
1265           continue;
1266         else
1267         if(flags == 1 &&
1268            oyStrcmp_(od_key,"manufacturer") != 0 &&
1269            oyStrcmp_(od_key,"model") != 0 &&
1270            oyStrcmp_(od_key,"serial") != 0
1271           )
1272           continue;
1273
1274         /* ignore a "profile_name" option */
1275         if(oyStrcmp_(od_key,"profile_name") == 0)
1276           continue;
1277
1278         odh = oyOptions_Find( oyConfigPriv_m(dh)->db, od_key );
1279
1280         odh_val = oyOption_GetValueString( odh, 0 );
1281         if( !odh_val )
1282           /* ignore non text options */
1283           match = 0;
1284
1285         if(match && oyStrcmp_( od_val, odh_val ) != 0)
1286           match = 0;
1287
1288         /*printf("pruefe: %s=%s match = %d flags=%d\n", od_key, od_val, match, flags);*/
1289
1290
1291         oyOption_Release( &od );
1292
1293         oyOption_Release( &odh );
1294
1295         if(match == 0)
1296           break;
1297       }
1298
1299       if(match)
1300         oyConfigs_MoveIn( matched, &dh, -1 );
1301       else
1302         oyConfig_Release( &dh );
1303     }
1304
1305     if(oyConfigs_Count( matched ))
1306       *matched_devices = matched;
1307     else
1308       oyConfigs_Release( &matched );
1309
1310   } else
1311     WARNc_S( "missed argument(s)" );
1312
1313   return error;
1314 }
1315
1316 /** Function oyDeviceFromJSON
1317  *  @brief   generate a device from a JSON device calibration
1318  *
1319  *  @param[in]    json_text            the device calibration
1320  *  @param[in]    options              optional
1321  *                                     - "underline_key_suffix" will be used as
1322  *                                       suffix for keys starting with underline
1323  *                                       '_'
1324  *                                     - "pos" integer selects position in array
1325  *  @param[out]   config               the device
1326  *  @return                            error
1327  *
1328  *  @version Oyranos: 0.3.3
1329  *  @since   2011/08/21 (Oyranos: 0.3.2)
1330  *  @date    2012/01/06
1331  */
1332 OYAPI int  OYEXPORT oyDeviceFromJSON ( const char        * json_text,
1333                                        oyOptions_s       * options,
1334                                        oyConfig_s       ** device )
1335 {
1336   int error = !json_text || !device;
1337   oyConfig_s * device_ = NULL;
1338   oyjl_value_s * json = 0,
1339                * json_device;
1340   char * val, * key, * t = NULL;
1341   const char * xpath = "org/freedesktop/openicc/device/[0]/[%d]";
1342   int count, i;
1343   int32_t pos = 0;
1344   const char * underline_key_suffix = oyOptions_FindString( options,
1345                                                     "underline_key_suffix", 0 );
1346
1347   yajl_status status;
1348
1349   device_ = oyConfig_FromRegistration( "//" OY_TYPE_STD "/config", 0 );
1350   status = oyjl_tree_from_json( json_text, &json, 0 );
1351   if(status != yajl_status_ok)
1352     WARNc2_S( "\"%s\" %d\n", _("found issues parsing JSON"), status );
1353
1354   error = oyOptions_FindInt( options, "pos", 0, &pos );
1355   oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1356                           xpath, pos );
1357
1358   json_device = oyjl_tree_get_value( json, t );
1359
1360   if(!json_device)
1361     WARNc2_S( "\"%s\" %s\n", t,_("not found:") );
1362   oyFree_m_( t );
1363       
1364   count = oyjl_value_count(json_device);
1365   for(i = 0; i < count; ++i)
1366   {
1367     oyjl_value_s * v = oyjl_value_pos_get( json_device, i );
1368     key = oyStringCopy_(oyjl_print_text( &v->value.object->key ), 0);
1369     val = oyjl_value_text( v, oyAllocateFunc_ );
1370
1371     if(key && key[0] && key[0] == '_' && underline_key_suffix)
1372     {
1373       t = 0;
1374       STRING_ADD( t, underline_key_suffix );
1375       STRING_ADD( t, key );
1376       oyFree_m_( key );
1377       key = t; t = 0;
1378     }
1379
1380     /* ignore empty keys or values */
1381     if(key && val)
1382       oyConfig_AddDBData( device_, key, val, OY_CREATE_NEW );
1383
1384     if(key) oyDeAllocateFunc_(key);
1385     if(val) oyDeAllocateFunc_(val);
1386   }
1387
1388   *device = device_;
1389   device_ = NULL;
1390
1391   return error;
1392 }
1393
1394 #define OPENICC_DEVICE_JSON_HEADER \
1395   "{\n" \
1396   "  \"org\": {\n" \
1397   "    \"freedesktop\": {\n" \
1398   "      \"openicc\": {\n" \
1399   "        \"device\": {\n" \
1400   "          \"%s\": [{\n"
1401 #define OPENICC_DEVICE_JSON_FOOTER \
1402   "            }\n" \
1403   "          ]\n" \
1404   "        }\n" \
1405   "      }\n" \
1406   "    }\n" \
1407   "  }\n" \
1408   "}\n"
1409
1410 /** Function oyDeviceToJSON
1411  *  @brief   get JSON format device calibration text from a device
1412  *
1413  *  @param[in]     config              the device
1414  *  @param[in]     options             unused
1415  *  @param[out]    json_text           the device calibration
1416  *  @param[in]     allocateFunc        user allocator
1417  *  @return                            error
1418  *
1419  *  @version Oyranos: 0.3.2
1420  *  @since   2011/08/21 (Oyranos: 0.3.2)
1421  *  @date    2011/08/21
1422  */
1423 OYAPI int OYEXPORT oyDeviceToJSON    ( oyConfig_s        * device,
1424                                        oyOptions_s       * options,
1425                                        char             ** json_text,
1426                                        oyAlloc_f           allocateFunc )
1427 {
1428   int error = 0;
1429   int count = oyConfig_Count( device ), j, k;
1430   char * t = NULL; 
1431   char * value, * key;
1432   const char * device_class = NULL;
1433   oyConfDomain_s * domain;
1434
1435   if(!error)
1436   {
1437       {
1438         oyOption_s * opt = oyConfig_Get( device, 0 );
1439
1440         domain = oyConfDomain_FromReg( oyOption_GetRegistration( opt ), 0 );
1441         device_class = oyConfDomain_GetText( domain, "device_class", oyNAME_NICK );
1442         oyOption_Release( &opt );
1443
1444         /* add device class */
1445         oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1446                             OPENICC_DEVICE_JSON_HEADER, device_class );
1447
1448         /* add device and driver calibration properties */
1449         for(j = 0; j < count; ++j)
1450         {
1451           int vals_n = 0;
1452           char ** vals = 0, * val = 0;
1453           opt = oyConfig_Get( device, j );
1454
1455           key = oyFilterRegistrationToText( oyOption_GetRegistration( opt ),
1456                                             oyFILTER_REG_MAX, 0 );
1457           value = oyOption_GetValueText( opt, oyAllocateFunc_ );
1458
1459           if(value && count > j)
1460           {
1461             if(value[0] == '<')
1462                oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1463                "              \"%s\": \"%s\"",
1464                      key, value );
1465             else
1466             {
1467               /* split into a array with a useful delimiter */
1468               vals = oyStringSplit_( value, '?', &vals_n, malloc );
1469               if(vals_n > 1)
1470               {
1471                 STRING_ADD( val, "              \"");
1472                 STRING_ADD( val, key );
1473                 STRING_ADD( val, ": [" );
1474                 for(k = 0; k < vals_n; ++k)
1475                 {
1476                   if(k != 0)
1477                   STRING_ADD( val, "," );
1478                   STRING_ADD( val, "\"" );
1479                   STRING_ADD( val, vals[k] );
1480                   STRING_ADD( val, "\"" );
1481                 }
1482                 STRING_ADD( val, "]");
1483                 oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1484                      "%s", val );
1485                 if(val) free( val );
1486               } else
1487                 oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1488                      "              \"%s\": \"%s\"",
1489                      key, value );
1490
1491               oyStringListRelease_( &vals, vals_n, free );
1492             }
1493           }
1494           if(value && j < count - 1)
1495             oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1496                                 ",\n" );
1497           oyOption_Release( &opt );
1498           if(key)
1499             oyFree_m_( key );
1500           if(value)
1501             oyFree_m_( value );
1502         }
1503
1504         oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1505                             "\n"OPENICC_DEVICE_JSON_FOOTER );
1506         oyConfDomain_Release( &domain );
1507       }
1508
1509       if(json_text && t)
1510       {
1511         *json_text = oyStringCopy_( t, allocateFunc );
1512         oyFree_m_( t );
1513       }
1514   }
1515
1516   return error;
1517 }
1518
1519 #define OPENICC_DEVICE_JSON_HEADER_BASE \
1520   "{\n" \
1521   "  \"org\": {\n" \
1522   "    \"freedesktop\": {\n" \
1523   "      \"openicc\": {\n" \
1524   "        \"device\": {\n" \
1525   "          \"%s\":\n"
1526 #define OPENICC_DEVICE_JSON_FOOTER_BASE \
1527   "        }\n" \
1528   "      }\n" \
1529   "    }\n" \
1530   "  }\n" \
1531   "}\n"
1532
1533 int   oyCompareRanks_                ( const void       * rank1,
1534                                        const void       * rank2 )
1535 {const int32_t *r1=(int32_t*)rank1, *r2=(int32_t*)rank2; if(r1[1] < r2[1]) return 1; else return 0;}
1536
1537 /** Function  oyDevicesFromTaxiDB
1538  *  @brief    search a calibration state in the taxi DB for a device
1539  *
1540  *  oyDevicesFromTaxiDB() needs a device containing the calibration state and
1541  *  gives you a list of found device in Taxi DB. You can extract the
1542  *  device ID inside the "TAXI_id" string from the returned devices "db"
1543  *  options sets.
1544  *  Typical you want one entry in the profiles list assigned with that
1545  *  device. oyProfile_FromTaxiDB() can be used to download that and
1546  *  oyProfile_Install() helps installing it, while doing some consistency
1547  *  checks.
1548  *
1549  *  @verbatim
1550     // get a device
1551     oyConfig_s * device = 0;
1552     oyDeviceGet( 0, "monitor", ":0.0", 0, &device );
1553
1554     // get all Taxi DB entries for a device
1555     oyConfigs_s * taxi_devices = 0;
1556     int error;
1557
1558     error = oyDevicesFromTaxiDB( device, 0, &taxi_devices, 0 );
1559
1560     // see how many are included
1561     int n = oyConfigs_Count( taxi_devices ),
1562         i;
1563     char * id = calloc( sizeof(char), 1024 );
1564     for(i = 0; i < n; ++i)
1565     {
1566       int32_t rank = 0;
1567       oyOptions_s * options = 0;
1568       oyProfile_s * ip;
1569       oyConfig_s * taxi_device = oyConfigs_Get( taxi_devices, i );
1570
1571       error = oyConfig_Compare( device, taxi_device, &rank );
1572
1573       // get first profile from Taxi DB
1574       if(i == 0)
1575       {
1576         // select the first assigned profile in position zero
1577         snprintf( id, 1024, "%s/0", oyOptions_FindString(
1578                                        *oyConfig_GetOptions(taxi_device,"db"),
1579                                        "TAXI_id", 0 ));
1580         error = oyOptions_SetFromText( &options,
1581                                        "//" OY_TYPE_STD "/db/TAXI_id",
1582                                        id,
1583                                        OY_CREATE_NEW );
1584         ip = oyProfile_FromTaxiDB( options, NULL );
1585         oyOptions_Release( &options );
1586         if(rank > 0)
1587         {
1588           error = oyOptions_SetFromText( &options,
1589                                          "////device", "1",
1590                                          OY_CREATE_NEW );
1591           error = oyProfile_Install( ip, options );
1592           if(!ip)
1593             printf( "No valid Profile obtained: %s\n", id );
1594           if(error == oyERROR_DATA_AMBIGUITY)
1595             printf( "Profile already installed: %s\n", oyProfile_GetText( ip, oyNAME_DESCRIPTION ));
1596           else if(error == oyERROR_DATA_WRITE)
1597             printf( "User Path can not be written\n" );
1598           else if(error == oyCORRUPTED)
1599             printf( "Profile not useable: %s\n", oyProfile_GetText( ip, oyNAME_DESCRIPTION ) );
1600           else if(error > 0)
1601             printf( "%s - %d","Internal Error", error );
1602         }
1603       }
1604       if(rank > 0)
1605       {
1606         printf( "rank[%d]\n", rank );
1607       }
1608     }
1609
1610     // release data
1611     oyConfigs_Release( &taxi_devices );
1612     @endverbatim
1613  *
1614  *  @param[in]     device              the device
1615  *  @param[in]     options             not used
1616  *  @param[out]    devices             the obtained device calibrations
1617  *  @return                            0 - good, >= 1 - error + a message should
1618  *                                     be sent
1619  *
1620  *  @version Oyranos: 0.9.1
1621  *  @since   2011/09/14 (Oyranos: 0.3.2)
1622  *  @date    2012/11/15
1623  */
1624 OYAPI int  OYEXPORT
1625              oyDevicesFromTaxiDB     ( oyConfig_s        * device,
1626                                        oyOptions_s       * options,
1627                                        oyConfigs_s      ** devices,
1628                                        oyObject_s          obj )
1629 {
1630   int error = 0;
1631   oyConfigs_s * configs_ = 0,
1632               * taxi_devices = 0;
1633   oyConfig_s_ * s = (oyConfig_s_*)device;
1634   char * manufacturers;
1635   size_t size = 0;
1636   int n;
1637   const char * short_name = NULL,
1638              * long_name = NULL,
1639              * name = NULL;
1640
1641   oyCheckType__m( oyOBJECT_CONFIG_S, return 0 )
1642
1643   error = oyDeviceCheckProperties ( device );
1644
1645
1646   manufacturers = oyReadUrlToMem_( "http://icc.opensuse.org/manufacturers",
1647                                    &size, "r", oyAllocateFunc_ );
1648
1649   
1650   if(manufacturers)
1651   {
1652     oyjl_value_s * root = 0;
1653     int count = 0, i;
1654     char * val = NULL,
1655          * key = NULL;
1656     char * json_text = NULL;
1657     const char * prefix = oyConfig_FindString( device, "prefix", 0 );
1658
1659     error = oyjl_tree_from_json( manufacturers, &root, NULL );
1660     if(prefix)
1661       oyStringAddPrintf_( &key, oyAllocateFunc_, oyDeAllocateFunc_,
1662                           "%smnft", prefix );
1663     else
1664       oyStringAddPrintf_( &key, oyAllocateFunc_, oyDeAllocateFunc_,
1665                           "mnft" );
1666     name = short_name = oyConfig_FindString( device, key, 0 );
1667     oyFree_m_(key);
1668     if(prefix)
1669       oyStringAddPrintf_( &key, oyAllocateFunc_, oyDeAllocateFunc_,
1670                           "%smanufacturer", prefix );
1671     else
1672       oyStringAddPrintf_( &key, oyAllocateFunc_, oyDeAllocateFunc_,
1673                           "manufacturer" );
1674     if(!short_name)
1675       name = long_name = oyConfig_FindString( device, key, 0 );
1676     oyFree_m_(key);
1677
1678     if(oy_debug)
1679       WARNc1_S("manufacturers:\n%s", manufacturers);
1680
1681     if(root)
1682     {
1683       int done = 0;
1684       oyjl_value_s * v = 0, * tv = 0;
1685
1686       count = oyjl_value_count(root);
1687       for(i = 0; i < count; ++i)
1688       {
1689         if(short_name)
1690           v = oyjl_tree_get_valuef( root, 
1691                               "[%d]/short_name", i );
1692         else if(long_name)
1693           v = oyjl_tree_get_valuef( root, 
1694                               "[%d]/long_name", i );
1695
1696         val = oyjl_value_text( v, oyAllocateFunc_ );
1697         if( val && name && strcmp( val, name) == 0 )
1698           done = 1;
1699         else
1700           DBG_NUM2_S("could not find device:\n%s %s",
1701                    oyNoEmptyString_m_(name), oyNoEmptyString_m_(val));
1702
1703         if(done) break;
1704         if(val) oyDeAllocateFunc_(val); val = 0;
1705       }
1706
1707       error = oyjl_tree_free( &root );
1708
1709       /* get the devices */
1710       if(done)
1711       {
1712         char * device_db, * t = NULL;
1713         oyOptions_s * opts = NULL;
1714         oyConfig_s * dev;
1715
1716         /* put a cloak around the bare meta data, so it behaves like OpenICC
1717          * JSON */
1718         oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1719                             OPENICC_DEVICE_JSON_HEADER_BASE, "dummy" );
1720
1721         /* the device DB JSON contains all device meta data for one
1722          * mnft / manufacturer */
1723         device_db = oyReadUrlToMemf_( &size, "r", oyAllocateFunc_,
1724                             "http://icc.opensuse.org/devices/%s", val );
1725         STRING_ADD( t, device_db );
1726         oyFree_m_( device_db );
1727
1728         oyStringAddPrintf_( &t, oyAllocateFunc_, oyDeAllocateFunc_,
1729                             "\n"OPENICC_DEVICE_JSON_FOOTER_BASE );
1730         device_db = t; t = NULL;
1731
1732         if(oy_debug)
1733           oyMessageFunc_p( oyMSG_DBG,(oyStruct_s*)device,
1734                        OY_DBG_FORMAT_
1735                        "http://icc.opensuse.org/devices/%s with header:\n%s",
1736                        OY_DBG_ARGS_,
1737                        val, oyNoEmptyString_m_(device_db) );
1738         error = oyjl_tree_from_json( device_db, &root, NULL );
1739
1740         error = oyOptions_SetFromText( &opts,
1741                                  "//" OY_TYPE_STD "/argv/underline_key_suffix",
1742                                  "TAXI", OY_CREATE_NEW );
1743
1744         tv = oyjl_tree_get_valuef( root, "org/freedesktop/openicc/device/[0]" );
1745         count = oyjl_value_count(tv);
1746         for(i = 0; i < count; ++i)
1747         {
1748           error = oyOptions_SetFromInt( &opts,
1749                                  "//" OY_TYPE_STD "/argv/pos",
1750                                  i, 0, OY_CREATE_NEW );
1751
1752           v = oyjl_tree_get_valuef( root, "org/freedesktop/openicc/device/[0]/[%d]/_id/$oid", i );
1753           val = oyjl_value_text( v, oyAllocateFunc_ );
1754           error = oyDeviceFromJSON( device_db, opts, &dev );
1755
1756           if(dev)
1757           {
1758             int j,n;
1759             oyConfig_AddDBData( dev, "TAXI_id", val, OY_CREATE_NEW );
1760             if(val) oyDeAllocateFunc_(val); val = 0;
1761
1762             v = oyjl_tree_get_valuef( root, "org/freedesktop/openicc/device/[0]/[%d]/profile_description", i );
1763             n = oyjl_value_count(v);
1764             for(j = 0; j < n; ++j)
1765             {
1766               v = oyjl_tree_get_valuef( root, "org/freedesktop/openicc/device/[0]/[%d]/profile_description/[%d]", i, j );
1767               val = oyjl_value_text( v, oyAllocateFunc_ );
1768               oyConfig_AddDBData( dev, "TAXI_profile_description", val, OY_CREATE_NEW );
1769               if(val) oyDeAllocateFunc_(val); val = 0;
1770               /* TODO store all profile descriptions */
1771               break;
1772             }
1773
1774             if(!configs_)
1775               configs_ = oyConfigs_New(0);
1776             oyConfigs_MoveIn( configs_, &dev, -1 );
1777           }
1778
1779           if(val) oyDeAllocateFunc_(val); val = 0;
1780           if(json_text) oyFree_m_( json_text );
1781         }
1782         oyOptions_Release( &opts );
1783         if(device_db) oyDeAllocateFunc_(device_db); device_db = 0;
1784       }
1785       oyjl_tree_free( &root );
1786     }
1787
1788     oyFree_m_( manufacturers );
1789
1790     if(!configs_)
1791     {
1792       oyDeviceToJSON( device, 0, &json_text, oyAllocateFunc_ );
1793       WARNc1_S("no profile found for\n%s", json_text);
1794       oyFree_m_(json_text);
1795     } else if(oy_debug)
1796     {
1797       count = oyConfigs_Count( configs_ );
1798       for( i = 0; i < count; ++i)
1799         WARNc1_S("%d", i);
1800     }
1801
1802     n = oyConfigs_Count( configs_ );
1803
1804     /* sort the devices by rank value */
1805     if(n)
1806     {
1807       oyConfig_s * taxi_dev;
1808       int32_t * ranks = 0;
1809
1810       taxi_devices = oyConfigs_New(0);
1811
1812       oyAllocHelper_m_(ranks, int32_t, n*2+1, 0, error = 1; return error );
1813       for(i = 0; i < n; ++i)
1814       {
1815         taxi_dev = oyConfigs_Get( configs_, i );
1816         ranks[2*i+0] = i;
1817         error = oyConfig_Compare( device, taxi_dev, &ranks[2*i+1] );
1818
1819         oyConfig_Release( &taxi_dev );
1820       }
1821       qsort( ranks, n, sizeof(int32_t)*2, oyCompareRanks_ );
1822       for(i = 0; i < n; ++i)
1823       {
1824         taxi_dev = oyConfigs_Get( configs_, ranks[2*i+0] );
1825
1826         if(oy_debug > 2)
1827         {
1828           char * json_text = 0;
1829           oyDeviceToJSON( taxi_dev, 0, &json_text, oyAllocateFunc_ );
1830           DBG_NUM1_S("%s\n", json_text );
1831           oyFree_m_(json_text);
1832         }
1833
1834         oyConfigs_MoveIn( taxi_devices, &taxi_dev, -1 );
1835       }
1836       oyConfigs_Release( &configs_ );
1837       oyOptions_Release( &options );
1838       oyFree_m_(ranks);
1839     }
1840
1841     if(devices)
1842       *devices = taxi_devices;
1843   }
1844
1845   return error;
1846 }
1847
1848
1849 /**
1850  *  @} *//* devices_handling
1851  */
1852
1853
1854 /** Function oyOptions_ForFilter
1855  *  @memberof oyOptions_s
1856  *  @brief   provide Oyranos behaviour settings
1857  *
1858  *  The returned options are read in from the Elektra settings and if thats not
1859  *  available from the inbuild defaults. The later can explicitely selected with
1860  *  oyOPTIONSOURCE_FILTER passed as flags argument.
1861  *  The key names map to the registration and XML syntax.
1862  *
1863  *  To obtain all advanced front end options from a meta module use:@verbatim
1864  *  flags = oyOPTIONATTRIBUTE_ADVANCED |
1865  *          oyOPTIONATTRIBUTE_FRONT |
1866  *          OY_SELECT_COMMON @endverbatim
1867  *
1868  *  @see OY_SELECT_FILTER OY_SELECT_COMMON oyOPTIONATTRIBUTE_e
1869  *
1870  *  @param[in]     registration        the filter registration to search for
1871  *  @param[in]     cmm                 a CMM to match
1872  *  @param[in]     flags               for inbuild defaults |
1873  *                                     oyOPTIONSOURCE_FILTER;
1874  *                                     for options marked as advanced |
1875  *                                     oyOPTIONATTRIBUTE_ADVANCED |
1876  *                                     OY_SELECT_FILTER |
1877  *                                     OY_SELECT_COMMON
1878  *  @param         object              the optional object
1879  *  @return                            the options
1880  *
1881  *  @version Oyranos: 0.3.0
1882  *  @since   2008/10/08 (Oyranos: 0.1.8)
1883  *  @date    2011/01/29
1884  */
1885 oyOptions_s *  oyOptions_ForFilter   ( const char        * registration,
1886                                        const char        * cmm,
1887                                        uint32_t            flags,
1888                                        oyObject_s          object )
1889 {
1890   oyOptions_s * s = 0;
1891   oyFilterCore_s_ * filter = 0;
1892   oyCMMapi4_s_ * cmm_api4 = 0;
1893   char * lib_name = 0;
1894   int error = 0;
1895
1896   /*  1. get filter */
1897   filter = oyFilterCore_New_( object );
1898
1899   error = !filter;
1900
1901   if(error <= 0)
1902     cmm_api4 = (oyCMMapi4_s_*) oyCMMsGetFilterApi_( cmm, registration,
1903                                                     oyOBJECT_CMM_API4_S );
1904
1905   if(cmm_api4)
1906     lib_name = cmm_api4->id_;
1907
1908   error = !(cmm_api4 && lib_name);
1909
1910   if(error <= 0)
1911     error = oyFilterCore_SetCMMapi4_( filter, cmm_api4 );
1912
1913   s = oyOptions_ForFilter_( filter, flags, object);
1914
1915   oyFilterCore_Release( (oyFilterCore_s**)&filter );
1916
1917   return s;
1918 }
1919
1920
1921
1922
1923 /** Function  oyOptions_ForFilter_
1924  *  @memberof oyOptions_s
1925  *  @brief    Provide Oyranos behaviour settings
1926  *  @internal
1927  *
1928  *  The returned options are read in from the Elektra settings and if thats not
1929  *  available from the inbuild defaults. The later can explicitely selected with
1930  *  oyOPTIONSOURCE_FILTER passed as flags argument.
1931  *  The key names map to the registration and XML syntax.
1932  *
1933  *  To obtain all front end options from a meta module use: @verbatim
1934     flags = oyOPTIONATTRIBUTE_ADVANCED |
1935             oyOPTIONATTRIBUTE_FRONT |
1936             OY_SELECT_COMMON @endverbatim
1937  *
1938  *  @param[in]     filter              the filter
1939  *  @param[in]     flags               for inbuild defaults |
1940  *                                     oyOPTIONSOURCE_FILTER;
1941  *                                     for options marked as advanced |
1942  *                                     oyOPTIONATTRIBUTE_ADVANCED |
1943  *                                     OY_SELECT_FILTER |
1944  *                                     OY_SELECT_COMMON
1945  *  @param         object              the optional object
1946  *  @return                            the options
1947  *
1948  *  @version Oyranos: 0.1.10
1949  *  @since   2008/12/08 (Oyranos: 0.1.9)
1950  *  @date    2009/07/27
1951  */
1952 oyOptions_s *  oyOptions_ForFilter_  ( oyFilterCore_s_   * filter,
1953                                        uint32_t            flags,
1954                                        oyObject_s          object )
1955 {
1956   oyOptions_s * s = 0,
1957               * opts_tmp = 0,
1958               * opts_tmp2 = 0;
1959   oyOption_s * o = 0;
1960   int error = !filter || !filter->api4_;
1961   char * type_txt = oyFilterRegistrationToText( filter->registration_,
1962                                                 oyFILTER_REG_TYPE, 0 );
1963   oyCMMapi5_s * api5 = 0;
1964   int i,n;
1965
1966   /* by default we parse both sources */
1967   if(!(flags & OY_SELECT_FILTER) && !(flags & OY_SELECT_COMMON))
1968     flags |= OY_SELECT_FILTER | OY_SELECT_COMMON;
1969
1970   if(!error)
1971   {
1972     /*
1973         Programm:
1974         1. get filter and its type
1975         2. get implementation for filter type
1976         3. parse static common options from meta module
1977         4. parse static options from filter
1978         5. merge both
1979         6. get stored values from disk
1980      */
1981
1982     /*  1. get filter */
1983
1984     /*  2. get implementation for filter type */
1985     api5 = (oyCMMapi5_s*)filter->api4_->api5_;
1986
1987     /*  3. parse static common options from a policy module */
1988     if(api5 && flags & OY_SELECT_COMMON)
1989     {
1990       oyCMMapiFilters_s * apis;
1991       int apis_n = 0;
1992       oyCMMapi9_s_ * cmm_api9_ = 0;
1993       char * klass, * api_reg;
1994
1995       klass = oyFilterRegistrationToText( filter->registration_,
1996                                           oyFILTER_REG_TYPE, 0 );
1997       api_reg = oyStringCopy_("//", oyAllocateFunc_ );
1998       STRING_ADD( api_reg, klass );
1999       oyFree_m_( klass );
2000
2001       s = oyOptions_New( 0 );
2002
2003       apis = oyCMMsGetFilterApis_( 0,0, api_reg,
2004                                    oyOBJECT_CMM_API9_S,
2005                                    oyFILTER_REG_MODE_STRIP_IMPLEMENTATION_ATTR,
2006                                    0,0);
2007       apis_n = oyCMMapiFilters_Count( apis );
2008       for(i = 0; i < apis_n; ++i)
2009       {
2010         cmm_api9_ = (oyCMMapi9_s_*) oyCMMapiFilters_Get( apis, i );
2011         if(oyFilterRegistrationMatch( filter->registration_, cmm_api9_->pattern,
2012                                       oyOBJECT_NONE ))
2013         {
2014           opts_tmp = oyOptions_FromText( cmm_api9_->options, 0, object );
2015           oyOptions_AppendOpts( s, opts_tmp );
2016           oyOptions_Release( &opts_tmp );
2017         }
2018         if(cmm_api9_->release)
2019           cmm_api9_->release( (oyStruct_s**)&cmm_api9_ );
2020       }
2021       oyCMMapiFilters_Release( &apis );
2022       oyFree_m_( api_reg );
2023       opts_tmp = s; s = 0;
2024     }
2025     /* requires step 2 */
2026
2027     /*  4. parse static options from filter */
2028     if(flags & OY_SELECT_FILTER)
2029       opts_tmp2 = oyOptions_FromText( filter->api4_->ui->options, 0, object );
2030
2031     /*  5. merge */
2032     s = oyOptions_FromBoolean( opts_tmp, opts_tmp2, oyBOOLEAN_UNION, object );
2033
2034     oyOptions_Release( &opts_tmp );
2035     oyOptions_Release( &opts_tmp2 );
2036
2037     /*  6. get stored values */
2038     n = oyOptions_Count( s );
2039     for(i = 0; i < n && error <= 0; ++i)
2040     {
2041       o = oyOptions_Get( s, i );
2042       oyOption_SetSource( o, oyOPTIONSOURCE_FILTER );
2043       oyOption_Release( &o );
2044     }
2045     error = oyOptions_DoFilter ( s, flags, type_txt );
2046   }
2047
2048   if(type_txt)
2049     oyDeAllocateFunc_( type_txt );
2050
2051   return s;
2052 }
2053
2054 /** Function oyOption_FromDB
2055  *  @memberof oyOption_s
2056  *  @brief   new option with registration and value filled from DB if available
2057  *
2058  *  @param         registration        no or full qualified registration
2059  *  @param         object              the optional object
2060  *  @return                            the option
2061  *
2062  *  @version Oyranos: 0.1.10
2063  *  @since   2009/01/24 (Oyranos: 0.1.10)
2064  *  @date    2009/01/24
2065  */
2066 oyOption_s *   oyOption_FromDB       ( const char        * registration,
2067                                        oyObject_s          object )
2068 {
2069   int error = !registration;
2070   oyOption_s * o = 0;
2071
2072   if(error <= 0)
2073   {
2074     /** This is merely a wrapper to oyOption_New() and
2075      *  oyOption_SetValueFromDB(). */
2076     o = oyOption_FromRegistration( registration, object );
2077     error = oyOption_SetFromText( o, 0, 0 );
2078     error = oyOption_SetValueFromDB( o );
2079     oyOption_SetSource( o, oyOPTIONSOURCE_DATA );
2080   }
2081
2082   return o;
2083 }
2084
2085
2086 /** Function oyOptions_SaveToDB
2087  *  @memberof oyOptions_s
2088  *  @brief   store a oyOptions_s in DB
2089  *
2090  *  @param[in]     options             the options
2091  *  @param[in]     registration        the registration
2092  *  @param[out]    new_reg             the new registration; optional
2093  *  @param[in]     alloc               the user allocator for new_reg; optional
2094  *  @return                            0 - good, 1 >= error
2095  *
2096  *  @version Oyranos: 0.3.0
2097  *  @since   2009/02/08 (Oyranos: 0.1.10)
2098  *  @date    2011/01/29
2099  */
2100 OYAPI int  OYEXPORT
2101                oyOptions_SaveToDB    ( oyOptions_s       * options,
2102                                        const char        * registration,
2103                                        char             ** new_reg,
2104                                        oyAlloc_f           allocateFunc )
2105 {
2106   int error = !options || !registration;
2107   oyOption_s * o = 0;
2108   int n,i;
2109   char * key_base_name = 0,
2110        * key_name = 0,
2111        * key_top = 0;
2112
2113   DBG_PROG_START
2114   oyExportStart_(EXPORT_PATH | EXPORT_SETTING);
2115
2116   if(error <= 0)
2117   {
2118     key_base_name = oySearchEmptyKeyname_( registration );
2119     error = !key_base_name;
2120     if(error <= 0)
2121     {
2122       STRING_ADD( key_base_name, OY_SLASH );
2123     }
2124
2125     n = oyOptions_Count( options );
2126     for( i = 0; i < n; ++i )
2127     {
2128       o = oyOptions_Get( options, i );
2129       key_top = oyFilterRegistrationToText( oyOption_GetRegistration(o),
2130                                             oyFILTER_REG_MAX, 0 );
2131
2132
2133       STRING_ADD( key_name, key_base_name );
2134       STRING_ADD( key_name, key_top );
2135       if(oyOption_GetValueString(o,0))
2136         error = oyAddKey_valueComment_( key_name, oyOption_GetValueString(o,0),
2137                                         0 );
2138 # if 0
2139       else if(o->value_type == oyVAL_STRUCT &&
2140               o->value && o->value->oy_struct->type_ == oyOBJECT_BLOB_S)
2141         error = 0;/*oyAddKeyBlobComment_();*/
2142 #endif
2143       else
2144         WARNcc_S( (oyStruct_s*)o,
2145                     "Could not save non string / non binary option" );
2146
2147       oyOption_Release( &o );
2148       oyFree_m_( key_name );
2149     }
2150
2151     if(error <= 0 && new_reg && key_base_name)
2152     {
2153       key_base_name[strlen(key_base_name)-1] = '\000';
2154       *new_reg = oyStringCopy_(key_base_name, allocateFunc);
2155     }
2156     oyFree_m_( key_base_name );
2157   }
2158
2159   oyExportEnd_();
2160   DBG_PROG_ENDE
2161   return error;
2162 }
2163
2164 /** Function  oyOption_SetValueFromDB
2165  *  @memberof oyOption_s
2166  *  @brief    Value filled from DB if available
2167  *
2168  *  @param         option              the option
2169  *  @return                            error
2170  *
2171  *  @version Oyranos: 0.1.10
2172  *  @since   2009/01/24 (Oyranos: 0.1.10)
2173  *  @date    2009/05/25
2174  */
2175 int            oyOption_SetValueFromDB  ( oyOption_s        * option )
2176 {
2177   int error = !option || !oyOption_GetRegistration(option);
2178   char * text = 0;
2179   oyPointer ptr = 0;
2180   size_t size = 0;
2181   oyOption_s * s = option;
2182
2183   if(error)
2184     return error;
2185
2186   oyCheckType__m( oyOBJECT_OPTION_S, return 1 )
2187
2188   oyExportStart_(EXPORT_SETTING);
2189
2190   if(error <= 0)
2191     text = oyGetKeyString_( oyOption_GetText( option, oyNAME_DESCRIPTION),
2192                             oyAllocateFunc_ );
2193
2194   if(error <= 0)
2195   {
2196     /** Change the option value only if something was found in the DB. */
2197     if(text && text[0])
2198     {
2199       oyOption_SetFromText( option, text, 0 );
2200       oyOption_SetSource( s, oyOPTIONSOURCE_DATA );
2201     }
2202     else
2203     {
2204       ptr = oyGetKeyBinary_( oyOption_GetRegistration(s), &size, oyAllocateFunc_ );
2205       if(ptr && size)
2206       {
2207         oyOption_SetFromData( option, ptr, size );
2208         oyOption_SetSource( s, oyOPTIONSOURCE_DATA );
2209         oyFree_m_( ptr );
2210       }
2211     }
2212   }
2213
2214   if(text)
2215     oyFree_m_( text );
2216
2217   oyExportEnd_();
2218
2219   return error;
2220 }
2221
2222 /** Function oyOptions_DoFilter
2223  *  @memberof oyOptions_s
2224  *  @brief   filter the options
2225  *
2226  *  The returned options are read in from the Elektra settings and if thats not
2227  *  available from the inbuild defaults. The later can explicitely selected with
2228  *  oyOPTIONSOURCE_FILTER passed as flags argument. advanced options can be 
2229  *  filtered out by adding oyOPTIONATTRIBUTE_ADVANCED.
2230  *
2231  *  Modules should handle the advanced options as well but shall normally
2232  *  not act upon them. The convention to set them zero, keeps them inactive.
2233  *  
2234  *  On the front end side the CMM cache has to include them, as they will 
2235  *  influence the hash sum generation. The question arrises, whether to include
2236  *  these options marked as non visible along the path or require the CMM cache
2237  *  code to check each time for them on cache lookup. The oyOption_s::flags
2238  *  is already in place. So we use it and do inclusion. Front end options can be
2239  *  filtered as they do not affect the CMM cache.
2240  *
2241  *  @see oyOptions_Add
2242  *
2243  *  @param         opts                the options
2244  *  @param[in]     flags               for inbuild defaults |
2245  *                                     oyOPTIONSOURCE_FILTER;
2246  *                                     for options marked as advanced |
2247  *                                     oyOPTIONATTRIBUTE_ADVANCED;
2248  *                                     for front end options |
2249  *                                     oyOPTIONATTRIBUTE_FRONT
2250  *  @param         filter_type         the type level from a registration
2251  *  @return                            options
2252  *
2253  *  @version Oyranos: 0.1.9
2254  *  @since   2008/11/27 (Oyranos: 0.1.9)
2255  *  @date    2008/11/27
2256  */
2257 int          oyOptions_DoFilter      ( oyOptions_s       * opts,
2258                                        uint32_t            flags,
2259                                        const char        * filter_type )
2260 {
2261   oyOptions_s * opts_tmp = 0;
2262   oyOption_s * o = 0;
2263   int error = !opts;
2264   char * text;
2265   int i,n;
2266
2267   oyExportStart_(EXPORT_SETTING);
2268   oyExportEnd_();
2269
2270   if(error <= 0 && (flags || filter_type))
2271   {
2272     /*  6. get stored values */
2273     n = oyOptions_Count( opts );
2274     opts_tmp = oyOptions_New(0);
2275     for(i = 0; i < n; ++i)
2276     {
2277       int skip = 0;
2278
2279       o = oyOptions_Get( opts, i );
2280
2281
2282       /* usage/type range filter */
2283       if(filter_type)
2284       {
2285         text = oyFilterRegistrationToText( oyOption_GetRegistration(o),
2286                                            oyFILTER_REG_TYPE, 0);
2287         if(oyStrcmp_( filter_type, text ) != 0)
2288           skip = 1;
2289
2290         oyFree_m_( text );
2291       }
2292
2293       /* front end options filter */
2294       if(!skip && !(flags & oyOPTIONATTRIBUTE_FRONT))
2295       {
2296         text = oyStrrchr_( oyOption_GetRegistration(o), '/' );
2297
2298         if(text)
2299            text = oyStrchr_( text, '.' );
2300         if(text)
2301           if(oyStrstr_( text, "front" ))
2302             skip = 1;
2303       }
2304
2305       /* advanced options mark and zero */
2306       if(!skip && !(flags & oyOPTIONATTRIBUTE_ADVANCED))
2307       {
2308         text = oyStrrchr_( oyOption_GetRegistration(o), '/' );
2309         if(text)
2310            text = oyStrchr_( text, '.' );
2311         if(text)
2312           if(oyStrstr_( text, "advanced" ))
2313           {
2314             oyOption_SetFromText( o, "0", 0 );
2315             oyOption_SetFlags( o,
2316                               oyOption_GetFlags(o) & (~oyOPTIONATTRIBUTE_EDIT));
2317           }
2318       } else
2319       /* Elektra settings, modify value */
2320       if(!skip && !(flags & oyOPTIONSOURCE_FILTER))
2321       {
2322         text = oyGetKeyString_( oyOption_GetText( o, oyNAME_DESCRIPTION),
2323                                 oyAllocateFunc_ );
2324         if(text && text[0])
2325         {
2326           error = oyOption_SetFromText( o, text, 0 );
2327           oyOption_SetFlags(o, oyOption_GetFlags(o) & (~oyOPTIONATTRIBUTE_EDIT));
2328           oyOption_SetSource( o, oyOPTIONSOURCE_USER );
2329           oyFree_m_( text );
2330         }
2331       }
2332
2333       if(!skip)
2334         oyOptions_Add( opts_tmp, o, -1, opts->oy_ );
2335
2336       oyOption_Release( &o );
2337     }
2338
2339     n = oyOptions_Count( opts_tmp );
2340     error = oyOptions_Clear(opts);
2341     for( i = 0; i < n && !error; ++i )
2342     {
2343       o = oyOptions_Get( opts_tmp, i );
2344       error = oyOptions_MoveIn( opts, &o, -1 );
2345     }
2346     oyOptions_Release( &opts_tmp );
2347   }
2348
2349   return error;
2350 }
2351
2352
2353 /** Function  oyFilterNode_GetOptions
2354  *  @memberof oyFilterNode_s
2355  *  @brief    Get filter options
2356  *
2357  *  Options are typical user visible settings, which can be presistently stored
2358  *  as user preferences and can be displayed in filter dialogs.
2359  *
2360  *  @param[in,out] node                filter object
2361  *  @param         flags               see oyOptions_s::oyOptions_ForFilter()
2362  *  @return                            the options
2363  *
2364  *  @version Oyranos: 0.5.0
2365  *  @since   2008/06/26 (Oyranos: 0.1.8)
2366  *  @date    2012/06/12
2367  */
2368 oyOptions_s* oyFilterNode_GetOptions ( oyFilterNode_s    * node,
2369                                        int                 flags )
2370 {
2371   oyOptions_s * options = 0;
2372   oyFilterNode_s * s = node;
2373   int error = 0;
2374
2375   oyFilterNode_s_ ** node_ = (oyFilterNode_s_**)&node;
2376
2377   if(!node)
2378     return 0;
2379
2380   oyCheckType__m( oyOBJECT_FILTER_NODE_S, return 0 )
2381
2382   if(flags || !(*node_)->core->options_)
2383   {
2384     options = oyOptions_ForFilter_( (*node_)->core, flags, (*node_)->core->oy_ );
2385     if(!(*node_)->core->options_)
2386       (*node_)->core->options_ = oyOptions_Copy( options, 0 );
2387     else
2388       error = oyOptions_Filter( &(*node_)->core->options_, 0, 0,
2389                                 oyBOOLEAN_UNION,
2390                                 0, options );
2391     if(error)
2392       WARNc2_S("%s %d", _("found issues"),error);
2393     if(!(*node_)->core->options_)
2394       (*node_)->core->options_ = oyOptions_New( 0 );
2395   }
2396
2397   options = oyOptions_Copy( (*node_)->core->options_, 0 );
2398
2399   /** Observe exported options for changes and propagate to a existing graph. */
2400   error = oyOptions_ObserverAdd( options, (oyStruct_s*)node,
2401                                  0, oyFilterNode_Observe_ );
2402   if(error)
2403     WARNc2_S("%s %d", _("found issues"),error);
2404
2405   return options;
2406 }
2407
2408 /** Function  oyFilterNode_GetUi
2409  *  @memberof oyFilterNode_s
2410  *  @brief    Get filter options XFORMS
2411  *
2412  *  @param[in,out] node                filter object
2413  *  @param[out]    ui_text             XFORMS fitting to the node Options
2414  *  @param[out]    namespaces          additional XML namespaces
2415  *  @param         allocateFunc        optional user allocator
2416  *  @return                            the options
2417  *
2418  *  @version Oyranos: 0.5.0
2419  *  @since   2009/07/29 (Oyranos: 0.1.10)
2420  *  @date    2012/06/12
2421  */
2422 int            oyFilterNode_GetUi    ( oyFilterNode_s     * node,
2423                                        char              ** ui_text,
2424                                        char             *** namespaces,
2425                                        oyAlloc_f            allocateFunc )
2426 {
2427   int error = 0;
2428   oyFilterNode_s * s = node;
2429   oyOptions_s * options = 0;
2430   char * text = 0,
2431        * tmp = 0;
2432
2433   oyFilterNode_s_ ** node_ = (oyFilterNode_s_**)&node;
2434
2435   if(!node)
2436     return 0;
2437
2438   oyCheckType__m( oyOBJECT_FILTER_NODE_S, return 1 )
2439
2440   if(!allocateFunc)
2441     allocateFunc = oyAllocateFunc_;
2442
2443   if(!error)
2444     options = oyFilterNode_GetOptions( node, 0 );
2445
2446   if(!error)
2447   {
2448     oyCMMapiFilters_s * apis;
2449     int apis_n = 0, i,j = 0;
2450     oyCMMapi9_s * cmm_api9 = 0;
2451     oyCMMapi9_s_ ** cmm_api9_ = (oyCMMapi9_s_**)&cmm_api9;
2452     char * class_name, * api_reg;
2453     const char * reg = (*node_)->core->registration_;
2454
2455     class_name = oyFilterRegistrationToText( reg, oyFILTER_REG_TYPE, 0 );
2456     api_reg = oyStringCopy_("//", oyAllocateFunc_ );
2457     STRING_ADD( api_reg, class_name );
2458     oyFree_m_( class_name );
2459
2460     apis = oyCMMsGetFilterApis_( 0,0, api_reg, oyOBJECT_CMM_API9_S,
2461                                  oyFILTER_REG_MODE_STRIP_IMPLEMENTATION_ATTR,
2462                                  0,0 );
2463     apis_n = oyCMMapiFilters_Count( apis );
2464     for(i = 0; i < apis_n; ++i)
2465     {
2466       cmm_api9 = (oyCMMapi9_s*) oyCMMapiFilters_Get( apis, i );
2467
2468       if(oyFilterRegistrationMatch( reg, (*cmm_api9_)->pattern, 0 ))
2469       {
2470         if((*cmm_api9_)->oyCMMuiGet)
2471           error = (*cmm_api9_)->oyCMMuiGet( options, &tmp, oyAllocateFunc_ );
2472
2473         if(error)
2474         {
2475           WARNc2_S( "%s %s",_("error in module:"), (*cmm_api9_)->registration );
2476           return 1;
2477
2478         } else
2479         if(tmp)
2480         {
2481           STRING_ADD( text, tmp );
2482           STRING_ADD( text, "\n" );
2483           oyFree_m_(tmp);
2484
2485           if(namespaces && (*cmm_api9_)->xml_namespace)
2486           {
2487             if(j == 0)
2488             {
2489               size_t len = (apis_n - i + 1) * sizeof(char*);
2490               *namespaces = allocateFunc( len );
2491               memset(*namespaces, 0, len);
2492             }
2493             *namespaces[j] = oyStringCopy_( (*cmm_api9_)->xml_namespace,
2494                                             allocateFunc );
2495             ++j;
2496             namespaces[j] = 0;
2497           }
2498         }
2499       }
2500
2501       if(cmm_api9->release)
2502         cmm_api9->release( (oyStruct_s**)&cmm_api9 );
2503     }
2504     oyCMMapiFilters_Release( &apis );
2505   }
2506
2507   if(!error && (*node_)->core->api4_->ui->oyCMMuiGet)
2508   {
2509     /* @todo and how to mix in the values? */
2510     error = (*node_)->core->api4_->ui->oyCMMuiGet( options, &tmp, oyAllocateFunc_ );
2511     if(tmp)
2512     {
2513       STRING_ADD( text, tmp );
2514       oyFree_m_(tmp);
2515     }
2516   }
2517
2518   oyOptions_Release( &options );
2519
2520   if(error <= 0 && text)
2521   {
2522     *ui_text = oyStringCopy_( text, allocateFunc );
2523   }
2524
2525   return error;
2526 }
2527
2528 /** \addtogroup misc Miscellaneous
2529
2530  *  @{
2531  */
2532
2533
2534 /** \addtogroup objects_generic
2535
2536  *  @{
2537  */
2538
2539
2540
2541 /**
2542  *  @} *//* objects_generic
2543  */
2544
2545
2546
2547 /** \addtogroup objects_value Values Handling
2548
2549  *  @{
2550  */
2551
2552
2553 /** @internal
2554  *  @struct  oyConfDomain_s_
2555  *  @brief   a ConfDomain object
2556  *  @extends oyStruct_s
2557  *
2558  *  @version Oyranos: 0.1.10
2559  *  @since   2009/12/30 (Oyranos: 0.1.10)
2560  *  @date    2009/12/30
2561  */
2562 typedef struct {
2563   oyOBJECT_e           type_;          /**< struct type oyOBJECT_CONF_DOMAIN_S */ 
2564   oyStruct_Copy_f      copy;           /**< copy function */
2565   oyStruct_Release_f   release;        /**< release function */
2566   oyObject_s           oy_;            /**< base object */
2567
2568   oyCMMapi8_s        * api8;
2569 } oyConfDomain_s_;
2570
2571 oyConfDomain_s_ *
2572            oyConfDomain_New_         ( oyObject_s          object );
2573 oyConfDomain_s_ *
2574            oyConfDomain_FromReg_     ( const char        * registration,
2575                                        oyObject_s          object );
2576 oyConfDomain_s_ *
2577            oyConfDomain_Copy_        ( oyConfDomain_s_   * obj,
2578                                        oyObject_s          object);
2579 int
2580            oyConfDomain_Release_     ( oyConfDomain_s_   **obj );
2581
2582 const char * oyConfDomain_GetText_   ( oyConfDomain_s_   * obj,
2583                                        const char        * name,
2584                                        oyNAME_e            type );
2585 const char **oyConfDomain_GetTexts_  ( oyConfDomain_s_   * obj );
2586
2587 /* --- Public_API Begin --- */
2588
2589 /** Function oyConfDomain_New
2590  *  @memberof oyConfDomain_s
2591  *  @brief   allocate a new ConfDomain object
2592  *
2593  *  @version Oyranos: 0.1.10
2594  *  @since   2009/12/30 (Oyranos: 0.1.10)
2595  *  @date    2009/12/30
2596  */
2597 OYAPI oyConfDomain_s * OYEXPORT
2598            oyConfDomain_FromReg      ( const char        * registration_domain,
2599                                        oyObject_s          object )
2600 {
2601   oyConfDomain_s_ * obj = 0;
2602
2603   obj = oyConfDomain_FromReg_( registration_domain, object );
2604
2605   return (oyConfDomain_s*) obj;
2606 }
2607
2608 /** Function oyConfDomain_Copy
2609  *  @memberof oyConfDomain_s
2610  *  @brief   copy or reference a ConfDomain object
2611  *
2612  *  @param[in]     obj                 struct object
2613  *  @param         object              the optional object
2614  *
2615  *  @version Oyranos: 0.1.10
2616  *  @since   2009/12/30 (Oyranos: 0.1.10)
2617  *  @date    2009/12/30
2618  */
2619 OYAPI oyConfDomain_s * OYEXPORT
2620            oyConfDomain_Copy         ( oyConfDomain_s    * obj,
2621                                        oyObject_s          object )
2622 {
2623   oyConfDomain_s_ * s = (oyConfDomain_s_*) obj;
2624
2625   if(s)
2626     oyCheckType__m( oyOBJECT_CONF_DOMAIN_S, return 0 );
2627
2628   s = oyConfDomain_Copy_( s, (oyObject_s) object );
2629
2630   return (oyConfDomain_s*) s;
2631 }
2632  
2633 /** Function oyConfDomain_Release
2634  *  @memberof oyConfDomain_s
2635  *  @brief   release and possibly deallocate a ConfDomain object
2636  *
2637  *  @param[in,out] obj                 struct object
2638  *
2639  *  @version Oyranos: 0.1.10
2640  *  @since   2009/12/30 (Oyranos: 0.1.10)
2641  *  @date    2009/12/30
2642  */
2643 OYAPI int  OYEXPORT
2644            oyConfDomain_Release      ( oyConfDomain_s    **obj )
2645 {
2646   oyConfDomain_s_ * s = 0;
2647
2648   if(!obj || !*obj)
2649     return 0;
2650
2651   s = (oyConfDomain_s_*) *obj;
2652
2653   oyCheckType__m( oyOBJECT_CONF_DOMAIN_S, return 1 )
2654
2655   *obj = 0;
2656
2657   return oyConfDomain_Release_( &s );
2658 }
2659
2660 /** Function oyConfDomain_GetText
2661  *  @memberof oyConfDomain_s
2662  *  @brief   obtain a UI text from a ConfDomain object
2663  *
2664  *  @param[in,out] obj                 struct object
2665  *  @param[in]     name                the category to return
2666  *  @param[in]     type                the type of string
2667  *
2668  *  @version Oyranos: 0.1.10
2669  *  @since   2009/12/30 (Oyranos: 0.1.10)
2670  *  @date    2009/12/30
2671  */
2672 OYAPI const char * OYEXPORT
2673            oyConfDomain_GetText      ( oyConfDomain_s    * obj,
2674                                        const char        * name,
2675                                        oyNAME_e            type )
2676 {
2677   oyConfDomain_s_ * s = (oyConfDomain_s_*) obj;
2678   const char * text = 0;
2679
2680   if(s)
2681     oyCheckType__m( oyOBJECT_CONF_DOMAIN_S, return 0 );
2682
2683   text = oyConfDomain_GetText_( s, name, type );
2684
2685   return text;
2686 }
2687
2688 /** Function oyConfDomain_GetTexts
2689  *  @memberof oyConfDomain_s
2690  *  @brief   obtain a list of possible UI text from a ConfDomain object
2691  *
2692  *  @return                            zero terminated list of strings,
2693  *                                     Each string is a "name" option to
2694  *                                     oyConfDomain_GetText().
2695  *
2696  *  @version Oyranos: 0.1.10
2697  *  @since   2009/12/30 (Oyranos: 0.1.10)
2698  *  @date    2009/12/30
2699  */
2700 OYAPI const char ** OYEXPORT
2701            oyConfDomain_GetTexts     ( oyConfDomain_s    * obj )
2702 {
2703   oyConfDomain_s_ * s = (oyConfDomain_s_*) obj;
2704   const char ** texts = 0;
2705
2706   if(s)
2707     oyCheckType__m( oyOBJECT_CONF_DOMAIN_S, return 0 );
2708
2709   texts = oyConfDomain_GetTexts_( s );
2710
2711   return texts;
2712 }
2713
2714 /* --- Public_API End --- */
2715
2716
2717 /** @internal
2718  *  Function oyConfDomain_New_
2719  *  @memberof oyConfDomain_s_
2720  *  @brief   allocate a new ConfDomain object
2721  *
2722  *  @version Oyranos: 0.1.10
2723  *  @since   2009/12/30 (Oyranos: 0.1.10)
2724  *  @date    2009/12/30
2725  */
2726 oyConfDomain_s_ * oyConfDomain_New_  ( oyObject_s          object )
2727 {
2728   /* ---- start of common object constructor ----- */
2729   oyOBJECT_e type = oyOBJECT_CONF_DOMAIN_S;
2730 # define STRUCT_TYPE oyConfDomain_s_
2731   int error = 0;
2732   oyObject_s    s_obj = oyObject_NewFrom( object );
2733   STRUCT_TYPE * s = 0;
2734
2735   if(s_obj)
2736     s = (STRUCT_TYPE*)s_obj->allocateFunc_(sizeof(STRUCT_TYPE));
2737
2738   if(!s || !s_obj)
2739   {
2740     WARNc_S(_("MEM Error."));
2741     return NULL;
2742   }
2743
2744   error = !memset( s, 0, sizeof(STRUCT_TYPE) );
2745
2746   s->type_ = type;
2747   s->copy = (oyStruct_Copy_f) oyConfDomain_Copy;
2748   s->release = (oyStruct_Release_f) oyConfDomain_Release;
2749
2750   s->oy_ = s_obj;
2751
2752   error = !oyObject_SetParent( s_obj, type, (oyPointer)s );
2753   if(error)
2754     return 0;
2755 # undef STRUCT_TYPE
2756   /* ---- end of common object constructor ------- */
2757
2758   s->api8 = 0;
2759
2760   return s;
2761 }
2762
2763 oyConfDomain_s_ * oyConfDomain_FromReg_(
2764                                        const char        * registration,
2765                                        oyObject_s          object )
2766 {
2767   oyConfDomain_s_ * s = oyConfDomain_New_( object );
2768   int error = !s;
2769   oyCMMapi8_s * cmm_api8 = 0;
2770
2771   if(error <= 0)
2772   {
2773     cmm_api8 = (oyCMMapi8_s*) oyCMMsGetFilterApi_( 0, registration,
2774                                                    oyOBJECT_CMM_API8_S );
2775     error = !cmm_api8;
2776   }
2777
2778   if(error <= 0)
2779     s->api8 = cmm_api8;
2780
2781   return s;
2782 }
2783
2784 /** @internal
2785  *  Function oyConfDomain_Copy__
2786  *  @memberof oyConfDomain_s_
2787  *  @brief   real copy a ConfDomain object
2788  *
2789  *  @param[in]     obj                 struct object
2790  *  @param         object              the optional object
2791  *
2792  *  @version Oyranos: 0.1.10
2793  *  @since   2009/12/30 (Oyranos: 0.1.10)
2794  *  @date    2009/12/30
2795  */
2796 oyConfDomain_s_ * oyConfDomain_Copy__ (
2797                                        oyConfDomain_s_   * obj,
2798                                        oyObject_s          object )
2799 {
2800   oyConfDomain_s_ * s = 0;
2801   int error = 0;
2802
2803   if(!obj || !object)
2804     return s;
2805
2806   s = oyConfDomain_New_( object );
2807   error = !s;
2808
2809   if(!error)
2810   {
2811
2812     if(obj->api8)
2813     {
2814       if(obj->api8->copy)
2815         s->api8 = (oyCMMapi8_s*) obj->api8->copy( (oyStruct_s*)s->api8,
2816                                                   object );
2817       else
2818         s->api8 = obj->api8;
2819     }
2820   }
2821
2822   if(error)
2823     oyConfDomain_Release_( &s );
2824
2825   return s;
2826 }
2827
2828 /** @internal
2829  *  Function oyConfDomain_Copy_
2830  *  @memberof oyConfDomain_s_
2831  *  @brief   copy or reference a ConfDomain object
2832  *
2833  *  @param[in]     obj                 struct object
2834  *  @param         object              the optional object
2835  *
2836  *  @version Oyranos: 0.1.10
2837  *  @since   2009/12/30 (Oyranos: 0.1.10)
2838  *  @date    2009/12/30
2839  */
2840 oyConfDomain_s_ * oyConfDomain_Copy_ ( oyConfDomain_s_   * obj,
2841                                        oyObject_s          object )
2842 {
2843   oyConfDomain_s_ * s = obj;
2844
2845   if(!obj)
2846     return 0;
2847
2848   if(obj && !object)
2849   {
2850     s = obj;
2851     oyObject_Copy( s->oy_ );
2852     return s;
2853   }
2854
2855   s = oyConfDomain_Copy__( obj, object );
2856
2857   return s;
2858 }
2859  
2860 /** @internal
2861  *  Function oyConfDomain_Release_
2862  *  @memberof oyConfDomain_s_
2863  *  @brief   release and possibly deallocate a ConfDomain object
2864  *
2865  *  @param[in,out] obj                 struct object
2866  *
2867  *  @version Oyranos: 0.1.10
2868  *  @since   2009/12/30 (Oyranos: 0.1.10)
2869  *  @date    2009/12/30
2870  */
2871 int        oyConfDomain_Release_     ( oyConfDomain_s_   **obj )
2872 {
2873   /* ---- start of common object destructor ----- */
2874   oyConfDomain_s_ * s = 0;
2875
2876   if(!obj || !*obj)
2877     return 0;
2878
2879   s = *obj;
2880
2881   *obj = 0;
2882
2883   if(oyObject_UnRef(s->oy_))
2884     return 0;
2885   /* ---- end of common object destructor ------- */
2886
2887
2888   if(s->oy_->deallocateFunc_)
2889   {
2890     oyDeAlloc_f deallocateFunc = s->oy_->deallocateFunc_;
2891
2892     if(s->api8)
2893     {
2894       if(s->api8->release)
2895         s->api8->release( (oyStruct_s**) &s->api8 );
2896       else
2897         s->api8 = 0;
2898     }
2899
2900     oyObject_Release( &s->oy_ );
2901
2902     deallocateFunc( s );
2903   }
2904
2905   return 0;
2906 }
2907
2908 /** @internal
2909  *  Function oyConfDomain_GetText_
2910  *  @memberof oyConfDomain_s
2911  *  @brief   obtain a UI text from a ConfDomain object
2912  *
2913  *  @param[in,out] obj                 struct object
2914  *  @param[in]     name                the category to return
2915  *  @param[in]     type                the type of string
2916  *
2917  *  @version Oyranos: 0.1.10
2918  *  @date    2009/12/30
2919  *  @since   2009/12/30 (Oyranos: 0.1.10)
2920  */
2921 const char * oyConfDomain_GetText_   ( oyConfDomain_s_   * obj,
2922                                        const char        * name,
2923                                        oyNAME_e            type )
2924 {
2925   const char * text = 0;
2926   oyConfDomain_s_ * s = obj;
2927   oyCMMui_s * ui = 0;
2928
2929   if(s->api8)
2930     ui = oyCMMapi8_GetUi(s->api8);
2931
2932   if(ui && oyCMMui_GetTextF(ui))
2933     text = oyCMMui_GetTextF(ui)( name, type, (oyStruct_s*)ui );
2934
2935   return text;
2936 }
2937
2938 /** @internal
2939  *  Function oyConfDomain_GetTexts
2940  *  @memberof oyConfDomain_s
2941  *  @brief   obtain a list of possible UI text from a ConfDomain object
2942  *
2943  *  @return                            zero terminated list of strings,
2944  *                                     Each string is a "name" option to
2945  *                                     oyConfDomain_GetText().
2946  *
2947  *  @version Oyranos: 0.1.10
2948  *  @since   2009/12/30 (Oyranos: 0.1.10)
2949  *  @date    2009/12/30
2950  */
2951 const char **oyConfDomain_GetTexts_  ( oyConfDomain_s_   * obj )
2952 {
2953   oyConfDomain_s_ * s = obj;
2954   const char ** texts = 0;
2955   oyCMMui_s * ui = 0;
2956
2957   if(s->api8)
2958     ui = oyCMMapi8_GetUi(s->api8);
2959
2960   if(ui)
2961     texts = oyCMMui_GetTexts(ui);
2962
2963   return texts;
2964 }
2965
2966
2967 /**
2968  *  @} *//* objects_value
2969  */
2970
2971 /** @} *//* misc */