GTK version

This commit is contained in:
Jan Djärv 2003-01-19 21:50:03 +00:00
parent 3c77dc44b8
commit 488dd4c404
20 changed files with 2350 additions and 564 deletions

View file

@ -1,3 +1,9 @@
2003-01-19 Jan D. <jan.h.d@swipnet.se>
* configure.in: Add --with-gtk, --with-x-toolkit=gtk
* INSTALL (DETAILED BUILDING AND INSTALLATION): Add text about GTK.
2003-01-14 Francesco Potort,Al(B <pot@gnu.org>
* configure.in (m68k-motorola-sysv): Removed (obsolete).

View file

@ -270,7 +270,7 @@ accept a list of directories, separated with colons.
To get more attractive menus, you can specify an X toolkit when you
configure Emacs; use the option `--with-x-toolkit=TOOLKIT', where
TOOLKIT is `athena' or `motif' (`yes' and `lucid' are synonyms for
TOOLKIT is `athena', `motif' or `gtk' (`yes' and `lucid' are synonyms for
`athena'). On some systems, it does not work to use a toolkit with
shared libraries. A free implementation of Motif, called LessTif, is
available ftom <http://www.lesstif.org>. Compiling with LessTif or
@ -280,6 +280,11 @@ bars, even without LessTif/Motif, if you have the Xaw3d library
installed (see "Image support libraries" above for Xaw3d
availability).
If `--with-x-toolkit=gtk' is specified, you can tell configure where
to search for GTK by specifying `--with-pkg-config-prog=PATH' where
PATH is the pathname to pkg-config. Note that GTK version 2.0 or
newer is required for Emacs.
The `--with-gcc' option specifies that the build process should
compile Emacs using GCC. If you don't want to use GCC, specify
`--with-gcc=no'. If you omit this option, `configure' will search

170
configure vendored
View file

@ -309,7 +309,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LN_S CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB INSTALL_INFO EGREP LIBSOUND SET_MAKE ALLOCA liblockfile LIBOBJS NEED_SETGID KMEM_GROUP GETLOADAVG_LIBS version configuration canonical srcdir lispdir locallisppath lisppath x_default_search_path etcdir archlibdir docdir bitmapdir gamedir gameuser c_switch_system c_switch_machine LD_SWITCH_X_SITE LD_SWITCH_X_SITE_AUX C_SWITCH_X_SITE X_TOOLKIT_TYPE machfile opsysfile carbon_appdir LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LN_S CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB INSTALL_INFO EGREP LIBSOUND SET_MAKE PKG_CONFIG GTK_CFLAGS GTK_LIBS ALLOCA liblockfile LIBOBJS NEED_SETGID KMEM_GROUP GETLOADAVG_LIBS version configuration canonical srcdir lispdir locallisppath lisppath x_default_search_path etcdir archlibdir docdir bitmapdir gamedir gameuser c_switch_system c_switch_machine LD_SWITCH_X_SITE LD_SWITCH_X_SITE_AUX C_SWITCH_X_SITE X_TOOLKIT_TYPE machfile opsysfile carbon_appdir LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -866,12 +866,15 @@ Optional Packages:
--with-kerberos5 support Kerberos version 5 authenticated POP
--with-hesiod support Hesiod to get the POP server host
--without-sound don't compile with sound support
--with-x-toolkit=KIT use an X toolkit (KIT = yes/lucid/athena/motif/no)
--with-x-toolkit=KIT use an X toolkit
(KIT = yes/lucid/athena/motif/gtk/no)
--with-xpm use -lXpm for displaying XPM images
--with-jpeg use -ljpeg for displaying JPEG images
--with-tiff use -ltiff for displaying TIFF images
--with-gif use -lungif for displaying GIF images
--with-png use -lpng for displaying PNG images
--with-gtk use GTK (same as --with-x-toolkit=gtk)
--with-pkg-config-prog Path to pkg-config to use for finding GTK
--without-toolkit-scroll-bars
don't use Motif or Xaw3d scroll bars
--without-xim don't use X11 XIM
@ -1402,12 +1405,13 @@ if test "${with_x_toolkit+set}" = set; then
l | lu | luc | luci | lucid ) val=lucid ;;
a | at | ath | athe | athen | athena ) val=athena ;;
m | mo | mot | moti | motif ) val=motif ;;
g | gt | gtk ) val=gtk ;;
* )
{ { echo "$as_me:$LINENO: error: \`--with-x-toolkit=$withval' is invalid\;
this option's value should be \`yes', \`no', \`lucid', \`athena', or \`motif'.
this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif' or \`gtk'.
Currently, \`yes', \`athena' and \`lucid' are synonyms." >&5
echo "$as_me: error: \`--with-x-toolkit=$withval' is invalid\;
this option's value should be \`yes', \`no', \`lucid', \`athena', or \`motif'.
this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif' or \`gtk'.
Currently, \`yes', \`athena' and \`lucid' are synonyms." >&2;}
{ (exit 1); exit 1; }; }
;;
@ -1446,6 +1450,18 @@ if test "${with_png+set}" = set; then
fi;
# Check whether --with-gtk or --without-gtk was given.
if test "${with_gtk+set}" = set; then
withval="$with_gtk"
fi;
# Check whether --with-pkg-config-prog or --without-pkg-config-prog was given.
if test "${with_pkg_config_prog+set}" = set; then
withval="$with_pkg_config_prog"
fi;
# Check whether --with-toolkit-scroll-bars or --without-toolkit-scroll-bars was given.
if test "${with_toolkit_scroll_bars+set}" = set; then
withval="$with_toolkit_scroll_bars"
@ -6800,6 +6816,8 @@ case "${window_system}" in
case "${with_x_toolkit}" in
athena | lucid ) USE_X_TOOLKIT=LUCID ;;
motif ) USE_X_TOOLKIT=MOTIF ;;
gtk ) with_gtk=yes
USE_X_TOOLKIT=none ;;
no ) USE_X_TOOLKIT=none ;;
* ) USE_X_TOOLKIT=maybe ;;
esac
@ -8058,6 +8076,134 @@ echo "${ECHO_T}before 5" >&6
fi
fi
HAVE_GTK=no
if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "gtk"; then
if test "$USE_X_TOOLKIT" != "none"; then
{ { echo "$as_me:$LINENO: error: Conflicting options, --with-gtk is incompatible with --with-x-toolkit=${with_x_toolkit}" >&5
echo "$as_me: error: Conflicting options, --with-gtk is incompatible with --with-x-toolkit=${with_x_toolkit}" >&2;}
{ (exit 1); exit 1; }; };
fi
GLIB_REQUIRED=2.0.1
GTK_REQUIRED=2.0.1
GTK_MODULES="gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED"
if test "X${with_pkg_config_prog}" != X; then
PKG_CONFIG="${with_pkg_config_prog}"
fi
succeeded=no
if test -z "$PKG_CONFIG"; then
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $PKG_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
;;
esac
fi
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
if test -n "$PKG_CONFIG"; then
echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
echo "${ECHO_T}$PKG_CONFIG" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
if test "$PKG_CONFIG" = "no" ; then
echo "*** The pkg-config script could not be found. Make sure it is"
echo "*** in your path, or give the full path to pkg-config with"
echo "*** the PKG_CONFIG environment variable or --with-pkg-config-prog."
echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
else
PKG_CONFIG_MIN_VERSION=0.9.0
if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
echo "$as_me:$LINENO: checking for $GTK_MODULES" >&5
echo $ECHO_N "checking for $GTK_MODULES... $ECHO_C" >&6
if $PKG_CONFIG --exists "$GTK_MODULES" ; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
succeeded=yes
echo "$as_me:$LINENO: checking GTK_CFLAGS" >&5
echo $ECHO_N "checking GTK_CFLAGS... $ECHO_C" >&6
GTK_CFLAGS=`$PKG_CONFIG --cflags "$GTK_MODULES"`
echo "$as_me:$LINENO: result: $GTK_CFLAGS" >&5
echo "${ECHO_T}$GTK_CFLAGS" >&6
echo "$as_me:$LINENO: checking GTK_LIBS" >&5
echo $ECHO_N "checking GTK_LIBS... $ECHO_C" >&6
GTK_LIBS=`$PKG_CONFIG --libs "$GTK_MODULES"`
echo "$as_me:$LINENO: result: $GTK_LIBS" >&5
echo "${ECHO_T}$GTK_LIBS" >&6
else
GTK_CFLAGS=""
GTK_LIBS=""
## If we have a custom action on failure, don't print errors, but
## do set a variable so people can do so.
GTK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$GTK_MODULES"`
echo $GTK_PKG_ERRORS
fi
else
echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
echo "*** See http://www.freedesktop.org/software/pkgconfig"
fi
fi
if test $succeeded = yes; then
:
else
{ { echo "$as_me:$LINENO: error: Library requirements ($GTK_MODULES) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5
echo "$as_me: error: Library requirements ($GTK_MODULES) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;}
{ (exit 1); exit 1; }; }
fi
C_SWITCH_X_SITE="$C_SWITCH_X_SITE $GTK_CFLAGS"
HAVE_GTK=yes
cat >>confdefs.h <<\_ACEOF
#define HAVE_GTK 1
_ACEOF
USE_X_TOOLKIT=none
with_toolkit_scroll_bars=yes
fi
if test x"${USE_X_TOOLKIT}" = xmaybe; then
if test x"${HAVE_X11R5}" = xyes; then
echo "$as_me:$LINENO: checking X11 version 5 with Xaw" >&5
@ -8650,6 +8796,12 @@ _ACEOF
USE_TOOLKIT_SCROLL_BARS=yes
fi
elif test "${HAVE_GTK}" = "yes"; then
cat >>confdefs.h <<\_ACEOF
#define USE_TOOLKIT_SCROLL_BARS 1
_ACEOF
USE_TOOLKIT_SCROLL_BARS=yes
fi
fi
@ -17845,6 +17997,13 @@ fi
#### Report on what we decided to do.
#### Report GTK as a toolkit, even if it doesn't use Xt.
#### It makes printing result more understandable as using GTK sets
#### toolkit_scroll_bars to yes by default.
if test "${HAVE_GTK}" = "yes"; then
USE_X_TOOLKIT=GTK
fi
echo "
Configured for \`${canonical}'.
@ -18566,6 +18725,9 @@ s,@INSTALL_INFO@,$INSTALL_INFO,;t t
s,@EGREP@,$EGREP,;t t
s,@LIBSOUND@,$LIBSOUND,;t t
s,@SET_MAKE@,$SET_MAKE,;t t
s,@PKG_CONFIG@,$PKG_CONFIG,;t t
s,@GTK_CFLAGS@,$GTK_CFLAGS,;t t
s,@GTK_LIBS@,$GTK_LIBS,;t t
s,@ALLOCA@,$ALLOCA,;t t
s,@liblockfile@,$liblockfile,;t t
s,@LIBOBJS@,$LIBOBJS,;t t

View file

@ -77,13 +77,15 @@ dnl This should be the last --with option, because --with-x is
dnl added later on when we find the path of X, and it's best to
dnl keep them together visually.
AC_ARG_WITH(x-toolkit,
[ --with-x-toolkit=KIT use an X toolkit (KIT = yes/lucid/athena/motif/no)],
[ --with-x-toolkit=KIT use an X toolkit
(KIT = yes/lucid/athena/motif/gtk/no)],
[ case "${withval}" in
y | ye | yes ) val=athena ;;
n | no ) val=no ;;
l | lu | luc | luci | lucid ) val=lucid ;;
a | at | ath | athe | athen | athena ) val=athena ;;
m | mo | mot | moti | motif ) val=motif ;;
g | gt | gtk ) val=gtk ;;
dnl These don't currently work.
dnl o | op | ope | open | open- | open-l | open-lo \
dnl | open-loo | open-look ) val=open-look ;;
@ -91,7 +93,7 @@ dnl | open-loo | open-look ) val=open-look ;;
dnl AC_MSG_ERROR([the `--with-x-toolkit' option is supposed to have a value
dnl which is `yes', `no', `lucid', `athena', `motif' or `open-look'.])
AC_MSG_ERROR([`--with-x-toolkit=$withval' is invalid\;
this option's value should be `yes', `no', `lucid', `athena', or `motif'.
this option's value should be `yes', `no', `lucid', `athena', `motif' or `gtk'.
Currently, `yes', `athena' and `lucid' are synonyms.])
;;
esac
@ -107,6 +109,10 @@ AC_ARG_WITH(gif,
[ --with-gif use -lungif for displaying GIF images])
AC_ARG_WITH(png,
[ --with-png use -lpng for displaying PNG images])
AC_ARG_WITH(gtk,
[ --with-gtk use GTK (same as --with-x-toolkit=gtk)])
AC_ARG_WITH(pkg-config-prog,
[ --with-pkg-config-prog Path to pkg-config to use for finding GTK])
AC_ARG_WITH(toolkit-scroll-bars,
[ --without-toolkit-scroll-bars
don't use Motif or Xaw3d scroll bars])
@ -1570,6 +1576,10 @@ case "${window_system}" in
athena | lucid ) USE_X_TOOLKIT=LUCID ;;
motif ) USE_X_TOOLKIT=MOTIF ;;
dnl open-look ) USE_X_TOOLKIT=OPEN_LOOK ;;
gtk ) with_gtk=yes
dnl Dont set this for GTK. A lot of tests below assumes Xt when
dnl USE_X_TOOLKIT is set.
USE_X_TOOLKIT=none ;;
no ) USE_X_TOOLKIT=none ;;
dnl If user did not say whether to use a toolkit,
dnl make this decision later: use the toolkit if we have X11R5 or newer.
@ -1781,6 +1791,89 @@ fail;
fi
fi
dnl This function defintion taken from Gnome 2.0
dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
dnl also defines GSTUFF_PKG_ERRORS on error
AC_DEFUN(PKG_CHECK_MODULES, [
succeeded=no
if test -z "$PKG_CONFIG"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
fi
if test "$PKG_CONFIG" = "no" ; then
echo "*** The pkg-config script could not be found. Make sure it is"
echo "*** in your path, or give the full path to pkg-config with"
echo "*** the PKG_CONFIG environment variable or --with-pkg-config-prog."
echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
else
PKG_CONFIG_MIN_VERSION=0.9.0
if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
AC_MSG_CHECKING(for $2)
if $PKG_CONFIG --exists "$2" ; then
AC_MSG_RESULT(yes)
succeeded=yes
AC_MSG_CHECKING($1_CFLAGS)
$1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
AC_MSG_RESULT($$1_CFLAGS)
AC_MSG_CHECKING($1_LIBS)
$1_LIBS=`$PKG_CONFIG --libs "$2"`
AC_MSG_RESULT($$1_LIBS)
else
$1_CFLAGS=""
$1_LIBS=""
## If we have a custom action on failure, don't print errors, but
## do set a variable so people can do so.
$1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
ifelse([$4], ,echo $$1_PKG_ERRORS,)
fi
AC_SUBST($1_CFLAGS)
AC_SUBST($1_LIBS)
else
echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
echo "*** See http://www.freedesktop.org/software/pkgconfig"
fi
fi
if test $succeeded = yes; then
ifelse([$3], , :, [$3])
else
ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
fi
])
HAVE_GTK=no
if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "gtk"; then
if test "$USE_X_TOOLKIT" != "none"; then
AC_MSG_ERROR([Conflicting options, --with-gtk is incompatible with --with-x-toolkit=${with_x_toolkit}]);
fi
GLIB_REQUIRED=2.0.1
GTK_REQUIRED=2.0.1
GTK_MODULES="gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED"
dnl Check if --with-pkg-config-prog has been given.
if test "X${with_pkg_config_prog}" != X; then
PKG_CONFIG="${with_pkg_config_prog}"
fi
dnl Checks for libraries.
PKG_CHECK_MODULES(GTK, $GTK_MODULES)
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
C_SWITCH_X_SITE="$C_SWITCH_X_SITE $GTK_CFLAGS"
HAVE_GTK=yes
AC_DEFINE(HAVE_GTK, 1, [Define to 1 if using GTK.])
USE_X_TOOLKIT=none
dnl GTK scrollbars resembles toolkit scrollbars alot, so to avoid
dnl a lot if #ifdef:s, say we have toolkit scrollbars.
with_toolkit_scroll_bars=yes
fi
dnl Do not put whitespace before the #include statements below.
dnl Older compilers (eg sunos4 cc) choke on it.
if test x"${USE_X_TOOLKIT}" = xmaybe; then
@ -1903,7 +1996,7 @@ if test "${HAVE_X11}" = "yes"; then
fi
fi
dnl Use toolkit scroll bars if configured for X toolkit and either
dnl Use toolkit scroll bars if configured for GTK or X toolkit and either
dnl using Motif or Xaw3d is available, and unless
dnl --with-toolkit-scroll-bars=no was specified.
@ -1920,6 +2013,9 @@ if test "${with_toolkit_scroll_bars}" != "no"; then
AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
USE_TOOLKIT_SCROLL_BARS=yes
fi
elif test "${HAVE_GTK}" = "yes"; then
AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
USE_TOOLKIT_SCROLL_BARS=yes
fi
fi
@ -2745,6 +2841,13 @@ End:
])dnl
#### Report on what we decided to do.
#### Report GTK as a toolkit, even if it doesn't use Xt.
#### It makes printing result more understandable as using GTK sets
#### toolkit_scroll_bars to yes by default.
if test "${HAVE_GTK}" = "yes"; then
USE_X_TOOLKIT=GTK
fi
echo "
Configured for \`${canonical}'.

View file

@ -1,3 +1,10 @@
2003-01-19 Jan D. <jan.h.d@swipnet.se>
* xresources.texi (GTK resources): New node.
(GTK widget names): New node.
(GTK names in Emacs): New node.
(GTK styles): New node.
2003-01-15 ShengHuo ZHU <zsh@cs.rochester.edu>
* gnus.texi: Do not use `path' in several locations.

