diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 43 | ||||
-rw-r--r-- | src/Makefile.in | 70 | ||||
-rw-r--r-- | src/atimer.c | 6 | ||||
-rw-r--r-- | src/config.in | 14 | ||||
-rw-r--r-- | src/dispextern.h | 17 | ||||
-rw-r--r-- | src/dispnew.c | 14 | ||||
-rw-r--r-- | src/emacs.c | 54 | ||||
-rw-r--r-- | src/fileio.c | 2 | ||||
-rw-r--r-- | src/fns.c | 5 | ||||
-rw-r--r-- | src/font.c | 7 | ||||
-rw-r--r-- | src/font.h | 3 | ||||
-rw-r--r-- | src/fontset.c | 3 | ||||
-rw-r--r-- | src/frame.c | 19 | ||||
-rw-r--r-- | src/frame.h | 12 | ||||
-rw-r--r-- | src/fringe.c | 20 | ||||
-rw-r--r-- | src/image.c | 1053 | ||||
-rw-r--r-- | src/keyboard.c | 46 | ||||
-rw-r--r-- | src/lisp.h | 24 | ||||
-rw-r--r-- | src/lread.c | 10 | ||||
-rw-r--r-- | src/m/intel386.h | 2 | ||||
-rw-r--r-- | src/mac.c | 5477 | ||||
-rw-r--r-- | src/macfns.c | 4429 | ||||
-rw-r--r-- | src/macgui.h | 496 | ||||
-rw-r--r-- | src/macmenu.c | 2101 | ||||
-rw-r--r-- | src/macselect.c | 1165 | ||||
-rw-r--r-- | src/macterm.c | 13451 | ||||
-rw-r--r-- | src/macterm.h | 795 | ||||
-rw-r--r-- | src/mactoolbox.c | 6615 | ||||
-rw-r--r-- | src/process.c | 2 | ||||
-rw-r--r-- | src/s/darwin.h | 61 | ||||
-rw-r--r-- | src/sysdep.c | 9 | ||||
-rw-r--r-- | src/sysselect.h | 4 | ||||
-rw-r--r-- | src/syssignal.h | 2 | ||||
-rw-r--r-- | src/term.c | 3 | ||||
-rw-r--r-- | src/termcap.c | 16 | ||||
-rw-r--r-- | src/termhooks.h | 17 | ||||
-rw-r--r-- | src/tparam.c | 4 | ||||
-rw-r--r-- | src/window.c | 3 | ||||
-rw-r--r-- | src/xdisp.c | 35 | ||||
-rw-r--r-- | src/xfaces.c | 57 |
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, ¤t_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 (¤t_psn, - kSetFrontProcessFrontWindowOnly); - else -#endif - SetFrontProcess (¤t_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 (¤t, 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), - ®ion_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, - ©_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; |