diff options
author | Karoly Lorentey <lorentey@elte.hu> | 2005-01-06 15:00:09 +0000 |
---|---|---|
committer | Karoly Lorentey <lorentey@elte.hu> | 2005-01-06 15:00:09 +0000 |
commit | 0feecea9fb7079a2c1fbfee32a992449a22cf478 (patch) | |
tree | 0826d68e3dc2ce370c7bd4dae7db3cffc3568321 /src | |
parent | 17d51b68fb4e7da4f18eff72c589b7ffc4f9c22c (diff) | |
parent | 1a63439b34c3455a317feda5c271dfdb7af0296b (diff) | |
download | emacs-0feecea9fb7079a2c1fbfee32a992449a22cf478.tar.gz emacs-0feecea9fb7079a2c1fbfee32a992449a22cf478.tar.bz2 emacs-0feecea9fb7079a2c1fbfee32a992449a22cf478.zip |
Merged in changes from CVS trunk.
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-747
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-748
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-749
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-750
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-751
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-752
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-78
Merge from emacs--cvs-trunk--0
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-79
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-80
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-278
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 200 | ||||
-rw-r--r-- | src/alloc.c | 37 | ||||
-rw-r--r-- | src/buffer.c | 31 | ||||
-rw-r--r-- | src/coding.c | 4 | ||||
-rw-r--r-- | src/data.c | 2 | ||||
-rw-r--r-- | src/dispextern.h | 4 | ||||
-rw-r--r-- | src/emacs.c | 4 | ||||
-rw-r--r-- | src/eval.c | 15 | ||||
-rw-r--r-- | src/fileio.c | 4 | ||||
-rw-r--r-- | src/fns.c | 4 | ||||
-rw-r--r-- | src/frame.c | 12 | ||||
-rw-r--r-- | src/gtkutil.c | 42 | ||||
-rw-r--r-- | src/image.c | 11 | ||||
-rw-r--r-- | src/keyboard.c | 10 | ||||
-rw-r--r-- | src/lisp.h | 8 | ||||
-rw-r--r-- | src/lread.c | 6 | ||||
-rw-r--r-- | src/mac.c | 344 | ||||
-rw-r--r-- | src/macfns.c | 157 | ||||
-rw-r--r-- | src/macgui.h | 28 | ||||
-rw-r--r-- | src/macterm.c | 748 | ||||
-rw-r--r-- | src/macterm.h | 9 | ||||
-rw-r--r-- | src/process.c | 2 | ||||
-rw-r--r-- | src/xdisp.c | 450 | ||||
-rw-r--r-- | src/xfaces.c | 3 | ||||
-rw-r--r-- | src/xfns.c | 10 | ||||
-rw-r--r-- | src/xmenu.c | 43 |
26 files changed, 1459 insertions, 729 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 8d09c5bfd2f..26ea457a2fe 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,203 @@ +2004-12-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> + + * xmenu.c (popup_get_selection): Only pop down dialogs + on C-g and Escape. + (popup_get_selection): Remove parameter down_on_keypress. + (create_and_show_popup_menu, create_and_show_dialog): Remove + parameter down_on_keypress to popup_get_selection. + +2004-12-27 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * dispextern.h: Change HAVE_CARBON to MAC_OS. + (struct glyph_string): Likewise. + * emacs.c (main) [MAC_OS8]: Call mac_term_init instead of + mac_initialize. + * fileio.c (Fnext_read_file_uses_dialog_p, Fread_file_name): + Change TARGET_API_MAC_CARBON to HAVE_CARBON. + * fns.c (vector): Change MAC_OSX to MAC_OS. + * frame.c (x_set_frame_parameters, x_report_frame_params) + (x_set_fullscreen): Remove #ifndef HAVE_CARBON. + (x_set_border_width, Vdefault_frame_scroll_bars): Change + HAVE_CARBON to MAC_OS. + * image.c [MAC_OS]: Include sys/stat.h. + [MAC_OS && !MAC_OSX]: Include sys/param.h, ImageCompression.h, and + QuickTimeComponents.h. + * mac.c [!MAC_OSX] (mac_wait_next_event): Add extern. + [!MAC_OSX] (select): Use mac_wait_next_event. + [!MAC_OSX] (run_mac_command): Change EXEC_SUFFIXES to + Vexec_suffixes. + [!MAC_OSX] (select, run_mac_command): Change `#ifdef + TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'. + (mac_clear_font_name_table): Add extern. + (Fmac_clear_font_name_table): New defun. + (syms_of_mac): Defsubr it. + [MAC_OSX] (SELECT_POLLING_PERIOD_USEC): New define. + [MAC_OSX] (select_and_poll_event): New function. + [MAC_OSX] (sys_select): Use it. + [MAC_OSX && SELECT_USE_CFSOCKET] (socket_callback): New function. + [MAC_OSX && SELECT_USE_CFSOCKET] + (SELECT_TIMEOUT_THRESHOLD_RUNLOOP, EVENT_CLASS_SOCK): New defines. + [MAC_OSX] (sys_select) [SELECT_USE_CFSOCKET]: Use CFSocket and + RunLoop for simultaneously monitoring two kinds of inputs, window + events and process outputs, without periodically polling. + * macfns.c (mac_initialized): Remove extern. + (stricmp): Put in #if 0. All callers changed to use xstricmp in + xfaces.c. + (strnicmp): Decrement `n' at the end of each loop, not the + beginning. + (check_mac): Use the term "Mac native windows" instead of "Mac + OS". + (check_x_display_info, x_display_info_for_name): Sync with xfns.c. + (mac_get_rdb_resource): New function (from w32reg.c). + (x_get_string_resource): Use it. + (install_window_handler): Add extern. + (mac_window): New function. + (Fx_create_frame): Use it instead of make_mac_frame. Set + parameter for Qfullscreen. Call x_wm_set_size_hint. + (Fx_open_connection, Fx_close_connection): New defuns. + (syms_of_macfns): Defsubr them. + (x_create_tip_frame) [TARGET_API_MAC_CARBON]: Add + kWindowNoUpdatesAttribute to the window attribute. + (x_create_tip_frame) [!TARGET_API_MAC_CARBON]: Use NewCWindow. + (x_create_tip_frame): Don't call ShowWindow. + (Fx_show_tip): Call ShowWindow. + (Fx_file_dialog): Change `#ifdef TARGET_API_MAC_CARBON' to `#if + TARGET_API_MAC_CARBON'. + (mac_frame_parm_handlers): Set handlers for Qfullscreen. + (syms_of_macfns) [MAC_OSX]: Initialize mac_in_use to 0. + * macgui.h [!MAC_OSX]: Don't include Controls.h. Include + Windows.h. + (Window): Typedef to WindowPtr and move outside `#if + TARGET_API_MAC_CARBON'. + (XSizeHints): New struct. + * macterm.c (x_update_begin, x_update_end) + [TARGET_API_MAC_CARBON]: Disable screen updates during update of a + frame. + (x_draw_glyph_string_background, x_draw_glyph_string_foreground) + [MAC_OS8]: Use XDrawImageString/XDrawImageString16. + (construct_mouse_click): Put in #if 0. + (x_check_fullscreen, x_check_fullscreen_move): Remove decls. + (x_scroll_bar_create, x_scroll_bar_handle_click): Change `#ifdef + TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'. + (activate_scroll_bars, deactivate_scroll_bars) + [!TARGET_API_MAC_CARBON]: Use ActivateControl/DeactivateControl. + (x_make_frame_visible) [TARGET_API_MAC_CARBON]: Reposition window + if the position is neither user-specified nor program-specified. + (x_free_frame_resources): Free size_hints. + (x_wm_set_size_hint): Allocate size_hints if needed. Set + size_hints. + (mac_clear_font_name_table): New function. + (mac_do_list_fonts): Initialize font_name_table if needed. + (x_list_fonts): Don't initialize font_name_table. Add BLOCK_INPUT + around mac_do_list_fonts. + (mac_unload_font): New function. + (x_load_font): Add BLOCK_INPUT around XLoadQueryFont. + (init_mac_drag_n_drop, mac_do_receive_drag): Enclose declarations + and definitions with #if TARGET_API_MAC_CARBON. + [USE_CARBON_EVENTS] (mac_handle_window_event): Add decl. + (install_window_handler): Add decl. + (do_window_update): Add BeginUpdate/EndUpdate for the tooltip + window. Use UpdateControls. Get the rectangle that should be + updated and restrict the target of expose_frame to it. + (do_grow_window): Set minimum height/width according to + size_hints. + (do_grow_window) [TARGET_API_MAC_CARBON]: Use ResizeWindow. + (do_zoom_window): Don't use x_set_window_size. + [USE_CARBON_EVENTS] (mac_handle_window_event): New function. + (install_window_handler): New function. + [!USE_CARBON_EVENTS] (mouse_region): New variable. + [!USE_CARBON_EVENTS] (mac_wait_next_event): New function. + (XTread_socket) [USE_CARBON_EVENTS]: Move call to + GetEventDispatcherTarget inside BLOCK_INPUT. + (XTread_socket) [!USE_CARBON_EVENTS]: Use mac_wait_next_event. + Update mouse_region when mouse is moved. + (make_mac_frame): Remove. + (make_mac_terminal_frame): Put in #ifdef MAC_OS8. Initialize + mouse pointer shapes. Change values of f->left_pos and + f->top_pos. Don't use make_mac_frame. Use NewCWindow. Don't + call ShowWindow. + (mac_initialize_display_info) [MAC_OSX]: Create mac_id_name from + Vinvocation_name and Vsystem_name. + (mac_make_rdb): New function (from w32term.c). + (mac_term_init): Use it. Add BLOCK_INPUT. Error if display has + already been opened. Don't pass argument to + mac_initialize_display_info. Don't set dpyinfo->height/width. + Add entries to x_display_list and x_display_name_list. + (x_delete_display): New function. + (mac_initialize): Don't call mac_initialize_display_info. + (syms_of_macterm) [!MAC_OSX]: Don't call Fprovide. + * macterm.h (check_mac): Add extern. + (struct mac_output): New member size_hints. + (FRAME_SIZE_HINTS): New macro. + (mac_unload_font): Add extern. + * xdisp.c (expose_window, expose_frame): Remove kludges for Mac. + * xfaces.c (clear_font_table) [MAC_OS]: call mac_unload_font. + +2004-12-27 Richard M. Stallman <rms@gnu.org> + + * buffer.c (Fbuffer_disable_undo): Deleted (moved to simple.el). + (syms_of_buffer): Don't defsubr it. + + * process.c (list_processes_1): Set undo_list instead + of calling Fbuffer_disable_undo. + + * xdisp.c (single_display_spec_string_p): Renamed from + single_display_prop_string_p. + (single_display_spec_intangible_p): Renamed from + single_display_prop_intangible_p. + (handle_single_display_spec): Renamed from handle_single_display_prop. + Rewritten to be easier to understand. + + * Change in load-history format. Functions now get (defun . NAME), + and variables get just NAME. + + * data.c (Fdefalias): Use (defun . FN_NAME) in LOADHIST_ATTACH. + + * eval.c (Fdefun, Fdefmacro): Use (defun . FN_NAME) in LOADHIST_ATTACH. + (Fdefvaralias, Fdefvar, Fdefconst): Use just SYM in LOADHIST_ATTACH. + (Qdefvar): Var deleted. + (syms_of_eval): Don't initialze it. + + * lread.c (syms_of_lread) <load-history>: Doc fix. + +2004-12-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> + + * xmenu.c (popup_get_selection): Pop down on C-g. + (set_frame_menubar): Install translations for Lucid/Motif/Lesstif that + pops down menu on C-g. + (xdialog_show): If dialog popped down and no button in the dialog was + pushed, call Fsignal to quit. + (xmenu_show): In no toolkit version, if menu returns NO_SELECT call + Fsignal to quit. + + * xfns.c (Fx_file_dialog): Motif/Lesstif version: Pop down on C-g. + + * gtkutil.c (xg_initialize): Install bindings for C-g so that + dialogs and menus pop down. + +2004-12-25 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> + + * gtkutil.c (update_frame_tool_bar): Make the value of + tool-bar-button-margin control margins of images in tool bar. + + * alloc.c (check_depth): New variable. + (overrun_check_malloc, overrun_check_realloc): Only add + overhead and write check pattern if check_depth is 1 (to handle + recursive calls). Increase/decrease check_depth in entry/exit. + (overrun_check_free): Only check for overhead if check_depth is 1. + Increase/decrease check_depth in entry/exit. + +2004-12-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> + + * keyboard.c (input_available_signal): Call SIGNAL_THREAD_CHECK + before touching input_available_clear_time, to avoid accessing it + from multiple threads. + +2004-12-23 Jason Rumney <jasonr@gnu.org> + + * image.c (__WIN32__) [HAVE_NTGUI]: Define for correct behaviour + of JPEG library. + 2004-12-22 Richard M. Stallman <rms@gnu.org> * emacs.c (main): If batch mode, set Vundo_outer_limit to nil. diff --git a/src/alloc.c b/src/alloc.c index 7a6a1344d6c..eabbf5192f4 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -602,6 +602,27 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] = ((unsigned)(ptr[-4]) << 24)) +/* The call depth in overrun_check functions. For example, this might happen: + xmalloc() + overrun_check_malloc() + -> malloc -> (via hook)_-> emacs_blocked_malloc + -> overrun_check_malloc + call malloc (hooks are NULL, so real malloc is called). + malloc returns 10000. + add overhead, return 10016. + <- (back in overrun_check_malloc) + add overhead again, return 10032 + xmalloc returns 10032. + + (time passes). + + xfree(10032) + overrun_check_free(10032) + decrease overhed + free(10016) <- crash, because 10000 is the original pointer. */ + +static int check_depth; + /* Like malloc, but wraps allocated block with header and trailer. */ POINTER_TYPE * @@ -609,15 +630,17 @@ overrun_check_malloc (size) size_t size; { register unsigned char *val; + size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; - val = (unsigned char *) malloc (size + XMALLOC_OVERRUN_CHECK_SIZE*2); - if (val) + val = (unsigned char *) malloc (size + overhead); + if (val && check_depth == 1) { bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); val += XMALLOC_OVERRUN_CHECK_SIZE; XMALLOC_PUT_SIZE(val, size); bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); } + --check_depth; return (POINTER_TYPE *)val; } @@ -631,8 +654,10 @@ overrun_check_realloc (block, size) size_t size; { register unsigned char *val = (unsigned char *)block; + size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; if (val + && check_depth == 1 && bcmp (xmalloc_overrun_check_header, val - XMALLOC_OVERRUN_CHECK_SIZE, XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) @@ -647,15 +672,16 @@ overrun_check_realloc (block, size) bzero (val, XMALLOC_OVERRUN_CHECK_SIZE); } - val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + XMALLOC_OVERRUN_CHECK_SIZE*2); + val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); - if (val) + if (val && check_depth == 1) { bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); val += XMALLOC_OVERRUN_CHECK_SIZE; XMALLOC_PUT_SIZE(val, size); bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); } + --check_depth; return (POINTER_TYPE *)val; } @@ -667,7 +693,9 @@ overrun_check_free (block) { unsigned char *val = (unsigned char *)block; + ++check_depth; if (val + && check_depth == 1 && bcmp (xmalloc_overrun_check_header, val - XMALLOC_OVERRUN_CHECK_SIZE, XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) @@ -683,6 +711,7 @@ overrun_check_free (block) } free (val); + --check_depth; } #undef malloc diff --git a/src/buffer.c b/src/buffer.c index 2d931272467..38678dc5a49 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1251,29 +1251,6 @@ If BUFFER is omitted or nil, some interesting buffer is returned. */) return buf; } -DEFUN ("buffer-disable-undo", Fbuffer_disable_undo, Sbuffer_disable_undo, - 0, 1, "", - doc: /* Make BUFFER stop keeping undo information. -No argument or nil as argument means do this for the current buffer. */) - (buffer) - register Lisp_Object buffer; -{ - Lisp_Object real_buffer; - - if (NILP (buffer)) - XSETBUFFER (real_buffer, current_buffer); - else - { - real_buffer = Fget_buffer (buffer); - if (NILP (real_buffer)) - nsberror (buffer); - } - - XBUFFER (real_buffer)->undo_list = Qt; - - return Qnil; -} - DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo, 0, 1, "", doc: /* Start keeping undo information for buffer BUFFER. @@ -5671,9 +5648,10 @@ A value of nil means to use the scroll bar width from the window's frame. */); DEFVAR_PER_BUFFER ("vertical-scroll-bar", ¤t_buffer->vertical_scroll_bar_type, Qnil, doc: /* *Position of this buffer's vertical scroll bar. -A value of left or right means to place the vertical scroll bar at that side -of the window; a value of nil means that this window has no vertical scroll bar. -A value of t means to use the vertical scroll bar type from the window's frame. */); +The value takes effect whenever you display this buffer in a window. +A value of `left' or `right' means put the vertical scroll bar at that side +of the window; a value of nil means don't show any vertical scroll bars. +A value of t (the default) means do whatever the window's frame specifies. */); DEFVAR_PER_BUFFER ("indicate-empty-lines", ¤t_buffer->indicate_empty_lines, Qnil, @@ -5951,7 +5929,6 @@ to the default frame line height. */); defsubr (&Sbuffer_modified_tick); defsubr (&Srename_buffer); defsubr (&Sother_buffer); - defsubr (&Sbuffer_disable_undo); defsubr (&Sbuffer_enable_undo); defsubr (&Skill_buffer); defsubr (&Sset_buffer_major_mode); diff --git a/src/coding.c b/src/coding.c index 3ddd7ea957d..ce78af7d8d3 100644 --- a/src/coding.c +++ b/src/coding.c @@ -5877,7 +5877,6 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace) REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG) REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG Here, we are sure that NEW >= ORIG. */ - float ratio; if (coding->produced <= coding->consumed) { @@ -5887,7 +5886,8 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace) } else { - ratio = (coding->produced - coding->consumed) / coding->consumed; + float ratio = coding->produced - coding->consumed; + ratio /= coding->consumed; require = len_byte * ratio; } first = 0; diff --git a/src/data.c b/src/data.c index 811619b58b3..be1e4d33bbb 100644 --- a/src/data.c +++ b/src/data.c @@ -723,7 +723,7 @@ determined by DEFINITION. */) && EQ (XCAR (XSYMBOL (symbol)->function), Qautoload)) LOADHIST_ATTACH (Fcons (Qt, symbol)); definition = Ffset (symbol, definition); - LOADHIST_ATTACH (symbol); + LOADHIST_ATTACH (Fcons (Qdefun, symbol)); if (!NILP (docstring)) Fput (symbol, Qfunction_documentation, docstring); return definition; diff --git a/src/dispextern.h b/src/dispextern.h index d3d70b28cf8..b7dcfb799d0 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -62,7 +62,7 @@ typedef XImage *XImagePtr; typedef HDC XImagePtr_or_DC; #endif -#ifdef HAVE_CARBON +#ifdef MAC_OS #include "macgui.h" typedef struct mac_display_info Display_Info; /* Mac equivalent of XImage. */ @@ -1166,7 +1166,7 @@ struct glyph_string unsigned for_overlaps_p : 1; /* The GC to use for drawing this glyph string. */ -#if defined(HAVE_X_WINDOWS) || defined(HAVE_CARBON) +#if defined(HAVE_X_WINDOWS) || defined(MAC_OS) GC gc; #endif #if defined(HAVE_NTGUI) diff --git a/src/emacs.c b/src/emacs.c index b16ea78b9b8..cbe386d3296 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1307,7 +1307,7 @@ main (argc, argv 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_initialize, and init_keyboard have already + syms_of_frame, mac_term_init, and init_keyboard have already been called. */ syms_of_textprop (); syms_of_macfns (); @@ -1319,7 +1319,7 @@ main (argc, argv syms_of_search (); syms_of_frame (); - mac_initialize (); + mac_term_init (build_string ("Mac"), NULL, NULL); init_keyboard (); #endif diff --git a/src/eval.c b/src/eval.c index df528e3da80..9c27caa29ca 100644 --- a/src/eval.c +++ b/src/eval.c @@ -88,7 +88,7 @@ struct catchtag *catchlist; int gcpro_level; #endif -Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp, Qdefun, Qdefvar; +Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp, Qdefun; Lisp_Object Qinhibit_quit, Vinhibit_quit, Vquit_flag; Lisp_Object Qand_rest, Qand_optional; Lisp_Object Qdebug_on_error; @@ -647,7 +647,7 @@ usage: (defun NAME ARGLIST [DOCSTRING] BODY...) */) && EQ (XCAR (XSYMBOL (fn_name)->function), Qautoload)) LOADHIST_ATTACH (Fcons (Qt, fn_name)); Ffset (fn_name, defn); - LOADHIST_ATTACH (fn_name); + LOADHIST_ATTACH (Fcons (Qdefun, fn_name)); return fn_name; } @@ -716,7 +716,7 @@ usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...) */) && EQ (XCAR (XSYMBOL (fn_name)->function), Qautoload)) LOADHIST_ATTACH (Fcons (Qt, fn_name)); Ffset (fn_name, defn); - LOADHIST_ATTACH (fn_name); + LOADHIST_ATTACH (Fcons (Qdefun, fn_name)); return fn_name; } @@ -742,7 +742,7 @@ The return value is ALIASED. */) sym->indirect_variable = 1; sym->value = aliased; sym->constant = SYMBOL_CONSTANT_P (aliased); - LOADHIST_ATTACH (Fcons (Qdefvar, symbol)); + LOADHIST_ATTACH (symbol); if (!NILP (docstring)) Fput (symbol, Qvariable_documentation, docstring); @@ -810,7 +810,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) tem = Fpurecopy (tem); Fput (sym, Qvariable_documentation, tem); } - LOADHIST_ATTACH (Fcons (Qdefvar, sym)); + LOADHIST_ATTACH (sym); } else /* Simple (defvar <var>) should not count as a definition at all. @@ -853,7 +853,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) tem = Fpurecopy (tem); Fput (sym, Qvariable_documentation, tem); } - LOADHIST_ATTACH (Fcons (Qdefvar, sym)); + LOADHIST_ATTACH (sym); return sym; } @@ -3376,9 +3376,6 @@ before making `inhibit-quit' nil. */); Qdefun = intern ("defun"); staticpro (&Qdefun); - Qdefvar = intern ("defvar"); - staticpro (&Qdefvar); - Qand_rest = intern ("&rest"); staticpro (&Qand_rest); diff --git a/src/fileio.c b/src/fileio.c index 195cff2bc8c..f038bca2865 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -6190,7 +6190,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 (TARGET_API_MAC_CARBON) +#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (HAVE_CARBON) if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) && use_dialog_box && use_file_dialog @@ -6331,7 +6331,7 @@ and `read-file-name-function'. */) GCPRO2 (insdef, default_filename); -#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (TARGET_API_MAC_CARBON) +#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (HAVE_CARBON) if (! NILP (Fnext_read_file_uses_dialog_p ())) { /* If DIR contains a file name, split it. */ diff --git a/src/fns.c b/src/fns.c index 457be6c96a9..b163223803c 100644 --- a/src/fns.c +++ b/src/fns.c @@ -26,8 +26,8 @@ Boston, MA 02111-1307, USA. */ #endif #include <time.h> -#ifndef MAC_OSX -/* On Mac OS X, defining this conflicts with precompiled headers. */ +#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. */ diff --git a/src/frame.c b/src/frame.c index 660b9db4316..06ffc04f2d1 100644 --- a/src/frame.c +++ b/src/frame.c @@ -3052,8 +3052,6 @@ x_set_frame_parameters (f, alist) XSETINT (icon_top, 0); } -#ifndef HAVE_CARBON - /* MAC_TODO: fullscreen */ if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set) { /* If the frame is visible already and the fullscreen parameter is @@ -3069,7 +3067,6 @@ x_set_frame_parameters (f, alist) if (new_top != f->top_pos || new_left != f->left_pos) x_set_offset (f, new_left, new_top, 1); } -#endif /* Don't set these parameters unless they've been explicitly specified. The window might be mapped or resized while we're in @@ -3230,14 +3227,11 @@ x_report_frame_params (f, alistptr) store_in_alist (alistptr, Qdisplay, XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); -#ifndef HAVE_CARBON -/* A Mac Window is identified by a struct, not an integer. */ if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) tem = Qnil; else XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc); store_in_alist (alistptr, Qparent_id, tem); -#endif } @@ -3249,7 +3243,6 @@ x_set_fullscreen (f, new_value, old_value) struct frame *f; Lisp_Object new_value, old_value; { -#ifndef HAVE_CARBON if (NILP (new_value)) f->want_fullscreen = FULLSCREEN_NONE; else if (EQ (new_value, Qfullboth)) @@ -3258,7 +3251,6 @@ x_set_fullscreen (f, new_value, old_value) f->want_fullscreen = FULLSCREEN_WIDTH; else if (EQ (new_value, Qfullheight)) f->want_fullscreen = FULLSCREEN_HEIGHT; -#endif } @@ -3378,7 +3370,7 @@ x_set_border_width (f, arg, oldval) if (XINT (arg) == f->border_width) return; -#ifndef HAVE_CARBON +#ifndef MAC_OS if (FRAME_X_WINDOW (f) != 0) error ("Cannot change the border width of a window"); #endif /* MAC_TODO */ @@ -4300,7 +4292,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(HAVE_CARBON) +#if defined(HAVE_NTGUI) || defined(MAC_OS) /* MS-Windows has scroll bars on the right by default. */ Vdefault_frame_scroll_bars = Qright; #else diff --git a/src/gtkutil.c b/src/gtkutil.c index 317f7824267..22919230a65 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -3356,12 +3356,37 @@ update_frame_tool_bar (f) GList *icon_list; GList *iter; struct x_output *x = f->output_data.x; + int hmargin, vmargin; if (! FRAME_GTK_WIDGET (f)) return; BLOCK_INPUT; + if (INTEGERP (Vtool_bar_button_margin) + && XINT (Vtool_bar_button_margin) > 0) + { + hmargin = XFASTINT (Vtool_bar_button_margin); + vmargin = XFASTINT (Vtool_bar_button_margin); + } + else if (CONSP (Vtool_bar_button_margin)) + { + if (INTEGERP (XCAR (Vtool_bar_button_margin)) + && XINT (XCAR (Vtool_bar_button_margin)) > 0) + hmargin = XFASTINT (XCAR (Vtool_bar_button_margin)); + + if (INTEGERP (XCDR (Vtool_bar_button_margin)) + && XINT (XCDR (Vtool_bar_button_margin)) > 0) + vmargin = XFASTINT (XCDR (Vtool_bar_button_margin)); + } + + /* The natural size (i.e. when GTK uses 0 as margin) looks best, + so take DEFAULT_TOOL_BAR_BUTTON_MARGIN to mean "default for GTK", + i.e. zero. This means that margins less than + DEFAULT_TOOL_BAR_BUTTON_MARGIN has no effect. */ + hmargin = max (0, hmargin - DEFAULT_TOOL_BAR_BUTTON_MARGIN); + vmargin = max (0, vmargin - DEFAULT_TOOL_BAR_BUTTON_MARGIN); + if (! x->toolbar_widget) xg_create_tool_bar (f); @@ -3425,6 +3450,8 @@ update_frame_tool_bar (f) { GtkWidget *w = xg_get_image_for_pixmap (f, img, x->widget, NULL); + gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); + gtk_toolbar_append_item (GTK_TOOLBAR (x->toolbar_widget), 0, 0, 0, w, @@ -3480,6 +3507,8 @@ update_frame_tool_bar (f) XG_TOOL_BAR_IMAGE_DATA); g_list_free (chlist); + gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin); + if (old_img != img->pixmap) (void) xg_get_image_for_pixmap (f, img, x->widget, wimage); @@ -3549,6 +3578,8 @@ free_frame_tool_bar (f) void xg_initialize () { + GtkBindingSet *binding_set; + xg_ignore_gtk_scrollbar = 0; xg_detached_menus = 0; xg_menu_cb_list.prev = xg_menu_cb_list.next = @@ -3571,6 +3602,17 @@ xg_initialize () "gtk-key-theme-name", "Emacs", EMACS_CLASS); + + /* Make dialogs close on C-g. Since file dialog inherits from + dialog, this works for them also. */ + binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_DIALOG)); + gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK, + "close", 0); + + /* Make menus close on C-g. */ + binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_MENU_SHELL)); + gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK, + "cancel", 0); } #endif /* USE_GTK */ diff --git a/src/image.c b/src/image.c index 18ffc2db3a4..9c2f6962b6e 100644 --- a/src/image.c +++ b/src/image.c @@ -83,16 +83,19 @@ typedef struct w32_bitmap_record Bitmap_Record; #ifdef MAC_OS #include "macterm.h" +#include <sys/stat.h> #ifndef MAC_OSX #include <alloca.h> +#include <sys/param.h> #endif #ifdef MAC_OSX -#include <sys/stat.h> #include <QuickTime/QuickTime.h> #else /* not MAC_OSX */ #include <Windows.h> #include <Gestalt.h> #include <TextUtils.h> +#include <ImageCompression.h> +#include <QuickTimeComponents.h> #endif /* not MAC_OSX */ /* MAC_TODO : Color tables on Mac. */ @@ -6269,6 +6272,12 @@ jpeg_image_p (object) #undef HAVE_STDLIB_H #endif /* HAVE_STLIB_H */ +#if defined (HAVE_NTGUI) && !defined (__WIN32__) +/* jpeglib.h will define boolean differently depending on __WIN32__, + so make sure it is defined. */ +#define __WIN32__ 1 +#endif + #include <jpeglib.h> #include <jerror.h> #include <setjmp.h> diff --git a/src/keyboard.c b/src/keyboard.c index 122a8e6b025..5c2fbf29cae 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6910,14 +6910,16 @@ input_available_signal (signo) sigisheld (SIGIO); #endif - if (input_available_clear_time) - EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); - #ifdef SYNC_INPUT interrupt_input_pending = 1; #else - SIGNAL_THREAD_CHECK (signo); +#endif + + if (input_available_clear_time) + EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); + +#ifndef SYNC_INPUT handle_async_input (); #endif diff --git a/src/lisp.h b/src/lisp.h index 59ce03435f5..b3220f43f34 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1671,8 +1671,16 @@ extern void defvar_kboard P_ ((char *, int)); #define DEFVAR_LISP_NOPRO(lname, vname, doc) defvar_lisp_nopro (lname, vname) #define DEFVAR_BOOL(lname, vname, doc) defvar_bool (lname, vname) #define DEFVAR_INT(lname, vname, doc) defvar_int (lname, vname) + +/* TYPE is nil for a general Lisp variable. + An integer specifies a type; then only LIsp values + with that type code are allowed (except that nil is allowed too). + LNAME is the LIsp-level variable name. + VNAME is the name of the buffer slot. + DOC is a dummy where you write the doc string as a comment. */ #define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ defvar_per_buffer (lname, vname, type, 0) + #define DEFVAR_KBOARD(lname, vname, doc) \ defvar_kboard (lname, \ (int)((char *)(¤t_kboard->vname) \ diff --git a/src/lread.c b/src/lread.c index 895c063d04a..42531149286 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3847,10 +3847,10 @@ when the corresponding call to `provide' is made. */); Each alist element is a list that starts with a file name, except for one element (optional) that starts with nil and describes definitions evaluated from buffers not visiting files. -The remaining elements of each list are symbols defined as functions, +The remaining elements of each list are symbols defined as variables and cons cells of the form `(provide . FEATURE)', `(require . FEATURE)', -`(defvar . VARIABLE), `(autoload . SYMBOL)', and `(t . SYMBOL)'. -An element `(t . SYMBOL)' precedes an entry that is just SYMBOL, +`(defun . FUNCTION)', `(autoload . SYMBOL)', and `(t . SYMBOL)'. +An element `(t . SYMBOL)' precedes an entry `(defun . FUNCTION)', and means that SYMBOL was an autoload before this file redefined it as a function. */); Vload_history = Qnil; diff --git a/src/mac.c b/src/mac.c index 53e56cfb541..99e0d44830b 100644 --- a/src/mac.c +++ b/src/mac.c @@ -845,6 +845,8 @@ check_alarm () } +extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean); + int select (n, rfds, wfds, efds, timeout) int n; @@ -853,49 +855,24 @@ select (n, rfds, wfds, efds, timeout) SELECT_TYPE *efds; struct timeval *timeout; { -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON return 1; #else /* not TARGET_API_MAC_CARBON */ - EMACS_TIME end_time, now; EventRecord e; + UInt32 sleep_time = EMACS_SECS (*timeout) * 60 + + ((EMACS_USECS (*timeout) * 60) / 1000000); /* Can only handle wait for keyboard input. */ if (n > 1 || wfds || efds) return -1; - EMACS_GET_TIME (end_time); - EMACS_ADD_TIME (end_time, end_time, *timeout); - - do - { - /* Also return true if an event other than a keyDown has - occurred. This causes kbd_buffer_get_event in keyboard.c to - call read_avail_input which in turn calls XTread_socket to - poll for these events. Otherwise these never get processed - except but a very slow poll timer. */ - if (FD_ISSET (0, rfds) && EventAvail (everyEvent, &e)) - return 1; - - /* Also check movement of the mouse. */ - { - Point mouse_pos; - static Point old_mouse_pos = {-1, -1}; - - GetMouse (&mouse_pos); - if (!EqualPt (mouse_pos, old_mouse_pos)) - { - old_mouse_pos = mouse_pos; - return 1; - } - } - - WaitNextEvent (0, &e, 1UL, NULL); /* Accept no event; wait 1 - tic. by T.I. */ - - EMACS_GET_TIME (now); - EMACS_SUB_TIME (now, end_time, now); - } - while (!EMACS_TIME_NEG_P (now)); + /* Also return true if an event other than a keyDown has occurred. + This causes kbd_buffer_get_event in keyboard.c to call + read_avail_input which in turn calls XTread_socket to poll for + these events. Otherwise these never get processed except but a + very slow poll timer. */ + if (FD_ISSET (0, rfds) && mac_wait_next_event (&e, sleep_time, false)) + return 1; return 0; #endif /* not TARGET_API_MAC_CARBON */ @@ -1996,7 +1973,7 @@ run_mac_command (argv, workdir, infn, outfn, errfn) const char *workdir; const char *infn, *outfn, *errfn; { -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON return -1; #else /* not TARGET_API_MAC_CARBON */ char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1]; @@ -2081,7 +2058,7 @@ run_mac_command (argv, workdir, infn, outfn, errfn) strcat (t, newargv[0]); #endif /* 0 */ Lisp_Object path; - openp (Vexec_path, build_string (newargv[0]), EXEC_SUFFIXES, &path, + openp (Vexec_path, build_string (newargv[0]), Vexec_suffixes, &path, make_number (X_OK)); if (NILP (path)) @@ -2793,17 +2770,98 @@ and t is the same as `SECONDARY'. */) return Qnil; } +extern void mac_clear_font_name_table P_ ((void)); + +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; +} + #ifdef MAC_OSX #undef select extern int inhibit_window_system; extern int noninteractive; -/* When Emacs is started from the Finder, SELECT always immediately - returns as if input is present when file descriptor 0 is polled for - input. Strangely, when Emacs is run as a GUI application from the - command line, it blocks in the same situation. This `wrapper' of - the system call SELECT corrects this discrepancy. */ +/* 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 defined] + Only the window event channel and socket read channels are + involved, and timeout is not too short (greater than + SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds). + -> Create CFSocket for each socket and add it into the current + event RunLoop so that an `ready-to-read' event can be posted + to the event queue that is also used for window events. Then + ReceiveNextEvent 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). */ + +#define SELECT_POLLING_PERIOD_USEC 20000 +#ifdef SELECT_USE_CFSOCKET +#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2 +#define EVENT_CLASS_SOCK 'Sock' + +static void +socket_callback (s, type, address, data, info) + CFSocketRef s; + CFSocketCallBackType type; + CFDataRef address; + const void *data; + void *info; +{ + EventRef event; + + CreateEvent (NULL, EVENT_CLASS_SOCK, 0, 0, kEventAttributeNone, &event); + PostEventToQueue (GetCurrentEventQueue (), event, kEventPriorityStandard); + ReleaseEvent (event); +} +#endif /* SELECT_USE_CFSOCKET */ + +static int +select_and_poll_event (n, rfds, wfds, efds, timeout) + int n; + SELECT_TYPE *rfds; + SELECT_TYPE *wfds; + SELECT_TYPE *efds; + struct timeval *timeout; +{ + int r; + OSErr err; + + r = select (n, rfds, wfds, efds, timeout); + if (r != -1) + { + BLOCK_INPUT; + err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, + kEventLeaveInQueue, NULL); + UNBLOCK_INPUT; + if (err == noErr) + { + FD_SET (0, rfds); + r++; + } + } + return r; +} + +#ifndef MAC_OS_X_VERSION_10_2 +#undef SELECT_INVALIDATE_CFSOCKET +#endif + int sys_select (n, rfds, wfds, efds, timeout) int n; @@ -2813,91 +2871,182 @@ sys_select (n, rfds, wfds, efds, timeout) struct timeval *timeout; { OSErr err; - EMACS_TIME end_time, now, remaining_time; - + int i, r; + EMACS_TIME select_timeout; + if (inhibit_window_system || noninteractive || rfds == NULL || !FD_ISSET (0, rfds)) return select (n, rfds, wfds, efds, timeout); - + + FD_CLR (0, rfds); + if (wfds == NULL && efds == NULL) { - int i; + int nsocks = 0; + SELECT_TYPE orfds = *rfds; + + EventTimeout timeout_sec = + (timeout + ? (EMACS_SECS (*timeout) * kEventDurationSecond + + EMACS_USECS (*timeout) * kEventDurationMicrosecond) + : kEventDurationForever); for (i = 1; i < n; i++) if (FD_ISSET (i, rfds)) - break; - if (i == n) - { - EventTimeout timeout_sec = - (timeout - ? (EMACS_SECS (*timeout) * kEventDurationSecond - + EMACS_USECS (*timeout) * kEventDurationMicrosecond) - : kEventDurationForever); + nsocks++; + if (nsocks == 0) + { BLOCK_INPUT; err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL); UNBLOCK_INPUT; if (err == noErr) { - FD_ZERO (rfds); FD_SET (0, rfds); return 1; } else return 0; } - } - if (timeout) - { - remaining_time = *timeout; - EMACS_GET_TIME (now); - EMACS_ADD_TIME (end_time, now, remaining_time); - } - FD_CLR (0, rfds); - do - { - EMACS_TIME select_timeout; - SELECT_TYPE orfds = *rfds; - int r; + /* 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 (n, rfds, wfds, efds, &select_timeout); + if (r != 0 || timeout_sec == 0.0) + return r; - EMACS_SET_SECS_USECS (select_timeout, 0, 20000); + *rfds = orfds; - if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) - select_timeout = remaining_time; +#ifdef SELECT_USE_CFSOCKET + if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) + goto poll_periodically; - r = select (n, &orfds, wfds, efds, &select_timeout); - BLOCK_INPUT; - err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, - kEventLeaveInQueue, NULL); - UNBLOCK_INPUT; - if (r > 0) - { - *rfds = orfds; - if (err == noErr) + { + CFRunLoopRef runloop = + (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ()); + EventTypeSpec specs[] = {{EVENT_CLASS_SOCK, 0}}; +#ifdef SELECT_INVALIDATE_CFSOCKET + CFSocketRef *shead, *s; +#else + CFRunLoopSourceRef *shead, *s; +#endif + + BLOCK_INPUT; + +#ifdef SELECT_INVALIDATE_CFSOCKET + shead = xmalloc (sizeof (CFSocketRef) * nsocks); +#else + shead = xmalloc (sizeof (CFRunLoopSourceRef) * nsocks); +#endif + s = shead; + for (i = 1; i < n; i++) + if (FD_ISSET (i, rfds)) { - FD_SET (0, rfds); - r++; + CFSocketRef socket = + CFSocketCreateWithNative (NULL, i, kCFSocketReadCallBack, + socket_callback, NULL); + CFRunLoopSourceRef source = + CFSocketCreateRunLoopSource (NULL, socket, 0); + +#ifdef SELECT_INVALIDATE_CFSOCKET + CFSocketSetSocketFlags (socket, 0); +#endif + CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode); +#ifdef SELECT_INVALIDATE_CFSOCKET + CFRelease (source); + *s = socket; +#else + CFRelease (socket); + *s = source; +#endif + s++; } - return r; - } - else if (err == noErr) - { - FD_ZERO (rfds); - FD_SET (0, rfds); - return 1; - } - if (timeout) - { - EMACS_GET_TIME (now); - EMACS_SUB_TIME (remaining_time, end_time, now); - } + err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL); + + do + { + --s; +#ifdef SELECT_INVALIDATE_CFSOCKET + CFSocketInvalidate (*s); +#else + CFRunLoopRemoveSource (runloop, *s, kCFRunLoopDefaultMode); +#endif + CFRelease (*s); + } + while (s != shead); + + xfree (shead); + + if (err) + { + FD_ZERO (rfds); + r = 0; + } + else + { + FlushEventsMatchingListFromQueue (GetCurrentEventQueue (), + GetEventTypeCount (specs), + specs); + EMACS_SET_SECS_USECS (select_timeout, 0, 0); + r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); + } + + UNBLOCK_INPUT; + + return r; + } +#endif /* SELECT_USE_CFSOCKET */ } - while (!timeout || EMACS_TIME_LT (now, end_time)); - return 0; + poll_periodically: + { + EMACS_TIME end_time, now, remaining_time; + SELECT_TYPE orfds = *rfds, owfds, oefds; + + if (wfds) + owfds = *wfds; + if (efds) + oefds = *efds; + 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 (n, 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)); + + FD_ZERO (rfds); + if (wfds) + FD_ZERO (wfds); + if (efds) + FD_ZERO (efds); + return 0; + } } /* Set up environment variables so that Emacs can correctly find its @@ -3043,6 +3192,7 @@ syms_of_mac () defsubr (&Smac_paste_function); defsubr (&Smac_cut_function); defsubr (&Sx_selection_exists_p); + defsubr (&Smac_clear_font_name_table); defsubr (&Sdo_applescript); defsubr (&Smac_file_name_to_posix); diff --git a/src/macfns.c b/src/macfns.c index fdfe7a52416..dfbc5dacd5e 100644 --- a/src/macfns.c +++ b/src/macfns.c @@ -158,9 +158,7 @@ Lisp_Object Qshift; extern Lisp_Object Vwindow_system_version; -extern int mac_initialized; - - +#if 0 /* Use xstricmp instead. */ /* compare two strings ignoring case */ static int @@ -171,13 +169,14 @@ stricmp (const char *s, const char *t) 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); s++, t++) + for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++) if (*s == '\0') return 0; return n == 0 ? 0 : tolower (*s) - tolower (*t); @@ -190,7 +189,7 @@ void check_mac () { if (! mac_in_use) - error ("Mac OS not in use or not initialized"); + error ("Mac native windows not in use or not initialized"); } /* Nonzero if we can use mouse menus. @@ -228,33 +227,28 @@ struct mac_display_info * check_x_display_info (frame) Lisp_Object frame; { - if (!mac_initialized) - { - mac_initialize (); - mac_initialized = 1; - } + struct mac_display_info *dpyinfo = NULL; if (NILP (frame)) { struct frame *sf = XFRAME (selected_frame); if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf)) - return FRAME_MAC_DISPLAY_INFO (sf); + dpyinfo = FRAME_MAC_DISPLAY_INFO (sf); + else if (x_display_list != 0) + dpyinfo = x_display_list; else - return &one_mac_display_info; + error ("Mac native windows are not in use or not initialized"); } else if (STRINGP (frame)) - return x_display_info_for_name (frame); + dpyinfo = x_display_info_for_name (frame); else { - FRAME_PTR f; - - CHECK_LIVE_FRAME (frame); - f = XFRAME (frame); - if (! FRAME_MAC_P (f)) - error ("non-mac frame used"); - return FRAME_MAC_DISPLAY_INFO (f); + FRAME_PTR f = check_x_frame (frame); + dpyinfo = FRAME_MAC_DISPLAY_INFO (f); } + + return dpyinfo; } /* Return the Emacs frame-object corresponding to a mac window. @@ -1109,7 +1103,7 @@ mac_color_map_lookup (colorname) BLOCK_INPUT; for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++) - if (stricmp (colorname, mac_color_map[i].name) == 0) + if (xstricmp (colorname, mac_color_map[i].name) == 0) { ret = make_number (mac_color_map[i].color); break; @@ -2059,13 +2053,49 @@ x_set_scroll_bar_default_width (f) /* Subroutines of creating a frame. */ +static char * +mac_get_rdb_resource (rdb, resource) + char *rdb; + char *resource; +{ + char *value = rdb; + int len = strlen (resource); + + while (*value) + { + if ((strncmp (value, resource, len) == 0) && (value[len] == ':')) + return xstrdup (&value[len + 1]); + + value = strchr (value, '\0') + 1; + } + + return NULL; +} + +/* Retrieve the string resource specified by NAME with CLASS from + database RDB. */ + char * x_get_string_resource (rdb, name, class) XrmDatabase rdb; char *name, *class; { - /* MAC_TODO: implement resource strings */ + if (rdb) + { + char *resource; + + if (resource = mac_get_rdb_resource (rdb, name)) + return resource; + if (resource = mac_get_rdb_resource (rdb, class)) + return resource; + } + + /* MAC_TODO: implement resource strings. (Maybe Property Lists?) */ +#if 0 + return mac_get_string_resource (name, class); +#else return (char *)0; +#endif } /* Return the value of parameter PARAM. @@ -2229,36 +2259,38 @@ XParseGeometry (string, x, y, width, height) } -#if 0 /* MAC_TODO */ /* Create and set up the Mac window for frame F. */ +extern install_window_handler (WindowPtr); + static void -mac_window (f, window_prompting, minibuffer_only) +mac_window (f) struct frame *f; - long window_prompting; - int minibuffer_only; { Rect r; BLOCK_INPUT; - /* Use the resource name as the top-level window name - for looking up resources. Make a non-Lisp copy - for the window manager, so GC relocation won't bother it. - - Elsewhere we specify the window name for the window manager. */ - - { - char *str = (char *) SDATA (Vx_resource_name); - f->namebuf = (char *) xmalloc (strlen (str) + 1); - strcpy (f->namebuf, str); - } - 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 + CreateNewWindow (kDocumentWindowClass, + kWindowStandardDocumentAttributes + /* | kWindowToolbarButtonAttribute */, + &r, &FRAME_MAC_WINDOW (f)); + if (FRAME_MAC_WINDOW (f)) + { + SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac); + install_window_handler (FRAME_MAC_WINDOW (f)); + } +#else FRAME_MAC_WINDOW (f) - = NewCWindow (NULL, &r, "\p", 1, zoomDocProc, (WindowPtr) -1, 1, (long) f->output_data.mac); + = NewCWindow (NULL, &r, "\p", false, zoomDocProc, + (WindowPtr) -1, 1, (long) f->output_data.mac); +#endif + /* so that update events can find this mac_output struct */ + f->output_data.mac->mFP = f; /* point back to emacs frame */ validate_x_resource_name (); @@ -2276,17 +2308,11 @@ mac_window (f, window_prompting, minibuffer_only) x_set_name (f, name, explicit); } - ShowWindow (FRAME_MAC_WINDOW (f)); - UNBLOCK_INPUT; - if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) - initialize_frame_menubar (f); - if (FRAME_MAC_WINDOW (f) == 0) error ("Unable to create window"); } -#endif /* MAC_TODO */ /* Handle the icon stuff for this window. Perhaps later we might want an x_set_icon_position which can be called interactively as @@ -2703,6 +2729,8 @@ This function is an internal primitive--use `make-frame' instead. */) "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); x_default_parameter (f, parms, Qtitle, Qnil, "title", "Title", RES_TYPE_STRING); + x_default_parameter (f, parms, Qfullscreen, Qnil, + "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window; @@ -2728,8 +2756,7 @@ This function is an internal primitive--use `make-frame' instead. */) tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); f->no_split = minibuffer_only || EQ (tem, Qt); - /* mac_window (f, window_prompting, minibuffer_only); */ - make_mac_frame (f); + mac_window (f); x_icon (f, parms); x_make_gc (f); @@ -2763,14 +2790,12 @@ This function is an internal primitive--use `make-frame' instead. */) FRAME_LINES (f) = 0; change_frame_size (f, height, width, 1, 0, 0); -#if 0 /* MAC_TODO: when we have window manager hints */ /* 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; -#endif /* Make the window appear on the frame and enable display, unless the caller says not to. However, with explicit parent, Emacs @@ -3144,6 +3169,9 @@ x_display_info_for_name (name) CHECK_STRING (name); + if (! EQ (Vwindow_system, intern ("mac"))) + error ("Not using Mac native windows"); + for (dpyinfo = &one_mac_display_info, names = x_display_name_list; dpyinfo; dpyinfo = dpyinfo->next, names = XCDR (names)) @@ -3171,7 +3199,6 @@ x_display_info_for_name (name) return dpyinfo; } -#if 0 /* MAC_TODO: implement network support */ DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection, 1, 3, 0, doc: /* Open a connection to a server. @@ -3190,7 +3217,7 @@ terminate Emacs if we can't open the connection. */) CHECK_STRING (xrm_string); if (! EQ (Vwindow_system, intern ("mac"))) - error ("Not using Mac OS"); + error ("Not using Mac native windows"); if (! NILP (xrm_string)) xrm_option = (unsigned char *) SDATA (xrm_string); @@ -3238,11 +3265,9 @@ If DISPLAY is nil, that stands for the selected frame's display. */) 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); - x_unload_font (dpyinfo, dpyinfo->font_table[i].font); + mac_unload_font (dpyinfo, dpyinfo->font_table[i].font); } + x_destroy_all_bitmaps (dpyinfo); x_delete_display (dpyinfo); @@ -3250,7 +3275,6 @@ If DISPLAY is nil, that stands for the selected frame's display. */) return Qnil; } -#endif /* 0 */ 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. */) @@ -3813,18 +3837,23 @@ x_create_tip_frame (dpyinfo, parms, text) BLOCK_INPUT; SetRect (&r, 0, 0, 1, 1); +#if TARGET_API_MAC_CARBON if (CreateNewWindow (kHelpWindowClass, #ifdef MAC_OS_X_VERSION_10_2 kWindowIgnoreClicksAttribute | #endif + kWindowNoUpdatesAttribute | kWindowNoActivatesAttribute, &r, &tip_window) == noErr) +#else + if (tip_window = NewCWindow (NULL, &r, "\p", false, plainDBox, + NULL, false, 0L)) +#endif { FRAME_MAC_WINDOW (f) = tip_window; SetWRefCon (tip_window, (long) f->output_data.mac); /* so that update events can find this mac_output struct */ f->output_data.mac->mFP = f; - ShowWindow (tip_window); } UNBLOCK_INPUT; } @@ -4140,6 +4169,7 @@ Text larger than the specified size is clipped. */) BLOCK_INPUT; MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false); SizeWindow (FRAME_MAC_WINDOW (f), width, height, true); + ShowWindow (FRAME_MAC_WINDOW (f)); BringToFront (FRAME_MAC_WINDOW (f)); UNBLOCK_INPUT; @@ -4198,7 +4228,7 @@ Value is t if tooltip was open, nil otherwise. */) -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON /*********************************************************************** File selection dialog ***********************************************************************/ @@ -4405,14 +4435,19 @@ frame_parm_handler mac_frame_parm_handlers[] = x_set_fringe_width, x_set_fringe_width, 0, /* x_set_wait_for_wm, */ - 0, /* MAC_TODO: x_set_fullscreen, */ + x_set_fullscreen, }; void syms_of_macfns () { - /* Certainly running on Mac. */ +#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. */ @@ -4536,10 +4571,8 @@ Chinese, Japanese, and Korean. */); defsubr (&Sx_display_backing_store); defsubr (&Sx_display_save_under); defsubr (&Sx_create_frame); -#if 0 /* MAC_TODO: implement network support */ defsubr (&Sx_open_connection); defsubr (&Sx_close_connection); -#endif defsubr (&Sx_display_list); defsubr (&Sx_synchronize); diff --git a/src/macgui.h b/src/macgui.h index e5ea665ac15..1e1447dfaa8 100644 --- a/src/macgui.h +++ b/src/macgui.h @@ -62,18 +62,17 @@ typedef unsigned long Time; #else #include <QuickDraw.h> /* for WindowPtr */ #include <QDOffscreen.h> /* for GWorldPtr */ -#include <Controls.h> /* for ControlHandle in xdisp.c */ +#include <Windows.h> #include <Gestalt.h> #endif +typedef WindowPtr Window; typedef GWorldPtr Pixmap; #if TARGET_API_MAC_CARBON -typedef struct OpaqueWindowPtr *Window; #define Cursor ThemeCursor #define No_Cursor (-1) #else -typedef WindowPtr Window; #define SetPortWindowPort(w) SetPort(w) #define Cursor CursHandle #define No_Cursor (0) @@ -198,6 +197,29 @@ XCreateGC (void *, Window, unsigned long, XGCValues *); #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 */ diff --git a/src/macterm.c b/src/macterm.c index da3dcb15ee8..382400d1d85 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -1178,7 +1178,17 @@ static void x_update_begin (f) struct frame *f; { - /* Nothing to do. */ +#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 } @@ -1263,7 +1273,7 @@ mac_draw_vertical_window_border (w, x, y0, y1) 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 + support. Such windows don't have a cursor, so don't display it here. */ static void @@ -1327,6 +1337,9 @@ x_update_end (f) mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f)); +#if TARGET_API_MAC_CARBON + EnableScreenUpdates (); +#endif XFlush (FRAME_MAC_DISPLAY (f)); UNBLOCK_INPUT; } @@ -1983,7 +1996,7 @@ x_draw_glyph_string_background (s, force_p) } else #endif -#if 0 /* defined(MAC_OS8)*/ +#ifdef MAC_OS8 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width || s->font_not_found_p || s->extends_to_end_of_line_p @@ -2041,7 +2054,7 @@ x_draw_glyph_string_foreground (s) for (i = 0; i < s->nchars; ++i) char1b[i] = s->char2b[i].byte2; -#if 0 /* defined(MAC_OS8) */ +#ifdef MAC_OS8 /* Draw text with XDrawString if background has already been filled. Otherwise, use XDrawImageString. (Note that XDrawImageString is usually faster than XDrawString.) Always @@ -2059,7 +2072,7 @@ x_draw_glyph_string_foreground (s) XDrawString (s->display, s->window, s->gc, x, s->ybase - boff, char1b, s->nchars); } -#if 0 /* defined(MAC_OS8)*/ +#ifdef MAC_OS8 else { if (s->two_byte_p) @@ -3652,6 +3665,7 @@ x_get_keysym_name (keysym) +#if 0 /* Mouse clicks and mouse movement. Rah. */ /* Prepare a mouse-event in *RESULT for placement in the input queue. @@ -3685,6 +3699,7 @@ construct_mouse_click (result, event, f) result->arg = Qnil; return Qnil; } +#endif /* Function to report a mouse movement to the mainstream Emacs code. @@ -3754,8 +3769,6 @@ int disable_mouse_highlight; static struct scroll_bar *x_window_to_scroll_bar (); static void x_scroll_bar_report_motion (); -static void x_check_fullscreen P_ ((struct frame *)); -static void x_check_fullscreen_move P_ ((struct frame *)); static int glyph_rect P_ ((struct frame *f, int, int, Rect *)); @@ -4017,7 +4030,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height) r.right = left + width; r.bottom = disp_top + disp_height; -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0, kControlScrollBarProc, 0L); #else @@ -4395,7 +4408,7 @@ activate_scroll_bars (frame) while (! NILP (bar)) { ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar)); -#ifdef TARGET_API_MAC_CARBON +#if 1 /* TARGET_API_MAC_CARBON */ ActivateControl (ch); #else SetControlMaximum (ch, @@ -4419,10 +4432,10 @@ deactivate_scroll_bars (frame) while (! NILP (bar)) { ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar)); -#ifdef TARGET_API_MAC_CARBON +#if 1 /* TARGET_API_MAC_CARBON */ DeactivateControl (ch); #else - SetControlMaximum (ch, XINT (-1)); + SetControlMaximum (ch, -1); #endif bar = XSCROLL_BAR (bar)->next; } @@ -4466,7 +4479,7 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp) case kControlPageDownPart: bufp->part = scroll_bar_below_handle; break; -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON default: #else case kControlIndicatorPart: @@ -4974,13 +4987,16 @@ x_new_font (f, fontname) 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 font, 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. @@ -5369,6 +5385,25 @@ x_make_frame_visible (f) f->output_data.mac->asked_for_visible = 1; +#if TARGET_API_MAC_CARBON + if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition))) + { + struct frame *sf = SELECTED_FRAME (); + if (!FRAME_MAC_P (sf)) + RepositionWindow (FRAME_MAC_WINDOW (f), NULL, + kWindowCenterOnMainScreen); + else + RepositionWindow (FRAME_MAC_WINDOW (f), + FRAME_MAC_WINDOW (sf), +#ifdef MAC_OS_X_VERSION_10_2 + kWindowCascadeStartAtParentWindowScreen +#else + kWindowCascadeOnParentWindowScreen +#endif + ); + x_real_positions (f, &f->left_pos, &f->top_pos); + } +#endif ShowWindow (FRAME_MAC_WINDOW (f)); } @@ -5496,6 +5531,9 @@ x_free_frame_resources (f) x_free_gcs (f); + if (FRAME_SIZE_HINTS (f)) + xfree (FRAME_SIZE_HINTS (f)); + xfree (f->output_data.mac); f->output_data.mac = NULL; @@ -5548,143 +5586,39 @@ x_wm_set_size_hint (f, flags, user_position) long flags; int user_position; { -#if 0 /* MAC_TODO: connect this to the Appearance Manager */ - XSizeHints size_hints; - -#ifdef USE_X_TOOLKIT - Arg al[2]; - int ac = 0; - Dimension widget_width, widget_height; - Window window = XtWindow (f->output_data.x->widget); -#else /* not USE_X_TOOLKIT */ - Window window = FRAME_X_WINDOW (f); -#endif /* not USE_X_TOOLKIT */ - - /* Setting PMaxSize caused various problems. */ - size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; - - size_hints.x = f->left_pos; - size_hints.y = f->top_pos; - -#ifdef USE_X_TOOLKIT - XtSetArg (al[ac], XtNwidth, &widget_width); ac++; - XtSetArg (al[ac], XtNheight, &widget_height); ac++; - XtGetValues (f->output_data.x->widget, al, ac); - size_hints.height = widget_height; - size_hints.width = widget_width; -#else /* not USE_X_TOOLKIT */ - size_hints.height = FRAME_PIXEL_HEIGHT (f); - size_hints.width = FRAME_PIXEL_WIDTH (f); -#endif /* not USE_X_TOOLKIT */ - - size_hints.width_inc = FRAME_COLUMN_WIDTH (f); - size_hints.height_inc = FRAME_LINE_HEIGHT (f); - size_hints.max_width - = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); - size_hints.max_height - = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); - - /* Calculate the base and minimum sizes. - - (When we use the X toolkit, we don't do it here. - Instead we copy the values that the widgets are using, below.) */ -#ifndef USE_X_TOOLKIT - { - int base_width, base_height; - int min_rows = 0, min_cols = 0; - - base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); - base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); + int base_width, base_height, width_inc, height_inc; + int min_rows = 0, min_cols = 0; + XSizeHints *size_hints; - check_frame_size (f, &min_rows, &min_cols); + 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); - /* The window manager uses the base width hints to calculate the - current number of rows and columns in the frame while - resizing; min_width and min_height aren't useful for this - purpose, since they might not give the dimensions for a - zero-row, zero-column frame. + check_frame_size (f, &min_rows, &min_cols); - We use the base_width and base_height members if we have - them; otherwise, we set the min_width and min_height members - to the size for a zero x zero frame. */ - -#ifdef HAVE_X11R4 - size_hints.flags |= PBaseSize; - size_hints.base_width = base_width; - size_hints.base_height = base_height; - size_hints.min_width = base_width + min_cols * size_hints.width_inc; - size_hints.min_height = base_height + min_rows * size_hints.height_inc; -#else - size_hints.min_width = base_width; - size_hints.min_height = base_height; -#endif - } - - /* If we don't need the old flags, we don't need the old hint at all. */ - if (flags) + size_hints = FRAME_SIZE_HINTS (f); + if (size_hints == NULL) { - size_hints.flags |= flags; - goto no_read; + size_hints = FRAME_SIZE_HINTS (f) = xmalloc (sizeof (XSizeHints)); + bzero (size_hints, sizeof (XSizeHints)); } -#endif /* not USE_X_TOOLKIT */ - - { - XSizeHints hints; /* Sometimes I hate X Windows... */ - long supplied_return; - int value; - -#ifdef HAVE_X11R4 - value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints, - &supplied_return); -#else - value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints); -#endif - -#ifdef USE_X_TOOLKIT - size_hints.base_height = hints.base_height; - size_hints.base_width = hints.base_width; - size_hints.min_height = hints.min_height; - size_hints.min_width = hints.min_width; -#endif - - if (flags) - size_hints.flags |= flags; - else - { - if (value == 0) - hints.flags = 0; - if (hints.flags & PSize) - size_hints.flags |= PSize; - if (hints.flags & PPosition) - size_hints.flags |= PPosition; - if (hints.flags & USPosition) - size_hints.flags |= USPosition; - if (hints.flags & USSize) - size_hints.flags |= USSize; - } - } - -#ifndef USE_X_TOOLKIT - no_read: -#endif -#ifdef PWinGravity - size_hints.win_gravity = f->win_gravity; - size_hints.flags |= PWinGravity; + 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 (user_position) + if (flags) + size_hints->flags = flags; + else if (user_position) { - size_hints.flags &= ~ PPosition; - size_hints.flags |= USPosition; + size_hints->flags &= ~ PPosition; + size_hints->flags |= USPosition; } -#endif /* PWinGravity */ - -#ifdef HAVE_X11R4 - XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); -#else - XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); -#endif -#endif /* MAC_TODO */ } #if 0 /* MAC_TODO: hide application instead of iconify? */ @@ -6120,7 +6054,7 @@ init_font_name_table () break; sc = GetTextEncodingBase (encoding); decode_mac_font_name (name, sizeof (name), sc); - + /* Point the instance iterator at the current font family. */ if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr) break; @@ -6259,6 +6193,19 @@ init_font_name_table () } +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; +} + + enum xlfd_scalable_field_index { XLFD_SCL_PIXEL_SIZE, @@ -6311,6 +6258,9 @@ mac_do_list_fonts (pattern, maxnames) char *longest_start, *cur_start, *nonspecial; int longest_len, cur_len, 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; @@ -6471,9 +6421,6 @@ x_list_fonts (struct frame *f, Lisp_Object newlist = Qnil, tem, key; struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL; - if (font_name_table == NULL) /* Initialize when first used. */ - init_font_name_table (); - if (dpyinfo) { tem = XCDR (dpyinfo->name_list_element); @@ -6487,7 +6434,9 @@ x_list_fonts (struct frame *f, } } + BLOCK_INPUT; newlist = mac_do_list_fonts (SDATA (pattern), maxnames); + UNBLOCK_INPUT; /* MAC_TODO: add code for matching outline fonts here */ @@ -6791,6 +6740,18 @@ XLoadQueryFont (Display *dpy, char *fontname) } +void +mac_unload_font (dpyinfo, font) + struct mac_display_info *dpyinfo; + XFontStruct *font; +{ + xfree (font->fontname); + if (font->per_char) + xfree (font->per_char); + 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. @@ -6841,7 +6802,9 @@ x_load_font (f, fontname, size) if (size > 0 && !NILP (font_names)) fontname = (char *) SDATA (XCAR (font_names)); + BLOCK_INPUT; font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname); + UNBLOCK_INPUT; if (!font) return NULL; @@ -7121,15 +7084,21 @@ do_ae_print_documents (const AppleEvent *, AppleEvent *, long); static pascal OSErr do_ae_open_documents (AppleEvent *, AppleEvent *, long); static pascal OSErr do_ae_quit_application (AppleEvent *, AppleEvent *, long); +#if TARGET_API_MAC_CARBON /* Drag and Drop */ static OSErr init_mac_drag_n_drop (); static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference); +#endif #if USE_CARBON_EVENTS /* Preliminary Support for the OSX Services Menu */ static OSStatus mac_handle_service_event (EventHandlerCallRef,EventRef,void*); static void init_service_handler (); +/* Window Event Handler */ +static pascal OSStatus mac_handle_window_event (EventHandlerCallRef, + EventRef, void *); #endif +void install_window_handler (WindowPtr); extern void init_emacs_passwd_dir (); extern int emacs_main (int, char **, char **); @@ -7336,12 +7305,11 @@ do_window_update (WindowPtr win) { struct frame *f = mac_window_to_frame (win); - if (win == tip_window) - /* The tooltip has been drawn already. Avoid the - SET_FRAME_GARBAGED below. */ - return; + BeginUpdate (win); - if (f) + /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED + below. */ + if (win != tip_window) { if (f->async_visible == 0) { @@ -7358,17 +7326,30 @@ do_window_update (WindowPtr win) } else { - BeginUpdate (win); + Rect r; + handling_window_update = 1; - XClearWindow (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); +#if TARGET_API_MAC_CARBON + { + RgnHandle region = NewRgn (); - expose_frame (f, 0, 0, 0, 0); + GetPortVisibleRegion (GetWindowPort (win), region); + UpdateControls (win, region); + GetRegionBounds (region, &r); + DisposeRgn (region); + } +#else + UpdateControls (win, win->visRgn); + r = (*win->visRgn)->rgnBBox; +#endif + expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top); handling_window_update = 0; - EndUpdate (win); } } + + EndUpdate (win); } static int @@ -7530,20 +7511,43 @@ do_menu_choice (SInt32 menu_choice) static void do_grow_window (WindowPtr w, EventRecord *e) { - long grow_size; Rect limit_rect; - int rows, columns; + 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 - SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE); + 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) + 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, HiWord (grow_size)); - columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size)); + 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); } @@ -7561,7 +7565,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) GrafPtr save_port; Rect zoom_rect, port_rect; Point top_left; - int w_title_height, columns, rows; + int w_title_height, columns, rows, width, height; struct frame *f = mac_window_to_frame (w); #if TARGET_API_MAC_CARBON @@ -7636,12 +7640,26 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) #else port_rect = w->portRect; #endif - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, port_rect.bottom - port_rect.top); - columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, port_rect.right - port_rect.left); - x_set_window_size (f, 0, columns, rows); + height = port_rect.bottom - port_rect.top; + width = port_rect.right - port_rect.left; + + 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); + + change_frame_size (f, rows, columns, 0, 1, 0); + SET_FRAME_GARBAGED (f); + cancel_mouse_face (f); + + FRAME_PIXEL_WIDTH (f) = width; + FRAME_PIXEL_HEIGHT (f) = height; + } x_real_positions (f, &f->left_pos, &f->top_pos); } +#if TARGET_API_MAC_CARBON /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */ static OSErr init_mac_drag_n_drop () @@ -7649,6 +7667,7 @@ init_mac_drag_n_drop () OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL); return result; } +#endif /* Intialize AppleEvent dispatcher table for the required events. */ void @@ -7819,7 +7838,93 @@ mac_handle_service_event (EventHandlerCallRef callRef, } return err; } + + +static pascal OSStatus +mac_handle_window_event (next_handler, event, data) + EventHandlerCallRef next_handler; + EventRef event; + void *data; +{ + extern Lisp_Object Qcontrol; + + WindowPtr wp; + OSStatus result; + UInt32 attributes; + XSizeHints *size_hints; + + GetEventParameter (event, kEventParamDirectObject, typeWindowRef, + NULL, sizeof (WindowPtr), NULL, &wp); + + switch (GetEventKind (event)) + { + case kEventWindowBoundsChanging: + result = CallNextEventHandler (next_handler, event); + if (result != eventNotHandledErr) + return result; + + GetEventParameter (event, kEventParamAttributes, typeUInt32, + NULL, sizeof (UInt32), NULL, &attributes); + size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp)); + if ((attributes & kWindowBoundsChangeUserResize) + && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize)) + == (PResizeInc | PBaseSize | PMinSize))) + { + Rect bounds; + int width, height; + + GetEventParameter (event, kEventParamCurrentBounds, + typeQDRectangle, + NULL, sizeof (Rect), NULL, &bounds); + 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); + return noErr; + } + break; + } + + return eventNotHandledErr; +} +#endif /* USE_CARBON_EVENTS */ + + +void +install_window_handler (window) + WindowPtr window; +{ +#if USE_CARBON_EVENTS + EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowBoundsChanging}}; + static EventHandlerUPP handle_window_event_UPP = NULL; + + if (handle_window_event_UPP == NULL) + handle_window_event_UPP = NewEventHandlerUPP (mac_handle_window_event); + + InstallWindowEventHandler (window, handle_window_event_UPP, + GetEventTypeCount (specs), specs, NULL, NULL); #endif +} + /* Open Application Apple Event */ static pascal OSErr @@ -7915,6 +8020,7 @@ descriptor_error_exit: } +#if TARGET_API_MAC_CARBON static pascal OSErr mac_do_receive_drag (WindowPtr window, void *handlerRefCon, DragReference theDrag) @@ -7991,6 +8097,7 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon, } } } +#endif /* Print Document Apple Event */ @@ -8140,6 +8247,45 @@ keycode_to_xkeysym (int keyCode, int *xKeySym) return *xKeySym != 0; } +#if !USE_CARBON_EVENTS +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 (NILP (Fboundp (Qmac_ready_for_drag_n_drop))) + 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 USE_CARBON_EVENTS */ + /* Emacs calls this whenever it wants to read an input event from the user. */ int @@ -8151,9 +8297,7 @@ XTread_socket (sd, expected, hold_quit) int count = 0; #if USE_CARBON_EVENTS EventRef eventRef; - EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget (); -#else - EventMask event_mask; + EventTargetRef toolbox_dispatcher; #endif EventRecord er; struct mac_display_info *dpyinfo = &one_mac_display_info; @@ -8184,16 +8328,14 @@ XTread_socket (sd, expected, hold_quit) if (terminate_flag) Fkill_emacs (make_number (1)); -#if !USE_CARBON_EVENTS - event_mask = everyEvent; - if (NILP (Fboundp (Qmac_ready_for_drag_n_drop))) - event_mask -= highLevelEventMask; +#if USE_CARBON_EVENTS + toolbox_dispatcher = GetEventDispatcherTarget (); - while (WaitNextEvent (event_mask, &er, 0L, NULL)) -#else /* USE_CARBON_EVENTS */ while (!ReceiveNextEvent (0, NULL, kEventDurationNoWait, kEventRemoveFromQueue, &eventRef)) -#endif /* USE_CARBON_EVENTS */ +#else /* !USE_CARBON_EVENTS */ + while (mac_wait_next_event (&er, 0, true)) +#endif /* !USE_CARBON_EVENTS */ { int do_help = 0; struct frame *f; @@ -8260,6 +8402,7 @@ XTread_socket (sd, expected, hold_quit) SendEventToEventTarget (eventRef, toolbox_dispatcher); break; + default: /* Send the event to the appropriate receiver. */ SendEventToEventTarget (eventRef, toolbox_dispatcher); @@ -8497,6 +8640,10 @@ XTread_socket (sd, expected, hold_quit) break; case mouseMovedMessage: +#if !USE_CARBON_EVENTS + 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 = help_echo_object = help_echo_window = Qnil; help_echo_pos = -1; @@ -8697,21 +8844,21 @@ XTread_socket (sd, expected, hold_quit) unsigned char ch = inev.code; ByteCount actual_input_length, actual_output_length; unsigned char outbuf[32]; - - convert_status = TECConvertText (converter, &ch, 1, - &actual_input_length, + + convert_status = TECConvertText (converter, &ch, 1, + &actual_input_length, outbuf, 1, - &actual_output_length); - if (convert_status == noErr - && actual_input_length == 1 - && actual_output_length == 1) + &actual_output_length); + if (convert_status == noErr + && actual_input_length == 1 + && actual_output_length == 1) inev.code = *outbuf; - + /* Reset internal states of the converter object. - If it fails, create another one. */ + If it fails, create another one. */ convert_status = TECFlushText (converter, outbuf, sizeof (outbuf), - &actual_output_length); + &actual_output_length); if (convert_status != noErr) { TECDisposeConverter (converter); @@ -8719,7 +8866,7 @@ XTread_socket (sd, expected, hold_quit) kTextEncodingMacRoman, mac_keyboard_text_encoding); } - } + } } #if USE_CARBON_EVENTS @@ -8864,59 +9011,12 @@ __convert_from_newlines (unsigned char * p, size_t * n) } #endif - -/* Initialize the struct pointed to by MW to represent a new COLS x - ROWS Macintosh window, using font with name FONTNAME and size - FONTSIZE. */ -void -make_mac_frame (FRAME_PTR fp) -{ - mac_output *mwp; -#if TARGET_API_MAC_CARBON - static int making_terminal_window = 0; -#else - static int making_terminal_window = 1; -#endif - - mwp = fp->output_data.mac; - - BLOCK_INPUT; - if (making_terminal_window) - { - if (!(mwp->mWP = GetNewCWindow (TERM_WINDOW_RESOURCE, NULL, - (WindowPtr) -1))) - abort (); - making_terminal_window = 0; - } - else - { -#if TARGET_API_MAC_CARBON - Rect r; - - SetRect (&r, 0, 0, 1, 1); - if (CreateNewWindow (kDocumentWindowClass, - kWindowStandardDocumentAttributes - /* | kWindowToolbarButtonAttribute */, - &r, &mwp->mWP) != noErr) -#else - if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1))) -#endif - abort (); - } - - SetWRefCon (mwp->mWP, (long) mwp); - /* so that update events can find this mac_output struct */ - mwp->mFP = fp; /* point back to emacs frame */ - - SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false); - UNBLOCK_INPUT; -} - - +#ifdef MAC_OS8 void make_mac_terminal_frame (struct frame *f) { Lisp_Object frame; + Rect r; XSETFRAME (frame, f); @@ -8940,10 +9040,17 @@ make_mac_terminal_frame (struct frame *f) f->output_data.mac->mouse_pixel = 0xff00ff; f->output_data.mac->cursor_foreground_pixel = 0x0000ff; + f->output_data.mac->text_cursor = GetCursor (iBeamCursor); + f->output_data.mac->nontext_cursor = &arrow_cursor; + f->output_data.mac->modeline_cursor = &arrow_cursor; + f->output_data.mac->hand_cursor = &arrow_cursor; + f->output_data.mac->hourglass_cursor = GetCursor (watchCursor); + f->output_data.mac->horizontal_drag_cursor = &arrow_cursor; + FRAME_FONTSET (f) = -1; f->output_data.mac->explicit_parent = 0; - f->left_pos = 4; - f->top_pos = 4; + f->left_pos = 8; + f->top_pos = 32; f->border_width = 0; f->internal_border_width = 0; @@ -8954,7 +9061,20 @@ make_mac_terminal_frame (struct frame *f) f->new_text_cols = 0; f->new_text_lines = 0; - make_mac_frame (f); + 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, + (WindowPtr) -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); @@ -8970,9 +9090,8 @@ make_mac_terminal_frame (struct frame *f) Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, build_string ("white")), Qnil)); - - ShowWindow (f->output_data.mac->mWP); } +#endif /*********************************************************************** @@ -8989,12 +9108,7 @@ mac_initialize_display_info () bzero (dpyinfo, sizeof (*dpyinfo)); - /* Put it on x_display_name_list. */ - x_display_name_list = Fcons (Fcons (build_string ("Mac"), Qnil), - x_display_name_list); - dpyinfo->name_list_element = XCAR (x_display_name_list); - -#if 0 +#ifdef MAC_OSX dpyinfo->mac_id_name = (char *) xmalloc (SCHARS (Vinvocation_name) + SCHARS (Vsystem_name) @@ -9049,6 +9163,61 @@ mac_initialize_display_info () dpyinfo->mouse_face_hidden = 0; } +/* Create an xrdb-style database of resources to supercede registry settings. + The database is just a concatenation of C strings, finished by an additional + \0. The string are submitted to some basic normalization, so + + [ *]option[ *]:[ *]value... + + becomes + + option:value... + + but any whitespace following value is not removed. */ + +static char * +mac_make_rdb (xrm_option) + char *xrm_option; +{ + char *buffer = xmalloc (strlen (xrm_option) + 2); + char *current = buffer; + char ch; + int in_option = 1; + int before_value = 0; + + do { + ch = *xrm_option++; + + if (ch == '\n') + { + *current++ = '\0'; + in_option = 1; + before_value = 0; + } + else if (ch != ' ') + { + *current++ = ch; + if (in_option && (ch == ':')) + { + in_option = 0; + before_value = 1; + } + else if (before_value) + { + before_value = 0; + } + } + else if (!(in_option || before_value)) + { + *current++ = ch; + } + } while (ch); + + *current = '\0'; + + return buffer; +} + struct mac_display_info * mac_term_init (display_name, xrm_option, resource_name) Lisp_Object display_name; @@ -9056,7 +9225,8 @@ mac_term_init (display_name, xrm_option, resource_name) char *resource_name; { struct mac_display_info *dpyinfo; - GDHandle main_device_handle; + + BLOCK_INPUT; if (!mac_initialized) { @@ -9064,17 +9234,90 @@ mac_term_init (display_name, xrm_option, resource_name) mac_initialized = 1; } - mac_initialize_display_info (display_name); + if (x_display_list) + error ("Sorry, this version can only handle one display"); + + mac_initialize_display_info (); dpyinfo = &one_mac_display_info; - main_device_handle = LMGetMainDevice(); + dpyinfo->xrdb = xrm_option ? mac_make_rdb (xrm_option) : NULL; - dpyinfo->height = (**main_device_handle).gdRect.bottom; - dpyinfo->width = (**main_device_handle).gdRect.right; + /* 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, Qnil), + x_display_name_list); + dpyinfo->name_list_element = XCAR (x_display_name_list); + + 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->font_encoder) + 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)); + } +} + #ifdef MAC_OSX void @@ -9334,7 +9577,6 @@ mac_initialize () #endif BLOCK_INPUT; - mac_initialize_display_info (); #if TARGET_API_MAC_CARBON init_required_apple_events (); @@ -9372,7 +9614,9 @@ syms_of_macterm () Qsuper = intern ("super"); Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); +#ifdef MAC_OSX Fprovide (intern ("mac-carbon"), Qnil); +#endif staticpro (&Qreverse); Qreverse = intern ("reverse"); diff --git a/src/macterm.h b/src/macterm.h index 308a9200395..7c7d55c3790 100644 --- a/src/macterm.h +++ b/src/macterm.h @@ -218,6 +218,9 @@ struct mac_display_info struct image_cache *image_cache; }; +/* 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. */ @@ -388,6 +391,9 @@ struct mac_output { /* 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; + + /* Hints for the size and the position of a window. */ + XSizeHints *size_hints; }; typedef struct mac_output mac_output; @@ -404,6 +410,8 @@ typedef struct mac_output mac_output; #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 w32_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) @@ -593,6 +601,7 @@ extern void XFreePixmap P_ ((Display *, Pixmap)); extern void XSetForeground P_ ((Display *, GC, unsigned long)); extern void mac_draw_line_to_pixmap P_ ((Display *, Pixmap, GC, int, int, int, int)); +extern void mac_unload_font P_ ((struct mac_display_info *, XFontStruct *)); #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0 #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0 diff --git a/src/process.c b/src/process.c index 646b9aed6a8..c17b32eb3c5 100644 --- a/src/process.c +++ b/src/process.c @@ -1290,7 +1290,7 @@ list_processes_1 (query_only) XSETFASTINT (minspace, 1); set_buffer_internal (XBUFFER (Vstandard_output)); - Fbuffer_disable_undo (Vstandard_output); + current_buffer->undo_list = Qt; current_buffer->truncate_lines = Qt; diff --git a/src/xdisp.c b/src/xdisp.c index b0a8f953c9c..7cb9c0c92eb 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -810,7 +810,7 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 }; static void setup_for_ellipsis P_ ((struct it *, int)); static void mark_window_display_accurate_1 P_ ((struct window *, int)); -static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); +static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object)); static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); static int cursor_row_p P_ ((struct window *, struct glyph_row *)); static int redisplay_mode_lines P_ ((Lisp_Object, int)); @@ -832,7 +832,7 @@ static int store_frame_title P_ ((const unsigned char *, int, int)); static void x_consider_frame_title P_ ((Lisp_Object)); static void handle_stop P_ ((struct it *)); static int tool_bar_lines_needed P_ ((struct frame *)); -static int single_display_prop_intangible_p P_ ((Lisp_Object)); +static int single_display_spec_intangible_p P_ ((Lisp_Object)); static void ensure_echo_area_buffers P_ ((void)); static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object)); static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *)); @@ -926,7 +926,7 @@ static void compute_string_pos P_ ((struct text_pos *, struct text_pos, Lisp_Object)); static int face_before_or_after_it_pos P_ ((struct it *, int)); static int next_overlay_change P_ ((int)); -static int handle_single_display_prop P_ ((struct it *, Lisp_Object, +static int handle_single_display_spec P_ ((struct it *, Lisp_Object, Lisp_Object, struct text_pos *, int)); static int underlying_face_id P_ ((struct it *)); @@ -3275,7 +3275,10 @@ setup_for_ellipsis (it, len) ***********************************************************************/ /* Set up iterator IT from `display' property at its current position. - Called from handle_stop. */ + Called from handle_stop. + We return HANDLED_RETURN if some part of the display property + overrides the display of the buffer text itself. + Otherwise we return HANDLED_NORMALLY. */ static enum prop_handled handle_display_prop (it) @@ -3283,6 +3286,7 @@ handle_display_prop (it) { Lisp_Object prop, object; struct text_pos *position; + /* Nonzero if some property replaces the display of the text itself. */ int display_replaced_p = 0; if (STRINGP (it->string)) @@ -3330,7 +3334,7 @@ handle_display_prop (it) { for (; CONSP (prop); prop = XCDR (prop)) { - if (handle_single_display_prop (it, XCAR (prop), object, + if (handle_single_display_spec (it, XCAR (prop), object, position, display_replaced_p)) display_replaced_p = 1; } @@ -3339,13 +3343,13 @@ handle_display_prop (it) { int i; for (i = 0; i < ASIZE (prop); ++i) - if (handle_single_display_prop (it, AREF (prop, i), object, + if (handle_single_display_spec (it, AREF (prop, i), object, position, display_replaced_p)) display_replaced_p = 1; } else { - if (handle_single_display_prop (it, prop, object, position, 0)) + if (handle_single_display_spec (it, prop, object, position, 0)) display_replaced_p = 1; } @@ -3377,42 +3381,44 @@ display_prop_end (it, object, start_pos) } -/* Set up IT from a single `display' sub-property value PROP. OBJECT +/* Set up IT from a single `display' specification PROP. OBJECT is the object in which the `display' property was found. *POSITION is the position at which it was found. DISPLAY_REPLACED_P non-zero - means that we previously saw a display sub-property which already + means that we previously saw a display specification which already replaced text display with something else, for example an image; - ignore such properties after the first one has been processed. + we ignore such properties after the first one has been processed. - If PROP is a `space' or `image' sub-property, set *POSITION to the - end position of the `display' property. + If PROP is a `space' or `image' specification, and in some other + cases too, set *POSITION to the position where the `display' + property ends. Value is non-zero if something was found which replaces the display of buffer or string text. */ static int -handle_single_display_prop (it, prop, object, position, +handle_single_display_spec (it, spec, object, position, display_replaced_before_p) struct it *it; - Lisp_Object prop; + Lisp_Object spec; Lisp_Object object; struct text_pos *position; int display_replaced_before_p; { - Lisp_Object value; - int replaces_text_display_p = 0; Lisp_Object form; + Lisp_Object location, value; + struct text_pos start_pos; + int valid_p; - /* If PROP is a list of the form `(when FORM . VALUE)', FORM is - evaluated. If the result is nil, VALUE is ignored. */ + /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. + If the result is non-nil, use VALUE instead of SPEC. */ form = Qt; - if (CONSP (prop) && EQ (XCAR (prop), Qwhen)) + if (CONSP (spec) && EQ (XCAR (spec), Qwhen)) { - prop = XCDR (prop); - if (!CONSP (prop)) + spec = XCDR (spec); + if (!CONSP (spec)) return 0; - form = XCAR (prop); - prop = XCDR (prop); + form = XCAR (spec); + spec = XCDR (spec); } if (!NILP (form) && !EQ (form, Qt)) @@ -3438,15 +3444,15 @@ handle_single_display_prop (it, prop, object, position, if (NILP (form)) return 0; - if (CONSP (prop) - && EQ (XCAR (prop), Qheight) - && CONSP (XCDR (prop))) + /* Handle `(height HEIGHT)' specifications. */ + if (CONSP (spec) + && EQ (XCAR (spec), Qheight) + && CONSP (XCDR (spec))) { - if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) + if (!FRAME_WINDOW_P (it->f)) return 0; - - /* `(height HEIGHT)'. */ - it->font_height = XCAR (XCDR (prop)); + + it->font_height = XCAR (XCDR (spec)); if (!NILP (it->font_height)) { struct face *face = FACE_FROM_ID (it->f, it->face_id); @@ -3487,7 +3493,6 @@ handle_single_display_prop (it, prop, object, position, { /* Evaluate IT->font_height with `height' bound to the current specified height to get the new height. */ - Lisp_Object value; int count = SPECPDL_INDEX (); specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); @@ -3501,29 +3506,35 @@ handle_single_display_prop (it, prop, object, position, if (new_height > 0) it->face_id = face_with_height (it->f, it->face_id, new_height); } + + return 0; } - else if (CONSP (prop) - && EQ (XCAR (prop), Qspace_width) - && CONSP (XCDR (prop))) + + /* Handle `(space_width WIDTH)'. */ + if (CONSP (spec) + && EQ (XCAR (spec), Qspace_width) + && CONSP (XCDR (spec))) { - /* `(space_width WIDTH)'. */ - if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) + if (!FRAME_WINDOW_P (it->f)) return 0; - value = XCAR (XCDR (prop)); + value = XCAR (XCDR (spec)); if (NUMBERP (value) && XFLOATINT (value) > 0) it->space_width = value; + + return 0; } - else if (CONSP (prop) - && EQ (XCAR (prop), Qslice)) + + /* Handle `(slice X Y WIDTH HEIGHT)'. */ + if (CONSP (spec) + && EQ (XCAR (spec), Qslice)) { - /* `(slice X Y WIDTH HEIGHT)'. */ Lisp_Object tem; - if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) + if (!FRAME_WINDOW_P (it->f)) return 0; - if (tem = XCDR (prop), CONSP (tem)) + if (tem = XCDR (spec), CONSP (tem)) { it->slice.x = XCAR (tem); if (tem = XCDR (tem), CONSP (tem)) @@ -3537,17 +3548,20 @@ handle_single_display_prop (it, prop, object, position, } } } + + return 0; } - else if (CONSP (prop) - && EQ (XCAR (prop), Qraise) - && CONSP (XCDR (prop))) + + /* Handle `(raise FACTOR)'. */ + if (CONSP (spec) + && EQ (XCAR (spec), Qraise) + && CONSP (XCDR (spec))) { - /* `(raise FACTOR)'. */ if (!FRAME_WINDOW_P (it->f)) return 0; #ifdef HAVE_WINDOW_SYSTEM - value = XCAR (XCDR (prop)); + value = XCAR (XCDR (spec)); if (NUMBERP (value)) { struct face *face = FACE_FROM_ID (it->f, it->face_id); @@ -3555,188 +3569,194 @@ handle_single_display_prop (it, prop, object, position, * (FONT_HEIGHT (face->font))); } #endif /* HAVE_WINDOW_SYSTEM */ + + return 0; } - else if (!it->string_from_display_prop_p) - { - /* `((margin left-margin) VALUE)' or `((margin right-margin) - VALUE) or `((margin nil) VALUE)' or VALUE. */ - Lisp_Object location, value; - struct text_pos start_pos; - int valid_p; - /* Characters having this form of property are not displayed, so - we have to find the end of the property. */ - start_pos = *position; - *position = display_prop_end (it, object, start_pos); - value = Qnil; + /* Don't handle the other kinds of display specifications + inside a string that we got from a `display' property. */ + if (it->string_from_display_prop_p) + return 0; - /* Let's stop at the new position and assume that all - text properties change there. */ - it->stop_charpos = position->charpos; + /* Characters having this form of property are not displayed, so + we have to find the end of the property. */ + start_pos = *position; + *position = display_prop_end (it, object, start_pos); + value = Qnil; - if (CONSP (prop) - && (EQ (XCAR (prop), Qleft_fringe) - || EQ (XCAR (prop), Qright_fringe)) - && CONSP (XCDR (prop))) - { - int face_id = DEFAULT_FACE_ID; - int fringe_bitmap; + /* Stop the scan at that end position--we assume that all + text properties change there. */ + it->stop_charpos = position->charpos; - /* Save current settings of IT so that we can restore them - when we are finished with the glyph property value. */ + /* Handle `(left-fringe BITMAP [FACE])' + and `(right-fringe BITMAP [FACE])'. */ + if (CONSP (spec) + && (EQ (XCAR (spec), Qleft_fringe) + || EQ (XCAR (spec), Qright_fringe)) + && CONSP (XCDR (spec))) + { + int face_id = DEFAULT_FACE_ID; + int fringe_bitmap; - /* `(left-fringe BITMAP FACE)'. */ - if (!FRAME_WINDOW_P (it->f)) - return 0; + if (!FRAME_WINDOW_P (it->f)) + /* If we return here, POSITION has been advanced + across the text with this property. */ + return 0; #ifdef HAVE_WINDOW_SYSTEM - value = XCAR (XCDR (prop)); - if (!SYMBOLP (value) - || !(fringe_bitmap = lookup_fringe_bitmap (value))) - return 0; + value = XCAR (XCDR (spec)); + if (!SYMBOLP (value) + || !(fringe_bitmap = lookup_fringe_bitmap (value))) + /* If we return here, POSITION has been advanced + across the text with this property. */ + return 0; - if (CONSP (XCDR (XCDR (prop)))) - { - Lisp_Object face_name = XCAR (XCDR (XCDR (prop))); - int face_id2 = lookup_named_face (it->f, face_name, 'A', 0); - if (face_id2 >= 0) - face_id = face_id2; - } + if (CONSP (XCDR (XCDR (spec)))) + { + Lisp_Object face_name = XCAR (XCDR (XCDR (spec))); + int face_id2 = lookup_named_face (it->f, face_name, 'A', 0); + if (face_id2 >= 0) + face_id = face_id2; + } - push_it (it); + /* Save current settings of IT so that we can restore them + when we are finished with the glyph property value. */ - it->area = TEXT_AREA; - it->what = IT_IMAGE; - it->image_id = -1; /* no image */ - it->position = start_pos; - it->object = NILP (object) ? it->w->buffer : object; - it->method = next_element_from_image; - it->face_id = face_id; + push_it (it); - /* Say that we haven't consumed the characters with - `display' property yet. The call to pop_it in - set_iterator_to_next will clean this up. */ - *position = start_pos; + it->area = TEXT_AREA; + it->what = IT_IMAGE; + it->image_id = -1; /* no image */ + it->position = start_pos; + it->object = NILP (object) ? it->w->buffer : object; + it->method = next_element_from_image; + it->face_id = face_id; - if (EQ (XCAR (prop), Qleft_fringe)) - { - it->left_user_fringe_bitmap = fringe_bitmap; - it->left_user_fringe_face_id = face_id; - } - else - { - it->right_user_fringe_bitmap = fringe_bitmap; - it->right_user_fringe_face_id = face_id; - } -#endif /* HAVE_WINDOW_SYSTEM */ - return 1; - } + /* Say that we haven't consumed the characters with + `display' property yet. The call to pop_it in + set_iterator_to_next will clean this up. */ + *position = start_pos; - location = Qunbound; - if (CONSP (prop) && CONSP (XCAR (prop))) + if (EQ (XCAR (spec), Qleft_fringe)) { - Lisp_Object tem; + it->left_user_fringe_bitmap = fringe_bitmap; + it->left_user_fringe_face_id = face_id; + } + else + { + it->right_user_fringe_bitmap = fringe_bitmap; + it->right_user_fringe_face_id = face_id; + } +#endif /* HAVE_WINDOW_SYSTEM */ + return 1; + } - value = XCDR (prop); - if (CONSP (value)) - value = XCAR (value); + /* Prepare to handle `((margin left-margin) ...)', + `((margin right-margin) ...)' and `((margin nil) ...)' + prefixes for display specifications. */ + location = Qunbound; + if (CONSP (spec) && CONSP (XCAR (spec))) + { + Lisp_Object tem; - tem = XCAR (prop); - if (EQ (XCAR (tem), Qmargin) - && (tem = XCDR (tem), - tem = CONSP (tem) ? XCAR (tem) : Qnil, - (NILP (tem) - || EQ (tem, Qleft_margin) - || EQ (tem, Qright_margin)))) - location = tem; - } + value = XCDR (spec); + if (CONSP (value)) + value = XCAR (value); - if (EQ (location, Qunbound)) - { - location = Qnil; - value = prop; - } + tem = XCAR (spec); + if (EQ (XCAR (tem), Qmargin) + && (tem = XCDR (tem), + tem = CONSP (tem) ? XCAR (tem) : Qnil, + (NILP (tem) + || EQ (tem, Qleft_margin) + || EQ (tem, Qright_margin)))) + location = tem; + } + + if (EQ (location, Qunbound)) + { + location = Qnil; + value = spec; + } + + /* After this point, VALUE is the property after any + margin prefix has been stripped. It must be a string, + an image specification, or `(space ...)'. - valid_p = (STRINGP (value) + LOCATION specifies where to display: `left-margin', + `right-margin' or nil. */ + + valid_p = (STRINGP (value) #ifdef HAVE_WINDOW_SYSTEM - || (FRAME_WINDOW_P (it->f) && valid_image_p (value)) + || (FRAME_WINDOW_P (it->f) && valid_image_p (value)) #endif /* not HAVE_WINDOW_SYSTEM */ - || (CONSP (value) && EQ (XCAR (value), Qspace))); - - if ((EQ (location, Qleft_margin) - || EQ (location, Qright_margin) - || NILP (location)) - && valid_p - && !display_replaced_before_p) - { - replaces_text_display_p = 1; + || (CONSP (value) && EQ (XCAR (value), Qspace))); - /* Save current settings of IT so that we can restore them - when we are finished with the glyph property value. */ - push_it (it); + if (valid_p && !display_replaced_before_p) + { + /* Save current settings of IT so that we can restore them + when we are finished with the glyph property value. */ + push_it (it); + if (NILP (location)) + it->area = TEXT_AREA; + else if (EQ (location, Qleft_margin)) + it->area = LEFT_MARGIN_AREA; + else + it->area = RIGHT_MARGIN_AREA; - if (NILP (location)) - it->area = TEXT_AREA; - else if (EQ (location, Qleft_margin)) - it->area = LEFT_MARGIN_AREA; - else - it->area = RIGHT_MARGIN_AREA; + if (STRINGP (value)) + { + it->string = value; + it->multibyte_p = STRING_MULTIBYTE (it->string); + it->current.overlay_string_index = -1; + IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; + it->end_charpos = it->string_nchars = SCHARS (it->string); + it->method = next_element_from_string; + it->stop_charpos = 0; + it->string_from_display_prop_p = 1; + /* Say that we haven't consumed the characters with + `display' property yet. The call to pop_it in + set_iterator_to_next will clean this up. */ + *position = start_pos; + } + else if (CONSP (value) && EQ (XCAR (value), Qspace)) + { + it->method = next_element_from_stretch; + it->object = value; + it->current.pos = it->position = start_pos; - if (STRINGP (value)) - { - it->string = value; - it->multibyte_p = STRING_MULTIBYTE (it->string); - it->current.overlay_string_index = -1; - IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; - it->end_charpos = it->string_nchars = SCHARS (it->string); - it->method = next_element_from_string; - it->stop_charpos = 0; - it->string_from_display_prop_p = 1; - /* Say that we haven't consumed the characters with - `display' property yet. The call to pop_it in - set_iterator_to_next will clean this up. */ - *position = start_pos; - } - else if (CONSP (value) && EQ (XCAR (value), Qspace)) - { - it->method = next_element_from_stretch; - it->object = value; - it->current.pos = it->position = start_pos; - } -#ifdef HAVE_WINDOW_SYSTEM - else - { - if (FRAME_WINDOW_P (it->f)) - { - it->what = IT_IMAGE; - it->image_id = lookup_image (it->f, value); - it->position = start_pos; - it->object = NILP (object) ? it->w->buffer : object; - it->method = next_element_from_image; - } - - /* Say that we haven't consumed the characters with - `display' property yet. The call to pop_it in - set_iterator_to_next will clean this up. */ - *position = start_pos; - } -#endif /* HAVE_WINDOW_SYSTEM */ } +#ifdef HAVE_WINDOW_SYSTEM else - /* Invalid property or property not supported. Restore - the position to what it was before. */ - *position = start_pos; + { + it->what = IT_IMAGE; + it->image_id = lookup_image (it->f, value); + it->position = start_pos; + it->object = NILP (object) ? it->w->buffer : object; + it->method = next_element_from_image; + + /* Say that we haven't consumed the characters with + `display' property yet. The call to pop_it in + set_iterator_to_next will clean this up. */ + *position = start_pos; + } +#endif /* HAVE_WINDOW_SYSTEM */ + + return 1; } - return replaces_text_display_p; + /* Invalid property or property not supported. Restore + POSITION to what it was before. */ + *position = start_pos; + return 0; } -/* Check if PROP is a display sub-property value whose text should be +/* Check if SPEC is a display sub-property value whose text should be treated as intangible. */ static int -single_display_prop_intangible_p (prop) +single_display_spec_intangible_p (prop) Lisp_Object prop; { /* Skip over `when FORM'. */ @@ -3789,7 +3809,7 @@ display_prop_intangible_p (prop) /* A list of sub-properties. */ while (CONSP (prop)) { - if (single_display_prop_intangible_p (XCAR (prop))) + if (single_display_spec_intangible_p (XCAR (prop))) return 1; prop = XCDR (prop); } @@ -3799,11 +3819,11 @@ display_prop_intangible_p (prop) /* A vector of sub-properties. */ int i; for (i = 0; i < ASIZE (prop); ++i) - if (single_display_prop_intangible_p (AREF (prop, i))) + if (single_display_spec_intangible_p (AREF (prop, i))) return 1; } else - return single_display_prop_intangible_p (prop); + return single_display_spec_intangible_p (prop); return 0; } @@ -3812,7 +3832,7 @@ display_prop_intangible_p (prop) /* Return 1 if PROP is a display sub-property value containing STRING. */ static int -single_display_prop_string_p (prop, string) +single_display_spec_string_p (prop, string) Lisp_Object prop, string; { if (EQ (string, prop)) @@ -3857,7 +3877,7 @@ display_prop_string_p (prop, string) /* A list of sub-properties. */ while (CONSP (prop)) { - if (single_display_prop_string_p (XCAR (prop), string)) + if (single_display_spec_string_p (XCAR (prop), string)) return 1; prop = XCDR (prop); } @@ -3867,11 +3887,11 @@ display_prop_string_p (prop, string) /* A vector of sub-properties. */ int i; for (i = 0; i < ASIZE (prop); ++i) - if (single_display_prop_string_p (AREF (prop, i), string)) + if (single_display_spec_string_p (AREF (prop, i), string)) return 1; } else - return single_display_prop_string_p (prop, string); + return single_display_spec_string_p (prop, string); return 0; } @@ -6624,7 +6644,7 @@ message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte) } return 0; } - + /* Display an echo area message M with a specified length of NBYTES bytes. The string may include null characters. If M is 0, clear @@ -21890,20 +21910,6 @@ expose_window (w, fr) } } -#ifdef HAVE_CARBON - /* Display scroll bar for this window. */ - if (!NILP (w->vertical_scroll_bar)) - { - /* ++KFS: - If this doesn't work here (maybe some header files are missing), - make a function in macterm.c and call it to do the job! */ - ControlHandle ch - = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar)); - - Draw1Control (ch); - } -#endif - return mouse_face_overwritten_p; } @@ -21962,16 +21968,6 @@ expose_frame (f, x, y, w, h) return; } -#ifdef HAVE_CARBON - /* MAC_TODO: this is a kludge, but if scroll bars are not activated - or deactivated here, for unknown reasons, activated scroll bars - are shown in deactivated frames in some instances. */ - if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame) - activate_scroll_bars (f); - else - deactivate_scroll_bars (f); -#endif - /* If basic faces haven't been realized yet, there is no point in trying to redraw anything. This can happen when we get an expose event while Emacs is starting, e.g. by moving another window. */ diff --git a/src/xfaces.c b/src/xfaces.c index eb5f617b4a1..a1b6b4bc775 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -1075,6 +1075,9 @@ clear_font_table (dpyinfo) #ifdef WINDOWSNT w32_unload_font (dpyinfo, font_info->font); #endif +#ifdef MAC_OS + mac_unload_font (dpyinfo, font_info->font); +#endif UNBLOCK_INPUT; /* Mark font table slot free. */ diff --git a/src/xfns.c b/src/xfns.c index 2fe08e0a458..6a99dbf8e5b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5278,6 +5278,16 @@ or directory must exist. ONLY-DIR-P is ignored." */) XEvent event; x_menu_wait_for_event (0); XtAppNextEvent (Xt_app_con, &event); + if (event.type == KeyPress + && FRAME_X_DISPLAY (f) == event.xkey.display) + { + KeySym keysym = XLookupKeysym (&event.xkey, 0); + + /* Pop down on C-g. */ + if (keysym == XK_g && (event.xkey.state & ControlMask) != 0) + XtUnmanageChild (dialog); + } + (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f)); } diff --git a/src/xmenu.c b/src/xmenu.c index 45b0742df0e..774f404fd42 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -116,7 +116,7 @@ extern XtAppContext Xt_app_con; static Lisp_Object xdialog_show P_ ((FRAME_PTR, int, Lisp_Object, char **)); static void popup_get_selection P_ ((XEvent *, struct x_display_info *, - LWLIB_ID, int, int)); + LWLIB_ID, int)); /* Define HAVE_BOXES if menus can handle radio and toggle buttons. */ @@ -1186,24 +1186,21 @@ x_menu_wait_for_event (void *data) popped down (deactivated). This is used for x-popup-menu and x-popup-dialog; it is not used for the menu bar. - If DOWN_ON_KEYPRESS is nonzero, pop down if a key is pressed. - NOTE: All calls to popup_get_selection should be protected with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ static void -popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress) +popup_get_selection (initial_event, dpyinfo, id, do_timers) XEvent *initial_event; struct x_display_info *dpyinfo; LWLIB_ID id; int do_timers; - int down_on_keypress; { XEvent event; while (popup_activated_flag) { - if (initial_event) + if (initial_event) { event = *initial_event; initial_event = 0; @@ -1232,20 +1229,15 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress) event.xbutton.state = 0; #endif } - /* If the user presses a key that doesn't go to the menu, - deactivate the menu. - The user is likely to do that if we get wedged. - All toolkits now pop down menus on ESC. - For dialogs however, the focus may not be on the dialog, so - in that case, we pop down. */ + /* Pop down on C-g and Escape. */ else if (event.type == KeyPress - && down_on_keypress && dpyinfo->display == event.xbutton.display) { KeySym keysym = XLookupKeysym (&event.xkey, 0); - if (!IsModifierKey (keysym) - && x_any_window_to_frame (dpyinfo, event.xany.window) != NULL) - popup_activated_flag = 0; + + if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0) + || keysym == XK_Escape) /* Any escape, ignore modifiers. */ + popup_activated_flag = 0; } x_dispatch_event (&event, event.xany.display); @@ -2226,6 +2218,9 @@ set_frame_menubar (f, first_time, deep_p) } else { + char menuOverride[] = "Ctrl<KeyPress>g: MenuGadgetEscape()"; + XtTranslations override = XtParseTranslationTable (menuOverride); + menubar_widget = lw_create_widget ("menubar", "menubar", id, first_wv, f->output_data.x->column_widget, 0, @@ -2234,6 +2229,9 @@ set_frame_menubar (f, first_time, deep_p) popup_deactivate_callback, menu_highlight_callback); f->output_data.x->menubar_widget = menubar_widget; + + /* Make menu pop down on C-g. */ + XtOverrideTranslations (menubar_widget, override); } { @@ -2597,7 +2595,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click) make_number (menu_id & ~(-1 << (fact))))); /* Process events that apply to the menu. */ - popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0); + popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1); unbind_to (specpdl_count, Qnil); } @@ -2975,7 +2973,7 @@ create_and_show_dialog (f, first_wv) make_number (dialog_id & ~(-1 << (fact))))); popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), - dialog_id, 1, 1); + dialog_id, 1); unbind_to (count, Qnil); } @@ -3155,6 +3153,9 @@ xdialog_show (f, keymaps, title, error) } } } + else + /* Make "Cancel" equivalent to C-g. */ + Fsignal (Qquit, Qnil); return Qnil; } @@ -3500,7 +3501,13 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) case XM_FAILURE: *error = "Can't activate menu"; case XM_IA_SELECT: + entry = Qnil; + break; case XM_NO_SELECT: + /* Make "Cancel" equivalent to C-g unless this menu was popped up by + a mouse press. */ + if (! for_click) + Fsignal (Qquit, Qnil); entry = Qnil; break; } |