View file

@ -1,5 +1,5 @@
@c This is part of the Emacs manual.
@c Copyright (C) 1987,93,94,95,1997,2001 Free Software Foundation, Inc.
@c Copyright (C) 1987,93,94,95,1997,2001,03 Free Software Foundation, Inc.
@c See file emacs.texi for copying conditions.
@node X Resources, Antinews, Command Arguments, Top
@appendix X Options and Resources
@ -18,6 +18,7 @@ describes the X resources that Emacs recognizes and how to use them.
* Face Resources:: X resources for customizing faces.
* Lucid Resources:: X resources for Lucid menus.
* LessTif Resources:: X resources for LessTif and Motif menus.
* GTK resources:: Resources for GTK widgets.
@end menu
@node Resources
@ -520,3 +521,395 @@ The color for the border shadow, on the bottom and the right.
@item topShadowColor
The color for the border shadow, on the top and the left.
@end table
@node GTK resources
@appendixsec GTK resources
@cindex GTK resources and customization
@cindex resource files for GTK
@cindex @file{~/.gtkrc-2.0} file
@cindex @file{~/.emacs.d/gtkrc} file
If the Emacs installed at your site was built to use the GTK widget set,
then the menu bar, scroll bar and the dialogs can be customized with
the standard GTK @file{~/.gtkrc-2.0} file or with the Emacs specific
@file{~/.emacs.d/gtkrc} file; note that these files are only for
customizing specific GTK widget features. To customize Emacs font,
background, faces etc., use the normal X resources, see @ref{Resources}.
In these files you first defines a style and then how to apply that style
to widgets (@pxref{GTK widget names}). Here is an example of how to
change the font for Emacs menus:
@smallexample
# This is a comment.
style "menufont"
@{
font_name = "helvetica bold 14" # This is a Pango font name
@}
widget "*emacs-menuitem*" style "menufont"
@end smallexample
There are some things you can set without using any style or widget name,
which affect GTK as a whole. Most of these are poorly documented, but can
be found in the `Properties' section of the documentation page for
@code{GtkSetting}, in the GTK document references below.
One property of interest is @code{gtk-font-name} which sets the default
font for GTK; you must use Pango font names (@pxref{GTK styles}). A
@file{~/.gtkrc-2.0} file that just sets a default font looks like this:
@smallexample
gtk-font-name = "courier 12"
@end smallexample
If GTK at your site is installed under @var{prefix},
the resource file syntax is fully described in the GTK API
document
@file{@var{prefix}/share/gtk-doc/html/gtk/gtk-resource-files.html}.
@var{prefix} is usually @file{/usr} or @file{/usr/local}.
You can find the same document online at
@uref{http://developer.gnome.org/doc/API/2.0/gtk/gtk-Resource-Files.html}.
@menu
* GTK widget names:: How widgets in GTK are named in general.
* GTK names in Emacs:: GTK widget names in Emacs.
* GTK styles:: What can be customized in a GTK widget.
@end menu
@node GTK widget names
@appendixsubsec GTK widget names
@cindex GTK widget names
Widgets are specified by widget class or by widget name.
The widget class is the type of the widget, for example @code{GtkMenuBar}.
The widget name is the name given to a specific widget within a program.
A widget always have a class but it is not mandatory to give a name to
a widget. Absolute names are sequences of widget names or
widget classes, corresponding to hierarchies of widgets embedded within
other widgets. For example, if a @code{GtkWindow} contains a @code{GtkVBox}
which in turn contains a @code{GtkMenuBar}, the absolute class name
is @code{GtkWindow.GtkVBox.GtkMenuBar}.
@noindent
If the widgets are named ``top'', ``box'' and ``menubar'', the absolute
widget name is @code{top.box.menubar},
When assigning a style to a widget, you can use the absolute class
name or the absolute widget name.
There are two commands: @code{widget_class} will assign a style to
widgets, matching only against the absolute class name.
The command @code{widget} will match the absolute widget name,
but if there is no name for a widget in the hierarchy, the class is matched.
These commands require the absolute name and the style name to be
within double quotes. These commands are written at the top level in a
@file{~/.gtkrc-2.0} file, like this:
@smallexample
style "menufont"
@{
font_name = "helvetica bold 14"
@}
widget "top.box.menubar" style "menufont"
widget_class "GtkWindow.GtkVBox.GtkMenuBar" style "menufont"
@end smallexample
Matching of absolute names is done with shell ``glob'' syntax, that is
@samp{*} matches zero or more characters and @samp{?} matches one character.
So the following would assign @code{base_style} to all widgets:
@smallexample
widget "*" style "base_style"
@end smallexample
Given the absolute class name @code{GtkWindow.GtkVBox.GtkMenuBar}
and the corresponding absolute widget name @code{top.box.menubar},
the following all assign @code{my_style} to the menu bar:
@smallexample
widget_class "GtkWindow.GtkVBox.GtkMenuBar" style "my_style"
widget_class "GtkWindow.*.GtkMenuBar" style "my_style"
widget_class "*GtkMenuBar" style "my_style"
widget "top.box.menubar" style "my_style"
widget "*box*menubar" style "my_style"
widget "*menubar" style "my_style"
widget "*menu*" style "my_style"
@end smallexample
@node GTK names in Emacs
@appendixsubsec GTK names in Emacs
@cindex GTK widget names
@cindex GTK widget classes
In Emacs the top level widget for a frame is a @code{GtkWindow} that
contains a @code{GtkVBox}. The @code{GtkVBox} contains the
@code{GtkMenuBar} and a @code{GtkFixed} widget.
The vertical scroll bars, @code{GtkVScrollbar},
are contained in the @code{GtkFixed} widget.
The text you write in Emacs is drawn in the @code{GtkFixed} widget.
Dialogs in Emacs are @code{GtkDialog} widgets. The file dialog is a
@code{GtkFileSelection} widget.
@noindent
To set a style for the menu bar using the absolute class name, use:
@smallexample
widget_class "GtkWindow.GtkVBox.GtkMenuBar" style "my_style"
@end smallexample
@noindent
For the scroll bar, the absolute class name is:
@smallexample
widget_class
"GtkWindow.GtkVBox.GtkFixed.GtkVScrollbar"
style "my_style"
@end smallexample
@noindent
The names for the emacs widgets, and their classes, are:
@multitable {@code{verticalScrollbar plus}} {@code{GtkFileSelection} and some}
@item @code{emacs-filedialog}
@tab @code{GtkFileSelection}
@item @code{emacs-dialog}
@tab @code{GtkDialog}
@item @code{Emacs}
@tab @code{GtkWindow}
@item @code{pane}
@tab @code{GtkVHbox}
@item @code{emacs}
@tab @code{GtkFixed}
@item @code{menubar}
@tab @code{GtkMenuBar}
@item @code{verticalScrollbar}
@tab @code{GtkVScrollbar}
@item @code{emacs-menuitem}
@tab anything in menus
@end multitable
@noindent
Thus, for Emacs you can write the two examples above as:
@smallexample
widget "Emacs.pane.menubar" style "my_style"
widget "Emacs.pane.emacs.verticalScrollbar" style "my_style"
@end smallexample
GTK absolute names are quite strange when it comes to menus
and dialogs. The names do not start with @samp{Emacs}, as they are
free-standing windows and not contained (in the GTK sense) by the
Emacs GtkWindow. To customize the dialogs and menus, use wildcards like this:
@smallexample
widget "*emacs-dialog*" style "my_dialog_style"
widget "*emacs-filedialog* style "my_file_style"
widget "*emacs-menuitem* style "my_menu_style"
@end smallexample
An alternative is to put customization into @file{~/.emacs.d/gtkrc}.
This file is only read by Emacs, so anything in @file{~/.emacs.d/gtkrc}
affects Emacs but leaves other applications unaffected.
For example, the drop down menu in the file dialog can not
be customized by any absolute widget name, only by an absolute
class name. This is so because the widgets in the drop down menu does not
have names and the menu is not contained in the Emacs GtkWindow.
To have all menus in Emacs look the same, use this in @file{~/.emacs.d/gtkrc}:
@smallexample
widget_class "*Menu*" style "my_menu_style"
@end smallexample
@node GTK styles
@appendixsubsec GTK styles
@cindex GTK styles
In a GTK style you specify the appearance widgets shall have. You
can specify foreground and background color, background pixmap and font.
The edit widget (where you edit the text) in Emacs is a GTK widget,
but trying to specify a style for the edit widget will have no effect.
This is so that Emacs compiled for GTK is compatible with Emacs compiled
for other X toolkits. The settings for foreground, background and font
for the edit widget is taken from the X resources; @pxref{Resources}.
Here is an example of two style declarations, ``default'' and ``ruler'':
@smallexample
pixmap_path "/usr/share/pixmaps:/usr/include/X11/pixmaps"
style "default"
@{
font_name = "helvetica 12"
bg[NORMAL] = @{ 0.83, 0.80, 0.73 @}
bg[SELECTED] = @{ 0.0, 0.55, 0.55 @}
bg[INSENSITIVE] = @{ 0.77, 0.77, 0.66 @}
bg[ACTIVE] = @{ 0.0, 0.55, 0.55 @}
bg[PRELIGHT] = @{ 0.0, 0.55, 0.55 @}
fg[NORMAL] = "black"
fg[SELECTED] = @{ 0.9, 0.9, 0.9 @}
fg[ACTIVE] = "black"
fg[PRELIGHT] = @{ 0.9, 0.9, 0.9 @}
base[INSENSITIVE] = "#777766"
text[INSENSITIVE] = @{ 0.60, 0.65, 0.57 @}
bg_pixmap[NORMAL] = "background.xpm"
bg_pixmap[INSENSITIVE] = "background.xpm"
bg_pixmap[ACTIVE] = "background.xpm"
bg_pixmap[PRELIGHT] = "<none>"
@}
style "ruler" = "default"
@{
font_name = "helvetica 8"
@}
@end smallexample
The style ``ruler'' inherits from ``default''. This way you can build
on existing styles. The syntax for fonts and colors is described below.
As this example shows, it is possible to specify several values
for foreground and background depending on which state the widget has.
The possible states are
@table @code
@item NORMAL
This is the default state for widgets.
@item ACTIVE
This is the state for a widget that is ready to do something. It is
also for the trough of a scroll bar, i.e. @code{bg[ACTIVE] = "red"}
sets the scroll bar trough to red. Buttons that have been pressed but
not released yet (``armed'') are in this state.
@item PRELIGHT
This is the state when widgets that can be manipulated have the mouse
pointer over them. For example when the mouse is over the thumb in the
scroll bar or over a menu item. When the mouse is over a button that
is not pressed, the button is in this state.
@item SELECTED
This is the state when some data has been selected by the user. It can
be selected text or items selected in a list.
There is no place in Emacs where this setting has any effect.
@item INSENSITIVE
This is the state for widgets that are visible, but they can not be
manipulated like they normally can. For example, buttons that can't be
pressed and menu items that can't be selected.
Text for menu items that are not available can be set to yellow with
@code{fg[INSENSITIVE] = "yellow"}.
@end table
Here are the things that can go in a style declaration:
@table @code
@item bg[@var{state}] = @var{color}
This is the background color widgets use. This background is not used for
editable text, use @code{base} for that.
@item base[@var{state}] = @var{color}
This is the background color for editable text.
In Emacs, this color is used for the background of the text fields in the
file dialog.
@item bg_pixmap[@var{state}] = "@var{pixmap}"
You can specify a pixmap to be used instead of the background color.
@var{pixmap} is a file name. GTK can use a number of file formats,
including XPM, XBM, GIF, JPEG and PNG. If you want a widget to use the same
pixmap as its parent, use @samp{<parent>}. If you don't want any
pixmap use @samp{<none>}. Using @samp{<none>} can be useful
if your style inherits a style that does specify a pixmap.
GTK looks for the pixmap in directories specified in @code{pixmap_path}.
It is not possible to refer to a file by its absolute path name.
@code{pixmap_path} is a colon-separated list of directories within double
quotes, specified at the top level in a @file{gtkrc} file (i.e. not inside
a style definition; see example above):
@smallexample
pixmap_path "/usr/share/pixmaps:/usr/include/X11/pixmaps"
@end smallexample
@item fg[@var{state}] = @var{color}
This is the foreground color widgets use. This is the color
of text in menus and buttons. It is also the color for the arrows in the
scroll bar. For editable text, use @code{text}.
@item text[@var{state}] = @var{color}
This is the color for editable text. In Emacs, this color is used for the
text fields in the file dialog.
@item font_name = "@var{font}"
This is the font a widget shall use. @var{font} is a Pango font name,
for example ``Sans Italic 10'', ``Helvetica Bold 12'', ``Courier 14'',
``Times 18''. See below for exact syntax. The names are case insensitive.
@end table
Colors are specified in three ways, a name, a hexadecimal form or
an RGB triplet.
@noindent
A color name is written within double quotes, for example @code{"red"}.
@noindent
A hexadecimal form is written within double quotes. There are four forms,
@code{#rrrrggggbbbb}, @code{#rrrgggbbb},
@code{#rrggbb}, or @code{#rgb}. In each of these r, g and b are hex digits.
@noindent
An RGB triplet looks like @code{@{ r, g, b @}}, where r, g and b are either
integers in the range 0-65535 or floats in the range 0.0-1.0.
Pango font names have the form ``@var{family-list} @var{style-options}
@var{size}''.
@cindex Pango font name
@noindent
@var{family-list} is a comma separated list of font families optionally
terminated by a comma. This way you can specify several families and the
first one found will be used. @var{family} corresponds to the second part in
an X font name, for example in
@smallexample
-adobe-times-medium-r-normal--12-120-75-75-p-64-iso10646-1
@end smallexample
@noindent
the family name is ``times''.
@noindent
@var{style-options} is a whitespace separated list of words where each word
is a style, variant, weight, or stretch. The default value for all of
these is @code{normal}.
@noindent
A `style' corresponds to the fourth part of an X font name. In X font
names it is the character ``r'', ``i'' or ``o''; in Pango font names the
corresponding values are @code{normal}, @code{italic}, or @code{oblique}.
@noindent
A `variant' is either @code{normal} or @code{small-caps}.
Small caps is a font with the lower case characters replaced by
smaller variants of the capital characters.
@noindent
Weight describes the ``boldness'' of a font. It corresponds to the third
part of an X font name. It is one of @code{ultra-light}, @code{light},
@code{normal}, @code{bold}, @code{ultra-bold}, or @code{heavy}.
@noindent
Stretch gives the width of the font relative to other designs within a
family. It corresponds to the fifth part of an X font name. It is one of
@code{ultra-condensed}, @code{extra-condensed}, @code{condensed},
@code{semi-condensed}, @code{normal}, @code{semi-expanded},
@code{expanded}, @code{extra-expanded}, or @code{ultra-expanded}.
@noindent
@var{size} is a decimal number that describes the font size in points.

View file

@ -1,3 +1,113 @@
2003-01-19 Jan D. <jan.h.d@swipnet.se>
* Makefile.in (XOBJ): Add gtkutil.o if USE_GTK
(gtkutil.o): New file.
(TOOLKIT_DEFINES): Set to -DUSE_GTK if HAVE_GTK.
(LIBW): Set to @GTK_LIBS@ if USE_GTK.
* gtkutil.c: New file for GTK version.
* gtkutil.h: New file for GTK version.
* xterm.h: Add xt_or_gtk_widget.
Include gtk files for USE_GTK.
(struct x_output): Add toolbar_height.
(struct x_output): Add GTK widgets and Gdk size_hints.
(GTK_WIDGET_TO_X_WIN, FRAME_GTK_OUTER_WIDGET, FRAME_GTK_WIDGET)
(FRAME_OUTER_WINDOW): New macros for USE_GTK.
(FRAME_OUTER_TO_INNER_DIFF_Y): Add FRAME_TOOLBAR_HEIGHT to calculation.
* xterm.c: Include gtkutil.h for USE_GTK.
Declare extern void free_frame_menubar for USE_GTK.
(note_mouse_highlight): Check popup_activated for USE_GTK.
(xt_action_hook): Don't compile if USE_GTK.
(x_scroll_bar_to_input_event): Use CurrentTime for USE_GTK.
(xg_scroll_callback): New function.
(x_create_toolkit_scroll_bar): Call xg_create_scroll_bar for USE_GTK.
(x_set_toolkit_scroll_bar_thumb): Call xg_set_toolkit_scroll_bar_thumb
for USE_GTK.
(x_scroll_bar_create): Call xg_update_scrollbar_pos and
xg_show_scroll_bar for USE_GTK.
(x_scroll_bar_remove): Call xg_remove_scroll_bar for USE_GTK.
(XTset_vertical_scroll_bar): Call xg_update_scrollbar_pos for USE_GTK.
(event_handler_gdk): New function for USE_GTK.
(handle_one_xevent): Call xg_resize_widgets for USE_GTK.
(handle_one_xevent): Make sure widget is mapped before
calling x_real_positions for USE_GTK.
(XTread_socket): Add GTK event loop for USE_GTK.
(x_set_window_size): Call xg_frame_set_char_size for USE_GTK.
(x_make_frame_visible): Call gtk_widget_show_all for USE_GTK.
(x_make_frame_invisible): Call gtk_widget_hide for USE_GTK.
(x_iconify_frame): Add code for USE_GTK.
(x_free_frame_resources): Call gtk_widget_destroy for USE_GTK.
(x_wm_set_size_hint): Only compile if not USE_GTK. GTK version
is in gtkutil.c.
(x_term_init): Add initialization for GTK.
(syms_of_xterm): Set Vx_toolkit_scroll_bars for USE_GTK.
* xmenu.c: Include gtkutil.h for USE_GTK.
(Fx_popup_menu): Use current position if x and y is NIL.
(single_menu_item, single_menu_item, Fx_popup_dialog): Check
for USE_GTK.
(popup_widget_loop): New function for USE_GTK.
(x_activate_menubar): Add code for USE_GTK.
(popup_activate_callback, popup_deactivate_callback)
(menu_highlight_callback, menubar_selection_callback): USE_GTK versions
added.
(update_frame_menubar): Call xg_update_frame_menubar for USE_GTK.
(set_frame_menubar): Call xg_modify_menubar_widgets for USE_GTK.
(free_frame_menubar): Only compile if not USE_GTK. GTK version
is in gtkutil.c.
(popup_selection_callback): New version for USE_GTK.
(create_and_show_popup_menu): New fuction, one USE_GTK version and
one USE_X_TOOLKIT version.
(xmenu_show): Call create_and_show_popup_menu.
(dialog_selection_callback): New version for USE_GTK.
(create_and_show_dialog): New fuction, one USE_GTK version and
one USE_X_TOOLKIT version.
(xdialog_show): Call create_and_show_dialog.
* xfns.c: Include gtkutil for USE_GTK.
(x_window_to_frame, x_any_window_to_frame)
(x_non_menubar_window_to_frame, x_menubar_window_to_frame)
(x_top_window_to_frame): Add code for USE_GTK.
(x_set_background_color): Call xg_set_background_color for GTK.
(x_set_menu_bar_lines): Check for USE_GTK.
(x_set_tool_bar_lines): Call update_frame_tool_bar for USE_GTK.
(x_set_name, x_set_title): Call gtk_window_set_title for USE_GTK.
(x_window): Call xg_create_frame_widgets for USE_GTK.
(Fx_create_frame): Check for USE_GTK
(Fx_file_dialog): New implementation for USE_GTK.
* xdisp.c: Add check for USE_GTK for extern void set_frame_menubar.
(update_menu_bar): Add check for USE_GTK.
(update_tool_bar): Add check for USE_GTK and external tool bar.
(redisplay_tool_bar): Add check for USE_GTK and external tool bar.
(redisplay_internal): Add check for USE_GTK and popup_activated.
(redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_MENU_BAR.
(redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_TOOL_BAR.
(display_menu_bar): Add check for USE_GTK
* lisp.h: Declare Vx_resource_name extern.
* keyboard.c (kbd_buffer_get_event): Check MENU_BAR_ACTIVATE_EVENT
for USE_GTK.
(make_lispy_event): Check MENU_BAR_EVENT for USE_GTK.
* frame.h (struct frame): Add external_tool_bar. Check for USE_GTK.
(FRAME_EXTERNAL_TOOL_BAR): New macro.
(FRAME_EXTERNAL_MENU_BAR): Check for USE_GTK.
* fileio.c (Fread_file_name): Add check for USE_GTK.
* dispnew.c (adjust_frame_glyphs_for_window_redisplay): Add
check for USE_GTK.
* config.in: Added HAVE_GTK
* alloc.c (Fgarbage_collect): Call xg_mark_data for GTK.
2003-01-18 Stefan Monnier <monnier@cs.yale.edu>
* charset.h (Funibyte_char_to_multibyte): Export.

View file

@ -252,12 +252,19 @@ STARTFILES = START_FILES
#define C_SWITCH_ASM
#endif
#if HAVE_GTK
#define USE_GTK
TOOLKIT_DEFINES = -DUSE_GTK
#endif
#ifdef USE_X_TOOLKIT
#define USE_@X_TOOLKIT_TYPE@
TOOLKIT_DEFINES = -DUSE_@X_TOOLKIT_TYPE@
#else
#ifndef USE_GTK
TOOLKIT_DEFINES =
#endif
#endif
/* DO NOT use -R. There is a special hack described in lastfile.c
which is used instead. Some initialized data areas are modified
@ -300,7 +307,12 @@ ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAG) -I. -I${srcdi
#ifdef HAVE_MENUS
/* Include xmenu.o in the list of X object files. */
#ifdef USE_GTK
XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o gtkutil.o
#else
XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o
#endif
/* The X Menu stuff is present in the X10 distribution, but missing
from X11. If we have X10, just use the installed library;
@ -372,10 +384,17 @@ LIBXT= $(LIBW) LIBXMU -lXt $(LIBXTR6) -lXext
#endif /* not LIBXT_STATIC */
#else /* not USE_X_TOOLKIT */
#ifdef USE_GTK
LIBW=@GTK_LIBS@
OLDXMENU=
LIBXMENU=
#endif /* USE_GTK */
#ifdef HAVE_X_SM
LIBXT=-lSM -lICE
LIBXT=$(LIBW) -lSM -lICE
#else
LIBXT=
LIBXT=$(LIBW)
#endif
#endif /* not USE_X_TOOLKIT */
@ -1150,18 +1169,21 @@ xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h $(config_h)
xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
$(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
charset.h $(config_h)
charset.h gtkutil.h $(config_h)
xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \
msdos.h $(config_h)
gtkutil.h msdos.h $(config_h)
xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \
dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
keyboard.h gnu.h charset.h ccl.h fontset.h composite.h \
coding.h process.h $(config_h)
coding.h process.h gtkutil.h $(config_h)
xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \
charset.h coding.h ccl.h buffer.h atimer.h systime.h $(config_h)
xrdb.o: xrdb.c $(config_h) epaths.h
xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h
gtkutil.o: gtkutil.c gtkutil.h xterm.h lisp.h frame.h $(config_h) \
blockinput.h window.h atimer.h termhooks.h
hftctl.o: hftctl.c $(config_h)
sound.o: sound.c dispextern.h $(config_h)
atimer.o: atimer.c atimer.h systime.h $(config_h)

View file

@ -4266,6 +4266,13 @@ Garbage collection happens automatically if you cons more than
mark_stack ();
#endif
#ifdef USE_GTK
{
extern void xg_mark_data ();
xg_mark_data ();
}
#endif
gc_sweep ();
/* Clear the mark bits that we set in certain root slots. */

View file

@ -205,6 +205,9 @@ Boston, MA 02111-1307, USA. */
/* Define to 1 if you have the `grantpt' function. */
#undef HAVE_GRANTPT
/* Define to 1 if using GTK. */
#undef HAVE_GTK
/* Define to 1 if netdb.h declares h_errno. */
#undef HAVE_H_ERRNO

