aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Djärv2003-01-19 21:50:03 +0000
committerJan Djärv2003-01-19 21:50:03 +0000
commit488dd4c404eba70d48e4ee70141b8abcce2f863b (patch)
tree741ec2bb5abe963b292521e3a478e716a4ebb999
parent3c77dc44b8052a9bcb19486a605a861cf120b31e (diff)
downloademacs-488dd4c404eba70d48e4ee70141b8abcce2f863b.tar.gz
emacs-488dd4c404eba70d48e4ee70141b8abcce2f863b.zip
GTK version
-rw-r--r--ChangeLog6
-rw-r--r--INSTALL7
-rwxr-xr-xconfigure170
-rw-r--r--configure.in109
-rw-r--r--man/ChangeLog7
-rw-r--r--man/xresources.texi395
-rw-r--r--src/ChangeLog110
-rw-r--r--src/Makefile.in32
-rw-r--r--src/alloc.c7
-rw-r--r--src/config.in3
-rw-r--r--src/dispnew.c4
-rw-r--r--src/fileio.c4
-rw-r--r--src/frame.h20
-rw-r--r--src/keyboard.c13
-rw-r--r--src/lisp.h1
-rw-r--r--src/xdisp.c54
-rw-r--r--src/xfns.c778
-rw-r--r--src/xmenu.c698
-rw-r--r--src/xterm.c439
-rw-r--r--src/xterm.h55
20 files changed, 2349 insertions, 563 deletions
diff --git a/ChangeLog b/ChangeLog
index caaac815890..98fb59e3356 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
12003-01-19 Jan D. <jan.h.d@swipnet.se>
2
3 * configure.in: Add --with-gtk, --with-x-toolkit=gtk
4
5 * INSTALL (DETAILED BUILDING AND INSTALLATION): Add text about GTK.
6
12003-01-14 Francesco Potort,Al(B <pot@gnu.org> 72003-01-14 Francesco Potort,Al(B <pot@gnu.org>
2 8
3 * configure.in (m68k-motorola-sysv): Removed (obsolete). 9 * configure.in (m68k-motorola-sysv): Removed (obsolete).
diff --git a/INSTALL b/INSTALL
index 6b4278a3ff1..ab9c8057259 100644
--- a/INSTALL
+++ b/INSTALL
@@ -270,7 +270,7 @@ accept a list of directories, separated with colons.
270 270
271To get more attractive menus, you can specify an X toolkit when you 271To get more attractive menus, you can specify an X toolkit when you
272configure Emacs; use the option `--with-x-toolkit=TOOLKIT', where 272configure Emacs; use the option `--with-x-toolkit=TOOLKIT', where
273TOOLKIT is `athena' or `motif' (`yes' and `lucid' are synonyms for 273TOOLKIT is `athena', `motif' or `gtk' (`yes' and `lucid' are synonyms for
274`athena'). On some systems, it does not work to use a toolkit with 274`athena'). On some systems, it does not work to use a toolkit with
275shared libraries. A free implementation of Motif, called LessTif, is 275shared libraries. A free implementation of Motif, called LessTif, is
276available ftom <http://www.lesstif.org>. Compiling with LessTif or 276available ftom <http://www.lesstif.org>. Compiling with LessTif or
@@ -280,6 +280,11 @@ bars, even without LessTif/Motif, if you have the Xaw3d library
280installed (see "Image support libraries" above for Xaw3d 280installed (see "Image support libraries" above for Xaw3d
281availability). 281availability).
282 282
283If `--with-x-toolkit=gtk' is specified, you can tell configure where
284to search for GTK by specifying `--with-pkg-config-prog=PATH' where
285PATH is the pathname to pkg-config. Note that GTK version 2.0 or
286newer is required for Emacs.
287
283The `--with-gcc' option specifies that the build process should 288The `--with-gcc' option specifies that the build process should
284compile Emacs using GCC. If you don't want to use GCC, specify 289compile Emacs using GCC. If you don't want to use GCC, specify
285`--with-gcc=no'. If you omit this option, `configure' will search 290`--with-gcc=no'. If you omit this option, `configure' will search
diff --git a/configure b/configure
index 4e28a724c8e..58c410a7c22 100755
--- a/configure
+++ b/configure
@@ -309,7 +309,7 @@ ac_includes_default="\
309# include <unistd.h> 309# include <unistd.h>
310#endif" 310#endif"
311 311
312ac_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' 312ac_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'
313ac_subst_files='' 313ac_subst_files=''
314 314
315# Initialize some variables set by options. 315# Initialize some variables set by options.
@@ -866,12 +866,15 @@ Optional Packages:
866 --with-kerberos5 support Kerberos version 5 authenticated POP 866 --with-kerberos5 support Kerberos version 5 authenticated POP
867 --with-hesiod support Hesiod to get the POP server host 867 --with-hesiod support Hesiod to get the POP server host
868 --without-sound don't compile with sound support 868 --without-sound don't compile with sound support
869 --with-x-toolkit=KIT use an X toolkit (KIT = yes/lucid/athena/motif/no) 869 --with-x-toolkit=KIT use an X toolkit
870 (KIT = yes/lucid/athena/motif/gtk/no)
870 --with-xpm use -lXpm for displaying XPM images 871 --with-xpm use -lXpm for displaying XPM images
871 --with-jpeg use -ljpeg for displaying JPEG images 872 --with-jpeg use -ljpeg for displaying JPEG images
872 --with-tiff use -ltiff for displaying TIFF images 873 --with-tiff use -ltiff for displaying TIFF images
873 --with-gif use -lungif for displaying GIF images 874 --with-gif use -lungif for displaying GIF images
874 --with-png use -lpng for displaying PNG images 875 --with-png use -lpng for displaying PNG images
876 --with-gtk use GTK (same as --with-x-toolkit=gtk)
877 --with-pkg-config-prog Path to pkg-config to use for finding GTK
875 --without-toolkit-scroll-bars 878 --without-toolkit-scroll-bars
876 don't use Motif or Xaw3d scroll bars 879 don't use Motif or Xaw3d scroll bars
877 --without-xim don't use X11 XIM 880 --without-xim don't use X11 XIM
@@ -1402,12 +1405,13 @@ if test "${with_x_toolkit+set}" = set; then
1402 l | lu | luc | luci | lucid ) val=lucid ;; 1405 l | lu | luc | luci | lucid ) val=lucid ;;
1403 a | at | ath | athe | athen | athena ) val=athena ;; 1406 a | at | ath | athe | athen | athena ) val=athena ;;
1404 m | mo | mot | moti | motif ) val=motif ;; 1407 m | mo | mot | moti | motif ) val=motif ;;
1408 g | gt | gtk ) val=gtk ;;
1405 * ) 1409 * )
1406{ { echo "$as_me:$LINENO: error: \`--with-x-toolkit=$withval' is invalid\; 1410{ { echo "$as_me:$LINENO: error: \`--with-x-toolkit=$withval' is invalid\;
1407this option's value should be \`yes', \`no', \`lucid', \`athena', or \`motif'. 1411this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif' or \`gtk'.
1408Currently, \`yes', \`athena' and \`lucid' are synonyms." >&5 1412Currently, \`yes', \`athena' and \`lucid' are synonyms." >&5
1409echo "$as_me: error: \`--with-x-toolkit=$withval' is invalid\; 1413echo "$as_me: error: \`--with-x-toolkit=$withval' is invalid\;
1410this option's value should be \`yes', \`no', \`lucid', \`athena', or \`motif'. 1414this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif' or \`gtk'.
1411Currently, \`yes', \`athena' and \`lucid' are synonyms." >&2;} 1415Currently, \`yes', \`athena' and \`lucid' are synonyms." >&2;}
1412 { (exit 1); exit 1; }; } 1416 { (exit 1); exit 1; }; }
1413 ;; 1417 ;;
@@ -1446,6 +1450,18 @@ if test "${with_png+set}" = set; then
1446 1450
1447fi; 1451fi;
1448 1452
1453# Check whether --with-gtk or --without-gtk was given.
1454if test "${with_gtk+set}" = set; then
1455 withval="$with_gtk"
1456
1457fi;
1458
1459# Check whether --with-pkg-config-prog or --without-pkg-config-prog was given.
1460if test "${with_pkg_config_prog+set}" = set; then
1461 withval="$with_pkg_config_prog"
1462
1463fi;
1464
1449# Check whether --with-toolkit-scroll-bars or --without-toolkit-scroll-bars was given. 1465# Check whether --with-toolkit-scroll-bars or --without-toolkit-scroll-bars was given.
1450if test "${with_toolkit_scroll_bars+set}" = set; then 1466if test "${with_toolkit_scroll_bars+set}" = set; then
1451 withval="$with_toolkit_scroll_bars" 1467 withval="$with_toolkit_scroll_bars"
@@ -6800,6 +6816,8 @@ case "${window_system}" in
6800 case "${with_x_toolkit}" in 6816 case "${with_x_toolkit}" in
6801 athena | lucid ) USE_X_TOOLKIT=LUCID ;; 6817 athena | lucid ) USE_X_TOOLKIT=LUCID ;;
6802 motif ) USE_X_TOOLKIT=MOTIF ;; 6818 motif ) USE_X_TOOLKIT=MOTIF ;;
6819 gtk ) with_gtk=yes
6820 USE_X_TOOLKIT=none ;;
6803 no ) USE_X_TOOLKIT=none ;; 6821 no ) USE_X_TOOLKIT=none ;;
6804 * ) USE_X_TOOLKIT=maybe ;; 6822 * ) USE_X_TOOLKIT=maybe ;;
6805 esac 6823 esac
@@ -8058,6 +8076,134 @@ echo "${ECHO_T}before 5" >&6
8058 fi 8076 fi
8059fi 8077fi
8060 8078
8079
8080
8081HAVE_GTK=no
8082if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "gtk"; then
8083 if test "$USE_X_TOOLKIT" != "none"; then
8084 { { echo "$as_me:$LINENO: error: Conflicting options, --with-gtk is incompatible with --with-x-toolkit=${with_x_toolkit}" >&5
8085echo "$as_me: error: Conflicting options, --with-gtk is incompatible with --with-x-toolkit=${with_x_toolkit}" >&2;}
8086 { (exit 1); exit 1; }; };
8087 fi
8088 GLIB_REQUIRED=2.0.1
8089 GTK_REQUIRED=2.0.1
8090 GTK_MODULES="gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED"
8091
8092 if test "X${with_pkg_config_prog}" != X; then
8093 PKG_CONFIG="${with_pkg_config_prog}"
8094 fi
8095
8096 succeeded=no
8097
8098 if test -z "$PKG_CONFIG"; then
8099 # Extract the first word of "pkg-config", so it can be a program name with args.
8100set dummy pkg-config; ac_word=$2
8101echo "$as_me:$LINENO: checking for $ac_word" >&5
8102echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
8103if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
8104 echo $ECHO_N "(cached) $ECHO_C" >&6
8105else
8106 case $PKG_CONFIG in
8107 [\\/]* | ?:[\\/]*)
8108 ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
8109 ;;
8110 *)
8111 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
8112for as_dir in $PATH
8113do
8114 IFS=$as_save_IFS
8115 test -z "$as_dir" && as_dir=.
8116 for ac_exec_ext in '' $ac_executable_extensions; do
8117 if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
8118 ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
8119 echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
8120 break 2
8121 fi
8122done
8123done
8124
8125 test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
8126 ;;
8127esac
8128fi
8129PKG_CONFIG=$ac_cv_path_PKG_CONFIG
8130
8131if test -n "$PKG_CONFIG"; then
8132 echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
8133echo "${ECHO_T}$PKG_CONFIG" >&6
8134else
8135 echo "$as_me:$LINENO: result: no" >&5
8136echo "${ECHO_T}no" >&6
8137fi
8138
8139 fi
8140
8141 if test "$PKG_CONFIG" = "no" ; then
8142 echo "*** The pkg-config script could not be found. Make sure it is"
8143 echo "*** in your path, or give the full path to pkg-config with"
8144 echo "*** the PKG_CONFIG environment variable or --with-pkg-config-prog."
8145 echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
8146 else
8147 PKG_CONFIG_MIN_VERSION=0.9.0
8148 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
8149 echo "$as_me:$LINENO: checking for $GTK_MODULES" >&5
8150echo $ECHO_N "checking for $GTK_MODULES... $ECHO_C" >&6
8151
8152 if $PKG_CONFIG --exists "$GTK_MODULES" ; then
8153 echo "$as_me:$LINENO: result: yes" >&5
8154echo "${ECHO_T}yes" >&6
8155 succeeded=yes
8156
8157 echo "$as_me:$LINENO: checking GTK_CFLAGS" >&5
8158echo $ECHO_N "checking GTK_CFLAGS... $ECHO_C" >&6
8159 GTK_CFLAGS=`$PKG_CONFIG --cflags "$GTK_MODULES"`
8160 echo "$as_me:$LINENO: result: $GTK_CFLAGS" >&5
8161echo "${ECHO_T}$GTK_CFLAGS" >&6
8162
8163 echo "$as_me:$LINENO: checking GTK_LIBS" >&5
8164echo $ECHO_N "checking GTK_LIBS... $ECHO_C" >&6
8165 GTK_LIBS=`$PKG_CONFIG --libs "$GTK_MODULES"`
8166 echo "$as_me:$LINENO: result: $GTK_LIBS" >&5
8167echo "${ECHO_T}$GTK_LIBS" >&6
8168 else
8169 GTK_CFLAGS=""
8170 GTK_LIBS=""
8171 ## If we have a custom action on failure, don't print errors, but
8172 ## do set a variable so people can do so.
8173 GTK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$GTK_MODULES"`
8174 echo $GTK_PKG_ERRORS
8175 fi
8176
8177
8178
8179 else
8180 echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
8181 echo "*** See http://www.freedesktop.org/software/pkgconfig"
8182 fi
8183 fi
8184
8185 if test $succeeded = yes; then
8186 :
8187 else
8188 { { 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
8189echo "$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;}
8190 { (exit 1); exit 1; }; }
8191 fi
8192
8193
8194
8195 C_SWITCH_X_SITE="$C_SWITCH_X_SITE $GTK_CFLAGS"
8196 HAVE_GTK=yes
8197
8198cat >>confdefs.h <<\_ACEOF
8199#define HAVE_GTK 1
8200_ACEOF
8201
8202 USE_X_TOOLKIT=none
8203
8204 with_toolkit_scroll_bars=yes
8205fi
8206
8061if test x"${USE_X_TOOLKIT}" = xmaybe; then 8207if test x"${USE_X_TOOLKIT}" = xmaybe; then
8062 if test x"${HAVE_X11R5}" = xyes; then 8208 if test x"${HAVE_X11R5}" = xyes; then
8063 echo "$as_me:$LINENO: checking X11 version 5 with Xaw" >&5 8209 echo "$as_me:$LINENO: checking X11 version 5 with Xaw" >&5
@@ -8650,6 +8796,12 @@ _ACEOF
8650 8796
8651 USE_TOOLKIT_SCROLL_BARS=yes 8797 USE_TOOLKIT_SCROLL_BARS=yes
8652 fi 8798 fi
8799 elif test "${HAVE_GTK}" = "yes"; then
8800 cat >>confdefs.h <<\_ACEOF
8801#define USE_TOOLKIT_SCROLL_BARS 1
8802_ACEOF
8803
8804 USE_TOOLKIT_SCROLL_BARS=yes
8653 fi 8805 fi
8654fi 8806fi
8655 8807
@@ -17845,6 +17997,13 @@ fi
17845 17997
17846 17998
17847#### Report on what we decided to do. 17999#### Report on what we decided to do.
18000#### Report GTK as a toolkit, even if it doesn't use Xt.
18001#### It makes printing result more understandable as using GTK sets
18002#### toolkit_scroll_bars to yes by default.
18003if test "${HAVE_GTK}" = "yes"; then
18004 USE_X_TOOLKIT=GTK
18005fi
18006
17848echo " 18007echo "
17849Configured for \`${canonical}'. 18008Configured for \`${canonical}'.
17850 18009
@@ -18566,6 +18725,9 @@ s,@INSTALL_INFO@,$INSTALL_INFO,;t t
18566s,@EGREP@,$EGREP,;t t 18725s,@EGREP@,$EGREP,;t t
18567s,@LIBSOUND@,$LIBSOUND,;t t 18726s,@LIBSOUND@,$LIBSOUND,;t t
18568s,@SET_MAKE@,$SET_MAKE,;t t 18727s,@SET_MAKE@,$SET_MAKE,;t t
18728s,@PKG_CONFIG@,$PKG_CONFIG,;t t
18729s,@GTK_CFLAGS@,$GTK_CFLAGS,;t t
18730s,@GTK_LIBS@,$GTK_LIBS,;t t
18569s,@ALLOCA@,$ALLOCA,;t t 18731s,@ALLOCA@,$ALLOCA,;t t
18570s,@liblockfile@,$liblockfile,;t t 18732s,@liblockfile@,$liblockfile,;t t
18571s,@LIBOBJS@,$LIBOBJS,;t t 18733s,@LIBOBJS@,$LIBOBJS,;t t
diff --git a/configure.in b/configure.in
index 24f2b5908ad..e73ce2e3717 100644
--- a/configure.in
+++ b/configure.in
@@ -77,13 +77,15 @@ dnl This should be the last --with option, because --with-x is
77dnl added later on when we find the path of X, and it's best to 77dnl added later on when we find the path of X, and it's best to
78dnl keep them together visually. 78dnl keep them together visually.
79AC_ARG_WITH(x-toolkit, 79AC_ARG_WITH(x-toolkit,
80[ --with-x-toolkit=KIT use an X toolkit (KIT = yes/lucid/athena/motif/no)], 80[ --with-x-toolkit=KIT use an X toolkit
81 (KIT = yes/lucid/athena/motif/gtk/no)],
81[ case "${withval}" in 82[ case "${withval}" in
82 y | ye | yes ) val=athena ;; 83 y | ye | yes ) val=athena ;;
83 n | no ) val=no ;; 84 n | no ) val=no ;;
84 l | lu | luc | luci | lucid ) val=lucid ;; 85 l | lu | luc | luci | lucid ) val=lucid ;;
85 a | at | ath | athe | athen | athena ) val=athena ;; 86 a | at | ath | athe | athen | athena ) val=athena ;;
86 m | mo | mot | moti | motif ) val=motif ;; 87 m | mo | mot | moti | motif ) val=motif ;;
88 g | gt | gtk ) val=gtk ;;
87dnl These don't currently work. 89dnl These don't currently work.
88dnl o | op | ope | open | open- | open-l | open-lo \ 90dnl o | op | ope | open | open- | open-l | open-lo \
89dnl | open-loo | open-look ) val=open-look ;; 91dnl | open-loo | open-look ) val=open-look ;;
@@ -91,7 +93,7 @@ dnl | open-loo | open-look ) val=open-look ;;
91dnl AC_MSG_ERROR([the `--with-x-toolkit' option is supposed to have a value 93dnl AC_MSG_ERROR([the `--with-x-toolkit' option is supposed to have a value
92dnl which is `yes', `no', `lucid', `athena', `motif' or `open-look'.]) 94dnl which is `yes', `no', `lucid', `athena', `motif' or `open-look'.])
93AC_MSG_ERROR([`--with-x-toolkit=$withval' is invalid\; 95AC_MSG_ERROR([`--with-x-toolkit=$withval' is invalid\;
94this option's value should be `yes', `no', `lucid', `athena', or `motif'. 96this option's value should be `yes', `no', `lucid', `athena', `motif' or `gtk'.
95Currently, `yes', `athena' and `lucid' are synonyms.]) 97Currently, `yes', `athena' and `lucid' are synonyms.])
96 ;; 98 ;;
97 esac 99 esac
@@ -107,6 +109,10 @@ AC_ARG_WITH(gif,
107[ --with-gif use -lungif for displaying GIF images]) 109[ --with-gif use -lungif for displaying GIF images])
108AC_ARG_WITH(png, 110AC_ARG_WITH(png,
109[ --with-png use -lpng for displaying PNG images]) 111[ --with-png use -lpng for displaying PNG images])
112AC_ARG_WITH(gtk,
113[ --with-gtk use GTK (same as --with-x-toolkit=gtk)])
114AC_ARG_WITH(pkg-config-prog,
115[ --with-pkg-config-prog Path to pkg-config to use for finding GTK])
110AC_ARG_WITH(toolkit-scroll-bars, 116AC_ARG_WITH(toolkit-scroll-bars,
111[ --without-toolkit-scroll-bars 117[ --without-toolkit-scroll-bars
112 don't use Motif or Xaw3d scroll bars]) 118 don't use Motif or Xaw3d scroll bars])
@@ -1570,6 +1576,10 @@ case "${window_system}" in
1570 athena | lucid ) USE_X_TOOLKIT=LUCID ;; 1576 athena | lucid ) USE_X_TOOLKIT=LUCID ;;
1571 motif ) USE_X_TOOLKIT=MOTIF ;; 1577 motif ) USE_X_TOOLKIT=MOTIF ;;
1572dnl open-look ) USE_X_TOOLKIT=OPEN_LOOK ;; 1578dnl open-look ) USE_X_TOOLKIT=OPEN_LOOK ;;
1579 gtk ) with_gtk=yes
1580dnl Dont set this for GTK. A lot of tests below assumes Xt when
1581dnl USE_X_TOOLKIT is set.
1582 USE_X_TOOLKIT=none ;;
1573 no ) USE_X_TOOLKIT=none ;; 1583 no ) USE_X_TOOLKIT=none ;;
1574dnl If user did not say whether to use a toolkit, 1584dnl If user did not say whether to use a toolkit,
1575dnl make this decision later: use the toolkit if we have X11R5 or newer. 1585dnl make this decision later: use the toolkit if we have X11R5 or newer.
@@ -1781,6 +1791,89 @@ fail;
1781 fi 1791 fi
1782fi 1792fi
1783 1793
1794dnl This function defintion taken from Gnome 2.0
1795dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
1796dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
1797dnl also defines GSTUFF_PKG_ERRORS on error
1798AC_DEFUN(PKG_CHECK_MODULES, [
1799 succeeded=no
1800
1801 if test -z "$PKG_CONFIG"; then
1802 AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
1803 fi
1804
1805 if test "$PKG_CONFIG" = "no" ; then
1806 echo "*** The pkg-config script could not be found. Make sure it is"
1807 echo "*** in your path, or give the full path to pkg-config with"
1808 echo "*** the PKG_CONFIG environment variable or --with-pkg-config-prog."
1809 echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
1810 else
1811 PKG_CONFIG_MIN_VERSION=0.9.0
1812 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
1813 AC_MSG_CHECKING(for $2)
1814
1815 if $PKG_CONFIG --exists "$2" ; then
1816 AC_MSG_RESULT(yes)
1817 succeeded=yes
1818
1819 AC_MSG_CHECKING($1_CFLAGS)
1820 $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
1821 AC_MSG_RESULT($$1_CFLAGS)
1822
1823 AC_MSG_CHECKING($1_LIBS)
1824 $1_LIBS=`$PKG_CONFIG --libs "$2"`
1825 AC_MSG_RESULT($$1_LIBS)
1826 else
1827 $1_CFLAGS=""
1828 $1_LIBS=""
1829 ## If we have a custom action on failure, don't print errors, but
1830 ## do set a variable so people can do so.
1831 $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
1832 ifelse([$4], ,echo $$1_PKG_ERRORS,)
1833 fi
1834
1835 AC_SUBST($1_CFLAGS)
1836 AC_SUBST($1_LIBS)
1837 else
1838 echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
1839 echo "*** See http://www.freedesktop.org/software/pkgconfig"
1840 fi
1841 fi
1842
1843 if test $succeeded = yes; then
1844 ifelse([$3], , :, [$3])
1845 else
1846 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])
1847 fi
1848])
1849
1850HAVE_GTK=no
1851if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "gtk"; then
1852 if test "$USE_X_TOOLKIT" != "none"; then
1853 AC_MSG_ERROR([Conflicting options, --with-gtk is incompatible with --with-x-toolkit=${with_x_toolkit}]);
1854 fi
1855 GLIB_REQUIRED=2.0.1
1856 GTK_REQUIRED=2.0.1
1857 GTK_MODULES="gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED"
1858
1859 dnl Check if --with-pkg-config-prog has been given.
1860 if test "X${with_pkg_config_prog}" != X; then
1861 PKG_CONFIG="${with_pkg_config_prog}"
1862 fi
1863 dnl Checks for libraries.
1864 PKG_CHECK_MODULES(GTK, $GTK_MODULES)
1865 AC_SUBST(GTK_CFLAGS)
1866 AC_SUBST(GTK_LIBS)
1867 C_SWITCH_X_SITE="$C_SWITCH_X_SITE $GTK_CFLAGS"
1868 HAVE_GTK=yes
1869 AC_DEFINE(HAVE_GTK, 1, [Define to 1 if using GTK.])
1870 USE_X_TOOLKIT=none
1871
1872 dnl GTK scrollbars resembles toolkit scrollbars alot, so to avoid
1873 dnl a lot if #ifdef:s, say we have toolkit scrollbars.
1874 with_toolkit_scroll_bars=yes
1875fi
1876
1784dnl Do not put whitespace before the #include statements below. 1877dnl Do not put whitespace before the #include statements below.
1785dnl Older compilers (eg sunos4 cc) choke on it. 1878dnl Older compilers (eg sunos4 cc) choke on it.
1786if test x"${USE_X_TOOLKIT}" = xmaybe; then 1879if test x"${USE_X_TOOLKIT}" = xmaybe; then
@@ -1903,7 +1996,7 @@ if test "${HAVE_X11}" = "yes"; then
1903 fi 1996 fi
1904fi 1997fi
1905 1998
1906dnl Use toolkit scroll bars if configured for X toolkit and either 1999dnl Use toolkit scroll bars if configured for GTK or X toolkit and either
1907dnl using Motif or Xaw3d is available, and unless 2000dnl using Motif or Xaw3d is available, and unless
1908dnl --with-toolkit-scroll-bars=no was specified. 2001dnl --with-toolkit-scroll-bars=no was specified.
1909 2002
@@ -1920,6 +2013,9 @@ if test "${with_toolkit_scroll_bars}" != "no"; then
1920 AC_DEFINE(USE_TOOLKIT_SCROLL_BARS) 2013 AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
1921 USE_TOOLKIT_SCROLL_BARS=yes 2014 USE_TOOLKIT_SCROLL_BARS=yes
1922 fi 2015 fi
2016 elif test "${HAVE_GTK}" = "yes"; then
2017 AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
2018 USE_TOOLKIT_SCROLL_BARS=yes
1923 fi 2019 fi
1924fi 2020fi
1925 2021
@@ -2745,6 +2841,13 @@ End:
2745])dnl 2841])dnl
2746 2842
2747#### Report on what we decided to do. 2843#### Report on what we decided to do.
2844#### Report GTK as a toolkit, even if it doesn't use Xt.
2845#### It makes printing result more understandable as using GTK sets
2846#### toolkit_scroll_bars to yes by default.
2847if test "${HAVE_GTK}" = "yes"; then
2848 USE_X_TOOLKIT=GTK
2849fi
2850
2748echo " 2851echo "
2749Configured for \`${canonical}'. 2852Configured for \`${canonical}'.
2750 2853
diff --git a/man/ChangeLog b/man/ChangeLog
index 1b1f0ab7bc1..9f4f2c03ff9 100644
--- a/man/ChangeLog
+++ b/man/ChangeLog
@@ -1,3 +1,10 @@
12003-01-19 Jan D. <jan.h.d@swipnet.se>
2
3 * xresources.texi (GTK resources): New node.
4 (GTK widget names): New node.
5 (GTK names in Emacs): New node.
6 (GTK styles): New node.
7
12003-01-15 ShengHuo ZHU <zsh@cs.rochester.edu> 82003-01-15 ShengHuo ZHU <zsh@cs.rochester.edu>
2 9
3 * gnus.texi: Do not use `path' in several locations. 10 * gnus.texi: Do not use `path' in several locations.
diff --git a/man/xresources.texi b/man/xresources.texi
index 9312507b59f..e6451e76998 100644
--- a/man/xresources.texi
+++ b/man/xresources.texi
@@ -1,5 +1,5 @@
1@c This is part of the Emacs manual. 1@c This is part of the Emacs manual.
2@c Copyright (C) 1987,93,94,95,1997,2001 Free Software Foundation, Inc. 2@c Copyright (C) 1987,93,94,95,1997,2001,03 Free Software Foundation, Inc.
3@c See file emacs.texi for copying conditions. 3@c See file emacs.texi for copying conditions.
4@node X Resources, Antinews, Command Arguments, Top 4@node X Resources, Antinews, Command Arguments, Top
5@appendix X Options and Resources 5@appendix X Options and Resources
@@ -18,6 +18,7 @@ describes the X resources that Emacs recognizes and how to use them.
18* Face Resources:: X resources for customizing faces. 18* Face Resources:: X resources for customizing faces.
19* Lucid Resources:: X resources for Lucid menus. 19* Lucid Resources:: X resources for Lucid menus.
20* LessTif Resources:: X resources for LessTif and Motif menus. 20* LessTif Resources:: X resources for LessTif and Motif menus.
21* GTK resources:: Resources for GTK widgets.
21@end menu 22@end menu
22 23
23@node Resources 24@node Resources
@@ -520,3 +521,395 @@ The color for the border shadow, on the bottom and the right.
520@item topShadowColor 521@item topShadowColor
521The color for the border shadow, on the top and the left. 522The color for the border shadow, on the top and the left.
522@end table 523@end table
524
525
526@node GTK resources
527@appendixsec GTK resources
528@cindex GTK resources and customization
529@cindex resource files for GTK
530@cindex @file{~/.gtkrc-2.0} file
531@cindex @file{~/.emacs.d/gtkrc} file
532
533 If the Emacs installed at your site was built to use the GTK widget set,
534then the menu bar, scroll bar and the dialogs can be customized with
535the standard GTK @file{~/.gtkrc-2.0} file or with the Emacs specific
536@file{~/.emacs.d/gtkrc} file; note that these files are only for
537customizing specific GTK widget features. To customize Emacs font,
538background, faces etc., use the normal X resources, see @ref{Resources}.
539
540In these files you first defines a style and then how to apply that style
541to widgets (@pxref{GTK widget names}). Here is an example of how to
542change the font for Emacs menus:
543
544@smallexample
545# This is a comment.
546style "menufont"
547@{
548 font_name = "helvetica bold 14" # This is a Pango font name
549@}
550
551widget "*emacs-menuitem*" style "menufont"
552
553@end smallexample
554
555 There are some things you can set without using any style or widget name,
556which affect GTK as a whole. Most of these are poorly documented, but can
557be found in the `Properties' section of the documentation page for
558@code{GtkSetting}, in the GTK document references below.
559
560One property of interest is @code{gtk-font-name} which sets the default
561font for GTK; you must use Pango font names (@pxref{GTK styles}). A
562@file{~/.gtkrc-2.0} file that just sets a default font looks like this:
563
564@smallexample
565gtk-font-name = "courier 12"
566@end smallexample
567
568
569 If GTK at your site is installed under @var{prefix},
570the resource file syntax is fully described in the GTK API
571document
572@file{@var{prefix}/share/gtk-doc/html/gtk/gtk-resource-files.html}.
573@var{prefix} is usually @file{/usr} or @file{/usr/local}.
574You can find the same document online at
575@uref{http://developer.gnome.org/doc/API/2.0/gtk/gtk-Resource-Files.html}.
576
577
578@menu
579* GTK widget names:: How widgets in GTK are named in general.
580* GTK names in Emacs:: GTK widget names in Emacs.
581* GTK styles:: What can be customized in a GTK widget.
582@end menu
583
584
585@node GTK widget names
586@appendixsubsec GTK widget names
587@cindex GTK widget names
588
589 Widgets are specified by widget class or by widget name.
590The widget class is the type of the widget, for example @code{GtkMenuBar}.
591The widget name is the name given to a specific widget within a program.
592A widget always have a class but it is not mandatory to give a name to
593a widget. Absolute names are sequences of widget names or
594widget classes, corresponding to hierarchies of widgets embedded within
595other widgets. For example, if a @code{GtkWindow} contains a @code{GtkVBox}
596which in turn contains a @code{GtkMenuBar}, the absolute class name
597is @code{GtkWindow.GtkVBox.GtkMenuBar}.
598
599@noindent
600If the widgets are named ``top'', ``box'' and ``menubar'', the absolute
601widget name is @code{top.box.menubar},
602
603 When assigning a style to a widget, you can use the absolute class
604name or the absolute widget name.
605There are two commands: @code{widget_class} will assign a style to
606widgets, matching only against the absolute class name.
607The command @code{widget} will match the absolute widget name,
608but if there is no name for a widget in the hierarchy, the class is matched.
609These commands require the absolute name and the style name to be
610within double quotes. These commands are written at the top level in a
611@file{~/.gtkrc-2.0} file, like this:
612
613@smallexample
614style "menufont"
615@{
616 font_name = "helvetica bold 14"
617@}
618
619widget "top.box.menubar" style "menufont"
620widget_class "GtkWindow.GtkVBox.GtkMenuBar" style "menufont"
621@end smallexample
622
623
624 Matching of absolute names is done with shell ``glob'' syntax, that is
625@samp{*} matches zero or more characters and @samp{?} matches one character.
626So the following would assign @code{base_style} to all widgets:
627
628@smallexample
629widget "*" style "base_style"
630@end smallexample
631
632 Given the absolute class name @code{GtkWindow.GtkVBox.GtkMenuBar}
633and the corresponding absolute widget name @code{top.box.menubar},
634the following all assign @code{my_style} to the menu bar:
635
636@smallexample
637widget_class "GtkWindow.GtkVBox.GtkMenuBar" style "my_style"
638widget_class "GtkWindow.*.GtkMenuBar" style "my_style"
639widget_class "*GtkMenuBar" style "my_style"
640widget "top.box.menubar" style "my_style"
641widget "*box*menubar" style "my_style"
642widget "*menubar" style "my_style"
643widget "*menu*" style "my_style"
644@end smallexample
645
646@node GTK names in Emacs
647@appendixsubsec GTK names in Emacs
648@cindex GTK widget names
649@cindex GTK widget classes
650
651 In Emacs the top level widget for a frame is a @code{GtkWindow} that
652contains a @code{GtkVBox}. The @code{GtkVBox} contains the
653@code{GtkMenuBar} and a @code{GtkFixed} widget.
654The vertical scroll bars, @code{GtkVScrollbar},
655are contained in the @code{GtkFixed} widget.
656The text you write in Emacs is drawn in the @code{GtkFixed} widget.
657
658 Dialogs in Emacs are @code{GtkDialog} widgets. The file dialog is a
659@code{GtkFileSelection} widget.
660
661@noindent
662To set a style for the menu bar using the absolute class name, use:
663
664@smallexample
665widget_class "GtkWindow.GtkVBox.GtkMenuBar" style "my_style"
666@end smallexample
667
668@noindent
669For the scroll bar, the absolute class name is:
670
671@smallexample
672widget_class
673 "GtkWindow.GtkVBox.GtkFixed.GtkVScrollbar"
674 style "my_style"
675@end smallexample
676
677@noindent
678The names for the emacs widgets, and their classes, are:
679
680@multitable {@code{verticalScrollbar plus}} {@code{GtkFileSelection} and some}
681@item @code{emacs-filedialog}
682@tab @code{GtkFileSelection}
683@item @code{emacs-dialog}
684@tab @code{GtkDialog}
685@item @code{Emacs}
686@tab @code{GtkWindow}
687@item @code{pane}
688@tab @code{GtkVHbox}
689@item @code{emacs}
690@tab @code{GtkFixed}
691@item @code{menubar}
692@tab @code{GtkMenuBar}
693@item @code{verticalScrollbar}
694@tab @code{GtkVScrollbar}
695@item @code{emacs-menuitem}
696@tab anything in menus
697@end multitable
698
699@noindent
700Thus, for Emacs you can write the two examples above as:
701
702@smallexample
703widget "Emacs.pane.menubar" style "my_style"
704widget "Emacs.pane.emacs.verticalScrollbar" style "my_style"
705@end smallexample
706
707 GTK absolute names are quite strange when it comes to menus
708and dialogs. The names do not start with @samp{Emacs}, as they are
709free-standing windows and not contained (in the GTK sense) by the
710Emacs GtkWindow. To customize the dialogs and menus, use wildcards like this:
711
712@smallexample
713widget "*emacs-dialog*" style "my_dialog_style"
714widget "*emacs-filedialog* style "my_file_style"
715widget "*emacs-menuitem* style "my_menu_style"
716@end smallexample
717
718 An alternative is to put customization into @file{~/.emacs.d/gtkrc}.
719This file is only read by Emacs, so anything in @file{~/.emacs.d/gtkrc}
720affects Emacs but leaves other applications unaffected.
721For example, the drop down menu in the file dialog can not
722be customized by any absolute widget name, only by an absolute
723class name. This is so because the widgets in the drop down menu does not
724have names and the menu is not contained in the Emacs GtkWindow.
725To have all menus in Emacs look the same, use this in @file{~/.emacs.d/gtkrc}:
726
727@smallexample
728widget_class "*Menu*" style "my_menu_style"
729@end smallexample
730
731@node GTK styles
732@appendixsubsec GTK styles
733@cindex GTK styles
734
735 In a GTK style you specify the appearance widgets shall have. You
736can specify foreground and background color, background pixmap and font.
737The edit widget (where you edit the text) in Emacs is a GTK widget,
738but trying to specify a style for the edit widget will have no effect.
739This is so that Emacs compiled for GTK is compatible with Emacs compiled
740for other X toolkits. The settings for foreground, background and font
741for the edit widget is taken from the X resources; @pxref{Resources}.
742Here is an example of two style declarations, ``default'' and ``ruler'':
743
744@smallexample
745
746pixmap_path "/usr/share/pixmaps:/usr/include/X11/pixmaps"
747
748style "default"
749@{
750 font_name = "helvetica 12"
751
752 bg[NORMAL] = @{ 0.83, 0.80, 0.73 @}
753 bg[SELECTED] = @{ 0.0, 0.55, 0.55 @}
754 bg[INSENSITIVE] = @{ 0.77, 0.77, 0.66 @}
755 bg[ACTIVE] = @{ 0.0, 0.55, 0.55 @}
756 bg[PRELIGHT] = @{ 0.0, 0.55, 0.55 @}
757
758 fg[NORMAL] = "black"
759 fg[SELECTED] = @{ 0.9, 0.9, 0.9 @}
760 fg[ACTIVE] = "black"
761 fg[PRELIGHT] = @{ 0.9, 0.9, 0.9 @}
762
763 base[INSENSITIVE] = "#777766"
764 text[INSENSITIVE] = @{ 0.60, 0.65, 0.57 @}
765
766 bg_pixmap[NORMAL] = "background.xpm"
767 bg_pixmap[INSENSITIVE] = "background.xpm"
768 bg_pixmap[ACTIVE] = "background.xpm"
769 bg_pixmap[PRELIGHT] = "<none>"
770
771@}
772
773style "ruler" = "default"
774@{
775 font_name = "helvetica 8"
776@}
777
778@end smallexample
779
780 The style ``ruler'' inherits from ``default''. This way you can build
781on existing styles. The syntax for fonts and colors is described below.
782
783 As this example shows, it is possible to specify several values
784for foreground and background depending on which state the widget has.
785The possible states are
786@table @code
787@item NORMAL
788This is the default state for widgets.
789@item ACTIVE
790This is the state for a widget that is ready to do something. It is
791also for the trough of a scroll bar, i.e. @code{bg[ACTIVE] = "red"}
792sets the scroll bar trough to red. Buttons that have been pressed but
793not released yet (``armed'') are in this state.
794@item PRELIGHT
795This is the state when widgets that can be manipulated have the mouse
796pointer over them. For example when the mouse is over the thumb in the
797scroll bar or over a menu item. When the mouse is over a button that
798is not pressed, the button is in this state.
799@item SELECTED
800This is the state when some data has been selected by the user. It can
801be selected text or items selected in a list.
802There is no place in Emacs where this setting has any effect.
803@item INSENSITIVE
804This is the state for widgets that are visible, but they can not be
805manipulated like they normally can. For example, buttons that can't be
806pressed and menu items that can't be selected.
807Text for menu items that are not available can be set to yellow with
808@code{fg[INSENSITIVE] = "yellow"}.
809@end table
810
811Here are the things that can go in a style declaration:
812
813@table @code
814@item bg[@var{state}] = @var{color}
815This is the background color widgets use. This background is not used for
816editable text, use @code{base} for that.
817
818@item base[@var{state}] = @var{color}
819This is the background color for editable text.
820In Emacs, this color is used for the background of the text fields in the
821file dialog.
822
823@item bg_pixmap[@var{state}] = "@var{pixmap}"
824You can specify a pixmap to be used instead of the background color.
825@var{pixmap} is a file name. GTK can use a number of file formats,
826including XPM, XBM, GIF, JPEG and PNG. If you want a widget to use the same
827pixmap as its parent, use @samp{<parent>}. If you don't want any
828pixmap use @samp{<none>}. Using @samp{<none>} can be useful
829if your style inherits a style that does specify a pixmap.
830
831 GTK looks for the pixmap in directories specified in @code{pixmap_path}.
832It is not possible to refer to a file by its absolute path name.
833@code{pixmap_path} is a colon-separated list of directories within double
834quotes, specified at the top level in a @file{gtkrc} file (i.e. not inside
835a style definition; see example above):
836
837@smallexample
838pixmap_path "/usr/share/pixmaps:/usr/include/X11/pixmaps"
839@end smallexample
840
841@item fg[@var{state}] = @var{color}
842This is the foreground color widgets use. This is the color
843of text in menus and buttons. It is also the color for the arrows in the
844scroll bar. For editable text, use @code{text}.
845
846@item text[@var{state}] = @var{color}
847This is the color for editable text. In Emacs, this color is used for the
848text fields in the file dialog.
849
850@item font_name = "@var{font}"
851This is the font a widget shall use. @var{font} is a Pango font name,
852for example ``Sans Italic 10'', ``Helvetica Bold 12'', ``Courier 14'',
853``Times 18''. See below for exact syntax. The names are case insensitive.
854@end table
855
856 Colors are specified in three ways, a name, a hexadecimal form or
857an RGB triplet.
858
859@noindent
860A color name is written within double quotes, for example @code{"red"}.
861
862@noindent
863A hexadecimal form is written within double quotes. There are four forms,
864@code{#rrrrggggbbbb}, @code{#rrrgggbbb},
865@code{#rrggbb}, or @code{#rgb}. In each of these r, g and b are hex digits.
866
867@noindent
868An RGB triplet looks like @code{@{ r, g, b @}}, where r, g and b are either
869integers in the range 0-65535 or floats in the range 0.0-1.0.
870
871 Pango font names have the form ``@var{family-list} @var{style-options}
872@var{size}''.
873@cindex Pango font name
874@noindent
875@var{family-list} is a comma separated list of font families optionally
876terminated by a comma. This way you can specify several families and the
877first one found will be used. @var{family} corresponds to the second part in
878an X font name, for example in
879
880@smallexample
881-adobe-times-medium-r-normal--12-120-75-75-p-64-iso10646-1
882@end smallexample
883
884@noindent
885the family name is ``times''.
886
887@noindent
888@var{style-options} is a whitespace separated list of words where each word
889is a style, variant, weight, or stretch. The default value for all of
890these is @code{normal}.
891
892@noindent
893A `style' corresponds to the fourth part of an X font name. In X font
894names it is the character ``r'', ``i'' or ``o''; in Pango font names the
895corresponding values are @code{normal}, @code{italic}, or @code{oblique}.
896
897@noindent
898A `variant' is either @code{normal} or @code{small-caps}.
899Small caps is a font with the lower case characters replaced by
900smaller variants of the capital characters.
901
902@noindent
903Weight describes the ``boldness'' of a font. It corresponds to the third
904part of an X font name. It is one of @code{ultra-light}, @code{light},
905@code{normal}, @code{bold}, @code{ultra-bold}, or @code{heavy}.
906
907@noindent
908Stretch gives the width of the font relative to other designs within a
909family. It corresponds to the fifth part of an X font name. It is one of
910@code{ultra-condensed}, @code{extra-condensed}, @code{condensed},
911@code{semi-condensed}, @code{normal}, @code{semi-expanded},
912@code{expanded}, @code{extra-expanded}, or @code{ultra-expanded}.
913
914@noindent
915@var{size} is a decimal number that describes the font size in points.
diff --git a/src/ChangeLog b/src/ChangeLog
index e70b0b220cf..6fb53501632 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,113 @@
12003-01-19 Jan D. <jan.h.d@swipnet.se>
2
3 * Makefile.in (XOBJ): Add gtkutil.o if USE_GTK
4 (gtkutil.o): New file.
5 (TOOLKIT_DEFINES): Set to -DUSE_GTK if HAVE_GTK.
6 (LIBW): Set to @GTK_LIBS@ if USE_GTK.
7
8 * gtkutil.c: New file for GTK version.
9
10 * gtkutil.h: New file for GTK version.
11
12 * xterm.h: Add xt_or_gtk_widget.
13 Include gtk files for USE_GTK.
14 (struct x_output): Add toolbar_height.
15 (struct x_output): Add GTK widgets and Gdk size_hints.
16 (GTK_WIDGET_TO_X_WIN, FRAME_GTK_OUTER_WIDGET, FRAME_GTK_WIDGET)
17 (FRAME_OUTER_WINDOW): New macros for USE_GTK.
18 (FRAME_OUTER_TO_INNER_DIFF_Y): Add FRAME_TOOLBAR_HEIGHT to calculation.
19
20 * xterm.c: Include gtkutil.h for USE_GTK.
21 Declare extern void free_frame_menubar for USE_GTK.
22 (note_mouse_highlight): Check popup_activated for USE_GTK.
23 (xt_action_hook): Don't compile if USE_GTK.
24 (x_scroll_bar_to_input_event): Use CurrentTime for USE_GTK.
25 (xg_scroll_callback): New function.
26 (x_create_toolkit_scroll_bar): Call xg_create_scroll_bar for USE_GTK.
27 (x_set_toolkit_scroll_bar_thumb): Call xg_set_toolkit_scroll_bar_thumb
28 for USE_GTK.
29 (x_scroll_bar_create): Call xg_update_scrollbar_pos and
30 xg_show_scroll_bar for USE_GTK.
31 (x_scroll_bar_remove): Call xg_remove_scroll_bar for USE_GTK.
32 (XTset_vertical_scroll_bar): Call xg_update_scrollbar_pos for USE_GTK.
33 (event_handler_gdk): New function for USE_GTK.
34 (handle_one_xevent): Call xg_resize_widgets for USE_GTK.
35 (handle_one_xevent): Make sure widget is mapped before
36 calling x_real_positions for USE_GTK.
37 (XTread_socket): Add GTK event loop for USE_GTK.
38 (x_set_window_size): Call xg_frame_set_char_size for USE_GTK.
39 (x_make_frame_visible): Call gtk_widget_show_all for USE_GTK.
40 (x_make_frame_invisible): Call gtk_widget_hide for USE_GTK.
41 (x_iconify_frame): Add code for USE_GTK.
42 (x_free_frame_resources): Call gtk_widget_destroy for USE_GTK.
43 (x_wm_set_size_hint): Only compile if not USE_GTK. GTK version
44 is in gtkutil.c.
45 (x_term_init): Add initialization for GTK.
46 (syms_of_xterm): Set Vx_toolkit_scroll_bars for USE_GTK.
47
48 * xmenu.c: Include gtkutil.h for USE_GTK.
49 (Fx_popup_menu): Use current position if x and y is NIL.
50 (single_menu_item, single_menu_item, Fx_popup_dialog): Check
51 for USE_GTK.
52 (popup_widget_loop): New function for USE_GTK.
53 (x_activate_menubar): Add code for USE_GTK.
54 (popup_activate_callback, popup_deactivate_callback)
55 (menu_highlight_callback, menubar_selection_callback): USE_GTK versions
56 added.
57 (update_frame_menubar): Call xg_update_frame_menubar for USE_GTK.
58 (set_frame_menubar): Call xg_modify_menubar_widgets for USE_GTK.
59 (free_frame_menubar): Only compile if not USE_GTK. GTK version
60 is in gtkutil.c.
61 (popup_selection_callback): New version for USE_GTK.
62 (create_and_show_popup_menu): New fuction, one USE_GTK version and
63 one USE_X_TOOLKIT version.
64 (xmenu_show): Call create_and_show_popup_menu.
65 (dialog_selection_callback): New version for USE_GTK.
66 (create_and_show_dialog): New fuction, one USE_GTK version and
67 one USE_X_TOOLKIT version.
68 (xdialog_show): Call create_and_show_dialog.
69
70 * xfns.c: Include gtkutil for USE_GTK.
71 (x_window_to_frame, x_any_window_to_frame)
72 (x_non_menubar_window_to_frame, x_menubar_window_to_frame)
73 (x_top_window_to_frame): Add code for USE_GTK.
74 (x_set_background_color): Call xg_set_background_color for GTK.
75 (x_set_menu_bar_lines): Check for USE_GTK.
76 (x_set_tool_bar_lines): Call update_frame_tool_bar for USE_GTK.
77 (x_set_name, x_set_title): Call gtk_window_set_title for USE_GTK.
78 (x_window): Call xg_create_frame_widgets for USE_GTK.
79 (Fx_create_frame): Check for USE_GTK
80 (Fx_file_dialog): New implementation for USE_GTK.
81
82
83 * xdisp.c: Add check for USE_GTK for extern void set_frame_menubar.
84 (update_menu_bar): Add check for USE_GTK.
85 (update_tool_bar): Add check for USE_GTK and external tool bar.
86 (redisplay_tool_bar): Add check for USE_GTK and external tool bar.
87 (redisplay_internal): Add check for USE_GTK and popup_activated.
88 (redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_MENU_BAR.
89 (redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_TOOL_BAR.
90 (display_menu_bar): Add check for USE_GTK
91
92 * lisp.h: Declare Vx_resource_name extern.
93
94 * keyboard.c (kbd_buffer_get_event): Check MENU_BAR_ACTIVATE_EVENT
95 for USE_GTK.
96 (make_lispy_event): Check MENU_BAR_EVENT for USE_GTK.
97
98 * frame.h (struct frame): Add external_tool_bar. Check for USE_GTK.
99 (FRAME_EXTERNAL_TOOL_BAR): New macro.
100 (FRAME_EXTERNAL_MENU_BAR): Check for USE_GTK.
101
102 * fileio.c (Fread_file_name): Add check for USE_GTK.
103
104 * dispnew.c (adjust_frame_glyphs_for_window_redisplay): Add
105 check for USE_GTK.
106
107 * config.in: Added HAVE_GTK
108
109 * alloc.c (Fgarbage_collect): Call xg_mark_data for GTK.
110
12003-01-18 Stefan Monnier <monnier@cs.yale.edu> 1112003-01-18 Stefan Monnier <monnier@cs.yale.edu>
2 112
3 * charset.h (Funibyte_char_to_multibyte): Export. 113 * charset.h (Funibyte_char_to_multibyte): Export.
diff --git a/src/Makefile.in b/src/Makefile.in
index b8fe0c9f07f..0a65e83bc5c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -252,12 +252,19 @@ STARTFILES = START_FILES
252#define C_SWITCH_ASM 252#define C_SWITCH_ASM
253#endif 253#endif
254 254
255#if HAVE_GTK
256#define USE_GTK
257TOOLKIT_DEFINES = -DUSE_GTK
258#endif
259
255#ifdef USE_X_TOOLKIT 260#ifdef USE_X_TOOLKIT
256#define USE_@X_TOOLKIT_TYPE@ 261#define USE_@X_TOOLKIT_TYPE@
257TOOLKIT_DEFINES = -DUSE_@X_TOOLKIT_TYPE@ 262TOOLKIT_DEFINES = -DUSE_@X_TOOLKIT_TYPE@
258#else 263#else
264#ifndef USE_GTK
259TOOLKIT_DEFINES = 265TOOLKIT_DEFINES =
260#endif 266#endif
267#endif
261 268
262/* DO NOT use -R. There is a special hack described in lastfile.c 269/* DO NOT use -R. There is a special hack described in lastfile.c
263 which is used instead. Some initialized data areas are modified 270 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
300#ifdef HAVE_MENUS 307#ifdef HAVE_MENUS
301 308
302/* Include xmenu.o in the list of X object files. */ 309/* Include xmenu.o in the list of X object files. */
310
311#ifdef USE_GTK
312XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o gtkutil.o
313#else
303XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o 314XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o
315#endif
304 316
305/* The X Menu stuff is present in the X10 distribution, but missing 317/* The X Menu stuff is present in the X10 distribution, but missing
306 from X11. If we have X10, just use the installed library; 318 from X11. If we have X10, just use the installed library;
@@ -372,10 +384,17 @@ LIBXT= $(LIBW) LIBXMU -lXt $(LIBXTR6) -lXext
372#endif /* not LIBXT_STATIC */ 384#endif /* not LIBXT_STATIC */
373 385
374#else /* not USE_X_TOOLKIT */ 386#else /* not USE_X_TOOLKIT */
387
388#ifdef USE_GTK
389LIBW=@GTK_LIBS@
390OLDXMENU=
391LIBXMENU=
392#endif /* USE_GTK */
393
375#ifdef HAVE_X_SM 394#ifdef HAVE_X_SM
376LIBXT=-lSM -lICE 395LIBXT=$(LIBW) -lSM -lICE
377#else 396#else
378LIBXT= 397LIBXT=$(LIBW)
379#endif 398#endif
380#endif /* not USE_X_TOOLKIT */ 399#endif /* not USE_X_TOOLKIT */
381 400
@@ -1150,18 +1169,21 @@ xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
1150 window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h $(config_h) 1169 window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h $(config_h)
1151xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \ 1170xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
1152 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \ 1171 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
1153 charset.h $(config_h) 1172 charset.h gtkutil.h $(config_h)
1154xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \ 1173xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
1155 keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \ 1174 keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \
1156 msdos.h $(config_h) 1175 gtkutil.h msdos.h $(config_h)
1157xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \ 1176xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \
1158 dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \ 1177 dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
1159 keyboard.h gnu.h charset.h ccl.h fontset.h composite.h \ 1178 keyboard.h gnu.h charset.h ccl.h fontset.h composite.h \
1160 coding.h process.h $(config_h) 1179 coding.h process.h gtkutil.h $(config_h)
1161xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \ 1180xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \
1162 charset.h coding.h ccl.h buffer.h atimer.h systime.h $(config_h) 1181 charset.h coding.h ccl.h buffer.h atimer.h systime.h $(config_h)
1163xrdb.o: xrdb.c $(config_h) epaths.h 1182xrdb.o: xrdb.c $(config_h) epaths.h
1164xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h 1183xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h
1184gtkutil.o: gtkutil.c gtkutil.h xterm.h lisp.h frame.h $(config_h) \
1185 blockinput.h window.h atimer.h termhooks.h
1186
1165hftctl.o: hftctl.c $(config_h) 1187hftctl.o: hftctl.c $(config_h)
1166sound.o: sound.c dispextern.h $(config_h) 1188sound.o: sound.c dispextern.h $(config_h)
1167atimer.o: atimer.c atimer.h systime.h $(config_h) 1189atimer.o: atimer.c atimer.h systime.h $(config_h)
diff --git a/src/alloc.c b/src/alloc.c
index 281288e69db..c61a0d9fa83 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4266,6 +4266,13 @@ Garbage collection happens automatically if you cons more than
4266 mark_stack (); 4266 mark_stack ();
4267#endif 4267#endif
4268 4268
4269#ifdef USE_GTK
4270 {
4271 extern void xg_mark_data ();
4272 xg_mark_data ();
4273 }
4274#endif
4275
4269 gc_sweep (); 4276 gc_sweep ();
4270 4277
4271 /* Clear the mark bits that we set in certain root slots. */ 4278 /* Clear the mark bits that we set in certain root slots. */
diff --git a/src/config.in b/src/config.in
index a1868073c64..165bafb4629 100644
--- a/src/config.in
+++ b/src/config.in
@@ -205,6 +205,9 @@ Boston, MA 02111-1307, USA. */
205/* Define to 1 if you have the `grantpt' function. */ 205/* Define to 1 if you have the `grantpt' function. */
206#undef HAVE_GRANTPT 206#undef HAVE_GRANTPT
207 207
208/* Define to 1 if using GTK. */
209#undef HAVE_GTK
210
208/* Define to 1 if netdb.h declares h_errno. */ 211/* Define to 1 if netdb.h declares h_errno. */
209#undef HAVE_H_ERRNO 212#undef HAVE_H_ERRNO
210 213
diff --git a/src/dispnew.c b/src/dispnew.c
index 1d9ae986a37..4ea59834762 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -2371,7 +2371,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
2371 2371
2372 /* Allocate/ reallocate matrices of the dummy window used to display 2372 /* Allocate/ reallocate matrices of the dummy window used to display
2373 the menu bar under X when no X toolkit support is available. */ 2373 the menu bar under X when no X toolkit support is available. */
2374#ifndef USE_X_TOOLKIT 2374#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
2375 { 2375 {
2376 /* Allocate a dummy window if not already done. */ 2376 /* Allocate a dummy window if not already done. */
2377 if (NILP (f->menu_bar_window)) 2377 if (NILP (f->menu_bar_window))
@@ -2394,6 +2394,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
2394 } 2394 }
2395#endif /* not USE_X_TOOLKIT */ 2395#endif /* not USE_X_TOOLKIT */
2396 2396
2397#ifndef USE_GTK
2397 /* Allocate/ reallocate matrices of the tool bar window. If we 2398 /* Allocate/ reallocate matrices of the tool bar window. If we
2398 don't have a tool bar window yet, make one. */ 2399 don't have a tool bar window yet, make one. */
2399 if (NILP (f->tool_bar_window)) 2400 if (NILP (f->tool_bar_window))
@@ -2411,6 +2412,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
2411 XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f)); 2412 XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
2412 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f)); 2413 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2413 allocate_matrices_for_window_redisplay (w); 2414 allocate_matrices_for_window_redisplay (w);
2415#endif
2414} 2416}
2415 2417
2416 2418
diff --git a/src/fileio.c b/src/fileio.c
index 56086b6dfb1..bfb15d2954b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6116,8 +6116,8 @@ provides a file dialog box. */)
6116 (NILP (predicate) ? Qfile_exists_p : predicate)); 6116 (NILP (predicate) ? Qfile_exists_p : predicate));
6117 6117
6118 GCPRO2 (insdef, default_filename); 6118 GCPRO2 (insdef, default_filename);
6119 6119
6120#if defined (USE_MOTIF) || defined (HAVE_NTGUI) 6120#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
6121 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 6121 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
6122 && use_dialog_box 6122 && use_dialog_box
6123 && have_menus_p ()) 6123 && have_menus_p ())
diff --git a/src/frame.h b/src/frame.h
index 7db48632105..af2a66bad65 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -215,6 +215,11 @@ struct frame
215 be used for output. */ 215 be used for output. */
216 unsigned glyphs_initialized_p : 1; 216 unsigned glyphs_initialized_p : 1;
217 217
218#if defined (USE_GTK)
219 /* Nonzero means using a tool bar that comes from the toolkit. */
220 int external_tool_bar;
221#endif
222
218 /* Margin at the top of the frame. Used to display the tool-bar. */ 223 /* Margin at the top of the frame. Used to display the tool-bar. */
219 int tool_bar_lines; 224 int tool_bar_lines;
220 225
@@ -270,7 +275,8 @@ struct frame
270 /* Number of lines of menu bar. */ 275 /* Number of lines of menu bar. */
271 int menu_bar_lines; 276 int menu_bar_lines;
272 277
273#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 278#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
279 || defined (USE_GTK)
274 /* Nonzero means using a menu bar that comes from the X toolkit. */ 280 /* Nonzero means using a menu bar that comes from the X toolkit. */
275 int external_menu_bar; 281 int external_menu_bar;
276#endif 282#endif
@@ -457,10 +463,19 @@ typedef struct frame *FRAME_PTR;
457 These lines are counted in FRAME_HEIGHT. */ 463 These lines are counted in FRAME_HEIGHT. */
458#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines 464#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
459 465
466/* Nonzero if this frame should display a tool bar
467 in a way that does not use any text lines. */
468#if defined (USE_GTK)
469#define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
470#else
471#define FRAME_EXTERNAL_TOOL_BAR(f) 0
472#endif
473
460/* Number of lines of frame F used for the tool-bar. */ 474/* Number of lines of frame F used for the tool-bar. */
461 475
462#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines 476#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
463 477
478
464/* Lines above the top-most window in frame F. */ 479/* Lines above the top-most window in frame F. */
465 480
466#define FRAME_TOP_MARGIN(F) \ 481#define FRAME_TOP_MARGIN(F) \
@@ -468,7 +483,8 @@ typedef struct frame *FRAME_PTR;
468 483
469/* Nonzero if this frame should display a menu bar 484/* Nonzero if this frame should display a menu bar
470 in a way that does not use any text lines. */ 485 in a way that does not use any text lines. */
471#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 486#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
487 || defined (USE_GTK)
472#define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar 488#define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar
473#else 489#else
474#define FRAME_EXTERNAL_MENU_BAR(f) 0 490#define FRAME_EXTERNAL_MENU_BAR(f) 0
diff --git a/src/keyboard.c b/src/keyboard.c
index 9dbbda0276c..d54dcd22bc4 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3878,7 +3878,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
3878 XSETBUFFER (obj, current_buffer); 3878 XSETBUFFER (obj, current_buffer);
3879 kbd_fetch_ptr = event + 1; 3879 kbd_fetch_ptr = event + 1;
3880 } 3880 }
3881#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 3881#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
3882 || defined (USE_GTK)
3882 else if (event->kind == MENU_BAR_ACTIVATE_EVENT) 3883 else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
3883 { 3884 {
3884 kbd_fetch_ptr = event + 1; 3885 kbd_fetch_ptr = event + 1;
@@ -3985,7 +3986,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
3985 { 3986 {
3986 obj = make_lispy_event (event); 3987 obj = make_lispy_event (event);
3987 3988
3988#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS) 3989#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS) \
3990 || defined (USE_GTK)
3989 /* If this was a menu selection, then set the flag to inhibit 3991 /* If this was a menu selection, then set the flag to inhibit
3990 writing to last_nonmenu_event. Don't do this if the event 3992 writing to last_nonmenu_event. Don't do this if the event
3991 we're returning is (menu-bar), though; that indicates the 3993 we're returning is (menu-bar), though; that indicates the
@@ -5048,7 +5050,7 @@ make_lispy_event (event)
5048 pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), 5050 pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
5049 &column, &row, NULL, 1); 5051 &column, &row, NULL, 1);
5050 5052
5051#ifndef USE_X_TOOLKIT 5053#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
5052 /* In the non-toolkit version, clicks on the menu bar 5054 /* In the non-toolkit version, clicks on the menu bar
5053 are ordinary button events in the event buffer. 5055 are ordinary button events in the event buffer.
5054 Distinguish them, and invoke the menu. 5056 Distinguish them, and invoke the menu.
@@ -5100,7 +5102,7 @@ make_lispy_event (event)
5100 5102
5101 return Fcons (item, Fcons (position, Qnil)); 5103 return Fcons (item, Fcons (position, Qnil));
5102 } 5104 }
5103#endif /* not USE_X_TOOLKIT */ 5105#endif /* not USE_X_TOOLKIT && not USE_GTK */
5104 5106
5105 /* Set `window' to the window under frame pixel coordinates 5107 /* Set `window' to the window under frame pixel coordinates
5106 event->x/event->y. */ 5108 event->x/event->y. */
@@ -5589,7 +5591,8 @@ make_lispy_event (event)
5589 } 5591 }
5590#endif /* HAVE_MOUSE */ 5592#endif /* HAVE_MOUSE */
5591 5593
5592#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 5594#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
5595 || defined (USE_GTK)
5593 case MENU_BAR_EVENT: 5596 case MENU_BAR_EVENT:
5594 if (EQ (event->arg, event->frame_or_window)) 5597 if (EQ (event->arg, event->frame_or_window))
5595 /* This is the prefix key. We translate this to 5598 /* This is the prefix key. We translate this to
diff --git a/src/lisp.h b/src/lisp.h
index a71779a31c4..029c0618791 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3136,6 +3136,7 @@ extern int getloadavg P_ ((double *, int));
3136extern void syms_of_xfns P_ ((void)); 3136extern void syms_of_xfns P_ ((void));
3137extern void init_xfns P_ ((void)); 3137extern void init_xfns P_ ((void));
3138extern Lisp_Object Vx_resource_name; 3138extern Lisp_Object Vx_resource_name;
3139extern Lisp_Object Vx_resource_class;
3139EXFUN (Fxw_display_color_p, 1); 3140EXFUN (Fxw_display_color_p, 1);
3140EXFUN (Fx_file_dialog, 4); 3141EXFUN (Fx_file_dialog, 4);
3141#endif /* HAVE_X_WINDOWS */ 3142#endif /* HAVE_X_WINDOWS */
diff --git a/src/xdisp.c b/src/xdisp.c
index 769d861e36c..87770b52ddd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -200,7 +200,8 @@ Boston, MA 02111-1307, USA. */
200 200
201#define INFINITY 10000000 201#define INFINITY 10000000
202 202
203#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 203#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
204 || defined (USE_GTK)
204extern void set_frame_menubar P_ ((struct frame *f, int, int)); 205extern void set_frame_menubar P_ ((struct frame *f, int, int));
205extern int pending_menu_activation; 206extern int pending_menu_activation;
206#endif 207#endif
@@ -7518,7 +7519,8 @@ update_menu_bar (f, save_match_data)
7518 7519
7519 if (FRAME_WINDOW_P (f) 7520 if (FRAME_WINDOW_P (f)
7520 ? 7521 ?
7521#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 7522#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7523 || defined (USE_GTK)
7522 FRAME_EXTERNAL_MENU_BAR (f) 7524 FRAME_EXTERNAL_MENU_BAR (f)
7523#else 7525#else
7524 FRAME_MENU_BAR_LINES (f) > 0 7526 FRAME_MENU_BAR_LINES (f) > 0
@@ -7569,7 +7571,8 @@ update_menu_bar (f, save_match_data)
7569 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); 7571 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
7570 7572
7571 /* Redisplay the menu bar in case we changed it. */ 7573 /* Redisplay the menu bar in case we changed it. */
7572#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 7574#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7575 || defined (USE_GTK)
7573 if (FRAME_WINDOW_P (f) 7576 if (FRAME_WINDOW_P (f)
7574#if defined (MAC_OS) 7577#if defined (MAC_OS)
7575 /* All frames on Mac OS share the same menubar. So only the 7578 /* All frames on Mac OS share the same menubar. So only the
@@ -7582,11 +7585,11 @@ update_menu_bar (f, save_match_data)
7582 /* On a terminal screen, the menu bar is an ordinary screen 7585 /* On a terminal screen, the menu bar is an ordinary screen
7583 line, and this makes it get updated. */ 7586 line, and this makes it get updated. */
7584 w->update_mode_line = Qt; 7587 w->update_mode_line = Qt;
7585#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */ 7588#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
7586 /* In the non-toolkit version, the menu bar is an ordinary screen 7589 /* In the non-toolkit version, the menu bar is an ordinary screen
7587 line, and this makes it get updated. */ 7590 line, and this makes it get updated. */
7588 w->update_mode_line = Qt; 7591 w->update_mode_line = Qt;
7589#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */ 7592#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
7590 7593
7591 unbind_to (count, Qnil); 7594 unbind_to (count, Qnil);
7592 set_buffer_internal_1 (prev); 7595 set_buffer_internal_1 (prev);
@@ -7612,8 +7615,14 @@ update_tool_bar (f, save_match_data)
7612 struct frame *f; 7615 struct frame *f;
7613 int save_match_data; 7616 int save_match_data;
7614{ 7617{
7615 if (WINDOWP (f->tool_bar_window) 7618#ifdef USE_GTK
7616 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0) 7619 int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
7620#else
7621 int do_update = WINDOWP (f->tool_bar_window)
7622 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0;
7623#endif
7624
7625 if (do_update)
7617 { 7626 {
7618 Lisp_Object window; 7627 Lisp_Object window;
7619 struct window *w; 7628 struct window *w;
@@ -7991,6 +8000,12 @@ redisplay_tool_bar (f)
7991 struct it it; 8000 struct it it;
7992 struct glyph_row *row; 8001 struct glyph_row *row;
7993 int change_height_p = 0; 8002 int change_height_p = 0;
8003
8004#ifdef USE_GTK
8005 if (FRAME_EXTERNAL_TOOL_BAR(f))
8006 update_frame_tool_bar (f);
8007 return 0;
8008#endif
7994 8009
7995 /* If frame hasn't a tool-bar window or if it is zero-height, don't 8010 /* If frame hasn't a tool-bar window or if it is zero-height, don't
7996 do anything. This means you must start with tool-bar-lines 8011 do anything. This means you must start with tool-bar-lines
@@ -7998,7 +8013,7 @@ redisplay_tool_bar (f)
7998 can turn off tool-bars by specifying tool-bar-lines zero. */ 8013 can turn off tool-bars by specifying tool-bar-lines zero. */
7999 if (!WINDOWP (f->tool_bar_window) 8014 if (!WINDOWP (f->tool_bar_window)
8000 || (w = XWINDOW (f->tool_bar_window), 8015 || (w = XWINDOW (f->tool_bar_window),
8001 XFASTINT (w->height) == 0)) 8016 XFASTINT (w->height) == 0))
8002 return 0; 8017 return 0;
8003 8018
8004 /* Set up an iterator for the tool-bar window. */ 8019 /* Set up an iterator for the tool-bar window. */
@@ -8550,7 +8565,7 @@ redisplay_internal (preserve_echo_area)
8550 return; 8565 return;
8551 } 8566 }
8552 8567
8553#ifdef USE_X_TOOLKIT 8568#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
8554 if (popup_activated ()) 8569 if (popup_activated ())
8555 return; 8570 return;
8556#endif 8571#endif
@@ -10785,10 +10800,12 @@ redisplay_window (window, just_this_one_p)
10785 && EQ (FRAME_SELECTED_WINDOW (f), window)) 10800 && EQ (FRAME_SELECTED_WINDOW (f), window))
10786 { 10801 {
10787 int redisplay_menu_p = 0; 10802 int redisplay_menu_p = 0;
10803 int redisplay_tool_bar_p = 0;
10788 10804
10789 if (FRAME_WINDOW_P (f)) 10805 if (FRAME_WINDOW_P (f))
10790 { 10806 {
10791#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) 10807#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
10808 || defined (USE_GTK)
10792 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f); 10809 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
10793#else 10810#else
10794 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0; 10811 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
@@ -10801,10 +10818,17 @@ redisplay_window (window, just_this_one_p)
10801 display_menu_bar (w); 10818 display_menu_bar (w);
10802 10819
10803#ifdef HAVE_WINDOW_SYSTEM 10820#ifdef HAVE_WINDOW_SYSTEM
10804 if (WINDOWP (f->tool_bar_window) 10821#ifdef USE_GTK
10805 && (FRAME_TOOL_BAR_LINES (f) > 0 10822 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
10806 || auto_resize_tool_bars_p)) 10823#else
10807 redisplay_tool_bar (f); 10824 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
10825 && (FRAME_TOOL_BAR_LINES (f) > 0
10826 || auto_resize_tool_bars_p);
10827
10828#endif
10829
10830 if (redisplay_tool_bar_p)
10831 redisplay_tool_bar (f);
10808#endif 10832#endif
10809 } 10833 }
10810 10834
@@ -13535,7 +13559,7 @@ display_menu_bar (w)
13535 if (!NILP (Vwindow_system)) 13559 if (!NILP (Vwindow_system))
13536 return; 13560 return;
13537#endif 13561#endif
13538#ifdef USE_X_TOOLKIT 13562#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
13539 if (FRAME_X_P (f)) 13563 if (FRAME_X_P (f))
13540 return; 13564 return;
13541#endif 13565#endif
diff --git a/src/xfns.c b/src/xfns.c
index 85f402befb0..1b9b629b366 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -65,6 +65,10 @@ Boston, MA 02111-1307, USA. */
65#include "[.bitmaps]gray.xbm" 65#include "[.bitmaps]gray.xbm"
66#endif 66#endif
67 67
68#ifdef USE_GTK
69#include "gtkutil.h"
70#endif
71
68#ifdef USE_X_TOOLKIT 72#ifdef USE_X_TOOLKIT
69#include <X11/Shell.h> 73#include <X11/Shell.h>
70 74
@@ -284,11 +288,11 @@ check_x_display_info (frame)
284 Lisp_Object frame; 288 Lisp_Object frame;
285{ 289{
286 struct x_display_info *dpyinfo = NULL; 290 struct x_display_info *dpyinfo = NULL;
287 291
288 if (NILP (frame)) 292 if (NILP (frame))
289 { 293 {
290 struct frame *sf = XFRAME (selected_frame); 294 struct frame *sf = XFRAME (selected_frame);
291 295
292 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf)) 296 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
293 dpyinfo = FRAME_X_DISPLAY_INFO (sf); 297 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
294 else if (x_display_list != 0) 298 else if (x_display_list != 0)
@@ -332,7 +336,7 @@ x_window_to_frame (dpyinfo, wdesc)
332 if (f->output_data.x->hourglass_window == wdesc) 336 if (f->output_data.x->hourglass_window == wdesc)
333 return f; 337 return f;
334#ifdef USE_X_TOOLKIT 338#ifdef USE_X_TOOLKIT
335 if ((f->output_data.x->edit_widget 339 if ((f->output_data.x->edit_widget
336 && XtWindow (f->output_data.x->edit_widget) == wdesc) 340 && XtWindow (f->output_data.x->edit_widget) == wdesc)
337 /* A tooltip frame? */ 341 /* A tooltip frame? */
338 || (!f->output_data.x->edit_widget 342 || (!f->output_data.x->edit_widget
@@ -340,6 +344,15 @@ x_window_to_frame (dpyinfo, wdesc)
340 || f->output_data.x->icon_desc == wdesc) 344 || f->output_data.x->icon_desc == wdesc)
341 return f; 345 return f;
342#else /* not USE_X_TOOLKIT */ 346#else /* not USE_X_TOOLKIT */
347#ifdef USE_GTK
348 if (f->output_data.x->edit_widget)
349 {
350 GtkWidget *gwdesc = xg_win_to_widget (wdesc);
351 struct x_output *x = f->output_data.x;
352 if (gwdesc != 0 && gwdesc == x->edit_widget)
353 return f;
354 }
355#endif /* USE_GTK */
343 if (FRAME_X_WINDOW (f) == wdesc 356 if (FRAME_X_WINDOW (f) == wdesc
344 || f->output_data.x->icon_desc == wdesc) 357 || f->output_data.x->icon_desc == wdesc)
345 return f; 358 return f;
@@ -348,7 +361,7 @@ x_window_to_frame (dpyinfo, wdesc)
348 return 0; 361 return 0;
349} 362}
350 363
351#ifdef USE_X_TOOLKIT 364#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
352/* Like x_window_to_frame but also compares the window with the widget's 365/* Like x_window_to_frame but also compares the window with the widget's
353 windows. */ 366 windows. */
354 367
@@ -367,7 +380,7 @@ x_any_window_to_frame (dpyinfo, wdesc)
367 frame = XCAR (tail); 380 frame = XCAR (tail);
368 if (!GC_FRAMEP (frame)) 381 if (!GC_FRAMEP (frame))
369 continue; 382 continue;
370 383
371 f = XFRAME (frame); 384 f = XFRAME (frame);
372 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo) 385 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
373 { 386 {
@@ -377,20 +390,30 @@ x_any_window_to_frame (dpyinfo, wdesc)
377 found = f; 390 found = f;
378 else if (x->widget) 391 else if (x->widget)
379 { 392 {
380 if (wdesc == XtWindow (x->widget) 393#ifdef USE_GTK
381 || wdesc == XtWindow (x->column_widget) 394 GtkWidget *gwdesc = xg_win_to_widget (wdesc);
395 if (gwdesc != 0
396 && (gwdesc == x->widget
397 || gwdesc == x->edit_widget
398 || gwdesc == x->vbox_widget
399 || gwdesc == x->menubar_widget))
400 found = f;
401#else
402 if (wdesc == XtWindow (x->widget)
403 || wdesc == XtWindow (x->column_widget)
382 || wdesc == XtWindow (x->edit_widget)) 404 || wdesc == XtWindow (x->edit_widget))
383 found = f; 405 found = f;
384 /* Match if the window is this frame's menubar. */ 406 /* Match if the window is this frame's menubar. */
385 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget)) 407 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
386 found = f; 408 found = f;
409#endif
387 } 410 }
388 else if (FRAME_X_WINDOW (f) == wdesc) 411 else if (FRAME_X_WINDOW (f) == wdesc)
389 /* A tooltip frame. */ 412 /* A tooltip frame. */
390 found = f; 413 found = f;
391 } 414 }
392 } 415 }
393 416
394 return found; 417 return found;
395} 418}
396 419
@@ -419,10 +442,19 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc)
419 return f; 442 return f;
420 else if (x->widget) 443 else if (x->widget)
421 { 444 {
422 if (wdesc == XtWindow (x->widget) 445#ifdef USE_GTK
423 || wdesc == XtWindow (x->column_widget) 446 GtkWidget *gwdesc = xg_win_to_widget (wdesc);
447 if (gwdesc != 0
448 && (gwdesc == x->widget
449 || gwdesc == x->edit_widget
450 || gwdesc == x->vbox_widget))
451 return f;
452#else
453 if (wdesc == XtWindow (x->widget)
454 || wdesc == XtWindow (x->column_widget)
424 || wdesc == XtWindow (x->edit_widget)) 455 || wdesc == XtWindow (x->edit_widget))
425 return f; 456 return f;
457#endif
426 } 458 }
427 else if (FRAME_X_WINDOW (f) == wdesc) 459 else if (FRAME_X_WINDOW (f) == wdesc)
428 /* A tooltip frame. */ 460 /* A tooltip frame. */
@@ -452,9 +484,25 @@ x_menubar_window_to_frame (dpyinfo, wdesc)
452 continue; 484 continue;
453 x = f->output_data.x; 485 x = f->output_data.x;
454 /* Match if the window is this frame's menubar. */ 486 /* Match if the window is this frame's menubar. */
487#ifdef USE_GTK
488 if (x->menubar_widget)
489 {
490 GtkWidget *gwdesc = xg_win_to_widget (wdesc);
491 int found = 0;
492
493 BLOCK_INPUT;
494 if (gwdesc != 0
495 && (gwdesc == x->menubar_widget
496 || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
497 found = 1;
498 UNBLOCK_INPUT;
499 if (found) return f;
500 }
501#else
455 if (x->menubar_widget 502 if (x->menubar_widget
456 && lw_window_is_in_menubar (wdesc, x->menubar_widget)) 503 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
457 return f; 504 return f;
505#endif
458 } 506 }
459 return 0; 507 return 0;
460} 508}
@@ -484,16 +532,22 @@ x_top_window_to_frame (dpyinfo, wdesc)
484 if (x->widget) 532 if (x->widget)
485 { 533 {
486 /* This frame matches if the window is its topmost widget. */ 534 /* This frame matches if the window is its topmost widget. */
535#ifdef USE_GTK
536 GtkWidget *gwdesc = xg_win_to_widget (wdesc);
537 if (gwdesc == x->widget)
538 return f;
539#else
487 if (wdesc == XtWindow (x->widget)) 540 if (wdesc == XtWindow (x->widget))
488 return f; 541 return f;
489#if 0 /* I don't know why it did this, 542#if 0 /* I don't know why it did this,
490 but it seems logically wrong, 543 but it seems logically wrong,
491 and it causes trouble for MapNotify events. */ 544 and it causes trouble for MapNotify events. */
492 /* Match if the window is this frame's menubar. */ 545 /* Match if the window is this frame's menubar. */
493 if (x->menubar_widget 546 if (x->menubar_widget
494 && wdesc == XtWindow (x->menubar_widget)) 547 && wdesc == XtWindow (x->menubar_widget))
495 return f; 548 return f;
496#endif 549#endif
550#endif
497 } 551 }
498 else if (FRAME_X_WINDOW (f) == wdesc) 552 else if (FRAME_X_WINDOW (f) == wdesc)
499 /* Tooltip frame. */ 553 /* Tooltip frame. */
@@ -501,7 +555,7 @@ x_top_window_to_frame (dpyinfo, wdesc)
501 } 555 }
502 return 0; 556 return 0;
503} 557}
504#endif /* USE_X_TOOLKIT */ 558#endif /* USE_X_TOOLKIT || USE_GTK */
505 559
506 560
507 561
@@ -806,7 +860,7 @@ static struct x_frame_parm_table x_frame_parms[] =
806 {"right-fringe", x_set_fringe_width}, 860 {"right-fringe", x_set_fringe_width},
807 {"wait-for-wm", x_set_wait_for_wm}, 861 {"wait-for-wm", x_set_wait_for_wm},
808 {"fullscreen", x_set_fullscreen}, 862 {"fullscreen", x_set_fullscreen},
809 863
810}; 864};
811 865
812/* Attach the `x-frame-parameter' properties to 866/* Attach the `x-frame-parameter' properties to
@@ -925,7 +979,7 @@ x_set_frame_parameters (f, alist)
925 cursor_color) are dependent upon them. */ 979 cursor_color) are dependent upon them. */
926 /* Process default font as well, since fringe widths depends on it. */ 980 /* Process default font as well, since fringe widths depends on it. */
927 /* Also, process fullscreen, width and height depend upon that */ 981 /* Also, process fullscreen, width and height depend upon that */
928 for (p = 0; p < i; p++) 982 for (p = 0; p < i; p++)
929 { 983 {
930 Lisp_Object prop, val; 984 Lisp_Object prop, val;
931 985
@@ -940,7 +994,7 @@ x_set_frame_parameters (f, alist)
940 994
941 old_value = get_frame_param (f, prop); 995 old_value = get_frame_param (f, prop);
942 fullscreen_is_being_set |= EQ (prop, Qfullscreen); 996 fullscreen_is_being_set |= EQ (prop, Qfullscreen);
943 997
944 if (NILP (Fequal (val, old_value))) 998 if (NILP (Fequal (val, old_value)))
945 { 999 {
946 store_frame_param (f, prop, val); 1000 store_frame_param (f, prop, val);
@@ -1040,11 +1094,11 @@ x_set_frame_parameters (f, alist)
1040 position. Resize of the frame is taken care of in the code after 1094 position. Resize of the frame is taken care of in the code after
1041 this if-statement. */ 1095 this if-statement. */
1042 int new_left, new_top; 1096 int new_left, new_top;
1043 1097
1044 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left); 1098 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
1045 x_fullscreen_move (f, new_top, new_left); 1099 x_fullscreen_move (f, new_top, new_left);
1046 } 1100 }
1047 1101
1048 /* Don't set these parameters unless they've been explicitly 1102 /* Don't set these parameters unless they've been explicitly
1049 specified. The window might be mapped or resized while we're in 1103 specified. The window might be mapped or resized while we're in
1050 this function, and we don't want to override that unless the lisp 1104 this function, and we don't want to override that unless the lisp
@@ -1188,12 +1242,12 @@ x_real_positions (f, xptr, yptr)
1188 1242
1189 win = wm_window; 1243 win = wm_window;
1190 } 1244 }
1191 1245
1192 if (! had_errors) 1246 if (! had_errors)
1193 { 1247 {
1194 int ign; 1248 int ign;
1195 Window child, rootw; 1249 Window child, rootw;
1196 1250
1197 /* Get the real coordinates for the WM window upper left corner */ 1251 /* Get the real coordinates for the WM window upper left corner */
1198 XGetGeometry (FRAME_X_DISPLAY (f), win, 1252 XGetGeometry (FRAME_X_DISPLAY (f), win,
1199 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign); 1253 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
@@ -1232,23 +1286,23 @@ x_real_positions (f, xptr, yptr)
1232 /* From-window, to-window. */ 1286 /* From-window, to-window. */
1233 FRAME_X_DISPLAY_INFO (f)->root_window, 1287 FRAME_X_DISPLAY_INFO (f)->root_window,
1234 FRAME_OUTER_WINDOW (f), 1288 FRAME_OUTER_WINDOW (f),
1235 1289
1236 /* From-position, to-position. */ 1290 /* From-position, to-position. */
1237 real_x, real_y, &outer_x, &outer_y, 1291 real_x, real_y, &outer_x, &outer_y,
1238 1292
1239 /* Child of win. */ 1293 /* Child of win. */
1240 &child); 1294 &child);
1241 } 1295 }
1242 1296
1243 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f)); 1297 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
1244 } 1298 }
1245 1299
1246 x_uncatch_errors (FRAME_X_DISPLAY (f), count); 1300 x_uncatch_errors (FRAME_X_DISPLAY (f), count);
1247 1301
1248 UNBLOCK_INPUT; 1302 UNBLOCK_INPUT;
1249 1303
1250 if (had_errors) return; 1304 if (had_errors) return;
1251 1305
1252 f->output_data.x->x_pixels_diff = -win_x; 1306 f->output_data.x->x_pixels_diff = -win_x;
1253 f->output_data.x->y_pixels_diff = -win_y; 1307 f->output_data.x->y_pixels_diff = -win_y;
1254 f->output_data.x->x_pixels_outer_diff = -outer_x; 1308 f->output_data.x->x_pixels_outer_diff = -outer_x;
@@ -1508,7 +1562,7 @@ x_set_foreground_color (f, arg, oldval)
1508 if (FRAME_X_WINDOW (f) != 0) 1562 if (FRAME_X_WINDOW (f) != 0)
1509 { 1563 {
1510 Display *dpy = FRAME_X_DISPLAY (f); 1564 Display *dpy = FRAME_X_DISPLAY (f);
1511 1565
1512 BLOCK_INPUT; 1566 BLOCK_INPUT;
1513 XSetForeground (dpy, x->normal_gc, fg); 1567 XSetForeground (dpy, x->normal_gc, fg);
1514 XSetBackground (dpy, x->reverse_gc, fg); 1568 XSetBackground (dpy, x->reverse_gc, fg);
@@ -1519,15 +1573,15 @@ x_set_foreground_color (f, arg, oldval)
1519 x->cursor_pixel = x_copy_color (f, fg); 1573 x->cursor_pixel = x_copy_color (f, fg);
1520 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel); 1574 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
1521 } 1575 }
1522 1576
1523 UNBLOCK_INPUT; 1577 UNBLOCK_INPUT;
1524 1578
1525 update_face_from_frame_parameter (f, Qforeground_color, arg); 1579 update_face_from_frame_parameter (f, Qforeground_color, arg);
1526 1580
1527 if (FRAME_VISIBLE_P (f)) 1581 if (FRAME_VISIBLE_P (f))
1528 redraw_frame (f); 1582 redraw_frame (f);
1529 } 1583 }
1530 1584
1531 unload_color (f, old_fg); 1585 unload_color (f, old_fg);
1532} 1586}
1533 1587
@@ -1546,13 +1600,17 @@ x_set_background_color (f, arg, oldval)
1546 if (FRAME_X_WINDOW (f) != 0) 1600 if (FRAME_X_WINDOW (f) != 0)
1547 { 1601 {
1548 Display *dpy = FRAME_X_DISPLAY (f); 1602 Display *dpy = FRAME_X_DISPLAY (f);
1549 1603
1550 BLOCK_INPUT; 1604 BLOCK_INPUT;
1551 XSetBackground (dpy, x->normal_gc, bg); 1605 XSetBackground (dpy, x->normal_gc, bg);
1552 XSetForeground (dpy, x->reverse_gc, bg); 1606 XSetForeground (dpy, x->reverse_gc, bg);
1553 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg); 1607 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
1554 XSetForeground (dpy, x->cursor_gc, bg); 1608 XSetForeground (dpy, x->cursor_gc, bg);
1555 1609
1610#ifdef USE_GTK
1611 xg_set_background_color (f, bg);
1612#endif
1613
1556#ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with 1614#ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1557 toolkit scroll bars. */ 1615 toolkit scroll bars. */
1558 { 1616 {
@@ -1631,7 +1689,7 @@ x_set_mouse_color (f, arg, oldval)
1631 else 1689 else
1632 hourglass_cursor = XCreateFontCursor (dpy, XC_watch); 1690 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1633 x_check_errors (dpy, "bad hourglass pointer cursor: %s"); 1691 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1634 1692
1635 x_check_errors (dpy, "bad nontext pointer cursor: %s"); 1693 x_check_errors (dpy, "bad nontext pointer cursor: %s");
1636 if (!NILP (Vx_mode_pointer_shape)) 1694 if (!NILP (Vx_mode_pointer_shape))
1637 { 1695 {
@@ -1672,7 +1730,7 @@ x_set_mouse_color (f, arg, oldval)
1672 x_query_color (f, &fore_color); 1730 x_query_color (f, &fore_color);
1673 back_color.pixel = mask_color; 1731 back_color.pixel = mask_color;
1674 x_query_color (f, &back_color); 1732 x_query_color (f, &back_color);
1675 1733
1676 XRecolorCursor (dpy, cursor, &fore_color, &back_color); 1734 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1677 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color); 1735 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1678 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color); 1736 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
@@ -1703,7 +1761,7 @@ x_set_mouse_color (f, arg, oldval)
1703 && x->modeline_cursor != 0) 1761 && x->modeline_cursor != 0)
1704 XFreeCursor (dpy, f->output_data.x->modeline_cursor); 1762 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1705 x->modeline_cursor = mode_cursor; 1763 x->modeline_cursor = mode_cursor;
1706 1764
1707 if (cross_cursor != x->cross_cursor 1765 if (cross_cursor != x->cross_cursor
1708 && x->cross_cursor != 0) 1766 && x->cross_cursor != 0)
1709 XFreeCursor (dpy, x->cross_cursor); 1767 XFreeCursor (dpy, x->cross_cursor);
@@ -1737,7 +1795,7 @@ x_set_cursor_color (f, arg, oldval)
1737 } 1795 }
1738 else 1796 else
1739 fore_pixel = x->background_pixel; 1797 fore_pixel = x->background_pixel;
1740 1798
1741 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); 1799 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1742 pixel_allocated_p = 1; 1800 pixel_allocated_p = 1;
1743 1801
@@ -1749,7 +1807,7 @@ x_set_cursor_color (f, arg, oldval)
1749 x_free_colors (f, &pixel, 1); 1807 x_free_colors (f, &pixel, 1);
1750 pixel_allocated_p = 0; 1808 pixel_allocated_p = 0;
1751 } 1809 }
1752 1810
1753 pixel = x->mouse_pixel; 1811 pixel = x->mouse_pixel;
1754 if (pixel == fore_pixel) 1812 if (pixel == fore_pixel)
1755 { 1813 {
@@ -1957,7 +2015,7 @@ x_set_font (f, arg, oldval)
1957 ? x_new_fontset (f, SDATA (fontset_name)) 2015 ? x_new_fontset (f, SDATA (fontset_name))
1958 : x_new_font (f, SDATA (arg))); 2016 : x_new_font (f, SDATA (arg)));
1959 UNBLOCK_INPUT; 2017 UNBLOCK_INPUT;
1960 2018
1961 if (EQ (result, Qnil)) 2019 if (EQ (result, Qnil))
1962 error ("Font `%s' is not defined", SDATA (arg)); 2020 error ("Font `%s' is not defined", SDATA (arg));
1963 else if (EQ (result, Qt)) 2021 else if (EQ (result, Qt))
@@ -1973,7 +2031,7 @@ x_set_font (f, arg, oldval)
1973 } 2031 }
1974 else if (!NILP (Fequal (result, oldval))) 2032 else if (!NILP (Fequal (result, oldval)))
1975 return; 2033 return;
1976 2034
1977 store_frame_param (f, Qfont, result); 2035 store_frame_param (f, Qfont, result);
1978 recompute_basic_faces (f); 2036 recompute_basic_faces (f);
1979 } 2037 }
@@ -2119,7 +2177,7 @@ x_set_menu_bar_lines (f, value, oldval)
2119 /* Make sure we redisplay all windows in this frame. */ 2177 /* Make sure we redisplay all windows in this frame. */
2120 windows_or_buffers_changed++; 2178 windows_or_buffers_changed++;
2121 2179
2122#ifdef USE_X_TOOLKIT 2180#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
2123 FRAME_MENU_BAR_LINES (f) = 0; 2181 FRAME_MENU_BAR_LINES (f) = 0;
2124 if (nlines) 2182 if (nlines)
2125 { 2183 {
@@ -2136,7 +2194,7 @@ x_set_menu_bar_lines (f, value, oldval)
2136 if (FRAME_X_P (f)) 2194 if (FRAME_X_P (f))
2137 f->output_data.x->menubar_widget = 0; 2195 f->output_data.x->menubar_widget = 0;
2138 } 2196 }
2139#else /* not USE_X_TOOLKIT */ 2197#else /* not USE_X_TOOLKIT && not USE_GTK */
2140 FRAME_MENU_BAR_LINES (f) = nlines; 2198 FRAME_MENU_BAR_LINES (f) = nlines;
2141 x_change_window_heights (f->root_window, nlines - olines); 2199 x_change_window_heights (f->root_window, nlines - olines);
2142#endif /* not USE_X_TOOLKIT */ 2200#endif /* not USE_X_TOOLKIT */
@@ -2168,7 +2226,27 @@ x_set_tool_bar_lines (f, value, oldval)
2168 else 2226 else
2169 nlines = 0; 2227 nlines = 0;
2170 2228
2171 /* Make sure we redisplay all windows in this frame. */ 2229#ifdef USE_GTK
2230 FRAME_TOOL_BAR_LINES (f) = 0;
2231 if (nlines)
2232 {
2233 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
2234 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
2235 /* Make sure next redisplay shows the tool bar. */
2236 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
2237 update_frame_tool_bar (f);
2238 }
2239 else
2240 {
2241 if (FRAME_EXTERNAL_TOOL_BAR (f))
2242 free_frame_tool_bar (f);
2243 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
2244 }
2245
2246 return;
2247#endif
2248
2249 /* Make sure we redisplay all windows in this frame. */
2172 ++windows_or_buffers_changed; 2250 ++windows_or_buffers_changed;
2173 2251
2174 delta = nlines - FRAME_TOOL_BAR_LINES (f); 2252 delta = nlines - FRAME_TOOL_BAR_LINES (f);
@@ -2185,7 +2263,7 @@ x_set_tool_bar_lines (f, value, oldval)
2185 FRAME_TOOL_BAR_LINES (f) = nlines; 2263 FRAME_TOOL_BAR_LINES (f) = nlines;
2186 x_change_window_heights (root_window, delta); 2264 x_change_window_heights (root_window, delta);
2187 adjust_glyphs (f); 2265 adjust_glyphs (f);
2188 2266
2189 /* We also have to make sure that the internal border at the top of 2267 /* We also have to make sure that the internal border at the top of
2190 the frame, below the menu bar or tool bar, is redrawn when the 2268 the frame, below the menu bar or tool bar, is redrawn when the
2191 tool bar disappears. This is so because the internal border is 2269 tool bar disappears. This is so because the internal border is
@@ -2231,7 +2309,7 @@ x_set_scroll_bar_foreground (f, value, oldval)
2231 Lisp_Object value, oldval; 2309 Lisp_Object value, oldval;
2232{ 2310{
2233 unsigned long pixel; 2311 unsigned long pixel;
2234 2312
2235 if (STRINGP (value)) 2313 if (STRINGP (value))
2236 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f)); 2314 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
2237 else 2315 else
@@ -2239,7 +2317,7 @@ x_set_scroll_bar_foreground (f, value, oldval)
2239 2317
2240 if (f->output_data.x->scroll_bar_foreground_pixel != -1) 2318 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
2241 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel); 2319 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
2242 2320
2243 f->output_data.x->scroll_bar_foreground_pixel = pixel; 2321 f->output_data.x->scroll_bar_foreground_pixel = pixel;
2244 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f)) 2322 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
2245 { 2323 {
@@ -2271,10 +2349,10 @@ x_set_scroll_bar_background (f, value, oldval)
2271 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f)); 2349 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
2272 else 2350 else
2273 pixel = -1; 2351 pixel = -1;
2274 2352
2275 if (f->output_data.x->scroll_bar_background_pixel != -1) 2353 if (f->output_data.x->scroll_bar_background_pixel != -1)
2276 unload_color (f, f->output_data.x->scroll_bar_background_pixel); 2354 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
2277 2355
2278#ifdef USE_TOOLKIT_SCROLL_BARS 2356#ifdef USE_TOOLKIT_SCROLL_BARS
2279 /* Scrollbar shadow colors. */ 2357 /* Scrollbar shadow colors. */
2280 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1) 2358 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
@@ -2297,7 +2375,7 @@ x_set_scroll_bar_background (f, value, oldval)
2297 (*condemn_scroll_bars_hook) (f); 2375 (*condemn_scroll_bars_hook) (f);
2298 if (judge_scroll_bars_hook) 2376 if (judge_scroll_bars_hook)
2299 (*judge_scroll_bars_hook) (f); 2377 (*judge_scroll_bars_hook) (f);
2300 2378
2301 update_face_from_frame_parameter (f, Qscroll_bar_background, value); 2379 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
2302 redraw_frame (f); 2380 redraw_frame (f);
2303 } 2381 }
@@ -2392,7 +2470,7 @@ x_set_name (f, name, explicit)
2392 Lisp_Object name; 2470 Lisp_Object name;
2393 int explicit; 2471 int explicit;
2394{ 2472{
2395 /* Make sure that requests from lisp code override requests from 2473 /* Make sure that requests from lisp code override requests from
2396 Emacs redisplay code. */ 2474 Emacs redisplay code. */
2397 if (explicit) 2475 if (explicit)
2398 { 2476 {
@@ -2465,8 +2543,15 @@ x_set_name (f, name, explicit)
2465 XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), 2543 XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
2466 &icon); 2544 &icon);
2467#else /* not USE_X_TOOLKIT */ 2545#else /* not USE_X_TOOLKIT */
2546#ifdef USE_GTK
2547 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
2548 SDATA (name));
2549 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
2550 &icon);
2551#else /* not USE_GTK */
2468 XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text); 2552 XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
2469 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon); 2553 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
2554#endif /* not USE_GTK */
2470#endif /* not USE_X_TOOLKIT */ 2555#endif /* not USE_X_TOOLKIT */
2471 if (!NILP (f->icon_name) 2556 if (!NILP (f->icon_name)
2472 && icon.value != (unsigned char *) SDATA (f->icon_name)) 2557 && icon.value != (unsigned char *) SDATA (f->icon_name))
@@ -2570,8 +2655,15 @@ x_set_title (f, name, old_name)
2570 XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), 2655 XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
2571 &icon); 2656 &icon);
2572#else /* not USE_X_TOOLKIT */ 2657#else /* not USE_X_TOOLKIT */
2658#ifdef USE_GTK
2659 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
2660 SDATA (name));
2661 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
2662 &icon);
2663#else /* not USE_GTK */
2573 XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text); 2664 XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
2574 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon); 2665 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
2666#endif /* not USE_GTK */
2575#endif /* not USE_X_TOOLKIT */ 2667#endif /* not USE_X_TOOLKIT */
2576 if (!NILP (f->icon_name) 2668 if (!NILP (f->icon_name)
2577 && icon.value != (unsigned char *) SDATA (f->icon_name)) 2669 && icon.value != (unsigned char *) SDATA (f->icon_name))
@@ -2627,7 +2719,7 @@ x_set_vertical_scroll_bars (f, arg, oldval)
2627 = (NILP (arg) 2719 = (NILP (arg)
2628 ? vertical_scroll_bar_none 2720 ? vertical_scroll_bar_none
2629 : EQ (Qright, arg) 2721 : EQ (Qright, arg)
2630 ? vertical_scroll_bar_right 2722 ? vertical_scroll_bar_right
2631 : vertical_scroll_bar_left); 2723 : vertical_scroll_bar_left);
2632 2724
2633 /* We set this parameter before creating the X window for the 2725 /* We set this parameter before creating the X window for the
@@ -2658,7 +2750,7 @@ x_set_scroll_bar_width (f, arg, oldval)
2658 /* Make the actual width at least 14 pixels and a multiple of a 2750 /* Make the actual width at least 14 pixels and a multiple of a
2659 character width. */ 2751 character width. */
2660 FRAME_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; 2752 FRAME_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
2661 2753
2662 /* Use all of that space (aside from required margins) for the 2754 /* Use all of that space (aside from required margins) for the
2663 scroll bar. */ 2755 scroll bar. */
2664 FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = 0; 2756 FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = 0;
@@ -2987,7 +3079,7 @@ x_get_arg (dpyinfo, alist, param, attribute, class, type)
2987 if (!strcmp (SDATA (tem), "on") 3079 if (!strcmp (SDATA (tem), "on")
2988 || !strcmp (SDATA (tem), "true")) 3080 || !strcmp (SDATA (tem), "true"))
2989 return Qt; 3081 return Qt;
2990 else 3082 else
2991 return Qnil; 3083 return Qnil;
2992 3084
2993 case RES_TYPE_STRING: 3085 case RES_TYPE_STRING:
@@ -3106,11 +3198,11 @@ x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
3106 specified. */ 3198 specified. */
3107 tem = Qnil; 3199 tem = Qnil;
3108 } 3200 }
3109 3201
3110#else /* not USE_TOOLKIT_SCROLL_BARS */ 3202#else /* not USE_TOOLKIT_SCROLL_BARS */
3111 3203
3112 tem = Qnil; 3204 tem = Qnil;
3113 3205
3114#endif /* not USE_TOOLKIT_SCROLL_BARS */ 3206#endif /* not USE_TOOLKIT_SCROLL_BARS */
3115 } 3207 }
3116 3208
@@ -3308,7 +3400,7 @@ x_figure_window_size (f, parms)
3308 { 3400 {
3309 int left, top; 3401 int left, top;
3310 int width, height; 3402 int width, height;
3311 3403
3312 /* It takes both for some WM:s to place it where we want */ 3404 /* It takes both for some WM:s to place it where we want */
3313 window_prompting = USPosition | PPosition; 3405 window_prompting = USPosition | PPosition;
3314 x_fullscreen_adjust (f, &width, &height, &top, &left); 3406 x_fullscreen_adjust (f, &width, &height, &top, &left);
@@ -3319,7 +3411,7 @@ x_figure_window_size (f, parms)
3319 f->output_data.x->left_pos = left; 3411 f->output_data.x->left_pos = left;
3320 f->output_data.x->top_pos = top; 3412 f->output_data.x->top_pos = top;
3321 } 3413 }
3322 3414
3323 return window_prompting; 3415 return window_prompting;
3324} 3416}
3325 3417
@@ -3442,13 +3534,13 @@ xic_create_xfontset (f, base_fontname)
3442 char **missing_list; 3534 char **missing_list;
3443 int missing_count; 3535 int missing_count;
3444 char *def_string; 3536 char *def_string;
3445 3537
3446 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), 3538 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
3447 base_fontname, &missing_list, 3539 base_fontname, &missing_list,
3448 &missing_count, &def_string); 3540 &missing_count, &def_string);
3449 if (missing_list) 3541 if (missing_list)
3450 XFreeStringList (missing_list); 3542 XFreeStringList (missing_list);
3451 3543
3452 /* No need to free def_string. */ 3544 /* No need to free def_string. */
3453 return xfs; 3545 return xfs;
3454} 3546}
@@ -3488,7 +3580,7 @@ create_frame_xic (f)
3488 3580
3489 if (FRAME_XIC (f)) 3581 if (FRAME_XIC (f))
3490 return; 3582 return;
3491 3583
3492 xim = FRAME_X_XIM (f); 3584 xim = FRAME_X_XIM (f);
3493 if (xim) 3585 if (xim)
3494 { 3586 {
@@ -3586,7 +3678,7 @@ create_frame_xic (f)
3586 XFree (preedit_attr); 3678 XFree (preedit_attr);
3587 XFree (status_attr); 3679 XFree (status_attr);
3588 } 3680 }
3589 3681
3590 FRAME_XIC (f) = xic; 3682 FRAME_XIC (f) = xic;
3591 FRAME_XIC_STYLE (f) = xic_style; 3683 FRAME_XIC_STYLE (f) = xic_style;
3592 FRAME_XIC_FONTSET (f) = xfs; 3684 FRAME_XIC_FONTSET (f) = xfs;
@@ -3601,7 +3693,7 @@ free_frame_xic (f)
3601{ 3693{
3602 if (FRAME_XIC (f) == NULL) 3694 if (FRAME_XIC (f) == NULL)
3603 return; 3695 return;
3604 3696
3605 XDestroyIC (FRAME_XIC (f)); 3697 XDestroyIC (FRAME_XIC (f));
3606 if (FRAME_XIC_FONTSET (f)) 3698 if (FRAME_XIC_FONTSET (f))
3607 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); 3699 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
@@ -3622,7 +3714,7 @@ xic_set_preeditarea (w, x, y)
3622 struct frame *f = XFRAME (w->frame); 3714 struct frame *f = XFRAME (w->frame);
3623 XVaNestedList attr; 3715 XVaNestedList attr;
3624 XPoint spot; 3716 XPoint spot;
3625 3717
3626 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x); 3718 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x);
3627 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f)); 3719 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
3628 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL); 3720 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
@@ -3648,7 +3740,7 @@ xic_set_statusarea (f)
3648 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL); 3740 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
3649 XSetICValues (xic, XNStatusAttributes, attr, NULL); 3741 XSetICValues (xic, XNStatusAttributes, attr, NULL);
3650 XFree (attr); 3742 XFree (attr);
3651 3743
3652 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL); 3744 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
3653 XGetICValues (xic, XNStatusAttributes, attr, NULL); 3745 XGetICValues (xic, XNStatusAttributes, attr, NULL);
3654 XFree (attr); 3746 XFree (attr);
@@ -3664,7 +3756,9 @@ xic_set_statusarea (f)
3664 area.height = needed->height; 3756 area.height = needed->height;
3665 area.x = PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f); 3757 area.x = PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
3666 area.y = (PIXEL_HEIGHT (f) - area.height 3758 area.y = (PIXEL_HEIGHT (f) - area.height
3667 - FRAME_MENUBAR_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f)); 3759 - FRAME_MENUBAR_HEIGHT (f)
3760 - FRAME_TOOLBAR_HEIGHT (f)
3761 - FRAME_INTERNAL_BORDER_WIDTH (f));
3668 XFree (needed); 3762 XFree (needed);
3669 3763
3670 attr = XVaCreateNestedList (0, XNArea, &area, NULL); 3764 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
@@ -3692,7 +3786,7 @@ xic_set_xfontset (f, base_fontname)
3692 if (FRAME_XIC_STYLE (f) & XIMStatusArea) 3786 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
3693 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL); 3787 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
3694 XFree (attr); 3788 XFree (attr);
3695 3789
3696 if (FRAME_XIC_FONTSET (f)) 3790 if (FRAME_XIC_FONTSET (f))
3697 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); 3791 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
3698 FRAME_XIC_FONTSET (f) = xfs; 3792 FRAME_XIC_FONTSET (f) = xfs;
@@ -3728,7 +3822,7 @@ x_window (f, window_prompting, minibuffer_only)
3728 for the window manager, so GC relocation won't bother it. 3822 for the window manager, so GC relocation won't bother it.
3729 3823
3730 Elsewhere we specify the window name for the window manager. */ 3824 Elsewhere we specify the window name for the window manager. */
3731 3825
3732 { 3826 {
3733 char *str = (char *) SDATA (Vx_resource_name); 3827 char *str = (char *) SDATA (Vx_resource_name);
3734 f->namebuf = (char *) xmalloc (strlen (str) + 1); 3828 f->namebuf = (char *) xmalloc (strlen (str) + 1);
@@ -3765,7 +3859,7 @@ x_window (f, window_prompting, minibuffer_only)
3765 XtSetValues (pane_widget, al, ac); 3859 XtSetValues (pane_widget, al, ac);
3766 f->output_data.x->column_widget = pane_widget; 3860 f->output_data.x->column_widget = pane_widget;
3767 3861
3768 /* mappedWhenManaged to false tells to the paned window to not map/unmap 3862 /* mappedWhenManaged to false tells to the paned window to not map/unmap
3769 the emacs screen when changing menubar. This reduces flickering. */ 3863 the emacs screen when changing menubar. This reduces flickering. */
3770 3864
3771 ac = 0; 3865 ac = 0;
@@ -3779,10 +3873,10 @@ x_window (f, window_prompting, minibuffer_only)
3779 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++; 3873 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
3780 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget, 3874 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
3781 al, ac); 3875 al, ac);
3782 3876
3783 f->output_data.x->edit_widget = frame_widget; 3877 f->output_data.x->edit_widget = frame_widget;
3784 3878
3785 XtManageChild (frame_widget); 3879 XtManageChild (frame_widget);
3786 3880
3787 /* Do some needed geometry management. */ 3881 /* Do some needed geometry management. */
3788 { 3882 {
@@ -3791,7 +3885,7 @@ x_window (f, window_prompting, minibuffer_only)
3791 Arg al[2]; 3885 Arg al[2];
3792 int ac = 0; 3886 int ac = 0;
3793 int extra_borders = 0; 3887 int extra_borders = 0;
3794 int menubar_size 3888 int menubar_size
3795 = (f->output_data.x->menubar_widget 3889 = (f->output_data.x->menubar_widget
3796 ? (f->output_data.x->menubar_widget->core.height 3890 ? (f->output_data.x->menubar_widget->core.height
3797 + f->output_data.x->menubar_widget->core.border_width) 3891 + f->output_data.x->menubar_widget->core.border_width)
@@ -3835,13 +3929,13 @@ x_window (f, window_prompting, minibuffer_only)
3835 3929
3836 if (window_prompting & USPosition) 3930 if (window_prompting & USPosition)
3837 sprintf (shell_position, "=%dx%d%c%d%c%d", 3931 sprintf (shell_position, "=%dx%d%c%d%c%d",
3838 PIXEL_WIDTH (f) + extra_borders, 3932 PIXEL_WIDTH (f) + extra_borders,
3839 PIXEL_HEIGHT (f) + menubar_size + extra_borders, 3933 PIXEL_HEIGHT (f) + menubar_size + extra_borders,
3840 (xneg ? '-' : '+'), left, 3934 (xneg ? '-' : '+'), left,
3841 (yneg ? '-' : '+'), top); 3935 (yneg ? '-' : '+'), top);
3842 else 3936 else
3843 sprintf (shell_position, "=%dx%d", 3937 sprintf (shell_position, "=%dx%d",
3844 PIXEL_WIDTH (f) + extra_borders, 3938 PIXEL_WIDTH (f) + extra_borders,
3845 PIXEL_HEIGHT (f) + menubar_size + extra_borders); 3939 PIXEL_HEIGHT (f) + menubar_size + extra_borders);
3846 } 3940 }
3847 3941
@@ -3859,7 +3953,7 @@ x_window (f, window_prompting, minibuffer_only)
3859 XtManageChild (pane_widget); 3953 XtManageChild (pane_widget);
3860 XtRealizeWidget (shell_widget); 3954 XtRealizeWidget (shell_widget);
3861 3955
3862 FRAME_X_WINDOW (f) = XtWindow (frame_widget); 3956 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
3863 3957
3864 validate_x_resource_name (); 3958 validate_x_resource_name ();
3865 3959
@@ -3906,7 +4000,7 @@ x_window (f, window_prompting, minibuffer_only)
3906 attributes.event_mask |= fevent; 4000 attributes.event_mask |= fevent;
3907 } 4001 }
3908#endif /* HAVE_X_I18N */ 4002#endif /* HAVE_X_I18N */
3909 4003
3910 attribute_mask = CWEventMask; 4004 attribute_mask = CWEventMask;
3911 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget), 4005 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
3912 attribute_mask, &attributes); 4006 attribute_mask, &attributes);
@@ -3938,7 +4032,16 @@ x_window (f, window_prompting, minibuffer_only)
3938} 4032}
3939 4033
3940#else /* not USE_X_TOOLKIT */ 4034#else /* not USE_X_TOOLKIT */
4035#ifdef USE_GTK
4036void
4037x_window (f)
4038 FRAME_PTR f;
4039{
4040 if (! xg_create_frame_widgets (f))
4041 error ("Unable to create window");
4042}
3941 4043
4044#else /*! USE_GTK */
3942/* Create and set up the X window for frame F. */ 4045/* Create and set up the X window for frame F. */
3943 4046
3944void 4047void
@@ -3988,7 +4091,7 @@ x_window (f)
3988 } 4091 }
3989#endif 4092#endif
3990#endif /* HAVE_X_I18N */ 4093#endif /* HAVE_X_I18N */
3991 4094
3992 validate_x_resource_name (); 4095 validate_x_resource_name ();
3993 4096
3994 class_hints.res_name = (char *) SDATA (Vx_resource_name); 4097 class_hints.res_name = (char *) SDATA (Vx_resource_name);
@@ -4041,6 +4144,7 @@ x_window (f)
4041 error ("Unable to create window"); 4144 error ("Unable to create window");
4042} 4145}
4043 4146
4147#endif /* not USE_GTK */
4044#endif /* not USE_X_TOOLKIT */ 4148#endif /* not USE_X_TOOLKIT */
4045 4149
4046/* Handle the icon stuff for this window. Perhaps later we might 4150/* Handle the icon stuff for this window. Perhaps later we might
@@ -4152,7 +4256,7 @@ x_make_gc (f)
4152 this must be done on a per-frame basis. */ 4256 this must be done on a per-frame basis. */
4153 f->output_data.x->border_tile 4257 f->output_data.x->border_tile
4154 = (XCreatePixmapFromBitmapData 4258 = (XCreatePixmapFromBitmapData
4155 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, 4259 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4156 gray_bits, gray_width, gray_height, 4260 gray_bits, gray_width, gray_height,
4157 f->output_data.x->foreground_pixel, 4261 f->output_data.x->foreground_pixel,
4158 f->output_data.x->background_pixel, 4262 f->output_data.x->background_pixel,
@@ -4171,7 +4275,7 @@ x_free_gcs (f)
4171 Display *dpy = FRAME_X_DISPLAY (f); 4275 Display *dpy = FRAME_X_DISPLAY (f);
4172 4276
4173 BLOCK_INPUT; 4277 BLOCK_INPUT;
4174 4278
4175 if (f->output_data.x->normal_gc) 4279 if (f->output_data.x->normal_gc)
4176 { 4280 {
4177 XFreeGC (dpy, f->output_data.x->normal_gc); 4281 XFreeGC (dpy, f->output_data.x->normal_gc);
@@ -4183,7 +4287,7 @@ x_free_gcs (f)
4183 XFreeGC (dpy, f->output_data.x->reverse_gc); 4287 XFreeGC (dpy, f->output_data.x->reverse_gc);
4184 f->output_data.x->reverse_gc = 0; 4288 f->output_data.x->reverse_gc = 0;
4185 } 4289 }
4186 4290
4187 if (f->output_data.x->cursor_gc) 4291 if (f->output_data.x->cursor_gc)
4188 { 4292 {
4189 XFreeGC (dpy, f->output_data.x->cursor_gc); 4293 XFreeGC (dpy, f->output_data.x->cursor_gc);
@@ -4216,7 +4320,7 @@ unwind_create_frame (frame)
4216#if GLYPH_DEBUG 4320#if GLYPH_DEBUG
4217 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 4321 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4218#endif 4322#endif
4219 4323
4220 x_free_frame_resources (f); 4324 x_free_frame_resources (f);
4221 4325
4222 /* Check that reference counts are indeed correct. */ 4326 /* Check that reference counts are indeed correct. */
@@ -4224,7 +4328,7 @@ unwind_create_frame (frame)
4224 xassert (dpyinfo->image_cache->refcount == image_cache_refcount); 4328 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
4225 return Qt; 4329 return Qt;
4226 } 4330 }
4227 4331
4228 return Qnil; 4332 return Qnil;
4229} 4333}
4230 4334
@@ -4355,7 +4459,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4355 f->output_data.x->cursor_foreground_pixel = -1; 4459 f->output_data.x->cursor_foreground_pixel = -1;
4356 f->output_data.x->border_pixel = -1; 4460 f->output_data.x->border_pixel = -1;
4357 f->output_data.x->mouse_pixel = -1; 4461 f->output_data.x->mouse_pixel = -1;
4358 4462
4359 black = build_string ("black"); 4463 black = build_string ("black");
4360 GCPRO1 (black); 4464 GCPRO1 (black);
4361 f->output_data.x->foreground_pixel 4465 f->output_data.x->foreground_pixel
@@ -4418,7 +4522,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4418 else 4522 else
4419 font = x_new_font (f, SDATA (font)); 4523 font = x_new_font (f, SDATA (font));
4420 } 4524 }
4421 4525
4422 /* Try out a font which we hope has bold and italic variations. */ 4526 /* Try out a font which we hope has bold and italic variations. */
4423 if (!STRINGP (font)) 4527 if (!STRINGP (font))
4424 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"); 4528 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
@@ -4449,7 +4553,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4449 4553
4450 x_default_parameter (f, parms, Qborder_width, make_number (2), 4554 x_default_parameter (f, parms, Qborder_width, make_number (2),
4451 "borderWidth", "BorderWidth", RES_TYPE_NUMBER); 4555 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4452 4556
4453 /* This defaults to 1 in order to match xterm. We recognize either 4557 /* This defaults to 1 in order to match xterm. We recognize either
4454 internalBorderWidth or internalBorder (which is what xterm calls 4558 internalBorderWidth or internalBorder (which is what xterm calls
4455 it). */ 4559 it). */
@@ -4504,7 +4608,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4504 end up in init_iterator with a null face cache, which should not 4608 end up in init_iterator with a null face cache, which should not
4505 happen. */ 4609 happen. */
4506 init_frame_faces (f); 4610 init_frame_faces (f);
4507 4611
4508 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1), 4612 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
4509 "menuBar", "MenuBar", RES_TYPE_NUMBER); 4613 "menuBar", "MenuBar", RES_TYPE_NUMBER);
4510 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1), 4614 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
@@ -4530,7 +4634,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4530 if (FRAME_TOOL_BAR_LINES (f)) 4634 if (FRAME_TOOL_BAR_LINES (f))
4531 { 4635 {
4532 int margin, relief, bar_height; 4636 int margin, relief, bar_height;
4533 4637
4534 relief = (tool_bar_button_relief >= 0 4638 relief = (tool_bar_button_relief >= 0
4535 ? tool_bar_button_relief 4639 ? tool_bar_button_relief
4536 : DEFAULT_TOOL_BAR_BUTTON_RELIEF); 4640 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
@@ -4544,7 +4648,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4544 margin = XFASTINT (XCDR (Vtool_bar_button_margin)); 4648 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4545 else 4649 else
4546 margin = 0; 4650 margin = 0;
4547 4651
4548 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; 4652 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4549 f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f); 4653 f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
4550 } 4654 }
@@ -4578,7 +4682,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4578#else 4682#else
4579 x_window (f); 4683 x_window (f);
4580#endif 4684#endif
4581 4685
4582 x_icon (f, parms); 4686 x_icon (f, parms);
4583 x_make_gc (f); 4687 x_make_gc (f);
4584 4688
@@ -4606,7 +4710,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4606 f->height. */ 4710 f->height. */
4607 width = f->width; 4711 width = f->width;
4608 height = f->height; 4712 height = f->height;
4609 4713
4610 f->height = 0; 4714 f->height = 0;
4611 SET_FRAME_WIDTH (f, 0); 4715 SET_FRAME_WIDTH (f, 0);
4612 change_frame_size (f, height, width, 1, 0, 0); 4716 change_frame_size (f, height, width, 1, 0, 0);
@@ -4618,7 +4722,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4618 new frames. */ 4722 new frames. */
4619 call1 (Qface_set_after_frame_default, frame); 4723 call1 (Qface_set_after_frame_default, frame);
4620 4724
4621#ifdef USE_X_TOOLKIT 4725#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4622 /* Create the menu bar. */ 4726 /* Create the menu bar. */
4623 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) 4727 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
4624 { 4728 {
@@ -4626,13 +4730,15 @@ This function is an internal primitive--use `make-frame' instead. */)
4626 frame and we didn't make it visible. */ 4730 frame and we didn't make it visible. */
4627 initialize_frame_menubar (f); 4731 initialize_frame_menubar (f);
4628 4732
4733#ifndef USE_GTK
4629 /* This is a no-op, except under Motif where it arranges the 4734 /* This is a no-op, except under Motif where it arranges the
4630 main window for the widgets on it. */ 4735 main window for the widgets on it. */
4631 lw_set_main_areas (f->output_data.x->column_widget, 4736 lw_set_main_areas (f->output_data.x->column_widget,
4632 f->output_data.x->menubar_widget, 4737 f->output_data.x->menubar_widget,
4633 f->output_data.x->edit_widget); 4738 f->output_data.x->edit_widget);
4739#endif /* not USE_GTK */
4634 } 4740 }
4635#endif /* USE_X_TOOLKIT */ 4741#endif /* USE_X_TOOLKIT || USE_GTK */
4636 4742
4637 /* Tell the server what size and position, etc, we want, and how 4743 /* Tell the server what size and position, etc, we want, and how
4638 badly we want them. This should be done after we have the menu 4744 badly we want them. This should be done after we have the menu
@@ -4667,7 +4773,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4667 /* Make sure windows on this frame appear in calls to next-window 4773 /* Make sure windows on this frame appear in calls to next-window
4668 and similar functions. */ 4774 and similar functions. */
4669 Vwindow_list = Qnil; 4775 Vwindow_list = Qnil;
4670 4776
4671 return unbind_to (count, frame); 4777 return unbind_to (count, frame);
4672} 4778}
4673 4779
@@ -4715,7 +4821,7 @@ FRAME nil means use the selected frame. */)
4715 RevertToParent, CurrentTime); 4821 RevertToParent, CurrentTime);
4716 x_uncatch_errors (dpy, count); 4822 x_uncatch_errors (dpy, count);
4717 UNBLOCK_INPUT; 4823 UNBLOCK_INPUT;
4718 4824
4719 return Qnil; 4825 return Qnil;
4720} 4826}
4721 4827
@@ -5032,7 +5138,7 @@ If omitted or nil, that stands for the selected frame's display. */)
5032 error ("Display has an unknown visual class"); 5138 error ("Display has an unknown visual class");
5033 result = Qnil; 5139 result = Qnil;
5034 } 5140 }
5035 5141
5036 return result; 5142 return result;
5037} 5143}
5038 5144
@@ -5187,14 +5293,14 @@ select_visual (dpyinfo)
5187 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen), 5293 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
5188 dpyinfo->n_planes, class, &vinfo)) 5294 dpyinfo->n_planes, class, &vinfo))
5189 fatal ("Invalid visual specification `%s'", SDATA (value)); 5295 fatal ("Invalid visual specification `%s'", SDATA (value));
5190 5296
5191 dpyinfo->visual = vinfo.visual; 5297 dpyinfo->visual = vinfo.visual;
5192 } 5298 }
5193 else 5299 else
5194 { 5300 {
5195 int n_visuals; 5301 int n_visuals;
5196 XVisualInfo *vinfo, vinfo_template; 5302 XVisualInfo *vinfo, vinfo_template;
5197 5303
5198 dpyinfo->visual = DefaultVisualOfScreen (screen); 5304 dpyinfo->visual = DefaultVisualOfScreen (screen);
5199 5305
5200#ifdef HAVE_X11R4 5306#ifdef HAVE_X11R4
@@ -5488,7 +5594,7 @@ valid_image_p (object)
5488 Lisp_Object object; 5594 Lisp_Object object;
5489{ 5595{
5490 int valid_p = 0; 5596 int valid_p = 0;
5491 5597
5492 if (CONSP (object) && EQ (XCAR (object), Qimage)) 5598 if (CONSP (object) && EQ (XCAR (object), Qimage))
5493 { 5599 {
5494 Lisp_Object tem; 5600 Lisp_Object tem;
@@ -5504,7 +5610,7 @@ valid_image_p (object)
5504 if (type) 5610 if (type)
5505 valid_p = type->valid_p (object); 5611 valid_p = type->valid_p (object);
5506 } 5612 }
5507 5613
5508 break; 5614 break;
5509 } 5615 }
5510 } 5616 }
@@ -5623,7 +5729,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
5623 was found more than once, it's an error. */ 5729 was found more than once, it's an error. */
5624 keywords[i].value = value; 5730 keywords[i].value = value;
5625 ++keywords[i].count; 5731 ++keywords[i].count;
5626 5732
5627 if (keywords[i].count > 1) 5733 if (keywords[i].count > 1)
5628 return 0; 5734 return 0;
5629 5735
@@ -5667,7 +5773,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
5667 && XINT (value) <= 100) 5773 && XINT (value) <= 100)
5668 break; 5774 break;
5669 return 0; 5775 return 0;
5670 5776
5671 case IMAGE_NON_NEGATIVE_INTEGER_VALUE: 5777 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
5672 if (!INTEGERP (value) || XINT (value) < 0) 5778 if (!INTEGERP (value) || XINT (value) < 0)
5673 return 0; 5779 return 0;
@@ -5678,7 +5784,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
5678 5784
5679 case IMAGE_FUNCTION_VALUE: 5785 case IMAGE_FUNCTION_VALUE:
5680 value = indirect_function (value); 5786 value = indirect_function (value);
5681 if (SUBRP (value) 5787 if (SUBRP (value)
5682 || COMPILEDP (value) 5788 || COMPILEDP (value)
5683 || (CONSP (value) && EQ (XCAR (value), Qlambda))) 5789 || (CONSP (value) && EQ (XCAR (value), Qlambda)))
5684 break; 5790 break;
@@ -5727,7 +5833,7 @@ image_spec_value (spec, key, found)
5727 int *found; 5833 int *found;
5728{ 5834{
5729 Lisp_Object tail; 5835 Lisp_Object tail;
5730 5836
5731 xassert (valid_image_p (spec)); 5837 xassert (valid_image_p (spec));
5732 5838
5733 for (tail = XCDR (spec); 5839 for (tail = XCDR (spec);
@@ -5741,12 +5847,12 @@ image_spec_value (spec, key, found)
5741 return XCAR (XCDR (tail)); 5847 return XCAR (XCDR (tail));
5742 } 5848 }
5743 } 5849 }
5744 5850
5745 if (found) 5851 if (found)
5746 *found = 0; 5852 *found = 0;
5747 return Qnil; 5853 return Qnil;
5748} 5854}
5749 5855
5750 5856
5751DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0, 5857DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
5752 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT). 5858 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
@@ -5767,7 +5873,7 @@ or omitted means use the selected frame. */)
5767 struct image *img = IMAGE_FROM_ID (f, id); 5873 struct image *img = IMAGE_FROM_ID (f, id);
5768 int width = img->width + 2 * img->hmargin; 5874 int width = img->width + 2 * img->hmargin;
5769 int height = img->height + 2 * img->vmargin; 5875 int height = img->height + 2 * img->vmargin;
5770 5876
5771 if (NILP (pixels)) 5877 if (NILP (pixels))
5772 size = Fcons (make_float ((double) width / CANON_X_UNIT (f)), 5878 size = Fcons (make_float ((double) width / CANON_X_UNIT (f)),
5773 make_float ((double) height / CANON_Y_UNIT (f))); 5879 make_float ((double) height / CANON_Y_UNIT (f)));
@@ -5824,7 +5930,7 @@ make_image (spec, hash)
5824 unsigned hash; 5930 unsigned hash;
5825{ 5931{
5826 struct image *img = (struct image *) xmalloc (sizeof *img); 5932 struct image *img = (struct image *) xmalloc (sizeof *img);
5827 5933
5828 xassert (valid_image_p (spec)); 5934 xassert (valid_image_p (spec));
5829 bzero (img, sizeof *img); 5935 bzero (img, sizeof *img);
5830 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); 5936 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
@@ -5885,7 +5991,7 @@ prepare_image_for_display (f, img)
5885 if (img->pixmap == None && !img->load_failed_p) 5991 if (img->pixmap == None && !img->load_failed_p)
5886 img->load_failed_p = img->type->load (f, img) == 0; 5992 img->load_failed_p = img->type->load (f, img) == 0;
5887} 5993}
5888 5994
5889 5995
5890/* Value is the number of pixels for the ascent of image IMG when 5996/* Value is the number of pixels for the ascent of image IMG when
5891 drawn in face FACE. */ 5997 drawn in face FACE. */
@@ -5937,7 +6043,7 @@ four_corners_best (ximg, width, height)
5937 for (i = best_count = 0; i < 4; ++i) 6043 for (i = best_count = 0; i < 4; ++i)
5938 { 6044 {
5939 int j, n; 6045 int j, n;
5940 6046
5941 for (j = n = 0; j < 4; ++j) 6047 for (j = n = 0; j < 4; ++j)
5942 if (corners[i] == corners[j]) 6048 if (corners[i] == corners[j])
5943 ++n; 6049 ++n;
@@ -6053,7 +6159,7 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
6053 img->mask = None; 6159 img->mask = None;
6054 img->background_transparent_valid = 0; 6160 img->background_transparent_valid = 0;
6055 } 6161 }
6056 6162
6057 if (colors_p && img->ncolors) 6163 if (colors_p && img->ncolors)
6058 { 6164 {
6059 x_free_colors (f, img->colors, img->ncolors); 6165 x_free_colors (f, img->colors, img->ncolors);
@@ -6128,7 +6234,7 @@ make_image_cache ()
6128{ 6234{
6129 struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c); 6235 struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
6130 int size; 6236 int size;
6131 6237
6132 bzero (c, sizeof *c); 6238 bzero (c, sizeof *c);
6133 c->size = 50; 6239 c->size = 50;
6134 c->images = (struct image **) xmalloc (c->size * sizeof *c->images); 6240 c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
@@ -6153,7 +6259,7 @@ free_image_cache (f)
6153 6259
6154 /* Cache should not be referenced by any frame when freed. */ 6260 /* Cache should not be referenced by any frame when freed. */
6155 xassert (c->refcount == 0); 6261 xassert (c->refcount == 0);
6156 6262
6157 for (i = 0; i < c->used; ++i) 6263 for (i = 0; i < c->used; ++i)
6158 free_image (f, c->images[i]); 6264 free_image (f, c->images[i]);
6159 xfree (c->images); 6265 xfree (c->images);
@@ -6190,7 +6296,7 @@ clear_image_cache (f, force_p)
6190 /* Block input so that we won't be interrupted by a SIGIO 6296 /* Block input so that we won't be interrupted by a SIGIO
6191 while being in an inconsistent state. */ 6297 while being in an inconsistent state. */
6192 BLOCK_INPUT; 6298 BLOCK_INPUT;
6193 6299
6194 for (i = nfreed = 0; i < c->used; ++i) 6300 for (i = nfreed = 0; i < c->used; ++i)
6195 { 6301 {
6196 struct image *img = c->images[i]; 6302 struct image *img = c->images[i];
@@ -6209,7 +6315,7 @@ clear_image_cache (f, force_p)
6209 if (nfreed) 6315 if (nfreed)
6210 { 6316 {
6211 Lisp_Object tail, frame; 6317 Lisp_Object tail, frame;
6212 6318
6213 FOR_EACH_FRAME (tail, frame) 6319 FOR_EACH_FRAME (tail, frame)
6214 { 6320 {
6215 struct frame *f = XFRAME (frame); 6321 struct frame *f = XFRAME (frame);
@@ -6237,7 +6343,7 @@ FRAME t means clear the image caches of all frames. */)
6237 if (EQ (frame, Qt)) 6343 if (EQ (frame, Qt))
6238 { 6344 {
6239 Lisp_Object tail; 6345 Lisp_Object tail;
6240 6346
6241 FOR_EACH_FRAME (tail, frame) 6347 FOR_EACH_FRAME (tail, frame)
6242 if (FRAME_X_P (XFRAME (frame))) 6348 if (FRAME_X_P (XFRAME (frame)))
6243 clear_image_cache (XFRAME (frame), 1); 6349 clear_image_cache (XFRAME (frame), 1);
@@ -6264,7 +6370,7 @@ postprocess_image (f, img)
6264 Lisp_Object mask; 6370 Lisp_Object mask;
6265 6371
6266 spec = img->spec; 6372 spec = img->spec;
6267 6373
6268 /* `:heuristic-mask t' 6374 /* `:heuristic-mask t'
6269 `:mask heuristic' 6375 `:mask heuristic'
6270 means build a mask heuristically. 6376 means build a mask heuristically.
@@ -6274,16 +6380,16 @@ postprocess_image (f, img)
6274 image. 6380 image.
6275 `:mask nil' 6381 `:mask nil'
6276 means remove a mask, if any. */ 6382 means remove a mask, if any. */
6277 6383
6278 mask = image_spec_value (spec, QCheuristic_mask, NULL); 6384 mask = image_spec_value (spec, QCheuristic_mask, NULL);
6279 if (!NILP (mask)) 6385 if (!NILP (mask))
6280 x_build_heuristic_mask (f, img, mask); 6386 x_build_heuristic_mask (f, img, mask);
6281 else 6387 else
6282 { 6388 {
6283 int found_p; 6389 int found_p;
6284 6390
6285 mask = image_spec_value (spec, QCmask, &found_p); 6391 mask = image_spec_value (spec, QCmask, &found_p);
6286 6392
6287 if (EQ (mask, Qheuristic)) 6393 if (EQ (mask, Qheuristic))
6288 x_build_heuristic_mask (f, img, Qt); 6394 x_build_heuristic_mask (f, img, Qt);
6289 else if (CONSP (mask) 6395 else if (CONSP (mask)
@@ -6300,8 +6406,8 @@ postprocess_image (f, img)
6300 img->mask = None; 6406 img->mask = None;
6301 } 6407 }
6302 } 6408 }
6303 6409
6304 6410
6305 /* Should we apply an image transformation algorithm? */ 6411 /* Should we apply an image transformation algorithm? */
6306 conversion = image_spec_value (spec, QCconversion, NULL); 6412 conversion = image_spec_value (spec, QCconversion, NULL);
6307 if (EQ (conversion, Qdisabled)) 6413 if (EQ (conversion, Qdisabled))
@@ -6343,7 +6449,7 @@ lookup_image (f, spec)
6343 specification. */ 6449 specification. */
6344 xassert (FRAME_WINDOW_P (f)); 6450 xassert (FRAME_WINDOW_P (f));
6345 xassert (valid_image_p (spec)); 6451 xassert (valid_image_p (spec));
6346 6452
6347 GCPRO1 (spec); 6453 GCPRO1 (spec);
6348 6454
6349 /* Look up SPEC in the hash table of the image cache. */ 6455 /* Look up SPEC in the hash table of the image cache. */
@@ -6358,7 +6464,7 @@ lookup_image (f, spec)
6358 if (img == NULL) 6464 if (img == NULL)
6359 { 6465 {
6360 extern Lisp_Object Qpostscript; 6466 extern Lisp_Object Qpostscript;
6361 6467
6362 BLOCK_INPUT; 6468 BLOCK_INPUT;
6363 img = make_image (spec, hash); 6469 img = make_image (spec, hash);
6364 cache_image (f, img); 6470 cache_image (f, img);
@@ -6390,7 +6496,7 @@ lookup_image (f, spec)
6390 img->ascent = XFASTINT (ascent); 6496 img->ascent = XFASTINT (ascent);
6391 else if (EQ (ascent, Qcenter)) 6497 else if (EQ (ascent, Qcenter))
6392 img->ascent = CENTERED_IMAGE_ASCENT; 6498 img->ascent = CENTERED_IMAGE_ASCENT;
6393 6499
6394 margin = image_spec_value (spec, QCmargin, NULL); 6500 margin = image_spec_value (spec, QCmargin, NULL);
6395 if (INTEGERP (margin) && XINT (margin) >= 0) 6501 if (INTEGERP (margin) && XINT (margin) >= 0)
6396 img->vmargin = img->hmargin = XFASTINT (margin); 6502 img->vmargin = img->hmargin = XFASTINT (margin);
@@ -6402,7 +6508,7 @@ lookup_image (f, spec)
6402 if (XINT (XCDR (margin)) > 0) 6508 if (XINT (XCDR (margin)) > 0)
6403 img->vmargin = XFASTINT (XCDR (margin)); 6509 img->vmargin = XFASTINT (XCDR (margin));
6404 } 6510 }
6405 6511
6406 relief = image_spec_value (spec, QCrelief, NULL); 6512 relief = image_spec_value (spec, QCrelief, NULL);
6407 if (INTEGERP (relief)) 6513 if (INTEGERP (relief))
6408 { 6514 {
@@ -6436,9 +6542,9 @@ lookup_image (f, spec)
6436 /* We're using IMG, so set its timestamp to `now'. */ 6542 /* We're using IMG, so set its timestamp to `now'. */
6437 EMACS_GET_TIME (now); 6543 EMACS_GET_TIME (now);
6438 img->timestamp = EMACS_SECS (now); 6544 img->timestamp = EMACS_SECS (now);
6439 6545
6440 UNGCPRO; 6546 UNGCPRO;
6441 6547
6442 /* Value is the image id. */ 6548 /* Value is the image id. */
6443 return img->id; 6549 return img->id;
6444} 6550}
@@ -6590,7 +6696,7 @@ x_put_x_image (f, ximg, pixmap, width, height)
6590 int width, height; 6696 int width, height;
6591{ 6697{
6592 GC gc; 6698 GC gc;
6593 6699
6594 xassert (interrupt_input_blocked); 6700 xassert (interrupt_input_blocked);
6595 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL); 6701 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
6596 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height); 6702 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
@@ -6625,7 +6731,7 @@ x_find_image_file (file)
6625 6731
6626 /* Try to find FILE in data-directory, then x-bitmap-file-path. */ 6732 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
6627 fd = openp (search_path, file, Qnil, &file_found, Qnil); 6733 fd = openp (search_path, file, Qnil, &file_found, Qnil);
6628 6734
6629 if (fd == -1) 6735 if (fd == -1)
6630 file_found = Qnil; 6736 file_found = Qnil;
6631 else 6737 else
@@ -6667,7 +6773,7 @@ slurp_file (file, size)
6667 buf = NULL; 6773 buf = NULL;
6668 } 6774 }
6669 } 6775 }
6670 6776
6671 return buf; 6777 return buf;
6672} 6778}
6673 6779
@@ -6746,7 +6852,7 @@ enum xbm_token
6746 XBM_TK_NUMBER 6852 XBM_TK_NUMBER
6747}; 6853};
6748 6854
6749 6855
6750/* Return non-zero if OBJECT is a valid XBM-type image specification. 6856/* Return non-zero if OBJECT is a valid XBM-type image specification.
6751 A valid specification is a list starting with the symbol `image' 6857 A valid specification is a list starting with the symbol `image'
6752 The rest of the list is a property list which must contain an 6858 The rest of the list is a property list which must contain an
@@ -6781,7 +6887,7 @@ xbm_image_p (object)
6781 Lisp_Object object; 6887 Lisp_Object object;
6782{ 6888{
6783 struct image_keyword kw[XBM_LAST]; 6889 struct image_keyword kw[XBM_LAST];
6784 6890
6785 bcopy (xbm_format, kw, sizeof kw); 6891 bcopy (xbm_format, kw, sizeof kw);
6786 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm)) 6892 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
6787 return 0; 6893 return 0;
@@ -6813,13 +6919,13 @@ xbm_image_p (object)
6813 data = kw[XBM_DATA].value; 6919 data = kw[XBM_DATA].value;
6814 width = XFASTINT (kw[XBM_WIDTH].value); 6920 width = XFASTINT (kw[XBM_WIDTH].value);
6815 height = XFASTINT (kw[XBM_HEIGHT].value); 6921 height = XFASTINT (kw[XBM_HEIGHT].value);
6816 6922
6817 /* Check type of data, and width and height against contents of 6923 /* Check type of data, and width and height against contents of
6818 data. */ 6924 data. */
6819 if (VECTORP (data)) 6925 if (VECTORP (data))
6820 { 6926 {
6821 int i; 6927 int i;
6822 6928
6823 /* Number of elements of the vector must be >= height. */ 6929 /* Number of elements of the vector must be >= height. */
6824 if (XVECTOR (data)->size < height) 6930 if (XVECTOR (data)->size < height)
6825 return 0; 6931 return 0;
@@ -6879,7 +6985,7 @@ xbm_scan (s, end, sval, ival)
6879 int c; 6985 int c;
6880 6986
6881 loop: 6987 loop:
6882 6988
6883 /* Skip white space. */ 6989 /* Skip white space. */
6884 while (*s < end && (c = *(*s)++, isspace (c))) 6990 while (*s < end && (c = *(*s)++, isspace (c)))
6885 ; 6991 ;
@@ -6889,7 +6995,7 @@ xbm_scan (s, end, sval, ival)
6889 else if (isdigit (c)) 6995 else if (isdigit (c))
6890 { 6996 {
6891 int value = 0, digit; 6997 int value = 0, digit;
6892 6998
6893 if (c == '0' && *s < end) 6999 if (c == '0' && *s < end)
6894 { 7000 {
6895 c = *(*s)++; 7001 c = *(*s)++;
@@ -6987,7 +7093,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
6987 if (LA1 != (TOKEN)) \ 7093 if (LA1 != (TOKEN)) \
6988 goto failure; \ 7094 goto failure; \
6989 else \ 7095 else \
6990 match () 7096 match ()
6991 7097
6992#define expect_ident(IDENT) \ 7098#define expect_ident(IDENT) \
6993 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ 7099 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
@@ -7030,7 +7136,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
7030 { 7136 {
7031 if (strcmp (buffer, "unsigned") == 0) 7137 if (strcmp (buffer, "unsigned") == 0)
7032 { 7138 {
7033 match (); 7139 match ();
7034 expect_ident ("char"); 7140 expect_ident ("char");
7035 } 7141 }
7036 else if (strcmp (buffer, "short") == 0) 7142 else if (strcmp (buffer, "short") == 0)
@@ -7045,7 +7151,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
7045 else 7151 else
7046 goto failure; 7152 goto failure;
7047 } 7153 }
7048 else 7154 else
7049 goto failure; 7155 goto failure;
7050 7156
7051 expect (XBM_TK_IDENT); 7157 expect (XBM_TK_IDENT);
@@ -7068,7 +7174,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
7068 *p++ = val; 7174 *p++ = val;
7069 if (!padding_p || ((i + 2) % bytes_per_line)) 7175 if (!padding_p || ((i + 2) % bytes_per_line))
7070 *p++ = value >> 8; 7176 *p++ = value >> 8;
7071 7177
7072 if (LA1 == ',' || LA1 == '}') 7178 if (LA1 == ',' || LA1 == '}')
7073 match (); 7179 match ();
7074 else 7180 else
@@ -7081,9 +7187,9 @@ xbm_read_bitmap_data (contents, end, width, height, data)
7081 { 7187 {
7082 int val = value; 7188 int val = value;
7083 expect (XBM_TK_NUMBER); 7189 expect (XBM_TK_NUMBER);
7084 7190
7085 *p++ = val; 7191 *p++ = val;
7086 7192
7087 if (LA1 == ',' || LA1 == '}') 7193 if (LA1 == ',' || LA1 == '}')
7088 match (); 7194 match ();
7089 else 7195 else
@@ -7095,7 +7201,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
7095 return 1; 7201 return 1;
7096 7202
7097 failure: 7203 failure:
7098 7204
7099 if (data && *data) 7205 if (data && *data)
7100 { 7206 {
7101 xfree (*data); 7207 xfree (*data);
@@ -7122,7 +7228,7 @@ xbm_load_image (f, img, contents, end)
7122 int rc; 7228 int rc;
7123 unsigned char *data; 7229 unsigned char *data;
7124 int success_p = 0; 7230 int success_p = 0;
7125 7231
7126 rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); 7232 rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data);
7127 if (rc) 7233 if (rc)
7128 { 7234 {
@@ -7130,7 +7236,7 @@ xbm_load_image (f, img, contents, end)
7130 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); 7236 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
7131 unsigned long background = FRAME_BACKGROUND_PIXEL (f); 7237 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
7132 Lisp_Object value; 7238 Lisp_Object value;
7133 7239
7134 xassert (img->width > 0 && img->height > 0); 7240 xassert (img->width > 0 && img->height > 0);
7135 7241
7136 /* Get foreground and background colors, maybe allocate colors. */ 7242 /* Get foreground and background colors, maybe allocate colors. */
@@ -7183,7 +7289,7 @@ xbm_file_p (data)
7183 &w, &h, NULL)); 7289 &w, &h, NULL));
7184} 7290}
7185 7291
7186 7292
7187/* Fill image IMG which is used on frame F with pixmap data. Value is 7293/* Fill image IMG which is used on frame F with pixmap data. Value is
7188 non-zero if successful. */ 7294 non-zero if successful. */
7189 7295
@@ -7205,7 +7311,7 @@ xbm_load (f, img)
7205 char *contents; 7311 char *contents;
7206 int size; 7312 int size;
7207 struct gcpro gcpro1; 7313 struct gcpro gcpro1;
7208 7314
7209 file = x_find_image_file (file_name); 7315 file = x_find_image_file (file_name);
7210 GCPRO1 (file); 7316 GCPRO1 (file);
7211 if (!STRINGP (file)) 7317 if (!STRINGP (file))
@@ -7275,7 +7381,7 @@ xbm_load (f, img)
7275 int i; 7381 int i;
7276 char *p; 7382 char *p;
7277 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; 7383 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
7278 7384
7279 p = bits = (char *) alloca (nbytes * img->height); 7385 p = bits = (char *) alloca (nbytes * img->height);
7280 for (i = 0; i < img->height; ++i, p += nbytes) 7386 for (i = 0; i < img->height; ++i, p += nbytes)
7281 { 7387 {
@@ -7313,14 +7419,14 @@ xbm_load (f, img)
7313 7419
7314 return success_p; 7420 return success_p;
7315} 7421}
7316 7422
7317 7423
7318 7424
7319/*********************************************************************** 7425/***********************************************************************
7320 XPM images 7426 XPM images
7321 ***********************************************************************/ 7427 ***********************************************************************/
7322 7428
7323#if HAVE_XPM 7429#if HAVE_XPM
7324 7430
7325static int xpm_image_p P_ ((Lisp_Object object)); 7431static int xpm_image_p P_ ((Lisp_Object object));
7326static int xpm_load P_ ((struct frame *f, struct image *img)); 7432static int xpm_load P_ ((struct frame *f, struct image *img));
@@ -7437,7 +7543,7 @@ xpm_init_color_cache (f, attrs)
7437 { 7543 {
7438 int i; 7544 int i;
7439 XColor color; 7545 XColor color;
7440 7546
7441 for (i = 0; i < attrs->numsymbols; ++i) 7547 for (i = 0; i < attrs->numsymbols; ++i)
7442 if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), 7548 if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
7443 attrs->colorsymbols[i].value, &color)) 7549 attrs->colorsymbols[i].value, &color))
@@ -7480,7 +7586,7 @@ xpm_color_bucket (color_name)
7480{ 7586{
7481 unsigned h = 0; 7587 unsigned h = 0;
7482 char *s; 7588 char *s;
7483 7589
7484 for (s = color_name; *s; ++s) 7590 for (s = color_name; *s; ++s)
7485 h = (h << 2) ^ *s; 7591 h = (h << 2) ^ *s;
7486 return h %= XPM_COLOR_CACHE_BUCKETS; 7592 return h %= XPM_COLOR_CACHE_BUCKETS;
@@ -7500,10 +7606,10 @@ xpm_cache_color (f, color_name, color, bucket)
7500{ 7606{
7501 size_t nbytes; 7607 size_t nbytes;
7502 struct xpm_cached_color *p; 7608 struct xpm_cached_color *p;
7503 7609
7504 if (bucket < 0) 7610 if (bucket < 0)
7505 bucket = xpm_color_bucket (color_name); 7611 bucket = xpm_color_bucket (color_name);
7506 7612
7507 nbytes = sizeof *p + strlen (color_name); 7613 nbytes = sizeof *p + strlen (color_name);
7508 p = (struct xpm_cached_color *) xmalloc (nbytes); 7614 p = (struct xpm_cached_color *) xmalloc (nbytes);
7509 strcpy (p->name, color_name); 7615 strcpy (p->name, color_name);
@@ -7541,7 +7647,7 @@ xpm_lookup_color (f, color_name, color)
7541 color->blue); 7647 color->blue);
7542 p = xpm_cache_color (f, color_name, color, h); 7648 p = xpm_cache_color (f, color_name, color, h);
7543 } 7649 }
7544 7650
7545 return p != NULL; 7651 return p != NULL;
7546} 7652}
7547 7653
@@ -7668,7 +7774,7 @@ xpm_load (f, img)
7668 Lisp_Object tail; 7774 Lisp_Object tail;
7669 XpmColorSymbol *xpm_syms; 7775 XpmColorSymbol *xpm_syms;
7670 int i, size; 7776 int i, size;
7671 7777
7672 attrs.valuemask |= XpmColorSymbols; 7778 attrs.valuemask |= XpmColorSymbols;
7673 7779
7674 /* Count number of symbols. */ 7780 /* Count number of symbols. */
@@ -7701,7 +7807,7 @@ xpm_load (f, img)
7701#ifdef ALLOC_XPM_COLORS 7807#ifdef ALLOC_XPM_COLORS
7702 xpm_init_color_cache (f, &attrs); 7808 xpm_init_color_cache (f, &attrs);
7703#endif 7809#endif
7704 7810
7705 specified_file = image_spec_value (img->spec, QCfile, NULL); 7811 specified_file = image_spec_value (img->spec, QCfile, NULL);
7706 if (STRINGP (specified_file)) 7812 if (STRINGP (specified_file))
7707 { 7813 {
@@ -7711,7 +7817,7 @@ xpm_load (f, img)
7711 image_error ("Cannot find image file `%s'", specified_file, Qnil); 7817 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7712 return 0; 7818 return 0;
7713 } 7819 }
7714 7820
7715 rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 7821 rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7716 SDATA (file), &img->pixmap, &img->mask, 7822 SDATA (file), &img->pixmap, &img->mask,
7717 &attrs); 7823 &attrs);
@@ -7758,19 +7864,19 @@ xpm_load (f, img)
7758 case XpmOpenFailed: 7864 case XpmOpenFailed:
7759 image_error ("Error opening XPM file (%s)", img->spec, Qnil); 7865 image_error ("Error opening XPM file (%s)", img->spec, Qnil);
7760 break; 7866 break;
7761 7867
7762 case XpmFileInvalid: 7868 case XpmFileInvalid:
7763 image_error ("Invalid XPM file (%s)", img->spec, Qnil); 7869 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
7764 break; 7870 break;
7765 7871
7766 case XpmNoMemory: 7872 case XpmNoMemory:
7767 image_error ("Out of memory (%s)", img->spec, Qnil); 7873 image_error ("Out of memory (%s)", img->spec, Qnil);
7768 break; 7874 break;
7769 7875
7770 case XpmColorFailed: 7876 case XpmColorFailed:
7771 image_error ("Color allocation error (%s)", img->spec, Qnil); 7877 image_error ("Color allocation error (%s)", img->spec, Qnil);
7772 break; 7878 break;
7773 7879
7774 default: 7880 default:
7775 image_error ("Unknown error (%s)", img->spec, Qnil); 7881 image_error ("Unknown error (%s)", img->spec, Qnil);
7776 break; 7882 break;
@@ -7876,14 +7982,14 @@ lookup_rgb_color (f, r, g, b)
7876 color.red = r; 7982 color.red = r;
7877 color.green = g; 7983 color.green = g;
7878 color.blue = b; 7984 color.blue = b;
7879 7985
7880 cmap = FRAME_X_COLORMAP (f); 7986 cmap = FRAME_X_COLORMAP (f);
7881 rc = x_alloc_nearest_color (f, cmap, &color); 7987 rc = x_alloc_nearest_color (f, cmap, &color);
7882 7988
7883 if (rc) 7989 if (rc)
7884 { 7990 {
7885 ++ct_colors_allocated; 7991 ++ct_colors_allocated;
7886 7992
7887 p = (struct ct_color *) xmalloc (sizeof *p); 7993 p = (struct ct_color *) xmalloc (sizeof *p);
7888 p->r = r; 7994 p->r = r;
7889 p->g = g; 7995 p->g = g;
@@ -7929,7 +8035,7 @@ lookup_pixel_color (f, pixel)
7929 if (rc) 8035 if (rc)
7930 { 8036 {
7931 ++ct_colors_allocated; 8037 ++ct_colors_allocated;
7932 8038
7933 p = (struct ct_color *) xmalloc (sizeof *p); 8039 p = (struct ct_color *) xmalloc (sizeof *p);
7934 p->r = color.red; 8040 p->r = color.red;
7935 p->g = color.green; 8041 p->g = color.green;
@@ -7941,7 +8047,7 @@ lookup_pixel_color (f, pixel)
7941 else 8047 else
7942 return FRAME_FOREGROUND_PIXEL (f); 8048 return FRAME_FOREGROUND_PIXEL (f);
7943 } 8049 }
7944 8050
7945 return p->pixel; 8051 return p->pixel;
7946} 8052}
7947 8053
@@ -7967,7 +8073,7 @@ colors_in_color_table (n)
7967 colors = (unsigned long *) xmalloc (ct_colors_allocated 8073 colors = (unsigned long *) xmalloc (ct_colors_allocated
7968 * sizeof *colors); 8074 * sizeof *colors);
7969 *n = ct_colors_allocated; 8075 *n = ct_colors_allocated;
7970 8076
7971 for (i = j = 0; i < CT_SIZE; ++i) 8077 for (i = j = 0; i < CT_SIZE; ++i)
7972 for (p = ct_table[i]; p; p = p->next) 8078 for (p = ct_table[i]; p; p = p->next)
7973 colors[j++] = p->pixel; 8079 colors[j++] = p->pixel;
@@ -8042,7 +8148,7 @@ x_to_xcolors (f, img, rgb_p)
8042 for (y = 0; y < img->height; ++y) 8148 for (y = 0; y < img->height; ++y)
8043 { 8149 {
8044 XColor *row = p; 8150 XColor *row = p;
8045 8151
8046 for (x = 0; x < img->width; ++x, ++p) 8152 for (x = 0; x < img->width; ++x, ++p)
8047 p->pixel = XGetPixel (ximg, x, y); 8153 p->pixel = XGetPixel (ximg, x, y);
8048 8154
@@ -8069,9 +8175,9 @@ x_from_xcolors (f, img, colors)
8069 XImage *oimg; 8175 XImage *oimg;
8070 Pixmap pixmap; 8176 Pixmap pixmap;
8071 XColor *p; 8177 XColor *p;
8072 8178
8073 init_color_table (); 8179 init_color_table ();
8074 8180
8075 x_create_x_image_and_pixmap (f, img->width, img->height, 0, 8181 x_create_x_image_and_pixmap (f, img->width, img->height, 0,
8076 &oimg, &pixmap); 8182 &oimg, &pixmap);
8077 p = colors; 8183 p = colors;
@@ -8098,7 +8204,7 @@ x_from_xcolors (f, img, colors)
8098 8204
8099 MATRIX is a nine-element array specifying the transformation 8205 MATRIX is a nine-element array specifying the transformation
8100 matrix. See emboss_matrix for an example. 8206 matrix. See emboss_matrix for an example.
8101 8207
8102 COLOR_ADJUST is a color adjustment added to each pixel of the 8208 COLOR_ADJUST is a color adjustment added to each pixel of the
8103 outgoing image. */ 8209 outgoing image. */
8104 8210
@@ -8126,7 +8232,7 @@ x_detect_edges (f, img, matrix, color_adjust)
8126 p = COLOR (new, img->width - 1, y); 8232 p = COLOR (new, img->width - 1, y);
8127 p->red = p->green = p->blue = 0xffff/2; 8233 p->red = p->green = p->blue = 0xffff/2;
8128 } 8234 }
8129 8235
8130 for (x = 1; x < img->width - 1; ++x) 8236 for (x = 1; x < img->width - 1; ++x)
8131 { 8237 {
8132 p = COLOR (new, x, 0); 8238 p = COLOR (new, x, 0);
@@ -8138,7 +8244,7 @@ x_detect_edges (f, img, matrix, color_adjust)
8138 for (y = 1; y < img->height - 1; ++y) 8244 for (y = 1; y < img->height - 1; ++y)
8139 { 8245 {
8140 p = COLOR (new, 1, y); 8246 p = COLOR (new, 1, y);
8141 8247
8142 for (x = 1; x < img->width - 1; ++x, ++p) 8248 for (x = 1; x < img->width - 1; ++x, ++p)
8143 { 8249 {
8144 int r, g, b, y1, x1; 8250 int r, g, b, y1, x1;
@@ -8211,7 +8317,7 @@ x_edge_detection (f, img, matrix, color_adjust)
8211{ 8317{
8212 int i = 0; 8318 int i = 0;
8213 int trans[9]; 8319 int trans[9];
8214 8320
8215 if (CONSP (matrix)) 8321 if (CONSP (matrix))
8216 { 8322 {
8217 for (i = 0; 8323 for (i = 0;
@@ -8331,7 +8437,7 @@ x_build_heuristic_mask (f, img, how)
8331 /* Determine the background color of ximg. If HOW is `(R G B)' 8437 /* Determine the background color of ximg. If HOW is `(R G B)'
8332 take that as color. Otherwise, use the image's background color. */ 8438 take that as color. Otherwise, use the image's background color. */
8333 use_img_background = 1; 8439 use_img_background = 1;
8334 8440
8335 if (CONSP (how)) 8441 if (CONSP (how))
8336 { 8442 {
8337 int rgb[3], i; 8443 int rgb[3], i;
@@ -8350,7 +8456,7 @@ x_build_heuristic_mask (f, img, how)
8350 use_img_background = 0; 8456 use_img_background = 0;
8351 } 8457 }
8352 } 8458 }
8353 8459
8354 if (use_img_background) 8460 if (use_img_background)
8355 bg = four_corners_best (ximg, img->width, img->height); 8461 bg = four_corners_best (ximg, img->width, img->height);
8356 8462
@@ -8367,7 +8473,7 @@ x_build_heuristic_mask (f, img, how)
8367 x_put_x_image (f, mask_img, img->mask, img->width, img->height); 8473 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
8368 x_destroy_x_image (mask_img); 8474 x_destroy_x_image (mask_img);
8369 XDestroyImage (ximg); 8475 XDestroyImage (ximg);
8370 8476
8371 return 1; 8477 return 1;
8372} 8478}
8373 8479
@@ -8440,9 +8546,9 @@ pbm_image_p (object)
8440 Lisp_Object object; 8546 Lisp_Object object;
8441{ 8547{
8442 struct image_keyword fmt[PBM_LAST]; 8548 struct image_keyword fmt[PBM_LAST];
8443 8549
8444 bcopy (pbm_format, fmt, sizeof fmt); 8550 bcopy (pbm_format, fmt, sizeof fmt);
8445 8551
8446 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm)) 8552 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
8447 return 0; 8553 return 0;
8448 8554
@@ -8491,7 +8597,7 @@ pbm_scan_number (s, end)
8491 8597
8492/* Load PBM image IMG for use on frame F. */ 8598/* Load PBM image IMG for use on frame F. */
8493 8599
8494static int 8600static int
8495pbm_load (f, img) 8601pbm_load (f, img)
8496 struct frame *f; 8602 struct frame *f;
8497 struct image *img; 8603 struct image *img;
@@ -8554,7 +8660,7 @@ pbm_load (f, img)
8554 case '1': 8660 case '1':
8555 raw_p = 0, type = PBM_MONO; 8661 raw_p = 0, type = PBM_MONO;
8556 break; 8662 break;
8557 8663
8558 case '2': 8664 case '2':
8559 raw_p = 0, type = PBM_GRAY; 8665 raw_p = 0, type = PBM_GRAY;
8560 break; 8666 break;
@@ -8566,11 +8672,11 @@ pbm_load (f, img)
8566 case '4': 8672 case '4':
8567 raw_p = 1, type = PBM_MONO; 8673 raw_p = 1, type = PBM_MONO;
8568 break; 8674 break;
8569 8675
8570 case '5': 8676 case '5':
8571 raw_p = 1, type = PBM_GRAY; 8677 raw_p = 1, type = PBM_GRAY;
8572 break; 8678 break;
8573 8679
8574 case '6': 8680 case '6':
8575 raw_p = 1, type = PBM_COLOR; 8681 raw_p = 1, type = PBM_COLOR;
8576 break; 8682 break;
@@ -8591,7 +8697,7 @@ pbm_load (f, img)
8591 if (raw_p && max_color_idx > 255) 8697 if (raw_p && max_color_idx > 255)
8592 max_color_idx = 255; 8698 max_color_idx = 255;
8593 } 8699 }
8594 8700
8595 if (width < 0 8701 if (width < 0
8596 || height < 0 8702 || height < 0
8597 || (type != PBM_MONO && max_color_idx < 0)) 8703 || (type != PBM_MONO && max_color_idx < 0))
@@ -8600,7 +8706,7 @@ pbm_load (f, img)
8600 if (!x_create_x_image_and_pixmap (f, width, height, 0, 8706 if (!x_create_x_image_and_pixmap (f, width, height, 0,
8601 &ximg, &img->pixmap)) 8707 &ximg, &img->pixmap))
8602 goto error; 8708 goto error;
8603 8709
8604 /* Initialize the color hash table. */ 8710 /* Initialize the color hash table. */
8605 init_color_table (); 8711 init_color_table ();
8606 8712
@@ -8614,7 +8720,7 @@ pbm_load (f, img)
8614 /* Parse the image specification. */ 8720 /* Parse the image specification. */
8615 bcopy (pbm_format, fmt, sizeof fmt); 8721 bcopy (pbm_format, fmt, sizeof fmt);
8616 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); 8722 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
8617 8723
8618 /* Get foreground and background colors, maybe allocate colors. */ 8724 /* Get foreground and background colors, maybe allocate colors. */
8619 if (fmt[PBM_FOREGROUND].count 8725 if (fmt[PBM_FOREGROUND].count
8620 && STRINGP (fmt[PBM_FOREGROUND].value)) 8726 && STRINGP (fmt[PBM_FOREGROUND].value))
@@ -8626,7 +8732,7 @@ pbm_load (f, img)
8626 img->background = bg; 8732 img->background = bg;
8627 img->background_valid = 1; 8733 img->background_valid = 1;
8628 } 8734 }
8629 8735
8630 for (y = 0; y < height; ++y) 8736 for (y = 0; y < height; ++y)
8631 for (x = 0; x < width; ++x) 8737 for (x = 0; x < width; ++x)
8632 { 8738 {
@@ -8649,7 +8755,7 @@ pbm_load (f, img)
8649 for (x = 0; x < width; ++x) 8755 for (x = 0; x < width; ++x)
8650 { 8756 {
8651 int r, g, b; 8757 int r, g, b;
8652 8758
8653 if (type == PBM_GRAY) 8759 if (type == PBM_GRAY)
8654 r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end); 8760 r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end);
8655 else if (raw_p) 8761 else if (raw_p)
@@ -8664,7 +8770,7 @@ pbm_load (f, img)
8664 g = pbm_scan_number (&p, end); 8770 g = pbm_scan_number (&p, end);
8665 b = pbm_scan_number (&p, end); 8771 b = pbm_scan_number (&p, end);
8666 } 8772 }
8667 8773
8668 if (r < 0 || g < 0 || b < 0) 8774 if (r < 0 || g < 0 || b < 0)
8669 { 8775 {
8670 xfree (ximg->data); 8776 xfree (ximg->data);
@@ -8674,7 +8780,7 @@ pbm_load (f, img)
8674 img->spec, Qnil); 8780 img->spec, Qnil);
8675 goto error; 8781 goto error;
8676 } 8782 }
8677 8783
8678 /* RGB values are now in the range 0..max_color_idx. 8784 /* RGB values are now in the range 0..max_color_idx.
8679 Scale this to the range 0..0xffff supported by X. */ 8785 Scale this to the range 0..0xffff supported by X. */
8680 r = (double) r * 65535 / max_color_idx; 8786 r = (double) r * 65535 / max_color_idx;
@@ -8683,7 +8789,7 @@ pbm_load (f, img)
8683 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); 8789 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
8684 } 8790 }
8685 } 8791 }
8686 8792
8687 /* Store in IMG->colors the colors allocated for the image, and 8793 /* Store in IMG->colors the colors allocated for the image, and
8688 free the color table. */ 8794 free the color table. */
8689 img->colors = colors_in_color_table (&img->ncolors); 8795 img->colors = colors_in_color_table (&img->ncolors);
@@ -8692,11 +8798,11 @@ pbm_load (f, img)
8692 /* Maybe fill in the background field while we have ximg handy. */ 8798 /* Maybe fill in the background field while we have ximg handy. */
8693 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 8799 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8694 IMAGE_BACKGROUND (img, f, ximg); 8800 IMAGE_BACKGROUND (img, f, ximg);
8695 8801
8696 /* Put the image into a pixmap. */ 8802 /* Put the image into a pixmap. */
8697 x_put_x_image (f, ximg, img->pixmap, width, height); 8803 x_put_x_image (f, ximg, img->pixmap, width, height);
8698 x_destroy_x_image (ximg); 8804 x_destroy_x_image (ximg);
8699 8805
8700 img->width = width; 8806 img->width = width;
8701 img->height = height; 8807 img->height = height;
8702 8808
@@ -8778,7 +8884,7 @@ png_image_p (object)
8778{ 8884{
8779 struct image_keyword fmt[PNG_LAST]; 8885 struct image_keyword fmt[PNG_LAST];
8780 bcopy (png_format, fmt, sizeof fmt); 8886 bcopy (png_format, fmt, sizeof fmt);
8781 8887
8782 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng)) 8888 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
8783 return 0; 8889 return 0;
8784 8890
@@ -8835,7 +8941,7 @@ png_read_from_memory (png_ptr, data, length)
8835 8941
8836 if (length > tbr->len - tbr->index) 8942 if (length > tbr->len - tbr->index)
8837 png_error (png_ptr, "Read error"); 8943 png_error (png_ptr, "Read error");
8838 8944
8839 bcopy (tbr->bytes + tbr->index, data, length); 8945 bcopy (tbr->bytes + tbr->index, data, length);
8840 tbr->index = tbr->index + length; 8946 tbr->index = tbr->index + length;
8841} 8947}
@@ -8977,14 +9083,14 @@ png_load (f, img)
8977 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 9083 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
8978 &interlace_type, NULL, NULL); 9084 &interlace_type, NULL, NULL);
8979 9085
8980 /* If image contains simply transparency data, we prefer to 9086 /* If image contains simply transparency data, we prefer to
8981 construct a clipping mask. */ 9087 construct a clipping mask. */
8982 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) 9088 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
8983 transparent_p = 1; 9089 transparent_p = 1;
8984 else 9090 else
8985 transparent_p = 0; 9091 transparent_p = 0;
8986 9092
8987 /* This function is easier to write if we only have to handle 9093 /* This function is easier to write if we only have to handle
8988 one data format: RGB or RGBA with 8 bits per channel. Let's 9094 one data format: RGB or RGBA with 8 bits per channel. Let's
8989 transform other formats into that format. */ 9095 transform other formats into that format. */
8990 9096
@@ -8997,7 +9103,7 @@ png_load (f, img)
8997 png_set_expand (png_ptr); 9103 png_set_expand (png_ptr);
8998 9104
8999 /* Convert grayscale images to RGB. */ 9105 /* Convert grayscale images to RGB. */
9000 if (color_type == PNG_COLOR_TYPE_GRAY 9106 if (color_type == PNG_COLOR_TYPE_GRAY
9001 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 9107 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
9002 png_set_gray_to_rgb (png_ptr); 9108 png_set_gray_to_rgb (png_ptr);
9003 9109
@@ -9046,14 +9152,14 @@ png_load (f, img)
9046 } 9152 }
9047 } 9153 }
9048 else if (png_get_bKGD (png_ptr, info_ptr, &image_bg)) 9154 else if (png_get_bKGD (png_ptr, info_ptr, &image_bg))
9049 /* Image contains a background color with which to 9155 /* Image contains a background color with which to
9050 combine the image. */ 9156 combine the image. */
9051 png_set_background (png_ptr, image_bg, 9157 png_set_background (png_ptr, image_bg,
9052 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 9158 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
9053 else 9159 else
9054 { 9160 {
9055 /* Image does not contain a background color with which 9161 /* Image does not contain a background color with which
9056 to combine the image data via an alpha channel. Use 9162 to combine the image data via an alpha channel. Use
9057 the frame's background instead. */ 9163 the frame's background instead. */
9058 XColor color; 9164 XColor color;
9059 Colormap cmap; 9165 Colormap cmap;
@@ -9101,12 +9207,12 @@ png_load (f, img)
9101 fclose (fp); 9207 fclose (fp);
9102 fp = NULL; 9208 fp = NULL;
9103 } 9209 }
9104 9210
9105 /* Create the X image and pixmap. */ 9211 /* Create the X image and pixmap. */
9106 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, 9212 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
9107 &img->pixmap)) 9213 &img->pixmap))
9108 goto error; 9214 goto error;
9109 9215
9110 /* Create an image and pixmap serving as mask if the PNG image 9216 /* Create an image and pixmap serving as mask if the PNG image
9111 contains an alpha channel. */ 9217 contains an alpha channel. */
9112 if (channels == 4 9218 if (channels == 4
@@ -9137,16 +9243,16 @@ png_load (f, img)
9137 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); 9243 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
9138 9244
9139 /* An alpha channel, aka mask channel, associates variable 9245 /* An alpha channel, aka mask channel, associates variable
9140 transparency with an image. Where other image formats 9246 transparency with an image. Where other image formats
9141 support binary transparency---fully transparent or fully 9247 support binary transparency---fully transparent or fully
9142 opaque---PNG allows up to 254 levels of partial transparency. 9248 opaque---PNG allows up to 254 levels of partial transparency.
9143 The PNG library implements partial transparency by combining 9249 The PNG library implements partial transparency by combining
9144 the image with a specified background color. 9250 the image with a specified background color.
9145 9251
9146 I'm not sure how to handle this here nicely: because the 9252 I'm not sure how to handle this here nicely: because the
9147 background on which the image is displayed may change, for 9253 background on which the image is displayed may change, for
9148 real alpha channel support, it would be necessary to create 9254 real alpha channel support, it would be necessary to create
9149 a new image for each possible background. 9255 a new image for each possible background.
9150 9256
9151 What I'm doing now is that a mask is created if we have 9257 What I'm doing now is that a mask is created if we have
9152 boolean transparency information. Otherwise I'm using 9258 boolean transparency information. Otherwise I'm using
@@ -9292,9 +9398,9 @@ jpeg_image_p (object)
9292 Lisp_Object object; 9398 Lisp_Object object;
9293{ 9399{
9294 struct image_keyword fmt[JPEG_LAST]; 9400 struct image_keyword fmt[JPEG_LAST];
9295 9401
9296 bcopy (jpeg_format, fmt, sizeof fmt); 9402 bcopy (jpeg_format, fmt, sizeof fmt);
9297 9403
9298 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg)) 9404 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
9299 return 0; 9405 return 0;
9300 9406
@@ -9365,7 +9471,7 @@ our_skip_input_data (cinfo, num_bytes)
9365 { 9471 {
9366 if (num_bytes > src->bytes_in_buffer) 9472 if (num_bytes > src->bytes_in_buffer)
9367 ERREXIT (cinfo, JERR_INPUT_EOF); 9473 ERREXIT (cinfo, JERR_INPUT_EOF);
9368 9474
9369 src->bytes_in_buffer -= num_bytes; 9475 src->bytes_in_buffer -= num_bytes;
9370 src->next_input_byte += num_bytes; 9476 src->next_input_byte += num_bytes;
9371 } 9477 }
@@ -9403,7 +9509,7 @@ jpeg_memory_src (cinfo, data, len)
9403 src = (struct jpeg_source_mgr *) cinfo->src; 9509 src = (struct jpeg_source_mgr *) cinfo->src;
9404 src->next_input_byte = data; 9510 src->next_input_byte = data;
9405 } 9511 }
9406 9512
9407 src = (struct jpeg_source_mgr *) cinfo->src; 9513 src = (struct jpeg_source_mgr *) cinfo->src;
9408 src->init_source = our_init_source; 9514 src->init_source = our_init_source;
9409 src->fill_input_buffer = our_fill_input_buffer; 9515 src->fill_input_buffer = our_fill_input_buffer;
@@ -9418,7 +9524,7 @@ jpeg_memory_src (cinfo, data, len)
9418/* Load image IMG for use on frame F. Patterned after example.c 9524/* Load image IMG for use on frame F. Patterned after example.c
9419 from the JPEG lib. */ 9525 from the JPEG lib. */
9420 9526
9421static int 9527static int
9422jpeg_load (f, img) 9528jpeg_load (f, img)
9423 struct frame *f; 9529 struct frame *f;
9424 struct image *img; 9530 struct image *img;
@@ -9451,7 +9557,7 @@ jpeg_load (f, img)
9451 UNGCPRO; 9557 UNGCPRO;
9452 return 0; 9558 return 0;
9453 } 9559 }
9454 9560
9455 fp = fopen (SDATA (file), "r"); 9561 fp = fopen (SDATA (file), "r");
9456 if (fp == NULL) 9562 if (fp == NULL)
9457 { 9563 {
@@ -9465,7 +9571,7 @@ jpeg_load (f, img)
9465 error is detected. This function will perform a longjmp. */ 9571 error is detected. This function will perform a longjmp. */
9466 cinfo.err = jpeg_std_error (&mgr.pub); 9572 cinfo.err = jpeg_std_error (&mgr.pub);
9467 mgr.pub.error_exit = my_error_exit; 9573 mgr.pub.error_exit = my_error_exit;
9468 9574
9469 if ((rc = setjmp (mgr.setjmp_buffer)) != 0) 9575 if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
9470 { 9576 {
9471 if (rc == 1) 9577 if (rc == 1)
@@ -9476,7 +9582,7 @@ jpeg_load (f, img)
9476 image_error ("Error reading JPEG image `%s': %s", img->spec, 9582 image_error ("Error reading JPEG image `%s': %s", img->spec,
9477 build_string (buffer)); 9583 build_string (buffer));
9478 } 9584 }
9479 9585
9480 /* Close the input file and destroy the JPEG object. */ 9586 /* Close the input file and destroy the JPEG object. */
9481 if (fp) 9587 if (fp)
9482 fclose ((FILE *) fp); 9588 fclose ((FILE *) fp);
@@ -9487,7 +9593,7 @@ jpeg_load (f, img)
9487 9593
9488 /* Free pixmap and colors. */ 9594 /* Free pixmap and colors. */
9489 x_clear_image (f, img); 9595 x_clear_image (f, img);
9490 9596
9491 UNGCPRO; 9597 UNGCPRO;
9492 return 0; 9598 return 0;
9493 } 9599 }
@@ -9537,7 +9643,7 @@ jpeg_load (f, img)
9537 init_color_table (); 9643 init_color_table ();
9538 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors 9644 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
9539 * sizeof *colors); 9645 * sizeof *colors);
9540 9646
9541 for (i = 0; i < cinfo.actual_number_of_colors; ++i) 9647 for (i = 0; i < cinfo.actual_number_of_colors; ++i)
9542 { 9648 {
9543 /* Multiply RGB values with 255 because X expects RGB values 9649 /* Multiply RGB values with 255 because X expects RGB values
@@ -9573,7 +9679,7 @@ jpeg_load (f, img)
9573 /* Maybe fill in the background field while we have ximg handy. */ 9679 /* Maybe fill in the background field while we have ximg handy. */
9574 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 9680 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
9575 IMAGE_BACKGROUND (img, f, ximg); 9681 IMAGE_BACKGROUND (img, f, ximg);
9576 9682
9577 /* Put the image into the pixmap. */ 9683 /* Put the image into the pixmap. */
9578 x_put_x_image (f, ximg, img->pixmap, width, height); 9684 x_put_x_image (f, ximg, img->pixmap, width, height);
9579 x_destroy_x_image (ximg); 9685 x_destroy_x_image (ximg);
@@ -9654,10 +9760,10 @@ tiff_image_p (object)
9654{ 9760{
9655 struct image_keyword fmt[TIFF_LAST]; 9761 struct image_keyword fmt[TIFF_LAST];
9656 bcopy (tiff_format, fmt, sizeof fmt); 9762 bcopy (tiff_format, fmt, sizeof fmt);
9657 9763
9658 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff)) 9764 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
9659 return 0; 9765 return 0;
9660 9766
9661 /* Must specify either the :data or :file keyword. */ 9767 /* Must specify either the :data or :file keyword. */
9662 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; 9768 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
9663} 9769}
@@ -9721,22 +9827,22 @@ tiff_seek_in_memory (data, off, whence)
9721 case SEEK_SET: /* Go from beginning of source. */ 9827 case SEEK_SET: /* Go from beginning of source. */
9722 idx = off; 9828 idx = off;
9723 break; 9829 break;
9724 9830
9725 case SEEK_END: /* Go from end of source. */ 9831 case SEEK_END: /* Go from end of source. */
9726 idx = src->len + off; 9832 idx = src->len + off;
9727 break; 9833 break;
9728 9834
9729 case SEEK_CUR: /* Go from current position. */ 9835 case SEEK_CUR: /* Go from current position. */
9730 idx = src->index + off; 9836 idx = src->index + off;
9731 break; 9837 break;
9732 9838
9733 default: /* Invalid `whence'. */ 9839 default: /* Invalid `whence'. */
9734 return -1; 9840 return -1;
9735 } 9841 }
9736 9842
9737 if (idx > src->len || idx < 0) 9843 if (idx > src->len || idx < 0)
9738 return -1; 9844 return -1;
9739 9845
9740 src->index = idx; 9846 src->index = idx;
9741 return src->index; 9847 return src->index;
9742} 9848}
@@ -9787,7 +9893,7 @@ tiff_error_handler (title, format, ap)
9787{ 9893{
9788 char buf[512]; 9894 char buf[512];
9789 int len; 9895 int len;
9790 9896
9791 len = sprintf (buf, "TIFF error: %s ", title); 9897 len = sprintf (buf, "TIFF error: %s ", title);
9792 vsprintf (buf + len, format, ap); 9898 vsprintf (buf + len, format, ap);
9793 add_to_log (buf, Qnil, Qnil); 9899 add_to_log (buf, Qnil, Qnil);
@@ -9801,7 +9907,7 @@ tiff_warning_handler (title, format, ap)
9801{ 9907{
9802 char buf[512]; 9908 char buf[512];
9803 int len; 9909 int len;
9804 9910
9805 len = sprintf (buf, "TIFF warning: %s ", title); 9911 len = sprintf (buf, "TIFF warning: %s ", title);
9806 vsprintf (buf + len, format, ap); 9912 vsprintf (buf + len, format, ap);
9807 add_to_log (buf, Qnil, Qnil); 9913 add_to_log (buf, Qnil, Qnil);
@@ -9844,7 +9950,7 @@ tiff_load (f, img)
9844 UNGCPRO; 9950 UNGCPRO;
9845 return 0; 9951 return 0;
9846 } 9952 }
9847 9953
9848 /* Try to open the image file. */ 9954 /* Try to open the image file. */
9849 tiff = TIFFOpen (SDATA (file), "r"); 9955 tiff = TIFFOpen (SDATA (file), "r");
9850 if (tiff == NULL) 9956 if (tiff == NULL)
@@ -9883,7 +9989,7 @@ tiff_load (f, img)
9883 TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); 9989 TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
9884 TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); 9990 TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
9885 buf = (uint32 *) xmalloc (width * height * sizeof *buf); 9991 buf = (uint32 *) xmalloc (width * height * sizeof *buf);
9886 9992
9887 rc = TIFFReadRGBAImage (tiff, width, height, buf, 0); 9993 rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);
9888 TIFFClose (tiff); 9994 TIFFClose (tiff);
9889 if (!rc) 9995 if (!rc)
@@ -9909,21 +10015,21 @@ tiff_load (f, img)
9909 for (y = 0; y < height; ++y) 10015 for (y = 0; y < height; ++y)
9910 { 10016 {
9911 uint32 *row = buf + y * width; 10017 uint32 *row = buf + y * width;
9912 10018
9913 for (x = 0; x < width; ++x) 10019 for (x = 0; x < width; ++x)
9914 { 10020 {
9915 uint32 abgr = row[x]; 10021 uint32 abgr = row[x];
9916 int r = TIFFGetR (abgr) << 8; 10022 int r = TIFFGetR (abgr) << 8;
9917 int g = TIFFGetG (abgr) << 8; 10023 int g = TIFFGetG (abgr) << 8;
9918 int b = TIFFGetB (abgr) << 8; 10024 int b = TIFFGetB (abgr) << 8;
9919 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b)); 10025 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
9920 } 10026 }
9921 } 10027 }
9922 10028
9923 /* Remember the colors allocated for the image. Free the color table. */ 10029 /* Remember the colors allocated for the image. Free the color table. */
9924 img->colors = colors_in_color_table (&img->ncolors); 10030 img->colors = colors_in_color_table (&img->ncolors);
9925 free_color_table (); 10031 free_color_table ();
9926 10032
9927 img->width = width; 10033 img->width = width;
9928 img->height = height; 10034 img->height = height;
9929 10035
@@ -10015,10 +10121,10 @@ gif_image_p (object)
10015{ 10121{
10016 struct image_keyword fmt[GIF_LAST]; 10122 struct image_keyword fmt[GIF_LAST];
10017 bcopy (gif_format, fmt, sizeof fmt); 10123 bcopy (gif_format, fmt, sizeof fmt);
10018 10124
10019 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif)) 10125 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
10020 return 0; 10126 return 0;
10021 10127
10022 /* Must specify either the :data or :file keyword. */ 10128 /* Must specify either the :data or :file keyword. */
10023 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; 10129 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
10024} 10130}
@@ -10093,7 +10199,7 @@ gif_load (f, img)
10093 UNGCPRO; 10199 UNGCPRO;
10094 return 0; 10200 return 0;
10095 } 10201 }
10096 10202
10097 /* Open the GIF file. */ 10203 /* Open the GIF file. */
10098 gif = DGifOpenFileName (SDATA (file)); 10204 gif = DGifOpenFileName (SDATA (file));
10099 if (gif == NULL) 10205 if (gif == NULL)
@@ -10151,14 +10257,14 @@ gif_load (f, img)
10151 UNGCPRO; 10257 UNGCPRO;
10152 return 0; 10258 return 0;
10153 } 10259 }
10154 10260
10155 /* Allocate colors. */ 10261 /* Allocate colors. */
10156 gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap; 10262 gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
10157 if (!gif_color_map) 10263 if (!gif_color_map)
10158 gif_color_map = gif->SColorMap; 10264 gif_color_map = gif->SColorMap;
10159 init_color_table (); 10265 init_color_table ();
10160 bzero (pixel_colors, sizeof pixel_colors); 10266 bzero (pixel_colors, sizeof pixel_colors);
10161 10267
10162 for (i = 0; i < gif_color_map->ColorCount; ++i) 10268 for (i = 0; i < gif_color_map->ColorCount; ++i)
10163 { 10269 {
10164 int r = gif_color_map->Colors[i].Red << 8; 10270 int r = gif_color_map->Colors[i].Red << 8;
@@ -10171,7 +10277,7 @@ gif_load (f, img)
10171 free_color_table (); 10277 free_color_table ();
10172 10278
10173 /* Clear the part of the screen image that are not covered by 10279 /* Clear the part of the screen image that are not covered by
10174 the image from the GIF file. Full animated GIF support 10280 the image from the GIF file. Full animated GIF support
10175 requires more than can be done here (see the gif89 spec, 10281 requires more than can be done here (see the gif89 spec,
10176 disposal methods). Let's simply assume that the part 10282 disposal methods). Let's simply assume that the part
10177 not covered by a sub-image is in the frame's background color. */ 10283 not covered by a sub-image is in the frame's background color. */
@@ -10200,7 +10306,7 @@ gif_load (f, img)
10200 `raster' here because RasterBits below is a char *, and invites 10306 `raster' here because RasterBits below is a char *, and invites
10201 problems with bytes >= 0x80. */ 10307 problems with bytes >= 0x80. */
10202 raster = (unsigned char *) gif->SavedImages[ino].RasterBits; 10308 raster = (unsigned char *) gif->SavedImages[ino].RasterBits;
10203 10309
10204 if (gif->SavedImages[ino].ImageDesc.Interlace) 10310 if (gif->SavedImages[ino].ImageDesc.Interlace)
10205 { 10311 {
10206 static int interlace_start[] = {0, 4, 2, 1}; 10312 static int interlace_start[] = {0, 4, 2, 1};
@@ -10218,14 +10324,14 @@ gif_load (f, img)
10218 while (row >= image_height) 10324 while (row >= image_height)
10219 row = interlace_start[++pass]; 10325 row = interlace_start[++pass];
10220 } 10326 }
10221 10327
10222 for (x = 0; x < image_width; x++) 10328 for (x = 0; x < image_width; x++)
10223 { 10329 {
10224 int i = raster[(y * image_width) + x]; 10330 int i = raster[(y * image_width) + x];
10225 XPutPixel (ximg, x + image_left, row + image_top, 10331 XPutPixel (ximg, x + image_left, row + image_top,
10226 pixel_colors[i]); 10332 pixel_colors[i]);
10227 } 10333 }
10228 10334
10229 row += interlace_increment[pass]; 10335 row += interlace_increment[pass];
10230 } 10336 }
10231 } 10337 }
@@ -10238,17 +10344,17 @@ gif_load (f, img)
10238 XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); 10344 XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]);
10239 } 10345 }
10240 } 10346 }
10241 10347
10242 DGifCloseFile (gif); 10348 DGifCloseFile (gif);
10243 10349
10244 /* Maybe fill in the background field while we have ximg handy. */ 10350 /* Maybe fill in the background field while we have ximg handy. */
10245 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 10351 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
10246 IMAGE_BACKGROUND (img, f, ximg); 10352 IMAGE_BACKGROUND (img, f, ximg);
10247 10353
10248 /* Put the image into the pixmap, then free the X image and its buffer. */ 10354 /* Put the image into the pixmap, then free the X image and its buffer. */
10249 x_put_x_image (f, ximg, img->pixmap, width, height); 10355 x_put_x_image (f, ximg, img->pixmap, width, height);
10250 x_destroy_x_image (ximg); 10356 x_destroy_x_image (ximg);
10251 10357
10252 UNGCPRO; 10358 UNGCPRO;
10253 return 1; 10359 return 1;
10254} 10360}
@@ -10348,9 +10454,9 @@ gs_image_p (object)
10348 struct image_keyword fmt[GS_LAST]; 10454 struct image_keyword fmt[GS_LAST];
10349 Lisp_Object tem; 10455 Lisp_Object tem;
10350 int i; 10456 int i;
10351 10457
10352 bcopy (gs_format, fmt, sizeof fmt); 10458 bcopy (gs_format, fmt, sizeof fmt);
10353 10459
10354 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript)) 10460 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
10355 return 0; 10461 return 0;
10356 10462
@@ -10416,7 +10522,7 @@ gs_load (f, img)
10416 image_error ("Unable to create pixmap for `%s'", img->spec, Qnil); 10522 image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
10417 return 0; 10523 return 0;
10418 } 10524 }
10419 10525
10420 /* Call the loader to fill the pixmap. It returns a process object 10526 /* Call the loader to fill the pixmap. It returns a process object
10421 if successful. We do not record_unwind_protect here because 10527 if successful. We do not record_unwind_protect here because
10422 other places in redisplay like calling window scroll functions 10528 other places in redisplay like calling window scroll functions
@@ -10427,12 +10533,12 @@ gs_load (f, img)
10427 (unsigned long) FRAME_X_WINDOW (f), 10533 (unsigned long) FRAME_X_WINDOW (f),
10428 (unsigned long) img->pixmap); 10534 (unsigned long) img->pixmap);
10429 window_and_pixmap_id = build_string (buffer); 10535 window_and_pixmap_id = build_string (buffer);
10430 10536
10431 sprintf (buffer, "%lu %lu", 10537 sprintf (buffer, "%lu %lu",
10432 FRAME_FOREGROUND_PIXEL (f), 10538 FRAME_FOREGROUND_PIXEL (f),
10433 FRAME_BACKGROUND_PIXEL (f)); 10539 FRAME_BACKGROUND_PIXEL (f));
10434 pixel_colors = build_string (buffer); 10540 pixel_colors = build_string (buffer);
10435 10541
10436 XSETFRAME (frame, f); 10542 XSETFRAME (frame, f);
10437 loader = image_spec_value (img->spec, QCloader, NULL); 10543 loader = image_spec_value (img->spec, QCloader, NULL);
10438 if (NILP (loader)) 10544 if (NILP (loader))
@@ -10470,7 +10576,7 @@ x_kill_gs_process (pixmap, f)
10470 instance, give up. */ 10576 instance, give up. */
10471 if (i == c->used) 10577 if (i == c->used)
10472 return; 10578 return;
10473 10579
10474 /* Kill the GS process. We should have found PIXMAP in the image 10580 /* Kill the GS process. We should have found PIXMAP in the image
10475 cache and its image should contain a process object. */ 10581 cache and its image should contain a process object. */
10476 img = c->images[i]; 10582 img = c->images[i];
@@ -10494,10 +10600,10 @@ x_kill_gs_process (pixmap, f)
10494 if (ximg) 10600 if (ximg)
10495 { 10601 {
10496 int x, y; 10602 int x, y;
10497 10603
10498 /* Initialize the color table. */ 10604 /* Initialize the color table. */
10499 init_color_table (); 10605 init_color_table ();
10500 10606
10501 /* For each pixel of the image, look its color up in the 10607 /* For each pixel of the image, look its color up in the
10502 color table. After having done so, the color table will 10608 color table. After having done so, the color table will
10503 contain an entry for each color used by the image. */ 10609 contain an entry for each color used by the image. */
@@ -10526,7 +10632,7 @@ x_kill_gs_process (pixmap, f)
10526 else 10632 else
10527 image_error ("Cannot get X image of `%s'; colors will not be freed", 10633 image_error ("Cannot get X image of `%s'; colors will not be freed",
10528 img->spec, Qnil); 10634 img->spec, Qnil);
10529 10635
10530 UNBLOCK_INPUT; 10636 UNBLOCK_INPUT;
10531 } 10637 }
10532 10638
@@ -10629,8 +10735,8 @@ value. */)
10629 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 10735 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
10630 prop_atom, 0, bytes_remaining, 10736 prop_atom, 0, bytes_remaining,
10631 False, XA_STRING, 10737 False, XA_STRING,
10632 &actual_type, &actual_format, 10738 &actual_type, &actual_format,
10633 &actual_size, &bytes_remaining, 10739 &actual_size, &bytes_remaining,
10634 (unsigned char **) &tmp_data); 10740 (unsigned char **) &tmp_data);
10635 if (rc == Success && tmp_data) 10741 if (rc == Success && tmp_data)
10636 prop_value = make_string (tmp_data, size); 10742 prop_value = make_string (tmp_data, size);
@@ -10679,7 +10785,7 @@ start_hourglass ()
10679{ 10785{
10680 EMACS_TIME delay; 10786 EMACS_TIME delay;
10681 int secs, usecs = 0; 10787 int secs, usecs = 0;
10682 10788
10683 cancel_hourglass (); 10789 cancel_hourglass ();
10684 10790
10685 if (INTEGERP (Vhourglass_delay) 10791 if (INTEGERP (Vhourglass_delay)
@@ -10695,7 +10801,7 @@ start_hourglass ()
10695 } 10801 }
10696 else 10802 else
10697 secs = DEFAULT_HOURGLASS_DELAY; 10803 secs = DEFAULT_HOURGLASS_DELAY;
10698 10804
10699 EMACS_SET_SECS_USECS (delay, secs, usecs); 10805 EMACS_SET_SECS_USECS (delay, secs, usecs);
10700 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, 10806 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
10701 show_hourglass, NULL); 10807 show_hourglass, NULL);
@@ -10713,7 +10819,7 @@ cancel_hourglass ()
10713 cancel_atimer (hourglass_atimer); 10819 cancel_atimer (hourglass_atimer);
10714 hourglass_atimer = NULL; 10820 hourglass_atimer = NULL;
10715 } 10821 }
10716 10822
10717 if (hourglass_shown_p) 10823 if (hourglass_shown_p)
10718 hide_hourglass (); 10824 hide_hourglass ();
10719} 10825}
@@ -10739,17 +10845,17 @@ show_hourglass (timer)
10739 if (!hourglass_shown_p) 10845 if (!hourglass_shown_p)
10740 { 10846 {
10741 Lisp_Object rest, frame; 10847 Lisp_Object rest, frame;
10742 10848
10743 BLOCK_INPUT; 10849 BLOCK_INPUT;
10744 10850
10745 FOR_EACH_FRAME (rest, frame) 10851 FOR_EACH_FRAME (rest, frame)
10746 { 10852 {
10747 struct frame *f = XFRAME (frame); 10853 struct frame *f = XFRAME (frame);
10748 10854
10749 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f)) 10855 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
10750 { 10856 {
10751 Display *dpy = FRAME_X_DISPLAY (f); 10857 Display *dpy = FRAME_X_DISPLAY (f);
10752 10858
10753#ifdef USE_X_TOOLKIT 10859#ifdef USE_X_TOOLKIT
10754 if (f->output_data.x->widget) 10860 if (f->output_data.x->widget)
10755#else 10861#else
@@ -10757,14 +10863,14 @@ show_hourglass (timer)
10757#endif 10863#endif
10758 { 10864 {
10759 f->output_data.x->hourglass_p = 1; 10865 f->output_data.x->hourglass_p = 1;
10760 10866
10761 if (!f->output_data.x->hourglass_window) 10867 if (!f->output_data.x->hourglass_window)
10762 { 10868 {
10763 unsigned long mask = CWCursor; 10869 unsigned long mask = CWCursor;
10764 XSetWindowAttributes attrs; 10870 XSetWindowAttributes attrs;
10765 10871
10766 attrs.cursor = f->output_data.x->hourglass_cursor; 10872 attrs.cursor = f->output_data.x->hourglass_cursor;
10767 10873
10768 f->output_data.x->hourglass_window 10874 f->output_data.x->hourglass_window
10769 = XCreateWindow (dpy, FRAME_OUTER_WINDOW (f), 10875 = XCreateWindow (dpy, FRAME_OUTER_WINDOW (f),
10770 0, 0, 32000, 32000, 0, 0, 10876 0, 0, 32000, 32000, 0, 0,
@@ -10772,7 +10878,7 @@ show_hourglass (timer)
10772 CopyFromParent, 10878 CopyFromParent,
10773 mask, &attrs); 10879 mask, &attrs);
10774 } 10880 }
10775 10881
10776 XMapRaised (dpy, f->output_data.x->hourglass_window); 10882 XMapRaised (dpy, f->output_data.x->hourglass_window);
10777 XFlush (dpy); 10883 XFlush (dpy);
10778 } 10884 }
@@ -10799,7 +10905,7 @@ hide_hourglass ()
10799 FOR_EACH_FRAME (rest, frame) 10905 FOR_EACH_FRAME (rest, frame)
10800 { 10906 {
10801 struct frame *f = XFRAME (frame); 10907 struct frame *f = XFRAME (frame);
10802 10908
10803 if (FRAME_X_P (f) 10909 if (FRAME_X_P (f)
10804 /* Watch out for newly created frames. */ 10910 /* Watch out for newly created frames. */
10805 && f->output_data.x->hourglass_window) 10911 && f->output_data.x->hourglass_window)
@@ -10828,7 +10934,7 @@ static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
10828 Lisp_Object, Lisp_Object)); 10934 Lisp_Object, Lisp_Object));
10829static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object, 10935static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
10830 Lisp_Object, int, int, int *, int *)); 10936 Lisp_Object, int, int, int *, int *));
10831 10937
10832/* The frame of a currently visible tooltip. */ 10938/* The frame of a currently visible tooltip. */
10833 10939
10834Lisp_Object tip_frame; 10940Lisp_Object tip_frame;
@@ -10861,7 +10967,7 @@ unwind_create_tip_frame (frame)
10861 tip_window = None; 10967 tip_window = None;
10862 tip_frame = Qnil; 10968 tip_frame = Qnil;
10863 } 10969 }
10864 10970
10865 return deleted; 10971 return deleted;
10866} 10972}
10867 10973
@@ -10925,7 +11031,7 @@ x_create_tip_frame (dpyinfo, parms, text)
10925 Ferase_buffer (); 11031 Ferase_buffer ();
10926 Finsert (1, &text); 11032 Finsert (1, &text);
10927 set_buffer_internal_1 (old_buffer); 11033 set_buffer_internal_1 (old_buffer);
10928 11034
10929 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; 11035 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
10930 record_unwind_protect (unwind_create_tip_frame, frame); 11036 record_unwind_protect (unwind_create_tip_frame, frame);
10931 11037
@@ -10961,7 +11067,7 @@ x_create_tip_frame (dpyinfo, parms, text)
10961 { 11067 {
10962 Lisp_Object black; 11068 Lisp_Object black;
10963 struct gcpro gcpro1; 11069 struct gcpro gcpro1;
10964 11070
10965 black = build_string ("black"); 11071 black = build_string ("black");
10966 GCPRO1 (black); 11072 GCPRO1 (black);
10967 f->output_data.x->foreground_pixel 11073 f->output_data.x->foreground_pixel
@@ -11011,7 +11117,7 @@ x_create_tip_frame (dpyinfo, parms, text)
11011 else 11117 else
11012 font = x_new_font (f, SDATA (font)); 11118 font = x_new_font (f, SDATA (font));
11013 } 11119 }
11014 11120
11015 /* Try out a font which we hope has bold and italic variations. */ 11121 /* Try out a font which we hope has bold and italic variations. */
11016 if (!STRINGP (font)) 11122 if (!STRINGP (font))
11017 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"); 11123 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
@@ -11036,7 +11142,7 @@ x_create_tip_frame (dpyinfo, parms, text)
11036 11142
11037 x_default_parameter (f, parms, Qborder_width, make_number (2), 11143 x_default_parameter (f, parms, Qborder_width, make_number (2),
11038 "borderWidth", "BorderWidth", RES_TYPE_NUMBER); 11144 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
11039 11145
11040 /* This defaults to 2 in order to match xterm. We recognize either 11146 /* This defaults to 2 in order to match xterm. We recognize either
11041 internalBorderWidth or internalBorder (which is what xterm calls 11147 internalBorderWidth or internalBorder (which is what xterm calls
11042 it). */ 11148 it). */
@@ -11074,7 +11180,7 @@ x_create_tip_frame (dpyinfo, parms, text)
11074 end up in init_iterator with a null face cache, which should not 11180 end up in init_iterator with a null face cache, which should not
11075 happen. */ 11181 happen. */
11076 init_frame_faces (f); 11182 init_frame_faces (f);
11077 11183
11078 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; 11184 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
11079 window_prompting = x_figure_window_size (f, parms); 11185 window_prompting = x_figure_window_size (f, parms);
11080 11186
@@ -11097,12 +11203,12 @@ x_create_tip_frame (dpyinfo, parms, text)
11097 { 11203 {
11098 XSetWindowAttributes attrs; 11204 XSetWindowAttributes attrs;
11099 unsigned long mask; 11205 unsigned long mask;
11100 11206
11101 BLOCK_INPUT; 11207 BLOCK_INPUT;
11102 mask = CWBackPixel | CWOverrideRedirect | CWEventMask; 11208 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
11103 if (DoesSaveUnders (dpyinfo->screen)) 11209 if (DoesSaveUnders (dpyinfo->screen))
11104 mask |= CWSaveUnder; 11210 mask |= CWSaveUnder;
11105 11211
11106 /* Window managers look at the override-redirect flag to determine 11212 /* Window managers look at the override-redirect flag to determine
11107 whether or net to give windows a decoration (Xlib spec, chapter 11213 whether or net to give windows a decoration (Xlib spec, chapter
11108 3.2.8). */ 11214 3.2.8). */
@@ -11141,12 +11247,12 @@ x_create_tip_frame (dpyinfo, parms, text)
11141 f->height = 0; 11247 f->height = 0;
11142 SET_FRAME_WIDTH (f, 0); 11248 SET_FRAME_WIDTH (f, 0);
11143 change_frame_size (f, height, width, 1, 0, 0); 11249 change_frame_size (f, height, width, 1, 0, 0);
11144 11250
11145 /* Add `tooltip' frame parameter's default value. */ 11251 /* Add `tooltip' frame parameter's default value. */
11146 if (NILP (Fframe_parameter (frame, intern ("tooltip")))) 11252 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
11147 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt), 11253 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
11148 Qnil)); 11254 Qnil));
11149 11255
11150 /* Set up faces after all frame parameters are known. This call 11256 /* Set up faces after all frame parameters are known. This call
11151 also merges in face attributes specified for new frames. 11257 also merges in face attributes specified for new frames.
11152 11258
@@ -11161,12 +11267,12 @@ x_create_tip_frame (dpyinfo, parms, text)
11161 /* Set tip_frame here, so that */ 11267 /* Set tip_frame here, so that */
11162 tip_frame = frame; 11268 tip_frame = frame;
11163 call1 (Qface_set_after_frame_default, frame); 11269 call1 (Qface_set_after_frame_default, frame);
11164 11270
11165 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) 11271 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
11166 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg), 11272 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
11167 Qnil)); 11273 Qnil));
11168 } 11274 }
11169 11275
11170 f->no_split = 1; 11276 f->no_split = 1;
11171 11277
11172 UNGCPRO; 11278 UNGCPRO;
@@ -11209,11 +11315,11 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
11209 int win_x, win_y; 11315 int win_x, win_y;
11210 Window root, child; 11316 Window root, child;
11211 unsigned pmask; 11317 unsigned pmask;
11212 11318
11213 /* User-specified position? */ 11319 /* User-specified position? */
11214 left = Fcdr (Fassq (Qleft, parms)); 11320 left = Fcdr (Fassq (Qleft, parms));
11215 top = Fcdr (Fassq (Qtop, parms)); 11321 top = Fcdr (Fassq (Qtop, parms));
11216 11322
11217 /* Move the tooltip window where the mouse pointer is. Resize and 11323 /* Move the tooltip window where the mouse pointer is. Resize and
11218 show it. */ 11324 show it. */
11219 if (!INTEGERP (left) || !INTEGERP (top)) 11325 if (!INTEGERP (left) || !INTEGERP (top))
@@ -11282,7 +11388,7 @@ Text larger than the specified size is clipped. */)
11282 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 11388 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
11283 int old_windows_or_buffers_changed = windows_or_buffers_changed; 11389 int old_windows_or_buffers_changed = windows_or_buffers_changed;
11284 int count = SPECPDL_INDEX (); 11390 int count = SPECPDL_INDEX ();
11285 11391
11286 specbind (Qinhibit_redisplay, Qt); 11392 specbind (Qinhibit_redisplay, Qt);
11287 11393
11288 GCPRO4 (string, parms, frame, timeout); 11394 GCPRO4 (string, parms, frame, timeout);
@@ -11293,12 +11399,12 @@ Text larger than the specified size is clipped. */)
11293 timeout = make_number (5); 11399 timeout = make_number (5);
11294 else 11400 else
11295 CHECK_NATNUM (timeout); 11401 CHECK_NATNUM (timeout);
11296 11402
11297 if (NILP (dx)) 11403 if (NILP (dx))
11298 dx = make_number (5); 11404 dx = make_number (5);
11299 else 11405 else
11300 CHECK_NUMBER (dx); 11406 CHECK_NUMBER (dx);
11301 11407
11302 if (NILP (dy)) 11408 if (NILP (dy))
11303 dy = make_number (-10); 11409 dy = make_number (-10);
11304 else 11410 else
@@ -11318,7 +11424,7 @@ Text larger than the specified size is clipped. */)
11318 && !NILP (Fequal (last_parms, parms))) 11424 && !NILP (Fequal (last_parms, parms)))
11319 { 11425 {
11320 struct frame *f = XFRAME (tip_frame); 11426 struct frame *f = XFRAME (tip_frame);
11321 11427
11322 /* Only DX and DY have changed. */ 11428 /* Only DX and DY have changed. */
11323 if (!NILP (tip_timer)) 11429 if (!NILP (tip_timer))
11324 { 11430 {
@@ -11365,7 +11471,7 @@ Text larger than the specified size is clipped. */)
11365 /* Set up the frame's root window. */ 11471 /* Set up the frame's root window. */
11366 w = XWINDOW (FRAME_ROOT_WINDOW (f)); 11472 w = XWINDOW (FRAME_ROOT_WINDOW (f));
11367 w->left = w->top = make_number (0); 11473 w->left = w->top = make_number (0);
11368 11474
11369 if (CONSP (Vx_max_tooltip_size) 11475 if (CONSP (Vx_max_tooltip_size)
11370 && INTEGERP (XCAR (Vx_max_tooltip_size)) 11476 && INTEGERP (XCAR (Vx_max_tooltip_size))
11371 && XINT (XCAR (Vx_max_tooltip_size)) > 0 11477 && XINT (XCAR (Vx_max_tooltip_size)) > 0
@@ -11380,7 +11486,7 @@ Text larger than the specified size is clipped. */)
11380 w->width = make_number (80); 11486 w->width = make_number (80);
11381 w->height = make_number (40); 11487 w->height = make_number (40);
11382 } 11488 }
11383 11489
11384 f->window_width = XINT (w->width); 11490 f->window_width = XINT (w->width);
11385 adjust_glyphs (f); 11491 adjust_glyphs (f);
11386 w->pseudo_window_p = 1; 11492 w->pseudo_window_p = 1;
@@ -11418,7 +11524,7 @@ Text larger than the specified size is clipped. */)
11418 } 11524 }
11419 else 11525 else
11420 row_width = row->pixel_width; 11526 row_width = row->pixel_width;
11421 11527
11422 height += row->height; 11528 height += row->height;
11423 width = max (width, row_width); 11529 width = max (width, row_width);
11424 } 11530 }
@@ -11437,7 +11543,7 @@ Text larger than the specified size is clipped. */)
11437 root_x, root_y, width, height); 11543 root_x, root_y, width, height);
11438 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 11544 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
11439 UNBLOCK_INPUT; 11545 UNBLOCK_INPUT;
11440 11546
11441 /* Draw into the window. */ 11547 /* Draw into the window. */
11442 w->must_be_updated_p = 1; 11548 w->must_be_updated_p = 1;
11443 update_single_window (w, 1); 11549 update_single_window (w, 1);
@@ -11468,16 +11574,16 @@ Value is t if tooltip was open, nil otherwise. */)
11468 /* Return quickly if nothing to do. */ 11574 /* Return quickly if nothing to do. */
11469 if (NILP (tip_timer) && NILP (tip_frame)) 11575 if (NILP (tip_timer) && NILP (tip_frame))
11470 return Qnil; 11576 return Qnil;
11471 11577
11472 frame = tip_frame; 11578 frame = tip_frame;
11473 timer = tip_timer; 11579 timer = tip_timer;
11474 GCPRO2 (frame, timer); 11580 GCPRO2 (frame, timer);
11475 tip_frame = tip_timer = deleted = Qnil; 11581 tip_frame = tip_timer = deleted = Qnil;
11476 11582
11477 count = SPECPDL_INDEX (); 11583 count = SPECPDL_INDEX ();
11478 specbind (Qinhibit_redisplay, Qt); 11584 specbind (Qinhibit_redisplay, Qt);
11479 specbind (Qinhibit_quit, Qt); 11585 specbind (Qinhibit_quit, Qt);
11480 11586
11481 if (!NILP (timer)) 11587 if (!NILP (timer))
11482 call1 (Qcancel_timer, timer); 11588 call1 (Qcancel_timer, timer);
11483 11589
@@ -11580,7 +11686,7 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
11580 dir = Fexpand_file_name (dir, Qnil); 11686 dir = Fexpand_file_name (dir, Qnil);
11581 dir_xmstring = XmStringCreateLocalized (SDATA (dir)); 11687 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
11582 pattern_xmstring = XmStringCreateLocalized ("*"); 11688 pattern_xmstring = XmStringCreateLocalized ("*");
11583 11689
11584 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac; 11690 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
11585 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac; 11691 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
11586 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac; 11692 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
@@ -11603,7 +11709,7 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
11603 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON); 11709 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
11604 XtSetSensitive (help, False); 11710 XtSetSensitive (help, False);
11605 11711
11606 /* Mark OK button as default. */ 11712 /* Mark OK button as default. */
11607 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON), 11713 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
11608 XmNshowAsDefault, True, NULL); 11714 XmNshowAsDefault, True, NULL);
11609 11715
@@ -11663,7 +11769,7 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
11663 { 11769 {
11664 XmString text; 11770 XmString text;
11665 String data; 11771 String data;
11666 11772
11667 XtVaGetValues (dialog, XmNtextString, &text, NULL); 11773 XtVaGetValues (dialog, XmNtextString, &text, NULL);
11668 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data); 11774 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
11669 XmStringFree (text); 11775 XmStringFree (text);
@@ -11682,12 +11788,64 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
11682 /* Make "Cancel" equivalent to C-g. */ 11788 /* Make "Cancel" equivalent to C-g. */
11683 if (NILP (file)) 11789 if (NILP (file))
11684 Fsignal (Qquit, Qnil); 11790 Fsignal (Qquit, Qnil);
11685 11791
11686 return unbind_to (count, file); 11792 return unbind_to (count, file);
11687} 11793}
11688 11794
11689#endif /* USE_MOTIF */ 11795#endif /* USE_MOTIF */
11690 11796
11797#ifdef USE_GTK
11798
11799DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
11800 "Read file name, prompting with PROMPT in directory DIR.\n\
11801Use a file selection dialog.\n\
11802Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
11803specified. Don't let the user enter a file name in the file\n\
11804selection dialog's entry field, if MUSTMATCH is non-nil.")
11805 (prompt, dir, default_filename, mustmatch)
11806 Lisp_Object prompt, dir, default_filename, mustmatch;
11807{
11808 FRAME_PTR f = SELECTED_FRAME ();
11809 char *fn;
11810 Lisp_Object file = Qnil;
11811 int count = specpdl_ptr - specpdl;
11812 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
11813 char *cdef_file;
11814 char *cprompt;
11815
11816 GCPRO5 (prompt, dir, default_filename, mustmatch, file);
11817 CHECK_STRING (prompt);
11818 CHECK_STRING (dir);
11819
11820 /* Prevent redisplay. */
11821 specbind (Qinhibit_redisplay, Qt);
11822
11823 BLOCK_INPUT;
11824
11825 if (STRINGP (default_filename))
11826 cdef_file = SDATA (default_filename);
11827 else
11828 cdef_file = SDATA (dir);
11829
11830 fn = xg_get_file_name (f, SDATA (prompt), cdef_file, ! NILP (mustmatch));
11831
11832 if (fn)
11833 {
11834 file = build_string (fn);
11835 xfree (fn);
11836 }
11837
11838 UNBLOCK_INPUT;
11839 UNGCPRO;
11840
11841 /* Make "Cancel" equivalent to C-g. */
11842 if (NILP (file))
11843 Fsignal (Qquit, Qnil);
11844
11845 return unbind_to (count, file);
11846}
11847
11848#endif /* USE_GTK */
11691 11849
11692 11850
11693/*********************************************************************** 11851/***********************************************************************
@@ -11734,7 +11892,7 @@ usual X keysyms. */)
11734 UNBLOCK_INPUT; 11892 UNBLOCK_INPUT;
11735 return Qnil; 11893 return Qnil;
11736 } 11894 }
11737 11895
11738 have_keys = Qnil; 11896 have_keys = Qnil;
11739 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd); 11897 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
11740 if (kb) 11898 if (kb)
@@ -11761,7 +11919,7 @@ usual X keysyms. */)
11761 } 11919 }
11762 11920
11763 XkbFreeClientMap (kb, 0, True); 11921 XkbFreeClientMap (kb, 0, True);
11764 11922
11765 if (delete_keycode 11923 if (delete_keycode
11766 && backspace_keycode 11924 && backspace_keycode
11767 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode 11925 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
@@ -11891,7 +12049,7 @@ syms_of_xfns ()
11891 staticpro (&QCcolor_adjustment); 12049 staticpro (&QCcolor_adjustment);
11892 QCmask = intern (":mask"); 12050 QCmask = intern (":mask");
11893 staticpro (&QCmask); 12051 staticpro (&QCmask);
11894 12052
11895 Qface_set_after_frame_default = intern ("face-set-after-frame-default"); 12053 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
11896 staticpro (&Qface_set_after_frame_default); 12054 staticpro (&Qface_set_after_frame_default);
11897 12055
@@ -11959,7 +12117,7 @@ or when you set the mouse color. */);
11959 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p, 12117 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
11960 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); 12118 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
11961 display_hourglass_p = 1; 12119 display_hourglass_p = 1;
11962 12120
11963 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay, 12121 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
11964 doc: /* *Seconds to wait before displaying an hourglass pointer. 12122 doc: /* *Seconds to wait before displaying an hourglass pointer.
11965Value must be an integer or float. */); 12123Value must be an integer or float. */);
@@ -11995,7 +12153,7 @@ or when you set the mouse color. */);
11995 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS). 12153 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
11996Text larger than this is clipped. */); 12154Text larger than this is clipped. */);
11997 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40)); 12155 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
11998 12156
11999 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, 12157 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
12000 doc: /* Non-nil if no X window manager is in use. 12158 doc: /* Non-nil if no X window manager is in use.
12001Emacs doesn't try to figure this out; this is always nil 12159Emacs doesn't try to figure this out; this is always nil
@@ -12064,7 +12222,7 @@ meaning don't clear the cache. */);
12064 defsubr (&Sx_synchronize); 12222 defsubr (&Sx_synchronize);
12065 defsubr (&Sx_focus_frame); 12223 defsubr (&Sx_focus_frame);
12066 defsubr (&Sx_backspace_delete_keys_p); 12224 defsubr (&Sx_backspace_delete_keys_p);
12067 12225
12068 /* Setting callback functions for fontset handler. */ 12226 /* Setting callback functions for fontset handler. */
12069 get_font_info_func = x_get_font_info; 12227 get_font_info_func = x_get_font_info;
12070 12228
@@ -12072,7 +12230,7 @@ meaning don't clear the cache. */);
12072 And the pointer assigned has the wrong type, anyway. */ 12230 And the pointer assigned has the wrong type, anyway. */
12073 list_fonts_func = x_list_fonts; 12231 list_fonts_func = x_list_fonts;
12074#endif 12232#endif
12075 12233
12076 load_font_func = x_load_font; 12234 load_font_func = x_load_font;
12077 find_ccl_program_func = x_find_ccl_program; 12235 find_ccl_program_func = x_find_ccl_program;
12078 query_font_func = x_query_font; 12236 query_font_func = x_query_font;
@@ -12113,16 +12271,16 @@ meaning don't clear the cache. */);
12113 Qxpm = intern ("xpm"); 12271 Qxpm = intern ("xpm");
12114 staticpro (&Qxpm); 12272 staticpro (&Qxpm);
12115#endif 12273#endif
12116 12274
12117#if HAVE_JPEG 12275#if HAVE_JPEG
12118 Qjpeg = intern ("jpeg"); 12276 Qjpeg = intern ("jpeg");
12119 staticpro (&Qjpeg); 12277 staticpro (&Qjpeg);
12120#endif 12278#endif
12121 12279
12122#if HAVE_TIFF 12280#if HAVE_TIFF
12123 Qtiff = intern ("tiff"); 12281 Qtiff = intern ("tiff");
12124 staticpro (&Qtiff); 12282 staticpro (&Qtiff);
12125#endif 12283#endif
12126 12284
12127#if HAVE_GIF 12285#if HAVE_GIF
12128 Qgif = intern ("gif"); 12286 Qgif = intern ("gif");
@@ -12162,27 +12320,27 @@ init_xfns ()
12162{ 12320{
12163 image_types = NULL; 12321 image_types = NULL;
12164 Vimage_types = Qnil; 12322 Vimage_types = Qnil;
12165 12323
12166 define_image_type (&xbm_type); 12324 define_image_type (&xbm_type);
12167 define_image_type (&gs_type); 12325 define_image_type (&gs_type);
12168 define_image_type (&pbm_type); 12326 define_image_type (&pbm_type);
12169 12327
12170#if HAVE_XPM 12328#if HAVE_XPM
12171 define_image_type (&xpm_type); 12329 define_image_type (&xpm_type);
12172#endif 12330#endif
12173 12331
12174#if HAVE_JPEG 12332#if HAVE_JPEG
12175 define_image_type (&jpeg_type); 12333 define_image_type (&jpeg_type);
12176#endif 12334#endif
12177 12335
12178#if HAVE_TIFF 12336#if HAVE_TIFF
12179 define_image_type (&tiff_type); 12337 define_image_type (&tiff_type);
12180#endif 12338#endif
12181 12339
12182#if HAVE_GIF 12340#if HAVE_GIF
12183 define_image_type (&gif_type); 12341 define_image_type (&gif_type);
12184#endif 12342#endif
12185 12343
12186#if HAVE_PNG 12344#if HAVE_PNG
12187 define_image_type (&png_type); 12345 define_image_type (&png_type);
12188#endif 12346#endif
diff --git a/src/xmenu.c b/src/xmenu.c
index e4b039808ec..bc3e22e3e16 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -81,7 +81,9 @@ Boston, MA 02111-1307, USA. */
81#endif /* USE_LUCID */ 81#endif /* USE_LUCID */
82#include "../lwlib/lwlib.h" 82#include "../lwlib/lwlib.h"
83#else /* not USE_X_TOOLKIT */ 83#else /* not USE_X_TOOLKIT */
84#ifndef USE_GTK
84#include "../oldXMenu/XMenu.h" 85#include "../oldXMenu/XMenu.h"
86#endif
85#endif /* not USE_X_TOOLKIT */ 87#endif /* not USE_X_TOOLKIT */
86#endif /* HAVE_X_WINDOWS */ 88#endif /* HAVE_X_WINDOWS */
87 89
@@ -116,6 +118,13 @@ static void popup_get_selection ();
116/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */ 118/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */
117 119
118#define HAVE_BOXES 1 120#define HAVE_BOXES 1
121#endif /* USE_X_TOOLKIT */
122
123#ifdef USE_GTK
124#include "gtkutil.h"
125#define HAVE_BOXES 1
126extern void set_frame_menubar ();
127static Lisp_Object xdialog_show ();
119#endif 128#endif
120 129
121static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 130static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
@@ -194,7 +203,7 @@ static int menu_items_submenu_depth;
194 203
195/* Flag which when set indicates a dialog or menu has been posted by 204/* Flag which when set indicates a dialog or menu has been posted by
196 Xt on behalf of one of the widget sets. */ 205 Xt on behalf of one of the widget sets. */
197int popup_activated_flag; 206static int popup_activated_flag;
198 207
199static int next_menubar_widget_id; 208static int next_menubar_widget_id;
200 209
@@ -593,7 +602,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
593 } 602 }
594#endif /* not HAVE_BOXES */ 603#endif /* not HAVE_BOXES */
595 604
596#ifndef USE_X_TOOLKIT 605#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
597 if (!NILP(map)) 606 if (!NILP(map))
598 /* Indicate visually that this is a submenu. */ 607 /* Indicate visually that this is a submenu. */
599 item_string = concat2 (item_string, build_string (" >")); 608 item_string = concat2 (item_string, build_string (" >"));
@@ -606,7 +615,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
606 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], 615 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
607 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); 616 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
608 617
609#ifdef USE_X_TOOLKIT 618#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
610 /* Display a submenu using the toolkit. */ 619 /* Display a submenu using the toolkit. */
611 if (! (NILP (map) || NILP (enabled))) 620 if (! (NILP (map) || NILP (enabled)))
612 { 621 {
@@ -771,6 +780,7 @@ cached information about equivalent key sequences. */)
771#ifdef HAVE_MENUS 780#ifdef HAVE_MENUS
772 if (! NILP (position)) 781 if (! NILP (position))
773 { 782 {
783 int get_current_pos_p = 0;
774 check_x (); 784 check_x ();
775 785
776 /* Decode the first argument: find the window and the coordinates. */ 786 /* Decode the first argument: find the window and the coordinates. */
@@ -778,6 +788,38 @@ cached information about equivalent key sequences. */)
778 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 788 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
779 || EQ (XCAR (position), Qtool_bar)))) 789 || EQ (XCAR (position), Qtool_bar))))
780 { 790 {
791 get_current_pos_p = 1;
792 }
793 else
794 {
795 tem = Fcar (position);
796 if (CONSP (tem))
797 {
798 window = Fcar (Fcdr (position));
799 x = Fcar (tem);
800 y = Fcar (Fcdr (tem));
801 }
802 else
803 {
804 for_click = 1;
805 tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
806 window = Fcar (tem); /* POSN_WINDOW (tem) */
807 tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
808 x = Fcar (tem);
809 y = Fcdr (tem);
810 }
811
812 /* If a click happens in an external tool bar or a detached
813 tool bar, x and y is NIL. In that case, use the current
814 mouse position. This happens for the help button in the
815 tool bar. Ideally popup-menu should pass NIL to
816 this function, but it doesn't. */
817 if (NILP (x) && NILP (y))
818 get_current_pos_p = 1;
819 }
820
821 if (get_current_pos_p)
822 {
781 /* Use the mouse's current position. */ 823 /* Use the mouse's current position. */
782 FRAME_PTR new_f = SELECTED_FRAME (); 824 FRAME_PTR new_f = SELECTED_FRAME ();
783#ifdef HAVE_X_WINDOWS 825#ifdef HAVE_X_WINDOWS
@@ -813,25 +855,6 @@ cached information about equivalent key sequences. */)
813 XSETFASTINT (y, 0); 855 XSETFASTINT (y, 0);
814 } 856 }
815 } 857 }
816 else
817 {
818 tem = Fcar (position);
819 if (CONSP (tem))
820 {
821 window = Fcar (Fcdr (position));
822 x = Fcar (tem);
823 y = Fcar (Fcdr (tem));
824 }
825 else
826 {
827 for_click = 1;
828 tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
829 window = Fcar (tem); /* POSN_WINDOW (tem) */
830 tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
831 x = Fcar (tem);
832 y = Fcdr (tem);
833 }
834 }
835 858
836 CHECK_NUMBER (x); 859 CHECK_NUMBER (x);
837 CHECK_NUMBER (y); 860 CHECK_NUMBER (y);
@@ -1040,7 +1063,7 @@ on the left of the dialog box and all following items on the right.
1040 but I don't want to make one now. */ 1063 but I don't want to make one now. */
1041 CHECK_WINDOW (window); 1064 CHECK_WINDOW (window);
1042 1065
1043#ifndef USE_X_TOOLKIT 1066#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1044 /* Display a menu with these alternatives 1067 /* Display a menu with these alternatives
1045 in the middle of frame F. */ 1068 in the middle of frame F. */
1046 { 1069 {
@@ -1081,7 +1104,7 @@ on the left of the dialog box and all following items on the right.
1081#endif 1104#endif
1082} 1105}
1083 1106
1084#ifdef USE_X_TOOLKIT 1107#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1085 1108
1086/* Loop in Xt until the menu pulldown or dialog popup has been 1109/* Loop in Xt until the menu pulldown or dialog popup has been
1087 popped down (deactivated). This is used for x-popup-menu 1110 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.
1092 NOTE: All calls to popup_get_selection should be protected 1115 NOTE: All calls to popup_get_selection should be protected
1093 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ 1116 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
1094 1117
1118#ifdef USE_X_TOOLKIT
1095static void 1119static void
1096popup_get_selection (initial_event, dpyinfo, id, do_timers) 1120popup_get_selection (initial_event, dpyinfo, id, do_timers)
1097 XEvent *initial_event; 1121 XEvent *initial_event;
@@ -1148,6 +1172,24 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
1148 } 1172 }
1149} 1173}
1150 1174
1175#endif /* USE_X_TOOLKIT */
1176
1177#ifdef USE_GTK
1178/* Loop util popup_activated_flag is set to zero in a callback.
1179 Used for popup menus and dialogs. */
1180static void
1181popup_widget_loop ()
1182{
1183 ++popup_activated_flag;
1184
1185 /* Process events in the Gtk event loop until done. */
1186 while (popup_activated_flag)
1187 {
1188 gtk_main_iteration ();
1189 }
1190}
1191#endif
1192
1151/* Activate the menu bar of frame F. 1193/* Activate the menu bar of frame F.
1152 This is called from keyboard.c when it gets the 1194 This is called from keyboard.c when it gets the
1153 MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue. 1195 MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
@@ -1169,9 +1211,20 @@ x_activate_menubar (f)
1169 if (!f->output_data.x->saved_menu_event->type) 1211 if (!f->output_data.x->saved_menu_event->type)
1170 return; 1212 return;
1171 1213
1214#ifdef USE_GTK
1215 if (! xg_win_to_widget (f->output_data.x->saved_menu_event->xany.window))
1216 return;
1217#endif
1218
1172 set_frame_menubar (f, 0, 1); 1219 set_frame_menubar (f, 0, 1);
1173 BLOCK_INPUT; 1220 BLOCK_INPUT;
1221#ifdef USE_GTK
1222 XPutBackEvent (f->output_data.x->display_info->display,
1223 f->output_data.x->saved_menu_event);
1224 popup_activated_flag = 1;
1225#else
1174 XtDispatchEvent (f->output_data.x->saved_menu_event); 1226 XtDispatchEvent (f->output_data.x->saved_menu_event);
1227#endif
1175 UNBLOCK_INPUT; 1228 UNBLOCK_INPUT;
1176#ifdef USE_MOTIF 1229#ifdef USE_MOTIF
1177 if (f->output_data.x->saved_menu_event->type == ButtonRelease) 1230 if (f->output_data.x->saved_menu_event->type == ButtonRelease)
@@ -1193,6 +1246,7 @@ popup_activated ()
1193/* This callback is invoked when the user selects a menubar cascade 1246/* This callback is invoked when the user selects a menubar cascade
1194 pushbutton, but before the pulldown menu is posted. */ 1247 pushbutton, but before the pulldown menu is posted. */
1195 1248
1249#ifndef USE_GTK
1196static void 1250static void
1197popup_activate_callback (widget, id, client_data) 1251popup_activate_callback (widget, id, client_data)
1198 Widget widget; 1252 Widget widget;
@@ -1201,10 +1255,20 @@ popup_activate_callback (widget, id, client_data)
1201{ 1255{
1202 popup_activated_flag = 1; 1256 popup_activated_flag = 1;
1203} 1257}
1258#endif
1204 1259
1205/* This callback is invoked when a dialog or menu is finished being 1260/* This callback is invoked when a dialog or menu is finished being
1206 used and has been unposted. */ 1261 used and has been unposted. */
1207 1262
1263#ifdef USE_GTK
1264static void
1265popup_deactivate_callback (widget, client_data)
1266 GtkWidget *widget;
1267 gpointer client_data;
1268{
1269 popup_activated_flag = 0;
1270}
1271#else
1208static void 1272static void
1209popup_deactivate_callback (widget, id, client_data) 1273popup_deactivate_callback (widget, id, client_data)
1210 Widget widget; 1274 Widget widget;
@@ -1213,27 +1277,20 @@ popup_deactivate_callback (widget, id, client_data)
1213{ 1277{
1214 popup_activated_flag = 0; 1278 popup_activated_flag = 0;
1215} 1279}
1280#endif
1216 1281
1217/* Lwlib callback called when menu items are highlighted/unhighlighted
1218 while moving the mouse over them. WIDGET is the menu bar or menu
1219 popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
1220 the widget_value structure for the menu item, or null in case of
1221 unhighlighting. */
1222 1282
1223void 1283/* Function that finds the frame for WIDGET and shows the HELP text
1224menu_highlight_callback (widget, id, call_data) 1284 for that widget.
1225 Widget widget; 1285 F is the frame if known, or NULL if not known. */
1226 LWLIB_ID id; 1286static void
1227 void *call_data; 1287show_help_event (f, widget, help)
1288 FRAME_PTR f;
1289 xt_or_gtk_widget widget;
1290 Lisp_Object help;
1228{ 1291{
1229 widget_value *wv = (widget_value *) call_data; 1292 Lisp_Object frame;
1230 struct frame *f;
1231 Lisp_Object frame, help;
1232 1293
1233 help = wv ? wv->help : Qnil;
1234
1235 /* Determine the frame for the help event. */
1236 f = menubar_id_to_frame (id);
1237 if (f) 1294 if (f)
1238 { 1295 {
1239 XSETFRAME (frame, f); 1296 XSETFRAME (frame, f);
@@ -1243,7 +1300,7 @@ menu_highlight_callback (widget, id, call_data)
1243 { 1300 {
1244 /* WIDGET is the popup menu. It's parent is the frame's 1301 /* WIDGET is the popup menu. It's parent is the frame's
1245 widget. See which frame that is. */ 1302 widget. See which frame that is. */
1246 Widget frame_widget = XtParent (widget); 1303 xt_or_gtk_widget frame_widget = XtParent (widget);
1247 Lisp_Object tail; 1304 Lisp_Object tail;
1248 1305
1249 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) 1306 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
@@ -1259,32 +1316,77 @@ menu_highlight_callback (widget, id, call_data)
1259 } 1316 }
1260} 1317}
1261 1318
1262/* This callback is called from the menu bar pulldown menu 1319/* Callback called when menu items are highlighted/unhighlighted
1263 when the user makes a selection. 1320 while moving the mouse over them. WIDGET is the menu bar or menu
1264 Figure out what the user chose 1321 popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
1265 and put the appropriate events into the keyboard buffer. */ 1322 the data structure for the menu item, or null in case of
1323 unhighlighting. */
1266 1324
1267static void 1325#ifdef USE_GTK
1268menubar_selection_callback (widget, id, client_data) 1326void
1327menu_highlight_callback (widget, call_data)
1328 GtkWidget *widget;
1329 gpointer call_data;
1330{
1331 xg_menu_item_cb_data *cb_data;
1332 Lisp_Object help;
1333
1334 cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (widget),
1335 XG_ITEM_DATA);
1336 if (! cb_data) return;
1337
1338 help = call_data ? cb_data->help : Qnil;
1339
1340 /* If popup_activated_flag is greater than 1 we are in a popup menu.
1341 Don't show help for them, they won't appear before the
1342 popup is popped down. */
1343 if (popup_activated_flag <= 1)
1344 show_help_event (cb_data->cl_data->f, widget, help);
1345}
1346#else
1347void
1348menu_highlight_callback (widget, id, call_data)
1269 Widget widget; 1349 Widget widget;
1270 LWLIB_ID id; 1350 LWLIB_ID id;
1271 XtPointer client_data; 1351 void *call_data;
1352{
1353 struct frame *f;
1354 Lisp_Object help;
1355
1356 widget_value *wv = (widget_value *) call_data;
1357
1358 help = wv ? wv->help : Qnil;
1359
1360 /* Determine the frame for the help event. */
1361 f = menubar_id_to_frame (id);
1362
1363 show_help_event (f, widget, help);
1364}
1365#endif
1366
1367/* Find the menu selection and store it in the keyboard buffer.
1368 F is the frame the menu is on.
1369 MENU_BAR_ITEMS_USED is the length of VECTOR.
1370 VECTOR is an array of menu events for the whole menu.
1371 */
1372void
1373find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
1374 FRAME_PTR f;
1375 int menu_bar_items_used;
1376 Lisp_Object vector;
1377 void *client_data;
1272{ 1378{
1273 Lisp_Object prefix, entry; 1379 Lisp_Object prefix, entry;
1274 FRAME_PTR f = menubar_id_to_frame (id);
1275 Lisp_Object vector;
1276 Lisp_Object *subprefix_stack; 1380 Lisp_Object *subprefix_stack;
1277 int submenu_depth = 0; 1381 int submenu_depth = 0;
1278 int i; 1382 int i;
1279 1383
1280 if (!f)
1281 return;
1282 entry = Qnil; 1384 entry = Qnil;
1283 subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * sizeof (Lisp_Object)); 1385 subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof (Lisp_Object));
1284 vector = f->menu_bar_vector;
1285 prefix = Qnil; 1386 prefix = Qnil;
1286 i = 0; 1387 i = 0;
1287 while (i < f->menu_bar_items_used) 1388
1389 while (i < menu_bar_items_used)
1288 { 1390 {
1289 if (EQ (XVECTOR (vector)->contents[i], Qnil)) 1391 if (EQ (XVECTOR (vector)->contents[i], Qnil))
1290 { 1392 {
@@ -1348,6 +1450,59 @@ menubar_selection_callback (widget, id, client_data)
1348 } 1450 }
1349} 1451}
1350 1452
1453
1454#ifdef USE_GTK
1455/* Gtk calls callbacks just because we tell it what item should be
1456 selected in a radio group. If this variable is set to a non-zero
1457 value, we are creating menus and don't want callbacks right now.
1458*/
1459static int xg_crazy_callback_abort;
1460
1461/* This callback is called from the menu bar pulldown menu
1462 when the user makes a selection.
1463 Figure out what the user chose
1464 and put the appropriate events into the keyboard buffer. */
1465static void
1466menubar_selection_callback (widget, client_data)
1467 GtkWidget *widget;
1468 gpointer client_data;
1469{
1470 xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data;
1471
1472 if (xg_crazy_callback_abort)
1473 return;
1474
1475 if (! cb_data || ! cb_data->cl_data || ! cb_data->cl_data->f)
1476 return;
1477
1478 find_and_call_menu_selection (cb_data->cl_data->f,
1479 cb_data->cl_data->menu_bar_items_used,
1480 cb_data->cl_data->menu_bar_vector,
1481 cb_data->call_data);
1482}
1483
1484#else /* not USE_GTK */
1485
1486/* This callback is called from the menu bar pulldown menu
1487 when the user makes a selection.
1488 Figure out what the user chose
1489 and put the appropriate events into the keyboard buffer. */
1490static void
1491menubar_selection_callback (widget, id, client_data)
1492 Widget widget;
1493 LWLIB_ID id;
1494 XtPointer client_data;
1495{
1496 FRAME_PTR f;
1497
1498 f = menubar_id_to_frame (id);
1499 if (!f)
1500 return;
1501 find_and_call_menu_selection (f, f->menu_bar_items_used,
1502 f->menu_bar_vector, client_data);
1503}
1504#endif /* not USE_GTK */
1505
1351/* Allocate a widget_value, blocking input. */ 1506/* Allocate a widget_value, blocking input. */
1352 1507
1353widget_value * 1508widget_value *
@@ -1623,9 +1778,12 @@ static int
1623update_frame_menubar (f) 1778update_frame_menubar (f)
1624 FRAME_PTR f; 1779 FRAME_PTR f;
1625{ 1780{
1781#ifdef USE_GTK
1782 return xg_update_frame_menubar (f);
1783#else
1626 struct x_output *x = f->output_data.x; 1784 struct x_output *x = f->output_data.x;
1627 int columns, rows; 1785 int columns, rows;
1628 1786
1629 if (!x->menubar_widget || XtIsManaged (x->menubar_widget)) 1787 if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
1630 return 0; 1788 return 0;
1631 1789
@@ -1657,6 +1815,7 @@ update_frame_menubar (f)
1657 /* Force the pane widget to resize itself with the right values. */ 1815 /* Force the pane widget to resize itself with the right values. */
1658 EmacsFrameSetCharSize (x->edit_widget, columns, rows); 1816 EmacsFrameSetCharSize (x->edit_widget, columns, rows);
1659 UNBLOCK_INPUT; 1817 UNBLOCK_INPUT;
1818#endif
1660 return 1; 1819 return 1;
1661} 1820}
1662 1821
@@ -1670,21 +1829,25 @@ set_frame_menubar (f, first_time, deep_p)
1670 int first_time; 1829 int first_time;
1671 int deep_p; 1830 int deep_p;
1672{ 1831{
1673 Widget menubar_widget = f->output_data.x->menubar_widget; 1832 xt_or_gtk_widget menubar_widget = f->output_data.x->menubar_widget;
1833#ifdef USE_X_TOOLKIT
1834 LWLIB_ID id;
1835#endif
1674 Lisp_Object items; 1836 Lisp_Object items;
1675 widget_value *wv, *first_wv, *prev_wv = 0; 1837 widget_value *wv, *first_wv, *prev_wv = 0;
1676 int i, last_i; 1838 int i, last_i;
1677 int *submenu_start, *submenu_end; 1839 int *submenu_start, *submenu_end;
1678 int *submenu_top_level_items, *submenu_n_panes; 1840 int *submenu_top_level_items, *submenu_n_panes;
1679 1841
1680 LWLIB_ID id;
1681 1842
1682 XSETFRAME (Vmenu_updating_frame, f); 1843 XSETFRAME (Vmenu_updating_frame, f);
1683 1844
1845#ifdef USE_X_TOOLKIT
1684 if (f->output_data.x->id == 0) 1846 if (f->output_data.x->id == 0)
1685 f->output_data.x->id = next_menubar_widget_id++; 1847 f->output_data.x->id = next_menubar_widget_id++;
1686 id = f->output_data.x->id; 1848 id = f->output_data.x->id;
1687 1849#endif
1850
1688 if (! menubar_widget) 1851 if (! menubar_widget)
1689 deep_p = 1; 1852 deep_p = 1;
1690 else if (pending_menu_activation && !deep_p) 1853 else if (pending_menu_activation && !deep_p)
@@ -1893,6 +2056,35 @@ set_frame_menubar (f, first_time, deep_p)
1893 2056
1894 BLOCK_INPUT; 2057 BLOCK_INPUT;
1895 2058
2059#ifdef USE_GTK
2060 xg_crazy_callback_abort = 1;
2061 if (menubar_widget)
2062 {
2063 /* The third arg is DEEP_P, which says to consider the entire
2064 menu trees we supply, rather than just the menu bar item names. */
2065 xg_modify_menubar_widgets (menubar_widget,
2066 f,
2067 first_wv,
2068 deep_p,
2069 G_CALLBACK (menubar_selection_callback),
2070 G_CALLBACK (popup_deactivate_callback),
2071 G_CALLBACK (menu_highlight_callback));
2072 }
2073 else
2074 {
2075 GtkWidget *wvbox = f->output_data.x->vbox_widget;
2076
2077 menubar_widget
2078 = xg_create_widget ("menubar", "menubar", f, first_wv,
2079 G_CALLBACK (menubar_selection_callback),
2080 G_CALLBACK (popup_deactivate_callback),
2081 G_CALLBACK (menu_highlight_callback));
2082
2083 f->output_data.x->menubar_widget = menubar_widget;
2084 }
2085
2086
2087#else /* not USE_GTK */
1896 if (menubar_widget) 2088 if (menubar_widget)
1897 { 2089 {
1898 /* Disable resizing (done for Motif!) */ 2090 /* Disable resizing (done for Motif!) */
@@ -1939,10 +2131,15 @@ set_frame_menubar (f, first_time, deep_p)
1939 2131
1940 f->output_data.x->menubar_height = menubar_size; 2132 f->output_data.x->menubar_height = menubar_size;
1941 } 2133 }
2134#endif /* not USE_GTK */
1942 2135
1943 free_menubar_widget_value_tree (first_wv); 2136 free_menubar_widget_value_tree (first_wv);
1944 update_frame_menubar (f); 2137 update_frame_menubar (f);
1945 2138
2139#ifdef USE_GTK
2140 xg_crazy_callback_abort = 0;
2141#endif
2142
1946 UNBLOCK_INPUT; 2143 UNBLOCK_INPUT;
1947} 2144}
1948 2145
@@ -1963,8 +2160,10 @@ initialize_frame_menubar (f)
1963 2160
1964 2161
1965/* Get rid of the menu bar of frame F, and free its storage. 2162/* Get rid of the menu bar of frame F, and free its storage.
1966 This is used when deleting a frame, and when turning off the menu bar. */ 2163 This is used when deleting a frame, and when turning off the menu bar.
2164 For GTK this function is in gtkutil.c. */
1967 2165
2166#ifndef USE_GTK
1968void 2167void
1969free_frame_menubar (f) 2168free_frame_menubar (f)
1970 FRAME_PTR f; 2169 FRAME_PTR f;
@@ -2011,8 +2210,9 @@ free_frame_menubar (f)
2011 UNBLOCK_INPUT; 2210 UNBLOCK_INPUT;
2012 } 2211 }
2013} 2212}
2213#endif /* not USE_GTK */
2014 2214
2015#endif /* USE_X_TOOLKIT */ 2215#endif /* USE_X_TOOLKIT || USE_GTK */
2016 2216
2017/* xmenu_show actually displays a menu using the panes and items in menu_items 2217/* xmenu_show actually displays a menu using the panes and items in menu_items
2018 and returns the value selected from it. 2218 and returns the value selected from it.
@@ -2030,7 +2230,116 @@ free_frame_menubar (f)
2030 ERROR is a place to store an error message string in case of failure. 2230 ERROR is a place to store an error message string in case of failure.
2031 (We return nil on failure, but the value doesn't actually matter.) */ 2231 (We return nil on failure, but the value doesn't actually matter.) */
2032 2232
2033#ifdef USE_X_TOOLKIT 2233#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
2234
2235/* The item selected in the popup menu. */
2236static Lisp_Object *volatile menu_item_selection;
2237
2238#ifdef USE_GTK
2239
2240/* Used when position a popup menu. See menu_position_func and
2241 create_and_show_popup_menu below. */
2242struct next_popup_x_y
2243{
2244 int x;
2245 int y;
2246};
2247
2248/* The menu position function to use if we are not putting a popup
2249 menu where the pointer is.
2250 MENU is the menu to pop up.
2251 X and Y shall on exit contain x/y where the menu shall pop up.
2252 PUSH_IN is not documented in the GTK manual.
2253 USER_DATA is any data passed in when calling gtk_menu_popup.
2254 Here it points to a struct next_popup_x_y where the coordinates
2255 to store in *X and *Y are.
2256
2257 Here only X and Y are used. */
2258static void
2259menu_position_func (menu, x, y, push_in, user_data)
2260 GtkMenu *menu;
2261 gint *x;
2262 gint *y;
2263 gboolean *push_in;
2264 gpointer user_data;
2265{
2266 *x = ((struct next_popup_x_y*)user_data)->x;
2267 *y = ((struct next_popup_x_y*)user_data)->y;
2268}
2269
2270static void
2271popup_selection_callback (widget, client_data)
2272 GtkWidget *widget;
2273 gpointer client_data;
2274{
2275 xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data;
2276
2277 if (xg_crazy_callback_abort) return;
2278 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
2279}
2280
2281/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
2282 menu pops down.
2283 menu_item_selection will be set to the selection. */
2284static void
2285create_and_show_popup_menu (f, first_wv, x, y, for_click)
2286 FRAME_PTR f;
2287 widget_value *first_wv;
2288 int x;
2289 int y;
2290 int for_click;
2291{
2292 int i;
2293 GtkWidget *menu;
2294 GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */
2295 struct next_popup_x_y popup_x_y;
2296
2297 xg_crazy_callback_abort = 1;
2298 menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
2299 G_CALLBACK (popup_selection_callback),
2300 G_CALLBACK (popup_deactivate_callback),
2301 G_CALLBACK (menu_highlight_callback));
2302 xg_crazy_callback_abort = 0;
2303
2304 for (i = 0; i < 5; i++)
2305 if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
2306 break;
2307
2308 if (! for_click)
2309 {
2310 /* Not invoked by a click. pop up at x/y. */
2311 pos_func = menu_position_func;
2312
2313 /* Adjust coordinates to be root-window-relative. */
2314 x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2315 y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2316
2317 popup_x_y.x = x;
2318 popup_x_y.y = y;
2319 }
2320
2321 /* Display the menu. */
2322 gtk_widget_show_all (menu);
2323 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
2324
2325 xg_did_tearoff = 0;
2326 /* Set this to one. popup_widget_loop increases it by one, so it becomes
2327 two. show_help_echo uses this to detect popup menus. */
2328 popup_activated_flag = 1;
2329 /* Process events that apply to the menu. */
2330 popup_widget_loop ();
2331
2332 if (xg_did_tearoff)
2333 xg_keep_popup (menu, xg_did_tearoff);
2334 else
2335 gtk_widget_destroy (menu);
2336
2337 /* Must reset this manually because the button release event is not passed
2338 to Emacs event loop. */
2339 FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
2340}
2341
2342#else /* not USE_GTK */
2034 2343
2035/* We need a unique id for each widget handled by the Lucid Widget 2344/* We need a unique id for each widget handled by the Lucid Widget
2036 library. 2345 library.
@@ -2042,8 +2351,6 @@ free_frame_menubar (f)
2042 next_menubar_widget_id. */ 2351 next_menubar_widget_id. */
2043LWLIB_ID widget_id_tick; 2352LWLIB_ID widget_id_tick;
2044 2353
2045static Lisp_Object *volatile menu_item_selection;
2046
2047static void 2354static void
2048popup_selection_callback (widget, id, client_data) 2355popup_selection_callback (widget, id, client_data)
2049 Widget widget; 2356 Widget widget;
@@ -2053,6 +2360,76 @@ popup_selection_callback (widget, id, client_data)
2053 menu_item_selection = (Lisp_Object *) client_data; 2360 menu_item_selection = (Lisp_Object *) client_data;
2054} 2361}
2055 2362
2363/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
2364 menu pops down.
2365 menu_item_selection will be set to the selection. */
2366static void
2367create_and_show_popup_menu (f, first_wv, x, y, for_click)
2368 FRAME_PTR f;
2369 widget_value *first_wv;
2370 int x;
2371 int y;
2372 int for_click;
2373{
2374 int i;
2375 Arg av[2];
2376 int ac = 0;
2377 XButtonPressedEvent dummy;
2378 LWLIB_ID menu_id;
2379 Widget menu;
2380 Window child;
2381
2382 menu_id = widget_id_tick++;
2383 menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
2384 f->output_data.x->widget, 1, 0,
2385 popup_selection_callback,
2386 popup_deactivate_callback,
2387 menu_highlight_callback);
2388
2389 dummy.type = ButtonPress;
2390 dummy.serial = 0;
2391 dummy.send_event = 0;
2392 dummy.display = FRAME_X_DISPLAY (f);
2393 dummy.time = CurrentTime;
2394 dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window;
2395 dummy.window = dummy.root;
2396 dummy.subwindow = dummy.root;
2397 dummy.x = x;
2398 dummy.y = y;
2399
2400 /* Adjust coordinates to be root-window-relative. */
2401 x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2402 y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2403
2404 dummy.x_root = x;
2405 dummy.y_root = y;
2406
2407 dummy.state = 0;
2408 dummy.button = 0;
2409 for (i = 0; i < 5; i++)
2410 if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
2411 dummy.button = i;
2412
2413 /* Don't allow any geometry request from the user. */
2414 XtSetArg (av[ac], XtNgeometry, 0); ac++;
2415 XtSetValues (menu, av, ac);
2416
2417 /* Display the menu. */
2418 lw_popup_menu (menu, (XEvent *) &dummy);
2419 popup_activated_flag = 1;
2420
2421 /* Process events that apply to the menu. */
2422 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0);
2423
2424 /* fp turned off the following statement and wrote a comment
2425 that it is unnecessary--that the menu has already disappeared.
2426 Nowadays the menu disappears ok, all right, but
2427 we need to delete the widgets or multiple ones will pile up. */
2428 lw_destroy_all_widgets (menu_id);
2429}
2430
2431#endif /* not USE_GTK */
2432
2056static Lisp_Object 2433static Lisp_Object
2057xmenu_show (f, x, y, for_click, keymaps, title, error) 2434xmenu_show (f, x, y, for_click, keymaps, title, error)
2058 FRAME_PTR f; 2435 FRAME_PTR f;
@@ -2064,17 +2441,12 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
2064 char **error; 2441 char **error;
2065{ 2442{
2066 int i; 2443 int i;
2067 LWLIB_ID menu_id;
2068 Widget menu;
2069 Arg av[2];
2070 int ac = 0;
2071 widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; 2444 widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
2072 widget_value **submenu_stack 2445 widget_value **submenu_stack
2073 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 2446 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
2074 Lisp_Object *subprefix_stack 2447 Lisp_Object *subprefix_stack
2075 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); 2448 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
2076 int submenu_depth = 0; 2449 int submenu_depth = 0;
2077 XButtonPressedEvent dummy;
2078 2450
2079 int first_pane; 2451 int first_pane;
2080 2452
@@ -2266,70 +2638,14 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
2266 first_wv->contents = wv_title; 2638 first_wv->contents = wv_title;
2267 } 2639 }
2268 2640
2269 /* Actually create the menu. */
2270 menu_id = widget_id_tick++;
2271 menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
2272 f->output_data.x->widget, 1, 0,
2273 popup_selection_callback,
2274 popup_deactivate_callback,
2275 menu_highlight_callback);
2276
2277 /* See if whe positions are up to date. Temporary code to be removed
2278 when we are sure positions are always up to date. */
2279 {
2280 int real_x, real_y;
2281 x_real_positions (f, &real_x, &real_y);
2282
2283 if (real_x != f->output_data.x->left_pos ||
2284 real_y != f->output_data.x->top_pos)
2285 abort ();
2286 }
2287
2288 dummy.type = ButtonPress;
2289 dummy.serial = 0;
2290 dummy.send_event = 0;
2291 dummy.display = FRAME_X_DISPLAY (f);
2292 dummy.time = CurrentTime;
2293 dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window;
2294 dummy.window = dummy.root;
2295 dummy.subwindow = dummy.root;
2296 dummy.x = x;
2297 dummy.y = y;
2298
2299 /* Adjust coordinates to be root-window-relative. */
2300 x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2301 y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2302
2303 dummy.x_root = x;
2304 dummy.y_root = y;
2305 dummy.state = 0;
2306 dummy.button = 0;
2307 for (i = 0; i < 5; i++)
2308 if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
2309 dummy.button = i;
2310
2311 /* Don't allow any geometry request from the user. */
2312 XtSetArg (av[ac], XtNgeometry, 0); ac++;
2313 XtSetValues (menu, av, ac);
2314
2315 /* Free the widget_value objects we used to specify the contents. */
2316 free_menubar_widget_value_tree (first_wv);
2317
2318 /* No selection has been chosen yet. */ 2641 /* No selection has been chosen yet. */
2319 menu_item_selection = 0; 2642 menu_item_selection = 0;
2320 2643
2321 /* Display the menu. */ 2644 /* Actually create and show the menu until popped down. */
2322 lw_popup_menu (menu, (XEvent *) &dummy); 2645 create_and_show_popup_menu (f, first_wv, x, y, for_click);
2323 popup_activated_flag = 1;
2324 2646
2325 /* Process events that apply to the menu. */ 2647 /* Free the widget_value objects we used to specify the contents. */
2326 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0); 2648 free_menubar_widget_value_tree (first_wv);
2327
2328 /* fp turned off the following statement and wrote a comment
2329 that it is unnecessary--that the menu has already disappeared.
2330 Nowadays the menu disappears ok, all right, but
2331 we need to delete the widgets or multiple ones will pile up. */
2332 lw_destroy_all_widgets (menu_id);
2333 2649
2334 /* Find the selected item, and its pane, to return 2650 /* Find the selected item, and its pane, to return
2335 the proper value. */ 2651 the proper value. */
@@ -2389,6 +2705,48 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
2389 return Qnil; 2705 return Qnil;
2390} 2706}
2391 2707
2708#ifdef USE_GTK
2709static void
2710dialog_selection_callback (widget, client_data)
2711 GtkWidget *widget;
2712 gpointer client_data;
2713{
2714 /* The EMACS_INT cast avoids a warning. There's no problem
2715 as long as pointers have enough bits to hold small integers. */
2716 if ((int) (EMACS_INT) client_data != -1)
2717 menu_item_selection = (Lisp_Object *) client_data;
2718
2719 popup_activated_flag = 0;
2720}
2721
2722/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
2723 dialog pops down.
2724 menu_item_selection will be set to the selection. */
2725static void
2726create_and_show_dialog (f, first_wv)
2727 FRAME_PTR f;
2728 widget_value *first_wv;
2729{
2730 GtkWidget *menu;
2731
2732 menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
2733 G_CALLBACK (dialog_selection_callback),
2734 G_CALLBACK (popup_deactivate_callback),
2735 0);
2736
2737 if (menu)
2738 {
2739 /* Display the menu. */
2740 gtk_widget_show_all (menu);
2741
2742 /* Process events that apply to the menu. */
2743 popup_widget_loop ();
2744
2745 gtk_widget_destroy (menu);
2746 }
2747}
2748
2749#else /* not USE_GTK */
2392static void 2750static void
2393dialog_selection_callback (widget, id, client_data) 2751dialog_selection_callback (widget, id, client_data)
2394 Widget widget; 2752 Widget widget;
@@ -2399,12 +2757,14 @@ dialog_selection_callback (widget, id, client_data)
2399 as long as pointers have enough bits to hold small integers. */ 2757 as long as pointers have enough bits to hold small integers. */
2400 if ((int) (EMACS_INT) client_data != -1) 2758 if ((int) (EMACS_INT) client_data != -1)
2401 menu_item_selection = (Lisp_Object *) client_data; 2759 menu_item_selection = (Lisp_Object *) client_data;
2760
2402 BLOCK_INPUT; 2761 BLOCK_INPUT;
2403 lw_destroy_all_widgets (id); 2762 lw_destroy_all_widgets (id);
2404 UNBLOCK_INPUT; 2763 UNBLOCK_INPUT;
2405 popup_activated_flag = 0; 2764 popup_activated_flag = 0;
2406} 2765}
2407 2766
2767
2408/* ARG is the LWLIB ID of the dialog box, represented 2768/* ARG is the LWLIB ID of the dialog box, represented
2409 as a Lisp object as (HIGHPART . LOWPART). */ 2769 as a Lisp object as (HIGHPART . LOWPART). */
2410 2770
@@ -2421,6 +2781,46 @@ xdialog_show_unwind (arg)
2421 return Qnil; 2781 return Qnil;
2422} 2782}
2423 2783
2784
2785/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
2786 dialog pops down.
2787 menu_item_selection will be set to the selection. */
2788static void
2789create_and_show_dialog (f, first_wv)
2790 FRAME_PTR f;
2791 widget_value *first_wv;
2792{
2793 LWLIB_ID dialog_id;
2794
2795 dialog_id = widget_id_tick++;
2796 lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
2797 f->output_data.x->widget, 1, 0,
2798 dialog_selection_callback, 0, 0);
2799 lw_modify_all_widgets (dialog_id, first_wv->contents, True);
2800
2801 /* Display the dialog box. */
2802 lw_pop_up_all_widgets (dialog_id);
2803 popup_activated_flag = 1;
2804
2805 /* Process events that apply to the dialog box.
2806 Also handle timers. */
2807 {
2808 int count = SPECPDL_INDEX ();
2809 int fact = 4 * sizeof (LWLIB_ID);
2810
2811 /* xdialog_show_unwind is responsible for popping the dialog box down. */
2812 record_unwind_protect (xdialog_show_unwind,
2813 Fcons (make_number (dialog_id >> (fact)),
2814 make_number (dialog_id & ~(-1 << (fact)))));
2815
2816 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
2817
2818 unbind_to (count, Qnil);
2819 }
2820}
2821
2822#endif /* not USE_GTK */
2823
2424static char * button_names [] = { 2824static char * button_names [] = {
2425 "button1", "button2", "button3", "button4", "button5", 2825 "button1", "button2", "button3", "button4", "button5",
2426 "button6", "button7", "button8", "button9", "button10" }; 2826 "button6", "button7", "button8", "button9", "button10" };
@@ -2433,7 +2833,6 @@ xdialog_show (f, keymaps, title, error)
2433 char **error; 2833 char **error;
2434{ 2834{
2435 int i, nb_buttons=0; 2835 int i, nb_buttons=0;
2436 LWLIB_ID dialog_id;
2437 char dialog_name[6]; 2836 char dialog_name[6];
2438 2837
2439 widget_value *wv, *first_wv = 0, *prev_wv = 0; 2838 widget_value *wv, *first_wv = 0, *prev_wv = 0;
@@ -2543,38 +2942,17 @@ xdialog_show (f, keymaps, title, error)
2543 first_wv = wv; 2942 first_wv = wv;
2544 } 2943 }
2545 2944
2546 /* Actually create the dialog. */
2547 dialog_id = widget_id_tick++;
2548 lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
2549 f->output_data.x->widget, 1, 0,
2550 dialog_selection_callback, 0, 0);
2551 lw_modify_all_widgets (dialog_id, first_wv->contents, True);
2552 /* Free the widget_value objects we used to specify the contents. */
2553 free_menubar_widget_value_tree (first_wv);
2554
2555 /* No selection has been chosen yet. */ 2945 /* No selection has been chosen yet. */
2556 menu_item_selection = 0; 2946 menu_item_selection = 0;
2557 2947
2558 /* Display the dialog box. */ 2948 /* Actually create and show the dialog. */
2559 lw_pop_up_all_widgets (dialog_id); 2949 create_and_show_dialog (f, first_wv);
2560 popup_activated_flag = 1;
2561
2562 /* Process events that apply to the dialog box.
2563 Also handle timers. */
2564 {
2565 int count = SPECPDL_INDEX ();
2566
2567 /* xdialog_show_unwind is responsible for popping the dialog box down. */
2568 record_unwind_protect (xdialog_show_unwind,
2569 Fcons (make_number (dialog_id >> (4 * sizeof (LWLIB_ID))),
2570 make_number (dialog_id & ~(-1 << (4 * sizeof (LWLIB_ID))))));
2571
2572 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
2573
2574 unbind_to (count, Qnil);
2575 }
2576 2950
2577 /* Find the selected item and pane, and return the corresponding value. */ 2951 /* Free the widget_value objects we used to specify the contents. */
2952 free_menubar_widget_value_tree (first_wv);
2953
2954 /* Find the selected item, and its pane, to return
2955 the proper value. */
2578 if (menu_item_selection != 0) 2956 if (menu_item_selection != 0)
2579 { 2957 {
2580 Lisp_Object prefix; 2958 Lisp_Object prefix;
@@ -2619,7 +2997,7 @@ xdialog_show (f, keymaps, title, error)
2619 return Qnil; 2997 return Qnil;
2620} 2998}
2621 2999
2622#else /* not USE_X_TOOLKIT */ 3000#else /* not USE_X_TOOLKIT && not USE_GTK */
2623 3001
2624/* The frame of the last activated non-toolkit menu bar. 3002/* The frame of the last activated non-toolkit menu bar.
2625 Used to generate menu help events. */ 3003 Used to generate menu help events. */
diff --git a/src/xterm.c b/src/xterm.c
index 220c45e648c..348355d2b5b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -97,17 +97,23 @@ Boston, MA 02111-1307, USA. */
97#include <unistd.h> 97#include <unistd.h>
98#endif 98#endif
99 99
100#ifdef USE_GTK
101#include "gtkutil.h"
102#endif
103
100#ifdef USE_LUCID 104#ifdef USE_LUCID
101extern int xlwmenu_window_p P_ ((Widget w, Window window)); 105extern int xlwmenu_window_p P_ ((Widget w, Window window));
102extern void xlwmenu_redisplay P_ ((Widget)); 106extern void xlwmenu_redisplay P_ ((Widget));
103#endif 107#endif
104 108
105#ifdef USE_X_TOOLKIT 109#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
106 110
107extern void free_frame_menubar P_ ((struct frame *)); 111extern void free_frame_menubar P_ ((struct frame *));
108extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *, 112extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *,
109 int)); 113 int));
114#endif
110 115
116#ifdef USE_X_TOOLKIT
111#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES) 117#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
112#define HACK_EDITRES 118#define HACK_EDITRES
113extern void _XEditResCheckMessages (); 119extern void _XEditResCheckMessages ();
@@ -138,7 +144,7 @@ extern void _XEditResCheckMessages ();
138 144
139#endif /* USE_X_TOOLKIT */ 145#endif /* USE_X_TOOLKIT */
140 146
141#ifndef USE_X_TOOLKIT 147#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
142#define x_any_window_to_frame x_window_to_frame 148#define x_any_window_to_frame x_window_to_frame
143#define x_top_window_to_frame x_window_to_frame 149#define x_top_window_to_frame x_window_to_frame
144#endif 150#endif
@@ -520,6 +526,12 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
520 unsigned long *)); 526 unsigned long *));
521static void x_check_fullscreen P_ ((struct frame *)); 527static void x_check_fullscreen P_ ((struct frame *));
522static void x_check_fullscreen_move P_ ((struct frame *)); 528static void x_check_fullscreen_move P_ ((struct frame *));
529static int handle_one_xevent P_ ((struct x_display_info *,
530 XEvent *,
531 struct input_event **,
532 int *,
533 int *));
534
523 535
524/* Flush display of frame F, or of all frames if F is null. */ 536/* Flush display of frame F, or of all frames if F is null. */
525 537
@@ -4330,6 +4342,7 @@ x_draw_image_glyph_string (s)
4330 4342
4331 height = s->height - 2 * box_line_vwidth; 4343 height = s->height - 2 * box_line_vwidth;
4332 4344
4345
4333 /* Fill background with face under the image. Do it only if row is 4346 /* Fill background with face under the image. Do it only if row is
4334 taller than image or if image has a clip mask to reduce 4347 taller than image or if image has a clip mask to reduce
4335 flickering. */ 4348 flickering. */
@@ -7074,7 +7087,7 @@ note_mouse_highlight (f, x, y)
7074 struct buffer *b; 7087 struct buffer *b;
7075 7088
7076 /* When a menu is active, don't highlight because this looks odd. */ 7089 /* When a menu is active, don't highlight because this looks odd. */
7077#ifdef USE_X_TOOLKIT 7090#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
7078 if (popup_activated ()) 7091 if (popup_activated ())
7079 return; 7092 return;
7080#endif 7093#endif
@@ -8399,7 +8412,7 @@ static void
8399x_process_timeouts (timer) 8412x_process_timeouts (timer)
8400 struct atimer *timer; 8413 struct atimer *timer;
8401{ 8414{
8402 if (toolkit_scroll_bar_interaction || popup_activated_flag) 8415 if (toolkit_scroll_bar_interaction || popup_activated ())
8403 { 8416 {
8404 BLOCK_INPUT; 8417 BLOCK_INPUT;
8405 while (XtAppPending (Xt_app_con) & XtIMTimer) 8418 while (XtAppPending (Xt_app_con) & XtIMTimer)
@@ -8494,10 +8507,6 @@ static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
8494 int, int, int)); 8507 int, int, int));
8495 8508
8496 8509
8497/* Id of action hook installed for scroll bars. */
8498
8499static XtActionHookId action_hook_id;
8500
8501/* Lisp window being scrolled. Set when starting to interact with 8510/* Lisp window being scrolled. Set when starting to interact with
8502 a toolkit scroll bar, reset to nil when ending the interaction. */ 8511 a toolkit scroll bar, reset to nil when ending the interaction. */
8503 8512
@@ -8510,6 +8519,11 @@ static int last_scroll_bar_part;
8510/* Whether this is an Xaw with arrow-scrollbars. This should imply 8519/* Whether this is an Xaw with arrow-scrollbars. This should imply
8511 that movements of 1/20 of the screen size are mapped to up/down. */ 8520 that movements of 1/20 of the screen size are mapped to up/down. */
8512 8521
8522#ifndef USE_GTK
8523/* Id of action hook installed for scroll bars. */
8524
8525static XtActionHookId action_hook_id;
8526
8513static Boolean xaw3d_arrow_scroll; 8527static Boolean xaw3d_arrow_scroll;
8514 8528
8515/* Whether the drag scrolling maintains the mouse at the top of the 8529/* 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,
8562 toolkit_scroll_bar_interaction = 0; 8576 toolkit_scroll_bar_interaction = 0;
8563 } 8577 }
8564} 8578}
8579#endif /* not USE_GTK */
8565 8580
8566/* A vector of windows used for communication between 8581/* A vector of windows used for communication between
8567 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ 8582 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
@@ -8655,7 +8670,11 @@ x_scroll_bar_to_input_event (event, ievent)
8655 ievent->kind = SCROLL_BAR_CLICK_EVENT; 8670 ievent->kind = SCROLL_BAR_CLICK_EVENT;
8656 ievent->frame_or_window = window; 8671 ievent->frame_or_window = window;
8657 ievent->arg = Qnil; 8672 ievent->arg = Qnil;
8673#ifdef USE_GTK
8674 ievent->timestamp = CurrentTime;
8675#else
8658 ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f)); 8676 ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
8677#endif
8659 ievent->part = ev->data.l[1]; 8678 ievent->part = ev->data.l[1];
8660 ievent->code = ev->data.l[2]; 8679 ievent->code = ev->data.l[2];
8661 ievent->x = make_number ((int) ev->data.l[3]); 8680 ievent->x = make_number ((int) ev->data.l[3]);
@@ -8749,8 +8768,80 @@ xm_scroll_callback (widget, client_data, call_data)
8749} 8768}
8750 8769
8751 8770
8752#else /* !USE_MOTIF, i.e. Xaw. */ 8771#else /* !USE_MOTIF, i.e. Xaw or GTK */
8772#ifdef USE_GTK
8773/* Scroll bar callback for Gtk scroll bars. WIDGET is the scroll
8774 bar adjustment widget. DATA is a pointer to the scroll_bar structure. */
8775
8776static void
8777xg_scroll_callback (widget, data)
8778 GtkWidget *widget;
8779 gpointer data;
8780{
8781 struct scroll_bar *bar = (struct scroll_bar *) data;
8782 gdouble previous;
8783 gdouble position;
8784 gdouble *p;
8785 int diff;
8786
8787 int part = -1, whole = 0, portion = 0;
8788 GtkAdjustment *adj = GTK_ADJUSTMENT (widget);
8789
8790 if (xg_ignore_gtk_scrollbar) return;
8791
8792 position = gtk_adjustment_get_value (adj);
8793
8794 p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
8795 if (! p)
8796 {
8797 p = (gdouble*) xmalloc (sizeof (gdouble));
8798 *p = XG_SB_MIN;
8799 g_object_set_data (G_OBJECT (widget), XG_LAST_SB_DATA, p);
8800 }
8801
8802 previous = *p;
8803 *p = position;
8804
8805 diff = (int) (position - previous);
8806
8807 if (diff == (int) adj->step_increment)
8808 {
8809 part = scroll_bar_down_arrow;
8810 bar->dragging = Qnil;
8811 }
8812 else if (-diff == (int) adj->step_increment)
8813 {
8814 part = scroll_bar_up_arrow;
8815 bar->dragging = Qnil;
8816 }
8817 else if (diff == (int) adj->page_increment)
8818 {
8819 part = scroll_bar_below_handle;
8820 bar->dragging = Qnil;
8821 }
8822 else if (-diff == (int) adj->page_increment)
8823 {
8824 part = scroll_bar_above_handle;
8825 bar->dragging = Qnil;
8826 }
8827 else
8828 {
8829 part = scroll_bar_handle;
8830 whole = adj->upper - adj->page_size;
8831 portion = min (position, whole);
8832 bar->dragging = make_number (portion);
8833 }
8834
8835 if (part >= 0)
8836 {
8837 xg_ignore_next_thumb = 1;
8838 window_being_scrolled = bar->window;
8839 last_scroll_bar_part = part;
8840 x_send_scroll_bar_event (bar->window, part, portion, whole);
8841 }
8842}
8753 8843
8844#else /* not USE_GTK */
8754 8845
8755/* Xaw scroll bar callback. Invoked when the thumb is dragged. 8846/* Xaw scroll bar callback. Invoked when the thumb is dragged.
8756 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the 8847 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)
8833 x_send_scroll_bar_event (bar->window, part, position, height); 8924 x_send_scroll_bar_event (bar->window, part, position, height);
8834} 8925}
8835 8926
8836 8927#endif /* not USE_GTK */
8837#endif /* not USE_MOTIF */ 8928#endif /* not USE_MOTIF */
8838 8929
8930#define SCROLL_BAR_NAME "verticalScrollBar"
8839 8931
8840/* Create the widget for scroll bar BAR on frame F. Record the widget 8932/* Create the widget for scroll bar BAR on frame F. Record the widget
8841 and X window of the scroll bar in BAR. */ 8933 and X window of the scroll bar in BAR. */
8842 8934
8935#ifdef USE_GTK
8936static void
8937x_create_toolkit_scroll_bar (f, bar)
8938 struct frame *f;
8939 struct scroll_bar *bar;
8940{
8941 char *scroll_bar_name = SCROLL_BAR_NAME;
8942
8943 BLOCK_INPUT;
8944 xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
8945 scroll_bar_name);
8946 UNBLOCK_INPUT;
8947}
8948
8949#else /* not USE_GTK */
8950
8843static void 8951static void
8844x_create_toolkit_scroll_bar (f, bar) 8952x_create_toolkit_scroll_bar (f, bar)
8845 struct frame *f; 8953 struct frame *f;
@@ -8849,7 +8957,7 @@ x_create_toolkit_scroll_bar (f, bar)
8849 Widget widget; 8957 Widget widget;
8850 Arg av[20]; 8958 Arg av[20];
8851 int ac = 0; 8959 int ac = 0;
8852 char *scroll_bar_name = "verticalScrollBar"; 8960 char *scroll_bar_name = SCROLL_BAR_NAME;
8853 unsigned long pixel; 8961 unsigned long pixel;
8854 8962
8855 BLOCK_INPUT; 8963 BLOCK_INPUT;
@@ -9022,11 +9130,22 @@ x_create_toolkit_scroll_bar (f, bar)
9022 9130
9023 UNBLOCK_INPUT; 9131 UNBLOCK_INPUT;
9024} 9132}
9133#endif /* not USE_GTK */
9025 9134
9026 9135
9027/* Set the thumb size and position of scroll bar BAR. We are currently 9136/* Set the thumb size and position of scroll bar BAR. We are currently
9028 displaying PORTION out of a whole WHOLE, and our position POSITION. */ 9137 displaying PORTION out of a whole WHOLE, and our position POSITION. */
9029 9138
9139#ifdef USE_GTK
9140static void
9141x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
9142 struct scroll_bar *bar;
9143 int portion, position, whole;
9144{
9145 xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
9146}
9147
9148#else /* not USE_GTK */
9030static void 9149static void
9031x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) 9150x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
9032 struct scroll_bar *bar; 9151 struct scroll_bar *bar;
@@ -9149,6 +9268,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
9149 9268
9150 UNBLOCK_INPUT; 9269 UNBLOCK_INPUT;
9151} 9270}
9271#endif /* not USE_GTK */
9152 9272
9153#endif /* USE_TOOLKIT_SCROLL_BARS */ 9273#endif /* USE_TOOLKIT_SCROLL_BARS */
9154 9274
@@ -9237,6 +9357,15 @@ x_scroll_bar_create (w, top, left, width, height)
9237 /* Map the window/widget. */ 9357 /* Map the window/widget. */
9238#ifdef USE_TOOLKIT_SCROLL_BARS 9358#ifdef USE_TOOLKIT_SCROLL_BARS
9239 { 9359 {
9360#ifdef USE_GTK
9361 xg_update_scrollbar_pos (f,
9362 SCROLL_BAR_X_WINDOW (bar),
9363 top,
9364 left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
9365 width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9366 max (height, 1));
9367 xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
9368#else /* not USE_GTK */
9240 Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); 9369 Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
9241 XtConfigureWidget (scroll_bar, 9370 XtConfigureWidget (scroll_bar,
9242 left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, 9371 left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
@@ -9244,6 +9373,7 @@ x_scroll_bar_create (w, top, left, width, height)
9244 width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, 9373 width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9245 max (height, 1), 0); 9374 max (height, 1), 0);
9246 XtMapWidget (scroll_bar); 9375 XtMapWidget (scroll_bar);
9376#endif /* not USE_GTK */
9247 } 9377 }
9248#else /* not USE_TOOLKIT_SCROLL_BARS */ 9378#else /* not USE_TOOLKIT_SCROLL_BARS */
9249 XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar)); 9379 XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
@@ -9378,7 +9508,11 @@ x_scroll_bar_remove (bar)
9378 BLOCK_INPUT; 9508 BLOCK_INPUT;
9379 9509
9380#ifdef USE_TOOLKIT_SCROLL_BARS 9510#ifdef USE_TOOLKIT_SCROLL_BARS
9511#ifdef USE_GTK
9512 xg_remove_scroll_bar (f, SCROLL_BAR_X_WINDOW (bar));
9513#else /* not USE_GTK */
9381 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar)); 9514 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
9515#endif /* not USE_GTK */
9382#else 9516#else
9383 XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar)); 9517 XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
9384#endif 9518#endif
@@ -9472,20 +9606,30 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
9472 9606
9473#ifdef USE_TOOLKIT_SCROLL_BARS 9607#ifdef USE_TOOLKIT_SCROLL_BARS
9474 9608
9609#ifdef USE_GTK
9610 if (mask)
9611 xg_update_scrollbar_pos (f,
9612 SCROLL_BAR_X_WINDOW (bar),
9613 top,
9614 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
9615 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9616 max (height, 1));
9617#else /* not USE_GTK */
9618
9475 /* Since toolkit scroll bars are smaller than the space reserved 9619 /* Since toolkit scroll bars are smaller than the space reserved
9476 for them on the frame, we have to clear "under" them. */ 9620 for them on the frame, we have to clear "under" them. */
9477 if (width > 0 && height > 0) 9621 if (width > 0 && height > 0)
9478 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 9622 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
9479 left, top, width, height, False); 9623 left, top, width, height, False);
9480
9481 /* Move/size the scroll bar widget. */ 9624 /* Move/size the scroll bar widget. */
9482 if (mask) 9625 if (mask)
9483 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar), 9626 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
9484 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, 9627 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
9485 top, 9628 top,
9486 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, 9629 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9487 max (height, 1), 0); 9630 max (height, 1), 0);
9488 9631
9632#endif /* not USE_GTK */
9489#else /* not USE_TOOLKIT_SCROLL_BARS */ 9633#else /* not USE_TOOLKIT_SCROLL_BARS */
9490 9634
9491 /* Clear areas not covered by the scroll bar because of 9635 /* Clear areas not covered by the scroll bar because of
@@ -10070,6 +10214,41 @@ enum
10070 X_EVENT_DROP 10214 X_EVENT_DROP
10071}; 10215};
10072 10216
10217#ifdef USE_GTK
10218static struct x_display_info *current_dpyinfo;
10219static struct input_event **current_bufp;
10220static int *current_numcharsp;
10221static int current_count;
10222static int current_finish;
10223
10224/* This is the filter function invoked by the GTK event loop.
10225 It is invoked before the XEvent is translated to a GdkEvent,
10226 so we have a chanse to act on the event before GTK. */
10227static GdkFilterReturn
10228event_handler_gdk (gxev, ev, data)
10229 GdkXEvent *gxev;
10230 GdkEvent *ev;
10231 gpointer data;
10232{
10233 XEvent *xev = (XEvent*)gxev;
10234
10235 if (current_numcharsp)
10236 current_count += handle_one_xevent (current_dpyinfo,
10237 xev,
10238 current_bufp,
10239 current_numcharsp,
10240 &current_finish);
10241 else
10242 x_dispatch_event (xev, GDK_DISPLAY ());
10243
10244 if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
10245 return GDK_FILTER_REMOVE;
10246
10247 return GDK_FILTER_CONTINUE;
10248}
10249#endif /* USE_GTK */
10250
10251
10073/* Handles the XEvent EVENT on display DPYINFO. 10252/* Handles the XEvent EVENT on display DPYINFO.
10074 10253
10075 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. 10254 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@@ -10079,7 +10258,7 @@ enum
10079 Events representing keys are stored in buffer *BUFP_R, 10258 Events representing keys are stored in buffer *BUFP_R,
10080 which can hold up to *NUMCHARSP characters. 10259 which can hold up to *NUMCHARSP characters.
10081 We return the number of characters stored into the buffer. */ 10260 We return the number of characters stored into the buffer. */
10082 10261
10083static int 10262static int
10084handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) 10263handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10085 struct x_display_info *dpyinfo; 10264 struct x_display_info *dpyinfo;
@@ -10097,7 +10276,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10097 XEvent event = *eventp; 10276 XEvent event = *eventp;
10098 10277
10099 *finish = X_EVENT_NORMAL; 10278 *finish = X_EVENT_NORMAL;
10100 10279
10101 switch (event.type) 10280 switch (event.type)
10102 { 10281 {
10103 case ClientMessage: 10282 case ClientMessage:
@@ -10514,8 +10693,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10514 case KeyPress: 10693 case KeyPress:
10515 10694
10516 /* Dispatch KeyPress events when in menu. */ 10695 /* Dispatch KeyPress events when in menu. */
10517 if (popup_activated_flag) 10696 if (popup_activated ())
10518 goto OTHER; 10697 goto OTHER;
10698
10519 f = x_any_window_to_frame (dpyinfo, event.xkey.window); 10699 f = x_any_window_to_frame (dpyinfo, event.xkey.window);
10520 10700
10521 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) 10701 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
@@ -11080,6 +11260,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11080 if (f) 11260 if (f)
11081 { 11261 {
11082#ifndef USE_X_TOOLKIT 11262#ifndef USE_X_TOOLKIT
11263#ifdef USE_GTK
11264 xg_resize_widgets (f, event.xconfigure.width,
11265 event.xconfigure.height);
11266#else /* not USE_GTK */
11083 /* If there is a pending resize for fullscreen, don't 11267 /* If there is a pending resize for fullscreen, don't
11084 do this one, the right one will come later. 11268 do this one, the right one will come later.
11085 The toolkit version doesn't seem to need this, but we 11269 The toolkit version doesn't seem to need this, but we
@@ -11108,20 +11292,31 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11108 SET_FRAME_GARBAGED (f); 11292 SET_FRAME_GARBAGED (f);
11109 cancel_mouse_face (f); 11293 cancel_mouse_face (f);
11110 } 11294 }
11295#endif /* not USE_GTK */
11111#endif 11296#endif
11112 11297
11113 f->output_data.x->pixel_width = event.xconfigure.width; 11298 f->output_data.x->pixel_width = event.xconfigure.width;
11114 f->output_data.x->pixel_height = event.xconfigure.height; 11299 f->output_data.x->pixel_height = event.xconfigure.height;
11115 11300
11301#ifdef USE_GTK
11302 /* GTK creates windows but doesn't map them.
11303 Only get real positions and check fullscreen when mapped. */
11304 if (FRAME_GTK_OUTER_WIDGET (f)
11305 && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
11306 {
11307#endif
11116 /* What we have now is the position of Emacs's own window. 11308 /* What we have now is the position of Emacs's own window.
11117 Convert that to the position of the window manager window. */ 11309 Convert that to the position of the window manager window. */
11118 x_real_positions (f, &f->output_data.x->left_pos, 11310 x_real_positions (f, &f->output_data.x->left_pos,
11119 &f->output_data.x->top_pos); 11311 &f->output_data.x->top_pos);
11120 11312
11121 x_check_fullscreen_move(f); 11313 x_check_fullscreen_move (f);
11122 if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT) 11314 if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
11123 f->output_data.x->want_fullscreen &= 11315 f->output_data.x->want_fullscreen &=
11124 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH); 11316 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
11317#ifdef USE_GTK
11318 }
11319#endif
11125#ifdef HAVE_X_I18N 11320#ifdef HAVE_X_I18N
11126 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) 11321 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
11127 xic_set_statusarea (f); 11322 xic_set_statusarea (f);
@@ -11137,8 +11332,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11137 } 11332 }
11138 goto OTHER; 11333 goto OTHER;
11139 11334
11140 case ButtonPress:
11141 case ButtonRelease: 11335 case ButtonRelease:
11336 case ButtonPress:
11142 { 11337 {
11143 /* If we decide we want to generate an event to be seen 11338 /* If we decide we want to generate an event to be seen
11144 by the rest of Emacs, we put it here. */ 11339 by the rest of Emacs, we put it here. */
@@ -11179,7 +11374,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11179 if (!tool_bar_p) 11374 if (!tool_bar_p)
11180 if (!dpyinfo->x_focus_frame 11375 if (!dpyinfo->x_focus_frame
11181 || f == dpyinfo->x_focus_frame) 11376 || f == dpyinfo->x_focus_frame)
11182 construct_mouse_click (&emacs_event, &event, f); 11377 {
11378 if (! popup_activated ())
11379 construct_mouse_click (&emacs_event, &event, f);
11380 }
11183 } 11381 }
11184 else 11382 else
11185 { 11383 {
@@ -11207,9 +11405,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11207 last_tool_bar_item = -1; 11405 last_tool_bar_item = -1;
11208 } 11406 }
11209 else 11407 else
11210 { 11408 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
11211 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
11212 }
11213 11409
11214 if (numchars >= 1 && emacs_event.kind != NO_EVENT) 11410 if (numchars >= 1 && emacs_event.kind != NO_EVENT)
11215 { 11411 {
@@ -11219,14 +11415,19 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11219 numchars--; 11415 numchars--;
11220 } 11416 }
11221 11417
11222#ifdef USE_X_TOOLKIT 11418#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
11223 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window); 11419 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
11224 /* For a down-event in the menu bar, 11420 /* For a down-event in the menu bar,
11225 don't pass it to Xt right now. 11421 don't pass it to Xt right now.
11226 Instead, save it away 11422 Instead, save it away
11227 and we will pass it to Xt from kbd_buffer_get_event. 11423 and we will pass it to Xt from kbd_buffer_get_event.
11228 That way, we can run some Lisp code first. */ 11424 That way, we can run some Lisp code first. */
11229 if (f && event.type == ButtonPress 11425 if (
11426#ifdef USE_GTK
11427 ! popup_activated ()
11428 &&
11429#endif
11430 f && event.type == ButtonPress
11230 /* Verify the event is really within the menu bar 11431 /* Verify the event is really within the menu bar
11231 and not just sent to it due to grabbing. */ 11432 and not just sent to it due to grabbing. */
11232 && event.xbutton.x >= 0 11433 && event.xbutton.x >= 0
@@ -11237,6 +11438,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11237 { 11438 {
11238 SET_SAVED_BUTTON_EVENT; 11439 SET_SAVED_BUTTON_EVENT;
11239 XSETFRAME (last_mouse_press_frame, f); 11440 XSETFRAME (last_mouse_press_frame, f);
11441#ifdef USE_GTK
11442 *finish = X_EVENT_DROP;
11443#endif
11240 } 11444 }
11241 else if (event.type == ButtonPress) 11445 else if (event.type == ButtonPress)
11242 { 11446 {
@@ -11260,7 +11464,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11260#endif /* USE_MOTIF */ 11464#endif /* USE_MOTIF */
11261 else 11465 else
11262 goto OTHER; 11466 goto OTHER;
11263#endif /* USE_X_TOOLKIT */ 11467#endif /* USE_X_TOOLKIT || USE_GTK */
11264 } 11468 }
11265 break; 11469 break;
11266 11470
@@ -11297,7 +11501,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11297 } 11501 }
11298 11502
11299 goto ret; 11503 goto ret;
11300 11504
11301 out: 11505 out:
11302 *finish = X_EVENT_GOTO_OUT; 11506 *finish = X_EVENT_GOTO_OUT;
11303 11507
@@ -11427,6 +11631,31 @@ XTread_socket (sd, bufp, numchars, expected)
11427 UNBLOCK_INPUT; 11631 UNBLOCK_INPUT;
11428#endif 11632#endif
11429 11633
11634#ifdef USE_GTK
11635 /* For GTK we must use the GTK event loop. But XEvents gets passed
11636 to our filter function above, and then to the big event switch.
11637 We use a bunch of globals to communicate with our filter function,
11638 that is kind of ugly, but it works. */
11639 current_dpyinfo = dpyinfo;
11640
11641 while (gtk_events_pending ())
11642 {
11643 static int nr = 0;
11644 current_count = count;
11645 current_numcharsp = &numchars;
11646 current_bufp = &bufp;
11647
11648 gtk_main_iteration ();
11649
11650 count = current_count;
11651 current_bufp = 0;
11652 current_numcharsp = 0;
11653
11654 if (current_finish == X_EVENT_GOTO_OUT)
11655 goto out;
11656 }
11657
11658#else /* not USE_GTK */
11430 while (XPending (dpyinfo->display)) 11659 while (XPending (dpyinfo->display))
11431 { 11660 {
11432 int finish; 11661 int finish;
@@ -11457,6 +11686,7 @@ XTread_socket (sd, bufp, numchars, expected)
11457 if (finish == X_EVENT_GOTO_OUT) 11686 if (finish == X_EVENT_GOTO_OUT)
11458 goto out; 11687 goto out;
11459 } 11688 }
11689#endif /* USE_GTK */
11460 } 11690 }
11461 11691
11462 out:; 11692 out:;
@@ -12922,11 +13152,7 @@ x_calc_absolute_position (f)
12922 if (! ((flags & XNegative) || (flags & YNegative))) 13152 if (! ((flags & XNegative) || (flags & YNegative)))
12923 return; 13153 return;
12924 13154
12925#ifdef USE_X_TOOLKIT 13155 this_window = FRAME_OUTER_WINDOW (f);
12926 this_window = XtWindow (f->output_data.x->widget);
12927#else
12928 this_window = FRAME_X_WINDOW (f);
12929#endif
12930 13156
12931 /* Find the position of the outside upper-left corner of 13157 /* Find the position of the outside upper-left corner of
12932 the inner window, with respect to the outer window. 13158 the inner window, with respect to the outer window.
@@ -13057,13 +13283,8 @@ x_set_offset (f, xoff, yoff, change_gravity)
13057 } 13283 }
13058#endif 13284#endif
13059 13285
13060#ifdef USE_X_TOOLKIT 13286 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
13061 XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), 13287 modified_left, modified_top);
13062 modified_left, modified_top);
13063#else /* not USE_X_TOOLKIT */
13064 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
13065 modified_left, modified_top);
13066#endif /* not USE_X_TOOLKIT */
13067 UNBLOCK_INPUT; 13288 UNBLOCK_INPUT;
13068} 13289}
13069 13290
@@ -13249,7 +13470,12 @@ x_set_window_size (f, change_gravity, cols, rows)
13249{ 13470{
13250 BLOCK_INPUT; 13471 BLOCK_INPUT;
13251 13472
13252#ifdef USE_X_TOOLKIT 13473#ifdef USE_GTK
13474 if (FRAME_GTK_WIDGET (f))
13475 xg_frame_set_char_size (f, cols, rows);
13476 else
13477 x_set_window_size_1 (f, change_gravity, cols, rows);
13478#elif USE_X_TOOLKIT
13253 13479
13254 if (f->output_data.x->widget != NULL) 13480 if (f->output_data.x->widget != NULL)
13255 { 13481 {
@@ -13445,7 +13671,11 @@ x_make_frame_visible (f)
13445 /* This was XtPopup, but that did nothing for an iconified frame. */ 13671 /* This was XtPopup, but that did nothing for an iconified frame. */
13446 XtMapWidget (f->output_data.x->widget); 13672 XtMapWidget (f->output_data.x->widget);
13447#else /* not USE_X_TOOLKIT */ 13673#else /* not USE_X_TOOLKIT */
13674#ifdef USE_GTK
13675 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
13676#else
13448 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 13677 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
13678#endif /* not USE_GTK */
13449#endif /* not USE_X_TOOLKIT */ 13679#endif /* not USE_X_TOOLKIT */
13450#if 0 /* This seems to bring back scroll bars in the wrong places 13680#if 0 /* This seems to bring back scroll bars in the wrong places
13451 if the window configuration has changed. They seem 13681 if the window configuration has changed. They seem
@@ -13596,6 +13826,14 @@ x_make_frame_invisible (f)
13596 by hand again (they have already done that once for this window.) */ 13826 by hand again (they have already done that once for this window.) */
13597 x_wm_set_size_hint (f, (long) 0, 1); 13827 x_wm_set_size_hint (f, (long) 0, 1);
13598 13828
13829#ifdef USE_GTK
13830 if (FRAME_GTK_OUTER_WIDGET (f))
13831 {
13832 gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
13833 goto out;
13834 }
13835#endif
13836
13599#ifdef HAVE_X11R4 13837#ifdef HAVE_X11R4
13600 13838
13601 if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window, 13839 if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
@@ -13630,6 +13868,7 @@ x_make_frame_invisible (f)
13630 XUnmapWindow (FRAME_X_DISPLAY (f), window); 13868 XUnmapWindow (FRAME_X_DISPLAY (f), window);
13631#endif /* ! defined (HAVE_X11R4) */ 13869#endif /* ! defined (HAVE_X11R4) */
13632 13870
13871 out:
13633 /* We can't distinguish this from iconification 13872 /* We can't distinguish this from iconification
13634 just by the event that we get from the server. 13873 just by the event that we get from the server.
13635 So we can't win using the usual strategy of letting 13874 So we can't win using the usual strategy of letting
@@ -13669,6 +13908,22 @@ x_iconify_frame (f)
13669 if (!NILP (type)) 13908 if (!NILP (type))
13670 x_bitmap_icon (f, type); 13909 x_bitmap_icon (f, type);
13671 13910
13911#ifdef USE_GTK
13912 if (FRAME_GTK_OUTER_WIDGET (f))
13913 {
13914 if (! FRAME_VISIBLE_P (f))
13915 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
13916
13917 gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
13918 f->iconified = 1;
13919 f->visible = 1;
13920 f->async_iconified = 1;
13921 f->async_visible = 0;
13922 UNBLOCK_INPUT;
13923 return;
13924 }
13925#endif
13926
13672#ifdef USE_X_TOOLKIT 13927#ifdef USE_X_TOOLKIT
13673 13928
13674 if (! FRAME_VISIBLE_P (f)) 13929 if (! FRAME_VISIBLE_P (f))
@@ -13803,6 +14058,18 @@ x_free_frame_resources (f)
13803 14058
13804 free_frame_menubar (f); 14059 free_frame_menubar (f);
13805#else /* !USE_X_TOOLKIT */ 14060#else /* !USE_X_TOOLKIT */
14061
14062#ifdef USE_GTK
14063 /* In the GTK version, tooltips are normal X
14064 frames. We must check and free both types. */
14065 if (FRAME_GTK_OUTER_WIDGET (f))
14066 {
14067 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
14068 FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow below */
14069 FRAME_GTK_OUTER_WIDGET (f) = 0;
14070 }
14071#endif /* USE_GTK */
14072
13806 if (FRAME_X_WINDOW (f)) 14073 if (FRAME_X_WINDOW (f))
13807 XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 14074 XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
13808#endif /* !USE_X_TOOLKIT */ 14075#endif /* !USE_X_TOOLKIT */
@@ -13888,8 +14155,10 @@ x_destroy_window (f)
13888 FLAGS is the flags word to use--or 0 meaning preserve the flags 14155 FLAGS is the flags word to use--or 0 meaning preserve the flags
13889 that the window now has. 14156 that the window now has.
13890 If USER_POSITION is nonzero, we set the USPosition 14157 If USER_POSITION is nonzero, we set the USPosition
13891 flag (this is useful when FLAGS is 0). */ 14158 flag (this is useful when FLAGS is 0).
14159 The GTK version is in gtkutils.c */
13892 14160
14161#ifndef USE_GTK
13893void 14162void
13894x_wm_set_size_hint (f, flags, user_position) 14163x_wm_set_size_hint (f, flags, user_position)
13895 struct frame *f; 14164 struct frame *f;
@@ -13902,10 +14171,9 @@ x_wm_set_size_hint (f, flags, user_position)
13902 Arg al[2]; 14171 Arg al[2];
13903 int ac = 0; 14172 int ac = 0;
13904 Dimension widget_width, widget_height; 14173 Dimension widget_width, widget_height;
13905 Window window = XtWindow (f->output_data.x->widget); 14174#endif
13906#else /* not USE_X_TOOLKIT */ 14175
13907 Window window = FRAME_X_WINDOW (f); 14176 Window window = FRAME_OUTER_WINDOW (f);
13908#endif /* not USE_X_TOOLKIT */
13909 14177
13910 /* Setting PMaxSize caused various problems. */ 14178 /* Setting PMaxSize caused various problems. */
13911 size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; 14179 size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
@@ -14032,6 +14300,7 @@ x_wm_set_size_hint (f, flags, user_position)
14032 XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); 14300 XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
14033#endif 14301#endif
14034} 14302}
14303#endif /* not USE_GTK */
14035 14304
14036/* Used for IconicState or NormalState */ 14305/* Used for IconicState or NormalState */
14037 14306
@@ -14063,7 +14332,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
14063 Pixmap icon_pixmap; 14332 Pixmap icon_pixmap;
14064 14333
14065#ifndef USE_X_TOOLKIT 14334#ifndef USE_X_TOOLKIT
14066 Window window = FRAME_X_WINDOW (f); 14335 Window window = FRAME_OUTER_WINDOW (f);
14067#endif 14336#endif
14068 14337
14069 if (pixmap_id > 0) 14338 if (pixmap_id > 0)
@@ -14864,6 +15133,67 @@ x_term_init (display_name, xrm_option, resource_name)
14864 x_initialized = 1; 15133 x_initialized = 1;
14865 } 15134 }
14866 15135
15136#ifdef USE_GTK
15137 {
15138#define NUM_ARGV 10
15139 int argc;
15140 char *argv[NUM_ARGV];
15141 char **argv2 = argv;
15142 GdkAtom atom;
15143
15144 /* GTK 2.0 can only handle one display, GTK 2.2 can handle more
15145 than one, but this remains to be implemented. */
15146 if (x_initialized > 1)
15147 return 0;
15148
15149 x_initialized++;
15150
15151 for (argc = 0; argc < NUM_ARGV; ++argc)
15152 argv[argc] = 0;
15153
15154 argc = 0;
15155 argv[argc++] = initial_argv[0];
15156
15157 if (! NILP (display_name))
15158 {
15159 argv[argc++] = "--display";
15160 argv[argc++] = SDATA (display_name);
15161 }
15162
15163 argv[argc++] = "--name";
15164 argv[argc++] = resource_name;
15165
15166 gtk_init (&argc, &argv2);
15167
15168 /* gtk_init does set_locale. We must fix locale after calling it. */
15169 fixup_locale ();
15170 xg_initialize ();
15171
15172 dpy = GDK_DISPLAY ();
15173
15174 /* NULL window -> events for all windows go to our function */
15175 gdk_window_add_filter (NULL, event_handler_gdk, NULL);
15176
15177 /* Load our own gtkrc if it exists. */
15178 {
15179 struct gcpro gcpro1, gcpro2;
15180 char *file = "~/.emacs.d/gtkrc";
15181 Lisp_Object s, abs_file;
15182
15183 GCPRO2 (str, abs_file);
15184 s = make_string (file, strlen (file));
15185 abs_file = Fexpand_file_name(s, Qnil);
15186
15187 if (! NILP (abs_file) && Ffile_readable_p (abs_file))
15188 gtk_rc_parse (SDATA (abs_file));
15189
15190 UNGCPRO;
15191 }
15192
15193 XSetErrorHandler (x_error_handler);
15194 XSetIOErrorHandler (x_io_error_quitter);
15195 }
15196#else /* not USE_GTK */
14867#ifdef USE_X_TOOLKIT 15197#ifdef USE_X_TOOLKIT
14868 /* weiner@footloose.sps.mot.com reports that this causes 15198 /* weiner@footloose.sps.mot.com reports that this causes
14869 errors with X11R5: 15199 errors with X11R5:
@@ -14904,6 +15234,7 @@ x_term_init (display_name, xrm_option, resource_name)
14904#endif 15234#endif
14905 dpy = XOpenDisplay (SDATA (display_name)); 15235 dpy = XOpenDisplay (SDATA (display_name));
14906#endif /* not USE_X_TOOLKIT */ 15236#endif /* not USE_X_TOOLKIT */
15237#endif /* not USE_GTK*/
14907 15238
14908 /* Detect failure. */ 15239 /* Detect failure. */
14909 if (dpy == 0) 15240 if (dpy == 0)
@@ -15363,9 +15694,11 @@ x_initialize ()
15363#endif 15694#endif
15364 15695
15365#ifdef USE_TOOLKIT_SCROLL_BARS 15696#ifdef USE_TOOLKIT_SCROLL_BARS
15697#ifndef USE_GTK
15366 xaw3d_arrow_scroll = False; 15698 xaw3d_arrow_scroll = False;
15367 xaw3d_pick_top = True; 15699 xaw3d_pick_top = True;
15368#endif 15700#endif
15701#endif
15369 15702
15370 /* Note that there is no real way portable across R3/R4 to get the 15703 /* Note that there is no real way portable across R3/R4 to get the
15371 original error handler. */ 15704 original error handler. */
@@ -15445,6 +15778,8 @@ Otherwise, value is a symbol describing the X toolkit. */);
15445 Vx_toolkit_scroll_bars = intern ("motif"); 15778 Vx_toolkit_scroll_bars = intern ("motif");
15446#elif defined HAVE_XAW3D 15779#elif defined HAVE_XAW3D
15447 Vx_toolkit_scroll_bars = intern ("xaw3d"); 15780 Vx_toolkit_scroll_bars = intern ("xaw3d");
15781#elif USE_GTK
15782 Vx_toolkit_scroll_bars = intern ("gtk");
15448#else 15783#else
15449 Vx_toolkit_scroll_bars = intern ("xaw"); 15784 Vx_toolkit_scroll_bars = intern ("xaw");
15450#endif 15785#endif
diff --git a/src/xterm.h b/src/xterm.h
index 9e8779bf55d..7ad148c0004 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -33,6 +33,18 @@ Boston, MA 02111-1307, USA. */
33 window inside a widget instead of one 33 window inside a widget instead of one
34 that Xt creates... */ 34 that Xt creates... */
35#include <X11/StringDefs.h> 35#include <X11/StringDefs.h>
36
37typedef Widget xt_or_gtk_widget;
38#endif
39
40#ifdef USE_GTK
41#include <gtk/gtk.h>
42#include <gdk/gdkx.h>
43
44/* Some definitions to reduce conditionals. */
45typedef GtkWidget *xt_or_gtk_widget;
46#define XtParent(x) (gtk_widget_get_parent (x))
47
36#endif 48#endif
37 49
38/* The class of this X application. */ 50/* The class of this X application. */
@@ -348,7 +360,7 @@ extern void check_x P_ ((void));
348 360
349extern struct frame *x_window_to_frame P_ ((struct x_display_info *, int)); 361extern struct frame *x_window_to_frame P_ ((struct x_display_info *, int));
350 362
351#ifdef USE_X_TOOLKIT 363#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
352extern struct frame *x_any_window_to_frame P_ ((struct x_display_info *, int)); 364extern struct frame *x_any_window_to_frame P_ ((struct x_display_info *, int));
353extern struct frame *x_non_menubar_window_to_frame P_ ((struct x_display_info *, int)); 365extern struct frame *x_non_menubar_window_to_frame P_ ((struct x_display_info *, int));
354extern struct frame *x_top_window_to_frame P_ ((struct x_display_info *, int)); 366extern struct frame *x_top_window_to_frame P_ ((struct x_display_info *, int));
@@ -403,6 +415,10 @@ struct x_output
403 if the menubar is turned off. */ 415 if the menubar is turned off. */
404 int menubar_height; 416 int menubar_height;
405 417
418 /* Height of tool bar widget, in pixels.
419 Zero if not using an external tool bar. */
420 int toolbar_height;
421
406 /* Height of a line, in pixels. */ 422 /* Height of a line, in pixels. */
407 int line_height; 423 int line_height;
408 424
@@ -446,6 +462,26 @@ struct x_output
446 Widget menubar_widget; 462 Widget menubar_widget;
447#endif 463#endif
448 464
465#ifdef USE_GTK
466 /* The widget of this screen. This is the window of a top widget. */
467 GtkWidget *widget;
468 /* The widget of the edit portion of this screen; the window in
469 "window_desc" is inside of this. */
470 GtkWidget *edit_widget;
471 /* The widget used for laying out widgets vertically. */
472 GtkWidget *vbox_widget;
473 /* The menubar in this frame. */
474 GtkWidget *menubar_widget;
475 /* The tool bar in this frame */
476 GtkWidget *toolbar_widget;
477 /* The handle box that makes the tool bar detachable. */
478 GtkWidget *handlebox_widget;
479
480 /* The last size hints set. */
481 GdkGeometry size_hints;
482 long hint_flags;
483#endif
484
449 /* If >=0, a bitmap index. The indicated bitmap is used for the 485 /* If >=0, a bitmap index. The indicated bitmap is used for the
450 icon. */ 486 icon. */
451 int icon_bitmap; 487 int icon_bitmap;
@@ -638,13 +674,28 @@ enum
638 XtWindow ((f)->output_data.x->widget) : \ 674 XtWindow ((f)->output_data.x->widget) : \
639 FRAME_X_WINDOW (f)) 675 FRAME_X_WINDOW (f))
640#else 676#else
677#ifdef USE_GTK
678#define GTK_WIDGET_TO_X_WIN(w) \
679 ((w) && (w)->window ? GDK_WINDOW_XWINDOW ((w)->window) : 0)
680
681#define FRAME_GTK_OUTER_WIDGET(f) ((f)->output_data.x->widget)
682#define FRAME_GTK_WIDGET(f) ((f)->output_data.x->edit_widget)
683#define FRAME_OUTER_WINDOW(f) \
684 (FRAME_GTK_OUTER_WIDGET (f) ? \
685 GTK_WIDGET_TO_X_WIN (FRAME_GTK_OUTER_WIDGET (f)) : \
686 FRAME_X_WINDOW (f))
687
688#else /* !USE_GTK */
641#define FRAME_OUTER_WINDOW(f) (FRAME_X_WINDOW (f)) 689#define FRAME_OUTER_WINDOW(f) (FRAME_X_WINDOW (f))
690#endif /* !USE_GTK */
642#endif 691#endif
643 692
693
644#define FRAME_FONT(f) ((f)->output_data.x->font) 694#define FRAME_FONT(f) ((f)->output_data.x->font)
645#define FRAME_FONTSET(f) ((f)->output_data.x->fontset) 695#define FRAME_FONTSET(f) ((f)->output_data.x->fontset)
646#define FRAME_INTERNAL_BORDER_WIDTH(f) ((f)->output_data.x->internal_border_width) 696#define FRAME_INTERNAL_BORDER_WIDTH(f) ((f)->output_data.x->internal_border_width)
647#define FRAME_MENUBAR_HEIGHT(f) ((f)->output_data.x->menubar_height) 697#define FRAME_MENUBAR_HEIGHT(f) ((f)->output_data.x->menubar_height)
698#define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.x->toolbar_height)
648#define FRAME_LINE_HEIGHT(f) ((f)->output_data.x->line_height) 699#define FRAME_LINE_HEIGHT(f) ((f)->output_data.x->line_height)
649 700
650/* Width of the default font of frame F. Must be defined by each 701/* Width of the default font of frame F. Must be defined by each
@@ -681,7 +732,7 @@ enum
681 ((f)->output_data.x->x_pixels_outer_diff) 732 ((f)->output_data.x->x_pixels_outer_diff)
682#define FRAME_OUTER_TO_INNER_DIFF_Y(f) \ 733#define FRAME_OUTER_TO_INNER_DIFF_Y(f) \
683 ((f)->output_data.x->y_pixels_outer_diff \ 734 ((f)->output_data.x->y_pixels_outer_diff \
684 + (f)->output_data.x->menubar_height) 735 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
685 736
686 737
687#define FRAME_XIC(f) ((f)->output_data.x->xic) 738#define FRAME_XIC(f) ((f)->output_data.x->xic)