summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog43
-rw-r--r--src/Makefile.in70
-rw-r--r--src/atimer.c6
-rw-r--r--src/config.in14
-rw-r--r--src/dispextern.h17
-rw-r--r--src/dispnew.c14
-rw-r--r--src/emacs.c54
-rw-r--r--src/fileio.c2
-rw-r--r--src/fns.c5
-rw-r--r--src/font.c7
-rw-r--r--src/font.h3
-rw-r--r--src/fontset.c3
-rw-r--r--src/frame.c19
-rw-r--r--src/frame.h12
-rw-r--r--src/fringe.c20
-rw-r--r--src/image.c1053
-rw-r--r--src/keyboard.c46
-rw-r--r--src/lisp.h24
-rw-r--r--src/lread.c10
-rw-r--r--src/m/intel386.h2
-rw-r--r--src/mac.c5477
-rw-r--r--src/macfns.c4429
-rw-r--r--src/macgui.h496
-rw-r--r--src/macmenu.c2101
-rw-r--r--src/macselect.c1165
-rw-r--r--src/macterm.c13451
-rw-r--r--src/macterm.h795
-rw-r--r--src/mactoolbox.c6615
-rw-r--r--src/process.c2
-rw-r--r--src/s/darwin.h61
-rw-r--r--src/sysdep.c9
-rw-r--r--src/sysselect.h4
-rw-r--r--src/syssignal.h2
-rw-r--r--src/term.c3
-rw-r--r--src/termcap.c16
-rw-r--r--src/termhooks.h17
-rw-r--r--src/tparam.c4
-rw-r--r--src/window.c3
-rw-r--r--src/xdisp.c35
-rw-r--r--src/xfaces.c57
40 files changed, 131 insertions, 36035 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 7fc50521d1d..dff7b738860 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,46 @@
+2008-07-27 Dan Nicolaescu <dann@ics.uci.edu>
+
+ Remove support for Mac Carbon.
+ * mactoolbox.c:
+ * macterm.h:
+ * macterm.c:
+ * macselect.c:
+ * macmenu.c:
+ * macgui.h:
+ * macfns.c:
+ * mac.c: Remove file.
+ * s/darwin.h:
+ * m/intel386.h:
+ * xfaces.c:
+ * xdisp.c:
+ * window.c:
+ * tparam.c:
+ * termhooks.h:
+ * termcap.c:
+ * term.c:
+ * syssignal.h:
+ * sysselect.h:
+ * sysdep.c:
+ * process.c:
+ * lread.c:
+ * lisp.h:
+ * keyboard.c:
+ * image.c:
+ * fringe.c:
+ * frame.h:
+ * frame.c:
+ * fontset.c:
+ * font.h:
+ * font.c:
+ * fns.c:
+ * fileio.c:
+ * emacs.c:
+ * dispnew.c:
+ * dispextern.h:
+ * config.in:
+ * atimer.c:
+ * Makefile.in: Remove code for Carbon
+
2008-07-26 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* macterm.c (XDrawLine) [USE_MAC_IMAGE_IO]: Remove spurious return.
diff --git a/src/Makefile.in b/src/Makefile.in
index 3dcaa83ad00..2fe5990a1a5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -513,13 +513,6 @@ MSDOS_OBJ = dosfns.o msdos.o w16select.o
CYGWIN_OBJ = sheap.o
#endif
-#ifdef HAVE_CARBON
-mac = ../mac/
-MAC_OBJ = mac.o macterm.o macfns.o macmenu.o macselect.o fontset.o fringe.o image.o mactoolbox.o
-emacsapp = $(PWD)/$(mac)Emacs.app/
-emacsappsrc = ${srcdir}/../mac/Emacs.app/
-#endif
-
#ifdef HAVE_NS
ns_appdir=@ns_appdir@/
ns_appbindir=@ns_appbindir@/
@@ -557,14 +550,14 @@ obj= dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
process.o callproc.o \
region-cache.o sound.o atimer.o \
doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \
- $(MSDOS_OBJ) $(MAC_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_DRIVERS)
+ $(MSDOS_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_DRIVERS)
/* Object files used on some machine or other.
These go in the DOC file on all machines
in case they are needed there. */
SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
- mac.o macterm.o macfns.o macmenu.o macselect.o fontset.o \
+ fontset.o \
nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \
w32.o w32console.o w32fns.o w32heap.o w32inevt.o \
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o $(FONT_DRIVERS)
@@ -1089,7 +1082,7 @@ filelock.o: filelock.c buffer.h character.h charset.h coding.h systime.h \
filemode.o: filemode.c $(config_h)
frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
blockinput.h atimer.h systime.h buffer.h character.h fontset.h font.h \
- msdos.h dosfns.h dispextern.h w32term.h macterm.h macgui.h termchar.h \
+ msdos.h dosfns.h dispextern.h w32term.h termchar.h \
$(config_h)
fringe.o: fringe.c dispextern.h frame.h window.h buffer.h termhooks.h $(config_h)
font.o: font.c dispextern.h frame.h window.h ccl.h character.h charset.h \
@@ -1099,7 +1092,7 @@ fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h character.h \
charset.h frame.h keyboard.h termhooks.h font.h $(config_h)
getloadavg.o: getloadavg.c $(config_h)
image.o: image.c frame.h window.h dispextern.h blockinput.h atimer.h \
- systime.h xterm.h w32term.h w32gui.h macterm.h macgui.h font.h \
+ systime.h xterm.h w32term.h w32gui.h font.h \
nsterm.h nsgui.h $(config_h)
indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
termopts.h disptab.h region-cache.h character.h category.h composite.h \
@@ -1109,7 +1102,7 @@ insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h character.h \
keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \
commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h atimer.h \
- xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h macgui.h nsterm.h \
+ xterm.h puresize.h msdos.h keymap.h w32term.h nsterm.h \
$(config_h)
keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
atimer.h systime.h puresize.h character.h intervals.h keymap.h window.h \
@@ -1176,15 +1169,15 @@ widget.o: widget.c xterm.h frame.h dispextern.h widgetprv.h \
window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
disptab.h keyboard.h dispextern.h msdos.h composite.h \
keymap.h blockinput.h atimer.h systime.h $(INTERVAL_SRC) \
- xterm.h w32term.h macterm.h macgui.h nsterm.h $(config_h)
+ xterm.h w32term.h nsterm.h $(config_h)
xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h \
coding.h termchar.h frame.h window.h disptab.h termhooks.h character.h \
charset.h $(config_h) keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h \
- w32term.h macterm.h macgui.h nsterm.h msdos.h composite.h fontset.h \
+ w32term.h nsterm.h msdos.h composite.h fontset.h \
blockinput.h atimer.h systime.h keymap.h font.h
xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
window.h character.h charset.h msdos.h dosfns.h composite.h atimer.h \
- systime.h keyboard.h fontset.h w32term.h macterm.h macgui.h nsterm.h \
+ systime.h keyboard.h fontset.h w32term.h nsterm.h \
$(INTERVAL_SRC) termchar.h termhooks.h font.h $(config_h)
xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
$(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
@@ -1252,53 +1245,6 @@ composite.o: composite.c buffer.h character.h $(INTERVAL_SRC) $(config_h)
OTHER_FILES and OBJECTS_MACHINE
select which of these should be compiled. */
-#ifdef HAVE_CARBON
-buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \
- fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \
- scroll.o sysdep.o term.o terminal.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \
- xterm.o xselect.o sound.o: macgui.h
-mac.o: mac.c process.h sysselect.h blockinput.h atimer.h systime.h charset.h \
- coding.h ccl.h $(config_h)
-macfns.o: macfns.c charset.h macterm.h macgui.h frame.h window.h buffer.h \
- dispextern.h macgui.h fontset.h $(INTERVAL_SRC) keyboard.h blockinput.h \
- atimer.h systime.h epaths.h termhooks.h coding.h $(config_h)
-macmenu.o: macmenu.c termhooks.h frame.h window.h dispextern.h macgui.h \
- keyboard.h blockinput.h atimer.h systime.h buffer.h macterm.h $(config_h)
-macterm.o: blockinput.h atimer.h systime.h syssignal.h macterm.h macgui.h \
- frame.h charset.h ccl.h dispextern.h fontset.h termhooks.h termopts.h \
- termchar.h disptab.h buffer.h window.h keyboard.h $(INTERVAL_SRC) \
- process.h coding.h $(config_h)
-macselect.o: blockinput.h atimer.h systime.h macterm.h macgui.h frame.h \
- keymap.h $(config_h)
-mactoolbox.o: blockinput.h atimer.h systime.h macterm.h macgui.h frame.h \
- charset.h coding.h ccl.h dispextern.h fontset.h termhooks.h buffer.h \
- window.h keyboard.h $(config_h)
-
-${emacsapp}Contents/Resources/English.lproj:
- mkdir -p $@
-
-ifneq (${emacsapp},${emacsappsrc})
-${emacsapp}Contents/Info.plist: ${emacsappsrc}Contents/Info.plist
- cp $< $@
-${emacsapp}Contents/PkgInfo: ${emacsappsrc}Contents/PkgInfo
- cp $< $@
-${emacsapp}Contents/Resources/Emacs.icns: ${emacsappsrc}Contents/Resources/Emacs.icns
- mkdir -p ${emacsapp}Contents/Resources
- cp $< $@
-${emacsapp}Contents/Resources/English.lproj/InfoPlist.strings: ${emacsappsrc}Contents/Resources/English.lproj/InfoPlist.strings
- cp $< $@
-endif
-
-macosx-bundle: ${emacsapp}Contents/Resources/English.lproj \
- ${emacsapp}Contents/Info.plist ${emacsapp}Contents/PkgInfo \
- ${emacsapp}Contents/Resources/Emacs.icns \
- ${emacsapp}Contents/Resources/English.lproj/InfoPlist.strings
-macosx-app: macosx-bundle ${emacsapp}Contents/MacOS/Emacs
-${emacsapp}Contents/MacOS/Emacs: emacs${EXEEXT}
- mkdir -p ${emacsapp}Contents/MacOS/;
- cd ${emacsapp}Contents/MacOS/; cp ../../../../src/emacs${EXEEXT} Emacs${EXEEXT}
-#endif /* HAVE_CARBON */
-
#ifdef HAVE_NS
buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \
fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \
diff --git a/src/atimer.c b/src/atimer.c
index f1e2b1dfdd5..916c965de92 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -368,9 +368,7 @@ run_timers ()
t = atimers;
atimers = atimers->next;
-#ifndef MAC_OSX
t->fn (t);
-#endif
if (t->type == ATIMER_CONTINUOUS)
{
@@ -382,10 +380,6 @@ run_timers ()
t->next = free_atimers;
free_atimers = t;
}
-#ifdef MAC_OSX
- /* Fix for Ctrl-G. Perhaps this should apply to all platforms. */
- t->fn (t);
-#endif
EMACS_GET_TIME (now);
}
diff --git a/src/config.in b/src/config.in
index 40474fa90d1..46e1f93d2b3 100644
--- a/src/config.in
+++ b/src/config.in
@@ -92,9 +92,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if ALSA is available. */
#undef HAVE_ALSA
-/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
-#undef HAVE_AVAILABILITYMACROS_H
-
/* Define to 1 if you have the `bcmp' function. */
#undef HAVE_BCMP
@@ -104,9 +101,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
-/* Define to 1 if you are using the Carbon API on Mac OS X. */
-#undef HAVE_CARBON
-
/* Define to 1 if you have the `cbrt' function. */
#undef HAVE_CBRT
@@ -980,7 +974,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* If we're using X11/Carbon/GNUstep, define some consequences. */
-#if defined HAVE_X_WINDOWS || defined(HAVE_CARBON) || defined(HAVE_NS)
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
#define HAVE_WINDOW_SYSTEM
#define MULTI_KBOARD
#define HAVE_MOUSE
@@ -997,10 +991,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define CANNOT_DUMP
#endif
-/* TODO: These are used for the Carbon port only. */
-#undef MAC_OS
-#undef MAC_OSX
-
/* Define AMPERSAND_FULL_NAME if you use the convention
that & in the full name stands for the login id. */
/* Turned on June 1996 supposing nobody will mind it. */
@@ -1044,7 +1034,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Set up some defines, C and LD flags for NeXTstep interface on GNUstep.
(There is probably a better place to do this, but right now the Cocoa
- side does this in s/darwin.h, following the Carbon port, and we cannot
+ side does this in s/darwin.h and we cannot
parallel this exactly since GNUstep is multi-OS. */
#ifdef HAVE_NS
# ifdef C_SWITCH_SYSTEM
diff --git a/src/dispextern.h b/src/dispextern.h
index 5c06437f634..2d6e0d026f1 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -61,14 +61,6 @@ typedef XImage *XImagePtr;
typedef HDC XImagePtr_or_DC;
#endif
-#ifdef MAC_OS
-#include "macgui.h"
-typedef struct mac_display_info Display_Info;
-/* Mac equivalent of XImage. */
-typedef Pixmap XImagePtr;
-typedef XImagePtr XImagePtr_or_DC;
-#endif
-
#ifdef HAVE_NS
#include "nsgui.h"
/* following typedef needed to accomodate the MSDOS port, believe it or not */
@@ -1220,7 +1212,7 @@ struct glyph_string
unsigned padding_p : 1;
/* The GC to use for drawing this glyph string. */
-#if defined(HAVE_X_WINDOWS) || defined(MAC_OS)
+#if defined(HAVE_X_WINDOWS)
GC gc;
#endif
#if defined(HAVE_NTGUI)
@@ -2814,10 +2806,6 @@ void compute_fringe_widths P_ ((struct frame *, int));
void w32_init_fringe P_ ((struct redisplay_interface *));
void w32_reset_fringes P_ ((void));
#endif
-#ifdef MAC_OS
-void mac_init_fringe P_ ((struct redisplay_interface *));
-#endif
-
/* Defined in image.c */
#ifdef HAVE_WINDOW_SYSTEM
@@ -2923,9 +2911,6 @@ void gamma_correct P_ ((struct frame *, XColor *));
#ifdef WINDOWSNT
void gamma_correct P_ ((struct frame *, COLORREF *));
#endif
-#ifdef MAC_OS
-void gamma_correct P_ ((struct frame *, unsigned long *));
-#endif
#ifdef HAVE_WINDOW_SYSTEM
diff --git a/src/dispnew.c b/src/dispnew.c
index 7c2a265a16e..4c55f2e7adb 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -59,10 +59,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "w32term.h"
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
-#include "macterm.h"
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
#include "nsterm.h"
#endif
@@ -6887,16 +6883,6 @@ init_display ()
}
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- if (!inhibit_window_system)
- {
- Vinitial_window_system = intern ("mac");
- Vwindow_system_version = make_number (1);
- adjust_frame_glyphs_initially ();
- return;
- }
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
if (!inhibit_window_system
#ifndef CANNOT_DUMP
diff --git a/src/emacs.c b/src/emacs.c
index 96ae4001c39..9d1e69f600f 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -351,8 +351,8 @@ int fatal_error_in_progress;
void (*fatal_error_signal_hook) P_ ((void));
#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-/* When compiled with GTK and running under Gnome, or Carbon under Mac
- OS X, multiple threads may be created. Keep track of our main
+/* When compiled with GTK and running under Gnome,
+ multiple threads may be created. Keep track of our main
thread to make sure signals are delivered to it (see syssignal.h). */
pthread_t main_thread;
@@ -837,7 +837,7 @@ main (argc, argv
run_time_remap (argv[0]);
#endif
-#if defined (MAC_OSX) || defined (NS_IMPL_COCOA)
+#if defined (NS_IMPL_COCOA)
if (!initialized)
unexec_init_emacs_zone ();
#endif
@@ -921,19 +921,6 @@ main (argc, argv
}
#endif
-#ifdef MAC_OSX
- /* Skip process serial number passed in the form -psn_x_y as
- command-line argument. The WindowServer adds this option when
- Emacs is invoked from the Finder or by the `open' command. In
- these cases, the working directory becomes `/', so we change it
- to the user's home directory. */
- if (argc > skip_args + 1 && strncmp (argv[skip_args+1], "-psn_", 5) == 0)
- {
- chdir (getenv ("HOME"));
- skip_args++;
- }
-#endif /* MAC_OSX */
-
#ifdef VMS
/* If -map specified, map the data file in. */
{
@@ -1284,27 +1271,6 @@ main (argc, argv
CANNOT_DUMP is defined. */
syms_of_keyboard ();
-#ifdef MAC_OS8
- /* init_window_once calls make_terminal_frame which on Mac OS
- creates a full-fledge output_mac type frame. This does not
- work correctly before syms_of_textprop, syms_of_macfns,
- syms_of_ccl, syms_of_fontset, syms_of_xterm, syms_of_search,
- syms_of_frame, mac_term_init, and init_keyboard have already
- been called. */
- syms_of_textprop ();
- syms_of_macfns ();
- syms_of_ccl ();
- syms_of_fontset ();
- syms_of_macterm ();
- syms_of_macmenu ();
- syms_of_macselect ();
- syms_of_search ();
- syms_of_frame ();
-
- init_atimer ();
- mac_term_init (build_string ("Mac"), NULL, NULL);
- init_keyboard ();
-#endif
/* Called before syms_of_fileio, because it sets up Qerror_condition. */
syms_of_data ();
syms_of_fileio ();
@@ -1508,11 +1474,6 @@ main (argc, argv
init_ntproc (); /* must precede init_editfns. */
#endif
-#if defined (MAC_OSX) && defined (HAVE_CARBON)
- if (initialized)
- init_mac_osx_environment ();
-#endif
-
#ifdef HAVE_NS
#ifndef CANNOT_DUMP
if (initialized)
@@ -1558,7 +1519,6 @@ main (argc, argv
/* The basic levels of Lisp must come first. */
/* And data must come first of all
for the sake of symbols like error-message. */
- /* Called before init_window_once for Mac OS Classic. */
syms_of_data ();
syms_of_chartab ();
syms_of_lread ();
@@ -1641,14 +1601,6 @@ main (argc, argv
syms_of_fontset ();
#endif /* HAVE_NTGUI */
-#if defined (MAC_OSX) && defined (HAVE_CARBON)
- syms_of_macterm ();
- syms_of_macfns ();
- syms_of_macmenu ();
- syms_of_macselect ();
- syms_of_fontset ();
-#endif /* MAC_OSX && HAVE_CARBON */
-
#ifdef HAVE_NS
syms_of_nsterm ();
syms_of_nsfns ();
diff --git a/src/fileio.c b/src/fileio.c
index 820d3a2cdfa..918c06fdced 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6087,7 +6087,7 @@ The return value is only relevant for a call to `read-file-name' that happens
before any other event (mouse or keypress) is handeled. */)
()
{
-#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (HAVE_CARBON)
+#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& use_file_dialog
diff --git a/src/fns.c b/src/fns.c
index 4614ba130cb..087a050f580 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -25,16 +25,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#endif
#include <time.h>
-#ifndef MAC_OS
-/* On Mac OS, defining this conflicts with precompiled headers. */
-
/* Note on some machines this defines `vector' as a typedef,
so make sure we don't use that name in this file. */
#undef vector
#define vector *****
-#endif /* ! MAC_OSX */
-
#include "lisp.h"
#include "commands.h"
#include "character.h"
diff --git a/src/font.c b/src/font.c
index 9ceedddb297..7c15842d959 100644
--- a/src/font.c
+++ b/src/font.c
@@ -50,10 +50,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "nsterm.h"
#endif /* HAVE_NS */
-#ifdef MAC_OS
-#include "macterm.h"
-#endif /* MAC_OS */
-
Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
#ifdef HAVE_NS
@@ -5146,9 +5142,6 @@ EMACS_FONT_LOG is set. Otherwise, it is set to t. */);
#ifdef HAVE_NS
syms_of_nsfont ();
#endif /* HAVE_NS */
-#ifdef MAC_OS
- syms_of_atmfont ();
-#endif /* MAC_OS */
#endif /* HAVE_WINDOW_SYSTEM */
}
diff --git a/src/font.h b/src/font.h
index a6360e1432e..ebfec7a78c1 100644
--- a/src/font.h
+++ b/src/font.h
@@ -857,9 +857,6 @@ extern struct font_driver xftfont_driver;
extern struct font_driver w32font_driver;
extern struct font_driver uniscribe_font_driver;
#endif /* WINDOWSNT */
-#ifdef MAC_OS
-extern struct font_driver atmfont_driver;
-#endif /* MAC_OS */
#ifdef HAVE_NS
extern struct font_driver nsfont_driver;
#endif /* HAVE_NS */
diff --git a/src/fontset.c b/src/fontset.c
index edcbaa63070..3f89cb86866 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -50,9 +50,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_NS
#include "nsterm.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#include "termhooks.h"
#include "font.h"
diff --git a/src/frame.c b/src/frame.c
index 989341eb48a..edcf3a54bc8 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -29,9 +29,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef WINDOWSNT
#include "w32term.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#ifdef HAVE_NS
#include "nsterm.h"
#endif
@@ -206,7 +203,6 @@ DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
Value is t for a termcap frame (a character-only terminal),
`x' for an Emacs frame that is really an X window,
`w32' for an Emacs frame that is a window on MS-Windows display,
-`mac' for an Emacs frame on a Macintosh Carbon display,
`ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
`pc' for a direct-write MS-DOS frame.
See also `frame-live-p'. */)
@@ -702,17 +698,10 @@ affects all frames on the same terminal device. */)
abort ();
#else /* not MSDOS */
-#if 0
- /* This can happen for multi-tty when using both terminal frames and
- Carbon frames. */
- if (sf->output_method != output_mac)
- error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
-#else
#if 0 /* This should work now! */
if (sf->output_method != output_termcap)
error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
#endif
-#endif
#endif /* not MSDOS */
{
@@ -1470,10 +1459,6 @@ But FORCE inhibits this too. */)
if (FRAME_X_P (f))
x_clear_frame_selections (f);
#endif
-#ifdef MAC_OS
- if (FRAME_MAC_P (f))
- x_clear_frame_selections (f);
-#endif
/* Free glyphs.
This function must be called before the window tree of the
@@ -4500,7 +4485,7 @@ Setting this variable does not affect existing frames, only new ones. */);
DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
doc: /* Default position of scroll bars on this window-system. */);
#ifdef HAVE_WINDOW_SYSTEM
-#if defined(HAVE_NTGUI) || defined(MAC_OS) || defined(NS_IMPL_COCOA)
+#if defined(HAVE_NTGUI) || defined(NS_IMPL_COCOA)
/* MS-Windows and Mac OS X have scroll bars on the right by default. */
Vdefault_frame_scroll_bars = Qright;
#else
@@ -4567,7 +4552,7 @@ You should set this variable to tell Emacs how your window manager
handles focus, since there is no way in general for Emacs to find out
automatically. */);
#ifdef HAVE_WINDOW_SYSTEM
-#if defined(HAVE_NTGUI) || defined(MAC_OS) || defined(HAVE_NS)
+#if defined(HAVE_NTGUI) || defined(HAVE_NS)
focus_follows_mouse = 0;
#else
focus_follows_mouse = 1;
diff --git a/src/frame.h b/src/frame.h
index d070feeaef8..cae3de11641 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -245,7 +245,7 @@ struct frame
auto-resize-tool-bar is set to grow-only. */
unsigned minimize_tool_bar_window_p : 1;
-#if defined (USE_GTK) || defined (HAVE_NS) || defined (MAC_OS)
+#if defined (USE_GTK) || defined (HAVE_NS)
/* Nonzero means using a tool bar that comes from the toolkit. */
int external_tool_bar;
#endif
@@ -334,7 +334,6 @@ struct frame
struct tty_output *tty; /* termchar.h */
struct x_output *x; /* xterm.h */
struct w32_output *w32; /* w32term.h */
- struct mac_output *mac; /* macterm.h */
struct ns_output *ns; /* nsterm.h */
EMACS_INT nothing;
}
@@ -362,7 +361,7 @@ struct frame
/* Number of lines of menu bar. */
int menu_bar_lines;
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
/* Nonzero means using a menu bar that comes from the X toolkit. */
unsigned int external_menu_bar : 1;
@@ -534,9 +533,6 @@ typedef struct frame *FRAME_PTR;
#ifdef HAVE_NTGUI
#define FRAME_WINDOW_P(f) FRAME_W32_P (f)
#endif
-#ifdef MAC_OS
-#define FRAME_WINDOW_P(f) FRAME_MAC_P (f)
-#endif
#ifdef HAVE_NS
#define FRAME_WINDOW_P(f) FRAME_NS_P(f)
#endif
@@ -578,7 +574,7 @@ typedef struct frame *FRAME_PTR;
/* Nonzero if this frame should display a tool bar
in a way that does not use any text lines. */
-#if defined (USE_GTK) || defined (HAVE_NS) || defined (MAC_OS)
+#if defined (USE_GTK) || defined (HAVE_NS)
#define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
#else
#define FRAME_EXTERNAL_TOOL_BAR(f) 0
@@ -596,7 +592,7 @@ typedef struct frame *FRAME_PTR;
/* Nonzero if this frame should display a menu bar
in a way that does not use any text lines. */
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
#define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar
#else
diff --git a/src/fringe.c b/src/fringe.c
index ad40df5a2fd..1d642bf4066 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1374,15 +1374,6 @@ init_fringe_bitmap (which, fb, once_p)
}
#endif /* HAVE_X_WINDOWS */
-#if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
- unsigned short *bits = fb->bits;
- int j;
- for (j = 0; j < fb->height; j++)
- {
- unsigned short b = *bits;
- *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
- }
-#endif /* MAC_OS && WORDS_BIG_ENDIAN */
}
if (!once_p)
@@ -1696,15 +1687,10 @@ init_fringe ()
}
}
-#if defined (HAVE_NTGUI) || defined (MAC_OS)
+#ifdef HAVE_NTGUI
void
-#ifdef HAVE_NTGUI
-w32_init_fringe (rif)
-#else /* MAC_OS */
-mac_init_fringe (rif)
-#endif
- struct redisplay_interface *rif;
+w32_init_fringe (struct redisplay_interface *rif)
{
int bt;
@@ -1717,9 +1703,7 @@ mac_init_fringe (rif)
rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
}
}
-#endif
-#ifdef HAVE_NTGUI
void
w32_reset_fringes ()
{
diff --git a/src/image.c b/src/image.c
index 7aee1e6512e..1312d132f5c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -81,56 +81,6 @@ typedef struct w32_bitmap_record Bitmap_Record;
#define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
#endif /* HAVE_NTGUI */
-
-#ifdef MAC_OS
-#include "macterm.h"
-#include <sys/stat.h>
-#ifndef MAC_OSX
-#include <alloca.h>
-#include <sys/param.h>
-#endif
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
-#include <QuickTime/QuickTime.h>
-#else /* not MAC_OSX */
-#include <QuickTime.h>
-#endif /* not MAC_OSX */
-#else /* not TARGET_API_MAC_CARBON */
-#include <Windows.h>
-#include <Gestalt.h>
-#include <TextUtils.h>
-#include <ImageCompression.h>
-#include <QuickTimeComponents.h>
-#endif /* not TARGET_API_MAC_CARBON */
-
-/* MAC_TODO : Color tables on Mac. */
-#undef COLOR_TABLE_SUPPORT
-
-#define ZPixmap 0 /* arbitrary */
-typedef struct mac_bitmap_record Bitmap_Record;
-
-#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
-#define NO_PIXMAP 0
-
-#define RGB_PIXEL_COLOR unsigned long
-
-#if USE_MAC_IMAGE_IO
-#define PIX_MASK_DRAW 255
-#define PIX_MASK_RETAIN 0
-#else
-/* A black pixel in a mask bitmap/pixmap means ``draw a source
- pixel''. A white pixel means ``retain the current pixel''. */
-#define PIX_MASK_DRAW RGB_TO_ULONG(0,0,0)
-#define PIX_MASK_RETAIN RGB_TO_ULONG(255,255,255)
-#endif
-
-#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
-#define x_defined_color mac_defined_color
-#define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes)
-
-#endif /* MAC_OS */
-
-
#ifdef HAVE_NS
#include "nsterm.h"
#include <sys/types.h>
@@ -564,12 +514,6 @@ x_create_bitmap_from_data (f, bits, width, height)
return -1;
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
- if (width % 16 != 0)
- return -1;
-#endif
-
#ifdef HAVE_NS
void *bitmap = ns_image_from_XBM(bits, width, height);
if (!bitmap)
@@ -577,10 +521,6 @@ x_create_bitmap_from_data (f, bits, width, height)
#endif
id = x_allocate_bitmap_record (f);
-#ifdef MAC_OS
- dpyinfo->bitmaps[id - 1].bitmap_data = (char *) xmalloc (height * width);
- bcopy (bits, dpyinfo->bitmaps[id - 1].bitmap_data, height * width);
-#endif /* MAC_OS */
#ifdef HAVE_NS
dpyinfo->bitmaps[id - 1].img = bitmap;
@@ -616,10 +556,6 @@ x_create_bitmap_from_file (f, file)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-#ifdef MAC_OS
- return -1; /* MAC_TODO : bitmap support */
-#endif /* MAC_OS */
-
#ifdef HAVE_NTGUI
return -1; /* W32_TODO : bitmap support */
#endif /* HAVE_NTGUI */
@@ -707,11 +643,6 @@ free_bitmap_record (dpyinfo, bm)
DeleteObject (bm->pixmap);
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- xfree (bm->bitmap_data); /* Added ++kfs */
- bm->bitmap_data = NULL;
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
ns_release_object(bm->img);
#endif
@@ -1446,17 +1377,6 @@ prepare_image_for_display (f, img)
if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
img->load_failed_p = img->type->load (f, img) == 0;
-#if defined (MAC_OS) && USE_CG_DRAWING
- if (!img->load_failed_p && img->data.ptr_val == NULL)
- {
- img->data.ptr_val = mac_create_cg_image_from_image (f, img);
- if (img->data.ptr_val == NULL)
- {
- img->load_failed_p = 1;
- img->type->free (f, img);
- }
- }
-#endif
}
@@ -1718,7 +1638,6 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
if (colors_p && img->ncolors)
{
- /* MAC_TODO: color table support. */
/* W32_TODO: color table support. */
#ifdef HAVE_X_WINDOWS
x_free_colors (f, img->colors, img->ncolors);
@@ -1728,13 +1647,6 @@ x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
img->ncolors = 0;
}
-#if defined (MAC_OS) && USE_CG_DRAWING
- if (img->data.ptr_val)
- {
- CGImageRelease (img->data.ptr_val);
- img->data.ptr_val = NULL;
- }
-#endif
}
/* Free X resources of image IMG which is used on frame F. */
@@ -2279,7 +2191,7 @@ mark_image_cache (struct image_cache *c)
/***********************************************************************
- X / MAC / W32 support code
+ X / NS / W32 support code
***********************************************************************/
#ifdef HAVE_NTGUI
@@ -2464,29 +2376,6 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- Display *display = FRAME_X_DISPLAY (f);
- Window window = FRAME_X_WINDOW (f);
-
- xassert (interrupt_input_blocked);
-
- /* Allocate a pixmap of the same size. */
- *pixmap = XCreatePixmap (display, window, width, height, depth);
- if (*pixmap == NO_PIXMAP)
- {
- *ximg = NULL;
- image_error ("Unable to create X pixmap", Qnil, Qnil);
- return 0;
- }
-
-#if !USE_MAC_IMAGE_IO
- LockPixels (GetGWorldPixMap (*pixmap));
-#endif
- *ximg = *pixmap;
- return 1;
-
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
*pixmap = ns_image_for_XPM(width, height, depth);
if (*pixmap == 0)
@@ -2520,9 +2409,6 @@ x_destroy_x_image (ximg)
ximg->data = NULL;
xfree (ximg);
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- XDestroyImage (ximg);
-#endif /* MAC_OS */
#ifdef HAVE_NS
ns_release_object(ximg);
#endif /* HAVE_NS */
@@ -2557,10 +2443,6 @@ x_put_x_image (f, ximg, pixmap, width, height)
#endif
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- xassert (ximg == pixmap);
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
xassert (ximg == pixmap);
ns_retain_object(ximg);
@@ -2648,593 +2530,6 @@ slurp_file (file, size)
-#ifdef MAC_OS
-
-/***********************************************************************
- MAC Image Load Functions
- ***********************************************************************/
-
-#if USE_MAC_IMAGE_IO
-static int
-image_load_image_io (f, img, type)
- struct frame *f;
- struct image *img;
- CFStringRef type;
-{
- CFDictionaryRef options, src_props = NULL, props = NULL;
- CFStringRef keys[2];
- CFTypeRef values[2];
- Lisp_Object specified_file, specified_data;
- CGImageSourceRef source = NULL;
- size_t count;
- CGImageRef image = NULL;
- int loop_count = -1;
- double delay_time = -1.0;
- int width, height;
- XImagePtr ximg = NULL;
- CGContextRef context;
- CGRect rectangle;
- int has_alpha_p, gif_p;
-
- gif_p = UTTypeEqual (type, kUTTypeGIF);
-
- keys[0] = kCGImageSourceTypeIdentifierHint;
- values[0] = (CFTypeRef) type;
- keys[1] = kCGImageSourceShouldCache;
- values[1] = (CFTypeRef) kCFBooleanFalse;
- options = CFDictionaryCreate (NULL, (const void **) keys,
- (const void **) values,
- sizeof (keys) / sizeof (keys[0]),
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (options == NULL)
- {
- image_error ("Error creating options for image `%s'", img->spec, Qnil);
- return 0;
- }
-
- /* Open the file. */
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- if (NILP (specified_data))
- {
- Lisp_Object file;
- CFStringRef path;
- CFURLRef url;
-
- file = x_find_image_file (specified_file);
- if (!STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- return 0;
- }
- path = cfstring_create_with_utf8_cstring (SDATA (file));
- if (path)
- {
- url = CFURLCreateWithFileSystemPath (NULL, path,
- kCFURLPOSIXPathStyle, 0);
- CFRelease (path);
- if (url)
- {
- source = CGImageSourceCreateWithURL (url, NULL);
- CFRelease (url);
- }
- }
- }
- else
- {
- CFDataRef data = CFDataCreate (NULL, SDATA (specified_data),
- SBYTES (specified_data));
-
- if (data)
- {
- source = CGImageSourceCreateWithData (data, options);
- CFRelease (data);
- }
- }
- CFRelease (options);
-
- if (source)
- {
- CFStringRef real_type = CGImageSourceGetType (source);
-
- if (real_type && UTTypeEqual (type, real_type))
- src_props = CGImageSourceCopyProperties (source, NULL);
- if (src_props)
- {
- EMACS_INT ino = 0;
-
- count = CGImageSourceGetCount (source);
- if (gif_p)
- {
- Lisp_Object image = image_spec_value (img->spec, QCindex, NULL);
-
- if (INTEGERP (image))
- ino = XFASTINT (image);
- }
- if (ino >= 0 && ino < count)
- {
- props = CGImageSourceCopyPropertiesAtIndex (source, ino, NULL);
- if (props)
- image = CGImageSourceCreateImageAtIndex (source, ino, NULL);
- }
- }
- CFRelease (source);
- }
-
- if (image == NULL)
- {
- if (src_props)
- CFRelease (src_props);
- if (props)
- CFRelease (props);
- image_error ("Error reading image `%s'", img->spec, Qnil);
- return 0;
- }
- else
- {
- CFBooleanRef boolean;
-
- if (CFDictionaryGetValueIfPresent (props, kCGImagePropertyHasAlpha,
- (const void **) &boolean))
- has_alpha_p = CFBooleanGetValue (boolean);
- if (gif_p)
- {
- CFDictionaryRef dict;
- CFNumberRef number;
-
- dict = CFDictionaryGetValue (src_props,
- kCGImagePropertyGIFDictionary);
- if (dict
- && CFDictionaryGetValueIfPresent (dict,
- kCGImagePropertyGIFLoopCount,
- (const void **) &number))
- CFNumberGetValue (number, kCFNumberIntType, &loop_count);
-
- dict = CFDictionaryGetValue (props, kCGImagePropertyGIFDictionary);
- if (dict
- && CFDictionaryGetValueIfPresent (dict,
- kCGImagePropertyGIFDelayTime,
- (const void **) &number))
- CFNumberGetValue (number, kCFNumberDoubleType, &delay_time);
- }
- CFRelease (src_props);
- CFRelease (props);
- }
-
- width = img->width = CGImageGetWidth (image);
- height = img->height = CGImageGetHeight (image);
-
- if (!check_image_size (f, width, height))
- {
- CGImageRelease (image);
- image_error ("Invalid image size", Qnil, Qnil);
- return 0;
- }
-
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- {
- CGImageRelease (image);
- image_error ("Out of memory (%s)", img->spec, Qnil);
- return 0;
- }
- rectangle = CGRectMake (0, 0, width, height);
-
- context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8,
- ximg->bytes_per_line,
- mac_cg_color_space_rgb,
- kCGImageAlphaNoneSkipFirst
- | kCGBitmapByteOrder32Host);
- if (has_alpha_p)
- {
- Lisp_Object specified_bg;
- XColor color;
-
- specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg)
- || !mac_defined_color (f, SDATA (specified_bg), &color, 0))
- {
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- color.red = RED16_FROM_ULONG (color.pixel);
- color.green = GREEN16_FROM_ULONG (color.pixel);
- color.blue = BLUE16_FROM_ULONG (color.pixel);
- }
- CGContextSetRGBFillColor (context, color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0, 1.0);
- CGContextFillRect (context, rectangle);
- }
- CGContextDrawImage (context, rectangle, image);
- CGContextRelease (context);
- CGImageRelease (image);
-
- /* Save GIF image extension data for `image-extension-data'.
- Format is (count IMAGES
- 0xff "NETSCAPE2.0" 0x00 DATA_SUB_BLOCK_FOR_LOOP_COUNT
- 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK). */
- if (gif_p)
- {
- img->data.lisp_val = Qnil;
- if (delay_time >= 0)
- {
- Lisp_Object gce = make_uninit_string (4);
- int centisec = delay_time * 100.0 + 0.5;
-
- /* Fill the delay time field. */
- SSET (gce, 1, centisec & 0xff);
- SSET (gce, 2, (centisec >> 8) & 0xff);
- /* We don't know about other fields. */
- SSET (gce, 0, 0);
- SSET (gce, 3, 0);
- img->data.lisp_val = Fcons (make_number (0xf9),
- Fcons (gce,
- img->data.lisp_val));
- }
- if (loop_count >= 0)
- {
- Lisp_Object data_sub_block = make_uninit_string (3);
-
- SSET (data_sub_block, 0, 0x01);
- SSET (data_sub_block, 1, loop_count & 0xff);
- SSET (data_sub_block, 2, (loop_count >> 8) & 0xff);
- img->data.lisp_val = Fcons (make_number (0),
- Fcons (data_sub_block,
- img->data.lisp_val));
- img->data.lisp_val = Fcons (make_number (0xff),
- Fcons (build_string ("NETSCAPE2.0"),
- img->data.lisp_val));
- }
- if (count > 1)
- img->data.lisp_val = Fcons (Qcount,
- Fcons (make_number (count),
- img->data.lisp_val));
- }
-
- /* Maybe fill in the background field while we have ximg handy. */
- if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
- IMAGE_BACKGROUND (img, f, ximg);
-
- /* Put the image into the pixmap. */
- x_put_x_image (f, ximg, img->pixmap, width, height);
- x_destroy_x_image (ximg);
- return 1;
-}
-#else /* !USE_MAC_IMAGE_IO */
-static int image_load_quicktime P_ ((struct frame *, struct image *img,
- OSType));
-#ifdef MAC_OSX
-static int image_load_quartz2d P_ ((struct frame *, struct image *img, int));
-#endif
-
-static OSErr
-find_image_fsspec (specified_file, file, fss)
- Lisp_Object specified_file, *file;
- FSSpec *fss;
-{
- OSErr err;
- AEDesc desc;
-
- *file = x_find_image_file (specified_file);
- if (!STRINGP (*file))
- return fnfErr; /* file or directory not found;
- incomplete pathname */
- /* Try to open the image file. */
- err = AECoercePtr (TYPE_FILE_NAME, SDATA (*file),
- SBYTES (*file), typeFSS, &desc);
- if (err == noErr)
- {
-#if TARGET_API_MAC_CARBON
- err = AEGetDescData (&desc, fss, sizeof (FSSpec));
-#else
- *fss = *(FSSpec *)(*(desc.dataHandle));
-#endif
- AEDisposeDesc (&desc);
- }
- return err;
-}
-
-static int
-image_load_qt_1 (f, img, type, fss, dh)
- struct frame *f;
- struct image *img;
- OSType type;
- const FSSpec *fss;
- Handle dh;
-{
- ComponentResult err;
- GraphicsImportComponent gi;
- Rect rect;
- int width, height;
- ImageDescriptionHandle desc_handle;
- short draw_all_pixels;
- Lisp_Object specified_bg;
- XColor color;
- XImagePtr ximg;
- RGBColor bg_color;
-
- err = OpenADefaultComponent (GraphicsImporterComponentType, type, &gi);
- if (err != noErr)
- {
- image_error ("Cannot get importer component for `%s'", img->spec, Qnil);
- return 0;
- }
- if (dh == NULL)
- {
- /* read from file system spec */
- err = GraphicsImportSetDataFile (gi, fss);
- if (err != noErr)
- {
- image_error ("Cannot set fsspec to graphics importer for '%s'",
- img->spec, Qnil);
- goto error;
- }
- }
- else
- {
- /* read from data handle */
- err = GraphicsImportSetDataHandle (gi, dh);
- if (err != noErr)
- {
- image_error ("Cannot set data handle to graphics importer for `%s'",
- img->spec, Qnil);
- goto error;
- }
- }
- err = GraphicsImportGetImageDescription (gi, &desc_handle);
- if (err != noErr || desc_handle == NULL)
- {
- image_error ("Error reading `%s'", img->spec, Qnil);
- goto error;
- }
- width = img->width = (*desc_handle)->width;
- height = img->height = (*desc_handle)->height;
- DisposeHandle ((Handle)desc_handle);
-
- if (!check_image_size (f, width, height))
- {
- image_error ("Invalid image size", Qnil, Qnil);
- goto error;
- }
-
- err = GraphicsImportDoesDrawAllPixels (gi, &draw_all_pixels);
-#if 0
- /* Don't check the error code here. It may have an undocumented
- value -32766. */
- if (err != noErr)
- {
- image_error ("Error reading `%s'", img->spec, Qnil);
- goto error;
- }
-#endif
- if (draw_all_pixels != graphicsImporterDrawsAllPixels)
- {
- specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg) ||
- !mac_defined_color (f, SDATA (specified_bg), &color, 0))
- {
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- color.red = RED16_FROM_ULONG (color.pixel);
- color.green = GREEN16_FROM_ULONG (color.pixel);
- color.blue = BLUE16_FROM_ULONG (color.pixel);
- }
- }
-
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- goto error;
- if (draw_all_pixels != graphicsImporterDrawsAllPixels)
- {
- CGrafPtr old_port;
- GDHandle old_gdh;
-
- GetGWorld (&old_port, &old_gdh);
- SetGWorld (ximg, NULL);
- bg_color.red = color.red;
- bg_color.green = color.green;
- bg_color.blue = color.blue;
- RGBBackColor (&bg_color);
-#if TARGET_API_MAC_CARBON
- GetPortBounds (ximg, &rect);
- EraseRect (&rect);
-#else
- EraseRect (&(ximg->portRect));
-#endif
- SetGWorld (old_port, old_gdh);
- }
- GraphicsImportSetGWorld (gi, ximg, NULL);
- GraphicsImportDraw (gi);
- CloseComponent (gi);
-
- /* Maybe fill in the background field while we have ximg handy. */
- if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
- IMAGE_BACKGROUND (img, f, ximg);
-
- /* Put the image into the pixmap. */
- x_put_x_image (f, ximg, img->pixmap, width, height);
- x_destroy_x_image (ximg);
- return 1;
-
- error:
- CloseComponent (gi);
- return 0;
-}
-
-
-/* Load an image using the QuickTime Graphics Importer.
- Note: The alpha channel does not work for PNG images. */
-static int
-image_load_quicktime (f, img, type)
- struct frame *f;
- struct image *img;
- OSType type;
-{
- Lisp_Object specified_file;
- Lisp_Object specified_data;
- OSErr err;
-
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- if (NILP (specified_data))
- {
- /* Read from a file */
- Lisp_Object file;
- FSSpec fss;
-
- err = find_image_fsspec (specified_file, &file, &fss);
- if (err != noErr)
- {
- if (err == fnfErr)
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- else
- image_error ("Cannot open `%s'", file, Qnil);
- return 0;
- }
- return image_load_qt_1 (f, img, type, &fss, NULL);
- }
- else
- {
- /* Memory source! */
- int success_p;
- Handle dh;
-
- err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
- if (err != noErr)
- {
- image_error ("Cannot allocate data handle for `%s'",
- img->spec, Qnil);
- return 0;
- }
- success_p = image_load_qt_1 (f, img, type, NULL, dh);
- DisposeHandle (dh);
- return success_p;
- }
-}
-
-
-#ifdef MAC_OSX
-static int
-image_load_quartz2d (f, img, png_p)
- struct frame *f;
- struct image *img;
- int png_p;
-{
- Lisp_Object file, specified_file;
- Lisp_Object specified_data, specified_bg;
- struct gcpro gcpro1;
- CGDataProviderRef source;
- CGImageRef image;
- int width, height;
- XColor color;
- XImagePtr ximg = NULL;
- CGContextRef context;
- CGRect rectangle;
-
- /* Open the file. */
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- file = Qnil;
- GCPRO1 (file);
-
- if (NILP (specified_data))
- {
- CFStringRef path;
- CFURLRef url;
-
- file = x_find_image_file (specified_file);
- if (!STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
- return 0;
- }
- path = cfstring_create_with_utf8_cstring (SDATA (file));
- url = CFURLCreateWithFileSystemPath (NULL, path,
- kCFURLPOSIXPathStyle, 0);
- CFRelease (path);
- source = CGDataProviderCreateWithURL (url);
- CFRelease (url);
- }
- else
- source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
- SBYTES (specified_data), NULL);
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (png_p)
- image = CGImageCreateWithPNGDataProvider (source, NULL, false,
- kCGRenderingIntentDefault);
- else
-#endif
- image = CGImageCreateWithJPEGDataProvider (source, NULL, false,
- kCGRenderingIntentDefault);
-
- CGDataProviderRelease (source);
- if (image == NULL)
- {
- UNGCPRO;
- image_error ("Error reading image `%s'", img->spec, Qnil);
- return 0;
- }
- width = img->width = CGImageGetWidth (image);
- height = img->height = CGImageGetHeight (image);
-
- if (!check_image_size (f, width, height))
- {
- CGImageRelease (image);
- UNGCPRO;
- image_error ("Invalid image size", Qnil, Qnil);
- return 0;
- }
-
- if (png_p)
- {
- specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg) ||
- !mac_defined_color (f, SDATA (specified_bg), &color, 0))
- {
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- color.red = RED16_FROM_ULONG (color.pixel);
- color.green = GREEN16_FROM_ULONG (color.pixel);
- color.blue = BLUE16_FROM_ULONG (color.pixel);
- }
- }
-
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- {
- CGImageRelease (image);
- UNGCPRO;
- return 0;
- }
- rectangle = CGRectMake (0, 0, width, height);
- QDBeginCGContext (ximg, &context);
- if (png_p)
- {
- CGContextSetRGBFillColor (context, color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0, 1.0);
- CGContextFillRect (context, rectangle);
- }
- CGContextDrawImage (context, rectangle, image);
- QDEndCGContext (ximg, &context);
- CGImageRelease (image);
-
- /* Maybe fill in the background field while we have ximg handy. */
- if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
- IMAGE_BACKGROUND (img, f, ximg);
-
- /* Put the image into the pixmap. */
- x_put_x_image (f, ximg, img->pixmap, width, height);
- x_destroy_x_image (ximg);
- UNGCPRO;
- return 1;
-}
-#endif
-#endif /* !USE_MAC_IMAGE_IO */
-
-#endif /* MAC_OS */
-
-
/***********************************************************************
XBM images
***********************************************************************/
@@ -4011,13 +3306,13 @@ xbm_load (f, img)
XPM images
***********************************************************************/
-#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
static int xpm_image_p P_ ((Lisp_Object object));
static int xpm_load P_ ((struct frame *f, struct image *img));
static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
-#endif /* HAVE_XPM || MAC_OS || HAVE_NS */
+#endif /* HAVE_XPM || HAVE_NS */
#ifdef HAVE_XPM
#ifdef HAVE_NTGUI
@@ -4040,7 +3335,7 @@ static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
#endif /* HAVE_NTGUI */
#endif /* HAVE_XPM */
-#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
/* The symbol `xpm' identifying XPM-format images. */
Lisp_Object Qxpm;
@@ -4367,7 +3662,7 @@ xpm_image_p (object)
|| xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
}
-#endif /* HAVE_XPM || MAC_OS || HAVE_NS */
+#endif /* HAVE_XPM || HAVE_NS */
#if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
int
@@ -4646,9 +3941,9 @@ xpm_load (f, img)
#endif /* HAVE_XPM */
-#if defined (MAC_OS) || ( defined (HAVE_NS) && !defined (HAVE_XPM) )
+#if defined (HAVE_NS) && !defined (HAVE_XPM)
-/* XPM support functions for Mac OS where libxpm is not available.
+/* XPM support functions for NS where libxpm is not available.
Only XPM version 3 (without any extensions) is supported. */
static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
@@ -5132,7 +4427,7 @@ xpm_load (f, img)
return success_p;
}
-#endif /* MAC_OS || (HAVE_NS && !HAVE_XPM) */
+#endif /* HAVE_NS && !HAVE_XPM */
@@ -5393,11 +4688,6 @@ lookup_rgb_color (f, r, g, b)
{
unsigned long pixel;
-#ifdef MAC_OS
- pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
- gamma_correct (f, &pixel);
-#endif /* MAC_OS */
-
#ifdef HAVE_NTGUI
pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
#endif /* HAVE_NTGUI */
@@ -5510,11 +4800,11 @@ x_to_xcolors (f, img, rgb_p)
p->pixel = GET_PIXEL (ximg, x, y);
if (rgb_p)
{
-#if defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_NS)
p->red = RED16_FROM_ULONG (p->pixel);
p->green = GREEN16_FROM_ULONG (p->pixel);
p->blue = BLUE16_FROM_ULONG (p->pixel);
-#endif /* MAC_OS */
+#endif /* HAVE_NS */
#ifdef HAVE_NTGUI
p->red = 256 * GetRValue (p->pixel);
p->green = 256 * GetGValue (p->pixel);
@@ -5807,11 +5097,7 @@ x_disable_image (f, img)
#ifndef HAVE_NS //TODO: NS support, however this not needed for toolbars
-#ifdef MAC_OS
-#define MaskForeground(f) PIX_MASK_DRAW
-#else
#define MaskForeground(f) WHITE_PIX_DEFAULT (f)
-#endif
gc = XCreateGC (dpy, img->pixmap, 0, NULL);
XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
@@ -6422,7 +5708,7 @@ pbm_load (f, img)
PNG
***********************************************************************/
-#if defined (HAVE_PNG) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
/* Function prototypes. */
@@ -6494,7 +5780,7 @@ png_image_p (object)
return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
}
-#endif /* HAVE_PNG || MAC_OS || HAVE_NS */
+#endif /* HAVE_PNG || HAVE_NS */
#ifdef HAVE_PNG
@@ -6882,19 +6168,6 @@ png_load (f, img)
frame_background.blue = GetBValue (color);
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- unsigned long color;
- png_color_16 frame_background;
- color = FRAME_BACKGROUND_PIXEL (f);
-#if 0 /* MAC/W32 TODO : Colormap support. */
- x_query_color (f, &color);
-#endif
- bzero (&frame_background, sizeof frame_background);
- frame_background.red = RED_FROM_ULONG (color);
- frame_background.green = GREEN_FROM_ULONG (color);
- frame_background.blue = BLUE_FROM_ULONG (color);
-#endif /* MAC_OS */
-
fn_png_set_background (png_ptr, &frame_background,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
@@ -7038,22 +6311,6 @@ png_load (f, img)
#else /* HAVE_PNG */
-#ifdef MAC_OS
-static int
-png_load (f, img)
- struct frame *f;
- struct image *img;
-{
-#if USE_MAC_IMAGE_IO
- return image_load_image_io (f, img, kUTTypePNG);
-#elif MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- return image_load_quartz2d (f, img, 1);
-#else
- return image_load_quicktime (f, img, kQTFileTypePNG);
-#endif
-}
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
static int
png_load (struct frame *f, struct image *img)
@@ -7073,7 +6330,7 @@ png_load (struct frame *f, struct image *img)
JPEG
***********************************************************************/
-#if defined (HAVE_JPEG) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
static int jpeg_image_p P_ ((Lisp_Object object));
static int jpeg_load P_ ((struct frame *f, struct image *img));
@@ -7144,7 +6401,7 @@ jpeg_image_p (object)
return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
}
-#endif /* HAVE_JPEG || MAC_OS || HAVE_NS */
+#endif /* HAVE_JPEG || HAVE_NS */
#ifdef HAVE_JPEG
@@ -7628,22 +6885,6 @@ jpeg_load (f, img)
#else /* HAVE_JPEG */
-#ifdef MAC_OS
-static int
-jpeg_load (f, img)
- struct frame *f;
- struct image *img;
-{
-#if USE_MAC_IMAGE_IO
- return image_load_image_io (f, img, kUTTypeJPEG);
-#elif defined (MAC_OSX)
- return image_load_quartz2d (f, img, 0);
-#else
- return image_load_quicktime (f, img, kQTFileTypeJPEG);
-#endif
-}
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
static int
jpeg_load (struct frame *f, struct image *img)
@@ -7662,7 +6903,7 @@ jpeg_load (struct frame *f, struct image *img)
TIFF
***********************************************************************/
-#if defined (HAVE_TIFF) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
static int tiff_image_p P_ ((Lisp_Object object));
static int tiff_load P_ ((struct frame *f, struct image *img));
@@ -7732,7 +6973,7 @@ tiff_image_p (object)
return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
}
-#endif /* HAVE_TIFF || MAC_OS || HAVE_NS */
+#endif /* HAVE_TIFF || HAVE_NS */
#ifdef HAVE_TIFF
@@ -8065,20 +7306,6 @@ tiff_load (f, img)
#else /* HAVE_TIFF */
-#ifdef MAC_OS
-static int
-tiff_load (f, img)
- struct frame *f;
- struct image *img;
-{
-#if USE_MAC_IMAGE_IO
- return image_load_image_io (f, img, kUTTypeTIFF);
-#else
- return image_load_quicktime (f, img, kQTFileTypeTIFF);
-#endif
-}
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
static int
tiff_load (struct frame *f, struct image *img)
@@ -8097,7 +7324,7 @@ tiff_load (struct frame *f, struct image *img)
GIF
***********************************************************************/
-#if defined (HAVE_GIF) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_GIF) || defined (HAVE_NS)
static int gif_image_p P_ ((Lisp_Object object));
static int gif_load P_ ((struct frame *f, struct image *img));
@@ -8182,11 +7409,11 @@ gif_image_p (object)
return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
}
-#endif /* HAVE_GIF || MAC_OS */
+#endif /* HAVE_GIF */
#ifdef HAVE_GIF
-#if defined (HAVE_NTGUI) || defined (MAC_OS)
+#if defined (HAVE_NTGUI)
/* winuser.h might define DrawText to DrawTextA or DrawTextW.
Undefine before redefining to avoid a preprocessor warning. */
#ifdef DrawText
@@ -8197,11 +7424,11 @@ gif_image_p (object)
#include <gif_lib.h>
#undef DrawText
-#else /* HAVE_NTGUI || MAC_OS */
+#else /* HAVE_NTGUI */
#include <gif_lib.h>
-#endif /* HAVE_NTGUI || MAC_OS */
+#endif /* HAVE_NTGUI */
#ifdef HAVE_NTGUI
@@ -8515,217 +7742,6 @@ gif_load (f, img)
#else /* !HAVE_GIF */
-#ifdef MAC_OS
-static int
-gif_load (f, img)
- struct frame *f;
- struct image *img;
-{
-#if USE_MAC_IMAGE_IO
- return image_load_image_io (f, img, kUTTypeGIF);
-#else /* !USE_MAC_IMAGE_IO */
- Lisp_Object specified_file, file;
- Lisp_Object specified_data;
- OSErr err;
- Boolean graphic_p, movie_p, prefer_graphic_p;
- Handle dh = NULL;
- Movie movie = NULL;
- Lisp_Object image;
- Track track = NULL;
- Media media = NULL;
- long nsamples;
- Rect rect;
- Lisp_Object specified_bg;
- XColor color;
- RGBColor bg_color;
- int width, height;
- XImagePtr ximg;
- TimeScale time_scale;
- TimeValue time, duration;
- int ino;
- CGrafPtr old_port;
- GDHandle old_gdh;
-
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- /* Animated gifs use QuickTime Movie Toolbox. So initialize it here. */
- EnterMovies ();
-
- if (NILP (specified_data))
- {
- /* Read from a file */
- FSSpec fss;
- short refnum;
-
- err = find_image_fsspec (specified_file, &file, &fss);
- if (err != noErr)
- {
- if (err == fnfErr)
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- else
- goto open_error;
- }
-
- err = CanQuickTimeOpenFile (&fss, kQTFileTypeGIF, 0,
- &graphic_p, &movie_p, &prefer_graphic_p, 0);
- if (err != noErr)
- goto open_error;
-
- if (!graphic_p && !movie_p)
- goto open_error;
- if (prefer_graphic_p)
- return image_load_qt_1 (f, img, kQTFileTypeGIF, &fss, NULL);
- err = OpenMovieFile (&fss, &refnum, fsRdPerm);
- if (err != noErr)
- goto open_error;
- err = NewMovieFromFile (&movie, refnum, NULL, NULL, 0, NULL);
- CloseMovieFile (refnum);
- if (err != noErr)
- {
- image_error ("Error reading `%s'", file, Qnil);
- return 0;
- }
- }
- else
- {
- /* Memory source! */
- Handle dref = NULL;
- long file_type_atom[3];
-
- err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
- if (err != noErr)
- {
- image_error ("Cannot allocate data handle for `%s'",
- img->spec, Qnil);
- goto error;
- }
-
- file_type_atom[0] = EndianU32_NtoB (sizeof (long) * 3);
- file_type_atom[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType);
- file_type_atom[2] = EndianU32_NtoB (kQTFileTypeGIF);
- err = PtrToHand (&dh, &dref, sizeof (Handle));
- if (err == noErr)
- /* no file name */
- err = PtrAndHand ("\p", dref, 1);
- if (err == noErr)
- err = PtrAndHand (file_type_atom, dref, sizeof (long) * 3);
- if (err != noErr)
- {
- image_error ("Cannot allocate handle data ref for `%s'", img->spec, Qnil);
- goto error;
- }
- err = CanQuickTimeOpenDataRef (dref, HandleDataHandlerSubType, &graphic_p,
- &movie_p, &prefer_graphic_p, 0);
- if (err != noErr)
- goto open_error;
-
- if (!graphic_p && !movie_p)
- goto open_error;
- if (prefer_graphic_p)
- {
- int success_p;
-
- DisposeHandle (dref);
- success_p = image_load_qt_1 (f, img, kQTFileTypeGIF, NULL, dh);
- DisposeHandle (dh);
- return success_p;
- }
- err = NewMovieFromDataRef (&movie, 0, NULL, dref,
- HandleDataHandlerSubType);
- DisposeHandle (dref);
- if (err != noErr)
- goto open_error;
- }
-
- image = image_spec_value (img->spec, QCindex, NULL);
- ino = INTEGERP (image) ? XFASTINT (image) : 0;
- track = GetMovieIndTrack (movie, 1);
- media = GetTrackMedia (track);
- nsamples = GetMediaSampleCount (media);
- if (ino >= nsamples)
- {
- image_error ("Invalid image number `%s' in image `%s'",
- image, img->spec);
- goto error;
- }
- time_scale = GetMediaTimeScale (media);
-
- specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg)
- || !mac_defined_color (f, SDATA (specified_bg), &color, 0))
- {
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- color.red = RED16_FROM_ULONG (color.pixel);
- color.green = GREEN16_FROM_ULONG (color.pixel);
- color.blue = BLUE16_FROM_ULONG (color.pixel);
- }
- GetMovieBox (movie, &rect);
- width = img->width = rect.right - rect.left;
- height = img->height = rect.bottom - rect.top;
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- goto error;
-
- GetGWorld (&old_port, &old_gdh);
- SetGWorld (ximg, NULL);
- bg_color.red = color.red;
- bg_color.green = color.green;
- bg_color.blue = color.blue;
- RGBBackColor (&bg_color);
- SetGWorld (old_port, old_gdh);
- SetMovieActive (movie, 1);
- SetMovieGWorld (movie, ximg, NULL);
- SampleNumToMediaTime (media, ino + 1, &time, &duration);
- SetMovieTimeValue (movie, time);
- MoviesTask (movie, 0L);
- DisposeTrackMedia (media);
- DisposeMovieTrack (track);
- DisposeMovie (movie);
- if (dh)
- DisposeHandle (dh);
-
- /* Save GIF image extension data for `image-extension-data'.
- Format is (count IMAGES 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK). */
- {
- Lisp_Object gce = make_uninit_string (4);
- int centisec = ((float)duration / time_scale) * 100.0f + 0.5f;
-
- /* Fill the delay time field. */
- SSET (gce, 1, centisec & 0xff);
- SSET (gce, 2, (centisec >> 8) & 0xff);
- /* We don't know about other fields. */
- SSET (gce, 0, 0);
- SSET (gce, 3, 0);
-
- img->data.lisp_val = list4 (Qcount, make_number (nsamples),
- make_number (0xf9), gce);
- }
-
- /* Maybe fill in the background field while we have ximg handy. */
- if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
- IMAGE_BACKGROUND (img, f, ximg);
-
- /* Put the image into the pixmap. */
- x_put_x_image (f, ximg, img->pixmap, width, height);
- x_destroy_x_image (ximg);
- return 1;
-
- open_error:
- image_error ("Cannot open `%s'", file, Qnil);
- error:
- if (media)
- DisposeTrackMedia (media);
- if (track)
- DisposeMovieTrack (track);
- if (movie)
- DisposeMovie (movie);
- if (dh)
- DisposeHandle (dh);
- return 0;
-#endif /* !USE_MAC_IMAGE_IO */
-}
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
static int
gif_load (struct frame *f, struct image *img)
@@ -9069,11 +8085,6 @@ svg_load_image (f, img, contents, size)
background.red >>= 8;
background.green >>= 8;
background.blue >>= 8;
-#elif defined (MAC_OS)
- background.pixel = FRAME_BACKGROUND_PIXEL (f);
- background.red = RED_FROM_ULONG (background.pixel);
- background.green = GREEN_FROM_ULONG (background.pixel);
- background.blue = BLUE_FROM_ULONG (background.pixel);
#elif defined (HAVE_NTGUI)
background.pixel = FRAME_BACKGROUND_PIXEL (f);
#if 0 /* W32 TODO : Colormap support. */
@@ -9086,7 +8097,7 @@ svg_load_image (f, img, contents, size)
background.red >>= 8;
background.green >>= 8;
background.blue >>= 8;
-#else /* not HAVE_X_WINDOWS && not MAC_OS*/
+#else /* not HAVE_X_WINDOWS*/
#error FIXME
#endif
}
@@ -9524,27 +8535,27 @@ of `image-library-alist', which see). */)
if (CONSP (tested))
return XCDR (tested);
-#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
if (EQ (type, Qxpm))
return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
#endif
-#if defined (HAVE_JPEG) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
if (EQ (type, Qjpeg))
return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
#endif
-#if defined (HAVE_TIFF) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
if (EQ (type, Qtiff))
return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
#endif
-#if defined (HAVE_GIF) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_GIF) || defined (HAVE_NS)
if (EQ (type, Qgif))
return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
#endif
-#if defined (HAVE_PNG) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
if (EQ (type, Qpng))
return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
#endif
@@ -9669,31 +8680,31 @@ non-numeric, there is no explicit limit on the size of images. */);
staticpro (&QCpt_height);
#endif /* HAVE_GHOSTSCRIPT */
-#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_XPM) || defined (HAVE_NS)
Qxpm = intern ("xpm");
staticpro (&Qxpm);
ADD_IMAGE_TYPE (Qxpm);
#endif
-#if defined (HAVE_JPEG) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS)
Qjpeg = intern ("jpeg");
staticpro (&Qjpeg);
ADD_IMAGE_TYPE (Qjpeg);
#endif
-#if defined (HAVE_TIFF) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS)
Qtiff = intern ("tiff");
staticpro (&Qtiff);
ADD_IMAGE_TYPE (Qtiff);
#endif
-#if defined (HAVE_GIF) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_GIF) || defined (HAVE_NS)
Qgif = intern ("gif");
staticpro (&Qgif);
ADD_IMAGE_TYPE (Qgif);
#endif
-#if defined (HAVE_PNG) || defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_PNG) || defined (HAVE_NS)
Qpng = intern ("png");
staticpro (&Qpng);
ADD_IMAGE_TYPE (Qpng);
diff --git a/src/keyboard.c b/src/keyboard.c
index 716d1101aab..92ae3db087f 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -76,10 +76,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "w32term.h"
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
-
#ifdef HAVE_NS
#include "nsterm.h"
#endif
@@ -479,14 +475,11 @@ Lisp_Object Qmouse_fixup_help_message;
/* Symbols to denote kinds of events. */
Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
-#if defined (WINDOWSNT) || defined (MAC_OS)
+#if defined (WINDOWSNT)
Lisp_Object Qlanguage_change;
#endif
Lisp_Object Qdrag_n_drop;
Lisp_Object Qsave_session;
-#ifdef MAC_OS
-Lisp_Object Qmac_apple_event;
-#endif
#ifdef HAVE_DBUS
Lisp_Object Qdbus_event;
#endif
@@ -4149,7 +4142,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
#endif
}
-#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (HAVE_X11) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS)
else if (event->kind == DELETE_WINDOW_EVENT)
{
@@ -4159,7 +4152,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
kbd_fetch_ptr = event + 1;
}
#endif
-#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (HAVE_X11) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS)
else if (event->kind == ICONIFY_EVENT)
{
@@ -4182,7 +4175,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
XSETBUFFER (obj, current_buffer);
kbd_fetch_ptr = event + 1;
}
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined(HAVE_NS) || defined (USE_GTK)
else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
{
@@ -4192,16 +4185,11 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
x_activate_menubar (XFRAME (event->frame_or_window));
}
#endif
-#if defined (WINDOWSNT) || defined (MAC_OS)
+#if defined (WINDOWSNT)
else if (event->kind == LANGUAGE_CHANGE_EVENT)
{
-#ifdef MAC_OS
- /* Make an event (language-change (KEY_SCRIPT)). */
- obj = Fcons (make_number (event->code), Qnil);
-#else
/* Make an event (language-change (FRAME CHARSET LCID)). */
obj = Fcons (event->frame_or_window, Qnil);
-#endif
obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
kbd_fetch_ptr = event + 1;
}
@@ -4292,7 +4280,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
{
obj = make_lispy_event (event);
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined(HAVE_NS) || defined (USE_GTK)
/* If this was a menu selection, then set the flag to inhibit
writing to last_nonmenu_event. Don't do this if the event
@@ -6095,7 +6083,7 @@ make_lispy_event (event)
}
#endif /* HAVE_MOUSE */
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined(HAVE_NS) || defined (USE_GTK)
case MENU_BAR_EVENT:
if (EQ (event->arg, event->frame_or_window))
@@ -6134,19 +6122,6 @@ make_lispy_event (event)
case SAVE_SESSION_EVENT:
return Qsave_session;
-#ifdef MAC_OS
- case MAC_APPLE_EVENT:
- {
- Lisp_Object spec[2];
-
- spec[0] = event->x;
- spec[1] = event->y;
- return Fcons (Qmac_apple_event,
- Fcons (Fvector (2, spec),
- Fcons (event->arg, Qnil)));
- }
-#endif
-
#ifdef HAVE_DBUS
case DBUS_EVENT:
{
@@ -11767,7 +11742,7 @@ syms_of_keyboard ()
staticpro (&Qfunction_key);
Qmouse_click = intern ("mouse-click");
staticpro (&Qmouse_click);
-#if defined (WINDOWSNT) || defined (MAC_OS)
+#if defined (WINDOWSNT)
Qlanguage_change = intern ("language-change");
staticpro (&Qlanguage_change);
#endif
@@ -11777,11 +11752,6 @@ syms_of_keyboard ()
Qsave_session = intern ("save-session");
staticpro (&Qsave_session);
-#ifdef MAC_OS
- Qmac_apple_event = intern ("mac-apple-event");
- staticpro (&Qmac_apple_event);
-#endif
-
#ifdef HAVE_DBUS
Qdbus_event = intern ("dbus-event");
staticpro (&Qdbus_event);
diff --git a/src/lisp.h b/src/lisp.h
index 340a0352b6d..872a8c9d99f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -157,7 +157,7 @@ extern void die P_((const char *, const char *, int)) NO_RETURN;
#endif
/* Let's USE_LSB_TAG on systems where we know malloc returns mult-of-8. */
-#if defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ || defined MAC_OSX || defined(NS_IMPL_COCOA)
+#if defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ || defined(NS_IMPL_COCOA)
/* We also need to be able to specify mult-of-8 alignment on static vars. */
# if defined DECL_ALIGN
/* We currently do not support USE_LSB_TAG with a union Lisp_Object. */
@@ -3325,28 +3325,8 @@ extern void syms_of_xterm P_ ((void));
EXFUN (Fmsdos_downcase_filename, 1);
#endif
-#ifdef MAC_OS
-/* Defined in macfns.c */
-extern void syms_of_macfns P_ ((void));
-
-/* Defined in macselect.c */
-extern void syms_of_macselect P_ ((void));
-
-/* Defined in macterm.c */
-extern void syms_of_macterm P_ ((void));
-
-/* Defined in macmenu.c */
-extern void syms_of_macmenu P_ ((void));
-
-/* Defined in mac.c */
-extern void syms_of_mac P_ ((void));
-#ifdef MAC_OSX
-extern void init_mac_osx_environment P_ ((void));
-#endif /* MAC_OSX */
-#endif /* MAC_OS */
-
#ifdef HAVE_MENUS
-/* Defined in (x|mac|w32)fns.c... */
+/* Defined in (x|w32)fns.c... */
extern int have_menus_p P_ ((void));
#endif
diff --git a/src/lread.c b/src/lread.c
index 6ec8dff6cfd..872b6cfc2fc 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4095,15 +4095,11 @@ init_lread ()
}
#endif
-#if (!(defined(WINDOWSNT) || (defined(HAVE_CARBON)) || (defined(HAVE_NS))))
+#if (!(defined(WINDOWSNT) || (defined(HAVE_NS))))
/* When Emacs is invoked over network shares on NT, PATH_LOADSEARCH is
almost never correct, thereby causing a warning to be printed out that
confuses users. Since PATH_LOADSEARCH is always overridden by the
- EMACSLOADPATH environment variable below, disable the warning on NT.
- Also, when using the "self-contained" option for Carbon Emacs for MacOSX,
- the "standard" paths may not exist and would be overridden by
- EMACSLOADPATH as on NT. Since this depends on how the executable
- was build and packaged, turn off the warnings in general */
+ EMACSLOADPATH environment variable below, disable the warning on NT. */
/* Warn if dirs in the *standard* path don't exist. */
if (!turn_off_warning)
@@ -4125,7 +4121,7 @@ init_lread ()
}
}
}
-#endif /* !(WINDOWSNT || HAVE_CARBON || HAVE_NS) */
+#endif /* !(WINDOWSNT || HAVE_NS) */
/* If the EMACSLOADPATH environment variable is set, use its value.
This doesn't apply if we're dumping. */
diff --git a/src/m/intel386.h b/src/m/intel386.h
index 75ec5a301cf..a897184b35f 100644
--- a/src/m/intel386.h
+++ b/src/m/intel386.h
@@ -103,7 +103,7 @@ NOTE-END */
#define SEGMENT_MASK ((SEGMENT_SIZE)-1)
#endif
-#if defined (MAC_OSX) || defined (DARWIN)
+#if defined (DARWIN)
#ifdef _LP64
/* For Intel Mac, with CC='gcc -arch x86_64'. */
#define NO_ARG_ARRAY
diff --git a/src/mac.c b/src/mac.c
deleted file mode 100644
index 20872b2bdc9..00000000000
--- a/src/mac.c
+++ /dev/null
@@ -1,5477 +0,0 @@
-/* Unix emulation routines for GNU Emacs on the Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Contributed by Andrew Choi (akochoi@mac.com). */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "lisp.h"
-#include "process.h"
-#ifdef MAC_OSX
-#undef select
-#endif
-#include "systime.h"
-#include "sysselect.h"
-#include "blockinput.h"
-
-#include "macterm.h"
-
-#include "charset.h"
-#include "coding.h"
-#if !TARGET_API_MAC_CARBON
-#include <Files.h>
-#include <MacTypes.h>
-#include <TextUtils.h>
-#include <Folders.h>
-#include <Resources.h>
-#include <Aliases.h>
-#include <Timer.h>
-#include <OSA.h>
-#include <AppleScript.h>
-#include <Events.h>
-#include <Processes.h>
-#include <EPPC.h>
-#include <MacLocales.h>
-#include <Endian.h>
-#endif /* not TARGET_API_MAC_CARBON */
-
-#include <utime.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#if __MWERKS__
-#include <unistd.h>
-#endif
-
-/* The system script code. */
-static int mac_system_script_code;
-
-/* The system locale identifier string. */
-static Lisp_Object Vmac_system_locale;
-
-/* An instance of the AppleScript component. */
-static ComponentInstance as_scripting_component;
-/* The single script context used for all script executions. */
-static OSAID as_script_context;
-
-#ifndef MAC_OSX
-#if TARGET_API_MAC_CARBON
-static int wakeup_from_rne_enabled_p = 0;
-#define ENABLE_WAKEUP_FROM_RNE (wakeup_from_rne_enabled_p = 1)
-#define DISABLE_WAKEUP_FROM_RNE (wakeup_from_rne_enabled_p = 0)
-#else
-#define ENABLE_WAKEUP_FROM_RNE 0
-#define DISABLE_WAKEUP_FROM_RNE 0
-#endif
-#endif
-
-#ifndef MAC_OSX
-static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
-static OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int));
-#endif
-
-/* When converting from Mac to Unix pathnames, /'s in folder names are
- converted to :'s. This function, used in copying folder names,
- performs a strncat and converts all character a to b in the copy of
- the string s2 appended to the end of s1. */
-
-void
-string_cat_and_replace (char *s1, const char *s2, int n, char a, char b)
-{
- int l1 = strlen (s1);
- int l2 = strlen (s2);
- char *p = s1 + l1;
- int i;
-
- strncat (s1, s2, n);
- for (i = 0; i < l2; i++)
- {
- if (*p == a)
- *p = b;
- p++;
- }
-}
-
-
-/* Convert a Mac pathname to Posix form. A Mac full pathname is one
- that does not begin with a ':' and contains at least one ':'. A Mac
- full pathname causes a '/' to be prepended to the Posix pathname.
- The algorithm for the rest of the pathname is as follows:
- For each segment between two ':',
- if it is non-null, copy as is and then add a '/' at the end,
- otherwise, insert a "../" into the Posix pathname.
- Returns 1 if successful; 0 if fails. */
-
-int
-mac_to_posix_pathname (const char *mfn, char *ufn, int ufnbuflen)
-{
- const char *p, *q, *pe;
-
- strcpy (ufn, "");
-
- if (*mfn == '\0')
- return 1;
-
- p = strchr (mfn, ':');
- if (p != 0 && p != mfn) /* full pathname */
- strcat (ufn, "/");
-
- p = mfn;
- if (*p == ':')
- p++;
-
- pe = mfn + strlen (mfn);
- while (p < pe)
- {
- q = strchr (p, ':');
- if (q)
- {
- if (q == p)
- { /* two consecutive ':' */
- if (strlen (ufn) + 3 >= ufnbuflen)
- return 0;
- strcat (ufn, "../");
- }
- else
- {
- if (strlen (ufn) + (q - p) + 1 >= ufnbuflen)
- return 0;
- string_cat_and_replace (ufn, p, q - p, '/', ':');
- strcat (ufn, "/");
- }
- p = q + 1;
- }
- else
- {
- if (strlen (ufn) + (pe - p) >= ufnbuflen)
- return 0;
- string_cat_and_replace (ufn, p, pe - p, '/', ':');
- /* no separator for last one */
- p = pe;
- }
- }
-
- return 1;
-}
-
-
-extern char *get_temp_dir_name ();
-
-
-/* Convert a Posix pathname to Mac form. Approximately reverse of the
- above in algorithm. */
-
-int
-posix_to_mac_pathname (const char *ufn, char *mfn, int mfnbuflen)
-{
- const char *p, *q, *pe;
- char expanded_pathname[MAXPATHLEN+1];
-
- strcpy (mfn, "");
-
- if (*ufn == '\0')
- return 1;
-
- p = ufn;
-
- /* Check for and handle volume names. Last comparison: strangely
- somewhere "/.emacs" is passed. A temporary fix for now. */
- if (*p == '/' && strchr (p+1, '/') == NULL && strcmp (p, "/.emacs") != 0)
- {
- if (strlen (p) + 1 > mfnbuflen)
- return 0;
- strcpy (mfn, p+1);
- strcat (mfn, ":");
- return 1;
- }
-
- /* expand to emacs dir found by init_emacs_passwd_dir */
- if (strncmp (p, "~emacs/", 7) == 0)
- {
- struct passwd *pw = getpwnam ("emacs");
- p += 7;
- if (strlen (pw->pw_dir) + strlen (p) > MAXPATHLEN)
- return 0;
- strcpy (expanded_pathname, pw->pw_dir);
- strcat (expanded_pathname, p);
- p = expanded_pathname;
- /* now p points to the pathname with emacs dir prefix */
- }
- else if (strncmp (p, "/tmp/", 5) == 0)
- {
- char *t = get_temp_dir_name ();
- p += 5;
- if (strlen (t) + strlen (p) > MAXPATHLEN)
- return 0;
- strcpy (expanded_pathname, t);
- strcat (expanded_pathname, p);
- p = expanded_pathname;
- /* now p points to the pathname with emacs dir prefix */
- }
- else if (*p != '/') /* relative pathname */
- strcat (mfn, ":");
-
- if (*p == '/')
- p++;
-
- pe = p + strlen (p);
- while (p < pe)
- {
- q = strchr (p, '/');
- if (q)
- {
- if (q - p == 2 && *p == '.' && *(p+1) == '.')
- {
- if (strlen (mfn) + 1 >= mfnbuflen)
- return 0;
- strcat (mfn, ":");
- }
- else
- {
- if (strlen (mfn) + (q - p) + 1 >= mfnbuflen)
- return 0;
- string_cat_and_replace (mfn, p, q - p, ':', '/');
- strcat (mfn, ":");
- }
- p = q + 1;
- }
- else
- {
- if (strlen (mfn) + (pe - p) >= mfnbuflen)
- return 0;
- string_cat_and_replace (mfn, p, pe - p, ':', '/');
- p = pe;
- }
- }
-
- return 1;
-}
-
-
-/***********************************************************************
- Conversions on Apple event objects
- ***********************************************************************/
-
-static Lisp_Object Qundecoded_file_name;
-
-static struct {
- AEKeyword keyword;
- char *name;
- Lisp_Object symbol;
-} ae_attr_table [] =
- {{keyTransactionIDAttr, "transaction-id"},
- {keyReturnIDAttr, "return-id"},
- {keyEventClassAttr, "event-class"},
- {keyEventIDAttr, "event-id"},
- {keyAddressAttr, "address"},
- {keyOptionalKeywordAttr, "optional-keyword"},
- {keyTimeoutAttr, "timeout"},
- {keyInteractLevelAttr, "interact-level"},
- {keyEventSourceAttr, "event-source"},
- /* {keyMissedKeywordAttr, "missed-keyword"}, */
- {keyOriginalAddressAttr, "original-address"},
- {keyReplyRequestedAttr, "reply-requested"},
- {KEY_EMACS_SUSPENSION_ID_ATTR, "emacs-suspension-id"}
- };
-
-static Lisp_Object
-mac_aelist_to_lisp (desc_list)
- const AEDescList *desc_list;
-{
- OSErr err;
- long count;
- Lisp_Object result, elem;
- DescType desc_type;
- Size size;
- AEKeyword keyword;
- AEDesc desc;
- int attribute_p = 0;
-
- err = AECountItems (desc_list, &count);
- if (err != noErr)
- return Qnil;
- result = Qnil;
-
- again:
- while (count > 0)
- {
- if (attribute_p)
- {
- keyword = ae_attr_table[count - 1].keyword;
- err = AESizeOfAttribute (desc_list, keyword, &desc_type, &size);
- }
- else
- err = AESizeOfNthItem (desc_list, count, &desc_type, &size);
-
- if (err == noErr)
- switch (desc_type)
- {
- case typeAEList:
- case typeAERecord:
- case typeAppleEvent:
- if (attribute_p)
- err = AEGetAttributeDesc (desc_list, keyword, typeWildCard,
- &desc);
- else
- err = AEGetNthDesc (desc_list, count, typeWildCard,
- &keyword, &desc);
- if (err != noErr)
- break;
- elem = mac_aelist_to_lisp (&desc);
- AEDisposeDesc (&desc);
- break;
-
- default:
- if (desc_type == typeNull)
- elem = Qnil;
- else
- {
- elem = make_uninit_string (size);
- if (attribute_p)
- err = AEGetAttributePtr (desc_list, keyword, typeWildCard,
- &desc_type, SDATA (elem),
- size, &size);
- else
- err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword,
- &desc_type, SDATA (elem), size, &size);
- }
- if (err != noErr)
- break;
- desc_type = EndianU32_NtoB (desc_type);
- elem = Fcons (make_unibyte_string ((char *) &desc_type, 4), elem);
- break;
- }
-
- if (err == noErr || desc_list->descriptorType == typeAEList)
- {
- if (err != noErr)
- elem = Qnil; /* Don't skip elements in AEList. */
- else if (desc_list->descriptorType != typeAEList)
- {
- if (attribute_p)
- elem = Fcons (ae_attr_table[count-1].symbol, elem);
- else
- {
- keyword = EndianU32_NtoB (keyword);
- elem = Fcons (make_unibyte_string ((char *) &keyword, 4),
- elem);
- }
- }
-
- result = Fcons (elem, result);
- }
-
- count--;
- }
-
- if (desc_list->descriptorType == typeAppleEvent && !attribute_p)
- {
- attribute_p = 1;
- count = sizeof (ae_attr_table) / sizeof (ae_attr_table[0]);
- goto again;
- }
-
- desc_type = EndianU32_NtoB (desc_list->descriptorType);
- return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
-}
-
-Lisp_Object
-mac_aedesc_to_lisp (desc)
- const AEDesc *desc;
-{
- OSErr err = noErr;
- DescType desc_type = desc->descriptorType;
- Lisp_Object result;
-
- switch (desc_type)
- {
- case typeNull:
- result = Qnil;
- break;
-
- case typeAEList:
- case typeAERecord:
- case typeAppleEvent:
- return mac_aelist_to_lisp (desc);
-#if 0
- /* The following one is much simpler, but creates and disposes
- of Apple event descriptors many times. */
- {
- long count;
- Lisp_Object elem;
- AEKeyword keyword;
- AEDesc desc1;
-
- err = AECountItems (desc, &count);
- if (err != noErr)
- break;
- result = Qnil;
- while (count > 0)
- {
- err = AEGetNthDesc (desc, count, typeWildCard, &keyword, &desc1);
- if (err != noErr)
- break;
- elem = mac_aedesc_to_lisp (&desc1);
- AEDisposeDesc (&desc1);
- if (desc_type != typeAEList)
- {
- keyword = EndianU32_NtoB (keyword);
- elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem);
- }
- result = Fcons (elem, result);
- count--;
- }
- }
-#endif
- break;
-
- default:
-#if TARGET_API_MAC_CARBON
- result = make_uninit_string (AEGetDescDataSize (desc));
- err = AEGetDescData (desc, SDATA (result), SBYTES (result));
-#else
- result = make_uninit_string (GetHandleSize (desc->dataHandle));
- memcpy (SDATA (result), *(desc->dataHandle), SBYTES (result));
-#endif
- break;
- }
-
- if (err != noErr)
- return Qnil;
-
- desc_type = EndianU32_NtoB (desc_type);
- return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
-}
-
-OSErr
-mac_ae_put_lisp (desc, keyword_or_index, obj)
- AEDescList *desc;
- UInt32 keyword_or_index;
- Lisp_Object obj;
-{
- OSErr err;
-
- if (!(desc->descriptorType == typeAppleEvent
- || desc->descriptorType == typeAERecord
- || desc->descriptorType == typeAEList))
- return errAEWrongDataType;
-
- if (CONSP (obj) && STRINGP (XCAR (obj)) && SBYTES (XCAR (obj)) == 4)
- {
- DescType desc_type1 = EndianU32_BtoN (*((UInt32 *) SDATA (XCAR (obj))));
- Lisp_Object data = XCDR (obj), rest;
- AEDesc desc1;
-
- switch (desc_type1)
- {
- case typeNull:
- case typeAppleEvent:
- break;
-
- case typeAEList:
- case typeAERecord:
- err = AECreateList (NULL, 0, desc_type1 == typeAERecord, &desc1);
- if (err == noErr)
- {
- for (rest = data; CONSP (rest); rest = XCDR (rest))
- {
- UInt32 keyword_or_index1 = 0;
- Lisp_Object elem = XCAR (rest);
-
- if (desc_type1 == typeAERecord)
- {
- if (CONSP (elem) && STRINGP (XCAR (elem))
- && SBYTES (XCAR (elem)) == 4)
- {
- keyword_or_index1 =
- EndianU32_BtoN (*((UInt32 *)
- SDATA (XCAR (elem))));
- elem = XCDR (elem);
- }
- else
- continue;
- }
-
- err = mac_ae_put_lisp (&desc1, keyword_or_index1, elem);
- if (err != noErr)
- break;
- }
-
- if (err == noErr)
- {
- if (desc->descriptorType == typeAEList)
- err = AEPutDesc (desc, keyword_or_index, &desc1);
- else
- err = AEPutParamDesc (desc, keyword_or_index, &desc1);
- }
-
- AEDisposeDesc (&desc1);
- }
- return err;
-
- default:
- if (!STRINGP (data))
- break;
- if (desc->descriptorType == typeAEList)
- err = AEPutPtr (desc, keyword_or_index, desc_type1,
- SDATA (data), SBYTES (data));
- else
- err = AEPutParamPtr (desc, keyword_or_index, desc_type1,
- SDATA (data), SBYTES (data));
- return err;
- }
- }
-
- if (desc->descriptorType == typeAEList)
- err = AEPutPtr (desc, keyword_or_index, typeNull, NULL, 0);
- else
- err = AEPutParamPtr (desc, keyword_or_index, typeNull, NULL, 0);
-
- return err;
-}
-
-static pascal OSErr
-mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
- to_type, handler_refcon, result)
- DescType type_code;
- const void *data_ptr;
- Size data_size;
- DescType to_type;
- long handler_refcon;
- AEDesc *result;
-{
- OSErr err;
-
- if (type_code == typeNull)
- err = errAECoercionFail;
- else if (type_code == to_type || to_type == typeWildCard)
- err = AECreateDesc (TYPE_FILE_NAME, data_ptr, data_size, result);
- else if (type_code == TYPE_FILE_NAME)
- /* Coercion from undecoded file name. */
- {
-#ifdef MAC_OSX
- CFStringRef str;
- CFURLRef url = NULL;
- CFDataRef data = NULL;
-
- str = CFStringCreateWithBytes (NULL, data_ptr, data_size,
- kCFStringEncodingUTF8, false);
- if (str)
- {
- url = CFURLCreateWithFileSystemPath (NULL, str,
- kCFURLPOSIXPathStyle, false);
- CFRelease (str);
- }
- if (url)
- {
- data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
- CFRelease (url);
- }
- if (data)
- {
- err = AECoercePtr (typeFileURL, CFDataGetBytePtr (data),
- CFDataGetLength (data), to_type, result);
- CFRelease (data);
- }
- else
- err = memFullErr;
-
- if (err != noErr)
- {
- /* Just to be paranoid ... */
- FSRef fref;
- char *buf;
-
- buf = xmalloc (data_size + 1);
- memcpy (buf, data_ptr, data_size);
- buf[data_size] = '\0';
- err = FSPathMakeRef (buf, &fref, NULL);
- xfree (buf);
- if (err == noErr)
- err = AECoercePtr (typeFSRef, &fref, sizeof (FSRef),
- to_type, result);
- }
-#else
- FSSpec fs;
- char *buf;
-
- buf = xmalloc (data_size + 1);
- memcpy (buf, data_ptr, data_size);
- buf[data_size] = '\0';
- err = posix_pathname_to_fsspec (buf, &fs);
- xfree (buf);
- if (err == noErr)
- err = AECoercePtr (typeFSS, &fs, sizeof (FSSpec), to_type, result);
-#endif
- }
- else if (to_type == TYPE_FILE_NAME)
- /* Coercion to undecoded file name. */
- {
-#ifdef MAC_OSX
- CFURLRef url = NULL;
- CFStringRef str = NULL;
- CFDataRef data = NULL;
-
- if (type_code == typeFileURL)
- url = CFURLCreateWithBytes (NULL, data_ptr, data_size,
- kCFStringEncodingUTF8, NULL);
- else
- {
- AEDesc desc;
- Size size;
- char *buf;
-
- err = AECoercePtr (type_code, data_ptr, data_size,
- typeFileURL, &desc);
- if (err == noErr)
- {
- size = AEGetDescDataSize (&desc);
- buf = xmalloc (size);
- err = AEGetDescData (&desc, buf, size);
- if (err == noErr)
- url = CFURLCreateWithBytes (NULL, buf, size,
- kCFStringEncodingUTF8, NULL);
- xfree (buf);
- AEDisposeDesc (&desc);
- }
- }
- if (url)
- {
- str = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle);
- CFRelease (url);
- }
- if (str)
- {
- data = CFStringCreateExternalRepresentation (NULL, str,
- kCFStringEncodingUTF8,
- '\0');
- CFRelease (str);
- }
- if (data)
- {
- err = AECreateDesc (TYPE_FILE_NAME, CFDataGetBytePtr (data),
- CFDataGetLength (data), result);
- CFRelease (data);
- }
-
- if (err != noErr)
- {
- /* Coercion from typeAlias to typeFileURL fails on Mac OS X
- 10.2. In such cases, try typeFSRef as a target type. */
- char file_name[MAXPATHLEN];
-
- if (type_code == typeFSRef && data_size == sizeof (FSRef))
- err = FSRefMakePath (data_ptr, file_name, sizeof (file_name));
- else
- {
- AEDesc desc;
- FSRef fref;
-
- err = AECoercePtr (type_code, data_ptr, data_size,
- typeFSRef, &desc);
- if (err == noErr)
- {
- err = AEGetDescData (&desc, &fref, sizeof (FSRef));
- AEDisposeDesc (&desc);
- }
- if (err == noErr)
- err = FSRefMakePath (&fref, file_name, sizeof (file_name));
- }
- if (err == noErr)
- err = AECreateDesc (TYPE_FILE_NAME, file_name,
- strlen (file_name), result);
- }
-#else
- char file_name[MAXPATHLEN];
-
- if (type_code == typeFSS && data_size == sizeof (FSSpec))
- err = fsspec_to_posix_pathname (data_ptr, file_name,
- sizeof (file_name) - 1);
- else
- {
- AEDesc desc;
- FSSpec fs;
-
- err = AECoercePtr (type_code, data_ptr, data_size, typeFSS, &desc);
- if (err == noErr)
- {
-#if TARGET_API_MAC_CARBON
- err = AEGetDescData (&desc, &fs, sizeof (FSSpec));
-#else
- fs = *(FSSpec *)(*(desc.dataHandle));
-#endif
- AEDisposeDesc (&desc);
- }
- if (err == noErr)
- err = fsspec_to_posix_pathname (&fs, file_name,
- sizeof (file_name) - 1);
- }
- if (err == noErr)
- err = AECreateDesc (TYPE_FILE_NAME, file_name,
- strlen (file_name), result);
-#endif
- }
- else
- abort ();
-
- if (err != noErr)
- return errAECoercionFail;
- return noErr;
-}
-
-static pascal OSErr
-mac_coerce_file_name_desc (from_desc, to_type, handler_refcon, result)
- const AEDesc *from_desc;
- DescType to_type;
- long handler_refcon;
- AEDesc *result;
-{
- OSErr err = noErr;
- DescType from_type = from_desc->descriptorType;
-
- if (from_type == typeNull)
- err = errAECoercionFail;
- else if (from_type == to_type || to_type == typeWildCard)
- err = AEDuplicateDesc (from_desc, result);
- else
- {
- char *data_ptr;
- Size data_size;
-
-#if TARGET_API_MAC_CARBON
- data_size = AEGetDescDataSize (from_desc);
-#else
- data_size = GetHandleSize (from_desc->dataHandle);
-#endif
- data_ptr = xmalloc (data_size);
-#if TARGET_API_MAC_CARBON
- err = AEGetDescData (from_desc, data_ptr, data_size);
-#else
- memcpy (data_ptr, *(from_desc->dataHandle), data_size);
-#endif
- if (err == noErr)
- err = mac_coerce_file_name_ptr (from_type, data_ptr,
- data_size, to_type,
- handler_refcon, result);
- xfree (data_ptr);
- }
-
- if (err != noErr)
- return errAECoercionFail;
- return noErr;
-}
-
-OSErr
-init_coercion_handler ()
-{
- OSErr err;
-
- static AECoercePtrUPP coerce_file_name_ptrUPP = NULL;
- static AECoerceDescUPP coerce_file_name_descUPP = NULL;
-
- if (coerce_file_name_ptrUPP == NULL)
- {
- coerce_file_name_ptrUPP = NewAECoercePtrUPP (mac_coerce_file_name_ptr);
- coerce_file_name_descUPP = NewAECoerceDescUPP (mac_coerce_file_name_desc);
- }
-
- err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
- (AECoercionHandlerUPP)
- coerce_file_name_ptrUPP, 0, false, false);
- if (err == noErr)
- err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
- (AECoercionHandlerUPP)
- coerce_file_name_ptrUPP, 0, false, false);
- if (err == noErr)
- err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
- coerce_file_name_descUPP, 0, true, false);
- if (err == noErr)
- err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
- coerce_file_name_descUPP, 0, true, false);
- return err;
-}
-
-#if TARGET_API_MAC_CARBON
-OSErr
-create_apple_event (class, id, result)
- AEEventClass class;
- AEEventID id;
- AppleEvent *result;
-{
- OSErr err;
- static const ProcessSerialNumber psn = {0, kCurrentProcess};
- AEAddressDesc address_desc;
-
- err = AECreateDesc (typeProcessSerialNumber, &psn,
- sizeof (ProcessSerialNumber), &address_desc);
- if (err == noErr)
- {
- err = AECreateAppleEvent (class, id,
- &address_desc, /* NULL is not allowed
- on Mac OS Classic. */
- kAutoGenerateReturnID,
- kAnyTransactionID, result);
- AEDisposeDesc (&address_desc);
- }
-
- return err;
-}
-
-Lisp_Object
-mac_event_parameters_to_lisp (event, num_params, names, types)
- EventRef event;
- UInt32 num_params;
- const EventParamName *names;
- const EventParamType *types;
-{
- OSStatus err;
- Lisp_Object result = Qnil;
- UInt32 i;
- ByteCount size;
-#ifdef MAC_OSX
- CFStringRef string;
- CFDataRef data;
-#endif
- char *buf = NULL;
-
- for (i = 0; i < num_params; i++)
- {
- EventParamName name = names[i];
- EventParamType type = types[i];
-
- switch (type)
- {
-#ifdef MAC_OSX
- case typeCFStringRef:
- err = GetEventParameter (event, name, typeCFStringRef, NULL,
- sizeof (CFStringRef), NULL, &string);
- if (err != noErr)
- break;
- data = CFStringCreateExternalRepresentation (NULL, string,
- kCFStringEncodingUTF8,
- '?');
- if (data == NULL)
- break;
- name = EndianU32_NtoB (name);
- type = EndianU32_NtoB (typeUTF8Text);
- result =
- Fcons (Fcons (make_unibyte_string ((char *) &name, 4),
- Fcons (make_unibyte_string ((char *) &type, 4),
- make_unibyte_string (CFDataGetBytePtr (data),
- CFDataGetLength (data)))),
- result);
- CFRelease (data);
- break;
-#endif
-
- default:
- err = GetEventParameter (event, name, type, NULL, 0, &size, NULL);
- if (err != noErr)
- break;
- buf = xrealloc (buf, size);
- err = GetEventParameter (event, name, type, NULL, size, NULL, buf);
- if (err == noErr)
- {
- name = EndianU32_NtoB (name);
- type = EndianU32_NtoB (type);
- result =
- Fcons (Fcons (make_unibyte_string ((char *) &name, 4),
- Fcons (make_unibyte_string ((char *) &type, 4),
- make_unibyte_string (buf, size))),
- result);
- }
- break;
- }
- }
- xfree (buf);
-
- return result;
-}
-#endif /* TARGET_API_MAC_CARBON */
-
-/***********************************************************************
- Conversion between Lisp and Core Foundation objects
- ***********************************************************************/
-
-#if TARGET_API_MAC_CARBON
-static Lisp_Object Qstring, Qnumber, Qboolean, Qdate, Qdata;
-static Lisp_Object Qarray, Qdictionary;
-
-struct cfdict_context
-{
- Lisp_Object *result;
- int with_tag, hash_bound;
-};
-
-/* C string to CFString. */
-
-CFStringRef
-cfstring_create_with_utf8_cstring (c_str)
- const char *c_str;
-{
- CFStringRef str;
-
- str = CFStringCreateWithCString (NULL, c_str, kCFStringEncodingUTF8);
- if (str == NULL)
- /* Failed to interpret as UTF 8. Fall back on Mac Roman. */
- str = CFStringCreateWithCString (NULL, c_str, kCFStringEncodingMacRoman);
-
- return str;
-}
-
-
-/* Lisp string to CFString. */
-
-CFStringRef
-cfstring_create_with_string (s)
- Lisp_Object s;
-{
- CFStringRef string = NULL;
-
- if (STRING_MULTIBYTE (s))
- {
- char *p, *end = SDATA (s) + SBYTES (s);
-
- for (p = SDATA (s); p < end; p++)
- if (!isascii (*p))
- {
- s = ENCODE_UTF_8 (s);
- break;
- }
- string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s),
- kCFStringEncodingUTF8, false);
- }
-
- if (string == NULL)
- /* Failed to interpret as UTF 8. Fall back on Mac Roman. */
- string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s),
- kCFStringEncodingMacRoman, false);
-
- return string;
-}
-
-
-/* From CFData to a lisp string. Always returns a unibyte string. */
-
-Lisp_Object
-cfdata_to_lisp (data)
- CFDataRef data;
-{
- CFIndex len = CFDataGetLength (data);
- Lisp_Object result = make_uninit_string (len);
-
- CFDataGetBytes (data, CFRangeMake (0, len), SDATA (result));
-
- return result;
-}
-
-
-/* From CFString to a lisp string. Returns a unibyte string
- containing a UTF-8 byte sequence. */
-
-Lisp_Object
-cfstring_to_lisp_nodecode (string)
- CFStringRef string;
-{
- Lisp_Object result = Qnil;
- const char *s = CFStringGetCStringPtr (string, kCFStringEncodingUTF8);
-
- if (s)
- result = make_unibyte_string (s, strlen (s));
- else
- {
- CFDataRef data =
- CFStringCreateExternalRepresentation (NULL, string,
- kCFStringEncodingUTF8, '?');
-
- if (data)
- {
- result = cfdata_to_lisp (data);
- CFRelease (data);
- }
- }
-
- return result;
-}
-
-
-/* From CFString to a lisp string. Never returns a unibyte string
- (even if it only contains ASCII characters).
- This may cause GC during code conversion. */
-
-Lisp_Object
-cfstring_to_lisp (string)
- CFStringRef string;
-{
- Lisp_Object result = cfstring_to_lisp_nodecode (string);
-
- if (!NILP (result))
- {
- result = code_convert_string_norecord (result, Qutf_8, 0);
- /* This may be superfluous. Just to make sure that the result
- is a multibyte string. */
- result = string_to_multibyte (result);
- }
-
- return result;
-}
-
-
-/* CFNumber to a lisp integer or a lisp float. */
-
-Lisp_Object
-cfnumber_to_lisp (number)
- CFNumberRef number;
-{
- Lisp_Object result = Qnil;
-#if BITS_PER_EMACS_INT > 32
- SInt64 int_val;
- CFNumberType emacs_int_type = kCFNumberSInt64Type;
-#else
- SInt32 int_val;
- CFNumberType emacs_int_type = kCFNumberSInt32Type;
-#endif
- double float_val;
-
- if (CFNumberGetValue (number, emacs_int_type, &int_val)
- && !FIXNUM_OVERFLOW_P (int_val))
- result = make_number (int_val);
- else
- if (CFNumberGetValue (number, kCFNumberDoubleType, &float_val))
- result = make_float (float_val);
- return result;
-}
-
-
-/* CFDate to a list of three integers as in a return value of
- `current-time'. */
-
-Lisp_Object
-cfdate_to_lisp (date)
- CFDateRef date;
-{
- CFTimeInterval sec;
- int high, low, microsec;
-
- sec = CFDateGetAbsoluteTime (date) + kCFAbsoluteTimeIntervalSince1970;
- high = sec / 65536.0;
- low = sec - high * 65536.0;
- microsec = (sec - floor (sec)) * 1000000.0;
-
- return list3 (make_number (high), make_number (low), make_number (microsec));
-}
-
-
-/* CFBoolean to a lisp symbol, `t' or `nil'. */
-
-Lisp_Object
-cfboolean_to_lisp (boolean)
- CFBooleanRef boolean;
-{
- return CFBooleanGetValue (boolean) ? Qt : Qnil;
-}
-
-
-/* Any Core Foundation object to a (lengthy) lisp string. */
-
-Lisp_Object
-cfobject_desc_to_lisp (object)
- CFTypeRef object;
-{
- Lisp_Object result = Qnil;
- CFStringRef desc = CFCopyDescription (object);
-
- if (desc)
- {
- result = cfstring_to_lisp (desc);
- CFRelease (desc);
- }
-
- return result;
-}
-
-
-/* Callback functions for cfproperty_list_to_lisp. */
-
-static void
-cfdictionary_add_to_list (key, value, context)
- const void *key;
- const void *value;
- void *context;
-{
- struct cfdict_context *cxt = (struct cfdict_context *)context;
-
- *cxt->result =
- Fcons (Fcons (cfstring_to_lisp (key),
- cfproperty_list_to_lisp (value, cxt->with_tag,
- cxt->hash_bound)),
- *cxt->result);
-}
-
-static void
-cfdictionary_puthash (key, value, context)
- const void *key;
- const void *value;
- void *context;
-{
- Lisp_Object lisp_key = cfstring_to_lisp (key);
- struct cfdict_context *cxt = (struct cfdict_context *)context;
- struct Lisp_Hash_Table *h = XHASH_TABLE (*(cxt->result));
- unsigned hash_code;
-
- hash_lookup (h, lisp_key, &hash_code);
- hash_put (h, lisp_key,
- cfproperty_list_to_lisp (value, cxt->with_tag, cxt->hash_bound),
- hash_code);
-}
-
-
-/* Convert CFPropertyList PLIST to a lisp object. If WITH_TAG is
- non-zero, a symbol that represents the type of the original Core
- Foundation object is prepended. HASH_BOUND specifies which kinds
- of the lisp objects, alists or hash tables, are used as the targets
- of the conversion from CFDictionary. If HASH_BOUND is negative,
- always generate alists. If HASH_BOUND >= 0, generate an alist if
- the number of keys in the dictionary is smaller than HASH_BOUND,
- and a hash table otherwise. */
-
-Lisp_Object
-cfproperty_list_to_lisp (plist, with_tag, hash_bound)
- CFPropertyListRef plist;
- int with_tag, hash_bound;
-{
- CFTypeID type_id = CFGetTypeID (plist);
- Lisp_Object tag = Qnil, result = Qnil;
- struct gcpro gcpro1, gcpro2;
-
- GCPRO2 (tag, result);
-
- if (type_id == CFStringGetTypeID ())
- {
- tag = Qstring;
- result = cfstring_to_lisp (plist);
- }
- else if (type_id == CFNumberGetTypeID ())
- {
- tag = Qnumber;
- result = cfnumber_to_lisp (plist);
- }
- else if (type_id == CFBooleanGetTypeID ())
- {
- tag = Qboolean;
- result = cfboolean_to_lisp (plist);
- }
- else if (type_id == CFDateGetTypeID ())
- {
- tag = Qdate;
- result = cfdate_to_lisp (plist);
- }
- else if (type_id == CFDataGetTypeID ())
- {
- tag = Qdata;
- result = cfdata_to_lisp (plist);
- }
- else if (type_id == CFArrayGetTypeID ())
- {
- CFIndex index, count = CFArrayGetCount (plist);
-
- tag = Qarray;
- result = Fmake_vector (make_number (count), Qnil);
- for (index = 0; index < count; index++)
- XVECTOR (result)->contents[index] =
- cfproperty_list_to_lisp (CFArrayGetValueAtIndex (plist, index),
- with_tag, hash_bound);
- }
- else if (type_id == CFDictionaryGetTypeID ())
- {
- struct cfdict_context context;
- CFIndex count = CFDictionaryGetCount (plist);
-
- tag = Qdictionary;
- context.result = &result;
- context.with_tag = with_tag;
- context.hash_bound = hash_bound;
- if (hash_bound < 0 || count < hash_bound)
- {
- result = Qnil;
- CFDictionaryApplyFunction (plist, cfdictionary_add_to_list,
- &context);
- }
- else
- {
- result = make_hash_table (Qequal,
- make_number (count),
- make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil, Qnil);
- CFDictionaryApplyFunction (plist, cfdictionary_puthash,
- &context);
- }
- }
- else
- abort ();
-
- UNGCPRO;
-
- if (with_tag)
- result = Fcons (tag, result);
-
- return result;
-}
-#endif
-
-
-/***********************************************************************
- Emulation of the X Resource Manager
- ***********************************************************************/
-
-/* Parser functions for resource lines. Each function takes an
- address of a variable whose value points to the head of a string.
- The value will be advanced so that it points to the next character
- of the parsed part when the function returns.
-
- A resource name such as "Emacs*font" is parsed into a non-empty
- list called `quarks'. Each element is either a Lisp string that
- represents a concrete component, a Lisp symbol LOOSE_BINDING
- (actually Qlambda) that represents any number (>=0) of intervening
- components, or a Lisp symbol SINGLE_COMPONENT (actually Qquote)
- that represents as any single component. */
-
-#define P (*p)
-
-#define LOOSE_BINDING Qlambda /* '*' ("L"oose) */
-#define SINGLE_COMPONENT Qquote /* '?' ("Q"uestion) */
-
-static void
-skip_white_space (p)
- const char **p;
-{
- /* WhiteSpace = {<space> | <horizontal tab>} */
- while (*P == ' ' || *P == '\t')
- P++;
-}
-
-static int
-parse_comment (p)
- const char **p;
-{
- /* Comment = "!" {<any character except null or newline>} */
- if (*P == '!')
- {
- P++;
- while (*P)
- if (*P++ == '\n')
- break;
- return 1;
- }
- else
- return 0;
-}
-
-/* Don't interpret filename. Just skip until the newline. */
-static int
-parse_include_file (p)
- const char **p;
-{
- /* IncludeFile = "#" WhiteSpace "include" WhiteSpace FileName WhiteSpace */
- if (*P == '#')
- {
- P++;
- while (*P)
- if (*P++ == '\n')
- break;
- return 1;
- }
- else
- return 0;
-}
-
-static char
-parse_binding (p)
- const char **p;
-{
- /* Binding = "." | "*" */
- if (*P == '.' || *P == '*')
- {
- char binding = *P++;
-
- while (*P == '.' || *P == '*')
- if (*P++ == '*')
- binding = '*';
- return binding;
- }
- else
- return '\0';
-}
-
-static Lisp_Object
-parse_component (p)
- const char **p;
-{
- /* Component = "?" | ComponentName
- ComponentName = NameChar {NameChar}
- NameChar = "a"-"z" | "A"-"Z" | "0"-"9" | "_" | "-" */
- if (*P == '?')
- {
- P++;
- return SINGLE_COMPONENT;
- }
- else if (isalnum (*P) || *P == '_' || *P == '-')
- {
- const char *start = P++;
-
- while (isalnum (*P) || *P == '_' || *P == '-')
- P++;
-
- return make_unibyte_string (start, P - start);
- }
- else
- return Qnil;
-}
-
-static Lisp_Object
-parse_resource_name (p)
- const char **p;
-{
- Lisp_Object result = Qnil, component;
- char binding;
-
- /* ResourceName = [Binding] {Component Binding} ComponentName */
- if (parse_binding (p) == '*')
- result = Fcons (LOOSE_BINDING, result);
-
- component = parse_component (p);
- if (NILP (component))
- return Qnil;
-
- result = Fcons (component, result);
- while ((binding = parse_binding (p)) != '\0')
- {
- if (binding == '*')
- result = Fcons (LOOSE_BINDING, result);
- component = parse_component (p);
- if (NILP (component))
- return Qnil;
- else
- result = Fcons (component, result);
- }
-
- /* The final component should not be '?'. */
- if (EQ (component, SINGLE_COMPONENT))
- return Qnil;
-
- return Fnreverse (result);
-}
-
-static Lisp_Object
-parse_value (p)
- const char **p;
-{
- char *q, *buf;
- Lisp_Object seq = Qnil, result;
- int buf_len, total_len = 0, len, continue_p;
-
- q = strchr (P, '\n');
- buf_len = q ? q - P : strlen (P);
- buf = xmalloc (buf_len);
-
- while (1)
- {
- q = buf;
- continue_p = 0;
- while (*P)
- {
- if (*P == '\n')
- {
- P++;
- break;
- }
- else if (*P == '\\')
- {
- P++;
- if (*P == '\0')
- break;
- else if (*P == '\n')
- {
- P++;
- continue_p = 1;
- break;
- }
- else if (*P == 'n')
- {
- *q++ = '\n';
- P++;
- }
- else if ('0' <= P[0] && P[0] <= '7'
- && '0' <= P[1] && P[1] <= '7'
- && '0' <= P[2] && P[2] <= '7')
- {
- *q++ = ((P[0] - '0') << 6) + ((P[1] - '0') << 3) + (P[2] - '0');
- P += 3;
- }
- else
- *q++ = *P++;
- }
- else
- *q++ = *P++;
- }
- len = q - buf;
- seq = Fcons (make_unibyte_string (buf, len), seq);
- total_len += len;
-
- if (continue_p)
- {
- q = strchr (P, '\n');
- len = q ? q - P : strlen (P);
- if (len > buf_len)
- {
- xfree (buf);
- buf_len = len;
- buf = xmalloc (buf_len);
- }
- }
- else
- break;
- }
- xfree (buf);
-
- if (SBYTES (XCAR (seq)) == total_len)
- return make_string (SDATA (XCAR (seq)), total_len);
- else
- {
- buf = xmalloc (total_len);
- q = buf + total_len;
- for (; CONSP (seq); seq = XCDR (seq))
- {
- len = SBYTES (XCAR (seq));
- q -= len;
- memcpy (q, SDATA (XCAR (seq)), len);
- }
- result = make_string (buf, total_len);
- xfree (buf);
- return result;
- }
-}
-
-static Lisp_Object
-parse_resource_line (p)
- const char **p;
-{
- Lisp_Object quarks, value;
-
- /* ResourceLine = Comment | IncludeFile | ResourceSpec | <empty line> */
- if (parse_comment (p) || parse_include_file (p))
- return Qnil;
-
- /* ResourceSpec = WhiteSpace ResourceName WhiteSpace ":" WhiteSpace Value */
- skip_white_space (p);
- quarks = parse_resource_name (p);
- if (NILP (quarks))
- goto cleanup;
- skip_white_space (p);
- if (*P != ':')
- goto cleanup;
- P++;
- skip_white_space (p);
- value = parse_value (p);
- return Fcons (quarks, value);
-
- cleanup:
- /* Skip the remaining data as a dummy value. */
- parse_value (p);
- return Qnil;
-}
-
-#undef P
-
-/* Equivalents of X Resource Manager functions.
-
- An X Resource Database acts as a collection of resource names and
- associated values. It is implemented as a trie on quarks. Namely,
- each edge is labeled by either a string, LOOSE_BINDING, or
- SINGLE_COMPONENT. Each node has a node id, which is a unique
- nonnegative integer, and the root node id is 0. A database is
- implemented as a hash table that maps a pair (SRC-NODE-ID .
- EDGE-LABEL) to DEST-NODE-ID. It also holds a maximum node id used
- in the table as a value for HASHKEY_MAX_NID. A value associated to
- a node is recorded as a value for the node id.
-
- A database also has a cache for past queries as a value for
- HASHKEY_QUERY_CACHE. It is another hash table that maps
- "NAME-STRING\0CLASS-STRING" to the result of the query. */
-
-#define HASHKEY_MAX_NID (make_number (0))
-#define HASHKEY_QUERY_CACHE (make_number (-1))
-
-static XrmDatabase
-xrm_create_database ()
-{
- XrmDatabase database;
-
- database = make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
- make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil, Qnil);
- Fputhash (HASHKEY_MAX_NID, make_number (0), database);
- Fputhash (HASHKEY_QUERY_CACHE, Qnil, database);
-
- return database;
-}
-
-static void
-xrm_q_put_resource (database, quarks, value)
- XrmDatabase database;
- Lisp_Object quarks, value;
-{
- struct Lisp_Hash_Table *h = XHASH_TABLE (database);
- unsigned hash_code;
- int max_nid, i;
- Lisp_Object node_id, key;
-
- max_nid = XINT (Fgethash (HASHKEY_MAX_NID, database, Qnil));
-
- XSETINT (node_id, 0);
- for (; CONSP (quarks); quarks = XCDR (quarks))
- {
- key = Fcons (node_id, XCAR (quarks));
- i = hash_lookup (h, key, &hash_code);
- if (i < 0)
- {
- max_nid++;
- XSETINT (node_id, max_nid);
- hash_put (h, key, node_id, hash_code);
- }
- else
- node_id = HASH_VALUE (h, i);
- }
- Fputhash (node_id, value, database);
-
- Fputhash (HASHKEY_MAX_NID, make_number (max_nid), database);
- Fputhash (HASHKEY_QUERY_CACHE, Qnil, database);
-}
-
-/* Merge multiple resource entries specified by DATA into a resource
- database DATABASE. DATA points to the head of a null-terminated
- string consisting of multiple resource lines. It's like a
- combination of XrmGetStringDatabase and XrmMergeDatabases. */
-
-void
-xrm_merge_string_database (database, data)
- XrmDatabase database;
- const char *data;
-{
- Lisp_Object quarks_value;
-
- while (*data)
- {
- quarks_value = parse_resource_line (&data);
- if (!NILP (quarks_value))
- xrm_q_put_resource (database,
- XCAR (quarks_value), XCDR (quarks_value));
- }
-}
-
-static Lisp_Object
-xrm_q_get_resource_1 (database, node_id, quark_name, quark_class)
- XrmDatabase database;
- Lisp_Object node_id, quark_name, quark_class;
-{
- struct Lisp_Hash_Table *h = XHASH_TABLE (database);
- Lisp_Object key, labels[3], value;
- int i, k;
-
- if (!CONSP (quark_name))
- return Fgethash (node_id, database, Qnil);
-
- /* First, try tight bindings */
- labels[0] = XCAR (quark_name);
- labels[1] = XCAR (quark_class);
- labels[2] = SINGLE_COMPONENT;
-
- key = Fcons (node_id, Qnil);
- for (k = 0; k < sizeof (labels) / sizeof (*labels); k++)
- {
- XSETCDR (key, labels[k]);
- i = hash_lookup (h, key, NULL);
- if (i >= 0)
- {
- value = xrm_q_get_resource_1 (database, HASH_VALUE (h, i),
- XCDR (quark_name), XCDR (quark_class));
- if (!NILP (value))
- return value;
- }
- }
-
- /* Then, try loose bindings */
- XSETCDR (key, LOOSE_BINDING);
- i = hash_lookup (h, key, NULL);
- if (i >= 0)
- {
- value = xrm_q_get_resource_1 (database, HASH_VALUE (h, i),
- quark_name, quark_class);
- if (!NILP (value))
- return value;
- else
- return xrm_q_get_resource_1 (database, node_id,
- XCDR (quark_name), XCDR (quark_class));
- }
- else
- return Qnil;
-}
-
-static Lisp_Object
-xrm_q_get_resource (database, quark_name, quark_class)
- XrmDatabase database;
- Lisp_Object quark_name, quark_class;
-{
- return xrm_q_get_resource_1 (database, make_number (0),
- quark_name, quark_class);
-}
-
-/* Retrieve a resource value for the specified NAME and CLASS from the
- resource database DATABASE. It corresponds to XrmGetResource. */
-
-Lisp_Object
-xrm_get_resource (database, name, class)
- XrmDatabase database;
- const char *name, *class;
-{
- Lisp_Object key, query_cache, quark_name, quark_class, tmp;
- int i, nn, nc;
- struct Lisp_Hash_Table *h;
- unsigned hash_code;
-
- nn = strlen (name);
- nc = strlen (class);
- key = make_uninit_string (nn + nc + 1);
- strcpy (SDATA (key), name);
- strncpy (SDATA (key) + nn + 1, class, nc);
-
- query_cache = Fgethash (HASHKEY_QUERY_CACHE, database, Qnil);
- if (NILP (query_cache))
- {
- query_cache = make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
- make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil, Qnil);
- Fputhash (HASHKEY_QUERY_CACHE, query_cache, database);
- }
- h = XHASH_TABLE (query_cache);
- i = hash_lookup (h, key, &hash_code);
- if (i >= 0)
- return HASH_VALUE (h, i);
-
- quark_name = parse_resource_name (&name);
- if (*name != '\0')
- return Qnil;
- for (tmp = quark_name, nn = 0; CONSP (tmp); tmp = XCDR (tmp), nn++)
- if (!STRINGP (XCAR (tmp)))
- return Qnil;
-
- quark_class = parse_resource_name (&class);
- if (*class != '\0')
- return Qnil;
- for (tmp = quark_class, nc = 0; CONSP (tmp); tmp = XCDR (tmp), nc++)
- if (!STRINGP (XCAR (tmp)))
- return Qnil;
-
- if (nn != nc)
- return Qnil;
- else
- {
- tmp = xrm_q_get_resource (database, quark_name, quark_class);
- hash_put (h, key, tmp, hash_code);
- return tmp;
- }
-}
-
-#if TARGET_API_MAC_CARBON
-static Lisp_Object
-xrm_cfproperty_list_to_value (plist)
- CFPropertyListRef plist;
-{
- CFTypeID type_id = CFGetTypeID (plist);
-
- if (type_id == CFStringGetTypeID ())
- return cfstring_to_lisp (plist);
- else if (type_id == CFNumberGetTypeID ())
- {
- CFStringRef string;
- Lisp_Object result = Qnil;
-
- string = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@"), plist);
- if (string)
- {
- result = cfstring_to_lisp (string);
- CFRelease (string);
- }
- return result;
- }
- else if (type_id == CFBooleanGetTypeID ())
- return build_string (CFBooleanGetValue (plist) ? "true" : "false");
- else if (type_id == CFDataGetTypeID ())
- return cfdata_to_lisp (plist);
- else
- return Qnil;
-}
-#endif
-
-/* Create a new resource database from the preferences for the
- application APPLICATION. APPLICATION is either a string that
- specifies an application ID, or NULL that represents the current
- application. */
-
-XrmDatabase
-xrm_get_preference_database (application)
- const char *application;
-{
-#if TARGET_API_MAC_CARBON
- CFStringRef app_id, *keys, user_doms[2], host_doms[2];
- CFMutableSetRef key_set = NULL;
- CFArrayRef key_array;
- CFIndex index, count;
- char *res_name;
- XrmDatabase database;
- Lisp_Object quarks = Qnil, value = Qnil;
- CFPropertyListRef plist;
- int iu, ih;
- struct gcpro gcpro1, gcpro2, gcpro3;
-
- user_doms[0] = kCFPreferencesCurrentUser;
- user_doms[1] = kCFPreferencesAnyUser;
- host_doms[0] = kCFPreferencesCurrentHost;
- host_doms[1] = kCFPreferencesAnyHost;
-
- database = xrm_create_database ();
-
- GCPRO3 (database, quarks, value);
-
- app_id = kCFPreferencesCurrentApplication;
- if (application)
- {
- app_id = cfstring_create_with_utf8_cstring (application);
- if (app_id == NULL)
- goto out;
- }
- if (!CFPreferencesAppSynchronize (app_id))
- goto out;
-
- key_set = CFSetCreateMutable (NULL, 0, &kCFCopyStringSetCallBacks);
- if (key_set == NULL)
- goto out;
- for (iu = 0; iu < sizeof (user_doms) / sizeof (*user_doms) ; iu++)
- for (ih = 0; ih < sizeof (host_doms) / sizeof (*host_doms); ih++)
- {
- key_array = CFPreferencesCopyKeyList (app_id, user_doms[iu],
- host_doms[ih]);
- if (key_array)
- {
- count = CFArrayGetCount (key_array);
- for (index = 0; index < count; index++)
- CFSetAddValue (key_set,
- CFArrayGetValueAtIndex (key_array, index));
- CFRelease (key_array);
- }
- }
-
- count = CFSetGetCount (key_set);
- keys = xmalloc (sizeof (CFStringRef) * count);
- CFSetGetValues (key_set, (const void **)keys);
- for (index = 0; index < count; index++)
- {
- res_name = SDATA (cfstring_to_lisp_nodecode (keys[index]));
- quarks = parse_resource_name (&res_name);
- if (!(NILP (quarks) || *res_name))
- {
- plist = CFPreferencesCopyAppValue (keys[index], app_id);
- value = xrm_cfproperty_list_to_value (plist);
- CFRelease (plist);
- if (!NILP (value))
- xrm_q_put_resource (database, quarks, value);
- }
- }
-
- xfree (keys);
- out:
- if (key_set)
- CFRelease (key_set);
- CFRelease (app_id);
-
- UNGCPRO;
-
- return database;
-#else
- return xrm_create_database ();
-#endif
-}
-
-
-#ifndef MAC_OSX
-
-/* The following functions with "sys_" prefix are stubs to Unix
- functions that have already been implemented by CW or MPW. The
- calls to them in Emacs source course are #define'd to call the sys_
- versions by the header files s-mac.h. In these stubs pathnames are
- converted between their Unix and Mac forms. */
-
-
-/* Unix epoch is Jan 1, 1970 while Mac epoch is Jan 1, 1904: 66 years
- + 17 leap days. These are for adjusting time values returned by
- MacOS Toolbox functions. */
-
-#define MAC_UNIX_EPOCH_DIFF ((365L * 66 + 17) * 24 * 60 * 60)
-
-#ifdef __MWERKS__
-#if __MSL__ < 0x6000
-/* CW Pro 5 epoch is Jan 1, 1900 (aaarghhhhh!); remember, 1900 is not
- a leap year! This is for adjusting time_t values returned by MSL
- functions. */
-#define CW_OR_MPW_UNIX_EPOCH_DIFF ((365L * 70 + 17) * 24 * 60 * 60)
-#else /* __MSL__ >= 0x6000 */
-/* CW changes Pro 6 to follow Unix! */
-#define CW_OR_MPW_UNIX_EPOCH_DIFF ((365L * 66 + 17) * 24 * 60 * 60)
-#endif /* __MSL__ >= 0x6000 */
-#elif __MRC__
-/* MPW library functions follow Unix (confused?). */
-#define CW_OR_MPW_UNIX_EPOCH_DIFF ((365L * 66 + 17) * 24 * 60 * 60)
-#else /* not __MRC__ */
-You lose!!!
-#endif /* not __MRC__ */
-
-
-/* Define our own stat function for both MrC and CW. The reason for
- doing this: "stat" is both the name of a struct and function name:
- can't use the same trick like that for sys_open, sys_close, etc. to
- redirect Emacs's calls to our own version that converts Unix style
- filenames to Mac style filename because all sorts of compilation
- errors will be generated if stat is #define'd to be sys_stat. */
-
-int
-stat_noalias (const char *path, struct stat *buf)
-{
- char mac_pathname[MAXPATHLEN+1];
- CInfoPBRec cipb;
-
- if (posix_to_mac_pathname (path, mac_pathname, MAXPATHLEN+1) == 0)
- return -1;
-
- c2pstr (mac_pathname);
- cipb.hFileInfo.ioNamePtr = mac_pathname;
- cipb.hFileInfo.ioVRefNum = 0;
- cipb.hFileInfo.ioDirID = 0;
- cipb.hFileInfo.ioFDirIndex = 0;
- /* set to 0 to get information about specific dir or file */
-
- errno = PBGetCatInfo (&cipb, false);
- if (errno == -43) /* -43: fnfErr defined in Errors.h */
- errno = ENOENT;
- if (errno != noErr)
- return -1;
-
- if (cipb.hFileInfo.ioFlAttrib & 0x10) /* bit 4 = 1 for directories */
- {
- buf->st_mode = S_IFDIR | S_IREAD | S_IEXEC;
-
- if (!(cipb.hFileInfo.ioFlAttrib & 0x1))
- buf->st_mode |= S_IWRITE; /* bit 1 = 1 for locked files/directories */
- buf->st_ino = cipb.dirInfo.ioDrDirID;
- buf->st_dev = cipb.dirInfo.ioVRefNum;
- buf->st_size = cipb.dirInfo.ioDrNmFls;
- /* size of dir = number of files and dirs */
- buf->st_atime
- = buf->st_mtime
- = cipb.dirInfo.ioDrMdDat - MAC_UNIX_EPOCH_DIFF;
- buf->st_ctime = cipb.dirInfo.ioDrCrDat - MAC_UNIX_EPOCH_DIFF;
- }
- else
- {
- buf->st_mode = S_IFREG | S_IREAD;
- if (!(cipb.hFileInfo.ioFlAttrib & 0x1))
- buf->st_mode |= S_IWRITE; /* bit 1 = 1 for locked files/directories */
- if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
- buf->st_mode |= S_IEXEC;
- buf->st_ino = cipb.hFileInfo.ioDirID;
- buf->st_dev = cipb.hFileInfo.ioVRefNum;
- buf->st_size = cipb.hFileInfo.ioFlLgLen;
- buf->st_atime
- = buf->st_mtime
- = cipb.hFileInfo.ioFlMdDat - MAC_UNIX_EPOCH_DIFF;
- buf->st_ctime = cipb.hFileInfo.ioFlCrDat - MAC_UNIX_EPOCH_DIFF;
- }
-
- if (cipb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000)
- {
- /* identify alias files as symlinks */
- buf->st_mode &= ~S_IFREG;
- buf->st_mode |= S_IFLNK;
- }
-
- buf->st_nlink = 1;
- buf->st_uid = getuid ();
- buf->st_gid = getgid ();
- buf->st_rdev = 0;
-
- return 0;
-}
-
-
-int
-lstat (const char *path, struct stat *buf)
-{
- int result;
- char true_pathname[MAXPATHLEN+1];
-
- /* Try looking for the file without resolving aliases first. */
- if ((result = stat_noalias (path, buf)) >= 0)
- return result;
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- return stat_noalias (true_pathname, buf);
-}
-
-
-int
-stat (const char *path, struct stat *sb)
-{
- int result;
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- int len;
-
- if ((result = stat_noalias (path, sb)) >= 0 &&
- ! (sb->st_mode & S_IFLNK))
- return result;
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- {
- fully_resolved_name[len] = '\0';
- /* in fact our readlink terminates strings */
- return lstat (fully_resolved_name, sb);
- }
- else
- return lstat (true_pathname, sb);
-}
-
-
-#if __MRC__
-/* CW defines fstat in stat.mac.c while MPW does not provide this
- function. Without the information of how to get from a file
- descriptor in MPW StdCLib to a Mac OS file spec, it should be hard
- to implement this function. Fortunately, there is only one place
- where this function is called in our configuration: in fileio.c,
- where only the st_dev and st_ino fields are used to determine
- whether two fildes point to different i-nodes to prevent copying
- a file onto itself equal. What we have here probably needs
- improvement. */
-
-int
-fstat (int fildes, struct stat *buf)
-{
- buf->st_dev = 0;
- buf->st_ino = fildes;
- buf->st_mode = S_IFREG; /* added by T.I. for the copy-file */
- return 0; /* success */
-}
-#endif /* __MRC__ */
-
-
-int
-mkdir (const char *dirname, int mode)
-{
-#pragma unused(mode)
-
- HFileParam hfpb;
- char true_pathname[MAXPATHLEN+1], mac_pathname[MAXPATHLEN+1];
-
- if (find_true_pathname (dirname, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- if (posix_to_mac_pathname (true_pathname, mac_pathname, MAXPATHLEN+1) == 0)
- return -1;
-
- c2pstr (mac_pathname);
- hfpb.ioNamePtr = mac_pathname;
- hfpb.ioVRefNum = 0; /* ignored unless name is invalid */
- hfpb.ioDirID = 0; /* parent is the root */
-
- errno = PBDirCreate ((HParmBlkPtr) &hfpb, false);
- /* just return the Mac OSErr code for now */
- return errno == noErr ? 0 : -1;
-}
-
-
-#undef rmdir
-sys_rmdir (const char *dirname)
-{
- HFileParam hfpb;
- char mac_pathname[MAXPATHLEN+1];
-
- if (posix_to_mac_pathname (dirname, mac_pathname, MAXPATHLEN+1) == 0)
- return -1;
-
- c2pstr (mac_pathname);
- hfpb.ioNamePtr = mac_pathname;
- hfpb.ioVRefNum = 0; /* ignored unless name is invalid */
- hfpb.ioDirID = 0; /* parent is the root */
-
- errno = PBHDelete ((HParmBlkPtr) &hfpb, false);
- return errno == noErr ? 0 : -1;
-}
-
-
-#ifdef __MRC__
-/* No implementation yet. */
-int
-execvp (const char *path, ...)
-{
- return -1;
-}
-#endif /* __MRC__ */
-
-
-int
-utime (const char *path, const struct utimbuf *times)
-{
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- int len;
- char mac_pathname[MAXPATHLEN+1];
- CInfoPBRec cipb;
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_name[len] = '\0';
- else
- strcpy (fully_resolved_name, true_pathname);
-
- if (!posix_to_mac_pathname (fully_resolved_name, mac_pathname, MAXPATHLEN+1))
- return -1;
-
- c2pstr (mac_pathname);
- cipb.hFileInfo.ioNamePtr = mac_pathname;
- cipb.hFileInfo.ioVRefNum = 0;
- cipb.hFileInfo.ioDirID = 0;
- cipb.hFileInfo.ioFDirIndex = 0;
- /* set to 0 to get information about specific dir or file */
-
- errno = PBGetCatInfo (&cipb, false);
- if (errno != noErr)
- return -1;
-
- if (cipb.hFileInfo.ioFlAttrib & 0x10) /* bit 4 = 1 for directories */
- {
- if (times)
- cipb.dirInfo.ioDrMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF;
- else
- GetDateTime (&cipb.dirInfo.ioDrMdDat);
- }
- else
- {
- if (times)
- cipb.hFileInfo.ioFlMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF;
- else
- GetDateTime (&cipb.hFileInfo.ioFlMdDat);
- }
-
- errno = PBSetCatInfo (&cipb, false);
- return errno == noErr ? 0 : -1;
-}
-
-
-#ifndef F_OK
-#define F_OK 0
-#endif
-#ifndef X_OK
-#define X_OK 1
-#endif
-#ifndef W_OK
-#define W_OK 2
-#endif
-
-/* Like stat, but test for access mode in hfpb.ioFlAttrib */
-int
-access (const char *path, int mode)
-{
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- int len;
- char mac_pathname[MAXPATHLEN+1];
- CInfoPBRec cipb;
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_name[len] = '\0';
- else
- strcpy (fully_resolved_name, true_pathname);
-
- if (!posix_to_mac_pathname (fully_resolved_name, mac_pathname, MAXPATHLEN+1))
- return -1;
-
- c2pstr (mac_pathname);
- cipb.hFileInfo.ioNamePtr = mac_pathname;
- cipb.hFileInfo.ioVRefNum = 0;
- cipb.hFileInfo.ioDirID = 0;
- cipb.hFileInfo.ioFDirIndex = 0;
- /* set to 0 to get information about specific dir or file */
-
- errno = PBGetCatInfo (&cipb, false);
- if (errno != noErr)
- return -1;
-
- if (mode == F_OK) /* got this far, file exists */
- return 0;
-
- if (mode & X_OK)
- if (cipb.hFileInfo.ioFlAttrib & 0x10) /* path refers to a directory */
- return 0;
- else
- {
- if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
- return 0;
- else
- return -1;
- }
-
- if (mode & W_OK)
- return (cipb.hFileInfo.ioFlAttrib & 0x1) ? -1 : 0;
- /* don't allow if lock bit is on */
-
- return -1;
-}
-
-
-#define DEV_NULL_FD 0x10000
-
-#undef open
-int
-sys_open (const char *path, int oflag)
-{
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- int len;
- char mac_pathname[MAXPATHLEN+1];
-
- if (strcmp (path, "/dev/null") == 0)
- return DEV_NULL_FD; /* some bogus fd to be ignored in write */
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_name[len] = '\0';
- else
- strcpy (fully_resolved_name, true_pathname);
-
- if (!posix_to_mac_pathname (fully_resolved_name, mac_pathname, MAXPATHLEN+1))
- return -1;
- else
- {
-#ifdef __MRC__
- int res = open (mac_pathname, oflag);
- /* if (oflag == O_WRONLY || oflag == O_RDWR) */
- if (oflag & O_CREAT)
- fsetfileinfo (mac_pathname, MAC_EMACS_CREATOR_CODE, 'TEXT');
- return res;
-#else /* not __MRC__ */
- return open (mac_pathname, oflag);
-#endif /* not __MRC__ */
- }
-}
-
-
-#undef creat
-int
-sys_creat (const char *path, mode_t mode)
-{
- char true_pathname[MAXPATHLEN+1];
- int len;
- char mac_pathname[MAXPATHLEN+1];
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- if (!posix_to_mac_pathname (true_pathname, mac_pathname, MAXPATHLEN+1))
- return -1;
- else
- {
-#ifdef __MRC__
- int result = creat (mac_pathname);
- fsetfileinfo (mac_pathname, MAC_EMACS_CREATOR_CODE, 'TEXT');
- return result;
-#else /* not __MRC__ */
- return creat (mac_pathname, mode);
-#endif /* not __MRC__ */
- }
-}
-
-
-#undef unlink
-int
-sys_unlink (const char *path)
-{
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- int len;
- char mac_pathname[MAXPATHLEN+1];
-
- if (find_true_pathname (path, true_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_name[len] = '\0';
- else
- strcpy (fully_resolved_name, true_pathname);
-
- if (!posix_to_mac_pathname (fully_resolved_name, mac_pathname, MAXPATHLEN+1))
- return -1;
- else
- return unlink (mac_pathname);
-}
-
-
-#undef read
-int
-sys_read (int fildes, char *buf, int count)
-{
- if (fildes == 0) /* this should not be used for console input */
- return -1;
- else
-#if __MSL__ >= 0x6000
- return _read (fildes, buf, count);
-#else
- return read (fildes, buf, count);
-#endif
-}
-
-
-#undef write
-int
-sys_write (int fildes, const char *buf, int count)
-{
- if (fildes == DEV_NULL_FD)
- return count;
- else
-#if __MSL__ >= 0x6000
- return _write (fildes, buf, count);
-#else
- return write (fildes, buf, count);
-#endif
-}
-
-
-#undef rename
-int
-sys_rename (const char * old_name, const char * new_name)
-{
- char true_old_pathname[MAXPATHLEN+1], true_new_pathname[MAXPATHLEN+1];
- char fully_resolved_old_name[MAXPATHLEN+1];
- int len;
- char mac_old_name[MAXPATHLEN+1], mac_new_name[MAXPATHLEN+1];
-
- if (find_true_pathname (old_name, true_old_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- len = readlink (true_old_pathname, fully_resolved_old_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_old_name[len] = '\0';
- else
- strcpy (fully_resolved_old_name, true_old_pathname);
-
- if (find_true_pathname (new_name, true_new_pathname, MAXPATHLEN+1) == -1)
- return -1;
-
- if (strcmp (fully_resolved_old_name, true_new_pathname) == 0)
- return 0;
-
- if (!posix_to_mac_pathname (fully_resolved_old_name,
- mac_old_name,
- MAXPATHLEN+1))
- return -1;
-
- if (!posix_to_mac_pathname(true_new_pathname, mac_new_name, MAXPATHLEN+1))
- return -1;
-
- /* If a file with new_name already exists, rename deletes the old
- file in Unix. CW version fails in these situation. So we add a
- call to unlink here. */
- (void) unlink (mac_new_name);
-
- return rename (mac_old_name, mac_new_name);
-}
-
-
-#undef fopen
-extern FILE *fopen (const char *name, const char *mode);
-FILE *
-sys_fopen (const char *name, const char *mode)
-{
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- int len;
- char mac_pathname[MAXPATHLEN+1];
-
- if (find_true_pathname (name, true_pathname, MAXPATHLEN+1) == -1)
- return 0;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_name[len] = '\0';
- else
- strcpy (fully_resolved_name, true_pathname);
-
- if (!posix_to_mac_pathname (fully_resolved_name, mac_pathname, MAXPATHLEN+1))
- return 0;
- else
- {
-#ifdef __MRC__
- if (mode[0] == 'w' || mode[0] == 'a')
- fsetfileinfo (mac_pathname, MAC_EMACS_CREATOR_CODE, 'TEXT');
-#endif /* not __MRC__ */
- return fopen (mac_pathname, mode);
- }
-}
-
-
-extern Boolean mac_wait_next_event P_ ((EventRecord *, UInt32, Boolean));
-
-int
-select (nfds, rfds, wfds, efds, timeout)
- int nfds;
- SELECT_TYPE *rfds, *wfds, *efds;
- EMACS_TIME *timeout;
-{
- OSStatus err = noErr;
-
- /* Can only handle wait for keyboard input. */
- if (nfds > 1 || wfds || efds)
- return -1;
-
- /* Try detect_input_pending before ReceiveNextEvent in the same
- BLOCK_INPUT block, in case that some input has already been read
- asynchronously. */
- BLOCK_INPUT;
- ENABLE_WAKEUP_FROM_RNE;
- if (!detect_input_pending ())
- {
-#if TARGET_API_MAC_CARBON
- EventTimeout timeoutval =
- (timeout
- ? (EMACS_SECS (*timeout) * kEventDurationSecond
- + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
- : kEventDurationForever);
-
- if (timeoutval == 0.0)
- err = eventLoopTimedOutErr;
- else
- err = ReceiveNextEvent (0, NULL, timeoutval,
- kEventLeaveInQueue, NULL);
-#else /* not TARGET_API_MAC_CARBON */
- EventRecord e;
- UInt32 sleep_time = EMACS_SECS (*timeout) * 60 +
- ((EMACS_USECS (*timeout) * 60) / 1000000);
-
- if (sleep_time == 0)
- err = -9875; /* eventLoopTimedOutErr */
- else
- {
- if (mac_wait_next_event (&e, sleep_time, false))
- err = noErr;
- else
- err = -9875; /* eventLoopTimedOutErr */
- }
-#endif /* not TARGET_API_MAC_CARBON */
- }
- DISABLE_WAKEUP_FROM_RNE;
- UNBLOCK_INPUT;
-
- if (err == noErr)
- {
- /* Pretend that `select' is interrupted by a signal. */
- detect_input_pending ();
- errno = EINTR;
- return -1;
- }
- else
- {
- if (rfds)
- FD_ZERO (rfds);
- return 0;
- }
-}
-
-
-/* Simulation of SIGALRM. The stub for function signal stores the
- signal handler function in alarm_signal_func if a SIGALRM is
- encountered. */
-
-#include <signal.h>
-#include "syssignal.h"
-
-static TMTask mac_atimer_task;
-
-static QElemPtr mac_atimer_qlink = (QElemPtr) &mac_atimer_task;
-
-static int signal_mask = 0;
-
-#ifdef __MRC__
-__sigfun alarm_signal_func = (__sigfun) 0;
-#elif __MWERKS__
-__signal_func_ptr alarm_signal_func = (__signal_func_ptr) 0;
-#else /* not __MRC__ and not __MWERKS__ */
-You lose!!!
-#endif /* not __MRC__ and not __MWERKS__ */
-
-#undef signal
-#ifdef __MRC__
-extern __sigfun signal (int signal, __sigfun signal_func);
-__sigfun
-sys_signal (int signal_num, __sigfun signal_func)
-#elif __MWERKS__
-extern __signal_func_ptr signal (int signal, __signal_func_ptr signal_func);
-__signal_func_ptr
-sys_signal (int signal_num, __signal_func_ptr signal_func)
-#else /* not __MRC__ and not __MWERKS__ */
- You lose!!!
-#endif /* not __MRC__ and not __MWERKS__ */
-{
- if (signal_num != SIGALRM)
- return signal (signal_num, signal_func);
- else
- {
-#ifdef __MRC__
- __sigfun old_signal_func;
-#elif __MWERKS__
- __signal_func_ptr old_signal_func;
-#else
- You lose!!!
-#endif
- old_signal_func = alarm_signal_func;
- alarm_signal_func = signal_func;
- return old_signal_func;
- }
-}
-
-
-static pascal void
-mac_atimer_handler (qlink)
- TMTaskPtr qlink;
-{
- if (alarm_signal_func)
- (alarm_signal_func) (SIGALRM);
-}
-
-
-static void
-set_mac_atimer (count)
- long count;
-{
- static TimerUPP mac_atimer_handlerUPP = NULL;
-
- if (mac_atimer_handlerUPP == NULL)
- mac_atimer_handlerUPP = NewTimerUPP (mac_atimer_handler);
- mac_atimer_task.tmCount = 0;
- mac_atimer_task.tmAddr = mac_atimer_handlerUPP;
- mac_atimer_qlink = (QElemPtr) &mac_atimer_task;
- InsTime (mac_atimer_qlink);
- if (count)
- PrimeTime (mac_atimer_qlink, count);
-}
-
-
-int
-remove_mac_atimer (remaining_count)
- long *remaining_count;
-{
- if (mac_atimer_qlink)
- {
- RmvTime (mac_atimer_qlink);
- if (remaining_count)
- *remaining_count = mac_atimer_task.tmCount;
- mac_atimer_qlink = NULL;
-
- return 0;
- }
- else
- return -1;
-}
-
-
-int
-sigblock (int mask)
-{
- int old_mask = signal_mask;
-
- signal_mask |= mask;
-
- if ((old_mask ^ signal_mask) & sigmask (SIGALRM))
- remove_mac_atimer (NULL);
-
- return old_mask;
-}
-
-
-int
-sigsetmask (int mask)
-{
- int old_mask = signal_mask;
-
- signal_mask = mask;
-
- if ((old_mask ^ signal_mask) & sigmask (SIGALRM))
- if (signal_mask & sigmask (SIGALRM))
- remove_mac_atimer (NULL);
- else
- set_mac_atimer (mac_atimer_task.tmCount);
-
- return old_mask;
-}
-
-
-int
-alarm (int seconds)
-{
- long remaining_count;
-
- if (remove_mac_atimer (&remaining_count) == 0)
- {
- set_mac_atimer (seconds * 1000);
-
- return remaining_count / 1000;
- }
- else
- {
- mac_atimer_task.tmCount = seconds * 1000;
-
- return 0;
- }
-}
-
-
-int
-setitimer (which, value, ovalue)
- int which;
- const struct itimerval *value;
- struct itimerval *ovalue;
-{
- long remaining_count;
- long count = (EMACS_SECS (value->it_value) * 1000
- + (EMACS_USECS (value->it_value) + 999) / 1000);
-
- if (remove_mac_atimer (&remaining_count) == 0)
- {
- if (ovalue)
- {
- bzero (ovalue, sizeof (*ovalue));
- EMACS_SET_SECS_USECS (ovalue->it_value, remaining_count / 1000,
- (remaining_count % 1000) * 1000);
- }
- set_mac_atimer (count);
- }
- else
- mac_atimer_task.tmCount = count;
-
- return 0;
-}
-
-
-/* gettimeofday should return the amount of time (in a timeval
- structure) since midnight today. The toolbox function Microseconds
- returns the number of microseconds (in a UnsignedWide value) since
- the machine was booted. Also making this complicated is WideAdd,
- WideSubtract, etc. take wide values. */
-
-int
-gettimeofday (tp)
- struct timeval *tp;
-{
- static inited = 0;
- static wide wall_clock_at_epoch, clicks_at_epoch;
- UnsignedWide uw_microseconds;
- wide w_microseconds;
- time_t sys_time (time_t *);
-
- /* If this function is called for the first time, record the number
- of seconds since midnight and the number of microseconds since
- boot at the time of this first call. */
- if (!inited)
- {
- time_t systime;
- inited = 1;
- systime = sys_time (NULL);
- /* Store microseconds since midnight in wall_clock_at_epoch. */
- WideMultiply (systime, 1000000L, &wall_clock_at_epoch);
- Microseconds (&uw_microseconds);
- /* Store microseconds since boot in clicks_at_epoch. */
- clicks_at_epoch.hi = uw_microseconds.hi;
- clicks_at_epoch.lo = uw_microseconds.lo;
- }
-
- /* Get time since boot */
- Microseconds (&uw_microseconds);
-
- /* Convert to time since midnight*/
- w_microseconds.hi = uw_microseconds.hi;
- w_microseconds.lo = uw_microseconds.lo;
- WideSubtract (&w_microseconds, &clicks_at_epoch);
- WideAdd (&w_microseconds, &wall_clock_at_epoch);
- tp->tv_sec = WideDivide (&w_microseconds, 1000000L, &tp->tv_usec);
-
- return 0;
-}
-
-
-#ifdef __MRC__
-unsigned int
-sleep (unsigned int seconds)
-{
- unsigned long time_up;
- EventRecord e;
-
- time_up = TickCount () + seconds * 60;
- while (TickCount () < time_up)
- {
- /* Accept no event; just wait. by T.I. */
- WaitNextEvent (0, &e, 30, NULL);
- }
-
- return (0);
-}
-#endif /* __MRC__ */
-
-
-/* The time functions adjust time values according to the difference
- between the Unix and CW epoches. */
-
-#undef gmtime
-extern struct tm *gmtime (const time_t *);
-struct tm *
-sys_gmtime (const time_t *timer)
-{
- time_t unix_time = *timer + CW_OR_MPW_UNIX_EPOCH_DIFF;
-
- return gmtime (&unix_time);
-}
-
-
-#undef localtime
-extern struct tm *localtime (const time_t *);
-struct tm *
-sys_localtime (const time_t *timer)
-{
-#if __MSL__ >= 0x6000
- time_t unix_time = *timer;
-#else
- time_t unix_time = *timer + CW_OR_MPW_UNIX_EPOCH_DIFF;
-#endif
-
- return localtime (&unix_time);
-}
-
-
-#undef ctime
-extern char *ctime (const time_t *);
-char *
-sys_ctime (const time_t *timer)
-{
-#if __MSL__ >= 0x6000
- time_t unix_time = *timer;
-#else
- time_t unix_time = *timer + CW_OR_MPW_UNIX_EPOCH_DIFF;
-#endif
-
- return ctime (&unix_time);
-}
-
-
-#undef time
-extern time_t time (time_t *);
-time_t
-sys_time (time_t *timer)
-{
-#if __MSL__ >= 0x6000
- time_t mac_time = time (NULL);
-#else
- time_t mac_time = time (NULL) - CW_OR_MPW_UNIX_EPOCH_DIFF;
-#endif
-
- if (timer)
- *timer = mac_time;
-
- return mac_time;
-}
-
-
-/* no subprocesses, empty wait */
-
-int
-wait (int pid)
-{
- return 0;
-}
-
-
-void
-croak (char *badfunc)
-{
- printf ("%s not yet implemented\r\n", badfunc);
- exit (1);
-}
-
-
-char *
-mktemp (char *template)
-{
- int len, k;
- static seqnum = 0;
-
- len = strlen (template);
- k = len - 1;
- while (k >= 0 && template[k] == 'X')
- k--;
-
- k++; /* make k index of first 'X' */
-
- if (k < len)
- {
- /* Zero filled, number of digits equal to the number of X's. */
- sprintf (&template[k], "%0*d", len-k, seqnum++);
-
- return template;
- }
- else
- return 0;
-}
-
-
-/* Emulate getpwuid, getpwnam and others. */
-
-#define PASSWD_FIELD_SIZE 256
-
-static char my_passwd_name[PASSWD_FIELD_SIZE];
-static char my_passwd_dir[MAXPATHLEN+1];
-
-static struct passwd my_passwd =
-{
- my_passwd_name,
- my_passwd_dir,
-};
-
-static struct group my_group =
-{
- /* There are no groups on the mac, so we just return "root" as the
- group name. */
- "root",
-};
-
-
-/* Initialized by main () in macterm.c to pathname of emacs directory. */
-
-char emacs_passwd_dir[MAXPATHLEN+1];
-
-char *
-getwd (char *);
-
-void
-init_emacs_passwd_dir ()
-{
- int found = false;
-
- if (getwd (emacs_passwd_dir) && getwd (my_passwd_dir))
- {
- /* Need pathname of first ancestor that begins with "emacs"
- since Mac emacs application is somewhere in the emacs-*
- tree. */
- int len = strlen (emacs_passwd_dir);
- int j = len - 1;
- /* j points to the "/" following the directory name being
- compared. */
- int i = j - 1;
- while (i >= 0 && !found)
- {
- while (i >= 0 && emacs_passwd_dir[i] != '/')
- i--;
- if (emacs_passwd_dir[i] == '/' && i+5 < len)
- found = (strncmp (&(emacs_passwd_dir[i+1]), "emacs", 5) == 0);
- if (found)
- emacs_passwd_dir[j+1] = '\0';
- else
- {
- j = i;
- i = j - 1;
- }
- }
- }
-
- if (!found)
- {
- /* Setting to "/" probably won't work but set it to something
- anyway. */
- strcpy (emacs_passwd_dir, "/");
- strcpy (my_passwd_dir, "/");
- }
-}
-
-
-static struct passwd emacs_passwd =
-{
- "emacs",
- emacs_passwd_dir,
-};
-
-static int my_passwd_inited = 0;
-
-
-static void
-init_my_passwd ()
-{
- char **owner_name;
-
- /* Note: my_passwd_dir initialized in int_emacs_passwd_dir to
- directory where Emacs was started. */
-
- owner_name = (char **) GetResource ('STR ',-16096);
- if (owner_name)
- {
- HLock (owner_name);
- BlockMove ((unsigned char *) *owner_name,
- (unsigned char *) my_passwd_name,
- *owner_name[0]+1);
- HUnlock (owner_name);
- p2cstr ((unsigned char *) my_passwd_name);
- }
- else
- my_passwd_name[0] = 0;
-}
-
-
-struct passwd *
-getpwuid (uid_t uid)
-{
- if (!my_passwd_inited)
- {
- init_my_passwd ();
- my_passwd_inited = 1;
- }
-
- return &my_passwd;
-}
-
-
-struct group *
-getgrgid (gid_t gid)
-{
- return &my_group;
-}
-
-
-struct passwd *
-getpwnam (const char *name)
-{
- if (strcmp (name, "emacs") == 0)
- return &emacs_passwd;
-
- if (!my_passwd_inited)
- {
- init_my_passwd ();
- my_passwd_inited = 1;
- }
-
- return &my_passwd;
-}
-
-
-/* The functions fork, kill, sigsetmask, sigblock, request_sigio,
- setpgrp, setpriority, and unrequest_sigio are defined to be empty
- as in msdos.c. */
-
-
-int
-fork ()
-{
- return -1;
-}
-
-
-int
-kill (int x, int y)
-{
- return -1;
-}
-
-
-void
-sys_subshell ()
-{
- error ("Can't spawn subshell");
-}
-
-
-void
-request_sigio (void)
-{
-}
-
-
-void
-unrequest_sigio (void)
-{
-}
-
-
-int
-setpgrp ()
-{
- return 0;
-}
-
-
-/* No pipes yet. */
-
-int
-pipe (int _fildes[2])
-{
- errno = EACCES;
- return -1;
-}
-
-
-/* Hard and symbolic links. */
-
-int
-symlink (const char *name1, const char *name2)
-{
- errno = ENOENT;
- return -1;
-}
-
-
-int
-link (const char *name1, const char *name2)
-{
- errno = ENOENT;
- return -1;
-}
-
-#endif /* ! MAC_OSX */
-
-/* Determine the path name of the file specified by VREFNUM, DIRID,
- and NAME and place that in the buffer PATH of length
- MAXPATHLEN. */
-static int
-path_from_vol_dir_name (char *path, int man_path_len, short vol_ref_num,
- long dir_id, ConstStr255Param name)
-{
- Str255 dir_name;
- CInfoPBRec cipb;
- OSErr err;
-
- if (strlen (name) > man_path_len)
- return 0;
-
- memcpy (dir_name, name, name[0]+1);
- memcpy (path, name, name[0]+1);
- p2cstr (path);
-
- cipb.dirInfo.ioDrParID = dir_id;
- cipb.dirInfo.ioNamePtr = dir_name;
-
- do
- {
- cipb.dirInfo.ioVRefNum = vol_ref_num;
- cipb.dirInfo.ioFDirIndex = -1;
- cipb.dirInfo.ioDrDirID = cipb.dirInfo.ioDrParID;
- /* go up to parent each time */
-
- err = PBGetCatInfo (&cipb, false);
- if (err != noErr)
- return 0;
-
- p2cstr (dir_name);
- if (strlen (dir_name) + strlen (path) + 1 >= man_path_len)
- return 0;
-
- strcat (dir_name, ":");
- strcat (dir_name, path);
- /* attach to front since we're going up directory tree */
- strcpy (path, dir_name);
- }
- while (cipb.dirInfo.ioDrDirID != fsRtDirID);
- /* stop when we see the volume's root directory */
-
- return 1; /* success */
-}
-
-
-#ifndef MAC_OSX
-
-static OSErr
-posix_pathname_to_fsspec (ufn, fs)
- const char *ufn;
- FSSpec *fs;
-{
- Str255 mac_pathname;
-
- if (posix_to_mac_pathname (ufn, mac_pathname, sizeof (mac_pathname)) == 0)
- return fnfErr;
- else
- {
- c2pstr (mac_pathname);
- return FSMakeFSSpec (0, 0, mac_pathname, fs);
- }
-}
-
-static OSErr
-fsspec_to_posix_pathname (fs, ufn, ufnbuflen)
- const FSSpec *fs;
- char *ufn;
- int ufnbuflen;
-{
- char mac_pathname[MAXPATHLEN];
-
- if (path_from_vol_dir_name (mac_pathname, sizeof (mac_pathname) - 1,
- fs->vRefNum, fs->parID, fs->name)
- && mac_to_posix_pathname (mac_pathname, ufn, ufnbuflen))
- return noErr;
- else
- return fnfErr;
-}
-
-int
-readlink (const char *path, char *buf, int bufsiz)
-{
- char mac_sym_link_name[MAXPATHLEN+1];
- OSErr err;
- FSSpec fsspec;
- Boolean target_is_folder, was_aliased;
- Str255 directory_name, mac_pathname;
- CInfoPBRec cipb;
-
- if (posix_to_mac_pathname (path, mac_sym_link_name, MAXPATHLEN+1) == 0)
- return -1;
-
- c2pstr (mac_sym_link_name);
- err = FSMakeFSSpec (0, 0, mac_sym_link_name, &fsspec);
- if (err != noErr)
- {
- errno = ENOENT;
- return -1;
- }
-
- err = ResolveAliasFile (&fsspec, true, &target_is_folder, &was_aliased);
- if (err != noErr || !was_aliased)
- {
- errno = ENOENT;
- return -1;
- }
-
- if (path_from_vol_dir_name (mac_pathname, 255, fsspec.vRefNum, fsspec.parID,
- fsspec.name) == 0)
- {
- errno = ENOENT;
- return -1;
- }
-
- if (mac_to_posix_pathname (mac_pathname, buf, bufsiz) == 0)
- {
- errno = ENOENT;
- return -1;
- }
-
- return strlen (buf);
-}
-
-
-/* Convert a path to one with aliases fully expanded. */
-
-static int
-find_true_pathname (const char *path, char *buf, int bufsiz)
-{
- char *q, temp[MAXPATHLEN+1];
- const char *p;
- int len;
-
- if (bufsiz <= 0 || path == 0 || path[0] == '\0')
- return -1;
-
- buf[0] = '\0';
-
- p = path;
- if (*p == '/')
- q = strchr (p + 1, '/');
- else
- q = strchr (p, '/');
- len = 0; /* loop may not be entered, e.g., for "/" */
-
- while (q)
- {
- strcpy (temp, buf);
- strncat (temp, p, q - p);
- len = readlink (temp, buf, bufsiz);
- if (len <= -1)
- {
- if (strlen (temp) + 1 > bufsiz)
- return -1;
- strcpy (buf, temp);
- }
- strcat (buf, "/");
- len++;
- p = q + 1;
- q = strchr(p, '/');
- }
-
- if (len + strlen (p) + 1 >= bufsiz)
- return -1;
-
- strcat (buf, p);
- return len + strlen (p);
-}
-
-
-mode_t
-umask (mode_t numask)
-{
- static mode_t mask = 022;
- mode_t oldmask = mask;
- mask = numask;
- return oldmask;
-}
-
-
-int
-chmod (const char *path, mode_t mode)
-{
- /* say it always succeed for now */
- return 0;
-}
-
-
-int
-fchmod (int fd, mode_t mode)
-{
- /* say it always succeed for now */
- return 0;
-}
-
-
-int
-fchown (int fd, uid_t owner, gid_t group)
-{
- /* say it always succeed for now */
- return 0;
-}
-
-
-int
-dup (int oldd)
-{
-#ifdef __MRC__
- return fcntl (oldd, F_DUPFD, 0);
-#elif __MWERKS__
- /* current implementation of fcntl in fcntl.mac.c simply returns old
- descriptor */
- return fcntl (oldd, F_DUPFD);
-#else
-You lose!!!
-#endif
-}
-
-
-/* This is from the original sysdep.c. Emulate BSD dup2. First close
- newd if it already exists. Then, attempt to dup oldd. If not
- successful, call dup2 recursively until we are, then close the
- unsuccessful ones. */
-
-int
-dup2 (int oldd, int newd)
-{
- int fd, ret;
-
- close (newd);
-
- fd = dup (oldd);
- if (fd == -1)
- return -1;
- if (fd == newd)
- return newd;
- ret = dup2 (oldd, newd);
- close (fd);
- return ret;
-}
-
-
-/* let it fail for now */
-
-char *
-sbrk (int incr)
-{
- return (char *) -1;
-}
-
-
-int
-fsync (int fd)
-{
- return 0;
-}
-
-
-int
-ioctl (int d, int request, void *argp)
-{
- return -1;
-}
-
-
-#ifdef __MRC__
-int
-isatty (int fildes)
-{
- if (fildes >=0 && fildes <= 2)
- return 1;
- else
- return 0;
-}
-
-
-int
-getgid ()
-{
- return 100;
-}
-
-
-int
-getegid ()
-{
- return 100;
-}
-
-
-int
-getuid ()
-{
- return 200;
-}
-
-
-int
-geteuid ()
-{
- return 200;
-}
-#endif /* __MRC__ */
-
-
-#ifdef __MWERKS__
-#if __MSL__ < 0x6000
-#undef getpid
-int
-getpid ()
-{
- return 9999;
-}
-#endif
-#endif /* __MWERKS__ */
-
-#endif /* ! MAC_OSX */
-
-
-/* Return the path to the directory in which Emacs can create
- temporary files. The MacOS "temporary items" directory cannot be
- used because it removes the file written by a process when it
- exits. In that sense it's more like "/dev/null" than "/tmp" (but
- again not exactly). And of course Emacs needs to read back the
- files written by its subprocesses. So here we write the files to a
- directory "Emacs" in the Preferences Folder. This directory is
- created if it does not exist. */
-
-char *
-get_temp_dir_name ()
-{
- static char *temp_dir_name = NULL;
- short vol_ref_num;
- long dir_id;
- OSErr err;
- Str255 full_path;
- char unix_dir_name[MAXPATHLEN+1];
- DIR *dir;
-
- /* Cache directory name with pointer temp_dir_name.
- Look for it only the first time. */
- if (!temp_dir_name)
- {
- err = FindFolder (kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
- &vol_ref_num, &dir_id);
- if (err != noErr)
- return NULL;
-
- if (!path_from_vol_dir_name (full_path, 255, vol_ref_num, dir_id, "\p"))
- return NULL;
-
- if (strlen (full_path) + 6 <= MAXPATHLEN)
- strcat (full_path, "Emacs:");
- else
- return NULL;
-
- if (!mac_to_posix_pathname (full_path, unix_dir_name, MAXPATHLEN+1))
- return NULL;
-
- dir = opendir (unix_dir_name); /* check whether temp directory exists */
- if (dir)
- closedir (dir);
- else if (mkdir (unix_dir_name, 0700) != 0) /* create it if not */
- return NULL;
-
- temp_dir_name = (char *) malloc (strlen (unix_dir_name) + 1);
- strcpy (temp_dir_name, unix_dir_name);
- }
-
- return temp_dir_name;
-}
-
-#ifndef MAC_OSX
-
-/* Allocate and construct an array of pointers to strings from a list
- of strings stored in a 'STR#' resource. The returned pointer array
- is stored in the style of argv and environ: if the 'STR#' resource
- contains numString strings, a pointer array with numString+1
- elements is returned in which the last entry contains a null
- pointer. The pointer to the pointer array is passed by pointer in
- parameter t. The resource ID of the 'STR#' resource is passed in
- parameter StringListID.
- */
-
-void
-get_string_list (char ***t, short string_list_id)
-{
- Handle h;
- Ptr p;
- int i, num_strings;
-
- h = GetResource ('STR#', string_list_id);
- if (h)
- {
- HLock (h);
- p = *h;
- num_strings = * (short *) p;
- p += sizeof(short);
- *t = (char **) malloc (sizeof (char *) * (num_strings + 1));
- for (i = 0; i < num_strings; i++)
- {
- short length = *p++;
- (*t)[i] = (char *) malloc (length + 1);
- strncpy ((*t)[i], p, length);
- (*t)[i][length] = '\0';
- p += length;
- }
- (*t)[num_strings] = 0;
- HUnlock (h);
- }
- else
- {
- /* Return no string in case GetResource fails. Bug fixed by
- Ikegami Tsutomu. Caused MPW build to crash without sym -on
- option (no sym -on implies -opt local). */
- *t = (char **) malloc (sizeof (char *));
- (*t)[0] = 0;
- }
-}
-
-
-static char *
-get_path_to_system_folder ()
-{
- short vol_ref_num;
- long dir_id;
- OSErr err;
- Str255 full_path;
- static char system_folder_unix_name[MAXPATHLEN+1];
- DIR *dir;
-
- err = FindFolder (kOnSystemDisk, kSystemFolderType, kDontCreateFolder,
- &vol_ref_num, &dir_id);
- if (err != noErr)
- return NULL;
-
- if (!path_from_vol_dir_name (full_path, 255, vol_ref_num, dir_id, "\p"))
- return NULL;
-
- if (!mac_to_posix_pathname (full_path, system_folder_unix_name,
- MAXPATHLEN+1))
- return NULL;
-
- return system_folder_unix_name;
-}
-
-
-char **environ;
-
-#define ENVIRON_STRING_LIST_ID 128
-
-/* Get environment variable definitions from STR# resource. */
-
-void
-init_environ ()
-{
- int i;
-
- get_string_list (&environ, ENVIRON_STRING_LIST_ID);
-
- i = 0;
- while (environ[i])
- i++;
-
- /* Make HOME directory the one Emacs starts up in if not specified
- by resource. */
- if (getenv ("HOME") == NULL)
- {
- environ = (char **) realloc (environ, sizeof (char *) * (i + 2));
- if (environ)
- {
- environ[i] = (char *) malloc (strlen (my_passwd_dir) + 6);
- if (environ[i])
- {
- strcpy (environ[i], "HOME=");
- strcat (environ[i], my_passwd_dir);
- }
- environ[i+1] = 0;
- i++;
- }
- }
-
- /* Make HOME directory the one Emacs starts up in if not specified
- by resource. */
- if (getenv ("MAIL") == NULL)
- {
- environ = (char **) realloc (environ, sizeof (char *) * (i + 2));
- if (environ)
- {
- char * path_to_system_folder = get_path_to_system_folder ();
- environ[i] = (char *) malloc (strlen (path_to_system_folder) + 22);
- if (environ[i])
- {
- strcpy (environ[i], "MAIL=");
- strcat (environ[i], path_to_system_folder);
- strcat (environ[i], "Eudora Folder/In");
- }
- environ[i+1] = 0;
- }
- }
-}
-
-
-/* Return the value of the environment variable NAME. */
-
-char *
-getenv (const char *name)
-{
- int length = strlen(name);
- char **e;
-
- for (e = environ; *e != 0; e++)
- if (strncmp(*e, name, length) == 0 && (*e)[length] == '=')
- return &(*e)[length + 1];
-
- if (strcmp (name, "TMPDIR") == 0)
- return get_temp_dir_name ();
-
- return 0;
-}
-
-
-#ifdef __MRC__
-/* see Interfaces&Libraries:Interfaces:CIncludes:signal.h */
-char *sys_siglist[] =
-{
- "Zero is not a signal!!!",
- "Abort", /* 1 */
- "Interactive user interrupt", /* 2 */ "?",
- "Floating point exception", /* 4 */ "?", "?", "?",
- "Illegal instruction", /* 8 */ "?", "?", "?", "?", "?", "?", "?",
- "Segment violation", /* 16 */ "?", "?", "?", "?", "?", "?", "?",
- "?", "?", "?", "?", "?", "?", "?", "?",
- "Terminal" /* 32 */
-};
-#elif __MWERKS__
-char *sys_siglist[] =
-{
- "Zero is not a signal!!!",
- "Abort",
- "Floating point exception",
- "Illegal instruction",
- "Interactive user interrupt",
- "Segment violation",
- "Terminal"
-};
-#else /* not __MRC__ and not __MWERKS__ */
-You lose!!!
-#endif /* not __MRC__ and not __MWERKS__ */
-
-
-#include <utsname.h>
-
-int
-uname (struct utsname *name)
-{
- char **system_name;
- system_name = GetString (-16413); /* IM - Resource Manager Reference */
- if (system_name)
- {
- BlockMove (*system_name, name->nodename, (*system_name)[0]+1);
- p2cstr (name->nodename);
- return 0;
- }
- else
- return -1;
-}
-
-
-/* Event class of HLE sent to subprocess. */
-const OSType kEmacsSubprocessSend = 'ESND';
-
-/* Event class of HLE sent back from subprocess. */
-const OSType kEmacsSubprocessReply = 'ERPY';
-
-
-char *
-mystrchr (char *s, char c)
-{
- while (*s && *s != c)
- {
- if (*s == '\\')
- s++;
- s++;
- }
-
- if (*s)
- {
- *s = '\0';
- return s;
- }
- else
- return NULL;
-}
-
-
-char *
-mystrtok (char *s)
-{
- while (*s)
- s++;
-
- return s + 1;
-}
-
-
-void
-mystrcpy (char *to, char *from)
-{
- while (*from)
- {
- if (*from == '\\')
- from++;
- *to++ = *from++;
- }
- *to = '\0';
-}
-
-
-/* Start a Mac subprocess. Arguments for it is passed in argv (null
- terminated). The process should run with the default directory
- "workdir", read input from "infn", and write output and error to
- "outfn" and "errfn", resp. The Process Manager call
- LaunchApplication is used to start the subprocess. We use high
- level events as the mechanism to pass arguments to the subprocess
- and to make Emacs wait for the subprocess to terminate and pass
- back a result code. The bulk of the code here packs the arguments
- into one message to be passed together with the high level event.
- Emacs also sometimes starts a subprocess using a shell to perform
- wildcard filename expansion. Since we don't really have a shell on
- the Mac, this case is detected and the starting of the shell is
- by-passed. We really need to add code here to do filename
- expansion to support such functionality.
-
- We can't use this strategy in Carbon because the High Level Event
- APIs are not available. */
-
-int
-run_mac_command (argv, workdir, infn, outfn, errfn)
- unsigned char **argv;
- const char *workdir;
- const char *infn, *outfn, *errfn;
-{
-#if TARGET_API_MAC_CARBON
- return -1;
-#else /* not TARGET_API_MAC_CARBON */
- char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1];
- char macinfn[MAXPATHLEN+1], macoutfn[MAXPATHLEN+1], macerrfn[MAXPATHLEN+1];
- int paramlen, argc, newargc, j, retries;
- char **newargv, *param, *p;
- OSErr iErr;
- FSSpec spec;
- LaunchParamBlockRec lpbr;
- EventRecord send_event, reply_event;
- RgnHandle cursor_region_handle;
- TargetID targ;
- unsigned long ref_con, len;
-
- if (posix_to_mac_pathname (workdir, macworkdir, MAXPATHLEN+1) == 0)
- return -1;
- if (posix_to_mac_pathname (infn, macinfn, MAXPATHLEN+1) == 0)
- return -1;
- if (posix_to_mac_pathname (outfn, macoutfn, MAXPATHLEN+1) == 0)
- return -1;
- if (posix_to_mac_pathname (errfn, macerrfn, MAXPATHLEN+1) == 0)
- return -1;
-
- paramlen = strlen (macworkdir) + strlen (macinfn) + strlen (macoutfn)
- + strlen (macerrfn) + 4; /* count nulls at end of strings */
-
- argc = 0;
- while (argv[argc])
- argc++;
-
- if (argc == 0)
- return -1;
-
- /* If a subprocess is invoked with a shell, we receive 3 arguments
- of the form: "<path to emacs bins>/sh" "-c" "<path to emacs
- bins>/<command> <command args>" */
- j = strlen (argv[0]);
- if (j >= 3 && strcmp (argv[0]+j-3, "/sh") == 0
- && argc == 3 && strcmp (argv[1], "-c") == 0)
- {
- char *command, *t, tempmacpathname[MAXPATHLEN+1];
-
- /* The arguments for the command in argv[2] are separated by
- spaces. Count them and put the count in newargc. */
- command = (char *) alloca (strlen (argv[2])+2);
- strcpy (command, argv[2]);
- if (command[strlen (command) - 1] != ' ')
- strcat (command, " ");
-
- t = command;
- newargc = 0;
- t = mystrchr (t, ' ');
- while (t)
- {
- newargc++;
- t = mystrchr (t+1, ' ');
- }
-
- newargv = (char **) alloca (sizeof (char *) * newargc);
-
- t = command;
- for (j = 0; j < newargc; j++)
- {
- newargv[j] = (char *) alloca (strlen (t) + 1);
- mystrcpy (newargv[j], t);
-
- t = mystrtok (t);
- paramlen += strlen (newargv[j]) + 1;
- }
-
- if (strncmp (newargv[0], "~emacs/", 7) == 0)
- {
- if (posix_to_mac_pathname (newargv[0], tempmacpathname, MAXPATHLEN+1)
- == 0)
- return -1;
- }
- else
- { /* sometimes Emacs call "sh" without a path for the command */
-#if 0
- char *t = (char *) alloca (strlen (newargv[0]) + 7 + 1);
- strcpy (t, "~emacs/");
- strcat (t, newargv[0]);
-#endif /* 0 */
- Lisp_Object path;
- openp (Vexec_path, build_string (newargv[0]), Vexec_suffixes, &path,
- make_number (X_OK));
-
- if (NILP (path))
- return -1;
- if (posix_to_mac_pathname (SDATA (path), tempmacpathname,
- MAXPATHLEN+1) == 0)
- return -1;
- }
- strcpy (macappname, tempmacpathname);
- }
- else
- {
- if (posix_to_mac_pathname (argv[0], macappname, MAXPATHLEN+1) == 0)
- return -1;
-
- newargv = (char **) alloca (sizeof (char *) * argc);
- newargc = argc;
- for (j = 1; j < argc; j++)
- {
- if (strncmp (argv[j], "~emacs/", 7) == 0)
- {
- char *t = strchr (argv[j], ' ');
- if (t)
- {
- char tempcmdname[MAXPATHLEN+1], tempmaccmdname[MAXPATHLEN+1];
- strncpy (tempcmdname, argv[j], t-argv[j]);
- tempcmdname[t-argv[j]] = '\0';
- if (posix_to_mac_pathname (tempcmdname, tempmaccmdname,
- MAXPATHLEN+1) == 0)
- return -1;
- newargv[j] = (char *) alloca (strlen (tempmaccmdname)
- + strlen (t) + 1);
- strcpy (newargv[j], tempmaccmdname);
- strcat (newargv[j], t);
- }
- else
- {
- char tempmaccmdname[MAXPATHLEN+1];
- if (posix_to_mac_pathname (argv[j], tempmaccmdname,
- MAXPATHLEN+1) == 0)
- return -1;
- newargv[j] = (char *) alloca (strlen (tempmaccmdname)+1);
- strcpy (newargv[j], tempmaccmdname);
- }
- }
- else
- newargv[j] = argv[j];
- paramlen += strlen (newargv[j]) + 1;
- }
- }
-
- /* After expanding all the arguments, we now know the length of the
- parameter block to be sent to the subprocess as a message
- attached to the HLE. */
- param = (char *) malloc (paramlen + 1);
- if (!param)
- return -1;
-
- p = param;
- *p++ = newargc;
- /* first byte of message contains number of arguments for command */
- strcpy (p, macworkdir);
- p += strlen (macworkdir);
- *p++ = '\0';
- /* null terminate strings sent so it's possible to use strcpy over there */
- strcpy (p, macinfn);
- p += strlen (macinfn);
- *p++ = '\0';
- strcpy (p, macoutfn);
- p += strlen (macoutfn);
- *p++ = '\0';
- strcpy (p, macerrfn);
- p += strlen (macerrfn);
- *p++ = '\0';
- for (j = 1; j < newargc; j++)
- {
- strcpy (p, newargv[j]);
- p += strlen (newargv[j]);
- *p++ = '\0';
- }
-
- c2pstr (macappname);
-
- iErr = FSMakeFSSpec (0, 0, macappname, &spec);
-
- if (iErr != noErr)
- {
- free (param);
- return -1;
- }
-
- lpbr.launchBlockID = extendedBlock;
- lpbr.launchEPBLength = extendedBlockLen;
- lpbr.launchControlFlags = launchContinue + launchNoFileFlags;
- lpbr.launchAppSpec = &spec;
- lpbr.launchAppParameters = NULL;
-
- iErr = LaunchApplication (&lpbr); /* call the subprocess */
- if (iErr != noErr)
- {
- free (param);
- return -1;
- }
-
- send_event.what = kHighLevelEvent;
- send_event.message = kEmacsSubprocessSend;
- /* Event ID stored in "where" unused */
-
- retries = 3;
- /* OS may think current subprocess has terminated if previous one
- terminated recently. */
- do
- {
- iErr = PostHighLevelEvent (&send_event, &lpbr.launchProcessSN, 0, param,
- paramlen + 1, receiverIDisPSN);
- }
- while (iErr == sessClosedErr && retries-- > 0);
-
- if (iErr != noErr)
- {
- free (param);
- return -1;
- }
-
- cursor_region_handle = NewRgn ();
-
- /* Wait for the subprocess to finish, when it will send us a ERPY
- high level event. */
- while (1)
- if (WaitNextEvent (highLevelEventMask, &reply_event, 180,
- cursor_region_handle)
- && reply_event.message == kEmacsSubprocessReply)
- break;
-
- /* The return code is sent through the refCon */
- iErr = AcceptHighLevelEvent (&targ, &ref_con, NULL, &len);
- if (iErr != noErr)
- {
- DisposeHandle ((Handle) cursor_region_handle);
- free (param);
- return -1;
- }
-
- DisposeHandle ((Handle) cursor_region_handle);
- free (param);
-
- return ref_con;
-#endif /* not TARGET_API_MAC_CARBON */
-}
-
-
-DIR *
-opendir (const char *dirname)
-{
- char true_pathname[MAXPATHLEN+1], fully_resolved_name[MAXPATHLEN+1];
- char mac_pathname[MAXPATHLEN+1], vol_name[MAXPATHLEN+1];
- DIR *dirp;
- CInfoPBRec cipb;
- HVolumeParam vpb;
- int len, vol_name_len;
-
- if (find_true_pathname (dirname, true_pathname, MAXPATHLEN+1) == -1)
- return 0;
-
- len = readlink (true_pathname, fully_resolved_name, MAXPATHLEN);
- if (len > -1)
- fully_resolved_name[len] = '\0';
- else
- strcpy (fully_resolved_name, true_pathname);
-
- dirp = (DIR *) malloc (sizeof(DIR));
- if (!dirp)
- return 0;
-
- /* Handle special case when dirname is "/": sets up for readir to
- get all mount volumes. */
- if (strcmp (fully_resolved_name, "/") == 0)
- {
- dirp->getting_volumes = 1; /* special all mounted volumes DIR struct */
- dirp->current_index = 1; /* index for first volume */
- return dirp;
- }
-
- /* Handle typical cases: not accessing all mounted volumes. */
- if (!posix_to_mac_pathname (fully_resolved_name, mac_pathname, MAXPATHLEN+1))
- return 0;
-
- /* Emacs calls opendir without the trailing '/', Mac needs trailing ':' */
- len = strlen (mac_pathname);
- if (mac_pathname[len - 1] != ':' && len < MAXPATHLEN)
- strcat (mac_pathname, ":");
-
- /* Extract volume name */
- vol_name_len = strchr (mac_pathname, ':') - mac_pathname;
- strncpy (vol_name, mac_pathname, vol_name_len);
- vol_name[vol_name_len] = '\0';
- strcat (vol_name, ":");
-
- c2pstr (mac_pathname);
- cipb.hFileInfo.ioNamePtr = mac_pathname;
- /* using full pathname so vRefNum and DirID ignored */
- cipb.hFileInfo.ioVRefNum = 0;
- cipb.hFileInfo.ioDirID = 0;
- cipb.hFileInfo.ioFDirIndex = 0;
- /* set to 0 to get information about specific dir or file */
-
- errno = PBGetCatInfo (&cipb, false);
- if (errno != noErr)
- {
- errno = ENOENT;
- return 0;
- }
-
- if (!(cipb.hFileInfo.ioFlAttrib & 0x10)) /* bit 4 = 1 for directories */
- return 0; /* not a directory */
-
- dirp->dir_id = cipb.dirInfo.ioDrDirID; /* used later in readdir */
- dirp->getting_volumes = 0;
- dirp->current_index = 1; /* index for first file/directory */
-
- c2pstr (vol_name);
- vpb.ioNamePtr = vol_name;
- /* using full pathname so vRefNum and DirID ignored */
- vpb.ioVRefNum = 0;
- vpb.ioVolIndex = -1;
- errno = PBHGetVInfo ((union HParamBlockRec *) &vpb, false);
- if (errno != noErr)
- {
- errno = ENOENT;
- return 0;
- }
-
- dirp->vol_ref_num = vpb.ioVRefNum;
-
- return dirp;
-}
-
-int
-closedir (DIR *dp)
-{
- free (dp);
-
- return 0;
-}
-
-
-struct dirent *
-readdir (DIR *dp)
-{
- HParamBlockRec hpblock;
- CInfoPBRec cipb;
- static struct dirent s_dirent;
- static Str255 s_name;
- int done;
- char *p;
-
- /* Handle the root directory containing the mounted volumes. Call
- PBHGetVInfo specifying an index to obtain the info for a volume.
- PBHGetVInfo returns an error when it receives an index beyond the
- last volume, at which time we should return a nil dirent struct
- pointer. */
- if (dp->getting_volumes)
- {
- hpblock.volumeParam.ioNamePtr = s_name;
- hpblock.volumeParam.ioVRefNum = 0;
- hpblock.volumeParam.ioVolIndex = dp->current_index;
-
- errno = PBHGetVInfo (&hpblock, false);
- if (errno != noErr)
- {
- errno = ENOENT;
- return 0;
- }
-
- p2cstr (s_name);
- strcat (s_name, "/"); /* need "/" for stat to work correctly */
-
- dp->current_index++;
-
- s_dirent.d_ino = hpblock.volumeParam.ioVRefNum;
- s_dirent.d_name = s_name;
-
- return &s_dirent;
- }
- else
- {
- cipb.hFileInfo.ioVRefNum = dp->vol_ref_num;
- cipb.hFileInfo.ioNamePtr = s_name;
- /* location to receive filename returned */
-
- /* return only visible files */
- done = false;
- while (!done)
- {
- cipb.hFileInfo.ioDirID = dp->dir_id;
- /* directory ID found by opendir */
- cipb.hFileInfo.ioFDirIndex = dp->current_index;
-
- errno = PBGetCatInfo (&cipb, false);
- if (errno != noErr)
- {
- errno = ENOENT;
- return 0;
- }
-
- /* insist on a visible entry */
- if (cipb.hFileInfo.ioFlAttrib & 0x10) /* directory? */
- done = !(cipb.dirInfo.ioDrUsrWds.frFlags & fInvisible);
- else
- done = !(cipb.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible);
-
- dp->current_index++;
- }
-
- p2cstr (s_name);
-
- p = s_name;
- while (*p)
- {
- if (*p == '/')
- *p = ':';
- p++;
- }
-
- s_dirent.d_ino = cipb.dirInfo.ioDrDirID;
- /* value unimportant: non-zero for valid file */
- s_dirent.d_name = s_name;
-
- return &s_dirent;
- }
-}
-
-
-char *
-getwd (char *path)
-{
- char mac_pathname[MAXPATHLEN+1];
- Str255 directory_name;
- OSErr errno;
- CInfoPBRec cipb;
-
- if (path_from_vol_dir_name (mac_pathname, 255, 0, 0, "\p") == 0)
- return NULL;
-
- if (mac_to_posix_pathname (mac_pathname, path, MAXPATHLEN+1) == 0)
- return 0;
- else
- return path;
-}
-
-#endif /* ! MAC_OSX */
-
-
-void
-initialize_applescript ()
-{
- AEDesc null_desc;
- OSAError osaerror;
-
- /* if open fails, as_scripting_component is set to NULL. Its
- subsequent use in OSA calls will fail with badComponentInstance
- error. */
- as_scripting_component = OpenDefaultComponent (kOSAComponentType,
- kAppleScriptSubtype);
-
- null_desc.descriptorType = typeNull;
- null_desc.dataHandle = 0;
- osaerror = OSAMakeContext (as_scripting_component, &null_desc,
- kOSANullScript, &as_script_context);
- if (osaerror)
- as_script_context = kOSANullScript;
- /* use default context if create fails */
-}
-
-
-void
-terminate_applescript()
-{
- OSADispose (as_scripting_component, as_script_context);
- CloseComponent (as_scripting_component);
-}
-
-/* Convert a lisp string to the 4 byte character code. */
-
-OSType
-mac_get_code_from_arg(Lisp_Object arg, OSType defCode)
-{
- OSType result;
- if (NILP(arg))
- {
- result = defCode;
- }
- else
- {
- /* check type string */
- CHECK_STRING(arg);
- if (SBYTES (arg) != 4)
- {
- error ("Wrong argument: need string of length 4 for code");
- }
- result = EndianU32_BtoN (*((UInt32 *) SDATA (arg)));
- }
- return result;
-}
-
-/* Convert the 4 byte character code into a 4 byte string. */
-
-Lisp_Object
-mac_get_object_from_code(OSType defCode)
-{
- UInt32 code = EndianU32_NtoB (defCode);
-
- return make_unibyte_string ((char *)&code, 4);
-}
-
-
-DEFUN ("mac-get-file-creator", Fmac_get_file_creator, Smac_get_file_creator, 1, 1, 0,
- doc: /* Get the creator code of FILENAME as a four character string. */)
- (filename)
- Lisp_Object filename;
-{
- OSStatus status;
-#ifdef MAC_OSX
- FSRef fref;
-#else
- FSSpec fss;
-#endif
- Lisp_Object result = Qnil;
- CHECK_STRING (filename);
-
- if (NILP(Ffile_exists_p(filename)) || !NILP(Ffile_directory_p(filename))) {
- return Qnil;
- }
- filename = Fexpand_file_name (filename, Qnil);
-
- BLOCK_INPUT;
-#ifdef MAC_OSX
- status = FSPathMakeRef(SDATA(ENCODE_FILE(filename)), &fref, NULL);
-#else
- status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (filename)), &fss);
-#endif
-
- if (status == noErr)
- {
-#ifdef MAC_OSX
- FSCatalogInfo catalogInfo;
-
- status = FSGetCatalogInfo(&fref, kFSCatInfoFinderInfo,
- &catalogInfo, NULL, NULL, NULL);
-#else
- FInfo finder_info;
-
- status = FSpGetFInfo (&fss, &finder_info);
-#endif
- if (status == noErr)
- {
-#ifdef MAC_OSX
- result = mac_get_object_from_code(((FileInfo*)&catalogInfo.finderInfo)->fileCreator);
-#else
- result = mac_get_object_from_code (finder_info.fdCreator);
-#endif
- }
- }
- UNBLOCK_INPUT;
- if (status != noErr) {
- error ("Error while getting file information.");
- }
- return result;
-}
-
-DEFUN ("mac-get-file-type", Fmac_get_file_type, Smac_get_file_type, 1, 1, 0,
- doc: /* Get the type code of FILENAME as a four character string. */)
- (filename)
- Lisp_Object filename;
-{
- OSStatus status;
-#ifdef MAC_OSX
- FSRef fref;
-#else
- FSSpec fss;
-#endif
- Lisp_Object result = Qnil;
- CHECK_STRING (filename);
-
- if (NILP(Ffile_exists_p(filename)) || !NILP(Ffile_directory_p(filename))) {
- return Qnil;
- }
- filename = Fexpand_file_name (filename, Qnil);
-
- BLOCK_INPUT;
-#ifdef MAC_OSX
- status = FSPathMakeRef(SDATA(ENCODE_FILE(filename)), &fref, NULL);
-#else
- status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (filename)), &fss);
-#endif
-
- if (status == noErr)
- {
-#ifdef MAC_OSX
- FSCatalogInfo catalogInfo;
-
- status = FSGetCatalogInfo(&fref, kFSCatInfoFinderInfo,
- &catalogInfo, NULL, NULL, NULL);
-#else
- FInfo finder_info;
-
- status = FSpGetFInfo (&fss, &finder_info);
-#endif
- if (status == noErr)
- {
-#ifdef MAC_OSX
- result = mac_get_object_from_code(((FileInfo*)&catalogInfo.finderInfo)->fileType);
-#else
- result = mac_get_object_from_code (finder_info.fdType);
-#endif
- }
- }
- UNBLOCK_INPUT;
- if (status != noErr) {
- error ("Error while getting file information.");
- }
- return result;
-}
-
-DEFUN ("mac-set-file-creator", Fmac_set_file_creator, Smac_set_file_creator, 1, 2, 0,
- doc: /* Set creator code of file FILENAME to CODE.
-If non-nil, CODE must be a 4-character string. Otherwise, 'EMAx' is
-assumed. Return non-nil if successful. */)
- (filename, code)
- Lisp_Object filename, code;
-{
- OSStatus status;
-#ifdef MAC_OSX
- FSRef fref;
-#else
- FSSpec fss;
-#endif
- OSType cCode;
- CHECK_STRING (filename);
-
- cCode = mac_get_code_from_arg(code, MAC_EMACS_CREATOR_CODE);
-
- if (NILP(Ffile_exists_p(filename)) || !NILP(Ffile_directory_p(filename))) {
- return Qnil;
- }
- filename = Fexpand_file_name (filename, Qnil);
-
- BLOCK_INPUT;
-#ifdef MAC_OSX
- status = FSPathMakeRef(SDATA(ENCODE_FILE(filename)), &fref, NULL);
-#else
- status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (filename)), &fss);
-#endif
-
- if (status == noErr)
- {
-#ifdef MAC_OSX
- FSCatalogInfo catalogInfo;
- FSRef parentDir;
- status = FSGetCatalogInfo(&fref, kFSCatInfoFinderInfo,
- &catalogInfo, NULL, NULL, &parentDir);
-#else
- FInfo finder_info;
-
- status = FSpGetFInfo (&fss, &finder_info);
-#endif
- if (status == noErr)
- {
-#ifdef MAC_OSX
- ((FileInfo*)&catalogInfo.finderInfo)->fileCreator = cCode;
- status = FSSetCatalogInfo(&fref, kFSCatInfoFinderInfo, &catalogInfo);
- /* TODO: on Mac OS 10.2, we need to touch the parent dir, FNNotify? */
-#else
- finder_info.fdCreator = cCode;
- status = FSpSetFInfo (&fss, &finder_info);
-#endif
- }
- }
- UNBLOCK_INPUT;
- if (status != noErr) {
- error ("Error while setting creator information.");
- }
- return Qt;
-}
-
-DEFUN ("mac-set-file-type", Fmac_set_file_type, Smac_set_file_type, 2, 2, 0,
- doc: /* Set file code of file FILENAME to CODE.
-CODE must be a 4-character string. Return non-nil if successful. */)
- (filename, code)
- Lisp_Object filename, code;
-{
- OSStatus status;
-#ifdef MAC_OSX
- FSRef fref;
-#else
- FSSpec fss;
-#endif
- OSType cCode;
- CHECK_STRING (filename);
-
- cCode = mac_get_code_from_arg(code, 0); /* Default to empty code*/
-
- if (NILP(Ffile_exists_p(filename)) || !NILP(Ffile_directory_p(filename))) {
- return Qnil;
- }
- filename = Fexpand_file_name (filename, Qnil);
-
- BLOCK_INPUT;
-#ifdef MAC_OSX
- status = FSPathMakeRef(SDATA(ENCODE_FILE(filename)), &fref, NULL);
-#else
- status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (filename)), &fss);
-#endif
-
- if (status == noErr)
- {
-#ifdef MAC_OSX
- FSCatalogInfo catalogInfo;
- FSRef parentDir;
- status = FSGetCatalogInfo(&fref, kFSCatInfoFinderInfo,
- &catalogInfo, NULL, NULL, &parentDir);
-#else
- FInfo finder_info;
-
- status = FSpGetFInfo (&fss, &finder_info);
-#endif
- if (status == noErr)
- {
-#ifdef MAC_OSX
- ((FileInfo*)&catalogInfo.finderInfo)->fileType = cCode;
- status = FSSetCatalogInfo(&fref, kFSCatInfoFinderInfo, &catalogInfo);
- /* TODO: on Mac OS 10.2, we need to touch the parent dir, FNNotify? */
-#else
- finder_info.fdType = cCode;
- status = FSpSetFInfo (&fss, &finder_info);
-#endif
- }
- }
- UNBLOCK_INPUT;
- if (status != noErr) {
- error ("Error while setting creator information.");
- }
- return Qt;
-}
-
-
-/* Compile and execute the AppleScript SCRIPT and return the error
- status as function value. A zero is returned if compilation and
- execution is successful, in which case *RESULT is set to a Lisp
- string containing the resulting script value. Otherwise, the Mac
- error code is returned and *RESULT is set to an error Lisp string.
- For documentation on the MacOS scripting architecture, see Inside
- Macintosh - Interapplication Communications: Scripting
- Components. */
-
-static long
-do_applescript (script, result)
- Lisp_Object script, *result;
-{
- AEDesc script_desc, result_desc, error_desc, *desc = NULL;
- OSErr error;
- OSAError osaerror;
-
- *result = Qnil;
-
- if (!as_scripting_component)
- initialize_applescript();
-
- error = AECreateDesc (typeChar, SDATA (script), SBYTES (script),
- &script_desc);
- if (error)
- return error;
-
- osaerror = OSADoScript (as_scripting_component, &script_desc, kOSANullScript,
- typeChar, kOSAModeNull, &result_desc);
-
- if (osaerror == noErr)
- /* success: retrieve resulting script value */
- desc = &result_desc;
- else if (osaerror == errOSAScriptError)
- /* error executing AppleScript: retrieve error message */
- if (!OSAScriptError (as_scripting_component, kOSAErrorMessage, typeChar,
- &error_desc))
- desc = &error_desc;
-
- if (desc)
- {
-#if TARGET_API_MAC_CARBON
- *result = make_uninit_string (AEGetDescDataSize (desc));
- AEGetDescData (desc, SDATA (*result), SBYTES (*result));
-#else /* not TARGET_API_MAC_CARBON */
- *result = make_uninit_string (GetHandleSize (desc->dataHandle));
- memcpy (SDATA (*result), *(desc->dataHandle), SBYTES (*result));
-#endif /* not TARGET_API_MAC_CARBON */
- AEDisposeDesc (desc);
- }
-
- AEDisposeDesc (&script_desc);
-
- return osaerror;
-}
-
-
-DEFUN ("do-applescript", Fdo_applescript, Sdo_applescript, 1, 1, 0,
- doc: /* Compile and execute AppleScript SCRIPT and return the result.
-If compilation and execution are successful, the resulting script
-value is returned as a string. Otherwise the function aborts and
-displays the error message returned by the AppleScript scripting
-component. */)
- (script)
- Lisp_Object script;
-{
- Lisp_Object result;
- long status;
-
- CHECK_STRING (script);
-
- BLOCK_INPUT;
- status = do_applescript (script, &result);
- UNBLOCK_INPUT;
- if (status == 0)
- return result;
- else if (!STRINGP (result))
- error ("AppleScript error %d", status);
- else
- error ("%s", SDATA (result));
-}
-
-
-DEFUN ("mac-file-name-to-posix", Fmac_file_name_to_posix,
- Smac_file_name_to_posix, 1, 1, 0,
- doc: /* Convert Macintosh FILENAME to Posix form. */)
- (filename)
- Lisp_Object filename;
-{
- char posix_filename[MAXPATHLEN+1];
-
- CHECK_STRING (filename);
-
- if (mac_to_posix_pathname (SDATA (filename), posix_filename, MAXPATHLEN))
- return build_string (posix_filename);
- else
- return Qnil;
-}
-
-
-DEFUN ("posix-file-name-to-mac", Fposix_file_name_to_mac,
- Sposix_file_name_to_mac, 1, 1, 0,
- doc: /* Convert Posix FILENAME to Mac form. */)
- (filename)
- Lisp_Object filename;
-{
- char mac_filename[MAXPATHLEN+1];
-
- CHECK_STRING (filename);
-
- if (posix_to_mac_pathname (SDATA (filename), mac_filename, MAXPATHLEN))
- return build_string (mac_filename);
- else
- return Qnil;
-}
-
-
-DEFUN ("mac-coerce-ae-data", Fmac_coerce_ae_data, Smac_coerce_ae_data, 3, 3, 0,
- doc: /* Coerce Apple event data SRC-DATA of type SRC-TYPE to DST-TYPE.
-Each type should be a string of length 4 or the symbol
-`undecoded-file-name'. */)
- (src_type, src_data, dst_type)
- Lisp_Object src_type, src_data, dst_type;
-{
- OSErr err;
- Lisp_Object result = Qnil;
- DescType src_desc_type, dst_desc_type;
- AEDesc dst_desc;
-
- CHECK_STRING (src_data);
- if (EQ (src_type, Qundecoded_file_name))
- src_desc_type = TYPE_FILE_NAME;
- else
- src_desc_type = mac_get_code_from_arg (src_type, 0);
-
- if (EQ (dst_type, Qundecoded_file_name))
- dst_desc_type = TYPE_FILE_NAME;
- else
- dst_desc_type = mac_get_code_from_arg (dst_type, 0);
-
- BLOCK_INPUT;
- err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
- dst_desc_type, &dst_desc);
- if (err == noErr)
- {
- result = Fcdr (mac_aedesc_to_lisp (&dst_desc));
- AEDisposeDesc (&dst_desc);
- }
- UNBLOCK_INPUT;
-
- return result;
-}
-
-
-#if TARGET_API_MAC_CARBON
-static Lisp_Object Qxml, Qmime_charset;
-static Lisp_Object QNFD, QNFKD, QNFC, QNFKC, QHFS_plus_D, QHFS_plus_C;
-
-DEFUN ("mac-get-preference", Fmac_get_preference, Smac_get_preference, 1, 4, 0,
- doc: /* Return the application preference value for KEY.
-KEY is either a string specifying a preference key, or a list of key
-strings. If it is a list, the (i+1)-th element is used as a key for
-the CFDictionary value obtained by the i-th element. Return nil if
-lookup is failed at some stage.
-
-Optional arg APPLICATION is an application ID string. If omitted or
-nil, that stands for the current application.
-
-Optional arg FORMAT specifies the data format of the return value. If
-omitted or nil, each Core Foundation object is converted into a
-corresponding Lisp object as follows:
-
- Core Foundation Lisp Tag
- ------------------------------------------------------------
- CFString Multibyte string string
- CFNumber Integer or float number
- CFBoolean Symbol (t or nil) boolean
- CFDate List of three integers date
- (cf. `current-time')
- CFData Unibyte string data
- CFArray Vector array
- CFDictionary Alist or hash table dictionary
- (depending on HASH-BOUND)
-
-If it is t, a symbol that represents the type of the original Core
-Foundation object is prepended. If it is `xml', the value is returned
-as an XML representation.
-
-Optional arg HASH-BOUND specifies which kinds of the list objects,
-alists or hash tables, are used as the targets of the conversion from
-CFDictionary. If HASH-BOUND is a negative integer or nil, always
-generate alists. If HASH-BOUND >= 0, generate an alist if the number
-of keys in the dictionary is smaller than HASH-BOUND, and a hash table
-otherwise. */)
- (key, application, format, hash_bound)
- Lisp_Object key, application, format, hash_bound;
-{
- CFStringRef app_id, key_str;
- CFPropertyListRef app_plist = NULL, plist;
- Lisp_Object result = Qnil, tmp;
- struct gcpro gcpro1, gcpro2;
-
- if (STRINGP (key))
- key = Fcons (key, Qnil);
- else
- {
- CHECK_CONS (key);
- for (tmp = key; CONSP (tmp); tmp = XCDR (tmp))
- CHECK_STRING_CAR (tmp);
- CHECK_LIST_END (tmp, key);
- }
- if (!NILP (application))
- CHECK_STRING (application);
- CHECK_SYMBOL (format);
- if (!NILP (hash_bound))
- CHECK_NUMBER (hash_bound);
-
- GCPRO2 (key, format);
-
- BLOCK_INPUT;
-
- app_id = kCFPreferencesCurrentApplication;
- if (!NILP (application))
- {
- app_id = cfstring_create_with_string (application);
- if (app_id == NULL)
- goto out;
- }
- if (!CFPreferencesAppSynchronize (app_id))
- goto out;
-
- key_str = cfstring_create_with_string (XCAR (key));
- if (key_str == NULL)
- goto out;
- app_plist = CFPreferencesCopyAppValue (key_str, app_id);
- CFRelease (key_str);
- if (app_plist == NULL)
- goto out;
-
- plist = app_plist;
- for (key = XCDR (key); CONSP (key); key = XCDR (key))
- {
- if (CFGetTypeID (plist) != CFDictionaryGetTypeID ())
- break;
- key_str = cfstring_create_with_string (XCAR (key));
- if (key_str == NULL)
- goto out;
- plist = CFDictionaryGetValue (plist, key_str);
- CFRelease (key_str);
- if (plist == NULL)
- goto out;
- }
-
- if (NILP (key))
- {
- if (EQ (format, Qxml))
- {
- CFDataRef data = CFPropertyListCreateXMLData (NULL, plist);
- if (data == NULL)
- goto out;
- result = cfdata_to_lisp (data);
- CFRelease (data);
- }
- else
- result =
- cfproperty_list_to_lisp (plist, EQ (format, Qt),
- NILP (hash_bound) ? -1 : XINT (hash_bound));
- }
-
- out:
- if (app_plist)
- CFRelease (app_plist);
- CFRelease (app_id);
-
- UNBLOCK_INPUT;
-
- UNGCPRO;
-
- return result;
-}
-
-
-static CFStringEncoding
-get_cfstring_encoding_from_lisp (obj)
- Lisp_Object obj;
-{
- CFStringRef iana_name;
- CFStringEncoding encoding = kCFStringEncodingInvalidId;
-
- if (NILP (obj))
- return kCFStringEncodingUnicode;
-
- if (INTEGERP (obj))
- return XINT (obj);
-
- if (SYMBOLP (obj) && !NILP (Fcoding_system_p (obj)))
- {
- Lisp_Object coding_spec, plist;
-
- coding_spec = Fget (obj, Qcoding_system);
- plist = XVECTOR (coding_spec)->contents[3];
- obj = Fplist_get (XVECTOR (coding_spec)->contents[3], Qmime_charset);
- }
-
- if (SYMBOLP (obj))
- obj = SYMBOL_NAME (obj);
-
- if (STRINGP (obj))
- {
- iana_name = cfstring_create_with_string (obj);
- if (iana_name)
- {
- encoding = CFStringConvertIANACharSetNameToEncoding (iana_name);
- CFRelease (iana_name);
- }
- }
-
- return encoding;
-}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-static CFStringRef
-cfstring_create_normalized (str, symbol)
- CFStringRef str;
- Lisp_Object symbol;
-{
- int form = -1;
- TextEncodingVariant variant;
- float initial_mag = 0.0;
- CFStringRef result = NULL;
-
- if (EQ (symbol, QNFD))
- form = kCFStringNormalizationFormD;
- else if (EQ (symbol, QNFKD))
- form = kCFStringNormalizationFormKD;
- else if (EQ (symbol, QNFC))
- form = kCFStringNormalizationFormC;
- else if (EQ (symbol, QNFKC))
- form = kCFStringNormalizationFormKC;
- else if (EQ (symbol, QHFS_plus_D))
- {
- variant = kUnicodeHFSPlusDecompVariant;
- initial_mag = 1.5;
- }
- else if (EQ (symbol, QHFS_plus_C))
- {
- variant = kUnicodeHFSPlusCompVariant;
- initial_mag = 1.0;
- }
-
- if (form >= 0)
- {
- CFMutableStringRef mut_str = CFStringCreateMutableCopy (NULL, 0, str);
-
- if (mut_str)
- {
- CFStringNormalize (mut_str, form);
- result = mut_str;
- }
- }
- else if (initial_mag > 0.0)
- {
- UnicodeToTextInfo uni = NULL;
- UnicodeMapping map;
- CFIndex length;
- UniChar *in_text, *buffer = NULL, *out_buf = NULL;
- OSStatus err = noErr;
- ByteCount out_read, out_size, out_len;
-
- map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
- kUnicodeNoSubset,
- kTextEncodingDefaultFormat);
- map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
- variant,
- kTextEncodingDefaultFormat);
- map.mappingVersion = kUnicodeUseLatestMapping;
-
- length = CFStringGetLength (str);
- out_size = (int)((float)length * initial_mag) * sizeof (UniChar);
- if (out_size < 32)
- out_size = 32;
-
- in_text = (UniChar *)CFStringGetCharactersPtr (str);
- if (in_text == NULL)
- {
- buffer = xmalloc (sizeof (UniChar) * length);
- CFStringGetCharacters (str, CFRangeMake (0, length), buffer);
- in_text = buffer;
- }
-
- if (in_text)
- err = CreateUnicodeToTextInfo (&map, &uni);
- while (err == noErr)
- {
- out_buf = xmalloc (out_size);
- err = ConvertFromUnicodeToText (uni, length * sizeof (UniChar),
- in_text,
- kUnicodeDefaultDirectionMask,
- 0, NULL, NULL, NULL,
- out_size, &out_read, &out_len,
- out_buf);
- if (err == noErr && out_read < length * sizeof (UniChar))
- {
- xfree (out_buf);
- out_size += length;
- }
- else
- break;
- }
- if (err == noErr)
- result = CFStringCreateWithCharacters (NULL, out_buf,
- out_len / sizeof (UniChar));
- if (uni)
- DisposeUnicodeToTextInfo (&uni);
- xfree (out_buf);
- xfree (buffer);
- }
- else
- {
- result = str;
- CFRetain (result);
- }
-
- return result;
-}
-#endif
-
-DEFUN ("mac-code-convert-string", Fmac_code_convert_string, Smac_code_convert_string, 3, 4, 0,
- doc: /* Convert STRING from SOURCE encoding to TARGET encoding.
-The conversion is performed using the converter provided by the system.
-Each encoding is specified by either a coding system symbol, a mime
-charset string, or an integer as a CFStringEncoding value. An encoding
-of nil means UTF-16 in native byte order, no byte order mark.
-On Mac OS X 10.2 and later, you can do Unicode Normalization by
-specifying the optional argument NORMALIZATION-FORM with a symbol NFD,
-NFKD, NFC, NFKC, HFS+D, or HFS+C.
-On successful conversion, return the result string, else return nil. */)
- (string, source, target, normalization_form)
- Lisp_Object string, source, target, normalization_form;
-{
- Lisp_Object result = Qnil;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- CFStringEncoding src_encoding, tgt_encoding;
- CFStringRef str = NULL;
-
- CHECK_STRING (string);
- if (!INTEGERP (source) && !STRINGP (source))
- CHECK_SYMBOL (source);
- if (!INTEGERP (target) && !STRINGP (target))
- CHECK_SYMBOL (target);
- CHECK_SYMBOL (normalization_form);
-
- GCPRO4 (string, source, target, normalization_form);
-
- BLOCK_INPUT;
-
- src_encoding = get_cfstring_encoding_from_lisp (source);
- tgt_encoding = get_cfstring_encoding_from_lisp (target);
-
- /* We really want string_to_unibyte, but since it doesn't exist yet, we
- use string_as_unibyte which works as well, except for the fact that
- it's too permissive (it doesn't check that the multibyte string only
- contain single-byte chars). */
- string = Fstring_as_unibyte (string);
- if (src_encoding != kCFStringEncodingInvalidId
- && tgt_encoding != kCFStringEncodingInvalidId)
- str = CFStringCreateWithBytes (NULL, SDATA (string), SBYTES (string),
- src_encoding, !NILP (source));
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (str)
- {
- CFStringRef saved_str = str;
-
- str = cfstring_create_normalized (saved_str, normalization_form);
- CFRelease (saved_str);
- }
-#endif
- if (str)
- {
- CFIndex str_len, buf_len;
-
- str_len = CFStringGetLength (str);
- if (CFStringGetBytes (str, CFRangeMake (0, str_len), tgt_encoding, 0,
- !NILP (target), NULL, 0, &buf_len) == str_len)
- {
- result = make_uninit_string (buf_len);
- CFStringGetBytes (str, CFRangeMake (0, str_len), tgt_encoding, 0,
- !NILP (target), SDATA (result), buf_len, NULL);
- }
- CFRelease (str);
- }
-
- UNBLOCK_INPUT;
-
- UNGCPRO;
-
- return result;
-}
-
-DEFUN ("mac-process-hi-command", Fmac_process_hi_command, Smac_process_hi_command, 1, 1, 0,
- doc: /* Send a HI command whose ID is COMMAND-ID to the command chain.
-COMMAND-ID must be a 4-character string. Some common command IDs are
-defined in the Carbon Event Manager. */)
- (command_id)
- Lisp_Object command_id;
-{
- OSStatus err;
- HICommand command;
-
- bzero (&command, sizeof (HICommand));
- command.commandID = mac_get_code_from_arg (command_id, 0);
-
- BLOCK_INPUT;
- err = ProcessHICommand (&command);
- UNBLOCK_INPUT;
-
- if (err != noErr)
- error ("HI command (command ID: '%s') not handled.", SDATA (command_id));
-
- return Qnil;
-}
-
-#endif /* TARGET_API_MAC_CARBON */
-
-
-static Lisp_Object
-mac_get_system_locale ()
-{
- OSStatus err;
- LangCode lang;
- RegionCode region;
- LocaleRef locale;
- Str255 str;
-
- lang = GetScriptVariable (smSystemScript, smScriptLang);
- region = GetScriptManagerVariable (smRegionCode);
- err = LocaleRefFromLangOrRegionCode (lang, region, &locale);
- if (err == noErr)
- err = LocaleRefGetPartString (locale, kLocaleAllPartsMask,
- sizeof (str), str);
- if (err == noErr)
- return build_string (str);
- else
- return Qnil;
-}
-
-
-#ifdef MAC_OSX
-
-extern int inhibit_window_system;
-extern int noninteractive;
-
-/* Unlike in X11, window events in Carbon do not come from sockets.
- So we cannot simply use `select' to monitor two kinds of inputs:
- window events and process outputs. We emulate such functionality
- by regarding fd 0 as the window event channel and simultaneously
- monitoring both kinds of input channels. It is implemented by
- dividing into some cases:
- 1. The window event channel is not involved.
- -> Use `select'.
- 2. Sockets are not involved.
- -> Use ReceiveNextEvent.
- 3. [If SELECT_USE_CFSOCKET is set]
- Only the window event channel and socket read/write channels are
- involved, and timeout is not too short (greater than
- SELECT_TIMEOUT_THRESHOLD_RUNLOOP seconds).
- -> Create CFSocket for each socket and add it into the current
- event RunLoop so that the current event loop gets quit when
- the socket becomes ready. Then mac_run_loop_run_once can
- wait for both kinds of inputs.
- 4. Otherwise.
- -> Periodically poll the window input channel while repeatedly
- executing `select' with a short timeout
- (SELECT_POLLING_PERIOD_USEC microseconds). */
-
-#ifndef SELECT_USE_CFSOCKET
-#define SELECT_USE_CFSOCKET 1
-#endif
-
-#define SELECT_POLLING_PERIOD_USEC 100000
-#if SELECT_USE_CFSOCKET
-#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2
-
-/* Dictionary of file descriptors vs CFSocketRef's allocated in
- sys_select. */
-static CFMutableDictionaryRef cfsockets_for_select;
-
-/* Process ID of Emacs. */
-static pid_t mac_emacs_pid;
-
-static void
-socket_callback (s, type, address, data, info)
- CFSocketRef s;
- CFSocketCallBackType type;
- CFDataRef address;
- const void *data;
- void *info;
-{
-}
-#endif /* SELECT_USE_CFSOCKET */
-
-static int
-select_and_poll_event (nfds, rfds, wfds, efds, timeout)
- int nfds;
- SELECT_TYPE *rfds, *wfds, *efds;
- EMACS_TIME *timeout;
-{
- int timedout_p = 0;
- int r = 0;
- EMACS_TIME select_timeout;
- EventTimeout timeoutval =
- (timeout
- ? (EMACS_SECS (*timeout) * kEventDurationSecond
- + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
- : kEventDurationForever);
- SELECT_TYPE orfds, owfds, oefds;
-
- if (timeout == NULL)
- {
- if (rfds) orfds = *rfds;
- if (wfds) owfds = *wfds;
- if (efds) oefds = *efds;
- }
-
- /* Try detect_input_pending before mac_run_loop_run_once in the same
- BLOCK_INPUT block, in case that some input has already been read
- asynchronously. */
- BLOCK_INPUT;
- while (1)
- {
- if (detect_input_pending ())
- break;
-
- EMACS_SET_SECS_USECS (select_timeout, 0, 0);
- r = select (nfds, rfds, wfds, efds, &select_timeout);
- if (r != 0)
- break;
-
- if (timeoutval == 0.0)
- timedout_p = 1;
- else
- timedout_p = mac_run_loop_run_once (timeoutval);
-
- if (timeout == NULL && timedout_p)
- {
- if (rfds) *rfds = orfds;
- if (wfds) *wfds = owfds;
- if (efds) *efds = oefds;
- }
- else
- break;
- }
- UNBLOCK_INPUT;
-
- if (r != 0)
- return r;
- else if (!timedout_p)
- {
- /* Pretend that `select' is interrupted by a signal. */
- detect_input_pending ();
- errno = EINTR;
- return -1;
- }
- else
- return 0;
-}
-
-/* Clean up the CFSocket associated with the file descriptor FD in
- case the same descriptor is used in other threads later. If no
- CFSocket is associated with FD, then return 0 without closing FD.
- Otherwise, return 1 with closing FD. */
-
-int
-mac_try_close_socket (fd)
- int fd;
-{
-#if SELECT_USE_CFSOCKET
- if (getpid () == mac_emacs_pid && cfsockets_for_select)
- {
- void *key = (void *) fd;
- CFSocketRef socket =
- (CFSocketRef) CFDictionaryGetValue (cfsockets_for_select, key);
-
- if (socket)
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- CFOptionFlags flags = CFSocketGetSocketFlags (socket);
-
- if (!(flags & kCFSocketCloseOnInvalidate))
- CFSocketSetSocketFlags (socket, flags | kCFSocketCloseOnInvalidate);
-#endif
- BLOCK_INPUT;
- CFSocketInvalidate (socket);
- CFDictionaryRemoveValue (cfsockets_for_select, key);
- UNBLOCK_INPUT;
-
- return 1;
- }
- }
-#endif
-
- return 0;
-}
-
-int
-sys_select (nfds, rfds, wfds, efds, timeout)
- int nfds;
- SELECT_TYPE *rfds, *wfds, *efds;
- EMACS_TIME *timeout;
-{
- int timedout_p = 0;
- int r;
- EMACS_TIME select_timeout;
- SELECT_TYPE orfds, owfds, oefds;
-
- if (inhibit_window_system || noninteractive
- || nfds < 1 || rfds == NULL || !FD_ISSET (0, rfds))
- return select (nfds, rfds, wfds, efds, timeout);
-
- FD_CLR (0, rfds);
- orfds = *rfds;
-
- if (wfds)
- owfds = *wfds;
- else
- FD_ZERO (&owfds);
-
- if (efds)
- oefds = *efds;
- else
- {
- EventTimeout timeoutval =
- (timeout
- ? (EMACS_SECS (*timeout) * kEventDurationSecond
- + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
- : kEventDurationForever);
-
- FD_SET (0, rfds); /* sentinel */
- do
- {
- nfds--;
- }
- while (!(FD_ISSET (nfds, rfds) || (wfds && FD_ISSET (nfds, wfds))));
- nfds++;
- FD_CLR (0, rfds);
-
- if (nfds == 1)
- return select_and_poll_event (nfds, rfds, wfds, efds, timeout);
-
- /* Avoid initial overhead of RunLoop setup for the case that
- some input is already available. */
- EMACS_SET_SECS_USECS (select_timeout, 0, 0);
- r = select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
- if (r != 0 || timeoutval == 0.0)
- return r;
-
- *rfds = orfds;
- if (wfds)
- *wfds = owfds;
-
-#if SELECT_USE_CFSOCKET
- if (timeoutval > 0 && timeoutval <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP)
- goto poll_periodically;
-
- /* Try detect_input_pending before mac_run_loop_run_once in the
- same BLOCK_INPUT block, in case that some input has already
- been read asynchronously. */
- BLOCK_INPUT;
- if (!detect_input_pending ())
- {
- int minfd, fd;
- CFRunLoopRef runloop =
- (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ());
- static CFMutableDictionaryRef sources;
-
- if (sources == NULL)
- sources =
- CFDictionaryCreateMutable (NULL, 0, NULL,
- &kCFTypeDictionaryValueCallBacks);
-
- if (cfsockets_for_select == NULL)
- cfsockets_for_select =
- CFDictionaryCreateMutable (NULL, 0, NULL,
- &kCFTypeDictionaryValueCallBacks);
-
- for (minfd = 1; ; minfd++) /* nfds-1 works as a sentinel. */
- if (FD_ISSET (minfd, rfds) || (wfds && FD_ISSET (minfd, wfds)))
- break;
-
- for (fd = minfd; fd < nfds; fd++)
- if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
- {
- void *key = (void *) fd;
- CFRunLoopSourceRef source =
- (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
-
- if (source == NULL || !CFRunLoopSourceIsValid (source))
- {
- CFSocketRef socket =
- CFSocketCreateWithNative (NULL, fd,
- (kCFSocketReadCallBack
- | kCFSocketConnectCallBack),
- socket_callback, NULL);
-
- if (socket == NULL)
- continue;
- CFDictionarySetValue (cfsockets_for_select, key, socket);
- source = CFSocketCreateRunLoopSource (NULL, socket, 0);
- CFRelease (socket);
- if (source == NULL)
- continue;
- CFDictionarySetValue (sources, key, source);
- CFRelease (source);
- }
- CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
- }
-
- timedout_p = mac_run_loop_run_once (timeoutval);
-
- for (fd = minfd; fd < nfds; fd++)
- if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
- {
- void *key = (void *) fd;
- CFRunLoopSourceRef source =
- (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
-
- CFRunLoopRemoveSource (runloop, source, kCFRunLoopDefaultMode);
- }
- }
- UNBLOCK_INPUT;
-
- if (!timedout_p)
- {
- EMACS_SET_SECS_USECS (select_timeout, 0, 0);
- return select_and_poll_event (nfds, rfds, wfds, efds,
- &select_timeout);
- }
- else
- {
- FD_ZERO (rfds);
- if (wfds)
- FD_ZERO (wfds);
- return 0;
- }
-#endif /* SELECT_USE_CFSOCKET */
- }
-
- poll_periodically:
- {
- EMACS_TIME end_time, now, remaining_time;
-
- if (timeout)
- {
- remaining_time = *timeout;
- EMACS_GET_TIME (now);
- EMACS_ADD_TIME (end_time, now, remaining_time);
- }
-
- do
- {
- EMACS_SET_SECS_USECS (select_timeout, 0, SELECT_POLLING_PERIOD_USEC);
- if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
- select_timeout = remaining_time;
- r = select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
- if (r != 0)
- return r;
-
- *rfds = orfds;
- if (wfds)
- *wfds = owfds;
- if (efds)
- *efds = oefds;
-
- if (timeout)
- {
- EMACS_GET_TIME (now);
- EMACS_SUB_TIME (remaining_time, end_time, now);
- }
- }
- while (!timeout || EMACS_TIME_LT (now, end_time));
-
- EMACS_SET_SECS_USECS (select_timeout, 0, 0);
- return select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
- }
-}
-
-/* Set up environment variables so that Emacs can correctly find its
- support files when packaged as an application bundle. Directories
- placed in /usr/local/share/emacs/<emacs-version>/, /usr/local/bin,
- and /usr/local/libexec/emacs/<emacs-version>/<system-configuration>
- by `make install' by default can instead be placed in
- .../Emacs.app/Contents/Resources/ and
- .../Emacs.app/Contents/MacOS/. Each of these environment variables
- is changed only if it is not already set. Presumably if the user
- sets an environment variable, he will want to use files in his path
- instead of ones in the application bundle. */
-void
-init_mac_osx_environment ()
-{
- CFBundleRef bundle;
- CFURLRef bundleURL;
- CFStringRef cf_app_bundle_pathname;
- int app_bundle_pathname_len;
- char *app_bundle_pathname;
- char *p, *q;
- struct stat st;
-
- mac_emacs_pid = getpid ();
-
- /* Initialize locale related variables. */
- mac_system_script_code =
- (ScriptCode) GetScriptManagerVariable (smSysScript);
- Vmac_system_locale = mac_get_system_locale ();
-
- /* Fetch the pathname of the application bundle as a C string into
- app_bundle_pathname. */
-
- bundle = CFBundleGetMainBundle ();
- if (!bundle || CFBundleGetIdentifier (bundle) == NULL)
- {
- /* We could not find the bundle identifier. For now, prevent
- the fatal error by bringing it up in the terminal. */
- inhibit_window_system = 1;
- return;
- }
-
- bundleURL = CFBundleCopyBundleURL (bundle);
- if (!bundleURL)
- return;
-
- cf_app_bundle_pathname = CFURLCopyFileSystemPath (bundleURL,
- kCFURLPOSIXPathStyle);
- app_bundle_pathname_len = CFStringGetLength (cf_app_bundle_pathname);
- app_bundle_pathname = (char *) alloca (app_bundle_pathname_len + 1);
-
- if (!CFStringGetCString (cf_app_bundle_pathname,
- app_bundle_pathname,
- app_bundle_pathname_len + 1,
- kCFStringEncodingISOLatin1))
- {
- CFRelease (cf_app_bundle_pathname);
- return;
- }
-
- CFRelease (cf_app_bundle_pathname);
-
- /* P should have sufficient room for the pathname of the bundle plus
- the subpath in it leading to the respective directories. Q
- should have three times that much room because EMACSLOADPATH can
- have the value "<path to site-lisp dir>:<path to lisp dir>:<path
- to leim dir>". */
- p = (char *) alloca (app_bundle_pathname_len + 50);
- q = (char *) alloca (3 * app_bundle_pathname_len + 150);
- if (!getenv ("EMACSLOADPATH"))
- {
- q[0] = '\0';
-
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/Resources/site-lisp");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- strcat (q, p);
-
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/Resources/lisp");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- {
- if (q[0] != '\0')
- strcat (q, ":");
- strcat (q, p);
- }
-
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/Resources/leim");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- {
- if (q[0] != '\0')
- strcat (q, ":");
- strcat (q, p);
- }
-
- if (q[0] != '\0')
- setenv ("EMACSLOADPATH", q, 1);
- }
-
- if (!getenv ("EMACSPATH"))
- {
- q[0] = '\0';
-
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/MacOS/libexec");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- strcat (q, p);
-
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/MacOS/bin");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- {
- if (q[0] != '\0')
- strcat (q, ":");
- strcat (q, p);
- }
-
- if (q[0] != '\0')
- setenv ("EMACSPATH", q, 1);
- }
-
- if (!getenv ("EMACSDATA"))
- {
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/Resources/etc");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- setenv ("EMACSDATA", p, 1);
- }
-
- if (!getenv ("EMACSDOC"))
- {
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/Resources/etc");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- setenv ("EMACSDOC", p, 1);
- }
-
- if (!getenv ("INFOPATH"))
- {
- strcpy (p, app_bundle_pathname);
- strcat (p, "/Contents/Resources/info");
- if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
- setenv ("INFOPATH", p, 1);
- }
-}
-#endif /* MAC_OSX */
-
-#if TARGET_API_MAC_CARBON
-void
-mac_wakeup_from_rne ()
-{
-#ifndef MAC_OSX
- if (wakeup_from_rne_enabled_p)
- /* Post a harmless event so as to wake up from
- ReceiveNextEvent. */
- mac_post_mouse_moved_event ();
-#endif
-}
-#endif
-
-void
-syms_of_mac ()
-{
- Qundecoded_file_name = intern ("undecoded-file-name");
- staticpro (&Qundecoded_file_name);
-
-#if TARGET_API_MAC_CARBON
- Qstring = intern ("string"); staticpro (&Qstring);
- Qnumber = intern ("number"); staticpro (&Qnumber);
- Qboolean = intern ("boolean"); staticpro (&Qboolean);
- Qdate = intern ("date"); staticpro (&Qdate);
- Qdata = intern ("data"); staticpro (&Qdata);
- Qarray = intern ("array"); staticpro (&Qarray);
- Qdictionary = intern ("dictionary"); staticpro (&Qdictionary);
-
- Qxml = intern ("xml");
- staticpro (&Qxml);
-
- Qmime_charset = intern ("mime-charset");
- staticpro (&Qmime_charset);
-
- QNFD = intern ("NFD"); staticpro (&QNFD);
- QNFKD = intern ("NFKD"); staticpro (&QNFKD);
- QNFC = intern ("NFC"); staticpro (&QNFC);
- QNFKC = intern ("NFKC"); staticpro (&QNFKC);
- QHFS_plus_D = intern ("HFS+D"); staticpro (&QHFS_plus_D);
- QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C);
-#endif
-
- {
- int i;
-
- for (i = 0; i < sizeof (ae_attr_table) / sizeof (ae_attr_table[0]); i++)
- {
- ae_attr_table[i].symbol = intern (ae_attr_table[i].name);
- staticpro (&ae_attr_table[i].symbol);
- }
- }
-
- defsubr (&Smac_coerce_ae_data);
-#if TARGET_API_MAC_CARBON
- defsubr (&Smac_get_preference);
- defsubr (&Smac_code_convert_string);
- defsubr (&Smac_process_hi_command);
-#endif
-
- defsubr (&Smac_set_file_creator);
- defsubr (&Smac_set_file_type);
- defsubr (&Smac_get_file_creator);
- defsubr (&Smac_get_file_type);
- defsubr (&Sdo_applescript);
- defsubr (&Smac_file_name_to_posix);
- defsubr (&Sposix_file_name_to_mac);
-
- DEFVAR_INT ("mac-system-script-code", &mac_system_script_code,
- doc: /* The system script code. */);
- mac_system_script_code = (ScriptCode) GetScriptManagerVariable (smSysScript);
-
- DEFVAR_LISP ("mac-system-locale", &Vmac_system_locale,
- doc: /* The system locale identifier string.
-This is not a POSIX locale ID, but an ICU locale ID. So encoding
-information is not included. */);
- Vmac_system_locale = mac_get_system_locale ();
-}
-
-/* arch-tag: 29d30c1f-0c6b-4f88-8a6d-0558d7f9dbff
- (do not change this comment) */
diff --git a/src/macfns.c b/src/macfns.c
deleted file mode 100644
index cb1e74c15f8..00000000000
--- a/src/macfns.c
+++ /dev/null
@@ -1,4429 +0,0 @@
-/* Graphical user interface functions for Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Contributed by Andrew Choi (akochoi@mac.com). */
-
-#include <config.h>
-#include <stdio.h>
-#include <math.h>
-
-#include "lisp.h"
-#include "macterm.h"
-#include "frame.h"
-#include "window.h"
-#include "buffer.h"
-#include "intervals.h"
-#include "dispextern.h"
-#include "keyboard.h"
-#include "blockinput.h"
-#include <epaths.h>
-#include "charset.h"
-#include "coding.h"
-#include "fontset.h"
-#include "systime.h"
-#include "termhooks.h"
-#include "atimer.h"
-
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/param.h>
-
-extern void free_frame_menubar ();
-
-#if TARGET_API_MAC_CARBON
-
-/* Carbon version info */
-
-static Lisp_Object Vmac_carbon_version_string;
-
-#endif /* TARGET_API_MAC_CARBON */
-
-/* The background and shape of the mouse pointer, and shape when not
- over text or in the modeline. */
-
-Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
-Lisp_Object Vx_hourglass_pointer_shape;
-
-/* The shape when over mouse-sensitive text. */
-
-Lisp_Object Vx_sensitive_text_pointer_shape;
-
-/* If non-nil, the pointer shape to indicate that windows can be
- dragged horizontally. */
-
-Lisp_Object Vx_window_horizontal_drag_shape;
-
-/* Color of chars displayed in cursor box. */
-
-Lisp_Object Vx_cursor_fore_pixel;
-
-/* Nonzero if using Windows. */
-
-static int mac_in_use;
-
-/* Non nil if no window manager is in use. */
-
-Lisp_Object Vx_no_window_manager;
-
-/* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
-
-Lisp_Object Vx_pixel_size_width_font_regexp;
-
-Lisp_Object Qnone;
-Lisp_Object Qsuppress_icon;
-Lisp_Object Qundefined_color;
-Lisp_Object Qcancel_timer;
-
-/* In dispnew.c */
-
-extern Lisp_Object Vwindow_system_version;
-
-#if GLYPH_DEBUG
-int image_cache_refcount, dpyinfo_refcount;
-#endif
-
-#if 0 /* Use xstrcasecmp instead. */
-/* compare two strings ignoring case */
-
-static int
-stricmp (const char *s, const char *t)
-{
- for ( ; tolower (*s) == tolower (*t); s++, t++)
- if (*s == '\0')
- return 0;
- return tolower (*s) - tolower (*t);
-}
-#endif
-
-/* compare two strings up to n characters, ignoring case */
-
-static int
-strnicmp (const char *s, const char *t, unsigned int n)
-{
- for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++)
- if (*s == '\0')
- return 0;
- return n == 0 ? 0 : tolower (*s) - tolower (*t);
-}
-
-
-/* Error if we are not running on Mac OS. */
-
-void
-check_mac ()
-{
- if (! mac_in_use)
- error ("Mac native windows not in use or not initialized");
-}
-
-/* Nonzero if we can use mouse menus.
- You should not call this unless HAVE_MENUS is defined. */
-
-int
-have_menus_p ()
-{
- return mac_in_use;
-}
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
- and checking validity for Mac. */
-
-FRAME_PTR
-check_x_frame (frame)
- Lisp_Object frame;
-{
- FRAME_PTR f;
-
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
- if (! FRAME_MAC_P (f))
- error ("Non-Mac frame used");
- return f;
-}
-
-/* Let the user specify a display with a frame.
- nil stands for the selected frame--or, if that is not a mac frame,
- the first display on the list. */
-
-struct mac_display_info *
-check_x_display_info (frame)
- Lisp_Object frame;
-{
- struct mac_display_info *dpyinfo = NULL;
-
- if (NILP (frame))
- {
- struct frame *sf = XFRAME (selected_frame);
-
- if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
- dpyinfo = FRAME_MAC_DISPLAY_INFO (sf);
- else if (x_display_list != 0)
- dpyinfo = x_display_list;
- else
- error ("Mac native windows are not in use or not initialized");
- }
- else if (STRINGP (frame))
- dpyinfo = x_display_info_for_name (frame);
- else
- {
- FRAME_PTR f = check_x_frame (frame);
- dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- }
-
- return dpyinfo;
-}
-
-
-
-static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
-static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
-
-void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-
-
-/* Store the screen positions of frame F into XPTR and YPTR.
- These are the positions of the containing window manager window,
- not Emacs's own window. */
-
-void
-x_real_positions (f, xptr, yptr)
- FRAME_PTR f;
- int *xptr, *yptr;
-{
- Rect inner, outer;
-
- mac_get_window_bounds (f, &inner, &outer);
-
- f->x_pixels_diff = inner.left - outer.left;
- f->y_pixels_diff = inner.top - outer.top;
-
- *xptr = outer.left;
- *yptr = outer.top;
-}
-
-
-/* The default colors for the Mac color map */
-typedef struct colormap_t
-{
- unsigned long color;
- char *name;
-} colormap_t;
-
-static const colormap_t mac_color_map[] =
-{
- { RGB_TO_ULONG(255, 250, 250), "snow" },
- { RGB_TO_ULONG(248, 248, 255), "ghost white" },
- { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
- { RGB_TO_ULONG(245, 245, 245), "white smoke" },
- { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
- { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
- { RGB_TO_ULONG(255, 250, 240), "floral white" },
- { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
- { RGB_TO_ULONG(253, 245, 230), "old lace" },
- { RGB_TO_ULONG(253, 245, 230), "OldLace" },
- { RGB_TO_ULONG(250, 240, 230), "linen" },
- { RGB_TO_ULONG(250, 235, 215), "antique white" },
- { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
- { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
- { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
- { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
- { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
- { RGB_TO_ULONG(255, 228, 196), "bisque" },
- { RGB_TO_ULONG(255, 218, 185), "peach puff" },
- { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
- { RGB_TO_ULONG(255, 222, 173), "navajo white" },
- { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
- { RGB_TO_ULONG(255, 228, 181), "moccasin" },
- { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
- { RGB_TO_ULONG(255, 255, 240), "ivory" },
- { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
- { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
- { RGB_TO_ULONG(255, 245, 238), "seashell" },
- { RGB_TO_ULONG(240, 255, 240), "honeydew" },
- { RGB_TO_ULONG(245, 255, 250), "mint cream" },
- { RGB_TO_ULONG(245, 255, 250), "MintCream" },
- { RGB_TO_ULONG(240, 255, 255), "azure" },
- { RGB_TO_ULONG(240, 248, 255), "alice blue" },
- { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
- { RGB_TO_ULONG(230, 230, 250), "lavender" },
- { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
- { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
- { RGB_TO_ULONG(255, 228, 225), "misty rose" },
- { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
- { RGB_TO_ULONG(255, 255, 255), "white" },
- { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
- { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
- { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
- { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
- { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
- { RGB_TO_ULONG(105, 105, 105), "dim gray" },
- { RGB_TO_ULONG(105, 105, 105), "DimGray" },
- { RGB_TO_ULONG(105, 105, 105), "dim grey" },
- { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
- { RGB_TO_ULONG(112, 128, 144), "slate gray" },
- { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
- { RGB_TO_ULONG(112, 128, 144), "slate grey" },
- { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
- { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
- { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
- { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
- { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
- { RGB_TO_ULONG(190, 190, 190), "gray" },
- { RGB_TO_ULONG(190, 190, 190), "grey" },
- { RGB_TO_ULONG(211, 211, 211), "light grey" },
- { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
- { RGB_TO_ULONG(211, 211, 211), "light gray" },
- { RGB_TO_ULONG(211, 211, 211), "LightGray" },
- { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
- { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
- { RGB_TO_ULONG(0 , 0 , 128), "navy" },
- { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
- { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
- { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
- { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
- { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
- { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
- { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
- { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
- { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
- { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
- { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
- { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
- { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
- { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
- { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
- { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
- { RGB_TO_ULONG(0 , 0 , 255), "blue" },
- { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
- { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
- { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
- { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
- { RGB_TO_ULONG(135, 206, 235), "sky blue" },
- { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
- { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
- { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
- { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
- { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
- { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
- { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
- { RGB_TO_ULONG(173, 216, 230), "light blue" },
- { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
- { RGB_TO_ULONG(176, 224, 230), "powder blue" },
- { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
- { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
- { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
- { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
- { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
- { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
- { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
- { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
- { RGB_TO_ULONG(0 , 255, 255), "cyan" },
- { RGB_TO_ULONG(224, 255, 255), "light cyan" },
- { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
- { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
- { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
- { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
- { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
- { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
- { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
- { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
- { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
- { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
- { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
- { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
- { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
- { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
- { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
- { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
- { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
- { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
- { RGB_TO_ULONG(152, 251, 152), "pale green" },
- { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
- { RGB_TO_ULONG(0 , 255, 127), "spring green" },
- { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
- { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
- { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
- { RGB_TO_ULONG(0 , 255, 0 ), "green" },
- { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
- { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
- { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
- { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
- { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
- { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
- { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
- { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
- { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
- { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
- { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
- { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
- { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
- { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
- { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
- { RGB_TO_ULONG(240, 230, 140), "khaki" },
- { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
- { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
- { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
- { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
- { RGB_TO_ULONG(255, 255, 224), "light yellow" },
- { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
- { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
- { RGB_TO_ULONG(255, 215, 0 ), "gold" },
- { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
- { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
- { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
- { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
- { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
- { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
- { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
- { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
- { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
- { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
- { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
- { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
- { RGB_TO_ULONG(205, 133, 63 ), "peru" },
- { RGB_TO_ULONG(222, 184, 135), "burlywood" },
- { RGB_TO_ULONG(245, 245, 220), "beige" },
- { RGB_TO_ULONG(245, 222, 179), "wheat" },
- { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
- { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
- { RGB_TO_ULONG(210, 180, 140), "tan" },
- { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
- { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
- { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
- { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
- { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
- { RGB_TO_ULONG(250, 128, 114), "salmon" },
- { RGB_TO_ULONG(255, 160, 122), "light salmon" },
- { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
- { RGB_TO_ULONG(255, 165, 0 ), "orange" },
- { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
- { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
- { RGB_TO_ULONG(255, 127, 80 ), "coral" },
- { RGB_TO_ULONG(240, 128, 128), "light coral" },
- { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
- { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
- { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
- { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
- { RGB_TO_ULONG(255, 0 , 0 ), "red" },
- { RGB_TO_ULONG(255, 105, 180), "hot pink" },
- { RGB_TO_ULONG(255, 105, 180), "HotPink" },
- { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
- { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
- { RGB_TO_ULONG(255, 192, 203), "pink" },
- { RGB_TO_ULONG(255, 182, 193), "light pink" },
- { RGB_TO_ULONG(255, 182, 193), "LightPink" },
- { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
- { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
- { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
- { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
- { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
- { RGB_TO_ULONG(208, 32 , 144), "violet red" },
- { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
- { RGB_TO_ULONG(255, 0 , 255), "magenta" },
- { RGB_TO_ULONG(238, 130, 238), "violet" },
- { RGB_TO_ULONG(221, 160, 221), "plum" },
- { RGB_TO_ULONG(218, 112, 214), "orchid" },
- { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
- { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
- { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
- { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
- { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
- { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
- { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
- { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
- { RGB_TO_ULONG(160, 32 , 240), "purple" },
- { RGB_TO_ULONG(147, 112, 219), "medium purple" },
- { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
- { RGB_TO_ULONG(216, 191, 216), "thistle" },
- { RGB_TO_ULONG(255, 250, 250), "snow1" },
- { RGB_TO_ULONG(238, 233, 233), "snow2" },
- { RGB_TO_ULONG(205, 201, 201), "snow3" },
- { RGB_TO_ULONG(139, 137, 137), "snow4" },
- { RGB_TO_ULONG(255, 245, 238), "seashell1" },
- { RGB_TO_ULONG(238, 229, 222), "seashell2" },
- { RGB_TO_ULONG(205, 197, 191), "seashell3" },
- { RGB_TO_ULONG(139, 134, 130), "seashell4" },
- { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
- { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
- { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
- { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
- { RGB_TO_ULONG(255, 228, 196), "bisque1" },
- { RGB_TO_ULONG(238, 213, 183), "bisque2" },
- { RGB_TO_ULONG(205, 183, 158), "bisque3" },
- { RGB_TO_ULONG(139, 125, 107), "bisque4" },
- { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
- { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
- { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
- { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
- { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
- { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
- { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
- { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
- { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
- { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
- { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
- { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
- { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
- { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
- { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
- { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
- { RGB_TO_ULONG(255, 255, 240), "ivory1" },
- { RGB_TO_ULONG(238, 238, 224), "ivory2" },
- { RGB_TO_ULONG(205, 205, 193), "ivory3" },
- { RGB_TO_ULONG(139, 139, 131), "ivory4" },
- { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
- { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
- { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
- { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
- { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
- { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
- { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
- { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
- { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
- { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
- { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
- { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
- { RGB_TO_ULONG(240, 255, 255), "azure1" },
- { RGB_TO_ULONG(224, 238, 238), "azure2" },
- { RGB_TO_ULONG(193, 205, 205), "azure3" },
- { RGB_TO_ULONG(131, 139, 139), "azure4" },
- { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
- { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
- { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
- { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
- { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
- { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
- { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
- { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
- { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
- { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
- { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
- { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
- { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
- { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
- { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
- { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
- { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
- { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
- { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
- { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
- { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
- { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
- { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
- { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
- { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
- { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
- { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
- { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
- { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
- { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
- { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
- { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
- { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
- { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
- { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
- { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
- { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
- { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
- { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
- { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
- { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
- { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
- { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
- { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
- { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
- { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
- { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
- { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
- { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
- { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
- { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
- { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
- { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
- { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
- { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
- { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
- { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
- { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
- { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
- { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
- { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
- { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
- { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
- { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
- { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
- { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
- { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
- { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
- { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
- { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
- { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
- { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
- { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
- { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
- { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
- { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
- { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
- { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
- { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
- { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
- { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
- { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
- { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
- { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
- { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
- { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
- { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
- { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
- { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
- { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
- { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
- { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
- { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
- { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
- { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
- { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
- { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
- { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
- { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
- { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
- { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
- { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
- { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
- { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
- { RGB_TO_ULONG(255, 246, 143), "khaki1" },
- { RGB_TO_ULONG(238, 230, 133), "khaki2" },
- { RGB_TO_ULONG(205, 198, 115), "khaki3" },
- { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
- { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
- { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
- { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
- { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
- { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
- { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
- { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
- { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
- { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
- { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
- { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
- { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
- { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
- { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
- { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
- { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
- { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
- { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
- { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
- { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
- { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
- { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
- { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
- { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
- { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
- { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
- { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
- { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
- { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
- { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
- { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
- { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
- { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
- { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
- { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
- { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
- { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
- { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
- { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
- { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
- { RGB_TO_ULONG(255, 231, 186), "wheat1" },
- { RGB_TO_ULONG(238, 216, 174), "wheat2" },
- { RGB_TO_ULONG(205, 186, 150), "wheat3" },
- { RGB_TO_ULONG(139, 126, 102), "wheat4" },
- { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
- { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
- { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
- { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
- { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
- { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
- { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
- { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
- { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
- { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
- { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
- { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
- { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
- { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
- { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
- { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
- { RGB_TO_ULONG(255, 140, 105), "salmon1" },
- { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
- { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
- { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
- { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
- { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
- { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
- { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
- { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
- { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
- { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
- { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
- { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
- { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
- { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
- { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
- { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
- { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
- { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
- { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
- { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
- { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
- { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
- { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
- { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
- { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
- { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
- { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
- { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
- { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
- { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
- { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
- { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
- { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
- { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
- { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
- { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
- { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
- { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
- { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
- { RGB_TO_ULONG(255, 181, 197), "pink1" },
- { RGB_TO_ULONG(238, 169, 184), "pink2" },
- { RGB_TO_ULONG(205, 145, 158), "pink3" },
- { RGB_TO_ULONG(139, 99 , 108), "pink4" },
- { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
- { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
- { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
- { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
- { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
- { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
- { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
- { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
- { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
- { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
- { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
- { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
- { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
- { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
- { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
- { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
- { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
- { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
- { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
- { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
- { RGB_TO_ULONG(255, 131, 250), "orchid1" },
- { RGB_TO_ULONG(238, 122, 233), "orchid2" },
- { RGB_TO_ULONG(205, 105, 201), "orchid3" },
- { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
- { RGB_TO_ULONG(255, 187, 255), "plum1" },
- { RGB_TO_ULONG(238, 174, 238), "plum2" },
- { RGB_TO_ULONG(205, 150, 205), "plum3" },
- { RGB_TO_ULONG(139, 102, 139), "plum4" },
- { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
- { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
- { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
- { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
- { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
- { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
- { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
- { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
- { RGB_TO_ULONG(155, 48 , 255), "purple1" },
- { RGB_TO_ULONG(145, 44 , 238), "purple2" },
- { RGB_TO_ULONG(125, 38 , 205), "purple3" },
- { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
- { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
- { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
- { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
- { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
- { RGB_TO_ULONG(255, 225, 255), "thistle1" },
- { RGB_TO_ULONG(238, 210, 238), "thistle2" },
- { RGB_TO_ULONG(205, 181, 205), "thistle3" },
- { RGB_TO_ULONG(139, 123, 139), "thistle4" },
- { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
- { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
- { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
- { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
- { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
- { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
- { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
- { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
- { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
- { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
- { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
- { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
- { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
- { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
- { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
- { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
- { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
- { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
- { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
- { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
- { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
- { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
- { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
- { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
- { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
- { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
- { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
- { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
- { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
- { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
- { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
- { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
- { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
- { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
- { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
- { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
- { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
- { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
- { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
- { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
- { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
- { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
- { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
- { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
- { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
- { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
- { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
- { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
- { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
- { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
- { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
- { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
- { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
- { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
- { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
- { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
- { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
- { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
- { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
- { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
- { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
- { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
- { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
- { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
- { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
- { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
- { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
- { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
- { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
- { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
- { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
- { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
- { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
- { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
- { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
- { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
- { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
- { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
- { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
- { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
- { RGB_TO_ULONG(102, 102, 102), "gray40" },
- { RGB_TO_ULONG(102, 102, 102), "grey40" },
- { RGB_TO_ULONG(105, 105, 105), "gray41" },
- { RGB_TO_ULONG(105, 105, 105), "grey41" },
- { RGB_TO_ULONG(107, 107, 107), "gray42" },
- { RGB_TO_ULONG(107, 107, 107), "grey42" },
- { RGB_TO_ULONG(110, 110, 110), "gray43" },
- { RGB_TO_ULONG(110, 110, 110), "grey43" },
- { RGB_TO_ULONG(112, 112, 112), "gray44" },
- { RGB_TO_ULONG(112, 112, 112), "grey44" },
- { RGB_TO_ULONG(115, 115, 115), "gray45" },
- { RGB_TO_ULONG(115, 115, 115), "grey45" },
- { RGB_TO_ULONG(117, 117, 117), "gray46" },
- { RGB_TO_ULONG(117, 117, 117), "grey46" },
- { RGB_TO_ULONG(120, 120, 120), "gray47" },
- { RGB_TO_ULONG(120, 120, 120), "grey47" },
- { RGB_TO_ULONG(122, 122, 122), "gray48" },
- { RGB_TO_ULONG(122, 122, 122), "grey48" },
- { RGB_TO_ULONG(125, 125, 125), "gray49" },
- { RGB_TO_ULONG(125, 125, 125), "grey49" },
- { RGB_TO_ULONG(127, 127, 127), "gray50" },
- { RGB_TO_ULONG(127, 127, 127), "grey50" },
- { RGB_TO_ULONG(130, 130, 130), "gray51" },
- { RGB_TO_ULONG(130, 130, 130), "grey51" },
- { RGB_TO_ULONG(133, 133, 133), "gray52" },
- { RGB_TO_ULONG(133, 133, 133), "grey52" },
- { RGB_TO_ULONG(135, 135, 135), "gray53" },
- { RGB_TO_ULONG(135, 135, 135), "grey53" },
- { RGB_TO_ULONG(138, 138, 138), "gray54" },
- { RGB_TO_ULONG(138, 138, 138), "grey54" },
- { RGB_TO_ULONG(140, 140, 140), "gray55" },
- { RGB_TO_ULONG(140, 140, 140), "grey55" },
- { RGB_TO_ULONG(143, 143, 143), "gray56" },
- { RGB_TO_ULONG(143, 143, 143), "grey56" },
- { RGB_TO_ULONG(145, 145, 145), "gray57" },
- { RGB_TO_ULONG(145, 145, 145), "grey57" },
- { RGB_TO_ULONG(148, 148, 148), "gray58" },
- { RGB_TO_ULONG(148, 148, 148), "grey58" },
- { RGB_TO_ULONG(150, 150, 150), "gray59" },
- { RGB_TO_ULONG(150, 150, 150), "grey59" },
- { RGB_TO_ULONG(153, 153, 153), "gray60" },
- { RGB_TO_ULONG(153, 153, 153), "grey60" },
- { RGB_TO_ULONG(156, 156, 156), "gray61" },
- { RGB_TO_ULONG(156, 156, 156), "grey61" },
- { RGB_TO_ULONG(158, 158, 158), "gray62" },
- { RGB_TO_ULONG(158, 158, 158), "grey62" },
- { RGB_TO_ULONG(161, 161, 161), "gray63" },
- { RGB_TO_ULONG(161, 161, 161), "grey63" },
- { RGB_TO_ULONG(163, 163, 163), "gray64" },
- { RGB_TO_ULONG(163, 163, 163), "grey64" },
- { RGB_TO_ULONG(166, 166, 166), "gray65" },
- { RGB_TO_ULONG(166, 166, 166), "grey65" },
- { RGB_TO_ULONG(168, 168, 168), "gray66" },
- { RGB_TO_ULONG(168, 168, 168), "grey66" },
- { RGB_TO_ULONG(171, 171, 171), "gray67" },
- { RGB_TO_ULONG(171, 171, 171), "grey67" },
- { RGB_TO_ULONG(173, 173, 173), "gray68" },
- { RGB_TO_ULONG(173, 173, 173), "grey68" },
- { RGB_TO_ULONG(176, 176, 176), "gray69" },
- { RGB_TO_ULONG(176, 176, 176), "grey69" },
- { RGB_TO_ULONG(179, 179, 179), "gray70" },
- { RGB_TO_ULONG(179, 179, 179), "grey70" },
- { RGB_TO_ULONG(181, 181, 181), "gray71" },
- { RGB_TO_ULONG(181, 181, 181), "grey71" },
- { RGB_TO_ULONG(184, 184, 184), "gray72" },
- { RGB_TO_ULONG(184, 184, 184), "grey72" },
- { RGB_TO_ULONG(186, 186, 186), "gray73" },
- { RGB_TO_ULONG(186, 186, 186), "grey73" },
- { RGB_TO_ULONG(189, 189, 189), "gray74" },
- { RGB_TO_ULONG(189, 189, 189), "grey74" },
- { RGB_TO_ULONG(191, 191, 191), "gray75" },
- { RGB_TO_ULONG(191, 191, 191), "grey75" },
- { RGB_TO_ULONG(194, 194, 194), "gray76" },
- { RGB_TO_ULONG(194, 194, 194), "grey76" },
- { RGB_TO_ULONG(196, 196, 196), "gray77" },
- { RGB_TO_ULONG(196, 196, 196), "grey77" },
- { RGB_TO_ULONG(199, 199, 199), "gray78" },
- { RGB_TO_ULONG(199, 199, 199), "grey78" },
- { RGB_TO_ULONG(201, 201, 201), "gray79" },
- { RGB_TO_ULONG(201, 201, 201), "grey79" },
- { RGB_TO_ULONG(204, 204, 204), "gray80" },
- { RGB_TO_ULONG(204, 204, 204), "grey80" },
- { RGB_TO_ULONG(207, 207, 207), "gray81" },
- { RGB_TO_ULONG(207, 207, 207), "grey81" },
- { RGB_TO_ULONG(209, 209, 209), "gray82" },
- { RGB_TO_ULONG(209, 209, 209), "grey82" },
- { RGB_TO_ULONG(212, 212, 212), "gray83" },
- { RGB_TO_ULONG(212, 212, 212), "grey83" },
- { RGB_TO_ULONG(214, 214, 214), "gray84" },
- { RGB_TO_ULONG(214, 214, 214), "grey84" },
- { RGB_TO_ULONG(217, 217, 217), "gray85" },
- { RGB_TO_ULONG(217, 217, 217), "grey85" },
- { RGB_TO_ULONG(219, 219, 219), "gray86" },
- { RGB_TO_ULONG(219, 219, 219), "grey86" },
- { RGB_TO_ULONG(222, 222, 222), "gray87" },
- { RGB_TO_ULONG(222, 222, 222), "grey87" },
- { RGB_TO_ULONG(224, 224, 224), "gray88" },
- { RGB_TO_ULONG(224, 224, 224), "grey88" },
- { RGB_TO_ULONG(227, 227, 227), "gray89" },
- { RGB_TO_ULONG(227, 227, 227), "grey89" },
- { RGB_TO_ULONG(229, 229, 229), "gray90" },
- { RGB_TO_ULONG(229, 229, 229), "grey90" },
- { RGB_TO_ULONG(232, 232, 232), "gray91" },
- { RGB_TO_ULONG(232, 232, 232), "grey91" },
- { RGB_TO_ULONG(235, 235, 235), "gray92" },
- { RGB_TO_ULONG(235, 235, 235), "grey92" },
- { RGB_TO_ULONG(237, 237, 237), "gray93" },
- { RGB_TO_ULONG(237, 237, 237), "grey93" },
- { RGB_TO_ULONG(240, 240, 240), "gray94" },
- { RGB_TO_ULONG(240, 240, 240), "grey94" },
- { RGB_TO_ULONG(242, 242, 242), "gray95" },
- { RGB_TO_ULONG(242, 242, 242), "grey95" },
- { RGB_TO_ULONG(245, 245, 245), "gray96" },
- { RGB_TO_ULONG(245, 245, 245), "grey96" },
- { RGB_TO_ULONG(247, 247, 247), "gray97" },
- { RGB_TO_ULONG(247, 247, 247), "grey97" },
- { RGB_TO_ULONG(250, 250, 250), "gray98" },
- { RGB_TO_ULONG(250, 250, 250), "grey98" },
- { RGB_TO_ULONG(252, 252, 252), "gray99" },
- { RGB_TO_ULONG(252, 252, 252), "grey99" },
- { RGB_TO_ULONG(255, 255, 255), "gray100" },
- { RGB_TO_ULONG(255, 255, 255), "grey100" },
- { RGB_TO_ULONG(169, 169, 169), "dark grey" },
- { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
- { RGB_TO_ULONG(169, 169, 169), "dark gray" },
- { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
- { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
- { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
- { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
- { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
- { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
- { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
- { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
- { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
- { RGB_TO_ULONG(144, 238, 144), "light green" },
- { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
-};
-
-Lisp_Object
-mac_color_map_lookup (colorname)
- const char *colorname;
-{
- Lisp_Object ret = Qnil;
- int i;
-
- BLOCK_INPUT;
-
- for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
- if (xstrcasecmp (colorname, mac_color_map[i].name) == 0)
- {
- ret = make_number (mac_color_map[i].color);
- break;
- }
-
- UNBLOCK_INPUT;
-
- return ret;
-}
-
-Lisp_Object
-x_to_mac_color (colorname)
- char * colorname;
-{
- register Lisp_Object ret = Qnil;
-
- BLOCK_INPUT;
-
- if (colorname[0] == '#')
- {
- /* Could be an old-style RGB Device specification. */
- char *color;
- int size;
- color = colorname + 1;
-
- size = strlen(color);
- if (size == 3 || size == 6 || size == 9 || size == 12)
- {
- unsigned long colorval;
- int i, pos;
- pos = 16;
- size /= 3;
- colorval = 0;
-
- for (i = 0; i < 3; i++)
- {
- char *end;
- char t;
- unsigned long value;
-
- /* The check for 'x' in the following conditional takes into
- account the fact that strtol allows a "0x" in front of
- our numbers, and we don't. */
- if (!isxdigit(color[0]) || color[1] == 'x')
- break;
- t = color[size];
- color[size] = '\0';
- value = strtoul(color, &end, 16);
- color[size] = t;
- if (errno == ERANGE || end - color != size)
- break;
- switch (size)
- {
- case 1:
- value = value * 0x10;
- break;
- case 2:
- break;
- case 3:
- value /= 0x10;
- break;
- case 4:
- value /= 0x100;
- break;
- }
- colorval |= (value << pos);
- pos -= 8;
- if (i == 2)
- {
- UNBLOCK_INPUT;
- return make_number (colorval);
- }
- color = end;
- }
- }
- }
- else if (strnicmp(colorname, "rgb:", 4) == 0)
- {
- char *color;
- unsigned long colorval;
- int i, pos;
- pos = 16;
-
- colorval = 0;
- color = colorname + 4;
- for (i = 0; i < 3; i++)
- {
- char *end;
- unsigned long value;
-
- /* The check for 'x' in the following conditional takes into
- account the fact that strtol allows a "0x" in front of
- our numbers, and we don't. */
- if (!isxdigit(color[0]) || color[1] == 'x')
- break;
- value = strtoul(color, &end, 16);
- if (errno == ERANGE)
- break;
- switch (end - color)
- {
- case 1:
- value = value * 0x10 + value;
- break;
- case 2:
- break;
- case 3:
- value /= 0x10;
- break;
- case 4:
- value /= 0x100;
- break;
- default:
- value = ULONG_MAX;
- }
- if (value == ULONG_MAX)
- break;
- colorval |= (value << pos);
- pos -= 0x8;
- if (i == 2)
- {
- if (*end != '\0')
- break;
- UNBLOCK_INPUT;
- return make_number (colorval);
- }
- if (*end != '/')
- break;
- color = end + 1;
- }
- }
- else if (strnicmp(colorname, "rgbi:", 5) == 0)
- {
- /* This is an RGB Intensity specification. */
- char *color;
- unsigned long colorval;
- int i, pos;
- pos = 16;
-
- colorval = 0;
- color = colorname + 5;
- for (i = 0; i < 3; i++)
- {
- char *end;
- double value;
- unsigned long val;
-
- value = strtod(color, &end);
- if (errno == ERANGE)
- break;
- if (value < 0.0 || value > 1.0)
- break;
- val = (unsigned long)(0x100 * value);
- /* We used 0x100 instead of 0xFF to give a continuous
- range between 0.0 and 1.0 inclusive. The next statement
- fixes the 1.0 case. */
- if (val == 0x100)
- val = 0xFF;
- colorval |= (val << pos);
- pos -= 0x8;
- if (i == 2)
- {
- if (*end != '\0')
- break;
- UNBLOCK_INPUT;
- return make_number (colorval);
- }
- if (*end != '/')
- break;
- color = end + 1;
- }
- }
-
- ret = mac_color_map_lookup (colorname);
-
- UNBLOCK_INPUT;
- return ret;
-}
-
-/* Gamma-correct COLOR on frame F. */
-
-void
-gamma_correct (f, color)
- struct frame *f;
- unsigned long *color;
-{
- if (f->gamma)
- {
- unsigned long red, green, blue;
-
- red = pow (RED_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
- green = pow (GREEN_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
- blue = pow (BLUE_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
- *color = RGB_TO_ULONG (red, green, blue);
- }
-}
-
-/* Decide if color named COLOR is valid for the display associated
- with the selected frame; if so, return the rgb values in COLOR_DEF.
- If ALLOC is nonzero, allocate a new colormap cell. */
-
-int
-mac_defined_color (f, color, color_def, alloc)
- FRAME_PTR f;
- char *color;
- XColor *color_def;
- int alloc;
-{
- register Lisp_Object tem;
- unsigned long mac_color_ref;
-
- tem = x_to_mac_color (color);
-
- if (!NILP (tem))
- {
- if (f)
- {
- /* Apply gamma correction. */
- mac_color_ref = XUINT (tem);
- gamma_correct (f, &mac_color_ref);
- XSETINT (tem, mac_color_ref);
- }
-
- color_def->pixel = mac_color_ref;
- color_def->red = RED16_FROM_ULONG (mac_color_ref);
- color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
- color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
-
- return 1;
- }
- else
- {
- return 0;
- }
-}
-
-/* Given a string ARG naming a color, compute a pixel value from it
- suitable for screen F.
- If F is not a color screen, return DEF (default) regardless of what
- ARG says. */
-
-int
-x_decode_color (f, arg, def)
- FRAME_PTR f;
- Lisp_Object arg;
- int def;
-{
- XColor cdef;
-
- CHECK_STRING (arg);
-
- if (strcmp (SDATA (arg), "black") == 0)
- return BLACK_PIX_DEFAULT (f);
- else if (strcmp (SDATA (arg), "white") == 0)
- return WHITE_PIX_DEFAULT (f);
-
-#if 0
- if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
- return def;
-#endif
-
- if (mac_defined_color (f, SDATA (arg), &cdef, 1))
- return cdef.pixel;
-
- /* defined_color failed; return an ultimate default. */
- return def;
-}
-
-/* Functions called only from `x_set_frame_param'
- to set individual parameters.
-
- If FRAME_MAC_WINDOW (f) is 0,
- the frame is being created and its window does not exist yet.
- In that case, just record the parameter's new value
- in the standard place; do not attempt to change the window. */
-
-void
-x_set_foreground_color (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- struct mac_output *mac = f->output_data.mac;
- unsigned long fg, old_fg;
-
- fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- old_fg = FRAME_FOREGROUND_PIXEL (f);
- FRAME_FOREGROUND_PIXEL (f) = fg;
-
- if (FRAME_MAC_WINDOW (f) != 0)
- {
- Display *dpy = FRAME_MAC_DISPLAY (f);
-
- BLOCK_INPUT;
- XSetForeground (dpy, mac->normal_gc, fg);
- XSetBackground (dpy, mac->reverse_gc, fg);
-
- if (mac->cursor_pixel == old_fg)
- {
- unload_color (f, mac->cursor_pixel);
- mac->cursor_pixel = fg;
- XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel);
- }
-
- UNBLOCK_INPUT;
-
- update_face_from_frame_parameter (f, Qforeground_color, arg);
-
- if (FRAME_VISIBLE_P (f))
- redraw_frame (f);
- }
-
- unload_color (f, old_fg);
-}
-
-void
-x_set_background_color (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- struct mac_output *mac = f->output_data.mac;
- unsigned long bg;
-
- bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
- unload_color (f, FRAME_BACKGROUND_PIXEL (f));
- FRAME_BACKGROUND_PIXEL (f) = bg;
-
- if (FRAME_MAC_WINDOW (f) != 0)
- {
- Display *dpy = FRAME_MAC_DISPLAY (f);
-
- BLOCK_INPUT;
- XSetBackground (dpy, mac->normal_gc, bg);
- XSetForeground (dpy, mac->reverse_gc, bg);
- mac_set_frame_window_background (f, bg);
- XSetForeground (dpy, mac->cursor_gc, bg);
-
- UNBLOCK_INPUT;
- update_face_from_frame_parameter (f, Qbackground_color, arg);
-
- if (FRAME_VISIBLE_P (f))
- redraw_frame (f);
- }
-}
-
-void
-x_set_mouse_color (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- struct x_output *x = f->output_data.x;
- Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
- Cursor hourglass_cursor, horizontal_drag_cursor;
- unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
-
- /* Don't let pointers be invisible. */
- if (mask_color == pixel)
- pixel = FRAME_FOREGROUND_PIXEL (f);
-
- f->output_data.mac->mouse_pixel = pixel;
-
- if (!NILP (Vx_pointer_shape))
- {
- CHECK_NUMBER (Vx_pointer_shape);
- cursor = XINT (Vx_pointer_shape);
- }
- else
- cursor = kThemeIBeamCursor;
-
- if (!NILP (Vx_nontext_pointer_shape))
- {
- CHECK_NUMBER (Vx_nontext_pointer_shape);
- nontext_cursor = XINT (Vx_nontext_pointer_shape);
- }
- else
- nontext_cursor = kThemeArrowCursor;
-
- if (!NILP (Vx_hourglass_pointer_shape))
- {
- CHECK_NUMBER (Vx_hourglass_pointer_shape);
- hourglass_cursor = XINT (Vx_hourglass_pointer_shape);
- }
- else
- hourglass_cursor = kThemeWatchCursor;
-
- if (!NILP (Vx_mode_pointer_shape))
- {
- CHECK_NUMBER (Vx_mode_pointer_shape);
- mode_cursor = XINT (Vx_mode_pointer_shape);
- }
- else
- mode_cursor = kThemeArrowCursor;
-
- if (!NILP (Vx_sensitive_text_pointer_shape))
- {
- CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
- hand_cursor = XINT (Vx_sensitive_text_pointer_shape);
- }
- else
- hand_cursor = kThemePointingHandCursor;
-
- if (!NILP (Vx_window_horizontal_drag_shape))
- {
- CHECK_NUMBER (Vx_window_horizontal_drag_shape);
- horizontal_drag_cursor = XINT (Vx_window_horizontal_drag_shape);
- }
- else
- horizontal_drag_cursor = kThemeResizeLeftRightCursor;
-
-#if 0 /* MAC_TODO: cursor color changes */
- {
- XColor fore_color, back_color;
-
- fore_color.pixel = f->output_data.mac->mouse_pixel;
- x_query_color (f, &fore_color);
- back_color.pixel = mask_color;
- x_query_color (f, &back_color);
-
- XRecolorCursor (dpy, cursor, &fore_color, &back_color);
- XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
- XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
- XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
- XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
- XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
- }
-#endif
-
- BLOCK_INPUT;
-
- if (FRAME_MAC_WINDOW (f) != 0)
- FRAME_TERMINAL (f)->rif->define_frame_cursor (f, cursor);
-
- f->output_data.mac->text_cursor = cursor;
- f->output_data.mac->nontext_cursor = nontext_cursor;
- f->output_data.mac->hourglass_cursor = hourglass_cursor;
- f->output_data.mac->modeline_cursor = mode_cursor;
- f->output_data.mac->hand_cursor = hand_cursor;
- f->output_data.mac->horizontal_drag_cursor = horizontal_drag_cursor;
-
- UNBLOCK_INPUT;
-
- update_face_from_frame_parameter (f, Qmouse_color, arg);
-}
-
-void
-x_set_cursor_color (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- unsigned long fore_pixel, pixel;
-
- if (!NILP (Vx_cursor_fore_pixel))
- fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
- WHITE_PIX_DEFAULT (f));
- else
- fore_pixel = FRAME_BACKGROUND_PIXEL (f);
-
- pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
-
- /* Make sure that the cursor color differs from the background color. */
- if (pixel == FRAME_BACKGROUND_PIXEL (f))
- {
- pixel = f->output_data.mac->mouse_pixel;
- if (pixel == fore_pixel)
- fore_pixel = FRAME_BACKGROUND_PIXEL (f);
- }
-
- f->output_data.mac->cursor_foreground_pixel = fore_pixel;
- f->output_data.mac->cursor_pixel = pixel;
-
- if (FRAME_MAC_WINDOW (f) != 0)
- {
- BLOCK_INPUT;
- /* Update frame's cursor_gc. */
- XSetBackground (FRAME_MAC_DISPLAY (f),
- f->output_data.mac->cursor_gc, pixel);
- XSetForeground (FRAME_MAC_DISPLAY (f),
- f->output_data.mac->cursor_gc, fore_pixel);
- UNBLOCK_INPUT;
-
- if (FRAME_VISIBLE_P (f))
- {
- x_update_cursor (f, 0);
- x_update_cursor (f, 1);
- }
- }
-
- update_face_from_frame_parameter (f, Qcursor_color, arg);
-}
-
-/* Set the border-color of frame F to pixel value PIX.
- Note that this does not fully take effect if done before
- F has a window. */
-
-void
-x_set_border_pixel (f, pix)
- struct frame *f;
- int pix;
-{
-
- f->output_data.mac->border_pixel = pix;
-
- if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
- {
- if (FRAME_VISIBLE_P (f))
- redraw_frame (f);
- }
-}
-
-/* Set the border-color of frame F to value described by ARG.
- ARG can be a string naming a color.
- The border-color is used for the border that is drawn by the server.
- Note that this does not fully take effect if done before
- F has a window; it must be redone when the window is created. */
-
-void
-x_set_border_color (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- int pix;
-
- CHECK_STRING (arg);
- pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- x_set_border_pixel (f, pix);
- update_face_from_frame_parameter (f, Qborder_color, arg);
-}
-
-
-void
-x_set_cursor_type (f, arg, oldval)
- FRAME_PTR f;
- Lisp_Object arg, oldval;
-{
- set_frame_cursor_types (f, arg);
-
- /* Make sure the cursor gets redrawn. */
- cursor_type_changed = 1;
-}
-
-#if 0 /* MAC_TODO: really no icon for Mac */
-void
-x_set_icon_type (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- int result;
-
- if (NILP (arg) && NILP (oldval))
- return;
-
- if (STRINGP (arg) && STRINGP (oldval)
- && EQ (Fstring_equal (oldval, arg), Qt))
- return;
-
- if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
- return;
-
- BLOCK_INPUT;
-
- result = x_bitmap_icon (f, arg);
- if (result)
- {
- UNBLOCK_INPUT;
- error ("No icon window available");
- }
-
- UNBLOCK_INPUT;
-}
-#endif /* MAC_TODO */
-
-void
-x_set_icon_name (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- int result;
-
- if (STRINGP (arg))
- {
- if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
- return;
- }
- else if (!NILP (arg) || NILP (oldval))
- return;
-
- f->icon_name = arg;
-
-#if 0 /* MAC_TODO */
- if (f->output_data.w32->icon_bitmap != 0)
- return;
-
- BLOCK_INPUT;
-
- result = x_text_icon (f,
- (char *) SDATA ((!NILP (f->icon_name)
- ? f->icon_name
- : !NILP (f->title)
- ? f->title
- : f->name)));
-
- if (result)
- {
- UNBLOCK_INPUT;
- error ("No icon window available");
- }
-
- /* If the window was unmapped (and its icon was mapped),
- the new icon is not mapped, so map the window in its stead. */
- if (FRAME_VISIBLE_P (f))
- {
-#ifdef USE_X_TOOLKIT
- XtPopup (f->output_data.w32->widget, XtGrabNone);
-#endif
- XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
- }
-
- XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
-#endif /* MAC_TODO */
-}
-
-
-void
-x_set_menu_bar_lines (f, value, oldval)
- struct frame *f;
- Lisp_Object value, oldval;
-{
- /* Make sure we redisplay all windows in this frame. */
- windows_or_buffers_changed++;
-
- FRAME_MENU_BAR_LINES (f) = 0;
- /* The menu bar is always shown. */
- FRAME_EXTERNAL_MENU_BAR (f) = 1;
- if (FRAME_MAC_P (f) && f->output_data.mac->menubar_widget == 0)
- /* Make sure next redisplay shows the menu bar. */
- XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
- adjust_glyphs (f);
-}
-
-
-/* Set the number of lines used for the tool bar of frame F to VALUE.
- VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
- is the old number of tool bar lines. This function changes the
- height of all windows on frame F to match the new tool bar height.
- The frame's height doesn't change. */
-
-void
-x_set_tool_bar_lines (f, value, oldval)
- struct frame *f;
- Lisp_Object value, oldval;
-{
- int delta, nlines, root_height;
- Lisp_Object root_window;
-
- /* Treat tool bars like menu bars. */
- if (FRAME_MINIBUF_ONLY_P (f))
- return;
-
- /* Use VALUE only if an integer >= 0. */
- if (INTEGERP (value) && XINT (value) >= 0)
- nlines = XFASTINT (value);
- else
- nlines = 0;
-
- /* Make sure we redisplay all windows in this frame. */
- ++windows_or_buffers_changed;
-
-#if USE_MAC_TOOLBAR
- FRAME_TOOL_BAR_LINES (f) = 0;
- if (nlines)
- {
- FRAME_EXTERNAL_TOOL_BAR (f) = 1;
- if (FRAME_MAC_P (f)
- && !mac_is_window_toolbar_visible (FRAME_MAC_WINDOW (f)))
- /* Make sure next redisplay shows the tool bar. */
- XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
- }
- else
- {
- if (FRAME_EXTERNAL_TOOL_BAR (f))
- free_frame_tool_bar (f);
- FRAME_EXTERNAL_TOOL_BAR (f) = 0;
- }
-
- return;
-#endif
-
- delta = nlines - FRAME_TOOL_BAR_LINES (f);
-
- /* Don't resize the tool-bar to more than we have room for. */
- root_window = FRAME_ROOT_WINDOW (f);
- root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
- if (root_height - delta < 1)
- {
- delta = root_height - 1;
- nlines = FRAME_TOOL_BAR_LINES (f) + delta;
- }
-
- FRAME_TOOL_BAR_LINES (f) = nlines;
- change_window_heights (root_window, delta);
- adjust_glyphs (f);
-
- /* We also have to make sure that the internal border at the top of
- the frame, below the menu bar or tool bar, is redrawn when the
- tool bar disappears. This is so because the internal border is
- below the tool bar if one is displayed, but is below the menu bar
- if there isn't a tool bar. The tool bar draws into the area
- below the menu bar. */
- if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
- {
- clear_frame (f);
- clear_current_matrices (f);
- }
-
- /* If the tool bar gets smaller, the internal border below it
- has to be cleared. It was formerly part of the display
- of the larger tool bar, and updating windows won't clear it. */
- if (delta < 0)
- {
- int height = FRAME_INTERNAL_BORDER_WIDTH (f);
- int width = FRAME_PIXEL_WIDTH (f);
- int y = nlines * FRAME_LINE_HEIGHT (f);
-
- BLOCK_INPUT;
- mac_clear_area (f, 0, y, width, height);
- UNBLOCK_INPUT;
-
- if (WINDOWP (f->tool_bar_window))
- clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
- }
-}
-
-
-
-/* Set the Mac window title to NAME for frame F. */
-
-static void
-x_set_name_internal (f, name)
- FRAME_PTR f;
- Lisp_Object name;
-{
- if (FRAME_MAC_WINDOW (f))
- {
- if (STRING_MULTIBYTE (name))
-#if TARGET_API_MAC_CARBON
- name = ENCODE_UTF_8 (name);
-#else
- name = ENCODE_SYSTEM (name);
-#endif
-
- BLOCK_INPUT;
-
- {
-#if TARGET_API_MAC_CARBON
- CFStringRef windowTitle =
- cfstring_create_with_utf8_cstring (SDATA (name));
-
- mac_set_window_title (FRAME_MAC_WINDOW (f), windowTitle);
- CFRelease (windowTitle);
-#else
- Str255 windowTitle;
- if (strlen (SDATA (name)) < 255)
- {
- strcpy (windowTitle, SDATA (name));
- c2pstr (windowTitle);
- SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
- }
-#endif
- }
-
- UNBLOCK_INPUT;
- }
-}
-
-/* Change the name of frame F to NAME. If NAME is nil, set F's name to
- mac_id_name.
-
- If EXPLICIT is non-zero, that indicates that lisp code is setting the
- name; if NAME is a string, set F's name to NAME and set
- F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
-
- If EXPLICIT is zero, that indicates that Emacs redisplay code is
- suggesting a new name, which lisp code should override; if
- F->explicit_name is set, ignore the new name; otherwise, set it. */
-
-void
-x_set_name (f, name, explicit)
- struct frame *f;
- Lisp_Object name;
- int explicit;
-{
- /* Make sure that requests from lisp code override requests from
- Emacs redisplay code. */
- if (explicit)
- {
- /* If we're switching from explicit to implicit, we had better
- update the mode lines and thereby update the title. */
- if (f->explicit_name && NILP (name))
- update_mode_lines = 1;
-
- f->explicit_name = ! NILP (name);
- }
- else if (f->explicit_name)
- return;
-
- /* If NAME is nil, set the name to the mac_id_name. */
- if (NILP (name))
- {
- /* Check for no change needed in this very common case
- before we do any consing. */
- if (!strcmp (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name,
- SDATA (f->name)))
- return;
- name = build_string (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name);
- }
- else
- CHECK_STRING (name);
-
- /* Don't change the name if it's already NAME. */
- if (! NILP (Fstring_equal (name, f->name)))
- return;
-
- f->name = name;
-
- /* For setting the frame title, the title parameter should override
- the name parameter. */
- if (! NILP (f->title))
- name = f->title;
-
- x_set_name_internal (f, name);
-}
-
-/* This function should be called when the user's lisp code has
- specified a name for the frame; the name will override any set by the
- redisplay code. */
-void
-x_explicitly_set_name (f, arg, oldval)
- FRAME_PTR f;
- Lisp_Object arg, oldval;
-{
- x_set_name (f, arg, 1);
-}
-
-/* This function should be called by Emacs redisplay code to set the
- name; names set this way will never override names set by the user's
- lisp code. */
-void
-x_implicitly_set_name (f, arg, oldval)
- FRAME_PTR f;
- Lisp_Object arg, oldval;
-{
- x_set_name (f, arg, 0);
-}
-
-/* Change the title of frame F to NAME.
- If NAME is nil, use the frame name as the title. */
-
-void
-x_set_title (f, name, old_name)
- struct frame *f;
- Lisp_Object name, old_name;
-{
- /* Don't change the title if it's already NAME. */
- if (EQ (name, f->title))
- return;
-
- update_mode_lines = 1;
-
- f->title = name;
-
- if (NILP (name))
- name = f->name;
- else
- CHECK_STRING (name);
-
- x_set_name_internal (f, name);
-}
-
-void
-x_set_scroll_bar_default_width (f)
- struct frame *f;
-{
- /* Imitate X without X Toolkit */
-
- int wid = FRAME_COLUMN_WIDTH (f);
-
-#ifdef MAC_OSX
- FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH;
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
- wid - 1) / wid;
-#else /* not MAC_OSX */
- /* Make the actual width at least 14 pixels and a multiple of a
- character width. */
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
-
- /* Use all of that space (aside from required margins) for the
- scroll bar. */
- FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
-#endif /* not MAC_OSX */
-}
-
-static void
-mac_set_font (f, arg, oldval)
- struct frame *f;
- Lisp_Object arg, oldval;
-{
- x_set_font (f, arg, oldval);
-#if USE_MAC_FONT_PANEL
- {
- Lisp_Object focus_frame = x_get_focus_frame (f);
-
- if ((NILP (focus_frame) && f == SELECTED_FRAME ())
- || XFRAME (focus_frame) == f)
- {
- BLOCK_INPUT;
- mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
- UNBLOCK_INPUT;
- }
- }
-#endif
-}
-
-void
-mac_update_title_bar (f, save_match_data)
- struct frame *f;
- int save_match_data;
-{
-#if TARGET_API_MAC_CARBON
- struct window *w;
- int modified_p;
-
- if (!FRAME_MAC_P (f))
- return;
-
- w = XWINDOW (FRAME_SELECTED_WINDOW (f));
- modified_p = (BUF_SAVE_MODIFF (XBUFFER (w->buffer))
- < BUF_MODIFF (XBUFFER (w->buffer)));
- if (windows_or_buffers_changed
- /* Minibuffer modification status shown in the close button is
- confusing. */
- || (!MINI_WINDOW_P (w)
- && (modified_p != !NILP (w->last_had_star))))
- {
- BLOCK_INPUT;
- mac_set_window_modified (FRAME_MAC_WINDOW (f),
- !MINI_WINDOW_P (w) && modified_p);
- mac_update_proxy_icon (f);
- UNBLOCK_INPUT;
- }
-#endif
-}
-
-
-/* Subroutines of creating a frame. */
-
-/* Retrieve the string resource specified by NAME with CLASS from
- database RDB.
-
- The return value points to the contents of a Lisp string. So it
- will not be valid after the next GC where string compaction will
- occur. */
-
-char *
-x_get_string_resource (rdb, name, class)
- XrmDatabase rdb;
- char *name, *class;
-{
- Lisp_Object value = xrm_get_resource (rdb, name, class);
-
- if (STRINGP (value))
- return SDATA (value);
- else
- return NULL;
-}
-
-/* Return the value of parameter PARAM.
-
- First search ALIST, then Vdefault_frame_alist, then the X defaults
- database, using ATTRIBUTE as the attribute name and CLASS as its class.
-
- Convert the resource to the type specified by desired_type.
-
- If no default is specified, return Qunbound. If you call
- mac_get_arg, make sure you deal with Qunbound in a reasonable way,
- and don't let it get stored in any Lisp-visible variables! */
-
-static Lisp_Object
-mac_get_arg (alist, param, attribute, class, type)
- Lisp_Object alist, param;
- char *attribute;
- char *class;
- enum resource_types type;
-{
- return x_get_arg (check_x_display_info (Qnil),
- alist, param, attribute, class, type);
-}
-
-
-/* XParseGeometry copied from w32xfns.c */
-
-/*
- * XParseGeometry parses strings of the form
- * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
- * width, height, xoffset, and yoffset are unsigned integers.
- * Example: "=80x24+300-49"
- * The equal sign is optional.
- * It returns a bitmask that indicates which of the four values
- * were actually found in the string. For each value found,
- * the corresponding argument is updated; for each value
- * not found, the corresponding argument is left unchanged.
- */
-
-static int
-read_integer (string, NextString)
- register char *string;
- char **NextString;
-{
- register int Result = 0;
- int Sign = 1;
-
- if (*string == '+')
- string++;
- else if (*string == '-')
- {
- string++;
- Sign = -1;
- }
- for (; (*string >= '0') && (*string <= '9'); string++)
- {
- Result = (Result * 10) + (*string - '0');
- }
- *NextString = string;
- if (Sign >= 0)
- return (Result);
- else
- return (-Result);
-}
-
-int
-XParseGeometry (string, x, y, width, height)
- char *string;
- int *x, *y;
- unsigned int *width, *height; /* RETURN */
-{
- int mask = NoValue;
- register char *strind;
- unsigned int tempWidth, tempHeight;
- int tempX, tempY;
- char *nextCharacter;
-
- if ((string == NULL) || (*string == '\0')) return (mask);
- if (*string == '=')
- string++; /* ignore possible '=' at beg of geometry spec */
-
- strind = (char *)string;
- if (*strind != '+' && *strind != '-' && *strind != 'x')
- {
- tempWidth = read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
- return (0);
- strind = nextCharacter;
- mask |= WidthValue;
- }
-
- if (*strind == 'x' || *strind == 'X')
- {
- strind++;
- tempHeight = read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
- return (0);
- strind = nextCharacter;
- mask |= HeightValue;
- }
-
- if ((*strind == '+') || (*strind == '-'))
- {
- if (*strind == '-')
- {
- strind++;
- tempX = -read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
- return (0);
- strind = nextCharacter;
- mask |= XNegative;
-
- }
- else
- {
- strind++;
- tempX = read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
- return (0);
- strind = nextCharacter;
- }
- mask |= XValue;
- if ((*strind == '+') || (*strind == '-'))
- {
- if (*strind == '-')
- {
- strind++;
- tempY = -read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
- return (0);
- strind = nextCharacter;
- mask |= YNegative;
-
- }
- else
- {
- strind++;
- tempY = read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
- return (0);
- strind = nextCharacter;
- }
- mask |= YValue;
- }
- }
-
- /* If strind isn't at the end of the string the it's an invalid
- geometry specification. */
-
- if (*strind != '\0') return (0);
-
- if (mask & XValue)
- *x = tempX;
- if (mask & YValue)
- *y = tempY;
- if (mask & WidthValue)
- *width = tempWidth;
- if (mask & HeightValue)
- *height = tempHeight;
- return (mask);
-}
-
-
-/* Create and set up the Mac window for frame F. */
-
-static void
-mac_window (f)
- struct frame *f;
-{
- BLOCK_INPUT;
-
- mac_create_frame_window (f, 0);
-
- if (FRAME_MAC_WINDOW (f))
- mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
-
-#if USE_MAC_TOOLBAR
- /* At the moment, the size of the tool bar is not yet known. We
- record the gravity value of the newly created window and use it
- to adjust the position of the window (especially for a negative
- specification of its vertical position) when the tool bar is
- first redisplayed. */
- if (FRAME_EXTERNAL_TOOL_BAR (f))
- f->output_data.mac->toolbar_win_gravity = f->win_gravity;
-#endif
-
- validate_x_resource_name ();
-
- /* x_set_name normally ignores requests to set the name if the
- requested name is the same as the current name. This is the one
- place where that assumption isn't correct; f->name is set, but
- the server hasn't been told. */
- {
- Lisp_Object name;
- int explicit = f->explicit_name;
-
- f->explicit_name = 0;
- name = f->name;
- f->name = Qnil;
- x_set_name (f, name, explicit);
- }
-
- UNBLOCK_INPUT;
-
- if (FRAME_MAC_WINDOW (f) == 0)
- error ("Unable to create window");
-}
-
-/* Handle the icon stuff for this window. Perhaps later we might
- want an x_set_icon_position which can be called interactively as
- well. */
-
-static void
-x_icon (f, parms)
- struct frame *f;
- Lisp_Object parms;
-{
- Lisp_Object icon_x, icon_y;
-
- /* Set the position of the icon. Note that Windows 95 groups all
- icons in the tray. */
- icon_x = mac_get_arg (parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
- icon_y = mac_get_arg (parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
- if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
- {
- CHECK_NUMBER (icon_x);
- CHECK_NUMBER (icon_y);
- }
- else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
- error ("Both left and top icon corners of icon must be specified");
-
- BLOCK_INPUT;
-
- if (! EQ (icon_x, Qunbound))
- x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
-
-#if 0 /* TODO */
- /* Start up iconic or window? */
- x_wm_set_window_state
- (f, (EQ (w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
- ? IconicState
- : NormalState));
-
- x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
- ? f->icon_name
- : f->name)));
-#endif
-
- UNBLOCK_INPUT;
-}
-
-
-void
-x_make_gc (f)
- struct frame *f;
-{
- XGCValues gc_values;
-
- BLOCK_INPUT;
-
- /* Create the GCs of this frame.
- Note that many default values are used. */
-
- /* Normal video */
- gc_values.font = FRAME_FONT (f);
- gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
- gc_values.background = FRAME_BACKGROUND_PIXEL (f);
- f->output_data.mac->normal_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
- FRAME_MAC_WINDOW (f),
- GCFont | GCForeground | GCBackground,
- &gc_values);
-
- /* Reverse video style. */
- gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
- gc_values.background = FRAME_FOREGROUND_PIXEL (f);
- f->output_data.mac->reverse_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
- FRAME_MAC_WINDOW (f),
- GCFont | GCForeground | GCBackground,
- &gc_values);
-
- /* Cursor has cursor-color background, background-color foreground. */
- gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
- gc_values.background = f->output_data.mac->cursor_pixel;
- f->output_data.mac->cursor_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
- FRAME_MAC_WINDOW (f),
- GCFont | GCForeground | GCBackground,
- &gc_values);
-
- /* Reliefs. */
- f->output_data.mac->white_relief.gc = 0;
- f->output_data.mac->black_relief.gc = 0;
-
-#if 0
- /* Create the gray border tile used when the pointer is not in
- the frame. Since this depends on the frame's pixel values,
- this must be done on a per-frame basis. */
- f->output_data.x->border_tile
- = (XCreatePixmapFromBitmapData
- (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
- gray_bits, gray_width, gray_height,
- FRAME_FOREGROUND_PIXEL (f),
- FRAME_BACKGROUND_PIXEL (f),
- DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
-#endif
-
- UNBLOCK_INPUT;
-}
-
-
-/* Free what was was allocated in x_make_gc. */
-
-void
-x_free_gcs (f)
- struct frame *f;
-{
- Display *dpy = FRAME_MAC_DISPLAY (f);
-
- BLOCK_INPUT;
-
- if (f->output_data.mac->normal_gc)
- {
- XFreeGC (dpy, f->output_data.mac->normal_gc);
- f->output_data.mac->normal_gc = 0;
- }
-
- if (f->output_data.mac->reverse_gc)
- {
- XFreeGC (dpy, f->output_data.mac->reverse_gc);
- f->output_data.mac->reverse_gc = 0;
- }
-
- if (f->output_data.mac->cursor_gc)
- {
- XFreeGC (dpy, f->output_data.mac->cursor_gc);
- f->output_data.mac->cursor_gc = 0;
- }
-
-#if 0
- if (f->output_data.mac->border_tile)
- {
- XFreePixmap (dpy, f->output_data.mac->border_tile);
- f->output_data.mac->border_tile = 0;
- }
-#endif
-
- if (f->output_data.mac->white_relief.gc)
- {
- XFreeGC (dpy, f->output_data.mac->white_relief.gc);
- f->output_data.mac->white_relief.gc = 0;
- }
-
- if (f->output_data.mac->black_relief.gc)
- {
- XFreeGC (dpy, f->output_data.mac->black_relief.gc);
- f->output_data.mac->black_relief.gc = 0;
- }
-
- UNBLOCK_INPUT;
-}
-
-
-/* Handler for signals raised during x_create_frame and
- x_create_top_frame. FRAME is the frame which is partially
- constructed. */
-
-static Lisp_Object
-unwind_create_frame (frame)
- Lisp_Object frame;
-{
- struct frame *f = XFRAME (frame);
-
- /* If frame is ``official'', nothing to do. */
- if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
- {
-#if GLYPH_DEBUG
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-#endif
-
- x_free_frame_resources (f);
-
-#if GLYPH_DEBUG
- /* Check that reference counts are indeed correct. */
- xassert (dpyinfo->reference_count == dpyinfo_refcount);
- xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
-#endif
- return Qt;
- }
-
- return Qnil;
-}
-
-
-DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
- 1, 1, 0,
- doc: /* Make a new window, which is called a "frame" in Emacs terms.
-Return an Emacs frame object.
-PARAMETERS is an alist of frame parameters.
-If the parameters specify that the frame should not have a minibuffer,
-and do not specify a specific minibuffer window to use,
-then `default-minibuffer-frame' must be a frame whose minibuffer can
-be shared by the new frame.
-
-This function is an internal primitive--use `make-frame' instead. */)
- (parameters)
- Lisp_Object parameters;
-{
- struct frame *f;
- Lisp_Object frame, tem;
- Lisp_Object name;
- int minibuffer_only = 0;
- long window_prompting = 0;
- int width, height;
- int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- Lisp_Object display;
- struct mac_display_info *dpyinfo = NULL;
- Lisp_Object parent;
- struct kboard *kb;
-
- check_mac ();
-
- parms = Fcopy_alist (parms);
-
- /* Use this general default value to start with
- until we know if this frame has a specified name. */
- Vx_resource_name = Vinvocation_name;
-
- display = mac_get_arg (parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
- if (EQ (display, Qunbound))
- display = Qnil;
- dpyinfo = check_x_display_info (display);
- kb = dpyinfo->terminal->kboard;
-
- name = mac_get_arg (parameters, Qname, "name", "Name", RES_TYPE_STRING);
- if (!STRINGP (name)
- && ! EQ (name, Qunbound)
- && ! NILP (name))
- error ("Invalid frame name--not a string or nil");
-
- if (STRINGP (name))
- Vx_resource_name = name;
-
- /* See if parent window is specified. */
- parent = mac_get_arg (parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
- if (EQ (parent, Qunbound))
- parent = Qnil;
- if (! NILP (parent))
- CHECK_NUMBER (parent);
-
- /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
- /* No need to protect DISPLAY because that's not used after passing
- it to make_frame_without_minibuffer. */
- frame = Qnil;
- GCPRO4 (parameters, parent, name, frame);
- tem = mac_get_arg (parameters, Qminibuffer, "minibuffer", "Minibuffer",
- RES_TYPE_SYMBOL);
- if (EQ (tem, Qnone) || NILP (tem))
- f = make_frame_without_minibuffer (Qnil, kb, display);
- else if (EQ (tem, Qonly))
- {
- f = make_minibuffer_frame ();
- minibuffer_only = 1;
- }
- else if (WINDOWP (tem))
- f = make_frame_without_minibuffer (tem, kb, display);
- else
- f = make_frame (1);
-
- XSETFRAME (frame, f);
-
- /* Note that X Windows does support scroll bars. */
- FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
-
- f->terminal = dpyinfo->terminal;
- f->terminal->reference_count++;
-
- f->output_method = output_mac;
- f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
- bzero (f->output_data.mac, sizeof (struct mac_output));
- FRAME_FONTSET (f) = -1;
- record_unwind_protect (unwind_create_frame, frame);
-
- f->icon_name
- = mac_get_arg (parameters, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
- if (! STRINGP (f->icon_name))
- f->icon_name = Qnil;
-
- /* XXX Is this needed? */
- /*FRAME_MAC_DISPLAY_INFO (f) = dpyinfo;*/
-
- /* With FRAME_MAC_DISPLAY_INFO set up, this unwind-protect is safe. */
-#if GLYPH_DEBUG
- image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
- dpyinfo_refcount = dpyinfo->reference_count;
-#endif /* GLYPH_DEBUG */
- FRAME_KBOARD (f) = kb;
-
- /* Specify the parent under which to make this window. */
-
- if (!NILP (parent))
- {
- f->output_data.mac->parent_desc = (Window) XFASTINT (parent);
- f->output_data.mac->explicit_parent = 1;
- }
- else
- {
- f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
- f->output_data.mac->explicit_parent = 0;
- }
-
- /* Set the name; the functions to which we pass f expect the name to
- be set. */
- if (EQ (name, Qunbound) || NILP (name))
- {
- f->name = build_string (dpyinfo->mac_id_name);
- f->explicit_name = 0;
- }
- else
- {
- f->name = name;
- f->explicit_name = 1;
- /* use the frame's title when getting resources for this frame. */
- specbind (Qx_resource_name, name);
- }
-
- /* Extract the window parameters from the supplied values
- that are needed to determine window geometry. */
- {
- Lisp_Object font;
-
- font = mac_get_arg (parameters, Qfont, "font", "Font", RES_TYPE_STRING);
-
- BLOCK_INPUT;
- /* First, try whatever font the caller has specified. */
- if (STRINGP (font))
- {
- tem = Fquery_fontset (font, Qnil);
- if (STRINGP (tem))
- font = x_new_fontset (f, tem);
- else
- font = x_new_font (f, SDATA (font));
- }
- /* Try out a font which we hope has bold and italic variations. */
-#if USE_ATSUI
- if (! STRINGP (font))
- font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1");
-#endif
- if (! STRINGP (font))
- font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
- /* If those didn't work, look for something which will at least work. */
- if (! STRINGP (font))
- font = x_new_fontset (f, build_string ("fontset-standard"));
- if (! STRINGP (font))
- font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
- if (! STRINGP (font))
- font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
- if (! STRINGP (font))
- error ("Cannot find any usable font");
- UNBLOCK_INPUT;
-
- x_default_parameter (f, parameters, Qfont, font,
- "font", "Font", RES_TYPE_STRING);
- }
-
- /* XXX Shouldn't this be borderWidth, not borderwidth ?*/
- x_default_parameter (f, parameters, Qborder_width, make_number (0),
- "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
- /* This defaults to 2 in order to match xterm. We recognize either
- internalBorderWidth or internalBorder (which is what xterm calls
- it). */
- if (NILP (Fassq (Qinternal_border_width, parameters)))
- {
- Lisp_Object value;
-
- value = mac_get_arg (parameters, Qinternal_border_width,
- "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
- if (! EQ (value, Qunbound))
- parameters = Fcons (Fcons (Qinternal_border_width, value),
- parameters);
- }
- /* Default internalBorderWidth to 0 on Windows to match other programs. */
- x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
- "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
- x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
- "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
-
- /* Also do the stuff which must be set before the window exists. */
- x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
- "foreground", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
- "background", "Background", RES_TYPE_STRING);
- x_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
- "pointerColor", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parameters, Qcursor_color, build_string ("black"),
- "cursorColor", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parameters, Qborder_color, build_string ("black"),
- "borderColor", "BorderColor", RES_TYPE_STRING);
- x_default_parameter (f, parameters, Qscreen_gamma, Qnil,
- "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
- x_default_parameter (f, parameters, Qline_spacing, Qnil,
- "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
- x_default_parameter (f, parameters, Qleft_fringe, Qnil,
- "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
- x_default_parameter (f, parameters, Qright_fringe, Qnil,
- "rightFringe", "RightFringe", RES_TYPE_NUMBER);
-
-
- /* Init faces before x_default_parameter is called for scroll-bar
- parameters because that function calls x_set_scroll_bar_width,
- which calls change_frame_size, which calls Fset_window_buffer,
- which runs hooks, which call Fvertical_motion. At the end, we
- end up in init_iterator with a null face cache, which should not
- happen. */
- init_frame_faces (f);
-
- x_default_parameter (f, parameters, Qmenu_bar_lines, make_number (1),
- "menuBar", "MenuBar", RES_TYPE_NUMBER);
- x_default_parameter (f, parameters, Qtool_bar_lines, make_number (1),
- "toolBar", "ToolBar", RES_TYPE_NUMBER);
-
- x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
- "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
- x_default_parameter (f, parameters, Qtitle, Qnil,
- "title", "Title", RES_TYPE_STRING);
- x_default_parameter (f, parameters, Qfullscreen, Qnil,
- "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
-
- f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
-
- /* Compute the size of the window. */
- window_prompting = x_figure_window_size (f, parameters, 1);
-
- tem = mac_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
- f->no_split = minibuffer_only || EQ (tem, Qt);
-
- mac_window (f);
- x_icon (f, parameters);
-
- x_make_gc (f);
-
- /* Now consider the frame official. */
- FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
- Vframe_list = Fcons (frame, Vframe_list);
-
- /* We need to do this after creating the window, so that the
- icon-creation functions can say whose icon they're describing. */
- x_default_parameter (f, parameters, Qicon_type, Qnil,
- "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
-
- x_default_parameter (f, parameters, Qauto_raise, Qnil,
- "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- x_default_parameter (f, parameters, Qauto_lower, Qnil,
- "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- x_default_parameter (f, parameters, Qcursor_type, Qbox,
- "cursorType", "CursorType", RES_TYPE_SYMBOL);
- x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
- "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
-
- /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
- Change will not be effected unless different from the current
- FRAME_LINES (f). */
- width = FRAME_COLS (f);
- height = FRAME_LINES (f);
-
- FRAME_LINES (f) = 0;
- SET_FRAME_COLS (f, 0);
- change_frame_size (f, height, width, 1, 0, 0);
-
- /* Tell the server what size and position, etc, we want, and how
- badly we want them. This should be done after we have the menu
- bar so that its size can be taken into account. */
- BLOCK_INPUT;
- x_wm_set_size_hint (f, window_prompting, 0);
- UNBLOCK_INPUT;
-
- /* Make the window appear on the frame and enable display, unless
- the caller says not to. However, with explicit parent, Emacs
- cannot control visibility, so don't try. */
- if (! f->output_data.mac->explicit_parent)
- {
- Lisp_Object visibility;
-
- visibility = mac_get_arg (parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
- if (EQ (visibility, Qunbound))
- visibility = Qt;
-
- if (EQ (visibility, Qicon))
- x_iconify_frame (f);
- else if (! NILP (visibility))
- x_make_frame_visible (f);
- else
- /* Must have been Qnil. */
- ;
- }
-
- /* Initialize `default-minibuffer-frame' in case this is the first
- frame on this display device. */
- if (FRAME_HAS_MINIBUF_P (f)
- && (!FRAMEP (kb->Vdefault_minibuffer_frame)
- || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
- kb->Vdefault_minibuffer_frame = frame;
-
- /* All remaining specified parameters, which have not been "used"
- by x_get_arg and friends, now go in the misc. alist of the frame. */
- for (tem = parameters; CONSP (tem); tem = XCDR (tem))
- if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
- f->param_alist = Fcons (XCAR (tem), f->param_alist);
-
- UNGCPRO;
-
- /* Make sure windows on this frame appear in calls to next-window
- and similar functions. */
- Vwindow_list = Qnil;
-
- return unbind_to (count, frame);
-}
-
-
-/* FRAME is used only to get a handle on the X display. We don't pass the
- display info directly because we're called from frame.c, which doesn't
- know about that structure. */
-
-Lisp_Object
-x_get_focus_frame (frame)
- struct frame *frame;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
- Lisp_Object xfocus;
- if (! dpyinfo->x_focus_frame)
- return Qnil;
-
- XSETFRAME (xfocus, dpyinfo->x_focus_frame);
- return xfocus;
-}
-
-
-DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
- doc: /* Set the input focus to FRAME.
-FRAME nil means use the selected frame. */)
- (frame)
- Lisp_Object frame;
-{
- OSErr err;
- ProcessSerialNumber front_psn;
- static const ProcessSerialNumber current_psn = {0, kCurrentProcess};
- Boolean front_p;
- struct frame *f = check_x_frame (frame);
-
- BLOCK_INPUT;
- /* Move the current process to the foreground if it is not. Don't
- call SetFrontProcess if the current process is already running in
- the foreground so as not to change the z-order of windows. */
- err = GetFrontProcess (&front_psn);
- if (err == noErr)
- err = SameProcess (&front_psn, &current_psn, &front_p);
- if (err == noErr)
- if (!front_p)
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (mac_front_non_floating_window () == FRAME_MAC_WINDOW (f))
- SetFrontProcessWithOptions (&current_psn,
- kSetFrontProcessFrontWindowOnly);
- else
-#endif
- SetFrontProcess (&current_psn);
- }
-
-#ifdef MAC_OSX
- mac_activate_window (mac_active_non_floating_window (), false);
- mac_activate_window (FRAME_MAC_WINDOW (f), true);
-#else
-#if !TARGET_API_MAC_CARBON
- /* SelectWindow (Non-Carbon) does not issue deactivate events if the
- possibly inactive window that is to be selected is already the
- frontmost one. */
- SendBehind (FRAME_MAC_WINDOW (f), NULL);
-#endif
- /* This brings the window to the front. */
- SelectWindow (FRAME_MAC_WINDOW (f));
-#endif
- UNBLOCK_INPUT;
-
- return Qnil;
-}
-
-
-DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
- doc: /* Internal function called by `color-defined-p', which see. */)
- (color, frame)
- Lisp_Object color, frame;
-{
- XColor foo;
- FRAME_PTR f = check_x_frame (frame);
-
- CHECK_STRING (color);
-
- if (mac_defined_color (f, SDATA (color), &foo, 0))
- return Qt;
- else
- return Qnil;
-}
-
-DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
- doc: /* Internal function called by `color-values', which see. */)
- (color, frame)
- Lisp_Object color, frame;
-{
- XColor foo;
- FRAME_PTR f = check_x_frame (frame);
-
- CHECK_STRING (color);
-
- if (mac_defined_color (f, SDATA (color), &foo, 0))
- return list3 (make_number (foo.red),
- make_number (foo.green),
- make_number (foo.blue));
- else
- return Qnil;
-}
-
-DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
- doc: /* Internal function called by `display-color-p', which see. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- if (!dpyinfo->color_p)
- return Qnil;
-
- return Qt;
-}
-
-DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
- 0, 1, 0,
- doc: /* Return t if DISPLAY supports shades of gray.
-Note that color displays do support shades of gray.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- if (dpyinfo->n_planes <= 1)
- return Qnil;
-
- return Qt;
-}
-
-DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
- 0, 1, 0,
- doc: /* Return the width in pixels of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- return make_number (dpyinfo->width);
-}
-
-DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
- Sx_display_pixel_height, 0, 1, 0,
- doc: /* Return the height in pixels of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- return make_number (dpyinfo->height);
-}
-
-DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
- 0, 1, 0,
- doc: /* Return the number of bitplanes of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- return make_number (dpyinfo->n_planes);
-}
-
-DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
- 0, 1, 0,
- doc: /* Return the number of color cells of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- /* We force 24+ bit depths to 24-bit to prevent an overflow. */
- return make_number (1 << min (dpyinfo->n_planes, 24));
-}
-
-DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
- Sx_server_max_request_size,
- 0, 1, 0,
- doc: /* Return the maximum request size of the server of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
- return make_number (1);
-}
-
-DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- doc: /* Return the "vendor ID" string of the Mac OS system (Apple).
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- return build_string ("Apple Inc.");
-}
-
-DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- doc: /* Return the version numbers of the Mac OS system.
-The value is a list of three integers: the major and minor
-version numbers, and the vendor-specific release
-number. See also the function `x-server-vendor'.
-
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- UInt32 response, major, minor, bugfix;
- OSErr err;
-
- BLOCK_INPUT;
- err = Gestalt (gestaltSystemVersion, &response);
- if (err == noErr)
- {
- if (response >= 0x00001040)
- {
- err = Gestalt ('sys1', &major);
- if (err == noErr)
- err = Gestalt ('sys2', &minor);
- if (err == noErr)
- err = Gestalt ('sys3', &bugfix);
- }
- else
- {
- bugfix = response & 0xf;
- response >>= 4;
- minor = response & 0xf;
- response >>= 4;
- /* convert BCD to int */
- major = response - (response >> 4) * 6;
- }
- }
- UNBLOCK_INPUT;
-
- if (err != noErr)
- error ("Cannot get Mac OS version");
-
- return Fcons (make_number (major),
- Fcons (make_number (minor),
- Fcons (make_number (bugfix),
- Qnil)));
-}
-
-DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- doc: /* Return the number of screens on the server of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- return make_number (1);
-}
-
-DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
- doc: /* Return the height in millimeters of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
- float mm_per_pixel;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGDisplayScreenSize != NULL)
-#endif
- {
- CGSize size;
-
- BLOCK_INPUT;
- size = CGDisplayScreenSize (kCGDirectMainDisplay);
- mm_per_pixel = size.height / CGDisplayPixelsHigh (kCGDirectMainDisplay);
- UNBLOCK_INPUT;
- }
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else /* CGDisplayScreenSize == NULL */
-#endif
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- {
- /* This is an approximation. */
- mm_per_pixel = 25.4f / dpyinfo->resy;
- }
-#endif
-
- return make_number ((int) (dpyinfo->height * mm_per_pixel + 0.5f));
-}
-
-DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
- doc: /* Return the width in millimeters of DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
- float mm_per_pixel;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGDisplayScreenSize != NULL)
-#endif
- {
- CGSize size;
-
- BLOCK_INPUT;
- size = CGDisplayScreenSize (kCGDirectMainDisplay);
- mm_per_pixel = size.width / CGDisplayPixelsWide (kCGDirectMainDisplay);
- UNBLOCK_INPUT;
- }
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else /* CGDisplayScreenSize == NULL */
-#endif
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- {
- /* This is an approximation. */
- mm_per_pixel = 25.4f / dpyinfo->resx;
- }
-#endif
-
- return make_number ((int) (dpyinfo->width * mm_per_pixel + 0.5f));
-}
-
-DEFUN ("x-display-backing-store", Fx_display_backing_store,
- Sx_display_backing_store, 0, 1, 0,
- doc: /* Return an indication of whether DISPLAY does backing store.
-The value may be `always', `when-mapped', or `not-useful'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- return intern ("not-useful");
-}
-
-DEFUN ("x-display-visual-class", Fx_display_visual_class,
- Sx_display_visual_class, 0, 1, 0,
- doc: /* Return the visual class of DISPLAY.
-The value is one of the symbols `static-gray', `gray-scale',
-`static-color', `pseudo-color', `true-color', or `direct-color'.
-
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
-
-#if 0
- switch (dpyinfo->visual->class)
- {
- case StaticGray: return (intern ("static-gray"));
- case GrayScale: return (intern ("gray-scale"));
- case StaticColor: return (intern ("static-color"));
- case PseudoColor: return (intern ("pseudo-color"));
- case TrueColor: return (intern ("true-color"));
- case DirectColor: return (intern ("direct-color"));
- default:
- error ("Display has an unknown visual class");
- }
-#endif /* 0 */
-
- return (intern ("true-color"));
-}
-
-DEFUN ("x-display-save-under", Fx_display_save_under,
- Sx_display_save_under, 0, 1, 0,
- doc: /* Return t if DISPLAY supports the save-under feature.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- return Qnil;
-}
-
-int
-x_pixel_width (f)
- register struct frame *f;
-{
- return FRAME_PIXEL_WIDTH (f);
-}
-
-int
-x_pixel_height (f)
- register struct frame *f;
-{
- return FRAME_PIXEL_HEIGHT (f);
-}
-
-int
-x_char_width (f)
- register struct frame *f;
-{
- return FRAME_COLUMN_WIDTH (f);
-}
-
-int
-x_char_height (f)
- register struct frame *f;
-{
- return FRAME_LINE_HEIGHT (f);
-}
-
-int
-x_screen_planes (f)
- register struct frame *f;
-{
- return FRAME_MAC_DISPLAY_INFO (f)->n_planes;
-}
-
-/* Return the display structure for the display named NAME.
- Open a new connection if necessary. */
-
-struct mac_display_info *
-x_display_info_for_name (name)
- Lisp_Object name;
-{
- Lisp_Object names;
- struct mac_display_info *dpyinfo;
-
- CHECK_STRING (name);
-
- for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
- dpyinfo;
- dpyinfo = dpyinfo->next, names = XCDR (names))
- {
- Lisp_Object tem;
- tem = Fstring_equal (XCAR (XCAR (names)), name);
- if (!NILP (tem))
- return dpyinfo;
- }
-
- /* Use this general default value to start with. */
- Vx_resource_name = Vinvocation_name;
-
- validate_x_resource_name ();
-
- dpyinfo = mac_term_init (name, (unsigned char *) 0,
- (char *) SDATA (Vx_resource_name));
-
- if (dpyinfo == 0)
- error ("Cannot connect to server %s", SDATA (name));
-
- mac_in_use = 1;
- XSETFASTINT (Vwindow_system_version, 3);
-
- return dpyinfo;
-}
-
-DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
- 1, 3, 0,
- doc: /* Open a connection to a server.
-DISPLAY is the name of the display to connect to.
-Optional second arg XRM-STRING is a string of resources in xrdb format.
-If the optional third arg MUST-SUCCEED is non-nil,
-terminate Emacs if we can't open the connection. */)
- (display, xrm_string, must_succeed)
- Lisp_Object display, xrm_string, must_succeed;
-{
- unsigned char *xrm_option;
- struct mac_display_info *dpyinfo;
-
- CHECK_STRING (display);
- if (! NILP (xrm_string))
- CHECK_STRING (xrm_string);
-
- if (! NILP (xrm_string))
- xrm_option = (unsigned char *) SDATA (xrm_string);
- else
- xrm_option = (unsigned char *) 0;
-
- validate_x_resource_name ();
-
- /* This is what opens the connection and sets x_current_display.
- This also initializes many symbols, such as those used for input. */
- dpyinfo = mac_term_init (display, xrm_option,
- (char *) SDATA (Vx_resource_name));
-
- if (dpyinfo == 0)
- {
- if (!NILP (must_succeed))
- fatal ("Cannot connect to server %s.\n",
- SDATA (display));
- else
- error ("Cannot connect to server %s", SDATA (display));
- }
-
- mac_in_use = 1;
-
- XSETFASTINT (Vwindow_system_version, 3);
- return Qnil;
-}
-
-DEFUN ("x-close-connection", Fx_close_connection,
- Sx_close_connection, 1, 1, 0,
- doc: /* Close the connection to DISPLAY's server.
-For DISPLAY, specify either a frame or a display name (a string).
-If DISPLAY is nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
-{
- struct mac_display_info *dpyinfo = check_x_display_info (display);
- int i;
-
- if (dpyinfo->reference_count > 0)
- error ("Display still has frames on it");
-
- BLOCK_INPUT;
- /* Free the fonts in the font table. */
- for (i = 0; i < dpyinfo->n_fonts; i++)
- if (dpyinfo->font_table[i].name)
- {
- mac_unload_font (dpyinfo, dpyinfo->font_table[i].font);
- }
-
- x_destroy_all_bitmaps (dpyinfo);
-
- x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
-
- return Qnil;
-}
-
-DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
- doc: /* Return the list of display names that Emacs has connections to. */)
- ()
-{
- Lisp_Object tail, result;
-
- result = Qnil;
- for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
- result = Fcons (XCAR (XCAR (tail)), result);
-
- return result;
-}
-
-DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
- doc: /* This is a noop on Mac OS systems. */)
- (on, display)
- Lisp_Object display, on;
-{
- return Qnil;
-}
-
-/* x_sync is a no-op on Mac. */
-
-void
-x_sync (f)
- FRAME_PTR f;
-{
-}
-
-
-/***********************************************************************
- Window properties
- ***********************************************************************/
-
-DEFUN ("x-change-window-property", Fx_change_window_property,
- Sx_change_window_property, 2, 6, 0,
- doc: /* Change window property PROP to VALUE on the X window of FRAME.
-VALUE may be a string or a list of conses, numbers and/or strings.
-If an element in the list is a string, it is converted to
-an Atom and the value of the Atom is used. If an element is a cons,
-it is converted to a 32 bit number where the car is the 16 top bits and the
-cdr is the lower 16 bits.
-FRAME nil or omitted means use the selected frame.
-If TYPE is given and non-nil, it is the name of the type of VALUE.
-If TYPE is not given or nil, the type is STRING.
-FORMAT gives the size in bits of each element if VALUE is a list.
-It must be one of 8, 16 or 32.
-If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
-If OUTER_P is non-nil, the property is changed for the outer X window of
-FRAME. Default is to change on the edit X window.
-
-Value is VALUE. */)
- (prop, value, frame, type, format, outer_p)
- Lisp_Object prop, value, frame, type, format, outer_p;
-{
-#if 0 /* MAC_TODO : port window properties to Mac */
- struct frame *f = check_x_frame (frame);
- Atom prop_atom;
-
- CHECK_STRING (prop);
- CHECK_STRING (value);
-
- BLOCK_INPUT;
- prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
- XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
- prop_atom, XA_STRING, 8, PropModeReplace,
- SDATA (value), SCHARS (value));
-
- /* Make sure the property is set when we return. */
- XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
-
-#endif /* MAC_TODO */
-
- return value;
-}
-
-
-DEFUN ("x-delete-window-property", Fx_delete_window_property,
- Sx_delete_window_property, 1, 2, 0,
- doc: /* Remove window property PROP from X window of FRAME.
-FRAME nil or omitted means use the selected frame. Value is PROP. */)
- (prop, frame)
- Lisp_Object prop, frame;
-{
-#if 0 /* MAC_TODO : port window properties to Mac */
-
- struct frame *f = check_x_frame (frame);
- Atom prop_atom;
-
- CHECK_STRING (prop);
- BLOCK_INPUT;
- prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
- XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
-
- /* Make sure the property is removed when we return. */
- XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
-#endif /* MAC_TODO */
-
- return prop;
-}
-
-
-DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
- 1, 2, 0,
- doc: /* Value is the value of window property PROP on FRAME.
-If FRAME is nil or omitted, use the selected frame. Value is nil
-if FRAME hasn't a property with name PROP or if PROP has no string
-value. */)
- (prop, frame)
- Lisp_Object prop, frame;
-{
-#if 0 /* MAC_TODO : port window properties to Mac */
-
- struct frame *f = check_x_frame (frame);
- Atom prop_atom;
- int rc;
- Lisp_Object prop_value = Qnil;
- char *tmp_data = NULL;
- Atom actual_type;
- int actual_format;
- unsigned long actual_size, bytes_remaining;
-
- CHECK_STRING (prop);
- BLOCK_INPUT;
- prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
- rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
- prop_atom, 0, 0, False, XA_STRING,
- &actual_type, &actual_format, &actual_size,
- &bytes_remaining, (unsigned char **) &tmp_data);
- if (rc == Success)
- {
- int size = bytes_remaining;
-
- XFree (tmp_data);
- tmp_data = NULL;
-
- rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
- prop_atom, 0, bytes_remaining,
- False, XA_STRING,
- &actual_type, &actual_format,
- &actual_size, &bytes_remaining,
- (unsigned char **) &tmp_data);
- if (rc == Success)
- prop_value = make_string (tmp_data, size);
-
- XFree (tmp_data);
- }
-
- UNBLOCK_INPUT;
-
- return prop_value;
-
-#endif /* MAC_TODO */
- return Qnil;
-}
-
-
-
-/***********************************************************************
- Busy cursor
- ***********************************************************************/
-
-/* Timer function of hourglass_atimer. TIMER is equal to
- hourglass_atimer.
-
- On Mac, busy status is shown by the progress indicator (chasing
- arrows) at the upper-right corner of each frame instead of the
- hourglass pointer. */
-
-void
-show_hourglass (timer)
- struct atimer *timer;
-{
-#if TARGET_API_MAC_CARBON
- /* The timer implementation will cancel this timer automatically
- after this function has run. Set hourglass_atimer to null
- so that we know the timer doesn't have to be canceled. */
- hourglass_atimer = NULL;
-
- if (!hourglass_shown_p)
- {
- Lisp_Object rest, frame;
-
- BLOCK_INPUT;
-
- FOR_EACH_FRAME (rest, frame)
- {
- struct frame *f = XFRAME (frame);
-
- if (FRAME_LIVE_P (f) && FRAME_MAC_P (f)
- && FRAME_MAC_WINDOW (f) != tip_window)
- mac_show_hourglass (f);
- }
-
- hourglass_shown_p = 1;
- UNBLOCK_INPUT;
- }
-#endif /* TARGET_API_MAC_CARBON */
-}
-
-
-/* Hide the progress indicators on all frames, if it is currently
- shown. */
-
-void
-hide_hourglass ()
-{
-#if TARGET_API_MAC_CARBON
- if (hourglass_shown_p)
- {
- Lisp_Object rest, frame;
-
- BLOCK_INPUT;
- FOR_EACH_FRAME (rest, frame)
- {
- struct frame *f = XFRAME (frame);
-
- if (FRAME_MAC_P (f))
- mac_hide_hourglass (f);
- }
-
- hourglass_shown_p = 0;
- UNBLOCK_INPUT;
- }
-#endif /* TARGET_API_MAC_CARBON */
-}
-
-
-
-/***********************************************************************
- Tool tips
- ***********************************************************************/
-
-static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
- Lisp_Object, Lisp_Object));
-static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
- Lisp_Object, int, int, int *, int *));
-
-/* The frame of a currently visible tooltip. */
-
-Lisp_Object tip_frame;
-
-/* If non-nil, a timer started that hides the last tooltip when it
- fires. */
-
-Lisp_Object tip_timer;
-Window tip_window;
-
-/* If non-nil, a vector of 3 elements containing the last args
- with which x-show-tip was called. See there. */
-
-Lisp_Object last_show_tip_args;
-
-/* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
-
-Lisp_Object Vx_max_tooltip_size;
-
-
-static Lisp_Object
-unwind_create_tip_frame (frame)
- Lisp_Object frame;
-{
- Lisp_Object deleted;
-
- deleted = unwind_create_frame (frame);
- if (EQ (deleted, Qt))
- {
- tip_window = NULL;
- tip_frame = Qnil;
- }
-
- return deleted;
-}
-
-
-/* Create a frame for a tooltip on the display described by DPYINFO.
- PARMS is a list of frame parameters. TEXT is the string to
- display in the tip frame. Value is the frame.
-
- Note that functions called here, esp. x_default_parameter can
- signal errors, for instance when a specified color name is
- undefined. We have to make sure that we're in a consistent state
- when this happens. */
-
-static Lisp_Object
-x_create_tip_frame (dpyinfo, parms, text)
- struct mac_display_info *dpyinfo;
- Lisp_Object parms, text;
-{
- struct frame *f;
- Lisp_Object frame, tem;
- Lisp_Object name;
- long window_prompting = 0;
- int width, height;
- int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3;
- struct kboard *kb;
- int face_change_count_before = face_change_count;
- Lisp_Object buffer;
- struct buffer *old_buffer;
-
- check_mac ();
-
- parms = Fcopy_alist (parms);
-
- kb = dpyinfo->terminal->kboard;
-
- /* Get the name of the frame to use for resource lookup. */
- name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
- if (!STRINGP (name)
- && !EQ (name, Qunbound)
- && !NILP (name))
- error ("Invalid frame name--not a string or nil");
-
- frame = Qnil;
- GCPRO3 (parms, name, frame);
- f = make_frame (1);
- XSETFRAME (frame, f);
-
- buffer = Fget_buffer_create (build_string (" *tip*"));
- Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
- old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (buffer));
- current_buffer->truncate_lines = Qnil;
- specbind (Qinhibit_read_only, Qt);
- specbind (Qinhibit_modification_hooks, Qt);
- Ferase_buffer ();
- Finsert (1, &text);
- set_buffer_internal_1 (old_buffer);
-
- FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
- record_unwind_protect (unwind_create_tip_frame, frame);
-
- /* By setting the output method, we're essentially saying that
- the frame is live, as per FRAME_LIVE_P. If we get a signal
- from this point on, x_destroy_window might screw up reference
- counts etc. */
- f->terminal = dpyinfo->terminal;
- f->terminal->reference_count++;
- f->output_method = output_mac;
- f->output_data.mac =
- (struct mac_output *) xmalloc (sizeof (struct mac_output));
- bzero (f->output_data.mac, sizeof (struct mac_output));
-
- FRAME_FONTSET (f) = -1;
- f->icon_name = Qnil;
-/* FRAME_X_DISPLAY_INFO (f) = dpyinfo; */
-#if GLYPH_DEBUG
- image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
- dpyinfo_refcount = dpyinfo->reference_count;
-#endif /* GLYPH_DEBUG */
- FRAME_KBOARD (f) = kb;
- f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
- f->output_data.mac->explicit_parent = 0;
-
- /* Set the name; the functions to which we pass f expect the name to
- be set. */
- if (EQ (name, Qunbound) || NILP (name))
- {
- f->name = build_string (dpyinfo->mac_id_name);
- f->explicit_name = 0;
- }
- else
- {
- f->name = name;
- f->explicit_name = 1;
- /* use the frame's title when getting resources for this frame. */
- specbind (Qx_resource_name, name);
- }
-
- /* Extract the window parameters from the supplied values that are
- needed to determine window geometry. */
- {
- Lisp_Object font;
-
- font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
-
- BLOCK_INPUT;
- /* First, try whatever font the caller has specified. */
- if (STRINGP (font))
- {
- tem = Fquery_fontset (font, Qnil);
- if (STRINGP (tem))
- font = x_new_fontset (f, tem);
- else
- font = x_new_font (f, SDATA (font));
- }
-
- /* Try out a font which we hope has bold and italic variations. */
-#if USE_ATSUI
- if (! STRINGP (font))
- font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1");
-#endif
- if (! STRINGP (font))
- font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
- /* If those didn't work, look for something which will at least work. */
- if (! STRINGP (font))
- font = x_new_fontset (f, build_string ("fontset-standard"));
- if (! STRINGP (font))
- font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
- if (! STRINGP (font))
- font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
- UNBLOCK_INPUT;
- if (! STRINGP (font))
- error ("Cannot find any usable font");
-
- x_default_parameter (f, parms, Qfont, font,
- "font", "Font", RES_TYPE_STRING);
- }
-
- x_default_parameter (f, parms, Qborder_width, make_number (2),
- "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
-
- /* This defaults to 2 in order to match xterm. We recognize either
- internalBorderWidth or internalBorder (which is what xterm calls
- it). */
- if (NILP (Fassq (Qinternal_border_width, parms)))
- {
- Lisp_Object value;
-
- value = mac_get_arg (parms, Qinternal_border_width,
- "internalBorder", "internalBorder", RES_TYPE_NUMBER);
- if (! EQ (value, Qunbound))
- parms = Fcons (Fcons (Qinternal_border_width, value),
- parms);
- }
-
- x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
- "internalBorderWidth", "internalBorderWidth",
- RES_TYPE_NUMBER);
-
- /* Also do the stuff which must be set before the window exists. */
- x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
- "foreground", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
- "background", "Background", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
- "pointerColor", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
- "cursorColor", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qborder_color, build_string ("black"),
- "borderColor", "BorderColor", RES_TYPE_STRING);
-
- /* Init faces before x_default_parameter is called for scroll-bar
- parameters because that function calls x_set_scroll_bar_width,
- which calls change_frame_size, which calls Fset_window_buffer,
- which runs hooks, which call Fvertical_motion. At the end, we
- end up in init_iterator with a null face cache, which should not
- happen. */
- init_frame_faces (f);
-
- f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
-
- window_prompting = x_figure_window_size (f, parms, 0);
-
- BLOCK_INPUT;
-
- mac_create_frame_window (f, 1);
-
- if (FRAME_MAC_WINDOW (f))
- {
- mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
- tip_window = FRAME_MAC_WINDOW (f);
- }
-
- UNBLOCK_INPUT;
-
- x_make_gc (f);
-
- x_default_parameter (f, parms, Qauto_raise, Qnil,
- "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- x_default_parameter (f, parms, Qauto_lower, Qnil,
- "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- x_default_parameter (f, parms, Qcursor_type, Qbox,
- "cursorType", "CursorType", RES_TYPE_SYMBOL);
-
- /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
- Change will not be effected unless different from the current
- FRAME_LINES (f). */
- width = FRAME_COLS (f);
- height = FRAME_LINES (f);
- SET_FRAME_COLS (f, 0);
- FRAME_LINES (f) = 0;
- change_frame_size (f, height, width, 1, 0, 0);
-
- /* Add `tooltip' frame parameter's default value. */
- if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
- Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
- Qnil));
-
- /* Set up faces after all frame parameters are known. This call
- also merges in face attributes specified for new frames.
-
- Frame parameters may be changed if .Xdefaults contains
- specifications for the default font. For example, if there is an
- `Emacs.default.attributeBackground: pink', the `background-color'
- attribute of the frame get's set, which let's the internal border
- of the tooltip frame appear in pink. Prevent this. */
- {
- Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
-
- /* Set tip_frame here, so that */
- tip_frame = frame;
- call2 (Qface_set_after_frame_default, frame, Qnil);
-
- if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
- Qnil));
- }
-
- f->no_split = 1;
-
- UNGCPRO;
-
- /* It is now ok to make the frame official even if we get an error
- below. And the frame needs to be on Vframe_list or making it
- visible won't work. */
- Vframe_list = Fcons (frame, Vframe_list);
-
- /* Now that the frame is official, it counts as a reference to
- its display. */
- FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
-
- /* Setting attributes of faces of the tooltip frame from resources
- and similar will increment face_change_count, which leads to the
- clearing of all current matrices. Since this isn't necessary
- here, avoid it by resetting face_change_count to the value it
- had before we created the tip frame. */
- face_change_count = face_change_count_before;
-
- /* Discard the unwind_protect. */
- return unbind_to (count, frame);
-}
-
-
-/* Compute where to display tip frame F. PARMS is the list of frame
- parameters for F. DX and DY are specified offsets from the current
- location of the mouse. WIDTH and HEIGHT are the width and height
- of the tooltip. Return coordinates relative to the root window of
- the display in *ROOT_X, and *ROOT_Y. */
-
-static void
-compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
- struct frame *f;
- Lisp_Object parms, dx, dy;
- int width, height;
- int *root_x, *root_y;
-{
- Lisp_Object left, top;
-
- /* User-specified position? */
- left = Fcdr (Fassq (Qleft, parms));
- top = Fcdr (Fassq (Qtop, parms));
-
- /* Move the tooltip window where the mouse pointer is. Resize and
- show it. */
- if (!INTEGERP (left) || !INTEGERP (top))
- {
- Point mouse_pos;
-
- BLOCK_INPUT;
-#if TARGET_API_MAC_CARBON
- mac_get_global_mouse (&mouse_pos);
-#else
- GetMouse (&mouse_pos);
- LocalToGlobal (&mouse_pos);
-#endif
- *root_x = mouse_pos.h;
- *root_y = mouse_pos.v;
- UNBLOCK_INPUT;
- }
-
- if (INTEGERP (top))
- *root_y = XINT (top);
- else if (*root_y + XINT (dy) <= 0)
- *root_y = 0; /* Can happen for negative dy */
- else if (*root_y + XINT (dy) + height <= FRAME_MAC_DISPLAY_INFO (f)->height)
- /* It fits below the pointer */
- *root_y += XINT (dy);
- else if (height + XINT (dy) <= *root_y)
- /* It fits above the pointer. */
- *root_y -= height + XINT (dy);
- else
- /* Put it on the top. */
- *root_y = 0;
-
- if (INTEGERP (left))
- *root_x = XINT (left);
- else if (*root_x + XINT (dx) <= 0)
- *root_x = 0; /* Can happen for negative dx */
- else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
- /* It fits to the right of the pointer. */
- *root_x += XINT (dx);
- else if (width + XINT (dx) <= *root_x)
- /* It fits to the left of the pointer. */
- *root_x -= width + XINT (dx);
- else
- /* Put it left-justified on the screen -- it ought to fit that way. */
- *root_x = 0;
-}
-
-
-DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
- doc: /* Show STRING in a "tooltip" window on frame FRAME.
-A tooltip window is a small window displaying a string.
-
-This is an internal function; Lisp code should call `tooltip-show'.
-
-FRAME nil or omitted means use the selected frame.
-
-PARMS is an optional list of frame parameters which can be used to
-change the tooltip's appearance.
-
-Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
-means use the default timeout of 5 seconds.
-
-If the list of frame parameters PARMS contains a `left' parameter,
-the tooltip is displayed at that x-position. Otherwise it is
-displayed at the mouse position, with offset DX added (default is 5 if
-DX isn't specified). Likewise for the y-position; if a `top' frame
-parameter is specified, it determines the y-position of the tooltip
-window, otherwise it is displayed at the mouse position, with offset
-DY added (default is -10).
-
-A tooltip's maximum size is specified by `x-max-tooltip-size'.
-Text larger than the specified size is clipped. */)
- (string, frame, parms, timeout, dx, dy)
- Lisp_Object string, frame, parms, timeout, dx, dy;
-{
- struct frame *f;
- struct window *w;
- int root_x, root_y;
- struct buffer *old_buffer;
- struct text_pos pos;
- int i, width, height;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- int old_windows_or_buffers_changed = windows_or_buffers_changed;
- int count = SPECPDL_INDEX ();
-
- specbind (Qinhibit_redisplay, Qt);
-
- GCPRO4 (string, parms, frame, timeout);
-
- CHECK_STRING (string);
- f = check_x_frame (frame);
- if (NILP (timeout))
- timeout = make_number (5);
- else
- CHECK_NATNUM (timeout);
-
- if (NILP (dx))
- dx = make_number (5);
- else
- CHECK_NUMBER (dx);
-
- if (NILP (dy))
- dy = make_number (-10);
- else
- CHECK_NUMBER (dy);
-
- if (NILP (last_show_tip_args))
- last_show_tip_args = Fmake_vector (make_number (3), Qnil);
-
- if (!NILP (tip_frame))
- {
- Lisp_Object last_string = AREF (last_show_tip_args, 0);
- Lisp_Object last_frame = AREF (last_show_tip_args, 1);
- Lisp_Object last_parms = AREF (last_show_tip_args, 2);
-
- if (EQ (frame, last_frame)
- && !NILP (Fequal (last_string, string))
- && !NILP (Fequal (last_parms, parms)))
- {
- struct frame *f = XFRAME (tip_frame);
-
- /* Only DX and DY have changed. */
- if (!NILP (tip_timer))
- {
- Lisp_Object timer = tip_timer;
- tip_timer = Qnil;
- call1 (Qcancel_timer, timer);
- }
-
- BLOCK_INPUT;
- compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
- FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
- mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
- UNBLOCK_INPUT;
- goto start_timer;
- }
- }
-
- /* Hide a previous tip, if any. */
- Fx_hide_tip ();
-
- ASET (last_show_tip_args, 0, string);
- ASET (last_show_tip_args, 1, frame);
- ASET (last_show_tip_args, 2, parms);
-
- /* Add default values to frame parameters. */
- if (NILP (Fassq (Qname, parms)))
- parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
- if (NILP (Fassq (Qinternal_border_width, parms)))
- parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
- if (NILP (Fassq (Qborder_width, parms)))
- parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
- if (NILP (Fassq (Qborder_color, parms)))
- parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
- if (NILP (Fassq (Qbackground_color, parms)))
- parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
- parms);
-
- /* Create a frame for the tooltip, and record it in the global
- variable tip_frame. */
- frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
- f = XFRAME (frame);
-
- /* Set up the frame's root window. */
- w = XWINDOW (FRAME_ROOT_WINDOW (f));
- w->left_col = w->top_line = make_number (0);
-
- if (CONSP (Vx_max_tooltip_size)
- && INTEGERP (XCAR (Vx_max_tooltip_size))
- && XINT (XCAR (Vx_max_tooltip_size)) > 0
- && INTEGERP (XCDR (Vx_max_tooltip_size))
- && XINT (XCDR (Vx_max_tooltip_size)) > 0)
- {
- w->total_cols = XCAR (Vx_max_tooltip_size);
- w->total_lines = XCDR (Vx_max_tooltip_size);
- }
- else
- {
- w->total_cols = make_number (80);
- w->total_lines = make_number (40);
- }
-
- FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
- adjust_glyphs (f);
- w->pseudo_window_p = 1;
-
- /* Display the tooltip text in a temporary buffer. */
- old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
- current_buffer->truncate_lines = Qnil;
- clear_glyph_matrix (w->desired_matrix);
- clear_glyph_matrix (w->current_matrix);
- SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
- try_window (FRAME_ROOT_WINDOW (f), pos, 0);
-
- /* Compute width and height of the tooltip. */
- width = height = 0;
- for (i = 0; i < w->desired_matrix->nrows; ++i)
- {
- struct glyph_row *row = &w->desired_matrix->rows[i];
- struct glyph *last;
- int row_width;
-
- /* Stop at the first empty row at the end. */
- if (!row->enabled_p || !row->displays_text_p)
- break;
-
- /* Let the row go over the full width of the frame. */
- row->full_width_p = 1;
-
- /* There's a glyph at the end of rows that is used to place
- the cursor there. Don't include the width of this glyph. */
- if (row->used[TEXT_AREA])
- {
- last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
- row_width = row->pixel_width - last->pixel_width;
- }
- else
- row_width = row->pixel_width;
-
- height += row->height;
- width = max (width, row_width);
- }
-
- /* Add the frame's internal border to the width and height the X
- window should have. */
- height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
- width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
-
- /* Move the tooltip window where the mouse pointer is. Resize and
- show it. */
- compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
-
- BLOCK_INPUT;
- mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
- mac_size_window (FRAME_MAC_WINDOW (f), width, height, true);
- mac_show_window (FRAME_MAC_WINDOW (f));
- mac_bring_window_to_front (FRAME_MAC_WINDOW (f));
- UNBLOCK_INPUT;
-
- FRAME_PIXEL_WIDTH (f) = width;
- FRAME_PIXEL_HEIGHT (f) = height;
-
- /* Draw into the window. */
- w->must_be_updated_p = 1;
- update_single_window (w, 1);
-
- /* Restore original current buffer. */
- set_buffer_internal_1 (old_buffer);
- windows_or_buffers_changed = old_windows_or_buffers_changed;
-
- start_timer:
- /* Let the tip disappear after timeout seconds. */
- tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
- intern ("x-hide-tip"));
-
- UNGCPRO;
- return unbind_to (count, Qnil);
-}
-
-
-DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
- doc: /* Hide the current tooltip window, if there is any.
-Value is t if tooltip was open, nil otherwise. */)
- ()
-{
- int count;
- Lisp_Object deleted, frame, timer;
- struct gcpro gcpro1, gcpro2;
-
- /* Return quickly if nothing to do. */
- if (NILP (tip_timer) && NILP (tip_frame))
- return Qnil;
-
- frame = tip_frame;
- timer = tip_timer;
- GCPRO2 (frame, timer);
- tip_frame = tip_timer = deleted = Qnil;
-
- count = SPECPDL_INDEX ();
- specbind (Qinhibit_redisplay, Qt);
- specbind (Qinhibit_quit, Qt);
-
- if (!NILP (timer))
- call1 (Qcancel_timer, timer);
-
- if (FRAMEP (frame))
- {
- Fdelete_frame (frame, Qnil);
- deleted = Qt;
- }
-
- UNGCPRO;
- return unbind_to (count, deleted);
-}
-
-
-
-/***********************************************************************
- File selection dialog
- ***********************************************************************/
-
-#if TARGET_API_MAC_CARBON
-DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
- doc: /* Read file name, prompting with PROMPT in directory DIR.
-Use a file selection dialog.
-Select DEFAULT-FILENAME in the dialog's file selection box, if
-specified. Ensure that file exists if MUSTMATCH is non-nil.
-If ONLY-DIR-P is non-nil, the user can only select directories. */)
- (prompt, dir, default_filename, mustmatch, only_dir_p)
- Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
-{
- return mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p);
-}
-#endif
-
-
-/***********************************************************************
- Fonts
- ***********************************************************************/
-
-DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table,
- Smac_clear_font_name_table, 0, 0, 0,
- doc: /* Clear the font name table. */)
- ()
-{
- check_mac ();
- mac_clear_font_name_table ();
- return Qnil;
-}
-
-#if USE_MAC_FONT_PANEL
-DEFUN ("mac-set-font-panel-visible-p", Fmac_set_font_panel_visible_p,
- Smac_set_font_panel_visible_p, 1, 1, 0,
- doc: /* Make the font panel visible if and only if FLAG is non-nil.
-This is for internal use only. Use `mac-font-panel-mode' instead. */)
- (flag)
- Lisp_Object flag;
-{
- OSStatus err = noErr;
-
- check_mac ();
-
- BLOCK_INPUT;
- if (NILP (flag) != !mac_font_panel_visible_p ())
- {
- err = mac_show_hide_font_panel ();
- if (err == noErr && !NILP (flag))
- {
- Lisp_Object focus_frame = x_get_focus_frame (SELECTED_FRAME ());
- struct frame *f = (NILP (focus_frame) ? SELECTED_FRAME ()
- : XFRAME (focus_frame));
-
- mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
- }
- }
- UNBLOCK_INPUT;
-
- if (err != noErr)
- error ("Cannot change visibility of the font panel");
- return Qnil;
-}
-#endif
-
-#if USE_ATSUI
-extern Lisp_Object mac_atsu_font_face_attributes P_ ((ATSUFontID));
-
-DEFUN ("mac-atsu-font-face-attributes", Fmac_atsu_font_face_attributes,
- Smac_atsu_font_face_attributes, 1, 1, 0,
- doc: /* Return plist of face attributes and values for ATSU font ID.
-ID is specified by either an integer or a float. */)
- (id)
- Lisp_Object id;
-{
- ATSUFontID font_id;
- Lisp_Object result;
-
- check_mac ();
- CHECK_NUMBER_OR_FLOAT (id);
- font_id = INTEGERP (id) ? XINT (id) : XFLOAT_DATA (id);
- BLOCK_INPUT;
- result = mac_atsu_font_face_attributes (font_id);
- UNBLOCK_INPUT;
- return result;
-}
-#endif
-
-
-/***********************************************************************
- Initialization
- ***********************************************************************/
-
-/* Keep this list in the same order as frame_parms in frame.c.
- Use 0 for unsupported frame parameters. */
-
-frame_parm_handler mac_frame_parm_handlers[] =
-{
- x_set_autoraise,
- x_set_autolower,
- x_set_background_color,
- x_set_border_color,
- x_set_border_width,
- x_set_cursor_color,
- x_set_cursor_type,
- mac_set_font,
- x_set_foreground_color,
- x_set_icon_name,
- 0, /* MAC_TODO: x_set_icon_type, */
- x_set_internal_border_width,
- x_set_menu_bar_lines,
- x_set_mouse_color,
- x_explicitly_set_name,
- x_set_scroll_bar_width,
- x_set_title,
- x_set_unsplittable,
- x_set_vertical_scroll_bars,
- x_set_visibility,
- x_set_tool_bar_lines,
- 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
- 0, /* MAC_TODO: x_set_scroll_bar_background, */
- x_set_screen_gamma,
- x_set_line_spacing,
- x_set_fringe_width,
- x_set_fringe_width,
- 0, /* x_set_wait_for_wm, */
- x_set_fullscreen,
- 0, /* x_set_font_backend, */
- 0 /* x_set_alpha, */
-};
-
-void
-syms_of_macfns ()
-{
-#ifdef MAC_OSX
- /* This is zero if not using Mac native windows. */
- mac_in_use = 0;
-#else
- /* Certainly running on Mac native windows. */
- mac_in_use = 1;
-#endif
-
- /* The section below is built by the lisp expression at the top of the file,
- just above where these variables are declared. */
- /*&&& init symbols here &&&*/
- Qnone = intern ("none");
- staticpro (&Qnone);
- Qsuppress_icon = intern ("suppress-icon");
- staticpro (&Qsuppress_icon);
- Qundefined_color = intern ("undefined-color");
- staticpro (&Qundefined_color);
- Qcancel_timer = intern ("cancel-timer");
- staticpro (&Qcancel_timer);
- /* This is the end of symbol initialization. */
-
- /* Text property `display' should be nonsticky by default. */
- Vtext_property_default_nonsticky
- = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
-
-
- Fput (Qundefined_color, Qerror_conditions,
- Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
- Fput (Qundefined_color, Qerror_message,
- build_string ("Undefined color"));
-
- DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
- doc: /* The shape of the pointer when over text.
-Changing the value does not affect existing frames
-unless you set the mouse color. */);
- Vx_pointer_shape = Qnil;
-
-#if 0 /* This doesn't really do anything. */
- DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
- doc: /* The shape of the pointer when not over text.
-This variable takes effect when you create a new frame
-or when you set the mouse color. */);
-#endif
- Vx_nontext_pointer_shape = Qnil;
-
- DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
- doc: /* The shape of the pointer when Emacs is busy.
-This variable takes effect when you create a new frame
-or when you set the mouse color. */);
- Vx_hourglass_pointer_shape = Qnil;
-
-#if 0 /* This doesn't really do anything. */
- DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
- doc: /* The shape of the pointer when over the mode line.
-This variable takes effect when you create a new frame
-or when you set the mouse color. */);
-#endif
- Vx_mode_pointer_shape = Qnil;
-
- DEFVAR_LISP ("x-sensitive-text-pointer-shape",
- &Vx_sensitive_text_pointer_shape,
- doc: /* The shape of the pointer when over mouse-sensitive text.
-This variable takes effect when you create a new frame
-or when you set the mouse color. */);
- Vx_sensitive_text_pointer_shape = Qnil;
-
- DEFVAR_LISP ("x-window-horizontal-drag-cursor",
- &Vx_window_horizontal_drag_shape,
- doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
-This variable takes effect when you create a new frame
-or when you set the mouse color. */);
- Vx_window_horizontal_drag_shape = Qnil;
-
- DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
- doc: /* A string indicating the foreground color of the cursor box. */);
- Vx_cursor_fore_pixel = Qnil;
-
- DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
- doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
-Text larger than this is clipped. */);
- Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
-
- DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
- doc: /* Non-nil if no window manager is in use.
-Emacs doesn't try to figure this out; this is always nil
-unless you set it to something else. */);
- /* We don't have any way to find this out, so set it to nil
- and maybe the user would like to set it to t. */
- Vx_no_window_manager = Qnil;
-
- DEFVAR_LISP ("x-pixel-size-width-font-regexp",
- &Vx_pixel_size_width_font_regexp,
- doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
-
-Since Emacs gets width of a font matching with this regexp from
-PIXEL_SIZE field of the name, font finding mechanism gets faster for
-such a font. This is especially effective for such large fonts as
-Chinese, Japanese, and Korean. */);
- Vx_pixel_size_width_font_regexp = Qnil;
-
-#if TARGET_API_MAC_CARBON
- DEFVAR_LISP ("mac-carbon-version-string", &Vmac_carbon_version_string,
- doc: /* Version info for Carbon API. */);
- {
- OSErr err;
- UInt32 response;
- char carbon_version[16] = "Unknown";
-
- err = Gestalt (gestaltCarbonVersion, &response);
- if (err == noErr)
- sprintf (carbon_version, "%u.%u.%u",
- (response >> 8) & 0xf, (response >> 4) & 0xf, response & 0xf);
- Vmac_carbon_version_string = build_string (carbon_version);
- }
-#endif /* TARGET_API_MAC_CARBON */
-
- /* X window properties. */
- defsubr (&Sx_change_window_property);
- defsubr (&Sx_delete_window_property);
- defsubr (&Sx_window_property);
-
- defsubr (&Sxw_display_color_p);
- defsubr (&Sx_display_grayscale_p);
- defsubr (&Sxw_color_defined_p);
- defsubr (&Sxw_color_values);
- defsubr (&Sx_server_max_request_size);
- defsubr (&Sx_server_vendor);
- defsubr (&Sx_server_version);
- defsubr (&Sx_display_pixel_width);
- defsubr (&Sx_display_pixel_height);
- defsubr (&Sx_display_mm_width);
- defsubr (&Sx_display_mm_height);
- defsubr (&Sx_display_screens);
- defsubr (&Sx_display_planes);
- defsubr (&Sx_display_color_cells);
- defsubr (&Sx_display_visual_class);
- defsubr (&Sx_display_backing_store);
- defsubr (&Sx_display_save_under);
- defsubr (&Sx_create_frame);
- defsubr (&Sx_open_connection);
- defsubr (&Sx_close_connection);
- defsubr (&Sx_display_list);
- defsubr (&Sx_synchronize);
- defsubr (&Sx_focus_frame);
-
- /* Setting callback functions for fontset handler. */
- get_font_info_func = x_get_font_info;
-
-#if 0 /* This function pointer doesn't seem to be used anywhere.
- And the pointer assigned has the wrong type, anyway. */
- list_fonts_func = x_list_fonts;
-#endif
-
- load_font_func = x_load_font;
- find_ccl_program_func = x_find_ccl_program;
- query_font_func = x_query_font;
- set_frame_fontset_func = mac_set_font;
- check_window_system_func = check_mac;
-
- hourglass_atimer = NULL;
- hourglass_shown_p = 0;
-
- defsubr (&Sx_show_tip);
- defsubr (&Sx_hide_tip);
- tip_timer = Qnil;
- staticpro (&tip_timer);
- tip_frame = Qnil;
- staticpro (&tip_frame);
-
- last_show_tip_args = Qnil;
- staticpro (&last_show_tip_args);
-
-#if TARGET_API_MAC_CARBON
- defsubr (&Sx_file_dialog);
-#endif
- defsubr (&Smac_clear_font_name_table);
-#if USE_MAC_FONT_PANEL
- defsubr (&Smac_set_font_panel_visible_p);
-#endif
-#if USE_ATSUI
- defsubr (&Smac_atsu_font_face_attributes);
-#endif
-}
-
-/* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
- (do not change this comment) */
diff --git a/src/macgui.h b/src/macgui.h
deleted file mode 100644
index 6b8e560cac2..00000000000
--- a/src/macgui.h
+++ /dev/null
@@ -1,496 +0,0 @@
-/* Definitions and headers for communication on the Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Contributed by Andrew Choi (akochoi@mac.com). */
-
-#ifndef EMACS_MACGUI_H
-#define EMACS_MACGUI_H
-
-typedef struct _XDisplay Display; /* opaque */
-
-typedef Lisp_Object XrmDatabase;
-
-typedef unsigned long Time;
-
-#ifdef HAVE_CARBON
-#undef Z
-#ifdef MAC_OSX
-#if ! HAVE_MKTIME || BROKEN_MKTIME
-#undef mktime
-#endif
-#undef DEBUG
-#undef free
-#undef malloc
-#undef realloc
-/* Macros max and min defined in lisp.h conflict with those in
- precompiled header Carbon.h. */
-#undef max
-#undef min
-#undef init_process
-#include <Carbon/Carbon.h>
-#if ! HAVE_MKTIME || BROKEN_MKTIME
-#undef mktime
-#define mktime emacs_mktime
-#endif
-#undef free
-#define free unexec_free
-#undef malloc
-#define malloc unexec_malloc
-#undef realloc
-#define realloc unexec_realloc
-#undef min
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#undef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#undef init_process
-#define init_process emacs_init_process
-#undef INFINITY
-#else /* not MAC_OSX */
-#undef SIGHUP
-#define OLDP2C 1
-#include <Carbon.h>
-#endif /* not MAC_OSX */
-#undef Z
-#define Z (current_buffer->text->z)
-#else /* not HAVE_CARBON */
-#include <Quickdraw.h> /* for WindowRef */
-#include <QDOffscreen.h> /* for GWorldPtr */
-#include <Appearance.h> /* for ThemeCursor */
-#include <Windows.h>
-#include <Controls.h>
-#include <Gestalt.h>
-#endif /* not HAVE_CARBON */
-
-/* Whether to use ATSUI (Apple Type Services for Unicode Imaging) for
- text drawing. */
-#if 0 /* Don't enable by default on the emacs-unicode-2 branch. */
-#ifndef USE_ATSUI
-#ifdef MAC_OSX
-#define USE_ATSUI 1
-#endif
-#endif
-#endif
-
-/* Whether to use low-level Quartz 2D (aka Core Graphics) text drawing
- in preference to ATSUI for ASCII and Latin-1 characters. */
-#ifndef USE_CG_TEXT_DRAWING
-#if USE_ATSUI && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#define USE_CG_TEXT_DRAWING 1
-#endif
-#endif
-
-/* Whether to use Quartz 2D routines for drawing operations other than
- texts. */
-#ifndef USE_CG_DRAWING
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-#define USE_CG_DRAWING 1
-#endif
-#endif
-
-/* Whether to use the standard Font Panel floating dialog. */
-#ifndef USE_MAC_FONT_PANEL
-#if USE_ATSUI && MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-#define USE_MAC_FONT_PANEL 1
-#endif
-#endif
-
-/* Whether to use Text Services Manager. */
-#ifndef USE_MAC_TSM
-#if TARGET_API_MAC_CARBON
-#define USE_MAC_TSM 1
-#endif
-#endif
-
-/* Whether to use HIToolbar. */
-#ifndef USE_MAC_TOOLBAR
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 && MAC_OS_X_VERSION_MIN_REQUIRED != 1020
-#define USE_MAC_TOOLBAR 1
-#endif
-#endif
-
-#ifndef CGFLOAT_DEFINED
-typedef float CGFloat;
-#endif
-
-typedef WindowRef Window;
-#if TARGET_API_MAC_CARBON
-typedef ScrapRef Selection;
-#else
-typedef int Selection;
-#endif
-#define mac_set_window_title SetWindowTitleWithCFString
-#define mac_set_window_modified SetWindowModified
-#define mac_is_window_visible IsWindowVisible
-#define mac_is_window_collapsed IsWindowCollapsed
-#define mac_bring_window_to_front BringToFront
-#define mac_send_window_behind SendBehind
-#define mac_hide_window HideWindow
-#define mac_show_window ShowWindow
-#define mac_collapse_window CollapseWindow
-#define mac_front_non_floating_window FrontNonFloatingWindow
-#define mac_active_non_floating_window ActiveNonFloatingWindow
-#define mac_activate_window ActivateWindow
-#define mac_move_window_structure MoveWindowStructure
-#define mac_move_window MoveWindow
-#define mac_size_window SizeWindow
-#define mac_get_global_mouse GetGlobalMouse
-#define mac_is_window_toolbar_visible IsWindowToolbarVisible
-#define mac_rect_make(f, x, y, w, h) CGRectMake (x, y, w, h)
-
-#if USE_MAC_IMAGE_IO
-typedef struct _XImage
-{
- int width, height; /* size of image */
- char *data; /* pointer to image data */
- int bytes_per_line; /* accelarator to next line */
- int bits_per_pixel; /* bits per pixel (ZPixmap) */
-} *Pixmap;
-#else
-typedef GWorldPtr Pixmap;
-#endif
-
-#define Cursor ThemeCursor
-#define No_Cursor (-1)
-
-#define FACE_DEFAULT (~0)
-
-#if !TARGET_API_MAC_CARBON
-#define GetPixDepth(pmh) ((*(pmh))->pixelSize)
-#endif
-
-
-/* Emulate XCharStruct. */
-/* If the sum of ascent and descent is negative, that means some
- special status specified by enum pcm_status. */
-typedef struct _XCharStruct
-{
- short lbearing; /* origin to left edge of raster */
- short rbearing; /* origin to right edge of raster */
- short width; /* advance to next char's origin */
- short ascent; /* baseline to top edge of raster */
- short descent; /* baseline to bottom edge of raster */
-#if 0
- unsigned short attributes; /* per char flags (not predefined) */
-#endif
-} XCharStruct;
-
-enum pcm_status
- {
- PCM_VALID = 0, /* pcm data is valid */
- PCM_INVALID = -1, /* pcm data is invalid */
- };
-
-#define STORE_XCHARSTRUCT(xcs, w, bds) \
- ((xcs).width = (w), \
- (xcs).lbearing = (bds).left, \
- (xcs).rbearing = (bds).right, \
- (xcs).ascent = -(bds).top, \
- (xcs).descent = (bds).bottom)
-
-struct MacFontStruct {
- char *full_name;
-
- short mac_fontnum; /* font number of font used in this window */
- int mac_fontsize; /* size of font */
- short mac_fontface; /* plain, bold, italics, etc. */
-#if TARGET_API_MAC_CARBON
- int mac_scriptcode; /* Mac OS script code for font used */
-#else
- short mac_scriptcode; /* Mac OS script code for font used */
-#endif
-#if USE_ATSUI
- ATSUStyle mac_style; /* NULL if QuickDraw Text is used */
-#if USE_CG_TEXT_DRAWING
- CGFontRef cg_font; /* NULL if ATSUI text drawing is used */
- CGGlyph *cg_glyphs; /* Likewise */
-#endif
-#endif
-
-/* from Xlib.h */
-#if 0
- XExtData *ext_data; /* hook for extension to hang data */
- Font fid; /* Font id for this font */
- unsigned direction; /* hint about the direction font is painted */
-#endif /* 0 */
- unsigned min_char_or_byte2;/* first character */
- unsigned max_char_or_byte2;/* last character */
- unsigned min_byte1; /* first row that exists */
- unsigned max_byte1; /* last row that exists */
-#if 0
- Bool all_chars_exist; /* flag if all characters have nonzero size */
- unsigned default_char; /* char to print for undefined character */
- int n_properties; /* how many properties there are */
- XFontProp *properties; /* pointer to array of additional properties */
-#endif /* 0 */
- XCharStruct min_bounds; /* minimum bounds over all existing char */
- XCharStruct max_bounds; /* maximum bounds over all existing char */
- union {
- XCharStruct *per_char; /* first_char to last_char information */
- XCharStruct **rows; /* first row to last row information */
- } bounds;
- int ascent; /* logical extent above baseline for spacing */
- int descent; /* logical decent below baseline for spacing */
-};
-
-typedef struct MacFontStruct MacFontStruct;
-typedef struct MacFontStruct XFontStruct;
-
-/* Structure borrowed from Xlib.h to represent two-byte characters. */
-
-typedef struct {
- unsigned char byte1;
- unsigned char byte2;
-} XChar2b;
-
-#define STORE_XCHAR2B(chp, b1, b2) \
- ((chp)->byte1 = (b1), (chp)->byte2 = (b2))
-
-#define XCHAR2B_BYTE1(chp) \
- ((chp)->byte1)
-
-#define XCHAR2B_BYTE2(chp) \
- ((chp)->byte2)
-
-
-/* Emulate X GC's by keeping color and font info in a structure. */
-typedef struct _XGCValues
-{
- unsigned long foreground;
- unsigned long background;
- XFontStruct *font;
-} XGCValues;
-
-typedef struct _XGC
-{
- /* Original value. */
- XGCValues xgcv;
-
- /* Cached data members follow. */
-
- /* QuickDraw foreground color. */
- RGBColor fore_color;
-
- /* QuickDraw background color. */
- RGBColor back_color;
-
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- /* Quartz 2D foreground color. */
- CGColorRef cg_fore_color;
-
- /* Quartz 2D background color. */
- CGColorRef cg_back_color;
-#endif
-
-#define MAX_CLIP_RECTS 2
- /* Number of clipping rectangles. */
- int n_clip_rects;
-
- /* QuickDraw clipping region. Ignored if n_clip_rects == 0. */
- RgnHandle clip_region;
-
-#if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING)
- /* Clipping rectangles used in Quartz 2D drawing. The y-coordinate
- is in QuickDraw's. */
- CGRect clip_rects[MAX_CLIP_RECTS];
-#endif
-} *GC;
-
-#define GCForeground (1L<<2)
-#define GCBackground (1L<<3)
-#define GCFont (1L<<14)
-#define GCGraphicsExposures 0
-
-/* Bit Gravity */
-
-#define ForgetGravity 0
-#define NorthWestGravity 1
-#define NorthGravity 2
-#define NorthEastGravity 3
-#define WestGravity 4
-#define CenterGravity 5
-#define EastGravity 6
-#define SouthWestGravity 7
-#define SouthGravity 8
-#define SouthEastGravity 9
-#define StaticGravity 10
-
-#define NoValue 0x0000
-#define XValue 0x0001
-#define YValue 0x0002
-#define WidthValue 0x0004
-#define HeightValue 0x0008
-#define AllValues 0x000F
-#define XNegative 0x0010
-#define YNegative 0x0020
-
-typedef struct {
- long flags; /* marks which fields in this structure are defined */
-#if 0
- int x, y; /* obsolete for new window mgrs, but clients */
- int width, height; /* should set so old wm's don't mess up */
-#endif
- int min_width, min_height;
-#if 0
- int max_width, max_height;
-#endif
- int width_inc, height_inc;
-#if 0
- struct {
- int x; /* numerator */
- int y; /* denominator */
- } min_aspect, max_aspect;
-#endif
- int base_width, base_height; /* added by ICCCM version 1 */
-#if 0
- int win_gravity; /* added by ICCCM version 1 */
-#endif
-} XSizeHints;
-
-#define USPosition (1L << 0) /* user specified x, y */
-#define USSize (1L << 1) /* user specified width, height */
-
-#define PPosition (1L << 2) /* program specified position */
-#define PSize (1L << 3) /* program specified size */
-#define PMinSize (1L << 4) /* program specified minimum size */
-#define PMaxSize (1L << 5) /* program specified maximum size */
-#define PResizeInc (1L << 6) /* program specified resize increments */
-#define PAspect (1L << 7) /* program specified min and max aspect ratios */
-#define PBaseSize (1L << 8) /* program specified base for incrementing */
-#define PWinGravity (1L << 9) /* program specified window gravity */
-
-typedef struct {
- int x, y;
- unsigned width, height;
-} XRectangle;
-
-#define NativeRectangle Rect
-
-#define CONVERT_TO_XRECT(xr,nr) \
- ((xr).x = (nr).left, \
- (xr).y = (nr).top, \
- (xr).width = ((nr).right - (nr).left), \
- (xr).height = ((nr).bottom - (nr).top))
-
-#define CONVERT_FROM_XRECT(xr,nr) \
- ((nr).left = (xr).x, \
- (nr).top = (xr).y, \
- (nr).right = ((xr).x + (xr).width), \
- (nr).bottom = ((xr).y + (xr).height))
-
-#define STORE_NATIVE_RECT(nr,x,y,width,height) \
- ((nr).left = (x), \
- (nr).top = (y), \
- (nr).right = ((nr).left + (width)), \
- (nr).bottom = ((nr).top + (height)))
-
-/* Definitions copied from lwlib.h */
-
-typedef void * XtPointer;
-
-enum button_type
-{
- BUTTON_TYPE_NONE,
- BUTTON_TYPE_TOGGLE,
- BUTTON_TYPE_RADIO
-};
-
-/* This structure is based on the one in ../lwlib/lwlib.h, modified
- for Mac OS. */
-typedef struct _widget_value
-{
- /* name of widget */
- Lisp_Object lname;
- char* name;
- /* value (meaning depend on widget type) */
- char* value;
- /* keyboard equivalent. no implications for XtTranslations */
- Lisp_Object lkey;
- char* key;
- /* Help string or nil if none.
- GC finds this string through the frame's menu_bar_vector
- or through menu_items. */
- Lisp_Object help;
- /* true if enabled */
- Boolean enabled;
- /* true if selected */
- Boolean selected;
- /* The type of a button. */
- enum button_type button_type;
- /* true if menu title */
- Boolean title;
-#if 0
- /* true if was edited (maintained by get_value) */
- Boolean edited;
- /* true if has changed (maintained by lw library) */
- change_type change;
- /* true if this widget itself has changed,
- but not counting the other widgets found in the `next' field. */
- change_type this_one_change;
-#endif
- /* Contents of the sub-widgets, also selected slot for checkbox */
- struct _widget_value* contents;
- /* data passed to callback */
- XtPointer call_data;
- /* next one in the list */
- struct _widget_value* next;
-#if 0
- /* slot for the toolkit dependent part. Always initialize to NULL. */
- void* toolkit_data;
- /* tell us if we should free the toolkit data slot when freeing the
- widget_value itself. */
- Boolean free_toolkit_data;
-
- /* we resource the widget_value structures; this points to the next
- one on the free list if this one has been deallocated.
- */
- struct _widget_value *free_list;
-#endif
-} widget_value;
-
-#if MAC_OS8
-#define M_APPLE 234
-#define I_ABOUT 1
-
-#define EXTRA_STACK_ALLOC (256 * 1024)
-
-#define ARGV_STRING_LIST_ID 129
-#define RAM_TOO_LARGE_ALERT_ID 129
-#define ABOUT_ALERT_ID 128
-#endif
-
-#define DIALOG_LEFT_MARGIN (112)
-#define DIALOG_TOP_MARGIN (24)
-#define DIALOG_RIGHT_MARGIN (24)
-#define DIALOG_BOTTOM_MARGIN (20)
-#define DIALOG_MIN_INNER_WIDTH (338)
-#define DIALOG_MAX_INNER_WIDTH (564)
-#define DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE (12)
-#define DIALOG_BUTTON_BUTTON_VERTICAL_SPACE (12)
-#define DIALOG_BUTTON_MIN_WIDTH (68)
-#define DIALOG_TEXT_MIN_HEIGHT (50)
-#define DIALOG_TEXT_BUTTONS_VERTICAL_SPACE (10)
-#define DIALOG_ICON_WIDTH (64)
-#define DIALOG_ICON_HEIGHT (64)
-#define DIALOG_ICON_LEFT_MARGIN (24)
-#define DIALOG_ICON_TOP_MARGIN (15)
-
-#endif /* EMACS_MACGUI_H */
-
-/* arch-tag: 5a0da49a-35e2-418b-a58c-8a55778ae849
- (do not change this comment) */
diff --git a/src/macmenu.c b/src/macmenu.c
deleted file mode 100644
index b3ccf578ae9..00000000000
--- a/src/macmenu.c
+++ /dev/null
@@ -1,2101 +0,0 @@
-/* Menu support for GNU Emacs on Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Contributed by Andrew Choi (akochoi@mac.com). */
-
-#include <config.h>
-
-#include <stdio.h>
-
-#include "lisp.h"
-#include "frame.h"
-#include "termhooks.h"
-#include "keyboard.h"
-#include "keymap.h"
-#include "window.h"
-#include "blockinput.h"
-#include "buffer.h"
-#include "charset.h"
-#include "coding.h"
-
-/* This may include sys/types.h, and that somehow loses
- if this is not done before the other system files. */
-#include "macterm.h"
-
-/* Load sys/types.h if not already loaded.
- In some systems loading it twice is suicidal. */
-#ifndef makedev
-#include <sys/types.h>
-#endif
-
-#include "dispextern.h"
-
-#if TARGET_API_MAC_CARBON
-#define HAVE_DIALOGS 1
-#endif
-
-#undef HAVE_MULTILINGUAL_MENU
-
-/******************************************************************/
-
-/* Assumed by other routines to zero area returned. */
-#define malloc_widget_value() (void *)memset (xmalloc (sizeof (widget_value)),\
- 0, (sizeof (widget_value)))
-#define free_widget_value(wv) xfree (wv)
-
-/******************************************************************/
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif /* no TRUE */
-
-Lisp_Object Qdebug_on_next_call;
-
-extern Lisp_Object Vmenu_updating_frame;
-
-extern Lisp_Object Qmenu_bar, Qmac_apple_event;
-
-extern Lisp_Object QCtoggle, QCradio;
-
-extern Lisp_Object Voverriding_local_map;
-extern Lisp_Object Voverriding_local_map_menu_flag;
-
-extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-
-extern Lisp_Object Qmenu_bar_update_hook;
-
-void set_frame_menubar P_ ((FRAME_PTR, int, int));
-
-#if TARGET_API_MAC_CARBON
-#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str)
-#else
-#define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str)
-#endif
-
-static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object));
-#ifdef HAVE_DIALOGS
-static Lisp_Object mac_dialog_show P_ ((FRAME_PTR, int, Lisp_Object,
- Lisp_Object, char **));
-#endif
-static Lisp_Object mac_menu_show P_ ((struct frame *, int, int, int, int,
- Lisp_Object, char **));
-static void keymap_panes P_ ((Lisp_Object *, int, int));
-static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
- int, int));
-static void list_of_panes P_ ((Lisp_Object));
-static void list_of_items P_ ((Lisp_Object));
-
-
-/* This holds a Lisp vector that holds the results of decoding
- the keymaps or alist-of-alists that specify a menu.
-
- It describes the panes and items within the panes.
-
- Each pane is described by 3 elements in the vector:
- t, the pane name, the pane's prefix key.
- Then follow the pane's items, with 5 elements per item:
- the item string, the enable flag, the item's value,
- the definition, and the equivalent keyboard key's description string.
-
- In some cases, multiple levels of menus may be described.
- A single vector slot containing nil indicates the start of a submenu.
- A single vector slot containing lambda indicates the end of a submenu.
- The submenu follows a menu item which is the way to reach the submenu.
-
- A single vector slot containing quote indicates that the
- following items should appear on the right of a dialog box.
-
- Using a Lisp vector to hold this information while we decode it
- takes care of protecting all the data from GC. */
-
-#define MENU_ITEMS_PANE_NAME 1
-#define MENU_ITEMS_PANE_PREFIX 2
-#define MENU_ITEMS_PANE_LENGTH 3
-
-enum menu_item_idx
-{
- MENU_ITEMS_ITEM_NAME = 0,
- MENU_ITEMS_ITEM_ENABLE,
- MENU_ITEMS_ITEM_VALUE,
- MENU_ITEMS_ITEM_EQUIV_KEY,
- MENU_ITEMS_ITEM_DEFINITION,
- MENU_ITEMS_ITEM_TYPE,
- MENU_ITEMS_ITEM_SELECTED,
- MENU_ITEMS_ITEM_HELP,
- MENU_ITEMS_ITEM_LENGTH
-};
-
-static Lisp_Object menu_items;
-
-/* Number of slots currently allocated in menu_items. */
-static int menu_items_allocated;
-
-/* This is the index in menu_items of the first empty slot. */
-static int menu_items_used;
-
-/* The number of panes currently recorded in menu_items,
- excluding those within submenus. */
-static int menu_items_n_panes;
-
-/* Current depth within submenus. */
-static int menu_items_submenu_depth;
-
-/* Nonzero means a menu is currently active. */
-int popup_activated_flag;
-
-/* This is set nonzero after the user activates the menu bar, and set
- to zero again after the menu bars are redisplayed by prepare_menu_bar.
- While it is nonzero, all calls to set_frame_menubar go deep.
-
- I don't understand why this is needed, but it does seem to be
- needed on Motif, according to Marcus Daniels <marcus@sysc.pdx.edu>. */
-
-int pending_menu_activation;
-
-/* Initialize the menu_items structure if we haven't already done so.
- Also mark it as currently empty. */
-
-static void
-init_menu_items ()
-{
- if (NILP (menu_items))
- {
- menu_items_allocated = 60;
- menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
- }
-
- menu_items_used = 0;
- menu_items_n_panes = 0;
- menu_items_submenu_depth = 0;
-}
-
-/* Call at the end of generating the data in menu_items. */
-
-static void
-finish_menu_items ()
-{
-}
-
-/* Call when finished using the data for the current menu
- in menu_items. */
-
-static void
-discard_menu_items ()
-{
- /* Free the structure if it is especially large.
- Otherwise, hold on to it, to save time. */
- if (menu_items_allocated > 200)
- {
- menu_items = Qnil;
- menu_items_allocated = 0;
- }
-}
-
-/* This undoes save_menu_items, and it is called by the specpdl unwind
- mechanism. */
-
-static Lisp_Object
-restore_menu_items (saved)
- Lisp_Object saved;
-{
- menu_items = XCAR (saved);
- menu_items_allocated = (VECTORP (menu_items) ? ASIZE (menu_items) : 0);
- saved = XCDR (saved);
- menu_items_used = XINT (XCAR (saved));
- saved = XCDR (saved);
- menu_items_n_panes = XINT (XCAR (saved));
- saved = XCDR (saved);
- menu_items_submenu_depth = XINT (XCAR (saved));
- return Qnil;
-}
-
-/* Push the whole state of menu_items processing onto the specpdl.
- It will be restored when the specpdl is unwound. */
-
-static void
-save_menu_items ()
-{
- Lisp_Object saved = list4 (menu_items,
- make_number (menu_items_used),
- make_number (menu_items_n_panes),
- make_number (menu_items_submenu_depth));
- record_unwind_protect (restore_menu_items, saved);
- menu_items = Qnil;
-}
-
-/* Make the menu_items vector twice as large. */
-
-static void
-grow_menu_items ()
-{
- menu_items_allocated *= 2;
- menu_items = larger_vector (menu_items, menu_items_allocated, Qnil);
-}
-
-/* Begin a submenu. */
-
-static void
-push_submenu_start ()
-{
- if (menu_items_used + 1 > menu_items_allocated)
- grow_menu_items ();
-
- XVECTOR (menu_items)->contents[menu_items_used++] = Qnil;
- menu_items_submenu_depth++;
-}
-
-/* End a submenu. */
-
-static void
-push_submenu_end ()
-{
- if (menu_items_used + 1 > menu_items_allocated)
- grow_menu_items ();
-
- XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda;
- menu_items_submenu_depth--;
-}
-
-/* Indicate boundary between left and right. */
-
-static void
-push_left_right_boundary ()
-{
- if (menu_items_used + 1 > menu_items_allocated)
- grow_menu_items ();
-
- XVECTOR (menu_items)->contents[menu_items_used++] = Qquote;
-}
-
-/* Start a new menu pane in menu_items.
- NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */
-
-static void
-push_menu_pane (name, prefix_vec)
- Lisp_Object name, prefix_vec;
-{
- if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated)
- grow_menu_items ();
-
- if (menu_items_submenu_depth == 0)
- menu_items_n_panes++;
- XVECTOR (menu_items)->contents[menu_items_used++] = Qt;
- XVECTOR (menu_items)->contents[menu_items_used++] = name;
- XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
-}
-
-/* Push one menu item into the current pane. NAME is the string to
- display. ENABLE if non-nil means this item can be selected. KEY
- is the key generated by choosing this item, or nil if this item
- doesn't really have a definition. DEF is the definition of this
- item. EQUIV is the textual description of the keyboard equivalent
- for this item (or nil if none). TYPE is the type of this menu
- item, one of nil, `toggle' or `radio'. */
-
-static void
-push_menu_item (name, enable, key, def, equiv, type, selected, help)
- Lisp_Object name, enable, key, def, equiv, type, selected, help;
-{
- if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
- grow_menu_items ();
-
- XVECTOR (menu_items)->contents[menu_items_used++] = name;
- XVECTOR (menu_items)->contents[menu_items_used++] = enable;
- XVECTOR (menu_items)->contents[menu_items_used++] = key;
- XVECTOR (menu_items)->contents[menu_items_used++] = equiv;
- XVECTOR (menu_items)->contents[menu_items_used++] = def;
- XVECTOR (menu_items)->contents[menu_items_used++] = type;
- XVECTOR (menu_items)->contents[menu_items_used++] = selected;
- XVECTOR (menu_items)->contents[menu_items_used++] = help;
-}
-
-/* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
- and generate menu panes for them in menu_items.
- If NOTREAL is nonzero,
- don't bother really computing whether an item is enabled. */
-
-static void
-keymap_panes (keymaps, nmaps, notreal)
- Lisp_Object *keymaps;
- int nmaps;
- int notreal;
-{
- int mapno;
-
- init_menu_items ();
-
- /* Loop over the given keymaps, making a pane for each map.
- But don't make a pane that is empty--ignore that map instead.
- P is the number of panes we have made so far. */
- for (mapno = 0; mapno < nmaps; mapno++)
- single_keymap_panes (keymaps[mapno],
- Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10);
-
- finish_menu_items ();
-}
-
-/* Args passed between single_keymap_panes and single_menu_item. */
-struct skp
- {
- Lisp_Object pending_maps;
- int maxdepth, notreal;
- };
-
-static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
- void *));
-
-/* This is a recursive subroutine of keymap_panes.
- It handles one keymap, KEYMAP.
- The other arguments are passed along
- or point to local variables of the previous function.
- If NOTREAL is nonzero, only check for equivalent key bindings, don't
- evaluate expressions in menu items and don't make any menu.
-
- If we encounter submenus deeper than MAXDEPTH levels, ignore them. */
-
-static void
-single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
- Lisp_Object keymap;
- Lisp_Object pane_name;
- Lisp_Object prefix;
- int notreal;
- int maxdepth;
-{
- struct skp skp;
- struct gcpro gcpro1;
-
- skp.pending_maps = Qnil;
- skp.maxdepth = maxdepth;
- skp.notreal = notreal;
-
- if (maxdepth <= 0)
- return;
-
- push_menu_pane (pane_name, prefix);
-
- GCPRO1 (skp.pending_maps);
- map_keymap (keymap, single_menu_item, Qnil, &skp, 1);
- UNGCPRO;
-
- /* Process now any submenus which want to be panes at this level. */
- while (CONSP (skp.pending_maps))
- {
- Lisp_Object elt, eltcdr, string;
- elt = XCAR (skp.pending_maps);
- eltcdr = XCDR (elt);
- string = XCAR (eltcdr);
- /* We no longer discard the @ from the beginning of the string here.
- Instead, we do this in mac_menu_show. */
- single_keymap_panes (Fcar (elt), string,
- XCDR (eltcdr), notreal, maxdepth - 1);
- skp.pending_maps = XCDR (skp.pending_maps);
- }
-}
-
-/* This is a subroutine of single_keymap_panes that handles one
- keymap entry.
- KEY is a key in a keymap and ITEM is its binding.
- SKP->PENDING_MAPS_PTR is a list of keymaps waiting to be made into
- separate panes.
- If SKP->NOTREAL is nonzero, only check for equivalent key bindings, don't
- evaluate expressions in menu items and don't make any menu.
- If we encounter submenus deeper than SKP->MAXDEPTH levels, ignore them. */
-
-static void
-single_menu_item (key, item, dummy, skp_v)
- Lisp_Object key, item, dummy;
- void *skp_v;
-{
- Lisp_Object map, item_string, enabled;
- struct gcpro gcpro1, gcpro2;
- int res;
- struct skp *skp = skp_v;
-
- /* Parse the menu item and leave the result in item_properties. */
- GCPRO2 (key, item);
- res = parse_menu_item (item, skp->notreal, 0);
- UNGCPRO;
- if (!res)
- return; /* Not a menu item. */
-
- map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
-
- if (skp->notreal)
- {
- /* We don't want to make a menu, just traverse the keymaps to
- precompute equivalent key bindings. */
- if (!NILP (map))
- single_keymap_panes (map, Qnil, key, 1, skp->maxdepth - 1);
- return;
- }
-
- enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
- item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
-
- if (!NILP (map) && SREF (item_string, 0) == '@')
- {
- if (!NILP (enabled))
- /* An enabled separate pane. Remember this to handle it later. */
- skp->pending_maps = Fcons (Fcons (map, Fcons (item_string, key)),
- skp->pending_maps);
- return;
- }
-
- push_menu_item (item_string, enabled, key,
- XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
- XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
- XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
- XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
- XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
-
- /* Display a submenu using the toolkit. */
- if (! (NILP (map) || NILP (enabled)))
- {
- push_submenu_start ();
- single_keymap_panes (map, Qnil, key, 0, skp->maxdepth - 1);
- push_submenu_end ();
- }
-}
-
-/* Push all the panes and items of a menu described by the
- alist-of-alists MENU.
- This handles old-fashioned calls to x-popup-menu. */
-
-static void
-list_of_panes (menu)
- Lisp_Object menu;
-{
- Lisp_Object tail;
-
- init_menu_items ();
-
- for (tail = menu; CONSP (tail); tail = XCDR (tail))
- {
- Lisp_Object elt, pane_name, pane_data;
- elt = XCAR (tail);
- pane_name = Fcar (elt);
- CHECK_STRING (pane_name);
- push_menu_pane (ENCODE_MENU_STRING (pane_name), Qnil);
- pane_data = Fcdr (elt);
- CHECK_CONS (pane_data);
- list_of_items (pane_data);
- }
-
- finish_menu_items ();
-}
-
-/* Push the items in a single pane defined by the alist PANE. */
-
-static void
-list_of_items (pane)
- Lisp_Object pane;
-{
- Lisp_Object tail, item, item1;
-
- for (tail = pane; CONSP (tail); tail = XCDR (tail))
- {
- item = XCAR (tail);
- if (STRINGP (item))
- push_menu_item (ENCODE_MENU_STRING (item), Qnil, Qnil, Qt,
- Qnil, Qnil, Qnil, Qnil);
- else if (CONSP (item))
- {
- item1 = XCAR (item);
- CHECK_STRING (item1);
- push_menu_item (ENCODE_MENU_STRING (item1), Qt, XCDR (item),
- Qt, Qnil, Qnil, Qnil, Qnil);
- }
- else
- push_left_right_boundary ();
-
- }
-}
-
-static Lisp_Object
-cleanup_popup_menu (arg)
- Lisp_Object arg;
-{
- discard_menu_items ();
- return Qnil;
-}
-
-DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
- doc: /* Pop up a deck-of-cards menu and return user's selection.
-POSITION is a position specification. This is either a mouse button event
-or a list ((XOFFSET YOFFSET) WINDOW)
-where XOFFSET and YOFFSET are positions in pixels from the top left
-corner of WINDOW. (WINDOW may be a window or a frame object.)
-This controls the position of the top left of the menu as a whole.
-If POSITION is t, it means to use the current mouse position.
-
-MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
-The menu items come from key bindings that have a menu string as well as
-a definition; actually, the "definition" in such a key binding looks like
-\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
-the keymap as a top-level element.
-
-If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
-Otherwise, REAL-DEFINITION should be a valid key binding definition.
-
-You can also use a list of keymaps as MENU.
- Then each keymap makes a separate pane.
-
-When MENU is a keymap or a list of keymaps, the return value is the
-list of events corresponding to the user's choice. Note that
-`x-popup-menu' does not actually execute the command bound to that
-sequence of events.
-
-Alternatively, you can specify a menu of multiple panes
- with a list of the form (TITLE PANE1 PANE2...),
-where each pane is a list of form (TITLE ITEM1 ITEM2...).
-Each ITEM is normally a cons cell (STRING . VALUE);
-but a string can appear as an item--that makes a nonselectable line
-in the menu.
-With this form of menu, the return value is VALUE from the chosen item.
-
-If POSITION is nil, don't display the menu at all, just precalculate the
-cached information about equivalent key sequences.
-
-If the user gets rid of the menu without making a valid choice, for
-instance by clicking the mouse away from a valid choice or by typing
-keyboard input, then this normally results in a quit and
-`x-popup-menu' does not return. But if POSITION is a mouse button
-event (indicating that the user invoked the menu with the mouse) then
-no quit occurs and `x-popup-menu' returns nil. */)
- (position, menu)
- Lisp_Object position, menu;
-{
- Lisp_Object keymap, tem;
- int xpos = 0, ypos = 0;
- Lisp_Object title;
- char *error_name = NULL;
- Lisp_Object selection;
- FRAME_PTR f = NULL;
- Lisp_Object x, y, window;
- int keymaps = 0;
- int for_click = 0;
- int specpdl_count = SPECPDL_INDEX ();
- struct gcpro gcpro1;
-
-#ifdef HAVE_MENUS
- if (! NILP (position))
- {
- check_mac ();
-
- /* Decode the first argument: find the window and the coordinates. */
- if (EQ (position, Qt)
- || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
- || EQ (XCAR (position), Qtool_bar)
- || EQ (XCAR (position), Qmac_apple_event))))
- {
- /* Use the mouse's current position. */
- FRAME_PTR new_f = SELECTED_FRAME ();
- Lisp_Object bar_window;
- enum scroll_bar_part part;
- unsigned long time;
-
- if (FRAME_TERMINAL (new_f)->mouse_position_hook)
- (*FRAME_TERMINAL (new_f)->mouse_position_hook) (&new_f, 1, &bar_window,
- &part, &x, &y, &time);
- if (new_f != 0)
- XSETFRAME (window, new_f);
- else
- {
- window = selected_window;
- XSETFASTINT (x, 0);
- XSETFASTINT (y, 0);
- }
- }
- else
- {
- tem = Fcar (position);
- if (CONSP (tem))
- {
- window = Fcar (Fcdr (position));
- x = XCAR (tem);
- y = Fcar (XCDR (tem));
- }
- else
- {
- for_click = 1;
- tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
- window = Fcar (tem); /* POSN_WINDOW (tem) */
- tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
- x = Fcar (tem);
- y = Fcdr (tem);
- }
- }
-
- CHECK_NUMBER (x);
- CHECK_NUMBER (y);
-
- /* Decode where to put the menu. */
-
- if (FRAMEP (window))
- {
- f = XFRAME (window);
- xpos = 0;
- ypos = 0;
- }
- else if (WINDOWP (window))
- {
- CHECK_LIVE_WINDOW (window);
- f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
-
- xpos = WINDOW_LEFT_EDGE_X (XWINDOW (window));
- ypos = WINDOW_TOP_EDGE_Y (XWINDOW (window));
- }
- else
- /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
- but I don't want to make one now. */
- CHECK_WINDOW (window);
-
- xpos += XINT (x);
- ypos += XINT (y);
-
- XSETFRAME (Vmenu_updating_frame, f);
- }
- else
- Vmenu_updating_frame = Qnil;
-#endif /* HAVE_MENUS */
-
- title = Qnil;
- GCPRO1 (title);
-
- /* Decode the menu items from what was specified. */
-
- keymap = get_keymap (menu, 0, 0);
- if (CONSP (keymap))
- {
- /* We were given a keymap. Extract menu info from the keymap. */
- Lisp_Object prompt;
-
- /* Extract the detailed info to make one pane. */
- keymap_panes (&menu, 1, NILP (position));
-
- /* Search for a string appearing directly as an element of the keymap.
- That string is the title of the menu. */
- prompt = Fkeymap_prompt (keymap);
- if (NILP (title) && !NILP (prompt))
- title = prompt;
-
- /* Make that be the pane title of the first pane. */
- if (!NILP (prompt) && menu_items_n_panes >= 0)
- XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt;
-
- keymaps = 1;
- }
- else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
- {
- /* We were given a list of keymaps. */
- int nmaps = XFASTINT (Flength (menu));
- Lisp_Object *maps
- = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
- int i;
-
- title = Qnil;
-
- /* The first keymap that has a prompt string
- supplies the menu title. */
- for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem))
- {
- Lisp_Object prompt;
-
- maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0);
-
- prompt = Fkeymap_prompt (keymap);
- if (NILP (title) && !NILP (prompt))
- title = prompt;
- }
-
- /* Extract the detailed info to make one pane. */
- keymap_panes (maps, nmaps, NILP (position));
-
- /* Make the title be the pane title of the first pane. */
- if (!NILP (title) && menu_items_n_panes >= 0)
- XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title;
-
- keymaps = 1;
- }
- else
- {
- /* We were given an old-fashioned menu. */
- title = Fcar (menu);
- CHECK_STRING (title);
-
- list_of_panes (Fcdr (menu));
-
- keymaps = 0;
- }
-
- if (NILP (position))
- {
- discard_menu_items ();
- UNGCPRO;
- return Qnil;
- }
-
-#ifdef HAVE_MENUS
- /* Display them in a menu. */
- record_unwind_protect (cleanup_popup_menu, Qnil);
- BLOCK_INPUT;
-
- selection = mac_menu_show (f, xpos, ypos, for_click,
- keymaps, title, &error_name);
- UNBLOCK_INPUT;
- unbind_to (specpdl_count, Qnil);
-
- UNGCPRO;
-#endif /* HAVE_MENUS */
-
- if (error_name) error (error_name);
- return selection;
-}
-
-#ifdef HAVE_MENUS
-
-DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
- doc: /* Pop up a dialog box and return user's selection.
-POSITION specifies which frame to use.
-This is normally a mouse button event or a window or frame.
-If POSITION is t, it means to use the frame the mouse is on.
-The dialog box appears in the middle of the specified frame.
-
-CONTENTS specifies the alternatives to display in the dialog box.
-It is a list of the form (DIALOG ITEM1 ITEM2...).
-Each ITEM is a cons cell (STRING . VALUE).
-The return value is VALUE from the chosen item.
-
-An ITEM may also be just a string--that makes a nonselectable item.
-An ITEM may also be nil--that means to put all preceding items
-on the left of the dialog box and all following items on the right.
-\(By default, approximately half appear on each side.)
-
-If HEADER is non-nil, the frame title for the box is "Information",
-otherwise it is "Question".
-
-If the user gets rid of the dialog box without making a valid choice,
-for instance using the window manager, then this produces a quit and
-`x-popup-dialog' does not return. */)
- (position, contents, header)
- Lisp_Object position, contents, header;
-{
- FRAME_PTR f = NULL;
- Lisp_Object window;
-
- check_mac ();
-
- /* Decode the first argument: find the window or frame to use. */
- if (EQ (position, Qt)
- || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
- || EQ (XCAR (position), Qtool_bar)
- || EQ (XCAR (position), Qmac_apple_event))))
- {
-#if 0 /* Using the frame the mouse is on may not be right. */
- /* Use the mouse's current position. */
- FRAME_PTR new_f = SELECTED_FRAME ();
- Lisp_Object bar_window;
- enum scroll_bar_part part;
- unsigned long time;
- Lisp_Object x, y;
-
- (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time);
-
- if (new_f != 0)
- XSETFRAME (window, new_f);
- else
- window = selected_window;
-#endif
- window = selected_window;
- }
- else if (CONSP (position))
- {
- Lisp_Object tem;
- tem = Fcar (position);
- if (CONSP (tem))
- window = Fcar (Fcdr (position));
- else
- {
- tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
- window = Fcar (tem); /* POSN_WINDOW (tem) */
- }
- }
- else if (WINDOWP (position) || FRAMEP (position))
- window = position;
- else
- window = Qnil;
-
- /* Decode where to put the menu. */
-
- if (FRAMEP (window))
- f = XFRAME (window);
- else if (WINDOWP (window))
- {
- CHECK_LIVE_WINDOW (window);
- f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
- }
- else
- /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
- but I don't want to make one now. */
- CHECK_WINDOW (window);
-
-#ifndef HAVE_DIALOGS
- /* Display a menu with these alternatives
- in the middle of frame F. */
- {
- Lisp_Object x, y, frame, newpos;
- XSETFRAME (frame, f);
- XSETINT (x, x_pixel_width (f) / 2);
- XSETINT (y, x_pixel_height (f) / 2);
- newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil));
-
- return Fx_popup_menu (newpos,
- Fcons (Fcar (contents), Fcons (contents, Qnil)));
- }
-#else /* HAVE_DIALOGS */
- {
- Lisp_Object title;
- char *error_name;
- Lisp_Object selection;
- int specpdl_count = SPECPDL_INDEX ();
-
- /* Decode the dialog items from what was specified. */
- title = Fcar (contents);
- CHECK_STRING (title);
-
- list_of_panes (Fcons (contents, Qnil));
-
- /* Display them in a dialog box. */
- record_unwind_protect (cleanup_popup_menu, Qnil);
- BLOCK_INPUT;
- selection = mac_dialog_show (f, 0, title, header, &error_name);
- UNBLOCK_INPUT;
- unbind_to (specpdl_count, Qnil);
-
- if (error_name) error (error_name);
- return selection;
- }
-#endif /* HAVE_DIALOGS */
-}
-
-/* Find the menu selection and store it in the keyboard buffer.
- F is the frame the menu is on.
- MENU_BAR_ITEMS_USED is the length of VECTOR.
- VECTOR is an array of menu events for the whole menu. */
-
-void
-find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
- FRAME_PTR f;
- int menu_bar_items_used;
- Lisp_Object vector;
- void *client_data;
-{
- Lisp_Object prefix, entry;
- Lisp_Object *subprefix_stack;
- int submenu_depth = 0;
- int i;
-
- entry = Qnil;
- subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof (Lisp_Object));
- prefix = Qnil;
- i = 0;
-
- while (i < menu_bar_items_used)
- {
- if (EQ (XVECTOR (vector)->contents[i], Qnil))
- {
- subprefix_stack[submenu_depth++] = prefix;
- prefix = entry;
- i++;
- }
- else if (EQ (XVECTOR (vector)->contents[i], Qlambda))
- {
- prefix = subprefix_stack[--submenu_depth];
- i++;
- }
- else if (EQ (XVECTOR (vector)->contents[i], Qt))
- {
- prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX];
- i += MENU_ITEMS_PANE_LENGTH;
- }
- else
- {
- entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE];
- /* The EMACS_INT cast avoids a warning. There's no problem
- as long as pointers have enough bits to hold small integers. */
- if ((int) (EMACS_INT) client_data == i)
- {
- int j;
- struct input_event buf;
- Lisp_Object frame;
- EVENT_INIT (buf);
-
- XSETFRAME (frame, f);
- buf.kind = MENU_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = frame;
- kbd_buffer_store_event (&buf);
-
- for (j = 0; j < submenu_depth; j++)
- if (!NILP (subprefix_stack[j]))
- {
- buf.kind = MENU_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = subprefix_stack[j];
- kbd_buffer_store_event (&buf);
- }
-
- if (!NILP (prefix))
- {
- buf.kind = MENU_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = prefix;
- kbd_buffer_store_event (&buf);
- }
-
- buf.kind = MENU_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = entry;
- kbd_buffer_store_event (&buf);
-
- return;
- }
- i += MENU_ITEMS_ITEM_LENGTH;
- }
- }
-}
-
-/* Allocate a widget_value, blocking input. */
-
-widget_value *
-xmalloc_widget_value ()
-{
- widget_value *value;
-
- BLOCK_INPUT;
- value = malloc_widget_value ();
- UNBLOCK_INPUT;
-
- return value;
-}
-
-/* This recursively calls free_widget_value on the tree of widgets.
- It must free all data that was malloc'ed for these widget_values.
- In Emacs, many slots are pointers into the data of Lisp_Strings, and
- must be left alone. */
-
-void
-free_menubar_widget_value_tree (wv)
- widget_value *wv;
-{
- if (! wv) return;
-
- wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
-
- if (wv->contents && (wv->contents != (widget_value*)1))
- {
- free_menubar_widget_value_tree (wv->contents);
- wv->contents = (widget_value *) 0xDEADBEEF;
- }
- if (wv->next)
- {
- free_menubar_widget_value_tree (wv->next);
- wv->next = (widget_value *) 0xDEADBEEF;
- }
- BLOCK_INPUT;
- free_widget_value (wv);
- UNBLOCK_INPUT;
-}
-
-/* Set up data in menu_items for a menu bar item
- whose event type is ITEM_KEY (with string ITEM_NAME)
- and whose contents come from the list of keymaps MAPS. */
-
-static int
-parse_single_submenu (item_key, item_name, maps)
- Lisp_Object item_key, item_name, maps;
-{
- Lisp_Object length;
- int len;
- Lisp_Object *mapvec;
- int i;
- int top_level_items = 0;
-
- length = Flength (maps);
- len = XINT (length);
-
- /* Convert the list MAPS into a vector MAPVEC. */
- mapvec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
- for (i = 0; i < len; i++)
- {
- mapvec[i] = Fcar (maps);
- maps = Fcdr (maps);
- }
-
- /* Loop over the given keymaps, making a pane for each map.
- But don't make a pane that is empty--ignore that map instead. */
- for (i = 0; i < len; i++)
- {
- if (!KEYMAPP (mapvec[i]))
- {
- /* Here we have a command at top level in the menu bar
- as opposed to a submenu. */
- top_level_items = 1;
- push_menu_pane (Qnil, Qnil);
- push_menu_item (item_name, Qt, item_key, mapvec[i],
- Qnil, Qnil, Qnil, Qnil);
- }
- else
- {
- Lisp_Object prompt;
- prompt = Fkeymap_prompt (mapvec[i]);
- single_keymap_panes (mapvec[i],
- !NILP (prompt) ? prompt : item_name,
- item_key, 0, 10);
- }
- }
-
- return top_level_items;
-}
-
-/* Create a tree of widget_value objects
- representing the panes and items
- in menu_items starting at index START, up to index END. */
-
-static widget_value *
-digest_single_submenu (start, end, top_level_items)
- int start, end, top_level_items;
-{
- widget_value *wv, *prev_wv, *save_wv, *first_wv;
- int i;
- int submenu_depth = 0;
- widget_value **submenu_stack;
- int panes_seen = 0;
-
- submenu_stack
- = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
- wv = xmalloc_widget_value ();
- wv->name = "menu";
- wv->value = 0;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- first_wv = wv;
- save_wv = 0;
- prev_wv = 0;
-
- /* Loop over all panes and items made by the preceding call
- to parse_single_submenu and construct a tree of widget_value objects.
- Ignore the panes and items used by previous calls to
- digest_single_submenu, even though those are also in menu_items. */
- i = start;
- while (i < end)
- {
- if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
- {
- submenu_stack[submenu_depth++] = save_wv;
- save_wv = prev_wv;
- prev_wv = 0;
- i++;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
- {
- prev_wv = save_wv;
- save_wv = submenu_stack[--submenu_depth];
- i++;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
- && submenu_depth != 0)
- i += MENU_ITEMS_PANE_LENGTH;
- /* Ignore a nil in the item list.
- It's meaningful only for dialog boxes. */
- else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
- i += 1;
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
- {
- /* Create a new pane. */
- Lisp_Object pane_name, prefix;
- char *pane_string;
-
- panes_seen++;
-
- pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
- prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
-
-#ifndef HAVE_MULTILINGUAL_MENU
- if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
- {
- pane_name = ENCODE_MENU_STRING (pane_name);
- AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
- }
-#endif
- pane_string = (NILP (pane_name)
- ? "" : (char *) SDATA (pane_name));
- /* If there is just one top-level pane, put all its items directly
- under the top-level menu. */
- if (menu_items_n_panes == 1)
- pane_string = "";
-
- /* If the pane has a meaningful name,
- make the pane a top-level menu item
- with its items as a submenu beneath it. */
- if (strcmp (pane_string, ""))
- {
- wv = xmalloc_widget_value ();
- if (save_wv)
- save_wv->next = wv;
- else
- first_wv->contents = wv;
- wv->lname = pane_name;
- /* Set value to 1 so update_submenu_strings can handle '@' */
- wv->value = (char *)1;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- save_wv = wv;
- }
- else
- save_wv = first_wv;
-
- prev_wv = 0;
- i += MENU_ITEMS_PANE_LENGTH;
- }
- else
- {
- /* Create a new item within current pane. */
- Lisp_Object item_name, enable, descrip, def, type, selected;
- Lisp_Object help;
-
- /* All items should be contained in panes. */
- if (panes_seen == 0)
- abort ();
-
- item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
- enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
- descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
- def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
- type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
- selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
- help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
-
-#ifndef HAVE_MULTILINGUAL_MENU
- if (STRING_MULTIBYTE (item_name))
- {
- item_name = ENCODE_MENU_STRING (item_name);
- AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
- }
-
- if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
- {
- descrip = ENCODE_MENU_STRING (descrip);
- AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
- }
-#endif /* not HAVE_MULTILINGUAL_MENU */
-
- wv = xmalloc_widget_value ();
- if (prev_wv)
- prev_wv->next = wv;
- else
- save_wv->contents = wv;
-
- wv->lname = item_name;
- if (!NILP (descrip))
- wv->lkey = descrip;
- wv->value = 0;
- /* The EMACS_INT cast avoids a warning. There's no problem
- as long as pointers have enough bits to hold small integers. */
- wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0);
- wv->enabled = !NILP (enable);
-
- if (NILP (type))
- wv->button_type = BUTTON_TYPE_NONE;
- else if (EQ (type, QCradio))
- wv->button_type = BUTTON_TYPE_RADIO;
- else if (EQ (type, QCtoggle))
- wv->button_type = BUTTON_TYPE_TOGGLE;
- else
- abort ();
-
- wv->selected = !NILP (selected);
- if (! STRINGP (help))
- help = Qnil;
-
- wv->help = help;
-
- prev_wv = wv;
-
- i += MENU_ITEMS_ITEM_LENGTH;
- }
- }
-
- /* If we have just one "menu item"
- that was originally a button, return it by itself. */
- if (top_level_items && first_wv->contents && first_wv->contents->next == 0)
- {
- wv = first_wv->contents;
- free_widget_value (first_wv);
- return wv;
- }
-
- return first_wv;
-}
-
-/* Walk through the widget_value tree starting at FIRST_WV and update
- the char * pointers from the corresponding lisp values.
- We do this after building the whole tree, since GC may happen while the
- tree is constructed, and small strings are relocated. So we must wait
- until no GC can happen before storing pointers into lisp values. */
-static void
-update_submenu_strings (first_wv)
- widget_value *first_wv;
-{
- widget_value *wv;
-
- for (wv = first_wv; wv; wv = wv->next)
- {
- if (STRINGP (wv->lname))
- {
- wv->name = SDATA (wv->lname);
-
- /* Ignore the @ that means "separate pane".
- This is a kludge, but this isn't worth more time. */
- if (wv->value == (char *)1)
- {
- if (wv->name[0] == '@')
- wv->name++;
- wv->value = 0;
- }
- }
-
- if (STRINGP (wv->lkey))
- wv->key = SDATA (wv->lkey);
-
- if (wv->contents)
- update_submenu_strings (wv->contents);
- }
-}
-
-
-/* Set the contents of the menubar widgets of frame F.
- The argument FIRST_TIME is currently ignored;
- it is set the first time this is called, from initialize_frame_menubar. */
-
-void
-set_frame_menubar (f, first_time, deep_p)
- FRAME_PTR f;
- int first_time;
- int deep_p;
-{
- int menubar_widget = f->output_data.mac->menubar_widget;
- Lisp_Object items;
- widget_value *wv, *first_wv, *prev_wv = 0;
- int i, last_i = 0;
- int *submenu_start, *submenu_end;
- int *submenu_top_level_items, *submenu_n_panes;
-
- XSETFRAME (Vmenu_updating_frame, f);
-
- /* This seems to be unnecessary for Carbon. */
-#if 0
- if (! menubar_widget)
- deep_p = 1;
- else if (pending_menu_activation && !deep_p)
- deep_p = 1;
-#endif
-
- if (deep_p)
- {
- /* Make a widget-value tree representing the entire menu trees. */
-
- struct buffer *prev = current_buffer;
- Lisp_Object buffer;
- int specpdl_count = SPECPDL_INDEX ();
- int previous_menu_items_used = f->menu_bar_items_used;
- Lisp_Object *previous_items
- = (Lisp_Object *) alloca (previous_menu_items_used
- * sizeof (Lisp_Object));
-
- /* If we are making a new widget, its contents are empty,
- do always reinitialize them. */
- if (! menubar_widget)
- previous_menu_items_used = 0;
-
- buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
- specbind (Qinhibit_quit, Qt);
- /* Don't let the debugger step into this code
- because it is not reentrant. */
- specbind (Qdebug_on_next_call, Qnil);
-
- record_unwind_save_match_data ();
- if (NILP (Voverriding_local_map_menu_flag))
- {
- specbind (Qoverriding_terminal_local_map, Qnil);
- specbind (Qoverriding_local_map, Qnil);
- }
-
- set_buffer_internal_1 (XBUFFER (buffer));
-
- /* Run the Lucid hook. */
- safe_run_hooks (Qactivate_menubar_hook);
-
- /* If it has changed current-menubar from previous value,
- really recompute the menubar from the value. */
- if (! NILP (Vlucid_menu_bar_dirty_flag))
- call0 (Qrecompute_lucid_menubar);
- safe_run_hooks (Qmenu_bar_update_hook);
- FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
-
- items = FRAME_MENU_BAR_ITEMS (f);
-
- /* Save the frame's previous menu bar contents data. */
- if (previous_menu_items_used)
- bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
- previous_menu_items_used * sizeof (Lisp_Object));
-
- /* Fill in menu_items with the current menu bar contents.
- This can evaluate Lisp code. */
- save_menu_items ();
-
- menu_items = f->menu_bar_vector;
- menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
- submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
- submenu_top_level_items
- = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- init_menu_items ();
- for (i = 0; i < XVECTOR (items)->size; i += 4)
- {
- Lisp_Object key, string, maps;
-
- last_i = i;
-
- key = XVECTOR (items)->contents[i];
- string = XVECTOR (items)->contents[i + 1];
- maps = XVECTOR (items)->contents[i + 2];
- if (NILP (string))
- break;
-
- submenu_start[i] = menu_items_used;
-
- menu_items_n_panes = 0;
- submenu_top_level_items[i]
- = parse_single_submenu (key, string, maps);
- submenu_n_panes[i] = menu_items_n_panes;
-
- submenu_end[i] = menu_items_used;
- }
-
- finish_menu_items ();
-
- /* Convert menu_items into widget_value trees
- to display the menu. This cannot evaluate Lisp code. */
-
- wv = xmalloc_widget_value ();
- wv->name = "menubar";
- wv->value = 0;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- first_wv = wv;
-
- for (i = 0; i < last_i; i += 4)
- {
- menu_items_n_panes = submenu_n_panes[i];
- wv = digest_single_submenu (submenu_start[i], submenu_end[i],
- submenu_top_level_items[i]);
- if (prev_wv)
- prev_wv->next = wv;
- else
- first_wv->contents = wv;
- /* Don't set wv->name here; GC during the loop might relocate it. */
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- prev_wv = wv;
- }
-
- set_buffer_internal_1 (prev);
-
- /* If there has been no change in the Lisp-level contents
- of the menu bar, skip redisplaying it. Just exit. */
-
- /* Compare the new menu items with the ones computed last time. */
- for (i = 0; i < previous_menu_items_used; i++)
- if (menu_items_used == i
- || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))
- break;
- if (i == menu_items_used && i == previous_menu_items_used && i != 0)
- {
- /* The menu items have not changed. Don't bother updating
- the menus in any form, since it would be a no-op. */
- free_menubar_widget_value_tree (first_wv);
- discard_menu_items ();
- unbind_to (specpdl_count, Qnil);
- return;
- }
-
- /* The menu items are different, so store them in the frame. */
- f->menu_bar_vector = menu_items;
- f->menu_bar_items_used = menu_items_used;
-
- /* This calls restore_menu_items to restore menu_items, etc.,
- as they were outside. */
- unbind_to (specpdl_count, Qnil);
-
- /* Now GC cannot happen during the lifetime of the widget_value,
- so it's safe to store data from a Lisp_String. */
- wv = first_wv->contents;
- for (i = 0; i < XVECTOR (items)->size; i += 4)
- {
- Lisp_Object string;
- string = XVECTOR (items)->contents[i + 1];
- if (NILP (string))
- break;
- wv->name = (char *) SDATA (string);
- update_submenu_strings (wv->contents);
- wv = wv->next;
- }
-
- }
- else
- {
- /* Make a widget-value tree containing
- just the top level menu bar strings. */
-
- wv = xmalloc_widget_value ();
- wv->name = "menubar";
- wv->value = 0;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- first_wv = wv;
-
- items = FRAME_MENU_BAR_ITEMS (f);
- for (i = 0; i < XVECTOR (items)->size; i += 4)
- {
- Lisp_Object string;
-
- string = XVECTOR (items)->contents[i + 1];
- if (NILP (string))
- break;
-
- wv = xmalloc_widget_value ();
- wv->name = (char *) SDATA (string);
- wv->value = 0;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- /* This prevents lwlib from assuming this
- menu item is really supposed to be empty. */
- /* The EMACS_INT cast avoids a warning.
- This value just has to be different from small integers. */
- wv->call_data = (void *) (EMACS_INT) (-1);
-
- if (prev_wv)
- prev_wv->next = wv;
- else
- first_wv->contents = wv;
- prev_wv = wv;
- }
-
- /* Forget what we thought we knew about what is in the
- detailed contents of the menu bar menus.
- Changing the top level always destroys the contents. */
- f->menu_bar_items_used = 0;
- }
-
- /* Create or update the menu bar widget. */
-
- BLOCK_INPUT;
-
- /* Non-null value to indicate menubar has already been "created". */
- f->output_data.mac->menubar_widget = 1;
-
- mac_fill_menubar (first_wv->contents, deep_p);
-
- free_menubar_widget_value_tree (first_wv);
-
- UNBLOCK_INPUT;
-}
-
-/* Get rid of the menu bar of frame F, and free its storage.
- This is used when deleting a frame, and when turning off the menu bar. */
-
-void
-free_frame_menubar (f)
- FRAME_PTR f;
-{
- f->output_data.mac->menubar_widget = 0;
-}
-
-
-/* The item selected in the popup menu. */
-int menu_item_selection;
-
-/* Mac_menu_show actually displays a menu using the panes and items in
- menu_items and returns the value selected from it; we assume input
- is blocked by the caller. */
-
-/* F is the frame the menu is for.
- X and Y are the frame-relative specified position,
- relative to the inside upper left corner of the frame F.
- FOR_CLICK is nonzero if this menu was invoked for a mouse click.
- KEYMAPS is 1 if this menu was specified with keymaps;
- in that case, we return a list containing the chosen item's value
- and perhaps also the pane's prefix.
- TITLE is the specified menu title.
- ERROR is a place to store an error message string in case of failure.
- (We return nil on failure, but the value doesn't actually matter.) */
-
-static Lisp_Object
-mac_menu_show (f, x, y, for_click, keymaps, title, error)
- FRAME_PTR f;
- int x;
- int y;
- int for_click;
- int keymaps;
- Lisp_Object title;
- char **error;
-{
- int i;
- widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
- widget_value **submenu_stack
- = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
- Lisp_Object *subprefix_stack
- = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
- int submenu_depth = 0;
-
- int first_pane;
-
- *error = NULL;
-
- if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
- {
- *error = "Empty menu";
- return Qnil;
- }
-
- /* Create a tree of widget_value objects
- representing the panes and their items. */
- wv = xmalloc_widget_value ();
- wv->name = "menu";
- wv->value = 0;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- first_wv = wv;
- first_pane = 1;
-
- /* Loop over all panes and items, filling in the tree. */
- i = 0;
- while (i < menu_items_used)
- {
- if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
- {
- submenu_stack[submenu_depth++] = save_wv;
- save_wv = prev_wv;
- prev_wv = 0;
- first_pane = 1;
- i++;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
- {
- prev_wv = save_wv;
- save_wv = submenu_stack[--submenu_depth];
- first_pane = 0;
- i++;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
- && submenu_depth != 0)
- i += MENU_ITEMS_PANE_LENGTH;
- /* Ignore a nil in the item list.
- It's meaningful only for dialog boxes. */
- else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
- i += 1;
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
- {
- /* Create a new pane. */
- Lisp_Object pane_name, prefix;
- char *pane_string;
-
- pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
- prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
-
-#ifndef HAVE_MULTILINGUAL_MENU
- if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
- {
- pane_name = ENCODE_MENU_STRING (pane_name);
- AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
- }
-#endif
- pane_string = (NILP (pane_name)
- ? "" : (char *) SDATA (pane_name));
- /* If there is just one top-level pane, put all its items directly
- under the top-level menu. */
- if (menu_items_n_panes == 1)
- pane_string = "";
-
- /* If the pane has a meaningful name,
- make the pane a top-level menu item
- with its items as a submenu beneath it. */
- if (!keymaps && strcmp (pane_string, ""))
- {
- wv = xmalloc_widget_value ();
- if (save_wv)
- save_wv->next = wv;
- else
- first_wv->contents = wv;
- wv->name = pane_string;
- if (keymaps && !NILP (prefix))
- wv->name++;
- wv->value = 0;
- wv->enabled = 1;
- wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
- save_wv = wv;
- prev_wv = 0;
- }
- else if (first_pane)
- {
- save_wv = wv;
- prev_wv = 0;
- }
- first_pane = 0;
- i += MENU_ITEMS_PANE_LENGTH;
- }
- else
- {
- /* Create a new item within current pane. */
- Lisp_Object item_name, enable, descrip, def, type, selected, help;
- item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
- enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
- descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
- def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
- type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
- selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
- help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
-
-#ifndef HAVE_MULTILINGUAL_MENU
- if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
- {
- item_name = ENCODE_MENU_STRING (item_name);
- AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
- }
-
- if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
- {
- descrip = ENCODE_MENU_STRING (descrip);
- AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
- }
-#endif /* not HAVE_MULTILINGUAL_MENU */
-
- wv = xmalloc_widget_value ();
- if (prev_wv)
- prev_wv->next = wv;
- else
- save_wv->contents = wv;
- wv->name = (char *) SDATA (item_name);
- if (!NILP (descrip))
- wv->key = (char *) SDATA (descrip);
- wv->value = 0;
- /* Use the contents index as call_data, since we are
- restricted to 16-bits. */
- wv->call_data = !NILP (def) ? (void *) (EMACS_INT) i : 0;
- wv->enabled = !NILP (enable);
-
- if (NILP (type))
- wv->button_type = BUTTON_TYPE_NONE;
- else if (EQ (type, QCtoggle))
- wv->button_type = BUTTON_TYPE_TOGGLE;
- else if (EQ (type, QCradio))
- wv->button_type = BUTTON_TYPE_RADIO;
- else
- abort ();
-
- wv->selected = !NILP (selected);
-
- if (! STRINGP (help))
- help = Qnil;
-
- wv->help = help;
-
- prev_wv = wv;
-
- i += MENU_ITEMS_ITEM_LENGTH;
- }
- }
-
- /* Deal with the title, if it is non-nil. */
- if (!NILP (title))
- {
- widget_value *wv_title = xmalloc_widget_value ();
- widget_value *wv_sep = xmalloc_widget_value ();
-
- /* Maybe replace this separator with a bitmap or owner-draw item
- so that it looks better. Having two separators looks odd. */
- wv_sep->name = "--";
- wv_sep->next = first_wv->contents;
- wv_sep->help = Qnil;
-
-#ifndef HAVE_MULTILINGUAL_MENU
- if (STRING_MULTIBYTE (title))
- title = ENCODE_MENU_STRING (title);
-#endif
-
- wv_title->name = (char *) SDATA (title);
- wv_title->enabled = FALSE;
- wv_title->title = TRUE;
- wv_title->button_type = BUTTON_TYPE_NONE;
- wv_title->help = Qnil;
- wv_title->next = wv_sep;
- first_wv->contents = wv_title;
- }
-
- /* No selection has been chosen yet. */
- menu_item_selection = 0;
-
- /* Actually create and show the menu until popped down. */
- create_and_show_popup_menu (f, first_wv, x, y, for_click);
-
- /* Free the widget_value objects we used to specify the contents. */
- free_menubar_widget_value_tree (first_wv);
-
- /* Find the selected item, and its pane, to return
- the proper value. */
- if (menu_item_selection != 0)
- {
- Lisp_Object prefix, entry;
-
- prefix = entry = Qnil;
- i = 0;
- while (i < menu_items_used)
- {
- if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
- {
- subprefix_stack[submenu_depth++] = prefix;
- prefix = entry;
- i++;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
- {
- prefix = subprefix_stack[--submenu_depth];
- i++;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
- {
- prefix
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
- i += MENU_ITEMS_PANE_LENGTH;
- }
- /* Ignore a nil in the item list.
- It's meaningful only for dialog boxes. */
- else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
- i += 1;
- else
- {
- entry
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
- if (menu_item_selection == i)
- {
- if (keymaps != 0)
- {
- int j;
-
- entry = Fcons (entry, Qnil);
- if (!NILP (prefix))
- entry = Fcons (prefix, entry);
- for (j = submenu_depth - 1; j >= 0; j--)
- if (!NILP (subprefix_stack[j]))
- entry = Fcons (subprefix_stack[j], entry);
- }
- return entry;
- }
- i += MENU_ITEMS_ITEM_LENGTH;
- }
- }
- }
- else if (!for_click)
- /* Make "Cancel" equivalent to C-g. */
- Fsignal (Qquit, Qnil);
-
- return Qnil;
-}
-
-
-#ifdef HAVE_DIALOGS
-/* Construct native Mac OS dialog based on widget_value tree. */
-
-static char * button_names [] = {
- "button1", "button2", "button3", "button4", "button5",
- "button6", "button7", "button8", "button9", "button10" };
-
-static Lisp_Object
-mac_dialog_show (f, keymaps, title, header, error_name)
- FRAME_PTR f;
- int keymaps;
- Lisp_Object title, header;
- char **error_name;
-{
- int i, nb_buttons=0;
- char dialog_name[6];
-
- widget_value *wv, *first_wv = 0, *prev_wv = 0;
-
- /* Number of elements seen so far, before boundary. */
- int left_count = 0;
- /* 1 means we've seen the boundary between left-hand elts and right-hand. */
- int boundary_seen = 0;
-
- *error_name = NULL;
-
- if (menu_items_n_panes > 1)
- {
- *error_name = "Multiple panes in dialog box";
- return Qnil;
- }
-
- /* Create a tree of widget_value objects
- representing the text label and buttons. */
- {
- Lisp_Object pane_name, prefix;
- char *pane_string;
- pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME];
- prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX];
- pane_string = (NILP (pane_name)
- ? "" : (char *) SDATA (pane_name));
- prev_wv = xmalloc_widget_value ();
- prev_wv->value = pane_string;
- if (keymaps && !NILP (prefix))
- prev_wv->name++;
- prev_wv->enabled = 1;
- prev_wv->name = "message";
- prev_wv->help = Qnil;
- first_wv = prev_wv;
-
- /* Loop over all panes and items, filling in the tree. */
- i = MENU_ITEMS_PANE_LENGTH;
- while (i < menu_items_used)
- {
-
- /* Create a new item within current pane. */
- Lisp_Object item_name, enable, descrip;
- item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
- enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
- descrip
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
-
- if (NILP (item_name))
- {
- free_menubar_widget_value_tree (first_wv);
- *error_name = "Submenu in dialog items";
- return Qnil;
- }
- if (EQ (item_name, Qquote))
- {
- /* This is the boundary between left-side elts
- and right-side elts. Stop incrementing right_count. */
- boundary_seen = 1;
- i++;
- continue;
- }
- if (nb_buttons >= 9)
- {
- free_menubar_widget_value_tree (first_wv);
- *error_name = "Too many dialog items";
- return Qnil;
- }
-
- wv = xmalloc_widget_value ();
- prev_wv->next = wv;
- wv->name = (char *) button_names[nb_buttons];
- if (!NILP (descrip))
- wv->key = (char *) SDATA (descrip);
- wv->value = (char *) SDATA (item_name);
- wv->call_data = (void *) i;
- /* menu item is identified by its index in menu_items table */
- wv->enabled = !NILP (enable);
- wv->help = Qnil;
- prev_wv = wv;
-
- if (! boundary_seen)
- left_count++;
-
- nb_buttons++;
- i += MENU_ITEMS_ITEM_LENGTH;
- }
-
- /* If the boundary was not specified,
- by default put half on the left and half on the right. */
- if (! boundary_seen)
- left_count = nb_buttons - nb_buttons / 2;
-
- wv = xmalloc_widget_value ();
- wv->name = dialog_name;
- wv->help = Qnil;
-
- /* Frame title: 'Q' = Question, 'I' = Information.
- Can also have 'E' = Error if, one day, we want
- a popup for errors. */
- if (NILP(header))
- dialog_name[0] = 'Q';
- else
- dialog_name[0] = 'I';
-
- /* Dialog boxes use a really stupid name encoding
- which specifies how many buttons to use
- and how many buttons are on the right. */
- dialog_name[1] = '0' + nb_buttons;
- dialog_name[2] = 'B';
- dialog_name[3] = 'R';
- /* Number of buttons to put on the right. */
- dialog_name[4] = '0' + nb_buttons - left_count;
- dialog_name[5] = 0;
- wv->contents = first_wv;
- first_wv = wv;
- }
-
- /* No selection has been chosen yet. */
- menu_item_selection = 0;
-
- /* Force a redisplay before showing the dialog. If a frame is created
- just before showing the dialog, its contents may not have been fully
- drawn. */
- Fredisplay (Qt);
-
- /* Actually create the dialog. */
-#if TARGET_API_MAC_CARBON
- create_and_show_dialog (f, first_wv);
-#else
- menu_item_selection = mac_dialog (first_wv);
-#endif
-
- /* Free the widget_value objects we used to specify the contents. */
- free_menubar_widget_value_tree (first_wv);
-
- /* Find the selected item, and its pane, to return
- the proper value. */
- if (menu_item_selection != 0)
- {
- Lisp_Object prefix;
-
- prefix = Qnil;
- i = 0;
- while (i < menu_items_used)
- {
- Lisp_Object entry;
-
- if (EQ (XVECTOR (menu_items)->contents[i], Qt))
- {
- prefix
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
- i += MENU_ITEMS_PANE_LENGTH;
- }
- else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
- {
- /* This is the boundary between left-side elts and
- right-side elts. */
- ++i;
- }
- else
- {
- entry
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
- if (menu_item_selection == i)
- {
- if (keymaps != 0)
- {
- entry = Fcons (entry, Qnil);
- if (!NILP (prefix))
- entry = Fcons (prefix, entry);
- }
- return entry;
- }
- i += MENU_ITEMS_ITEM_LENGTH;
- }
- }
- }
- else
- /* Make "Cancel" equivalent to C-g. */
- Fsignal (Qquit, Qnil);
-
- return Qnil;
-}
-#endif /* HAVE_DIALOGS */
-
-
-/* Is this item a separator? */
-int
-name_is_separator (name)
- const char *name;
-{
- const char *start = name;
-
- /* Check if name string consists of only dashes ('-'). */
- while (*name == '-') name++;
- /* Separators can also be of the form "--:TripleSuperMegaEtched"
- or "--deep-shadow". We don't implement them yet, se we just treat
- them like normal separators. */
- return (*name == '\0' || start + 2 == name);
-}
-#endif /* HAVE_MENUS */
-
-/* Detect if a menu is currently active. */
-
-int
-popup_activated ()
-{
- return popup_activated_flag;
-}
-
-/* The following is used by delayed window autoselection. */
-
-DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
- doc: /* Return t if a menu or popup dialog is active. */)
- ()
-{
-#if TARGET_API_MAC_CARBON
- return (popup_activated ()) ? Qt : Qnil;
-#else
- /* Always return Qnil since menu selection functions do not return
- until a selection has been made or cancelled. */
- return Qnil;
-#endif
-}
-
-void
-syms_of_macmenu ()
-{
- staticpro (&menu_items);
- menu_items = Qnil;
-
- Qdebug_on_next_call = intern ("debug-on-next-call");
- staticpro (&Qdebug_on_next_call);
-
- defsubr (&Sx_popup_menu);
- defsubr (&Smenu_or_popup_active_p);
-#ifdef HAVE_MENUS
- defsubr (&Sx_popup_dialog);
-#endif
-}
-
-/* arch-tag: 40b2c6c7-b8a9-4a49-b930-1b2707184cce
- (do not change this comment) */
diff --git a/src/macselect.c b/src/macselect.c
deleted file mode 100644
index b505698fab0..00000000000
--- a/src/macselect.c
+++ /dev/null
@@ -1,1165 +0,0 @@
-/* Selection processing for Emacs on Mac OS.
- Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include "lisp.h"
-#include "macterm.h"
-#include "blockinput.h"
-#include "keymap.h"
-
-#if !TARGET_API_MAC_CARBON
-#include <Endian.h>
-#endif
-
-static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
-static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
-static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
- Lisp_Object,
- Lisp_Object));
-
-Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS;
-
-static Lisp_Object Vx_lost_selection_functions;
-/* Coding system for communicating with other programs via selections. */
-static Lisp_Object Vselection_coding_system;
-
-/* Coding system for the next communicating with other programs. */
-static Lisp_Object Vnext_selection_coding_system;
-
-static Lisp_Object Qforeign_selection;
-
-/* The timestamp of the last input event Emacs received from the
- window server. */
-/* Defined in keyboard.c. */
-extern unsigned long last_event_timestamp;
-
-/* This is an association list whose elements are of the form
- ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME OWNERSHIP-INFO)
- SELECTION-NAME is a lisp symbol.
- SELECTION-VALUE is the value that emacs owns for that selection.
- It may be any kind of Lisp object.
- SELECTION-TIMESTAMP is the time at which emacs began owning this selection,
- as a cons of two 16-bit numbers (making a 32 bit time.)
- FRAME is the frame for which we made the selection.
- OWNERSHIP-INFO is a value saved when emacs owns for that selection.
- If another application takes the ownership of that selection
- later, then newly examined ownership info value should be
- different from the saved one.
- If there is an entry in this alist, the current ownership info for
- the selection coincides with OWNERSHIP-INFO, then it can be
- assumed that Emacs owns that selection.
- The only (eq) parts of this list that are visible from Lisp are the
- selection-values. */
-static Lisp_Object Vselection_alist;
-
-/* This is an alist whose CARs are selection-types and whose CDRs are
- the names of Lisp functions to call to convert the given Emacs
- selection value to a string representing the given selection type.
- This is for Lisp-level extension of the emacs selection
- handling. */
-Lisp_Object Vselection_converter_alist;
-
-/* A selection name (represented as a Lisp symbol) can be associated
- with a named scrap via `mac-scrap-name' property. Likewise for a
- selection type with a scrap flavor type via `mac-ostype'. */
-Lisp_Object Qmac_scrap_name, Qmac_ostype;
-
-
-/* Do protocol to assert ourself as a selection owner.
- Update the Vselection_alist so that we can reply to later requests for
- our selection. */
-
-static void
-x_own_selection (selection_name, selection_value)
- Lisp_Object selection_name, selection_value;
-{
- OSStatus err;
- Selection sel;
- struct gcpro gcpro1, gcpro2;
- Lisp_Object rest, handler_fn, value, target_type;
- int count;
-
- CHECK_SYMBOL (selection_name);
-
- GCPRO2 (selection_name, selection_value);
-
- BLOCK_INPUT;
-
- err = mac_get_selection_from_symbol (selection_name, 1, &sel);
- if (err == noErr && sel)
- {
- /* Don't allow a quit within the converter.
- When the user types C-g, he would be surprised
- if by luck it came during a converter. */
- count = SPECPDL_INDEX ();
- specbind (Qinhibit_quit, Qt);
-
- for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
- {
- if (!(CONSP (XCAR (rest))
- && (target_type = XCAR (XCAR (rest)),
- SYMBOLP (target_type))
- && mac_valid_selection_target_p (target_type)
- && (handler_fn = XCDR (XCAR (rest)),
- SYMBOLP (handler_fn))))
- continue;
-
- if (!NILP (handler_fn))
- value = call3 (handler_fn, selection_name,
- target_type, selection_value);
-
- if (NILP (value))
- continue;
-
- if (mac_valid_selection_value_p (value, target_type))
- err = mac_put_selection_value (sel, target_type, value);
- else if (CONSP (value)
- && EQ (XCAR (value), target_type)
- && mac_valid_selection_value_p (XCDR (value), target_type))
- err = mac_put_selection_value (sel, target_type, XCDR (value));
- }
-
- unbind_to (count, Qnil);
- }
-
- UNBLOCK_INPUT;
-
- UNGCPRO;
-
- if (sel && err != noErr)
- error ("Can't set selection");
-
- /* Now update the local cache */
- {
- Lisp_Object selection_time;
- Lisp_Object selection_data;
- Lisp_Object ownership_info;
- Lisp_Object prev_value;
-
- selection_time = long_to_cons (last_event_timestamp);
- if (sel)
- {
- BLOCK_INPUT;
- ownership_info = mac_get_selection_ownership_info (sel);
- UNBLOCK_INPUT;
- }
- else
- ownership_info = Qnil; /* dummy value for local-only selection */
- selection_data = Fcons (selection_name,
- Fcons (selection_value,
- Fcons (selection_time,
- Fcons (selected_frame,
- Fcons (ownership_info,
- Qnil)))));
- prev_value = assq_no_quit (selection_name, Vselection_alist);
-
- Vselection_alist = Fcons (selection_data, Vselection_alist);
-
- /* If we already owned the selection, remove the old selection data.
- Perhaps we should destructively modify it instead.
- Don't use Fdelq as that may QUIT. */
- if (!NILP (prev_value))
- {
- Lisp_Object rest; /* we know it's not the CAR, so it's easy. */
- for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
- if (EQ (prev_value, Fcar (XCDR (rest))))
- {
- XSETCDR (rest, Fcdr (XCDR (rest)));
- break;
- }
- }
- }
-}
-
-/* Given a selection-name and desired type, look up our local copy of
- the selection value and convert it to the type.
- The value is nil or a string.
- This function is used both for remote requests (LOCAL_REQUEST is zero)
- and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
-
- This calls random Lisp code, and may signal or gc. */
-
-static Lisp_Object
-x_get_local_selection (selection_symbol, target_type, local_request)
- Lisp_Object selection_symbol, target_type;
- int local_request;
-{
- Lisp_Object local_value;
- Lisp_Object handler_fn, value, type, check;
- int count;
-
- if (NILP (Fx_selection_owner_p (selection_symbol)))
- return Qnil;
-
- local_value = assq_no_quit (selection_symbol, Vselection_alist);
-
- /* TIMESTAMP is a special case 'cause that's easiest. */
- if (EQ (target_type, QTIMESTAMP))
- {
- handler_fn = Qnil;
- value = XCAR (XCDR (XCDR (local_value)));
- }
-#if 0
- else if (EQ (target_type, QDELETE))
- {
- handler_fn = Qnil;
- Fx_disown_selection_internal
- (selection_symbol,
- XCAR (XCDR (XCDR (local_value))));
- value = QNULL;
- }
-#endif
- else
- {
- /* Don't allow a quit within the converter.
- When the user types C-g, he would be surprised
- if by luck it came during a converter. */
- count = SPECPDL_INDEX ();
- specbind (Qinhibit_quit, Qt);
-
- CHECK_SYMBOL (target_type);
- handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
- /* gcpro is not needed here since nothing but HANDLER_FN
- is live, and that ought to be a symbol. */
-
- if (!NILP (handler_fn))
- value = call3 (handler_fn,
- selection_symbol, (local_request ? Qnil : target_type),
- XCAR (XCDR (local_value)));
- else
- value = Qnil;
- unbind_to (count, Qnil);
- }
-
- if (local_request)
- return value;
-
- /* Make sure this value is of a type that we could transmit
- to another application. */
-
- type = target_type;
- check = value;
- if (CONSP (value)
- && SYMBOLP (XCAR (value)))
- type = XCAR (value),
- check = XCDR (value);
-
- if (NILP (value) || mac_valid_selection_value_p (check, type))
- return value;
-
- signal_error ("Invalid data returned by selection-conversion function",
- list2 (handler_fn, value));
-}
-
-
-/* Clear all selections that were made from frame F.
- We do this when about to delete a frame. */
-
-void
-x_clear_frame_selections (f)
- FRAME_PTR f;
-{
- Lisp_Object frame;
- Lisp_Object rest;
-
- XSETFRAME (frame, f);
-
- /* Otherwise, we're really honest and truly being told to drop it.
- Don't use Fdelq as that may QUIT;. */
-
- /* Delete elements from the beginning of Vselection_alist. */
- while (!NILP (Vselection_alist)
- && EQ (frame, Fcar (Fcdr (Fcdr (Fcdr (Fcar (Vselection_alist)))))))
- {
- /* Let random Lisp code notice that the selection has been stolen. */
- Lisp_Object hooks, selection_symbol;
-
- hooks = Vx_lost_selection_functions;
- selection_symbol = Fcar (Fcar (Vselection_alist));
-
- if (!EQ (hooks, Qunbound)
- && !NILP (Fx_selection_owner_p (selection_symbol)))
- {
- for (; CONSP (hooks); hooks = Fcdr (hooks))
- call1 (Fcar (hooks), selection_symbol);
-#if 0 /* This can crash when deleting a frame
- from x_connection_closed. Anyway, it seems unnecessary;
- something else should cause a redisplay. */
- redisplay_preserve_echo_area (21);
-#endif
- }
-
- Vselection_alist = Fcdr (Vselection_alist);
- }
-
- /* Delete elements after the beginning of Vselection_alist. */
- for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
- if (EQ (frame, Fcar (Fcdr (Fcdr (Fcdr (Fcar (XCDR (rest))))))))
- {
- /* Let random Lisp code notice that the selection has been stolen. */
- Lisp_Object hooks, selection_symbol;
-
- hooks = Vx_lost_selection_functions;
- selection_symbol = Fcar (Fcar (XCDR (rest)));
-
- if (!EQ (hooks, Qunbound)
- && !NILP (Fx_selection_owner_p (selection_symbol)))
- {
- for (; CONSP (hooks); hooks = Fcdr (hooks))
- call1 (Fcar (hooks), selection_symbol);
-#if 0 /* See above */
- redisplay_preserve_echo_area (22);
-#endif
- }
- XSETCDR (rest, Fcdr (XCDR (rest)));
- break;
- }
-}
-
-/* Do protocol to read selection-data from the server.
- Converts this to Lisp data and returns it. */
-
-static Lisp_Object
-x_get_foreign_selection (selection_symbol, target_type, time_stamp)
- Lisp_Object selection_symbol, target_type, time_stamp;
-{
- OSStatus err;
- Selection sel;
- Lisp_Object result = Qnil;
-
- BLOCK_INPUT;
-
- err = mac_get_selection_from_symbol (selection_symbol, 0, &sel);
- if (err == noErr && sel)
- {
- if (EQ (target_type, QTARGETS))
- {
- result = mac_get_selection_target_list (sel);
- result = Fvconcat (1, &result);
- }
- else
- {
- result = mac_get_selection_value (sel, target_type);
- if (STRINGP (result))
- Fput_text_property (make_number (0), make_number (SBYTES (result)),
- Qforeign_selection, target_type, result);
- }
- }
-
- UNBLOCK_INPUT;
-
- return result;
-}
-
-
-DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
- Sx_own_selection_internal, 2, 2, 0,
- doc: /* Assert a selection of the given TYPE with the given VALUE.
-TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-VALUE is typically a string, or a cons of two markers, but may be
-anything that the functions on `selection-converter-alist' know about. */)
- (selection_name, selection_value)
- Lisp_Object selection_name, selection_value;
-{
- check_mac ();
- CHECK_SYMBOL (selection_name);
- if (NILP (selection_value)) error ("SELECTION-VALUE may not be nil");
- x_own_selection (selection_name, selection_value);
- return selection_value;
-}
-
-
-/* Request the selection value from the owner. If we are the owner,
- simply return our selection value. If we are not the owner, this
- will block until all of the data has arrived. */
-
-DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
- Sx_get_selection_internal, 2, 3, 0,
- doc: /* Return text selected from some Mac application.
-SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-TYPE is the type of data desired, typically `STRING'.
-TIME_STAMP is ignored on Mac. */)
- (selection_symbol, target_type, time_stamp)
- Lisp_Object selection_symbol, target_type, time_stamp;
-{
- Lisp_Object val = Qnil;
- struct gcpro gcpro1, gcpro2;
- GCPRO2 (target_type, val); /* we store newly consed data into these */
- check_mac ();
- CHECK_SYMBOL (selection_symbol);
- CHECK_SYMBOL (target_type);
-
- val = x_get_local_selection (selection_symbol, target_type, 1);
-
- if (NILP (val))
- {
- val = x_get_foreign_selection (selection_symbol, target_type, time_stamp);
- goto DONE;
- }
-
- if (CONSP (val)
- && SYMBOLP (XCAR (val)))
- {
- val = XCDR (val);
- if (CONSP (val) && NILP (XCDR (val)))
- val = XCAR (val);
- }
- DONE:
- UNGCPRO;
- return val;
-}
-
-DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
- Sx_disown_selection_internal, 1, 2, 0,
- doc: /* If we own the selection SELECTION, disown it.
-Disowning it means there is no such selection. */)
- (selection, time)
- Lisp_Object selection;
- Lisp_Object time;
-{
- OSStatus err;
- Selection sel;
- Lisp_Object local_selection_data;
-
- check_mac ();
- CHECK_SYMBOL (selection);
-
- if (NILP (Fx_selection_owner_p (selection)))
- return Qnil; /* Don't disown the selection when we're not the owner. */
-
- local_selection_data = assq_no_quit (selection, Vselection_alist);
-
- /* Don't use Fdelq as that may QUIT;. */
-
- if (EQ (local_selection_data, Fcar (Vselection_alist)))
- Vselection_alist = Fcdr (Vselection_alist);
- else
- {
- Lisp_Object rest;
- for (rest = Vselection_alist; CONSP (rest); rest = XCDR (rest))
- if (EQ (local_selection_data, Fcar (XCDR (rest))))
- {
- XSETCDR (rest, Fcdr (XCDR (rest)));
- break;
- }
- }
-
- /* Let random lisp code notice that the selection has been stolen. */
-
- {
- Lisp_Object rest;
- rest = Vx_lost_selection_functions;
- if (!EQ (rest, Qunbound))
- {
- for (; CONSP (rest); rest = Fcdr (rest))
- call1 (Fcar (rest), selection);
- prepare_menu_bars ();
- redisplay_preserve_echo_area (20);
- }
- }
-
- BLOCK_INPUT;
-
- err = mac_get_selection_from_symbol (selection, 0, &sel);
- if (err == noErr && sel)
- mac_clear_selection (&sel);
-
- UNBLOCK_INPUT;
-
- return Qt;
-}
-
-
-DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
- 0, 1, 0,
- doc: /* Whether the current Emacs process owns the given SELECTION.
-The arg should be the name of the selection in question, typically one of
-the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-For convenience, the symbol nil is the same as `PRIMARY',
-and t is the same as `SECONDARY'. */)
- (selection)
- Lisp_Object selection;
-{
- OSStatus err;
- Selection sel;
- Lisp_Object result = Qnil, local_selection_data;
-
- check_mac ();
- CHECK_SYMBOL (selection);
- if (EQ (selection, Qnil)) selection = QPRIMARY;
- if (EQ (selection, Qt)) selection = QSECONDARY;
-
- local_selection_data = assq_no_quit (selection, Vselection_alist);
-
- if (NILP (local_selection_data))
- return Qnil;
-
- BLOCK_INPUT;
-
- err = mac_get_selection_from_symbol (selection, 0, &sel);
- if (err == noErr && sel)
- {
- Lisp_Object ownership_info;
-
- ownership_info = XCAR (XCDR (XCDR (XCDR (XCDR (local_selection_data)))));
- if (!NILP (Fequal (ownership_info,
- mac_get_selection_ownership_info (sel))))
- result = Qt;
- }
- else
- result = Qt;
-
- UNBLOCK_INPUT;
-
- return result;
-}
-
-DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
- 0, 1, 0,
- doc: /* Whether there is an owner for the given SELECTION.
-The arg should be the name of the selection in question, typically one of
-the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-For convenience, the symbol nil is the same as `PRIMARY',
-and t is the same as `SECONDARY'. */)
- (selection)
- Lisp_Object selection;
-{
- OSStatus err;
- Selection sel;
- Lisp_Object result = Qnil, rest;
-
- /* It should be safe to call this before we have an Mac frame. */
- if (! FRAME_MAC_P (SELECTED_FRAME ()))
- return Qnil;
-
- CHECK_SYMBOL (selection);
- if (!NILP (Fx_selection_owner_p (selection)))
- return Qt;
- if (EQ (selection, Qnil)) selection = QPRIMARY;
- if (EQ (selection, Qt)) selection = QSECONDARY;
-
- BLOCK_INPUT;
-
- err = mac_get_selection_from_symbol (selection, 0, &sel);
- if (err == noErr && sel)
- for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
- {
- if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
- && mac_selection_has_target_p (sel, XCAR (XCAR (rest))))
- {
- result = Qt;
- break;
- }
- }
-
- UNBLOCK_INPUT;
-
- return result;
-}
-
-
-/***********************************************************************
- Apple event support
-***********************************************************************/
-int mac_ready_for_apple_events = 0;
-Lisp_Object Vmac_apple_event_map;
-Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id;
-static Lisp_Object Qemacs_suspension_id;
-extern Lisp_Object Qundefined;
-extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object,
- const AEDesc *));
-
-struct apple_event_binding
-{
- UInt32 code; /* Apple event class or ID. */
- Lisp_Object key, binding;
-};
-
-struct suspended_ae_info
-{
- UInt32 expiration_tick, suspension_id;
- AppleEvent apple_event, reply;
- struct suspended_ae_info *next;
-};
-
-/* List of apple events deferred at the startup time. */
-static struct suspended_ae_info *deferred_apple_events = NULL;
-
-/* List of suspended apple events, in order of expiration_tick. */
-static struct suspended_ae_info *suspended_apple_events = NULL;
-
-static void
-find_event_binding_fun (key, binding, args, data)
- Lisp_Object key, binding, args;
- void *data;
-{
- struct apple_event_binding *event_binding =
- (struct apple_event_binding *)data;
- Lisp_Object code_string;
-
- if (!SYMBOLP (key))
- return;
- code_string = Fget (key, args);
- if (STRINGP (code_string) && SBYTES (code_string) == 4
- && (EndianU32_BtoN (*((UInt32 *) SDATA (code_string)))
- == event_binding->code))
- {
- event_binding->key = key;
- event_binding->binding = binding;
- }
-}
-
-static void
-find_event_binding (keymap, event_binding, class_p)
- Lisp_Object keymap;
- struct apple_event_binding *event_binding;
- int class_p;
-{
- if (event_binding->code == 0)
- event_binding->binding =
- access_keymap (keymap, event_binding->key, 0, 1, 0);
- else
- {
- event_binding->binding = Qnil;
- map_keymap (keymap, find_event_binding_fun,
- class_p ? Qmac_apple_event_class : Qmac_apple_event_id,
- event_binding, 0);
- }
-}
-
-void
-mac_find_apple_event_spec (class, id, class_key, id_key, binding)
- AEEventClass class;
- AEEventID id;
- Lisp_Object *class_key, *id_key, *binding;
-{
- struct apple_event_binding event_binding;
- Lisp_Object keymap;
-
- *binding = Qnil;
-
- keymap = get_keymap (Vmac_apple_event_map, 0, 0);
- if (NILP (keymap))
- return;
-
- event_binding.code = class;
- event_binding.key = *class_key;
- event_binding.binding = Qnil;
- find_event_binding (keymap, &event_binding, 1);
- *class_key = event_binding.key;
- keymap = get_keymap (event_binding.binding, 0, 0);
- if (NILP (keymap))
- return;
-
- event_binding.code = id;
- event_binding.key = *id_key;
- event_binding.binding = Qnil;
- find_event_binding (keymap, &event_binding, 0);
- *id_key = event_binding.key;
- *binding = event_binding.binding;
-}
-
-static OSErr
-defer_apple_events (apple_event, reply)
- const AppleEvent *apple_event, *reply;
-{
- OSErr err;
- struct suspended_ae_info *new;
-
- new = xmalloc (sizeof (struct suspended_ae_info));
- bzero (new, sizeof (struct suspended_ae_info));
- new->apple_event.descriptorType = typeNull;
- new->reply.descriptorType = typeNull;
-
- err = AESuspendTheCurrentEvent (apple_event);
-
- /* Mac OS 10.3 Xcode manual says AESuspendTheCurrentEvent makes
- copies of the Apple event and the reply, but Mac OS 10.4 Xcode
- manual says it doesn't. Anyway we create copies of them and save
- them in `deferred_apple_events'. */
- if (err == noErr)
- err = AEDuplicateDesc (apple_event, &new->apple_event);
- if (err == noErr)
- err = AEDuplicateDesc (reply, &new->reply);
- if (err == noErr)
- {
- new->next = deferred_apple_events;
- deferred_apple_events = new;
- }
- else
- {
- AEDisposeDesc (&new->apple_event);
- AEDisposeDesc (&new->reply);
- xfree (new);
- }
-
- return err;
-}
-
-static OSErr
-mac_handle_apple_event_1 (class, id, apple_event, reply)
- Lisp_Object class, id;
- const AppleEvent *apple_event;
- AppleEvent *reply;
-{
- OSErr err;
- static UInt32 suspension_id = 0;
- struct suspended_ae_info *new;
-
- new = xmalloc (sizeof (struct suspended_ae_info));
- bzero (new, sizeof (struct suspended_ae_info));
- new->apple_event.descriptorType = typeNull;
- new->reply.descriptorType = typeNull;
-
- err = AESuspendTheCurrentEvent (apple_event);
- if (err == noErr)
- err = AEDuplicateDesc (apple_event, &new->apple_event);
- if (err == noErr)
- err = AEDuplicateDesc (reply, &new->reply);
- if (err == noErr)
- err = AEPutAttributePtr (&new->apple_event, KEY_EMACS_SUSPENSION_ID_ATTR,
- typeUInt32, &suspension_id, sizeof (UInt32));
- if (err == noErr)
- {
- OSErr err1;
- SInt32 reply_requested;
-
- err1 = AEGetAttributePtr (&new->apple_event, keyReplyRequestedAttr,
- typeSInt32, NULL, &reply_requested,
- sizeof (SInt32), NULL);
- if (err1 != noErr)
- {
- /* Emulate keyReplyRequestedAttr in older versions. */
- reply_requested = reply->descriptorType != typeNull;
- err = AEPutAttributePtr (&new->apple_event, keyReplyRequestedAttr,
- typeSInt32, &reply_requested,
- sizeof (SInt32));
- }
- }
- if (err == noErr)
- {
- SInt32 timeout = 0;
- struct suspended_ae_info **p;
-
- new->suspension_id = suspension_id;
- suspension_id++;
- err = AEGetAttributePtr (apple_event, keyTimeoutAttr, typeSInt32,
- NULL, &timeout, sizeof (SInt32), NULL);
- new->expiration_tick = TickCount () + timeout;
-
- for (p = &suspended_apple_events; *p; p = &(*p)->next)
- if ((*p)->expiration_tick >= new->expiration_tick)
- break;
- new->next = *p;
- *p = new;
-
- mac_store_apple_event (class, id, &new->apple_event);
- }
- else
- {
- AEDisposeDesc (&new->reply);
- AEDisposeDesc (&new->apple_event);
- xfree (new);
- }
-
- return err;
-}
-
-pascal OSErr
-mac_handle_apple_event (apple_event, reply, refcon)
- const AppleEvent *apple_event;
- AppleEvent *reply;
- SInt32 refcon;
-{
- OSErr err;
- UInt32 suspension_id;
- AEEventClass event_class;
- AEEventID event_id;
- Lisp_Object class_key, id_key, binding;
-
- if (!mac_ready_for_apple_events)
- {
- err = defer_apple_events (apple_event, reply);
- if (err != noErr)
- return errAEEventNotHandled;
- return noErr;
- }
-
- err = AEGetAttributePtr (apple_event, KEY_EMACS_SUSPENSION_ID_ATTR,
- typeUInt32, NULL,
- &suspension_id, sizeof (UInt32), NULL);
- if (err == noErr)
- /* Previously suspended event. Pass it to the next handler. */
- return errAEEventNotHandled;
-
- err = AEGetAttributePtr (apple_event, keyEventClassAttr, typeType, NULL,
- &event_class, sizeof (AEEventClass), NULL);
- if (err == noErr)
- err = AEGetAttributePtr (apple_event, keyEventIDAttr, typeType, NULL,
- &event_id, sizeof (AEEventID), NULL);
- if (err == noErr)
- {
- mac_find_apple_event_spec (event_class, event_id,
- &class_key, &id_key, &binding);
- if (!NILP (binding) && !EQ (binding, Qundefined))
- {
- if (INTEGERP (binding))
- return XINT (binding);
- err = mac_handle_apple_event_1 (class_key, id_key,
- apple_event, reply);
- }
- else
- err = errAEEventNotHandled;
- }
- if (err == noErr)
- return noErr;
- else
- return errAEEventNotHandled;
-}
-
-static int
-cleanup_suspended_apple_events (head, all_p)
- struct suspended_ae_info **head;
- int all_p;
-{
- UInt32 current_tick = TickCount (), nresumed = 0;
- struct suspended_ae_info *p, *next;
-
- for (p = *head; p; p = next)
- {
- if (!all_p && p->expiration_tick > current_tick)
- break;
- AESetTheCurrentEvent (&p->apple_event);
- AEResumeTheCurrentEvent (&p->apple_event, &p->reply,
- (AEEventHandlerUPP) kAENoDispatch, 0);
- AEDisposeDesc (&p->reply);
- AEDisposeDesc (&p->apple_event);
- nresumed++;
- next = p->next;
- xfree (p);
- }
- *head = p;
-
- return nresumed;
-}
-
-void
-cleanup_all_suspended_apple_events ()
-{
- cleanup_suspended_apple_events (&deferred_apple_events, 1);
- cleanup_suspended_apple_events (&suspended_apple_events, 1);
-}
-
-static UInt32
-get_suspension_id (apple_event)
- Lisp_Object apple_event;
-{
- Lisp_Object tem;
-
- CHECK_CONS (apple_event);
- CHECK_STRING_CAR (apple_event);
- if (SBYTES (XCAR (apple_event)) != 4
- || strcmp (SDATA (XCAR (apple_event)), "aevt") != 0)
- error ("Not an apple event");
-
- tem = assq_no_quit (Qemacs_suspension_id, XCDR (apple_event));
- if (NILP (tem))
- error ("Suspension ID not available");
-
- tem = XCDR (tem);
- if (!(CONSP (tem)
- && STRINGP (XCAR (tem)) && SBYTES (XCAR (tem)) == 4
- && strcmp (SDATA (XCAR (tem)), "magn") == 0
- && STRINGP (XCDR (tem)) && SBYTES (XCDR (tem)) == 4))
- error ("Bad suspension ID format");
-
- return *((UInt32 *) SDATA (XCDR (tem)));
-}
-
-
-DEFUN ("mac-process-deferred-apple-events", Fmac_process_deferred_apple_events, Smac_process_deferred_apple_events, 0, 0, 0,
- doc: /* Process Apple events that are deferred at the startup time. */)
- ()
-{
- if (mac_ready_for_apple_events)
- return Qnil;
-
- BLOCK_INPUT;
- mac_ready_for_apple_events = 1;
- if (deferred_apple_events)
- {
- struct suspended_ae_info *prev, *tail, *next;
-
- /* `nreverse' deferred_apple_events. */
- prev = NULL;
- for (tail = deferred_apple_events; tail; tail = next)
- {
- next = tail->next;
- tail->next = prev;
- prev = tail;
- }
-
- /* Now `prev' points to the first cell. */
- for (tail = prev; tail; tail = next)
- {
- next = tail->next;
- AEResumeTheCurrentEvent (&tail->apple_event, &tail->reply,
- ((AEEventHandlerUPP)
- kAEUseStandardDispatch), 0);
- AEDisposeDesc (&tail->reply);
- AEDisposeDesc (&tail->apple_event);
- xfree (tail);
- }
-
- deferred_apple_events = NULL;
- }
- UNBLOCK_INPUT;
-
- return Qt;
-}
-
-DEFUN ("mac-cleanup-expired-apple-events", Fmac_cleanup_expired_apple_events, Smac_cleanup_expired_apple_events, 0, 0, 0,
- doc: /* Clean up expired Apple events.
-Return the number of expired events. */)
- ()
-{
- int nexpired;
-
- BLOCK_INPUT;
- nexpired = cleanup_suspended_apple_events (&suspended_apple_events, 0);
- UNBLOCK_INPUT;
-
- return make_number (nexpired);
-}
-
-DEFUN ("mac-ae-set-reply-parameter", Fmac_ae_set_reply_parameter, Smac_ae_set_reply_parameter, 3, 3, 0,
- doc: /* Set parameter KEYWORD to DESCRIPTOR on reply of APPLE-EVENT.
-KEYWORD is a 4-byte string. DESCRIPTOR is a Lisp representation of an
-Apple event descriptor. It has the form of (TYPE . DATA), where TYPE
-is a 4-byte string. Valid format of DATA is as follows:
-
- * If TYPE is "null", then DATA is nil.
- * If TYPE is "list", then DATA is a list (DESCRIPTOR1 ... DESCRIPTORn).
- * If TYPE is "reco", then DATA is a list ((KEYWORD1 . DESCRIPTOR1)
- ... (KEYWORDn . DESCRIPTORn)).
- * If TYPE is "aevt", then DATA is ignored and the descriptor is
- treated as null.
- * Otherwise, DATA is a string.
-
-If a (sub-)descriptor is in an invalid format, it is silently treated
-as null.
-
-Return t if the parameter is successfully set. Otherwise return nil. */)
- (apple_event, keyword, descriptor)
- Lisp_Object apple_event, keyword, descriptor;
-{
- Lisp_Object result = Qnil;
- UInt32 suspension_id;
- struct suspended_ae_info *p;
-
- suspension_id = get_suspension_id (apple_event);
-
- CHECK_STRING (keyword);
- if (SBYTES (keyword) != 4)
- error ("Apple event keyword must be a 4-byte string: %s",
- SDATA (keyword));
-
- BLOCK_INPUT;
- for (p = suspended_apple_events; p; p = p->next)
- if (p->suspension_id == suspension_id)
- break;
- if (p && p->reply.descriptorType != typeNull)
- {
- OSErr err;
-
- err = mac_ae_put_lisp (&p->reply,
- EndianU32_BtoN (*((UInt32 *) SDATA (keyword))),
- descriptor);
- if (err == noErr)
- result = Qt;
- }
- UNBLOCK_INPUT;
-
- return result;
-}
-
-DEFUN ("mac-resume-apple-event", Fmac_resume_apple_event, Smac_resume_apple_event, 1, 2, 0,
- doc: /* Resume handling of APPLE-EVENT.
-Every Apple event handled by the Lisp interpreter is suspended first.
-This function resumes such a suspended event either to complete Apple
-event handling to give a reply, or to redispatch it to other handlers.
-
-If optional ERROR-CODE is an integer, it specifies the error number
-that is set in the reply. If ERROR-CODE is t, the resumed event is
-handled with the standard dispatching mechanism, but it is not handled
-by Emacs again, thus it is redispatched to other handlers.
-
-Return t if APPLE-EVENT is successfully resumed. Otherwise return
-nil, which means the event is already resumed or expired. */)
- (apple_event, error_code)
- Lisp_Object apple_event, error_code;
-{
- Lisp_Object result = Qnil;
- UInt32 suspension_id;
- struct suspended_ae_info **p, *ae;
-
- suspension_id = get_suspension_id (apple_event);
-
- BLOCK_INPUT;
- for (p = &suspended_apple_events; *p; p = &(*p)->next)
- if ((*p)->suspension_id == suspension_id)
- break;
- if (*p)
- {
- ae = *p;
- *p = (*p)->next;
- if (INTEGERP (error_code)
- && ae->reply.descriptorType != typeNull)
- {
- SInt32 errn = XINT (error_code);
-
- AEPutParamPtr (&ae->reply, keyErrorNumber, typeSInt32,
- &errn, sizeof (SInt32));
- }
- AESetTheCurrentEvent (&ae->apple_event);
- AEResumeTheCurrentEvent (&ae->apple_event, &ae->reply,
- ((AEEventHandlerUPP)
- (EQ (error_code, Qt) ?
- kAEUseStandardDispatch : kAENoDispatch)),
- 0);
- AEDisposeDesc (&ae->reply);
- AEDisposeDesc (&ae->apple_event);
- xfree (ae);
- result = Qt;
- }
- UNBLOCK_INPUT;
-
- return result;
-}
-
-
-/***********************************************************************
- Drag and drop support
-***********************************************************************/
-#if TARGET_API_MAC_CARBON
-Lisp_Object Vmac_dnd_known_types;
-#endif /* TARGET_API_MAC_CARBON */
-
-
-/***********************************************************************
- Services menu support
-***********************************************************************/
-#ifdef MAC_OSX
-/* Selection name for communication via Services menu. */
-Lisp_Object Vmac_service_selection;
-#endif
-
-void
-syms_of_macselect ()
-{
- defsubr (&Sx_get_selection_internal);
- defsubr (&Sx_own_selection_internal);
- defsubr (&Sx_disown_selection_internal);
- defsubr (&Sx_selection_owner_p);
- defsubr (&Sx_selection_exists_p);
- defsubr (&Smac_process_deferred_apple_events);
- defsubr (&Smac_cleanup_expired_apple_events);
- defsubr (&Smac_resume_apple_event);
- defsubr (&Smac_ae_set_reply_parameter);
-
- Vselection_alist = Qnil;
- staticpro (&Vselection_alist);
-
- DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
- doc: /* An alist associating selection-types with functions.
-These functions are called to convert the selection, with three args:
-the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
-a desired type to which the selection should be converted;
-and the local selection value (whatever was given to `x-own-selection').
-
-The function should return the value to send to the Scrap Manager
-\(must be a string). A return value of nil
-means that the conversion could not be done. */);
- Vselection_converter_alist = Qnil;
-
- DEFVAR_LISP ("x-lost-selection-functions", &Vx_lost_selection_functions,
- doc: /* A list of functions to be called when Emacs loses a selection.
-\(This happens when a Lisp program explicitly clears the selection.)
-The functions are called with one argument, the selection type
-\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
- Vx_lost_selection_functions = Qnil;
-
- DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
- doc: /* Coding system for communicating with other programs.
-When sending or receiving text via cut_buffer, selection, and clipboard,
-the text is encoded or decoded by this coding system.
-The default value is determined by the system script code. */);
- Vselection_coding_system = Qnil;
-
- DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
- doc: /* Coding system for the next communication with other programs.
-Usually, `selection-coding-system' is used for communicating with
-other programs. But, if this variable is set, it is used for the
-next communication only. After the communication, this variable is
-set to nil. */);
- Vnext_selection_coding_system = Qnil;
-
- DEFVAR_LISP ("mac-apple-event-map", &Vmac_apple_event_map,
- doc: /* Keymap for Apple events handled by Emacs. */);
- Vmac_apple_event_map = Qnil;
-
-#if TARGET_API_MAC_CARBON
- DEFVAR_LISP ("mac-dnd-known-types", &Vmac_dnd_known_types,
- doc: /* The types accepted by default for dropped data.
-The types are chosen in the order they appear in the list. */);
- Vmac_dnd_known_types = mac_dnd_default_known_types ();
-#endif
-
-#ifdef MAC_OSX
- DEFVAR_LISP ("mac-service-selection", &Vmac_service_selection,
- doc: /* Selection name for communication via Services menu. */);
- Vmac_service_selection = intern ("PRIMARY");
-#endif
-
- QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
- QSECONDARY = intern ("SECONDARY"); staticpro (&QSECONDARY);
- QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
- QTARGETS = intern ("TARGETS"); staticpro (&QTARGETS);
-
- Qforeign_selection = intern ("foreign-selection");
- staticpro (&Qforeign_selection);
-
- Qmac_scrap_name = intern ("mac-scrap-name");
- staticpro (&Qmac_scrap_name);
-
- Qmac_ostype = intern ("mac-ostype");
- staticpro (&Qmac_ostype);
-
- Qmac_apple_event_class = intern ("mac-apple-event-class");
- staticpro (&Qmac_apple_event_class);
-
- Qmac_apple_event_id = intern ("mac-apple-event-id");
- staticpro (&Qmac_apple_event_id);
-
- Qemacs_suspension_id = intern ("emacs-suspension-id");
- staticpro (&Qemacs_suspension_id);
-}
-
-/* arch-tag: f3c91ad8-99e0-4bd6-9eef-251b2f848732
- (do not change this comment) */
diff --git a/src/macterm.c b/src/macterm.c
deleted file mode 100644
index 4deaa91dc5e..00000000000
--- a/src/macterm.c
+++ /dev/null
@@ -1,13451 +0,0 @@
-/* Implementation of GUI terminal on the Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Contributed by Andrew Choi (akochoi@mac.com). */
-
-#include <config.h>
-#include <signal.h>
-
-#include <stdio.h>
-
-#include "lisp.h"
-#include "blockinput.h"
-
-#include "macterm.h"
-
-#ifndef MAC_OSX
-#include <alloca.h>
-#endif
-
-#if !TARGET_API_MAC_CARBON
-#include <Quickdraw.h>
-#include <ToolUtils.h>
-#include <Sound.h>
-#include <Events.h>
-#include <Script.h>
-#include <Resources.h>
-#include <Fonts.h>
-#include <TextUtils.h>
-#include <LowMem.h>
-#include <Controls.h>
-#include <Windows.h>
-#include <Displays.h>
-#if defined (__MRC__) || (__MSL__ >= 0x6000)
-#include <ControlDefinitions.h>
-#endif
-
-#if __profile__
-#include <profiler.h>
-#endif
-#endif /* not TARGET_API_MAC_CARBON */
-
-#include "systty.h"
-#include "systime.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <sys/stat.h>
-
-#include "charset.h"
-#include "coding.h"
-#include "frame.h"
-#include "dispextern.h"
-#include "fontset.h"
-#include "termhooks.h"
-#include "termopts.h"
-#include "termchar.h"
-#include "disptab.h"
-#include "buffer.h"
-#include "window.h"
-#include "keyboard.h"
-#include "intervals.h"
-#include "atimer.h"
-#include "keymap.h"
-#include "character.h"
-#include "ccl.h"
-
-
-
-/* Non-nil means Emacs uses toolkit scroll bars. */
-
-Lisp_Object Vx_toolkit_scroll_bars;
-
-/* If non-zero, the text will be rendered using Core Graphics text
- rendering which may anti-alias the text. */
-int mac_use_core_graphics;
-
-
-/* Non-zero means that a HELP_EVENT has been generated since Emacs
- start. */
-
-static int any_help_event_p;
-
-/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
-static Lisp_Object last_window;
-
-/* Non-zero means make use of UNDERLINE_POSITION font properties.
- (Not yet supported.) */
-int x_use_underline_position_properties;
-
-/* Non-zero means to draw the underline at the same place as the descent line. */
-
-int x_underline_at_descent_line;
-
-/* This is a chain of structures for all the X displays currently in
- use. */
-
-struct x_display_info *x_display_list;
-
-/* This is a list of cons cells, each of the form (NAME
- FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
- x_display_list and in the same order. NAME is the name of the
- frame. FONT-LIST-CACHE records previous values returned by
- x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
- equivalent, which is implemented with a Lisp object, for the
- display. */
-
-Lisp_Object x_display_name_list;
-
-/* This is display since Mac does not support multiple ones. */
-struct mac_display_info one_mac_display_info;
-
-/* Frame being updated by update_frame. This is declared in term.c.
- This is set by update_begin and looked at by all the XT functions.
- It is zero while not inside an update. In that case, the XT
- functions assume that `selected_frame' is the frame to apply to. */
-
-extern struct frame *updating_frame;
-
-/* This is a frame waiting to be auto-raised, within XTread_socket. */
-
-struct frame *pending_autoraise_frame;
-
-/* Mouse movement.
-
- Formerly, we used PointerMotionHintMask (in standard_event_mask)
- so that we would have to call XQueryPointer after each MotionNotify
- event to ask for another such event. However, this made mouse tracking
- slow, and there was a bug that made it eventually stop.
-
- Simply asking for MotionNotify all the time seems to work better.
-
- In order to avoid asking for motion events and then throwing most
- of them away or busy-polling the server for mouse positions, we ask
- the server for pointer motion hints. This means that we get only
- one event per group of mouse movements. "Groups" are delimited by
- other kinds of events (focus changes and button clicks, for
- example), or by XQueryPointer calls; when one of these happens, we
- get another MotionNotify event the next time the mouse moves. This
- is at least as efficient as getting motion events when mouse
- tracking is on, and I suspect only negligibly worse when tracking
- is off. */
-
-/* Where the mouse was last time we reported a mouse event. */
-
-static Rect last_mouse_glyph;
-static FRAME_PTR last_mouse_glyph_frame;
-
-/* The scroll bar in which the last X motion event occurred.
-
- If the last X motion event occurred in a scroll bar, we set this so
- XTmouse_position can know whether to report a scroll bar motion or
- an ordinary motion.
-
- If the last X motion event didn't occur in a scroll bar, we set
- this to Qnil, to tell XTmouse_position to return an ordinary motion
- event. */
-
-static Lisp_Object last_mouse_scroll_bar;
-
-/* This is a hack. We would really prefer that XTmouse_position would
- return the time associated with the position it returns, but there
- doesn't seem to be any way to wrest the time-stamp from the server
- along with the position query. So, we just keep track of the time
- of the last movement we received, and return that in hopes that
- it's somewhat accurate. */
-
-static Time last_mouse_movement_time;
-
-struct scroll_bar *tracked_scroll_bar = NULL;
-
-/* Incremented by XTread_socket whenever it really tries to read
- events. */
-
-#ifdef __STDC__
-static int volatile input_signal_count;
-#else
-static int input_signal_count;
-#endif
-
-extern Lisp_Object Vsystem_name;
-
-extern Lisp_Object Qeql;
-
-/* A mask of extra modifier bits to put into every keyboard char. */
-
-extern EMACS_INT extra_keyboard_modifiers;
-
-/* The keysyms to use for the various modifiers. */
-
-static Lisp_Object Qalt, Qhyper, Qsuper, Qcontrol, Qmeta, Qmodifier_value;
-
-extern int inhibit_window_system;
-
-#if __MRC__ && !TARGET_API_MAC_CARBON
-QDGlobals qd; /* QuickDraw global information structure. */
-#endif
-
-#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
-
-struct mac_display_info *mac_display_info_for_display (Display *);
-static void x_update_window_end P_ ((struct window *, int, int));
-int x_catch_errors P_ ((Display *));
-void x_uncatch_errors P_ ((Display *, int));
-void x_lower_frame P_ ((struct frame *));
-void x_scroll_bar_clear P_ ((struct frame *));
-int x_had_errors_p P_ ((Display *));
-void x_wm_set_size_hint P_ ((struct frame *, long, int));
-void x_raise_frame P_ ((struct frame *));
-void x_set_window_size P_ ((struct frame *, int, int, int));
-void x_wm_set_window_state P_ ((struct frame *, int));
-void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-static void mac_initialize P_ ((void));
-static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
-static int x_compute_min_glyph_bounds P_ ((struct frame *));
-static void x_update_end P_ ((struct frame *));
-static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((struct terminal *));
-static void XTreset_terminal_modes P_ ((struct terminal *));
-static void x_clear_frame P_ ((struct frame *));
-static void frame_highlight P_ ((struct frame *));
-static void frame_unhighlight P_ ((struct frame *));
-static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
-static void mac_focus_changed P_ ((int, struct mac_display_info *,
- struct frame *, struct input_event *));
-static void x_detect_focus_change P_ ((struct mac_display_info *,
- const EventRecord *,
- struct input_event *));
-static void XTframe_rehighlight P_ ((struct frame *));
-static void x_frame_rehighlight P_ ((struct x_display_info *));
-static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
-static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
- enum text_cursor_kinds));
-
-static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
-static void x_flush P_ ((struct frame *f));
-static void x_update_begin P_ ((struct frame *));
-static void x_update_window_begin P_ ((struct window *));
-static void x_after_update_window_line P_ ((struct glyph_row *));
-static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
- enum scroll_bar_part *,
- Lisp_Object *, Lisp_Object *,
- unsigned long *));
-
-static int is_emacs_window P_ ((WindowRef));
-static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
-static void XSetFont P_ ((Display *, GC, XFontStruct *));
-static struct terminal *mac_create_terminal P_ ((struct mac_display_info *dpyinfo));
-
-
-#define GC_FORE_COLOR(gc) (&(gc)->fore_color)
-#define GC_BACK_COLOR(gc) (&(gc)->back_color)
-#define GC_FONT(gc) ((gc)->xgcv.font)
-#define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc)
-
-#define CG_SET_FILL_COLOR(context, color) \
- CGContextSetRGBFillColor (context, \
- RED_FROM_ULONG (color) / 255.0f, \
- GREEN_FROM_ULONG (color) / 255.0f, \
- BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
-#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
- do { \
- if (CGColorGetTypeID != NULL) \
- CGContextSetFillColorWithColor (context, cg_color); \
- else \
- CG_SET_FILL_COLOR (context, color); \
- } while (0)
-#else
-#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
- CGContextSetFillColorWithColor (context, cg_color)
-#endif
-#else
-#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
- CG_SET_FILL_COLOR (context, color)
-#endif
-#define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc) \
- CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
- (gc)->cg_fore_color)
-#define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc) \
- CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.background, \
- (gc)->cg_back_color)
-
-
-#define CG_SET_STROKE_COLOR(context, color) \
- CGContextSetRGBStrokeColor (context, \
- RED_FROM_ULONG (color) / 255.0f, \
- GREEN_FROM_ULONG (color) / 255.0f, \
- BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
-#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
- do { \
- if (CGColorGetTypeID != NULL) \
- CGContextSetStrokeColorWithColor (context, cg_color); \
- else \
- CG_SET_STROKE_COLOR (context, color); \
- } while (0)
-#else
-#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
- CGContextSetStrokeColorWithColor (context, cg_color)
-#endif
-#else
-#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
- CG_SET_STROKE_COLOR (context, color)
-#endif
-#define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, gc) \
- CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
- (gc)->cg_fore_color)
-
-#if USE_CG_DRAWING
-#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
-
-/* Fringe bitmaps. */
-
-static int max_fringe_bmp = 0;
-static CGImageRef *fringe_bmp = 0;
-
-CGColorSpaceRef mac_cg_color_space_rgb;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-static CGColorRef mac_cg_color_black;
-#endif
-
-static void
-init_cg_color ()
-{
- mac_cg_color_space_rgb = CGColorSpaceCreateDeviceRGB ();
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- /* Don't check the availability of CGColorCreate; this symbol is
- defined even in Mac OS X 10.1. */
- if (CGColorGetTypeID != NULL)
-#endif
- {
- CGFloat rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
-
- mac_cg_color_black = CGColorCreate (mac_cg_color_space_rgb, rgba);
- }
-#endif
-}
-
-static CGContextRef
-mac_begin_cg_clip (f, gc)
- struct frame *f;
- GC gc;
-{
- CGContextRef context = FRAME_CG_CONTEXT (f);
-
- if (!context)
- {
- QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
- FRAME_CG_CONTEXT (f) = context;
- }
-
- CGContextSaveGState (context);
- CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f));
- CGContextScaleCTM (context, 1, -1);
- if (gc && gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
-
- return context;
-}
-
-static void
-mac_end_cg_clip (f)
- struct frame *f;
-{
- CGContextRestoreGState (FRAME_CG_CONTEXT (f));
-}
-
-void
-mac_prepare_for_quickdraw (f)
- struct frame *f;
-{
- if (f == NULL)
- {
- Lisp_Object rest, frame;
- FOR_EACH_FRAME (rest, frame)
- if (FRAME_MAC_P (XFRAME (frame)))
- mac_prepare_for_quickdraw (XFRAME (frame));
- }
- else
- {
- CGContextRef context = FRAME_CG_CONTEXT (f);
-
- if (context)
- {
- CGContextSynchronize (context);
- QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)),
- &FRAME_CG_CONTEXT (f));
- }
- }
-}
-#endif
-
-static RgnHandle saved_port_clip_region = NULL;
-
-static void
-mac_begin_clip (f, gc)
- struct frame *f;
- GC gc;
-{
- static RgnHandle new_region = NULL;
-
- if (saved_port_clip_region == NULL)
- saved_port_clip_region = NewRgn ();
- if (new_region == NULL)
- new_region = NewRgn ();
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- if (gc->n_clip_rects)
- {
- GetClip (saved_port_clip_region);
- SectRgn (saved_port_clip_region, gc->clip_region, new_region);
- SetClip (new_region);
- }
-}
-
-static void
-mac_end_clip (gc)
- GC gc;
-{
- if (gc->n_clip_rects)
- SetClip (saved_port_clip_region);
-}
-
-
-/* X display function emulation */
-
-/* Mac version of XDrawLine. */
-
-static void
-mac_draw_line (f, gc, x1, y1, x2, y2)
- struct frame *f;
- GC gc;
- int x1, y1, x2, y2;
-{
-#if USE_CG_DRAWING
- CGContextRef context;
- CGFloat gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
-
- if (y1 != y2)
- gx1 += 0.5f, gx2 += 0.5f;
- if (x1 != x2)
- gy1 += 0.5f, gy2 += 0.5f;
-
- context = mac_begin_cg_clip (f, gc);
- CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextBeginPath (context);
- CGContextMoveToPoint (context, gx1, gy1);
- CGContextAddLineToPoint (context, gx2, gy2);
- CGContextClosePath (context);
- CGContextStrokePath (context);
- mac_end_cg_clip (f);
-#else
- if (x1 == x2)
- {
- if (y1 > y2)
- y1--;
- else if (y2 > y1)
- y2--;
- }
- else if (y1 == y2)
- {
- if (x1 > x2)
- x1--;
- else
- x2--;
- }
-
- mac_begin_clip (f, gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- MoveTo (x1, y1);
- LineTo (x2, y2);
- mac_end_clip (gc);
-#endif
-}
-
-/* Mac version of XDrawLine (to Pixmap). */
-
-void
-XDrawLine (display, p, gc, x1, y1, x2, y2)
- Display *display;
- Pixmap p;
- GC gc;
- int x1, y1, x2, y2;
-{
-#if USE_MAC_IMAGE_IO
- CGContextRef context;
- XImagePtr ximg = p;
- CGColorSpaceRef color_space;
- CGImageAlphaInfo alpha_info;
- CGFloat gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
-
- if (y1 != y2)
- gx1 += 0.5f, gx2 += 0.5f;
- if (x1 != x2)
- gy1 += 0.5f, gy2 += 0.5f;
-
- if (ximg->bits_per_pixel == 32)
- {
- color_space = mac_cg_color_space_rgb;
- alpha_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
- }
- else
- {
- color_space = NULL;
- alpha_info = kCGImageAlphaOnly;
- }
- context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8,
- ximg->bytes_per_line, color_space,
- alpha_info);
- if (ximg->bits_per_pixel == 32)
- CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
- else
- CGContextSetGrayStrokeColor (context, gc->xgcv.foreground / 255.0f, 1.0);
- CGContextMoveToPoint (context, gx1, gy1);
- CGContextAddLineToPoint (context, gx2, gy2);
- CGContextClosePath (context);
- CGContextStrokePath (context);
- CGContextRelease (context);
-#else
- CGrafPtr old_port;
- GDHandle old_gdh;
-
- if (x1 == x2)
- {
- if (y1 > y2)
- y1--;
- else if (y2 > y1)
- y2--;
- }
- else if (y1 == y2)
- {
- if (x1 > x2)
- x1--;
- else
- x2--;
- }
-
- GetGWorld (&old_port, &old_gdh);
- SetGWorld (p, NULL);
-
- RGBForeColor (GC_FORE_COLOR (gc));
-
- LockPixels (GetGWorldPixMap (p));
- MoveTo (x1, y1);
- LineTo (x2, y2);
- UnlockPixels (GetGWorldPixMap (p));
-
- SetGWorld (old_port, old_gdh);
-#endif
-}
-
-
-static void
-mac_erase_rectangle (f, gc, x, y, width, height)
- struct frame *f;
- GC gc;
- int x, y;
- unsigned int width, height;
-{
-#if USE_CG_DRAWING
- {
- CGContextRef context;
-
- context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context, mac_rect_make (f, x, y, width, height));
- mac_end_cg_clip (f);
- }
-#else
- {
- Rect r;
-
- mac_begin_clip (f, gc);
- RGBBackColor (GC_BACK_COLOR (gc));
- SetRect (&r, x, y, x + width, y + height);
- EraseRect (&r);
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- mac_end_clip (gc);
- }
-#endif
-}
-
-
-/* Mac version of XClearArea. */
-
-void
-mac_clear_area (f, x, y, width, height)
- struct frame *f;
- int x, y;
- unsigned int width, height;
-{
- mac_erase_rectangle (f, FRAME_NORMAL_GC (f), x, y, width, height);
-}
-
-/* Mac version of XClearWindow. */
-
-static void
-mac_clear_window (f)
- struct frame *f;
-{
-#if USE_CG_DRAWING
- {
- CGContextRef context;
- GC gc = FRAME_NORMAL_GC (f);
-
- context = mac_begin_cg_clip (f, NULL);
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
- FRAME_PIXEL_HEIGHT (f)));
- mac_end_cg_clip (f);
- }
-#else /* !USE_CG_DRAWING */
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-
-#if TARGET_API_MAC_CARBON
- {
- Rect r;
-
- GetWindowPortBounds (FRAME_MAC_WINDOW (f), &r);
- EraseRect (&r);
- }
-#else /* not TARGET_API_MAC_CARBON */
- EraseRect (&(FRAME_MAC_WINDOW (f)->portRect));
-#endif /* not TARGET_API_MAC_CARBON */
-#endif
-}
-
-
-/* Mac replacement for XCopyArea. */
-
-#if USE_CG_DRAWING
-static void
-mac_draw_cg_image (image, f, gc, src_x, src_y, width, height,
- dest_x, dest_y, overlay_p)
- CGImageRef image;
- struct frame *f;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y, overlay_p;
-{
- CGContextRef context;
- CGFloat port_height = FRAME_PIXEL_HEIGHT (f);
- CGRect dest_rect = mac_rect_make (f, dest_x, dest_y, width, height);
-
- context = mac_begin_cg_clip (f, gc);
- if (!overlay_p)
- {
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context, dest_rect);
- }
- CGContextClipToRect (context, dest_rect);
- CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
- if (CGImageIsMask (image))
- CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextDrawImage (context,
- mac_rect_make (f, dest_x - src_x,
- port_height - (dest_y - src_y
- + CGImageGetHeight (image)),
- CGImageGetWidth (image),
- CGImageGetHeight (image)),
- image);
- mac_end_cg_clip (f);
-}
-
-#else /* !USE_CG_DRAWING */
-
-static void
-mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p)
- struct frame *f;
- GC gc;
- int x, y, width, height;
- unsigned short *bits;
- int overlay_p;
-{
- BitMap bitmap;
- Rect r;
-
- bitmap.rowBytes = sizeof(unsigned short);
- bitmap.baseAddr = (char *)bits;
- SetRect (&(bitmap.bounds), 0, 0, width, height);
-
- mac_begin_clip (f, gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- RGBBackColor (GC_BACK_COLOR (gc));
- SetRect (&r, x, y, x + width, y + height);
-#if TARGET_API_MAC_CARBON
- {
- CGrafPtr port;
-
- GetPort (&port);
- LockPortBits (port);
- CopyBits (&bitmap, GetPortBitMapForCopyBits (port),
- &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0);
- UnlockPortBits (port);
- }
-#else /* not TARGET_API_MAC_CARBON */
- CopyBits (&bitmap, &(FRAME_MAC_WINDOW (f)->portBits), &(bitmap.bounds), &r,
- overlay_p ? srcOr : srcCopy, 0);
-#endif /* not TARGET_API_MAC_CARBON */
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- mac_end_clip (gc);
-}
-#endif /* !USE_CG_DRAWING */
-
-
-/* Mac replacement for XCreateBitmapFromBitmapData. */
-
-static void
-mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
- BitMap *bitmap;
- char *bits;
- int w, h;
-{
- static const unsigned char swap_nibble[16]
- = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
- 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
- 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
- 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
- int i, j, w1;
- char *p;
-
- w1 = (w + 7) / 8; /* nb of 8bits elt in X bitmap */
- bitmap->rowBytes = ((w + 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
- bitmap->baseAddr = xmalloc (bitmap->rowBytes * h);
- bzero (bitmap->baseAddr, bitmap->rowBytes * h);
- for (i = 0; i < h; i++)
- {
- p = bitmap->baseAddr + i * bitmap->rowBytes;
- for (j = 0; j < w1; j++)
- {
- /* Bitswap XBM bytes to match how Mac does things. */
- unsigned char c = *bits++;
- *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
- | (swap_nibble[(c>>4) & 0xf]));
- }
- }
-
- SetRect (&(bitmap->bounds), 0, 0, w, h);
-}
-
-
-static void
-mac_free_bitmap (bitmap)
- BitMap *bitmap;
-{
- xfree (bitmap->baseAddr);
-}
-
-
-Pixmap
-XCreatePixmap (display, w, width, height, depth)
- Display *display;
- Window w;
- unsigned int width, height;
- unsigned int depth;
-{
-#if USE_MAC_IMAGE_IO
- XImagePtr ximg;
-
- ximg = xmalloc (sizeof (*ximg));
- ximg->width = width;
- ximg->height = height;
- ximg->bits_per_pixel = depth == 1 ? 8 : 32;
- ximg->bytes_per_line = width * (ximg->bits_per_pixel / 8);
- ximg->data = xmalloc (ximg->bytes_per_line * height);
- return ximg;
-#else
- Pixmap pixmap;
- Rect r;
- QDErr err;
-
-#ifdef MAC_OS8
- SetPortWindowPort (w);
-#endif
- SetRect (&r, 0, 0, width, height);
-#if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
- if (depth == 1)
-#endif
- err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0);
-#if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
- else
- /* CreateCGImageFromPixMaps requires ARGB format. */
- err = QTNewGWorld (&pixmap, k32ARGBPixelFormat, &r, NULL, NULL, 0);
-#endif
- if (err != noErr)
- return NULL;
- return pixmap;
-#endif
-}
-
-
-Pixmap
-XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
- Display *display;
- Window w;
- char *data;
- unsigned int width, height;
- unsigned long fg, bg;
- unsigned int depth;
-{
- Pixmap pixmap;
- BitMap bitmap;
-#if USE_MAC_IMAGE_IO
- CGDataProviderRef provider;
- CGImageRef image_mask;
- CGContextRef context;
-
- pixmap = XCreatePixmap (display, w, width, height, depth);
- if (pixmap == NULL)
- return NULL;
-
- mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
- provider = CGDataProviderCreateWithData (NULL, bitmap.baseAddr,
- bitmap.rowBytes * height, NULL);
- image_mask = CGImageMaskCreate (width, height, 1, 1, bitmap.rowBytes,
- provider, NULL, 0);
- CGDataProviderRelease (provider);
-
- context = CGBitmapContextCreate (pixmap->data, width, height, 8,
- pixmap->bytes_per_line,
- mac_cg_color_space_rgb,
- kCGImageAlphaNoneSkipFirst
- | kCGBitmapByteOrder32Host);
-
- CG_SET_FILL_COLOR (context, fg);
- CGContextFillRect (context, CGRectMake (0, 0, width, height));
- CG_SET_FILL_COLOR (context, bg);
- CGContextDrawImage (context, CGRectMake (0, 0, width, height), image_mask);
- CGContextRelease (context);
- CGImageRelease (image_mask);
-#else
- CGrafPtr old_port;
- GDHandle old_gdh;
- static GC gc = NULL;
-
- if (gc == NULL)
- gc = XCreateGC (display, w, 0, NULL);
-
- pixmap = XCreatePixmap (display, w, width, height, depth);
- if (pixmap == NULL)
- return NULL;
-
- GetGWorld (&old_port, &old_gdh);
- SetGWorld (pixmap, NULL);
- mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
- XSetForeground (display, gc, fg);
- XSetBackground (display, gc, bg);
- RGBForeColor (GC_FORE_COLOR (gc));
- RGBBackColor (GC_BACK_COLOR (gc));
- LockPixels (GetGWorldPixMap (pixmap));
-#if TARGET_API_MAC_CARBON
- CopyBits (&bitmap, GetPortBitMapForCopyBits (pixmap),
- &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
-#else /* not TARGET_API_MAC_CARBON */
- CopyBits (&bitmap, &(((GrafPtr)pixmap)->portBits),
- &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
-#endif /* not TARGET_API_MAC_CARBON */
- UnlockPixels (GetGWorldPixMap (pixmap));
- SetGWorld (old_port, old_gdh);
-#endif
- mac_free_bitmap (&bitmap);
-
- return pixmap;
-}
-
-
-void
-XFreePixmap (display, pixmap)
- Display *display;
- Pixmap pixmap;
-{
-#if USE_MAC_IMAGE_IO
- if (pixmap)
- {
- xfree (pixmap->data);
- xfree (pixmap);
- }
-#else
- DisposeGWorld (pixmap);
-#endif
-}
-
-
-/* Mac replacement for XFillRectangle. */
-
-static void
-mac_fill_rectangle (f, gc, x, y, width, height)
- struct frame *f;
- GC gc;
- int x, y;
- unsigned int width, height;
-{
-#if USE_CG_DRAWING
- CGContextRef context;
-
- context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextFillRect (context, mac_rect_make (f, x, y, width, height));
- mac_end_cg_clip (f);
-#else
- Rect r;
-
- mac_begin_clip (f, gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- SetRect (&r, x, y, x + width, y + height);
- PaintRect (&r); /* using foreground color of gc */
- mac_end_clip (gc);
-#endif
-}
-
-
-/* Mac replacement for XDrawRectangle: dest is a window. */
-
-static void
-mac_draw_rectangle (f, gc, x, y, width, height)
- struct frame *f;
- GC gc;
- int x, y;
- unsigned int width, height;
-{
-#if USE_CG_DRAWING
- CGContextRef context;
-
- context = mac_begin_cg_clip (f, gc);
- CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextStrokeRect (context,
- CGRectMake (x + 0.5f, y + 0.5f, width, height));
- mac_end_cg_clip (f);
-#else
- Rect r;
-
- mac_begin_clip (f, gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- SetRect (&r, x, y, x + width + 1, y + height + 1);
- FrameRect (&r); /* using foreground color of gc */
- mac_end_clip (gc);
-#endif
-}
-
-
-static void
-mac_invert_rectangle (f, x, y, width, height)
- struct frame *f;
- int x, y;
- unsigned int width, height;
-{
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1020
- if (CGContextSetBlendMode != NULL)
-#endif
- {
- CGContextRef context;
-
- context = mac_begin_cg_clip (f, NULL);
- CGContextSetRGBFillColor (context, 1.0f, 1.0f, 1.0f, 1.0f);
- CGContextSetBlendMode (context, kCGBlendModeDifference);
- CGContextFillRect (context, mac_rect_make (f, x, y, width, height));
- mac_end_cg_clip (f);
- }
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1020
- else /* CGContextSetBlendMode == NULL */
-#endif
-#endif /* USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 */
-#if !USE_CG_DRAWING || MAC_OS_X_VERSION_MAX_ALLOWED < 1040 || (MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1020)
- {
- Rect r;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- SetRect (&r, x, y, x + width, y + height);
-
- InvertRect (&r);
-}
-
-
-#if USE_ATSUI
-static OSStatus
-atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
- ConstUniCharArrayPtr text;
- UniCharCount text_length;
- ATSUStyle style;
- ATSUTextLayout *text_layout;
-{
- OSStatus err;
- static ATSUTextLayout saved_text_layout = NULL;
-
- if (saved_text_layout == NULL)
- {
- static const UniCharCount lengths[] = {kATSUToTextEnd};
- static const ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
- static const ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
- static ATSLineLayoutOptions line_layout =
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
- | kATSLineUseQDRendering
-#else
- kATSLineIsDisplayOnly | kATSLineFractDisable
-#endif
- ;
- static const ATSUAttributeValuePtr values[] = {&line_layout};
-
- err = ATSUCreateTextLayoutWithTextPtr (text,
- kATSUFromTextBeginning,
- kATSUToTextEnd,
- text_length,
- 1, lengths, &style,
- &saved_text_layout);
- if (err == noErr)
- err = ATSUSetLayoutControls (saved_text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
- if (err == noErr)
- err = ATSUSetTransientFontMatching (saved_text_layout, true);
- }
- else
- {
- err = ATSUSetRunStyle (saved_text_layout, style,
- kATSUFromTextBeginning, kATSUToTextEnd);
- if (err == noErr)
- err = ATSUSetTextPointerLocation (saved_text_layout, text,
- kATSUFromTextBeginning,
- kATSUToTextEnd,
- text_length);
- }
-
- if (err == noErr)
- *text_layout = saved_text_layout;
- return err;
-}
-
-
-static void
-mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char)
- struct frame *f;
- GC gc;
- int x, y;
- char *buf;
- int nchars, bg_width, overstrike_p, bytes_per_char;
-{
- OSStatus err;
- ATSUTextLayout text_layout;
-
- xassert (bytes_per_char == 2);
-
-#ifndef WORDS_BIG_ENDIAN
- {
- int i;
- UniChar *text = (UniChar *)buf;
-
- for (i = 0; i < nchars; i++)
- text[i] = EndianU16_BtoN (text[i]);
- }
-#endif
- err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
- nchars,
- GC_FONT (gc)->mac_style,
- &text_layout);
- if (err != noErr)
- return;
-#ifdef MAC_OSX
- if (!mac_use_core_graphics)
- {
-#endif
- mac_begin_clip (f, gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- if (bg_width)
- {
- Rect r;
-
- SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
- x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
- RGBBackColor (GC_BACK_COLOR (gc));
- EraseRect (&r);
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- }
- MoveTo (x, y);
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
- if (overstrike_p)
- {
- MoveTo (x + 1, y);
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
- }
- mac_end_clip (gc);
-#ifdef MAC_OSX
- }
- else
- {
- static CGContextRef context;
- CGFloat port_height = FRAME_PIXEL_HEIGHT (f);
- static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
- static const ByteCount sizes[] = {sizeof (CGContextRef)};
- static const ATSUAttributeValuePtr values[] = {&context};
-
-#if USE_CG_DRAWING
- context = mac_begin_cg_clip (f, gc);
-#else
- CGrafPtr port;
-
- GetPort (&port);
- QDBeginCGContext (port, &context);
- if (gc->n_clip_rects || bg_width)
- {
- CGContextTranslateCTM (context, 0, port_height);
- CGContextScaleCTM (context, 1, -1);
- if (gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects,
- gc->n_clip_rects);
-#endif
- if (bg_width)
- {
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context,
- mac_rect_make (f,
- x, y - FONT_BASE (GC_FONT (gc)),
- bg_width,
- FONT_HEIGHT (GC_FONT (gc))));
- }
- CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
-#if !USE_CG_DRAWING
- }
-#endif
- CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- err = ATSUSetLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
- if (err == noErr)
- {
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- Long2Fix (x), Long2Fix (port_height - y));
- if (overstrike_p)
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- Long2Fix (x + 1), Long2Fix (port_height - y));
- }
-#if USE_CG_DRAWING
- mac_end_cg_clip (f);
- context = NULL;
-#else
- CGContextSynchronize (context);
- QDEndCGContext (port, &context);
-#endif
-#if 0
- /* This doesn't work on Mac OS X 10.1. */
- ATSUClearLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]), tags);
-#else
- ATSUSetLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
-#endif
- }
-#endif /* MAC_OSX */
-}
-#endif /* USE_ATSUI */
-
-
-static void
-mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char)
- struct frame *f;
- GC gc;
- int x, y;
- char *buf;
- int nchars, bg_width, overstrike_p, bytes_per_char;
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- UInt32 savedFlags;
-#endif
-
- mac_begin_clip (f, gc);
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (mac_use_core_graphics)
- savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
-#endif
- RGBForeColor (GC_FORE_COLOR (gc));
-#ifdef MAC_OS8
- if (bg_width)
- {
- RGBBackColor (GC_BACK_COLOR (gc));
- TextMode (srcCopy);
- }
- else
- TextMode (srcOr);
-#else
- /* We prefer not to use srcCopy text transfer mode on Mac OS X
- because:
- - Screen is double-buffered. (In srcCopy mode, a text is drawn
- into an offscreen graphics world first. So performance gain
- cannot be expected.)
- - It lowers rendering quality.
- - Some fonts leave garbage on cursor movement. */
- if (bg_width)
- {
- Rect r;
-
- RGBBackColor (GC_BACK_COLOR (gc));
- SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
- x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
- EraseRect (&r);
- }
- TextMode (srcOr);
-#endif
- TextFont (GC_FONT (gc)->mac_fontnum);
- TextSize (GC_FONT (gc)->mac_fontsize);
- TextFace (GC_FONT (gc)->mac_fontface);
- MoveTo (x, y);
- DrawText (buf, 0, nchars * bytes_per_char);
- if (overstrike_p)
- {
- TextMode (srcOr);
- MoveTo (x + 1, y);
- DrawText (buf, 0, nchars * bytes_per_char);
- }
- if (bg_width)
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- mac_end_clip (gc);
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (mac_use_core_graphics)
- SwapQDTextFlags(savedFlags);
-#endif
-}
-
-
-static INLINE void
-mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char)
- struct frame *f;
- GC gc;
- int x, y;
- char *buf;
- int nchars, bg_width, overstrike_p, bytes_per_char;
-{
-#if USE_ATSUI
- if (GC_FONT (gc)->mac_style)
- mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char);
- else
-#endif /* USE_ATSUI */
- mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char);
-}
-
-
-/* Mac replacement for XDrawImageString. */
-
-static void
-mac_draw_image_string (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
- struct frame *f;
- GC gc;
- int x, y;
- char *buf;
- int nchars, bg_width, overstrike_p;
-{
- mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, 1);
-}
-
-
-/* Mac replacement for XDrawImageString16. */
-
-static void
-mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
- struct frame *f;
- GC gc;
- int x, y;
- XChar2b *buf;
- int nchars, bg_width, overstrike_p;
-{
- mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width,
- overstrike_p, 2);
-}
-
-
-/* Mac replacement for XQueryTextExtents, but takes a character. If
- STYLE is NULL, measurement is done by QuickDraw Text routines for
- the font of the current graphics port. If CG_GLYPH is not NULL,
- *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
-
-static OSStatus
-mac_query_char_extents (style, c,
- font_ascent_return, font_descent_return,
- overall_return, cg_glyph)
-#if USE_ATSUI
- ATSUStyle style;
-#else
- void *style;
-#endif
- int c;
- int *font_ascent_return, *font_descent_return;
- XCharStruct *overall_return;
-#if USE_CG_TEXT_DRAWING
- CGGlyph *cg_glyph;
-#else
- void *cg_glyph;
-#endif
-{
- OSStatus err = noErr;
- int width;
- Rect char_bounds;
-
-#if USE_ATSUI
- if (style)
- {
- ATSUTextLayout text_layout;
- UniChar ch = c;
-
- err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
- if (err == noErr
- && (font_ascent_return || font_descent_return || overall_return))
- {
- ATSTrapezoid glyph_bounds;
-
- err = ATSUGetGlyphBounds (text_layout, 0, 0,
- kATSUFromTextBeginning, kATSUToTextEnd,
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kATSUseFractionalOrigins,
-#else
- kATSUseDeviceOrigins,
-#endif
- 1, &glyph_bounds, NULL);
- if (err == noErr)
- {
- xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
- == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
-
- width = Fix2Long (glyph_bounds.upperRight.x
- - glyph_bounds.upperLeft.x);
- if (font_ascent_return)
- *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y);
- if (font_descent_return)
- *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y);
- }
- }
- if (err == noErr && overall_return)
- {
- err = ATSUMeasureTextImage (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- 0, 0, &char_bounds);
- if (err == noErr)
- STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
-#if USE_CG_TEXT_DRAWING
- if (err == noErr && cg_glyph)
- {
- OSStatus err1;
- ATSUGlyphInfoArray glyph_info_array;
- ByteCount count = sizeof (ATSUGlyphInfoArray);
-
- err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
- kATSUToTextEnd, NULL, NULL, NULL);
- if (err1 == noErr)
- err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
- kATSUToTextEnd, &count,
- &glyph_info_array);
- if (err1 == noErr
- /* Make sure that we don't have to make layout
- adjustments. */
- && glyph_info_array.glyphs[0].deltaY == 0.0f
- && glyph_info_array.glyphs[0].idealX == 0.0f
- && glyph_info_array.glyphs[0].screenX == 0)
- {
- xassert (glyph_info_array.glyphs[0].glyphID);
- *cg_glyph = glyph_info_array.glyphs[0].glyphID;
- }
- else
- *cg_glyph = 0;
- }
-#endif
- }
- }
- else
-#endif
- {
- if (font_ascent_return || font_descent_return)
- {
- FontInfo font_info;
-
- GetFontInfo (&font_info);
- if (font_ascent_return)
- *font_ascent_return = font_info.ascent;
- if (font_descent_return)
- *font_descent_return = font_info.descent;
- }
- if (overall_return)
- {
- char ch = c;
-
- width = CharWidth (ch);
- QDTextBounds (1, &ch, &char_bounds);
- STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
- }
- }
-
- return err;
-}
-
-
-/* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
-
-static int
-mac_text_extents_16 (font_struct, string, nchars, overall_return)
- XFontStruct *font_struct;
- XChar2b *string;
- int nchars;
- XCharStruct *overall_return;
-{
- int i;
- short width = 0, lbearing = 0, rbearing = 0;
- XCharStruct *pcm;
-
- for (i = 0; i < nchars; i++)
- {
- pcm = mac_per_char_metric (font_struct, string, 0);
- if (pcm == NULL)
- width += FONT_WIDTH (font_struct);
- else
- {
- lbearing = min (lbearing, width + pcm->lbearing);
- rbearing = max (rbearing, width + pcm->rbearing);
- width += pcm->width;
- }
- string++;
- }
-
- overall_return->lbearing = lbearing;
- overall_return->rbearing = rbearing;
- overall_return->width = width;
-
- /* What's the meaning of the return value of XTextExtents16? */
-}
-
-
-#if USE_CG_TEXT_DRAWING
-static int cg_text_anti_aliasing_threshold = 8;
-
-static void
-init_cg_text_anti_aliasing_threshold ()
-{
- int threshold;
- Boolean valid_p;
-
- threshold =
- CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
- kCFPreferencesCurrentApplication,
- &valid_p);
- if (valid_p)
- cg_text_anti_aliasing_threshold = threshold;
-}
-
-static int
-mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
- struct frame *f;
- GC gc;
- int x, y;
- XChar2b *buf;
- int nchars, bg_width, overstrike_p;
-{
- CGFloat port_height, gx, gy;
- int i;
- CGContextRef context;
- CGGlyph *glyphs;
- CGSize *advances;
-
- if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL)
- return 0;
-
- port_height = FRAME_PIXEL_HEIGHT (f);
- gx = x;
- gy = port_height - y;
- glyphs = (CGGlyph *)buf;
- advances = alloca (sizeof (CGSize) * nchars);
- if (advances == NULL)
- return 0;
- for (i = 0; i < nchars; i++)
- {
- XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
-
- advances[i].width = pcm->width;
- advances[i].height = 0;
- glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2];
- buf++;
- }
-
-#if USE_CG_DRAWING
- context = mac_begin_cg_clip (f, gc);
-#else
- QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
- if (gc->n_clip_rects || bg_width)
- {
- CGContextTranslateCTM (context, 0, port_height);
- CGContextScaleCTM (context, 1, -1);
- if (gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
-#endif
- if (bg_width)
- {
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect
- (context,
- mac_rect_make (f, gx, y - FONT_BASE (GC_FONT (gc)),
- bg_width, FONT_HEIGHT (GC_FONT (gc))));
- }
- CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
-#if !USE_CG_DRAWING
- }
-#endif
- CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextSetFont (context, GC_FONT (gc)->cg_font);
- CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize);
- if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold)
- CGContextSetShouldAntialias (context, false);
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGContextShowGlyphsWithAdvances != NULL)
-#endif
- {
- CGContextSetTextPosition (context, gx, gy);
- CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
- if (overstrike_p)
- {
- CGContextSetTextPosition (context, gx + 1.0f, gy);
- CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
- }
- }
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else /* CGContextShowGlyphsWithAdvances == NULL */
-#endif
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- {
- for (i = 0; i < nchars; i++)
- {
- CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
- if (overstrike_p)
- CGContextShowGlyphsAtPoint (context, gx + 1.0f, gy, glyphs + i, 1);
- gx += advances[i].width;
- }
- }
-#endif
-#if USE_CG_DRAWING
- mac_end_cg_clip (f);
-#else
- CGContextSynchronize (context);
- QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
-#endif
-
- return 1;
-}
-#endif
-
-
-#if !USE_CG_DRAWING
-/* Mac replacement for XCopyArea: dest must be window. */
-
-static void
-mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
- Pixmap src;
- struct frame *f;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y;
-{
- Rect src_r, dest_r;
-
- mac_begin_clip (f, gc);
-
- SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
- SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
-
- ForeColor (blackColor);
- BackColor (whiteColor);
-
- LockPixels (GetGWorldPixMap (src));
-#if TARGET_API_MAC_CARBON
- {
- CGrafPtr port;
-
- GetPort (&port);
- LockPortBits (port);
- CopyBits (GetPortBitMapForCopyBits (src),
- GetPortBitMapForCopyBits (port),
- &src_r, &dest_r, srcCopy, 0);
- UnlockPortBits (port);
- }
-#else /* not TARGET_API_MAC_CARBON */
- CopyBits (&(((GrafPtr)src)->portBits), &(FRAME_MAC_WINDOW (f)->portBits),
- &src_r, &dest_r, srcCopy, 0);
-#endif /* not TARGET_API_MAC_CARBON */
- UnlockPixels (GetGWorldPixMap (src));
-
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-
- mac_end_clip (gc);
-}
-
-
-static void
-mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
- width, height, dest_x, dest_y)
- Pixmap src, mask;
- struct frame *f;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y;
-{
- Rect src_r, dest_r;
-
- mac_begin_clip (f, gc);
-
- SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
- SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
-
- ForeColor (blackColor);
- BackColor (whiteColor);
-
- LockPixels (GetGWorldPixMap (src));
- LockPixels (GetGWorldPixMap (mask));
-#if TARGET_API_MAC_CARBON
- {
- CGrafPtr port;
-
- GetPort (&port);
- LockPortBits (port);
- CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
- GetPortBitMapForCopyBits (port),
- &src_r, &src_r, &dest_r);
- UnlockPortBits (port);
- }
-#else /* not TARGET_API_MAC_CARBON */
- CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
- &(FRAME_MAC_WINDOW (f)->portBits), &src_r, &src_r, &dest_r);
-#endif /* not TARGET_API_MAC_CARBON */
- UnlockPixels (GetGWorldPixMap (mask));
- UnlockPixels (GetGWorldPixMap (src));
-
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-
- mac_end_clip (gc);
-}
-#endif /* !USE_CG_DRAWING */
-
-
-/* Mac replacement for XCopyArea: used only for scrolling. */
-
-static void
-mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
- struct frame *f;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y;
-{
-#if TARGET_API_MAC_CARBON
- Rect src_r;
- RgnHandle dummy = NewRgn (); /* For avoiding update events. */
-
- SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- ScrollWindowRect (FRAME_MAC_WINDOW (f),
- &src_r, dest_x - src_x, dest_y - src_y,
- kScrollWindowNoOptions, dummy);
- DisposeRgn (dummy);
-#else /* not TARGET_API_MAC_CARBON */
- Rect src_r, dest_r;
- WindowRef w = FRAME_MAC_WINDOW (f);
-
- mac_begin_clip (f, gc);
-
- SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
- SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
-
- /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
- color mapping in CopyBits. Otherwise, it will be slow. */
- ForeColor (blackColor);
- BackColor (whiteColor);
- CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
-
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-
- mac_end_clip (gc);
-#endif /* not TARGET_API_MAC_CARBON */
-}
-
-
-/* Mac replacement for XChangeGC. */
-
-static void
-XChangeGC (display, gc, mask, xgcv)
- Display *display;
- GC gc;
- unsigned long mask;
- XGCValues *xgcv;
-{
- if (mask & GCForeground)
- XSetForeground (display, gc, xgcv->foreground);
- if (mask & GCBackground)
- XSetBackground (display, gc, xgcv->background);
- if (mask & GCFont)
- XSetFont (display, gc, xgcv->font);
-}
-
-
-/* Mac replacement for XCreateGC. */
-
-GC
-XCreateGC (display, d, mask, xgcv)
- Display *display;
- void *d;
- unsigned long mask;
- XGCValues *xgcv;
-{
- GC gc = xmalloc (sizeof (*gc));
-
- bzero (gc, sizeof (*gc));
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGColorGetTypeID != NULL)
-#endif
- {
- gc->cg_fore_color = gc->cg_back_color = mac_cg_color_black;
- CGColorRetain (gc->cg_fore_color);
- CGColorRetain (gc->cg_back_color);
- }
-#endif
- XChangeGC (display, gc, mask, xgcv);
-
- return gc;
-}
-
-
-/* Used in xfaces.c. */
-
-void
-XFreeGC (display, gc)
- Display *display;
- GC gc;
-{
- if (gc->clip_region)
- DisposeRgn (gc->clip_region);
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGColorGetTypeID != NULL)
-#endif
- {
- CGColorRelease (gc->cg_fore_color);
- CGColorRelease (gc->cg_back_color);
- }
-#endif
- xfree (gc);
-}
-
-
-/* Mac replacement for XGetGCValues. */
-
-static void
-XGetGCValues (display, gc, mask, xgcv)
- Display *display;
- GC gc;
- unsigned long mask;
- XGCValues *xgcv;
-{
- if (mask & GCForeground)
- xgcv->foreground = gc->xgcv.foreground;
- if (mask & GCBackground)
- xgcv->background = gc->xgcv.background;
- if (mask & GCFont)
- xgcv->font = gc->xgcv.font;
-}
-
-
-/* Mac replacement for XSetForeground. */
-
-void
-XSetForeground (display, gc, color)
- Display *display;
- GC gc;
- unsigned long color;
-{
- if (gc->xgcv.foreground != color)
- {
- gc->xgcv.foreground = color;
- gc->fore_color.red = RED16_FROM_ULONG (color);
- gc->fore_color.green = GREEN16_FROM_ULONG (color);
- gc->fore_color.blue = BLUE16_FROM_ULONG (color);
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGColorGetTypeID != NULL)
-#endif
- {
- CGColorRelease (gc->cg_fore_color);
- if (color == 0)
- {
- gc->cg_fore_color = mac_cg_color_black;
- CGColorRetain (gc->cg_fore_color);
- }
- else
- {
- CGFloat rgba[4];
-
- rgba[0] = gc->fore_color.red / 65535.0f;
- rgba[1] = gc->fore_color.green / 65535.0f;
- rgba[2] = gc->fore_color.blue / 65535.0f;
- rgba[3] = 1.0f;
- gc->cg_fore_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
- }
- }
-#endif
- }
-}
-
-
-/* Mac replacement for XSetBackground. */
-
-void
-XSetBackground (display, gc, color)
- Display *display;
- GC gc;
- unsigned long color;
-{
- if (gc->xgcv.background != color)
- {
- gc->xgcv.background = color;
- gc->back_color.red = RED16_FROM_ULONG (color);
- gc->back_color.green = GREEN16_FROM_ULONG (color);
- gc->back_color.blue = BLUE16_FROM_ULONG (color);
-#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGColorGetTypeID != NULL)
-#endif
- {
- CGColorRelease (gc->cg_back_color);
- if (color == 0)
- {
- gc->cg_back_color = mac_cg_color_black;
- CGColorRetain (gc->cg_back_color);
- }
- else
- {
- CGFloat rgba[4];
-
- rgba[0] = gc->back_color.red / 65535.0f;
- rgba[1] = gc->back_color.green / 65535.0f;
- rgba[2] = gc->back_color.blue / 65535.0f;
- rgba[3] = 1.0f;
- gc->cg_back_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
- }
- }
-#endif
- }
-}
-
-
-/* Mac replacement for XSetFont. */
-
-static void
-XSetFont (display, gc, font)
- Display *display;
- GC gc;
- XFontStruct *font;
-{
- gc->xgcv.font = font;
-}
-
-
-/* Mac replacement for XSetClipRectangles. */
-
-static void
-mac_set_clip_rectangles (f, gc, rectangles, n)
- struct frame *f;
- GC gc;
- Rect *rectangles;
- int n;
-{
- int i;
-
- xassert (n >= 0 && n <= MAX_CLIP_RECTS);
-
- gc->n_clip_rects = n;
- if (n > 0)
- {
- if (gc->clip_region == NULL)
- gc->clip_region = NewRgn ();
- RectRgn (gc->clip_region, rectangles);
- if (n > 1)
- {
- RgnHandle region = NewRgn ();
-
- for (i = 1; i < n; i++)
- {
- RectRgn (region, rectangles + i);
- UnionRgn (gc->clip_region, region, gc->clip_region);
- }
- DisposeRgn (region);
- }
- }
-#if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING)
- for (i = 0; i < n; i++)
- {
- Rect *rect = rectangles + i;
-
- gc->clip_rects[i] = mac_rect_make (f, rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top);
- }
-#endif
-}
-
-
-/* Mac replacement for XSetClipMask. */
-
-static INLINE void
-mac_reset_clip_rectangles (f, gc)
- struct frame *f;
- GC gc;
-{
- gc->n_clip_rects = 0;
-}
-
-
-/* Mac replacement for XSetWindowBackground. */
-
-void
-XSetWindowBackground (display, w, color)
- Display *display;
- WindowRef w;
- unsigned long color;
-{
-#if !TARGET_API_MAC_CARBON
- AuxWinHandle aw_handle;
- CTabHandle ctab_handle;
- ColorSpecPtr ct_table;
- short ct_size;
-#endif
- RGBColor bg_color;
-
- bg_color.red = RED16_FROM_ULONG (color);
- bg_color.green = GREEN16_FROM_ULONG (color);
- bg_color.blue = BLUE16_FROM_ULONG (color);
-
-#if TARGET_API_MAC_CARBON
- SetWindowContentColor (w, &bg_color);
-#else
- if (GetAuxWin (w, &aw_handle))
- {
- ctab_handle = (*aw_handle)->awCTable;
- HandToHand ((Handle *) &ctab_handle);
- ct_table = (*ctab_handle)->ctTable;
- ct_size = (*ctab_handle)->ctSize;
- while (ct_size > -1)
- {
- if (ct_table->value == 0)
- {
- ct_table->rgb = bg_color;
- CTabChanged (ctab_handle);
- SetWinColor (w, (WCTabHandle) ctab_handle);
- }
- ct_size--;
- }
- }
-#endif
-}
-
-/* Flush display of frame F, or of all frames if F is null. */
-
-static void
-x_flush (f)
- struct frame *f;
-{
-#if TARGET_API_MAC_CARBON
- BLOCK_INPUT;
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- if (f)
- QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL);
- else
- QDFlushPortBuffer (GetQDGlobalsThePort (), NULL);
- UNBLOCK_INPUT;
-#endif
-}
-
-
-/* Remove calls to XFlush by defining XFlush to an empty replacement.
- Calls to XFlush should be unnecessary because the X output buffer
- is flushed automatically as needed by calls to XPending,
- XNextEvent, or XWindowEvent according to the XFlush man page.
- XTread_socket calls XPending. Removing XFlush improves
- performance. */
-
-#define XFlush(DISPLAY) (void) 0
-
-#if USE_CG_DRAWING
-static void
-mac_flush_display_optional (f)
- struct frame *f;
-{
- BLOCK_INPUT;
- mac_prepare_for_quickdraw (f);
- UNBLOCK_INPUT;
-}
-#endif
-
-/***********************************************************************
- Starting and ending an update
- ***********************************************************************/
-
-/* Start an update of frame F. This function is installed as a hook
- for update_begin, i.e. it is called when update_begin is called.
- This function is called prior to calls to x_update_window_begin for
- each window being updated. */
-
-static void
-x_update_begin (f)
- struct frame *f;
-{
-#if TARGET_API_MAC_CARBON
- /* During update of a frame, availability of input events is
- periodically checked with ReceiveNextEvent if
- redisplay-dont-pause is nil. That normally flushes window buffer
- changes for every check, and thus screen update looks waving even
- if no input is available. So we disable screen updates during
- update of a frame. */
- BLOCK_INPUT;
- DisableScreenUpdates ();
- UNBLOCK_INPUT;
-#endif
-}
-
-
-/* Start update of window W. Set the global variable updated_window
- to the window being updated and set output_cursor to the cursor
- position of W. */
-
-static void
-x_update_window_begin (w)
- struct window *w;
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct mac_display_info *display_info = FRAME_MAC_DISPLAY_INFO (f);
-
- updated_window = w;
- set_output_cursor (&w->cursor);
-
- BLOCK_INPUT;
-
- if (f == display_info->mouse_face_mouse_frame)
- {
- /* Don't do highlighting for mouse motion during the update. */
- display_info->mouse_face_defer = 1;
-
- /* If F needs to be redrawn, simply forget about any prior mouse
- highlighting. */
- if (FRAME_GARBAGED_P (f))
- display_info->mouse_face_window = Qnil;
-
-#if 0 /* Rows in a current matrix containing glyphs in mouse-face have
- their mouse_face_p flag set, which means that they are always
- unequal to rows in a desired matrix which never have that
- flag set. So, rows containing mouse-face glyphs are never
- scrolled, and we don't have to switch the mouse highlight off
- here to prevent it from being scrolled. */
-
- /* Can we tell that this update does not affect the window
- where the mouse highlight is? If so, no need to turn off.
- Likewise, don't do anything if the frame is garbaged;
- in that case, the frame's current matrix that we would use
- is all wrong, and we will redisplay that line anyway. */
- if (!NILP (display_info->mouse_face_window)
- && w == XWINDOW (display_info->mouse_face_window))
- {
- int i;
-
- for (i = 0; i < w->desired_matrix->nrows; ++i)
- if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
- break;
-
- if (i < w->desired_matrix->nrows)
- clear_mouse_face (display_info);
- }
-#endif /* 0 */
- }
-
- UNBLOCK_INPUT;
-}
-
-
-/* Draw a vertical window border from (x,y0) to (x,y1) */
-
-static void
-mac_draw_vertical_window_border (w, x, y0, y1)
- struct window *w;
- int x, y0, y1;
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct face *face;
-
- face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID);
- if (face)
- XSetForeground (FRAME_MAC_DISPLAY (f), f->output_data.mac->normal_gc,
- face->foreground);
-
- mac_draw_line (f, f->output_data.mac->normal_gc, x, y0, x, y1);
-}
-
-/* End update of window W (which is equal to updated_window).
-
- Draw vertical borders between horizontally adjacent windows, and
- display W's cursor if CURSOR_ON_P is non-zero.
-
- MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
- glyphs in mouse-face were overwritten. In that case we have to
- make sure that the mouse-highlight is properly redrawn.
-
- W may be a menu bar pseudo-window in case we don't have X toolkit
- support. Such windows don't have a cursor, so don't display it
- here. */
-
-static void
-x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
- struct window *w;
- int cursor_on_p, mouse_face_overwritten_p;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (XFRAME (w->frame));
-
- if (!w->pseudo_window_p)
- {
- BLOCK_INPUT;
-
- if (cursor_on_p)
- display_and_set_cursor (w, 1, output_cursor.hpos,
- output_cursor.vpos,
- output_cursor.x, output_cursor.y);
-
- if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
-
- UNBLOCK_INPUT;
- }
-
- /* If a row with mouse-face was overwritten, arrange for
- XTframe_up_to_date to redisplay the mouse highlight. */
- if (mouse_face_overwritten_p)
- {
- dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
- dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
- dpyinfo->mouse_face_window = Qnil;
- }
-
- updated_window = NULL;
-}
-
-
-/* End update of frame F. This function is installed as a hook in
- update_end. */
-
-static void
-x_update_end (f)
- struct frame *f;
-{
- /* Mouse highlight may be displayed again. */
- FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
-
- BLOCK_INPUT;
-#if TARGET_API_MAC_CARBON
- EnableScreenUpdates ();
-#endif
- XFlush (FRAME_MAC_DISPLAY (f));
- UNBLOCK_INPUT;
-}
-
-
-/* This function is called from various places in xdisp.c whenever a
- complete update has been performed. The global variable
- updated_window is not available here. */
-
-static void
-XTframe_up_to_date (f)
- struct frame *f;
-{
- if (FRAME_MAC_P (f))
- {
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- if (dpyinfo->mouse_face_deferred_gc
- || f == dpyinfo->mouse_face_mouse_frame)
- {
- BLOCK_INPUT;
- if (dpyinfo->mouse_face_mouse_frame)
- note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
- dpyinfo->mouse_face_mouse_x,
- dpyinfo->mouse_face_mouse_y);
- dpyinfo->mouse_face_deferred_gc = 0;
- UNBLOCK_INPUT;
- }
- }
-}
-
-
-/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
- arrow bitmaps, or clear the fringes if no bitmaps are required
- before DESIRED_ROW is made current. The window being updated is
- found in updated_window. This function is called from
- update_window_line only if it is known that there are differences
- between bitmaps to be drawn between current row and DESIRED_ROW. */
-
-static void
-x_after_update_window_line (desired_row)
- struct glyph_row *desired_row;
-{
- struct window *w = updated_window;
- struct frame *f;
- int width, height;
-
- xassert (w);
-
- if (!desired_row->mode_line_p && !w->pseudo_window_p)
- desired_row->redraw_fringe_bitmaps_p = 1;
-
- /* When a window has disappeared, make sure that no rest of
- full-width rows stays visible in the internal border. Could
- check here if updated_window is the leftmost/rightmost window,
- but I guess it's not worth doing since vertically split windows
- are almost never used, internal border is rarely set, and the
- overhead is very small. */
- if (windows_or_buffers_changed
- && desired_row->full_width_p
- && (f = XFRAME (w->frame),
- width = FRAME_INTERNAL_BORDER_WIDTH (f),
- width != 0)
- && (height = desired_row->visible_height,
- height > 0))
- {
- int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
-
- /* Internal border is drawn below the tool bar. */
- if (WINDOWP (f->tool_bar_window)
- && w == XWINDOW (f->tool_bar_window))
- y -= width;
-
- BLOCK_INPUT;
- mac_clear_area (f, 0, y, width, height);
- mac_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
- UNBLOCK_INPUT;
- }
-}
-
-
-/* Draw the bitmap WHICH in one of the left or right fringes of
- window W. ROW is the glyph row for which to display the bitmap; it
- determines the vertical position at which the bitmap has to be
- drawn. */
-
-static void
-x_draw_fringe_bitmap (w, row, p)
- struct window *w;
- struct glyph_row *row;
- struct draw_fringe_bitmap_params *p;
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- Display *display = FRAME_MAC_DISPLAY (f);
- struct face *face = p->face;
- int rowY;
- int overlay_p = p->overlay_p;
-
-#ifdef MAC_OSX
- if (!overlay_p)
- {
- int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
-
-#if 0 /* MAC_TODO: stipple */
- /* In case the same realized face is used for fringes and
- for something displayed in the text (e.g. face `region' on
- mono-displays, the fill style may have been changed to
- FillSolid in x_draw_glyph_string_background. */
- if (face->stipple)
- XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
- else
- XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
-#endif
-
- /* If the fringe is adjacent to the left (right) scroll bar of a
- leftmost (rightmost, respectively) window, then extend its
- background to the gap between the fringe and the bar. */
- if ((WINDOW_LEFTMOST_P (w)
- && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
- || (WINDOW_RIGHTMOST_P (w)
- && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
- {
- int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
-
- if (sb_width > 0)
- {
- int left = WINDOW_SCROLL_BAR_AREA_X (w);
- int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
-
- if (bx < 0
- && (left + width == p->x
- || p->x + p->wd == left))
- {
- /* Bitmap fills the fringe and we need background
- extension. */
- int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
-
- bx = p->x;
- nx = p->wd;
- by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
- row->y));
- ny = row->visible_height;
- }
-
- if (bx >= 0)
- {
- if (left + width == bx)
- {
- bx = left + sb_width;
- nx += width - sb_width;
- }
- else if (bx + nx == left)
- nx += width - sb_width;
- }
- }
- }
-
- if (bx >= 0)
- {
- mac_erase_rectangle (f, face->gc, bx, by, nx, ny);
- /* The fringe background has already been filled. */
- overlay_p = 1;
- }
-
-#if 0 /* MAC_TODO: stipple */
- if (!face->stipple)
- XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
-#endif
- }
-#endif /* MAC_OSX */
-
- /* Must clip because of partially visible lines. */
- rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
- if (p->y < rowY)
- {
- /* Adjust position of "bottom aligned" bitmap on partially
- visible last row. */
- int oldY = row->y;
- int oldVH = row->visible_height;
- row->visible_height = p->h;
- row->y -= rowY - p->y;
- x_clip_to_row (w, row, -1, face->gc);
- row->y = oldY;
- row->visible_height = oldVH;
- }
- else
- x_clip_to_row (w, row, -1, face->gc);
-
-#ifndef MAC_OSX
- if (p->bx >= 0 && !p->overlay_p)
- {
-#if 0 /* MAC_TODO: stipple */
- /* In case the same realized face is used for fringes and
- for something displayed in the text (e.g. face `region' on
- mono-displays, the fill style may have been changed to
- FillSolid in x_draw_glyph_string_background. */
- if (face->stipple)
- XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
- else
- XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
-#endif
-
- mac_erase_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
-
-#if 0 /* MAC_TODO: stipple */
- if (!face->stipple)
- XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
-#endif
- }
-#endif /* !MAC_OSX */
-
- if (p->which
-#if USE_CG_DRAWING
- && p->which < max_fringe_bmp
-#endif
- )
- {
- XGCValues gcv;
-
- XGetGCValues (display, face->gc, GCForeground, &gcv);
- XSetForeground (display, face->gc,
- (p->cursor_p
- ? (p->overlay_p ? face->background
- : f->output_data.mac->cursor_pixel)
- : face->foreground));
-#if USE_CG_DRAWING
- mac_draw_cg_image (fringe_bmp[p->which], f, face->gc, 0, p->dh,
- p->wd, p->h, p->x, p->y, overlay_p);
-#else
- mac_draw_bitmap (f, face->gc, p->x, p->y,
- p->wd, p->h, p->bits + p->dh, overlay_p);
-#endif
- XSetForeground (display, face->gc, gcv.foreground);
- }
-
- mac_reset_clip_rectangles (f, face->gc);
-}
-
-#if USE_CG_DRAWING
-static void
-mac_define_fringe_bitmap (which, bits, h, wd)
- int which;
- unsigned short *bits;
- int h, wd;
-{
- int i;
- CGDataProviderRef provider;
-
- if (which >= max_fringe_bmp)
- {
- i = max_fringe_bmp;
- max_fringe_bmp = which + 20;
- fringe_bmp = (CGImageRef *) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (CGImageRef));
- while (i < max_fringe_bmp)
- fringe_bmp[i++] = 0;
- }
-
- for (i = 0; i < h; i++)
- bits[i] = ~bits[i];
-
- BLOCK_INPUT;
-
- provider = CGDataProviderCreateWithData (NULL, bits,
- sizeof (unsigned short) * h, NULL);
- if (provider)
- {
- fringe_bmp[which] = CGImageMaskCreate (wd, h, 1, 1,
- sizeof (unsigned short),
- provider, NULL, 0);
- CGDataProviderRelease (provider);
- }
-
- UNBLOCK_INPUT;
-}
-
-static void
-mac_destroy_fringe_bitmap (which)
- int which;
-{
- if (which >= max_fringe_bmp)
- return;
-
- if (fringe_bmp[which])
- {
- BLOCK_INPUT;
- CGImageRelease (fringe_bmp[which]);
- UNBLOCK_INPUT;
- }
- fringe_bmp[which] = 0;
-}
-#endif
-
-
-/* This is called when starting Emacs and when restarting after
- suspend. When starting Emacs, no window is mapped. And nothing
- must be done to Emacs's own window if it is suspended (though that
- rarely happens). */
-
-static void
-XTset_terminal_modes (struct terminal *t)
-{
-}
-
-/* This is called when exiting or suspending Emacs. Exiting will make
- the windows go away, and suspending requires no action. */
-
-static void
-XTreset_terminal_modes (struct terminal *t)
-{
-}
-
-
-
-/***********************************************************************
- Display Iterator
- ***********************************************************************/
-
-/* Function prototypes of this page. */
-
-static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
-static int mac_encode_char P_ ((int, XChar2b *, struct font_info *,
- struct charset *, int *));
-
-
-static void
-pcm_init (pcm, count)
- XCharStruct *pcm;
- int count;
-{
- bzero (pcm, sizeof (XCharStruct) * count);
- while (--count >= 0)
- {
- pcm->descent = PCM_INVALID;
- pcm++;
- }
-}
-
-static enum pcm_status
-pcm_get_status (pcm)
- const XCharStruct *pcm;
-{
- int height = pcm->ascent + pcm->descent;
-
- /* Negative height means some special status. */
- return height >= 0 ? PCM_VALID : height;
-}
-
-/* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
- is not contained in the font. */
-
-static INLINE XCharStruct *
-x_per_char_metric (font, char2b)
- XFontStruct *font;
- XChar2b *char2b;
-{
- /* The result metric information. */
- XCharStruct *pcm = NULL;
-
- xassert (font && char2b);
-
-#if USE_ATSUI
- if (font->mac_style)
- {
- XCharStruct **row = font->bounds.rows + char2b->byte1;
-
- if (*row == NULL)
- {
- *row = xmalloc (sizeof (XCharStruct) * 0x100);
- pcm_init (*row, 0x100);
- }
- pcm = *row + char2b->byte2;
- if (pcm_get_status (pcm) != PCM_VALID)
- {
- BLOCK_INPUT;
- mac_query_char_extents (font->mac_style,
- (char2b->byte1 << 8) + char2b->byte2,
- NULL, NULL, pcm, NULL);
- UNBLOCK_INPUT;
- }
- }
- else
- {
-#endif
- if (font->bounds.per_char != NULL)
- {
- if (font->min_byte1 == 0 && font->max_byte1 == 0)
- {
- /* min_char_or_byte2 specifies the linear character index
- corresponding to the first element of the per_char array,
- max_char_or_byte2 is the index of the last character. A
- character with non-zero CHAR2B->byte1 is not in the font.
- A character with byte2 less than min_char_or_byte2 or
- greater max_char_or_byte2 is not in the font. */
- if (char2b->byte1 == 0
- && char2b->byte2 >= font->min_char_or_byte2
- && char2b->byte2 <= font->max_char_or_byte2)
- pcm = font->bounds.per_char
- + (char2b->byte2 - font->min_char_or_byte2);
- }
- else
- {
- /* If either min_byte1 or max_byte1 are nonzero, both
- min_char_or_byte2 and max_char_or_byte2 are less than
- 256, and the 2-byte character index values corresponding
- to the per_char array element N (counting from 0) are:
-
- byte1 = N/D + min_byte1
- byte2 = N\D + min_char_or_byte2
-
- where:
-
- D = max_char_or_byte2 - min_char_or_byte2 + 1
- / = integer division
- \ = integer modulus */
- if (char2b->byte1 >= font->min_byte1
- && char2b->byte1 <= font->max_byte1
- && char2b->byte2 >= font->min_char_or_byte2
- && char2b->byte2 <= font->max_char_or_byte2)
- {
- pcm = (font->bounds.per_char
- + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
- * (char2b->byte1 - font->min_byte1))
- + (char2b->byte2 - font->min_char_or_byte2));
- }
- }
- }
- else
- {
- /* If the per_char pointer is null, all glyphs between the first
- and last character indexes inclusive have the same
- information, as given by both min_bounds and max_bounds. */
- if (char2b->byte2 >= font->min_char_or_byte2
- && char2b->byte2 <= font->max_char_or_byte2)
- pcm = &font->max_bounds;
- }
-#if USE_ATSUI
- }
-#endif
-
- return ((pcm == NULL
- || (pcm->width == 0
-#if 0 /* Show hollow boxes for zero-width glyphs such as combining diacritics. */
- && (pcm->rbearing - pcm->lbearing) == 0
-#endif
- ))
- ? NULL : pcm);
-}
-
-/* RIF:
- */
-
-static XCharStruct *
-mac_per_char_metric (font, char2b, font_type)
- XFontStruct *font;
- XChar2b *char2b;
- int font_type;
-{
- return x_per_char_metric (font, char2b);
-}
-
-/* RIF:
- Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
- the two-byte form of C. Encoding is returned in *CHAR2B. */
-
-static int
-mac_encode_char (c, char2b, font_info, charset, two_byte_p)
- int c;
- XChar2b *char2b;
- struct font_info *font_info;
- struct charset *charset;
- int *two_byte_p;
-{
- XFontStruct *font = font_info->font;
-
- /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
- This may be either a program in a special encoder language or a
- fixed encoding. */
- if (font_info->font_encoder)
- {
- /* It's a program. */
- struct ccl_program *ccl = font_info->font_encoder;
-
- check_ccl_update (ccl);
- if (CHARSET_DIMENSION (charset) == 1)
- {
- ccl->reg[0] = CHARSET_ID (charset);
- ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
- ccl->reg[2] = -1;
- }
- else
- {
- ccl->reg[0] = CHARSET_ID (charset);
- ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
- ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
- }
-
- ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
-
- /* We assume that MSBs are appropriately set/reset by CCL
- program. */
- if (font->max_byte1 == 0) /* 1-byte font */
- STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
- else
- STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
- }
- else if (font_info->encoding_type)
- {
- /* Fixed encoding scheme. See fontset.h for the meaning of the
- encoding numbers. */
- unsigned char enc = font_info->encoding_type;
-
- if ((enc == 1 || enc == 2)
- && CHARSET_DIMENSION (charset) == 2)
- char2b->byte1 |= 0x80;
-
- if (enc == 1 || enc == 3)
- char2b->byte2 |= 0x80;
-
- if (enc == 4)
- {
- int code = (char2b->byte1 << 8) | char2b->byte2;
-
- JIS_TO_SJIS (code);
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- }
- }
-
- if (two_byte_p)
- *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
-
- return FONT_TYPE_UNKNOWN;
-}
-
-
-
-/***********************************************************************
- Glyph display
- ***********************************************************************/
-
-
-
-static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
-static void x_set_glyph_string_gc P_ ((struct glyph_string *));
-static void x_draw_glyph_string_background P_ ((struct glyph_string *,
- int));
-static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
-static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
-static void x_draw_glyph_string_box P_ ((struct glyph_string *));
-static void x_draw_glyph_string P_ ((struct glyph_string *));
-static void mac_compute_glyph_string_overhangs P_ ((struct glyph_string *));
-static void x_set_cursor_gc P_ ((struct glyph_string *));
-static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
-static void x_set_mouse_face_gc P_ ((struct glyph_string *));
-/*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
- unsigned long *, double, int));*/
-static void x_setup_relief_color P_ ((struct frame *, struct relief *,
- double, int, unsigned long));
-static void x_setup_relief_colors P_ ((struct glyph_string *));
-static void x_draw_image_glyph_string P_ ((struct glyph_string *));
-static void x_draw_image_relief P_ ((struct glyph_string *));
-static void x_draw_image_foreground P_ ((struct glyph_string *));
-static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
- int, int, int));
-static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
- int, int, int, int, int, int,
- Rect *));
-static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
- int, int, int, Rect *));
-
-#if GLYPH_DEBUG
-static void x_check_font P_ ((struct frame *, XFontStruct *));
-#endif
-
-
-/* Set S->gc to a suitable GC for drawing glyph string S in cursor
- face. */
-
-static void
-x_set_cursor_gc (s)
- struct glyph_string *s;
-{
- if (s->font == FRAME_FONT (s->f)
- && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
- && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
- && !s->cmp)
- s->gc = s->f->output_data.mac->cursor_gc;
- else
- {
- /* Cursor on non-default face: must merge. */
- XGCValues xgcv;
- unsigned long mask;
-
- xgcv.background = s->f->output_data.mac->cursor_pixel;
- xgcv.foreground = s->face->background;
-
- /* If the glyph would be invisible, try a different foreground. */
- if (xgcv.foreground == xgcv.background)
- xgcv.foreground = s->face->foreground;
- if (xgcv.foreground == xgcv.background)
- xgcv.foreground = s->f->output_data.mac->cursor_foreground_pixel;
- if (xgcv.foreground == xgcv.background)
- xgcv.foreground = s->face->foreground;
-
- /* Make sure the cursor is distinct from text in this face. */
- if (xgcv.background == s->face->background
- && xgcv.foreground == s->face->foreground)
- {
- xgcv.background = s->face->foreground;
- xgcv.foreground = s->face->background;
- }
-
- IF_DEBUG (x_check_font (s->f, s->font));
- xgcv.font = s->font;
- mask = GCForeground | GCBackground | GCFont;
-
- if (FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc)
- XChangeGC (s->display, FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc,
- mask, &xgcv);
- else
- FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc
- = XCreateGC (s->display, s->window, mask, &xgcv);
-
- s->gc = FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc;
- }
-}
-
-
-/* Set up S->gc of glyph string S for drawing text in mouse face. */
-
-static void
-x_set_mouse_face_gc (s)
- struct glyph_string *s;
-{
- int face_id;
- struct face *face;
-
- /* What face has to be used last for the mouse face? */
- face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
- face = FACE_FROM_ID (s->f, face_id);
- if (face == NULL)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
-
- if (s->first_glyph->type == CHAR_GLYPH)
- face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
- else
- face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
- s->face = FACE_FROM_ID (s->f, face_id);
- PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
-
- /* If font in this face is same as S->font, use it. */
- if (s->font == s->face->font)
- s->gc = s->face->gc;
- else
- {
- /* Otherwise construct scratch_cursor_gc with values from FACE
- but font FONT. */
- XGCValues xgcv;
- unsigned long mask;
-
- xgcv.background = s->face->background;
- xgcv.foreground = s->face->foreground;
- IF_DEBUG (x_check_font (s->f, s->font));
- xgcv.font = s->font;
- mask = GCForeground | GCBackground | GCFont;
-
- if (FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc)
- XChangeGC (s->display, FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc,
- mask, &xgcv);
- else
- FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc
- = XCreateGC (s->display, s->window, mask, &xgcv);
-
- s->gc = FRAME_MAC_DISPLAY_INFO (s->f)->scratch_cursor_gc;
- }
-
- xassert (s->gc != 0);
-}
-
-
-/* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
- Faces to use in the mode line have already been computed when the
- matrix was built, so there isn't much to do, here. */
-
-static INLINE void
-x_set_mode_line_face_gc (s)
- struct glyph_string *s;
-{
- s->gc = s->face->gc;
-}
-
-
-/* Set S->gc of glyph string S for drawing that glyph string. Set
- S->stippled_p to a non-zero value if the face of S has a stipple
- pattern. */
-
-static INLINE void
-x_set_glyph_string_gc (s)
- struct glyph_string *s;
-{
- PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
-
- if (s->hl == DRAW_NORMAL_TEXT)
- {
- s->gc = s->face->gc;
- s->stippled_p = s->face->stipple != 0;
- }
- else if (s->hl == DRAW_INVERSE_VIDEO)
- {
- x_set_mode_line_face_gc (s);
- s->stippled_p = s->face->stipple != 0;
- }
- else if (s->hl == DRAW_CURSOR)
- {
- x_set_cursor_gc (s);
- s->stippled_p = 0;
- }
- else if (s->hl == DRAW_MOUSE_FACE)
- {
- x_set_mouse_face_gc (s);
- s->stippled_p = s->face->stipple != 0;
- }
- else if (s->hl == DRAW_IMAGE_RAISED
- || s->hl == DRAW_IMAGE_SUNKEN)
- {
- s->gc = s->face->gc;
- s->stippled_p = s->face->stipple != 0;
- }
- else
- {
- s->gc = s->face->gc;
- s->stippled_p = s->face->stipple != 0;
- }
-
- /* GC must have been set. */
- xassert (s->gc != 0);
-}
-
-
-/* Set clipping for output of glyph string S. S may be part of a mode
- line or menu if we don't have X toolkit support. */
-
-static INLINE void
-x_set_glyph_string_clipping (s)
- struct glyph_string *s;
-{
- Rect rects[MAX_CLIP_RECTS];
- int n;
-
- n = get_glyph_string_clip_rects (s, rects, MAX_CLIP_RECTS);
- mac_set_clip_rectangles (s->f, s->gc, rects, n);
-}
-
-
-/* RIF:
- Compute left and right overhang of glyph string S. If S is a glyph
- string for a composition, assume overhangs don't exist. */
-
-static void
-mac_compute_glyph_string_overhangs (s)
- struct glyph_string *s;
-{
- if (!(s->cmp == NULL
- && s->first_glyph->type == CHAR_GLYPH))
- return;
-
- if (!s->two_byte_p
-#if USE_ATSUI
- || s->font->mac_style
-#endif
- )
- {
- XCharStruct cs;
-
- mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
- s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
- s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
- }
- else
- {
- Rect r;
- MacFontStruct *font = s->font;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (s->f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (s->f));
-
- TextFont (font->mac_fontnum);
- TextSize (font->mac_fontsize);
- TextFace (font->mac_fontface);
-
- QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
-
- s->right_overhang = r.right > s->width ? r.right - s->width : 0;
- s->left_overhang = r.left < 0 ? -r.left : 0;
- }
-}
-
-
-/* Fill rectangle X, Y, W, H with background color of glyph string S. */
-
-static INLINE void
-x_clear_glyph_string_rect (s, x, y, w, h)
- struct glyph_string *s;
- int x, y, w, h;
-{
- mac_erase_rectangle (s->f, s->gc, x, y, w, h);
-}
-
-
-/* Draw the background of glyph_string S. If S->background_filled_p
- is non-zero don't draw it. FORCE_P non-zero means draw the
- background even if it wouldn't be drawn normally. This is used
- when a string preceding S draws into the background of S, or S
- contains the first component of a composition. */
-
-static void
-x_draw_glyph_string_background (s, force_p)
- struct glyph_string *s;
- int force_p;
-{
- /* Nothing to do if background has already been drawn or if it
- shouldn't be drawn in the first place. */
- if (!s->background_filled_p)
- {
- int box_line_width = max (s->face->box_line_width, 0);
-
-#if 0 /* MAC_TODO: stipple */
- if (s->stippled_p)
- {
- /* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
- XFillRectangle (s->display, s->window, s->gc, s->x,
- s->y + box_line_width,
- s->background_width,
- s->height - 2 * box_line_width);
- XSetFillStyle (s->display, s->gc, FillSolid);
- s->background_filled_p = 1;
- }
- else
-#endif
- if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
- || s->font_not_found_p
- || s->extends_to_end_of_line_p
- || force_p)
- {
- x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
- s->background_width,
- s->height - 2 * box_line_width);
- s->background_filled_p = 1;
- }
- }
-}
-
-
-/* Draw the foreground of glyph string S. */
-
-static void
-x_draw_glyph_string_foreground (s)
- struct glyph_string *s;
-{
- int i, x, bg_width;
-
- /* If first glyph of S has a left box line, start drawing the text
- of S to the right of that box line. */
- if (s->face->box != FACE_NO_BOX
- && s->first_glyph->left_box_line_p)
- x = s->x + eabs (s->face->box_line_width);
- else
- x = s->x;
-
- /* Draw characters of S as rectangles if S's font could not be
- loaded. */
- if (s->font_not_found_p)
- {
- for (i = 0; i < s->nchars; ++i)
- {
- struct glyph *g = s->first_glyph + i;
- mac_draw_rectangle (s->f, s->gc, x, s->y,
- g->pixel_width - 1, s->height - 1);
- x += g->pixel_width;
- }
- }
- else
- {
- char *char1b = (char *) s->char2b;
- int boff = s->font_info->baseline_offset;
-
- if (s->font_info->vertical_centering)
- boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
-
- /* If we can use 8-bit functions, condense S->char2b. */
- if (!s->two_byte_p
-#if USE_ATSUI
- && GC_FONT (s->gc)->mac_style == NULL
-#endif
- )
- for (i = 0; i < s->nchars; ++i)
- char1b[i] = s->char2b[i].byte2;
-
- /* Draw text with XDrawString if background has already been
- filled. Otherwise, use XDrawImageString. (Note that
- XDrawImageString is usually faster than XDrawString.) Always
- use XDrawImageString when drawing the cursor so that there is
- no chance that characters under a box cursor are invisible. */
- if (s->for_overlaps
- || (s->background_filled_p && s->hl != DRAW_CURSOR))
- bg_width = 0; /* Corresponds to XDrawString. */
- else
- bg_width = s->background_width; /* Corresponds to XDrawImageString. */
-
- if (s->two_byte_p
-#if USE_ATSUI
- || GC_FONT (s->gc)->mac_style
-#endif
- )
-#if USE_CG_TEXT_DRAWING
- if (!s->two_byte_p
- && mac_draw_image_string_cg (s->f, s->gc, x, s->ybase - boff,
- s->char2b, s->nchars, bg_width,
- s->face->overstrike))
- ;
- else
-#endif
- mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff,
- s->char2b, s->nchars, bg_width,
- s->face->overstrike);
- else
- mac_draw_image_string (s->f, s->gc, x, s->ybase - boff,
- char1b, s->nchars, bg_width,
- s->face->overstrike);
- }
-}
-
-/* Draw the foreground of composite glyph string S. */
-
-static void
-x_draw_composite_glyph_string_foreground (s)
- struct glyph_string *s;
-{
- int i, x;
-
- /* If first glyph of S has a left box line, start drawing the text
- of S to the right of that box line. */
- if (s->face->box != FACE_NO_BOX
- && s->first_glyph->left_box_line_p)
- x = s->x + eabs (s->face->box_line_width);
- else
- x = s->x;
-
- /* S is a glyph string for a composition. S->gidx is the index of
- the first character drawn for glyphs of this composition.
- S->gidx == 0 means we are drawing the very first character of
- this composition. */
-
- /* Draw a rectangle for the composition if the font for the very
- first character of the composition could not be loaded. */
- if (s->font_not_found_p)
- {
- if (s->gidx == 0)
- mac_draw_rectangle (s->f, s->gc, x, s->y,
- s->width - 1, s->height - 1);
- }
- else
- {
- for (i = 0; i < s->nchars; i++, ++s->gidx)
- if (mac_per_char_metric (GC_FONT (s->gc), s->char2b + i, 0) == NULL)
- /* This is a nonexistent or zero-width glyph such as a
- combining diacritic. Draw a rectangle. */
- mac_draw_rectangle (s->f, s->gc,
- x + s->cmp->offsets[s->gidx * 2], s->y,
- FONT_WIDTH (GC_FONT (s->gc)) - 1, s->height - 1);
- else
- mac_draw_image_string_16 (s->f, s->gc,
- x + s->cmp->offsets[s->gidx * 2],
- s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
- s->char2b + i, 1, 0, s->face->overstrike);
- }
-}
-
-
-#ifdef USE_X_TOOLKIT
-
-static struct frame *x_frame_of_widget P_ ((Widget));
-
-
-/* Return the frame on which widget WIDGET is used.. Abort if frame
- cannot be determined. */
-
-static struct frame *
-x_frame_of_widget (widget)
- Widget widget;
-{
- struct x_display_info *dpyinfo;
- Lisp_Object tail;
- struct frame *f;
-
- dpyinfo = x_display_info_for_display (XtDisplay (widget));
-
- /* Find the top-level shell of the widget. Note that this function
- can be called when the widget is not yet realized, so XtWindow
- (widget) == 0. That's the reason we can't simply use
- x_any_window_to_frame. */
- while (!XtIsTopLevelShell (widget))
- widget = XtParent (widget);
-
- /* Look for a frame with that top-level widget. Allocate the color
- on that frame to get the right gamma correction value. */
- for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
- if (FRAMEP (XCAR (tail))
- && (f = XFRAME (XCAR (tail)),
- (f->output_data.nothing != 1
- && FRAME_X_DISPLAY_INFO (f) == dpyinfo))
- && f->output_data.x->widget == widget)
- return f;
-
- abort ();
-}
-
-
-/* Allocate the color COLOR->pixel on the screen and display of
- widget WIDGET in colormap CMAP. If an exact match cannot be
- allocated, try the nearest color available. Value is non-zero
- if successful. This is called from lwlib. */
-
-int
-x_alloc_nearest_color_for_widget (widget, cmap, color)
- Widget widget;
- Colormap cmap;
- XColor *color;
-{
- struct frame *f = x_frame_of_widget (widget);
- return x_alloc_nearest_color (f, cmap, color);
-}
-
-
-#endif /* USE_X_TOOLKIT */
-
-#if 0 /* MAC_TODO */
-
-/* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
- CMAP. If an exact match can't be allocated, try the nearest color
- available. Value is non-zero if successful. Set *COLOR to the
- color allocated. */
-
-int
-x_alloc_nearest_color (f, cmap, color)
- struct frame *f;
- Colormap cmap;
- XColor *color;
-{
- Display *display = FRAME_X_DISPLAY (f);
- Screen *screen = FRAME_X_SCREEN (f);
- int rc;
-
- gamma_correct (f, color);
- rc = XAllocColor (display, cmap, color);
- if (rc == 0)
- {
- /* If we got to this point, the colormap is full, so we're going
- to try to get the next closest color. The algorithm used is
- a least-squares matching, which is what X uses for closest
- color matching with StaticColor visuals. */
- int nearest, i;
- unsigned long nearest_delta = ~0;
- int ncells = XDisplayCells (display, XScreenNumberOfScreen (screen));
- XColor *cells = (XColor *) alloca (ncells * sizeof *cells);
-
- for (i = 0; i < ncells; ++i)
- cells[i].pixel = i;
- XQueryColors (display, cmap, cells, ncells);
-
- for (nearest = i = 0; i < ncells; ++i)
- {
- long dred = (color->red >> 8) - (cells[i].red >> 8);
- long dgreen = (color->green >> 8) - (cells[i].green >> 8);
- long dblue = (color->blue >> 8) - (cells[i].blue >> 8);
- unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue;
-
- if (delta < nearest_delta)
- {
- nearest = i;
- nearest_delta = delta;
- }
- }
-
- color->red = cells[nearest].red;
- color->green = cells[nearest].green;
- color->blue = cells[nearest].blue;
- rc = XAllocColor (display, cmap, color);
- }
-
-#ifdef DEBUG_X_COLORS
- if (rc)
- register_color (color->pixel);
-#endif /* DEBUG_X_COLORS */
-
- return rc;
-}
-
-
-/* Allocate color PIXEL on frame F. PIXEL must already be allocated.
- It's necessary to do this instead of just using PIXEL directly to
- get color reference counts right. */
-
-unsigned long
-x_copy_color (f, pixel)
- struct frame *f;
- unsigned long pixel;
-{
- XColor color;
-
- color.pixel = pixel;
- BLOCK_INPUT;
- XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
- XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
- UNBLOCK_INPUT;
-#ifdef DEBUG_X_COLORS
- register_color (pixel);
-#endif
- return color.pixel;
-}
-
-
-/* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
- It's necessary to do this instead of just using PIXEL directly to
- get color reference counts right. */
-
-unsigned long
-x_copy_dpy_color (dpy, cmap, pixel)
- Display *dpy;
- Colormap cmap;
- unsigned long pixel;
-{
- XColor color;
-
- color.pixel = pixel;
- BLOCK_INPUT;
- XQueryColor (dpy, cmap, &color);
- XAllocColor (dpy, cmap, &color);
- UNBLOCK_INPUT;
-#ifdef DEBUG_X_COLORS
- register_color (pixel);
-#endif
- return color.pixel;
-}
-
-#endif /* MAC_TODO */
-
-
-/* Brightness beyond which a color won't have its highlight brightness
- boosted.
-
- Nominally, highlight colors for `3d' faces are calculated by
- brightening an object's color by a constant scale factor, but this
- doesn't yield good results for dark colors, so for colors who's
- brightness is less than this value (on a scale of 0-255) have to
- use an additional additive factor.
-
- The value here is set so that the default menu-bar/mode-line color
- (grey75) will not have its highlights changed at all. */
-#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
-
-
-/* Allocate a color which is lighter or darker than *COLOR by FACTOR
- or DELTA. Try a color with RGB values multiplied by FACTOR first.
- If this produces the same color as COLOR, try a color where all RGB
- values have DELTA added. Return the allocated color in *COLOR.
- DISPLAY is the X display, CMAP is the colormap to operate on.
- Value is non-zero if successful. */
-
-static int
-mac_alloc_lighter_color (f, color, factor, delta)
- struct frame *f;
- unsigned long *color;
- double factor;
- int delta;
-{
- unsigned long new;
- long bright;
-
- /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
- delta /= 256;
-
- /* Change RGB values by specified FACTOR. Avoid overflow! */
- xassert (factor >= 0);
- new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))),
- min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))),
- min (0xff, (int) (factor * BLUE_FROM_ULONG (*color))));
-
- /* Calculate brightness of COLOR. */
- bright = (2 * RED_FROM_ULONG (*color) + 3 * GREEN_FROM_ULONG (*color)
- + BLUE_FROM_ULONG (*color)) / 6;
-
- /* We only boost colors that are darker than
- HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
- if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
- /* Make an additive adjustment to NEW, because it's dark enough so
- that scaling by FACTOR alone isn't enough. */
- {
- /* How far below the limit this color is (0 - 1, 1 being darker). */
- double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
- /* The additive adjustment. */
- int min_delta = delta * dimness * factor / 2;
-
- if (factor < 1)
- new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color)) - min_delta)),
- max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color)) - min_delta)),
- max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color)) - min_delta)));
- else
- new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta + RED_FROM_ULONG (*color)))),
- max (0, min (0xff, (int) (min_delta + GREEN_FROM_ULONG (*color)))),
- max (0, min (0xff, (int) (min_delta + BLUE_FROM_ULONG (*color)))));
- }
-
- if (new == *color)
- new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))),
- max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))),
- max (0, min (0xff, (int) (delta + BLUE_FROM_ULONG (*color)))));
-
- /* MAC_TODO: Map to palette and retry with delta if same? */
- /* MAC_TODO: Free colors (if using palette)? */
-
- if (new == *color)
- return 0;
-
- *color = new;
-
- return 1;
-}
-
-
-/* Set up the foreground color for drawing relief lines of glyph
- string S. RELIEF is a pointer to a struct relief containing the GC
- with which lines will be drawn. Use a color that is FACTOR or
- DELTA lighter or darker than the relief's background which is found
- in S->f->output_data.x->relief_background. If such a color cannot
- be allocated, use DEFAULT_PIXEL, instead. */
-
-static void
-x_setup_relief_color (f, relief, factor, delta, default_pixel)
- struct frame *f;
- struct relief *relief;
- double factor;
- int delta;
- unsigned long default_pixel;
-{
- XGCValues xgcv;
- struct mac_output *di = f->output_data.mac;
- unsigned long mask = GCForeground;
- unsigned long pixel;
- unsigned long background = di->relief_background;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- /* MAC_TODO: Free colors (if using palette)? */
-
- /* Allocate new color. */
- xgcv.foreground = default_pixel;
- pixel = background;
- if (dpyinfo->n_planes != 1
- && mac_alloc_lighter_color (f, &pixel, factor, delta))
- {
- relief->allocated_p = 1;
- xgcv.foreground = relief->pixel = pixel;
- }
-
- if (relief->gc == 0)
- {
-#if 0 /* MAC_TODO: stipple */
- xgcv.stipple = dpyinfo->gray;
- mask |= GCStipple;
-#endif
- relief->gc = XCreateGC (NULL, FRAME_MAC_WINDOW (f), mask, &xgcv);
- }
- else
- XChangeGC (NULL, relief->gc, mask, &xgcv);
-}
-
-
-/* Set up colors for the relief lines around glyph string S. */
-
-static void
-x_setup_relief_colors (s)
- struct glyph_string *s;
-{
- struct mac_output *di = s->f->output_data.mac;
- unsigned long color;
-
- if (s->face->use_box_color_for_shadows_p)
- color = s->face->box_color;
- else if (s->first_glyph->type == IMAGE_GLYPH
- && s->img->pixmap
- && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
- color = IMAGE_BACKGROUND (s->img, s->f, 0);
- else
- {
- XGCValues xgcv;
-
- /* Get the background color of the face. */
- XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
- color = xgcv.background;
- }
-
- if (di->white_relief.gc == 0
- || color != di->relief_background)
- {
- di->relief_background = color;
- x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
- WHITE_PIX_DEFAULT (s->f));
- x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
- BLACK_PIX_DEFAULT (s->f));
- }
-}
-
-
-/* Draw a relief on frame F inside the rectangle given by LEFT_X,
- TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
- to draw, it must be >= 0. RAISED_P non-zero means draw a raised
- relief. LEFT_P non-zero means draw a relief on the left side of
- the rectangle. RIGHT_P non-zero means draw a relief on the right
- side of the rectangle. CLIP_RECT is the clipping rectangle to use
- when drawing. */
-
-static void
-x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
- raised_p, top_p, bot_p, left_p, right_p, clip_rect)
- struct frame *f;
- int left_x, top_y, right_x, bottom_y, width;
- int top_p, bot_p, left_p, right_p, raised_p;
- Rect *clip_rect;
-{
- int i;
- GC gc;
-
- if (raised_p)
- gc = f->output_data.mac->white_relief.gc;
- else
- gc = f->output_data.mac->black_relief.gc;
- mac_set_clip_rectangles (f, gc, clip_rect, 1);
-
- /* Top. */
- if (top_p)
- for (i = 0; i < width; ++i)
- mac_draw_line (f, gc,
- left_x + i * left_p, top_y + i,
- right_x + 1 - i * right_p, top_y + i);
-
- /* Left. */
- if (left_p)
- for (i = 0; i < width; ++i)
- mac_draw_line (f, gc,
- left_x + i, top_y + i, left_x + i, bottom_y - i + 1);
-
- mac_reset_clip_rectangles (f, gc);
- if (raised_p)
- gc = f->output_data.mac->black_relief.gc;
- else
- gc = f->output_data.mac->white_relief.gc;
- mac_set_clip_rectangles (f, gc, clip_rect, 1);
-
- /* Bottom. */
- if (bot_p)
- for (i = 0; i < width; ++i)
- mac_draw_line (f, gc,
- left_x + i * left_p, bottom_y - i,
- right_x + 1 - i * right_p, bottom_y - i);
-
- /* Right. */
- if (right_p)
- for (i = 0; i < width; ++i)
- mac_draw_line (f, gc,
- right_x - i, top_y + i + 1, right_x - i, bottom_y - i);
-
- mac_reset_clip_rectangles (f, gc);
-}
-
-
-/* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
- RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
- draw, it must be >= 0. LEFT_P non-zero means draw a line on the
- left side of the rectangle. RIGHT_P non-zero means draw a line
- on the right side of the rectangle. CLIP_RECT is the clipping
- rectangle to use when drawing. */
-
-static void
-x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
- left_p, right_p, clip_rect)
- struct glyph_string *s;
- int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
- Rect *clip_rect;
-{
- XGCValues xgcv;
-
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->box_color);
- mac_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
-
- /* Top. */
- mac_fill_rectangle (s->f, s->gc, left_x, top_y,
- right_x - left_x + 1, width);
-
- /* Left. */
- if (left_p)
- mac_fill_rectangle (s->f, s->gc, left_x, top_y,
- width, bottom_y - top_y + 1);
-
- /* Bottom. */
- mac_fill_rectangle (s->f, s->gc, left_x, bottom_y - width + 1,
- right_x - left_x + 1, width);
-
- /* Right. */
- if (right_p)
- mac_fill_rectangle (s->f, s->gc, right_x - width + 1,
- top_y, width, bottom_y - top_y + 1);
-
- XSetForeground (s->display, s->gc, xgcv.foreground);
- mac_reset_clip_rectangles (s->f, s->gc);
-}
-
-
-/* Draw a box around glyph string S. */
-
-static void
-x_draw_glyph_string_box (s)
- struct glyph_string *s;
-{
- int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
- int left_p, right_p;
- struct glyph *last_glyph;
- Rect clip_rect;
-
- last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
- ? WINDOW_RIGHT_EDGE_X (s->w)
- : window_box_right (s->w, s->area));
-
- /* The glyph that may have a right box line. */
- last_glyph = (s->cmp || s->img
- ? s->first_glyph
- : s->first_glyph + s->nchars - 1);
-
- width = eabs (s->face->box_line_width);
- raised_p = s->face->box == FACE_RAISED_BOX;
- left_x = s->x;
- right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
- ? last_x - 1
- : min (last_x, s->x + s->background_width) - 1);
- top_y = s->y;
- bottom_y = top_y + s->height - 1;
-
- left_p = (s->first_glyph->left_box_line_p
- || (s->hl == DRAW_MOUSE_FACE
- && (s->prev == NULL
- || s->prev->hl != s->hl)));
- right_p = (last_glyph->right_box_line_p
- || (s->hl == DRAW_MOUSE_FACE
- && (s->next == NULL
- || s->next->hl != s->hl)));
-
- get_glyph_string_clip_rect (s, &clip_rect);
-
- if (s->face->box == FACE_SIMPLE_BOX)
- x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
- left_p, right_p, &clip_rect);
- else
- {
- x_setup_relief_colors (s);
- x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
- width, raised_p, 1, 1, left_p, right_p, &clip_rect);
- }
-}
-
-
-/* Draw foreground of image glyph string S. */
-
-static void
-x_draw_image_foreground (s)
- struct glyph_string *s;
-{
- int x = s->x;
- int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
-
- /* If first glyph of S has a left box line, start drawing it to the
- right of that line. */
- if (s->face->box != FACE_NO_BOX
- && s->first_glyph->left_box_line_p
- && s->slice.x == 0)
- x += eabs (s->face->box_line_width);
-
- /* If there is a margin around the image, adjust x- and y-position
- by that margin. */
- if (s->slice.x == 0)
- x += s->img->hmargin;
- if (s->slice.y == 0)
- y += s->img->vmargin;
-
- if (s->img->pixmap)
- {
- x_set_glyph_string_clipping (s);
-
-#if USE_CG_DRAWING
- mac_draw_cg_image (s->img->data.ptr_val,
- s->f, s->gc, s->slice.x, s->slice.y,
- s->slice.width, s->slice.height, x, y, 1);
-#endif
- if (s->img->mask)
-#if !USE_CG_DRAWING
- mac_copy_area_with_mask (s->img->pixmap, s->img->mask,
- s->f, s->gc, s->slice.x, s->slice.y,
- s->slice.width, s->slice.height, x, y);
-#else
- ;
-#endif
- else
- {
-#if !USE_CG_DRAWING
- mac_copy_area (s->img->pixmap,
- s->f, s->gc, s->slice.x, s->slice.y,
- s->slice.width, s->slice.height, x, y);
-#endif
-
- /* When the image has a mask, we can expect that at
- least part of a mouse highlight or a block cursor will
- be visible. If the image doesn't have a mask, make
- a block cursor visible by drawing a rectangle around
- the image. I believe it's looking better if we do
- nothing here for mouse-face. */
- if (s->hl == DRAW_CURSOR)
- {
- int r = s->img->relief;
- if (r < 0) r = -r;
- mac_draw_rectangle (s->f, s->gc, x - r, y - r,
- s->slice.width + r*2 - 1,
- s->slice.height + r*2 - 1);
- }
- }
- }
- else
- /* Draw a rectangle if image could not be loaded. */
- mac_draw_rectangle (s->f, s->gc, x, y,
- s->slice.width - 1, s->slice.height - 1);
-}
-
-
-/* Draw a relief around the image glyph string S. */
-
-static void
-x_draw_image_relief (s)
- struct glyph_string *s;
-{
- int x0, y0, x1, y1, thick, raised_p;
- Rect r;
- int x = s->x;
- int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
-
- /* If first glyph of S has a left box line, start drawing it to the
- right of that line. */
- if (s->face->box != FACE_NO_BOX
- && s->first_glyph->left_box_line_p
- && s->slice.x == 0)
- x += eabs (s->face->box_line_width);
-
- /* If there is a margin around the image, adjust x- and y-position
- by that margin. */
- if (s->slice.x == 0)
- x += s->img->hmargin;
- if (s->slice.y == 0)
- y += s->img->vmargin;
-
- if (s->hl == DRAW_IMAGE_SUNKEN
- || s->hl == DRAW_IMAGE_RAISED)
- {
- thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
- raised_p = s->hl == DRAW_IMAGE_RAISED;
- }
- else
- {
- thick = eabs (s->img->relief);
- raised_p = s->img->relief > 0;
- }
-
- x0 = x - thick;
- y0 = y - thick;
- x1 = x + s->slice.width + thick - 1;
- y1 = y + s->slice.height + thick - 1;
-
- x_setup_relief_colors (s);
- get_glyph_string_clip_rect (s, &r);
- x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
- s->slice.y == 0,
- s->slice.y + s->slice.height == s->img->height,
- s->slice.x == 0,
- s->slice.x + s->slice.width == s->img->width,
- &r);
-}
-
-
-/* Draw part of the background of glyph string S. X, Y, W, and H
- give the rectangle to draw. */
-
-static void
-x_draw_glyph_string_bg_rect (s, x, y, w, h)
- struct glyph_string *s;
- int x, y, w, h;
-{
-#if 0 /* MAC_TODO: stipple */
- if (s->stippled_p)
- {
- /* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
- XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
- XSetFillStyle (s->display, s->gc, FillSolid);
- }
- else
-#endif /* MAC_TODO */
- x_clear_glyph_string_rect (s, x, y, w, h);
-}
-
-
-/* Draw image glyph string S.
-
- s->y
- s->x +-------------------------
- | s->face->box
- |
- | +-------------------------
- | | s->img->margin
- | |
- | | +-------------------
- | | | the image
-
- */
-
-static void
-x_draw_image_glyph_string (s)
- struct glyph_string *s;
-{
- int x, y;
- int box_line_hwidth = eabs (s->face->box_line_width);
- int box_line_vwidth = max (s->face->box_line_width, 0);
- int height;
-
- height = s->height - 2 * box_line_vwidth;
-
-
- /* Fill background with face under the image. Do it only if row is
- taller than image or if image has a clip mask to reduce
- flickering. */
- s->stippled_p = s->face->stipple != 0;
- if (height > s->slice.height
- || s->img->hmargin
- || s->img->vmargin
- || s->img->mask
- || s->img->pixmap == 0
- || s->width != s->background_width)
- {
- x = s->x;
- if (s->first_glyph->left_box_line_p
- && s->slice.x == 0)
- x += box_line_hwidth;
-
- y = s->y;
- if (s->slice.y == 0)
- y += box_line_vwidth;
-
- x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
-
- s->background_filled_p = 1;
- }
-
- /* Draw the foreground. */
- x_draw_image_foreground (s);
-
- /* If we must draw a relief around the image, do it. */
- if (s->img->relief
- || s->hl == DRAW_IMAGE_RAISED
- || s->hl == DRAW_IMAGE_SUNKEN)
- x_draw_image_relief (s);
-}
-
-
-/* Draw stretch glyph string S. */
-
-static void
-x_draw_stretch_glyph_string (s)
- struct glyph_string *s;
-{
- xassert (s->first_glyph->type == STRETCH_GLYPH);
-
- if (s->hl == DRAW_CURSOR
- && !x_stretch_cursor_p)
- {
- /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
- as wide as the stretch glyph. */
- int width, background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
-
- if (x < left_x)
- {
- background_width -= left_x - x;
- x = left_x;
- }
- width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
-
- /* Draw cursor. */
- x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
-
- /* Clear rest using the GC of the original non-cursor face. */
- if (width < background_width)
- {
- int y = s->y;
- int w = background_width - width, h = s->height;
- Rect r;
- GC gc;
-
- x += width;
- if (s->row->mouse_face_p
- && cursor_in_mouse_face_p (s->w))
- {
- x_set_mouse_face_gc (s);
- gc = s->gc;
- }
- else
- gc = s->face->gc;
-
- get_glyph_string_clip_rect (s, &r);
- mac_set_clip_rectangles (s->f, gc, &r, 1);
-
-#if 0 /* MAC_TODO: stipple */
- if (s->face->stipple)
- {
- /* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, gc, FillOpaqueStippled);
- XFillRectangle (s->display, s->window, gc, x, y, w, h);
- XSetFillStyle (s->display, gc, FillSolid);
- }
- else
-#endif /* MAC_TODO */
- mac_erase_rectangle (s->f, gc, x, y, w, h);
- }
- }
- else if (!s->background_filled_p)
- {
- int background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
-
- /* Don't draw into left margin, fringe or scrollbar area
- except for header line and mode line. */
- if (x < left_x && !s->row->mode_line_p)
- {
- background_width -= left_x - x;
- x = left_x;
- }
- if (background_width > 0)
- x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
- }
-
- s->background_filled_p = 1;
-}
-
-
-/* Draw glyph string S. */
-
-static void
-x_draw_glyph_string (s)
- struct glyph_string *s;
-{
- int relief_drawn_p = 0;
-
- /* If S draws into the background of its successor that does not
- draw a cursor, draw the background of the successor first so that
- S can draw into it. This makes S->next use XDrawString instead
- of XDrawImageString. */
- if (s->next && s->right_overhang && !s->for_overlaps
- && s->next->hl != DRAW_CURSOR)
- {
- xassert (s->next->img == NULL);
- x_set_glyph_string_gc (s->next);
- x_set_glyph_string_clipping (s->next);
- x_draw_glyph_string_background (s->next, 1);
- }
-
- /* Set up S->gc, set clipping and draw S. */
- x_set_glyph_string_gc (s);
-
- /* Draw relief (if any) in advance for char/composition so that the
- glyph string can be drawn over it. */
- if (!s->for_overlaps
- && s->face->box != FACE_NO_BOX
- && (s->first_glyph->type == CHAR_GLYPH
- || s->first_glyph->type == COMPOSITE_GLYPH))
-
- {
- x_set_glyph_string_clipping (s);
- x_draw_glyph_string_background (s, 1);
- x_draw_glyph_string_box (s);
- x_set_glyph_string_clipping (s);
- relief_drawn_p = 1;
- }
- else
- x_set_glyph_string_clipping (s);
-
- switch (s->first_glyph->type)
- {
- case IMAGE_GLYPH:
- x_draw_image_glyph_string (s);
- break;
-
- case STRETCH_GLYPH:
- x_draw_stretch_glyph_string (s);
- break;
-
- case CHAR_GLYPH:
- if (s->for_overlaps)
- s->background_filled_p = 1;
- else
- x_draw_glyph_string_background (s, 0);
- x_draw_glyph_string_foreground (s);
- break;
-
- case COMPOSITE_GLYPH:
- if (s->for_overlaps || s->gidx > 0)
- s->background_filled_p = 1;
- else
- x_draw_glyph_string_background (s, 1);
- x_draw_composite_glyph_string_foreground (s);
- break;
-
- default:
- abort ();
- }
-
- if (!s->for_overlaps)
- {
- /* Draw underline. */
- if (s->face->underline_p)
- {
- unsigned long tem, h;
- int y;
-
-#if 0
- /* Get the underline thickness. Default is 1 pixel. */
- if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
-#endif
- h = 1;
-
- y = s->y + s->height - h;
- if (!x_underline_at_descent_line)
- {
- /* Get the underline position. This is the recommended
- vertical offset in pixels from the baseline to the top of
- the underline. This is a signed value according to the
- specs, and its default is
-
- ROUND ((maximum descent) / 2), with
- ROUND(x) = floor (x + 0.5) */
-
-#if 0
- if (x_use_underline_position_properties
- && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
- y = s->ybase + (long) tem;
- else
-#endif
- if (s->face->font)
- y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
- }
- /* FIXME: Obey underline_minimum_offset. */
- if (s->face->underline_defaulted_p)
- mac_fill_rectangle (s->f, s->gc, s->x, y,
- s->background_width, h);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->underline_color);
- mac_fill_rectangle (s->f, s->gc, s->x, y,
- s->background_width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
-
- /* Draw overline. */
- if (s->face->overline_p)
- {
- unsigned long dy = 0, h = 1;
-
- if (s->face->overline_color_defaulted_p)
- mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- s->background_width, h);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->overline_color);
- mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- s->background_width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
-
- /* Draw strike-through. */
- if (s->face->strike_through_p)
- {
- unsigned long h = 1;
- unsigned long dy = (s->height - h) / 2;
-
- if (s->face->strike_through_color_defaulted_p)
- mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- s->width, h);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->strike_through_color);
- mac_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- s->width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
-
- /* Draw relief if not yet drawn. */
- if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
- x_draw_glyph_string_box (s);
- }
-
- /* Reset clipping. */
- mac_reset_clip_rectangles (s->f, s->gc);
-}
-
-/* Shift display to make room for inserted glyphs. */
-
-void
-mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
- struct frame *f;
- int x, y, width, height, shift_by;
-{
- mac_scroll_area (f, f->output_data.mac->normal_gc,
- x, y, width, height,
- x + shift_by, y);
-}
-
-/* Delete N glyphs at the nominal cursor position. Not implemented
- for X frames. */
-
-static void
-x_delete_glyphs (n)
- register int n;
-{
- abort ();
-}
-
-
-/* Clear entire frame. If updating_frame is non-null, clear that
- frame. Otherwise clear the selected frame. */
-
-static void
-x_clear_frame (struct frame *f)
-{
- /* Clearing the frame will erase any cursor, so mark them all as no
- longer visible. */
- mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
- output_cursor.hpos = output_cursor.vpos = 0;
- output_cursor.x = -1;
-
- /* We don't set the output cursor here because there will always
- follow an explicit cursor_to. */
- BLOCK_INPUT;
- mac_clear_window (f);
-
- /* We have to clear the scroll bars, too. If we have changed
- colors or something like that, then they should be notified. */
- x_scroll_bar_clear (f);
-
- XFlush (FRAME_MAC_DISPLAY (f));
- UNBLOCK_INPUT;
-}
-
-
-
-/* Invert the middle quarter of the frame for .15 sec. */
-
-/* We use the select system call to do the waiting, so we have to make
- sure it's available. If it isn't, we just won't do visual bells. */
-
-#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
-
-
-/* Subtract the `struct timeval' values X and Y, storing the result in
- *RESULT. Return 1 if the difference is negative, otherwise 0. */
-
-static int
-timeval_subtract (result, x, y)
- struct timeval *result, x, y;
-{
- /* Perform the carry for the later subtraction by updating y. This
- is safer because on some systems the tv_sec member is unsigned. */
- if (x.tv_usec < y.tv_usec)
- {
- int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
- y.tv_usec -= 1000000 * nsec;
- y.tv_sec += nsec;
- }
-
- if (x.tv_usec - y.tv_usec > 1000000)
- {
- int nsec = (y.tv_usec - x.tv_usec) / 1000000;
- y.tv_usec += 1000000 * nsec;
- y.tv_sec -= nsec;
- }
-
- /* Compute the time remaining to wait. tv_usec is certainly
- positive. */
- result->tv_sec = x.tv_sec - y.tv_sec;
- result->tv_usec = x.tv_usec - y.tv_usec;
-
- /* Return indication of whether the result should be considered
- negative. */
- return x.tv_sec < y.tv_sec;
-}
-
-void
-XTflash (f)
- struct frame *f;
-{
- /* Get the height not including a menu bar widget. */
- int height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
- /* Height of each line to flash. */
- int flash_height = FRAME_LINE_HEIGHT (f);
- /* These will be the left and right margins of the rectangles. */
- int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
- int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
-
- int width;
-
- /* Don't flash the area between a scroll bar and the frame
- edge it is next to. */
- switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f))
- {
- case vertical_scroll_bar_left:
- flash_left += VERTICAL_SCROLL_BAR_WIDTH_TRIM;
- break;
-
- case vertical_scroll_bar_right:
- flash_right -= VERTICAL_SCROLL_BAR_WIDTH_TRIM;
- break;
-
- default:
- break;
- }
-
- width = flash_right - flash_left;
-
- BLOCK_INPUT;
-
- /* If window is tall, flash top and bottom line. */
- if (height > 3 * FRAME_LINE_HEIGHT (f))
- {
- mac_invert_rectangle (f, flash_left,
- (FRAME_INTERNAL_BORDER_WIDTH (f)
- + FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)),
- width, flash_height);
- mac_invert_rectangle (f, flash_left,
- (height - flash_height
- - FRAME_INTERNAL_BORDER_WIDTH (f)),
- width, flash_height);
- }
- else
- /* If it is short, flash it all. */
- mac_invert_rectangle (f, flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
- width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
-
- x_flush (f);
-
- {
- struct timeval wakeup;
-
- EMACS_GET_TIME (wakeup);
-
- /* Compute time to wait until, propagating carry from usecs. */
- wakeup.tv_usec += 150000;
- wakeup.tv_sec += (wakeup.tv_usec / 1000000);
- wakeup.tv_usec %= 1000000;
-
- /* Keep waiting until past the time wakeup or any input gets
- available. */
- while (! detect_input_pending ())
- {
- struct timeval current;
- struct timeval timeout;
-
- EMACS_GET_TIME (current);
-
- /* Break if result would be negative. */
- if (timeval_subtract (&current, wakeup, current))
- break;
-
- /* How long `select' should wait. */
- timeout.tv_sec = 0;
- timeout.tv_usec = 10000;
-
- /* Try to wait that long--but we might wake up sooner. */
- select (0, NULL, NULL, NULL, &timeout);
- }
- }
-
- /* If window is tall, flash top and bottom line. */
- if (height > 3 * FRAME_LINE_HEIGHT (f))
- {
- mac_invert_rectangle (f, flash_left,
- (FRAME_INTERNAL_BORDER_WIDTH (f)
- + FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)),
- width, flash_height);
- mac_invert_rectangle (f, flash_left,
- (height - flash_height
- - FRAME_INTERNAL_BORDER_WIDTH (f)),
- width, flash_height);
- }
- else
- /* If it is short, flash it all. */
- mac_invert_rectangle (f, flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
- width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
-
- x_flush (f);
-
- UNBLOCK_INPUT;
-}
-
-#endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
-
-
-/* Make audible bell. */
-
-void
-XTring_bell ()
-{
- struct frame *f = SELECTED_FRAME ();
-
-#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
- if (visible_bell)
- XTflash (f);
- else
-#endif
- {
- BLOCK_INPUT;
- SysBeep (1);
- XFlush (FRAME_MAC_DISPLAY (f));
- UNBLOCK_INPUT;
- }
-}
-
-
-/* Specify how many text lines, from the top of the window,
- should be affected by insert-lines and delete-lines operations.
- This, and those operations, are used only within an update
- that is bounded by calls to x_update_begin and x_update_end. */
-
-static void
-XTset_terminal_window (n)
- register int n;
-{
- /* This function intentionally left blank. */
-}
-
-
-
-/***********************************************************************
- Line Dance
- ***********************************************************************/
-
-/* Perform an insert-lines or delete-lines operation, inserting N
- lines or deleting -N lines at vertical position VPOS. */
-
-static void
-x_ins_del_lines (vpos, n)
- int vpos, n;
-{
- abort ();
-}
-
-
-/* Scroll part of the display as described by RUN. */
-
-static void
-x_scroll_run (w, run)
- struct window *w;
- struct run *run;
-{
- struct frame *f = XFRAME (w->frame);
- int x, y, width, height, from_y, to_y, bottom_y;
-
- /* Get frame-relative bounding box of the text display area of W,
- without mode lines. Include in this box the left and right
- fringe of W. */
- window_box (w, -1, &x, &y, &width, &height);
-
- from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
- to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
- bottom_y = y + height;
-
- if (to_y < from_y)
- {
- /* Scrolling up. Make sure we don't copy part of the mode
- line at the bottom. */
- if (from_y + run->height > bottom_y)
- height = bottom_y - from_y;
- else
- height = run->height;
- }
- else
- {
- /* Scolling down. Make sure we don't copy over the mode line.
- at the bottom. */
- if (to_y + run->height > bottom_y)
- height = bottom_y - to_y;
- else
- height = run->height;
- }
-
- BLOCK_INPUT;
-
- /* Cursor off. Will be switched on again in x_update_window_end. */
- updated_window = w;
- x_clear_cursor (w);
-
- mac_scroll_area (f, f->output_data.mac->normal_gc,
- x, from_y,
- width, height,
- x, to_y);
-
- UNBLOCK_INPUT;
-}
-
-
-
-/***********************************************************************
- Exposure Events
- ***********************************************************************/
-
-
-static void
-frame_highlight (f)
- struct frame *f;
-{
- x_update_cursor (f, 1);
-}
-
-static void
-frame_unhighlight (f)
- struct frame *f;
-{
- x_update_cursor (f, 1);
-}
-
-/* The focus has changed. Update the frames as necessary to reflect
- the new situation. Note that we can't change the selected frame
- here, because the Lisp code we are interrupting might become confused.
- Each event gets marked with the frame in which it occurred, so the
- Lisp code can tell when the switch took place by examining the events. */
-
-static void
-x_new_focus_frame (dpyinfo, frame)
- struct x_display_info *dpyinfo;
- struct frame *frame;
-{
- struct frame *old_focus = dpyinfo->x_focus_frame;
-
- if (frame != dpyinfo->x_focus_frame)
- {
- /* Set this before calling other routines, so that they see
- the correct value of x_focus_frame. */
- dpyinfo->x_focus_frame = frame;
-
- if (old_focus && old_focus->auto_lower)
- x_lower_frame (old_focus);
-
-#if 0
- selected_frame = frame;
- XSETFRAME (XWINDOW (selected_frame->selected_window)->frame,
- selected_frame);
- Fselect_window (selected_frame->selected_window, Qnil);
- choose_minibuf_frame ();
-#endif /* ! 0 */
-
- if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
- pending_autoraise_frame = dpyinfo->x_focus_frame;
- else
- pending_autoraise_frame = 0;
-
-#if USE_MAC_FONT_PANEL
- if (frame)
- mac_set_font_info_for_selection (frame, DEFAULT_FACE_ID, 0);
-#endif
- }
-
- x_frame_rehighlight (dpyinfo);
-}
-
-/* Handle FocusIn and FocusOut state changes for FRAME.
- If FRAME has focus and there exists more than one frame, puts
- a FOCUS_IN_EVENT into *BUFP. */
-
-static void
-mac_focus_changed (type, dpyinfo, frame, bufp)
- int type;
- struct mac_display_info *dpyinfo;
- struct frame *frame;
- struct input_event *bufp;
-{
- if (type == activeFlag)
- {
- if (dpyinfo->x_focus_event_frame != frame)
- {
- x_new_focus_frame (dpyinfo, frame);
- dpyinfo->x_focus_event_frame = frame;
-
- /* Don't stop displaying the initial startup message
- for a switch-frame event we don't need. */
- if (NILP (Vterminal_frame)
- && CONSP (Vframe_list)
- && !NILP (XCDR (Vframe_list)))
- {
- bufp->kind = FOCUS_IN_EVENT;
- XSETFRAME (bufp->frame_or_window, frame);
- }
- }
- }
- else
- {
- if (dpyinfo->x_focus_event_frame == frame)
- {
- dpyinfo->x_focus_event_frame = 0;
- x_new_focus_frame (dpyinfo, 0);
- }
- }
-}
-
-/* The focus may have changed. Figure out if it is a real focus change,
- by checking both FocusIn/Out and Enter/LeaveNotify events.
-
- Returns FOCUS_IN_EVENT event in *BUFP. */
-
-static void
-x_detect_focus_change (dpyinfo, event, bufp)
- struct mac_display_info *dpyinfo;
- const EventRecord *event;
- struct input_event *bufp;
-{
- struct frame *frame;
-
- frame = mac_window_to_frame ((WindowRef) event->message);
- if (! frame)
- return;
-
- /* On Mac, this is only called from focus events, so no switch needed. */
- mac_focus_changed ((event->modifiers & activeFlag),
- dpyinfo, frame, bufp);
-}
-
-
-/* Handle an event saying the mouse has moved out of an Emacs frame. */
-
-void
-x_mouse_leave (dpyinfo)
- struct x_display_info *dpyinfo;
-{
- x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
-}
-
-/* The focus has changed, or we have redirected a frame's focus to
- another frame (this happens when a frame uses a surrogate
- mini-buffer frame). Shift the highlight as appropriate.
-
- The FRAME argument doesn't necessarily have anything to do with which
- frame is being highlighted or un-highlighted; we only use it to find
- the appropriate X display info. */
-
-static void
-XTframe_rehighlight (frame)
- struct frame *frame;
-{
- x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
-}
-
-static void
-x_frame_rehighlight (dpyinfo)
- struct x_display_info *dpyinfo;
-{
- struct frame *old_highlight = dpyinfo->x_highlight_frame;
-
- if (dpyinfo->x_focus_frame)
- {
- dpyinfo->x_highlight_frame
- = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
- ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
- : dpyinfo->x_focus_frame);
- if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
- {
- FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame) = Qnil;
- dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
- }
- }
- else
- dpyinfo->x_highlight_frame = 0;
-
- if (dpyinfo->x_highlight_frame != old_highlight)
- {
- if (old_highlight)
- frame_unhighlight (old_highlight);
- if (dpyinfo->x_highlight_frame)
- frame_highlight (dpyinfo->x_highlight_frame);
- }
-}
-
-
-
-/* Convert a keysym to its name. */
-
-char *
-x_get_keysym_name (keysym)
- int keysym;
-{
- char *value;
-
- BLOCK_INPUT;
-#if 0
- value = XKeysymToString (keysym);
-#else
- value = 0;
-#endif
- UNBLOCK_INPUT;
-
- return value;
-}
-
-
-
-/* Function to report a mouse movement to the mainstream Emacs code.
- The input handler calls this.
-
- We have received a mouse movement event, which is given in *event.
- If the mouse is over a different glyph than it was last time, tell
- the mainstream emacs code by setting mouse_moved. If not, ask for
- another motion event, so we can check again the next time it moves. */
-
-static Point last_mouse_motion_position;
-static Lisp_Object last_mouse_motion_frame;
-
-static int
-note_mouse_movement (frame, pos)
- FRAME_PTR frame;
- Point *pos;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
-#if TARGET_API_MAC_CARBON
- Rect r;
-#endif
-
- last_mouse_movement_time = TickCount () * (1000 / 60); /* to milliseconds */
- last_mouse_motion_position = *pos;
- XSETFRAME (last_mouse_motion_frame, frame);
-
- if (frame == dpyinfo->mouse_face_mouse_frame
-#if TARGET_API_MAC_CARBON
- && !PtInRect (*pos, GetWindowPortBounds (FRAME_MAC_WINDOW (frame), &r))
-#else
- && !PtInRect (*pos, &FRAME_MAC_WINDOW (frame)->portRect)
-#endif
- )
- {
- /* This case corresponds to LeaveNotify in X11. If we move
- outside the frame, then we're certainly no longer on any text
- in the frame. */
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_mouse_frame = 0;
- if (!dpyinfo->grabbed)
- FRAME_RIF (frame)->define_frame_cursor (frame,
- frame->output_data.mac->nontext_cursor);
- }
-
- /* Has the mouse moved off the glyph it was on at the last sighting? */
- if (frame != last_mouse_glyph_frame
- || !PtInRect (*pos, &last_mouse_glyph))
- {
- frame->mouse_moved = 1;
- last_mouse_scroll_bar = Qnil;
- note_mouse_highlight (frame, pos->h, pos->v);
- /* Remember which glyph we're now on. */
- remember_mouse_glyph (frame, pos->h, pos->v, &last_mouse_glyph);
- last_mouse_glyph_frame = frame;
- return 1;
- }
-
- return 0;
-}
-
-
-/************************************************************************
- Mouse Face
- ************************************************************************/
-
-/* MAC TODO: This should be called from somewhere (or removed) ++KFS */
-
-static void
-redo_mouse_highlight ()
-{
- if (!NILP (last_mouse_motion_frame)
- && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
- note_mouse_highlight (XFRAME (last_mouse_motion_frame),
- last_mouse_motion_position.h,
- last_mouse_motion_position.v);
-}
-
-
-static struct frame *
-mac_focus_frame (dpyinfo)
- struct mac_display_info *dpyinfo;
-{
- if (dpyinfo->x_focus_frame)
- return dpyinfo->x_focus_frame;
- else
- /* Mac version may get events, such as a menu bar click, even when
- all the frames are invisible. In this case, we regard the
- event came to the selected frame. */
- return SELECTED_FRAME ();
-}
-
-
-/* Return the current position of the mouse.
- *FP should be a frame which indicates which display to ask about.
-
- If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
- and *PART to the frame, window, and scroll bar part that the mouse
- is over. Set *X and *Y to the portion and whole of the mouse's
- position on the scroll bar.
-
- If the mouse movement started elsewhere, set *FP to the frame the
- mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
- the mouse is over.
-
- Set *TIME to the server time-stamp for the time at which the mouse
- was at this position.
-
- Don't store anything if we don't have a valid set of values to report.
-
- This clears the mouse_moved flag, so we can wait for the next mouse
- movement. */
-
-static void
-XTmouse_position (fp, insist, bar_window, part, x, y, time)
- FRAME_PTR *fp;
- int insist;
- Lisp_Object *bar_window;
- enum scroll_bar_part *part;
- Lisp_Object *x, *y;
- unsigned long *time;
-{
- FRAME_PTR f1;
-
- BLOCK_INPUT;
-
- if (! NILP (last_mouse_scroll_bar) && insist == 0)
- x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
- else
- {
- Lisp_Object frame, tail;
-
- /* Clear the mouse-moved flag for every frame on this display. */
- FOR_EACH_FRAME (tail, frame)
- XFRAME (frame)->mouse_moved = 0;
-
- last_mouse_scroll_bar = Qnil;
-
- if (FRAME_MAC_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f1 = last_mouse_frame;
- else
- f1 = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp));
-
- if (f1)
- {
- /* Ok, we found a frame. Store all the values.
- last_mouse_glyph is a rectangle used to reduce the
- generation of mouse events. To not miss any motion
- events, we must divide the frame into rectangles of the
- size of the smallest character that could be displayed
- on it, i.e. into the same rectangles that matrices on
- the frame are divided into. */
- Point mouse_pos;
-
-#if TARGET_API_MAC_CARBON
- GetGlobalMouse (&mouse_pos);
- mouse_pos.h -= f1->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f1);
- mouse_pos.v -= f1->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f1);
-#else
- SetPortWindowPort (FRAME_MAC_WINDOW (f1));
- GetMouse (&mouse_pos);
-#endif
- remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v,
- &last_mouse_glyph);
- last_mouse_glyph_frame = f1;
-
- *bar_window = Qnil;
- *part = 0;
- *fp = f1;
- XSETINT (*x, mouse_pos.h);
- XSETINT (*y, mouse_pos.v);
- *time = last_mouse_movement_time;
- }
- }
-
- UNBLOCK_INPUT;
-}
-
-
-/************************************************************************
- Toolkit scroll bars
- ************************************************************************/
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
-
-static pascal void scroll_bar_timer_callback P_ ((EventLoopTimerRef, void *));
-static OSStatus install_scroll_bar_timer P_ ((void));
-static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval));
-static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode));
-static void construct_scroll_bar_click P_ ((struct scroll_bar *, int,
- struct input_event *));
-static OSStatus get_control_part_bounds P_ ((ControlRef, ControlPartCode,
- Rect *));
-static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
- ControlPartCode, Point,
- struct input_event *));
-static void x_scroll_bar_handle_release P_ ((struct scroll_bar *,
- struct input_event *));
-static void x_scroll_bar_handle_drag P_ ((WindowRef, struct scroll_bar *,
- Point, struct input_event *));
-static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
- int, int, int));
-
-/* Last scroll bar part sent in x_scroll_bar_handle_*. */
-
-static int last_scroll_bar_part;
-
-static EventLoopTimerRef scroll_bar_timer;
-
-static int scroll_bar_timer_event_posted_p;
-
-#define SCROLL_BAR_FIRST_DELAY 0.5
-#define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
-
-static pascal void
-scroll_bar_timer_callback (timer, data)
- EventLoopTimerRef timer;
- void *data;
-{
- OSStatus err;
-
- err = mac_post_mouse_moved_event ();
- if (err == noErr)
- scroll_bar_timer_event_posted_p = 1;
-}
-
-static OSStatus
-install_scroll_bar_timer ()
-{
- static EventLoopTimerUPP scroll_bar_timer_callbackUPP = NULL;
-
- if (scroll_bar_timer_callbackUPP == NULL)
- scroll_bar_timer_callbackUPP =
- NewEventLoopTimerUPP (scroll_bar_timer_callback);
-
- if (scroll_bar_timer == NULL)
- /* Mac OS X and CarbonLib 1.5 and later allow us to specify
- kEventDurationForever as delays. */
- return
- InstallEventLoopTimer (GetCurrentEventLoop (),
- kEventDurationForever, kEventDurationForever,
- scroll_bar_timer_callbackUPP, NULL,
- &scroll_bar_timer);
-}
-
-static OSStatus
-set_scroll_bar_timer (delay)
- EventTimerInterval delay;
-{
- if (scroll_bar_timer == NULL)
- install_scroll_bar_timer ();
-
- scroll_bar_timer_event_posted_p = 0;
-
- return SetEventLoopTimerNextFireTime (scroll_bar_timer, delay);
-}
-
-static int
-control_part_code_to_scroll_bar_part (part_code)
- ControlPartCode part_code;
-{
- switch (part_code)
- {
- case kControlUpButtonPart: return scroll_bar_up_arrow;
- case kControlDownButtonPart: return scroll_bar_down_arrow;
- case kControlPageUpPart: return scroll_bar_above_handle;
- case kControlPageDownPart: return scroll_bar_below_handle;
- case kControlIndicatorPart: return scroll_bar_handle;
- }
-
- return -1;
-}
-
-static void
-construct_scroll_bar_click (bar, part, bufp)
- struct scroll_bar *bar;
- int part;
- struct input_event *bufp;
-{
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = bar->window;
- bufp->arg = Qnil;
- bufp->part = part;
- bufp->code = 0;
- XSETINT (bufp->x, 0);
- XSETINT (bufp->y, 0);
- bufp->modifiers = 0;
-}
-
-static OSStatus
-get_control_part_bounds (ch, part_code, rect)
- ControlRef ch;
- ControlPartCode part_code;
- Rect *rect;
-{
- RgnHandle region = NewRgn ();
- OSStatus err;
-
- err = GetControlRegion (ch, part_code, region);
- if (err == noErr)
- GetRegionBounds (region, rect);
- DisposeRgn (region);
-
- return err;
-}
-
-static void
-x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
- struct scroll_bar *bar;
- ControlPartCode part_code;
- Point mouse_pos;
- struct input_event *bufp;
-{
- int part = control_part_code_to_scroll_bar_part (part_code);
-
- if (part < 0)
- return;
-
- if (part != scroll_bar_handle)
- {
- construct_scroll_bar_click (bar, part, bufp);
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
- set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY);
- bar->dragging = Qnil;
- }
- else
- {
- Rect r;
-
- get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
- kControlIndicatorPart, &r);
- XSETINT (bar->dragging, - (mouse_pos.v - r.top) - 1);
- }
-
- last_scroll_bar_part = part;
- tracked_scroll_bar = bar;
-}
-
-static void
-x_scroll_bar_handle_release (bar, bufp)
- struct scroll_bar *bar;
- struct input_event *bufp;
-{
- if (last_scroll_bar_part != scroll_bar_handle
- || (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0))
- construct_scroll_bar_click (bar, scroll_bar_end_scroll, bufp);
-
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
- set_scroll_bar_timer (kEventDurationForever);
-
- last_scroll_bar_part = -1;
- bar->dragging = Qnil;
- tracked_scroll_bar = NULL;
-}
-
-static void
-x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
- WindowRef win;
- struct scroll_bar *bar;
- Point mouse_pos;
- struct input_event *bufp;
-{
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
-
- if (last_scroll_bar_part == scroll_bar_handle)
- {
- int top, top_range;
- Rect r;
-
- get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
- kControlIndicatorPart, &r);
-
- if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0)
- XSETINT (bar->dragging, - (XINT (bar->dragging) + 1));
-
- top = mouse_pos.v - XINT (bar->dragging) - XINT (bar->track_top);
- top_range = XINT (bar->track_height) - XINT (bar->min_handle);
-
- if (top < 0)
- top = 0;
- if (top > top_range)
- top = top_range;
-
- construct_scroll_bar_click (bar, scroll_bar_handle, bufp);
- XSETINT (bufp->x, top);
- XSETINT (bufp->y, top_range);
- }
- else
- {
- ControlPartCode part_code;
- int unhilite_p = 0, part;
-
- if (ch != FindControlUnderMouse (mouse_pos, win, &part_code))
- unhilite_p = 1;
- else
- {
- part = control_part_code_to_scroll_bar_part (part_code);
-
- switch (last_scroll_bar_part)
- {
- case scroll_bar_above_handle:
- case scroll_bar_below_handle:
- if (part != scroll_bar_above_handle
- && part != scroll_bar_below_handle)
- unhilite_p = 1;
- break;
-
- case scroll_bar_up_arrow:
- case scroll_bar_down_arrow:
- if (part != scroll_bar_up_arrow
- && part != scroll_bar_down_arrow)
- unhilite_p = 1;
- break;
- }
- }
-
- if (unhilite_p)
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
- else if (part != last_scroll_bar_part
- || scroll_bar_timer_event_posted_p)
- {
- construct_scroll_bar_click (bar, part, bufp);
- last_scroll_bar_part = part;
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
- set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY);
- }
- }
-}
-
-/* Set the thumb size and position of scroll bar BAR. We are currently
- displaying PORTION out of a whole WHOLE, and our position POSITION. */
-
-static void
-x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
- struct scroll_bar *bar;
- int portion, position, whole;
-{
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- int value, viewsize, maximum;
-
- if (XINT (bar->track_height) == 0)
- return;
-
- if (whole <= portion)
- value = 0, viewsize = 1, maximum = 0;
- else
- {
- float scale;
-
- maximum = XINT (bar->track_height) - XINT (bar->min_handle);
- scale = (float) maximum / (whole - portion);
- value = position * scale + 0.5f;
- viewsize = (int) (portion * scale + 0.5f) + XINT (bar->min_handle);
- }
-
- BLOCK_INPUT;
-
- if (GetControlViewSize (ch) != viewsize
- || GetControl32BitValue (ch) != value
- || GetControl32BitMaximum (ch) != maximum)
- {
- /* Temporarily hide the scroll bar to avoid multiple redraws. */
- SetControlVisibility (ch, false, false);
-
- SetControl32BitMaximum (ch, maximum);
- SetControl32BitValue (ch, value);
- SetControlViewSize (ch, viewsize);
-
- SetControlVisibility (ch, true, true);
- }
-
- UNBLOCK_INPUT;
-}
-
-#endif /* USE_TOOLKIT_SCROLL_BARS */
-
-
-
-/************************************************************************
- Scroll bars, general
- ************************************************************************/
-
-/* Create a scroll bar and return the scroll bar vector for it. W is
- the Emacs window on which to create the scroll bar. TOP, LEFT,
- WIDTH and HEIGHT are the pixel coordinates and dimensions of the
- scroll bar. */
-
-static struct scroll_bar *
-x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
- struct window *w;
- int top, left, width, height, disp_top, disp_height;
-{
- struct frame *f = XFRAME (w->frame);
- struct scroll_bar *bar
- = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
- Rect r;
- ControlRef ch;
-
- BLOCK_INPUT;
-
- r.left = left;
- r.top = disp_top;
- r.right = left + width;
- r.bottom = disp_top + disp_height;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
-#if TARGET_API_MAC_CARBON
- ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p",
-#ifdef USE_TOOLKIT_SCROLL_BARS
- false,
-#else
- width < disp_height,
-#endif
- 0, 0, 0, kControlScrollBarProc, (long) bar);
-#else
- ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height,
- 0, 0, 0, scrollBarProc, (long) bar);
-#endif
- SET_SCROLL_BAR_CONTROL_REF (bar, ch);
-
- XSETWINDOW (bar->window, w);
- XSETINT (bar->top, top);
- XSETINT (bar->left, left);
- XSETINT (bar->width, width);
- XSETINT (bar->height, height);
- XSETINT (bar->start, 0);
- XSETINT (bar->end, 0);
- bar->dragging = Qnil;
-#ifdef MAC_OSX
- bar->fringe_extended_p = Qnil;
-#endif
- bar->redraw_needed_p = Qnil;
-#ifdef USE_TOOLKIT_SCROLL_BARS
- bar->track_top = Qnil;
- bar->track_height = Qnil;
- bar->min_handle = Qnil;
-#endif
-
- /* Add bar to its frame's list of scroll bars. */
- bar->next = FRAME_SCROLL_BARS (f);
- bar->prev = Qnil;
- XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
- if (!NILP (bar->next))
- XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
-
- UNBLOCK_INPUT;
- return bar;
-}
-
-
-/* Draw BAR's handle in the proper position.
-
- If the handle is already drawn from START to END, don't bother
- redrawing it, unless REBUILD is non-zero; in that case, always
- redraw it. (REBUILD is handy for drawing the handle after expose
- events.)
-
- Normally, we want to constrain the start and end of the handle to
- fit inside its rectangle, but if the user is dragging the scroll
- bar handle, we want to let them drag it down all the way, so that
- the bar's top is as far down as it goes; otherwise, there's no way
- to move to the very end of the buffer. */
-
-#ifndef USE_TOOLKIT_SCROLL_BARS
-
-static void
-x_scroll_bar_set_handle (bar, start, end, rebuild)
- struct scroll_bar *bar;
- int start, end;
- int rebuild;
-{
- int dragging = ! NILP (bar->dragging);
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
- int length = end - start;
-
- /* If the display is already accurate, do nothing. */
- if (! rebuild
- && start == XINT (bar->start)
- && end == XINT (bar->end))
- return;
-
- BLOCK_INPUT;
-
- /* Make sure the values are reasonable, and try to preserve the
- distance between start and end. */
- if (start < 0)
- start = 0;
- else if (start > top_range)
- start = top_range;
- end = start + length;
-
- if (end < start)
- end = start;
- else if (end > top_range && ! dragging)
- end = top_range;
-
- /* Store the adjusted setting in the scroll bar. */
- XSETINT (bar->start, start);
- XSETINT (bar->end, end);
-
- /* Clip the end position, just for display. */
- if (end > top_range)
- end = top_range;
-
- /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
- top positions, to make sure the handle is always at least that
- many pixels tall. */
- end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
-
- SetControlMinimum (ch, 0);
- /* Don't inadvertently activate deactivated scroll bars */
- if (GetControlMaximum (ch) != -1)
- SetControlMaximum (ch, top_range + VERTICAL_SCROLL_BAR_MIN_HANDLE
- - (end - start));
- SetControlValue (ch, start);
-#if TARGET_API_MAC_CARBON
- SetControlViewSize (ch, end - start);
-#endif
-
- UNBLOCK_INPUT;
-}
-
-#endif /* !USE_TOOLKIT_SCROLL_BARS */
-
-/* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
- nil. */
-
-static void
-x_scroll_bar_remove (bar)
- struct scroll_bar *bar;
-{
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-
- BLOCK_INPUT;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- /* Destroy the Mac scroll bar control */
- DisposeControl (SCROLL_BAR_CONTROL_REF (bar));
-
- /* Disassociate this scroll bar from its window. */
- XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
-
- UNBLOCK_INPUT;
-}
-
-
-/* Set the handle of the vertical scroll bar for WINDOW to indicate
- that we are displaying PORTION characters out of a total of WHOLE
- characters, starting at POSITION. If WINDOW has no scroll bar,
- create one. */
-
-static void
-XTset_vertical_scroll_bar (w, portion, whole, position)
- struct window *w;
- int portion, whole, position;
-{
- struct frame *f = XFRAME (w->frame);
- struct scroll_bar *bar;
- int top, height, left, sb_left, width, sb_width, disp_top, disp_height;
- int window_y, window_height;
-#ifdef MAC_OSX
- int fringe_extended_p;
-#endif
-
- /* Get window dimensions. */
- window_box (w, -1, 0, &window_y, 0, &window_height);
- top = window_y;
- width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
- height = window_height;
-
- /* Compute the left edge of the scroll bar area. */
- left = WINDOW_SCROLL_BAR_AREA_X (w);
-
- /* Compute the width of the scroll bar which might be less than
- the width of the area reserved for the scroll bar. */
- if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
- sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
- else
- sb_width = width;
-
- /* Compute the left edge of the scroll bar. */
- if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
- else
- sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
-
- /* Adjustments according to Inside Macintosh to make it look nice */
- disp_top = top;
- disp_height = height;
-#ifdef MAC_OS8
- if (disp_top == 0)
- {
- disp_top = -1;
- disp_height++;
- }
- else if (disp_top == FRAME_PIXEL_HEIGHT (f) - 16)
- {
- disp_top++;
- disp_height--;
- }
-
- if (sb_left + sb_width == FRAME_PIXEL_WIDTH (f))
- sb_left++;
-#endif
-
-#ifdef MAC_OSX
- if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
- fringe_extended_p = (WINDOW_LEFTMOST_P (w)
- && WINDOW_LEFT_FRINGE_WIDTH (w)
- && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
- || WINDOW_LEFT_MARGIN_COLS (w) == 0));
- else
- fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
- && WINDOW_RIGHT_FRINGE_WIDTH (w)
- && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
- || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
-#endif
-
- /* Does the scroll bar exist yet? */
- if (NILP (w->vertical_scroll_bar))
- {
- BLOCK_INPUT;
-#ifdef MAC_OSX
- if (fringe_extended_p)
- mac_clear_area (f, sb_left, top, sb_width, height);
- else
-#endif
- mac_clear_area (f, left, top, width, height);
- UNBLOCK_INPUT;
- bar = x_scroll_bar_create (w, top, sb_left, sb_width, height, disp_top,
- disp_height);
- XSETVECTOR (w->vertical_scroll_bar, bar);
- }
- else
- {
- /* It may just need to be moved and resized. */
- ControlRef ch;
-
- bar = XSCROLL_BAR (w->vertical_scroll_bar);
- ch = SCROLL_BAR_CONTROL_REF (bar);
-
- BLOCK_INPUT;
-
- /* If already correctly positioned, do nothing. */
- if (XINT (bar->left) == sb_left
- && XINT (bar->top) == top
- && XINT (bar->width) == sb_width
- && XINT (bar->height) == height
-#ifdef MAC_OSX
- && !NILP (bar->fringe_extended_p) == fringe_extended_p
-#endif
- )
- {
- if (!NILP (bar->redraw_needed_p))
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- Draw1Control (SCROLL_BAR_CONTROL_REF (bar));
- }
- }
- else
- {
- /* Since toolkit scroll bars are smaller than the space reserved
- for them on the frame, we have to clear "under" them. */
-#ifdef MAC_OSX
- if (fringe_extended_p)
- mac_clear_area (f, sb_left, top, sb_width, height);
- else
-#endif
- mac_clear_area (f, left, top, width, height);
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- HideControl (ch);
- MoveControl (ch, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, disp_top);
- SizeControl (ch, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
- disp_height);
-#ifndef USE_TOOLKIT_SCROLL_BARS
- if (sb_width < disp_height)
- ShowControl (ch);
-#endif
-
- /* Remember new settings. */
- XSETINT (bar->left, sb_left);
- XSETINT (bar->top, top);
- XSETINT (bar->width, sb_width);
- XSETINT (bar->height, height);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- bar->track_top = Qnil;
- bar->track_height = Qnil;
- bar->min_handle = Qnil;
-#endif
- }
-
- UNBLOCK_INPUT;
- }
-
-#ifdef MAC_OSX
- bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
-#endif
-
- bar->redraw_needed_p = Qnil;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (NILP (bar->track_top))
- {
- if (sb_width >= disp_height
-#ifdef MAC_OSX
- || sb_width < MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
-#endif
- )
- {
- XSETINT (bar->track_top, 0);
- XSETINT (bar->track_height, 0);
- XSETINT (bar->min_handle, 0);
- }
- else
- {
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- Rect r0, r1;
-
- BLOCK_INPUT;
-
- SetControl32BitMinimum (ch, 0);
- SetControl32BitMaximum (ch, 1 << 30);
- SetControlViewSize (ch, 1);
-
- /* Move the scroll bar thumb to the top. */
- SetControl32BitValue (ch, 0);
- get_control_part_bounds (ch, kControlIndicatorPart, &r0);
-
- /* Move the scroll bar thumb to the bottom. */
- SetControl32BitValue (ch, 1 << 30);
- get_control_part_bounds (ch, kControlIndicatorPart, &r1);
-
- UnionRect (&r0, &r1, &r0);
- XSETINT (bar->track_top, r0.top);
- XSETINT (bar->track_height, r0.bottom - r0.top);
- XSETINT (bar->min_handle, r1.bottom - r1.top);
-
- /* Don't show the scroll bar if its height is not enough to
- display the scroll bar thumb. */
- if (r0.bottom - r0.top > 0)
- ShowControl (ch);
-
- UNBLOCK_INPUT;
- }
- }
-
- x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- /* Set the scroll bar's current state, unless we're currently being
- dragged. */
- if (NILP (bar->dragging))
- {
- int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
-
- if (whole == 0)
- x_scroll_bar_set_handle (bar, 0, top_range, 0);
- else
- {
- int start = ((double) position * top_range) / whole;
- int end = ((double) (position + portion) * top_range) / whole;
- x_scroll_bar_set_handle (bar, start, end, 0);
- }
- }
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
-}
-
-
-/* The following three hooks are used when we're doing a thorough
- redisplay of the frame. We don't explicitly know which scroll bars
- are going to be deleted, because keeping track of when windows go
- away is a real pain - "Can you say set-window-configuration, boys
- and girls?" Instead, we just assert at the beginning of redisplay
- that *all* scroll bars are to be removed, and then save a scroll bar
- from the fiery pit when we actually redisplay its window. */
-
-/* Arrange for all scroll bars on FRAME to be removed at the next call
- to `*judge_scroll_bars_hook'. A scroll bar may be spared if
- `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
-
-static void
-XTcondemn_scroll_bars (frame)
- FRAME_PTR frame;
-{
- /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
- while (! NILP (FRAME_SCROLL_BARS (frame)))
- {
- Lisp_Object bar;
- bar = FRAME_SCROLL_BARS (frame);
- FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
- XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
- XSCROLL_BAR (bar)->prev = Qnil;
- if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
- XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
- FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
- }
-}
-
-
-/* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
- Note that WINDOW isn't necessarily condemned at all. */
-
-static void
-XTredeem_scroll_bar (window)
- struct window *window;
-{
- struct scroll_bar *bar;
- struct frame *f;
-
- /* We can't redeem this window's scroll bar if it doesn't have one. */
- if (NILP (window->vertical_scroll_bar))
- abort ();
-
- bar = XSCROLL_BAR (window->vertical_scroll_bar);
-
- /* Unlink it from the condemned list. */
- f = XFRAME (WINDOW_FRAME (window));
- if (NILP (bar->prev))
- {
- /* If the prev pointer is nil, it must be the first in one of
- the lists. */
- if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
- /* It's not condemned. Everything's fine. */
- return;
- else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
- window->vertical_scroll_bar))
- FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
- else
- /* If its prev pointer is nil, it must be at the front of
- one or the other! */
- abort ();
- }
- else
- XSCROLL_BAR (bar->prev)->next = bar->next;
-
- if (! NILP (bar->next))
- XSCROLL_BAR (bar->next)->prev = bar->prev;
-
- bar->next = FRAME_SCROLL_BARS (f);
- bar->prev = Qnil;
- XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
- if (! NILP (bar->next))
- XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
-}
-
-/* Remove all scroll bars on FRAME that haven't been saved since the
- last call to `*condemn_scroll_bars_hook'. */
-
-static void
-XTjudge_scroll_bars (f)
- FRAME_PTR f;
-{
- Lisp_Object bar, next;
-
- bar = FRAME_CONDEMNED_SCROLL_BARS (f);
-
- /* Clear out the condemned list now so we won't try to process any
- more events on the hapless scroll bars. */
- FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
-
- for (; ! NILP (bar); bar = next)
- {
- struct scroll_bar *b = XSCROLL_BAR (bar);
-
- x_scroll_bar_remove (b);
-
- next = b->next;
- b->next = b->prev = Qnil;
- }
-
- /* Now there should be no references to the condemned scroll bars,
- and they should get garbage-collected. */
-}
-
-
-/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
- is set to something other than NO_EVENT, it is enqueued.
-
- This may be called from a signal handler, so we have to ignore GC
- mark bits. */
-
-static void
-x_scroll_bar_handle_click (bar, part_code, er, bufp)
- struct scroll_bar *bar;
- ControlPartCode part_code;
- const EventRecord *er;
- struct input_event *bufp;
-{
- int win_y, top_range;
-
- if (! WINDOWP (bar->window))
- abort ();
-
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = bar->window;
- bufp->arg = Qnil;
-
- bar->dragging = Qnil;
-
- switch (part_code)
- {
- case kControlUpButtonPart:
- bufp->part = scroll_bar_up_arrow;
- break;
- case kControlDownButtonPart:
- bufp->part = scroll_bar_down_arrow;
- break;
- case kControlPageUpPart:
- bufp->part = scroll_bar_above_handle;
- break;
- case kControlPageDownPart:
- bufp->part = scroll_bar_below_handle;
- break;
-#if TARGET_API_MAC_CARBON
- default:
-#else
- case kControlIndicatorPart:
-#endif
- if (er->what == mouseDown)
- bar->dragging = make_number (0);
- XSETVECTOR (last_mouse_scroll_bar, bar);
- bufp->part = scroll_bar_handle;
- break;
- }
-
- win_y = XINT (bufp->y) - XINT (bar->top);
- top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar->height));
-
- win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
-
- win_y -= 24;
-
- if (! NILP (bar->dragging))
- win_y -= XINT (bar->dragging);
-
- if (win_y < 0)
- win_y = 0;
- if (win_y > top_range)
- win_y = top_range;
-
- XSETINT (bufp->x, win_y);
- XSETINT (bufp->y, top_range);
-}
-
-#ifndef USE_TOOLKIT_SCROLL_BARS
-
-/* Handle some mouse motion while someone is dragging the scroll bar.
-
- This may be called from a signal handler, so we have to ignore GC
- mark bits. */
-
-static void
-x_scroll_bar_note_movement (bar, y_pos, t)
- struct scroll_bar *bar;
- int y_pos;
- Time t;
-{
- FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
-
- last_mouse_movement_time = t;
-
- f->mouse_moved = 1;
- XSETVECTOR (last_mouse_scroll_bar, bar);
-
- /* If we're dragging the bar, display it. */
- if (! NILP (bar->dragging))
- {
- /* Where should the handle be now? */
- int new_start = y_pos - 24;
-
- if (new_start != XINT (bar->start))
- {
- int new_end = new_start + (XINT (bar->end) - XINT (bar->start));
-
- x_scroll_bar_set_handle (bar, new_start, new_end, 0);
- }
- }
-}
-
-#endif /* !USE_TOOLKIT_SCROLL_BARS */
-
-/* Return information to the user about the current position of the mouse
- on the scroll bar. */
-
-static void
-x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
- FRAME_PTR *fp;
- Lisp_Object *bar_window;
- enum scroll_bar_part *part;
- Lisp_Object *x, *y;
- unsigned long *time;
-{
- struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
-#if TARGET_API_MAC_CARBON
- WindowRef wp = GetControlOwner (ch);
-#else
- WindowRef wp = (*ch)->contrlOwner;
-#endif
- Point mouse_pos;
- struct frame *f = mac_window_to_frame (wp);
- int win_y, top_range;
-
-#if TARGET_API_MAC_CARBON
- GetGlobalMouse (&mouse_pos);
- mouse_pos.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- mouse_pos.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-#else
- SetPortWindowPort (wp);
- GetMouse (&mouse_pos);
-#endif
-
- win_y = mouse_pos.v - XINT (bar->top);
- top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
-
- win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
-
- win_y -= 24;
-
- if (! NILP (bar->dragging))
- win_y -= XINT (bar->dragging);
-
- if (win_y < 0)
- win_y = 0;
- if (win_y > top_range)
- win_y = top_range;
-
- *fp = f;
- *bar_window = bar->window;
-
- if (! NILP (bar->dragging))
- *part = scroll_bar_handle;
- else if (win_y < XINT (bar->start))
- *part = scroll_bar_above_handle;
- else if (win_y < XINT (bar->end) + VERTICAL_SCROLL_BAR_MIN_HANDLE)
- *part = scroll_bar_handle;
- else
- *part = scroll_bar_below_handle;
-
- XSETINT (*x, win_y);
- XSETINT (*y, top_range);
-
- f->mouse_moved = 0;
- last_mouse_scroll_bar = Qnil;
-
- *time = last_mouse_movement_time;
-}
-
-
-/* The screen has been cleared so we may have changed foreground or
- background colors, and the scroll bars may need to be redrawn.
- Clear out the scroll bars, and ask for expose events, so we can
- redraw them. */
-
-void
-x_scroll_bar_clear (f)
- FRAME_PTR f;
-{
- Lisp_Object bar;
-
- /* We can have scroll bars even if this is 0,
- if we just turned off scroll bar mode.
- But in that case we should not clear them. */
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
- for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
- bar = XSCROLL_BAR (bar)->next)
- XSCROLL_BAR (bar)->redraw_needed_p = Qt;
-}
-
-
-/***********************************************************************
- Tool-bars
- ***********************************************************************/
-#if USE_MAC_TOOLBAR
-
-/* In identifiers such as function/variable names, Emacs tool bar is
- referred to as `tool_bar', and Carbon HIToolbar as `toolbar'. */
-
-#define TOOLBAR_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar"))
-#define TOOLBAR_ICON_ITEM_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar.icon"))
-
-#define TOOLBAR_ITEM_COMMAND_ID_OFFSET 'Tb\0\0'
-#define TOOLBAR_ITEM_COMMAND_ID_P(id) \
- (((id) & ~0xffff) == TOOLBAR_ITEM_COMMAND_ID_OFFSET)
-#define TOOLBAR_ITEM_COMMAND_ID_VALUE(id) \
- ((id) - TOOLBAR_ITEM_COMMAND_ID_OFFSET)
-#define TOOLBAR_ITEM_MAKE_COMMAND_ID(value) \
- ((value) + TOOLBAR_ITEM_COMMAND_ID_OFFSET)
-
-static int mac_event_to_emacs_modifiers P_ ((EventRef));
-static void mac_handle_origin_change P_ ((struct frame *));
-static OSStatus mac_handle_toolbar_command_event P_ ((EventHandlerCallRef,
- EventRef, void *));
-
-static void
-mac_move_window_with_gravity (f, win_gravity, left, top)
- struct frame *f;
- int win_gravity;
- short left, top;
-{
- Rect inner, outer;
-
- mac_get_window_bounds (f, &inner, &outer);
-
- switch (win_gravity)
- {
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- left += inner.left - outer.left;
- break;
-
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- left += ((inner.left - outer.left) + (inner.right - outer.right)) / 2;
- break;
-
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- left += inner.right - outer.right;
- break;
- }
-
- switch (win_gravity)
- {
- case NorthWestGravity:
- case NorthGravity:
- case NorthEastGravity:
- top += inner.top - outer.top;
- break;
-
- case WestGravity:
- case CenterGravity:
- case EastGravity:
- top += ((inner.top - outer.top) + (inner.bottom - outer.bottom)) / 2;
- break;
-
- case SouthWestGravity:
- case SouthGravity:
- case SouthEastGravity:
- top += inner.bottom - outer.bottom;
- break;
- }
-
- MoveWindow (FRAME_MAC_WINDOW (f), left, top, false);
-}
-
-static void
-mac_get_window_origin_with_gravity (f, win_gravity, left, top)
- struct frame *f;
- int win_gravity;
- short *left, *top;
-{
- Rect inner, outer;
-
- mac_get_window_bounds (f, &inner, &outer);
-
- switch (win_gravity)
- {
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- *left = outer.left;
- break;
-
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- *left = outer.left + ((outer.right - outer.left)
- - (inner.right - inner.left)) / 2;
- break;
-
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- *left = outer.right - (inner.right - inner.left);
- break;
- }
-
- switch (win_gravity)
- {
- case NorthWestGravity:
- case NorthGravity:
- case NorthEastGravity:
- *top = outer.top;
- break;
-
- case WestGravity:
- case CenterGravity:
- case EastGravity:
- *top = outer.top + ((outer.bottom - outer.top)
- - (inner.bottom - inner.top)) / 2;
- break;
-
- case SouthWestGravity:
- case SouthGravity:
- case SouthEastGravity:
- *top = outer.bottom - (inner.bottom - inner.top);
- break;
- }
-}
-
-static OSStatus
-mac_handle_toolbar_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
- case kEventToolbarGetDefaultIdentifiers:
- result = noErr;
- break;
-
- case kEventToolbarGetAllowedIdentifiers:
- {
- CFMutableArrayRef array;
-
- GetEventParameter (event, kEventParamMutableArray,
- typeCFMutableArrayRef, NULL,
- sizeof (CFMutableArrayRef), NULL, &array);
- CFArrayAppendValue (array, TOOLBAR_ICON_ITEM_IDENTIFIER);
- result = noErr;
- }
- break;
-
- case kEventToolbarCreateItemWithIdentifier:
- {
- CFStringRef identifier;
- HIToolbarItemRef item = NULL;
-
- GetEventParameter (event, kEventParamToolbarItemIdentifier,
- typeCFStringRef, NULL,
- sizeof (CFStringRef), NULL, &identifier);
-
- if (CFStringCompare (identifier, TOOLBAR_ICON_ITEM_IDENTIFIER, 0)
- == kCFCompareEqualTo)
- HIToolbarItemCreate (identifier,
- kHIToolbarItemAllowDuplicates
- | kHIToolbarItemCantBeRemoved, &item);
-
- if (item)
- {
- SetEventParameter (event, kEventParamToolbarItem,
- typeHIToolbarItemRef,
- sizeof (HIToolbarItemRef), &item);
- result = noErr;
- }
- }
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-static CGImageRef
-mac_image_spec_to_cg_image (f, image)
- struct frame *f;
- Lisp_Object image;
-{
- if (!valid_image_p (image))
- return NULL;
- else
- {
- int img_id = lookup_image (f, image);
- struct image *img = IMAGE_FROM_ID (f, img_id);
-
- prepare_image_for_display (f, img);
-
- return img->data.ptr_val;
- }
-}
-
-/* Create a tool bar for frame F. */
-
-static OSStatus
-mac_create_frame_tool_bar (f)
- FRAME_PTR f;
-{
- OSStatus err;
- HIToolbarRef toolbar;
-
- err = HIToolbarCreate (TOOLBAR_IDENTIFIER, kHIToolbarNoAttributes,
- &toolbar);
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassToolbar, kEventToolbarGetDefaultIdentifiers},
- {kEventClassToolbar, kEventToolbarGetAllowedIdentifiers},
- {kEventClassToolbar, kEventToolbarCreateItemWithIdentifier}};
-
- err = InstallEventHandler (HIObjectGetEventTarget (toolbar),
- mac_handle_toolbar_event,
- GetEventTypeCount (specs), specs,
- f, NULL);
- }
-
- if (err == noErr)
- err = HIToolbarSetDisplayMode (toolbar, kHIToolbarDisplayModeIconOnly);
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess}};
-
- err = InstallWindowEventHandler (FRAME_MAC_WINDOW (f),
- mac_handle_toolbar_command_event,
- GetEventTypeCount (specs),
- specs, f, NULL);
- }
- if (err == noErr)
- err = SetWindowToolbar (FRAME_MAC_WINDOW (f), toolbar);
-
- if (toolbar)
- CFRelease (toolbar);
-
- return err;
-}
-
-/* Update the tool bar for frame F. Add new buttons and remove old. */
-
-void
-update_frame_tool_bar (f)
- FRAME_PTR f;
-{
- HIToolbarRef toolbar = NULL;
- short left, top;
- CFArrayRef old_items = NULL;
- CFIndex old_count;
- int i, pos, win_gravity = f->output_data.mac->toolbar_win_gravity;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- BLOCK_INPUT;
-
- GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
- if (toolbar == NULL)
- {
- mac_create_frame_tool_bar (f);
- GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
- if (toolbar == NULL)
- goto out;
- if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
- mac_get_window_origin_with_gravity (f, win_gravity, &left, &top);
- }
-
- HIToolbarCopyItems (toolbar, &old_items);
- if (old_items == NULL)
- goto out;
-
- old_count = CFArrayGetCount (old_items);
- pos = 0;
- for (i = 0; i < f->n_tool_bar_items; ++i)
- {
-#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
-
- int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
- int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
- int idx;
- Lisp_Object image;
- CGImageRef cg_image;
- CFStringRef label;
- HIToolbarItemRef item;
-
- /* If image is a vector, choose the image according to the
- button state. */
- image = PROP (TOOL_BAR_ITEM_IMAGES);
- if (VECTORP (image))
- {
- if (enabled_p)
- idx = (selected_p
- ? TOOL_BAR_IMAGE_ENABLED_SELECTED
- : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
- else
- idx = (selected_p
- ? TOOL_BAR_IMAGE_DISABLED_SELECTED
- : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
-
- xassert (ASIZE (image) >= idx);
- image = AREF (image, idx);
- }
- else
- idx = -1;
-
- cg_image = mac_image_spec_to_cg_image (f, image);
- /* Ignore invalid image specifications. */
- if (cg_image == NULL)
- continue;
-
- label = cfstring_create_with_string (PROP (TOOL_BAR_ITEM_CAPTION));
- if (label == NULL)
- label = CFSTR ("");
-
- if (pos < old_count)
- {
- CGImageRef old_cg_image = NULL;
- CFStringRef old_label = NULL;
- Boolean old_enabled_p;
-
- item = (HIToolbarItemRef) CFArrayGetValueAtIndex (old_items, pos);
-
- HIToolbarItemCopyImage (item, &old_cg_image);
- if (cg_image != old_cg_image)
- HIToolbarItemSetImage (item, cg_image);
- CGImageRelease (old_cg_image);
-
- HIToolbarItemCopyLabel (item, &old_label);
- if (CFStringCompare (label, old_label, 0) != kCFCompareEqualTo)
- HIToolbarItemSetLabel (item, label);
- CFRelease (old_label);
-
- old_enabled_p = HIToolbarItemIsEnabled (item);
- if ((enabled_p || idx >= 0) != old_enabled_p)
- HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
- }
- else
- {
- item = NULL;
- HIToolbarCreateItemWithIdentifier (toolbar,
- TOOLBAR_ICON_ITEM_IDENTIFIER,
- NULL, &item);
- if (item)
- {
- HIToolbarItemSetImage (item, cg_image);
- HIToolbarItemSetLabel (item, label);
- HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
- HIToolbarAppendItem (toolbar, item);
- CFRelease (item);
- }
- }
-
- CFRelease (label);
- if (item)
- {
- HIToolbarItemSetCommandID (item, TOOLBAR_ITEM_MAKE_COMMAND_ID (i));
- pos++;
- }
- }
-
- CFRelease (old_items);
-
- while (pos < old_count)
- HIToolbarRemoveItemAtIndex (toolbar, --old_count);
-
- ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), true,
- !win_gravity && f == mac_focus_frame (dpyinfo));
- /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events on
- toolbar visibility change. */
- mac_handle_origin_change (f);
- if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
- {
- mac_move_window_with_gravity (f, win_gravity, left, top);
- /* If the title bar is completely outside the screen, adjust the
- position. */
- ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
- kWindowConstrainMoveRegardlessOfFit
- | kWindowConstrainAllowPartial, NULL, NULL);
- f->output_data.mac->toolbar_win_gravity = 0;
- }
-
- out:
- UNBLOCK_INPUT;
-}
-
-/* Hide the tool bar on frame F. Unlike the counterpart on GTK+, it
- doesn't deallocate the resources. */
-
-void
-free_frame_tool_bar (f)
- FRAME_PTR f;
-{
- if (IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
- {
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- BLOCK_INPUT;
- ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), false,
- (NILP (Fsymbol_value
- (intern ("frame-notice-user-settings")))
- && f == mac_focus_frame (dpyinfo)));
- /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events
- on toolbar visibility change. */
- mac_handle_origin_change (f);
- UNBLOCK_INPUT;
- }
-}
-
-static void
-mac_tool_bar_note_mouse_movement (f, event)
- struct frame *f;
- EventRef event;
-{
- OSStatus err;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- int mouse_down_p;
- HIViewRef item_view;
- UInt32 command_id;
-
- mouse_down_p = (dpyinfo->grabbed
- && f == last_mouse_frame
- && FRAME_LIVE_P (f));
- if (mouse_down_p)
- return;
-
- err = HIViewGetViewForMouseEvent (HIViewGetRoot (FRAME_MAC_WINDOW (f)),
- event, &item_view);
- /* This doesn't work on Mac OS X 10.2. On Mac OS X 10.3 and 10.4, a
- toolbar item view seems to have the same command ID with that of
- the toolbar item. */
- if (err == noErr)
- err = GetControlCommandID (item_view, &command_id);
- if (err == noErr && TOOLBAR_ITEM_COMMAND_ID_P (command_id))
- {
- int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command_id);
-
- if (i < f->n_tool_bar_items)
- {
- HIRect bounds;
- HIViewRef content_view;
-
- err = HIViewGetBounds (item_view, &bounds);
- if (err == noErr)
- err = HIViewFindByID (HIViewGetRoot (FRAME_MAC_WINDOW (f)),
- kHIViewWindowContentID, &content_view);
- if (err == noErr)
- err = HIViewConvertRect (&bounds, item_view, content_view);
- if (err == noErr)
- SetRect (&last_mouse_glyph,
- CGRectGetMinX (bounds), CGRectGetMinY (bounds),
- CGRectGetMaxX (bounds), CGRectGetMaxY (bounds));
-
- help_echo_object = help_echo_window = Qnil;
- help_echo_pos = -1;
- help_echo_string = PROP (TOOL_BAR_ITEM_HELP);
- if (NILP (help_echo_string))
- help_echo_string = PROP (TOOL_BAR_ITEM_CAPTION);
- }
- }
-}
-
-static OSStatus
-mac_handle_toolbar_command_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- struct frame *f = (struct frame *) data;
- HICommand command;
-
- err = GetEventParameter (event, kEventParamDirectObject,
- typeHICommand, NULL,
- sizeof (HICommand), NULL, &command);
- if (err != noErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventCommandProcess:
- if (!TOOLBAR_ITEM_COMMAND_ID_P (command.commandID))
- result = CallNextEventHandler (next_handler, event);
- else
- {
- int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command.commandID);
-
- if (i < f->n_tool_bar_items
- && !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)))
- {
- Lisp_Object frame;
- struct input_event buf;
-
- EVENT_INIT (buf);
-
- XSETFRAME (frame, f);
- buf.kind = TOOL_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = frame;
- kbd_buffer_store_event (&buf);
-
- buf.kind = TOOL_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = PROP (TOOL_BAR_ITEM_KEY);
- buf.modifiers = mac_event_to_emacs_modifiers (event);
- kbd_buffer_store_event (&buf);
-
- result = noErr;
- }
- }
- break;
-
- default:
- abort ();
- }
-#undef PROP
-
- return result;
-}
-#endif /* USE_MAC_TOOLBAR */
-
-
-/***********************************************************************
- Text Cursor
- ***********************************************************************/
-
-/* Set clipping for output in glyph row ROW. W is the window in which
- we operate. GC is the graphics context to set clipping in.
-
- ROW may be a text row or, e.g., a mode line. Text rows must be
- clipped to the interior of the window dedicated to text display,
- mode lines must be clipped to the whole window. */
-
-static void
-x_clip_to_row (w, row, area, gc)
- struct window *w;
- struct glyph_row *row;
- int area;
- GC gc;
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- Rect clip_rect;
- int window_x, window_y, window_width;
-
- window_box (w, area, &window_x, &window_y, &window_width, 0);
-
- clip_rect.left = window_x;
- clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
- clip_rect.top = max (clip_rect.top, window_y);
- clip_rect.right = clip_rect.left + window_width;
- clip_rect.bottom = clip_rect.top + row->visible_height;
-
- mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f), gc, &clip_rect, 1);
-}
-
-
-/* Draw a hollow box cursor on window W in glyph row ROW. */
-
-static void
-x_draw_hollow_cursor (w, row)
- struct window *w;
- struct glyph_row *row;
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- Display *dpy = FRAME_MAC_DISPLAY (f);
- int x, y, wd, h;
- XGCValues xgcv;
- struct glyph *cursor_glyph;
- GC gc;
-
- /* Get the glyph the cursor is on. If we can't tell because
- the current matrix is invalid or such, give up. */
- cursor_glyph = get_phys_cursor_glyph (w);
- if (cursor_glyph == NULL)
- return;
-
- /* Compute frame-relative coordinates for phys cursor. */
- get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
- wd = w->phys_cursor_width;
-
- /* The foreground of cursor_gc is typically the same as the normal
- background color, which can cause the cursor box to be invisible. */
- xgcv.foreground = f->output_data.mac->cursor_pixel;
- if (dpyinfo->scratch_cursor_gc)
- XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground, &xgcv);
- else
- dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_MAC_WINDOW (f),
- GCForeground, &xgcv);
- gc = dpyinfo->scratch_cursor_gc;
-
- /* Set clipping, draw the rectangle, and reset clipping again. */
- x_clip_to_row (w, row, TEXT_AREA, gc);
- mac_draw_rectangle (f, gc, x, y, wd, h - 1);
- mac_reset_clip_rectangles (dpy, gc);
-}
-
-
-/* Draw a bar cursor on window W in glyph row ROW.
-
- Implementation note: One would like to draw a bar cursor with an
- angle equal to the one given by the font property XA_ITALIC_ANGLE.
- Unfortunately, I didn't find a font yet that has this property set.
- --gerd. */
-
-static void
-x_draw_bar_cursor (w, row, width, kind)
- struct window *w;
- struct glyph_row *row;
- int width;
- enum text_cursor_kinds kind;
-{
- struct frame *f = XFRAME (w->frame);
- struct glyph *cursor_glyph;
-
- /* If cursor is out of bounds, don't draw garbage. This can happen
- in mini-buffer windows when switching between echo area glyphs
- and mini-buffer. */
- cursor_glyph = get_phys_cursor_glyph (w);
- if (cursor_glyph == NULL)
- return;
-
- /* If on an image, draw like a normal cursor. That's usually better
- visible than drawing a bar, esp. if the image is large so that
- the bar might not be in the window. */
- if (cursor_glyph->type == IMAGE_GLYPH)
- {
- struct glyph_row *row;
- row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
- draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
- }
- else
- {
- Display *dpy = FRAME_MAC_DISPLAY (f);
- Window window = FRAME_MAC_WINDOW (f);
- GC gc = FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc;
- unsigned long mask = GCForeground | GCBackground;
- struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
- XGCValues xgcv;
-
- /* If the glyph's background equals the color we normally draw
- the bar cursor in, the bar cursor in its normal color is
- invisible. Use the glyph's foreground color instead in this
- case, on the assumption that the glyph's colors are chosen so
- that the glyph is legible. */
- if (face->background == f->output_data.mac->cursor_pixel)
- xgcv.background = xgcv.foreground = face->foreground;
- else
- xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel;
-
- if (gc)
- XChangeGC (dpy, gc, mask, &xgcv);
- else
- {
- gc = XCreateGC (dpy, window, mask, &xgcv);
- FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
- }
-
- if (width < 0)
- width = FRAME_CURSOR_WIDTH (f);
- width = min (cursor_glyph->pixel_width, width);
-
- w->phys_cursor_width = width;
- x_clip_to_row (w, row, TEXT_AREA, gc);
-
- if (kind == BAR_CURSOR)
- mac_fill_rectangle (f, gc,
- WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
- WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
- width, row->height);
- else
- mac_fill_rectangle (f, gc,
- WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
- WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
- row->height - width),
- cursor_glyph->pixel_width,
- width);
-
- mac_reset_clip_rectangles (f, gc);
- }
-}
-
-
-/* RIF: Define cursor CURSOR on frame F. */
-
-static void
-mac_define_frame_cursor (f, cursor)
- struct frame *f;
- Cursor cursor;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- if (dpyinfo->x_focus_frame == f)
- SetThemeCursor (cursor);
-}
-
-
-/* RIF: Clear area on frame F. */
-
-static void
-mac_clear_frame_area (f, x, y, width, height)
- struct frame *f;
- int x, y, width, height;
-{
- mac_clear_area (f, x, y, width, height);
-}
-
-
-/* RIF: Draw cursor on window W. */
-
-static void
-mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, active_p)
- struct window *w;
- struct glyph_row *glyph_row;
- int x, y;
- int cursor_type, cursor_width;
- int on_p, active_p;
-{
- if (on_p)
- {
- w->phys_cursor_type = cursor_type;
- w->phys_cursor_on_p = 1;
-
- if (glyph_row->exact_window_width_line_p
- && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
- {
- glyph_row->cursor_in_fringe_p = 1;
- draw_fringe_bitmap (w, glyph_row, 0);
- }
- else
- switch (cursor_type)
- {
- case HOLLOW_BOX_CURSOR:
- x_draw_hollow_cursor (w, glyph_row);
- break;
-
- case FILLED_BOX_CURSOR:
- draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
- break;
-
- case BAR_CURSOR:
- x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
- break;
-
- case HBAR_CURSOR:
- x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
- break;
-
- case NO_CURSOR:
- w->phys_cursor_width = 0;
- break;
-
- default:
- abort ();
- }
- }
-}
-
-
-/* Icons. */
-
-#if 0 /* MAC_TODO: no icon support yet. */
-int
-x_bitmap_icon (f, icon)
- struct frame *f;
- Lisp_Object icon;
-{
- HANDLE hicon;
-
- if (FRAME_W32_WINDOW (f) == 0)
- return 1;
-
- if (NILP (icon))
- hicon = LoadIcon (hinst, EMACS_CLASS);
- else if (STRINGP (icon))
- hicon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
- LR_DEFAULTSIZE | LR_LOADFROMFILE);
- else if (SYMBOLP (icon))
- {
- LPCTSTR name;
-
- if (EQ (icon, intern ("application")))
- name = (LPCTSTR) IDI_APPLICATION;
- else if (EQ (icon, intern ("hand")))
- name = (LPCTSTR) IDI_HAND;
- else if (EQ (icon, intern ("question")))
- name = (LPCTSTR) IDI_QUESTION;
- else if (EQ (icon, intern ("exclamation")))
- name = (LPCTSTR) IDI_EXCLAMATION;
- else if (EQ (icon, intern ("asterisk")))
- name = (LPCTSTR) IDI_ASTERISK;
- else if (EQ (icon, intern ("winlogo")))
- name = (LPCTSTR) IDI_WINLOGO;
- else
- return 1;
-
- hicon = LoadIcon (NULL, name);
- }
- else
- return 1;
-
- if (hicon == NULL)
- return 1;
-
- PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
- (LPARAM) hicon);
-
- return 0;
-}
-#endif /* MAC_TODO */
-
-/************************************************************************
- Handling X errors
- ************************************************************************/
-
-/* Display Error Handling functions not used on W32. Listing them here
- helps diff stay in step when comparing w32term.c with xterm.c.
-
-x_error_catcher (display, error)
-x_catch_errors (dpy)
-x_catch_errors_unwind (old_val)
-x_check_errors (dpy, format)
-x_had_errors_p (dpy)
-x_clear_errors (dpy)
-x_uncatch_errors (dpy, count)
-x_trace_wire ()
-x_connection_signal (signalnum)
-x_connection_closed (dpy, error_message)
-x_error_quitter (display, error)
-x_error_handler (display, error)
-x_io_error_quitter (display)
-
- */
-
-
-/* Changing the font of the frame. */
-
-/* Give frame F the font named FONTNAME as its default font, and
- return the full name of that font. FONTNAME may be a wildcard
- pattern; in that case, we choose some font that fits the pattern.
- The return value shows which font we chose. */
-
-Lisp_Object
-x_new_font (f, fontname)
- struct frame *f;
- register char *fontname;
-{
- struct font_info *fontp
- = FS_LOAD_FONT (f, fontname);
-
- if (!fontp)
- return Qnil;
-
- if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
- /* This font is already set in frame F. There's nothing more to
- do. */
- return build_string (fontp->full_name);
-
- FRAME_FONT (f) = (XFontStruct *) (fontp->font);
- FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
- FRAME_FONTSET (f) = -1;
-
- FRAME_COLUMN_WIDTH (f) = fontp->average_width;
- FRAME_SPACE_WIDTH (f) = fontp->space_width;
- FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
-
- compute_fringe_widths (f, 1);
-
- /* Compute the scroll bar width in character columns. */
- if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
- {
- int wid = FRAME_COLUMN_WIDTH (f);
- FRAME_CONFIG_SCROLL_BAR_COLS (f)
- = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
- }
- else
- {
- int wid = FRAME_COLUMN_WIDTH (f);
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
- }
-
- /* Now make the frame display the given font. */
- if (FRAME_MAC_WINDOW (f) != 0)
- {
- XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->normal_gc,
- FRAME_FONT (f));
- XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->reverse_gc,
- FRAME_FONT (f));
- XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc,
- FRAME_FONT (f));
-
- /* Don't change the size of a tip frame; there's no point in
- doing it because it's done in Fx_show_tip, and it leads to
- problems because the tip frame has no widget. */
- if (NILP (tip_frame) || XFRAME (tip_frame) != f)
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
- }
-
- return build_string (fontp->full_name);
-}
-
-/* Give frame F the fontset named FONTSETNAME as its default fontset,
- and return the full name of that fontset. FONTSETNAME may be a
- wildcard pattern; in that case, we choose some fontset that fits
- the pattern. FONTSETNAME may be a font name for ASCII characters;
- in that case, we create a fontset from that font name.
-
- The return value shows which fontset we chose.
- If FONTSETNAME specifies the default fontset, return Qt.
- If an ASCII font in the specified fontset can't be loaded, return
- Qnil. */
-
-Lisp_Object
-x_new_fontset (f, fontsetname)
- struct frame *f;
- Lisp_Object fontsetname;
-{
- int fontset = fs_query_fontset (fontsetname, 0);
- Lisp_Object result;
-
- if (fontset > 0 && FRAME_FONTSET(f) == fontset)
- /* This fontset is already set in frame F. There's nothing more
- to do. */
- return fontset_name (fontset);
- else if (fontset == 0)
- /* The default fontset can't be the default font. */
- return Qt;
-
- if (fontset > 0)
- result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
- else
- result = x_new_font (f, SDATA (fontsetname));
-
- if (!STRINGP (result))
- /* Can't load ASCII font. */
- return Qnil;
-
- if (fontset < 0)
- fontset = new_fontset_from_font_name (result);
-
- /* Since x_new_font doesn't update any fontset information, do it now. */
- FRAME_FONTSET (f) = fontset;
-
- return fontset_name (fontset);
-}
-
-
-/***********************************************************************
- TODO: W32 Input Methods
- ***********************************************************************/
-/* Listing missing functions from xterm.c helps diff stay in step.
-
-xim_destroy_callback (xim, client_data, call_data)
-xim_open_dpy (dpyinfo, resource_name)
-struct xim_inst_t
-xim_instantiate_callback (display, client_data, call_data)
-xim_initialize (dpyinfo, resource_name)
-xim_close_dpy (dpyinfo)
-
- */
-
-
-void
-mac_get_window_bounds (f, inner, outer)
- struct frame *f;
- Rect *inner, *outer;
-{
-#if TARGET_API_MAC_CARBON
- GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowContentRgn, inner);
- GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
-#else /* not TARGET_API_MAC_CARBON */
- RgnHandle region = NewRgn ();
-
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
- *inner = (*region)->rgnBBox;
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
- *outer = (*region)->rgnBBox;
- DisposeRgn (region);
-#endif /* not TARGET_API_MAC_CARBON */
-}
-
-static void
-mac_handle_origin_change (f)
- struct frame *f;
-{
- x_real_positions (f, &f->left_pos, &f->top_pos);
-}
-
-static void
-mac_handle_size_change (f, pixelwidth, pixelheight)
- struct frame *f;
- int pixelwidth, pixelheight;
-{
- int cols, rows;
-
- cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
-
- if (cols != FRAME_COLS (f)
- || rows != FRAME_LINES (f)
- || pixelwidth != FRAME_PIXEL_WIDTH (f)
- || pixelheight != FRAME_PIXEL_HEIGHT (f))
- {
- /* We pass 1 for DELAY since we can't run Lisp code inside of
- a BLOCK_INPUT. */
- change_frame_size (f, rows, cols, 0, 1, 0);
- FRAME_PIXEL_WIDTH (f) = pixelwidth;
- FRAME_PIXEL_HEIGHT (f) = pixelheight;
-
- /* If cursor was outside the new size, mark it as off. */
- mark_window_cursors_off (XWINDOW (f->root_window));
-
- /* Clear out any recollection of where the mouse highlighting
- was, since it might be in a place that's outside the new
- frame size. Actually checking whether it is outside is a
- pain in the neck, so don't try--just let the highlighting be
- done afresh with new size. */
- cancel_mouse_face (f);
-
-#if TARGET_API_MAC_CARBON
- if (f->output_data.mac->hourglass_control)
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- MoveControl (f->output_data.mac->hourglass_control,
- pixelwidth - HOURGLASS_WIDTH, 0);
- }
-#endif
- }
-}
-
-
-/* Calculate the absolute position in frame F
- from its current recorded position values and gravity. */
-
-void
-x_calc_absolute_position (f)
- struct frame *f;
-{
- int flags = f->size_hint_flags;
- Rect inner, outer;
-
- /* We have nothing to do if the current position
- is already for the top-left corner. */
- if (! ((flags & XNegative) || (flags & YNegative)))
- return;
-
- /* Find the offsets of the outside upper-left corner of
- the inner window, with respect to the outer window. */
- BLOCK_INPUT;
- mac_get_window_bounds (f, &inner, &outer);
- UNBLOCK_INPUT;
-
- /* Treat negative positions as relative to the leftmost bottommost
- position that fits on the screen. */
- if (flags & XNegative)
- f->left_pos += (FRAME_MAC_DISPLAY_INFO (f)->width
- - (outer.right - outer.left));
-
- if (flags & YNegative)
- f->top_pos += (FRAME_MAC_DISPLAY_INFO (f)->height
- - (outer.bottom - outer.top));
-
- /* The left_pos and top_pos
- are now relative to the top and left screen edges,
- so the flags should correspond. */
- f->size_hint_flags &= ~ (XNegative | YNegative);
-}
-
-/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
- to really change the position, and 0 when calling from
- x_make_frame_visible (in that case, XOFF and YOFF are the current
- position values). It is -1 when calling from x_set_frame_parameters,
- which means, do adjust for borders but don't change the gravity. */
-
-void
-x_set_offset (f, xoff, yoff, change_gravity)
- struct frame *f;
- register int xoff, yoff;
- int change_gravity;
-{
- if (change_gravity > 0)
- {
- f->top_pos = yoff;
- f->left_pos = xoff;
- f->size_hint_flags &= ~ (XNegative | YNegative);
- if (xoff < 0)
- f->size_hint_flags |= XNegative;
- if (yoff < 0)
- f->size_hint_flags |= YNegative;
- f->win_gravity = NorthWestGravity;
- }
- x_calc_absolute_position (f);
-
- BLOCK_INPUT;
- x_wm_set_size_hint (f, (long) 0, 0);
-
-#if TARGET_API_MAC_CARBON
- MoveWindowStructure (FRAME_MAC_WINDOW (f), f->left_pos, f->top_pos);
- /* If the title bar is completely outside the screen, adjust the
- position. */
- ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
- kWindowConstrainMoveRegardlessOfFit
- | kWindowConstrainAllowPartial, NULL, NULL);
- if (!NILP (tip_frame) && XFRAME (tip_frame) == f)
- mac_handle_origin_change (f);
-#else
- {
- Rect inner, outer, screen_rect, dummy;
- RgnHandle region = NewRgn ();
-
- mac_get_window_bounds (f, &inner, &outer);
- f->x_pixels_diff = inner.left - outer.left;
- f->y_pixels_diff = inner.top - outer.top;
- MoveWindow (FRAME_MAC_WINDOW (f), f->left_pos + f->x_pixels_diff,
- f->top_pos + f->y_pixels_diff, false);
-
- /* If the title bar is completely outside the screen, adjust the
- position. The variable `outer' holds the title bar rectangle.
- The variable `inner' holds slightly smaller one than `outer',
- so that the calculation of overlapping may not become too
- strict. */
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn, region);
- outer = (*region)->rgnBBox;
- DisposeRgn (region);
- inner = outer;
- InsetRect (&inner, 8, 8);
- screen_rect = qd.screenBits.bounds;
- screen_rect.top += GetMBarHeight ();
-
- if (!SectRect (&inner, &screen_rect, &dummy))
- {
- if (inner.right <= screen_rect.left)
- f->left_pos = screen_rect.left;
- else if (inner.left >= screen_rect.right)
- f->left_pos = screen_rect.right - (outer.right - outer.left);
-
- if (inner.bottom <= screen_rect.top)
- f->top_pos = screen_rect.top;
- else if (inner.top >= screen_rect.bottom)
- f->top_pos = screen_rect.bottom - (outer.bottom - outer.top);
-
- MoveWindow (FRAME_MAC_WINDOW (f), f->left_pos + f->x_pixels_diff,
- f->top_pos + f->y_pixels_diff, false);
- }
- }
-#endif
-
- UNBLOCK_INPUT;
-}
-
-/* Call this to change the size of frame F's x-window.
- If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
- for this size change and subsequent size changes.
- Otherwise we leave the window gravity unchanged. */
-
-void
-x_set_window_size (f, change_gravity, cols, rows)
- struct frame *f;
- int change_gravity;
- int cols, rows;
-{
- int pixelwidth, pixelheight;
-
- BLOCK_INPUT;
-
- check_frame_size (f, &rows, &cols);
- f->scroll_bar_actual_width
- = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
-
- compute_fringe_widths (f, 0);
-
- pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
- pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-
- f->win_gravity = NorthWestGravity;
- x_wm_set_size_hint (f, (long) 0, 0);
-
- SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
-
-#if TARGET_API_MAC_CARBON
- if (!NILP (tip_frame) && f == XFRAME (tip_frame))
-#endif
- mac_handle_size_change (f, pixelwidth, pixelheight);
-
- if (f->output_data.mac->internal_border_width
- != FRAME_INTERNAL_BORDER_WIDTH (f))
- {
- mac_clear_window (f);
- f->output_data.mac->internal_border_width
- = FRAME_INTERNAL_BORDER_WIDTH (f);
- }
-
- SET_FRAME_GARBAGED (f);
-
- UNBLOCK_INPUT;
-}
-
-/* Mouse warping. */
-
-void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
-
-void
-x_set_mouse_position (f, x, y)
- struct frame *f;
- int x, y;
-{
- int pix_x, pix_y;
-
- pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2;
- pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2;
-
- if (pix_x < 0) pix_x = 0;
- if (pix_x > FRAME_PIXEL_WIDTH (f)) pix_x = FRAME_PIXEL_WIDTH (f);
-
- if (pix_y < 0) pix_y = 0;
- if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f);
-
- x_set_mouse_pixel_position (f, pix_x, pix_y);
-}
-
-void
-x_set_mouse_pixel_position (f, pix_x, pix_y)
- struct frame *f;
- int pix_x, pix_y;
-{
-#ifdef MAC_OSX
- pix_x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- pix_y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-
- BLOCK_INPUT;
- CGWarpMouseCursorPosition (CGPointMake (pix_x, pix_y));
- UNBLOCK_INPUT;
-#else
-#if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
- BLOCK_INPUT;
-
- XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
- 0, 0, 0, 0, pix_x, pix_y);
- UNBLOCK_INPUT;
-#endif
-#endif
-}
-
-/* focus shifting, raising and lowering. */
-
-void
-x_focus_on_frame (f)
- struct frame *f;
-{
-#if 0 /* This proves to be unpleasant. */
- x_raise_frame (f);
-#endif
-#if 0
- /* I don't think that the ICCCM allows programs to do things like this
- without the interaction of the window manager. Whatever you end up
- doing with this code, do it to x_unfocus_frame too. */
- XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- RevertToPointerRoot, CurrentTime);
-#endif /* ! 0 */
-}
-
-void
-x_unfocus_frame (f)
- struct frame *f;
-{
-}
-
-/* Raise frame F. */
-
-void
-x_raise_frame (f)
- struct frame *f;
-{
- if (f->async_visible)
- {
- BLOCK_INPUT;
- BringToFront (FRAME_MAC_WINDOW (f));
- UNBLOCK_INPUT;
- }
-}
-
-/* Lower frame F. */
-
-void
-x_lower_frame (f)
- struct frame *f;
-{
- if (f->async_visible)
- {
- BLOCK_INPUT;
- SendBehind (FRAME_MAC_WINDOW (f), NULL);
- UNBLOCK_INPUT;
- }
-}
-
-static void
-XTframe_raise_lower (f, raise_flag)
- FRAME_PTR f;
- int raise_flag;
-{
- if (raise_flag)
- x_raise_frame (f);
- else
- x_lower_frame (f);
-}
-
-/* Change of visibility. */
-
-static void
-mac_handle_visibility_change (f)
- struct frame *f;
-{
- WindowRef wp = FRAME_MAC_WINDOW (f);
- int visible = 0, iconified = 0;
- struct input_event buf;
-
- if (IsWindowVisible (wp))
- {
- if (IsWindowCollapsed (wp))
- iconified = 1;
- else
- visible = 1;
- }
-
- if (!f->async_visible && visible)
- {
- if (f->iconified)
- {
- /* wait_reading_process_output will notice this and update
- the frame's display structures. If we were made
- invisible, we should not set garbaged, because that stops
- redrawing on Update events. */
- SET_FRAME_GARBAGED (f);
-
- EVENT_INIT (buf);
- buf.kind = DEICONIFY_EVENT;
- XSETFRAME (buf.frame_or_window, f);
- buf.arg = Qnil;
- kbd_buffer_store_event (&buf);
- }
- else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list)))
- /* Force a redisplay sooner or later to update the
- frame titles in case this is the second frame. */
- record_asynch_buffer_change ();
- }
- else if (f->async_visible && !visible)
- if (iconified)
- {
- EVENT_INIT (buf);
- buf.kind = ICONIFY_EVENT;
- XSETFRAME (buf.frame_or_window, f);
- buf.arg = Qnil;
- kbd_buffer_store_event (&buf);
- }
-
- f->async_visible = visible;
- f->async_iconified = iconified;
-}
-
-/* This tries to wait until the frame is really visible.
- However, if the window manager asks the user where to position
- the frame, this will return before the user finishes doing that.
- The frame will not actually be visible at that time,
- but it will become visible later when the window manager
- finishes with it. */
-
-void
-x_make_frame_visible (f)
- struct frame *f;
-{
- BLOCK_INPUT;
-
- if (! FRAME_VISIBLE_P (f))
- {
- /* We test FRAME_GARBAGED_P here to make sure we don't
- call x_set_offset a second time
- if we get to x_make_frame_visible a second time
- before the window gets really visible. */
- if (! FRAME_ICONIFIED_P (f)
- && ! f->output_data.mac->asked_for_visible)
- x_set_offset (f, f->left_pos, f->top_pos, 0);
-
- f->output_data.mac->asked_for_visible = 1;
-
- CollapseWindow (FRAME_MAC_WINDOW (f), false);
- ShowWindow (FRAME_MAC_WINDOW (f));
- }
-
- XFlush (FRAME_MAC_DISPLAY (f));
-
- /* Synchronize to ensure Emacs knows the frame is visible
- before we do anything else. We do this loop with input not blocked
- so that incoming events are handled. */
- {
- Lisp_Object frame;
- int count;
-
- /* This must come after we set COUNT. */
- UNBLOCK_INPUT;
-
- XSETFRAME (frame, f);
-
- /* Wait until the frame is visible. Process X events until a
- MapNotify event has been seen, or until we think we won't get a
- MapNotify at all.. */
- for (count = input_signal_count + 10;
- input_signal_count < count && !FRAME_VISIBLE_P (f);)
- {
- /* Force processing of queued events. */
- x_sync (f);
-
- /* Machines that do polling rather than SIGIO have been
- observed to go into a busy-wait here. So we'll fake an
- alarm signal to let the handler know that there's something
- to be read. We used to raise a real alarm, but it seems
- that the handler isn't always enabled here. This is
- probably a bug. */
- if (input_polling_used ())
- {
- /* It could be confusing if a real alarm arrives while
- processing the fake one. Turn it off and let the
- handler reset it. */
- extern void poll_for_input_1 P_ ((void));
- int old_poll_suppress_count = poll_suppress_count;
- poll_suppress_count = 1;
- poll_for_input_1 ();
- poll_suppress_count = old_poll_suppress_count;
- }
-
- /* See if a MapNotify event has been processed. */
- FRAME_SAMPLE_VISIBILITY (f);
- }
- }
-}
-
-/* Change from mapped state to withdrawn state. */
-
-/* Make the frame visible (mapped and not iconified). */
-
-void
-x_make_frame_invisible (f)
- struct frame *f;
-{
- /* A deactivate event does not occur when the last visible frame is
- made invisible. So if we clear the highlight here, it will not
- be rehighlighted when it is made visible. */
-#if 0
- /* Don't keep the highlight on an invisible frame. */
- if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f)
- FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0;
-#endif
-
- BLOCK_INPUT;
-
-#if !TARGET_API_MAC_CARBON
- /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
- that the current position of the window is user-specified, rather than
- program-specified, so that when the window is mapped again, it will be
- placed at the same location, without forcing the user to position it
- by hand again (they have already done that once for this window.) */
- x_wm_set_size_hint (f, (long) 0, 1);
-#endif
-
- HideWindow (FRAME_MAC_WINDOW (f));
-
- UNBLOCK_INPUT;
-
-#if !TARGET_API_MAC_CARBON
- mac_handle_visibility_change (f);
-#endif
-}
-
-/* Change window state from mapped to iconified. */
-
-void
-x_iconify_frame (f)
- struct frame *f;
-{
- OSStatus err;
-
- /* A deactivate event does not occur when the last visible frame is
- iconified. So if we clear the highlight here, it will not be
- rehighlighted when it is deiconified. */
-#if 0
- /* Don't keep the highlight on an invisible frame. */
- if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f)
- FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0;
-#endif
-
- if (f->async_iconified)
- return;
-
- BLOCK_INPUT;
-
- FRAME_SAMPLE_VISIBILITY (f);
-
- if (! FRAME_VISIBLE_P (f))
- ShowWindow (FRAME_MAC_WINDOW (f));
-
- err = CollapseWindow (FRAME_MAC_WINDOW (f), true);
-
- UNBLOCK_INPUT;
-
- if (err != noErr)
- error ("Can't notify window manager of iconification");
-
-#if !TARGET_API_MAC_CARBON
- mac_handle_visibility_change (f);
-#endif
-}
-
-
-/* Free X resources of frame F. */
-
-void
-x_free_frame_resources (f)
- struct frame *f;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowRef wp = FRAME_MAC_WINDOW (f);
-
- BLOCK_INPUT;
-
- if (wp != tip_window)
- remove_window_handler (wp);
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- DisposeWindow (wp);
- if (wp == tip_window)
- /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
- closed' event. So we reset tip_window here. */
- tip_window = NULL;
-
- free_frame_menubar (f);
-
- if (FRAME_FACE_CACHE (f))
- free_frame_faces (f);
-
- x_free_gcs (f);
-
- xfree (FRAME_SIZE_HINTS (f));
-
- xfree (f->output_data.mac);
- f->output_data.mac = NULL;
-
- if (f == dpyinfo->x_focus_frame)
- {
- dpyinfo->x_focus_frame = 0;
-#if USE_MAC_FONT_PANEL
- mac_set_font_info_for_selection (NULL, DEFAULT_FACE_ID, 0);
-#endif
- }
- if (f == dpyinfo->x_focus_event_frame)
- dpyinfo->x_focus_event_frame = 0;
- if (f == dpyinfo->x_highlight_frame)
- dpyinfo->x_highlight_frame = 0;
-
- if (f == dpyinfo->mouse_face_mouse_frame)
- {
- dpyinfo->mouse_face_beg_row
- = dpyinfo->mouse_face_beg_col = -1;
- dpyinfo->mouse_face_end_row
- = dpyinfo->mouse_face_end_col = -1;
- dpyinfo->mouse_face_window = Qnil;
- dpyinfo->mouse_face_deferred_gc = 0;
- dpyinfo->mouse_face_mouse_frame = 0;
- }
-
- UNBLOCK_INPUT;
-}
-
-
-/* Destroy the X window of frame F. */
-
-void
-x_destroy_window (f)
- struct frame *f;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- x_free_frame_resources (f);
-
- dpyinfo->reference_count--;
-}
-
-
-/* Setting window manager hints. */
-
-/* Set the normal size hints for the window manager, for frame F.
- FLAGS is the flags word to use--or 0 meaning preserve the flags
- that the window now has.
- If USER_POSITION is nonzero, we set the USPosition
- flag (this is useful when FLAGS is 0). */
-void
-x_wm_set_size_hint (f, flags, user_position)
- struct frame *f;
- long flags;
- int user_position;
-{
- int base_width, base_height, width_inc, height_inc;
- int min_rows = 0, min_cols = 0;
- XSizeHints *size_hints;
-
- base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
- base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
- width_inc = FRAME_COLUMN_WIDTH (f);
- height_inc = FRAME_LINE_HEIGHT (f);
-
- check_frame_size (f, &min_rows, &min_cols);
-
- size_hints = FRAME_SIZE_HINTS (f);
- if (size_hints == NULL)
- {
- size_hints = FRAME_SIZE_HINTS (f) = xmalloc (sizeof (XSizeHints));
- bzero (size_hints, sizeof (XSizeHints));
- }
-
- size_hints->flags |= PResizeInc | PMinSize | PBaseSize ;
- size_hints->width_inc = width_inc;
- size_hints->height_inc = height_inc;
- size_hints->min_width = base_width + min_cols * width_inc;
- size_hints->min_height = base_height + min_rows * height_inc;
- size_hints->base_width = base_width;
- size_hints->base_height = base_height;
-
- if (flags)
- size_hints->flags = flags;
- else if (user_position)
- {
- size_hints->flags &= ~ PPosition;
- size_hints->flags |= USPosition;
- }
-}
-
-#if 0 /* MAC_TODO: hide application instead of iconify? */
-/* Used for IconicState or NormalState */
-
-void
-x_wm_set_window_state (f, state)
- struct frame *f;
- int state;
-{
-#ifdef USE_X_TOOLKIT
- Arg al[1];
-
- XtSetArg (al[0], XtNinitialState, state);
- XtSetValues (f->output_data.x->widget, al, 1);
-#else /* not USE_X_TOOLKIT */
- Window window = FRAME_X_WINDOW (f);
-
- f->output_data.x->wm_hints.flags |= StateHint;
- f->output_data.x->wm_hints.initial_state = state;
-
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
-#endif /* not USE_X_TOOLKIT */
-}
-
-void
-x_wm_set_icon_pixmap (f, pixmap_id)
- struct frame *f;
- int pixmap_id;
-{
- Pixmap icon_pixmap;
-
-#ifndef USE_X_TOOLKIT
- Window window = FRAME_X_WINDOW (f);
-#endif
-
- if (pixmap_id > 0)
- {
- icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
- f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
- }
- else
- {
- /* It seems there is no way to turn off use of an icon pixmap.
- The following line does it, only if no icon has yet been created,
- for some window managers. But with mwm it crashes.
- Some people say it should clear the IconPixmapHint bit in this case,
- but that doesn't work, and the X consortium said it isn't the
- right thing at all. Since there is no way to win,
- best to explicitly give up. */
-#if 0
- f->output_data.x->wm_hints.icon_pixmap = None;
-#else
- return;
-#endif
- }
-
-#ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
-
- {
- Arg al[1];
- XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
- XtSetValues (f->output_data.x->widget, al, 1);
- }
-
-#else /* not USE_X_TOOLKIT */
-
- f->output_data.x->wm_hints.flags |= IconPixmapHint;
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
-
-#endif /* not USE_X_TOOLKIT */
-}
-
-#endif /* MAC_TODO */
-
-void
-x_wm_set_icon_position (f, icon_x, icon_y)
- struct frame *f;
- int icon_x, icon_y;
-{
-#if 0 /* MAC_TODO: no icons on Mac */
-#ifdef USE_X_TOOLKIT
- Window window = XtWindow (f->output_data.x->widget);
-#else
- Window window = FRAME_X_WINDOW (f);
-#endif
-
- f->output_data.x->wm_hints.flags |= IconPositionHint;
- f->output_data.x->wm_hints.icon_x = icon_x;
- f->output_data.x->wm_hints.icon_y = icon_y;
-
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
-#endif /* MAC_TODO */
-}
-
-
-/***********************************************************************
- XLFD Pattern Match
- ***********************************************************************/
-
-/* An XLFD pattern is divided into blocks delimited by '*'. This
- structure holds information for each block. */
-struct xlfdpat_block
-{
- /* Length of the pattern string in this block. Non-zero except for
- the first and the last blocks. */
- int len;
-
- /* Pattern string except the last character in this block. The last
- character is replaced with NUL in order to use it as a
- sentinel. */
- unsigned char *pattern;
-
- /* Last character of the pattern string. Must not be '?'. */
- unsigned char last_char;
-
- /* One of the tables for the Boyer-Moore string search. It
- specifies the number of positions to proceed for each character
- with which the match fails. */
- int skip[256];
-
- /* The skip value for the last character in the above `skip' is
- assigned to `infinity' in order to simplify a loop condition.
- The original value is saved here. */
- int last_char_skip;
-};
-
-struct xlfdpat
-{
- /* Normalized pattern string. "Normalized" means that capital
- letters are lowered, blocks are not empty except the first and
- the last ones, and trailing '?'s in a block that is not the last
- one are moved to the next one. The last character in each block
- is replaced with NUL. */
- unsigned char *buf;
-
- /* Number of characters except '*'s and trailing '?'s in the
- normalized pattern string. */
- int nchars;
-
- /* Number of trailing '?'s in the normalized pattern string. */
- int trailing_anychars;
-
- /* Number of blocks and information for each block. The latter is
- NULL if the pattern is exact (no '*' or '?' in it). */
- int nblocks;
- struct xlfdpat_block *blocks;
-};
-
-static void
-xlfdpat_destroy (pat)
- struct xlfdpat *pat;
-{
- if (pat)
- {
- if (pat->buf)
- {
- xfree (pat->blocks);
- xfree (pat->buf);
- }
- xfree (pat);
- }
-}
-
-static struct xlfdpat *
-xlfdpat_create (pattern)
- const char *pattern;
-{
- struct xlfdpat *pat;
- int nblocks, i, skip;
- unsigned char last_char, *p, *q, *anychar_head;
- const unsigned char *ptr;
- struct xlfdpat_block *blk;
-
- pat = xmalloc (sizeof (struct xlfdpat));
- pat->buf = xmalloc (strlen (pattern) + 1);
-
- /* Normalize the pattern string and store it to `pat->buf'. */
- nblocks = 0;
- anychar_head = NULL;
- q = pat->buf;
- last_char = '\0';
- for (ptr = pattern; *ptr; ptr++)
- {
- unsigned char c = *ptr;
-
- if (c == '*')
- if (last_char == '*')
- /* ...a** -> ...a* */
- continue;
- else
- {
- if (last_char == '?')
- {
- if (anychar_head > pat->buf && *(anychar_head - 1) == '*')
- /* ...*??* -> ...*?? */
- continue;
- else
- /* ...a??* -> ...a*?? */
- {
- *anychar_head++ = '*';
- c = '?';
- }
- }
- nblocks++;
- }
- else if (c == '?')
- {
- if (last_char != '?')
- anychar_head = q;
- }
- else
- /* On Mac OS X 10.3, tolower also converts non-ASCII
- characters for some locales. */
- if (isascii (c))
- c = tolower (c);
-
- *q++ = last_char = c;
- }
- *q = '\0';
- nblocks++;
- pat->nblocks = nblocks;
- if (last_char != '?')
- pat->trailing_anychars = 0;
- else
- {
- pat->trailing_anychars = q - anychar_head;
- q = anychar_head;
- }
- pat->nchars = q - pat->buf - (nblocks - 1);
-
- if (anychar_head == NULL && nblocks == 1)
- {
- /* The pattern is exact. */
- pat->blocks = NULL;
- return pat;
- }
-
- pat->blocks = xmalloc (sizeof (struct xlfdpat_block) * nblocks);
-
- /* Divide the normalized pattern into blocks. */
- p = pat->buf;
- for (blk = pat->blocks; blk < pat->blocks + nblocks - 1; blk++)
- {
- blk->pattern = p;
- while (*p != '*')
- p++;
- blk->len = p - blk->pattern;
- p++;
- }
- blk->pattern = p;
- blk->len = q - blk->pattern;
-
- /* Setup a table for the Boyer-Moore string search. */
- for (blk = pat->blocks; blk < pat->blocks + nblocks; blk++)
- if (blk->len != 0)
- {
- blk->last_char = blk->pattern[blk->len - 1];
- blk->pattern[blk->len - 1] = '\0';
-
- for (skip = 1; skip < blk->len; skip++)
- if (blk->pattern[blk->len - skip - 1] == '?')
- break;
-
- for (i = 0; i < 256; i++)
- blk->skip[i] = skip;
-
- p = blk->pattern + (blk->len - skip);
- while (--skip > 0)
- blk->skip[*p++] = skip;
-
- blk->last_char_skip = blk->skip[blk->last_char];
- }
-
- return pat;
-}
-
-static INLINE int
-xlfdpat_exact_p (pat)
- struct xlfdpat *pat;
-{
- return pat->blocks == NULL;
-}
-
-/* Return the first string in STRING + 0, ..., STRING + START_MAX such
- that the pattern in *BLK matches with its prefix. Return NULL
- there is no such strings. STRING must be lowered in advance. */
-
-static const char *
-xlfdpat_block_match_1 (blk, string, start_max)
- struct xlfdpat_block *blk;
- const unsigned char *string;
- int start_max;
-{
- int start, infinity;
- unsigned char *p;
- const unsigned char *s;
-
- xassert (blk->len > 0);
- xassert (start_max + blk->len <= strlen (string));
- xassert (blk->last_char != '?');
-
- /* See the comments in the function `boyer_moore' (search.c) for the
- use of `infinity'. */
- infinity = start_max + blk->len + 1;
- blk->skip[blk->last_char] = infinity;
-
- start = 0;
- do
- {
- /* Check the last character of the pattern. */
- s = string + blk->len - 1;
- do
- {
- start += blk->skip[*(s + start)];
- }
- while (start <= start_max);
-
- if (start < infinity)
- /* Couldn't find the last character. */
- return NULL;
-
- /* No less than `infinity' means we could find the last
- character at `s[start - infinity]'. */
- start -= infinity;
-
- /* Check the remaining characters. We prefer making no-'?'
- cases faster because the use of '?' is really rare. */
- p = blk->pattern;
- s = string + start;
- do
- {
- while (*p++ == *s++)
- ;
- }
- while (*(p - 1) == '?');
-
- if (*(p - 1) == '\0')
- /* Matched. */
- return string + start;
-
- /* Didn't match. */
- start += blk->last_char_skip;
- }
- while (start <= start_max);
-
- return NULL;
-}
-
-#define xlfdpat_block_match(b, s, m) \
- ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
- : xlfdpat_block_match_1 (b, s, m))
-
-/* Check if XLFD pattern PAT, which is generated by `xlfdpat_create',
- matches with STRING. STRING must be lowered in advance. */
-
-static int
-xlfdpat_match (pat, string)
- struct xlfdpat *pat;
- const unsigned char *string;
-{
- int str_len, nblocks, i, start_max;
- struct xlfdpat_block *blk;
- const unsigned char *s;
-
- xassert (pat->nblocks > 0);
-
- if (xlfdpat_exact_p (pat))
- return strcmp (pat->buf, string) == 0;
-
- /* The number of the characters in the string must not be smaller
- than that in the pattern. */
- str_len = strlen (string);
- if (str_len < pat->nchars + pat->trailing_anychars)
- return 0;
-
- /* Chop off the trailing '?'s. */
- str_len -= pat->trailing_anychars;
-
- /* The last block. When it is non-empty, it must match at the end
- of the string. */
- nblocks = pat->nblocks;
- blk = pat->blocks + (nblocks - 1);
- if (nblocks == 1)
- /* The last block is also the first one. */
- return (str_len == blk->len
- && (blk->len == 0 || xlfdpat_block_match (blk, string, 0)));
- else if (blk->len != 0)
- if (!xlfdpat_block_match (blk, string + (str_len - blk->len), 0))
- return 0;
-
- /* The first block. When it is non-empty, it must match at the
- beginning of the string. */
- blk = pat->blocks;
- if (blk->len != 0)
- {
- s = xlfdpat_block_match (blk, string, 0);
- if (s == NULL)
- return 0;
- string = s + blk->len;
- }
-
- /* The rest of the blocks. */
- start_max = str_len - pat->nchars;
- for (i = 1, blk++; i < nblocks - 1; i++, blk++)
- {
- s = xlfdpat_block_match (blk, string, start_max);
- if (s == NULL)
- return 0;
- start_max -= s - string;
- string = s + blk->len;
- }
-
- return 1;
-}
-
-
-/***********************************************************************
- Fonts
- ***********************************************************************/
-
-/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
-
-struct font_info *
-x_get_font_info (f, font_idx)
- FRAME_PTR f;
- int font_idx;
-{
- return (FRAME_MAC_FONT_TABLE (f) + font_idx);
-}
-
-/* the global font name table */
-static char **font_name_table = NULL;
-static int font_name_table_size = 0;
-static int font_name_count = 0;
-
-/* Alist linking font family names to Font Manager font family
- references (which can also be used as QuickDraw font IDs). We use
- an alist because hash tables are not ready when the terminal frame
- for Mac OS Classic is created. */
-static Lisp_Object fm_font_family_alist;
-#if USE_ATSUI
-/* Hash table linking font family names to ATSU font IDs. */
-static Lisp_Object atsu_font_id_hash;
-/* Alist linking Font Manager style to face attributes. */
-static Lisp_Object fm_style_face_attributes_alist;
-extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
-#endif
-
-/* Alist linking character set strings to Mac text encoding and Emacs
- coding system. */
-static Lisp_Object Vmac_charset_info_alist;
-
-static Lisp_Object
-create_text_encoding_info_alist ()
-{
- Lisp_Object result = Qnil, rest;
-
- for (rest = Vmac_charset_info_alist; CONSP (rest); rest = XCDR (rest))
- {
- Lisp_Object charset_info = XCAR (rest);
- Lisp_Object charset, coding_system, text_encoding;
- Lisp_Object existing_info;
-
- if (!(CONSP (charset_info)
- && (charset = XCAR (charset_info),
- STRINGP (charset))
- && CONSP (XCDR (charset_info))
- && (text_encoding = XCAR (XCDR (charset_info)),
- INTEGERP (text_encoding))
- && CONSP (XCDR (XCDR (charset_info)))
- && (coding_system = XCAR (XCDR (XCDR (charset_info))),
- SYMBOLP (coding_system))))
- continue;
-
- existing_info = assq_no_quit (text_encoding, result);
- if (NILP (existing_info))
- result = Fcons (list3 (text_encoding, coding_system, charset),
- result);
- else
- if (NILP (Fmember (charset, XCDR (XCDR (existing_info)))))
- XSETCDR (XCDR (existing_info),
- Fcons (charset, XCDR (XCDR (existing_info))));
- }
-
- return result;
-}
-
-
-static void
-decode_mac_font_name (name, size, coding_system)
- char *name;
- int size;
- Lisp_Object coding_system;
-{
- struct coding_system coding;
- char *buf, *p;
-
- if (!NILP (coding_system) && !NILP (Fcoding_system_p (coding_system)))
- {
- for (p = name; *p; p++)
- if (!isascii (*p) || iscntrl (*p))
- break;
-
- if (*p)
- {
- setup_coding_system (coding_system, &coding);
- coding.src_multibyte = 0;
- coding.dst_multibyte = 1;
- coding.mode |= CODING_MODE_LAST_BLOCK;
- coding.dst_bytes = size;
- coding.destination = (unsigned char *) alloca (coding.dst_bytes);
-
- decode_coding_c_string (&coding, name, strlen (name), Qnil);
- bcopy (coding.destination, name, min (coding.produced, size));
- name[min (coding.produced, size)] = '\0';
- }
- }
-
- /* If there's just one occurrence of '-' in the family name, it is
- replaced with '_'. (More than one occurrence of '-' means a
- "FOUNDRY-FAMILY-CHARSET"-style name.) */
- p = strchr (name, '-');
- if (p && strchr (p + 1, '-') == NULL)
- *p = '_';
-
- for (p = name; *p; p++)
- /* On Mac OS X 10.3, tolower also converts non-ASCII characters
- for some locales. */
- if (isascii (*p))
- *p = tolower (*p);
-}
-
-
-static char *
-mac_to_x_fontname (name, size, style, charset)
- const char *name;
- int size;
- Style style;
- char *charset;
-{
- Str31 foundry, cs;
- Str255 family;
- char xf[256], *result;
- unsigned char *p;
-
- if (sscanf (name, "%31[^-]-%255[^-]-%31s", foundry, family, cs) == 3)
- charset = cs;
- else
- {
- strcpy(foundry, "Apple");
- strcpy(family, name);
- }
-
- sprintf (xf, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
- style & bold ? "bold" : "medium", style & italic ? 'i' : 'r',
- size, size * 10, size ? 72 : 0, size ? 72 : 0, size * 10, charset);
-
- result = xmalloc (strlen (foundry) + strlen (family) + strlen (xf) + 3 + 1);
- sprintf (result, "-%s-%s-%s", foundry, family, xf);
- for (p = result; *p; p++)
- /* On Mac OS X 10.3, tolower also converts non-ASCII characters
- for some locales. */
- if (isascii (*p))
- *p = tolower (*p);
- return result;
-}
-
-
-/* Parse fully-specified and instantiated X11 font spec XF, and store
- the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the
- parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the
- caller must allocate at least 256 and 32 bytes respectively. For
- ordinary Mac fonts, the value stored to FAMILY should just be their
- names, like "monaco", "Taipei", etc. Fonts converted from the GNU
- intlfonts collection contain their charset designation in their
- names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both
- types of font names are handled accordingly. */
-
-const int kDefaultFontSize = 12;
-
-static int
-parse_x_font_name (xf, family, size, style, charset)
- const char *xf;
- char *family;
- int *size;
- Style *style;
- char *charset;
-{
- Str31 foundry, weight;
- int point_size, avgwidth;
- char slant[2], *p;
-
- if (sscanf (xf, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
- foundry, family, weight, slant, size,
- &point_size, &avgwidth, charset) != 8
- && sscanf (xf, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
- foundry, family, weight, slant, size,
- &point_size, &avgwidth, charset) != 8)
- return 0;
-
- if (*size == 0)
- {
- if (point_size > 0)
- *size = point_size / 10;
- else if (avgwidth > 0)
- *size = avgwidth / 10;
- }
- if (*size == 0)
- *size = kDefaultFontSize;
-
- *style = normal;
- if (strcmp (weight, "bold") == 0)
- *style |= bold;
- if (*slant == 'i')
- *style |= italic;
-
- if (NILP (Fassoc (build_string (charset), Vmac_charset_info_alist)))
- {
- int foundry_len = strlen (foundry), family_len = strlen (family);
-
- if (foundry_len + family_len + strlen (charset) + 2 < sizeof (Str255))
- {
- /* Like sprintf (family, "%s-%s-%s", foundry, family, charset),
- but take overlap into account. */
- memmove (family + foundry_len + 1, family, family_len);
- memcpy (family, foundry, foundry_len);
- family[foundry_len] = '-';
- family[foundry_len + 1 + family_len] = '-';
- strcpy (family + foundry_len + 1 + family_len + 1, charset);
- }
- else
- return 0;
- }
-
- for (p = family; *p; p++)
- /* On Mac OS X 10.3, tolower also converts non-ASCII characters
- for some locales. */
- if (isascii (*p))
- *p = tolower (*p);
-
- return 1;
-}
-
-
-static void
-add_font_name_table_entry (char *font_name)
-{
- if (font_name_table_size == 0)
- {
- font_name_table_size = 256;
- font_name_table = (char **)
- xmalloc (font_name_table_size * sizeof (char *));
- }
- else if (font_name_count + 1 >= font_name_table_size)
- {
- font_name_table_size *= 2;
- font_name_table = (char **)
- xrealloc (font_name_table,
- font_name_table_size * sizeof (char *));
- }
-
- font_name_table[font_name_count++] = font_name;
-}
-
-static void
-add_mac_font_name (name, size, style, charset)
- const char *name;
- int size;
- Style style;
- const char *charset;
-{
- if (size > 0)
- add_font_name_table_entry (mac_to_x_fontname (name, size, style, charset));
- else
- {
- add_font_name_table_entry (mac_to_x_fontname (name, 0, style, charset));
- add_font_name_table_entry (mac_to_x_fontname (name, 0, italic, charset));
- add_font_name_table_entry (mac_to_x_fontname (name, 0, bold, charset));
- add_font_name_table_entry (mac_to_x_fontname (name, 0, italic | bold,
- charset));
- }
-}
-
-#if USE_ATSUI
-static FMFontStyle
-fm_get_style_from_font (font)
- FMFont font;
-{
- OSStatus err;
- FMFontStyle style = normal;
- ByteCount len;
- UInt16 mac_style;
- FMFontFamily font_family;
-#define FONT_HEADER_MAC_STYLE_OFFSET (4*4 + 2*2 + 8*2 + 2*4)
-
- /* FMGetFontFamilyInstanceFromFont returns `normal' as the style of
- some font (e.g., Optima) even if it is `bold'. */
- err = FMGetFontTable (font, 'head', FONT_HEADER_MAC_STYLE_OFFSET,
- sizeof (mac_style), &mac_style, &len);
- if (err == noErr
- && len >= FONT_HEADER_MAC_STYLE_OFFSET + sizeof (mac_style))
- style = EndianU16_BtoN (mac_style);
- else
- FMGetFontFamilyInstanceFromFont (font, &font_family, &style);
-
- return style;
-}
-
-static ATSUFontID
-atsu_find_font_from_family_name (family)
- const char *family;
-{
- struct Lisp_Hash_Table *h = XHASH_TABLE (atsu_font_id_hash);
- unsigned hash_code;
- int i;
- Lisp_Object rest, best;
- FMFontStyle min_style, style;
-
- i = hash_lookup (h, make_unibyte_string (family, strlen (family)),
- &hash_code);
- if (i < 0)
- return kATSUInvalidFontID;
-
- rest = HASH_VALUE (h, i);
- if (INTEGERP (rest) || (CONSP (rest) && INTEGERP (XCDR (rest))))
- return cons_to_long (rest);
-
- rest = Fnreverse (rest);
- best = XCAR (rest);
- rest = XCDR (rest);
- if (!NILP (rest)
- && (min_style = fm_get_style_from_font (cons_to_long (best))) != normal)
- do
- {
- style = fm_get_style_from_font (cons_to_long (XCAR (rest)));
- if (style < min_style)
- {
- best = XCAR (rest);
- if (style == normal)
- break;
- else
- min_style = style;
- }
- rest = XCDR (rest);
- }
- while (!NILP (rest));
-
- HASH_VALUE (h, i) = best;
- return cons_to_long (best);
-}
-
-static Lisp_Object
-fm_style_to_face_attributes (fm_style)
- FMFontStyle fm_style;
-{
- Lisp_Object tem;
-
- fm_style &= (bold | italic);
- tem = assq_no_quit (make_number (fm_style),
- fm_style_face_attributes_alist);
- if (!NILP (tem))
- return XCDR (tem);
-
- tem = list4 (QCweight, fm_style & bold ? Qbold : Qnormal,
- QCslant, fm_style & italic ? Qitalic : Qnormal);
- fm_style_face_attributes_alist =
- Fcons (Fcons (make_number (fm_style), tem),
- fm_style_face_attributes_alist);
-
- return tem;
-}
-
-static Lisp_Object
-atsu_find_font_family_name (font_id)
- ATSUFontID font_id;
-{
- OSStatus err;
- ByteCount len;
- Lisp_Object family = Qnil;
-
- err = ATSUFindFontName (font_id, kFontFamilyName,
- kFontMacintoshPlatform, kFontNoScript,
- kFontNoLanguage, 0, NULL, &len, NULL);
- if (err == noErr)
- {
- family = make_uninit_string (len);
- err = ATSUFindFontName (font_id, kFontFamilyName,
- kFontMacintoshPlatform, kFontNoScript,
- kFontNoLanguage, len, SDATA (family),
- NULL, NULL);
- }
- if (err == noErr)
- decode_mac_font_name (SDATA (family), len + 1, Qnil);
-
- return family;
-}
-
-Lisp_Object
-mac_atsu_font_face_attributes (font_id)
- ATSUFontID font_id;
-{
- Lisp_Object family, style_attrs;
-
- family = atsu_find_font_family_name (font_id);
- if (NILP (family))
- return Qnil;
- style_attrs = fm_style_to_face_attributes (fm_get_style_from_font (font_id));
- return Fcons (QCfamily, Fcons (family, style_attrs));
-}
-#endif
-
-/* Sets up the table font_name_table to contain the list of all fonts
- in the system the first time the table is used so that the Resource
- Manager need not be accessed every time this information is
- needed. */
-
-static void
-init_font_name_table ()
-{
-#if TARGET_API_MAC_CARBON
- FMFontFamilyIterator ffi;
- FMFontFamilyInstanceIterator ffii;
- FMFontFamily ff;
- Lisp_Object text_encoding_info_alist;
- struct gcpro gcpro1;
-
- text_encoding_info_alist = create_text_encoding_info_alist ();
-
-#if USE_ATSUI
-#if USE_CG_TEXT_DRAWING
- init_cg_text_anti_aliasing_threshold ();
-#endif
- if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode),
- text_encoding_info_alist)))
- {
- OSStatus err;
- struct Lisp_Hash_Table *h;
- unsigned hash_code;
- ItemCount nfonts, i;
- ATSUFontID *font_ids = NULL;
- Lisp_Object prev_family = Qnil;
- int j;
-
- atsu_font_id_hash =
- make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
- make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil, Qnil);
- h = XHASH_TABLE (atsu_font_id_hash);
-
- err = ATSUFontCount (&nfonts);
- if (err == noErr)
- {
- font_ids = xmalloc (sizeof (ATSUFontID) * nfonts);
- err = ATSUGetFontIDs (font_ids, nfonts, NULL);
- }
- if (err == noErr)
- for (i = 0; i < nfonts; i++)
- {
- Lisp_Object family;
-
- family = atsu_find_font_family_name (font_ids[i]);
- if (NILP (family) || SREF (family, 0) == '.')
- continue;
- if (!NILP (Fequal (prev_family, family)))
- family = prev_family;
- else
- j = hash_lookup (h, family, &hash_code);
- if (j < 0)
- {
- add_mac_font_name (SDATA (family), 0, normal, "iso10646-1");
- j = hash_put (h, family, Fcons (long_to_cons (font_ids[i]),
- Qnil), hash_code);
- }
- else if (EQ (prev_family, family))
- HASH_VALUE (h, j) = Fcons (long_to_cons (font_ids[i]),
- HASH_VALUE (h, j));
- prev_family = family;
- }
- xfree (font_ids);
- }
-#endif
-
- /* Create a dummy instance iterator here to avoid creating and
- destroying it in the loop. */
- if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr)
- return;
- /* Create an iterator to enumerate the font families. */
- if (FMCreateFontFamilyIterator (NULL, NULL, kFMDefaultOptions, &ffi)
- != noErr)
- {
- FMDisposeFontFamilyInstanceIterator (&ffii);
- return;
- }
-
- GCPRO1 (text_encoding_info_alist);
-
- while (FMGetNextFontFamily (&ffi, &ff) == noErr)
- {
- Str255 name;
- FMFont font;
- FMFontStyle style;
- FMFontSize size;
- TextEncoding encoding;
- TextEncodingBase sc;
- Lisp_Object text_encoding_info, family;
-
- if (FMGetFontFamilyName (ff, name) != noErr)
- continue;
- p2cstr (name);
- if (*name == '.')
- continue;
-
- if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
- continue;
- sc = GetTextEncodingBase (encoding);
- text_encoding_info = assq_no_quit (make_number (sc),
- text_encoding_info_alist);
- if (NILP (text_encoding_info))
- text_encoding_info = assq_no_quit (make_number (kTextEncodingMacRoman),
- text_encoding_info_alist);
- decode_mac_font_name (name, sizeof (name),
- XCAR (XCDR (text_encoding_info)));
- family = build_string (name);
- if (!NILP (Fassoc (family, fm_font_family_alist)))
- continue;
- fm_font_family_alist = Fcons (Fcons (family, make_number (ff)),
- fm_font_family_alist);
-
- /* Point the instance iterator at the current font family. */
- if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
- continue;
-
- while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
- == noErr)
- {
- Lisp_Object rest = XCDR (XCDR (text_encoding_info));
-
- if (size > 0 || style == normal)
- for (; CONSP (rest); rest = XCDR (rest))
- add_mac_font_name (name, size, style, SDATA (XCAR (rest)));
- }
- }
-
- UNGCPRO;
-
- /* Dispose of the iterators. */
- FMDisposeFontFamilyIterator (&ffi);
- FMDisposeFontFamilyInstanceIterator (&ffii);
-#else /* !TARGET_API_MAC_CARBON */
- GrafPtr port;
- SInt16 fontnum, old_fontnum;
- int num_mac_fonts = CountResources('FOND');
- int i, j;
- Handle font_handle, font_handle_2;
- short id, scriptcode;
- ResType type;
- Str255 name;
- struct FontAssoc *fat;
- struct AsscEntry *assc_entry;
- Lisp_Object text_encoding_info_alist, text_encoding_info, family;
- struct gcpro gcpro1;
-
- GetPort (&port); /* save the current font number used */
- old_fontnum = port->txFont;
-
- text_encoding_info_alist = create_text_encoding_info_alist ();
-
- GCPRO1 (text_encoding_info_alist);
-
- for (i = 1; i <= num_mac_fonts; i++) /* get all available fonts */
- {
- font_handle = GetIndResource ('FOND', i);
- if (!font_handle)
- continue;
-
- GetResInfo (font_handle, &id, &type, name);
- GetFNum (name, &fontnum);
- p2cstr (name);
- if (fontnum == 0 || *name == '.')
- continue;
-
- TextFont (fontnum);
- scriptcode = FontToScript (fontnum);
- text_encoding_info = assq_no_quit (make_number (scriptcode),
- text_encoding_info_alist);
- if (NILP (text_encoding_info))
- text_encoding_info = assq_no_quit (make_number (smRoman),
- text_encoding_info_alist);
- decode_mac_font_name (name, sizeof (name),
- XCAR (XCDR (text_encoding_info)));
- family = build_string (name);
- if (!NILP (Fassoc (family, fm_font_family_alist)))
- continue;
- fm_font_family_alist = Fcons (Fcons (family, make_number (fontnum)),
- fm_font_family_alist);
- do
- {
- HLock (font_handle);
-
- if (GetResourceSizeOnDisk (font_handle)
- >= sizeof (struct FamRec))
- {
- fat = (struct FontAssoc *) (*font_handle
- + sizeof (struct FamRec));
- assc_entry
- = (struct AsscEntry *) (*font_handle
- + sizeof (struct FamRec)
- + sizeof (struct FontAssoc));
-
- for (j = 0; j <= fat->numAssoc; j++, assc_entry++)
- {
- Lisp_Object rest = XCDR (XCDR (text_encoding_info));
-
- for (; CONSP (rest); rest = XCDR (rest))
- add_mac_font_name (name, assc_entry->fontSize,
- assc_entry->fontStyle,
- SDATA (XCAR (rest)));
- }
- }
-
- HUnlock (font_handle);
- font_handle_2 = GetNextFOND (font_handle);
- ReleaseResource (font_handle);
- font_handle = font_handle_2;
- }
- while (ResError () == noErr && font_handle);
- }
-
- UNGCPRO;
-
- TextFont (old_fontnum);
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-
-void
-mac_clear_font_name_table ()
-{
- int i;
-
- for (i = 0; i < font_name_count; i++)
- xfree (font_name_table[i]);
- xfree (font_name_table);
- font_name_table = NULL;
- font_name_table_size = font_name_count = 0;
- fm_font_family_alist = Qnil;
-}
-
-
-enum xlfd_scalable_field_index
- {
- XLFD_SCL_PIXEL_SIZE,
- XLFD_SCL_POINT_SIZE,
- XLFD_SCL_AVGWIDTH,
- XLFD_SCL_LAST
- };
-
-static const int xlfd_scalable_fields[] =
- {
- 6, /* PIXEL_SIZE */
- 7, /* POINT_SIZE */
- 11, /* AVGWIDTH */
- -1
- };
-
-static Lisp_Object
-mac_do_list_fonts (pattern, maxnames)
- const char *pattern;
- int maxnames;
-{
- int i, n_fonts = 0;
- Lisp_Object font_list = Qnil;
- struct xlfdpat *pat;
- char *scaled;
- const char *ptr;
- int scl_val[XLFD_SCL_LAST], *val;
- const int *field;
- int exact;
-
- if (font_name_table == NULL) /* Initialize when first used. */
- init_font_name_table ();
-
- for (i = 0; i < XLFD_SCL_LAST; i++)
- scl_val[i] = -1;
-
- /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
- POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
- fonts are scaled according to the specified size. */
- ptr = pattern;
- i = 0;
- field = xlfd_scalable_fields;
- val = scl_val;
- if (*ptr == '-')
- do
- {
- ptr++;
- if (i == *field)
- {
- if ('0' <= *ptr && *ptr <= '9')
- {
- *val = *ptr++ - '0';
- while ('0' <= *ptr && *ptr <= '9' && *val < 10000)
- *val = *val * 10 + *ptr++ - '0';
- if (*ptr != '-')
- *val = -1;
- }
- field++;
- val++;
- }
- ptr = strchr (ptr, '-');
- i++;
- }
- while (ptr && i < 14);
-
- if (i == 14 && ptr == NULL)
- {
- if (scl_val[XLFD_SCL_PIXEL_SIZE] < 0)
- scl_val[XLFD_SCL_PIXEL_SIZE] =
- (scl_val[XLFD_SCL_POINT_SIZE] > 0 ? scl_val[XLFD_SCL_POINT_SIZE] / 10
- : (scl_val[XLFD_SCL_AVGWIDTH] > 0 ? scl_val[XLFD_SCL_AVGWIDTH] / 10
- : -1));
- if (scl_val[XLFD_SCL_POINT_SIZE] < 0)
- scl_val[XLFD_SCL_POINT_SIZE] =
- (scl_val[XLFD_SCL_PIXEL_SIZE] > 0 ? scl_val[XLFD_SCL_PIXEL_SIZE] * 10
- : (scl_val[XLFD_SCL_AVGWIDTH] > 0 ? scl_val[XLFD_SCL_AVGWIDTH]
- : -1));
- if (scl_val[XLFD_SCL_AVGWIDTH] < 0)
- scl_val[XLFD_SCL_AVGWIDTH] =
- (scl_val[XLFD_SCL_PIXEL_SIZE] > 0 ? scl_val[XLFD_SCL_PIXEL_SIZE] * 10
- : (scl_val[XLFD_SCL_POINT_SIZE] > 0 ? scl_val[XLFD_SCL_POINT_SIZE]
- : -1));
- }
- else
- scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
-
- pat = xlfdpat_create (pattern);
- if (pat == NULL)
- return Qnil;
-
- exact = xlfdpat_exact_p (pat);
-
- for (i = 0; i < font_name_count; i++)
- {
- if (xlfdpat_match (pat, font_name_table[i]))
- {
- font_list = Fcons (build_string (font_name_table[i]), font_list);
- if (exact || (maxnames > 0 && ++n_fonts >= maxnames))
- break;
- }
- else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
- && (ptr = strstr (font_name_table[i], "-0-0-0-0-m-0-")))
- {
- int former_len = ptr - font_name_table[i];
-
- scaled = xmalloc (strlen (font_name_table[i]) + 20 + 1);
- memcpy (scaled, font_name_table[i], former_len);
- sprintf (scaled + former_len,
- "-%d-%d-72-72-m-%d-%s",
- scl_val[XLFD_SCL_PIXEL_SIZE],
- scl_val[XLFD_SCL_POINT_SIZE],
- scl_val[XLFD_SCL_AVGWIDTH],
- ptr + sizeof ("-0-0-0-0-m-0-") - 1);
-
- if (xlfdpat_match (pat, scaled))
- {
- font_list = Fcons (build_string (scaled), font_list);
- xfree (scaled);
- if (exact || (maxnames > 0 && ++n_fonts >= maxnames))
- break;
- }
- else
- xfree (scaled);
- }
- }
-
- xlfdpat_destroy (pat);
-
- return font_list;
-}
-
-/* Return a list of names of available fonts matching PATTERN on frame F.
-
- Frame F null means we have not yet created any frame on Mac, and
- consult the first display in x_display_list. MAXNAMES sets a limit
- on how many fonts to match. */
-
-Lisp_Object
-x_list_fonts (f, pattern, size, maxnames)
- struct frame *f;
- Lisp_Object pattern;
- int size, maxnames;
-{
- Lisp_Object list = Qnil, patterns, tem, key;
- struct mac_display_info *dpyinfo
- = f ? FRAME_MAC_DISPLAY_INFO (f) : x_display_list;
-
- xassert (size <= 0);
-
- patterns = Fassoc (pattern, Valternate_fontname_alist);
- if (NILP (patterns))
- patterns = Fcons (pattern, Qnil);
-
- for (; CONSP (patterns); patterns = XCDR (patterns))
- {
- pattern = XCAR (patterns);
-
- if (!STRINGP (pattern))
- continue;
-
- tem = XCAR (XCDR (dpyinfo->name_list_element));
- key = Fcons (pattern, make_number (maxnames));
-
- list = Fassoc (key, tem);
- if (!NILP (list))
- {
- list = Fcdr_safe (list);
- /* We have a cashed list. Don't have to get the list again. */
- goto label_cached;
- }
-
- BLOCK_INPUT;
- list = mac_do_list_fonts (SDATA (pattern), maxnames);
- UNBLOCK_INPUT;
-
- /* MAC_TODO: add code for matching outline fonts here */
-
- /* Now store the result in the cache. */
- XSETCAR (XCDR (dpyinfo->name_list_element),
- Fcons (Fcons (key, list),
- XCAR (XCDR (dpyinfo->name_list_element))));
-
- label_cached:
- if (NILP (list)) continue; /* Try the remaining alternatives. */
- }
-
- return list;
-}
-
-
-#if GLYPH_DEBUG
-
-/* Check that FONT is valid on frame F. It is if it can be found in F's
- font table. */
-
-static void
-x_check_font (f, font)
- struct frame *f;
- XFontStruct *font;
-{
- int i;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-
- xassert (font != NULL);
-
- for (i = 0; i < dpyinfo->n_fonts; i++)
- if (dpyinfo->font_table[i].name
- && font == dpyinfo->font_table[i].font)
- break;
-
- xassert (i < dpyinfo->n_fonts);
-}
-
-#endif /* GLYPH_DEBUG != 0 */
-
-/* Set *W to the minimum width, *H to the minimum font height of FONT.
- Note: There are (broken) X fonts out there with invalid XFontStruct
- min_bounds contents. For example, handa@etl.go.jp reports that
- "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
- have font->min_bounds.width == 0. */
-
-static INLINE void
-x_font_min_bounds (font, w, h)
- MacFontStruct *font;
- int *w, *h;
-{
- *h = FONT_HEIGHT (font);
- *w = font->min_bounds.width;
-}
-
-
-/* Compute the smallest character width and smallest font height over
- all fonts available on frame F. Set the members smallest_char_width
- and smallest_font_height in F's x_display_info structure to
- the values computed. Value is non-zero if smallest_font_height or
- smallest_char_width become smaller than they were before. */
-
-static int
-x_compute_min_glyph_bounds (f)
- struct frame *f;
-{
- int i;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- MacFontStruct *font;
- int old_width = dpyinfo->smallest_char_width;
- int old_height = dpyinfo->smallest_font_height;
-
- dpyinfo->smallest_font_height = 100000;
- dpyinfo->smallest_char_width = 100000;
-
- for (i = 0; i < dpyinfo->n_fonts; ++i)
- if (dpyinfo->font_table[i].name)
- {
- struct font_info *fontp = dpyinfo->font_table + i;
- int w, h;
-
- font = (MacFontStruct *) fontp->font;
- xassert (font != (MacFontStruct *) ~0);
- x_font_min_bounds (font, &w, &h);
-
- dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
- dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
- }
-
- xassert (dpyinfo->smallest_char_width > 0
- && dpyinfo->smallest_font_height > 0);
-
- return (dpyinfo->n_fonts == 1
- || dpyinfo->smallest_char_width < old_width
- || dpyinfo->smallest_font_height < old_height);
-}
-
-
-/* Determine whether given string is a fully-specified XLFD: all 14
- fields are present, none is '*'. */
-
-static int
-is_fully_specified_xlfd (p)
- const char *p;
-{
- int i;
- char *q;
-
- if (*p != '-')
- return 0;
-
- for (i = 0; i < 13; i++)
- {
- q = strchr (p + 1, '-');
- if (q == NULL)
- return 0;
- if (q - p == 2 && *(p + 1) == '*')
- return 0;
- p = q;
- }
-
- if (strchr (p + 1, '-') != NULL)
- return 0;
-
- if (*(p + 1) == '*' && *(p + 2) == '\0')
- return 0;
-
- return 1;
-}
-
-
-/* mac_load_query_font creates and returns an internal representation
- for a font in a MacFontStruct struct. There is really no concept
- corresponding to "loading" a font on the Mac. But we check its
- existence and find the font number and all other information for it
- and store them in the returned MacFontStruct. */
-
-static MacFontStruct *
-mac_load_query_font (f, fontname)
- struct frame *f;
- char *fontname;
-{
- int size;
- char *name;
- Str255 family;
- Str31 charset;
- SInt16 fontnum;
-#if USE_ATSUI
- static ATSUFontID font_id;
- ATSUStyle mac_style = NULL;
-#endif
- Style fontface;
-#if TARGET_API_MAC_CARBON
- TextEncoding encoding;
- int scriptcode;
-#else
- short scriptcode;
-#endif
- MacFontStruct *font;
- XCharStruct *space_bounds = NULL, *pcm;
-
- if (is_fully_specified_xlfd (fontname))
- name = fontname;
- else
- {
- Lisp_Object matched_fonts;
-
- matched_fonts = mac_do_list_fonts (fontname, 1);
- if (NILP (matched_fonts))
- return NULL;
- name = SDATA (XCAR (matched_fonts));
- }
-
- if (parse_x_font_name (name, family, &size, &fontface, charset) == 0)
- return NULL;
-
-#if USE_ATSUI
- if (strcmp (charset, "iso10646-1") == 0) /* XXX */
- {
- OSStatus err;
- static const ATSUAttributeTag tags[] =
- {kATSUFontTag, kATSUSizeTag,
- kATSUQDBoldfaceTag, kATSUQDItalicTag};
- static const ByteCount sizes[] =
- {sizeof (ATSUFontID), sizeof (Fixed),
- sizeof (Boolean), sizeof (Boolean)};
- static Fixed size_fixed;
- static Boolean bold_p, italic_p;
- static const ATSUAttributeValuePtr values[] =
- {&font_id, &size_fixed,
- &bold_p, &italic_p};
- static const ATSUFontFeatureType types[] =
- {kAllTypographicFeaturesType, kDiacriticsType};
- static const ATSUFontFeatureSelector selectors[] =
- {kAllTypeFeaturesOffSelector, kDecomposeDiacriticsSelector};
- FMFontStyle style;
-
- font_id = atsu_find_font_from_family_name (family);
- if (font_id == kATSUInvalidFontID)
- return NULL;
- size_fixed = Long2Fix (size);
- bold_p = (fontface & bold) != 0;
- italic_p = (fontface & italic) != 0;
- err = ATSUCreateStyle (&mac_style);
- if (err != noErr)
- return NULL;
- err = ATSUSetFontFeatures (mac_style, sizeof (types) / sizeof (types[0]),
- types, selectors);
- if (err != noErr)
- return NULL;
- err = ATSUSetAttributes (mac_style, sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
- if (err != noErr)
- return NULL;
- err = FMGetFontFamilyInstanceFromFont (font_id, &fontnum, &style);
- if (err != noErr)
- fontnum = -1;
- scriptcode = kTextEncodingMacUnicode;
- }
- else
-#endif
- {
- Lisp_Object tmp = Fassoc (build_string (family), fm_font_family_alist);
-
- if (NILP (tmp))
- return NULL;
- fontnum = XINT (XCDR (tmp));
-#if TARGET_API_MAC_CARBON
- if (FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr)
- return NULL;
- scriptcode = GetTextEncodingBase (encoding);
-#else
- scriptcode = FontToScript (fontnum);
-#endif
- }
-
- font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct));
-
- font->mac_fontnum = fontnum;
- font->mac_fontsize = size;
- font->mac_fontface = fontface;
- font->mac_scriptcode = scriptcode;
-#if USE_ATSUI
- font->mac_style = mac_style;
-#if USE_CG_TEXT_DRAWING
- font->cg_font = NULL;
- font->cg_glyphs = NULL;
-#endif
-#endif
-
- /* Apple Japanese (SJIS) font is listed as both
- "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
- (Roman script) in init_font_name_table (). The latter should be
- treated as a one-byte font. */
- if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0)
- font->mac_scriptcode = smRoman;
-
- font->full_name = mac_to_x_fontname (family, size, fontface, charset);
-
-#if USE_ATSUI
- if (font->mac_style)
- {
- OSStatus err;
- UniChar c;
-
- font->min_byte1 = 0;
- font->max_byte1 = 0xff;
- font->min_char_or_byte2 = 0;
- font->max_char_or_byte2 = 0xff;
-
- font->bounds.rows = xmalloc (sizeof (XCharStruct *) * 0x100);
- bzero (font->bounds.rows, sizeof (XCharStruct *) * 0x100);
- font->bounds.rows[0] = xmalloc (sizeof (XCharStruct) * 0x100);
- pcm_init (font->bounds.rows[0], 0x100);
-
-#if USE_CG_TEXT_DRAWING
- if (fontnum != -1)
- {
- FMFontStyle style;
- ATSFontRef ats_font;
-
- err = FMGetFontFromFontFamilyInstance (fontnum, fontface,
- &font_id, &style);
- /* Use CG text drawing if italic/bold is not synthesized. */
- if (err == noErr && style == fontface)
- {
- ats_font = FMGetATSFontRefFromFont (font_id);
- font->cg_font = CGFontCreateWithPlatformFont (&ats_font);
- }
- }
-
- if (font->cg_font)
- {
- font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100);
- bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
- }
-#endif
- space_bounds = font->bounds.rows[0] + 0x20;
- err = mac_query_char_extents (font->mac_style, 0x20,
- &font->ascent, &font->descent,
- space_bounds,
-#if USE_CG_TEXT_DRAWING
- (font->cg_glyphs ? font->cg_glyphs + 0x20
- : NULL)
-#else
- NULL
-#endif
- );
- if (err != noErr
- || space_bounds->width <= 0 || FONT_HEIGHT (font) <= 0)
- {
- mac_unload_font (&one_mac_display_info, font);
- return NULL;
- }
-
- pcm = font->bounds.rows[0];
- for (c = 0x21; c <= 0xff; c++)
- {
- if (c == 0xad)
- /* Soft hyphen is not supported in ATSUI. */
- continue;
- else if (c == 0x7f)
- {
-#if USE_CG_TEXT_DRAWING
- if (font->cg_glyphs)
- {
- c = 0x9f;
- pcm = NULL;
- continue;
- }
-#endif
- break;
- }
-
- mac_query_char_extents (font->mac_style, c, NULL, NULL,
- pcm ? pcm + c : NULL,
-#if USE_CG_TEXT_DRAWING
- (font->cg_glyphs ? font->cg_glyphs + c
- : NULL)
-#else
- NULL
-#endif
- );
-
-#if USE_CG_TEXT_DRAWING
- if (font->cg_glyphs && font->cg_glyphs[c] == 0)
- {
- /* Don't use CG text drawing if font substitution occurs in
- ASCII or Latin-1 characters. */
- CGFontRelease (font->cg_font);
- font->cg_font = NULL;
- xfree (font->cg_glyphs);
- font->cg_glyphs = NULL;
- if (pcm == NULL)
- break;
- }
-#endif
- }
- }
- else
-#endif
- {
- OSStatus err;
- FontInfo the_fontinfo;
- int is_two_byte_font;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- TextFont (fontnum);
- TextSize (size);
- TextFace (fontface);
-
- GetFontInfo (&the_fontinfo);
-
- font->ascent = the_fontinfo.ascent;
- font->descent = the_fontinfo.descent;
-
- is_two_byte_font = (font->mac_scriptcode == smJapanese
- || font->mac_scriptcode == smTradChinese
- || font->mac_scriptcode == smSimpChinese
- || font->mac_scriptcode == smKorean);
-
- if (is_two_byte_font)
- {
- int char_width;
-
- font->min_byte1 = 0xa1;
- font->max_byte1 = 0xfe;
- font->min_char_or_byte2 = 0xa1;
- font->max_char_or_byte2 = 0xfe;
-
- /* Use the width of an "ideographic space" of that font
- because the_fontinfo.widMax returns the wrong width for
- some fonts. */
- switch (font->mac_scriptcode)
- {
- case smJapanese:
- font->min_byte1 = 0x81;
- font->max_byte1 = 0xfc;
- font->min_char_or_byte2 = 0x40;
- font->max_char_or_byte2 = 0xfc;
- char_width = StringWidth("\p\x81\x40");
- break;
- case smTradChinese:
- font->min_char_or_byte2 = 0x40;
- char_width = StringWidth("\p\xa1\x40");
- break;
- case smSimpChinese:
- char_width = StringWidth("\p\xa1\xa1");
- break;
- case smKorean:
- char_width = StringWidth("\p\xa1\xa1");
- break;
- }
-
- font->bounds.per_char = NULL;
-
- if (fontface & italic)
- font->max_bounds.rbearing = char_width + 1;
- else
- font->max_bounds.rbearing = char_width;
- font->max_bounds.lbearing = 0;
- font->max_bounds.width = char_width;
- font->max_bounds.ascent = the_fontinfo.ascent;
- font->max_bounds.descent = the_fontinfo.descent;
-
- font->min_bounds = font->max_bounds;
- }
- else
- {
- int c;
-
- font->min_byte1 = font->max_byte1 = 0;
- font->min_char_or_byte2 = 0x20;
- font->max_char_or_byte2 = 0xff;
-
- font->bounds.per_char =
- xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
- bzero (font->bounds.per_char,
- sizeof (XCharStruct) * (0xff - 0x20 + 1));
-
- space_bounds = font->bounds.per_char;
- err = mac_query_char_extents (NULL, 0x20, &font->ascent,
- &font->descent, space_bounds, NULL);
- if (err != noErr || space_bounds->width <= 0)
- {
- mac_unload_font (&one_mac_display_info, font);
- return NULL;
- }
-
- for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
- mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
- }
- }
-
- if (space_bounds)
- {
- int c;
-
- font->min_bounds = font->max_bounds = *space_bounds;
- for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++)
- if (pcm->width > 0)
- {
- font->min_bounds.lbearing = min (font->min_bounds.lbearing,
- pcm->lbearing);
- font->min_bounds.rbearing = min (font->min_bounds.rbearing,
- pcm->rbearing);
- font->min_bounds.width = min (font->min_bounds.width,
- pcm->width);
- font->min_bounds.ascent = min (font->min_bounds.ascent,
- pcm->ascent);
- font->min_bounds.descent = min (font->min_bounds.descent,
- pcm->descent);
-
- font->max_bounds.lbearing = max (font->max_bounds.lbearing,
- pcm->lbearing);
- font->max_bounds.rbearing = max (font->max_bounds.rbearing,
- pcm->rbearing);
- font->max_bounds.width = max (font->max_bounds.width,
- pcm->width);
- font->max_bounds.ascent = max (font->max_bounds.ascent,
- pcm->ascent);
- font->max_bounds.descent = max (font->max_bounds.descent,
- pcm->descent);
- }
- if (
-#if USE_ATSUI
- font->mac_style == NULL &&
-#endif
- font->max_bounds.width == font->min_bounds.width
- && font->min_bounds.lbearing >= 0
- && font->max_bounds.rbearing <= font->max_bounds.width)
- {
- /* Fixed width and no overhangs. */
- xfree (font->bounds.per_char);
- font->bounds.per_char = NULL;
- }
- }
-
-#if !defined (MAC_OS8) || USE_ATSUI
- /* AppKit and WebKit do some adjustment to the heights of Courier,
- Helvetica, and Times. This only works on the environments where
- srcCopy text transfer mode is never used. */
- if (
-#ifdef MAC_OS8 /* implies USE_ATSUI */
- font->mac_style &&
-#endif
- (strcmp (family, "courier") == 0 || strcmp (family, "helvetica") == 0
- || strcmp (family, "times") == 0))
- font->ascent += (font->ascent + font->descent) * .15 + 0.5;
-#endif
-
- return font;
-}
-
-
-void
-mac_unload_font (dpyinfo, font)
- struct mac_display_info *dpyinfo;
- XFontStruct *font;
-{
- xfree (font->full_name);
-#if USE_ATSUI
- if (font->mac_style)
- {
- int i;
-
- for (i = font->min_byte1; i <= font->max_byte1; i++)
- xfree (font->bounds.rows[i]);
- xfree (font->bounds.rows);
- ATSUDisposeStyle (font->mac_style);
- }
- else
-#endif
- xfree (font->bounds.per_char);
-#if USE_CG_TEXT_DRAWING
- if (font->cg_font)
- CGFontRelease (font->cg_font);
- xfree (font->cg_glyphs);
-#endif
- xfree (font);
-}
-
-
-/* Load font named FONTNAME of the size SIZE for frame F, and return a
- pointer to the structure font_info while allocating it dynamically.
- If SIZE is 0, load any size of font.
- If loading is failed, return NULL. */
-
-struct font_info *
-x_load_font (f, fontname, size)
- struct frame *f;
- register char *fontname;
- int size;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- Lisp_Object font_names;
-
- /* Get a list of all the fonts that match this name. Once we
- have a list of matching fonts, we compare them against the fonts
- we already have by comparing names. */
- font_names = x_list_fonts (f, build_string (fontname), size, 1);
-
- if (!NILP (font_names))
- {
- Lisp_Object tail;
- int i;
-
- for (i = 0; i < dpyinfo->n_fonts; i++)
- for (tail = font_names; CONSP (tail); tail = XCDR (tail))
- if (dpyinfo->font_table[i].name
- && (!strcmp (dpyinfo->font_table[i].name,
- SDATA (XCAR (tail)))
- || !strcmp (dpyinfo->font_table[i].full_name,
- SDATA (XCAR (tail)))))
- return (dpyinfo->font_table + i);
- }
- else
- return NULL;
-
- /* Load the font and add it to the table. */
- {
- struct MacFontStruct *font;
- struct font_info *fontp;
- int i;
-
- fontname = (char *) SDATA (XCAR (font_names));
-
- BLOCK_INPUT;
- font = mac_load_query_font (f, fontname);
- UNBLOCK_INPUT;
- if (!font)
- return NULL;
-
- /* Find a free slot in the font table. */
- for (i = 0; i < dpyinfo->n_fonts; ++i)
- if (dpyinfo->font_table[i].name == NULL)
- break;
-
- /* If no free slot found, maybe enlarge the font table. */
- if (i == dpyinfo->n_fonts
- && dpyinfo->n_fonts == dpyinfo->font_table_size)
- {
- int sz;
- dpyinfo->font_table_size = max (16, 2 * dpyinfo->font_table_size);
- sz = dpyinfo->font_table_size * sizeof *dpyinfo->font_table;
- dpyinfo->font_table
- = (struct font_info *) xrealloc (dpyinfo->font_table, sz);
- }
-
- fontp = dpyinfo->font_table + i;
- if (i == dpyinfo->n_fonts)
- ++dpyinfo->n_fonts;
-
- /* Now fill in the slots of *FONTP. */
- BLOCK_INPUT;
- bzero (fontp, sizeof (*fontp));
- fontp->font = font;
- fontp->font_idx = i;
- fontp->charset = -1; /* fs_load_font sets it. */
- fontp->name = (char *) xmalloc (strlen (fontname) + 1);
- bcopy (fontname, fontp->name, strlen (fontname) + 1);
-
- if (font->min_bounds.width == font->max_bounds.width)
- {
- /* Fixed width font. */
- fontp->average_width = fontp->space_width = font->min_bounds.width;
- }
- else
- {
- XChar2b char2b;
- XCharStruct *pcm;
-
- char2b.byte1 = 0x00, char2b.byte2 = 0x20;
- pcm = mac_per_char_metric (font, &char2b, 0);
- if (pcm)
- fontp->space_width = pcm->width;
- else
- fontp->space_width = FONT_WIDTH (font);
-
- if (pcm)
- {
- int width = pcm->width;
- for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
- if ((pcm = mac_per_char_metric (font, &char2b, 0)) != NULL)
- width += pcm->width;
- fontp->average_width = width / 95;
- }
- else
- fontp->average_width = FONT_WIDTH (font);
- }
-
- fontp->full_name = (char *) xmalloc (strlen (font->full_name) + 1);
- bcopy (font->full_name, fontp->full_name, strlen (font->full_name) + 1);
-
- fontp->size = font->max_bounds.width;
- fontp->height = FONT_HEIGHT (font);
- {
- /* For some font, ascent and descent in max_bounds field is
- larger than the above value. */
- int max_height = font->max_bounds.ascent + font->max_bounds.descent;
- if (max_height > fontp->height)
- fontp->height = max_height;
- }
-
- /* MAC_TODO: The script encoding is irrelevant in unicode? */
- /* The slot `encoding' specifies how to map a character
- code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
- the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
- (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
- 2:0xA020..0xFF7F). For the moment, we don't know which charset
- uses this font. So, we set information in fontp->encoding_type
- which is never used by any charset. If mapping can't be
- decided, set FONT_ENCODING_NOT_DECIDED. */
- if (font->mac_scriptcode == smJapanese)
- fontp->encoding_type = 4;
- else
- {
- fontp->encoding_type
- = (font->max_byte1 == 0
- /* 1-byte font */
- ? (font->min_char_or_byte2 < 0x80
- ? (font->max_char_or_byte2 < 0x80
- ? 0 /* 0x20..0x7F */
- : FONT_ENCODING_NOT_DECIDED) /* 0x20..0xFF */
- : 1) /* 0xA0..0xFF */
- /* 2-byte font */
- : (font->min_byte1 < 0x80
- ? (font->max_byte1 < 0x80
- ? (font->min_char_or_byte2 < 0x80
- ? (font->max_char_or_byte2 < 0x80
- ? 0 /* 0x2020..0x7F7F */
- : FONT_ENCODING_NOT_DECIDED) /* 0x2020..0x7FFF */
- : 3) /* 0x20A0..0x7FFF */
- : FONT_ENCODING_NOT_DECIDED) /* 0x20??..0xA0?? */
- : (font->min_char_or_byte2 < 0x80
- ? (font->max_char_or_byte2 < 0x80
- ? 2 /* 0xA020..0xFF7F */
- : FONT_ENCODING_NOT_DECIDED) /* 0xA020..0xFFFF */
- : 1))); /* 0xA0A0..0xFFFF */
- }
-
-#if 0 /* MAC_TODO: fill these out with more reasonably values */
- fontp->baseline_offset
- = (XGetFontProperty (font, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
- ? (long) value : 0);
- fontp->relative_compose
- = (XGetFontProperty (font, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
- ? (long) value : 0);
- fontp->default_ascent
- = (XGetFontProperty (font, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
- ? (long) value : 0);
-#else
- fontp->baseline_offset = 0;
- fontp->relative_compose = 0;
- fontp->default_ascent = 0;
-#endif
-
- /* Set global flag fonts_changed_p to non-zero if the font loaded
- has a character with a smaller width than any other character
- before, or if the font loaded has a smaller height than any
- other font loaded before. If this happens, it will make a
- glyph matrix reallocation necessary. */
- fonts_changed_p |= x_compute_min_glyph_bounds (f);
- UNBLOCK_INPUT;
- return fontp;
- }
-}
-
-
-/* Return a pointer to struct font_info of a font named FONTNAME for
- frame F. If no such font is loaded, return NULL. */
-
-struct font_info *
-x_query_font (f, fontname)
- struct frame *f;
- register char *fontname;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- int i;
-
- for (i = 0; i < dpyinfo->n_fonts; i++)
- if (dpyinfo->font_table[i].name
- && (!xstrcasecmp (dpyinfo->font_table[i].name, fontname)
- || !xstrcasecmp (dpyinfo->font_table[i].full_name, fontname)))
- return (dpyinfo->font_table + i);
- return NULL;
-}
-
-
-/* Find a CCL program for a font specified by FONTP, and set the member
- `encoder' of the structure. */
-
-void
-x_find_ccl_program (fontp)
- struct font_info *fontp;
-{
- Lisp_Object list, elt;
-
- for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
- {
- elt = XCAR (list);
- if (CONSP (elt)
- && STRINGP (XCAR (elt))
- && (fast_c_string_match_ignore_case (XCAR (elt), fontp->name)
- >= 0))
- break;
- }
- if (! NILP (list))
- {
- struct ccl_program *ccl
- = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
-
- if (setup_ccl_program (ccl, XCDR (elt)) < 0)
- xfree (ccl);
- else
- fontp->font_encoder = ccl;
- }
-}
-
-#if USE_MAC_FONT_PANEL
-/* Whether Font Panel has been shown before. The first call to font
- panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
- slow. This variable is used for deferring such a call as much as
- possible. */
-static int font_panel_shown_p = 0;
-
-extern Lisp_Object Qfont;
-static Lisp_Object Qpanel_closed, Qselection;
-
-static OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
- Lisp_Object,
- Lisp_Object,
- EventRef, UInt32,
- const EventParamName *,
- const EventParamType *));
-
-int
-mac_font_panel_visible_p ()
-{
- return font_panel_shown_p && FPIsFontPanelVisible ();
-}
-
-static pascal OSStatus
-mac_handle_font_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus result, err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_sel[] = {kEventParamATSUFontID,
- kEventParamATSUFontSize,
- kEventParamFMFontFamily,
- kEventParamFMFontStyle,
- kEventParamFMFontSize,
- kEventParamFontColor};
- static const EventParamType types_sel[] = {typeATSUFontID,
- typeATSUSize,
- typeFMFontFamily,
- typeFMFontStyle,
- typeFMFontSize,
- typeFontColor};
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventFontPanelClosed:
- id_key = Qpanel_closed;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
-
- case kEventFontSelection:
- id_key = Qselection;
- num_params = sizeof (names_sel) / sizeof (names_sel[0]);
- names = names_sel;
- types = types_sel;
- break;
- }
-
- err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
- event, num_params,
- names, types);
- if (err == noErr)
- result = noErr;
-
- return result;
-}
-
-OSStatus
-mac_show_hide_font_panel ()
-{
- if (!font_panel_shown_p)
- {
- OSStatus err;
-
- static const EventTypeSpec specs[] =
- {{kEventClassFont, kEventFontPanelClosed},
- {kEventClassFont, kEventFontSelection}};
-
- err = InstallApplicationEventHandler (mac_handle_font_event,
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- if (err != noErr)
- return err;
-
- font_panel_shown_p = 1;
- }
-
- return FPShowHideFontPanel ();
-}
-
-OSStatus
-mac_set_font_info_for_selection (f, face_id, c)
- struct frame *f;
- int face_id, c;
-{
- OSStatus err;
- EventTargetRef target = NULL;
- XFontStruct *font = NULL;
-
- if (!mac_font_panel_visible_p ())
- return noErr;
-
- if (f)
- {
- target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
-
- if (FRAME_FACE_CACHE (f) && CHAR_VALID_P (c, 0))
- {
- struct face *face;
-
- face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
- face = FACE_FROM_ID (f, face_id);
- font = face->font;
- }
- }
-
- if (font == NULL)
- err = SetFontInfoForSelection (kFontSelectionATSUIType, 0, NULL, target);
- else
- {
- if (font->mac_fontnum != -1)
- {
- FontSelectionQDStyle qd_style;
-
- qd_style.version = kFontSelectionQDStyleVersionZero;
- qd_style.instance.fontFamily = font->mac_fontnum;
- qd_style.instance.fontStyle = font->mac_fontface;
- qd_style.size = font->mac_fontsize;
- qd_style.hasColor = false;
-
- err = SetFontInfoForSelection (kFontSelectionQDType,
- 1, &qd_style, target);
- }
- else
- err = SetFontInfoForSelection (kFontSelectionATSUIType,
- 1, &font->mac_style, target);
- }
-
- return err;
-}
-#endif
-
-
-/* The Mac Event loop code */
-
-#if !TARGET_API_MAC_CARBON
-#include <Events.h>
-#include <Quickdraw.h>
-#include <Balloons.h>
-#include <Devices.h>
-#include <Fonts.h>
-#include <Gestalt.h>
-#include <Menus.h>
-#include <Processes.h>
-#include <Sound.h>
-#include <ToolUtils.h>
-#include <TextUtils.h>
-#include <Dialogs.h>
-#include <Script.h>
-#include <Types.h>
-#include <Resources.h>
-
-#if __MWERKS__
-#include <unix.h>
-#endif
-#endif /* ! TARGET_API_MAC_CARBON */
-
-#define M_APPLE 234
-#define I_ABOUT 1
-
-#define DEFAULT_NUM_COLS 80
-
-#define MIN_DOC_SIZE 64
-#define MAX_DOC_SIZE 32767
-
-#define EXTRA_STACK_ALLOC (256 * 1024)
-
-#define ARGV_STRING_LIST_ID 129
-#define ABOUT_ALERT_ID 128
-#define RAM_TOO_LARGE_ALERT_ID 129
-
-/* Contains the string "reverse", which is a constant for mouse button emu.*/
-Lisp_Object Qreverse;
-
-
-/* Modifier associated with the control key, or nil to ignore. */
-Lisp_Object Vmac_control_modifier;
-
-/* Modifier associated with the option key, or nil to ignore. */
-Lisp_Object Vmac_option_modifier;
-
-/* Modifier associated with the command key, or nil to ignore. */
-Lisp_Object Vmac_command_modifier;
-
-/* Modifier associated with the function key, or nil to ignore. */
-Lisp_Object Vmac_function_modifier;
-
-/* True if the option and command modifiers should be used to emulate
- a three button mouse */
-Lisp_Object Vmac_emulate_three_button_mouse;
-
-#if TARGET_API_MAC_CARBON
-/* Non-zero if the mouse wheel button (i.e. button 4) should map to
- mouse-2, instead of mouse-3. */
-int mac_wheel_button_is_mouse_2;
-
-/* If non-zero, the Mac "Command" key is passed on to the Mac Toolbox
- for processing before Emacs sees it. */
-int mac_pass_command_to_system;
-
-/* If non-zero, the Mac "Control" key is passed on to the Mac Toolbox
- for processing before Emacs sees it. */
-int mac_pass_control_to_system;
-#endif
-
-/* Points to the variable `inev' in the function XTread_socket. It is
- used for passing an input event to the function back from
- Carbon/Apple event handlers. */
-static struct input_event *read_socket_inev = NULL;
-
-/* Whether or not the screen configuration has changed. */
-static int mac_screen_config_changed = 0;
-
-Point saved_menu_event_location;
-
-/* Apple Events */
-#if TARGET_API_MAC_CARBON
-static Lisp_Object Qhi_command;
-#ifdef MAC_OSX
-extern Lisp_Object Qwindow;
-static Lisp_Object Qtoolbar_switch_mode;
-#endif
-#if USE_MAC_TSM
-static TSMDocumentID tsm_document_id;
-Lisp_Object Qtext_input;
-Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
-Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
-extern Lisp_Object Qbefore_string;
-static Lisp_Object Vmac_ts_script_language_on_focus;
-static Lisp_Object saved_ts_script_language_on_focus;
-static ScriptLanguageRecord saved_ts_language;
-static Component saved_ts_component;
-#endif
-#endif /* TARGET_API_MAC_CARBON */
-extern int mac_ready_for_apple_events;
-extern Lisp_Object Qundefined;
-extern void init_apple_event_handler P_ ((void));
-extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
- Lisp_Object *, Lisp_Object *,
- Lisp_Object *));
-extern OSErr init_coercion_handler P_ ((void));
-
-/* Drag and Drop */
-extern OSErr install_drag_handler P_ ((WindowRef));
-extern void remove_drag_handler P_ ((WindowRef));
-
-#if TARGET_API_MAC_CARBON
-/* Showing help echo string during menu tracking */
-extern OSStatus install_menu_target_item_handler P_ ((void));
-
-#ifdef MAC_OSX
-extern OSStatus install_service_handler ();
-Lisp_Object Qservice, Qpaste, Qperform;
-Lisp_Object Qmouse_drag_overlay;
-#endif
-#endif
-
-extern void init_emacs_passwd_dir ();
-extern int emacs_main (int, char **, char **);
-
-extern void initialize_applescript();
-extern void terminate_applescript();
-
-/* Table for translating Mac keycode to X keysym values. Contributed
- by Sudhir Shenoy.
- Mapping for special keys is now identical to that in Apple X11
- except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
- on the right of the Cmd key on laptops, and fn + `enter' (->
- <linefeed>). */
-static const unsigned char keycode_to_xkeysym_table[] = {
- /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
- /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
- /*0x38*/ 0, 0, 0, 0,
- /*0x3C*/ 0, 0, 0, 0,
-
- /*0x40*/ 0xce /*f17*/, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
- /*0x44*/ 0, 0xab /*kp-add*/, 0, 0x0b /*clear*/,
- /*0x48*/ 0, 0, 0, 0xaf /*kp-divide*/,
- /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0xcf /*f18*/,
-
- /*0x50*/ 0xd0 /*f19*/, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
- /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
- /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
- /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
-
- /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
- /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
- /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
- /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
-
- /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
- /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
- /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
- /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
-};
-
-#ifdef MAC_OSX
-/* Table for translating Mac keycode with the laptop `fn' key to that
- without it. Destination symbols in comments are keys on US
- keyboard, and they may not be the same on other types of keyboards.
- If the destination is identical to the source (f1 ... f12), it
- doesn't map `fn' key to a modifier. */
-static const unsigned char fn_keycode_to_keycode_table[] = {
- /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- /*0x30*/ 0, 0, 0, 0,
- /*0x34*/ 0, 0, 0, 0,
- /*0x38*/ 0, 0, 0, 0,
- /*0x3C*/ 0, 0, 0, 0,
-
- /*0x40*/ 0x40 /*f17 = f17*/, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
- /*0x44*/ 0, 0x2c /*kp-add -> '/'*/, 0, 0x16 /*clear -> '6'*/,
- /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
- /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0x4f /*f18 = f18*/,
-
- /*0x50*/ 0x50 /*f19 = f19*/, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
- /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
- /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
- /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
-
- /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
- /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
- /*0x68*/ 0, 0, 0, 0,
- /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
-
- /*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
- /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
- /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 0,
- /*0x7C*/ 0, 0, 0, 0
-};
-#endif /* MAC_OSX */
-
-static int
-#if TARGET_API_MAC_CARBON
-mac_to_emacs_modifiers (UInt32 mods)
-#else
-mac_to_emacs_modifiers (EventModifiers mods)
-#endif
-{
- unsigned int result = 0;
- if (mods & shiftKey)
- result |= shift_modifier;
-
- /* Deactivated to simplify configuration:
- if Vmac_option_modifier is non-NIL, we fully process the Option
- key. Otherwise, we only process it if an additional Ctrl or Command
- is pressed. That way the system may convert the character to a
- composed one.
- if ((mods & optionKey) &&
- (( !NILP(Vmac_option_modifier) ||
- ((mods & cmdKey) || (mods & controlKey))))) */
-
- if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
- Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
- if (INTEGERP(val))
- result |= XUINT(val);
- }
- if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) {
- Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value);
- if (INTEGERP(val))
- result |= XUINT(val);
- }
- if (!NILP (Vmac_control_modifier) && (mods & controlKey)) {
- Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value);
- if (INTEGERP(val))
- result |= XUINT(val);
- }
-
-#ifdef MAC_OSX
- if (!NILP (Vmac_function_modifier) && (mods & kEventKeyModifierFnMask)) {
- Lisp_Object val = Fget(Vmac_function_modifier, Qmodifier_value);
- if (INTEGERP(val))
- result |= XUINT(val);
- }
-#endif
-
- return result;
-}
-
-static UInt32
-mac_mapped_modifiers (modifiers)
- UInt32 modifiers;
-{
- UInt32 mapped_modifiers_all =
- (NILP (Vmac_control_modifier) ? 0 : controlKey)
- | (NILP (Vmac_option_modifier) ? 0 : optionKey)
- | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-
-#ifdef MAC_OSX
- mapped_modifiers_all |=
- (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
-#endif
-
- return mapped_modifiers_all & modifiers;
-}
-
-static int
-mac_get_emulated_btn ( UInt32 modifiers )
-{
- int result = 0;
- if (!NILP (Vmac_emulate_three_button_mouse)) {
- int cmdIs3 = !EQ (Vmac_emulate_three_button_mouse, Qreverse);
- if (modifiers & cmdKey)
- result = cmdIs3 ? 2 : 1;
- else if (modifiers & optionKey)
- result = cmdIs3 ? 1 : 2;
- }
- return result;
-}
-
-#ifdef MAC_OSX
-void
-mac_get_selected_range (w, range)
- struct window *w;
- CFRange *range;
-{
- Lisp_Object overlay = find_symbol_value (Qmouse_drag_overlay);
- struct buffer *b = XBUFFER (w->buffer);
- int begv = BUF_BEGV (b), zv = BUF_ZV (b);
- int start, end;
-
- if (OVERLAYP (overlay)
- && EQ (Foverlay_buffer (overlay), w->buffer)
- && (start = XINT (Foverlay_start (overlay)),
- end = XINT (Foverlay_end (overlay)),
- start != end))
- ;
- else
- {
- if (w == XWINDOW (selected_window) && b == current_buffer)
- start = PT;
- else
- start = marker_position (w->pointm);
-
- if (NILP (Vtransient_mark_mode) || NILP (b->mark_active))
- end = start;
- else
- {
- int mark_pos = marker_position (b->mark);
-
- if (start <= mark_pos)
- end = mark_pos;
- else
- {
- end = start;
- start = mark_pos;
- }
- }
- }
-
- if (start != end)
- {
- if (start < begv)
- start = begv;
- else if (start > zv)
- start = zv;
-
- if (end < begv)
- end = begv;
- else if (end > zv)
- end = zv;
- }
-
- range->location = start - begv;
- range->length = end - start;
-}
-
-/* Store the text of the buffer BUF from START to END as Unicode
- characters in CHARACTERS. Return non-zero if successful. */
-
-int
-mac_store_buffer_text_to_unicode_chars (buf, start, end, characters)
- struct buffer *buf;
- int start, end;
- UniChar *characters;
-{
- int start_byte, end_byte, char_count, byte_count;
- struct coding_system coding;
- unsigned char *dst = (unsigned char *) characters;
-
- start_byte = buf_charpos_to_bytepos (buf, start);
- end_byte = buf_charpos_to_bytepos (buf, end);
- char_count = end - start;
- byte_count = end_byte - start_byte;
-
- if (setup_coding_system (
-#ifdef WORDS_BIG_ENDIAN
- intern ("utf-16be")
-#else
- intern ("utf-16le")
-#endif
- , &coding) < 0)
- return 0;
-
- coding.src_multibyte = !NILP (buf->enable_multibyte_characters);
- coding.dst_multibyte = 0;
- coding.mode |= CODING_MODE_LAST_BLOCK;
- coding.composing = COMPOSITION_DISABLED;
-
- if (BUF_GPT_BYTE (buf) <= start_byte || end_byte <= BUF_GPT_BYTE (buf))
- encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst,
- byte_count, char_count * sizeof (UniChar));
- else
- {
- int first_byte_count = BUF_GPT_BYTE (buf) - start_byte;
-
- encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst,
- first_byte_count, char_count * sizeof (UniChar));
- if (coding.result == CODING_FINISH_NORMAL)
- encode_coding (&coding,
- BUF_BYTE_ADDRESS (buf, start_byte + first_byte_count),
- dst + coding.produced,
- byte_count - first_byte_count,
- char_count * sizeof (UniChar) - coding.produced);
- }
-
- if (coding.result != CODING_FINISH_NORMAL)
- return 0;
-
- return 1;
-}
-
-void
-mac_ax_selected_text_range (f, range)
- struct frame *f;
- CFRange *range;
-{
- mac_get_selected_range (XWINDOW (f->selected_window), range);
-}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-unsigned int
-mac_ax_number_of_characters (f)
- struct frame *f;
-{
- struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
-
- return BUF_ZV (b) - BUF_BEGV (b);
-}
-#endif
-#endif
-
-#if USE_MAC_TSM
-OSStatus
-mac_restore_keyboard_input_source ()
-{
- OSStatus err = noErr;
- ScriptLanguageRecord slrec, *slptr = NULL;
-
- if (EQ (Vmac_ts_script_language_on_focus, Qt)
- && EQ (saved_ts_script_language_on_focus, Qt))
- slptr = &saved_ts_language;
- else if (CONSP (Vmac_ts_script_language_on_focus)
- && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
- && INTEGERP (XCDR (Vmac_ts_script_language_on_focus))
- && CONSP (saved_ts_script_language_on_focus)
- && EQ (XCAR (saved_ts_script_language_on_focus),
- XCAR (Vmac_ts_script_language_on_focus))
- && EQ (XCDR (saved_ts_script_language_on_focus),
- XCDR (Vmac_ts_script_language_on_focus)))
- {
- slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
- slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
- slptr = &slrec;
- }
-
- if (slptr)
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- err = SetDefaultInputMethodOfClass (saved_ts_component, slptr,
- kKeyboardInputMethodClass);
-#else
- err = SetDefaultInputMethod (saved_ts_component, slptr);
-#endif
- if (err == noErr)
- err = SetTextServiceLanguage (slptr);
-
- /* Seems to be needed on Mac OS X 10.2. */
- if (err == noErr)
- KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
- }
-
- return err;
-}
-
-void
-mac_save_keyboard_input_source ()
-{
- OSStatus err;
- ScriptLanguageRecord slrec, *slptr = NULL;
-
- saved_ts_script_language_on_focus = Vmac_ts_script_language_on_focus;
-
- if (EQ (Vmac_ts_script_language_on_focus, Qt))
- {
- err = GetTextServiceLanguage (&saved_ts_language);
- if (err == noErr)
- slptr = &saved_ts_language;
- }
- else if (CONSP (Vmac_ts_script_language_on_focus)
- && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
- && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
- {
- slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
- slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
- slptr = &slrec;
- }
-
- if (slptr)
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
- kKeyboardInputMethodClass);
-#else
- GetDefaultInputMethod (&saved_ts_component, slptr);
-#endif
- }
-}
-#endif
-
-#if TARGET_API_MAC_CARBON
-/***** Code to handle C-g testing *****/
-extern int quit_char;
-extern int make_ctrl_char P_ ((int));
-
-int
-mac_quit_char_key_p (modifiers, key_code)
- UInt32 modifiers, key_code;
-{
- UInt32 char_code;
- unsigned long some_state = 0;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- int c, emacs_modifiers;
-
- /* Mask off modifier keys that are mapped to some Emacs modifiers. */
- key_code |= (modifiers & ~(mac_mapped_modifiers (modifiers)));
- char_code = KeyTranslate (kchr_ptr, key_code, &some_state);
- if (char_code & ~0xff)
- return 0;
-
- emacs_modifiers = mac_to_emacs_modifiers (modifiers);
- if (emacs_modifiers & ctrl_modifier)
- c = make_ctrl_char (char_code);
-
- c |= (emacs_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
-
- return c == quit_char;
-}
-#endif
-
-#if TARGET_API_MAC_CARBON
-/* Obtains the event modifiers from the event ref and then calls
- mac_to_emacs_modifiers. */
-static int
-mac_event_to_emacs_modifiers (EventRef eventRef)
-{
- UInt32 mods = 0, class;
-
- GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
- sizeof (UInt32), NULL, &mods);
- class = GetEventClass (eventRef);
- if (!NILP (Vmac_emulate_three_button_mouse) &&
- (class == kEventClassMouse || class == kEventClassCommand))
- {
- mods &= ~(optionKey | cmdKey);
- }
- return mac_to_emacs_modifiers (mods);
-}
-
-/* Given an event ref, return the code to use for the mouse button
- code in the emacs input_event. */
-static int
-mac_get_mouse_btn (EventRef ref)
-{
- EventMouseButton result = kEventMouseButtonPrimary;
- GetEventParameter (ref, kEventParamMouseButton, typeMouseButton, NULL,
- sizeof (EventMouseButton), NULL, &result);
- switch (result)
- {
- case kEventMouseButtonPrimary:
- if (NILP (Vmac_emulate_three_button_mouse))
- return 0;
- else {
- UInt32 mods = 0;
- GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
- sizeof (UInt32), NULL, &mods);
- return mac_get_emulated_btn(mods);
- }
- case kEventMouseButtonSecondary:
- return mac_wheel_button_is_mouse_2 ? 2 : 1;
- case kEventMouseButtonTertiary:
- case 4: /* 4 is the number for the mouse wheel button */
- return mac_wheel_button_is_mouse_2 ? 1 : 2;
- default:
- return 0;
- }
-}
-
-/* Normally, ConvertEventRefToEventRecord will correctly handle all
- events. However the click of the mouse wheel is not converted to a
- mouseDown or mouseUp event. Likewise for dead key events. This
- calls ConvertEventRefToEventRecord, but then checks to see if it is
- a mouse up/down, or a dead key Carbon event that has not been
- converted, and if so, converts it by hand (to be picked up in the
- XTread_socket loop). */
-static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
-{
- OSStatus err;
- Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
- EventKind action;
-
- if (result)
- return result;
-
- switch (GetEventClass (eventRef))
- {
- case kEventClassMouse:
- switch (GetEventKind (eventRef))
- {
- case kEventMouseDown:
- eventRec->what = mouseDown;
- result = 1;
- break;
-
- case kEventMouseUp:
- eventRec->what = mouseUp;
- result = 1;
- break;
-
- default:
- break;
- }
- break;
-
- case kEventClassKeyboard:
- switch (GetEventKind (eventRef))
- {
- case kEventRawKeyDown:
- action = keyDown;
- goto keystroke_common;
- case kEventRawKeyRepeat:
- action = autoKey;
- goto keystroke_common;
- case kEventRawKeyUp:
- action = keyUp;
- keystroke_common:
- {
- unsigned char char_codes;
- UInt32 key_code;
-
- err = GetEventParameter (eventRef, kEventParamKeyMacCharCodes,
- typeChar, NULL, sizeof (char),
- NULL, &char_codes);
- if (err == noErr)
- err = GetEventParameter (eventRef, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr)
- {
- eventRec->what = action;
- eventRec->message = char_codes | ((key_code & 0xff) << 8);
- result = 1;
- }
- }
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (result)
- {
- /* Need where and when. */
- UInt32 mods = 0;
-
- GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint,
- NULL, sizeof (Point), NULL, &eventRec->where);
- /* Use two step process because new event modifiers are 32-bit
- and old are 16-bit. Currently, only loss is NumLock & Fn. */
- GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
- NULL, sizeof (UInt32), NULL, &mods);
- eventRec->modifiers = mods;
-
- eventRec->when = EventTimeToTicks (GetEventTime (eventRef));
- }
-
- return result;
-}
-
-#endif
-
-#ifdef MAC_OS8
-static void
-do_get_menus (void)
-{
- Handle menubar_handle;
- MenuRef menu;
-
- menubar_handle = GetNewMBar (128);
- if(menubar_handle == NULL)
- abort ();
- SetMenuBar (menubar_handle);
- DrawMenuBar ();
-
-#if !TARGET_API_MAC_CARBON
- menu = GetMenuRef (M_APPLE);
- if (menu != NULL)
- AppendResMenu (menu, 'DRVR');
- else
- abort ();
-#endif
-}
-
-
-static void
-do_init_managers (void)
-{
-#if !TARGET_API_MAC_CARBON
- InitGraf (&qd.thePort);
- InitFonts ();
- FlushEvents (everyEvent, 0);
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (NULL);
-#endif /* !TARGET_API_MAC_CARBON */
- InitCursor ();
-
-#if !TARGET_API_MAC_CARBON
- /* set up some extra stack space for use by emacs */
- SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
-
- /* MaxApplZone must be called for AppleScript to execute more
- complicated scripts */
- MaxApplZone ();
- MoreMasters ();
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-static void
-do_check_ram_size (void)
-{
- SInt32 physical_ram_size, logical_ram_size;
-
- if (Gestalt (gestaltPhysicalRAMSize, &physical_ram_size) != noErr
- || Gestalt (gestaltLogicalRAMSize, &logical_ram_size) != noErr
- || physical_ram_size > (1 << VALBITS)
- || logical_ram_size > (1 << VALBITS))
- {
- StopAlert (RAM_TOO_LARGE_ALERT_ID, NULL);
- exit (1);
- }
-}
-#endif /* MAC_OS8 */
-
-static void
-do_window_update (WindowRef win)
-{
- struct frame *f = mac_window_to_frame (win);
-
- BeginUpdate (win);
-
- /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
- below. */
- if (win != tip_window)
- {
- if (f->async_visible == 0)
- {
- /* Update events may occur when a frame gets iconified. */
-#if 0
- f->async_visible = 1;
- f->async_iconified = 0;
- SET_FRAME_GARBAGED (f);
-#endif
- }
- else
- {
- Rect r;
-#if TARGET_API_MAC_CARBON
- RgnHandle region = NewRgn ();
-
- GetPortVisibleRegion (GetWindowPort (win), region);
- GetRegionBounds (region, &r);
- expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- UpdateControls (win, region);
- DisposeRgn (region);
-#else
- r = (*win->visRgn)->rgnBBox;
- expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
- UpdateControls (win, win->visRgn);
-#endif
- }
- }
-
- EndUpdate (win);
-}
-
-static int
-is_emacs_window (WindowRef win)
-{
- Lisp_Object tail, frame;
-
- if (!win)
- return 0;
-
- FOR_EACH_FRAME (tail, frame)
- if (FRAME_MAC_P (XFRAME (frame)))
- if (FRAME_MAC_WINDOW (XFRAME (frame)) == win)
- return 1;
-
- return 0;
-}
-
-#if USE_MAC_TSM
-static OSStatus
-mac_tsm_resume ()
-{
- OSStatus err;
- ScriptLanguageRecord slrec, *slptr = NULL;
-
- err = ActivateTSMDocument (tsm_document_id);
-
- if (err == noErr)
- {
- if (EQ (Vmac_ts_script_language_on_focus, Qt)
- && EQ (saved_ts_script_language_on_focus, Qt))
- slptr = &saved_ts_language;
- else if (CONSP (Vmac_ts_script_language_on_focus)
- && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
- && INTEGERP (XCDR (Vmac_ts_script_language_on_focus))
- && CONSP (saved_ts_script_language_on_focus)
- && EQ (XCAR (saved_ts_script_language_on_focus),
- XCAR (Vmac_ts_script_language_on_focus))
- && EQ (XCDR (saved_ts_script_language_on_focus),
- XCDR (Vmac_ts_script_language_on_focus)))
- {
- slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
- slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
- slptr = &slrec;
- }
- }
-
- if (slptr)
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- err = SetDefaultInputMethodOfClass (saved_ts_component, slptr,
- kKeyboardInputMethodClass);
-#else
- err = SetDefaultInputMethod (saved_ts_component, slptr);
-#endif
- if (err == noErr)
- err = SetTextServiceLanguage (slptr);
-
- /* Seems to be needed on Mac OS X 10.2. */
- if (err == noErr)
- KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
- }
-
- return err;
-}
-
-static OSStatus
-mac_tsm_suspend ()
-{
- OSStatus err;
- ScriptLanguageRecord slrec, *slptr = NULL;
-
- saved_ts_script_language_on_focus = Vmac_ts_script_language_on_focus;
-
- if (EQ (Vmac_ts_script_language_on_focus, Qt))
- {
- err = GetTextServiceLanguage (&saved_ts_language);
- if (err == noErr)
- slptr = &saved_ts_language;
- }
- else if (CONSP (Vmac_ts_script_language_on_focus)
- && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
- && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
- {
- slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
- slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
- slptr = &slrec;
- }
-
- if (slptr)
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
- kKeyboardInputMethodClass);
-#else
- GetDefaultInputMethod (&saved_ts_component, slptr);
-#endif
- }
-
- err = DeactivateTSMDocument (tsm_document_id);
-
- return err;
-}
-#endif
-
-#if !TARGET_API_MAC_CARBON
-void
-do_apple_menu (SInt16 menu_item)
-{
- Str255 item_name;
- SInt16 da_driver_refnum;
-
- if (menu_item == I_ABOUT)
- NoteAlert (ABOUT_ALERT_ID, NULL);
- else
- {
- GetMenuItemText (GetMenuRef (M_APPLE), menu_item, item_name);
- da_driver_refnum = OpenDeskAcc (item_name);
- }
-}
-#endif /* !TARGET_API_MAC_CARBON */
-
-/* Handle drags in size box. Based on code contributed by Ben
- Mesander and IM - Window Manager A. */
-
-static void
-do_grow_window (w, e)
- WindowRef w;
- const EventRecord *e;
-{
- Rect limit_rect;
- int rows, columns, width, height;
- struct frame *f = mac_window_to_frame (w);
- XSizeHints *size_hints = FRAME_SIZE_HINTS (f);
- int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE;
-#if TARGET_API_MAC_CARBON
- Rect new_rect;
-#else
- long grow_size;
-#endif
-
- if (size_hints->flags & PMinSize)
- {
- min_width = size_hints->min_width;
- min_height = size_hints->min_height;
- }
- SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE);
-
-#if TARGET_API_MAC_CARBON
- if (!ResizeWindow (w, e->where, &limit_rect, &new_rect))
- return;
- height = new_rect.bottom - new_rect.top;
- width = new_rect.right - new_rect.left;
-#else
- grow_size = GrowWindow (w, e->where, &limit_rect);
- /* see if it really changed size */
- if (grow_size == 0)
- return;
- height = HiWord (grow_size);
- width = LoWord (grow_size);
-#endif
-
- if (width != FRAME_PIXEL_WIDTH (f)
- || height != FRAME_PIXEL_HEIGHT (f))
- {
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
-
- x_set_window_size (f, 0, columns, rows);
- }
-}
-
-
-#if TARGET_API_MAC_CARBON
-static Point
-mac_get_ideal_size (f)
- struct frame *f;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowRef w = FRAME_MAC_WINDOW (f);
- Point ideal_size;
- Rect standard_rect;
- int height, width, columns, rows;
-
- ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
- ideal_size.v = dpyinfo->height;
- IsWindowInStandardState (w, &ideal_size, &standard_rect);
- /* Adjust the standard size according to character boundaries. */
- width = standard_rect.right - standard_rect.left;
- height = standard_rect.bottom - standard_rect.top;
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
- ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
- ideal_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-
- return ideal_size;
-}
-#endif
-
-/* Handle clicks in zoom box. Calculation of "standard state" based
- on code in IM - Window Manager A and code contributed by Ben
- Mesander. The standard state of an Emacs window is 80-characters
- wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
-
-static void
-do_zoom_window (WindowRef w, int zoom_in_or_out)
-{
- Rect zoom_rect, port_rect;
- int width, height;
- struct frame *f = mac_window_to_frame (w);
-#if TARGET_API_MAC_CARBON
- Point ideal_size = mac_get_ideal_size (f);
-
- GetWindowBounds (w, kWindowContentRgn, &port_rect);
- if (IsWindowInStandardState (w, &ideal_size, &zoom_rect)
- && port_rect.left == zoom_rect.left
- && port_rect.top == zoom_rect.top)
- zoom_in_or_out = inZoomIn;
- else
- zoom_in_or_out = inZoomOut;
-
-#ifdef MAC_OS8
- mac_clear_window (f);
-#endif
- ZoomWindowIdeal (w, zoom_in_or_out, &ideal_size);
-#else /* not TARGET_API_MAC_CARBON */
- GrafPtr save_port;
- Point top_left;
- int w_title_height, rows;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- GetPort (&save_port);
-
- SetPortWindowPort (w);
-
- /* Clear window to avoid flicker. */
- EraseRect (&(w->portRect));
- if (zoom_in_or_out == inZoomOut)
- {
- SetPt (&top_left, w->portRect.left, w->portRect.top);
- LocalToGlobal (&top_left);
-
- /* calculate height of window's title bar */
- w_title_height = top_left.v - 1
- - (**((WindowPeek) w)->strucRgn).rgnBBox.top + GetMBarHeight ();
-
- /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
- zoom_rect = qd.screenBits.bounds;
- zoom_rect.top += w_title_height;
- InsetRect (&zoom_rect, 8, 4); /* not too tight */
-
- zoom_rect.right = zoom_rect.left
- + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-
- /* Adjust the standard size according to character boundaries. */
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
- zoom_rect.bottom =
- zoom_rect.top + FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-
- (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
- = zoom_rect;
- }
-
- ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo));
-
- SetPort (save_port);
-#endif /* not TARGET_API_MAC_CARBON */
-
-#if !TARGET_API_MAC_CARBON
- /* retrieve window size and update application values */
- port_rect = w->portRect;
- height = port_rect.bottom - port_rect.top;
- width = port_rect.right - port_rect.left;
-
- mac_handle_size_change (f, width, height);
- mac_handle_origin_change (f);
-#endif
-}
-
-static void
-mac_set_unicode_keystroke_event (code, buf)
- UniChar code;
- struct input_event *buf;
-{
- int charset_id, c1, c2;
-
- if (code < 0x80)
- {
- buf->kind = ASCII_KEYSTROKE_EVENT;
- buf->code = code;
- }
- else if (code < 0x100)
- {
- if (code < 0xA0)
- charset_id = CHARSET_8_BIT_CONTROL;
- else
- charset_id = charset_latin_iso8859_1;
- buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- buf->code = MAKE_CHAR (charset_id, code, 0);
- }
- else
- {
- if (code < 0x2500)
- charset_id = charset_mule_unicode_0100_24ff,
- code -= 0x100;
- else if (code < 0x33FF)
- charset_id = charset_mule_unicode_2500_33ff,
- code -= 0x2500;
- else if (code >= 0xE000)
- charset_id = charset_mule_unicode_e000_ffff,
- code -= 0xE000;
- c1 = (code / 96) + 32, c2 = (code % 96) + 32;
- buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- buf->code = MAKE_CHAR (charset_id, c1, c2);
- }
-}
-
-static void
-do_keystroke (action, char_code, key_code, modifiers, timestamp, buf)
- EventKind action;
- unsigned char char_code;
- UInt32 key_code, modifiers;
- unsigned long timestamp;
- struct input_event *buf;
-{
- static SInt16 last_key_script = -1;
- SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
- UInt32 mapped_modifiers = mac_mapped_modifiers (modifiers);
-
-#ifdef MAC_OSX
- if (mapped_modifiers & kEventKeyModifierFnMask
- && key_code <= 0x7f
- && fn_keycode_to_keycode_table[key_code])
- key_code = fn_keycode_to_keycode_table[key_code];
-#endif
-
- if (key_code <= 0x7f && keycode_to_xkeysym_table[key_code])
- {
- buf->kind = NON_ASCII_KEYSTROKE_EVENT;
- buf->code = 0xff00 | keycode_to_xkeysym_table[key_code];
-#ifdef MAC_OSX
- if (modifiers & kEventKeyModifierFnMask
- && key_code <= 0x7f
- && fn_keycode_to_keycode_table[key_code] == key_code)
- modifiers &= ~kEventKeyModifierFnMask;
-#endif
- }
- else if (mapped_modifiers)
- {
- /* translate the keycode back to determine the original key */
-#ifdef MAC_OSX
- UCKeyboardLayout *uchr_ptr = NULL;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- OSStatus err;
- KeyboardLayoutRef layout;
-
- err = KLGetCurrentKeyboardLayout (&layout);
- if (err == noErr)
- err = KLGetKeyboardLayoutProperty (layout, kKLuchrData,
- (const void **) &uchr_ptr);
-#else
- static SInt16 last_key_layout_id = 0;
- static Handle uchr_handle = (Handle)-1;
- SInt16 current_key_layout_id =
- GetScriptVariable (current_key_script, smScriptKeys);
-
- if (uchr_handle == (Handle)-1
- || last_key_layout_id != current_key_layout_id)
- {
- uchr_handle = GetResource ('uchr', current_key_layout_id);
- last_key_layout_id = current_key_layout_id;
- }
- if (uchr_handle)
- uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
-#endif
-
- if (uchr_ptr)
- {
- OSStatus status;
- UInt16 key_action = action - keyDown;
- UInt32 modifier_key_state = (modifiers & ~mapped_modifiers) >> 8;
- UInt32 keyboard_type = LMGetKbdType ();
- SInt32 dead_key_state = 0;
- UniChar code;
- UniCharCount actual_length;
-
- status = UCKeyTranslate (uchr_ptr, key_code, key_action,
- modifier_key_state, keyboard_type,
- kUCKeyTranslateNoDeadKeysMask,
- &dead_key_state,
- 1, &actual_length, &code);
- if (status == noErr && actual_length == 1)
- mac_set_unicode_keystroke_event (code, buf);
- }
-#endif /* MAC_OSX */
-
- if (buf->kind == NO_EVENT)
- {
- /* This code comes from Keyboard Resource, Appendix C of IM
- - Text. This is necessary since shift is ignored in KCHR
- table translation when option or command is pressed. It
- also does not translate correctly control-shift chars
- like C-% so mask off shift here also. */
- /* Mask off modifier keys that are mapped to some Emacs
- modifiers. */
- int new_modifiers = modifiers & ~mapped_modifiers;
- /* set high byte of keycode to modifier high byte*/
- int new_key_code = key_code | new_modifiers;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- unsigned long some_state = 0;
- UInt32 new_char_code;
-
- new_char_code = KeyTranslate (kchr_ptr, new_key_code, &some_state);
- if (new_char_code == 0)
- /* Seems like a dead key. Append up-stroke. */
- new_char_code = KeyTranslate (kchr_ptr, new_key_code | 0x80,
- &some_state);
- if (new_char_code)
- {
- buf->kind = ASCII_KEYSTROKE_EVENT;
- buf->code = new_char_code & 0xff;
- }
- }
- }
-
- if (buf->kind == NO_EVENT)
- {
- buf->kind = ASCII_KEYSTROKE_EVENT;
- buf->code = char_code;
- }
-
- buf->modifiers = mac_to_emacs_modifiers (modifiers);
- buf->modifiers |= (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
-
-#if TARGET_API_MAC_CARBON
- if (buf->kind == ASCII_KEYSTROKE_EVENT
- && buf->code >= 0x80 && buf->modifiers)
- {
- OSStatus err;
- TextEncoding encoding = kTextEncodingMacRoman;
- TextToUnicodeInfo ttu_info;
-
- UpgradeScriptInfoToTextEncoding (current_key_script,
- kTextLanguageDontCare,
- kTextRegionDontCare,
- NULL, &encoding);
- err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
- if (err == noErr)
- {
- UniChar code;
- Str255 pstr;
- ByteCount unicode_len;
-
- pstr[0] = 1;
- pstr[1] = buf->code;
- err = ConvertFromPStringToUnicode (ttu_info, pstr,
- sizeof (UniChar),
- &unicode_len, &code);
- if (err == noErr && unicode_len == sizeof (UniChar))
- mac_set_unicode_keystroke_event (code, buf);
- DisposeTextToUnicodeInfo (&ttu_info);
- }
- }
-#endif
-
- if (buf->kind == ASCII_KEYSTROKE_EVENT
- && buf->code >= 0x80
- && last_key_script != current_key_script)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = LANGUAGE_CHANGE_EVENT;
- event.arg = Qnil;
- event.code = current_key_script;
- event.timestamp = timestamp;
- kbd_buffer_store_event (&event);
- last_key_script = current_key_script;
- }
-}
-
-void
-mac_store_apple_event (class, id, desc)
- Lisp_Object class, id;
- const AEDesc *desc;
-{
- struct input_event buf;
-
- EVENT_INIT (buf);
-
- buf.kind = MAC_APPLE_EVENT;
- buf.x = class;
- buf.y = id;
- XSETFRAME (buf.frame_or_window,
- mac_focus_frame (&one_mac_display_info));
- /* Now that Lisp object allocations are protected by BLOCK_INPUT, it
- is safe to use them during read_socket_hook. */
- buf.arg = mac_aedesc_to_lisp (desc);
- kbd_buffer_store_event (&buf);
-}
-
-#if TARGET_API_MAC_CARBON
-static OSStatus
-mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
- event, num_params, names, types)
- AEEventClass class;
- AEEventID id;
- Lisp_Object class_key, id_key;
- EventRef event;
- UInt32 num_params;
- const EventParamName *names;
- const EventParamType *types;
-{
- OSStatus err = eventNotHandledErr;
- Lisp_Object binding;
-
- mac_find_apple_event_spec (class, id, &class_key, &id_key, &binding);
- if (!NILP (binding) && !EQ (binding, Qundefined))
- {
- if (INTEGERP (binding))
- err = XINT (binding);
- else
- {
- AppleEvent apple_event;
- err = create_apple_event_from_event_ref (event, num_params,
- names, types,
- &apple_event);
- if (err == noErr)
- {
- mac_store_apple_event (class_key, id_key, &apple_event);
- AEDisposeDesc (&apple_event);
- mac_wakeup_from_rne ();
- }
- }
- }
-
- return err;
-}
-
-void
-mac_store_drag_event (window, mouse_pos, modifiers, desc)
- WindowRef window;
- Point mouse_pos;
- SInt16 modifiers;
- const AEDesc *desc;
-{
- struct input_event buf;
-
- EVENT_INIT (buf);
-
- buf.kind = DRAG_N_DROP_EVENT;
- buf.modifiers = mac_to_emacs_modifiers (modifiers);
- buf.timestamp = TickCount () * (1000 / 60);
- XSETINT (buf.x, mouse_pos.h);
- XSETINT (buf.y, mouse_pos.v);
- XSETFRAME (buf.frame_or_window, mac_window_to_frame (window));
- buf.arg = mac_aedesc_to_lisp (desc);
- kbd_buffer_store_event (&buf);
-}
-
-#ifdef MAC_OSX
-OSStatus
-mac_store_service_event (event)
- EventRef event;
-{
- OSStatus err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_pfm[] =
- {kEventParamServiceMessageName, kEventParamServiceUserData};
- static const EventParamType types_pfm[] =
- {typeCFStringRef, typeCFStringRef};
-
- switch (GetEventKind (event))
- {
- case kEventServicePaste:
- id_key = Qpaste;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
-
- case kEventServicePerform:
- id_key = Qperform;
- num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
- names = names_pfm;
- types = types_pfm;
- break;
-
- default:
- abort ();
- }
-
- err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
- event, num_params,
- names, types);
-
- return err;
-}
-#endif /* MAC_OSX */
-
-static pascal OSStatus
-mac_handle_window_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- WindowRef wp;
- OSStatus err, result = eventNotHandledErr;
- struct frame *f;
- UInt32 attributes;
- XSizeHints *size_hints;
-
- err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
- NULL, sizeof (WindowRef), NULL, &wp);
- if (err != noErr)
- return eventNotHandledErr;
-
- f = mac_window_to_frame (wp);
- switch (GetEventKind (event))
- {
- /* -- window refresh events -- */
-
- case kEventWindowUpdate:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- do_window_update (wp);
- result = noErr;
- break;
-
- /* -- window state change events -- */
-
- case kEventWindowShowing:
- size_hints = FRAME_SIZE_HINTS (f);
- if (!(size_hints->flags & (USPosition | PPosition)))
- {
- struct frame *sf = SELECTED_FRAME ();
-
- if (!(FRAME_MAC_P (sf) && sf->async_visible))
- RepositionWindow (wp, NULL, kWindowCenterOnMainScreen);
- else
- {
- RepositionWindow (wp, FRAME_MAC_WINDOW (sf),
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kWindowCascadeStartAtParentWindowScreen
-#else
- kWindowCascadeOnParentWindowScreen
-#endif
- );
-#if USE_MAC_TOOLBAR
- /* This is a workaround. RepositionWindow fails to put
- a window at the cascading position when its parent
- window has a Carbon HIToolbar. */
- if ((f->left_pos == sf->left_pos
- && f->top_pos == sf->top_pos)
- || (f->left_pos == sf->left_pos + 10 * 2
- && f->top_pos == sf->top_pos + 32 * 2))
- MoveWindowStructure (wp, sf->left_pos + 10, sf->top_pos + 32);
-#endif
- }
- result = noErr;
- }
- break;
-
- case kEventWindowHiding:
- /* Before unmapping the window, update the WM_SIZE_HINTS
- property to claim that the current position of the window is
- user-specified, rather than program-specified, so that when
- the window is mapped again, it will be placed at the same
- location, without forcing the user to position it by hand
- again (they have already done that once for this window.) */
- x_wm_set_size_hint (f, (long) 0, 1);
- result = noErr;
- break;
-
- case kEventWindowShown:
- case kEventWindowHidden:
- case kEventWindowCollapsed:
- case kEventWindowExpanded:
- mac_handle_visibility_change (f);
- result = noErr;
- break;
-
- case kEventWindowBoundsChanging:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
- NULL, sizeof (UInt32), NULL, &attributes);
- if (err != noErr)
- break;
-
- size_hints = FRAME_SIZE_HINTS (f);
- if ((attributes & kWindowBoundsChangeUserResize)
- && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
- == (PResizeInc | PBaseSize | PMinSize)))
- {
- Rect bounds;
- int width, height;
-
- err = GetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, NULL, sizeof (Rect),
- NULL, &bounds);
- if (err != noErr)
- break;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
-
- if (width < size_hints->min_width)
- width = size_hints->min_width;
- else
- width = size_hints->base_width
- + (int) ((width - size_hints->base_width)
- / (float) size_hints->width_inc + .5)
- * size_hints->width_inc;
-
- if (height < size_hints->min_height)
- height = size_hints->min_height;
- else
- height = size_hints->base_height
- + (int) ((height - size_hints->base_height)
- / (float) size_hints->height_inc + .5)
- * size_hints->height_inc;
-
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
- SetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, sizeof (Rect), &bounds);
- result = noErr;
- }
- break;
-
- case kEventWindowBoundsChanged:
- err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
- NULL, sizeof (UInt32), NULL, &attributes);
- if (err != noErr)
- break;
-
- if (attributes & kWindowBoundsChangeSizeChanged)
- {
- Rect bounds;
-
- err = GetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, NULL, sizeof (Rect),
- NULL, &bounds);
- if (err == noErr)
- {
- int width, height;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
- mac_handle_size_change (f, width, height);
- mac_wakeup_from_rne ();
- }
- }
-
- if (attributes & kWindowBoundsChangeOriginChanged)
- mac_handle_origin_change (f);
-
- result = noErr;
- break;
-
- /* -- window action events -- */
-
- case kEventWindowClose:
- {
- struct input_event buf;
-
- EVENT_INIT (buf);
- buf.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (buf.frame_or_window, f);
- buf.arg = Qnil;
- kbd_buffer_store_event (&buf);
- }
- result = noErr;
- break;
-
- case kEventWindowGetIdealSize:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- {
- Point ideal_size = mac_get_ideal_size (f);
-
- err = SetEventParameter (event, kEventParamDimensions,
- typeQDPoint, sizeof (Point), &ideal_size);
- if (err == noErr)
- result = noErr;
- }
- break;
-
-#ifdef MAC_OSX
- case kEventWindowToolbarSwitchMode:
- {
- static const EventParamName names[] = {kEventParamDirectObject,
- kEventParamWindowMouseLocation,
- kEventParamKeyModifiers,
- kEventParamMouseButton,
- kEventParamClickCount,
- kEventParamMouseChord};
- static const EventParamType types[] = {typeWindowRef,
- typeQDPoint,
- typeUInt32,
- typeMouseButton,
- typeUInt32,
- typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- err = mac_store_event_ref_as_apple_event (0, 0,
- Qwindow,
- Qtoolbar_switch_mode,
- event, num_params,
- names, types);
- }
- if (err == noErr)
- result = noErr;
- break;
-#endif
-
-#if USE_MAC_TSM
- /* -- window focus events -- */
-
- case kEventWindowFocusAcquired:
- err = mac_tsm_resume ();
- if (err == noErr)
- result = noErr;
- break;
-
- case kEventWindowFocusRelinquish:
- err = mac_tsm_suspend ();
- if (err == noErr)
- result = noErr;
- break;
-#endif
-
- default:
- abort ();
- }
-
- return result;
-}
-
-static pascal OSStatus
-mac_handle_application_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
-#if USE_MAC_TSM
- case kEventAppActivated:
- err = mac_tsm_resume ();
- break;
-
- case kEventAppDeactivated:
- err = mac_tsm_suspend ();
- break;
-#endif
-
- default:
- abort ();
- }
-
- if (err == noErr)
- result = noErr;
-
- return result;
-}
-
-static pascal OSStatus
-mac_handle_keyboard_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- UInt32 event_kind, key_code, modifiers;
- unsigned char char_code;
-
- event_kind = GetEventKind (event);
- switch (event_kind)
- {
- case kEventRawKeyDown:
- case kEventRawKeyRepeat:
- case kEventRawKeyUp:
- /* When using Carbon Events, we need to pass raw keyboard events
- to the TSM ourselves. If TSM handles it, it will pass back
- noErr, otherwise it will pass back "eventNotHandledErr" and
- we can process it normally. */
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- if (read_socket_inev == NULL)
- break;
-
-#if USE_MAC_TSM
- if (read_socket_inev->kind != NO_EVENT)
- {
- result = noErr;
- break;
- }
-#endif
-
- if (event_kind == kEventRawKeyUp)
- break;
-
- err = GetEventParameter (event, kEventParamKeyMacCharCodes,
- typeChar, NULL,
- sizeof (char), NULL, &char_code);
- if (err != noErr)
- break;
-
- err = GetEventParameter (event, kEventParamKeyCode,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &key_code);
- if (err != noErr)
- break;
-
- err = GetEventParameter (event, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
- if (err != noErr)
- break;
-
- do_keystroke ((event_kind == kEventRawKeyDown ? keyDown : autoKey),
- char_code, key_code, modifiers,
- ((unsigned long)
- (GetEventTime (event) / kEventDurationMillisecond)),
- read_socket_inev);
- result = noErr;
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-static pascal OSStatus
-mac_handle_command_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- HICommand command;
- static const EventParamName names[] =
- {kEventParamDirectObject, kEventParamKeyModifiers};
- static const EventParamType types[] =
- {typeHICommand, typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
- NULL, sizeof (HICommand), NULL, &command);
- if (err != noErr)
- return eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
- case kEventCommandProcess:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- err = GetEventParameter (event, kEventParamDirectObject,
- typeHICommand, NULL,
- sizeof (HICommand), NULL, &command);
-
- if (err != noErr || command.commandID == 0)
- break;
-
- /* A HI command event is mapped to an Apple event whose event
- class symbol is `hi-command' and event ID is its command
- ID. */
- err = mac_store_event_ref_as_apple_event (0, command.commandID,
- Qhi_command, Qnil,
- event, num_params,
- names, types);
- if (err == noErr)
- result = noErr;
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-static pascal OSStatus
-mac_handle_mouse_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
- case kEventMouseWheelMoved:
- {
- WindowRef wp;
- struct frame *f;
- EventMouseWheelAxis axis;
- SInt32 delta;
- Point point;
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr || read_socket_inev == NULL)
- break;
-
- f = mac_focus_frame (&one_mac_display_info);
-
- err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
- NULL, sizeof (WindowRef), NULL, &wp);
- if (err != noErr
- || wp != FRAME_MAC_WINDOW (f))
- break;
-
- err = GetEventParameter (event, kEventParamMouseWheelAxis,
- typeMouseWheelAxis, NULL,
- sizeof (EventMouseWheelAxis), NULL, &axis);
- if (err != noErr || axis != kEventMouseWheelAxisY)
- break;
-
- err = GetEventParameter (event, kEventParamMouseLocation,
- typeQDPoint, NULL, sizeof (Point),
- NULL, &point);
- if (err != noErr)
- break;
-
- point.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- point.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
- if (point.h < 0 || point.v < 0
- || EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
- f->tool_bar_window))
- break;
-
- err = GetEventParameter (event, kEventParamMouseWheelDelta,
- typeSInt32, NULL, sizeof (SInt32),
- NULL, &delta);
- if (err != noErr)
- break;
-
- read_socket_inev->kind = WHEEL_EVENT;
- read_socket_inev->code = 0;
- read_socket_inev->modifiers =
- (mac_event_to_emacs_modifiers (event)
- | ((delta < 0) ? down_modifier : up_modifier));
- XSETINT (read_socket_inev->x, point.h);
- XSETINT (read_socket_inev->y, point.v);
- XSETFRAME (read_socket_inev->frame_or_window, f);
-
- result = noErr;
- }
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-#if USE_MAC_TSM
-static pascal OSStatus
-mac_handle_text_input_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result;
- Lisp_Object id_key = Qnil;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static UInt32 seqno_uaia = 0;
- static const EventParamName names_uaia[] =
- {kEventParamTextInputSendComponentInstance,
- kEventParamTextInputSendRefCon,
- kEventParamTextInputSendSLRec,
- kEventParamTextInputSendFixLen,
- kEventParamTextInputSendText,
- kEventParamTextInputSendUpdateRng,
- kEventParamTextInputSendHiliteRng,
- kEventParamTextInputSendClauseRng,
- kEventParamTextInputSendPinRng,
- kEventParamTextInputSendTextServiceEncoding,
- kEventParamTextInputSendTextServiceMacEncoding,
- EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
- static const EventParamType types_uaia[] =
- {typeComponentInstance,
- typeLongInteger,
- typeIntlWritingCode,
- typeLongInteger,
-#ifdef MAC_OSX
- typeUnicodeText,
-#else
- typeChar,
-#endif
- typeTextRangeArray,
- typeTextRangeArray,
- typeOffsetArray,
- typeTextRange,
- typeUInt32,
- typeUInt32,
- typeUInt32};
- static const EventParamName names_ufke[] =
- {kEventParamTextInputSendComponentInstance,
- kEventParamTextInputSendRefCon,
- kEventParamTextInputSendSLRec,
- kEventParamTextInputSendText};
- static const EventParamType types_ufke[] =
- {typeComponentInstance,
- typeLongInteger,
- typeIntlWritingCode,
- typeUnicodeText};
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventTextInputUpdateActiveInputArea:
- id_key = Qupdate_active_input_area;
- num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
- names = names_uaia;
- types = types_uaia;
- SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
- typeUInt32, sizeof (UInt32), &seqno_uaia);
- seqno_uaia++;
- result = noErr;
- break;
-
- case kEventTextInputUnicodeForKeyEvent:
- {
- EventRef kbd_event;
- UInt32 actual_size, modifiers;
-
- err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
- typeEventRef, NULL, sizeof (EventRef), NULL,
- &kbd_event);
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
- if (err == noErr && mac_mapped_modifiers (modifiers))
- /* There're mapped modifier keys. Process it in
- do_keystroke. */
- break;
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
- typeUnicodeText, NULL, 0, &actual_size,
- NULL);
- if (err == noErr && actual_size == sizeof (UniChar))
- {
- UniChar code;
-
- err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
- typeUnicodeText, NULL,
- sizeof (UniChar), NULL, &code);
- if (err == noErr && code < 0x80)
- {
- /* ASCII character. Process it in do_keystroke. */
- if (read_socket_inev && code >= 0x20 && code <= 0x7e)
- {
- UInt32 key_code;
-
- err = GetEventParameter (kbd_event, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (!(err == noErr && key_code <= 0x7f
- && keycode_to_xkeysym_table [key_code]))
- {
- struct frame *f =
- mac_focus_frame (&one_mac_display_info);
-
- read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
- read_socket_inev->code = code;
- read_socket_inev->modifiers =
- mac_to_emacs_modifiers (modifiers);
- read_socket_inev->modifiers |=
- (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (read_socket_inev->frame_or_window, f);
- }
- }
- break;
- }
- }
- if (err == noErr)
- {
- /* Non-ASCII keystrokes without mapped modifiers are
- processed at the Lisp level. */
- id_key = Qunicode_for_key_event;
- num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
- names = names_ufke;
- types = types_ufke;
- result = noErr;
- }
- }
- break;
-
- case kEventTextInputOffsetToPos:
- {
- struct frame *f;
- struct window *w;
- Point p;
-
- if (!OVERLAYP (Vmac_ts_active_input_overlay))
- break;
-
- /* Strictly speaking, this is not always correct because
- previous events may change some states about display. */
- if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
- {
- /* Active input area is displayed around the current point. */
- f = SELECTED_FRAME ();
- w = XWINDOW (f->selected_window);
- }
- else if (WINDOWP (echo_area_window))
- {
- /* Active input area is displayed in the echo area. */
- w = XWINDOW (echo_area_window);
- f = WINDOW_XFRAME (w);
- }
- else
- break;
-
- p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
- + WINDOW_LEFT_FRINGE_WIDTH (w)
- + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
- p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
- + FONT_BASE (FRAME_FONT (f))
- + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
- err = SetEventParameter (event, kEventParamTextInputReplyPoint,
- typeQDPoint, sizeof (typeQDPoint), &p);
- if (err == noErr)
- result = noErr;
- }
- break;
-
- default:
- abort ();
- }
-
- if (!NILP (id_key))
- err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
- event, num_params,
- names, types);
- return result;
-}
-#endif
-#endif /* TARGET_API_MAC_CARBON */
-
-
-OSStatus
-install_window_handler (window)
- WindowRef window;
-{
- OSStatus err = noErr;
-
-#if TARGET_API_MAC_CARBON
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {
- /* -- window refresh events -- */
- {kEventClassWindow, kEventWindowUpdate},
- /* -- window state change events -- */
- {kEventClassWindow, kEventWindowShowing},
- {kEventClassWindow, kEventWindowHiding},
- {kEventClassWindow, kEventWindowShown},
- {kEventClassWindow, kEventWindowHidden},
- {kEventClassWindow, kEventWindowCollapsed},
- {kEventClassWindow, kEventWindowExpanded},
- {kEventClassWindow, kEventWindowBoundsChanging},
- {kEventClassWindow, kEventWindowBoundsChanged},
- /* -- window action events -- */
- {kEventClassWindow, kEventWindowClose},
- {kEventClassWindow, kEventWindowGetIdealSize},
-#ifdef MAC_OSX
- {kEventClassWindow, kEventWindowToolbarSwitchMode},
-#endif
-#if USE_MAC_TSM
- /* -- window focus events -- */
- {kEventClassWindow, kEventWindowFocusAcquired},
- {kEventClassWindow, kEventWindowFocusRelinquish},
-#endif
- };
- static EventHandlerUPP handle_window_eventUPP = NULL;
-
- if (handle_window_eventUPP == NULL)
- handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
-
- err = InstallWindowEventHandler (window, handle_window_eventUPP,
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-#endif
-
- if (err == noErr)
- err = install_drag_handler (window);
-
- return err;
-}
-
-void
-remove_window_handler (window)
- WindowRef window;
-{
- remove_drag_handler (window);
-}
-
-#if TARGET_API_MAC_CARBON
-static OSStatus
-install_application_handler ()
-{
- OSStatus err = noErr;
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] = {
-#if USE_MAC_TSM
- {kEventClassApplication, kEventAppActivated},
- {kEventClassApplication, kEventAppDeactivated},
-#endif
- };
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_application_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassKeyboard, kEventRawKeyDown},
- {kEventClassKeyboard, kEventRawKeyRepeat},
- {kEventClassKeyboard, kEventRawKeyUp}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_keyboard_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_command_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassMouse, kEventMouseWheelMoved}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_mouse_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
-#if USE_MAC_TSM
- if (err == noErr)
- {
- static const EventTypeSpec spec[] =
- {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
- {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
- {kEventClassTextInput, kEventTextInputOffsetToPos}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_text_input_event),
- GetEventTypeCount (spec),
- spec, NULL, NULL);
- }
-#endif
-
- if (err == noErr)
- err = install_menu_target_item_handler ();
-
-#ifdef MAC_OSX
- if (err == noErr)
- err = install_service_handler ();
-#endif
-
- return err;
-}
-#endif
-
-static pascal void
-mac_handle_dm_notification (event)
- AppleEvent *event;
-{
- mac_screen_config_changed = 1;
-}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-static void
-mac_handle_cg_display_reconfig (display, flags, user_info)
- CGDirectDisplayID display;
- CGDisplayChangeSummaryFlags flags;
- void *user_info;
-{
- mac_screen_config_changed = 1;
-}
-#endif
-
-static OSErr
-init_dm_notification_handler ()
-{
- OSErr err = noErr;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CGDisplayRegisterReconfigurationCallback != NULL)
-#endif
- {
- CGDisplayRegisterReconfigurationCallback (mac_handle_cg_display_reconfig,
- NULL);
- }
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else /* CGDisplayRegisterReconfigurationCallback == NULL */
-#endif
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- {
- static DMNotificationUPP handle_dm_notificationUPP = NULL;
- ProcessSerialNumber psn;
-
- if (handle_dm_notificationUPP == NULL)
- handle_dm_notificationUPP =
- NewDMNotificationUPP (mac_handle_dm_notification);
-
- err = GetCurrentProcess (&psn);
- if (err == noErr)
- err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
- }
-#endif
-
- return err;
-}
-
-static void
-mac_get_screen_info (dpyinfo)
- struct mac_display_info *dpyinfo;
-{
-#ifdef MAC_OSX
- /* HasDepth returns true if it is possible to have a 32 bit display,
- but this may not be what is actually used. Mac OSX can do better. */
- dpyinfo->color_p = CGDisplaySamplesPerPixel (kCGDirectMainDisplay) > 1;
- dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
- {
- CGDisplayErr err;
- CGDisplayCount ndisps;
- CGDirectDisplayID *displays;
-
- err = CGGetActiveDisplayList (0, NULL, &ndisps);
- if (err == noErr)
- {
- displays = alloca (sizeof (CGDirectDisplayID) * ndisps);
- err = CGGetActiveDisplayList (ndisps, displays, &ndisps);
- }
- if (err == noErr)
- {
- CGRect bounds = CGRectZero;
-
- while (ndisps-- > 0)
- bounds = CGRectUnion (bounds, CGDisplayBounds (displays[ndisps]));
- dpyinfo->height = CGRectGetHeight (bounds);
- dpyinfo->width = CGRectGetWidth (bounds);
- }
- else
- {
- dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
- dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
- }
- }
-#else /* !MAC_OSX */
- {
- GDHandle gdh = GetMainDevice ();
- Rect rect = (**gdh).gdRect;
-
- dpyinfo->color_p = TestDeviceAttribute (gdh, gdDevType);
- for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
- if (HasDepth (gdh, dpyinfo->n_planes, gdDevType, dpyinfo->color_p))
- break;
-
- for (gdh = DMGetFirstScreenDevice (dmOnlyActiveDisplays); gdh;
- gdh = DMGetNextScreenDevice (gdh, dmOnlyActiveDisplays))
- UnionRect (&rect, &(**gdh).gdRect, &rect);
-
- dpyinfo->height = rect.bottom - rect.top;
- dpyinfo->width = rect.right - rect.left;
- }
-#endif /* !MAC_OSX */
-}
-
-
-#if __profile__
-void
-profiler_exit_proc ()
-{
- ProfilerDump ("\pEmacs.prof");
- ProfilerTerm ();
-}
-#endif
-
-/* These few functions implement Emacs as a normal Mac application
- (almost): set up the heap and the Toolbox, handle necessary system
- events plus a few simple menu events. They also set up Emacs's
- access to functions defined in the rest of this file. Emacs uses
- function hooks to perform all its terminal I/O. A complete list of
- these functions appear in termhooks.h. For what they do, read the
- comments there and see also w32term.c and xterm.c. What's
- noticeably missing here is the event loop, which is normally
- present in most Mac application. After performing the necessary
- Mac initializations, main passes off control to emacs_main
- (corresponding to main in emacs.c). Emacs_main calls XTread_socket
- (defined further below) to read input. This is where
- WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
-
-#ifdef MAC_OS8
-#undef main
-int
-main (void)
-{
-#if __profile__ /* is the profiler on? */
- if (ProfilerInit(collectDetailed, bestTimeBase, 5000, 200))
- exit(1);
-#endif
-
-#if __MWERKS__
- /* set creator and type for files created by MSL */
- _fcreator = MAC_EMACS_CREATOR_CODE;
- _ftype = 'TEXT';
-#endif
-
- do_init_managers ();
-
- do_get_menus ();
-
-#ifndef USE_LSB_TAG
- do_check_ram_size ();
-#endif
-
- init_emacs_passwd_dir ();
-
- init_environ ();
-
- init_coercion_handler ();
-
- initialize_applescript ();
-
- init_apple_event_handler ();
-
- init_dm_notification_handler ();
-
- {
- char **argv;
- int argc = 0;
-
- /* set up argv array from STR# resource */
- get_string_list (&argv, ARGV_STRING_LIST_ID);
- while (argv[argc])
- argc++;
-
- /* free up AppleScript resources on exit */
- atexit (terminate_applescript);
-
-#if __profile__ /* is the profiler on? */
- atexit (profiler_exit_proc);
-#endif
-
- /* 3rd param "envp" never used in emacs_main */
- (void) emacs_main (argc, argv, 0);
- }
-
- /* Never reached - real exit in Fkill_emacs */
- return 0;
-}
-#endif
-
-#if !TARGET_API_MAC_CARBON
-static RgnHandle mouse_region = NULL;
-
-Boolean
-mac_wait_next_event (er, sleep_time, dequeue)
- EventRecord *er;
- UInt32 sleep_time;
- Boolean dequeue;
-{
- static EventRecord er_buf = {nullEvent};
- UInt32 target_tick, current_tick;
- EventMask event_mask;
-
- if (mouse_region == NULL)
- mouse_region = NewRgn ();
-
- event_mask = everyEvent;
- if (!mac_ready_for_apple_events)
- event_mask -= highLevelEventMask;
-
- current_tick = TickCount ();
- target_tick = current_tick + sleep_time;
-
- if (er_buf.what == nullEvent)
- while (!WaitNextEvent (event_mask, &er_buf,
- target_tick - current_tick, mouse_region))
- {
- current_tick = TickCount ();
- if (target_tick <= current_tick)
- return false;
- }
-
- *er = er_buf;
- if (dequeue)
- er_buf.what = nullEvent;
- return true;
-}
-#endif /* not TARGET_API_MAC_CARBON */
-
-#if TARGET_API_MAC_CARBON
-OSStatus
-mac_post_mouse_moved_event ()
-{
- EventRef event = NULL;
- OSStatus err;
-
- err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0,
- kEventAttributeNone, &event);
- if (err == noErr)
- {
- Point mouse_pos;
-
- GetGlobalMouse (&mouse_pos);
- err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
- sizeof (Point), &mouse_pos);
- }
- if (err == noErr)
- {
- UInt32 modifiers = GetCurrentKeyModifiers ();
-
- err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32,
- sizeof (UInt32), &modifiers);
- }
- if (err == noErr)
- err = PostEventToQueue (GetCurrentEventQueue (), event,
- kEventPriorityStandard);
- if (event)
- ReleaseEvent (event);
-
- return err;
-}
-#endif
-
-/* Emacs calls this whenever it wants to read an input event from the
- user. */
-int
-XTread_socket (sd, expected, hold_quit)
- int sd, expected;
- struct input_event *hold_quit;
-{
- struct input_event inev;
- int count = 0;
-#if TARGET_API_MAC_CARBON
- EventRef eventRef;
- EventTargetRef toolbox_dispatcher;
-#endif
- EventRecord er;
- struct mac_display_info *dpyinfo = &one_mac_display_info;
-
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- BLOCK_INPUT;
-
- /* So people can tell when we have read the available input. */
- input_signal_count++;
-
- ++handling_signal;
-
-#if TARGET_API_MAC_CARBON
- toolbox_dispatcher = GetEventDispatcherTarget ();
-
- while (
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (NULL),
-#endif
- !ReceiveNextEvent (0, NULL, kEventDurationNoWait,
- kEventRemoveFromQueue, &eventRef))
-#else /* !TARGET_API_MAC_CARBON */
- while (mac_wait_next_event (&er, 0, true))
-#endif /* !TARGET_API_MAC_CARBON */
- {
- int do_help = 0;
- struct frame *f;
- unsigned long timestamp;
-
- EVENT_INIT (inev);
- inev.kind = NO_EVENT;
- inev.arg = Qnil;
-
-#if TARGET_API_MAC_CARBON
- timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
-
- if (!mac_convert_event_ref (eventRef, &er))
- goto OTHER;
-#else /* !TARGET_API_MAC_CARBON */
- timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-#endif /* !TARGET_API_MAC_CARBON */
-
- switch (er.what)
- {
- case mouseDown:
- case mouseUp:
- {
- WindowRef window_ptr;
- ControlPartCode part_code;
- int tool_bar_p = 0;
-
-#if TARGET_API_MAC_CARBON
- OSStatus err;
-
- /* This is needed to send mouse events like aqua window
- buttons to the correct handler. */
- read_socket_inev = &inev;
- err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- if (err != eventNotHandledErr)
- break;
-#endif
- last_mouse_glyph_frame = 0;
-
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- {
- window_ptr = FRAME_MAC_WINDOW (last_mouse_frame);
- part_code = inContent;
- }
- else
- {
- part_code = FindWindow (er.where, &window_ptr);
- if (tip_window && window_ptr == tip_window)
- {
- HideWindow (tip_window);
- part_code = FindWindow (er.where, &window_ptr);
- }
- }
-
- if (er.what != mouseDown &&
- (part_code != inContent || dpyinfo->grabbed == 0))
- break;
-
- switch (part_code)
- {
- case inMenuBar:
- f = mac_focus_frame (dpyinfo);
- saved_menu_event_location = er.where;
- inev.kind = MENU_BAR_ACTIVATE_EVENT;
- XSETFRAME (inev.frame_or_window, f);
- break;
-
- case inContent:
- if (
-#if TARGET_API_MAC_CARBON
- FrontNonFloatingWindow ()
-#else
- FrontWindow ()
-#endif
- != window_ptr
- || (mac_window_to_frame (window_ptr)
- != dpyinfo->x_focus_frame))
- SelectWindow (window_ptr);
- else
- {
- ControlPartCode control_part_code;
- ControlRef ch;
- Point mouse_loc;
-#ifdef MAC_OSX
- ControlKind control_kind;
-#endif
-
- f = mac_window_to_frame (window_ptr);
- /* convert to local coordinates of new window */
- mouse_loc.h = (er.where.h
- - (f->left_pos
- + FRAME_OUTER_TO_INNER_DIFF_X (f)));
- mouse_loc.v = (er.where.v
- - (f->top_pos
- + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
-#if TARGET_API_MAC_CARBON
- ch = FindControlUnderMouse (mouse_loc, window_ptr,
- &control_part_code);
-#ifdef MAC_OSX
- if (ch)
- GetControlKind (ch, &control_kind);
-#endif
-#else
- control_part_code = FindControl (mouse_loc, window_ptr,
- &ch);
-#endif
-
-#if TARGET_API_MAC_CARBON
- inev.code = mac_get_mouse_btn (eventRef);
- inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
- inev.code = mac_get_emulated_btn (er.modifiers);
- inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
- XSETINT (inev.x, mouse_loc.h);
- XSETINT (inev.y, mouse_loc.v);
-
- if ((dpyinfo->grabbed && tracked_scroll_bar)
- || (ch != 0
-#ifndef USE_TOOLKIT_SCROLL_BARS
- /* control_part_code becomes kControlNoPart if
- a progress indicator is clicked. */
- && control_part_code != kControlNoPart
-#else /* USE_TOOLKIT_SCROLL_BARS */
-#ifdef MAC_OSX
- && control_kind.kind == kControlKindScrollBar
-#endif /* MAC_OSX */
-#endif /* USE_TOOLKIT_SCROLL_BARS */
- ))
- {
- struct scroll_bar *bar;
-
- if (dpyinfo->grabbed && tracked_scroll_bar)
- {
- bar = tracked_scroll_bar;
-#ifndef USE_TOOLKIT_SCROLL_BARS
- control_part_code = kControlIndicatorPart;
-#endif
- }
- else
- bar = (struct scroll_bar *) GetControlReference (ch);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- /* Make the "Ctrl-Mouse-2 splits window" work
- for toolkit scroll bars. */
- if (inev.modifiers & ctrl_modifier)
- x_scroll_bar_handle_click (bar, control_part_code,
- &er, &inev);
- else if (er.what == mouseDown)
- x_scroll_bar_handle_press (bar, control_part_code,
- mouse_loc, &inev);
- else
- x_scroll_bar_handle_release (bar, &inev);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- x_scroll_bar_handle_click (bar, control_part_code,
- &er, &inev);
- if (er.what == mouseDown
- && control_part_code == kControlIndicatorPart)
- tracked_scroll_bar = bar;
- else
- tracked_scroll_bar = NULL;
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
- }
- else
- {
- Lisp_Object window;
- int x = mouse_loc.h;
- int y = mouse_loc.v;
-
- window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
- if (EQ (window, f->tool_bar_window))
- {
- if (er.what == mouseDown)
- handle_tool_bar_click (f, x, y, 1, 0);
- else
- handle_tool_bar_click (f, x, y, 0,
- inev.modifiers);
- tool_bar_p = 1;
- }
- else
- {
- XSETFRAME (inev.frame_or_window, f);
- inev.kind = MOUSE_CLICK_EVENT;
- }
- }
-
- if (er.what == mouseDown)
- {
- dpyinfo->grabbed |= (1 << inev.code);
- last_mouse_frame = f;
-
- if (!tool_bar_p)
- last_tool_bar_item = -1;
- }
- else
- {
- if ((dpyinfo->grabbed & (1 << inev.code)) == 0)
- /* If a button is released though it was not
- previously pressed, that would be because
- of multi-button emulation. */
- dpyinfo->grabbed = 0;
- else
- dpyinfo->grabbed &= ~(1 << inev.code);
- }
-
- /* Ignore any mouse motion that happened before
- this event; any subsequent mouse-movement Emacs
- events should reflect only motion after the
- ButtonPress. */
- if (f != 0)
- f->mouse_moved = 0;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (inev.kind == MOUSE_CLICK_EVENT
- || (inev.kind == SCROLL_BAR_CLICK_EVENT
- && (inev.modifiers & ctrl_modifier)))
-#endif
- switch (er.what)
- {
- case mouseDown:
- inev.modifiers |= down_modifier;
- break;
- case mouseUp:
- inev.modifiers |= up_modifier;
- break;
- }
- }
- break;
-
- case inDrag:
-#if TARGET_API_MAC_CARBON
- case inProxyIcon:
- if (IsWindowPathSelectClick (window_ptr, &er))
- {
- WindowPathSelect (window_ptr, NULL, NULL);
- break;
- }
- if (part_code == inProxyIcon
- && (TrackWindowProxyDrag (window_ptr, er.where)
- != errUserWantsToDragWindow))
- break;
- DragWindow (window_ptr, er.where, NULL);
-#else /* not TARGET_API_MAC_CARBON */
- DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
- /* Update the frame parameters. */
- {
- struct frame *f = mac_window_to_frame (window_ptr);
-
- if (f && !f->async_iconified)
- mac_handle_origin_change (f);
- }
-#endif /* not TARGET_API_MAC_CARBON */
- break;
-
- case inGoAway:
- if (TrackGoAway (window_ptr, er.where))
- {
- inev.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (inev.frame_or_window,
- mac_window_to_frame (window_ptr));
- }
- break;
-
- /* window resize handling added --ben */
- case inGrow:
- do_grow_window (window_ptr, &er);
- break;
-
- /* window zoom handling added --ben */
- case inZoomIn:
- case inZoomOut:
- if (TrackBox (window_ptr, er.where, part_code))
- do_zoom_window (window_ptr, part_code);
- break;
-
-#if USE_MAC_TOOLBAR
- case inStructure:
- {
- OSStatus err;
- HIViewRef ch;
-
- err = HIViewGetViewForMouseEvent (HIViewGetRoot (window_ptr),
- eventRef, &ch);
- /* This doesn't work on Mac OS X 10.2. */
- if (err == noErr)
- HIViewClick (ch, eventRef);
- }
- break;
-#endif /* USE_MAC_TOOLBAR */
-
- default:
- break;
- }
- }
- break;
-
-#if !TARGET_API_MAC_CARBON
- case updateEvt:
- do_window_update ((WindowRef) er.message);
- break;
-#endif
-
- case osEvt:
- switch ((er.message >> 24) & 0x000000FF)
- {
- case mouseMovedMessage:
-#if !TARGET_API_MAC_CARBON
- SetRectRgn (mouse_region, er.where.h, er.where.v,
- er.where.h + 1, er.where.v + 1);
-#endif
- previous_help_echo_string = help_echo_string;
- help_echo_string = Qnil;
-
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f = last_mouse_frame;
- else
- f = dpyinfo->x_focus_frame;
-
- if (dpyinfo->mouse_face_hidden)
- {
- dpyinfo->mouse_face_hidden = 0;
- clear_mouse_face (dpyinfo);
- }
-
- if (f)
- {
- WindowRef wp = FRAME_MAC_WINDOW (f);
- Point mouse_pos;
-
- mouse_pos.h = (er.where.h
- - (f->left_pos
- + FRAME_OUTER_TO_INNER_DIFF_X (f)));
- mouse_pos.v = (er.where.v
- - (f->top_pos
- + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
- if (dpyinfo->grabbed && tracked_scroll_bar)
-#ifdef USE_TOOLKIT_SCROLL_BARS
- x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
- mouse_pos, &inev);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- x_scroll_bar_note_movement (tracked_scroll_bar,
- mouse_pos.v
- - XINT (tracked_scroll_bar->top),
- er.when * (1000 / 60));
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
- else
- {
- /* Generate SELECT_WINDOW_EVENTs when needed. */
- if (!NILP (Vmouse_autoselect_window))
- {
- Lisp_Object window;
-
- window = window_from_coordinates (f,
- mouse_pos.h,
- mouse_pos.v,
- 0, 0, 0, 0);
-
- /* Window will be selected only when it is
- not selected now and last mouse movement
- event was not in it. Minibuffer window
- will be selected only when it is active. */
- if (WINDOWP (window)
- && !EQ (window, last_window)
- && !EQ (window, selected_window)
- /* For click-to-focus window managers
- create event iff we don't leave the
- selected frame. */
- && (focus_follows_mouse
- || (EQ (XWINDOW (window)->frame,
- XWINDOW (selected_window)->frame))))
- {
- inev.kind = SELECT_WINDOW_EVENT;
- inev.frame_or_window = window;
- }
-
- last_window=window;
- }
- if (!note_mouse_movement (f, &mouse_pos))
- help_echo_string = previous_help_echo_string;
-#if USE_MAC_TOOLBAR
- else
- mac_tool_bar_note_mouse_movement (f, eventRef);
-#endif
- }
- }
-
- /* If the contents of the global variable
- help_echo_string has changed, generate a
- HELP_EVENT. */
- if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
- do_help = 1;
- break;
-
- default:
- goto OTHER;
- }
- break;
-
- case activateEvt:
- {
- WindowRef window_ptr = (WindowRef) er.message;
- OSErr err;
- ControlRef root_control;
-
- if (window_ptr == tip_window)
- {
- HideWindow (tip_window);
- break;
- }
-
- if (!is_emacs_window (window_ptr))
- goto OTHER;
-
- f = mac_window_to_frame (window_ptr);
-
- if ((er.modifiers & activeFlag) != 0)
- {
- /* A window has been activated */
- Point mouse_loc;
-
- err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
- if (err == noErr)
- ActivateControl (root_control);
-
- x_detect_focus_change (dpyinfo, &er, &inev);
-
- mouse_loc.h = (er.where.h
- - (f->left_pos
- + FRAME_OUTER_TO_INNER_DIFF_X (f)));
- mouse_loc.v = (er.where.v
- - (f->top_pos
- + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
- /* Window-activated event counts as mouse movement,
- so update things that depend on mouse position. */
- note_mouse_movement (f, &mouse_loc);
- }
- else
- {
- /* A window has been deactivated */
- err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
- if (err == noErr)
- DeactivateControl (root_control);
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (dpyinfo->grabbed && tracked_scroll_bar)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = NO_EVENT;
- x_scroll_bar_handle_release (tracked_scroll_bar, &event);
- if (event.kind != NO_EVENT)
- {
- event.timestamp = timestamp;
- kbd_buffer_store_event_hold (&event, hold_quit);
- count++;
- }
- }
-#endif
- dpyinfo->grabbed = 0;
-
- x_detect_focus_change (dpyinfo, &er, &inev);
-
- if (f == dpyinfo->mouse_face_mouse_frame)
- {
- /* If we move outside the frame, then we're
- certainly no longer on any text in the
- frame. */
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_mouse_frame = 0;
- }
-
- /* Generate a nil HELP_EVENT to cancel a help-echo.
- Do it only if there's something to cancel.
- Otherwise, the startup message is cleared when the
- mouse leaves the frame. */
- if (any_help_event_p)
- do_help = -1;
- }
- }
- break;
-
- case keyDown:
- case keyUp:
- case autoKey:
- ObscureCursor ();
-
- f = mac_focus_frame (dpyinfo);
- XSETFRAME (inev.frame_or_window, f);
-
- /* If mouse-highlight is an integer, input clears out mouse
- highlighting. */
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
- {
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
- }
-
- {
- UInt32 modifiers = er.modifiers, mapped_modifiers;
-
-#ifdef MAC_OSX
- GetEventParameter (eventRef, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
-#endif
- mapped_modifiers = mac_mapped_modifiers (modifiers);
-
-#if TARGET_API_MAC_CARBON
- if (!(mapped_modifiers
- & ~(mac_pass_command_to_system ? cmdKey : 0)
- & ~(mac_pass_control_to_system ? controlKey : 0)))
- goto OTHER;
- else
-#endif
- if (er.what != keyUp)
- do_keystroke (er.what, er.message & charCodeMask,
- (er.message & keyCodeMask) >> 8,
- modifiers, timestamp, &inev);
- }
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent (&er);
- break;
-
- default:
- OTHER:
-#if TARGET_API_MAC_CARBON
- {
- OSStatus err;
-
- read_socket_inev = &inev;
- err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- }
-#endif
- break;
- }
-#if TARGET_API_MAC_CARBON
- ReleaseEvent (eventRef);
-#endif
-
- if (inev.kind != NO_EVENT)
- {
- inev.timestamp = timestamp;
- kbd_buffer_store_event_hold (&inev, hold_quit);
- count++;
- }
-
- if (do_help
- && !(hold_quit && hold_quit->kind != NO_EVENT))
- {
- Lisp_Object frame;
-
- if (f)
- XSETFRAME (frame, f);
- else
- frame = Qnil;
-
- if (do_help > 0)
- {
- any_help_event_p = 1;
- gen_help_event (help_echo_string, frame, help_echo_window,
- help_echo_object, help_echo_pos);
- }
- else
- {
- help_echo_string = Qnil;
- gen_help_event (Qnil, frame, Qnil, Qnil, 0);
- }
- count++;
- }
- }
-
- /* If the focus was just given to an autoraising frame,
- raise it now. */
- /* ??? This ought to be able to handle more than one such frame. */
- if (pending_autoraise_frame)
- {
- x_raise_frame (pending_autoraise_frame);
- pending_autoraise_frame = 0;
- }
-
- if (mac_screen_config_changed)
- {
- mac_get_screen_info (dpyinfo);
- mac_screen_config_changed = 0;
- }
-
-#if !TARGET_API_MAC_CARBON
- /* Check which frames are still visible. We do this here because
- there doesn't seem to be any direct notification from the Window
- Manager that the visibility of a window has changed (at least,
- not in all cases). */
- {
- Lisp_Object tail, frame;
-
- FOR_EACH_FRAME (tail, frame)
- {
- struct frame *f = XFRAME (frame);
-
- /* The tooltip has been drawn already. Avoid the
- SET_FRAME_GARBAGED in mac_handle_visibility_change. */
- if (EQ (frame, tip_frame))
- continue;
-
- if (FRAME_MAC_P (f))
- mac_handle_visibility_change (f);
- }
- }
-#endif
-
- --handling_signal;
- UNBLOCK_INPUT;
- return count;
-}
-
-
-/* Need to override CodeWarrior's input function so no conversion is
- done on newlines Otherwise compiled functions in .elc files will be
- read incorrectly. Defined in ...:MSL C:MSL
- Common:Source:buffer_io.c. */
-#ifdef __MWERKS__
-void
-__convert_to_newlines (unsigned char * p, size_t * n)
-{
-#pragma unused(p,n)
-}
-
-void
-__convert_from_newlines (unsigned char * p, size_t * n)
-{
-#pragma unused(p,n)
-}
-#endif
-
-#ifdef MAC_OS8
-void
-make_mac_terminal_frame (struct frame *f)
-{
- Lisp_Object frame;
- Rect r;
-
- XSETFRAME (frame, f);
-
- f->output_method = output_mac;
- f->output_data.mac = (struct mac_output *)
- xmalloc (sizeof (struct mac_output));
- bzero (f->output_data.mac, sizeof (struct mac_output));
-
- XSETFRAME (FRAME_KBOARD (f)->Vdefault_minibuffer_frame, f);
-
- FRAME_COLS (f) = 96;
- FRAME_LINES (f) = 4;
-
- FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
- FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
-
- FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
-
- f->output_data.mac->cursor_pixel = 0;
- f->output_data.mac->border_pixel = 0x00ff00;
- f->output_data.mac->mouse_pixel = 0xff00ff;
- f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
-
- f->output_data.mac->text_cursor = kThemeIBeamCursor;
- f->output_data.mac->nontext_cursor = kThemeArrowCursor;
- f->output_data.mac->modeline_cursor = kThemeArrowCursor;
- f->output_data.mac->hand_cursor = kThemePointingHandCursor;
- f->output_data.mac->hourglass_cursor = kThemeWatchCursor;
- f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor;
-
- FRAME_FONTSET (f) = -1;
- f->output_data.mac->explicit_parent = 0;
- f->left_pos = 8;
- f->top_pos = 32;
- f->border_width = 0;
-
- f->internal_border_width = 0;
-
- f->auto_raise = 1;
- f->auto_lower = 1;
-
- f->new_text_cols = 0;
- f->new_text_lines = 0;
-
- SetRect (&r, f->left_pos, f->top_pos,
- f->left_pos + FRAME_PIXEL_WIDTH (f),
- f->top_pos + FRAME_PIXEL_HEIGHT (f));
-
- BLOCK_INPUT;
-
- if (!(FRAME_MAC_WINDOW (f) =
- NewCWindow (NULL, &r, "\p", true, dBoxProc,
- (WindowRef) -1, 1, (long) f->output_data.mac)))
- abort ();
- /* so that update events can find this mac_output struct */
- f->output_data.mac->mFP = f; /* point back to emacs frame */
-
- UNBLOCK_INPUT;
-
- x_make_gc (f);
-
- /* Need to be initialized for unshow_buffer in window.c. */
- selected_window = f->selected_window;
-
- Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qfont,
- build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil));
- Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qforeground_color,
- build_string ("black")), Qnil));
- Fmodify_frame_parameters (frame,
- Fcons (Fcons (Qbackground_color,
- build_string ("white")), Qnil));
-}
-#endif
-
-
-/***********************************************************************
- Initialization
- ***********************************************************************/
-
-static int mac_initialized = 0;
-
-static XrmDatabase
-mac_make_rdb (xrm_option)
- const char *xrm_option;
-{
- XrmDatabase database;
-
- database = xrm_get_preference_database (NULL);
- if (xrm_option)
- xrm_merge_string_database (database, xrm_option);
-
- return database;
-}
-
-struct mac_display_info *
-mac_term_init (display_name, xrm_option, resource_name)
- Lisp_Object display_name;
- char *xrm_option;
- char *resource_name;
-{
- struct mac_display_info *dpyinfo;
- struct terminal *terminal;
-
- BLOCK_INPUT;
-
- if (!mac_initialized)
- {
- mac_initialize ();
- mac_initialized = 1;
- }
-
- if (x_display_list)
- error ("Sorry, this version can only handle one display");
-
- dpyinfo = &one_mac_display_info;
- bzero (dpyinfo, sizeof (*dpyinfo));
-
- terminal = mac_create_terminal (dpyinfo);
-
- /* Set the name of the terminal. */
- terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
- strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
- terminal->name[SBYTES (display_name)] = 0;
-
-#ifdef MAC_OSX
- dpyinfo->mac_id_name
- = (char *) xmalloc (SCHARS (Vinvocation_name)
- + SCHARS (Vsystem_name)
- + 2);
- sprintf (dpyinfo->mac_id_name, "%s@%s",
- SDATA (Vinvocation_name), SDATA (Vsystem_name));
-#else
- dpyinfo->mac_id_name = (char *) xmalloc (strlen ("Mac Display") + 1);
- strcpy (dpyinfo->mac_id_name, "Mac Display");
-#endif
-
- dpyinfo->reference_count = 0;
- dpyinfo->resx = 72.0;
- dpyinfo->resy = 72.0;
-
- mac_get_screen_info (dpyinfo);
-
- dpyinfo->grabbed = 0;
- dpyinfo->root_window = NULL;
- dpyinfo->terminal->image_cache = make_image_cache ();
-
- dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
- dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
- dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
- dpyinfo->mouse_face_window = Qnil;
- dpyinfo->mouse_face_overlay = Qnil;
- dpyinfo->mouse_face_hidden = 0;
-
- dpyinfo->xrdb = mac_make_rdb (xrm_option);
-
- /* Put this display on the chain. */
- dpyinfo->next = x_display_list;
- x_display_list = dpyinfo;
-
- /* Put it on x_display_name_list. */
- x_display_name_list = Fcons (Fcons (display_name,
- Fcons (Qnil, dpyinfo->xrdb)),
- x_display_name_list);
- dpyinfo->name_list_element = XCAR (x_display_name_list);
-
- /* FIXME: Untested.
- Add the default keyboard. */
- add_keyboard_wait_descriptor (0);
-
-#if USE_CG_DRAWING
- mac_init_fringe (terminal->rif);
-#endif
-
- UNBLOCK_INPUT;
-
- return dpyinfo;
-}
-
-/* Get rid of display DPYINFO, assuming all frames are already gone. */
-
-void
-x_delete_display (dpyinfo)
- struct mac_display_info *dpyinfo;
-{
- int i;
-
- /* Discard this display from x_display_name_list and x_display_list.
- We can't use Fdelq because that can quit. */
- if (! NILP (x_display_name_list)
- && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
- x_display_name_list = XCDR (x_display_name_list);
- else
- {
- Lisp_Object tail;
-
- tail = x_display_name_list;
- while (CONSP (tail) && CONSP (XCDR (tail)))
- {
- if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
- {
- XSETCDR (tail, XCDR (XCDR (tail)));
- break;
- }
- tail = XCDR (tail);
- }
- }
-
- if (x_display_list == dpyinfo)
- x_display_list = dpyinfo->next;
- else
- {
- struct x_display_info *tail;
-
- for (tail = x_display_list; tail; tail = tail->next)
- if (tail->next == dpyinfo)
- tail->next = tail->next->next;
- }
-
- /* Free the font names in the font table. */
- for (i = 0; i < dpyinfo->n_fonts; i++)
- if (dpyinfo->font_table[i].name)
- {
- if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
- xfree (dpyinfo->font_table[i].full_name);
- xfree (dpyinfo->font_table[i].name);
- }
-
- if (dpyinfo->font_table)
- {
- xfree (dpyinfo->font_table->font_encoder);
- xfree (dpyinfo->font_table);
- }
- xfree (dpyinfo->mac_id_name);
-
- if (x_display_list == 0)
- {
- mac_clear_font_name_table ();
- bzero (dpyinfo, sizeof (*dpyinfo));
- }
-}
-
-
-static void
-init_menu_bar ()
-{
-#ifdef MAC_OSX
- OSStatus err;
- MenuRef menu;
- MenuItemIndex menu_index;
-
- err = GetIndMenuItemWithCommandID (NULL, kHICommandQuit, 1,
- &menu, &menu_index);
- if (err == noErr)
- SetMenuItemCommandKey (menu, menu_index, false, 0);
- EnableMenuCommand (NULL, kHICommandPreferences);
- err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1,
- &menu, &menu_index);
- if (err == noErr)
- {
- SetMenuItemCommandKey (menu, menu_index, false, 0);
- InsertMenuItemTextWithCFString (menu, NULL,
- 0, kMenuItemAttrSeparator, 0);
- InsertMenuItemTextWithCFString (menu, CFSTR ("About Emacs"),
- 0, 0, kHICommandAbout);
- }
-#else /* !MAC_OSX */
-#if TARGET_API_MAC_CARBON
- SetMenuItemCommandID (GetMenuRef (M_APPLE), I_ABOUT, kHICommandAbout);
-#endif
-#endif
-}
-
-#if USE_MAC_TSM
-static void
-init_tsm ()
-{
-#ifdef MAC_OSX
- static InterfaceTypeList types = {kUnicodeDocument};
-#else
- static InterfaceTypeList types = {kTextService};
-#endif
-
- NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
- &tsm_document_id, 0);
-}
-#endif
-
-/* Set up use of X before we make the first connection. */
-
-extern frame_parm_handler mac_frame_parm_handlers[];
-
-static struct redisplay_interface x_redisplay_interface =
-{
- mac_frame_parm_handlers,
- x_produce_glyphs,
- x_write_glyphs,
- x_insert_glyphs,
- x_clear_end_of_line,
- x_scroll_run,
- x_after_update_window_line,
- x_update_window_begin,
- x_update_window_end,
- x_cursor_to,
- x_flush,
-#if USE_CG_DRAWING
- mac_flush_display_optional,
-#else
- 0, /* flush_display_optional */
-#endif
- x_clear_window_mouse_face,
- x_get_glyph_overhangs,
- x_fix_overlapping_area,
- x_draw_fringe_bitmap,
-#if USE_CG_DRAWING
- mac_define_fringe_bitmap,
- mac_destroy_fringe_bitmap,
-#else
- 0, /* define_fringe_bitmap */
- 0, /* destroy_fringe_bitmap */
-#endif
- mac_per_char_metric,
- mac_encode_char,
- mac_compute_glyph_string_overhangs,
- x_draw_glyph_string,
- mac_define_frame_cursor,
- mac_clear_frame_area,
- mac_draw_window_cursor,
- mac_draw_vertical_window_border,
- mac_shift_glyphs_for_insert
-};
-
-static struct terminal *
-mac_create_terminal (struct mac_display_info *dpyinfo)
-{
- struct terminal *terminal;
-
- terminal = create_terminal ();
-
- terminal->type = output_mac;
- terminal->display_info.mac = dpyinfo;
- dpyinfo->terminal = terminal;
-
- terminal->clear_frame_hook = x_clear_frame;
- terminal->ins_del_lines_hook = x_ins_del_lines;
- terminal->delete_glyphs_hook = x_delete_glyphs;
- terminal->ring_bell_hook = XTring_bell;
- terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
- terminal->set_terminal_modes_hook = XTset_terminal_modes;
- terminal->update_begin_hook = x_update_begin;
- terminal->update_end_hook = x_update_end;
- terminal->set_terminal_window_hook = XTset_terminal_window;
- terminal->read_socket_hook = XTread_socket;
- terminal->frame_up_to_date_hook = XTframe_up_to_date;
- terminal->mouse_position_hook = XTmouse_position;
- terminal->frame_rehighlight_hook = XTframe_rehighlight;
- terminal->frame_raise_lower_hook = XTframe_raise_lower;
- /* terminal->fullscreen_hook = XTfullscreen_hook; */
- terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
- terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
- terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
- terminal->delete_frame_hook = x_destroy_window;
- /* terminal->delete_terminal_hook = x_delete_terminal; */
-
- terminal->rif = &x_redisplay_interface;
-#if 0
- TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
- TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
- TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
- TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
- TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
- scrolls off the
- bottom */
-#else
- terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
- terminal->char_ins_del_ok = 1;
- terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
- terminal->fast_clear_end_of_line = 1; /* X does this well. */
- terminal->memory_below_frame = 0; /* We don't remember what scrolls
- off the bottom. */
-
-#endif
-
- /* FIXME: This keyboard setup is 100% untested, just copied from
- w32_create_terminal in order to set window-system now that it's
- a keyboard object. */
- /* We don't yet support separate terminals on Mac, so don't try to share
- keyboards between virtual terminals that are on the same physical
- terminal like X does. */
- terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
- init_kboard (terminal->kboard);
- terminal->kboard->Vwindow_system = intern ("mac");
- terminal->kboard->next_kboard = all_kboards;
- all_kboards = terminal->kboard;
- /* Don't let the initial kboard remain current longer than necessary.
- That would cause problems if a file loaded on startup tries to
- prompt in the mini-buffer. */
- if (current_kboard == initial_kboard)
- current_kboard = terminal->kboard;
- terminal->kboard->reference_count++;
-
- return terminal;
-}
-
-static void
-mac_initialize ()
-{
-
- baud_rate = 19200;
-
- last_tool_bar_item = -1;
- any_help_event_p = 0;
-
- /* Try to use interrupt input; if we can't, then start polling. */
- Fset_input_interrupt_mode (Qt);
-
- BLOCK_INPUT;
-
-#if TARGET_API_MAC_CARBON
-
- install_application_handler ();
-
- init_menu_bar ();
-
-#if USE_MAC_TSM
- init_tsm ();
-#endif
-
-#ifdef MAC_OSX
- init_coercion_handler ();
-
- init_apple_event_handler ();
-
- init_dm_notification_handler ();
-
- if (!inhibit_window_system)
- {
- static const ProcessSerialNumber psn = {0, kCurrentProcess};
-
- SetFrontProcess (&psn);
- }
-#endif
-#endif
-
-#if USE_CG_DRAWING
- init_cg_color ();
-#endif
-
- UNBLOCK_INPUT;
-
-}
-
-
-void
-syms_of_macterm ()
-{
-#if 0
- staticpro (&x_error_message_string);
- x_error_message_string = Qnil;
-#endif
-
- Qcontrol = intern ("control"); staticpro (&Qcontrol);
- Qmeta = intern ("meta"); staticpro (&Qmeta);
- Qalt = intern ("alt"); staticpro (&Qalt);
- Qhyper = intern ("hyper"); staticpro (&Qhyper);
- Qsuper = intern ("super"); staticpro (&Qsuper);
- Qmodifier_value = intern ("modifier-value");
- staticpro (&Qmodifier_value);
-
- Fput (Qcontrol, Qmodifier_value, make_number (ctrl_modifier));
- Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
- Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
- Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
- Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
-
-#if TARGET_API_MAC_CARBON
- Qhi_command = intern ("hi-command"); staticpro (&Qhi_command);
-#ifdef MAC_OSX
- Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
- staticpro (&Qtoolbar_switch_mode);
-#if USE_MAC_FONT_PANEL
- Qpanel_closed = intern ("panel-closed"); staticpro (&Qpanel_closed);
- Qselection = intern ("selection"); staticpro (&Qselection);
-#endif
-
- Qservice = intern ("service"); staticpro (&Qservice);
- Qpaste = intern ("paste"); staticpro (&Qpaste);
- Qperform = intern ("perform"); staticpro (&Qperform);
-
- Qmouse_drag_overlay = intern ("mouse-drag-overlay");
- staticpro (&Qmouse_drag_overlay);
-#endif
-#if USE_MAC_TSM
- Qtext_input = intern ("text-input"); staticpro (&Qtext_input);
- Qupdate_active_input_area = intern ("update-active-input-area");
- staticpro (&Qupdate_active_input_area);
- Qunicode_for_key_event = intern ("unicode-for-key-event");
- staticpro (&Qunicode_for_key_event);
-#endif
-#endif
-
-#ifdef MAC_OSX
- Fprovide (intern ("mac-carbon"), Qnil);
-#endif
-
- staticpro (&Qreverse);
- Qreverse = intern ("reverse");
-
- staticpro (&x_display_name_list);
- x_display_name_list = Qnil;
-
- staticpro (&last_mouse_scroll_bar);
- last_mouse_scroll_bar = Qnil;
-
- staticpro (&fm_font_family_alist);
- fm_font_family_alist = Qnil;
-
-#if USE_ATSUI
- staticpro (&atsu_font_id_hash);
- atsu_font_id_hash = Qnil;
-
- staticpro (&fm_style_face_attributes_alist);
- fm_style_face_attributes_alist = Qnil;
-#endif
-
-#if USE_MAC_TSM
- staticpro (&saved_ts_script_language_on_focus);
- saved_ts_script_language_on_focus = Qnil;
-#endif
-
- /* We don't yet support this, but defining this here avoids whining
- from cus-start.el and other places, like "M-x set-variable". */
- DEFVAR_BOOL ("x-use-underline-position-properties",
- &x_use_underline_position_properties,
- doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-A value of nil means ignore them. If you encounter fonts with bogus
-UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil.
-
-NOTE: Not supported on Mac yet. */);
- x_use_underline_position_properties = 0;
-
- DEFVAR_BOOL ("x-underline-at-descent-line",
- &x_underline_at_descent_line,
- doc: /* *Non-nil means to draw the underline at the same place as the descent line.
-A value of nil means to draw the underline according to the value of the
-variable `x-use-underline-position-properties', which is usually at the
-baseline level. The default value is nil. */);
- x_underline_at_descent_line = 0;
-
- DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
- doc: /* If not nil, Emacs uses toolkit scroll bars. */);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- Vx_toolkit_scroll_bars = Qt;
-#else
- Vx_toolkit_scroll_bars = Qnil;
-#endif
-
- staticpro (&last_mouse_motion_frame);
- last_mouse_motion_frame = Qnil;
-
-/* Variables to configure modifier key assignment. */
-
- DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier,
- doc: /* *Modifier key assumed when the Mac control key is pressed.
-The value can be `control', `meta', `alt', `hyper', or `super' for the
-respective modifier. The default is `control'. */);
- Vmac_control_modifier = Qcontrol;
-
- DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
- doc: /* *Modifier key assumed when the Mac alt/option key is pressed.
-The value can be `control', `meta', `alt', `hyper', or `super' for the
-respective modifier. If the value is nil then the key will act as the
-normal Mac control modifier, and the option key can be used to compose
-characters depending on the chosen Mac keyboard setting. */);
- Vmac_option_modifier = Qnil;
-
- DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier,
- doc: /* *Modifier key assumed when the Mac command key is pressed.
-The value can be `control', `meta', `alt', `hyper', or `super' for the
-respective modifier. The default is `meta'. */);
- Vmac_command_modifier = Qmeta;
-
- DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier,
- doc: /* *Modifier key assumed when the Mac function key is pressed.
-The value can be `control', `meta', `alt', `hyper', or `super' for the
-respective modifier. Note that remapping the function key may lead to
-unexpected results for some keys on non-US/GB keyboards. */);
- Vmac_function_modifier = Qnil;
-
- DEFVAR_LISP ("mac-emulate-three-button-mouse",
- &Vmac_emulate_three_button_mouse,
- doc: /* *Specify a way of three button mouse emulation.
-The value can be nil, t, or the symbol `reverse'.
-A value of nil means that no emulation should be done and the modifiers
-should be placed on the mouse-1 event.
-t means that when the option-key is held down while pressing the mouse
-button, the click will register as mouse-2 and while the command-key
-is held down, the click will register as mouse-3.
-The symbol `reverse' means that the option-key will register for
-mouse-3 and the command-key will register for mouse-2. */);
- Vmac_emulate_three_button_mouse = Qnil;
-
-#if TARGET_API_MAC_CARBON
- DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2,
- doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
-Otherwise, the right click will be treated as mouse-2 and the wheel
-button will be mouse-3. */);
- mac_wheel_button_is_mouse_2 = 1;
-
- DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system,
- doc: /* *Non-nil if command key presses are passed on to the Mac Toolbox. */);
- mac_pass_command_to_system = 1;
-
- DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system,
- doc: /* *Non-nil if control key presses are passed on to the Mac Toolbox. */);
- mac_pass_control_to_system = 1;
-
-#endif
-
- DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics,
- doc: /* *If non-nil, allow anti-aliasing.
-The text will be rendered using Core Graphics text rendering which
-may anti-alias the text. */);
-#if USE_CG_DRAWING
- mac_use_core_graphics = 1;
-#else
- mac_use_core_graphics = 0;
-#endif
-
- /* Register an entry for `mac-roman' so that it can be used when
- creating the terminal frame on Mac OS 9 before loading
- term/mac-win.elc. */
- DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist,
- doc: /* Alist of Emacs character sets vs text encodings and coding systems.
-Each entry should be of the form:
-
- (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
-
-where CHARSET-NAME is a string used in font names to identify the
-charset, TEXT-ENCODING is a TextEncodingBase value in Mac, and
-CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING. */);
- Vmac_charset_info_alist =
- Fcons (list3 (build_string ("mac-roman"),
- make_number (smRoman), Qnil), Qnil);
-
-#if USE_MAC_TSM
- DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
- doc: /* Overlay used to display Mac TSM active input area. */);
- Vmac_ts_active_input_overlay = Qnil;
-
- DEFVAR_LISP ("mac-ts-active-input-buf", &Vmac_ts_active_input_buf,
- doc: /* Byte sequence of the current Mac TSM active input area. */);
- /* `empty_string' is not ready yet on Mac OS Classic. */
- Vmac_ts_active_input_buf = build_string ("");
-
- DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus,
- doc: /* *How to change Mac TSM script/language when a frame gets focus.
-If the value is t, the input script and language are restored to those
-used in the last focus frame. If the value is a pair of integers, the
-input script and language codes, which are defined in the Script
-Manager, are set to its car and cdr parts, respectively. Otherwise,
-Emacs doesn't set them and thus follows the system default behavior. */);
- Vmac_ts_script_language_on_focus = Qnil;
-#endif
-}
-
-/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
- (do not change this comment) */
diff --git a/src/macterm.h b/src/macterm.h
deleted file mode 100644
index 28318a6d0b0..00000000000
--- a/src/macterm.h
+++ /dev/null
@@ -1,795 +0,0 @@
-/* Display module for Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Contributed by Andrew Choi (akochoi@mac.com). */
-
-#include "macgui.h"
-#include "frame.h"
-
-#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
-#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-
-#define ALPHA_FROM_ULONG(color) ((color) >> 24)
-#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
-#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
-#define BLUE_FROM_ULONG(color) ((color) & 0xff)
-
-/* Do not change `* 0x101' in the following lines to `<< 8'. If
- changed, image masks in 1-bit depth will not work. */
-#define RED16_FROM_ULONG(color) (RED_FROM_ULONG(color) * 0x101)
-#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG(color) * 0x101)
-#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG(color) * 0x101)
-
-#define BLACK_PIX_DEFAULT(f) RGB_TO_ULONG(0,0,0)
-#define WHITE_PIX_DEFAULT(f) RGB_TO_ULONG(255,255,255)
-
-#define FONT_WIDTH(f) ((f)->max_bounds.width)
-#define FONT_HEIGHT(f) ((f)->ascent + (f)->descent)
-#define FONT_BASE(f) ((f)->ascent)
-#define FONT_DESCENT(f) ((f)->descent)
-
-/* Structure recording bitmaps and reference count.
- If REFCOUNT is 0 then this record is free to be reused. */
-
-struct mac_bitmap_record
-{
- char *bitmap_data;
- char *file;
- int refcount;
- int height, width;
-};
-
-
-/* For each display (currently only one on mac), we have a structure that
- records information about it. */
-
-struct mac_display_info
-{
- /* Chain of all mac_display_info structures. */
- struct mac_display_info *next;
-
- /* The generic display parameters corresponding to this X display. */
- struct terminal *terminal;
-
- /* This is a cons cell of the form (NAME . FONT-LIST-CACHE).
- The same cons cell also appears in x_display_name_list. */
- Lisp_Object name_list_element;
-
- /* Number of frames that are on this display. */
- int reference_count;
-
- /* Dots per inch of the screen. */
- double resx, resy;
-
- /* Number of planes on this screen. */
- int n_planes;
-
- /* Whether the screen supports color */
- int color_p;
-
- /* Dimensions of this screen. */
- int height, width;
-
- /* Mask of things that cause the mouse to be grabbed. */
- int grabbed;
-
-#if 0
- /* Emacs bitmap-id of the default icon bitmap for this frame.
- Or -1 if none has been allocated yet. */
- int icon_bitmap_id;
-
-#endif
- /* The root window of this screen. */
- Window root_window;
-
- /* The cursor to use for vertical scroll bars. */
- Cursor vertical_scroll_bar_cursor;
-
- /* Resource data base */
- XrmDatabase xrdb;
-
- /* A table of all the fonts we have already loaded. */
- struct font_info *font_table;
-
- /* The current capacity of font_table. */
- int font_table_size;
-
- /* Minimum width over all characters in all fonts in font_table. */
- int smallest_char_width;
-
- /* Minimum font height over all fonts in font_table. */
- int smallest_font_height;
-
- /* Reusable Graphics Context for drawing a cursor in a non-default face. */
- GC scratch_cursor_gc;
-
- /* These variables describe the range of text currently shown in its
- mouse-face, together with the window they apply to. As long as
- the mouse stays within this range, we need not redraw anything on
- its account. Rows and columns are glyph matrix positions in
- MOUSE_FACE_WINDOW. */
- int mouse_face_beg_row, mouse_face_beg_col;
- int mouse_face_beg_x, mouse_face_beg_y;
- int mouse_face_end_row, mouse_face_end_col;
- int mouse_face_end_x, mouse_face_end_y;
- int mouse_face_past_end;
- Lisp_Object mouse_face_window;
- int mouse_face_face_id;
- Lisp_Object mouse_face_overlay;
-
- /* 1 if a mouse motion event came and we didn't handle it right away because
- gc was in progress. */
- int mouse_face_deferred_gc;
-
- /* FRAME and X, Y position of mouse when last checked for
- highlighting. X and Y can be negative or out of range for the frame. */
- struct frame *mouse_face_mouse_frame;
- int mouse_face_mouse_x, mouse_face_mouse_y;
-
- /* Nonzero means defer mouse-motion highlighting. */
- int mouse_face_defer;
-
- /* Nonzero means that the mouse highlight should not be shown. */
- int mouse_face_hidden;
-
- int mouse_face_image_state;
-
- char *mac_id_name;
-
- /* The number of fonts actually stored in the font table.
- font_table[n] is used and valid if 0 <= n < n_fonts. 0 <=
- n_fonts <= font_table_size and font_table[i].name != 0. */
- int n_fonts;
-
- /* Pointer to bitmap records. */
- struct mac_bitmap_record *bitmaps;
-
- /* Allocated size of bitmaps field. */
- int bitmaps_size;
-
- /* Last used bitmap index. */
- int bitmaps_last;
-
- /* The frame (if any) which has the window that has keyboard focus.
- Zero if none. This is examined by Ffocus_frame in macfns.c. Note
- that a mere EnterNotify event can set this; if you need to know the
- last frame specified in a FocusIn or FocusOut event, use
- x_focus_event_frame. */
- struct frame *x_focus_frame;
-
- /* The last frame mentioned in a FocusIn or FocusOut event. This is
- separate from x_focus_frame, because whether or not LeaveNotify
- events cause us to lose focus depends on whether or not we have
- received a FocusIn event for it. */
- struct frame *x_focus_event_frame;
-
- /* The frame which currently has the visual highlight, and should get
- keyboard input (other sorts of input have the frame encoded in the
- event). It points to the focus frame's selected window's
- frame. It differs from x_focus_frame when we're using a global
- minibuffer. */
- struct frame *x_highlight_frame;
-};
-
-/* This checks to make sure we have a display. */
-extern void check_mac P_ ((void));
-
-#define x_display_info mac_display_info
-
-/* This is a chain of structures for all the X displays currently in use. */
-extern struct x_display_info *x_display_list;
-
-/* This is a chain of structures for all the displays currently in use. */
-extern struct mac_display_info one_mac_display_info;
-
-/* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
- one for each element of x_display_list and in the same order.
- NAME is the name of the frame.
- FONT-LIST-CACHE records previous values returned by x-list-fonts. */
-extern Lisp_Object x_display_name_list;
-
-extern struct x_display_info *x_display_info_for_name P_ ((Lisp_Object));
-
-extern struct mac_display_info *mac_term_init P_ ((Lisp_Object, char *, char *));
-
-extern Lisp_Object x_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
-extern struct font_info *x_get_font_info P_ ((struct frame *f, int));
-extern struct font_info *x_load_font P_ ((struct frame *, char *, int));
-extern struct font_info *x_query_font P_ ((struct frame *, char *));
-extern void x_find_ccl_program P_ ((struct font_info *));
-
-/* When Emacs uses a tty window, tty_display in frame.c points to an
- x_output struct . */
-struct x_output
-{
- unsigned long background_pixel;
- unsigned long foreground_pixel;
-};
-
-/* The collection of data describing a window on the Mac. */
-struct mac_output
-{
- /* Placeholder for things accessed through output_data.x. Must
- appear first. */
- struct x_output x_compatible;
-
- /* Menubar "widget" handle. */
- int menubar_widget;
-
- FRAME_PTR mFP; /* points back to the frame struct */
-
- /* Here are the Graphics Contexts for the default font. */
- GC normal_gc; /* Normal video */
- GC reverse_gc; /* Reverse video */
- GC cursor_gc; /* cursor drawing */
-
- /* The window used for this frame.
- May be zero while the frame object is being created
- and the window has not yet been created. */
- Window window_desc;
-
- /* The window that is the parent of this window.
- Usually this is a window that was made by the window manager,
- but it can be the root window, and it can be explicitly specified
- (see the explicit_parent field, below). */
- Window parent_desc;
-
- /* Default ASCII font of this frame. */
- XFontStruct *font;
-
- /* The baseline offset of the default ASCII font. */
- int baseline_offset;
-
- /* If a fontset is specified for this frame instead of font, this
- value contains an ID of the fontset, else -1. */
- int fontset;
-
- /* Pixel values used for various purposes.
- border_pixel may be -1 meaning use a gray tile. */
- unsigned long cursor_pixel;
- unsigned long border_pixel;
- unsigned long mouse_pixel;
- unsigned long cursor_foreground_pixel;
-
-#if 0
- /* Foreground color for scroll bars. A value of -1 means use the
- default (black for non-toolkit scroll bars). */
- unsigned long scroll_bar_foreground_pixel;
-
- /* Background color for scroll bars. A value of -1 means use the
- default (background color of the frame for non-toolkit scroll
- bars). */
- unsigned long scroll_bar_background_pixel;
-#endif
-
- /* Descriptor for the cursor in use for this window. */
- Cursor text_cursor;
- Cursor nontext_cursor;
- Cursor modeline_cursor;
- Cursor hand_cursor;
- Cursor hourglass_cursor;
- Cursor horizontal_drag_cursor;
-#if 0
- /* Window whose cursor is hourglass_cursor. This window is temporarily
- mapped to display a hourglass-cursor. */
- Window hourglass_window;
-
- /* Non-zero means hourglass cursor is currently displayed. */
- unsigned hourglass_p : 1;
-
- /* Flag to set when the window needs to be completely repainted. */
- int needs_exposure;
-
-#endif
-
-#if TARGET_API_MAC_CARBON
- /* The Mac control reference for the hourglass (progress indicator)
- shown at the upper-right corner of the window. */
- ControlRef hourglass_control;
-#endif
-
- /* This is the Emacs structure for the display this frame is on. */
- /* struct w32_display_info *display_info; */
-
- /* Nonzero means our parent is another application's window
- and was explicitly specified. */
- char explicit_parent;
-
- /* Nonzero means tried already to make this frame visible. */
- char asked_for_visible;
-
- /* Relief GCs, colors etc. */
- struct relief
- {
- GC gc;
- unsigned long pixel;
- int allocated_p;
- }
- black_relief, white_relief;
-
- /* The background for which the above relief GCs were set up.
- They are changed only when a different background is involved. */
- unsigned long relief_background;
-
- /* Width of the internal border. */
- int internal_border_width;
-
- /* Hints for the size and the position of a window. */
- XSizeHints *size_hints;
-
-#if USE_MAC_TOOLBAR
- /* This variable records the gravity value of the window position if
- the window has an external tool bar when it is created. The
- position of the window is adjusted using this information when
- the tool bar is first redisplayed. Once the tool bar is
- redisplayed, it is set to 0 in order to avoid further
- adjustment. */
- int toolbar_win_gravity;
-#endif
-
-#if USE_CG_DRAWING
- /* Quartz 2D graphics context. */
- CGContextRef cg_context;
-#endif
-};
-
-typedef struct mac_output mac_output;
-
-/* Return the X output data for frame F. */
-#define FRAME_X_OUTPUT(f) ((f)->output_data.mac)
-
-/* Return the Mac window used for displaying data in frame F. */
-#define FRAME_MAC_WINDOW(f) ((f)->output_data.mac->window_desc)
-#define FRAME_X_WINDOW(f) ((f)->output_data.mac->window_desc)
-
-#define FRAME_FONT(f) ((f)->output_data.mac->font)
-#define FRAME_FONTSET(f) ((f)->output_data.mac->fontset)
-
-#define FRAME_BASELINE_OFFSET(f) ((f)->output_data.mac->baseline_offset)
-
-#define FRAME_SIZE_HINTS(f) ((f)->output_data.mac->size_hints)
-
-/* This gives the mac_display_info structure for the display F is on. */
-#define FRAME_MAC_DISPLAY_INFO(f) (&one_mac_display_info)
-#define FRAME_X_DISPLAY_INFO(f) (&one_mac_display_info)
-
-/* This is the `Display *' which frame F is on. */
-#define FRAME_MAC_DISPLAY(f) (0)
-#define FRAME_X_DISPLAY(f) (0)
-
-/* This is the 'font_info *' which frame F has. */
-#define FRAME_MAC_FONT_TABLE(f) (FRAME_MAC_DISPLAY_INFO (f)->font_table)
-
-/* Value is the smallest width of any character in any font on frame F. */
-
-#define FRAME_SMALLEST_CHAR_WIDTH(F) \
- FRAME_MAC_DISPLAY_INFO(F)->smallest_char_width
-
-/* Value is the smallest height of any font on frame F. */
-
-#define FRAME_SMALLEST_FONT_HEIGHT(F) \
- FRAME_MAC_DISPLAY_INFO(F)->smallest_font_height
-
-/* Mac-specific scroll bar stuff. */
-
-/* We represent scroll bars as lisp vectors. This allows us to place
- references to them in windows without worrying about whether we'll
- end up with windows referring to dead scroll bars; the garbage
- collector will free it when its time comes.
-
- We use struct scroll_bar as a template for accessing fields of the
- vector. */
-
-struct scroll_bar {
-
- /* These fields are shared by all vectors. */
- EMACS_INT size_from_Lisp_Vector_struct;
- struct Lisp_Vector *next_from_Lisp_Vector_struct;
-
- /* The window we're a scroll bar for. */
- Lisp_Object window;
-
- /* The next and previous in the chain of scroll bars in this frame. */
- Lisp_Object next, prev;
-
- /* The Mac control reference of this scroll bar. Since this is a
- pointer value, we store it split into two Lisp integers. */
- Lisp_Object control_ref_low, control_ref_high;
-
- /* The position and size of the scroll bar in pixels, relative to the
- frame. */
- Lisp_Object top, left, width, height;
-
- /* The starting and ending positions of the handle, relative to the
- handle area (i.e. zero is the top position, not
- SCROLL_BAR_TOP_BORDER). If they're equal, that means the handle
- hasn't been drawn yet.
-
- These are not actually the locations where the beginning and end
- are drawn; in order to keep handles from becoming invisible when
- editing large files, we establish a minimum height by always
- drawing handle bottoms VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
- where they would be normally; the bottom and top are in a
- different co-ordinate system. */
- Lisp_Object start, end;
-
- /* If the scroll bar handle is currently being dragged by the user,
- this is the number of pixels from the top of the handle to the
- place where the user grabbed it. If the handle is pressed but
- not dragged yet, this is a negative integer whose absolute value
- is the number of pixels plus 1. If the handle isn't currently
- being dragged, this is Qnil. */
- Lisp_Object dragging;
-
-#ifdef MAC_OSX
- /* t if the background of the fringe that is adjacent to a scroll
- bar is extended to the gap between the fringe and the bar. */
- Lisp_Object fringe_extended_p;
-#endif
-
- /* t if redraw needed in the next XTset_vertical_scroll_bar call. */
- Lisp_Object redraw_needed_p;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- /* The position and size of the scroll bar handle track area in
- pixels, relative to the frame. */
- Lisp_Object track_top, track_height;
-
- /* Minimum length of the scroll bar handle, in pixels. */
- Lisp_Object min_handle;
-#endif
-};
-
-/* The number of elements a vector holding a struct scroll_bar needs. */
-#define SCROLL_BAR_VEC_SIZE \
- ((sizeof (struct scroll_bar) \
- - sizeof (EMACS_INT) - sizeof (struct Lisp_Vector *)) \
- / sizeof (Lisp_Object))
-
-/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
-#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
-
-
-/* Building a C long integer from two lisp integers. */
-#define SCROLL_BAR_PACK(low, high) (XINT (high) << 16 | XINT (low))
-
-/* Setting two lisp integers to two parts of a C unsigned long. */
-#define SCROLL_BAR_UNPACK(low, high, ulong) \
- (XSETINT ((low), (ulong) & 0xffff), \
- XSETINT ((high), (ulong) >> 16))
-
-
-/* Extract the Mac control handle of the scroll bar from a struct
- scroll_bar. */
-#define SCROLL_BAR_CONTROL_REF(ptr) \
- ((ControlRef) SCROLL_BAR_PACK ((ptr)->control_ref_low, \
- (ptr)->control_ref_high))
-
-/* Store a Mac control handle in a struct scroll_bar. */
-#define SET_SCROLL_BAR_CONTROL_REF(ptr, ref) \
- (SCROLL_BAR_UNPACK ((ptr)->control_ref_low, \
- (ptr)->control_ref_high, (unsigned long) (ref)))
-
-/* Return the inside width of a vertical scroll bar, given the outside
- width. */
-#define VERTICAL_SCROLL_BAR_INSIDE_WIDTH(f, width) \
- ((width) \
- - VERTICAL_SCROLL_BAR_LEFT_BORDER \
- - VERTICAL_SCROLL_BAR_RIGHT_BORDER \
- - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2)
-
-/* Return the length of the rectangle within which the top of the
- handle must stay. This isn't equivalent to the inside height,
- because the scroll bar handle has a minimum height.
-
- This is the real range of motion for the scroll bar, so when we're
- scaling buffer positions to scroll bar positions, we use this, not
- VERTICAL_SCROLL_BAR_INSIDE_HEIGHT. */
-#define VERTICAL_SCROLL_BAR_TOP_RANGE(f,height) \
- (VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, height) \
- - VERTICAL_SCROLL_BAR_MIN_HANDLE - UP_AND_DOWN_ARROWS)
-
-/* Return the inside height of vertical scroll bar, given the outside
- height. See VERTICAL_SCROLL_BAR_TOP_RANGE too. */
-#define VERTICAL_SCROLL_BAR_INSIDE_HEIGHT(f,height) \
- ((height) - VERTICAL_SCROLL_BAR_TOP_BORDER \
- - VERTICAL_SCROLL_BAR_BOTTOM_BORDER)
-
-
-/* Border widths for scroll bars.
-
- Scroll bar windows don't have any borders; their border width is
- set to zero, and we redraw borders ourselves. This makes the code
- a bit cleaner, since we don't have to convert between outside width
- (used when relating to the rest of the screen) and inside width
- (used when sizing and drawing the scroll bar window itself).
-
- The handle moves up and down/back and forth in a rectangle inset
- from the edges of the scroll bar. These are widths by which we
- inset the handle boundaries from the scroll bar edges. */
-#define VERTICAL_SCROLL_BAR_LEFT_BORDER (0)
-#define VERTICAL_SCROLL_BAR_RIGHT_BORDER (0)
-#define VERTICAL_SCROLL_BAR_TOP_BORDER (0)
-#define VERTICAL_SCROLL_BAR_BOTTOM_BORDER (0)
-
-/* Minimum lengths for scroll bar handles, in pixels. */
-#define VERTICAL_SCROLL_BAR_MIN_HANDLE (16)
-
-/* Combined length of up and down arrow boxes in scroll bars, in pixels. */
-#define UP_AND_DOWN_ARROWS (32)
-
-/* Trimming off a few pixels from each side prevents
- text from glomming up against the scroll bar */
-#define VERTICAL_SCROLL_BAR_WIDTH_TRIM (0)
-
-/* Variations of possible Aqua scroll bar width. */
-#define MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH (15)
-#define MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH (11)
-
-/* Size of hourglass controls */
-#define HOURGLASS_WIDTH (15)
-#define HOURGLASS_HEIGHT (15)
-
-/* Some constants that are used locally. */
-/* Creator code for Emacs on Mac OS. */
-enum {
- MAC_EMACS_CREATOR_CODE = 'EMAx'
-};
-
-/* Apple event descriptor types */
-enum {
- TYPE_FILE_NAME = 'fNam'
-};
-
-/* Keywords for Apple event attributes */
-enum {
- KEY_EMACS_SUSPENSION_ID_ATTR = 'esId' /* typeUInt32 */
-};
-
-/* Carbon event parameter names. */
-enum {
- EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER = 'tsSn' /* typeUInt32 */
-};
-
-/* Some constants that are not defined in older versions. */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
-/* Keywords for Apple event attributes */
-enum {
- keyReplyRequestedAttr = 'repq'
-};
-#endif
-
-#if 0
-/* We can't determine the availability of these enumerators by
- MAC_OS_X_VERSION_MAX_ALLOWED, because they are defined in
- MacOSX10.3.9.sdk for Mac OS X 10.4, but not in Mac OS X 10.3. */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1040
-/* Gestalt selectors */
-enum {
- gestaltSystemVersionMajor = 'sys1',
- gestaltSystemVersionMinor = 'sys2',
- gestaltSystemVersionBugFix = 'sys3'
-};
-#endif
-#endif
-
-#ifdef MAC_OSX
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1020
-/* Apple event descriptor types */
-enum {
- typeUTF8Text = 'utf8'
-};
-
-/* Carbon event parameter names */
-enum {
- kEventParamWindowMouseLocation = 'wmou'
-};
-#endif
-
-/* kCGBitmapByteOrder32Host is defined in Universal SDK for 10.4 but
- not in PPC SDK for 10.4.0. */
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 && !defined (kCGBitmapByteOrder32Host)
-#define kCGBitmapByteOrder32Host 0
-#endif
-#endif /* MAC_OSX */
-
-struct frame;
-struct face;
-struct image;
-
-Lisp_Object display_x_get_resource P_ ((struct x_display_info *,
- Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object));
-struct frame *check_x_frame P_ ((Lisp_Object));
-EXFUN (Fx_display_color_p, 1);
-EXFUN (Fx_display_grayscale_p, 1);
-EXFUN (Fx_display_planes, 1);
-extern void x_free_gcs P_ ((struct frame *));
-extern int XParseGeometry P_ ((char *, int *, int *, unsigned int *,
- unsigned int *));
-
-/* Defined in macterm.c. */
-
-extern void x_set_window_size P_ ((struct frame *, int, int, int));
-extern void x_set_mouse_position P_ ((struct frame *, int, int));
-extern void x_set_mouse_pixel_position P_ ((struct frame *, int, int));
-extern void x_raise_frame P_ ((struct frame *));
-extern void x_lower_frame P_ ((struct frame *));
-extern void x_make_frame_visible P_ ((struct frame *));
-extern void x_make_frame_invisible P_ ((struct frame *));
-extern void x_iconify_frame P_ ((struct frame *));
-extern void x_free_frame_resources P_ ((struct frame *));
-extern void x_destroy_window P_ ((struct frame *));
-extern void x_wm_set_size_hint P_ ((struct frame *, long, int));
-extern void x_delete_display P_ ((struct x_display_info *));
-extern void mac_initialize P_ ((void));
-extern Pixmap XCreatePixmap P_ ((Display *, Window, unsigned int,
- unsigned int, unsigned int));
-extern Pixmap XCreatePixmapFromBitmapData P_ ((Display *, Window, char *,
- unsigned int, unsigned int,
- unsigned long, unsigned long,
- unsigned int));
-extern void XFreePixmap P_ ((Display *, Pixmap));
-extern GC XCreateGC P_ ((Display *, void *, unsigned long, XGCValues *));
-extern void XFreeGC P_ ((Display *, GC));
-extern void XSetForeground P_ ((Display *, GC, unsigned long));
-extern void XSetBackground P_ ((Display *, GC, unsigned long));
-extern void XDrawLine P_ ((Display *, Pixmap, GC, int, int, int, int));
-extern void mac_clear_area P_ ((struct frame *, int, int,
- unsigned int, unsigned int));
-extern void mac_unload_font P_ ((struct mac_display_info *, XFontStruct *));
-extern OSStatus mac_post_mouse_moved_event P_ ((void));
-extern int mac_quit_char_key_p P_ ((UInt32, UInt32));
-
-#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
-#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
-
-#if USE_MAC_IMAGE_IO
-extern CGColorSpaceRef mac_cg_color_space_rgb;
-#endif
-
-/* Defined in macselect.c */
-
-extern void x_clear_frame_selections P_ ((struct frame *));
-EXFUN (Fx_selection_owner_p, 1);
-
-/* Defined in macfns.c */
-
-extern void x_real_positions P_ ((struct frame *, int *, int *));
-extern void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-extern int x_pixel_width P_ ((struct frame *));
-extern int x_pixel_height P_ ((struct frame *));
-extern int x_char_width P_ ((struct frame *));
-extern int x_char_height P_ ((struct frame *));
-extern void x_sync P_ ((struct frame *));
-extern void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-extern void mac_update_title_bar P_ ((struct frame *, int));
-extern Lisp_Object x_get_focus_frame P_ ((struct frame *));
-
-/* Defined in mac.c. */
-
-extern void mac_clear_font_name_table P_ ((void));
-extern Lisp_Object mac_aedesc_to_lisp P_ ((const AEDesc *));
-extern OSErr mac_ae_put_lisp P_ ((AEDescList *, UInt32, Lisp_Object));
-#if TARGET_API_MAC_CARBON
-extern OSErr create_apple_event P_ ((AEEventClass, AEEventID, AppleEvent *));
-extern Lisp_Object mac_event_parameters_to_lisp P_ ((EventRef, UInt32,
- const EventParamName *,
- const EventParamType *));
-extern CFStringRef cfstring_create_with_utf8_cstring P_ ((const char *));
-extern CFStringRef cfstring_create_with_string P_ ((Lisp_Object));
-extern Lisp_Object cfdata_to_lisp P_ ((CFDataRef));
-extern Lisp_Object cfstring_to_lisp_nodecode P_ ((CFStringRef));
-extern Lisp_Object cfstring_to_lisp P_ ((CFStringRef));
-extern Lisp_Object cfnumber_to_lisp P_ ((CFNumberRef));
-extern Lisp_Object cfdate_to_lisp P_ ((CFDateRef));
-extern Lisp_Object cfboolean_to_lisp P_ ((CFBooleanRef));
-extern Lisp_Object cfobject_desc_to_lisp P_ ((CFTypeRef));
-extern Lisp_Object cfproperty_list_to_lisp P_ ((CFPropertyListRef, int, int));
-extern void mac_wakeup_from_rne P_ ((void));
-#endif
-extern void xrm_merge_string_database P_ ((XrmDatabase, const char *));
-extern Lisp_Object xrm_get_resource P_ ((XrmDatabase, const char *,
- const char *));
-extern XrmDatabase xrm_get_preference_database P_ ((const char *));
-EXFUN (Fmac_get_preference, 4);
-
-/* Defined in mactoolbox.c. */
-
-extern void mac_alert_sound_play P_ ((void));
-extern OSStatus install_application_handler P_ ((void));
-extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
-extern Rect *mac_get_frame_bounds P_ ((struct frame *, Rect *));
-extern void mac_get_frame_mouse P_ ((struct frame *, Point *));
-extern void mac_convert_frame_point_to_global P_ ((struct frame *, int *,
- int *));
-#if TARGET_API_MAC_CARBON
-extern void mac_update_proxy_icon P_ ((struct frame *));
-#endif
-extern void mac_set_frame_window_background P_ ((struct frame *,
- unsigned long));
-extern void mac_update_begin P_ ((struct frame *));
-extern void mac_update_end P_ ((struct frame *));
-extern void mac_frame_up_to_date P_ ((struct frame *));
-extern void x_flush P_ ((struct frame *));
-extern void mac_create_frame_window P_ ((struct frame *, int));
-extern void mac_dispose_frame_window P_ ((struct frame *));
-#if USE_CG_DRAWING
-extern CGContextRef mac_begin_cg_clip P_ ((struct frame *, GC));
-extern void mac_end_cg_clip P_ ((struct frame *));
-#endif
-extern void mac_begin_clip P_ ((struct frame *, GC));
-extern void mac_end_clip P_ ((struct frame *, GC));
-extern void mac_create_scroll_bar P_ ((struct scroll_bar *, const Rect *,
- Boolean));
-extern void mac_dispose_scroll_bar P_ ((struct scroll_bar *));
-extern void mac_set_scroll_bar_bounds P_ ((struct scroll_bar *, const Rect *));
-extern void mac_redraw_scroll_bar P_ ((struct scroll_bar *));
-#ifdef USE_TOOLKIT_SCROLL_BARS
-extern void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
- int, int, int));
-#else
-extern void x_scroll_bar_set_handle P_ ((scroll_bar *, int, int, int));
-#endif
-#if USE_MAC_FONT_PANEL
-extern int mac_font_panel_visible_p P_ ((void));
-extern OSStatus mac_show_hide_font_panel P_ ((void));
-extern OSStatus mac_set_font_info_for_selection P_ ((struct frame *, int, int));
-#endif
-#ifdef MAC_OSX
-extern Boolean mac_run_loop_run_once P_ ((EventTimeout));
-#endif
-#if USE_MAC_TOOLBAR
-extern void update_frame_tool_bar P_ ((FRAME_PTR f));
-extern void free_frame_tool_bar P_ ((FRAME_PTR f));
-#endif
-#if TARGET_API_MAC_CARBON
-extern void mac_show_hourglass P_ ((struct frame *));
-extern void mac_hide_hourglass P_ ((struct frame *));
-extern void mac_reposition_hourglass P_ ((struct frame *));
-extern Lisp_Object mac_file_dialog P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object));
-#endif
-extern void x_activate_menubar P_ ((struct frame *));
-extern void free_frame_menubar P_ ((struct frame *));
-extern void mac_fill_menubar P_ ((widget_value *, int));
-extern void create_and_show_popup_menu P_ ((FRAME_PTR, widget_value *,
- int, int, int));
-#if TARGET_API_MAC_CARBON
-extern void create_and_show_dialog P_ ((FRAME_PTR, widget_value *));
-#else
-extern int mac_dialog P_ ((widget_value *));
-#endif
-extern OSStatus mac_get_selection_from_symbol P_ ((Lisp_Object, int,
- Selection *));
-extern int mac_valid_selection_target_p P_ ((Lisp_Object));
-extern OSStatus mac_clear_selection P_ ((Selection *));
-extern Lisp_Object mac_get_selection_ownership_info P_ ((Selection));
-extern int mac_valid_selection_value_p P_ ((Lisp_Object, Lisp_Object));
-extern OSStatus mac_put_selection_value P_ ((Selection, Lisp_Object,
- Lisp_Object));
-extern int mac_selection_has_target_p P_ ((Selection, Lisp_Object));
-extern Lisp_Object mac_get_selection_value P_ ((Selection, Lisp_Object));
-extern Lisp_Object mac_get_selection_target_list P_ ((Selection));
-#if TARGET_API_MAC_CARBON
-extern Lisp_Object mac_dnd_default_known_types P_ ((void));
-#endif
-
-/* arch-tag: 6b4ca125-5bef-476d-8ee8-31ed808b7e79
- (do not change this comment) */
diff --git a/src/mactoolbox.c b/src/mactoolbox.c
deleted file mode 100644
index c6e5f8bcf8a..00000000000
--- a/src/mactoolbox.c
+++ /dev/null
@@ -1,6615 +0,0 @@
-/* Functions for GUI implemented with (HI)Toolbox on the Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include <stdio.h>
-
-#include "lisp.h"
-#include "blockinput.h"
-
-#include "macterm.h"
-
-#if !TARGET_API_MAC_CARBON
-#include <Quickdraw.h>
-#include <ToolUtils.h>
-#include <Sound.h>
-#include <Events.h>
-#include <Script.h>
-#include <Resources.h>
-#include <Fonts.h>
-#include <TextUtils.h>
-#include <LowMem.h>
-#include <Controls.h>
-#include <Windows.h>
-#include <Displays.h>
-#if defined (__MRC__) || (__MSL__ >= 0x6000)
-#include <ControlDefinitions.h>
-#endif
-
-#if __profile__
-#include <profiler.h>
-#endif
-#endif /* not TARGET_API_MAC_CARBON */
-
-#include "charset.h"
-#include "coding.h"
-#include "frame.h"
-#include "dispextern.h"
-#include "fontset.h"
-#include "termhooks.h"
-#include "buffer.h"
-#include "window.h"
-#include "keyboard.h"
-
-#include <sys/param.h>
-
-#ifndef MAC_OSX
-#include <alloca.h>
-#endif
-
-
-/************************************************************************
- General
- ************************************************************************/
-
-/* The difference in pixels between the top left corner of the
- Emacs window (including possible window manager decorations)
- and FRAME_MAC_WINDOW (f). */
-#define FRAME_OUTER_TO_INNER_DIFF_X(f) ((f)->x_pixels_diff)
-#define FRAME_OUTER_TO_INNER_DIFF_Y(f) ((f)->y_pixels_diff)
-
-#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
-
-void
-mac_alert_sound_play ()
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- AlertSoundPlay ();
-#else
- SysBeep (1);
-#endif
-}
-
-
-/************************************************************************
- Application
- ************************************************************************/
-
-extern struct frame *mac_focus_frame P_ ((struct mac_display_info *));
-extern void do_keystroke P_ ((EventKind, unsigned char, UInt32, UInt32,
- unsigned long, struct input_event *));
-extern UInt32 mac_mapped_modifiers P_ ((UInt32, UInt32));
-#if TARGET_API_MAC_CARBON
-extern int mac_to_emacs_modifiers P_ ((UInt32, UInt32));
-#else
-extern int mac_to_emacs_modifiers P_ ((EventModifiers, EventModifiers));
-#endif
-
-#if TARGET_API_MAC_CARBON
-/* Points to the variable `inev' in the function XTread_socket. It is
- used for passing an input event to the function back from
- Carbon/Apple event handlers. */
-static struct input_event *read_socket_inev = NULL;
-
-extern const unsigned char keycode_to_xkeysym_table[];
-extern EMACS_INT extra_keyboard_modifiers;
-
-extern Lisp_Object Qhi_command;
-#if USE_MAC_TSM
-static TSMDocumentID tsm_document_id;
-extern Lisp_Object Qtext_input;
-extern Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
-extern Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
-extern Lisp_Object Qbefore_string;
-#endif
-
-static int mac_event_to_emacs_modifiers P_ ((EventRef));
-static OSStatus install_menu_target_item_handler P_ ((void));
-#ifdef MAC_OSX
-static OSStatus install_service_handler P_ ((void));
-#endif
-
-extern OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
- Lisp_Object,
- Lisp_Object,
- EventRef, UInt32,
- const EventParamName *,
- const EventParamType *));
-extern int fast_find_position P_ ((struct window *, int, int *, int *,
- int *, int *, Lisp_Object));
-extern struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
- int *, int *, int *, int *, int *));
-extern void mac_ax_selected_text_range P_ ((struct frame *, CFRange *));
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-extern unsigned int mac_ax_number_of_characters P_ ((struct frame *));
-#endif
-
-#if USE_MAC_TSM
-extern OSStatus mac_restore_keyboard_input_source P_ ((void));
-extern void mac_save_keyboard_input_source P_ ((void));
-
-static OSStatus
-mac_tsm_resume ()
-{
- OSStatus err;
-
- err = ActivateTSMDocument (tsm_document_id);
- if (err == noErr)
- err = mac_restore_keyboard_input_source ();
-
- return err;
-}
-
-static OSStatus
-mac_tsm_suspend ()
-{
- OSStatus err;
-
- mac_save_keyboard_input_source ();
- err = DeactivateTSMDocument (tsm_document_id);
-
- return err;
-}
-
-static void
-init_tsm ()
-{
-#ifdef MAC_OSX
- static InterfaceTypeList types = {kUnicodeDocument};
-#else
- static InterfaceTypeList types = {kTextService};
-#endif
-
- NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
- &tsm_document_id, 0);
-}
-#endif /* USE_MAC_TSM */
-
-static pascal OSStatus
-mac_handle_keyboard_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- UInt32 event_kind, key_code, modifiers;
- unsigned char char_code;
-
- event_kind = GetEventKind (event);
- switch (event_kind)
- {
- case kEventRawKeyDown:
- case kEventRawKeyRepeat:
- case kEventRawKeyUp:
- /* When using Carbon Events, we need to pass raw keyboard events
- to the TSM ourselves. If TSM handles it, it will pass back
- noErr, otherwise it will pass back "eventNotHandledErr" and
- we can process it normally. */
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- if (read_socket_inev == NULL)
- break;
-
-#if USE_MAC_TSM
- if (read_socket_inev->kind != NO_EVENT)
- {
- result = noErr;
- break;
- }
-#endif
-
- if (event_kind == kEventRawKeyUp)
- break;
-
- err = GetEventParameter (event, kEventParamKeyMacCharCodes,
- typeChar, NULL,
- sizeof (char), NULL, &char_code);
- if (err != noErr)
- break;
-
- err = GetEventParameter (event, kEventParamKeyCode,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &key_code);
- if (err != noErr)
- break;
-
- err = GetEventParameter (event, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
- if (err != noErr)
- break;
-
- do_keystroke ((event_kind == kEventRawKeyDown ? keyDown : autoKey),
- char_code, key_code, modifiers,
- ((unsigned long)
- (GetEventTime (event) / kEventDurationMillisecond)),
- read_socket_inev);
- result = noErr;
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-static pascal OSStatus
-mac_handle_command_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- HICommand command;
- static const EventParamName names[] =
- {kEventParamDirectObject, kEventParamKeyModifiers};
- static const EventParamType types[] =
- {typeHICommand, typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
- NULL, sizeof (HICommand), NULL, &command);
- if (err != noErr)
- return eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
- case kEventCommandProcess:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- err = GetEventParameter (event, kEventParamDirectObject,
- typeHICommand, NULL,
- sizeof (HICommand), NULL, &command);
-
- if (err != noErr || command.commandID == 0)
- break;
-
- /* A HI command event is mapped to an Apple event whose event
- class symbol is `hi-command' and event ID is its command
- ID. */
- err = mac_store_event_ref_as_apple_event (0, command.commandID,
- Qhi_command, Qnil,
- event, num_params,
- names, types);
- if (err == noErr)
- result = noErr;
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-static pascal OSStatus
-mac_handle_mouse_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
- case kEventMouseWheelMoved:
- {
- WindowRef wp;
- struct frame *f;
- EventMouseWheelAxis axis;
- SInt32 delta;
- Point point;
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr || read_socket_inev == NULL)
- break;
-
- f = mac_focus_frame (&one_mac_display_info);
-
- err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
- NULL, sizeof (WindowRef), NULL, &wp);
- if (err != noErr
- || wp != FRAME_MAC_WINDOW (f))
- break;
-
- err = GetEventParameter (event, kEventParamMouseWheelAxis,
- typeMouseWheelAxis, NULL,
- sizeof (EventMouseWheelAxis), NULL, &axis);
- if (err != noErr || axis != kEventMouseWheelAxisY)
- break;
-
- err = GetEventParameter (event, kEventParamMouseLocation,
- typeQDPoint, NULL, sizeof (Point),
- NULL, &point);
- if (err != noErr)
- break;
-
- point.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- point.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
- if (point.h < 0 || point.v < 0
- || EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
- f->tool_bar_window))
- break;
-
- err = GetEventParameter (event, kEventParamMouseWheelDelta,
- typeSInt32, NULL, sizeof (SInt32),
- NULL, &delta);
- if (err != noErr)
- break;
-
- read_socket_inev->kind = WHEEL_EVENT;
- read_socket_inev->code = 0;
- read_socket_inev->modifiers =
- (mac_event_to_emacs_modifiers (event)
- | ((delta < 0) ? down_modifier : up_modifier));
- XSETINT (read_socket_inev->x, point.h);
- XSETINT (read_socket_inev->y, point.v);
- XSETFRAME (read_socket_inev->frame_or_window, f);
-
- result = noErr;
- }
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-#if USE_MAC_TSM
-extern void mac_get_selected_range P_ ((struct window *, CFRange *));
-extern int mac_store_buffer_text_to_unicode_chars P_ ((struct buffer *,
- int, int, UniChar *));
-
-static pascal OSStatus
-mac_handle_text_input_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result;
- Lisp_Object id_key = Qnil;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static UInt32 seqno_uaia = 0;
- static const EventParamName names_uaia[] =
- {kEventParamTextInputSendComponentInstance,
- kEventParamTextInputSendRefCon,
- kEventParamTextInputSendSLRec,
- kEventParamTextInputSendFixLen,
- kEventParamTextInputSendText,
- kEventParamTextInputSendUpdateRng,
- kEventParamTextInputSendHiliteRng,
- kEventParamTextInputSendClauseRng,
- kEventParamTextInputSendPinRng,
- kEventParamTextInputSendTextServiceEncoding,
- kEventParamTextInputSendTextServiceMacEncoding,
- EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
- static const EventParamType types_uaia[] =
- {typeComponentInstance,
- typeLongInteger,
- typeIntlWritingCode,
- typeLongInteger,
-#ifdef MAC_OSX
- typeUnicodeText,
-#else
- typeChar,
-#endif
- typeTextRangeArray,
- typeTextRangeArray,
- typeOffsetArray,
- typeTextRange,
- typeUInt32,
- typeUInt32,
- typeUInt32};
- static const EventParamName names_ufke[] =
- {kEventParamTextInputSendComponentInstance,
- kEventParamTextInputSendRefCon,
- kEventParamTextInputSendSLRec,
- kEventParamTextInputSendText};
- static const EventParamType types_ufke[] =
- {typeComponentInstance,
- typeLongInteger,
- typeIntlWritingCode,
- typeUnicodeText};
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventTextInputUpdateActiveInputArea:
- id_key = Qupdate_active_input_area;
- num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
- names = names_uaia;
- types = types_uaia;
- SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
- typeUInt32, sizeof (UInt32), &seqno_uaia);
- seqno_uaia++;
- result = noErr;
- break;
-
- case kEventTextInputUnicodeForKeyEvent:
- {
- EventRef kbd_event;
- UInt32 actual_size, modifiers, key_code;
-
- err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
- typeEventRef, NULL, sizeof (EventRef), NULL,
- &kbd_event);
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr && mac_mapped_modifiers (modifiers, key_code))
- /* There're mapped modifier keys. Process it in
- do_keystroke. */
- break;
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
- typeUnicodeText, NULL, 0, &actual_size,
- NULL);
- if (err == noErr && actual_size == sizeof (UniChar))
- {
- UniChar code;
-
- err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
- typeUnicodeText, NULL,
- sizeof (UniChar), NULL, &code);
- if (err == noErr && code < 0x80)
- {
- /* ASCII character. Process it in do_keystroke. */
- if (read_socket_inev && code >= 0x20 && code <= 0x7e
- && !(key_code <= 0x7f
- && keycode_to_xkeysym_table [key_code]))
- {
- struct frame *f = mac_focus_frame (&one_mac_display_info);
-
- read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
- read_socket_inev->code = code;
- read_socket_inev->modifiers =
- mac_to_emacs_modifiers (modifiers, 0);
- read_socket_inev->modifiers |=
- (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (read_socket_inev->frame_or_window, f);
- }
- break;
- }
- }
- if (err == noErr)
- {
- /* Non-ASCII keystrokes without mapped modifiers are
- processed at the Lisp level. */
- id_key = Qunicode_for_key_event;
- num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
- names = names_ufke;
- types = types_ufke;
- result = noErr;
- }
- }
- break;
-
- case kEventTextInputOffsetToPos:
- {
- long byte_offset;
- struct frame *f;
- struct window *w;
- Point p;
-
- err = GetEventParameter (event, kEventParamTextInputSendTextOffset,
- typeLongInteger, NULL, sizeof (long), NULL,
- &byte_offset);
- if (err != noErr)
- break;
-
- if (STRINGP (Vmac_ts_active_input_buf)
- && SBYTES (Vmac_ts_active_input_buf) != 0)
- {
- if (!OVERLAYP (Vmac_ts_active_input_overlay))
- break;
-
- /* Strictly speaking, this is not always correct because
- previous events may change some states about display. */
- if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
- {
- /* Active input area is displayed around the current point. */
- f = SELECTED_FRAME ();
- w = XWINDOW (f->selected_window);
- }
- else if (WINDOWP (echo_area_window))
- {
- /* Active input area is displayed in the echo area. */
- w = XWINDOW (echo_area_window);
- f = WINDOW_XFRAME (w);
- }
- else
- break;
-
- p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
- + WINDOW_LEFT_FRINGE_WIDTH (w)
- + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
- p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
- + FONT_BASE (FRAME_FONT (f))
- + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
- }
- else
- {
-#ifndef MAC_OSX
- break;
-#else /* MAC_OSX */
- CFRange sel_range;
- int charpos;
- int hpos, vpos, x, y;
- struct glyph_row *row;
- struct glyph *glyph;
- struct face *face;
-
- f = mac_focus_frame (&one_mac_display_info);
- w = XWINDOW (f->selected_window);
- mac_get_selected_range (w, &sel_range);
- charpos = (BUF_BEGV (XBUFFER (w->buffer)) + sel_range.location
- + byte_offset / (long) sizeof (UniChar));
-
- if (!fast_find_position (w, charpos, &hpos, &vpos, &x, &y, Qnil))
- {
- result = errOffsetInvalid;
- break;
- }
-
- row = MATRIX_ROW (w->current_matrix, vpos);
- glyph = row->glyphs[TEXT_AREA] + hpos;
- if (glyph->type != CHAR_GLYPH || glyph->glyph_not_available_p)
- break;
-
- p.h = (WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x)
- + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
- p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
- + row->visible_height
- + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
-
- face = FACE_FROM_ID (f, glyph->face_id);
- if (face && face->font)
- {
- XFontStruct *font = face->font;
- Fixed point_size = Long2Fix (font->mac_fontsize);
- short height = row->visible_height;
- short ascent = row->ascent;
-
- SetEventParameter (event,
- kEventParamTextInputReplyPointSize,
- typeFixed, sizeof (Fixed), &point_size);
- SetEventParameter (event,
- kEventParamTextInputReplyLineHeight,
- typeShortInteger, sizeof (short), &height);
- SetEventParameter (event,
- kEventParamTextInputReplyLineAscent,
- typeShortInteger, sizeof (short), &ascent);
- if (font->mac_fontnum != -1)
- {
- OSStatus err1;
- FMFont fm_font;
- FMFontStyle style;
-
- err1 = FMGetFontFromFontFamilyInstance (font->mac_fontnum,
- font->mac_fontface,
- &fm_font, &style);
- if (err1 == noErr)
- SetEventParameter (event, kEventParamTextInputReplyFMFont,
- typeUInt32, sizeof (UInt32), &fm_font);
- else
- {
- long qd_font = font->mac_fontnum;
-
- SetEventParameter (event, kEventParamTextInputReplyFont,
- typeLongInteger, sizeof (long),
- &qd_font);
- }
- }
- else if (font->mac_style)
- {
- OSStatus err1;
- ATSUFontID font_id;
-
- err1 = ATSUGetAttribute (font->mac_style, kATSUFontTag,
- sizeof (ATSUFontID), &font_id,
- NULL);
- if (err1 == noErr)
- SetEventParameter (event, kEventParamTextInputReplyFMFont,
- typeUInt32, sizeof (UInt32), &font_id);
- }
- else
- abort ();
- }
-#endif /* MAC_OSX */
- }
-
- err = SetEventParameter (event, kEventParamTextInputReplyPoint,
- typeQDPoint, sizeof (Point), &p);
- if (err == noErr)
- result = noErr;
- }
- break;
-
-#ifdef MAC_OSX
- case kEventTextInputPosToOffset:
- {
- Point point;
- Boolean leading_edge_p = true;
- struct frame *f;
- int x, y;
- Lisp_Object window;
- enum window_part part;
- long region_class = kTSMOutsideOfBody, byte_offset = 0;
-
- err = GetEventParameter (event, kEventParamTextInputSendCurrentPoint,
- typeQDPoint, NULL, sizeof (Point), NULL,
- &point);
- if (err != noErr)
- break;
-
- GetEventParameter (event, kEventParamTextInputReplyLeadingEdge,
- typeBoolean, NULL, sizeof (Boolean), NULL,
- &leading_edge_p);
-
- f = mac_focus_frame (&one_mac_display_info);
- x = point.h - (f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
- y = point.v - (f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
- window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
- if (WINDOWP (window) && EQ (window, f->selected_window))
- {
- struct window *w;
- struct buffer *b;
-
- /* Convert to window-relative pixel coordinates. */
- w = XWINDOW (window);
- frame_to_window_pixel_xy (w, &x, &y);
-
- /* Are we in a window whose display is up to date?
- And verify the buffer's text has not changed. */
- b = XBUFFER (w->buffer);
- if (part == ON_TEXT
- && EQ (w->window_end_valid, w->buffer)
- && XINT (w->last_modified) == BUF_MODIFF (b)
- && XINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
- {
- int hpos, vpos, area;
- struct glyph *glyph;
-
- /* Find the glyph under X/Y. */
- glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, 0, &area);
-
- if (glyph != NULL && area == TEXT_AREA)
- {
- byte_offset = ((glyph->charpos - BUF_BEGV (b))
- * sizeof (UniChar));
- region_class = kTSMInsideOfBody;
- }
- }
- }
-
- err = SetEventParameter (event, kEventParamTextInputReplyRegionClass,
- typeLongInteger, sizeof (long),
- &region_class);
- if (err == noErr)
- err = SetEventParameter (event, kEventParamTextInputReplyTextOffset,
- typeLongInteger, sizeof (long),
- &byte_offset);
- if (err == noErr)
- result = noErr;
- }
- break;
-
- case kEventTextInputGetSelectedText:
- {
- struct frame *f = mac_focus_frame (&one_mac_display_info);
- struct window *w = XWINDOW (f->selected_window);
- struct buffer *b = XBUFFER (w->buffer);
- CFRange sel_range;
- int start, end;
- UniChar *characters, c;
-
- if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
- /* Don't try to get buffer contents as the gap might be
- being altered. */
- break;
-
- mac_get_selected_range (w, &sel_range);
- if (sel_range.length == 0)
- {
- Boolean leading_edge_p;
-
- err = GetEventParameter (event,
- kEventParamTextInputReplyLeadingEdge,
- typeBoolean, NULL, sizeof (Boolean), NULL,
- &leading_edge_p);
- if (err != noErr)
- break;
-
- start = BUF_BEGV (b) + sel_range.location;
- if (!leading_edge_p)
- start--;
- end = start + 1;
- characters = &c;
-
- if (start < BUF_BEGV (b) || end > BUF_ZV (b))
- break;
- }
- else
- {
- start = BUF_BEGV (b) + sel_range.location;
- end = start + sel_range.length;
- characters = xmalloc (sel_range.length * sizeof (UniChar));
- }
-
- if (mac_store_buffer_text_to_unicode_chars (b, start, end, characters))
- err = SetEventParameter (event, kEventParamTextInputReplyText,
- typeUnicodeText,
- sel_range.length * sizeof (UniChar),
- characters);
- if (characters != &c)
- xfree (characters);
-
- if (err == noErr)
- result = noErr;
- }
- break;
-#endif /* MAC_OSX */
-
- default:
- abort ();
- }
-
- if (!NILP (id_key))
- err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
- event, num_params,
- names, types);
- return result;
-}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-static pascal OSStatus
-mac_handle_document_access_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result;
- struct frame *f = mac_focus_frame (&one_mac_display_info);
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventTSMDocumentAccessGetLength:
- {
- CFIndex count = mac_ax_number_of_characters (f);
-
- err = SetEventParameter (event, kEventParamTSMDocAccessCharacterCount,
- typeCFIndex, sizeof (CFIndex), &count);
- if (err == noErr)
- result = noErr;
- }
- break;
-
- case kEventTSMDocumentAccessGetSelectedRange:
- {
- CFRange sel_range;
-
- mac_ax_selected_text_range (f, &sel_range);
- err = SetEventParameter (event,
- kEventParamTSMDocAccessReplyCharacterRange,
- typeCFRange, sizeof (CFRange), &sel_range);
- if (err == noErr)
- result = noErr;
- }
- break;
-
- case kEventTSMDocumentAccessGetCharacters:
- {
- struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
- CFRange range;
- Ptr characters;
- int start, end;
-
- if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
- /* Don't try to get buffer contents as the gap might be
- being altered. */
- break;
-
- err = GetEventParameter (event,
- kEventParamTSMDocAccessSendCharacterRange,
- typeCFRange, NULL, sizeof (CFRange), NULL,
- &range);
- if (err == noErr)
- err = GetEventParameter (event,
- kEventParamTSMDocAccessSendCharactersPtr,
- typePtr, NULL, sizeof (Ptr), NULL,
- &characters);
- if (err != noErr)
- break;
-
- start = BUF_BEGV (b) + range.location;
- end = start + range.length;
- if (mac_store_buffer_text_to_unicode_chars (b, start, end,
- (UniChar *) characters))
- result = noErr;
- }
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-#endif
-#endif
-
-OSStatus
-install_application_handler ()
-{
- OSStatus err = noErr;
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassKeyboard, kEventRawKeyDown},
- {kEventClassKeyboard, kEventRawKeyRepeat},
- {kEventClassKeyboard, kEventRawKeyUp}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_keyboard_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_command_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassMouse, kEventMouseWheelMoved}};
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_mouse_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
-#if USE_MAC_TSM
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
- {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
- {kEventClassTextInput, kEventTextInputOffsetToPos},
-#ifdef MAC_OSX
- {kEventClassTextInput, kEventTextInputPosToOffset},
- {kEventClassTextInput, kEventTextInputGetSelectedText}
-#endif
- };
-
- err = InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_text_input_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength},
- {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange},
- {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters}};
-
- err = InstallApplicationEventHandler (mac_handle_document_access_event,
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-#endif
-#endif
-
- if (err == noErr)
- err = install_menu_target_item_handler ();
-
-#ifdef MAC_OSX
- if (err == noErr)
- err = install_service_handler ();
-#endif
-
- return err;
-}
-#endif /* TARGET_API_MAC_CARBON */
-
-
-/************************************************************************
- Windows
- ************************************************************************/
-
-#define DEFAULT_NUM_COLS 80
-
-#define MIN_DOC_SIZE 64
-#define MAX_DOC_SIZE 32767
-
-/* Drag and Drop */
-static OSErr install_drag_handler P_ ((WindowRef));
-static void remove_drag_handler P_ ((WindowRef));
-
-#if USE_CG_DRAWING
-static void mac_prepare_for_quickdraw P_ ((struct frame *));
-#endif
-
-extern void mac_handle_visibility_change P_ ((struct frame *));
-extern void mac_handle_origin_change P_ ((struct frame *));
-extern void mac_handle_size_change P_ ((struct frame *, int, int));
-
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
-extern Lisp_Object Qwindow;
-extern Lisp_Object Qtoolbar_switch_mode;
-#endif
-#endif
-
-static void
-do_window_update (WindowRef win)
-{
- struct frame *f = mac_window_to_frame (win);
-
- BeginUpdate (win);
-
- /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
- below. */
- if (win != tip_window)
- {
- if (f->async_visible == 0)
- {
- /* Update events may occur when a frame gets iconified. */
-#if 0
- f->async_visible = 1;
- f->async_iconified = 0;
- SET_FRAME_GARBAGED (f);
-#endif
- }
- else
- {
- Rect r;
-#if TARGET_API_MAC_CARBON
- RgnHandle region = NewRgn ();
-
- GetPortVisibleRegion (GetWindowPort (win), region);
- GetRegionBounds (region, &r);
- expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- UpdateControls (win, region);
- DisposeRgn (region);
-#else
- r = (*win->visRgn)->rgnBBox;
- expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
- UpdateControls (win, win->visRgn);
-#endif
- }
- }
-
- EndUpdate (win);
-}
-
-static int
-is_emacs_window (WindowRef win)
-{
- Lisp_Object tail, frame;
-
- if (!win)
- return 0;
-
- FOR_EACH_FRAME (tail, frame)
- if (FRAME_MAC_P (XFRAME (frame)))
- if (FRAME_MAC_WINDOW (XFRAME (frame)) == win)
- return 1;
-
- return 0;
-}
-
-/* Handle drags in size box. Based on code contributed by Ben
- Mesander and IM - Window Manager A. */
-
-static void
-do_grow_window (w, e)
- WindowRef w;
- const EventRecord *e;
-{
- Rect limit_rect;
- int rows, columns, width, height;
- struct frame *f = mac_window_to_frame (w);
- XSizeHints *size_hints = FRAME_SIZE_HINTS (f);
- int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE;
-#if TARGET_API_MAC_CARBON
- Rect new_rect;
-#else
- long grow_size;
-#endif
-
- if (size_hints->flags & PMinSize)
- {
- min_width = size_hints->min_width;
- min_height = size_hints->min_height;
- }
- SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE);
-
-#if TARGET_API_MAC_CARBON
- if (!ResizeWindow (w, e->where, &limit_rect, &new_rect))
- return;
- height = new_rect.bottom - new_rect.top;
- width = new_rect.right - new_rect.left;
-#else
- grow_size = GrowWindow (w, e->where, &limit_rect);
- /* see if it really changed size */
- if (grow_size == 0)
- return;
- height = HiWord (grow_size);
- width = LoWord (grow_size);
-#endif
-
- if (width != FRAME_PIXEL_WIDTH (f)
- || height != FRAME_PIXEL_HEIGHT (f))
- {
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
-
- x_set_window_size (f, 0, columns, rows);
- }
-}
-
-#if TARGET_API_MAC_CARBON
-static Point
-mac_get_ideal_size (f)
- struct frame *f;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowRef w = FRAME_MAC_WINDOW (f);
- Point ideal_size;
- Rect standard_rect;
- int height, width, columns, rows;
-
- ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
- ideal_size.v = dpyinfo->height;
- IsWindowInStandardState (w, &ideal_size, &standard_rect);
- /* Adjust the standard size according to character boundaries. */
- width = standard_rect.right - standard_rect.left;
- height = standard_rect.bottom - standard_rect.top;
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
- ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
- ideal_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-
- return ideal_size;
-}
-
-static pascal OSStatus
-mac_handle_window_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- WindowRef wp;
- OSStatus err, result = eventNotHandledErr;
- struct frame *f;
- UInt32 attributes;
- XSizeHints *size_hints;
-
- err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
- NULL, sizeof (WindowRef), NULL, &wp);
- if (err != noErr)
- return eventNotHandledErr;
-
- f = mac_window_to_frame (wp);
- switch (GetEventKind (event))
- {
- /* -- window refresh events -- */
-
- case kEventWindowUpdate:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- do_window_update (wp);
- result = noErr;
- break;
-
- /* -- window state change events -- */
-
- case kEventWindowShowing:
- size_hints = FRAME_SIZE_HINTS (f);
- if (!(size_hints->flags & (USPosition | PPosition)))
- {
- struct frame *sf = SELECTED_FRAME ();
-
- if (!(FRAME_MAC_P (sf) && sf->async_visible))
- RepositionWindow (wp, NULL, kWindowCenterOnMainScreen);
- else
- {
- RepositionWindow (wp, FRAME_MAC_WINDOW (sf),
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kWindowCascadeStartAtParentWindowScreen
-#else
- kWindowCascadeOnParentWindowScreen
-#endif
- );
-#if USE_MAC_TOOLBAR
- /* This is a workaround. RepositionWindow fails to put
- a window at the cascading position when its parent
- window has a Carbon HIToolbar. */
- if ((f->left_pos == sf->left_pos
- && f->top_pos == sf->top_pos)
- || (f->left_pos == sf->left_pos + 10 * 2
- && f->top_pos == sf->top_pos + 32 * 2))
- MoveWindowStructure (wp, sf->left_pos + 10, sf->top_pos + 32);
-#endif
- }
- result = noErr;
- }
- break;
-
- case kEventWindowHiding:
- /* Before unmapping the window, update the WM_SIZE_HINTS
- property to claim that the current position of the window is
- user-specified, rather than program-specified, so that when
- the window is mapped again, it will be placed at the same
- location, without forcing the user to position it by hand
- again (they have already done that once for this window.) */
- x_wm_set_size_hint (f, (long) 0, 1);
- result = noErr;
- break;
-
- case kEventWindowShown:
- case kEventWindowHidden:
- case kEventWindowCollapsed:
- case kEventWindowExpanded:
- mac_handle_visibility_change (f);
- result = noErr;
- break;
-
- case kEventWindowBoundsChanging:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
- NULL, sizeof (UInt32), NULL, &attributes);
- if (err != noErr)
- break;
-
- size_hints = FRAME_SIZE_HINTS (f);
- if ((attributes & kWindowBoundsChangeUserResize)
- && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
- == (PResizeInc | PBaseSize | PMinSize)))
- {
- Rect bounds;
- int width, height;
-
- err = GetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, NULL, sizeof (Rect),
- NULL, &bounds);
- if (err != noErr)
- break;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
-
- if (width < size_hints->min_width)
- width = size_hints->min_width;
- else
- width = size_hints->base_width
- + (int) ((width - size_hints->base_width)
- / (float) size_hints->width_inc + .5)
- * size_hints->width_inc;
-
- if (height < size_hints->min_height)
- height = size_hints->min_height;
- else
- height = size_hints->base_height
- + (int) ((height - size_hints->base_height)
- / (float) size_hints->height_inc + .5)
- * size_hints->height_inc;
-
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
- SetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, sizeof (Rect), &bounds);
- result = noErr;
- }
- break;
-
- case kEventWindowBoundsChanged:
- err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
- NULL, sizeof (UInt32), NULL, &attributes);
- if (err != noErr)
- break;
-
- if (attributes & kWindowBoundsChangeSizeChanged)
- {
- Rect bounds;
-
- err = GetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, NULL, sizeof (Rect),
- NULL, &bounds);
- if (err == noErr)
- {
- int width, height;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
- mac_handle_size_change (f, width, height);
- mac_wakeup_from_rne ();
- }
- }
-
- if (attributes & kWindowBoundsChangeOriginChanged)
- mac_handle_origin_change (f);
-
- result = noErr;
- break;
-
- /* -- window action events -- */
-
- case kEventWindowClose:
- {
- struct input_event buf;
-
- EVENT_INIT (buf);
- buf.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (buf.frame_or_window, f);
- buf.arg = Qnil;
- kbd_buffer_store_event (&buf);
- }
- result = noErr;
- break;
-
- case kEventWindowGetIdealSize:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- {
- Point ideal_size = mac_get_ideal_size (f);
-
- err = SetEventParameter (event, kEventParamDimensions,
- typeQDPoint, sizeof (Point), &ideal_size);
- if (err == noErr)
- result = noErr;
- }
- break;
-
-#ifdef MAC_OSX
- case kEventWindowToolbarSwitchMode:
- {
- static const EventParamName names[] = {kEventParamDirectObject,
- kEventParamWindowMouseLocation,
- kEventParamKeyModifiers,
- kEventParamMouseButton,
- kEventParamClickCount,
- kEventParamMouseChord};
- static const EventParamType types[] = {typeWindowRef,
- typeQDPoint,
- typeUInt32,
- typeMouseButton,
- typeUInt32,
- typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- err = mac_store_event_ref_as_apple_event (0, 0,
- Qwindow,
- Qtoolbar_switch_mode,
- event, num_params,
- names, types);
- }
- if (err == noErr)
- result = noErr;
- break;
-#endif
-
-#if USE_MAC_TSM
- /* -- window focus events -- */
-
- case kEventWindowFocusAcquired:
- err = mac_tsm_resume ();
- if (err == noErr)
- result = noErr;
- break;
-
- case kEventWindowFocusRelinquish:
- err = mac_tsm_suspend ();
- if (err == noErr)
- result = noErr;
- break;
-#endif
-
- default:
- abort ();
- }
-
- return result;
-}
-#endif
-
-/* Handle clicks in zoom box. Calculation of "standard state" based
- on code in IM - Window Manager A and code contributed by Ben
- Mesander. The standard state of an Emacs window is 80-characters
- wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
-
-static void
-do_zoom_window (WindowRef w, int zoom_in_or_out)
-{
- Rect zoom_rect, port_rect;
- int width, height;
- struct frame *f = mac_window_to_frame (w);
-#if TARGET_API_MAC_CARBON
- Point ideal_size = mac_get_ideal_size (f);
-
- GetWindowBounds (w, kWindowContentRgn, &port_rect);
- if (IsWindowInStandardState (w, &ideal_size, &zoom_rect)
- && port_rect.left == zoom_rect.left
- && port_rect.top == zoom_rect.top)
- zoom_in_or_out = inZoomIn;
- else
- zoom_in_or_out = inZoomOut;
-
-#ifdef MAC_OS8
- mac_clear_area (f, 0, 0, port_rect.right - port_rect.left,
- port_rect.bottom - port_rect.top);
-#endif
- ZoomWindowIdeal (w, zoom_in_or_out, &ideal_size);
-#else /* not TARGET_API_MAC_CARBON */
- GrafPtr save_port;
- Point top_left;
- int w_title_height, rows;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- GetPort (&save_port);
-
- SetPortWindowPort (w);
-
- /* Clear window to avoid flicker. */
- EraseRect (&(w->portRect));
- if (zoom_in_or_out == inZoomOut)
- {
- SetPt (&top_left, w->portRect.left, w->portRect.top);
- LocalToGlobal (&top_left);
-
- /* calculate height of window's title bar */
- w_title_height = top_left.v - 1
- - (**((WindowPeek) w)->strucRgn).rgnBBox.top + GetMBarHeight ();
-
- /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
- zoom_rect = qd.screenBits.bounds;
- zoom_rect.top += w_title_height;
- InsetRect (&zoom_rect, 8, 4); /* not too tight */
-
- zoom_rect.right = zoom_rect.left
- + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-
- /* Adjust the standard size according to character boundaries. */
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
- zoom_rect.bottom =
- zoom_rect.top + FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-
- (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
- = zoom_rect;
- }
-
- ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo));
-
- SetPort (save_port);
-#endif /* not TARGET_API_MAC_CARBON */
-
-#if !TARGET_API_MAC_CARBON
- /* retrieve window size and update application values */
- port_rect = w->portRect;
- height = port_rect.bottom - port_rect.top;
- width = port_rect.right - port_rect.left;
-
- mac_handle_size_change (f, width, height);
- mac_handle_origin_change (f);
-#endif
-}
-
-static OSStatus
-install_window_handler (window)
- WindowRef window;
-{
- OSStatus err = noErr;
-
-#if TARGET_API_MAC_CARBON
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {
- /* -- window refresh events -- */
- {kEventClassWindow, kEventWindowUpdate},
- /* -- window state change events -- */
- {kEventClassWindow, kEventWindowShowing},
- {kEventClassWindow, kEventWindowHiding},
- {kEventClassWindow, kEventWindowShown},
- {kEventClassWindow, kEventWindowHidden},
- {kEventClassWindow, kEventWindowCollapsed},
- {kEventClassWindow, kEventWindowExpanded},
- {kEventClassWindow, kEventWindowBoundsChanging},
- {kEventClassWindow, kEventWindowBoundsChanged},
- /* -- window action events -- */
- {kEventClassWindow, kEventWindowClose},
- {kEventClassWindow, kEventWindowGetIdealSize},
-#ifdef MAC_OSX
- {kEventClassWindow, kEventWindowToolbarSwitchMode},
-#endif
-#if USE_MAC_TSM
- /* -- window focus events -- */
- {kEventClassWindow, kEventWindowFocusAcquired},
- {kEventClassWindow, kEventWindowFocusRelinquish},
-#endif
- };
- static EventHandlerUPP handle_window_eventUPP = NULL;
-
- if (handle_window_eventUPP == NULL)
- handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
-
- err = InstallWindowEventHandler (window, handle_window_eventUPP,
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- }
-#endif
-
- if (err == noErr)
- err = install_drag_handler (window);
-
- return err;
-}
-
-static void
-remove_window_handler (window)
- WindowRef window;
-{
- remove_drag_handler (window);
-}
-
-void
-mac_get_window_bounds (f, inner, outer)
- struct frame *f;
- Rect *inner, *outer;
-{
-#if TARGET_API_MAC_CARBON
- GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowContentRgn, inner);
- GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
-#else /* not TARGET_API_MAC_CARBON */
- RgnHandle region = NewRgn ();
-
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
- *inner = (*region)->rgnBBox;
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
- *outer = (*region)->rgnBBox;
- DisposeRgn (region);
-#endif /* not TARGET_API_MAC_CARBON */
-}
-
-Rect *
-mac_get_frame_bounds (f, r)
- struct frame *f;
- Rect *r;
-{
-#if TARGET_API_MAC_CARBON
- return GetWindowPortBounds (FRAME_MAC_WINDOW (f), r);
-#else
- *r = FRAME_MAC_WINDOW (f)->portRect;
-
- return r;
-#endif
-}
-
-void
-mac_get_frame_mouse (f, point)
- struct frame *f;
- Point *point;
-{
-#if TARGET_API_MAC_CARBON
- GetGlobalMouse (point);
- point->h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- point->v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-#else
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- GetMouse (point);
-#endif
-}
-
-void
-mac_convert_frame_point_to_global (f, x, y)
- struct frame *f;
- int *x, *y;
-{
- *x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- *y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-}
-
-#if TARGET_API_MAC_CARBON
-void
-mac_update_proxy_icon (f)
- struct frame *f;
-{
- OSStatus err;
- Lisp_Object file_name =
- XBUFFER (XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer)->filename;
- Window w = FRAME_MAC_WINDOW (f);
- AliasHandle alias = NULL;
-
- err = GetWindowProxyAlias (w, &alias);
- if (err == errWindowDoesNotHaveProxy && !STRINGP (file_name))
- return;
-
- if (STRINGP (file_name))
- {
- AEDesc desc;
-#ifdef MAC_OSX
- FSRef fref, fref_proxy;
-#else
- FSSpec fss, fss_proxy;
-#endif
- Boolean changed;
- Lisp_Object encoded_file_name = ENCODE_FILE (file_name);
-
-#ifdef MAC_OSX
- err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name),
- SBYTES (encoded_file_name), typeFSRef, &desc);
-#else
- SetPortWindowPort (w);
- err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name),
- SBYTES (encoded_file_name), typeFSS, &desc);
-#endif
- if (err == noErr)
- {
-#ifdef MAC_OSX
- err = AEGetDescData (&desc, &fref, sizeof (FSRef));
-#else
- err = AEGetDescData (&desc, &fss, sizeof (FSSpec));
-#endif
- AEDisposeDesc (&desc);
- }
- if (err == noErr)
- {
- if (alias)
- {
- /* (FS)ResolveAlias never sets `changed' to true if
- `alias' is minimal. */
-#ifdef MAC_OSX
- err = FSResolveAlias (NULL, alias, &fref_proxy, &changed);
- if (err == noErr)
- err = FSCompareFSRefs (&fref, &fref_proxy);
-#else
- err = ResolveAlias (NULL, alias, &fss_proxy, &changed);
- if (err == noErr)
- err = !(fss.vRefNum == fss_proxy.vRefNum
- && fss.parID == fss_proxy.parID
- && EqualString (fss.name, fss_proxy.name,
- false, true));
-#endif
- }
- if (err != noErr || alias == NULL)
- {
- if (alias)
- DisposeHandle ((Handle) alias);
-#ifdef MAC_OSX
- err = FSNewAliasMinimal (&fref, &alias);
-#else
- err = NewAliasMinimal (&fss, &alias);
-#endif
- changed = true;
- }
- }
- if (err == noErr)
- if (changed)
- err = SetWindowProxyAlias (w, alias);
- }
-
- if (alias)
- DisposeHandle ((Handle) alias);
-
- if (err != noErr || !STRINGP (file_name))
- RemoveWindowProxy (w);
-}
-#endif
-
-/* Mac replacement for XSetWindowBackground. */
-
-void
-mac_set_frame_window_background (f, color)
- struct frame *f;
- unsigned long color;
-{
- WindowRef w = FRAME_MAC_WINDOW (f);
-#if !TARGET_API_MAC_CARBON
- AuxWinHandle aw_handle;
- CTabHandle ctab_handle;
- ColorSpecPtr ct_table;
- short ct_size;
-#endif
- RGBColor bg_color;
-
- bg_color.red = RED16_FROM_ULONG (color);
- bg_color.green = GREEN16_FROM_ULONG (color);
- bg_color.blue = BLUE16_FROM_ULONG (color);
-
-#if TARGET_API_MAC_CARBON
- SetWindowContentColor (w, &bg_color);
-#else
- if (GetAuxWin (w, &aw_handle))
- {
- ctab_handle = (*aw_handle)->awCTable;
- HandToHand ((Handle *) &ctab_handle);
- ct_table = (*ctab_handle)->ctTable;
- ct_size = (*ctab_handle)->ctSize;
- while (ct_size > -1)
- {
- if (ct_table->value == 0)
- {
- ct_table->rgb = bg_color;
- CTabChanged (ctab_handle);
- SetWinColor (w, (WCTabHandle) ctab_handle);
- }
- ct_size--;
- }
- }
-#endif
-}
-
-/* Flush display of frame F, or of all frames if F is null. */
-
-void
-x_flush (f)
- struct frame *f;
-{
-#if TARGET_API_MAC_CARBON
- BLOCK_INPUT;
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- if (f)
- QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL);
- else
- QDFlushPortBuffer (GetQDGlobalsThePort (), NULL);
- UNBLOCK_INPUT;
-#endif
-}
-
-#if USE_CG_DRAWING
-void
-mac_flush_display_optional (f)
- struct frame *f;
-{
- BLOCK_INPUT;
- mac_prepare_for_quickdraw (f);
- UNBLOCK_INPUT;
-}
-#endif
-
-void
-mac_update_begin (f)
- struct frame *f;
-{
-#if TARGET_API_MAC_CARBON
- /* During update of a frame, availability of input events is
- periodically checked with ReceiveNextEvent if
- redisplay-dont-pause is nil. That normally flushes window buffer
- changes for every check, and thus screen update looks waving even
- if no input is available. So we disable screen updates during
- update of a frame. */
- DisableScreenUpdates ();
-#endif
-}
-
-void
-mac_update_end (f)
- struct frame *f;
-{
-#if TARGET_API_MAC_CARBON
- EnableScreenUpdates ();
-#endif
-}
-
-void
-mac_frame_up_to_date (f)
- struct frame *f;
-{
- /* Nothing to do. */
-}
-
-void
-mac_create_frame_window (f, tooltip_p)
- struct frame *f;
- int tooltip_p;
-{
- Rect r;
-#if TARGET_API_MAC_CARBON
- WindowClass window_class;
- WindowAttributes attributes;
-#else
- short proc_id;
- WindowRef behind;
- Boolean go_away_flag;
-#endif
-
- if (!tooltip_p)
- {
- SetRect (&r, f->left_pos, f->top_pos,
- f->left_pos + FRAME_PIXEL_WIDTH (f),
- f->top_pos + FRAME_PIXEL_HEIGHT (f));
-#if TARGET_API_MAC_CARBON
- window_class = kDocumentWindowClass;
- attributes = (kWindowStandardDocumentAttributes
-#ifdef MAC_OSX
- | kWindowToolbarButtonAttribute
-#endif
- );
-#else
- proc_id = zoomDocProc;
- behind = (WindowRef) -1;
- go_away_flag = true;
-#endif
- }
- else
- {
- SetRect (&r, 0, 0, 1, 1);
-#if TARGET_API_MAC_CARBON
- window_class = kHelpWindowClass;
- attributes = (kWindowNoUpdatesAttribute
- | kWindowNoActivatesAttribute
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- | kWindowIgnoreClicksAttribute
-#endif
- );
-#else
- proc_id = plainDBox;
- behind = NULL;
- go_away_flag = false;
-#endif
- }
-
-#if TARGET_API_MAC_CARBON
- CreateNewWindow (window_class, attributes, &r, &FRAME_MAC_WINDOW (f));
- if (FRAME_MAC_WINDOW (f))
- {
- SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
- if (!tooltip_p)
- if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
- {
- DisposeWindow (FRAME_MAC_WINDOW (f));
- FRAME_MAC_WINDOW (f) = NULL;
- }
- }
-#else /* !TARGET_API_MAC_CARBON */
- FRAME_MAC_WINDOW (f)
- = NewCWindow (NULL, &r, "\p", false, proc_id, behind, go_away_flag,
- (long) f->output_data.mac);
-#endif /* !TARGET_API_MAC_CARBON */
- /* so that update events can find this mac_output struct */
- f->output_data.mac->mFP = f; /* point back to emacs frame */
-
-#ifndef MAC_OSX
- if (!tooltip_p)
- if (FRAME_MAC_WINDOW (f))
- {
- ControlRef root_control;
-
- if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr)
- {
- DisposeWindow (FRAME_MAC_WINDOW (f));
- FRAME_MAC_WINDOW (f) = NULL;
- }
- }
-#endif
-}
-
-/* Dispose of the Mac window of the frame F. */
-
-void
-mac_dispose_frame_window (f)
- struct frame *f;
-{
- WindowRef window = FRAME_MAC_WINDOW (f);
-
- if (window != tip_window)
- remove_window_handler (window);
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- DisposeWindow (window);
-}
-
-
-/************************************************************************
- View and Drawing
- ************************************************************************/
-
-#if USE_CG_DRAWING
-#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
-
-CGContextRef
-mac_begin_cg_clip (f, gc)
- struct frame *f;
- GC gc;
-{
- CGContextRef context = FRAME_CG_CONTEXT (f);
-
- if (!context)
- {
- QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
- FRAME_CG_CONTEXT (f) = context;
- }
-
- CGContextSaveGState (context);
- CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f));
- CGContextScaleCTM (context, 1, -1);
- if (gc && gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
-
- return context;
-}
-
-void
-mac_end_cg_clip (f)
- struct frame *f;
-{
- CGContextRestoreGState (FRAME_CG_CONTEXT (f));
-}
-
-static void
-mac_prepare_for_quickdraw (f)
- struct frame *f;
-{
- if (f == NULL)
- {
- Lisp_Object rest, frame;
- FOR_EACH_FRAME (rest, frame)
- if (FRAME_MAC_P (XFRAME (frame)))
- mac_prepare_for_quickdraw (XFRAME (frame));
- }
- else
- {
- CGContextRef context = FRAME_CG_CONTEXT (f);
-
- if (context)
- {
- CGContextSynchronize (context);
- QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)),
- &FRAME_CG_CONTEXT (f));
- }
- }
-}
-#endif
-
-static RgnHandle saved_port_clip_region = NULL;
-
-void
-mac_begin_clip (f, gc)
- struct frame *f;
- GC gc;
-{
- static RgnHandle new_region = NULL;
-
- if (saved_port_clip_region == NULL)
- saved_port_clip_region = NewRgn ();
- if (new_region == NULL)
- new_region = NewRgn ();
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- if (gc && gc->n_clip_rects)
- {
- GetClip (saved_port_clip_region);
- SectRgn (saved_port_clip_region, gc->clip_region, new_region);
- SetClip (new_region);
- }
-}
-
-void
-mac_end_clip (f, gc)
- struct frame *f;
- GC gc;
-{
- if (gc && gc->n_clip_rects)
- SetClip (saved_port_clip_region);
-}
-
-#if TARGET_API_MAC_CARBON
-/* Mac replacement for XCopyArea: used only for scrolling. */
-
-void
-mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
- struct frame *f;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y;
-{
- Rect src_r;
- RgnHandle dummy = NewRgn (); /* For avoiding update events. */
-
- SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- ScrollWindowRect (FRAME_MAC_WINDOW (f),
- &src_r, dest_x - src_x, dest_y - src_y,
- kScrollWindowNoOptions, dummy);
- DisposeRgn (dummy);
-}
-#endif
-
-
-/************************************************************************
- Scroll bars
- ************************************************************************/
-
-extern struct scroll_bar *tracked_scroll_bar;
-extern Lisp_Object last_mouse_scroll_bar;
-extern Time last_mouse_movement_time;
-
-static void x_scroll_bar_handle_click P_ ((struct scroll_bar *,
- ControlPartCode,
- const EventRecord *,
- struct input_event *));
-#ifndef USE_TOOLKIT_SCROLL_BARS
-static void x_scroll_bar_note_movement P_ ((struct scroll_bar *, int, Time));
-#else /* USE_TOOLKIT_SCROLL_BARS */
-static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
- ControlPartCode, Point,
- struct input_event *));
-static void x_scroll_bar_handle_release P_ ((struct scroll_bar *,
- struct input_event *));
-static void x_scroll_bar_handle_drag P_ ((WindowRef, struct scroll_bar *,
- Point, struct input_event *));
-static pascal void scroll_bar_timer_callback P_ ((EventLoopTimerRef, void *));
-static OSStatus install_scroll_bar_timer P_ ((void));
-static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval));
-static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode));
-static void construct_scroll_bar_click P_ ((struct scroll_bar *, int,
- struct input_event *));
-static OSStatus get_control_part_bounds P_ ((ControlRef, ControlPartCode,
- Rect *));
-static void update_scroll_bar_track_info P_ ((struct scroll_bar *));
-
-/* Last scroll bar part sent in x_scroll_bar_handle_*. */
-
-static int last_scroll_bar_part;
-
-static EventLoopTimerRef scroll_bar_timer;
-
-static int scroll_bar_timer_event_posted_p;
-
-#define SCROLL_BAR_FIRST_DELAY 0.5
-#define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
-
-static pascal void
-scroll_bar_timer_callback (timer, data)
- EventLoopTimerRef timer;
- void *data;
-{
- OSStatus err;
-
- err = mac_post_mouse_moved_event ();
- if (err == noErr)
- scroll_bar_timer_event_posted_p = 1;
-}
-
-static OSStatus
-install_scroll_bar_timer ()
-{
- static EventLoopTimerUPP scroll_bar_timer_callbackUPP = NULL;
-
- if (scroll_bar_timer_callbackUPP == NULL)
- scroll_bar_timer_callbackUPP =
- NewEventLoopTimerUPP (scroll_bar_timer_callback);
-
- if (scroll_bar_timer == NULL)
- /* Mac OS X and CarbonLib 1.5 and later allow us to specify
- kEventDurationForever as delays. */
- return
- InstallEventLoopTimer (GetCurrentEventLoop (),
- kEventDurationForever, kEventDurationForever,
- scroll_bar_timer_callbackUPP, NULL,
- &scroll_bar_timer);
-}
-
-static OSStatus
-set_scroll_bar_timer (delay)
- EventTimerInterval delay;
-{
- if (scroll_bar_timer == NULL)
- install_scroll_bar_timer ();
-
- scroll_bar_timer_event_posted_p = 0;
-
- return SetEventLoopTimerNextFireTime (scroll_bar_timer, delay);
-}
-
-static int
-control_part_code_to_scroll_bar_part (part_code)
- ControlPartCode part_code;
-{
- switch (part_code)
- {
- case kControlUpButtonPart: return scroll_bar_up_arrow;
- case kControlDownButtonPart: return scroll_bar_down_arrow;
- case kControlPageUpPart: return scroll_bar_above_handle;
- case kControlPageDownPart: return scroll_bar_below_handle;
- case kControlIndicatorPart: return scroll_bar_handle;
- }
-
- return -1;
-}
-
-static void
-construct_scroll_bar_click (bar, part, bufp)
- struct scroll_bar *bar;
- int part;
- struct input_event *bufp;
-{
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = bar->window;
- bufp->arg = Qnil;
- bufp->part = part;
- bufp->code = 0;
- XSETINT (bufp->x, 0);
- XSETINT (bufp->y, 0);
- bufp->modifiers = 0;
-}
-
-static OSStatus
-get_control_part_bounds (ch, part_code, rect)
- ControlRef ch;
- ControlPartCode part_code;
- Rect *rect;
-{
- RgnHandle region = NewRgn ();
- OSStatus err;
-
- err = GetControlRegion (ch, part_code, region);
- if (err == noErr)
- GetRegionBounds (region, rect);
- DisposeRgn (region);
-
- return err;
-}
-
-static void
-x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
- struct scroll_bar *bar;
- ControlPartCode part_code;
- Point mouse_pos;
- struct input_event *bufp;
-{
- int part = control_part_code_to_scroll_bar_part (part_code);
-
- if (part < 0)
- return;
-
- if (part != scroll_bar_handle)
- {
- construct_scroll_bar_click (bar, part, bufp);
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
- set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY);
- bar->dragging = Qnil;
- }
- else
- {
- Rect r;
-
- get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
- kControlIndicatorPart, &r);
- XSETINT (bar->dragging, - (mouse_pos.v - r.top) - 1);
- }
-
- last_scroll_bar_part = part;
- tracked_scroll_bar = bar;
-}
-
-static void
-x_scroll_bar_handle_release (bar, bufp)
- struct scroll_bar *bar;
- struct input_event *bufp;
-{
- if (last_scroll_bar_part != scroll_bar_handle
- || (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0))
- construct_scroll_bar_click (bar, scroll_bar_end_scroll, bufp);
-
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
- set_scroll_bar_timer (kEventDurationForever);
-
- last_scroll_bar_part = -1;
- bar->dragging = Qnil;
- tracked_scroll_bar = NULL;
-}
-
-static void
-x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
- WindowRef win;
- struct scroll_bar *bar;
- Point mouse_pos;
- struct input_event *bufp;
-{
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
-
- if (last_scroll_bar_part == scroll_bar_handle)
- {
- int top, top_range;
- Rect r;
-
- get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
- kControlIndicatorPart, &r);
-
- if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0)
- XSETINT (bar->dragging, - (XINT (bar->dragging) + 1));
-
- top = mouse_pos.v - XINT (bar->dragging) - XINT (bar->track_top);
- top_range = XINT (bar->track_height) - XINT (bar->min_handle);
-
- if (top < 0)
- top = 0;
- if (top > top_range)
- top = top_range;
-
- construct_scroll_bar_click (bar, scroll_bar_handle, bufp);
- XSETINT (bufp->x, top);
- XSETINT (bufp->y, top_range);
- }
- else
- {
- ControlPartCode part_code;
- int unhilite_p = 0, part;
-
- if (ch != FindControlUnderMouse (mouse_pos, win, &part_code))
- unhilite_p = 1;
- else
- {
- part = control_part_code_to_scroll_bar_part (part_code);
-
- switch (last_scroll_bar_part)
- {
- case scroll_bar_above_handle:
- case scroll_bar_below_handle:
- if (part != scroll_bar_above_handle
- && part != scroll_bar_below_handle)
- unhilite_p = 1;
- break;
-
- case scroll_bar_up_arrow:
- case scroll_bar_down_arrow:
- if (part != scroll_bar_up_arrow
- && part != scroll_bar_down_arrow)
- unhilite_p = 1;
- break;
- }
- }
-
- if (unhilite_p)
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
- else if (part != last_scroll_bar_part
- || scroll_bar_timer_event_posted_p)
- {
- construct_scroll_bar_click (bar, part, bufp);
- last_scroll_bar_part = part;
- HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
- set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY);
- }
- }
-}
-
-/* Update BAR->track_top, BAR->track_height, and BAR->min_handle for
- the scroll bar BAR. This function should be called when the bounds
- of the scroll bar is changed. */
-
-static void
-update_scroll_bar_track_info (bar)
- struct scroll_bar *bar;
-{
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- Rect r0, r1;
-
- GetControlBounds (ch, &r0);
-
- if (r0.right - r0.left >= r0.bottom - r0.top
-#ifdef MAC_OSX
- || r0.right - r0.left < MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
-#endif
- )
- {
- XSETINT (bar->track_top, 0);
- XSETINT (bar->track_height, 0);
- XSETINT (bar->min_handle, 0);
- }
- else
- {
- BLOCK_INPUT;
-
- SetControl32BitMinimum (ch, 0);
- SetControl32BitMaximum (ch, 1 << 30);
- SetControlViewSize (ch, 1);
-
- /* Move the scroll bar thumb to the top. */
- SetControl32BitValue (ch, 0);
- get_control_part_bounds (ch, kControlIndicatorPart, &r0);
-
- /* Move the scroll bar thumb to the bottom. */
- SetControl32BitValue (ch, 1 << 30);
- get_control_part_bounds (ch, kControlIndicatorPart, &r1);
-
- UnionRect (&r0, &r1, &r0);
- XSETINT (bar->track_top, r0.top);
- XSETINT (bar->track_height, r0.bottom - r0.top);
- XSETINT (bar->min_handle, r1.bottom - r1.top);
-
- /* Don't show the scroll bar if its height is not enough to
- display the scroll bar thumb. */
- if (r0.bottom - r0.top > 0)
- ShowControl (ch);
-
- UNBLOCK_INPUT;
- }
-}
-
-/* Set the thumb size and position of scroll bar BAR. We are currently
- displaying PORTION out of a whole WHOLE, and our position POSITION. */
-
-void
-x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
- struct scroll_bar *bar;
- int portion, position, whole;
-{
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- int value, viewsize, maximum;
-
- if (XINT (bar->track_height) == 0)
- return;
-
- if (whole <= portion)
- value = 0, viewsize = 1, maximum = 0;
- else
- {
- float scale;
-
- maximum = XINT (bar->track_height) - XINT (bar->min_handle);
- scale = (float) maximum / (whole - portion);
- value = position * scale + 0.5f;
- viewsize = (int) (portion * scale + 0.5f) + XINT (bar->min_handle);
- }
-
- BLOCK_INPUT;
-
- if (GetControlViewSize (ch) != viewsize
- || GetControl32BitValue (ch) != value
- || GetControl32BitMaximum (ch) != maximum)
- {
- /* Temporarily hide the scroll bar to avoid multiple redraws. */
- SetControlVisibility (ch, false, false);
-
- SetControl32BitMaximum (ch, maximum);
- SetControl32BitValue (ch, value);
- SetControlViewSize (ch, viewsize);
-
- SetControlVisibility (ch, true, true);
- }
-
- UNBLOCK_INPUT;
-}
-
-#endif /* USE_TOOLKIT_SCROLL_BARS */
-
-/* Create a scroll bar control for BAR. BOUNDS and VISIBLE specifies
- the initial geometry and visibility, respectively. The created
- control is stored in some members of BAR. */
-
-void
-mac_create_scroll_bar (bar, bounds, visible)
- struct scroll_bar *bar;
- const Rect *bounds;
- Boolean visible;
-{
- struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- ControlRef ch;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- ch = NewControl (FRAME_MAC_WINDOW (f), bounds, "\p", visible, 0, 0, 0,
-#if TARGET_API_MAC_CARBON
- kControlScrollBarProc,
-#else
- scrollBarProc,
-#endif
- (SInt32) bar);
- SET_SCROLL_BAR_CONTROL_REF (bar, ch);
-
- XSETINT (bar->start, 0);
- XSETINT (bar->end, 0);
- bar->dragging = Qnil;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- update_scroll_bar_track_info (bar);
-#endif
-}
-
-/* Dispose of the scroll bar control stored in some members of
- BAR. */
-
-void
-mac_dispose_scroll_bar (bar)
- struct scroll_bar *bar;
-{
-#if USE_CG_DRAWING
- struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-
- mac_prepare_for_quickdraw (f);
-#endif
- DisposeControl (SCROLL_BAR_CONTROL_REF (bar));
-}
-
-/* Set bounds of the scroll bar BAR to BOUNDS. */
-
-void
-mac_set_scroll_bar_bounds (bar, bounds)
- struct scroll_bar *bar;
- const Rect *bounds;
-{
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- SInt16 width, height;
-#if USE_CG_DRAWING
- struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-
- mac_prepare_for_quickdraw (f);
-#endif
-
- width = bounds->right - bounds->left;
- height = bounds->bottom - bounds->top;
- HideControl (ch);
- MoveControl (ch, bounds->left, bounds->top);
- SizeControl (ch, width, height);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- update_scroll_bar_track_info (bar);
-#else
- if (width < height)
- ShowControl (ch);
-#endif
-}
-
-/* Draw the scroll bar BAR. */
-
-void
-mac_redraw_scroll_bar (bar)
- struct scroll_bar *bar;
-{
-#if USE_CG_DRAWING
- struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-
- mac_prepare_for_quickdraw (f);
-#endif
- Draw1Control (SCROLL_BAR_CONTROL_REF (bar));
-}
-
-/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
- is set to something other than NO_EVENT, it is enqueued.
-
- This may be called from a signal handler, so we have to ignore GC
- mark bits. */
-
-static void
-x_scroll_bar_handle_click (bar, part_code, er, bufp)
- struct scroll_bar *bar;
- ControlPartCode part_code;
- const EventRecord *er;
- struct input_event *bufp;
-{
- int win_y, top_range;
-
- if (! GC_WINDOWP (bar->window))
- abort ();
-
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = bar->window;
- bufp->arg = Qnil;
-
- bar->dragging = Qnil;
-
- switch (part_code)
- {
- case kControlUpButtonPart:
- bufp->part = scroll_bar_up_arrow;
- break;
- case kControlDownButtonPart:
- bufp->part = scroll_bar_down_arrow;
- break;
- case kControlPageUpPart:
- bufp->part = scroll_bar_above_handle;
- break;
- case kControlPageDownPart:
- bufp->part = scroll_bar_below_handle;
- break;
-#if TARGET_API_MAC_CARBON
- default:
-#else
- case kControlIndicatorPart:
-#endif
- if (er->what == mouseDown)
- bar->dragging = make_number (0);
- XSETVECTOR (last_mouse_scroll_bar, bar);
- bufp->part = scroll_bar_handle;
- break;
- }
-
- win_y = XINT (bufp->y) - XINT (bar->top);
- top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar->height));
-
- win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
-
- win_y -= 24;
-
- if (! NILP (bar->dragging))
- win_y -= XINT (bar->dragging);
-
- if (win_y < 0)
- win_y = 0;
- if (win_y > top_range)
- win_y = top_range;
-
- XSETINT (bufp->x, win_y);
- XSETINT (bufp->y, top_range);
-}
-
-/* Return information to the user about the current position of the mouse
- on the scroll bar. */
-
-void
-x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
- FRAME_PTR *fp;
- Lisp_Object *bar_window;
- enum scroll_bar_part *part;
- Lisp_Object *x, *y;
- unsigned long *time;
-{
- struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
-#if TARGET_API_MAC_CARBON
- WindowRef wp = GetControlOwner (ch);
-#else
- WindowRef wp = (*ch)->contrlOwner;
-#endif
- Point mouse_pos;
- struct frame *f = mac_window_to_frame (wp);
- int win_y, top_range;
-
-#if TARGET_API_MAC_CARBON
- GetGlobalMouse (&mouse_pos);
- mouse_pos.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- mouse_pos.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-#else
- SetPortWindowPort (wp);
- GetMouse (&mouse_pos);
-#endif
-
- win_y = mouse_pos.v - XINT (bar->top);
- top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
-
- win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
-
- win_y -= 24;
-
- if (! NILP (bar->dragging))
- win_y -= XINT (bar->dragging);
-
- if (win_y < 0)
- win_y = 0;
- if (win_y > top_range)
- win_y = top_range;
-
- *fp = f;
- *bar_window = bar->window;
-
- if (! NILP (bar->dragging))
- *part = scroll_bar_handle;
- else if (win_y < XINT (bar->start))
- *part = scroll_bar_above_handle;
- else if (win_y < XINT (bar->end) + VERTICAL_SCROLL_BAR_MIN_HANDLE)
- *part = scroll_bar_handle;
- else
- *part = scroll_bar_below_handle;
-
- XSETINT (*x, win_y);
- XSETINT (*y, top_range);
-
- f->mouse_moved = 0;
- last_mouse_scroll_bar = Qnil;
-
- *time = last_mouse_movement_time;
-}
-
-#ifndef USE_TOOLKIT_SCROLL_BARS
-/* Draw BAR's handle in the proper position.
-
- If the handle is already drawn from START to END, don't bother
- redrawing it, unless REBUILD is non-zero; in that case, always
- redraw it. (REBUILD is handy for drawing the handle after expose
- events.)
-
- Normally, we want to constrain the start and end of the handle to
- fit inside its rectangle, but if the user is dragging the scroll
- bar handle, we want to let them drag it down all the way, so that
- the bar's top is as far down as it goes; otherwise, there's no way
- to move to the very end of the buffer. */
-
-void
-x_scroll_bar_set_handle (bar, start, end, rebuild)
- struct scroll_bar *bar;
- int start, end;
- int rebuild;
-{
- int dragging = ! NILP (bar->dragging);
- ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
- int length = end - start;
-
- /* If the display is already accurate, do nothing. */
- if (! rebuild
- && start == XINT (bar->start)
- && end == XINT (bar->end))
- return;
-
- BLOCK_INPUT;
-
- /* Make sure the values are reasonable, and try to preserve the
- distance between start and end. */
- if (start < 0)
- start = 0;
- else if (start > top_range)
- start = top_range;
- end = start + length;
-
- if (end < start)
- end = start;
- else if (end > top_range && ! dragging)
- end = top_range;
-
- /* Store the adjusted setting in the scroll bar. */
- XSETINT (bar->start, start);
- XSETINT (bar->end, end);
-
- /* Clip the end position, just for display. */
- if (end > top_range)
- end = top_range;
-
- /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
- top positions, to make sure the handle is always at least that
- many pixels tall. */
- end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
-
- SetControlMinimum (ch, 0);
- /* Don't inadvertently activate deactivated scroll bars */
- if (GetControlMaximum (ch) != -1)
- SetControlMaximum (ch, top_range + VERTICAL_SCROLL_BAR_MIN_HANDLE
- - (end - start));
- SetControlValue (ch, start);
-#if TARGET_API_MAC_CARBON
- SetControlViewSize (ch, end - start);
-#endif
-
- UNBLOCK_INPUT;
-}
-
-/* Handle some mouse motion while someone is dragging the scroll bar.
-
- This may be called from a signal handler, so we have to ignore GC
- mark bits. */
-
-static void
-x_scroll_bar_note_movement (bar, y_pos, t)
- struct scroll_bar *bar;
- int y_pos;
- Time t;
-{
- FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
-
- last_mouse_movement_time = t;
-
- f->mouse_moved = 1;
- XSETVECTOR (last_mouse_scroll_bar, bar);
-
- /* If we're dragging the bar, display it. */
- if (! GC_NILP (bar->dragging))
- {
- /* Where should the handle be now? */
- int new_start = y_pos - 24;
-
- if (new_start != XINT (bar->start))
- {
- int new_end = new_start + (XINT (bar->end) - XINT (bar->start));
-
- x_scroll_bar_set_handle (bar, new_start, new_end, 0);
- }
- }
-}
-#endif /* !USE_TOOLKIT_SCROLL_BARS */
-
-
-/***********************************************************************
- Tool-bars
- ***********************************************************************/
-
-#if USE_MAC_TOOLBAR
-/* In identifiers such as function/variable names, Emacs tool bar is
- referred to as `tool_bar', and Carbon HIToolbar as `toolbar'. */
-
-#define TOOLBAR_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar"))
-#define TOOLBAR_ICON_ITEM_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar.icon"))
-
-#define TOOLBAR_ITEM_COMMAND_ID_OFFSET 'Tb\0\0'
-#define TOOLBAR_ITEM_COMMAND_ID_P(id) \
- (((id) & ~0xffff) == TOOLBAR_ITEM_COMMAND_ID_OFFSET)
-#define TOOLBAR_ITEM_COMMAND_ID_VALUE(id) \
- ((id) - TOOLBAR_ITEM_COMMAND_ID_OFFSET)
-#define TOOLBAR_ITEM_MAKE_COMMAND_ID(value) \
- ((value) + TOOLBAR_ITEM_COMMAND_ID_OFFSET)
-
-static OSStatus mac_handle_toolbar_command_event P_ ((EventHandlerCallRef,
- EventRef, void *));
-
-extern Rect last_mouse_glyph;
-
-extern void mac_move_window_with_gravity P_ ((struct frame *, int,
- short, short));
-extern void mac_get_window_origin_with_gravity P_ ((struct frame *, int,
- short *, short *));
-extern CGImageRef mac_image_spec_to_cg_image P_ ((struct frame *,
- Lisp_Object));
-
-static OSStatus
-mac_handle_toolbar_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus result = eventNotHandledErr;
-
- switch (GetEventKind (event))
- {
- case kEventToolbarGetDefaultIdentifiers:
- result = noErr;
- break;
-
- case kEventToolbarGetAllowedIdentifiers:
- {
- CFMutableArrayRef array;
-
- GetEventParameter (event, kEventParamMutableArray,
- typeCFMutableArrayRef, NULL,
- sizeof (CFMutableArrayRef), NULL, &array);
- CFArrayAppendValue (array, TOOLBAR_ICON_ITEM_IDENTIFIER);
- result = noErr;
- }
- break;
-
- case kEventToolbarCreateItemWithIdentifier:
- {
- CFStringRef identifier;
- HIToolbarItemRef item = NULL;
-
- GetEventParameter (event, kEventParamToolbarItemIdentifier,
- typeCFStringRef, NULL,
- sizeof (CFStringRef), NULL, &identifier);
-
- if (CFStringCompare (identifier, TOOLBAR_ICON_ITEM_IDENTIFIER, 0)
- == kCFCompareEqualTo)
- HIToolbarItemCreate (identifier,
- kHIToolbarItemAllowDuplicates
- | kHIToolbarItemCantBeRemoved, &item);
-
- if (item)
- {
- SetEventParameter (event, kEventParamToolbarItem,
- typeHIToolbarItemRef,
- sizeof (HIToolbarItemRef), &item);
- result = noErr;
- }
- }
- break;
-
- default:
- abort ();
- }
-
- return result;
-}
-
-/* Create a tool bar for frame F. */
-
-static OSStatus
-mac_create_frame_tool_bar (f)
- FRAME_PTR f;
-{
- OSStatus err;
- HIToolbarRef toolbar;
-
- err = HIToolbarCreate (TOOLBAR_IDENTIFIER, kHIToolbarNoAttributes,
- &toolbar);
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassToolbar, kEventToolbarGetDefaultIdentifiers},
- {kEventClassToolbar, kEventToolbarGetAllowedIdentifiers},
- {kEventClassToolbar, kEventToolbarCreateItemWithIdentifier}};
-
- err = InstallEventHandler (HIObjectGetEventTarget (toolbar),
- mac_handle_toolbar_event,
- GetEventTypeCount (specs), specs,
- f, NULL);
- }
-
- if (err == noErr)
- err = HIToolbarSetDisplayMode (toolbar, kHIToolbarDisplayModeIconOnly);
- if (err == noErr)
- {
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess}};
-
- err = InstallWindowEventHandler (FRAME_MAC_WINDOW (f),
- mac_handle_toolbar_command_event,
- GetEventTypeCount (specs),
- specs, f, NULL);
- }
- if (err == noErr)
- err = SetWindowToolbar (FRAME_MAC_WINDOW (f), toolbar);
-
- if (toolbar)
- CFRelease (toolbar);
-
- return err;
-}
-
-/* Update the tool bar for frame F. Add new buttons and remove old. */
-
-void
-update_frame_tool_bar (f)
- FRAME_PTR f;
-{
- HIToolbarRef toolbar = NULL;
- short left, top;
- CFArrayRef old_items = NULL;
- CFIndex old_count;
- int i, pos, win_gravity = f->output_data.mac->toolbar_win_gravity;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- BLOCK_INPUT;
-
- GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
- if (toolbar == NULL)
- {
- mac_create_frame_tool_bar (f);
- GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
- if (toolbar == NULL)
- goto out;
- if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
- mac_get_window_origin_with_gravity (f, win_gravity, &left, &top);
- }
-
- HIToolbarCopyItems (toolbar, &old_items);
- if (old_items == NULL)
- goto out;
-
- old_count = CFArrayGetCount (old_items);
- pos = 0;
- for (i = 0; i < f->n_tool_bar_items; ++i)
- {
-#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
-
- int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
- int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
- int idx;
- Lisp_Object image;
- CGImageRef cg_image;
- CFStringRef label;
- HIToolbarItemRef item;
-
- /* If image is a vector, choose the image according to the
- button state. */
- image = PROP (TOOL_BAR_ITEM_IMAGES);
- if (VECTORP (image))
- {
- if (enabled_p)
- idx = (selected_p
- ? TOOL_BAR_IMAGE_ENABLED_SELECTED
- : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
- else
- idx = (selected_p
- ? TOOL_BAR_IMAGE_DISABLED_SELECTED
- : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
-
- xassert (ASIZE (image) >= idx);
- image = AREF (image, idx);
- }
- else
- idx = -1;
-
- cg_image = mac_image_spec_to_cg_image (f, image);
- /* Ignore invalid image specifications. */
- if (cg_image == NULL)
- continue;
-
- label = cfstring_create_with_string (PROP (TOOL_BAR_ITEM_CAPTION));
- if (label == NULL)
- label = CFSTR ("");
-
- if (pos < old_count)
- {
- CGImageRef old_cg_image = NULL;
- CFStringRef old_label = NULL;
- Boolean old_enabled_p;
-
- item = (HIToolbarItemRef) CFArrayGetValueAtIndex (old_items, pos);
-
- HIToolbarItemCopyImage (item, &old_cg_image);
- if (cg_image != old_cg_image)
- HIToolbarItemSetImage (item, cg_image);
- CGImageRelease (old_cg_image);
-
- HIToolbarItemCopyLabel (item, &old_label);
- if (CFStringCompare (label, old_label, 0) != kCFCompareEqualTo)
- HIToolbarItemSetLabel (item, label);
- CFRelease (old_label);
-
- old_enabled_p = HIToolbarItemIsEnabled (item);
- if ((enabled_p || idx >= 0) != old_enabled_p)
- HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
- }
- else
- {
- item = NULL;
- HIToolbarCreateItemWithIdentifier (toolbar,
- TOOLBAR_ICON_ITEM_IDENTIFIER,
- NULL, &item);
- if (item)
- {
- HIToolbarItemSetImage (item, cg_image);
- HIToolbarItemSetLabel (item, label);
- HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
- HIToolbarAppendItem (toolbar, item);
- CFRelease (item);
- }
- }
-
- CFRelease (label);
- if (item)
- {
- HIToolbarItemSetCommandID (item, TOOLBAR_ITEM_MAKE_COMMAND_ID (i));
- pos++;
- }
- }
-
- CFRelease (old_items);
-
- while (pos < old_count)
- HIToolbarRemoveItemAtIndex (toolbar, --old_count);
-
- ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), true,
- !win_gravity && f == mac_focus_frame (dpyinfo));
- /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events on
- toolbar visibility change. */
- mac_handle_origin_change (f);
- if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
- {
- mac_move_window_with_gravity (f, win_gravity, left, top);
- /* If the title bar is completely outside the screen, adjust the
- position. */
- ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
- kWindowConstrainMoveRegardlessOfFit
- | kWindowConstrainAllowPartial, NULL, NULL);
- f->output_data.mac->toolbar_win_gravity = 0;
- }
-
- out:
- UNBLOCK_INPUT;
-}
-
-/* Hide the tool bar on frame F. Unlike the counterpart on GTK+, it
- doesn't deallocate the resources. */
-
-void
-free_frame_tool_bar (f)
- FRAME_PTR f;
-{
- if (IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
- {
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
-
- BLOCK_INPUT;
- ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), false,
- (NILP (find_symbol_value
- (intern ("frame-notice-user-settings")))
- && f == mac_focus_frame (dpyinfo)));
- /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events
- on toolbar visibility change. */
- mac_handle_origin_change (f);
- UNBLOCK_INPUT;
- }
-}
-
-/* Report a mouse movement over toolbar to the mainstream Emacs
- code. */
-
-static void
-mac_tool_bar_note_mouse_movement (f, event)
- struct frame *f;
- EventRef event;
-{
- OSStatus err;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- int mouse_down_p;
- WindowRef window;
- WindowPartCode part_code;
- HIViewRef item_view;
- UInt32 command_id;
-
- mouse_down_p = (dpyinfo->grabbed
- && f == last_mouse_frame
- && FRAME_LIVE_P (f));
- if (mouse_down_p)
- return;
-
- err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef, NULL,
- sizeof (WindowRef), NULL, &window);
- if (err != noErr || window != FRAME_MAC_WINDOW (f))
- return;
-
- err = GetEventParameter (event, kEventParamWindowPartCode,
- typeWindowPartCode, NULL,
- sizeof (WindowPartCode), NULL, &part_code);
- if (err != noErr || part_code != inStructure)
- return;
-
- err = HIViewGetViewForMouseEvent (HIViewGetRoot (window), event, &item_view);
- /* This doesn't work on Mac OS X 10.2. On Mac OS X 10.3 and 10.4, a
- toolbar item view seems to have the same command ID with that of
- the toolbar item. */
- if (err == noErr)
- err = GetControlCommandID (item_view, &command_id);
- if (err == noErr && TOOLBAR_ITEM_COMMAND_ID_P (command_id))
- {
- int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command_id);
-
- if (i < f->n_tool_bar_items)
- {
- HIRect bounds;
- HIViewRef content_view;
-
- err = HIViewGetBounds (item_view, &bounds);
- if (err == noErr)
- err = HIViewFindByID (HIViewGetRoot (window),
- kHIViewWindowContentID, &content_view);
- if (err == noErr)
- err = HIViewConvertRect (&bounds, item_view, content_view);
- if (err == noErr)
- SetRect (&last_mouse_glyph,
- CGRectGetMinX (bounds), CGRectGetMinY (bounds),
- CGRectGetMaxX (bounds), CGRectGetMaxY (bounds));
-
- help_echo_object = help_echo_window = Qnil;
- help_echo_pos = -1;
- help_echo_string = PROP (TOOL_BAR_ITEM_HELP);
- if (NILP (help_echo_string))
- help_echo_string = PROP (TOOL_BAR_ITEM_CAPTION);
- }
- }
-}
-
-static OSStatus
-mac_handle_toolbar_command_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- struct frame *f = (struct frame *) data;
- HICommand command;
-
- err = GetEventParameter (event, kEventParamDirectObject,
- typeHICommand, NULL,
- sizeof (HICommand), NULL, &command);
- if (err != noErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventCommandProcess:
- if (!TOOLBAR_ITEM_COMMAND_ID_P (command.commandID))
- result = CallNextEventHandler (next_handler, event);
- else
- {
- int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command.commandID);
-
- if (i < f->n_tool_bar_items
- && !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)))
- {
- Lisp_Object frame;
- struct input_event buf;
-
- EVENT_INIT (buf);
-
- XSETFRAME (frame, f);
- buf.kind = TOOL_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = frame;
- kbd_buffer_store_event (&buf);
-
- buf.kind = TOOL_BAR_EVENT;
- buf.frame_or_window = frame;
- buf.arg = PROP (TOOL_BAR_ITEM_KEY);
- buf.modifiers = mac_event_to_emacs_modifiers (event);
- kbd_buffer_store_event (&buf);
-
- result = noErr;
- }
- }
- break;
-
- default:
- abort ();
- }
-#undef PROP
-
- return result;
-}
-#endif /* USE_MAC_TOOLBAR */
-
-
-/***********************************************************************
- Font Panel
- ***********************************************************************/
-
-#if USE_MAC_FONT_PANEL
-/* Whether Font Panel has been shown before. The first call to font
- panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
- slow. This variable is used for deferring such a call as much as
- possible. */
-static int font_panel_shown_p = 0;
-
-extern Lisp_Object Qpanel_closed, Qselection;
-extern Lisp_Object Qfont;
-
-/* Whether the font panel is currently visible. */
-
-int
-mac_font_panel_visible_p ()
-{
- return font_panel_shown_p && FPIsFontPanelVisible ();
-}
-
-static pascal OSStatus
-mac_handle_font_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus result, err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_sel[] = {kEventParamATSUFontID,
- kEventParamATSUFontSize,
- kEventParamFMFontFamily,
- kEventParamFMFontStyle,
- kEventParamFMFontSize,
- kEventParamFontColor};
- static const EventParamType types_sel[] = {typeATSUFontID,
- typeATSUSize,
- typeFMFontFamily,
- typeFMFontStyle,
- typeFMFontSize,
- typeFontColor};
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventFontPanelClosed:
- id_key = Qpanel_closed;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
-
- case kEventFontSelection:
- id_key = Qselection;
- num_params = sizeof (names_sel) / sizeof (names_sel[0]);
- names = names_sel;
- types = types_sel;
- break;
- }
-
- err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
- event, num_params,
- names, types);
- if (err == noErr)
- result = noErr;
-
- return result;
-}
-
-/* Toggle visiblity of the font panel. */
-
-OSStatus
-mac_show_hide_font_panel ()
-{
- if (!font_panel_shown_p)
- {
- OSStatus err;
-
- static const EventTypeSpec specs[] =
- {{kEventClassFont, kEventFontPanelClosed},
- {kEventClassFont, kEventFontSelection}};
-
- err = InstallApplicationEventHandler (mac_handle_font_event,
- GetEventTypeCount (specs),
- specs, NULL, NULL);
- if (err != noErr)
- return err;
-
- font_panel_shown_p = 1;
- }
-
- return FPShowHideFontPanel ();
-}
-
-/* Set the font selected in the font panel to the one corresponding to
- the face FACE_ID and the charcacter C in the frame F. */
-
-OSStatus
-mac_set_font_info_for_selection (f, face_id, c)
- struct frame *f;
- int face_id, c;
-{
- OSStatus err;
- EventTargetRef target = NULL;
- XFontStruct *font = NULL;
-
- if (!mac_font_panel_visible_p ())
- return noErr;
-
- if (f)
- {
- target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
-
- if (FRAME_FACE_CACHE (f) && CHAR_VALID_P (c, 0))
- {
- struct face *face;
-
- face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
- face = FACE_FROM_ID (f, face_id);
- font = face->font;
- }
- }
-
- if (font == NULL)
- err = SetFontInfoForSelection (kFontSelectionATSUIType, 0, NULL, target);
- else
- {
- if (font->mac_fontnum != -1)
- {
- FontSelectionQDStyle qd_style;
-
- qd_style.version = kFontSelectionQDStyleVersionZero;
- qd_style.instance.fontFamily = font->mac_fontnum;
- qd_style.instance.fontStyle = font->mac_fontface;
- qd_style.size = font->mac_fontsize;
- qd_style.hasColor = false;
-
- err = SetFontInfoForSelection (kFontSelectionQDType,
- 1, &qd_style, target);
- }
- else
- err = SetFontInfoForSelection (kFontSelectionATSUIType,
- 1, &font->mac_style, target);
- }
-
- return err;
-}
-#endif /* USE_MAC_FONT_PANEL */
-
-
-/************************************************************************
- Event Handling
- ************************************************************************/
-
-/* Non-zero means that a HELP_EVENT has been generated since Emacs
- start. */
-
-static int any_help_event_p;
-
-/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
-static Lisp_Object last_window;
-
-static Point saved_menu_event_location;
-
-extern struct frame *pending_autoraise_frame;
-
-extern FRAME_PTR last_mouse_glyph_frame;
-
-#ifdef __STDC__
-extern int volatile input_signal_count;
-#else
-extern int input_signal_count;
-#endif
-
-extern int mac_screen_config_changed;
-
-extern Lisp_Object Vmac_emulate_three_button_mouse;
-#if TARGET_API_MAC_CARBON
-extern int mac_wheel_button_is_mouse_2;
-extern int mac_pass_command_to_system;
-extern int mac_pass_control_to_system;
-#endif /* TARGET_API_MAC_CARBON */
-extern int mac_ready_for_apple_events;
-
-extern void mac_focus_changed P_ ((int, struct mac_display_info *,
- struct frame *, struct input_event *));
-extern int mac_get_emulated_btn P_ ((UInt32));
-extern int note_mouse_movement P_ ((FRAME_PTR, Point *));
-extern void mac_get_screen_info P_ ((struct mac_display_info *));
-
-/* The focus may have changed. Figure out if it is a real focus change,
- by checking both FocusIn/Out and Enter/LeaveNotify events.
-
- Returns FOCUS_IN_EVENT event in *BUFP. */
-
-static void
-x_detect_focus_change (dpyinfo, event, bufp)
- struct mac_display_info *dpyinfo;
- const EventRecord *event;
- struct input_event *bufp;
-{
- struct frame *frame;
-
- frame = mac_window_to_frame ((WindowRef) event->message);
- if (! frame)
- return;
-
- /* On Mac, this is only called from focus events, so no switch needed. */
- mac_focus_changed ((event->modifiers & activeFlag),
- dpyinfo, frame, bufp);
-}
-
-#if TARGET_API_MAC_CARBON
-/* Obtains the event modifiers from the event EVENTREF and then calls
- mac_to_emacs_modifiers. */
-
-static int
-mac_event_to_emacs_modifiers (EventRef eventRef)
-{
- UInt32 mods = 0, class;
-
- GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
- sizeof (UInt32), NULL, &mods);
- class = GetEventClass (eventRef);
- if (!NILP (Vmac_emulate_three_button_mouse)
- && (class == kEventClassMouse || class == kEventClassCommand))
- {
- mods &= ~(optionKey | cmdKey);
- }
- return mac_to_emacs_modifiers (mods, 0);
-}
-
-/* Given an event REF, return the code to use for the mouse button
- code in the emacs input_event. */
-
-static int
-mac_get_mouse_btn (EventRef ref)
-{
- EventMouseButton result = kEventMouseButtonPrimary;
- GetEventParameter (ref, kEventParamMouseButton, typeMouseButton, NULL,
- sizeof (EventMouseButton), NULL, &result);
- switch (result)
- {
- case kEventMouseButtonPrimary:
- if (NILP (Vmac_emulate_three_button_mouse))
- return 0;
- else {
- UInt32 mods = 0;
- GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
- sizeof (UInt32), NULL, &mods);
- return mac_get_emulated_btn(mods);
- }
- case kEventMouseButtonSecondary:
- return mac_wheel_button_is_mouse_2 ? 2 : 1;
- case kEventMouseButtonTertiary:
- case 4: /* 4 is the number for the mouse wheel button */
- return mac_wheel_button_is_mouse_2 ? 1 : 2;
- default:
- return 0;
- }
-}
-
-/* Normally, ConvertEventRefToEventRecord will correctly handle all
- events. However the click of the mouse wheel is not converted to a
- mouseDown or mouseUp event. Likewise for dead key events. This
- calls ConvertEventRefToEventRecord, but then checks to see if it is
- a mouse up/down, or a dead key Carbon event that has not been
- converted, and if so, converts it by hand (to be picked up in the
- XTread_socket loop). */
-static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
-{
- OSStatus err;
- Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
- EventKind action;
-
- if (result)
- return result;
-
- switch (GetEventClass (eventRef))
- {
- case kEventClassMouse:
- switch (GetEventKind (eventRef))
- {
- case kEventMouseDown:
- eventRec->what = mouseDown;
- result = 1;
- break;
-
- case kEventMouseUp:
- eventRec->what = mouseUp;
- result = 1;
- break;
-
- default:
- break;
- }
- break;
-
- case kEventClassKeyboard:
- switch (GetEventKind (eventRef))
- {
- case kEventRawKeyDown:
- action = keyDown;
- goto keystroke_common;
- case kEventRawKeyRepeat:
- action = autoKey;
- goto keystroke_common;
- case kEventRawKeyUp:
- action = keyUp;
- keystroke_common:
- {
- unsigned char char_codes;
- UInt32 key_code;
-
- err = GetEventParameter (eventRef, kEventParamKeyMacCharCodes,
- typeChar, NULL, sizeof (char),
- NULL, &char_codes);
- if (err == noErr)
- err = GetEventParameter (eventRef, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr)
- {
- eventRec->what = action;
- eventRec->message = char_codes | ((key_code & 0xff) << 8);
- result = 1;
- }
- }
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (result)
- {
- /* Need where and when. */
- UInt32 mods = 0;
-
- GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint,
- NULL, sizeof (Point), NULL, &eventRec->where);
- /* Use two step process because new event modifiers are 32-bit
- and old are 16-bit. Currently, only loss is NumLock & Fn. */
- GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
- NULL, sizeof (UInt32), NULL, &mods);
- eventRec->modifiers = mods;
-
- eventRec->when = EventTimeToTicks (GetEventTime (eventRef));
- }
-
- return result;
-}
-#endif /* TARGET_API_MAC_CARBON */
-
-#if !TARGET_API_MAC_CARBON
-static RgnHandle mouse_region = NULL;
-
-Boolean
-mac_wait_next_event (er, sleep_time, dequeue)
- EventRecord *er;
- UInt32 sleep_time;
- Boolean dequeue;
-{
- static EventRecord er_buf = {nullEvent};
- UInt32 target_tick, current_tick;
- EventMask event_mask;
-
- if (mouse_region == NULL)
- mouse_region = NewRgn ();
-
- event_mask = everyEvent;
- if (!mac_ready_for_apple_events)
- event_mask -= highLevelEventMask;
-
- current_tick = TickCount ();
- target_tick = current_tick + sleep_time;
-
- if (er_buf.what == nullEvent)
- while (!WaitNextEvent (event_mask, &er_buf,
- target_tick - current_tick, mouse_region))
- {
- current_tick = TickCount ();
- if (target_tick <= current_tick)
- return false;
- }
-
- *er = er_buf;
- if (dequeue)
- er_buf.what = nullEvent;
- return true;
-}
-#endif /* not TARGET_API_MAC_CARBON */
-
-#if TARGET_API_MAC_CARBON
-OSStatus
-mac_post_mouse_moved_event ()
-{
- EventRef event = NULL;
- OSStatus err;
-
- err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0,
- kEventAttributeNone, &event);
- if (err == noErr)
- {
- Point mouse_pos;
-
- GetGlobalMouse (&mouse_pos);
- err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
- sizeof (Point), &mouse_pos);
- }
- if (err == noErr)
- {
- UInt32 modifiers = GetCurrentKeyModifiers ();
-
- err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32,
- sizeof (UInt32), &modifiers);
- }
- if (err == noErr)
- err = PostEventToQueue (GetCurrentEventQueue (), event,
- kEventPriorityStandard);
- if (event)
- ReleaseEvent (event);
-
- return err;
-}
-#endif
-
-#ifdef MAC_OSX
-/* Run the current run loop in the default mode until some input
- happens or TIMEOUT seconds passes unless it is negative. Return
- true if timeout occurs first. */
-
-Boolean
-mac_run_loop_run_once (timeout)
- EventTimeout timeout;
-{
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (NULL);
-#endif
- return (CFRunLoopRunInMode (kCFRunLoopDefaultMode,
- timeout >= 0 ? timeout : 100000, true)
- == kCFRunLoopRunTimedOut);
-}
-#endif
-
-/* Emacs calls this whenever it wants to read an input event from the
- user. */
-
-int
-XTread_socket (sd, expected, hold_quit)
- int sd, expected;
- struct input_event *hold_quit;
-{
- struct input_event inev;
- int count = 0;
-#if TARGET_API_MAC_CARBON
- EventRef eventRef;
- EventTargetRef toolbox_dispatcher;
-#endif
- EventRecord er;
- struct mac_display_info *dpyinfo = &one_mac_display_info;
-
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- BLOCK_INPUT;
-
- /* So people can tell when we have read the available input. */
- input_signal_count++;
-
- ++handling_signal;
-
-#if TARGET_API_MAC_CARBON
- toolbox_dispatcher = GetEventDispatcherTarget ();
-
- while (
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (NULL),
-#endif
- !ReceiveNextEvent (0, NULL, kEventDurationNoWait,
- kEventRemoveFromQueue, &eventRef))
-#else /* !TARGET_API_MAC_CARBON */
- while (mac_wait_next_event (&er, 0, true))
-#endif /* !TARGET_API_MAC_CARBON */
- {
- int do_help = 0;
- struct frame *f;
- unsigned long timestamp;
-
- EVENT_INIT (inev);
- inev.kind = NO_EVENT;
- inev.arg = Qnil;
-
-#if TARGET_API_MAC_CARBON
- timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
-
- if (!mac_convert_event_ref (eventRef, &er))
- goto OTHER;
-#else /* !TARGET_API_MAC_CARBON */
- timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-#endif /* !TARGET_API_MAC_CARBON */
-
- switch (er.what)
- {
- case mouseDown:
- case mouseUp:
- {
- WindowRef window_ptr;
- ControlPartCode part_code;
- int tool_bar_p = 0;
-
-#if TARGET_API_MAC_CARBON
- OSStatus err;
-
- /* This is needed to send mouse events like aqua window
- buttons to the correct handler. */
- read_socket_inev = &inev;
- err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- if (err != eventNotHandledErr)
- break;
-#endif
- last_mouse_glyph_frame = 0;
-
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- {
- window_ptr = FRAME_MAC_WINDOW (last_mouse_frame);
- part_code = inContent;
- }
- else
- {
- part_code = FindWindow (er.where, &window_ptr);
- if (tip_window && window_ptr == tip_window)
- {
- HideWindow (tip_window);
- part_code = FindWindow (er.where, &window_ptr);
- }
- }
-
- if (er.what != mouseDown
- && (part_code != inContent || dpyinfo->grabbed == 0))
- break;
-
- switch (part_code)
- {
- case inMenuBar:
- f = mac_focus_frame (dpyinfo);
- saved_menu_event_location = er.where;
- inev.kind = MENU_BAR_ACTIVATE_EVENT;
- XSETFRAME (inev.frame_or_window, f);
- break;
-
- case inContent:
- if (
-#if TARGET_API_MAC_CARBON
- FrontNonFloatingWindow ()
-#else
- FrontWindow ()
-#endif
- != window_ptr
- || (mac_window_to_frame (window_ptr)
- != dpyinfo->x_focus_frame))
- SelectWindow (window_ptr);
- else
- {
- ControlPartCode control_part_code;
- ControlRef ch;
- Point mouse_loc;
-#ifdef MAC_OSX
- ControlKind control_kind;
-#endif
-
- f = mac_window_to_frame (window_ptr);
- /* convert to local coordinates of new window */
- mouse_loc.h = (er.where.h
- - (f->left_pos
- + FRAME_OUTER_TO_INNER_DIFF_X (f)));
- mouse_loc.v = (er.where.v
- - (f->top_pos
- + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
-#if TARGET_API_MAC_CARBON
- ch = FindControlUnderMouse (mouse_loc, window_ptr,
- &control_part_code);
-#ifdef MAC_OSX
- if (ch)
- GetControlKind (ch, &control_kind);
-#endif
-#else
- control_part_code = FindControl (mouse_loc, window_ptr,
- &ch);
-#endif
-
-#if TARGET_API_MAC_CARBON
- inev.code = mac_get_mouse_btn (eventRef);
- inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
- inev.code = mac_get_emulated_btn (er.modifiers);
- inev.modifiers = mac_to_emacs_modifiers (er.modifiers, 0);
-#endif
- XSETINT (inev.x, mouse_loc.h);
- XSETINT (inev.y, mouse_loc.v);
-
- if ((dpyinfo->grabbed && tracked_scroll_bar)
- || (ch != 0
-#ifndef USE_TOOLKIT_SCROLL_BARS
- /* control_part_code becomes kControlNoPart if
- a progress indicator is clicked. */
- && control_part_code != kControlNoPart
-#else /* USE_TOOLKIT_SCROLL_BARS */
-#ifdef MAC_OSX
- && control_kind.kind == kControlKindScrollBar
-#endif /* MAC_OSX */
-#endif /* USE_TOOLKIT_SCROLL_BARS */
- ))
- {
- struct scroll_bar *bar;
-
- if (dpyinfo->grabbed && tracked_scroll_bar)
- {
- bar = tracked_scroll_bar;
-#ifndef USE_TOOLKIT_SCROLL_BARS
- control_part_code = kControlIndicatorPart;
-#endif
- }
- else
- bar = (struct scroll_bar *) GetControlReference (ch);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- /* Make the "Ctrl-Mouse-2 splits window" work
- for toolkit scroll bars. */
- if (inev.modifiers & ctrl_modifier)
- x_scroll_bar_handle_click (bar, control_part_code,
- &er, &inev);
- else if (er.what == mouseDown)
- x_scroll_bar_handle_press (bar, control_part_code,
- mouse_loc, &inev);
- else
- x_scroll_bar_handle_release (bar, &inev);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- x_scroll_bar_handle_click (bar, control_part_code,
- &er, &inev);
- if (er.what == mouseDown
- && control_part_code == kControlIndicatorPart)
- tracked_scroll_bar = bar;
- else
- tracked_scroll_bar = NULL;
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
- }
- else
- {
- Lisp_Object window;
- int x = mouse_loc.h;
- int y = mouse_loc.v;
-
- window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
- if (EQ (window, f->tool_bar_window))
- {
- if (er.what == mouseDown)
- handle_tool_bar_click (f, x, y, 1, 0);
- else
- handle_tool_bar_click (f, x, y, 0,
- inev.modifiers);
- tool_bar_p = 1;
- }
- else
- {
- XSETFRAME (inev.frame_or_window, f);
- inev.kind = MOUSE_CLICK_EVENT;
- }
- }
-
- if (er.what == mouseDown)
- {
- dpyinfo->grabbed |= (1 << inev.code);
- last_mouse_frame = f;
-
- if (!tool_bar_p)
- last_tool_bar_item = -1;
- }
- else
- {
- if ((dpyinfo->grabbed & (1 << inev.code)) == 0)
- /* If a button is released though it was not
- previously pressed, that would be because
- of multi-button emulation. */
- dpyinfo->grabbed = 0;
- else
- dpyinfo->grabbed &= ~(1 << inev.code);
- }
-
- /* Ignore any mouse motion that happened before
- this event; any subsequent mouse-movement Emacs
- events should reflect only motion after the
- ButtonPress. */
- if (f != 0)
- f->mouse_moved = 0;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (inev.kind == MOUSE_CLICK_EVENT
- || (inev.kind == SCROLL_BAR_CLICK_EVENT
- && (inev.modifiers & ctrl_modifier)))
-#endif
- switch (er.what)
- {
- case mouseDown:
- inev.modifiers |= down_modifier;
- break;
- case mouseUp:
- inev.modifiers |= up_modifier;
- break;
- }
- }
- break;
-
- case inDrag:
-#if TARGET_API_MAC_CARBON
- case inProxyIcon:
- if (IsWindowPathSelectClick (window_ptr, &er))
- {
- WindowPathSelect (window_ptr, NULL, NULL);
- break;
- }
- if (part_code == inProxyIcon
- && (TrackWindowProxyDrag (window_ptr, er.where)
- != errUserWantsToDragWindow))
- break;
- DragWindow (window_ptr, er.where, NULL);
-#else /* not TARGET_API_MAC_CARBON */
- DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
- /* Update the frame parameters. */
- {
- struct frame *f = mac_window_to_frame (window_ptr);
-
- if (f && !f->async_iconified)
- mac_handle_origin_change (f);
- }
-#endif /* not TARGET_API_MAC_CARBON */
- break;
-
- case inGoAway:
- if (TrackGoAway (window_ptr, er.where))
- {
- inev.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (inev.frame_or_window,
- mac_window_to_frame (window_ptr));
- }
- break;
-
- /* window resize handling added --ben */
- case inGrow:
- do_grow_window (window_ptr, &er);
- break;
-
- /* window zoom handling added --ben */
- case inZoomIn:
- case inZoomOut:
- if (TrackBox (window_ptr, er.where, part_code))
- do_zoom_window (window_ptr, part_code);
- break;
-
-#if USE_MAC_TOOLBAR
- case inStructure:
- {
- OSStatus err;
- HIViewRef ch;
-
- if (FrontNonFloatingWindow () != window_ptr)
- SelectWindow (window_ptr);
-
- err = HIViewGetViewForMouseEvent (HIViewGetRoot (window_ptr),
- eventRef, &ch);
- /* This doesn't work on Mac OS X 10.2. */
- if (err == noErr)
- HIViewClick (ch, eventRef);
- }
- break;
-#endif /* USE_MAC_TOOLBAR */
-
- default:
- break;
- }
- }
- break;
-
-#if !TARGET_API_MAC_CARBON
- case updateEvt:
- do_window_update ((WindowRef) er.message);
- break;
-#endif
-
- case osEvt:
-#if TARGET_API_MAC_CARBON
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
- switch ((er.message >> 24) & 0x000000FF)
- {
-#if USE_MAC_TSM
- case suspendResumeMessage:
- if (er.message & resumeFlag)
- mac_tsm_resume ();
- else
- mac_tsm_suspend ();
- break;
-#endif
-
- case mouseMovedMessage:
-#if !TARGET_API_MAC_CARBON
- SetRectRgn (mouse_region, er.where.h, er.where.v,
- er.where.h + 1, er.where.v + 1);
-#endif
- previous_help_echo_string = help_echo_string;
- help_echo_string = Qnil;
-
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f = last_mouse_frame;
- else
- f = dpyinfo->x_focus_frame;
-
- if (dpyinfo->mouse_face_hidden)
- {
- dpyinfo->mouse_face_hidden = 0;
- clear_mouse_face (dpyinfo);
- }
-
- if (f)
- {
- WindowRef wp = FRAME_MAC_WINDOW (f);
- Point mouse_pos;
-
- mouse_pos.h = (er.where.h
- - (f->left_pos
- + FRAME_OUTER_TO_INNER_DIFF_X (f)));
- mouse_pos.v = (er.where.v
- - (f->top_pos
- + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
- if (dpyinfo->grabbed && tracked_scroll_bar)
-#ifdef USE_TOOLKIT_SCROLL_BARS
- x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
- mouse_pos, &inev);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- x_scroll_bar_note_movement (tracked_scroll_bar,
- mouse_pos.v
- - XINT (tracked_scroll_bar->top),
- er.when * (1000 / 60));
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
- else
- {
- /* Generate SELECT_WINDOW_EVENTs when needed. */
- if (!NILP (Vmouse_autoselect_window))
- {
- Lisp_Object window;
-
- window = window_from_coordinates (f,
- mouse_pos.h,
- mouse_pos.v,
- 0, 0, 0, 0);
-
- /* Window will be selected only when it is
- not selected now and last mouse movement
- event was not in it. Minibuffer window
- will be selected only when it is active. */
- if (WINDOWP (window)
- && !EQ (window, last_window)
- && !EQ (window, selected_window)
- /* For click-to-focus window managers
- create event iff we don't leave the
- selected frame. */
- && (focus_follows_mouse
- || (EQ (XWINDOW (window)->frame,
- XWINDOW (selected_window)->frame))))
- {
- inev.kind = SELECT_WINDOW_EVENT;
- inev.frame_or_window = window;
- }
-
- last_window=window;
- }
- if (!note_mouse_movement (f, &mouse_pos))
- help_echo_string = previous_help_echo_string;
-#if USE_MAC_TOOLBAR
- else
- mac_tool_bar_note_mouse_movement (f, eventRef);
-#endif
- }
- }
-
- /* If the contents of the global variable
- help_echo_string has changed, generate a
- HELP_EVENT. */
- if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
- do_help = 1;
- break;
- }
- break;
-
- case activateEvt:
- {
- WindowRef window_ptr = (WindowRef) er.message;
- OSErr err;
- ControlRef root_control;
-
- if (window_ptr == tip_window)
- {
- HideWindow (tip_window);
- break;
- }
-
- if (!is_emacs_window (window_ptr))
- goto OTHER;
-
- f = mac_window_to_frame (window_ptr);
-
- if ((er.modifiers & activeFlag) != 0)
- {
- /* A window has been activated */
- Point mouse_loc;
-
- err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
- if (err == noErr)
- ActivateControl (root_control);
-
- x_detect_focus_change (dpyinfo, &er, &inev);
-
- mouse_loc.h = (er.where.h
- - (f->left_pos
- + FRAME_OUTER_TO_INNER_DIFF_X (f)));
- mouse_loc.v = (er.where.v
- - (f->top_pos
- + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
- /* Window-activated event counts as mouse movement,
- so update things that depend on mouse position. */
- note_mouse_movement (f, &mouse_loc);
- }
- else
- {
- /* A window has been deactivated */
- err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
- if (err == noErr)
- DeactivateControl (root_control);
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (dpyinfo->grabbed && tracked_scroll_bar)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = NO_EVENT;
- x_scroll_bar_handle_release (tracked_scroll_bar, &event);
- if (event.kind != NO_EVENT)
- {
- event.timestamp = timestamp;
- kbd_buffer_store_event_hold (&event, hold_quit);
- count++;
- }
- }
-#endif
- dpyinfo->grabbed = 0;
-
- x_detect_focus_change (dpyinfo, &er, &inev);
-
- if (f == dpyinfo->mouse_face_mouse_frame)
- {
- /* If we move outside the frame, then we're
- certainly no longer on any text in the
- frame. */
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_mouse_frame = 0;
- }
-
- /* Generate a nil HELP_EVENT to cancel a help-echo.
- Do it only if there's something to cancel.
- Otherwise, the startup message is cleared when the
- mouse leaves the frame. */
- if (any_help_event_p)
- do_help = -1;
- }
- }
- break;
-
- case keyDown:
- case keyUp:
- case autoKey:
- ObscureCursor ();
-
- f = mac_focus_frame (dpyinfo);
- XSETFRAME (inev.frame_or_window, f);
-
- /* If mouse-highlight is an integer, input clears out mouse
- highlighting. */
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
- {
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
- }
-
- {
- UInt32 modifiers = er.modifiers, mapped_modifiers;
- UInt32 key_code = (er.message & keyCodeMask) >> 8;
-
-#ifdef MAC_OSX
- GetEventParameter (eventRef, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
-#endif
- mapped_modifiers = mac_mapped_modifiers (modifiers, key_code);
-
-#if TARGET_API_MAC_CARBON
- if (!(mapped_modifiers
- & ~(mac_pass_command_to_system ? cmdKey : 0)
- & ~(mac_pass_control_to_system ? controlKey : 0)))
- goto OTHER;
- else
-#endif
- if (er.what != keyUp)
- do_keystroke (er.what, er.message & charCodeMask,
- key_code, modifiers, timestamp, &inev);
- }
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent (&er);
- break;
-
- default:
- OTHER:
-#if TARGET_API_MAC_CARBON
- {
- OSStatus err;
-
- read_socket_inev = &inev;
- err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- }
-#endif
- break;
- }
-#if TARGET_API_MAC_CARBON
- ReleaseEvent (eventRef);
-#endif
-
- if (inev.kind != NO_EVENT)
- {
- inev.timestamp = timestamp;
- kbd_buffer_store_event_hold (&inev, hold_quit);
- count++;
- }
-
- if (do_help
- && !(hold_quit && hold_quit->kind != NO_EVENT))
- {
- Lisp_Object frame;
-
- if (f)
- XSETFRAME (frame, f);
- else
- frame = Qnil;
-
- if (do_help > 0)
- {
- any_help_event_p = 1;
- gen_help_event (help_echo_string, frame, help_echo_window,
- help_echo_object, help_echo_pos);
- }
- else
- {
- help_echo_string = Qnil;
- gen_help_event (Qnil, frame, Qnil, Qnil, 0);
- }
- count++;
- }
- }
-
- /* If the focus was just given to an autoraising frame,
- raise it now. */
- /* ??? This ought to be able to handle more than one such frame. */
- if (pending_autoraise_frame)
- {
- x_raise_frame (pending_autoraise_frame);
- pending_autoraise_frame = 0;
- }
-
- if (mac_screen_config_changed)
- {
- mac_get_screen_info (dpyinfo);
- mac_screen_config_changed = 0;
- }
-
-#if !TARGET_API_MAC_CARBON
- /* Check which frames are still visible. We do this here because
- there doesn't seem to be any direct notification from the Window
- Manager that the visibility of a window has changed (at least,
- not in all cases). */
- {
- Lisp_Object tail, frame;
-
- FOR_EACH_FRAME (tail, frame)
- {
- struct frame *f = XFRAME (frame);
-
- /* The tooltip has been drawn already. Avoid the
- SET_FRAME_GARBAGED in mac_handle_visibility_change. */
- if (EQ (frame, tip_frame))
- continue;
-
- if (FRAME_MAC_P (f))
- mac_handle_visibility_change (f);
- }
- }
-#endif
-
- --handling_signal;
- UNBLOCK_INPUT;
- return count;
-}
-
-
-/***********************************************************************
- Busy cursor
- ***********************************************************************/
-
-#if TARGET_API_MAC_CARBON
-/* Show the spinning progress indicator for the frame F. Create it if
- it doesn't exist yet. */
-
-void
-mac_show_hourglass (f)
- struct frame *f;
-{
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- if (!f->output_data.mac->hourglass_control)
- {
- Window w = FRAME_MAC_WINDOW (f);
- Rect r;
- ControlRef c;
-
- GetWindowPortBounds (w, &r);
- r.left = r.right - HOURGLASS_WIDTH;
- r.bottom = r.top + HOURGLASS_HEIGHT;
- if (CreateChasingArrowsControl (w, &r, &c) == noErr)
- f->output_data.mac->hourglass_control = c;
- }
-
- if (f->output_data.mac->hourglass_control)
- ShowControl (f->output_data.mac->hourglass_control);
-}
-
-/* Hide the spinning progress indicator for the frame F. Do nothing
- it doesn't exist yet. */
-
-void
-mac_hide_hourglass (f)
- struct frame *f;
-{
- if (f->output_data.mac->hourglass_control)
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- HideControl (f->output_data.mac->hourglass_control);
- }
-}
-
-/* Reposition the spinning progress indicator for the frame F. Do
- nothing it doesn't exist yet. */
-
-void
-mac_reposition_hourglass (f)
- struct frame *f;
-{
- if (f->output_data.mac->hourglass_control)
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- MoveControl (f->output_data.mac->hourglass_control,
- FRAME_PIXEL_WIDTH (f) - HOURGLASS_WIDTH, 0);
- }
-}
-#endif /* TARGET_API_MAC_CARBON */
-
-
-/***********************************************************************
- File selection dialog
- ***********************************************************************/
-
-#if TARGET_API_MAC_CARBON
-extern Lisp_Object Qfile_name_history;
-
-static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage,
- NavCBRecPtr, void *));
-
-/* The actual implementation of Fx_file_dialog. */
-
-Lisp_Object
-mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p)
- Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
-{
- Lisp_Object file = Qnil;
- int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
- char filename[MAXPATHLEN];
- static NavEventUPP mac_nav_event_callbackUPP = NULL;
-
- check_mac ();
-
- GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
- CHECK_STRING (prompt);
- CHECK_STRING (dir);
-
- /* Create the dialog with PROMPT as title, using DIR as initial
- directory and using "*" as pattern. */
- dir = Fexpand_file_name (dir, Qnil);
-
- {
- OSStatus status;
- NavDialogCreationOptions options;
- NavDialogRef dialogRef;
- NavTypeListHandle fileTypes = NULL;
- NavUserAction userAction;
- CFStringRef message=NULL, saveName = NULL;
-
- BLOCK_INPUT;
- /* No need for a callback function because we are modal */
- NavGetDefaultDialogCreationOptions(&options);
- options.modality = kWindowModalityAppModal;
- options.location.h = options.location.v = -1;
- options.optionFlags = kNavDefaultNavDlogOptions;
- options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
- options.optionFlags |= kNavSelectAllReadableItem;
- options.optionFlags &= ~kNavAllowMultipleFiles;
- if (!NILP(prompt))
- {
- message = cfstring_create_with_string (prompt);
- options.message = message;
- }
- /* Don't set the application, let it use default.
- options.clientName = CFSTR ("Emacs");
- */
-
- if (mac_nav_event_callbackUPP == NULL)
- mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback);
-
- if (!NILP (only_dir_p))
- status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP,
- NULL, NULL, &dialogRef);
- else if (NILP (mustmatch))
- {
- /* This is a save dialog */
- options.optionFlags |= kNavDontConfirmReplacement;
- options.actionButtonLabel = CFSTR ("Ok");
- options.windowTitle = CFSTR ("Enter name");
-
- if (STRINGP (default_filename))
- {
- Lisp_Object utf8 = ENCODE_UTF_8 (default_filename);
- char *begPtr = SDATA(utf8);
- char *filePtr = begPtr + SBYTES(utf8);
- while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1]))
- filePtr--;
- saveName = cfstring_create_with_utf8_cstring (filePtr);
- options.saveFileName = saveName;
- options.optionFlags |= kNavSelectDefaultLocation;
- }
- status = NavCreatePutFileDialog(&options,
- 'TEXT', kNavGenericSignature,
- mac_nav_event_callbackUPP, NULL,
- &dialogRef);
- }
- else
- {
- /* This is an open dialog*/
- status = NavCreateChooseFileDialog(&options, fileTypes,
- mac_nav_event_callbackUPP, NULL,
- NULL, NULL, &dialogRef);
- }
-
- /* Set the default location and continue*/
- if (status == noErr)
- {
- Lisp_Object encoded_dir = ENCODE_FILE (dir);
- AEDesc defLocAed;
-
- status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir),
- SBYTES (encoded_dir), &defLocAed);
- if (status == noErr)
- {
- NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
- AEDisposeDesc(&defLocAed);
- }
- status = NavDialogRun(dialogRef);
- }
-
- if (saveName) CFRelease(saveName);
- if (message) CFRelease(message);
-
- if (status == noErr) {
- userAction = NavDialogGetUserAction(dialogRef);
- switch (userAction)
- {
- case kNavUserActionNone:
- case kNavUserActionCancel:
- break; /* Treat cancel like C-g */
- case kNavUserActionOpen:
- case kNavUserActionChoose:
- case kNavUserActionSaveAs:
- {
- NavReplyRecord reply;
- Size len;
-
- status = NavDialogGetReply(dialogRef, &reply);
- if (status != noErr)
- break;
- status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME,
- NULL, NULL, filename,
- sizeof (filename) - 1, &len);
- if (status == noErr)
- {
- len = min (len, sizeof (filename) - 1);
- filename[len] = '\0';
- if (reply.saveFileName)
- {
- /* If it was a saved file, we need to add the file name */
- if (len && len < sizeof (filename) - 1
- && filename[len-1] != '/')
- filename[len++] = '/';
- CFStringGetCString(reply.saveFileName, filename+len,
- sizeof (filename) - len,
-#ifdef MAC_OSX
- kCFStringEncodingUTF8
-#else
- CFStringGetSystemEncoding ()
-#endif
- );
- }
- file = DECODE_FILE (make_unibyte_string (filename,
- strlen (filename)));
- }
- NavDisposeReply(&reply);
- }
- break;
- }
- NavDialogDispose(dialogRef);
- UNBLOCK_INPUT;
- }
- else {
- UNBLOCK_INPUT;
- /* Fall back on minibuffer if there was a problem */
- file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
- dir, mustmatch, dir, Qfile_name_history,
- default_filename, Qnil);
- }
- }
-
- UNGCPRO;
-
- /* Make "Cancel" equivalent to C-g. */
- if (NILP (file))
- Fsignal (Qquit, Qnil);
-
- return unbind_to (count, file);
-}
-
-/* Need to register some event callback function for enabling drag and
- drop in Navigation Service dialogs. */
-static pascal void
-mac_nav_event_callback (selector, parms, data)
- NavEventCallbackMessage selector;
- NavCBRecPtr parms;
- void *data;
-{
-}
-#endif
-
-
-/************************************************************************
- Menu
- ************************************************************************/
-
-#if !TARGET_API_MAC_CARBON
-#include <MacTypes.h>
-#include <Menus.h>
-#include <Quickdraw.h>
-#include <ToolUtils.h>
-#include <Fonts.h>
-#include <Controls.h>
-#include <Windows.h>
-#include <Events.h>
-#if defined (__MRC__) || (__MSL__ >= 0x6000)
-#include <ControlDefinitions.h>
-#endif
-#endif /* not TARGET_API_MAC_CARBON */
-
-extern int menu_item_selection;
-extern int popup_activated_flag;
-extern int name_is_separator P_ ((const char *));
-extern void find_and_call_menu_selection P_ ((FRAME_PTR, int, Lisp_Object,
- void *));
-extern void set_frame_menubar P_ ((FRAME_PTR, int, int));
-
-enum mac_menu_kind { /* Menu ID range */
- MAC_MENU_APPLE, /* 0 (Reserved by Apple) */
- MAC_MENU_MENU_BAR, /* 1 .. 233 */
- MAC_MENU_M_APPLE, /* 234 (== M_APPLE) */
- MAC_MENU_POPUP, /* 235 */
- MAC_MENU_DRIVER, /* 236 .. 255 (Reserved) */
- MAC_MENU_MENU_BAR_SUB, /* 256 .. 16383 */
- MAC_MENU_POPUP_SUB, /* 16384 .. 32767 */
- MAC_MENU_END /* 32768 */
-};
-
-static const int min_menu_id[] = {0, 1, 234, 235, 236, 256, 16384, 32768};
-
-static int fill_menu P_ ((MenuRef, widget_value *, enum mac_menu_kind, int));
-static void dispose_menus P_ ((enum mac_menu_kind, int));
-
-#if !TARGET_API_MAC_CARBON
-static void
-do_apple_menu (SInt16 menu_item)
-{
- Str255 item_name;
- SInt16 da_driver_refnum;
-
- if (menu_item == I_ABOUT)
- NoteAlert (ABOUT_ALERT_ID, NULL);
- else
- {
- GetMenuItemText (GetMenuRef (M_APPLE), menu_item, item_name);
- da_driver_refnum = OpenDeskAcc (item_name);
- }
-}
-#endif /* !TARGET_API_MAC_CARBON */
-
-/* Activate the menu bar of frame F.
- This is called from keyboard.c when it gets the
- MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
-
- To activate the menu bar, we use the button-press event location
- that was saved in saved_menu_event_location.
-
- But first we recompute the menu bar contents (the whole tree).
-
- The reason for saving the button event until here, instead of
- passing it to the toolkit right away, is that we can safely
- execute Lisp code. */
-
-void
-x_activate_menubar (f)
- FRAME_PTR f;
-{
- SInt32 menu_choice;
- SInt16 menu_id, menu_item;
-
- set_frame_menubar (f, 0, 1);
- BLOCK_INPUT;
-
- popup_activated_flag = 1;
- menu_choice = MenuSelect (saved_menu_event_location);
- popup_activated_flag = 0;
- menu_id = HiWord (menu_choice);
- menu_item = LoWord (menu_choice);
-
-#if !TARGET_API_MAC_CARBON
- if (menu_id == min_menu_id[MAC_MENU_M_APPLE])
- do_apple_menu (menu_item);
- else
-#endif
- if (menu_id)
- {
- MenuRef menu = GetMenuRef (menu_id);
-
- if (menu)
- {
- UInt32 refcon;
-
- GetMenuItemRefCon (menu, menu_item, &refcon);
- find_and_call_menu_selection (f, f->menu_bar_items_used,
- f->menu_bar_vector, (void *) refcon);
- }
- }
-
- HiliteMenu (0);
-
- UNBLOCK_INPUT;
-}
-
-#if TARGET_API_MAC_CARBON
-extern Lisp_Object Vshow_help_function;
-
-static Lisp_Object
-restore_show_help_function (old_show_help_function)
- Lisp_Object old_show_help_function;
-{
- Vshow_help_function = old_show_help_function;
-
- return Qnil;
-}
-
-static pascal OSStatus
-menu_target_item_handler (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err;
- MenuRef menu;
- MenuItemIndex menu_item;
- Lisp_Object help;
- GrafPtr port;
- int specpdl_count = SPECPDL_INDEX ();
-
- /* Don't be bothered with the overflowed toolbar items menu. */
- if (!popup_activated ())
- return eventNotHandledErr;
-
- err = GetEventParameter (event, kEventParamDirectObject, typeMenuRef,
- NULL, sizeof (MenuRef), NULL, &menu);
- if (err == noErr)
- err = GetEventParameter (event, kEventParamMenuItemIndex,
- typeMenuItemIndex, NULL,
- sizeof (MenuItemIndex), NULL, &menu_item);
- if (err == noErr)
- err = GetMenuItemProperty (menu, menu_item,
- MAC_EMACS_CREATOR_CODE, 'help',
- sizeof (Lisp_Object), NULL, &help);
- if (err != noErr)
- help = Qnil;
-
- /* Temporarily bind Vshow_help_function to Qnil because we don't
- want tooltips during menu tracking. */
- record_unwind_protect (restore_show_help_function, Vshow_help_function);
- Vshow_help_function = Qnil;
- GetPort (&port);
- show_help_echo (help, Qnil, Qnil, Qnil, 1);
- SetPort (port);
- unbind_to (specpdl_count, Qnil);
-
- return err == noErr ? noErr : eventNotHandledErr;
-}
-
-/* Showing help echo string during menu tracking. */
-
-static OSStatus
-install_menu_target_item_handler ()
-{
- static const EventTypeSpec specs[] =
- {{kEventClassMenu, kEventMenuTargetItem}};
-
- return InstallApplicationEventHandler (NewEventHandlerUPP
- (menu_target_item_handler),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
-}
-#endif /* TARGET_API_MAC_CARBON */
-
-/* Event handler function that pops down a menu on C-g. We can only pop
- down menus if CancelMenuTracking is present (OSX 10.3 or later). */
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-static pascal OSStatus
-menu_quit_handler (nextHandler, theEvent, userData)
- EventHandlerCallRef nextHandler;
- EventRef theEvent;
- void* userData;
-{
- OSStatus err;
- UInt32 keyCode;
- UInt32 keyModifiers;
-
- err = GetEventParameter (theEvent, kEventParamKeyCode,
- typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
-
- if (err == noErr)
- err = GetEventParameter (theEvent, kEventParamKeyModifiers,
- typeUInt32, NULL, sizeof(UInt32),
- NULL, &keyModifiers);
-
- if (err == noErr && mac_quit_char_key_p (keyModifiers, keyCode))
- {
- MenuRef menu = userData != 0
- ? (MenuRef)userData : AcquireRootMenu ();
-
- CancelMenuTracking (menu, true, 0);
- if (!userData) ReleaseMenu (menu);
- return noErr;
- }
-
- return CallNextEventHandler (nextHandler, theEvent);
-}
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-
-/* Add event handler to all menus that belong to KIND so we can detect
- C-g. ROOT_MENU is the root menu of the tracking session to dismiss
- when C-g is detected. NULL means the menu bar. If
- CancelMenuTracking isn't available, do nothing. */
-
-static void
-install_menu_quit_handler (kind, root_menu)
- enum mac_menu_kind kind;
- MenuRef root_menu;
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- static const EventTypeSpec typesList[] =
- {{kEventClassKeyboard, kEventRawKeyDown}};
- int id;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CancelMenuTracking == NULL)
- return;
-#endif
- for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++)
- {
- MenuRef menu = GetMenuRef (id);
-
- if (menu == NULL)
- break;
- InstallMenuEventHandler (menu, menu_quit_handler,
- GetEventTypeCount (typesList),
- typesList, root_menu, NULL);
- }
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-}
-
-static Lisp_Object
-pop_down_menu (arg)
- Lisp_Object arg;
-{
- struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
- FRAME_PTR f = p->pointer;
- MenuRef menu = GetMenuRef (min_menu_id[MAC_MENU_POPUP]);
-
- BLOCK_INPUT;
-
- /* Must reset this manually because the button release event is not
- passed to Emacs event loop. */
- FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
-
- /* delete all menus */
- dispose_menus (MAC_MENU_POPUP_SUB, 0);
- DeleteMenu (min_menu_id[MAC_MENU_POPUP]);
- DisposeMenu (menu);
-
- UNBLOCK_INPUT;
-
- return Qnil;
-}
-
-/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop
- until the menu pops down. Return the selection. */
-
-void
-create_and_show_popup_menu (f, first_wv, x, y, for_click)
- FRAME_PTR f;
- widget_value *first_wv;
- int x;
- int y;
- int for_click;
-{
- int result = 0;
- MenuRef menu = NewMenu (min_menu_id[MAC_MENU_POPUP], "\p");
- int menu_item_choice;
- int specpdl_count = SPECPDL_INDEX ();
-
- InsertMenu (menu, -1);
- fill_menu (menu, first_wv->contents, MAC_MENU_POPUP_SUB,
- min_menu_id[MAC_MENU_POPUP_SUB]);
-
- /* Add event handler so we can detect C-g. */
- install_menu_quit_handler (MAC_MENU_POPUP, menu);
- install_menu_quit_handler (MAC_MENU_POPUP_SUB, menu);
-
- record_unwind_protect (pop_down_menu, make_save_value (f, 0));
-
- /* Adjust coordinates to be root-window-relative. */
- x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-
- /* Display the menu. */
- popup_activated_flag = 1;
- menu_item_choice = PopUpMenuSelect (menu, y, x, 0);
- popup_activated_flag = 0;
-
- /* Get the refcon to find the correct item */
- if (menu_item_choice)
- {
- MenuRef sel_menu = GetMenuRef (HiWord (menu_item_choice));
-
- if (sel_menu)
- GetMenuItemRefCon (sel_menu, LoWord (menu_item_choice),
- (UInt32 *) &result);
- }
-
- unbind_to (specpdl_count, Qnil);
-
- menu_item_selection = result;
-}
-
-static void
-add_menu_item (menu, pos, wv)
- MenuRef menu;
- int pos;
- widget_value *wv;
-{
-#if TARGET_API_MAC_CARBON
- CFStringRef item_name;
-#else
- Str255 item_name;
-#endif
-
- if (name_is_separator (wv->name))
- AppendMenu (menu, "\p-");
- else
- {
- AppendMenu (menu, "\pX");
-
-#if TARGET_API_MAC_CARBON
- item_name = cfstring_create_with_utf8_cstring (wv->name);
-
- if (wv->key != NULL)
- {
- CFStringRef name, key;
-
- name = item_name;
- key = cfstring_create_with_utf8_cstring (wv->key);
- item_name = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@ %@"),
- name, key);
- CFRelease (name);
- CFRelease (key);
- }
-
- SetMenuItemTextWithCFString (menu, pos, item_name);
- CFRelease (item_name);
-
- if (wv->enabled)
- EnableMenuItem (menu, pos);
- else
- DisableMenuItem (menu, pos);
-
- if (STRINGP (wv->help))
- SetMenuItemProperty (menu, pos, MAC_EMACS_CREATOR_CODE, 'help',
- sizeof (Lisp_Object), &wv->help);
-#else /* ! TARGET_API_MAC_CARBON */
- item_name[sizeof (item_name) - 1] = '\0';
- strncpy (item_name, wv->name, sizeof (item_name) - 1);
- if (wv->key != NULL)
- {
- int len = strlen (item_name);
-
- strncpy (item_name + len, " ", sizeof (item_name) - 1 - len);
- len = strlen (item_name);
- strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len);
- }
- c2pstr (item_name);
- SetMenuItemText (menu, pos, item_name);
-
- if (wv->enabled)
- EnableItem (menu, pos);
- else
- DisableItem (menu, pos);
-#endif /* ! TARGET_API_MAC_CARBON */
-
- /* Draw radio buttons and tickboxes. */
- if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE
- || wv->button_type == BUTTON_TYPE_RADIO))
- SetItemMark (menu, pos, checkMark);
- else
- SetItemMark (menu, pos, noMark);
-
- SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
- }
-}
-
-/* Construct native Mac OS menu based on widget_value tree. */
-
-static int
-fill_menu (menu, wv, kind, submenu_id)
- MenuRef menu;
- widget_value *wv;
- enum mac_menu_kind kind;
- int submenu_id;
-{
- int pos;
-
- for (pos = 1; wv != NULL; wv = wv->next, pos++)
- {
- add_menu_item (menu, pos, wv);
- if (wv->contents && submenu_id < min_menu_id[kind + 1])
- {
- MenuRef submenu = NewMenu (submenu_id, "\pX");
-
- InsertMenu (submenu, -1);
-#if TARGET_API_MAC_CARBON
- SetMenuItemHierarchicalMenu (menu, pos, submenu);
-#else
- SetMenuItemHierarchicalID (menu, pos, submenu_id);
-#endif
- submenu_id = fill_menu (submenu, wv->contents, kind, submenu_id + 1);
- }
- }
-
- return submenu_id;
-}
-
-/* Fill menu bar with the items defined by WV. If DEEP_P, consider
- the entire menu trees we supply, rather than just the menu bar item
- names. */
-
-void
-mac_fill_menubar (wv, deep_p)
- widget_value *wv;
- int deep_p;
-{
- int id, submenu_id;
-#if !TARGET_API_MAC_CARBON
- int title_changed_p = 0;
-#endif
-
- /* Clean up the menu bar when filled by the entire menu trees. */
- if (deep_p)
- {
- dispose_menus (MAC_MENU_MENU_BAR, 0);
- dispose_menus (MAC_MENU_MENU_BAR_SUB, 0);
-#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
-#endif
- }
-
- /* Fill menu bar titles and submenus. Reuse the existing menu bar
- titles as much as possible to minimize redraw (if !deep_p). */
- submenu_id = min_menu_id[MAC_MENU_MENU_BAR_SUB];
- for (id = min_menu_id[MAC_MENU_MENU_BAR];
- wv != NULL && id < min_menu_id[MAC_MENU_MENU_BAR + 1];
- wv = wv->next, id++)
- {
- OSStatus err = noErr;
- MenuRef menu;
-#if TARGET_API_MAC_CARBON
- CFStringRef title;
-
- title = CFStringCreateWithCString (NULL, wv->name,
- kCFStringEncodingMacRoman);
-#else
- Str255 title;
-
- strncpy (title, wv->name, 255);
- title[255] = '\0';
- c2pstr (title);
-#endif
-
- menu = GetMenuRef (id);
- if (menu)
- {
-#if TARGET_API_MAC_CARBON
- CFStringRef old_title;
-
- err = CopyMenuTitleAsCFString (menu, &old_title);
- if (err == noErr)
- {
- if (CFStringCompare (title, old_title, 0) != kCFCompareEqualTo)
- {
-#ifdef MAC_OSX
- if (id + 1 == min_menu_id[MAC_MENU_MENU_BAR + 1]
- || GetMenuRef (id + 1) == NULL)
- {
- /* This is a workaround for Mac OS X 10.5 where
- just calling SetMenuTitleWithCFString fails
- to change the title of the last (Help) menu
- in the menu bar. */
- DeleteMenu (id);
- DisposeMenu (menu);
- menu = NULL;
- }
- else
-#endif /* MAC_OSX */
- err = SetMenuTitleWithCFString (menu, title);
- }
- CFRelease (old_title);
- }
- else
- err = SetMenuTitleWithCFString (menu, title);
-#else /* !TARGET_API_MAC_CARBON */
- if (!EqualString (title, (*menu)->menuData, false, false))
- {
- DeleteMenu (id);
- DisposeMenu (menu);
- menu = NewMenu (id, title);
- InsertMenu (menu, GetMenuRef (id + 1) ? id + 1 : 0);
- title_changed_p = 1;
- }
-#endif /* !TARGET_API_MAC_CARBON */
- }
-
- if (!menu)
- {
-#if TARGET_API_MAC_CARBON
- err = CreateNewMenu (id, 0, &menu);
- if (err == noErr)
- err = SetMenuTitleWithCFString (menu, title);
-#else
- menu = NewMenu (id, title);
-#endif
- if (err == noErr)
- {
- InsertMenu (menu, 0);
-#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
-#endif
- }
- }
-#if TARGET_API_MAC_CARBON
- CFRelease (title);
-#endif
-
- if (err == noErr)
- if (wv->contents)
- submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB,
- submenu_id);
- }
-
- if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuRef (id))
- {
- dispose_menus (MAC_MENU_MENU_BAR, id);
-#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
-#endif
- }
-
-#if !TARGET_API_MAC_CARBON
- if (title_changed_p)
- InvalMenuBar ();
-#endif
-
- /* Add event handler so we can detect C-g. */
- install_menu_quit_handler (MAC_MENU_MENU_BAR, NULL);
- install_menu_quit_handler (MAC_MENU_MENU_BAR_SUB, NULL);
-}
-
-/* Dispose of menus that belong to KIND, and remove them from the menu
- list. ID is the lower bound of menu IDs that will be processed. */
-
-static void
-dispose_menus (kind, id)
- enum mac_menu_kind kind;
- int id;
-{
- for (id = max (id, min_menu_id[kind]); id < min_menu_id[kind + 1]; id++)
- {
- MenuRef menu = GetMenuRef (id);
-
- if (menu == NULL)
- break;
- DeleteMenu (id);
- DisposeMenu (menu);
- }
-}
-
-static void
-init_menu_bar ()
-{
-#ifdef MAC_OSX
- OSStatus err;
- MenuRef menu;
- MenuItemIndex menu_index;
-
- err = GetIndMenuItemWithCommandID (NULL, kHICommandQuit, 1,
- &menu, &menu_index);
- if (err == noErr)
- SetMenuItemCommandKey (menu, menu_index, false, 0);
- EnableMenuCommand (NULL, kHICommandPreferences);
- err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1,
- &menu, &menu_index);
- if (err == noErr)
- {
- SetMenuItemCommandKey (menu, menu_index, false, 0);
- InsertMenuItemTextWithCFString (menu, NULL,
- 0, kMenuItemAttrSeparator, 0);
- InsertMenuItemTextWithCFString (menu, CFSTR ("About Emacs"),
- 0, 0, kHICommandAbout);
- }
-#else /* !MAC_OSX */
-#if TARGET_API_MAC_CARBON
- SetMenuItemCommandID (GetMenuRef (M_APPLE), I_ABOUT, kHICommandAbout);
-#endif
-#endif
-}
-
-
-/***********************************************************************
- Popup Dialog
- ***********************************************************************/
-
-#if TARGET_API_MAC_CARBON
-#define DIALOG_BUTTON_COMMAND_ID_OFFSET 'Bt\0\0'
-#define DIALOG_BUTTON_COMMAND_ID_P(id) \
- (((id) & ~0xffff) == DIALOG_BUTTON_COMMAND_ID_OFFSET)
-#define DIALOG_BUTTON_COMMAND_ID_VALUE(id) \
- ((id) - DIALOG_BUTTON_COMMAND_ID_OFFSET)
-#define DIALOG_BUTTON_MAKE_COMMAND_ID(value) \
- ((value) + DIALOG_BUTTON_COMMAND_ID_OFFSET)
-
-extern EMACS_TIME timer_check P_ ((int));
-static int quit_dialog_event_loop;
-
-static pascal OSStatus
-mac_handle_dialog_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result = eventNotHandledErr;
- WindowRef window = (WindowRef) data;
-
- switch (GetEventClass (event))
- {
- case kEventClassCommand:
- {
- HICommand command;
-
- err = GetEventParameter (event, kEventParamDirectObject,
- typeHICommand, NULL, sizeof (HICommand),
- NULL, &command);
- if (err == noErr)
- if (DIALOG_BUTTON_COMMAND_ID_P (command.commandID))
- {
- SetWRefCon (window, command.commandID);
- quit_dialog_event_loop = 1;
- break;
- }
-
- result = CallNextEventHandler (next_handler, event);
- }
- break;
-
- case kEventClassKeyboard:
- {
- OSStatus result;
- char char_code;
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- break;
-
- err = GetEventParameter (event, kEventParamKeyMacCharCodes,
- typeChar, NULL, sizeof (char),
- NULL, &char_code);
- if (err == noErr)
- switch (char_code)
- {
- case kEscapeCharCode:
- quit_dialog_event_loop = 1;
- break;
-
- default:
- {
- UInt32 modifiers, key_code;
-
- err = GetEventParameter (event, kEventParamKeyModifiers,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &modifiers);
- if (err == noErr)
- err = GetEventParameter (event, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr)
- if (mac_quit_char_key_p (modifiers, key_code))
- quit_dialog_event_loop = 1;
- }
- break;
- }
- }
- break;
-
- default:
- abort ();
- }
-
- if (quit_dialog_event_loop)
- {
- err = QuitEventLoop (GetCurrentEventLoop ());
- if (err == noErr)
- result = noErr;
- }
-
- return result;
-}
-
-static OSStatus
-install_dialog_event_handler (window)
- WindowRef window;
-{
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess},
- {kEventClassKeyboard, kEventRawKeyDown}};
- static EventHandlerUPP handle_dialog_eventUPP = NULL;
-
- if (handle_dialog_eventUPP == NULL)
- handle_dialog_eventUPP = NewEventHandlerUPP (mac_handle_dialog_event);
- return InstallWindowEventHandler (window, handle_dialog_eventUPP,
- GetEventTypeCount (specs), specs,
- window, NULL);
-}
-
-static Lisp_Object
-pop_down_dialog (arg)
- Lisp_Object arg;
-{
- struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
- WindowRef window = p->pointer;
-
- BLOCK_INPUT;
-
- if (popup_activated_flag)
- EndAppModalStateForWindow (window);
- DisposeWindow (window);
- popup_activated_flag = 0;
-
- UNBLOCK_INPUT;
-
- return Qnil;
-}
-
-/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
- dialog pops down.
- menu_item_selection will be set to the selection. */
-
-void
-create_and_show_dialog (f, first_wv)
- FRAME_PTR f;
- widget_value *first_wv;
-{
- OSStatus err;
- char *dialog_name, *message;
- int nb_buttons, first_group_count, i, result = 0;
- widget_value *wv;
- short buttons_height, text_height, inner_width, inner_height;
- Rect empty_rect, *rects;
- WindowRef window = NULL;
- ControlRef *buttons, default_button = NULL, text;
- int specpdl_count = SPECPDL_INDEX ();
-
- dialog_name = first_wv->name;
- nb_buttons = dialog_name[1] - '0';
- first_group_count = nb_buttons - (dialog_name[4] - '0');
-
- wv = first_wv->contents;
- message = wv->value;
-
- wv = wv->next;
- SetRect (&empty_rect, 0, 0, 0, 0);
-
- /* Create dialog window. */
- err = CreateNewWindow (kMovableModalWindowClass,
- kWindowStandardHandlerAttribute,
- &empty_rect, &window);
- if (err == noErr)
- {
- record_unwind_protect (pop_down_dialog, make_save_value (window, 0));
- err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
- true);
- }
- if (err == noErr)
- err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
- ? CFSTR ("Question")
- : CFSTR ("Information")));
-
- /* Create button controls and measure their optimal bounds. */
- if (err == noErr)
- {
- buttons = alloca (sizeof (ControlRef) * nb_buttons);
- rects = alloca (sizeof (Rect) * nb_buttons);
- for (i = 0; i < nb_buttons; i++)
- {
- CFStringRef label = cfstring_create_with_utf8_cstring (wv->value);
-
- if (label == NULL)
- err = memFullErr;
- else
- {
- err = CreatePushButtonControl (window, &empty_rect,
- label, &buttons[i]);
- CFRelease (label);
- }
- if (err == noErr)
- {
- if (!wv->enabled)
- {
-#ifdef MAC_OSX
- err = DisableControl (buttons[i]);
-#else
- err = DeactivateControl (buttons[i]);
-#endif
- }
- else if (default_button == NULL)
- default_button = buttons[i];
- }
- if (err == noErr)
- {
- SInt16 unused;
-
- rects[i] = empty_rect;
- err = GetBestControlRect (buttons[i], &rects[i], &unused);
- }
- if (err == noErr)
- {
- UInt32 command_id;
-
- OffsetRect (&rects[i], -rects[i].left, -rects[i].top);
- if (rects[i].right < DIALOG_BUTTON_MIN_WIDTH)
- rects[i].right = DIALOG_BUTTON_MIN_WIDTH;
- else if (rects[i].right > DIALOG_MAX_INNER_WIDTH)
- rects[i].right = DIALOG_MAX_INNER_WIDTH;
-
- command_id = DIALOG_BUTTON_MAKE_COMMAND_ID ((int) wv->call_data);
- err = SetControlCommandID (buttons[i], command_id);
- }
- if (err != noErr)
- break;
- wv = wv->next;
- }
- }
-
- /* Layout buttons. rects[i] is set relative to the bottom-right
- corner of the inner box. */
- if (err == noErr)
- {
- short bottom, right, max_height, left_align_shift;
-
- inner_width = DIALOG_MIN_INNER_WIDTH;
- bottom = right = max_height = 0;
- for (i = 0; i < nb_buttons; i++)
- {
- if (right - rects[i].right < - inner_width)
- {
- if (i != first_group_count
- && right - rects[i].right >= - DIALOG_MAX_INNER_WIDTH)
- inner_width = - (right - rects[i].right);
- else
- {
- bottom -= max_height + DIALOG_BUTTON_BUTTON_VERTICAL_SPACE;
- right = max_height = 0;
- }
- }
- if (max_height < rects[i].bottom)
- max_height = rects[i].bottom;
- OffsetRect (&rects[i], right - rects[i].right,
- bottom - rects[i].bottom);
- right = rects[i].left - DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
- if (i == first_group_count - 1)
- right -= DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
- }
- buttons_height = - (bottom - max_height);
-
- left_align_shift = - (inner_width + rects[nb_buttons - 1].left);
- for (i = nb_buttons - 1; i >= first_group_count; i--)
- {
- if (bottom != rects[i].bottom)
- {
- left_align_shift = - (inner_width + rects[i].left);
- bottom = rects[i].bottom;
- }
- OffsetRect (&rects[i], left_align_shift, 0);
- }
- }
-
- /* Create a static text control and measure its bounds. */
- if (err == noErr)
- {
- CFStringRef message_string;
- Rect bounds;
-
- message_string = cfstring_create_with_utf8_cstring (message);
- if (message_string == NULL)
- err = memFullErr;
- else
- {
- ControlFontStyleRec text_style;
-
- text_style.flags = 0;
- SetRect (&bounds, 0, 0, inner_width, 0);
- err = CreateStaticTextControl (window, &bounds, message_string,
- &text_style, &text);
- CFRelease (message_string);
- }
- if (err == noErr)
- {
- SInt16 unused;
-
- bounds = empty_rect;
- err = GetBestControlRect (text, &bounds, &unused);
- }
- if (err == noErr)
- {
- text_height = bounds.bottom - bounds.top;
- if (text_height < DIALOG_TEXT_MIN_HEIGHT)
- text_height = DIALOG_TEXT_MIN_HEIGHT;
- }
- }
-
- /* Place buttons. */
- if (err == noErr)
- {
- inner_height = (text_height + DIALOG_TEXT_BUTTONS_VERTICAL_SPACE
- + buttons_height);
-
- for (i = 0; i < nb_buttons; i++)
- {
- OffsetRect (&rects[i], DIALOG_LEFT_MARGIN + inner_width,
- DIALOG_TOP_MARGIN + inner_height);
- SetControlBounds (buttons[i], &rects[i]);
- }
- }
-
- /* Place text. */
- if (err == noErr)
- {
- Rect bounds;
-
- SetRect (&bounds, DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN,
- DIALOG_LEFT_MARGIN + inner_width,
- DIALOG_TOP_MARGIN + text_height);
- SetControlBounds (text, &bounds);
- }
-
- /* Create the application icon at the upper-left corner. */
- if (err == noErr)
- {
- ControlButtonContentInfo content;
- ControlRef icon;
- static const ProcessSerialNumber psn = {0, kCurrentProcess};
-#ifdef MAC_OSX
- FSRef app_location;
-#else
- ProcessInfoRec pinfo;
- FSSpec app_spec;
-#endif
- SInt16 unused;
-
- content.contentType = kControlContentIconRef;
-#ifdef MAC_OSX
- err = GetProcessBundleLocation (&psn, &app_location);
- if (err == noErr)
- err = GetIconRefFromFileInfo (&app_location, 0, NULL, 0, NULL,
- kIconServicesNormalUsageFlag,
- &content.u.iconRef, &unused);
-#else
- bzero (&pinfo, sizeof (ProcessInfoRec));
- pinfo.processInfoLength = sizeof (ProcessInfoRec);
- pinfo.processAppSpec = &app_spec;
- err = GetProcessInformation (&psn, &pinfo);
- if (err == noErr)
- err = GetIconRefFromFile (&app_spec, &content.u.iconRef, &unused);
-#endif
- if (err == noErr)
- {
- Rect bounds;
-
- SetRect (&bounds, DIALOG_ICON_LEFT_MARGIN, DIALOG_ICON_TOP_MARGIN,
- DIALOG_ICON_LEFT_MARGIN + DIALOG_ICON_WIDTH,
- DIALOG_ICON_TOP_MARGIN + DIALOG_ICON_HEIGHT);
- err = CreateIconControl (window, &bounds, &content, true, &icon);
- ReleaseIconRef (content.u.iconRef);
- }
- }
-
- /* Show the dialog window and run event loop. */
- if (err == noErr)
- if (default_button)
- err = SetWindowDefaultButton (window, default_button);
- if (err == noErr)
- err = install_dialog_event_handler (window);
- if (err == noErr)
- {
- SizeWindow (window,
- DIALOG_LEFT_MARGIN + inner_width + DIALOG_RIGHT_MARGIN,
- DIALOG_TOP_MARGIN + inner_height + DIALOG_BOTTOM_MARGIN,
- true);
- err = RepositionWindow (window, FRAME_MAC_WINDOW (f),
- kWindowAlertPositionOnParentWindow);
- }
- if (err == noErr)
- {
- SetWRefCon (window, 0);
- ShowWindow (window);
- BringToFront (window);
- popup_activated_flag = 1;
- err = BeginAppModalStateForWindow (window);
- }
- if (err == noErr)
- {
- EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget ();
-
- quit_dialog_event_loop = 0;
- while (1)
- {
- EMACS_TIME next_time = timer_check (1);
- long secs = EMACS_SECS (next_time);
- long usecs = EMACS_USECS (next_time);
- EventTimeout timeout;
- EventRef event;
-
- if (secs < 0 || (secs == 0 && usecs == 0))
- {
- /* Sometimes timer_check returns -1 (no timers) even if
- there are timers. So do a timeout anyway. */
- secs = 1;
- usecs = 0;
- }
-
- timeout = (secs * kEventDurationSecond
- + usecs * kEventDurationMicrosecond);
- err = ReceiveNextEvent (0, NULL, timeout, kEventRemoveFromQueue,
- &event);
- if (err == noErr)
- {
- SendEventToEventTarget (event, toolbox_dispatcher);
- ReleaseEvent (event);
- }
-#if 0 /* defined (MAC_OSX) */
- else if (err != eventLoopTimedOutErr)
- {
- if (err == eventLoopQuitErr)
- err = noErr;
- break;
- }
-#else
- /* The return value of ReceiveNextEvent seems to be
- unreliable. Use our own global variable instead. */
- if (quit_dialog_event_loop)
- {
- err = noErr;
- break;
- }
-#endif
- }
- }
- if (err == noErr)
- {
- UInt32 command_id = GetWRefCon (window);
-
- if (DIALOG_BUTTON_COMMAND_ID_P (command_id))
- result = DIALOG_BUTTON_COMMAND_ID_VALUE (command_id);
- }
-
- unbind_to (specpdl_count, Qnil);
-
- menu_item_selection = result;
-}
-#else /* not TARGET_API_MAC_CARBON */
-#define DIALOG_WINDOW_RESOURCE 130
-
-int
-mac_dialog (widget_value *wv)
-{
- char *dialog_name;
- char *prompt;
- char **button_labels;
- UInt32 *ref_cons;
- int nb_buttons;
- int left_count;
- int i;
- int dialog_width;
- Rect rect;
- WindowRef window_ptr;
- ControlRef ch;
- int left;
- EventRecord event_record;
- SInt16 part_code;
- int control_part_code;
- Point mouse;
-
- dialog_name = wv->name;
- nb_buttons = dialog_name[1] - '0';
- left_count = nb_buttons - (dialog_name[4] - '0');
- button_labels = (char **) alloca (sizeof (char *) * nb_buttons);
- ref_cons = (UInt32 *) alloca (sizeof (UInt32) * nb_buttons);
-
- wv = wv->contents;
- prompt = (char *) alloca (strlen (wv->value) + 1);
- strcpy (prompt, wv->value);
- c2pstr (prompt);
-
- wv = wv->next;
- for (i = 0; i < nb_buttons; i++)
- {
- button_labels[i] = wv->value;
- button_labels[i] = (char *) alloca (strlen (wv->value) + 1);
- strcpy (button_labels[i], wv->value);
- c2pstr (button_labels[i]);
- ref_cons[i] = (UInt32) wv->call_data;
- wv = wv->next;
- }
-
- window_ptr = GetNewCWindow (DIALOG_WINDOW_RESOURCE, NULL, (WindowRef) -1);
-
- SetPortWindowPort (window_ptr);
-
- TextFont (0);
- /* Left and right margins in the dialog are 13 pixels each.*/
- dialog_width = 14;
- /* Calculate width of dialog box: 8 pixels on each side of the text
- label in each button, 12 pixels between buttons. */
- for (i = 0; i < nb_buttons; i++)
- dialog_width += StringWidth (button_labels[i]) + 16 + 12;
-
- if (left_count != 0 && nb_buttons - left_count != 0)
- dialog_width += 12;
-
- dialog_width = max (dialog_width, StringWidth (prompt) + 26);
-
- SizeWindow (window_ptr, dialog_width, 78, 0);
- ShowWindow (window_ptr);
-
- SetPortWindowPort (window_ptr);
-
- TextFont (0);
-
- MoveTo (13, 29);
- DrawString (prompt);
-
- left = 13;
- for (i = 0; i < nb_buttons; i++)
- {
- int button_width = StringWidth (button_labels[i]) + 16;
- SetRect (&rect, left, 45, left + button_width, 65);
- ch = NewControl (window_ptr, &rect, button_labels[i], 1, 0, 0, 0,
- kControlPushButtonProc, ref_cons[i]);
- left += button_width + 12;
- if (i == left_count - 1)
- left += 12;
- }
-
- i = 0;
- while (!i)
- {
- if (WaitNextEvent (mDownMask, &event_record, 10, NULL))
- if (event_record.what == mouseDown)
- {
- part_code = FindWindow (event_record.where, &window_ptr);
- if (part_code == inContent)
- {
- mouse = event_record.where;
- GlobalToLocal (&mouse);
- control_part_code = FindControl (mouse, window_ptr, &ch);
- if (control_part_code == kControlButtonPart)
- if (TrackControl (ch, mouse, NULL))
- i = GetControlReference (ch);
- }
- }
- }
-
- DisposeWindow (window_ptr);
-
- return i;
-}
-#endif /* not TARGET_API_MAC_CARBON */
-
-
-/***********************************************************************
- Selection support
-***********************************************************************/
-
-#if !TARGET_API_MAC_CARBON
-#include <Scrap.h>
-#include <Endian.h>
-#endif
-
-extern Lisp_Object Vselection_converter_alist;
-extern Lisp_Object Qmac_scrap_name, Qmac_ostype;
-
-static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object,
- Selection));
-
-/* Get a reference to the selection corresponding to the symbol SYM.
- The reference is set to *SEL, and it becomes NULL if there's no
- corresponding selection. Clear the selection if CLEAR_P is
- non-zero. */
-
-OSStatus
-mac_get_selection_from_symbol (sym, clear_p, sel)
- Lisp_Object sym;
- int clear_p;
- Selection *sel;
-{
- OSStatus err = noErr;
- Lisp_Object str = Fget (sym, Qmac_scrap_name);
-
- if (!STRINGP (str))
- *sel = NULL;
- else
- {
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
- CFStringRef scrap_name = cfstring_create_with_string (str);
- OptionBits options = (clear_p ? kScrapClearNamedScrap
- : kScrapGetNamedScrap);
-
- err = GetScrapByName (scrap_name, options, sel);
- CFRelease (scrap_name);
-#else /* !MAC_OSX */
- if (clear_p)
- err = ClearCurrentScrap ();
- if (err == noErr)
- err = GetCurrentScrap (sel);
-#endif /* !MAC_OSX */
-#else /* !TARGET_API_MAC_CARBON */
- if (clear_p)
- err = ZeroScrap ();
- if (err == noErr)
- *sel = 1;
-#endif /* !TARGET_API_MAC_CARBON */
- }
-
- return err;
-}
-
-/* Get a scrap flavor type from the symbol SYM. Return 0 if no
- corresponding flavor type. If SEL is non-zero, the return value is
- non-zero only when the SEL has the flavor type. */
-
-static ScrapFlavorType
-get_flavor_type_from_symbol (sym, sel)
- Lisp_Object sym;
- Selection sel;
-{
- Lisp_Object str = Fget (sym, Qmac_ostype);
- ScrapFlavorType flavor_type;
-
- if (STRINGP (str) && SBYTES (str) == 4)
- flavor_type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
- else
- flavor_type = 0;
-
- if (flavor_type && sel)
- {
-#if TARGET_API_MAC_CARBON
- OSStatus err;
- ScrapFlavorFlags flags;
-
- err = GetScrapFlavorFlags (sel, flavor_type, &flags);
- if (err != noErr)
- flavor_type = 0;
-#else /* !TARGET_API_MAC_CARBON */
- SInt32 size, offset;
-
- size = GetScrap (NULL, flavor_type, &offset);
- if (size < 0)
- flavor_type = 0;
-#endif /* !TARGET_API_MAC_CARBON */
- }
-
- return flavor_type;
-}
-
-/* Check if the symbol SYM has a corresponding selection target type. */
-
-int
-mac_valid_selection_target_p (sym)
- Lisp_Object sym;
-{
- return get_flavor_type_from_symbol (sym, 0) != 0;
-}
-
-/* Clear the selection whose reference is *SEL. */
-
-OSStatus
-mac_clear_selection (sel)
- Selection *sel;
-{
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
- return ClearScrap (sel);
-#else
- OSStatus err;
-
- err = ClearCurrentScrap ();
- if (err == noErr)
- err = GetCurrentScrap (sel);
- return err;
-#endif
-#else /* !TARGET_API_MAC_CARBON */
- return ZeroScrap ();
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-/* Get ownership information for SEL. Emacs can detect a change of
- the ownership by comparing saved and current values of the
- ownership information. */
-
-Lisp_Object
-mac_get_selection_ownership_info (sel)
- Selection sel;
-{
-#if TARGET_API_MAC_CARBON
- return long_to_cons ((unsigned long) sel);
-#else /* !TARGET_API_MAC_CARBON */
- ScrapStuffPtr scrap_info = InfoScrap ();
-
- return make_number (scrap_info->scrapCount);
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-/* Return non-zero if VALUE is a valid selection value for TARGET. */
-
-int
-mac_valid_selection_value_p (value, target)
- Lisp_Object value, target;
-{
- return STRINGP (value);
-}
-
-/* Put Lisp object VALUE to the selection SEL. The target type is
- specified by TARGET. */
-
-OSStatus
-mac_put_selection_value (sel, target, value)
- Selection sel;
- Lisp_Object target, value;
-{
- ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, 0);
-
- if (flavor_type == 0 || !STRINGP (value))
- return noTypeErr;
-
-#if TARGET_API_MAC_CARBON
- return PutScrapFlavor (sel, flavor_type, kScrapFlavorMaskNone,
- SBYTES (value), SDATA (value));
-#else /* !TARGET_API_MAC_CARBON */
- return PutScrap (SBYTES (value), flavor_type, SDATA (value));
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-/* Check if data for the target type TARGET is available in SEL. */
-
-int
-mac_selection_has_target_p (sel, target)
- Selection sel;
- Lisp_Object target;
-{
- return get_flavor_type_from_symbol (target, sel) != 0;
-}
-
-/* Get data for the target type TARGET from SEL and create a Lisp
- string. Return nil if failed to get data. */
-
-Lisp_Object
-mac_get_selection_value (sel, target)
- Selection sel;
- Lisp_Object target;
-{
- OSStatus err;
- Lisp_Object result = Qnil;
- ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, sel);
-#if TARGET_API_MAC_CARBON
- Size size;
-
- if (flavor_type)
- {
- err = GetScrapFlavorSize (sel, flavor_type, &size);
- if (err == noErr)
- {
- do
- {
- result = make_uninit_string (size);
- err = GetScrapFlavorData (sel, flavor_type,
- &size, SDATA (result));
- if (err != noErr)
- result = Qnil;
- else if (size < SBYTES (result))
- result = make_unibyte_string (SDATA (result), size);
- }
- while (STRINGP (result) && size > SBYTES (result));
- }
- }
-#else
- Handle handle;
- SInt32 size, offset;
-
- if (flavor_type)
- size = GetScrap (NULL, flavor_type, &offset);
- if (size >= 0)
- {
- handle = NewHandle (size);
- HLock (handle);
- size = GetScrap (handle, flavor_type, &offset);
- if (size >= 0)
- result = make_unibyte_string (*handle, size);
- DisposeHandle (handle);
- }
-#endif
-
- return result;
-}
-
-/* Get the list of target types in SEL. The return value is a list of
- target type symbols possibly followed by scrap flavor type
- strings. */
-
-Lisp_Object
-mac_get_selection_target_list (sel)
- Selection sel;
-{
- Lisp_Object result = Qnil, rest, target;
-#if TARGET_API_MAC_CARBON
- OSStatus err;
- UInt32 count, i, type;
- ScrapFlavorInfo *flavor_info = NULL;
- Lisp_Object strings = Qnil;
-
- err = GetScrapFlavorCount (sel, &count);
- if (err == noErr)
- flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
- err = GetScrapFlavorInfoList (sel, &count, flavor_info);
- if (err != noErr)
- {
- xfree (flavor_info);
- flavor_info = NULL;
- }
- if (flavor_info == NULL)
- count = 0;
-#endif
- for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
- {
- ScrapFlavorType flavor_type = 0;
-
- if (CONSP (XCAR (rest))
- && (target = XCAR (XCAR (rest)),
- SYMBOLP (target))
- && (flavor_type = get_flavor_type_from_symbol (target, sel)))
- {
- result = Fcons (target, result);
-#if TARGET_API_MAC_CARBON
- for (i = 0; i < count; i++)
- if (flavor_info[i].flavorType == flavor_type)
- {
- flavor_info[i].flavorType = 0;
- break;
- }
-#endif
- }
- }
-#if TARGET_API_MAC_CARBON
- if (flavor_info)
- {
- for (i = 0; i < count; i++)
- if (flavor_info[i].flavorType)
- {
- type = EndianU32_NtoB (flavor_info[i].flavorType);
- strings = Fcons (make_unibyte_string ((char *) &type, 4), strings);
- }
- result = nconc2 (result, strings);
- xfree (flavor_info);
- }
-#endif
-
- return result;
-}
-
-
-/***********************************************************************
- Apple event support
-***********************************************************************/
-
-extern pascal OSErr mac_handle_apple_event P_ ((const AppleEvent *,
- AppleEvent *, SInt32));
-extern void cleanup_all_suspended_apple_events P_ ((void));
-
-void
-init_apple_event_handler ()
-{
- OSErr err;
- long result;
-
- /* Make sure we have Apple events before starting. */
- err = Gestalt (gestaltAppleEventsAttr, &result);
- if (err != noErr)
- abort ();
-
- if (!(result & (1 << gestaltAppleEventsPresent)))
- abort ();
-
- err = AEInstallEventHandler (typeWildCard, typeWildCard,
-#if TARGET_API_MAC_CARBON
- NewAEEventHandlerUPP (mac_handle_apple_event),
-#else
- NewAEEventHandlerProc (mac_handle_apple_event),
-#endif
- 0L, false);
- if (err != noErr)
- abort ();
-
- atexit (cleanup_all_suspended_apple_events);
-}
-
-
-/***********************************************************************
- Drag and drop support
-***********************************************************************/
-
-#if TARGET_API_MAC_CARBON
-extern Lisp_Object Vmac_dnd_known_types;
-
-static pascal OSErr mac_do_track_drag P_ ((DragTrackingMessage, WindowRef,
- void *, DragRef));
-static pascal OSErr mac_do_receive_drag P_ ((WindowRef, void *, DragRef));
-static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL;
-static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL;
-
-static OSErr
-create_apple_event_from_drag_ref (drag, num_types, types, result)
- DragRef drag;
- UInt32 num_types;
- const FlavorType *types;
- AppleEvent *result;
-{
- OSErr err;
- UInt16 num_items;
- AppleEvent items;
- long index;
- char *buf = NULL;
-
- err = CountDragItems (drag, &num_items);
- if (err != noErr)
- return err;
- err = AECreateList (NULL, 0, false, &items);
- if (err != noErr)
- return err;
-
- for (index = 1; index <= num_items; index++)
- {
- ItemReference item;
- DescType desc_type = typeNull;
- Size size;
-
- err = GetDragItemReferenceNumber (drag, index, &item);
- if (err == noErr)
- {
- int i;
-
- for (i = 0; i < num_types; i++)
- {
- err = GetFlavorDataSize (drag, item, types[i], &size);
- if (err == noErr)
- {
- buf = xrealloc (buf, size);
- err = GetFlavorData (drag, item, types[i], buf, &size, 0);
- }
- if (err == noErr)
- {
- desc_type = types[i];
- break;
- }
- }
- }
- err = AEPutPtr (&items, index, desc_type,
- desc_type != typeNull ? buf : NULL,
- desc_type != typeNull ? size : 0);
- if (err != noErr)
- break;
- }
- xfree (buf);
-
- if (err == noErr)
- {
- err = create_apple_event (0, 0, result); /* Dummy class and ID. */
- if (err == noErr)
- err = AEPutParamDesc (result, keyDirectObject, &items);
- if (err != noErr)
- AEDisposeDesc (result);
- }
-
- AEDisposeDesc (&items);
-
- return err;
-}
-
-static void
-mac_store_drag_event (window, mouse_pos, modifiers, desc)
- WindowRef window;
- Point mouse_pos;
- SInt16 modifiers;
- const AEDesc *desc;
-{
- struct input_event buf;
-
- EVENT_INIT (buf);
-
- buf.kind = DRAG_N_DROP_EVENT;
- buf.modifiers = mac_to_emacs_modifiers (modifiers, 0);
- buf.timestamp = TickCount () * (1000 / 60);
- XSETINT (buf.x, mouse_pos.h);
- XSETINT (buf.y, mouse_pos.v);
- XSETFRAME (buf.frame_or_window, mac_window_to_frame (window));
- buf.arg = mac_aedesc_to_lisp (desc);
- kbd_buffer_store_event (&buf);
-}
-
-static pascal OSErr
-mac_do_track_drag (message, window, refcon, drag)
- DragTrackingMessage message;
- WindowRef window;
- void *refcon;
- DragRef drag;
-{
- OSErr err = noErr;
- static int can_accept;
- UInt16 num_items, index;
-
- if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
- return dragNotAcceptedErr;
-
- switch (message)
- {
- case kDragTrackingEnterHandler:
- err = CountDragItems (drag, &num_items);
- if (err != noErr)
- break;
- can_accept = 0;
- for (index = 1; index <= num_items; index++)
- {
- ItemReference item;
- FlavorFlags flags;
- Lisp_Object rest;
-
- err = GetDragItemReferenceNumber (drag, index, &item);
- if (err != noErr)
- continue;
- for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
- {
- Lisp_Object str;
- FlavorType type;
-
- str = XCAR (rest);
- if (!(STRINGP (str) && SBYTES (str) == 4))
- continue;
- type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
-
- err = GetFlavorFlags (drag, item, type, &flags);
- if (err == noErr)
- {
- can_accept = 1;
- break;
- }
- }
- }
- break;
-
- case kDragTrackingEnterWindow:
- if (can_accept)
- {
- RgnHandle hilite_rgn = NewRgn ();
-
- if (hilite_rgn)
- {
- Rect r;
-
- GetWindowPortBounds (window, &r);
- OffsetRect (&r, -r.left, -r.top);
- RectRgn (hilite_rgn, &r);
- ShowDragHilite (drag, hilite_rgn, true);
- DisposeRgn (hilite_rgn);
- }
- SetThemeCursor (kThemeCopyArrowCursor);
- }
- break;
-
- case kDragTrackingInWindow:
- break;
-
- case kDragTrackingLeaveWindow:
- if (can_accept)
- {
- HideDragHilite (drag);
- SetThemeCursor (kThemeArrowCursor);
- }
- break;
-
- case kDragTrackingLeaveHandler:
- break;
- }
-
- if (err != noErr)
- return dragNotAcceptedErr;
- return noErr;
-}
-
-static pascal OSErr
-mac_do_receive_drag (window, refcon, drag)
- WindowRef window;
- void *refcon;
- DragRef drag;
-{
- OSErr err;
- int num_types, i;
- Lisp_Object rest, str;
- FlavorType *types;
- AppleEvent apple_event;
- Point mouse_pos;
- SInt16 modifiers;
-
- if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
- return dragNotAcceptedErr;
-
- num_types = 0;
- for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
- {
- str = XCAR (rest);
- if (STRINGP (str) && SBYTES (str) == 4)
- num_types++;
- }
-
- types = xmalloc (sizeof (FlavorType) * num_types);
- i = 0;
- for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
- {
- str = XCAR (rest);
- if (STRINGP (str) && SBYTES (str) == 4)
- types[i++] = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
- }
-
- err = create_apple_event_from_drag_ref (drag, num_types, types,
- &apple_event);
- xfree (types);
-
- if (err == noErr)
- err = GetDragMouse (drag, &mouse_pos, NULL);
- if (err == noErr)
- {
- GlobalToLocal (&mouse_pos);
- err = GetDragModifiers (drag, NULL, NULL, &modifiers);
- }
- if (err == noErr)
- {
- UInt32 key_modifiers = modifiers;
-
- err = AEPutParamPtr (&apple_event, kEventParamKeyModifiers,
- typeUInt32, &key_modifiers, sizeof (UInt32));
- }
-
- if (err == noErr)
- {
- mac_store_drag_event (window, mouse_pos, 0, &apple_event);
- AEDisposeDesc (&apple_event);
- mac_wakeup_from_rne ();
- return noErr;
- }
- else
- return dragNotAcceptedErr;
-}
-#endif /* TARGET_API_MAC_CARBON */
-
-static OSErr
-install_drag_handler (window)
- WindowRef window;
-{
- OSErr err = noErr;
-
-#if TARGET_API_MAC_CARBON
- if (mac_do_track_dragUPP == NULL)
- mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag);
- if (mac_do_receive_dragUPP == NULL)
- mac_do_receive_dragUPP = NewDragReceiveHandlerUPP (mac_do_receive_drag);
-
- err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
- if (err == noErr)
- err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
-#endif
-
- return err;
-}
-
-static void
-remove_drag_handler (window)
- WindowRef window;
-{
-#if TARGET_API_MAC_CARBON
- if (mac_do_track_dragUPP)
- RemoveTrackingHandler (mac_do_track_dragUPP, window);
- if (mac_do_receive_dragUPP)
- RemoveReceiveHandler (mac_do_receive_dragUPP, window);
-#endif
-}
-
-#if TARGET_API_MAC_CARBON
-/* Return default value for mac-dnd-known-types. */
-
-Lisp_Object
-mac_dnd_default_known_types ()
-{
- Lisp_Object result = list4 (build_string ("hfs "), build_string ("utxt"),
- build_string ("TEXT"), build_string ("TIFF"));
-
-#ifdef MAC_OSX
- result = Fcons (build_string ("furl"), result);
-#endif
-
- return result;
-}
-#endif
-
-
-/***********************************************************************
- Services menu support
-***********************************************************************/
-
-#ifdef MAC_OSX
-extern Lisp_Object Qservice, Qpaste, Qperform;
-extern Lisp_Object Vmac_service_selection;
-
-static OSStatus
-mac_store_service_event (event)
- EventRef event;
-{
- OSStatus err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_pfm[] =
- {kEventParamServiceMessageName, kEventParamServiceUserData};
- static const EventParamType types_pfm[] =
- {typeCFStringRef, typeCFStringRef};
-
- switch (GetEventKind (event))
- {
- case kEventServicePaste:
- id_key = Qpaste;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
-
- case kEventServicePerform:
- id_key = Qperform;
- num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
- names = names_pfm;
- types = types_pfm;
- break;
-
- default:
- abort ();
- }
-
- err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
- event, num_params,
- names, types);
-
- return err;
-}
-
-static OSStatus
-copy_scrap_flavor_data (from_scrap, to_scrap, flavor_type)
- ScrapRef from_scrap, to_scrap;
- ScrapFlavorType flavor_type;
-{
- OSStatus err;
- Size size, size_allocated;
- char *buf = NULL;
-
- err = GetScrapFlavorSize (from_scrap, flavor_type, &size);
- if (err == noErr)
- buf = xmalloc (size);
- while (buf)
- {
- size_allocated = size;
- err = GetScrapFlavorData (from_scrap, flavor_type, &size, buf);
- if (err != noErr)
- {
- xfree (buf);
- buf = NULL;
- }
- else if (size_allocated < size)
- buf = xrealloc (buf, size);
- else
- break;
- }
- if (err == noErr)
- {
- if (buf == NULL)
- err = memFullErr;
- else
- {
- err = PutScrapFlavor (to_scrap, flavor_type, kScrapFlavorMaskNone,
- size, buf);
- xfree (buf);
- }
- }
-
- return err;
-}
-
-static OSStatus
-mac_handle_service_event (call_ref, event, data)
- EventHandlerCallRef call_ref;
- EventRef event;
- void *data;
-{
- OSStatus err = noErr;
- ScrapRef cur_scrap, specific_scrap;
- UInt32 event_kind = GetEventKind (event);
- CFMutableArrayRef copy_types, paste_types;
- CFStringRef type;
- Lisp_Object rest;
- ScrapFlavorType flavor_type;
-
- /* Check if Vmac_service_selection is a valid selection that has a
- corresponding scrap. */
- if (!SYMBOLP (Vmac_service_selection))
- err = eventNotHandledErr;
- else
- err = mac_get_selection_from_symbol (Vmac_service_selection, 0, &cur_scrap);
- if (!(err == noErr && cur_scrap))
- return eventNotHandledErr;
-
- switch (event_kind)
- {
- case kEventServiceGetTypes:
- /* Set paste types. */
- err = GetEventParameter (event, kEventParamServicePasteTypes,
- typeCFMutableArrayRef, NULL,
- sizeof (CFMutableArrayRef), NULL,
- &paste_types);
- if (err != noErr)
- break;
-
- for (rest = Vselection_converter_alist; CONSP (rest);
- rest = XCDR (rest))
- if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
- && (flavor_type =
- get_flavor_type_from_symbol (XCAR (XCAR (rest)), 0)))
- {
- type = CreateTypeStringWithOSType (flavor_type);
- if (type)
- {
- CFArrayAppendValue (paste_types, type);
- CFRelease (type);
- }
- }
-
- /* Set copy types. */
- err = GetEventParameter (event, kEventParamServiceCopyTypes,
- typeCFMutableArrayRef, NULL,
- sizeof (CFMutableArrayRef), NULL,
- &copy_types);
- if (err != noErr)
- break;
-
- if (NILP (Fx_selection_owner_p (Vmac_service_selection)))
- break;
- else
- goto copy_all_flavors;
-
- case kEventServiceCopy:
- err = GetEventParameter (event, kEventParamScrapRef,
- typeScrapRef, NULL,
- sizeof (ScrapRef), NULL, &specific_scrap);
- if (err != noErr
- || NILP (Fx_selection_owner_p (Vmac_service_selection)))
- {
- err = eventNotHandledErr;
- break;
- }
-
- copy_all_flavors:
- {
- UInt32 count, i;
- ScrapFlavorInfo *flavor_info = NULL;
- ScrapFlavorFlags flags;
-
- err = GetScrapFlavorCount (cur_scrap, &count);
- if (err == noErr)
- flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
- err = GetScrapFlavorInfoList (cur_scrap, &count, flavor_info);
- if (err != noErr)
- {
- xfree (flavor_info);
- flavor_info = NULL;
- }
- if (flavor_info == NULL)
- break;
-
- for (i = 0; i < count; i++)
- {
- flavor_type = flavor_info[i].flavorType;
- err = GetScrapFlavorFlags (cur_scrap, flavor_type, &flags);
- if (err == noErr && !(flags & kScrapFlavorMaskSenderOnly))
- {
- if (event_kind == kEventServiceCopy)
- err = copy_scrap_flavor_data (cur_scrap, specific_scrap,
- flavor_type);
- else /* event_kind == kEventServiceGetTypes */
- {
- type = CreateTypeStringWithOSType (flavor_type);
- if (type)
- {
- CFArrayAppendValue (copy_types, type);
- CFRelease (type);
- }
- }
- }
- }
- xfree (flavor_info);
- }
- break;
-
- case kEventServicePaste:
- case kEventServicePerform:
- {
- int data_exists_p = 0;
-
- err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef,
- NULL, sizeof (ScrapRef), NULL,
- &specific_scrap);
- if (err == noErr)
- err = mac_clear_selection (&cur_scrap);
- if (err == noErr)
- for (rest = Vselection_converter_alist; CONSP (rest);
- rest = XCDR (rest))
- {
- if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))))
- continue;
- flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)),
- specific_scrap);
- if (flavor_type == 0)
- continue;
- err = copy_scrap_flavor_data (specific_scrap, cur_scrap,
- flavor_type);
- if (err == noErr)
- data_exists_p = 1;
- }
- if (!data_exists_p)
- err = eventNotHandledErr;
- else
- err = mac_store_service_event (event);
- }
- break;
- }
-
- if (err != noErr)
- err = eventNotHandledErr;
- return err;
-}
-
-static OSStatus
-install_service_handler ()
-{
- static const EventTypeSpec specs[] =
- {{kEventClassService, kEventServiceGetTypes},
- {kEventClassService, kEventServiceCopy},
- {kEventClassService, kEventServicePaste},
- {kEventClassService, kEventServicePerform}};
-
- return InstallApplicationEventHandler (NewEventHandlerUPP
- (mac_handle_service_event),
- GetEventTypeCount (specs),
- specs, NULL, NULL);
-}
-#endif /* MAC_OSX */
-
-
-/***********************************************************************
- Initialization
- ***********************************************************************/
-
-void
-mac_toolbox_initialize ()
-{
- any_help_event_p = 0;
-
- init_menu_bar ();
-
-#ifdef MAC_OSX
- init_apple_event_handler ();
-#endif
-#if USE_MAC_TSM
- init_tsm ();
-#endif
-}
-
-/* arch-tag: 71a597a8-6e9f-47b0-8b89-5a5ae3e16516
- (do not change this comment) */
diff --git a/src/process.c b/src/process.c
index e028ab93503..3d64ff2cdd0 100644
--- a/src/process.c
+++ b/src/process.c
@@ -7268,7 +7268,7 @@ init_process ()
}
#endif /* HAVE_SOCKETS */
-#if defined (DARWIN) || defined (MAC_OSX)
+#if defined (DARWIN)
/* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
processes. As such, we only change the default value. */
if (initialized)
diff --git a/src/s/darwin.h b/src/s/darwin.h
index 3c227afe621..42406a4d559 100644
--- a/src/s/darwin.h
+++ b/src/s/darwin.h
@@ -27,14 +27,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* BSD4_3 and BSD4_4 are already defined in sys/param.h */
#define BSD_SYSTEM
-/* MAC_OS is used to conditionally compile code common to both MAC_OS8
- and MAC_OSX. */
-#ifdef MAC_OSX
-#ifdef HAVE_CARBON
-#define MAC_OS
-#endif
-#endif
-
/* SYSTEM_TYPE should indicate the kind of system you are using.
It sets the Lisp variable system-type. */
@@ -133,20 +125,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define HAVE_SOCKETS if system supports 4.2-compatible sockets. */
#define HAVE_SOCKETS
-/* In Carbon, asynchronous I/O (using SIGIO) can't be used for window
- events because they don't come from sockets, even though it works
- fine on tty's. */
/* This seems to help in Ctrl-G detection under Cocoa, however at the cost
of some quirks that may or may not bother a given user. */
-#if defined (HAVE_CARBON) || defined (COCOA_EXPERIMENTAL_CTRL_G)
+#if defined (COCOA_EXPERIMENTAL_CTRL_G)
#define NO_SOCK_SIGIO
#endif
-/* Extra initialization calls in main for Mac OS X system type. */
-#ifdef HAVE_CARBON
-#define SYMS_SYSTEM syms_of_mac()
-#endif
-
/* Definitions for how to dump. Copied from nextstep.h. */
#define UNEXEC unexmacosx.o
@@ -158,7 +142,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Definitions for how to compile & link. */
-/* Link in the Carbon or AppKit lib. */
+/* Link in the AppKit lib. */
#ifdef HAVE_NS
/* PENDING: can this target be specified in a clearer way? */
#define OTHER_FILES ns-app
@@ -170,49 +154,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#else /* !HAVE_NS */
#define HEADERPAD_EXTRA 690
-/* This is for the Carbon port. Under the NeXTstep port, this is still picked
+/* FIXME: Is this needed?
+ This is for the Carbon port. Under the NeXTstep port, this is still picked
up during preprocessing, but is undone in config.in. */
#define C_SWITCH_SYSTEM -fpascal-strings -DMAC_OSX
-#ifdef HAVE_CARBON
-
-/* We need a little extra space, see ../../lisp/loadup.el. */
-#define SYSTEM_PURESIZE_EXTRA 30000
-
-/* Link in the Carbon lib. */
-#define LIBS_MACGUI -framework Carbon LIBS_IMAGE
-
-#ifdef HAVE_AVAILABILITYMACROS_H
-#include <AvailabilityMacros.h>
-#endif
-/* Tell src/Makefile.in to create files in the Mac OS X application
- bundle mac/Emacs.app. */
-#define OTHER_FILES macosx-app
-
-/* Whether to use the Image I/O framework for reading images. */
-#ifndef USE_MAC_IMAGE_IO
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040 || MAC_OS_X_VERSION_MIN_REQUIRED < 1020)
-#define USE_MAC_IMAGE_IO 1
-#endif
-#endif
-
-/* If the Image I/O framework is not used, fall back on QuickTime. */
-#if USE_MAC_IMAGE_IO
-#define LIBS_IMAGE
-#else
-#define LIBS_IMAGE -framework QuickTime
-#endif
-
-/* Reroute calls to SELECT to the version defined in mac.c to fix the
- problem of Emacs requiring an extra return to be typed to start
- working when started from the command line. */
-#if defined (emacs) || defined (temacs)
-#define select sys_select
-#endif
-
-#else /* !HAVE_CARBON */
#define LIBS_MACGUI
-#endif /* HAVE_CARBON */
#endif /* !HAVE_NS */
diff --git a/src/sysdep.c b/src/sysdep.c
index b4dda533936..c2e52a07f1b 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3031,15 +3031,6 @@ emacs_close (fd)
int did_retry = 0;
register int rtnval;
-#if defined (MAC_OSX) && defined (HAVE_CARBON)
- {
- extern int mac_try_close_socket P_ ((int));
-
- if (mac_try_close_socket (fd))
- return 0;
- }
-#endif
-
while ((rtnval = close (fd)) == -1
&& (errno == EINTR))
did_retry = 1;
diff --git a/src/sysselect.h b/src/sysselect.h
index e11d5ce04ac..7a8a185e49c 100644
--- a/src/sysselect.h
+++ b/src/sysselect.h
@@ -18,11 +18,11 @@ You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_SYS_SELECT_H
-#if defined (DARWIN) || defined (MAC_OSX) || defined (NS_IMPL_COCOA)
+#if defined (DARWIN) || defined (NS_IMPL_COCOA)
#undef init_process
#endif
#include <sys/select.h>
-#if defined (DARWIN) || defined (MAC_OSX) || defined (NS_IMPL_COCOA)
+#if defined (DARWIN) || defined (NS_IMPL_COCOA)
#define init_process emacs_init_process
#endif
#endif
diff --git a/src/syssignal.h b/src/syssignal.h
index 9451fa22f7e..1aaae5562ff 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -19,7 +19,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
extern void init_signals P_ ((void));
-#if defined (HAVE_GTK_AND_PTHREAD) || (defined (HAVE_CARBON) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1020)
+#if defined (HAVE_GTK_AND_PTHREAD)
#include <pthread.h>
/* If defined, asynchronous signals delivered to a non-main thread are
forwarded to the main thread. */
diff --git a/src/term.c b/src/term.c
index 71e0f557f29..c9e3a0e35cf 100644
--- a/src/term.c
+++ b/src/term.c
@@ -75,9 +75,6 @@ extern int tgetnum P_ ((char *id));
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#ifndef O_RDWR
#define O_RDWR 2
diff --git a/src/termcap.c b/src/termcap.c
index 411ab1f2fbe..291857697d8 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -144,9 +144,6 @@ find_capability (bp, cap)
return NULL;
}
-/* These are already defined in the System framework in Mac OS X and
- cause prebinding to fail. */
-#ifndef MAC_OSX
int
tgetnum (cap)
char *cap;
@@ -180,7 +177,6 @@ tgetstr (cap, area)
return NULL;
return tgetst1 (ptr, area);
}
-#endif /* MAC_OSX */
#ifdef IS_EBCDIC_HOST
/* Table, indexed by a character in range 0200 to 0300 with 0200 subtracted,
@@ -345,11 +341,7 @@ short ospeed;
int tputs_baud_rate;
#endif
-/* Already defined in the System framework in Mac OS X and causes
- prebinding to fail. */
-#ifndef MAC_OSX
char PC;
-#endif /* MAC_OSX */
#ifndef emacs
/* Actual baud rate if positive;
@@ -368,9 +360,6 @@ static int speeds[] =
#endif /* not emacs */
-/* Already defined in the System framework in Mac OS X and causes
- prebinding to fail. */
-#ifndef MAC_OSX
void
tputs (str, nlines, outfun)
register char *str;
@@ -433,7 +422,6 @@ tputs (str, nlines, outfun)
while (padcount-- > 0)
(*outfun) (PC);
}
-#endif /* MAC_OSX */
/* Finding the termcap entry in the termcap data base. */
@@ -505,9 +493,6 @@ valid_filename_p (fn)
0 if the data base is accessible but the type NAME is not defined
in it, and some other value otherwise. */
-/* Already defined in the System framework in Mac OS X and causes
- prebinding to fail. */
-#ifndef MAC_OSX
int
tgetent (bp, name)
char *bp, *name;
@@ -666,7 +651,6 @@ tgetent (bp, name)
term_entry = bp;
return 1;
}
-#endif /* MAC_OSX */
/* Given file open on FD and buffer BUFP,
scan the file from the beginning until a line is found
diff --git a/src/termhooks.h b/src/termhooks.h
index 1be9a1b45b9..df8d48944db 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -105,7 +105,7 @@ enum event_kind
HORIZ_WHEEL_EVENT, /* A wheel event generated by a second
horizontal wheel that is present on some
mice. See WHEEL_EVENT. */
-#if defined (WINDOWSNT) || defined (MAC_OS)
+#if defined (WINDOWSNT)
LANGUAGE_CHANGE_EVENT, /* A LANGUAGE_CHANGE_EVENT is
generated on WINDOWSNT or Mac OS
when the keyboard layout or input
@@ -176,16 +176,6 @@ enum event_kind
save yourself before shutdown. */
SAVE_SESSION_EVENT
-#ifdef MAC_OS
- /* Generated when an Apple event, a HICommand event, or a Services
- menu event is received and the corresponding handler is
- registered. Members `x' and `y' are for the event class and ID
- symbols, respectively. Member `arg' is a Lisp object converted
- from the received Apple event. Parameters for non-Apple events
- are converted to those in Apple events. */
- , MAC_APPLE_EVENT
-#endif
-
#ifdef HAVE_GPM
, GPM_CLICK_EVENT
#endif
@@ -317,7 +307,6 @@ extern struct tty_display_info *gpm_tty;
#endif /* CONSP */
-struct mac_display_info;
struct ns_display_info;
struct x_display_info;
struct w32_display_info;
@@ -369,7 +358,6 @@ struct terminal
struct tty_display_info *tty; /* termchar.h */
struct x_display_info *x; /* xterm.h */
struct w32_display_info *w32; /* w32term.h */
- struct mac_display_info *mac; /* macterm.h */
struct ns_display_info *ns; /* nsterm.h */
} display_info;
@@ -642,9 +630,6 @@ extern struct terminal *terminal_list;
#ifdef HAVE_NTGUI
#define FRAME_WINDOW_P(f) FRAME_W32_P (f)
#endif
-#ifdef MAC_OS
-#define FRAME_WINDOW_P(f) FRAME_MAC_P (f)
-#endif
#ifndef FRAME_WINDOW_P
#define FRAME_WINDOW_P(f) (0)
#endif
diff --git a/src/tparam.c b/src/tparam.c
index 8f7e79c32f7..dabf0ed9713 100644
--- a/src/tparam.c
+++ b/src/tparam.c
@@ -108,9 +108,6 @@ tparam (string, outstring, len, arg0, arg1, arg2, arg3)
return tparam1 (string, outstring, len, NULL, NULL, arg);
}
-/* These are already defined in the System framework in Mac OS X and
- cause prebinding to fail. */
-#ifndef MAC_OSX
char *BC;
char *UP;
@@ -128,7 +125,6 @@ tgoto (cm, hpos, vpos)
args[1] = hpos;
return tparam1 (cm, tgoto_buf, 50, UP, BC, args);
}
-#endif
static char *
tparam1 (string, outstring, len, up, left, argp)
diff --git a/src/window.c b/src/window.c
index 753ed50a20f..aa3077aa55a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -46,9 +46,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef MSDOS
#include "msdos.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#ifdef HAVE_NS
#include "nsterm.h"
#endif
diff --git a/src/xdisp.c b/src/xdisp.c
index a8967b2d6be..ba8ff1b6857 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -196,9 +196,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef WINDOWSNT
#include "w32term.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#ifdef HAVE_NS
#include "nsterm.h"
#endif
@@ -211,7 +208,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define INFINITY 10000000
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined(HAVE_NS) || defined (USE_GTK)
extern void set_frame_menubar P_ ((struct frame *f, int, int));
extern int pending_menu_activation;
@@ -1760,9 +1757,7 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
text, or we can't tell because W's current matrix is not up to
date. */
-#ifndef HAVE_CARBON
static
-#endif
struct glyph *
x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
struct window *w;
@@ -9603,9 +9598,6 @@ prepare_menu_bars ()
menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
#ifdef HAVE_WINDOW_SYSTEM
update_tool_bar (f, 0);
-#ifdef MAC_OS
- mac_update_title_bar (f, 0);
-#endif
#endif
UNGCPRO;
}
@@ -9618,9 +9610,6 @@ prepare_menu_bars ()
update_menu_bar (sf, 1, 0);
#ifdef HAVE_WINDOW_SYSTEM
update_tool_bar (sf, 1);
-#ifdef MAC_OS
- mac_update_title_bar (sf, 1);
-#endif
#endif
}
@@ -9672,7 +9661,7 @@ update_menu_bar (f, save_match_data, hooks_run)
if (FRAME_WINDOW_P (f)
?
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
FRAME_EXTERNAL_MENU_BAR (f)
#else
@@ -9731,11 +9720,11 @@ update_menu_bar (f, save_match_data, hooks_run)
FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
/* Redisplay the menu bar in case we changed it. */
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
if (FRAME_WINDOW_P (f))
{
-#if defined (MAC_OS) || defined (HAVE_NS)
+#if defined (HAVE_NS)
/* All frames on Mac OS share the same menubar. So only
the selected frame should be allowed to set it. */
if (f == SELECTED_FRAME ())
@@ -9746,11 +9735,11 @@ update_menu_bar (f, save_match_data, hooks_run)
/* On a terminal screen, the menu bar is an ordinary screen
line, and this makes it get updated. */
w->update_mode_line = Qt;
-#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || HAVE_NS || USE_GTK) */
+#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
/* In the non-toolkit version, the menu bar is an ordinary screen
line, and this makes it get updated. */
w->update_mode_line = Qt;
-#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || HAVE_NS || USE_GTK) */
+#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
unbind_to (count, Qnil);
set_buffer_internal_1 (prev);
@@ -11357,7 +11346,7 @@ redisplay_internal (preserve_echo_area)
return;
}
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (popup_activated ())
return;
#endif
@@ -13962,7 +13951,7 @@ redisplay_window (window, just_this_one_p)
if (FRAME_WINDOW_P (f))
{
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
#else
@@ -17117,10 +17106,6 @@ display_menu_bar (w)
if (FRAME_X_P (f))
return;
#endif
-#ifdef MAC_OS
- if (FRAME_MAC_P (f))
- return;
-#endif
#ifdef HAVE_NS
if (FRAME_NS_P (f))
@@ -22816,9 +22801,7 @@ cursor_in_mouse_face_p (w)
in 20.x as well, and I think it's too risky to install
so near the release of 21.1. 2001-09-25 gerd. */
-#ifndef HAVE_CARBON
static
-#endif
int
fast_find_position (w, charpos, hpos, vpos, x, y, stop)
struct window *w;
@@ -23530,7 +23513,7 @@ note_mouse_highlight (f, x, y)
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (popup_activated ())
return;
#endif
diff --git a/src/xfaces.c b/src/xfaces.c
index 4bdcd1e406e..ff5a636ee2d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -238,12 +238,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define GCGraphicsExposures 0
#endif /* WINDOWSNT */
-#ifdef MAC_OS
-#include "macterm.h"
-#define x_display_info mac_display_info
-#define check_x check_mac
-#endif /* MAC_OS */
-
#ifdef HAVE_NS
#include "nsterm.h"
#undef FRAME_X_DISPLAY_INFO
@@ -806,35 +800,6 @@ x_free_gc (f, gc)
}
#endif /* HAVE_NS */
-#ifdef MAC_OS
-/* Mac OS emulation of GCs */
-
-static INLINE GC
-x_create_gc (f, mask, xgcv)
- struct frame *f;
- unsigned long mask;
- XGCValues *xgcv;
-{
- GC gc;
- BLOCK_INPUT;
- gc = XCreateGC (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), mask, xgcv);
- UNBLOCK_INPUT;
- IF_DEBUG (++ngcs);
- return gc;
-}
-
-static INLINE void
-x_free_gc (f, gc)
- struct frame *f;
- GC gc;
-{
- eassert (interrupt_input_blocked);
- IF_DEBUG (xassert (--ngcs >= 0));
- XFreeGC (FRAME_MAC_DISPLAY (f), gc);
-}
-
-#endif /* MAC_OS */
-
/* Like strcasecmp/stricmp. Used to compare parts of font names which
are in ISO8859-1. */
@@ -909,9 +874,6 @@ init_frame_faces (f)
#ifdef WINDOWSNT
if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
#endif
-#ifdef MAC_OS
- if (!FRAME_MAC_P (f) || FRAME_MAC_WINDOW (f))
-#endif
#ifdef HAVE_NS
if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
#endif
@@ -1308,10 +1270,6 @@ defined_color (f, color_name, color_def, alloc)
else if (FRAME_W32_P (f))
return w32_defined_color (f, color_name, color_def, alloc);
#endif
-#ifdef MAC_OS
- else if (FRAME_MAC_P (f))
- return mac_defined_color (f, color_name, color_def, alloc);
-#endif
#ifdef HAVE_NS
else if (FRAME_NS_P (f))
return ns_defined_color (f, color_name, color_def, alloc, 1);
@@ -1736,14 +1694,7 @@ enum xlfd_swidth
font height, then for weight, then for slant.' This variable can be
set via set-face-font-sort-order. */
-#ifdef MAC_OS
-static int font_sort_order[4] = {
- XLFD_SWIDTH, XLFD_POINT_SIZE, XLFD_WEIGHT, XLFD_SLANT
-};
-#else
static int font_sort_order[4];
-#endif
-
#ifdef HAVE_WINDOW_SYSTEM
@@ -2384,13 +2335,7 @@ lface_fully_specified_p (attrs)
for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
- if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i]))
-#ifdef MAC_OS
- /* MAC_TODO: No stipple support on Mac OS yet, this index is
- always unspecified. */
- && i != LFACE_STIPPLE_INDEX
-#endif
- )
+ if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
break;
return i == LFACE_VECTOR_SIZE;