View file

@ -2371,7 +2371,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
/* Allocate/ reallocate matrices of the dummy window used to display
the menu bar under X when no X toolkit support is available. */
#ifndef USE_X_TOOLKIT
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
{
/* Allocate a dummy window if not already done. */
if (NILP (f->menu_bar_window))
@ -2394,6 +2394,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
}
#endif /* not USE_X_TOOLKIT */
#ifndef USE_GTK
/* Allocate/ reallocate matrices of the tool bar window. If we
don't have a tool bar window yet, make one. */
if (NILP (f->tool_bar_window))
@ -2411,6 +2412,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
allocate_matrices_for_window_redisplay (w);
#endif
}

View file

@ -6116,8 +6116,8 @@ provides a file dialog box. */)
(NILP (predicate) ? Qfile_exists_p : predicate));
GCPRO2 (insdef, default_filename);
#if defined (USE_MOTIF) || defined (HAVE_NTGUI)
#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& have_menus_p ())

View file

@ -215,6 +215,11 @@ struct frame
be used for output. */
unsigned glyphs_initialized_p : 1;
#if defined (USE_GTK)
/* Nonzero means using a tool bar that comes from the toolkit. */
int external_tool_bar;
#endif
/* Margin at the top of the frame. Used to display the tool-bar. */
int tool_bar_lines;
@ -270,7 +275,8 @@ struct frame
/* Number of lines of menu bar. */
int menu_bar_lines;
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
/* Nonzero means using a menu bar that comes from the X toolkit. */
int external_menu_bar;
#endif
@ -457,10 +463,19 @@ typedef struct frame *FRAME_PTR;
These lines are counted in FRAME_HEIGHT. */
#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
/* Nonzero if this frame should display a tool bar
in a way that does not use any text lines. */
#if defined (USE_GTK)
#define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
#else
#define FRAME_EXTERNAL_TOOL_BAR(f) 0
#endif
/* Number of lines of frame F used for the tool-bar. */
#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
/* Lines above the top-most window in frame F. */
#define FRAME_TOP_MARGIN(F) \
@ -468,7 +483,8 @@ typedef struct frame *FRAME_PTR;
/* Nonzero if this frame should display a menu bar
in a way that does not use any text lines. */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
#define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar
#else
#define FRAME_EXTERNAL_MENU_BAR(f) 0

