diff options
| author | Yuuki Harano | 2019-07-18 01:07:36 +0900 |
|---|---|---|
| committer | Jeff Walsh | 2020-11-22 14:46:55 +1100 |
| commit | 31bba950bc867e43188922a8ef03c2f07c6a784a (patch) | |
| tree | ce3034c5493812f3dc5a719b6bafa9d309b808e7 | |
| parent | 519a4ac39f7cd9e2339b203463704db48752bc5b (diff) | |
| download | emacs-31bba950bc867e43188922a8ef03c2f07c6a784a.tar.gz emacs-31bba950bc867e43188922a8ef03c2f07c6a784a.zip | |
Use gsettings instead of X resource database
* src/pgtkfns.c (pgtk_is_lower_char, pgtk_is_upper_char)
(pgtk_is_numeric_char, parse_resource_key)
(pgtk_get_defaults_value, pgtk_set_defaults_value)
(Fpgtk_set_resource, pgtk_get_string_resource): handle gsettings scheme
* m4/gsettings.m4: new file
* etc/org.gnu.emacs.defaults.gschema.xml: new file
* configure.ac (GLIB_DISABLE_DEPRECATION_WARNINGS)
(gsettingsschemadir):
* Makefile.in (gsettingsschemadir, GLIB_COMPILE_SCHEMAS)
(install, uninstall, clean):
* .gitignore: add gschema
*.gschema.valid は生成ファイルなので無視。
schema の置き場所を変更。
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile.in | 22 | ||||
| -rw-r--r-- | configure.ac | 4 | ||||
| -rw-r--r-- | etc/org.gnu.emacs.defaults.gschema.xml | 48 | ||||
| -rw-r--r-- | m4/gsettings.m4 | 88 | ||||
| -rw-r--r-- | src/pgtkfns.c | 228 |
6 files changed, 372 insertions, 21 deletions
diff --git a/.gitignore b/.gitignore index bf7e9349813..8ac0f483f9b 100644 --- a/.gitignore +++ b/.gitignore | |||
| @@ -298,3 +298,6 @@ nt/emacs.rc | |||
| 298 | nt/emacsclient.rc | 298 | nt/emacsclient.rc |
| 299 | src/gdb.ini | 299 | src/gdb.ini |
| 300 | /var/ | 300 | /var/ |
| 301 | |||
| 302 | # gsettings schema | ||
| 303 | /etc/*.gschema.valid | ||
diff --git a/Makefile.in b/Makefile.in index fbb1891ba72..984c6193442 100644 --- a/Makefile.in +++ b/Makefile.in | |||
| @@ -216,6 +216,9 @@ icondir=$(datarootdir)/icons | |||
| 216 | # The source directory for the icon files. | 216 | # The source directory for the icon files. |
| 217 | iconsrcdir=$(srcdir)/etc/images/icons | 217 | iconsrcdir=$(srcdir)/etc/images/icons |
| 218 | 218 | ||
| 219 | # Where to install the gsettings schema file. | ||
| 220 | gsettingsschemadir = @gsettingsschemadir@ | ||
| 221 | |||
| 219 | # ==================== Emacs-specific directories ==================== | 222 | # ==================== Emacs-specific directories ==================== |
| 220 | 223 | ||
| 221 | # These variables hold the values Emacs will actually use. They are | 224 | # These variables hold the values Emacs will actually use. They are |
| @@ -300,6 +303,8 @@ LN_S_FILEONLY = @LN_S_FILEONLY@ | |||
| 300 | # We use gzip to compress installed .el and some .txt files. | 303 | # We use gzip to compress installed .el and some .txt files. |
| 301 | GZIP_PROG = @GZIP_PROG@ | 304 | GZIP_PROG = @GZIP_PROG@ |
| 302 | 305 | ||
| 306 | GLIB_COMPILE_SCHEMAS = glib-compile-schemas | ||
| 307 | |||
| 303 | # ============================= Targets ============================== | 308 | # ============================= Targets ============================== |
| 304 | 309 | ||
| 305 | # Program name transformation. | 310 | # Program name transformation. |
| @@ -330,7 +335,9 @@ CONFIG_STATUS_FILES_IN = \ | |||
| 330 | COPYDIR = ${srcdir}/etc ${srcdir}/lisp | 335 | COPYDIR = ${srcdir}/etc ${srcdir}/lisp |
| 331 | COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}" | 336 | COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}" |
| 332 | 337 | ||
| 333 | all: ${SUBDIR} info | 338 | gsettings_SCHEMAS = etc/org.gnu.emacs.defaults.gschema.xml |
| 339 | |||
| 340 | all: ${SUBDIR} info $(gsettings_SCHEMAS:.xml=.valid) | ||
| 334 | 341 | ||
| 335 | .PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 etc-emacsver | 342 | .PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 etc-emacsver |
| 336 | 343 | ||
| @@ -468,7 +475,7 @@ $(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/m4/*.m4 | |||
| 468 | ## don't have to duplicate the list of utilities to install in | 475 | ## don't have to duplicate the list of utilities to install in |
| 469 | ## this Makefile as well. | 476 | ## this Makefile as well. |
| 470 | 477 | ||
| 471 | install: all install-arch-indep install-etcdoc install-arch-dep install-$(NTDIR) blessmail | 478 | install: all install-arch-indep install-etcdoc install-arch-dep install-$(NTDIR) blessmail install-gsettings-schemas |
| 472 | @true | 479 | @true |
| 473 | 480 | ||
| 474 | ## Ensure that $subdir contains a subdirs.el file. | 481 | ## Ensure that $subdir contains a subdirs.el file. |
| @@ -760,7 +767,7 @@ install-strip: | |||
| 760 | ### create (but not the noninstalled files such as 'make all' would create). | 767 | ### create (but not the noninstalled files such as 'make all' would create). |
| 761 | ### | 768 | ### |
| 762 | ### Don't delete the lisp and etc directories if they're in the source tree. | 769 | ### Don't delete the lisp and etc directories if they're in the source tree. |
| 763 | uninstall: uninstall-$(NTDIR) uninstall-doc | 770 | uninstall: uninstall-$(NTDIR) uninstall-doc uninstall-gsettings-schemas |
| 764 | rm -f "$(DESTDIR)$(includedir)/emacs-module.h" | 771 | rm -f "$(DESTDIR)$(includedir)/emacs-module.h" |
| 765 | $(MAKE) -C lib-src uninstall | 772 | $(MAKE) -C lib-src uninstall |
| 766 | -unset CDPATH; \ | 773 | -unset CDPATH; \ |
| @@ -857,7 +864,7 @@ clean_dirs = $(mostlyclean_dirs) nextstep | |||
| 857 | 864 | ||
| 858 | $(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean))) | 865 | $(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean))) |
| 859 | 866 | ||
| 860 | clean: $(clean_dirs:=_clean) | 867 | clean: $(clean_dirs:=_clean) clean-gsettings-schemas |
| 861 | $(MAKE) -C admin/charsets $@ | 868 | $(MAKE) -C admin/charsets $@ |
| 862 | [ ! -d test ] || $(MAKE) -C test $@ | 869 | [ ! -d test ] || $(MAKE) -C test $@ |
| 863 | -rm -f ./*.tmp etc/*.tmp* | 870 | -rm -f ./*.tmp etc/*.tmp* |
| @@ -1194,3 +1201,10 @@ gitmerge: | |||
| 1194 | ${GITMERGE_EMACS} -batch --no-site-file --no-site-lisp \ | 1201 | ${GITMERGE_EMACS} -batch --no-site-file --no-site-lisp \ |
| 1195 | -l ${srcdir}/admin/gitmerge.el \ | 1202 | -l ${srcdir}/admin/gitmerge.el \ |
| 1196 | --eval '(setq gitmerge-minimum-missing ${GITMERGE_NMIN})' -f gitmerge | 1203 | --eval '(setq gitmerge-minimum-missing ${GITMERGE_NMIN})' -f gitmerge |
| 1204 | |||
| 1205 | @GSETTINGS_RULES@ | ||
| 1206 | |||
| 1207 | install-gsettings-schemas: | ||
| 1208 | uninstall-gsettings-schemas: | ||
| 1209 | clean-gsettings-schemas: | ||
| 1210 | $(gsettings_SCHEMAS:.xml=.valid): | ||
diff --git a/configure.ac b/configure.ac index ce9d0168476..6d3652d97e1 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -2683,6 +2683,9 @@ if test "${opsys}" != "mingw32"; then | |||
| 2683 | AC_DEFINE([GLIB_DISABLE_DEPRECATION_WARNINGS], [1], | 2683 | AC_DEFINE([GLIB_DISABLE_DEPRECATION_WARNINGS], [1], |
| 2684 | [Define to 1 to disable Glib deprecation warnings.]) | 2684 | [Define to 1 to disable Glib deprecation warnings.]) |
| 2685 | fi | 2685 | fi |
| 2686 | if test "$window_system" = pgtk; then | ||
| 2687 | GLIB_GSETTINGS | ||
| 2688 | fi | ||
| 2686 | else | 2689 | else |
| 2687 | check_gtk2=yes | 2690 | check_gtk2=yes |
| 2688 | gtk3_pkg_errors="$GTK_PKG_ERRORS " | 2691 | gtk3_pkg_errors="$GTK_PKG_ERRORS " |
| @@ -5297,6 +5300,7 @@ AC_SUBST(prefix) | |||
| 5297 | AC_SUBST(exec_prefix) | 5300 | AC_SUBST(exec_prefix) |
| 5298 | AC_SUBST(bindir) | 5301 | AC_SUBST(bindir) |
| 5299 | AC_SUBST(datadir) | 5302 | AC_SUBST(datadir) |
| 5303 | AC_SUBST(gsettingsschemadir) | ||
| 5300 | AC_SUBST(sharedstatedir) | 5304 | AC_SUBST(sharedstatedir) |
| 5301 | AC_SUBST(libexecdir) | 5305 | AC_SUBST(libexecdir) |
| 5302 | AC_SUBST(mandir) | 5306 | AC_SUBST(mandir) |
diff --git a/etc/org.gnu.emacs.defaults.gschema.xml b/etc/org.gnu.emacs.defaults.gschema.xml new file mode 100644 index 00000000000..6f2c79196e6 --- /dev/null +++ b/etc/org.gnu.emacs.defaults.gschema.xml | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <schemalist> | ||
| 3 | |||
| 4 | <schema id="org.gnu.emacs.defaults"> | ||
| 5 | |||
| 6 | <key name='alpha' type='s'><default>''</default></key> | ||
| 7 | <key name='auto-raise-lower' type='s'><default>''</default></key> | ||
| 8 | <key name='auto-lower' type='s'><default>''</default></key> | ||
| 9 | <key name='auto-raise' type='s'><default>''</default></key> | ||
| 10 | <key name='background' type='s'><default>''</default></key> | ||
| 11 | <key name='background-mode' type='s'><default>''</default></key> | ||
| 12 | <key name='bitmap-icon' type='s'><default>''</default></key> | ||
| 13 | <key name='border-color' type='s'><default>''</default></key> | ||
| 14 | <key name='border-width' type='s'><default>''</default></key> | ||
| 15 | <key name='buffer-predicate' type='s'><default>''</default></key> | ||
| 16 | <key name='cursor-blink' type='s'><default>''</default></key> | ||
| 17 | <key name='cursor-type' type='s'><default>''</default></key> | ||
| 18 | <key name='cursor-color' type='s'><default>''</default></key> | ||
| 19 | <key name='font' type='s'><default>''</default></key> | ||
| 20 | <key name='font-backend' type='s'><default>''</default></key> | ||
| 21 | <key name='foreground' type='s'><default>''</default></key> | ||
| 22 | <key name='fullscreen' type='s'><default>''</default></key> | ||
| 23 | <key name='horizontal-scroll-bars' type='s'><default>''</default></key> | ||
| 24 | <key name='icon-name' type='s'><default>''</default></key> | ||
| 25 | <key name='inhibit-double-buffering' type='s'><default>''</default></key> | ||
| 26 | <key name='internal-border' type='s'><default>''</default></key> | ||
| 27 | <key name='internal-border-width' type='s'><default>''</default></key> | ||
| 28 | <key name='left-fringe' type='s'><default>''</default></key> | ||
| 29 | <key name='line-spacing' type='s'><default>''</default></key> | ||
| 30 | <key name='menu-bar' type='s'><default>''</default></key> | ||
| 31 | <key name='minibuffer' type='s'><default>''</default></key> | ||
| 32 | <key name='name' type='s'><default>''</default></key> | ||
| 33 | <key name='pointer-color' type='s'><default>''</default></key> | ||
| 34 | <key name='reverse-video' type='s'><default>''</default></key> | ||
| 35 | <key name='right-fringe' type='s'><default>''</default></key> | ||
| 36 | <key name='screen-gamma' type='s'><default>''</default></key> | ||
| 37 | <key name='scroll-bar' type='s'><default>''</default></key> | ||
| 38 | <key name='scroll-bar-height' type='s'><default>''</default></key> | ||
| 39 | <key name='scroll-bar-width' type='s'><default>''</default></key> | ||
| 40 | <key name='scroll-bars' type='s'><default>''</default></key> | ||
| 41 | <key name='title' type='s'><default>''</default></key> | ||
| 42 | <key name='tool-bar' type='s'><default>''</default></key> | ||
| 43 | <key name='vertical-scroll-bars' type='s'><default>''</default></key> | ||
| 44 | <key name='wait-for-w-m' type='s'><default>''</default></key> | ||
| 45 | |||
| 46 | </schema> | ||
| 47 | |||
| 48 | </schemalist> | ||
diff --git a/m4/gsettings.m4 b/m4/gsettings.m4 new file mode 100644 index 00000000000..882e6a83e76 --- /dev/null +++ b/m4/gsettings.m4 | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | # Increment this whenever this file is changed. | ||
| 2 | #serial 2 | ||
| 3 | |||
| 4 | dnl GLIB_GSETTINGS | ||
| 5 | dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether | ||
| 6 | dnl the schema should be compiled | ||
| 7 | dnl | ||
| 8 | |||
| 9 | AC_DEFUN([GLIB_GSETTINGS], | ||
| 10 | [ | ||
| 11 | dnl We can't use PKG_PREREQ because that needs 0.29. | ||
| 12 | m4_ifndef([PKG_PROG_PKG_CONFIG], | ||
| 13 | [pkg.m4 version 0.28 or later is required]) | ||
| 14 | |||
| 15 | m4_pattern_allow([AM_V_GEN]) | ||
| 16 | AC_ARG_ENABLE(schemas-compile, | ||
| 17 | AS_HELP_STRING([--disable-schemas-compile], | ||
| 18 | [Disable regeneration of gschemas.compiled on install]), | ||
| 19 | [case ${enableval} in | ||
| 20 | yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;; | ||
| 21 | no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;; | ||
| 22 | *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;; | ||
| 23 | esac]) | ||
| 24 | AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE]) | ||
| 25 | PKG_PROG_PKG_CONFIG([0.16]) | ||
| 26 | AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.0/schemas]) | ||
| 27 | AS_IF([test x$cross_compiling != xyes], | ||
| 28 | [PKG_CHECK_VAR([GLIB_COMPILE_SCHEMAS], [gio-2.0], [glib_compile_schemas])], | ||
| 29 | [AC_PATH_PROG([GLIB_COMPILE_SCHEMAS], [glib-compile-schemas])]) | ||
| 30 | AC_SUBST(GLIB_COMPILE_SCHEMAS) | ||
| 31 | if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then | ||
| 32 | ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2]) | ||
| 33 | else | ||
| 34 | ifelse([$1],,[:],[$1]) | ||
| 35 | fi | ||
| 36 | |||
| 37 | GSETTINGS_RULES=' | ||
| 38 | .PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas | ||
| 39 | |||
| 40 | mostlyclean-am: clean-gsettings-schemas | ||
| 41 | |||
| 42 | gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE)) | ||
| 43 | |||
| 44 | %.gschema.valid: %.gschema.xml $(gsettings__enum_file) | ||
| 45 | $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$< && mkdir -p [$](@D) && touch [$]@ | ||
| 46 | |||
| 47 | all-am: $(gsettings_SCHEMAS:.xml=.valid) | ||
| 48 | uninstall-am: uninstall-gsettings-schemas | ||
| 49 | install-data-am: install-gsettings-schemas | ||
| 50 | |||
| 51 | .SECONDARY: $(gsettings_SCHEMAS) | ||
| 52 | |||
| 53 | install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file) | ||
| 54 | @$(NORMAL_INSTALL) | ||
| 55 | if test -n "$^"; then \ | ||
| 56 | test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \ | ||
| 57 | $(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \ | ||
| 58 | test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \ | ||
| 59 | fi | ||
| 60 | |||
| 61 | uninstall-gsettings-schemas: | ||
| 62 | @$(NORMAL_UNINSTALL) | ||
| 63 | @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \ | ||
| 64 | files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \ | ||
| 65 | test -n "$$files" || exit 0; \ | ||
| 66 | echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \ | ||
| 67 | cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files | ||
| 68 | test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) | ||
| 69 | |||
| 70 | clean-gsettings-schemas: | ||
| 71 | rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) | ||
| 72 | |||
| 73 | ifdef gsettings_ENUM_NAMESPACE | ||
| 74 | $(gsettings__enum_file): $(gsettings_ENUM_FILES) | ||
| 75 | $(AM_V_GEN) glib-mkenums --comments '\''<!-- @comment@ -->'\'' --fhead "<schemalist>" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " <value nick='\''@valuenick@'\'' value='\''@valuenum@'\''/>" --vtail " </@type@>" --ftail "</schemalist>" [$]^ > [$]@.tmp && mv [$]@.tmp [$]@ | ||
| 76 | endif | ||
| 77 | ' | ||
| 78 | _GSETTINGS_SUBST(GSETTINGS_RULES) | ||
| 79 | ]) | ||
| 80 | |||
| 81 | dnl _GSETTINGS_SUBST(VARIABLE) | ||
| 82 | dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST | ||
| 83 | AC_DEFUN([_GSETTINGS_SUBST], | ||
| 84 | [ | ||
| 85 | AC_SUBST([$1]) | ||
| 86 | m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) | ||
| 87 | ] | ||
| 88 | ) | ||
diff --git a/src/pgtkfns.c b/src/pgtkfns.c index 845c2c6f331..04181825b1a 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c | |||
| @@ -1471,7 +1471,6 @@ Some window managers may refuse to restack windows. */) | |||
| 1471 | 1471 | ||
| 1472 | [window orderWindow: flag | 1472 | [window orderWindow: flag |
| 1473 | relativeTo: window2]; | 1473 | relativeTo: window2]; |
| 1474 | |||
| 1475 | #endif | 1474 | #endif |
| 1476 | return Qt; | 1475 | return Qt; |
| 1477 | } | 1476 | } |
| @@ -1482,22 +1481,211 @@ Some window managers may refuse to restack windows. */) | |||
| 1482 | } | 1481 | } |
| 1483 | } | 1482 | } |
| 1484 | 1483 | ||
| 1484 | #ifdef HAVE_GSETTINGS | ||
| 1485 | |||
| 1486 | #define RESOURCE_KEY_MAX_LEN 128 | ||
| 1487 | #define SCHEMA_ID "org.gnu.emacs.defaults" | ||
| 1488 | #define PATH_FOR_CLASS_TYPE "/org/gnu/emacs/defaults-by-class/" | ||
| 1489 | #define PATH_PREFIX_FOR_NAME_TYPE "/org/gnu/emacs/defaults-by-name/" | ||
| 1490 | |||
| 1491 | static inline int | ||
| 1492 | pgtk_is_lower_char (int c) | ||
| 1493 | { | ||
| 1494 | return c >= 'a' && c <= 'z'; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | static inline int | ||
| 1498 | pgtk_is_upper_char (int c) | ||
| 1499 | { | ||
| 1500 | return c >= 'A' && c <= 'Z'; | ||
| 1501 | } | ||
| 1502 | |||
| 1503 | static inline int | ||
| 1504 | pgtk_is_numeric_char (int c) | ||
| 1505 | { | ||
| 1506 | return c >= '0' && c <= '9'; | ||
| 1507 | } | ||
| 1508 | |||
| 1509 | static GSettings * | ||
| 1510 | parse_resource_key (const char *res_key, char *setting_key) | ||
| 1511 | { | ||
| 1512 | char path[32 + RESOURCE_KEY_MAX_LEN]; | ||
| 1513 | const char *sp = res_key; | ||
| 1514 | char *dp; | ||
| 1515 | |||
| 1516 | /* | ||
| 1517 | * res_key="emacs.cursorBlink" | ||
| 1518 | * -> path="/org/gnu/emacs/defaults-by-name/emacs/" | ||
| 1519 | * setting_key="cursor-blink" | ||
| 1520 | * | ||
| 1521 | * res_key="Emacs.CursorBlink" | ||
| 1522 | * -> path="/org/gnu/emacs/defaults-by-class/" | ||
| 1523 | * setting_key="cursor-blink" | ||
| 1524 | * | ||
| 1525 | * Returns GSettings* if setting_key exists in schema, otherwise NULL. | ||
| 1526 | */ | ||
| 1527 | |||
| 1528 | /* generate path */ | ||
| 1529 | if (pgtk_is_upper_char(*sp)) { | ||
| 1530 | /* First letter is upper case. It should be "Emacs", | ||
| 1531 | * but don't care. | ||
| 1532 | */ | ||
| 1533 | strcpy (path, PATH_FOR_CLASS_TYPE); | ||
| 1534 | while (*sp != '\0') { | ||
| 1535 | if (*sp == '.') | ||
| 1536 | break; | ||
| 1537 | sp++; | ||
| 1538 | } | ||
| 1539 | } else { | ||
| 1540 | strcpy (path, PATH_PREFIX_FOR_NAME_TYPE); | ||
| 1541 | dp = path + strlen (path); | ||
| 1542 | while (*sp != '\0') { | ||
| 1543 | int c = *sp; | ||
| 1544 | if (c == '.') | ||
| 1545 | break; | ||
| 1546 | if (pgtk_is_lower_char (c)) | ||
| 1547 | (void) 0; /* lower -> NOP */ | ||
| 1548 | else if (pgtk_is_upper_char (c)) | ||
| 1549 | c = c - 'A' + 'a'; /* upper -> lower */ | ||
| 1550 | else if (pgtk_is_numeric_char (c)) | ||
| 1551 | (void) 0; /* numeric -> NOP */ | ||
| 1552 | else | ||
| 1553 | return NULL; /* invalid */ | ||
| 1554 | *dp++ = c; | ||
| 1555 | sp++; | ||
| 1556 | } | ||
| 1557 | *dp++ = '/'; /* must ends with '/' */ | ||
| 1558 | *dp = '\0'; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | if (*sp++ != '.') | ||
| 1562 | return NULL; | ||
| 1563 | |||
| 1564 | /* generate setting_key */ | ||
| 1565 | dp = setting_key; | ||
| 1566 | while (*sp != '\0') { | ||
| 1567 | int c = *sp; | ||
| 1568 | if (pgtk_is_lower_char (c)) | ||
| 1569 | (void) 0; /* lower -> NOP */ | ||
| 1570 | else if (pgtk_is_upper_char (c)) { | ||
| 1571 | c = c - 'A' + 'a'; /* upper -> lower */ | ||
| 1572 | if (dp != setting_key) | ||
| 1573 | *dp++ = '-'; /* store '-' unless first char */ | ||
| 1574 | } else if (pgtk_is_numeric_char (c)) | ||
| 1575 | (void) 0; /* numeric -> NOP */ | ||
| 1576 | else | ||
| 1577 | return NULL; /* invalid */ | ||
| 1578 | |||
| 1579 | *dp++ = c; | ||
| 1580 | sp++; | ||
| 1581 | } | ||
| 1582 | *dp = '\0'; | ||
| 1583 | |||
| 1584 | /* check existence of setting_key */ | ||
| 1585 | GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default (); | ||
| 1586 | GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, FALSE); | ||
| 1587 | if (!g_settings_schema_has_key (scm, setting_key)) { | ||
| 1588 | g_settings_schema_unref (scm); | ||
| 1589 | return NULL; | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | /* create GSettings, and return it */ | ||
| 1593 | GSettings *gs = g_settings_new_full (scm, NULL, path); | ||
| 1594 | |||
| 1595 | g_settings_schema_unref (scm); | ||
| 1596 | return gs; | ||
| 1597 | } | ||
| 1598 | |||
| 1599 | const char * | ||
| 1600 | pgtk_get_defaults_value (const char *key) | ||
| 1601 | { | ||
| 1602 | char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2]; | ||
| 1603 | |||
| 1604 | if (strlen (key) >= RESOURCE_KEY_MAX_LEN) | ||
| 1605 | error ("resource key too long."); | ||
| 1606 | |||
| 1607 | GSettings *gs = parse_resource_key(key, skey); | ||
| 1608 | if (gs == NULL) { | ||
| 1609 | return NULL; | ||
| 1610 | } | ||
| 1611 | |||
| 1612 | gchar *str = g_settings_get_string (gs, skey); | ||
| 1613 | |||
| 1614 | /* There is no timing to free str. | ||
| 1615 | * So, copy it here and free it. | ||
| 1616 | * | ||
| 1617 | * MEMO: Resource values for emacs shouldn't need such a long string value. | ||
| 1618 | */ | ||
| 1619 | static char holder[128]; | ||
| 1620 | strncpy (holder, str, 128); | ||
| 1621 | holder[127] = '\0'; | ||
| 1622 | |||
| 1623 | g_object_unref (gs); | ||
| 1624 | g_free (str); | ||
| 1625 | return holder[0] != '\0' ? holder : NULL; | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | static void | ||
| 1629 | pgtk_set_defaults_value (const char *key, const char *value) | ||
| 1630 | { | ||
| 1631 | char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2]; | ||
| 1632 | |||
| 1633 | if (strlen (key) >= RESOURCE_KEY_MAX_LEN) | ||
| 1634 | error ("resource key too long."); | ||
| 1635 | |||
| 1636 | GSettings *gs = parse_resource_key(key, skey); | ||
| 1637 | if (gs == NULL) { | ||
| 1638 | error ("unknown resource key."); | ||
| 1639 | } | ||
| 1640 | if (value != NULL) { | ||
| 1641 | g_settings_set_string (gs, skey, value); | ||
| 1642 | } else { | ||
| 1643 | g_settings_reset (gs, skey); | ||
| 1644 | } | ||
| 1645 | |||
| 1646 | g_object_unref (gs); | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | #undef RESOURCE_KEY_MAX_LEN | ||
| 1650 | #undef SCHEMA_ID | ||
| 1651 | #undef PATH_FOR_CLASS_TYPE | ||
| 1652 | #undef PATH_PREFIX_FOR_NAME_TYPE | ||
| 1653 | |||
| 1654 | #else /* not HAVE_GSETTINGS */ | ||
| 1655 | |||
| 1485 | const char * | 1656 | const char * |
| 1486 | pgtk_get_defaults_value (const char *key) | 1657 | pgtk_get_defaults_value (const char *key) |
| 1487 | { | 1658 | { |
| 1488 | return NULL; | 1659 | return NULL; |
| 1489 | } | 1660 | } |
| 1490 | 1661 | ||
| 1491 | DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 3, 3, 0, | 1662 | static void |
| 1492 | doc: /* Set property NAME of OWNER to VALUE, from the defaults database. | 1663 | pgtk_set_defaults_value (const char *key, const char *value) |
| 1493 | If OWNER is nil, Emacs is assumed. | 1664 | { |
| 1494 | If VALUE is nil, the default is removed. */) | 1665 | error ("gsettings not supported."); |
| 1495 | (Lisp_Object owner, Lisp_Object name, Lisp_Object value) | 1666 | } |
| 1667 | |||
| 1668 | #endif | ||
| 1669 | |||
| 1670 | |||
| 1671 | DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 2, 2, 0, | ||
| 1672 | doc: /* Set the value of ATTRIBUTE, of class CLASS, as VALUE, into defaults database. */) | ||
| 1673 | (Lisp_Object attribute, Lisp_Object value) | ||
| 1496 | { | 1674 | { |
| 1497 | check_window_system (NULL); | 1675 | check_window_system (NULL); |
| 1498 | if (NILP (owner)) | 1676 | |
| 1499 | owner = build_string (pgtk_app_name); | 1677 | CHECK_STRING (attribute); |
| 1500 | CHECK_STRING (name); | 1678 | if (!NILP (value)) |
| 1679 | CHECK_STRING (value); | ||
| 1680 | |||
| 1681 | char *res = SSDATA (Vx_resource_name); | ||
| 1682 | char *attr = SSDATA (attribute); | ||
| 1683 | if (attr[0] >= 'A' && attr[0] <= 'Z') | ||
| 1684 | res = SSDATA (Vx_resource_class); | ||
| 1685 | |||
| 1686 | char *key = g_strdup_printf("%s.%s", res, attr); | ||
| 1687 | |||
| 1688 | pgtk_set_defaults_value(key, NILP (value) ? NULL : SSDATA (value)); | ||
| 1501 | 1689 | ||
| 1502 | return Qnil; | 1690 | return Qnil; |
| 1503 | } | 1691 | } |
| @@ -1794,20 +1982,26 @@ pgtk_set_scroll_bar_default_height (struct frame *f) | |||
| 1794 | const char * | 1982 | const char * |
| 1795 | pgtk_get_string_resource (XrmDatabase rdb, const char *name, const char *class) | 1983 | pgtk_get_string_resource (XrmDatabase rdb, const char *name, const char *class) |
| 1796 | { | 1984 | { |
| 1797 | /* remove appname prefix; TODO: allow for !="Emacs" */ | ||
| 1798 | const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0); | ||
| 1799 | |||
| 1800 | check_window_system (NULL); | 1985 | check_window_system (NULL); |
| 1801 | 1986 | ||
| 1802 | if (inhibit_x_resources) | 1987 | if (inhibit_x_resources) |
| 1803 | /* --quick was passed, so this is a no-op. */ | 1988 | /* --quick was passed, so this is a no-op. */ |
| 1804 | return NULL; | 1989 | return NULL; |
| 1805 | 1990 | ||
| 1806 | res = pgtk_get_defaults_value (toCheck); | 1991 | const char *res = pgtk_get_defaults_value (name); |
| 1807 | return (char *) (!res ? NULL | 1992 | if (res == NULL) |
| 1808 | : !c_strncasecmp (res, "YES", 3) ? "true" | 1993 | res = pgtk_get_defaults_value (class); |
| 1809 | : !c_strncasecmp (res, "NO", 2) ? "false" | 1994 | |
| 1810 | : res); | 1995 | if (res == NULL) |
| 1996 | return NULL; | ||
| 1997 | |||
| 1998 | if (c_strncasecmp (res, "YES", 3) == 0) | ||
| 1999 | return "true"; | ||
| 2000 | |||
| 2001 | if (c_strncasecmp (res, "NO", 2) == 0) | ||
| 2002 | return "false"; | ||
| 2003 | |||
| 2004 | return res; | ||
| 1811 | } | 2005 | } |
| 1812 | 2006 | ||
| 1813 | 2007 | ||