# HG changeset patch # User Steven Tamm # Date 1104168450 0 # Node ID 9bde7721ad0fe3b610d1754cec5e24fe7446fdcd # Parent c331d9c412f2205c6888c7fa1e7e9d2a8faaeb5d * 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. diff -r c331d9c412f2 -r 9bde7721ad0f src/ChangeLog --- a/src/ChangeLog Mon Dec 27 17:23:53 2004 +0000 +++ b/src/ChangeLog Mon Dec 27 17:27:30 2004 +0000 @@ -1,3 +1,130 @@ +2004-12-27 YAMAMOTO Mitsuharu + + * 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 * buffer.c (Fbuffer_disable_undo): Deleted (moved to simple.el). diff -r c331d9c412f2 -r 9bde7721ad0f src/dispextern.h --- a/src/dispextern.h Mon Dec 27 17:23:53 2004 +0000 +++ b/src/dispextern.h Mon Dec 27 17:27:30 2004 +0000 @@ -62,7 +62,7 @@ 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. */ @@ -1171,7 +1171,7 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/emacs.c --- a/src/emacs.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/emacs.c Mon Dec 27 17:27:30 2004 +0000 @@ -1306,7 +1306,7 @@ 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 (); @@ -1318,7 +1318,7 @@ syms_of_search (); syms_of_frame (); - mac_initialize (); + mac_term_init (build_string ("Mac"), NULL, NULL); init_keyboard (); #endif diff -r c331d9c412f2 -r 9bde7721ad0f src/fileio.c --- a/src/fileio.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/fileio.c Mon Dec 27 17:27:30 2004 +0000 @@ -6188,7 +6188,7 @@ 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 @@ -6329,7 +6329,7 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/fns.c --- a/src/fns.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/fns.c Mon Dec 27 17:27:30 2004 +0000 @@ -26,8 +26,8 @@ #endif #include -#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 -r c331d9c412f2 -r 9bde7721ad0f src/frame.c --- a/src/frame.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/frame.c Mon Dec 27 17:27:30 2004 +0000 @@ -2815,8 +2815,6 @@ 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 @@ -2832,7 +2830,6 @@ 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 @@ -2993,14 +2990,11 @@ 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 } @@ -3012,7 +3006,6 @@ 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)) @@ -3021,7 +3014,6 @@ f->want_fullscreen = FULLSCREEN_WIDTH; else if (EQ (new_value, Qfullheight)) f->want_fullscreen = FULLSCREEN_HEIGHT; -#endif } @@ -3141,7 +3133,7 @@ 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 */ @@ -4052,7 +4044,7 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/image.c --- a/src/image.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/image.c Mon Dec 27 17:27:30 2004 +0000 @@ -83,16 +83,19 @@ #ifdef MAC_OS #include "macterm.h" +#include #ifndef MAC_OSX #include +#include #endif #ifdef MAC_OSX -#include #include #else /* not MAC_OSX */ #include #include #include +#include +#include #endif /* not MAC_OSX */ /* MAC_TODO : Color tables on Mac. */ diff -r c331d9c412f2 -r 9bde7721ad0f src/mac.c --- a/src/mac.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/mac.c Mon Dec 27 17:27:30 2004 +0000 @@ -845,6 +845,8 @@ } +extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean); + int select (n, rfds, wfds, efds, timeout) int n; @@ -853,49 +855,24 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); + + /* 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; + + *rfds = orfds; + +#ifdef SELECT_USE_CFSOCKET + if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) + goto poll_periodically; + + { + 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)) + { + 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++; + } + + 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 */ } - FD_CLR (0, rfds); - do - { - EMACS_TIME select_timeout; - SELECT_TYPE orfds = *rfds; - int r; - - EMACS_SET_SECS_USECS (select_timeout, 0, 20000); - - if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) - select_timeout = remaining_time; - - 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) - { - FD_SET (0, rfds); - r++; - } + + 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; - } - 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); - } - } - while (!timeout || EMACS_TIME_LT (now, end_time)); - - return 0; + + *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 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/macfns.c --- a/src/macfns.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/macfns.c Mon Dec 27 17:27:30 2004 +0000 @@ -158,9 +158,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ } -#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 @@ 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 @@ "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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON /*********************************************************************** File selection dialog ***********************************************************************/ @@ -4405,14 +4435,19 @@ 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 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/macgui.h --- a/src/macgui.h Mon Dec 27 17:23:53 2004 +0000 +++ b/src/macgui.h Mon Dec 27 17:27:30 2004 +0000 @@ -62,18 +62,17 @@ #else #include /* for WindowPtr */ #include /* for GWorldPtr */ -#include /* for ControlHandle in xdisp.c */ +#include #include #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 @@ #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 -r c331d9c412f2 -r 9bde7721ad0f src/macterm.c --- a/src/macterm.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/macterm.c Mon Dec 27 17:27:30 2004 +0000 @@ -1178,7 +1178,17 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ +#if 0 /* Mouse clicks and mouse movement. Rah. */ /* Prepare a mouse-event in *RESULT for placement in the input queue. @@ -3685,6 +3699,7 @@ result->arg = Qnil; return Qnil; } +#endif /* Function to report a mouse movement to the mainstream Emacs code. @@ -3754,8 +3769,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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_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 @@ 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); - - check_frame_size (f, &min_rows, &min_cols); - - /* 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. - - 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. */ + int base_width, base_height, width_inc, height_inc; + int min_rows = 0, min_cols = 0; + XSizeHints *size_hints; + + base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); + base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); + width_inc = FRAME_COLUMN_WIDTH (f); + height_inc = FRAME_LINE_HEIGHT (f); + + check_frame_size (f, &min_rows, &min_cols); + + size_hints = FRAME_SIZE_HINTS (f); + if (size_hints == NULL) + { + size_hints = FRAME_SIZE_HINTS (f) = xmalloc (sizeof (XSizeHints)); + bzero (size_hints, sizeof (XSizeHints)); + } + + size_hints->flags |= PResizeInc | PMinSize | PBaseSize ; + size_hints->width_inc = width_inc; + size_hints->height_inc = height_inc; + size_hints->min_width = base_width + min_cols * width_inc; + size_hints->min_height = base_height + min_rows * height_inc; + size_hints->base_width = base_width; + size_hints->base_height = base_height; + if (flags) - { - size_hints.flags |= flags; - goto no_read; - } -#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; - - if (user_position) - { - 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 */ + size_hints->flags = flags; + else if (user_position) + { + size_hints->flags &= ~ PPosition; + size_hints->flags |= USPosition; + } } #if 0 /* MAC_TODO: hide application instead of iconify? */ @@ -6120,7 +6054,7 @@ 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 @@ } +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 @@ 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 @@ 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 @@ } } + 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 @@ } +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 @@ 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 @@ 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 (); -#endif +/* 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 @@ { 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; - - if (f) + BeginUpdate (win); + + /* 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 @@ } else { - BeginUpdate (win); + Rect r; + handling_window_update = 1; - XClearWindow (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); - - expose_frame (f, 0, 0, 0, 0); +#if TARGET_API_MAC_CARBON + { + RgnHandle region = NewRgn (); + + 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 @@ 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); - - SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE); - + XSizeHints *size_hints = FRAME_SIZE_HINTS (f); + int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE; +#if TARGET_API_MAC_CARBON + Rect new_rect; +#else + long grow_size; +#endif + + if (size_hints->flags & PMinSize) + { + min_width = size_hints->min_width; + min_height = size_hints->min_height; + } + SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE); + +#if TARGET_API_MAC_CARBON + if (!ResizeWindow (w, e->where, &limit_rect, &new_rect)) + return; + height = new_rect.bottom - new_rect.top; + width = new_rect.right - new_rect.left; +#else grow_size = GrowWindow (w, e->where, &limit_rect); - /* see if it really changed size */ - if (grow_size != 0) - { - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, HiWord (grow_size)); - columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size)); + if (grow_size == 0) + return; + height = HiWord (grow_size); + width = LoWord (grow_size); +#endif + + if (width != FRAME_PIXEL_WIDTH (f) + || height != FRAME_PIXEL_HEIGHT (f)) + { + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); + columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); x_set_window_size (f, 0, columns, rows); } @@ -7561,7 +7565,7 @@ 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 @@ #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 @@ 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 @@ } return err; } -#endif + + +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 @@ } +#if TARGET_API_MAC_CARBON static pascal OSErr mac_do_receive_drag (WindowPtr window, void *handlerRefCon, DragReference theDrag) @@ -7991,6 +8097,7 @@ } } } +#endif /* Print Document Apple Event */ @@ -8140,6 +8247,45 @@ 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 @@ 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 @@ 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; - - while (WaitNextEvent (event_mask, &er, 0L, NULL)) -#else /* USE_CARBON_EVENTS */ +#if USE_CARBON_EVENTS + toolbox_dispatcher = GetEventDispatcherTarget (); + 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 @@ SendEventToEventTarget (eventRef, toolbox_dispatcher); break; + default: /* Send the event to the appropriate receiver. */ SendEventToEventTarget (eventRef, toolbox_dispatcher); @@ -8497,6 +8640,10 @@ 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 @@ 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 @@ kTextEncodingMacRoman, mac_keyboard_text_encoding); } - } + } } #if USE_CARBON_EVENTS @@ -8864,59 +9011,12 @@ } #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 @@ 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 @@ 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 @@ Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, build_string ("white")), Qnil)); - - ShowWindow (f->output_data.mac->mWP); -} +} +#endif /*********************************************************************** @@ -8989,12 +9108,7 @@ 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 @@ 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 @@ char *resource_name; { struct mac_display_info *dpyinfo; - GDHandle main_device_handle; + + BLOCK_INPUT; if (!mac_initialized) { @@ -9064,17 +9234,90 @@ 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->height = (**main_device_handle).gdRect.bottom; - dpyinfo->width = (**main_device_handle).gdRect.right; + dpyinfo->xrdb = xrm_option ? mac_make_rdb (xrm_option) : NULL; + + /* 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 @@ -9333,7 +9576,6 @@ #endif BLOCK_INPUT; - mac_initialize_display_info (); #if TARGET_API_MAC_CARBON init_required_apple_events (); @@ -9371,7 +9613,9 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/macterm.h --- a/src/macterm.h Mon Dec 27 17:23:53 2004 +0000 +++ b/src/macterm.h Mon Dec 27 17:27:30 2004 +0000 @@ -218,6 +218,9 @@ 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 @@ /* 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; @@ -407,6 +413,8 @@ #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) @@ -596,6 +604,7 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/xdisp.c --- a/src/xdisp.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/xdisp.c Mon Dec 27 17:27:30 2004 +0000 @@ -21908,20 +21908,6 @@ } } -#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; } @@ -21980,16 +21966,6 @@ 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 -r c331d9c412f2 -r 9bde7721ad0f src/xfaces.c --- a/src/xfaces.c Mon Dec 27 17:23:53 2004 +0000 +++ b/src/xfaces.c Mon Dec 27 17:27:30 2004 +0000 @@ -1072,6 +1072,9 @@ #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. */