View file

@ -3878,7 +3878,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
XSETBUFFER (obj, current_buffer);
kbd_fetch_ptr = event + 1;
}
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
{
kbd_fetch_ptr = event + 1;
@ -3985,7 +3986,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
{
obj = make_lispy_event (event);
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS) \
|| defined (USE_GTK)
/* If this was a menu selection, then set the flag to inhibit
writing to last_nonmenu_event. Don't do this if the event
we're returning is (menu-bar), though; that indicates the
@ -5048,7 +5050,7 @@ make_lispy_event (event)
pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
&column, &row, NULL, 1);
#ifndef USE_X_TOOLKIT
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* In the non-toolkit version, clicks on the menu bar
are ordinary button events in the event buffer.
Distinguish them, and invoke the menu.
@ -5100,7 +5102,7 @@ make_lispy_event (event)
return Fcons (item, Fcons (position, Qnil));
}
#endif /* not USE_X_TOOLKIT */
#endif /* not USE_X_TOOLKIT && not USE_GTK */
/* Set `window' to the window under frame pixel coordinates
event->x/event->y. */
@ -5589,7 +5591,8 @@ make_lispy_event (event)
}
#endif /* HAVE_MOUSE */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
case MENU_BAR_EVENT:
if (EQ (event->arg, event->frame_or_window))
/* This is the prefix key. We translate this to

View file

@ -3136,6 +3136,7 @@ extern int getloadavg P_ ((double *, int));
extern void syms_of_xfns P_ ((void));
extern void init_xfns P_ ((void));
extern Lisp_Object Vx_resource_name;
extern Lisp_Object Vx_resource_class;
EXFUN (Fxw_display_color_p, 1);
EXFUN (Fx_file_dialog, 4);
#endif /* HAVE_X_WINDOWS */

View file

