1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-05 11:45:45 +00:00

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 の置き場所を変更。
This commit is contained in:
Yuuki Harano 2019-07-18 01:07:36 +09:00 committed by Jeff Walsh
parent 519a4ac39f
commit 31bba950bc
6 changed files with 372 additions and 21 deletions

3
.gitignore vendored
View File

@ -298,3 +298,6 @@ nt/emacs.rc
nt/emacsclient.rc
src/gdb.ini
/var/
# gsettings schema
/etc/*.gschema.valid

View File

@ -216,6 +216,9 @@ icondir=$(datarootdir)/icons
# The source directory for the icon files.
iconsrcdir=$(srcdir)/etc/images/icons
# Where to install the gsettings schema file.
gsettingsschemadir = @gsettingsschemadir@
# ==================== Emacs-specific directories ====================
# These variables hold the values Emacs will actually use. They are
@ -300,6 +303,8 @@ LN_S_FILEONLY = @LN_S_FILEONLY@
# We use gzip to compress installed .el and some .txt files.
GZIP_PROG = @GZIP_PROG@
GLIB_COMPILE_SCHEMAS = glib-compile-schemas
# ============================= Targets ==============================
# Program name transformation.
@ -330,7 +335,9 @@ CONFIG_STATUS_FILES_IN = \
COPYDIR = ${srcdir}/etc ${srcdir}/lisp
COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}"
all: ${SUBDIR} info
gsettings_SCHEMAS = etc/org.gnu.emacs.defaults.gschema.xml
all: ${SUBDIR} info $(gsettings_SCHEMAS:.xml=.valid)
.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 etc-emacsver
@ -468,7 +475,7 @@ $(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/m4/*.m4
## don't have to duplicate the list of utilities to install in
## this Makefile as well.
install: all install-arch-indep install-etcdoc install-arch-dep install-$(NTDIR) blessmail
install: all install-arch-indep install-etcdoc install-arch-dep install-$(NTDIR) blessmail install-gsettings-schemas
@true
## Ensure that $subdir contains a subdirs.el file.
@ -760,7 +767,7 @@ install-strip:
### create (but not the noninstalled files such as 'make all' would create).
###
### Don't delete the lisp and etc directories if they're in the source tree.
uninstall: uninstall-$(NTDIR) uninstall-doc
uninstall: uninstall-$(NTDIR) uninstall-doc uninstall-gsettings-schemas
rm -f "$(DESTDIR)$(includedir)/emacs-module.h"
$(MAKE) -C lib-src uninstall
-unset CDPATH; \
@ -857,7 +864,7 @@ clean_dirs = $(mostlyclean_dirs) nextstep
$(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean)))
clean: $(clean_dirs:=_clean)
clean: $(clean_dirs:=_clean) clean-gsettings-schemas
$(MAKE) -C admin/charsets $@
[ ! -d test ] || $(MAKE) -C test $@
-rm -f ./*.tmp etc/*.tmp*
@ -1194,3 +1201,10 @@ gitmerge:
${GITMERGE_EMACS} -batch --no-site-file --no-site-lisp \
-l ${srcdir}/admin/gitmerge.el \
--eval '(setq gitmerge-minimum-missing ${GITMERGE_NMIN})' -f gitmerge
@GSETTINGS_RULES@
install-gsettings-schemas:
uninstall-gsettings-schemas:
clean-gsettings-schemas:
$(gsettings_SCHEMAS:.xml=.valid):

View File

@ -2683,6 +2683,9 @@ if test "${opsys}" != "mingw32"; then
AC_DEFINE([GLIB_DISABLE_DEPRECATION_WARNINGS], [1],
[Define to 1 to disable Glib deprecation warnings.])
fi
if test "$window_system" = pgtk; then
GLIB_GSETTINGS
fi
else
check_gtk2=yes
gtk3_pkg_errors="$GTK_PKG_ERRORS "
@ -5297,6 +5300,7 @@ AC_SUBST(prefix)
AC_SUBST(exec_prefix)
AC_SUBST(bindir)
AC_SUBST(datadir)
AC_SUBST(gsettingsschemadir)
AC_SUBST(sharedstatedir)
AC_SUBST(libexecdir)
AC_SUBST(mandir)

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<schemalist>
<schema id="org.gnu.emacs.defaults">
<key name='alpha' type='s'><default>''</default></key>
<key name='auto-raise-lower' type='s'><default>''</default></key>
<key name='auto-lower' type='s'><default>''</default></key>
<key name='auto-raise' type='s'><default>''</default></key>
<key name='background' type='s'><default>''</default></key>
<key name='background-mode' type='s'><default>''</default></key>
<key name='bitmap-icon' type='s'><default>''</default></key>
<key name='border-color' type='s'><default>''</default></key>
<key name='border-width' type='s'><default>''</default></key>
<key name='buffer-predicate' type='s'><default>''</default></key>
<key name='cursor-blink' type='s'><default>''</default></key>
<key name='cursor-type' type='s'><default>''</default></key>
<key name='cursor-color' type='s'><default>''</default></key>
<key name='font' type='s'><default>''</default></key>
<key name='font-backend' type='s'><default>''</default></key>
<key name='foreground' type='s'><default>''</default></key>
<key name='fullscreen' type='s'><default>''</default></key>
<key name='horizontal-scroll-bars' type='s'><default>''</default></key>
<key name='icon-name' type='s'><default>''</default></key>
<key name='inhibit-double-buffering' type='s'><default>''</default></key>
<key name='internal-border' type='s'><default>''</default></key>
<key name='internal-border-width' type='s'><default>''</default></key>
<key name='left-fringe' type='s'><default>''</default></key>
<key name='line-spacing' type='s'><default>''</default></key>
<key name='menu-bar' type='s'><default>''</default></key>
<key name='minibuffer' type='s'><default>''</default></key>
<key name='name' type='s'><default>''</default></key>
<key name='pointer-color' type='s'><default>''</default></key>
<key name='reverse-video' type='s'><default>''</default></key>
<key name='right-fringe' type='s'><default>''</default></key>
<key name='screen-gamma' type='s'><default>''</default></key>
<key name='scroll-bar' type='s'><default>''</default></key>
<key name='scroll-bar-height' type='s'><default>''</default></key>
<key name='scroll-bar-width' type='s'><default>''</default></key>
<key name='scroll-bars' type='s'><default>''</default></key>
<key name='title' type='s'><default>''</default></key>
<key name='tool-bar' type='s'><default>''</default></key>
<key name='vertical-scroll-bars' type='s'><default>''</default></key>
<key name='wait-for-w-m' type='s'><default>''</default></key>
</schema>
</schemalist>

88
m4/gsettings.m4 Normal file
View File

@ -0,0 +1,88 @@
# Increment this whenever this file is changed.
#serial 2
dnl GLIB_GSETTINGS
dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether
dnl the schema should be compiled
dnl
AC_DEFUN([GLIB_GSETTINGS],
[
dnl We can't use PKG_PREREQ because that needs 0.29.
m4_ifndef([PKG_PROG_PKG_CONFIG],
[pkg.m4 version 0.28 or later is required])
m4_pattern_allow([AM_V_GEN])
AC_ARG_ENABLE(schemas-compile,
AS_HELP_STRING([--disable-schemas-compile],
[Disable regeneration of gschemas.compiled on install]),
[case ${enableval} in
yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;;
no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;;
esac])
AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE])
PKG_PROG_PKG_CONFIG([0.16])
AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.0/schemas])
AS_IF([test x$cross_compiling != xyes],
[PKG_CHECK_VAR([GLIB_COMPILE_SCHEMAS], [gio-2.0], [glib_compile_schemas])],
[AC_PATH_PROG([GLIB_COMPILE_SCHEMAS], [glib-compile-schemas])])
AC_SUBST(GLIB_COMPILE_SCHEMAS)
if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then
ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2])
else
ifelse([$1],,[:],[$1])
fi
GSETTINGS_RULES='
.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas
mostlyclean-am: clean-gsettings-schemas
gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE))
%.gschema.valid: %.gschema.xml $(gsettings__enum_file)
$(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$< && mkdir -p [$](@D) && touch [$]@
all-am: $(gsettings_SCHEMAS:.xml=.valid)
uninstall-am: uninstall-gsettings-schemas
install-data-am: install-gsettings-schemas
.SECONDARY: $(gsettings_SCHEMAS)
install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file)
@$(NORMAL_INSTALL)
if test -n "$^"; then \
test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \
$(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \
test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \
fi
uninstall-gsettings-schemas:
@$(NORMAL_UNINSTALL)
@list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \
test -n "$$files" || exit 0; \
echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files
test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir)
clean-gsettings-schemas:
rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file)
ifdef gsettings_ENUM_NAMESPACE
$(gsettings__enum_file): $(gsettings_ENUM_FILES)
$(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 [$]@
endif
'
_GSETTINGS_SUBST(GSETTINGS_RULES)
])
dnl _GSETTINGS_SUBST(VARIABLE)
dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST
AC_DEFUN([_GSETTINGS_SUBST],
[
AC_SUBST([$1])
m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])])
]
)

View File

@ -1471,7 +1471,6 @@ Some window managers may refuse to restack windows. */)
[window orderWindow: flag
relativeTo: window2];
#endif
return Qt;
}
@ -1482,22 +1481,211 @@ Some window managers may refuse to restack windows. */)
}
}
#ifdef HAVE_GSETTINGS
#define RESOURCE_KEY_MAX_LEN 128
#define SCHEMA_ID "org.gnu.emacs.defaults"
#define PATH_FOR_CLASS_TYPE "/org/gnu/emacs/defaults-by-class/"
#define PATH_PREFIX_FOR_NAME_TYPE "/org/gnu/emacs/defaults-by-name/"
static inline int
pgtk_is_lower_char (int c)
{
return c >= 'a' && c <= 'z';
}
static inline int
pgtk_is_upper_char (int c)
{
return c >= 'A' && c <= 'Z';
}
static inline int
pgtk_is_numeric_char (int c)
{
return c >= '0' && c <= '9';
}
static GSettings *
parse_resource_key (const char *res_key, char *setting_key)
{
char path[32 + RESOURCE_KEY_MAX_LEN];
const char *sp = res_key;
char *dp;
/*
* res_key="emacs.cursorBlink"
* -> path="/org/gnu/emacs/defaults-by-name/emacs/"
* setting_key="cursor-blink"
*
* res_key="Emacs.CursorBlink"
* -> path="/org/gnu/emacs/defaults-by-class/"
* setting_key="cursor-blink"
*
* Returns GSettings* if setting_key exists in schema, otherwise NULL.
*/
/* generate path */
if (pgtk_is_upper_char(*sp)) {
/* First letter is upper case. It should be "Emacs",
* but don't care.
*/
strcpy (path, PATH_FOR_CLASS_TYPE);
while (*sp != '\0') {
if (*sp == '.')
break;
sp++;
}
} else {
strcpy (path, PATH_PREFIX_FOR_NAME_TYPE);
dp = path + strlen (path);
while (*sp != '\0') {
int c = *sp;
if (c == '.')
break;
if (pgtk_is_lower_char (c))
(void) 0; /* lower -> NOP */
else if (pgtk_is_upper_char (c))
c = c - 'A' + 'a'; /* upper -> lower */
else if (pgtk_is_numeric_char (c))
(void) 0; /* numeric -> NOP */
else
return NULL; /* invalid */
*dp++ = c;
sp++;
}
*dp++ = '/'; /* must ends with '/' */
*dp = '\0';
}
if (*sp++ != '.')
return NULL;
/* generate setting_key */
dp = setting_key;
while (*sp != '\0') {
int c = *sp;
if (pgtk_is_lower_char (c))
(void) 0; /* lower -> NOP */
else if (pgtk_is_upper_char (c)) {
c = c - 'A' + 'a'; /* upper -> lower */
if (dp != setting_key)
*dp++ = '-'; /* store '-' unless first char */
} else if (pgtk_is_numeric_char (c))
(void) 0; /* numeric -> NOP */
else
return NULL; /* invalid */
*dp++ = c;
sp++;
}
*dp = '\0';
/* check existence of setting_key */
GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default ();
GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, FALSE);
if (!g_settings_schema_has_key (scm, setting_key)) {
g_settings_schema_unref (scm);
return NULL;
}
/* create GSettings, and return it */
GSettings *gs = g_settings_new_full (scm, NULL, path);
g_settings_schema_unref (scm);
return gs;
}
const char *
pgtk_get_defaults_value (const char *key)
{
char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
error ("resource key too long.");
GSettings *gs = parse_resource_key(key, skey);
if (gs == NULL) {
return NULL;
}
gchar *str = g_settings_get_string (gs, skey);
/* There is no timing to free str.
* So, copy it here and free it.
*
* MEMO: Resource values for emacs shouldn't need such a long string value.
*/
static char holder[128];
strncpy (holder, str, 128);
holder[127] = '\0';
g_object_unref (gs);
g_free (str);
return holder[0] != '\0' ? holder : NULL;
}
static void
pgtk_set_defaults_value (const char *key, const char *value)
{
char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
error ("resource key too long.");
GSettings *gs = parse_resource_key(key, skey);
if (gs == NULL) {
error ("unknown resource key.");
}
if (value != NULL) {
g_settings_set_string (gs, skey, value);
} else {
g_settings_reset (gs, skey);
}
g_object_unref (gs);
}
#undef RESOURCE_KEY_MAX_LEN
#undef SCHEMA_ID
#undef PATH_FOR_CLASS_TYPE
#undef PATH_PREFIX_FOR_NAME_TYPE
#else /* not HAVE_GSETTINGS */
const char *
pgtk_get_defaults_value (const char *key)
{
return NULL;
}
DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 3, 3, 0,
doc: /* Set property NAME of OWNER to VALUE, from the defaults database.
If OWNER is nil, Emacs is assumed.
If VALUE is nil, the default is removed. */)
(Lisp_Object owner, Lisp_Object name, Lisp_Object value)
static void
pgtk_set_defaults_value (const char *key, const char *value)
{
error ("gsettings not supported.");
}
#endif
DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 2, 2, 0,
doc: /* Set the value of ATTRIBUTE, of class CLASS, as VALUE, into defaults database. */)
(Lisp_Object attribute, Lisp_Object value)
{
check_window_system (NULL);
if (NILP (owner))
owner = build_string (pgtk_app_name);
CHECK_STRING (name);
CHECK_STRING (attribute);
if (!NILP (value))
CHECK_STRING (value);
char *res = SSDATA (Vx_resource_name);
char *attr = SSDATA (attribute);
if (attr[0] >= 'A' && attr[0] <= 'Z')
res = SSDATA (Vx_resource_class);
char *key = g_strdup_printf("%s.%s", res, attr);
pgtk_set_defaults_value(key, NILP (value) ? NULL : SSDATA (value));
return Qnil;
}
@ -1794,20 +1982,26 @@ pgtk_set_scroll_bar_default_height (struct frame *f)
const char *
pgtk_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
{
/* remove appname prefix; TODO: allow for !="Emacs" */
const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
check_window_system (NULL);
if (inhibit_x_resources)
/* --quick was passed, so this is a no-op. */
return NULL;
res = pgtk_get_defaults_value (toCheck);
return (char *) (!res ? NULL
: !c_strncasecmp (res, "YES", 3) ? "true"
: !c_strncasecmp (res, "NO", 2) ? "false"
: res);
const char *res = pgtk_get_defaults_value (name);
if (res == NULL)
res = pgtk_get_defaults_value (class);
if (res == NULL)
return NULL;
if (c_strncasecmp (res, "YES", 3) == 0)
return "true";
if (c_strncasecmp (res, "NO", 2) == 0)
return "false";
return res;
}