summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-01-04 17:58:18 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-01-05 22:24:58 +0900
commit1056b6ed01475817da2439012057d11865d2c5d8 (patch)
tree2f2cbcbceebdee3c67b503141c45fc5c5224fe41
parent6d448760f374638af69590d60bc8f896895240f8 (diff)
elm config - add the ability to have derived configurations from others
this adds the ability to have one profile automatically be derived from another with modifications applied. right now it only can do a very limited modification - multiple scale. over time this will expand. this is only inteded otbe sued by a DE like enlightenment, so it's not going to be documented fully at this point. @feature
-rw-r--r--src/lib/elm_config.c300
-rw-r--r--src/lib/elm_config.h41
-rw-r--r--src/lib/elm_priv.h2
3 files changed, 336 insertions, 7 deletions
diff --git a/src/lib/elm_config.c b/src/lib/elm_config.c
index 00723514d..ccf64985b 100644
--- a/src/lib/elm_config.c
+++ b/src/lib/elm_config.c
@@ -665,6 +665,285 @@ _elm_config_user_dir_snprintf(char *dst,
665 return 0; 665 return 0;
666} 666}
667 667
668typedef struct _Elm_Config_Derived Elm_Config_Derived;
669typedef struct _Elm_Config_Derived_Profile Elm_Config_Derived_Profile;
670
671struct _Elm_Config_Derived
672{
673 Eina_List *profiles;
674};
675
676struct _Elm_Config_Derived_Profile
677{
678 const char *profile;
679 const char *derive_options;
680};
681
682static Eet_Data_Descriptor *_config_derived_edd = NULL;
683static Eet_Data_Descriptor *_config_derived_profile_edd = NULL;
684
685static void
686_elm_config_profile_derived_init(void)
687{
688 Eet_Data_Descriptor_Class eddc;
689
690 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Derived);
691 eddc.func.str_direct_alloc = NULL;
692 eddc.func.str_direct_free = NULL;
693 _config_derived_edd = eet_data_descriptor_file_new(&eddc);
694
695 memset(&eddc, 0, sizeof(eddc)); /* just in case... */
696 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Derived_Profile);
697 eddc.func.str_direct_alloc = NULL;
698 eddc.func.str_direct_free = NULL;
699 _config_derived_profile_edd = eet_data_descriptor_file_new(&eddc);
700
701#define T Elm_Config_Derived_Profile
702#define D _config_derived_profile_edd
703 ELM_CONFIG_VAL(D, T, profile, EET_T_STRING);
704 ELM_CONFIG_VAL(D, T, derive_options, EET_T_STRING);
705#undef T
706#undef D
707
708#define T Elm_Config_Derived
709#define D _config_derived_edd
710 ELM_CONFIG_LIST(D, T, profiles, _config_derived_profile_edd);
711#undef T
712#undef D
713}
714
715static void
716_elm_config_profile_derived_shutdown(void)
717{
718 if (_config_derived_profile_edd)
719 {
720 eet_data_descriptor_free(_config_derived_profile_edd);
721 _config_derived_profile_edd = NULL;
722 }
723 if (_config_derived_edd)
724 {
725 eet_data_descriptor_free(_config_derived_edd);
726 _config_derived_edd = NULL;
727 }
728}
729
730static Elm_Config_Derived *
731_elm_config_derived_load(const char *profile)
732{
733 char buf[PATH_MAX];
734 Eet_File *ef;
735 Elm_Config_Derived *derived;
736
737 if (!profile) profile = _elm_profile;
738 _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s/derived.cfg",
739 profile);
740 ef = eet_open(buf, EET_FILE_MODE_READ);
741 if (ef)
742 {
743 derived = eet_data_read(ef, _config_derived_edd, "config");
744 eet_close(ef);
745 if (derived) return derived;
746 }
747 snprintf(buf, sizeof(buf), "%s/config/%s/derived.cfg",
748 _elm_data_dir, profile);
749 ef = eet_open(buf, EET_FILE_MODE_READ);
750 if (ef)
751 {
752 derived = eet_data_read(ef, _config_derived_edd, "config");
753 eet_close(ef);
754 if (derived) return derived;
755 }
756 return NULL;
757}
758
759static void
760_elm_config_profile_derived_save(const char *profile, Elm_Config_Derived *derived)
761{
762 Eet_File *ef;
763 char buf[PATH_MAX], buf2[PATH_MAX];
764
765 _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s",
766 profile ? profile : _elm_profile);
767 ecore_file_mkpath(buf);
768 _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s/derived.cfg.tmp",
769 profile ? profile : _elm_profile);
770 _elm_config_user_dir_snprintf(buf2, sizeof(buf2), "config/%s/derived.cfg",
771 profile ? profile : _elm_profile);
772 ef = eet_open(buf, EET_FILE_MODE_WRITE);
773 if (ef)
774 {
775 eet_data_write(ef, _config_derived_edd, "config", derived, 1);
776 eet_close(ef);
777 ecore_file_mv(buf, buf2);
778 }
779}
780
781static void
782_elm_config_derived_free(Elm_Config_Derived *derived)
783{
784 Elm_Config_Derived_Profile *dp;
785
786 if (!derived) return;
787 EINA_LIST_FREE(derived->profiles, dp)
788 {
789 eina_stringshare_del(dp->profile);
790 eina_stringshare_del(dp->derive_options);
791 free(dp);
792 }
793 free(derived);
794}
795
796static void
797_elm_config_derived_option_op_apply(Elm_Config *cfg, const char *op, const char *params)
798{
799 if (!strcmp(op, "scale-mul"))
800 {
801 int multiplier = atoi(params);
802 if (multiplier > 0)
803 {
804 cfg->scale = cfg->scale * (((double)multiplier) / 100.0);
805 }
806 }
807 // Add more derivation commands here
808}
809
810static void
811_elm_config_derived_option_apply(Elm_Config *cfg, const char *option)
812{
813 const char *p;
814 char *buf = alloca(strlen(option) + 1);
815 char *bp = buf;
816
817 p = option;
818 bp = buf;
819 for (;;)
820 {
821 if ((*p == 0) || (*p == ' '))
822 {
823 if (*p == ' ') p++;
824 *bp = 0;
825 _elm_config_derived_option_op_apply(cfg, buf, p);
826 return;
827 }
828 else
829 {
830 *bp = *p;
831 bp++;
832 }
833 if (*p == 0) break;
834 p++;
835 }
836}
837
838static void
839_elm_config_derived_apply(Elm_Config *cfg, const char *derive_options)
840{
841 // derive_options = "option1 param param2 ...; option2 param1 ..."
842 const char *p;
843 char *buf = alloca(strlen(derive_options) + 1);
844 char *bp = buf;
845
846 p = derive_options;
847 for (;;)
848 {
849 if ((*p == 0) || (*p == ';'))
850 {
851 if (*p == ';') p++;
852 *bp = 0;
853 _elm_config_derived_option_apply(cfg, buf);
854 bp = buf;
855 }
856 else
857 {
858 *bp = *p;
859 bp++;
860 }
861 if (*p == 0) break;
862 p++;
863 }
864}
865
866static void
867_elm_config_derived_save(Elm_Config *cfg, Elm_Config_Derived *derived)
868{
869 Elm_Config_Derived_Profile *dp;
870 Eina_List *l;
871
872 if (!derived) return;
873 EINA_LIST_FOREACH(derived->profiles, l, dp)
874 {
875 if ((dp->profile) && (dp->derive_options))
876 {
877 Elm_Config *cfg2;
878
879 cfg2 = malloc(sizeof(Elm_Config));
880 if (cfg2)
881 {
882 memcpy(cfg2, cfg, sizeof(Elm_Config));
883 _elm_config_derived_apply(cfg2, dp->derive_options);
884 _elm_config_save(cfg2, dp->profile);
885 free(cfg2);
886 }
887 }
888 }
889}
890
891EAPI void
892elm_config_profile_derived_add(const char *profile, const char *derive_options)
893{
894 Elm_Config_Derived *derived;
895
896 derived = _elm_config_derived_load(_elm_profile);
897 if (!derived) derived = calloc(1, sizeof(derived));
898 if (derived)
899 {
900 Elm_Config_Derived_Profile *dp = calloc(1, sizeof(Elm_Config_Derived_Profile));
901
902 if (dp)
903 {
904 dp->profile = eina_stringshare_add(profile);
905 dp->derive_options = eina_stringshare_add(derive_options);
906 derived->profiles = eina_list_append(derived->profiles, dp);
907 _elm_config_profile_derived_save(_elm_profile, derived);
908 _elm_config_derived_save(_elm_config, derived);
909 }
910 _elm_config_derived_free(derived);
911 }
912}
913
914EAPI void
915elm_config_profile_derived_del(const char *profile)
916{
917 Elm_Config_Derived *derived;
918 Elm_Config_Derived_Profile *dp;
919 Eina_List *l;
920
921 if (!profile) return;
922 derived = _elm_config_derived_load(_elm_profile);
923 if (derived)
924 {
925 EINA_LIST_FOREACH(derived->profiles, l, dp)
926 {
927 if ((dp->profile) && (!strcmp(dp->profile, profile)))
928 {
929 char buf[PATH_MAX];
930
931 _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s",
932 profile);
933 ecore_file_recursive_rm(buf);
934 derived->profiles = eina_list_remove_list(derived->profiles, l);
935 eina_stringshare_del(dp->profile);
936 eina_stringshare_del(dp->derive_options);
937 free(dp);
938 _elm_config_profile_derived_save(_elm_profile, derived);
939 _elm_config_derived_free(derived);
940 return;
941 }
942 }
943 _elm_config_derived_free(derived);
944 }
945}
946
668const char * 947const char *
669_elm_config_profile_dir_get(const char *prof, 948_elm_config_profile_dir_get(const char *prof,
670 Eina_Bool is_user) 949 Eina_Bool is_user)
@@ -1688,6 +1967,13 @@ _elm_config_profile_save(void)
1688 } 1967 }
1689 1968
1690 ecore_file_unlink(buf2); 1969 ecore_file_unlink(buf2);
1970
1971 derived = _elm_config_derived_load(profile ? profile : _elm_profile);
1972 if (derived)
1973 {
1974 _elm_config_derived_save(cfg, derived);
1975 _elm_config_derived_free(derived);
1976 }
1691 return EINA_TRUE; 1977 return EINA_TRUE;
1692 1978
1693err: 1979err:
@@ -1696,8 +1982,9 @@ err:
1696} 1982}
1697 1983
1698Eina_Bool 1984Eina_Bool
1699_elm_config_save(const char *profile) 1985_elm_config_save(Elm_Config *cfg, const char *profile)
1700{ 1986{
1987 Elm_Config_Derived *derived;
1701 char buf[4096], buf2[4096]; 1988 char buf[4096], buf2[4096];
1702 int ok = 0, ret; 1989 int ok = 0, ret;
1703 const char *err; 1990 const char *err;
@@ -1754,7 +2041,7 @@ _elm_config_save(const char *profile)
1754 if (!ef) 2041 if (!ef)
1755 return EINA_FALSE; 2042 return EINA_FALSE;
1756 2043
1757 ok = eet_data_write(ef, _config_edd, "config", _elm_config, 1); 2044 ok = eet_data_write(ef, _config_edd, "config", cfg, 1);
1758 if (!ok) 2045 if (!ok)
1759 goto err; 2046 goto err;
1760 2047
@@ -1888,7 +2175,7 @@ _config_update(void)
1888 _elm_config->config_version = ELM_CONFIG_VERSION; 2175 _elm_config->config_version = ELM_CONFIG_VERSION;
1889 /* after updating user config, we must save */ 2176 /* after updating user config, we must save */
1890 _config_free(tcfg); 2177 _config_free(tcfg);
1891 _elm_config_save(NULL); 2178 _elm_config_save(_elm_config, NULL);
1892} 2179}
1893 2180
1894static void 2181static void
@@ -2386,7 +2673,7 @@ elm_config_password_show_last_timeout_set(double password_show_last_timeout)
2386EAPI Eina_Bool 2673EAPI Eina_Bool
2387elm_config_save(void) 2674elm_config_save(void)
2388{ 2675{
2389 return _elm_config_save(NULL); 2676 return _elm_config_save(_elm_config, NULL);
2390} 2677}
2391 2678
2392EAPI void 2679EAPI void
@@ -2465,10 +2752,9 @@ EAPI void
2465elm_config_profile_save(const char *profile) 2752elm_config_profile_save(const char *profile)
2466{ 2753{
2467 EINA_SAFETY_ON_NULL_RETURN(profile); 2754 EINA_SAFETY_ON_NULL_RETURN(profile);
2468 _elm_config_save(profile); 2755 _elm_config_save(_elm_config, profile);
2469} 2756}
2470 2757
2471
2472EAPI const char * 2758EAPI const char *
2473elm_config_engine_get(void) 2759elm_config_engine_get(void)
2474{ 2760{
@@ -3441,6 +3727,7 @@ _elm_config_init(void)
3441 if (!ELM_EVENT_CONFIG_ALL_CHANGED) 3727 if (!ELM_EVENT_CONFIG_ALL_CHANGED)
3442 ELM_EVENT_CONFIG_ALL_CHANGED = ecore_event_type_new(); 3728 ELM_EVENT_CONFIG_ALL_CHANGED = ecore_event_type_new();
3443 _desc_init(); 3729 _desc_init();
3730 _elm_config_profile_derived_init();
3444 _profile_fetch_from_conf(); 3731 _profile_fetch_from_conf();
3445 _config_load(); 3732 _config_load();
3446 _env_get(); 3733 _env_get();
@@ -3821,6 +4108,7 @@ _elm_config_shutdown(void)
3821 ELM_SAFE_FREE(_elm_profile, free); 4108 ELM_SAFE_FREE(_elm_profile, free);
3822 _elm_font_overlays_del_free(); 4109 _elm_font_overlays_del_free();
3823 4110
4111 _elm_config_profile_derived_shutdown();
3824 _desc_shutdown(); 4112 _desc_shutdown();
3825 4113
3826 ELM_SAFE_FREE(_elm_key_bindings, eina_hash_free); 4114 ELM_SAFE_FREE(_elm_key_bindings, eina_hash_free);
diff --git a/src/lib/elm_config.h b/src/lib/elm_config.h
index 1d106153b..1c74b653d 100644
--- a/src/lib/elm_config.h
+++ b/src/lib/elm_config.h
@@ -179,6 +179,47 @@ EAPI void elm_config_profile_set(const char *profile);
179EAPI void elm_config_profile_save(const char *profile); 179EAPI void elm_config_profile_save(const char *profile);
180 180
181/** 181/**
182 * Add a new profile of the given name to be derived from the current profile
183 *
184 * This creates a new profile of name @p profile that will be derived from
185 * the currently used profile using the modification commands encoded in the
186 * @p derive_options string.
187 *
188 * At this point it is not expected that anyone would generally use this API
189 * except if you are a destktop environment and so the user base of this API
190 * will be enlightenment itself.
191 *
192 * @param profile The new profile's name
193 * @param derive_options A string of derive options detailing how to modify
194 *
195 * @see elm_config_profile_derived_del
196 * @ingroup Profile
197 *
198 * @since 1.17
199 */
200EAPI void elm_config_profile_derived_add(const char *profile, const char *derive_options);
201
202/**
203 * Deletes a profile that is derived from the current one
204 *
205 * This deletes a derived profile added by elm_config_profile_derived_add().
206 * This will delete the profile of the given name @p profile that is derived
207 * from the current profile.
208 *
209 * At this point it is not expected that anyone would generally use this API
210 * except if you are a destktop environment and so the user base of this API
211 * will be enlightenment itself.
212 *
213 * @param profile The profile's name that is to be deleted
214 *
215 * @see elm_config_profile_derived_add
216 * @ingroup Profile
217 *
218 * @since 1.17
219 */
220EAPI void elm_config_profile_derived_del(const char *profile);
221
222/**
182 * @} 223 * @}
183 */ 224 */
184 225
diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h
index f5f1cde38..7bd39cb92 100644
--- a/src/lib/elm_priv.h
+++ b/src/lib/elm_priv.h
@@ -433,7 +433,7 @@ void _elm_config_init(void);
433void _elm_config_sub_init(void); 433void _elm_config_sub_init(void);
434void _elm_config_shutdown(void); 434void _elm_config_shutdown(void);
435void _elm_config_sub_shutdown(void); 435void _elm_config_sub_shutdown(void);
436Eina_Bool _elm_config_save(const char *profile); 436Eina_Bool _elm_config_save(Elm_Config *cfg, const char *profile);
437void _elm_config_reload(void); 437void _elm_config_reload(void);
438size_t _elm_config_user_dir_snprintf(char *dst, size_t size, 438size_t _elm_config_user_dir_snprintf(char *dst, size_t size,
439 const char *fmt, ...) 439 const char *fmt, ...)