@ -200,7 +200,8 @@ Boston, MA 02111-1307, USA. */
#define INFINITY 10000000
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
extern void set_frame_menubar P_ ((struct frame *f, int, int));
extern int pending_menu_activation;
#endif
@ -7518,7 +7519,8 @@ update_menu_bar (f, save_match_data)
if (FRAME_WINDOW_P (f)
?
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
FRAME_EXTERNAL_MENU_BAR (f)
#else
FRAME_MENU_BAR_LINES (f) > 0
@ -7569,7 +7571,8 @@ update_menu_bar (f, save_match_data)
FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
/* Redisplay the menu bar in case we changed it. */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
if (FRAME_WINDOW_P (f)
#if defined (MAC_OS)
/* All frames on Mac OS share the same menubar. So only the
@ -7582,11 +7585,11 @@ update_menu_bar (f, save_match_data)
/* On a terminal screen, the menu bar is an ordinary screen
line, and this makes it get updated. */
w->update_mode_line = Qt;
#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
/* In the non-toolkit version, the menu bar is an ordinary screen
line, and this makes it get updated. */
w->update_mode_line = Qt;
#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
unbind_to (count, Qnil);
set_buffer_internal_1 (prev);
@ -7612,8 +7615,14 @@ update_tool_bar (f, save_match_data)
struct frame *f;
int save_match_data;
{
if (WINDOWP (f->tool_bar_window)
&& XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
#ifdef USE_GTK
int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
#else
int do_update = WINDOWP (f->tool_bar_window)
&& XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0;
#endif
if (do_update)
{
Lisp_Object window;
struct window *w;
@ -7991,6 +8000,12 @@ redisplay_tool_bar (f)
struct it it;
struct glyph_row *row;
int change_height_p = 0;
#ifdef USE_GTK
if (FRAME_EXTERNAL_TOOL_BAR(f))
update_frame_tool_bar (f);
return 0;
#endif
/* If frame hasn't a tool-bar window or if it is zero-height, don't
do anything. This means you must start with tool-bar-lines
@ -7998,7 +8013,7 @@ redisplay_tool_bar (f)
can turn off tool-bars by specifying tool-bar-lines zero. */
if (!WINDOWP (f->tool_bar_window)
|| (w = XWINDOW (f->tool_bar_window),
XFASTINT (w->height) == 0))
XFASTINT (w->height) == 0))
return 0;
/* Set up an iterator for the tool-bar window. */
@ -8550,7 +8565,7 @@ redisplay_internal (preserve_echo_area)
return;
}
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (popup_activated ())
return;
#endif
@ -10785,10 +10800,12 @@ redisplay_window (window, just_this_one_p)
&& EQ (FRAME_SELECTED_WINDOW (f), window))
{
int redisplay_menu_p = 0;
int redisplay_tool_bar_p = 0;
if (FRAME_WINDOW_P (f))
{
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
|| defined (USE_GTK)
redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
#else
redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
@ -10801,10 +10818,17 @@ redisplay_window (window, just_this_one_p)
display_menu_bar (w);
#ifdef HAVE_WINDOW_SYSTEM
if (WINDOWP (f->tool_bar_window)
&& (FRAME_TOOL_BAR_LINES (f) > 0
|| auto_resize_tool_bars_p))
redisplay_tool_bar (f);
#ifdef USE_GTK
redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
&& (FRAME_TOOL_BAR_LINES (f) > 0
|| auto_resize_tool_bars_p);
#endif
if (redisplay_tool_bar_p)
redisplay_tool_bar (f);
#endif
}
@ -13535,7 +13559,7 @@ display_menu_bar (w)
if (!NILP (Vwindow_system))
return;
#endif
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (FRAME_X_P (f))
return;
#endif

File diff suppressed because it is too large Load diff

View file

@ -81,7 +81,9 @@ Boston, MA 02111-1307, USA. */
#endif /* USE_LUCID */
#include "../lwlib/lwlib.h"
#else /* not USE_X_TOOLKIT */
#ifndef USE_GTK
#include "../oldXMenu/XMenu.h"
#endif
#endif /* not USE_X_TOOLKIT */
#endif /* HAVE_X_WINDOWS */
@ -116,6 +118,13 @@ static void popup_get_selection ();
/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */
#define HAVE_BOXES 1
#endif /* USE_X_TOOLKIT */
#ifdef USE_GTK
#include "gtkutil.h"
#define HAVE_BOXES 1
extern void set_frame_menubar ();
static Lisp_Object xdialog_show ();
#endif
static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
@ -194,7 +203,7 @@ static int menu_items_submenu_depth;
/* Flag which when set indicates a dialog or menu has been posted by
Xt on behalf of one of the widget sets. */
int popup_activated_flag;
static int popup_activated_flag;
static int next_menubar_widget_id;
@ -593,7 +602,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
}
#endif /* not HAVE_BOXES */
#ifndef USE_X_TOOLKIT
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
if (!NILP(map))
/* Indicate visually that this is a submenu. */
item_string = concat2 (item_string, build_string (" >"));
@ -606,7 +615,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Display a submenu using the toolkit. */
if (! (NILP (map) || NILP (enabled)))
{
@ -771,6 +780,7 @@ cached information about equivalent key sequences. */)
#ifdef HAVE_MENUS
if (! NILP (position))
{
int get_current_pos_p = 0;
check_x ();
/* Decode the first argument: find the window and the coordinates. */
@ -778,6 +788,38 @@ cached information about equivalent key sequences. */)
|| (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
|| EQ (XCAR (position), Qtool_bar))))
{
get_current_pos_p = 1;
}
else
{
tem = Fcar (position);
if (CONSP (tem))
{
window = Fcar (Fcdr (position));
x = Fcar (tem);
y = Fcar (Fcdr (tem));
}
else
{
for_click = 1;
tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
window = Fcar (tem); /* POSN_WINDOW (tem) */
tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
x = Fcar (tem);
y = Fcdr (tem);
}
/* If a click happens in an external tool bar or a detached
tool bar, x and y is NIL. In that case, use the current
mouse position. This happens for the help button in the
tool bar. Ideally popup-menu should pass NIL to
this function, but it doesn't. */
if (NILP (x) && NILP (y))
get_current_pos_p = 1;
}
if (get_current_pos_p)
{
/* Use the mouse's current position. */
FRAME_PTR new_f = SELECTED_FRAME ();
#ifdef HAVE_X_WINDOWS
@ -813,25 +855,6 @@ cached information about equivalent key sequences. */)
XSETFASTINT (y, 0);
}
}
else
{
tem = Fcar (position);
if (CONSP (tem))
{
window = Fcar (Fcdr (position));
x = Fcar (tem);
y = Fcar (Fcdr (tem));
}
else
{
for_click = 1;
tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
window = Fcar (tem); /* POSN_WINDOW (tem) */
tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
x = Fcar (tem);
y = Fcdr (tem);
}
}
CHECK_NUMBER (x);
CHECK_NUMBER (y);
@ -1040,7 +1063,7 @@ on the left of the dialog box and all following items on the right.
but I don't want to make one now. */
CHECK_WINDOW (window);
#ifndef USE_X_TOOLKIT
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Display a menu with these alternatives
in the middle of frame F. */
{
@ -1081,7 +1104,7 @@ on the left of the dialog box and all following items on the right.
#endif
}
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Loop in Xt until the menu pulldown or dialog popup has been
popped down (deactivated). This is used for x-popup-menu
@ -1092,6 +1115,7 @@ on the left of the dialog box and all following items on the right.
NOTE: All calls to popup_get_selection should be protected
with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
#ifdef USE_X_TOOLKIT
static void
popup_get_selection (initial_event, dpyinfo, id, do_timers)
XEvent *initial_event;
@ -1148,6 +1172,24 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
}
}
#endif /* USE_X_TOOLKIT */
#ifdef USE_GTK
/* Loop util popup_activated_flag is set to zero in a callback.
Used for popup menus and dialogs. */
static void
popup_widget_loop ()
{
++popup_activated_flag;
/* Process events in the Gtk event loop until done. */
while (popup_activated_flag)
{
gtk_main_iteration ();
}
}
#endif
/* Activate the menu bar of frame F.
This is called from keyboard.c when it gets the
MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
@ -1169,9 +1211,20 @@ x_activate_menubar (f)
if (!f->output_data.x->saved_menu_event->type)
return;
#ifdef USE_GTK
if (! xg_win_to_widget (f->output_data.x->saved_menu_event->xany.window))
return;
#endif
set_frame_menubar (f, 0, 1);
BLOCK_INPUT;
#ifdef USE_GTK
XPutBackEvent (f->output_data.x->display_info->display,
f->output_data.x->saved_menu_event);
popup_activated_flag = 1;
#else
XtDispatchEvent (f->output_data.x->saved_menu_event);
#endif
UNBLOCK_INPUT;
#ifdef USE_MOTIF
if (f->output_data.x->saved_menu_event->type == ButtonRelease)
@ -1193,6 +1246,7 @@ popup_activated ()
/* This callback is invoked when the user selects a menubar cascade
pushbutton, but before the pulldown menu is posted. */
#ifndef USE_GTK
static void
popup_activate_callback (widget, id, client_data)
Widget widget;
@ -1201,10 +1255,20 @@ popup_activate_callback (widget, id, client_data)
{
popup_activated_flag = 1;
}
#endif
/* This callback is invoked when a dialog or menu is finished being
used and has been unposted. */
#ifdef USE_GTK
static void
popup_deactivate_callback (widget, client_data)
GtkWidget *widget;
gpointer client_data;
{
popup_activated_flag = 0;
}
#else
static void
popup_deactivate_callback (widget, id, client_data)
Widget widget;
@ -1213,27 +1277,20 @@ popup_deactivate_callback (widget, id, client_data)
{
popup_activated_flag = 0;
}
#endif
/* Lwlib callback called when menu items are highlighted/unhighlighted
while moving the mouse over them. WIDGET is the menu bar or menu
popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
the widget_value structure for the menu item, or null in case of
unhighlighting. */
void
menu_highlight_callback (widget, id, call_data)
Widget widget;
LWLIB_ID id;
void *call_data;
/* Function that finds the frame for WIDGET and shows the HELP text
for that widget.
F is the frame if known, or NULL if not known. */
static void
show_help_event (f, widget, help)
FRAME_PTR f;
xt_or_gtk_widget widget;
Lisp_Object help;
{
widget_value *wv = (widget_value *) call_data;
struct frame *f;
Lisp_Object frame, help;
Lisp_Object frame;
help = wv ? wv->help : Qnil;
/* Determine the frame for the help event. */
f = menubar_id_to_frame (id);
if (f)
{
XSETFRAME (frame, f);
@ -1243,7 +1300,7 @@ menu_highlight_callback (widget, id, call_data)
{
/* WIDGET is the popup menu. It's parent is the frame's
widget. See which frame that is. */
Widget frame_widget = XtParent (widget);
xt_or_gtk_widget frame_widget = XtParent (widget);
Lisp_Object tail;
for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
@ -1259,32 +1316,77 @@ menu_highlight_callback (widget, id, call_data)
}
}
/* This callback is called from the menu bar pulldown menu
when the user makes a selection.
Figure out what the user chose
and put the appropriate events into the keyboard buffer. */
/* Callback called when menu items are highlighted/unhighlighted
while moving the mouse over them. WIDGET is the menu bar or menu
popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
the data structure for the menu item, or null in case of
unhighlighting. */
static void
menubar_selection_callback (widget, id, client_data)
#ifdef USE_GTK
void
menu_highlight_callback (widget, call_data)
GtkWidget *widget;
gpointer call_data;
{
xg_menu_item_cb_data *cb_data;
Lisp_Object help;
cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (widget),
XG_ITEM_DATA);
if (! cb_data) return;
help = call_data ? cb_data->help : Qnil;
/* If popup_activated_flag is greater than 1 we are in a popup menu.
Don't show help for them, they won't appear before the
popup is popped down. */
if (popup_activated_flag <= 1)
show_help_event (cb_data->cl_data->f, widget, help);
}
#else
void
menu_highlight_callback (widget, id, call_data)
Widget widget;
LWLIB_ID id;
XtPointer client_data;
void *call_data;
{
struct frame *f;
Lisp_Object help;
widget_value *wv = (widget_value *) call_data;
help = wv ? wv->help : Qnil;
/* Determine the frame for the help event. */
f = menubar_id_to_frame (id);
show_help_event (f, widget, help);
}
#endif
/* Find the menu selection and store it in the keyboard buffer.
F is the frame the menu is on.
MENU_BAR_ITEMS_USED is the length of VECTOR.
VECTOR is an array of menu events for the whole menu.
*/
void
find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
FRAME_PTR f;
int menu_bar_items_used;
Lisp_Object vector;
void *client_data;
{
Lisp_Object prefix, entry;
FRAME_PTR f = menubar_id_to_frame (id);
Lisp_Object vector;
Lisp_Object *subprefix_stack;
int submenu_depth = 0;
int i;
if (!f)
return;
entry = Qnil;
subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * sizeof (Lisp_Object));
vector = f->menu_bar_vector;
subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof (Lisp_Object));
prefix = Qnil;
i = 0;
while (i < f->menu_bar_items_used)
while (i < menu_bar_items_used)
{
if (EQ (XVECTOR (vector)->contents[i], Qnil))
{
@ -1348,6 +1450,59 @@ menubar_selection_callback (widget, id, client_data)
}
}
#ifdef USE_GTK
/* Gtk calls callbacks just because we tell it what item should be
selected in a radio group. If this variable is set to a non-zero
value, we are creating menus and don't want callbacks right now.
*/
static int xg_crazy_callback_abort;
/* This callback is called from the menu bar pulldown menu
when the user makes a selection.
Figure out what the user chose
and put the appropriate events into the keyboard buffer. */
static void
menubar_selection_callback (widget, client_data)
GtkWidget *widget;
gpointer client_data;
{
xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data;
if (xg_crazy_callback_abort)
return;
if (! cb_data || ! cb_data->cl_data || ! cb_data->cl_data->f)
return;
find_and_call_menu_selection (cb_data->cl_data->f,
cb_data->cl_data->menu_bar_items_used,
cb_data->cl_data->menu_bar_vector,
cb_data->call_data);
}
#else /* not USE_GTK */
/* This callback is called from the menu bar pulldown menu
when the user makes a selection.
Figure out what the user chose
and put the appropriate events into the keyboard buffer. */
static void
menubar_selection_callback (widget, id, client_data)
Widget widget;
LWLIB_ID id;
XtPointer client_data;
{
FRAME_PTR f;
f = menubar_id_to_frame (id);
if (!f)
return;
find_and_call_menu_selection (f, f->menu_bar_items_used,
f->menu_bar_vector, client_data);
}
#endif /* not USE_GTK */
/* Allocate a widget_value, blocking input. */
widget_value *
@ -1623,9 +1778,12 @@ static int
update_frame_menubar (f)
FRAME_PTR f;
{
#ifdef USE_GTK
return xg_update_frame_menubar (f);
#else
struct x_output *x = f->output_data.x;
int columns, rows;
if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
return 0;
@ -1657,6 +1815,7 @@ update_frame_menubar (f)
/* Force the pane widget to resize itself with the right values. */
EmacsFrameSetCharSize (x->edit_widget, columns, rows);
UNBLOCK_INPUT;
#endif
return 1;
}
@ -1670,21 +1829,25 @@ set_frame_menubar (f, first_time, deep_p)
int first_time;
int deep_p;
{
Widget menubar_widget = f->output_data.x->menubar_widget;
xt_or_gtk_widget menubar_widget = f->output_data.x->menubar_widget;
#ifdef USE_X_TOOLKIT
LWLIB_ID id;
#endif
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
int i, last_i;
int *submenu_start, *submenu_end;
int *submenu_top_level_items, *submenu_n_panes;
LWLIB_ID id;
XSETFRAME (Vmenu_updating_frame, f);
#ifdef USE_X_TOOLKIT
if (f->output_data.x->id == 0)
f->output_data.x->id = next_menubar_widget_id++;
id = f->output_data.x->id;
#endif
if (! menubar_widget)
deep_p = 1;
else if (pending_menu_activation && !deep_p)
@ -1893,6 +2056,35 @@ set_frame_menubar (f, first_time, deep_p)
BLOCK_INPUT;
#ifdef USE_GTK
xg_crazy_callback_abort = 1;
if (menubar_widget)
{
/* The third arg is DEEP_P, which says to consider the entire
menu trees we supply, rather than just the menu bar item names. */
xg_modify_menubar_widgets (menubar_widget,
f,
first_wv,
deep_p,
G_CALLBACK (menubar_selection_callback),
G_CALLBACK (popup_deactivate_callback),
G_CALLBACK (menu_highlight_callback));
}
else
{
GtkWidget *wvbox = f->output_data.x->vbox_widget;
menubar_widget
= xg_create_widget ("menubar", "menubar", f, first_wv,
G_CALLBACK (menubar_selection_callback),
G_CALLBACK (popup_deactivate_callback),
G_CALLBACK (menu_highlight_callback));
f->output_data.x->menubar_widget = menubar_widget;
}
#else /* not USE_GTK */
if (menubar_widget)
{
/* Disable resizing (done for Motif!) */
@ -1939,10 +2131,15 @@ set_frame_menubar (f, first_time, deep_p)
f->output_data.x->menubar_height = menubar_size;
}
#endif /* not USE_GTK */
free_menubar_widget_value_tree (first_wv);
update_frame_menubar (f);
#ifdef USE_GTK
xg_crazy_callback_abort = 0;
#endif
UNBLOCK_INPUT;
}
@ -1963,8 +2160,10 @@ initialize_frame_menubar (f)
/* Get rid of the menu bar of frame F, and free its storage.
This is used when deleting a frame, and when turning off the menu bar. */
This is used when deleting a frame, and when turning off the menu bar.
For GTK this function is in gtkutil.c. */
#ifndef USE_GTK
void
free_frame_menubar (f)
FRAME_PTR f;
@ -2011,8 +2210,9 @@ free_frame_menubar (f)
UNBLOCK_INPUT;
}
}
#endif /* not USE_GTK */
#endif /* USE_X_TOOLKIT */
#endif /* USE_X_TOOLKIT || USE_GTK */
/* xmenu_show actually displays a menu using the panes and items in menu_items
and returns the value selected from it.
@ -2030,7 +2230,116 @@ free_frame_menubar (f)
ERROR is a place to store an error message string in case of failure.
(We return nil on failure, but the value doesn't actually matter.) */
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* The item selected in the popup menu. */
static Lisp_Object *volatile menu_item_selection;
#ifdef USE_GTK
/* Used when position a popup menu. See menu_position_func and
create_and_show_popup_menu below. */
struct next_popup_x_y
{
int x;
int y;
};
/* The menu position function to use if we are not putting a popup
menu where the pointer is.
MENU is the menu to pop up.
X and Y shall on exit contain x/y where the menu shall pop up.
PUSH_IN is not documented in the GTK manual.
USER_DATA is any data passed in when calling gtk_menu_popup.
Here it points to a struct next_popup_x_y where the coordinates
to store in *X and *Y are.
Here only X and Y are used. */
static void
menu_position_func (menu, x, y, push_in, user_data)
GtkMenu *menu;
gint *x;
gint *y;
gboolean *push_in;
gpointer user_data;
{
*x = ((struct next_popup_x_y*)user_data)->x;
*y = ((struct next_popup_x_y*)user_data)->y;
}
static void
popup_selection_callback (widget, client_data)
GtkWidget *widget;
gpointer client_data;
{
xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data;
if (xg_crazy_callback_abort) return;
if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
}
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
menu pops down.
menu_item_selection will be set to the selection. */
static void
create_and_show_popup_menu (f, first_wv, x, y, for_click)
FRAME_PTR f;
widget_value *first_wv;
int x;
int y;
int for_click;
{
int i;
GtkWidget *menu;
GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */
struct next_popup_x_y popup_x_y;
xg_crazy_callback_abort = 1;
menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
G_CALLBACK (popup_selection_callback),
G_CALLBACK (popup_deactivate_callback),
G_CALLBACK (menu_highlight_callback));
xg_crazy_callback_abort = 0;
for (i = 0; i < 5; i++)
if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
break;
if (! for_click)
{
/* Not invoked by a click. pop up at x/y. */
pos_func = menu_position_func;
/* Adjust coordinates to be root-window-relative. */
x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
popup_x_y.x = x;
popup_x_y.y = y;
}
/* Display the menu. */
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
xg_did_tearoff = 0;
/* Set this to one. popup_widget_loop increases it by one, so it becomes
two. show_help_echo uses this to detect popup menus. */
popup_activated_flag = 1;
/* Process events that apply to the menu. */
popup_widget_loop ();
if (xg_did_tearoff)
xg_keep_popup (menu, xg_did_tearoff);
else
gtk_widget_destroy (menu);
/* Must reset this manually because the button release event is not passed
to Emacs event loop. */
FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
}
#else /* not USE_GTK */
/* We need a unique id for each widget handled by the Lucid Widget
library.
@ -2042,8 +2351,6 @@ free_frame_menubar (f)
next_menubar_widget_id. */
LWLIB_ID widget_id_tick;
static Lisp_Object *volatile menu_item_selection;
static void
popup_selection_callback (widget, id, client_data)
Widget widget;
@ -2053,6 +2360,76 @@ popup_selection_callback (widget, id, client_data)
menu_item_selection = (Lisp_Object *) client_data;
}
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
menu pops down.
menu_item_selection will be set to the selection. */
static void
create_and_show_popup_menu (f, first_wv, x, y, for_click)
FRAME_PTR f;
widget_value *first_wv;
int x;
int y;
int for_click;
{
int i;
Arg av[2];
int ac = 0;
XButtonPressedEvent dummy;
LWLIB_ID menu_id;
Widget menu;
Window child;
menu_id = widget_id_tick++;
menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
f->output_data.x->widget, 1, 0,
popup_selection_callback,
popup_deactivate_callback,
menu_highlight_callback);
dummy.type = ButtonPress;
dummy.serial = 0;
dummy.send_event = 0;
dummy.display = FRAME_X_DISPLAY (f);
dummy.time = CurrentTime;
dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window;
dummy.window = dummy.root;
dummy.subwindow = dummy.root;
dummy.x = x;
dummy.y = y;
/* Adjust coordinates to be root-window-relative. */
x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
dummy.x_root = x;
dummy.y_root = y;
dummy.state = 0;
dummy.button = 0;
for (i = 0; i < 5; i++)
if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
dummy.button = i;
/* Don't allow any geometry request from the user. */
XtSetArg (av[ac], XtNgeometry, 0); ac++;
XtSetValues (menu, av, ac);
/* Display the menu. */
lw_popup_menu (menu, (XEvent *) &dummy);
popup_activated_flag = 1;
/* Process events that apply to the menu. */
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0);
/* fp turned off the following statement and wrote a comment
that it is unnecessary--that the menu has already disappeared.
Nowadays the menu disappears ok, all right, but
we need to delete the widgets or multiple ones will pile up. */
lw_destroy_all_widgets (menu_id);
}
#endif /* not USE_GTK */
static Lisp_Object
xmenu_show (f, x, y, for_click, keymaps, title, error)
FRAME_PTR f;
@ -2064,17 +2441,12 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
char **error;
{
int i;
LWLIB_ID menu_id;
Widget menu;
Arg av[2];
int ac = 0;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
widget_value **submenu_stack
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
Lisp_Object *subprefix_stack
= (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
int submenu_depth = 0;
XButtonPressedEvent dummy;
int first_pane;
@ -2266,70 +2638,14 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
first_wv->contents = wv_title;
}
/* Actually create the menu. */
menu_id = widget_id_tick++;
menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
f->output_data.x->widget, 1, 0,
popup_selection_callback,
popup_deactivate_callback,
menu_highlight_callback);
/* See if whe positions are up to date. Temporary code to be removed
when we are sure positions are always up to date. */
{
int real_x, real_y;
x_real_positions (f, &real_x, &real_y);
if (real_x != f->output_data.x->left_pos ||
real_y != f->output_data.x->top_pos)
abort ();
}
dummy.type = ButtonPress;
dummy.serial = 0;
dummy.send_event = 0;
dummy.display = FRAME_X_DISPLAY (f);
dummy.time = CurrentTime;
dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window;
dummy.window = dummy.root;
dummy.subwindow = dummy.root;
dummy.x = x;
dummy.y = y;
/* Adjust coordinates to be root-window-relative. */
x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
dummy.x_root = x;
dummy.y_root = y;
dummy.state = 0;
dummy.button = 0;
for (i = 0; i < 5; i++)
if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
dummy.button = i;
/* Don't allow any geometry request from the user. */
XtSetArg (av[ac], XtNgeometry, 0); ac++;
XtSetValues (menu, av, ac);
/* Free the widget_value objects we used to specify the contents. */
free_menubar_widget_value_tree (first_wv);
/* No selection has been chosen yet. */
menu_item_selection = 0;
/* Display the menu. */
lw_popup_menu (menu, (XEvent *) &dummy);
popup_activated_flag = 1;
/* Actually create and show the menu until popped down. */
create_and_show_popup_menu (f, first_wv, x, y, for_click);
/* Process events that apply to the menu. */
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0);
/* fp turned off the following statement and wrote a comment
that it is unnecessary--that the menu has already disappeared.
Nowadays the menu disappears ok, all right, but
we need to delete the widgets or multiple ones will pile up. */
lw_destroy_all_widgets (menu_id);
/* Free the widget_value objects we used to specify the contents. */
free_menubar_widget_value_tree (first_wv);
/* Find the selected item, and its pane, to return
the proper value. */
@ -2389,6 +2705,48 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
return Qnil;
}
#ifdef USE_GTK
static void
dialog_selection_callback (widget, client_data)
GtkWidget *widget;
gpointer client_data;
{
/* The EMACS_INT cast avoids a warning. There's no problem
as long as pointers have enough bits to hold small integers. */
if ((int) (EMACS_INT) client_data != -1)
menu_item_selection = (Lisp_Object *) client_data;
popup_activated_flag = 0;
}
/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
dialog pops down.
menu_item_selection will be set to the selection. */
static void
create_and_show_dialog (f, first_wv)
FRAME_PTR f;
widget_value *first_wv;
{
GtkWidget *menu;
menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
G_CALLBACK (dialog_selection_callback),
G_CALLBACK (popup_deactivate_callback),
0);
if (menu)
{
/* Display the menu. */
gtk_widget_show_all (menu);
/* Process events that apply to the menu. */
popup_widget_loop ();
gtk_widget_destroy (menu);
}
}
#else /* not USE_GTK */
static void
dialog_selection_callback (widget, id, client_data)
Widget widget;
@ -2399,12 +2757,14 @@ dialog_selection_callback (widget, id, client_data)
as long as pointers have enough bits to hold small integers. */
if ((int) (EMACS_INT) client_data != -1)
menu_item_selection = (Lisp_Object *) client_data;
BLOCK_INPUT;
lw_destroy_all_widgets (id);
UNBLOCK_INPUT;
popup_activated_flag = 0;
}
/* ARG is the LWLIB ID of the dialog box, represented
as a Lisp object as (HIGHPART . LOWPART). */
@ -2421,6 +2781,46 @@ xdialog_show_unwind (arg)
return Qnil;
}
/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
dialog pops down.
menu_item_selection will be set to the selection. */
static void
create_and_show_dialog (f, first_wv)
FRAME_PTR f;
widget_value *first_wv;
{
LWLIB_ID dialog_id;
dialog_id = widget_id_tick++;
lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
f->output_data.x->widget, 1, 0,
dialog_selection_callback, 0, 0);
lw_modify_all_widgets (dialog_id, first_wv->contents, True);
/* Display the dialog box. */
lw_pop_up_all_widgets (dialog_id);
popup_activated_flag = 1;
/* Process events that apply to the dialog box.
Also handle timers. */
{
int count = SPECPDL_INDEX ();
int fact = 4 * sizeof (LWLIB_ID);
/* xdialog_show_unwind is responsible for popping the dialog box down. */
record_unwind_protect (xdialog_show_unwind,
Fcons (make_number (dialog_id >> (fact)),
make_number (dialog_id & ~(-1 << (fact)))));
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
unbind_to (count, Qnil);
}
}
#endif /* not USE_GTK */
static char * button_names [] = {
"button1", "button2", "button3", "button4", "button5",
"button6", "button7", "button8", "button9", "button10" };
@ -2433,7 +2833,6 @@ xdialog_show (f, keymaps, title, error)
char **error;
{
int i, nb_buttons=0;
LWLIB_ID dialog_id;
char dialog_name[6];
widget_value *wv, *first_wv = 0, *prev_wv = 0;
@ -2543,38 +2942,17 @@ xdialog_show (f, keymaps, title, error)
first_wv = wv;
}
/* Actually create the dialog. */
dialog_id = widget_id_tick++;
lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
f->output_data.x->widget, 1, 0,
dialog_selection_callback, 0, 0);
lw_modify_all_widgets (dialog_id, first_wv->contents, True);
/* Free the widget_value objects we used to specify the contents. */
free_menubar_widget_value_tree (first_wv);
/* No selection has been chosen yet. */
menu_item_selection = 0;
/* Display the dialog box. */
lw_pop_up_all_widgets (dialog_id);
popup_activated_flag = 1;
/* Actually create and show the dialog. */
create_and_show_dialog (f, first_wv);
/* Process events that apply to the dialog box.
Also handle timers. */
{
int count = SPECPDL_INDEX ();
/* xdialog_show_unwind is responsible for popping the dialog box down. */
record_unwind_protect (xdialog_show_unwind,
Fcons (make_number (dialog_id >> (4 * sizeof (LWLIB_ID))),
make_number (dialog_id & ~(-1 << (4 * sizeof (LWLIB_ID))))));
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
unbind_to (count, Qnil);
}
/* Find the selected item and pane, and return the corresponding value. */
/* Free the widget_value objects we used to specify the contents. */
free_menubar_widget_value_tree (first_wv);
/* Find the selected item, and its pane, to return
the proper value. */
if (menu_item_selection != 0)
{
Lisp_Object prefix;
@ -2619,7 +2997,7 @@ xdialog_show (f, keymaps, title, error)
return Qnil;
}
#else /* not USE_X_TOOLKIT */
#else /* not USE_X_TOOLKIT && not USE_GTK */
/* The frame of the last activated non-toolkit menu bar.
Used to generate menu help events. */

View file

@ -97,17 +97,23 @@ Boston, MA 02111-1307, USA. */
#include <unistd.h>
#endif
#ifdef USE_GTK
#include "gtkutil.h"
#endif
#ifdef USE_LUCID
extern int xlwmenu_window_p P_ ((Widget w, Window window));
extern void xlwmenu_redisplay P_ ((Widget));
#endif
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
extern void free_frame_menubar P_ ((struct frame *));
extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *,
int));
#endif
#ifdef USE_X_TOOLKIT
#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
#define HACK_EDITRES
extern void _XEditResCheckMessages ();
@ -138,7 +144,7 @@ extern void _XEditResCheckMessages ();
#endif /* USE_X_TOOLKIT */
#ifndef USE_X_TOOLKIT
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
#define x_any_window_to_frame x_window_to_frame
#define x_top_window_to_frame x_window_to_frame
#endif
@ -520,6 +526,12 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
unsigned long *));
static void x_check_fullscreen P_ ((struct frame *));
static void x_check_fullscreen_move P_ ((struct frame *));
static int handle_one_xevent P_ ((struct x_display_info *,
XEvent *,
struct input_event **,
int *,
int *));
/* Flush display of frame F, or of all frames if F is null. */
@ -4330,6 +4342,7 @@ x_draw_image_glyph_string (s)
height = s->height - 2 * box_line_vwidth;
/* Fill background with face under the image. Do it only if row is
taller than image or if image has a clip mask to reduce
flickering. */
@ -7074,7 +7087,7 @@ note_mouse_highlight (f, x, y)
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (popup_activated ())
return;
#endif
@ -8399,7 +8412,7 @@ static void
x_process_timeouts (timer)
struct atimer *timer;
{
if (toolkit_scroll_bar_interaction || popup_activated_flag)
if (toolkit_scroll_bar_interaction || popup_activated ())
{
BLOCK_INPUT;
while (XtAppPending (Xt_app_con) & XtIMTimer)
@ -8494,10 +8507,6 @@ static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
int, int, int));
/* Id of action hook installed for scroll bars. */
static XtActionHookId action_hook_id;
/* Lisp window being scrolled. Set when starting to interact with
a toolkit scroll bar, reset to nil when ending the interaction. */
@ -8510,6 +8519,11 @@ static int last_scroll_bar_part;
/* Whether this is an Xaw with arrow-scrollbars. This should imply
that movements of 1/20 of the screen size are mapped to up/down. */
#ifndef USE_GTK
/* Id of action hook installed for scroll bars. */
static XtActionHookId action_hook_id;
static Boolean xaw3d_arrow_scroll;
/* Whether the drag scrolling maintains the mouse at the top of the
@ -8562,6 +8576,7 @@ xt_action_hook (widget, client_data, action_name, event, params,
toolkit_scroll_bar_interaction = 0;
}
}
#endif /* not USE_GTK */
/* A vector of windows used for communication between
x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
@ -8655,7 +8670,11 @@ x_scroll_bar_to_input_event (event, ievent)
ievent->kind = SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
#ifdef USE_GTK
ievent->timestamp = CurrentTime;
#else
ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
#endif
ievent->part = ev->data.l[1];
ievent->code = ev->data.l[2];
ievent->x = make_number ((int) ev->data.l[3]);
@ -8749,8 +8768,80 @@ xm_scroll_callback (widget, client_data, call_data)
}
#else /* !USE_MOTIF, i.e. Xaw. */
#else /* !USE_MOTIF, i.e. Xaw or GTK */
#ifdef USE_GTK
/* Scroll bar callback for Gtk scroll bars. WIDGET is the scroll
bar adjustment widget. DATA is a pointer to the scroll_bar structure. */
static void
xg_scroll_callback (widget, data)
GtkWidget *widget;
gpointer data;
{
struct scroll_bar *bar = (struct scroll_bar *) data;
gdouble previous;
gdouble position;
gdouble *p;
int diff;
int part = -1, whole = 0, portion = 0;
GtkAdjustment *adj = GTK_ADJUSTMENT (widget);
if (xg_ignore_gtk_scrollbar) return;
position = gtk_adjustment_get_value (adj);
p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
if (! p)
{
p = (gdouble*) xmalloc (sizeof (gdouble));
*p = XG_SB_MIN;
g_object_set_data (G_OBJECT (widget), XG_LAST_SB_DATA, p);
}
previous = *p;
*p = position;
diff = (int) (position - previous);
if (diff == (int) adj->step_increment)
{
part = scroll_bar_down_arrow;
bar->dragging = Qnil;
}
else if (-diff == (int) adj->step_increment)
{
part = scroll_bar_up_arrow;
bar->dragging = Qnil;
}
else if (diff == (int) adj->page_increment)
{
part = scroll_bar_below_handle;
bar->dragging = Qnil;
}
else if (-diff == (int) adj->page_increment)
{
part = scroll_bar_above_handle;
bar->dragging = Qnil;
}
else
{
part = scroll_bar_handle;
whole = adj->upper - adj->page_size;
portion = min (position, whole);
bar->dragging = make_number (portion);
}
if (part >= 0)
{
xg_ignore_next_thumb = 1;
window_being_scrolled = bar->window;
last_scroll_bar_part = part;
x_send_scroll_bar_event (bar->window, part, portion, whole);
}
}
#else /* not USE_GTK */
/* Xaw scroll bar callback. Invoked when the thumb is dragged.
WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
@ -8833,13 +8924,30 @@ xaw_scroll_callback (widget, client_data, call_data)
x_send_scroll_bar_event (bar->window, part, position, height);
}
#endif /* not USE_GTK */
#endif /* not USE_MOTIF */
#define SCROLL_BAR_NAME "verticalScrollBar"
/* Create the widget for scroll bar BAR on frame F. Record the widget
and X window of the scroll bar in BAR. */
#ifdef USE_GTK
static void
x_create_toolkit_scroll_bar (f, bar)
struct frame *f;
struct scroll_bar *bar;
{
char *scroll_bar_name = SCROLL_BAR_NAME;
BLOCK_INPUT;
xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
scroll_bar_name);
UNBLOCK_INPUT;
}
#else /* not USE_GTK */
static void
x_create_toolkit_scroll_bar (f, bar)
struct frame *f;
@ -8849,7 +8957,7 @@ x_create_toolkit_scroll_bar (f, bar)
Widget widget;
Arg av[20];
int ac = 0;
char *scroll_bar_name = "verticalScrollBar";
char *scroll_bar_name = SCROLL_BAR_NAME;
unsigned long pixel;
BLOCK_INPUT;
@ -9022,11 +9130,22 @@ x_create_toolkit_scroll_bar (f, bar)
UNBLOCK_INPUT;
}
#endif /* not USE_GTK */
/* Set the thumb size and position of scroll bar BAR. We are currently
displaying PORTION out of a whole WHOLE, and our position POSITION. */
#ifdef USE_GTK
static void
x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
struct scroll_bar *bar;
int portion, position, whole;
{
xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
}
#else /* not USE_GTK */
static void
x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
struct scroll_bar *bar;
@ -9149,6 +9268,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
UNBLOCK_INPUT;
}
#endif /* not USE_GTK */
#endif /* USE_TOOLKIT_SCROLL_BARS */
@ -9237,6 +9357,15 @@ x_scroll_bar_create (w, top, left, width, height)
/* Map the window/widget. */
#ifdef USE_TOOLKIT_SCROLL_BARS
{
#ifdef USE_GTK
xg_update_scrollbar_pos (f,
SCROLL_BAR_X_WINDOW (bar),
top,
left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1));
xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
#else /* not USE_GTK */
Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
XtConfigureWidget (scroll_bar,
left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
@ -9244,6 +9373,7 @@ x_scroll_bar_create (w, top, left, width, height)
width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1), 0);
XtMapWidget (scroll_bar);
#endif /* not USE_GTK */
}
#else /* not USE_TOOLKIT_SCROLL_BARS */
XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
@ -9378,7 +9508,11 @@ x_scroll_bar_remove (bar)
BLOCK_INPUT;
#ifdef USE_TOOLKIT_SCROLL_BARS
#ifdef USE_GTK
xg_remove_scroll_bar (f, SCROLL_BAR_X_WINDOW (bar));
#else /* not USE_GTK */
XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
#endif /* not USE_GTK */
#else
XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
#endif
@ -9472,20 +9606,30 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
#ifdef USE_TOOLKIT_SCROLL_BARS
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
if (width > 0 && height > 0)
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
left, top, width, height, False);
#ifdef USE_GTK
if (mask)
xg_update_scrollbar_pos (f,
SCROLL_BAR_X_WINDOW (bar),
top,
sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1));
#else /* not USE_GTK */
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
if (width > 0 && height > 0)
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
left, top, width, height, False);
/* Move/size the scroll bar widget. */
if (mask)
XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
top,
sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1), 0);
XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
top,
sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1), 0);
#endif /* not USE_GTK */
#else /* not USE_TOOLKIT_SCROLL_BARS */
/* Clear areas not covered by the scroll bar because of
@ -10070,6 +10214,41 @@ enum
X_EVENT_DROP
};
#ifdef USE_GTK
static struct x_display_info *current_dpyinfo;
static struct input_event **current_bufp;
static int *current_numcharsp;
static int current_count;
static int current_finish;
/* This is the filter function invoked by the GTK event loop.
It is invoked before the XEvent is translated to a GdkEvent,
so we have a chanse to act on the event before GTK. */
static GdkFilterReturn
event_handler_gdk (gxev, ev, data)
GdkXEvent *gxev;
GdkEvent *ev;
gpointer data;
{
XEvent *xev = (XEvent*)gxev;
if (current_numcharsp)
current_count += handle_one_xevent (current_dpyinfo,
xev,
current_bufp,
current_numcharsp,
&current_finish);
else
x_dispatch_event (xev, GDK_DISPLAY ());
if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
return GDK_FILTER_REMOVE;
return GDK_FILTER_CONTINUE;
}
#endif /* USE_GTK */
/* Handles the XEvent EVENT on display DPYINFO.
*FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@ -10079,7 +10258,7 @@ enum
Events representing keys are stored in buffer *BUFP_R,
which can hold up to *NUMCHARSP characters.
We return the number of characters stored into the buffer. */
static int
handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
struct x_display_info *dpyinfo;
@ -10097,7 +10276,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
XEvent event = *eventp;
*finish = X_EVENT_NORMAL;
switch (event.type)
{
case ClientMessage:
@ -10514,8 +10693,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
case KeyPress:
/* Dispatch KeyPress events when in menu. */
if (popup_activated_flag)
if (popup_activated ())
goto OTHER;
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
@ -11080,6 +11260,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
if (f)
{
#ifndef USE_X_TOOLKIT
#ifdef USE_GTK
xg_resize_widgets (f, event.xconfigure.width,
event.xconfigure.height);
#else /* not USE_GTK */
/* If there is a pending resize for fullscreen, don't
do this one, the right one will come later.
The toolkit version doesn't seem to need this, but we
@ -11108,20 +11292,31 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
#endif /* not USE_GTK */
#endif
f->output_data.x->pixel_width = event.xconfigure.width;
f->output_data.x->pixel_height = event.xconfigure.height;
#ifdef USE_GTK
/* GTK creates windows but doesn't map them.
Only get real positions and check fullscreen when mapped. */
if (FRAME_GTK_OUTER_WIDGET (f)
&& GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
{
#endif
/* What we have now is the position of Emacs's own window.
Convert that to the position of the window manager window. */
x_real_positions (f, &f->output_data.x->left_pos,
&f->output_data.x->top_pos);
x_check_fullscreen_move(f);
x_check_fullscreen_move (f);
if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
f->output_data.x->want_fullscreen &=
~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
#ifdef USE_GTK
}
#endif
#ifdef HAVE_X_I18N
if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
xic_set_statusarea (f);
@ -11137,8 +11332,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
}
goto OTHER;
case ButtonPress:
case ButtonRelease:
case ButtonPress:
{
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
@ -11179,7 +11374,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
if (!tool_bar_p)
if (!dpyinfo->x_focus_frame
|| f == dpyinfo->x_focus_frame)
construct_mouse_click (&emacs_event, &event, f);
{
if (! popup_activated ())
construct_mouse_click (&emacs_event, &event, f);
}
}
else
{
@ -11207,9 +11405,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
last_tool_bar_item = -1;
}
else
{
dpyinfo->grabbed &= ~(1 << event.xbutton.button);
}
dpyinfo->grabbed &= ~(1 << event.xbutton.button);
if (numchars >= 1 && emacs_event.kind != NO_EVENT)
{
@ -11219,14 +11415,19 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
numchars--;
}
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
/* For a down-event in the menu bar,
don't pass it to Xt right now.
Instead, save it away
and we will pass it to Xt from kbd_buffer_get_event.
That way, we can run some Lisp code first. */
if (f && event.type == ButtonPress
if (
#ifdef USE_GTK
! popup_activated ()
&&
#endif
f && event.type == ButtonPress
/* Verify the event is really within the menu bar
and not just sent to it due to grabbing. */
&& event.xbutton.x >= 0
@ -11237,6 +11438,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
{
SET_SAVED_BUTTON_EVENT;
XSETFRAME (last_mouse_press_frame, f);
#ifdef USE_GTK
*finish = X_EVENT_DROP;
#endif
}
else if (event.type == ButtonPress)
{
@ -11260,7 +11464,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
#endif /* USE_MOTIF */
else
goto OTHER;
#endif /* USE_X_TOOLKIT */
#endif /* USE_X_TOOLKIT || USE_GTK */
}
break;
@ -11297,7 +11501,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
}
goto ret;
out:
*finish = X_EVENT_GOTO_OUT;
@ -11427,6 +11631,31 @@ XTread_socket (sd, bufp, numchars, expected)
UNBLOCK_INPUT;
#endif
#ifdef USE_GTK
/* For GTK we must use the GTK event loop. But XEvents gets passed
to our filter function above, and then to the big event switch.
We use a bunch of globals to communicate with our filter function,
that is kind of ugly, but it works. */
current_dpyinfo = dpyinfo;
while (gtk_events_pending ())
{
static int nr = 0;
current_count = count;
current_numcharsp = &numchars;
current_bufp = &bufp;
gtk_main_iteration ();
count = current_count;
current_bufp = 0;
current_numcharsp = 0;
if (current_finish == X_EVENT_GOTO_OUT)
goto out;
}
#else /* not USE_GTK */
while (XPending (dpyinfo->display))
{
int finish;
@ -11457,6 +11686,7 @@ XTread_socket (sd, bufp, numchars, expected)
if (finish == X_EVENT_GOTO_OUT)
goto out;
}
#endif /* USE_GTK */
}
out:;
@ -12922,11 +13152,7 @@ x_calc_absolute_position (f)
if (! ((flags & XNegative) || (flags & YNegative)))
return;
#ifdef USE_X_TOOLKIT
this_window = XtWindow (f->output_data.x->widget);
#else
this_window = FRAME_X_WINDOW (f);
#endif
this_window = FRAME_OUTER_WINDOW (f);
/* Find the position of the outside upper-left corner of
the inner window, with respect to the outer window.
@ -13057,13 +13283,8 @@ x_set_offset (f, xoff, yoff, change_gravity)
}
#endif
#ifdef USE_X_TOOLKIT
XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
modified_left, modified_top);
#else /* not USE_X_TOOLKIT */
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
modified_left, modified_top);
#endif /* not USE_X_TOOLKIT */
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
modified_left, modified_top);
UNBLOCK_INPUT;
}
@ -13249,7 +13470,12 @@ x_set_window_size (f, change_gravity, cols, rows)
{
BLOCK_INPUT;
#ifdef USE_X_TOOLKIT
#ifdef USE_GTK
if (FRAME_GTK_WIDGET (f))
xg_frame_set_char_size (f, cols, rows);
else
x_set_window_size_1 (f, change_gravity, cols, rows);
#elif USE_X_TOOLKIT
if (f->output_data.x->widget != NULL)
{
@ -13445,7 +13671,11 @@ x_make_frame_visible (f)
/* This was XtPopup, but that did nothing for an iconified frame. */
XtMapWidget (f->output_data.x->widget);
#else /* not USE_X_TOOLKIT */
#ifdef USE_GTK
gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
#else
XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* not USE_GTK */
#endif /* not USE_X_TOOLKIT */
#if 0 /* This seems to bring back scroll bars in the wrong places
if the window configuration has changed. They seem
@ -13596,6 +13826,14 @@ x_make_frame_invisible (f)
by hand again (they have already done that once for this window.) */
x_wm_set_size_hint (f, (long) 0, 1);
#ifdef USE_GTK
if (FRAME_GTK_OUTER_WIDGET (f))
{
gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
goto out;
}
#endif
#ifdef HAVE_X11R4
if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
@ -13630,6 +13868,7 @@ x_make_frame_invisible (f)
XUnmapWindow (FRAME_X_DISPLAY (f), window);
#endif /* ! defined (HAVE_X11R4) */
out:
/* We can't distinguish this from iconification
just by the event that we get from the server.
So we can't win using the usual strategy of letting
@ -13669,6 +13908,22 @@ x_iconify_frame (f)
if (!NILP (type))
x_bitmap_icon (f, type);
#ifdef USE_GTK
if (FRAME_GTK_OUTER_WIDGET (f))
{
if (! FRAME_VISIBLE_P (f))
gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
f->iconified = 1;
f->visible = 1;
f->async_iconified = 1;
f->async_visible = 0;
UNBLOCK_INPUT;
return;
}
#endif
#ifdef USE_X_TOOLKIT
if (! FRAME_VISIBLE_P (f))
@ -13803,6 +14058,18 @@ x_free_frame_resources (f)
free_frame_menubar (f);
#else /* !USE_X_TOOLKIT */
#ifdef USE_GTK
/* In the GTK version, tooltips are normal X
frames. We must check and free both types. */
if (FRAME_GTK_OUTER_WIDGET (f))
{
gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow below */
FRAME_GTK_OUTER_WIDGET (f) = 0;
}
#endif /* USE_GTK */
if (FRAME_X_WINDOW (f))
XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* !USE_X_TOOLKIT */
@ -13888,8 +14155,10 @@ x_destroy_window (f)
FLAGS is the flags word to use--or 0 meaning preserve the flags
that the window now has.
If USER_POSITION is nonzero, we set the USPosition
flag (this is useful when FLAGS is 0). */
flag (this is useful when FLAGS is 0).
The GTK version is in gtkutils.c */
#ifndef USE_GTK
void
x_wm_set_size_hint (f, flags, user_position)
struct frame *f;
@ -13902,10 +14171,9 @@ x_wm_set_size_hint (f, flags, user_position)
Arg al[2];
int ac = 0;
Dimension widget_width, widget_height;
Window window = XtWindow (f->output_data.x->widget);
#else /* not USE_X_TOOLKIT */
Window window = FRAME_X_WINDOW (f);
#endif /* not USE_X_TOOLKIT */
#endif
Window window = FRAME_OUTER_WINDOW (f);
/* Setting PMaxSize caused various problems. */
size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
@ -14032,6 +14300,7 @@ x_wm_set_size_hint (f, flags, user_position)
XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
#endif
}
#endif /* not USE_GTK */
/* Used for IconicState or NormalState */
@ -14063,7 +14332,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
Pixmap icon_pixmap;
#ifndef USE_X_TOOLKIT
Window window = FRAME_X_WINDOW (f);
Window window = FRAME_OUTER_WINDOW (f);
#endif
if (pixmap_id > 0)
@ -14864,6 +15133,67 @@ x_term_init (display_name, xrm_option, resource_name)
x_initialized = 1;
}
#ifdef USE_GTK
{
#define NUM_ARGV 10
int argc;
char *argv[NUM_ARGV];
char **argv2 = argv;
GdkAtom atom;
/* GTK 2.0 can only handle one display, GTK 2.2 can handle more
than one, but this remains to be implemented. */
if (x_initialized > 1)
return 0;
x_initialized++;
for (argc = 0; argc < NUM_ARGV; ++argc)
argv[argc] = 0;
argc = 0;
argv[argc++] = initial_argv[0];
if (! NILP (display_name))
{
argv[argc++] = "--display";
argv[argc++] = SDATA (display_name);
}
argv[argc++] = "--name";
argv[argc++] = resource_name;
gtk_init (&argc, &argv2);
/* gtk_init does set_locale. We must fix locale after calling it. */
fixup_locale ();
xg_initialize ();
dpy = GDK_DISPLAY ();
/* NULL window -> events for all windows go to our function */
gdk_window_add_filter (NULL, event_handler_gdk, NULL);
/* Load our own gtkrc if it exists. */
{
struct gcpro gcpro1, gcpro2;
char *file = "~/.emacs.d/gtkrc";
Lisp_Object s, abs_file;
GCPRO2 (str, abs_file);
s = make_string (file, strlen (file));
abs_file = Fexpand_file_name(s, Qnil);
if (! NILP (abs_file) && Ffile_readable_p (abs_file))
gtk_rc_parse (SDATA (abs_file));
UNGCPRO;
}
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_quitter);
}
#else /* not USE_GTK */
#ifdef USE_X_TOOLKIT
/* weiner@footloose.sps.mot.com reports that this causes
errors with X11R5:
@ -14904,6 +15234,7 @@ x_term_init (display_name, xrm_option, resource_name)
#endif
dpy = XOpenDisplay (SDATA (display_name));
#endif /* not USE_X_TOOLKIT */
#endif /* not USE_GTK*/
/* Detect failure. */
if (dpy == 0)
@ -15363,8 +15694,10 @@ x_initialize ()
#endif
#ifdef USE_TOOLKIT_SCROLL_BARS
#ifndef USE_GTK
xaw3d_arrow_scroll = False;
xaw3d_pick_top = True;
#endif
#endif
/* Note that there is no real way portable across R3/R4 to get the
@ -15445,6 +15778,8 @@ Otherwise, value is a symbol describing the X toolkit. */);
Vx_toolkit_scroll_bars = intern ("motif");
#elif defined HAVE_XAW3D
Vx_toolkit_scroll_bars = intern ("xaw3d");
#elif USE_GTK
Vx_toolkit_scroll_bars = intern ("gtk");
#else
Vx_toolkit_scroll_bars = intern ("xaw");
#endif

View file

@ -33,6 +33,18 @@ Boston, MA 02111-1307, USA. */
window inside a widget instead of one
that Xt creates... */
#include <X11/StringDefs.h>
typedef Widget xt_or_gtk_widget;
#endif
#ifdef USE_GTK
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
/* Some definitions to reduce conditionals. */
typedef GtkWidget *xt_or_gtk_widget;
#define XtParent(x) (gtk_widget_get_parent (x))
#endif
/* The class of this X application. */
@ -348,7 +360,7 @@ extern void check_x P_ ((void));
extern struct frame *x_window_to_frame P_ ((struct x_display_info *, int));
#ifdef USE_X_TOOLKIT
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
extern struct frame *x_any_window_to_frame P_ ((struct x_display_info *, int));
extern struct frame *x_non_menubar_window_to_frame P_ ((struct x_display_info *, int));
extern struct frame *x_top_window_to_frame P_ ((struct x_display_info *, int));
@ -403,6 +415,10 @@ struct x_output
if the menubar is turned off. */
int menubar_height;
/* Height of tool bar widget, in pixels.
Zero if not using an external tool bar. */
int toolbar_height;
/* Height of a line, in pixels. */
int line_height;
@ -446,6 +462,26 @@ struct x_output
Widget menubar_widget;
#endif
#ifdef USE_GTK
/* The widget of this screen. This is the window of a top widget. */
GtkWidget *widget;
/* The widget of the edit portion of this screen; the window in
"window_desc" is inside of this. */
GtkWidget *edit_widget;
/* The widget used for laying out widgets vertically. */
GtkWidget *vbox_widget;
/* The menubar in this frame. */
GtkWidget *menubar_widget;
/* The tool bar in this frame */
GtkWidget *toolbar_widget;
/* The handle box that makes the tool bar detachable. */
GtkWidget *handlebox_widget;
/* The last size hints set. */
GdkGeometry size_hints;
long hint_flags;
#endif
/* If >=0, a bitmap index. The indicated bitmap is used for the
icon. */
int icon_bitmap;
@ -638,13 +674,28 @@ enum
XtWindow ((f)->output_data.x->widget) : \
FRAME_X_WINDOW (f))
#else
#ifdef USE_GTK
#define GTK_WIDGET_TO_X_WIN(w) \
((w) && (w)->window ? GDK_WINDOW_XWINDOW ((w)->window) : 0)
#define FRAME_GTK_OUTER_WIDGET(f) ((f)->output_data.x->widget)
#define FRAME_GTK_WIDGET(f) ((f)->output_data.x->edit_widget)
#define FRAME_OUTER_WINDOW(f) \
(FRAME_GTK_OUTER_WIDGET (f) ? \
GTK_WIDGET_TO_X_WIN (FRAME_GTK_OUTER_WIDGET (f)) : \
FRAME_X_WINDOW (f))
#else /* !USE_GTK */
#define FRAME_OUTER_WINDOW(f) (FRAME_X_WINDOW (f))
#endif /* !USE_GTK */
#endif
#define FRAME_FONT(f) ((f)->output_data.x->font)
#define FRAME_FONTSET(f) ((f)->output_data.x->fontset)
#define FRAME_INTERNAL_BORDER_WIDTH(f) ((f)->output_data.x->internal_border_width)
#define FRAME_MENUBAR_HEIGHT(f) ((f)->output_data.x->menubar_height)
#define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.x->toolbar_height)
#define FRAME_LINE_HEIGHT(f) ((f)->output_data.x->line_height)
/* Width of the default font of frame F. Must be defined by each
@ -681,7 +732,7 @@ enum
((f)->output_data.x->x_pixels_outer_diff)
#define FRAME_OUTER_TO_INNER_DIFF_Y(f) \
((f)->output_data.x->y_pixels_outer_diff \
+ (f)->output_data.x->menubar_height)
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
#define FRAME_XIC(f) ((f)->output_data.x->xic)