1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
29 #include "blockinput.h"
38 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
39 obtain events from the event queue. If set to 0, WaitNextEvent is
41 #define USE_CARBON_EVENTS 1
42 #else /* not MAC_OSX */
43 #include <Quickdraw.h>
44 #include <ToolUtils.h>
48 #include <Resources.h>
50 #include <TextUtils.h>
54 #if defined (__MRC__) || (__MSL__ >= 0x6000)
55 #include <ControlDefinitions.h>
61 #endif /* not MAC_OSX */
75 #include "dispextern.h"
77 #include "termhooks.h"
84 #include "intervals.h"
85 #include "composite.h"
88 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
89 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
90 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
91 #define macShiftKey (shiftKey)
92 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
93 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
95 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
99 /* Non-nil means Emacs uses toolkit scroll bars. */
101 Lisp_Object Vx_toolkit_scroll_bars
;
103 /* Non-zero means that a HELP_EVENT has been generated since Emacs
106 static int any_help_event_p
;
108 /* Non-zero means autoselect window with the mouse cursor. */
110 int x_autoselect_window_p
;
112 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
114 int x_use_underline_position_properties
;
116 /* Non-zero means draw block and hollow cursor as wide as the glyph
117 under it. For example, if a block cursor is over a tab, it will be
118 drawn as wide as that tab on the display. */
121 /* This is a chain of structures for all the X displays currently in
124 struct x_display_info
*x_display_list
;
126 /* This is a list of cons cells, each of the form (NAME
127 . FONT-LIST-CACHE), one for each element of x_display_list and in
128 the same order. NAME is the name of the frame. FONT-LIST-CACHE
129 records previous values returned by x-list-fonts. */
131 Lisp_Object x_display_name_list
;
133 /* This is display since Mac does not support multiple ones. */
134 struct mac_display_info one_mac_display_info
;
136 /* Frame being updated by update_frame. This is declared in term.c.
137 This is set by update_begin and looked at by all the XT functions.
138 It is zero while not inside an update. In that case, the XT
139 functions assume that `selected_frame' is the frame to apply to. */
141 extern struct frame
*updating_frame
;
143 extern int waiting_for_input
;
145 /* This is a frame waiting to be auto-raised, within XTread_socket. */
147 struct frame
*pending_autoraise_frame
;
149 /* Non-zero means user is interacting with a toolkit scroll bar. */
151 static int toolkit_scroll_bar_interaction
;
155 Formerly, we used PointerMotionHintMask (in standard_event_mask)
156 so that we would have to call XQueryPointer after each MotionNotify
157 event to ask for another such event. However, this made mouse tracking
158 slow, and there was a bug that made it eventually stop.
160 Simply asking for MotionNotify all the time seems to work better.
162 In order to avoid asking for motion events and then throwing most
163 of them away or busy-polling the server for mouse positions, we ask
164 the server for pointer motion hints. This means that we get only
165 one event per group of mouse movements. "Groups" are delimited by
166 other kinds of events (focus changes and button clicks, for
167 example), or by XQueryPointer calls; when one of these happens, we
168 get another MotionNotify event the next time the mouse moves. This
169 is at least as efficient as getting motion events when mouse
170 tracking is on, and I suspect only negligibly worse when tracking
173 /* Where the mouse was last time we reported a mouse event. */
175 static Rect last_mouse_glyph
;
176 static Lisp_Object last_mouse_press_frame
;
178 /* The scroll bar in which the last X motion event occurred.
180 If the last X motion event occurred in a scroll bar, we set this so
181 XTmouse_position can know whether to report a scroll bar motion or
184 If the last X motion event didn't occur in a scroll bar, we set
185 this to Qnil, to tell XTmouse_position to return an ordinary motion
188 static Lisp_Object last_mouse_scroll_bar
;
190 /* This is a hack. We would really prefer that XTmouse_position would
191 return the time associated with the position it returns, but there
192 doesn't seem to be any way to wrest the time-stamp from the server
193 along with the position query. So, we just keep track of the time
194 of the last movement we received, and return that in hopes that
195 it's somewhat accurate. */
197 static Time last_mouse_movement_time
;
199 struct scroll_bar
*tracked_scroll_bar
= NULL
;
201 /* Incremented by XTread_socket whenever it really tries to read
205 static int volatile input_signal_count
;
207 static int input_signal_count
;
210 /* Used locally within XTread_socket. */
212 static int x_noop_count
;
214 /* Initial values of argv and argc. */
216 extern char **initial_argv
;
217 extern int initial_argc
;
219 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
221 /* Tells if a window manager is present or not. */
223 extern Lisp_Object Vx_no_window_manager
;
227 /* A mask of extra modifier bits to put into every keyboard char. */
229 extern int extra_keyboard_modifiers
;
231 /* The keysyms to use for the various modifiers. */
233 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qmodifier_value
;
235 static Lisp_Object Qvendor_specific_keysyms
;
238 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
241 extern int inhibit_window_system
;
244 QDGlobals qd
; /* QuickDraw global information structure. */
248 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
249 struct mac_display_info
*mac_display_info_for_display (Display
*);
250 static void x_update_window_end
P_ ((struct window
*, int, int));
251 static void mac_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
252 static int x_io_error_quitter
P_ ((Display
*));
253 int x_catch_errors
P_ ((Display
*));
254 void x_uncatch_errors
P_ ((Display
*, int));
255 void x_lower_frame
P_ ((struct frame
*));
256 void x_scroll_bar_clear
P_ ((struct frame
*));
257 int x_had_errors_p
P_ ((Display
*));
258 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
259 void x_raise_frame
P_ ((struct frame
*));
260 void x_set_window_size
P_ ((struct frame
*, int, int, int));
261 void x_wm_set_window_state
P_ ((struct frame
*, int));
262 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
263 void mac_initialize
P_ ((void));
264 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
265 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
266 static void x_update_end
P_ ((struct frame
*));
267 static void XTframe_up_to_date
P_ ((struct frame
*));
268 static void XTreassert_line_highlight
P_ ((int, int));
269 static void x_change_line_highlight
P_ ((int, int, int, int));
270 static void XTset_terminal_modes
P_ ((void));
271 static void XTreset_terminal_modes
P_ ((void));
272 static void x_clear_frame
P_ ((void));
273 static void frame_highlight
P_ ((struct frame
*));
274 static void frame_unhighlight
P_ ((struct frame
*));
275 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
276 static void XTframe_rehighlight
P_ ((struct frame
*));
277 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
278 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
279 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
280 enum text_cursor_kinds
));
282 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
283 static void x_flush
P_ ((struct frame
*f
));
284 static void x_update_begin
P_ ((struct frame
*));
285 static void x_update_window_begin
P_ ((struct window
*));
286 static void x_after_update_window_line
P_ ((struct glyph_row
*));
288 void activate_scroll_bars (FRAME_PTR
);
289 void deactivate_scroll_bars (FRAME_PTR
);
291 static int is_emacs_window (WindowPtr
);
293 int x_bitmap_icon (struct frame
*, Lisp_Object
);
294 void x_make_frame_visible (struct frame
*);
296 extern void window_scroll (Lisp_Object
, int, int, int);
298 /* Defined in macmenu.h. */
299 extern void menubar_selection_callback (FRAME_PTR
, int);
300 extern void set_frame_menubar (FRAME_PTR
, int, int);
302 /* X display function emulation */
305 XFreePixmap (display
, pixmap
)
306 Display
*display
; /* not used */
309 DisposeGWorld (pixmap
);
313 /* Set foreground color for subsequent QuickDraw commands. Assume
314 graphic port has already been set. */
317 mac_set_forecolor (unsigned long color
)
321 fg_color
.red
= RED16_FROM_ULONG (color
);
322 fg_color
.green
= GREEN16_FROM_ULONG (color
);
323 fg_color
.blue
= BLUE16_FROM_ULONG (color
);
325 RGBForeColor (&fg_color
);
329 /* Set background color for subsequent QuickDraw commands. Assume
330 graphic port has already been set. */
333 mac_set_backcolor (unsigned long color
)
337 bg_color
.red
= RED16_FROM_ULONG (color
);
338 bg_color
.green
= GREEN16_FROM_ULONG (color
);
339 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
341 RGBBackColor (&bg_color
);
344 /* Set foreground and background color for subsequent QuickDraw
345 commands. Assume that the graphic port has already been set. */
348 mac_set_colors (GC gc
)
350 mac_set_forecolor (gc
->foreground
);
351 mac_set_backcolor (gc
->background
);
354 /* Mac version of XDrawLine. */
357 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
363 SetPortWindowPort (w
);
372 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
381 GetGWorld (&old_port
, &old_gdh
);
386 LockPixels (GetGWorldPixMap (p
));
389 UnlockPixels (GetGWorldPixMap (p
));
391 SetGWorld (old_port
, old_gdh
);
394 /* Mac version of XClearArea. */
397 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
401 unsigned int width
, height
;
404 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
408 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
409 xgc
.background
= mwp
->x_compatible
.background_pixel
;
411 SetPortWindowPort (w
);
413 mac_set_colors (&xgc
);
414 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
419 /* Mac version of XClearWindow. */
422 XClearWindow (display
, w
)
426 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
429 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
430 xgc
.background
= mwp
->x_compatible
.background_pixel
;
432 SetPortWindowPort (w
);
434 mac_set_colors (&xgc
);
436 #if TARGET_API_MAC_CARBON
440 GetWindowPortBounds (w
, &r
);
443 #else /* not TARGET_API_MAC_CARBON */
444 EraseRect (&(w
->portRect
));
445 #endif /* not TARGET_API_MAC_CARBON */
449 /* Mac replacement for XCopyArea. */
452 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
456 int x
, y
, width
, height
;
457 unsigned short *bits
;
463 bitmap
.rowBytes
= sizeof(unsigned short);
464 bitmap
.baseAddr
= (char *)bits
;
465 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
467 SetPortWindowPort (w
);
470 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
472 #if TARGET_API_MAC_CARBON
473 LockPortBits (GetWindowPort (w
));
474 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
475 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
476 UnlockPortBits (GetWindowPort (w
));
477 #else /* not TARGET_API_MAC_CARBON */
478 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
479 overlay_p
? srcOr
: srcCopy
, 0);
480 #endif /* not TARGET_API_MAC_CARBON */
484 /* Mac replacement for XSetClipRectangles. */
487 mac_set_clip_rectangle (display
, w
, r
)
492 SetPortWindowPort (w
);
498 /* Mac replacement for XSetClipMask. */
501 mac_reset_clipping (display
, w
)
507 SetPortWindowPort (w
);
509 SetRect (&r
, -32767, -32767, 32767, 32767);
514 /* XBM bits seem to be backward within bytes compared with how
521 unsigned char reflected
= 0x00;
522 for (i
= 0; i
< 8; i
++)
524 if (orig
& (0x01 << i
))
525 reflected
|= 0x80 >> i
;
531 /* Mac replacement for XCreateBitmapFromBitmapData. */
534 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
542 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
543 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
544 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
545 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
546 for (i
= 0; i
< h
; i
++)
548 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
549 for (j
= 0; j
< w1
; j
++)
550 *p
++ = reflect_byte (*bits
++);
553 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
558 mac_free_bitmap (bitmap
)
561 xfree (bitmap
->baseAddr
);
566 XCreatePixmap (display
, w
, width
, height
, depth
)
567 Display
*display
; /* not used */
569 unsigned int width
, height
;
576 SetPortWindowPort (w
);
578 SetRect (&r
, 0, 0, width
, height
);
579 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
587 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
588 Display
*display
; /* not used */
591 unsigned int width
, height
;
592 unsigned long fg
, bg
;
593 unsigned int depth
; /* not used */
600 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
604 GetGWorld (&old_port
, &old_gdh
);
605 SetGWorld (pixmap
, NULL
);
606 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
607 mac_set_forecolor (fg
);
608 mac_set_backcolor (bg
);
609 LockPixels (GetGWorldPixMap (pixmap
));
610 #if TARGET_API_MAC_CARBON
611 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
612 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
613 #else /* not TARGET_API_MAC_CARBON */
614 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
615 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
616 #endif /* not TARGET_API_MAC_CARBON */
617 UnlockPixels (GetGWorldPixMap (pixmap
));
618 SetGWorld (old_port
, old_gdh
);
619 mac_free_bitmap (&bitmap
);
625 /* Mac replacement for XFillRectangle. */
628 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
633 unsigned int width
, height
;
637 SetPortWindowPort (w
);
640 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
642 PaintRect (&r
); /* using foreground color of gc */
646 #if 0 /* TODO: figure out if we need to do this on Mac. */
648 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
653 unsigned int width
, height
;
659 GetGWorld (&old_port
, &old_gdh
);
662 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
664 LockPixels (GetGWorldPixMap (p
));
665 PaintRect (&r
); /* using foreground color of gc */
666 UnlockPixels (GetGWorldPixMap (p
));
668 SetGWorld (old_port
, old_gdh
);
673 /* Mac replacement for XDrawRectangle: dest is a window. */
676 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
681 unsigned int width
, height
;
685 SetPortWindowPort (w
);
688 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
690 FrameRect (&r
); /* using foreground color of gc */
694 #if 0 /* TODO: figure out if we need to do this on Mac. */
695 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
698 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
703 unsigned int width
, height
;
709 GetGWorld (&old_port
, &old_gdh
);
712 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
714 LockPixels (GetGWorldPixMap (p
));
715 FrameRect (&r
); /* using foreground color of gc */
716 UnlockPixels (GetGWorldPixMap (p
));
718 SetGWorld (old_port
, old_gdh
);
724 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
731 int nchars
, mode
, bytes_per_char
;
733 SetPortWindowPort (w
);
737 TextFont (gc
->font
->mac_fontnum
);
738 TextSize (gc
->font
->mac_fontsize
);
739 TextFace (gc
->font
->mac_fontface
);
743 DrawText (buf
, 0, nchars
* bytes_per_char
);
747 /* Mac replacement for XDrawString. */
750 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
758 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
762 /* Mac replacement for XDrawString16. */
765 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
773 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
778 /* Mac replacement for XDrawImageString. */
781 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
789 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
793 /* Mac replacement for XDrawString16. */
796 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
804 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
809 /* Mac replacement for XCopyArea: dest must be window. */
812 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
819 unsigned int width
, height
;
824 SetPortWindowPort (dest
);
826 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
827 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
829 ForeColor (blackColor
);
830 BackColor (whiteColor
);
832 LockPixels (GetGWorldPixMap (src
));
833 #if TARGET_API_MAC_CARBON
834 LockPortBits (GetWindowPort (dest
));
835 CopyBits (GetPortBitMapForCopyBits (src
),
836 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
837 &src_r
, &dest_r
, srcCopy
, 0);
838 UnlockPortBits (GetWindowPort (dest
));
839 #else /* not TARGET_API_MAC_CARBON */
840 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
841 &src_r
, &dest_r
, srcCopy
, 0);
842 #endif /* not TARGET_API_MAC_CARBON */
843 UnlockPixels (GetGWorldPixMap (src
));
848 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
849 width
, height
, dest_x
, dest_y
)
855 unsigned int width
, height
;
860 SetPortWindowPort (dest
);
862 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
863 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
865 ForeColor (blackColor
);
866 BackColor (whiteColor
);
868 LockPixels (GetGWorldPixMap (src
));
869 LockPixels (GetGWorldPixMap (mask
));
870 #if TARGET_API_MAC_CARBON
871 LockPortBits (GetWindowPort (dest
));
872 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
873 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
874 &src_r
, &src_r
, &dest_r
);
875 UnlockPortBits (GetWindowPort (dest
));
876 #else /* not TARGET_API_MAC_CARBON */
877 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
878 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
879 #endif /* not TARGET_API_MAC_CARBON */
880 UnlockPixels (GetGWorldPixMap (mask
));
881 UnlockPixels (GetGWorldPixMap (src
));
886 /* Convert a pair of local coordinates to global (screen) coordinates.
887 Assume graphic port has been properly set. */
889 local_to_global_coord (short *h
, short *v
)
903 /* Mac replacement for XCopyArea: used only for scrolling. */
906 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
911 unsigned int width
, height
;
914 #if TARGET_API_MAC_CARBON
916 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
918 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
919 ScrollWindowRect (w
, &src_r
, dest_x
- src_x
, dest_y
- src_y
,
920 kScrollWindowNoOptions
, dummy
);
922 #else /* not TARGET_API_MAC_CARBON */
930 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
931 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
934 /* Need to use global coordinates and screenBits since src and dest
935 areas overlap in general. */
936 local_to_global_coord (&src_r
.left
, &src_r
.top
);
937 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
938 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
939 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
941 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
943 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
944 color mapping in CopyBits. Otherwise, it will be slow. */
945 ForeColor (blackColor
);
946 BackColor (whiteColor
);
947 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
951 #endif /* not TARGET_API_MAC_CARBON */
955 #if 0 /* TODO: figure out if we need to do this on Mac. */
956 /* Mac replacement for XCopyArea: dest must be Pixmap. */
959 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
965 unsigned int width
, height
;
972 GetGWorld (&old_port
, &old_gdh
);
973 SetGWorld (dest
, NULL
);
974 ForeColor (blackColor
);
975 BackColor (whiteColor
);
977 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
978 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
980 LockPixels (GetGWorldPixMap (src
));
981 LockPixels (GetGWorldPixMap (dest
));
982 #if TARGET_API_MAC_CARBON
983 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
984 &src_r
, &dest_r
, srcCopy
, 0);
985 #else /* not TARGET_API_MAC_CARBON */
986 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
987 &src_r
, &dest_r
, srcCopy
, 0);
988 #endif /* not TARGET_API_MAC_CARBON */
989 UnlockPixels (GetGWorldPixMap (dest
));
990 UnlockPixels (GetGWorldPixMap (src
));
992 SetGWorld (old_port
, old_gdh
);
997 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
998 width
, height
, dest_x
, dest_y
)
1000 Pixmap src
, mask
, dest
;
1003 unsigned int width
, height
;
1010 GetGWorld (&old_port
, &old_gdh
);
1011 SetGWorld (dest
, NULL
);
1012 ForeColor (blackColor
);
1013 BackColor (whiteColor
);
1015 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1016 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1018 LockPixels (GetGWorldPixMap (src
));
1019 LockPixels (GetGWorldPixMap (mask
));
1020 LockPixels (GetGWorldPixMap (dest
));
1021 #if TARGET_API_MAC_CARBON
1022 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1023 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
1024 #else /* not TARGET_API_MAC_CARBON */
1025 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1026 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
1027 #endif /* not TARGET_API_MAC_CARBON */
1028 UnlockPixels (GetGWorldPixMap (dest
));
1029 UnlockPixels (GetGWorldPixMap (mask
));
1030 UnlockPixels (GetGWorldPixMap (src
));
1032 SetGWorld (old_port
, old_gdh
);
1037 /* Mac replacement for XChangeGC. */
1040 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1043 if (mask
& GCForeground
)
1044 gc
->foreground
= xgcv
->foreground
;
1045 if (mask
& GCBackground
)
1046 gc
->background
= xgcv
->background
;
1048 gc
->font
= xgcv
->font
;
1052 /* Mac replacement for XCreateGC. */
1055 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1058 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1059 bzero (gc
, sizeof (XGCValues
));
1061 XChangeGC (ignore
, gc
, mask
, xgcv
);
1067 /* Used in xfaces.c. */
1070 XFreeGC (display
, gc
)
1078 /* Mac replacement for XGetGCValues. */
1081 XGetGCValues (void* ignore
, XGCValues
*gc
,
1082 unsigned long mask
, XGCValues
*xgcv
)
1084 XChangeGC (ignore
, xgcv
, mask
, gc
);
1088 /* Mac replacement for XSetForeground. */
1091 XSetForeground (display
, gc
, color
)
1094 unsigned long color
;
1096 gc
->foreground
= color
;
1100 /* Mac replacement for XSetFont. */
1103 XSetFont (display
, gc
, font
)
1113 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1114 int *direction
,int *font_ascent
,
1115 int *font_descent
, XCharStruct
*cs
)
1117 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1121 /* x_sync is a no-op on Mac. */
1129 /* Flush display of frame F, or of all frames if F is null. */
1135 #if TARGET_API_MAC_CARBON
1138 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1140 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1146 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1147 Calls to XFlush should be unnecessary because the X output buffer
1148 is flushed automatically as needed by calls to XPending,
1149 XNextEvent, or XWindowEvent according to the XFlush man page.
1150 XTread_socket calls XPending. Removing XFlush improves
1153 #define XFlush(DISPLAY) (void) 0
1156 /* Return the struct mac_display_info corresponding to DPY. There's
1159 struct mac_display_info
*
1160 mac_display_info_for_display (dpy
)
1163 return &one_mac_display_info
;
1168 /***********************************************************************
1169 Starting and ending an update
1170 ***********************************************************************/
1172 /* Start an update of frame F. This function is installed as a hook
1173 for update_begin, i.e. it is called when update_begin is called.
1174 This function is called prior to calls to x_update_window_begin for
1175 each window being updated. */
1181 /* Nothing to do. */
1185 /* Start update of window W. Set the global variable updated_window
1186 to the window being updated and set output_cursor to the cursor
1190 x_update_window_begin (w
)
1193 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1194 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1197 set_output_cursor (&w
->cursor
);
1201 if (f
== display_info
->mouse_face_mouse_frame
)
1203 /* Don't do highlighting for mouse motion during the update. */
1204 display_info
->mouse_face_defer
= 1;
1206 /* If F needs to be redrawn, simply forget about any prior mouse
1208 if (FRAME_GARBAGED_P (f
))
1209 display_info
->mouse_face_window
= Qnil
;
1211 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1212 their mouse_face_p flag set, which means that they are always
1213 unequal to rows in a desired matrix which never have that
1214 flag set. So, rows containing mouse-face glyphs are never
1215 scrolled, and we don't have to switch the mouse highlight off
1216 here to prevent it from being scrolled. */
1218 /* Can we tell that this update does not affect the window
1219 where the mouse highlight is? If so, no need to turn off.
1220 Likewise, don't do anything if the frame is garbaged;
1221 in that case, the frame's current matrix that we would use
1222 is all wrong, and we will redisplay that line anyway. */
1223 if (!NILP (display_info
->mouse_face_window
)
1224 && w
== XWINDOW (display_info
->mouse_face_window
))
1228 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1229 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1232 if (i
< w
->desired_matrix
->nrows
)
1233 clear_mouse_face (display_info
);
1242 /* Draw a vertical window border from (x,y0) to (x,y1) */
1245 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1249 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1251 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1252 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1256 /* End update of window W (which is equal to updated_window).
1258 Draw vertical borders between horizontally adjacent windows, and
1259 display W's cursor if CURSOR_ON_P is non-zero.
1261 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1262 glyphs in mouse-face were overwritten. In that case we have to
1263 make sure that the mouse-highlight is properly redrawn.
1265 W may be a menu bar pseudo-window in case we don't have X toolkit
1266 support. Such windows don't have a cursor, so don't display it
1270 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1272 int cursor_on_p
, mouse_face_overwritten_p
;
1274 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1276 if (!w
->pseudo_window_p
)
1281 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1283 output_cursor
.x
, output_cursor
.y
);
1285 if (draw_window_fringes (w
, 1))
1286 x_draw_vertical_border (w
);
1291 /* If a row with mouse-face was overwritten, arrange for
1292 XTframe_up_to_date to redisplay the mouse highlight. */
1293 if (mouse_face_overwritten_p
)
1295 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1296 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1297 dpyinfo
->mouse_face_window
= Qnil
;
1301 /* Unhide the caret. This won't actually show the cursor, unless it
1302 was visible before the corresponding call to HideCaret in
1303 x_update_window_begin. */
1304 if (w32_use_visible_system_caret
)
1305 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1308 updated_window
= NULL
;
1312 /* End update of frame F. This function is installed as a hook in
1319 /* Mouse highlight may be displayed again. */
1320 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1323 /* Reset the background color of Mac OS Window to that of the frame after
1324 update so that it is used by Mac Toolbox to clear the update region before
1325 an update event is generated. */
1326 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1328 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1330 XFlush (FRAME_MAC_DISPLAY (f
));
1335 /* This function is called from various places in xdisp.c whenever a
1336 complete update has been performed. The global variable
1337 updated_window is not available here. */
1340 XTframe_up_to_date (f
)
1343 if (FRAME_MAC_P (f
))
1345 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1347 if (dpyinfo
->mouse_face_deferred_gc
1348 || f
== dpyinfo
->mouse_face_mouse_frame
)
1351 if (dpyinfo
->mouse_face_mouse_frame
)
1352 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1353 dpyinfo
->mouse_face_mouse_x
,
1354 dpyinfo
->mouse_face_mouse_y
);
1355 dpyinfo
->mouse_face_deferred_gc
= 0;
1362 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1363 arrow bitmaps, or clear the fringes if no bitmaps are required
1364 before DESIRED_ROW is made current. The window being updated is
1365 found in updated_window. This function is called from
1366 update_window_line only if it is known that there are differences
1367 between bitmaps to be drawn between current row and DESIRED_ROW. */
1370 x_after_update_window_line (desired_row
)
1371 struct glyph_row
*desired_row
;
1373 struct window
*w
= updated_window
;
1379 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1380 desired_row
->redraw_fringe_bitmaps_p
= 1;
1382 /* When a window has disappeared, make sure that no rest of
1383 full-width rows stays visible in the internal border. Could
1384 check here if updated_window is the leftmost/rightmost window,
1385 but I guess it's not worth doing since vertically split windows
1386 are almost never used, internal border is rarely set, and the
1387 overhead is very small. */
1388 if (windows_or_buffers_changed
1389 && desired_row
->full_width_p
1390 && (f
= XFRAME (w
->frame
),
1391 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1393 && (height
= desired_row
->visible_height
,
1396 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1397 /* Internal border is drawn below the tool bar. */
1398 if (WINDOWP (f
->tool_bar_window
)
1399 && w
== XWINDOW (f
->tool_bar_window
))
1404 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1405 0, y
, width
, height
, 0);
1406 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1407 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1415 /* Draw the bitmap WHICH in one of the left or right fringes of
1416 window W. ROW is the glyph row for which to display the bitmap; it
1417 determines the vertical position at which the bitmap has to be
1421 x_draw_fringe_bitmap (w
, row
, p
)
1423 struct glyph_row
*row
;
1424 struct draw_fringe_bitmap_params
*p
;
1426 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1427 Display
*display
= FRAME_MAC_DISPLAY (f
);
1428 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1430 GC gc
= f
->output_data
.mac
->normal_gc
;
1431 struct face
*face
= p
->face
;
1434 /* Must clip because of partially visible lines. */
1435 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1438 /* Adjust position of "bottom aligned" bitmap on partially
1439 visible last row. */
1441 int oldVH
= row
->visible_height
;
1442 row
->visible_height
= p
->h
;
1443 row
->y
-= rowY
- p
->y
;
1444 x_clip_to_row (w
, row
, -1, gc
);
1446 row
->visible_height
= oldVH
;
1449 x_clip_to_row (w
, row
, -1, gc
);
1451 if (p
->bx
>= 0 && !p
->overlay_p
)
1454 gcv
.foreground
= face
->background
;
1456 #if 0 /* MAC_TODO: stipple */
1457 /* In case the same realized face is used for fringes and
1458 for something displayed in the text (e.g. face `region' on
1459 mono-displays, the fill style may have been changed to
1460 FillSolid in x_draw_glyph_string_background. */
1462 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1464 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1467 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1469 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1471 #if 0 /* MAC_TODO: stipple */
1473 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1479 unsigned short *bits
= p
->bits
+ p
->dh
;
1481 gcv
.foreground
= (p
->cursor_p
1482 ? (p
->overlay_p
? face
->background
1483 : f
->output_data
.mac
->cursor_pixel
)
1484 : face
->foreground
);
1485 gcv
.background
= face
->background
;
1487 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
,
1488 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1491 mac_reset_clipping (display
, window
);
1495 /* This is called when starting Emacs and when restarting after
1496 suspend. When starting Emacs, no window is mapped. And nothing
1497 must be done to Emacs's own window if it is suspended (though that
1501 XTset_terminal_modes ()
1505 /* This is called when exiting or suspending Emacs. Exiting will make
1506 the windows go away, and suspending requires no action. */
1509 XTreset_terminal_modes ()
1514 /***********************************************************************
1516 ***********************************************************************/
1518 /* Function prototypes of this page. */
1520 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1521 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1524 /* Return a pointer to per-char metric information in FONT of a
1525 character pointed by B which is a pointer to an XChar2b. */
1527 #define PER_CHAR_METRIC(font, b) \
1529 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1530 + (((font)->min_byte1 || (font)->max_byte1) \
1531 ? (((b)->byte1 - (font)->min_byte1) \
1532 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1534 : &((font)->max_bounds))
1537 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1538 is not contained in the font. */
1540 static INLINE XCharStruct
*
1541 x_per_char_metric (font
, char2b
)
1545 /* The result metric information. */
1546 XCharStruct
*pcm
= NULL
;
1548 xassert (font
&& char2b
);
1550 if (font
->per_char
!= NULL
)
1552 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1554 /* min_char_or_byte2 specifies the linear character index
1555 corresponding to the first element of the per_char array,
1556 max_char_or_byte2 is the index of the last character. A
1557 character with non-zero CHAR2B->byte1 is not in the font.
1558 A character with byte2 less than min_char_or_byte2 or
1559 greater max_char_or_byte2 is not in the font. */
1560 if (char2b
->byte1
== 0
1561 && char2b
->byte2
>= font
->min_char_or_byte2
1562 && char2b
->byte2
<= font
->max_char_or_byte2
)
1563 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1567 /* If either min_byte1 or max_byte1 are nonzero, both
1568 min_char_or_byte2 and max_char_or_byte2 are less than
1569 256, and the 2-byte character index values corresponding
1570 to the per_char array element N (counting from 0) are:
1572 byte1 = N/D + min_byte1
1573 byte2 = N\D + min_char_or_byte2
1577 D = max_char_or_byte2 - min_char_or_byte2 + 1
1578 / = integer division
1579 \ = integer modulus */
1580 if (char2b
->byte1
>= font
->min_byte1
1581 && char2b
->byte1
<= font
->max_byte1
1582 && char2b
->byte2
>= font
->min_char_or_byte2
1583 && char2b
->byte2
<= font
->max_char_or_byte2
)
1585 pcm
= (font
->per_char
1586 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1587 * (char2b
->byte1
- font
->min_byte1
))
1588 + (char2b
->byte2
- font
->min_char_or_byte2
));
1594 /* If the per_char pointer is null, all glyphs between the first
1595 and last character indexes inclusive have the same
1596 information, as given by both min_bounds and max_bounds. */
1597 if (char2b
->byte2
>= font
->min_char_or_byte2
1598 && char2b
->byte2
<= font
->max_char_or_byte2
)
1599 pcm
= &font
->max_bounds
;
1602 return ((pcm
== NULL
1603 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1610 static XCharStruct
*
1611 mac_per_char_metric (font
, char2b
, font_type
)
1616 return x_per_char_metric (font
, char2b
);
1620 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1621 the two-byte form of C. Encoding is returned in *CHAR2B. */
1624 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1627 struct font_info
*font_info
;
1630 int charset
= CHAR_CHARSET (c
);
1631 XFontStruct
*font
= font_info
->font
;
1633 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1634 This may be either a program in a special encoder language or a
1636 if (font_info
->font_encoder
)
1638 /* It's a program. */
1639 struct ccl_program
*ccl
= font_info
->font_encoder
;
1641 if (CHARSET_DIMENSION (charset
) == 1)
1643 ccl
->reg
[0] = charset
;
1644 ccl
->reg
[1] = char2b
->byte2
;
1648 ccl
->reg
[0] = charset
;
1649 ccl
->reg
[1] = char2b
->byte1
;
1650 ccl
->reg
[2] = char2b
->byte2
;
1653 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1655 /* We assume that MSBs are appropriately set/reset by CCL
1657 if (font
->max_byte1
== 0) /* 1-byte font */
1658 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1660 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1662 else if (font_info
->encoding
[charset
])
1664 /* Fixed encoding scheme. See fontset.h for the meaning of the
1665 encoding numbers. */
1666 int enc
= font_info
->encoding
[charset
];
1668 if ((enc
== 1 || enc
== 2)
1669 && CHARSET_DIMENSION (charset
) == 2)
1670 char2b
->byte1
|= 0x80;
1672 if (enc
== 1 || enc
== 3)
1673 char2b
->byte2
|= 0x80;
1679 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1680 char2b
->byte1
= sjis1
;
1681 char2b
->byte2
= sjis2
;
1686 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1688 return FONT_TYPE_UNKNOWN
;
1693 /***********************************************************************
1695 ***********************************************************************/
1698 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1699 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1700 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1702 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1703 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1704 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1705 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1706 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1707 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1708 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1709 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1710 unsigned long *, double, int));*/
1711 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1712 double, int, unsigned long));
1713 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1714 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1715 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1716 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1717 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1718 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1720 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1721 int, int, int, int, int, int,
1723 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1724 int, int, int, Rect
*));
1727 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1731 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1736 struct glyph_string
*s
;
1738 if (s
->font
== FRAME_FONT (s
->f
)
1739 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1740 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1742 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1745 /* Cursor on non-default face: must merge. */
1749 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1750 xgcv
.foreground
= s
->face
->background
;
1752 /* If the glyph would be invisible, try a different foreground. */
1753 if (xgcv
.foreground
== xgcv
.background
)
1754 xgcv
.foreground
= s
->face
->foreground
;
1755 if (xgcv
.foreground
== xgcv
.background
)
1756 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1757 if (xgcv
.foreground
== xgcv
.background
)
1758 xgcv
.foreground
= s
->face
->foreground
;
1760 /* Make sure the cursor is distinct from text in this face. */
1761 if (xgcv
.background
== s
->face
->background
1762 && xgcv
.foreground
== s
->face
->foreground
)
1764 xgcv
.background
= s
->face
->foreground
;
1765 xgcv
.foreground
= s
->face
->background
;
1768 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1769 xgcv
.font
= s
->font
;
1770 mask
= GCForeground
| GCBackground
| GCFont
;
1772 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1773 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1776 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1777 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1779 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1784 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1787 x_set_mouse_face_gc (s
)
1788 struct glyph_string
*s
;
1793 /* What face has to be used last for the mouse face? */
1794 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1795 face
= FACE_FROM_ID (s
->f
, face_id
);
1797 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1799 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1800 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1802 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1803 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1804 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1806 /* If font in this face is same as S->font, use it. */
1807 if (s
->font
== s
->face
->font
)
1808 s
->gc
= s
->face
->gc
;
1811 /* Otherwise construct scratch_cursor_gc with values from FACE
1816 xgcv
.background
= s
->face
->background
;
1817 xgcv
.foreground
= s
->face
->foreground
;
1818 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1819 xgcv
.font
= s
->font
;
1820 mask
= GCForeground
| GCBackground
| GCFont
;
1822 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1823 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1826 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1827 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1829 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1832 xassert (s
->gc
!= 0);
1836 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1837 Faces to use in the mode line have already been computed when the
1838 matrix was built, so there isn't much to do, here. */
1841 x_set_mode_line_face_gc (s
)
1842 struct glyph_string
*s
;
1844 s
->gc
= s
->face
->gc
;
1848 /* Set S->gc of glyph string S for drawing that glyph string. Set
1849 S->stippled_p to a non-zero value if the face of S has a stipple
1853 x_set_glyph_string_gc (s
)
1854 struct glyph_string
*s
;
1856 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1858 if (s
->hl
== DRAW_NORMAL_TEXT
)
1860 s
->gc
= s
->face
->gc
;
1861 s
->stippled_p
= s
->face
->stipple
!= 0;
1863 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1865 x_set_mode_line_face_gc (s
);
1866 s
->stippled_p
= s
->face
->stipple
!= 0;
1868 else if (s
->hl
== DRAW_CURSOR
)
1870 x_set_cursor_gc (s
);
1873 else if (s
->hl
== DRAW_MOUSE_FACE
)
1875 x_set_mouse_face_gc (s
);
1876 s
->stippled_p
= s
->face
->stipple
!= 0;
1878 else if (s
->hl
== DRAW_IMAGE_RAISED
1879 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1881 s
->gc
= s
->face
->gc
;
1882 s
->stippled_p
= s
->face
->stipple
!= 0;
1886 s
->gc
= s
->face
->gc
;
1887 s
->stippled_p
= s
->face
->stipple
!= 0;
1890 /* GC must have been set. */
1891 xassert (s
->gc
!= 0);
1895 /* Set clipping for output of glyph string S. S may be part of a mode
1896 line or menu if we don't have X toolkit support. */
1899 x_set_glyph_string_clipping (s
)
1900 struct glyph_string
*s
;
1903 get_glyph_string_clip_rect (s
, &r
);
1904 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1909 Compute left and right overhang of glyph string S. If S is a glyph
1910 string for a composition, assume overhangs don't exist. */
1913 mac_compute_glyph_string_overhangs (s
)
1914 struct glyph_string
*s
;
1917 /* MAC_TODO: XTextExtents16 does nothing yet... */
1920 && s
->first_glyph
->type
== CHAR_GLYPH
)
1923 int direction
, font_ascent
, font_descent
;
1924 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1925 &font_ascent
, &font_descent
, &cs
);
1926 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1927 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1933 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1936 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1937 struct glyph_string
*s
;
1942 xgcv
.foreground
= s
->gc
->background
;
1943 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1947 /* We prefer not to use XDrawImageString (srcCopy text transfer mode)
1948 on Mac OS X because:
1949 - Screen is double-buffered. (In srcCopy mode, a text is drawn
1950 into an offscreen graphics world first. So performance gain
1951 cannot be expected.)
1952 - It lowers rendering quality.
1953 - Some fonts leave garbage on cursor movement. */
1955 /* Draw the background of glyph_string S. If S->background_filled_p
1956 is non-zero don't draw it. FORCE_P non-zero means draw the
1957 background even if it wouldn't be drawn normally. This is used
1958 when a string preceding S draws into the background of S, or S
1959 contains the first component of a composition. */
1962 x_draw_glyph_string_background (s
, force_p
)
1963 struct glyph_string
*s
;
1966 /* Nothing to do if background has already been drawn or if it
1967 shouldn't be drawn in the first place. */
1968 if (!s
->background_filled_p
)
1970 int box_line_width
= max (s
->face
->box_line_width
, 0);
1972 #if 0 /* MAC_TODO: stipple */
1975 /* Fill background with a stipple pattern. */
1976 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1977 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1978 s
->y
+ box_line_width
,
1979 s
->background_width
,
1980 s
->height
- 2 * box_line_width
);
1981 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1982 s
->background_filled_p
= 1;
1986 #if 0 /* defined(MAC_OS8)*/
1987 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
1988 || s
->font_not_found_p
1989 || s
->extends_to_end_of_line_p
1993 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
1994 s
->background_width
,
1995 s
->height
- 2 * box_line_width
);
1996 s
->background_filled_p
= 1;
2002 /* Draw the foreground of glyph string S. */
2005 x_draw_glyph_string_foreground (s
)
2006 struct glyph_string
*s
;
2010 /* If first glyph of S has a left box line, start drawing the text
2011 of S to the right of that box line. */
2012 if (s
->face
->box
!= FACE_NO_BOX
2013 && s
->first_glyph
->left_box_line_p
)
2014 x
= s
->x
+ abs (s
->face
->box_line_width
);
2018 /* Draw characters of S as rectangles if S's font could not be
2020 if (s
->font_not_found_p
)
2022 for (i
= 0; i
< s
->nchars
; ++i
)
2024 struct glyph
*g
= s
->first_glyph
+ i
;
2025 mac_draw_rectangle (s
->display
, s
->window
,
2026 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2028 x
+= g
->pixel_width
;
2033 char *char1b
= (char *) s
->char2b
;
2034 int boff
= s
->font_info
->baseline_offset
;
2036 if (s
->font_info
->vertical_centering
)
2037 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2039 /* If we can use 8-bit functions, condense S->char2b. */
2041 for (i
= 0; i
< s
->nchars
; ++i
)
2042 char1b
[i
] = s
->char2b
[i
].byte2
;
2044 #if 0 /* defined(MAC_OS8) */
2045 /* Draw text with XDrawString if background has already been
2046 filled. Otherwise, use XDrawImageString. (Note that
2047 XDrawImageString is usually faster than XDrawString.) Always
2048 use XDrawImageString when drawing the cursor so that there is
2049 no chance that characters under a box cursor are invisible. */
2050 if (s
->for_overlaps_p
2051 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2054 /* Draw characters with 16-bit or 8-bit functions. */
2056 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2057 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2059 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2060 s
->ybase
- boff
, char1b
, s
->nchars
);
2062 #if 0 /* defined(MAC_OS8)*/
2066 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
2067 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2069 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
2070 s
->ybase
- boff
, char1b
, s
->nchars
);
2076 /* Draw the foreground of composite glyph string S. */
2079 x_draw_composite_glyph_string_foreground (s
)
2080 struct glyph_string
*s
;
2084 /* If first glyph of S has a left box line, start drawing the text
2085 of S to the right of that box line. */
2086 if (s
->face
->box
!= FACE_NO_BOX
2087 && s
->first_glyph
->left_box_line_p
)
2088 x
= s
->x
+ abs (s
->face
->box_line_width
);
2092 /* S is a glyph string for a composition. S->gidx is the index of
2093 the first character drawn for glyphs of this composition.
2094 S->gidx == 0 means we are drawing the very first character of
2095 this composition. */
2097 /* Draw a rectangle for the composition if the font for the very
2098 first character of the composition could not be loaded. */
2099 if (s
->font_not_found_p
)
2102 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2103 s
->width
- 1, s
->height
- 1);
2107 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2108 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2109 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2110 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2116 #ifdef USE_X_TOOLKIT
2118 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2121 /* Return the frame on which widget WIDGET is used.. Abort if frame
2122 cannot be determined. */
2124 static struct frame
*
2125 x_frame_of_widget (widget
)
2128 struct x_display_info
*dpyinfo
;
2132 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2134 /* Find the top-level shell of the widget. Note that this function
2135 can be called when the widget is not yet realized, so XtWindow
2136 (widget) == 0. That's the reason we can't simply use
2137 x_any_window_to_frame. */
2138 while (!XtIsTopLevelShell (widget
))
2139 widget
= XtParent (widget
);
2141 /* Look for a frame with that top-level widget. Allocate the color
2142 on that frame to get the right gamma correction value. */
2143 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2144 if (GC_FRAMEP (XCAR (tail
))
2145 && (f
= XFRAME (XCAR (tail
)),
2146 (f
->output_data
.nothing
!= 1
2147 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2148 && f
->output_data
.x
->widget
== widget
)
2155 /* Allocate the color COLOR->pixel on the screen and display of
2156 widget WIDGET in colormap CMAP. If an exact match cannot be
2157 allocated, try the nearest color available. Value is non-zero
2158 if successful. This is called from lwlib. */
2161 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2166 struct frame
*f
= x_frame_of_widget (widget
);
2167 return x_alloc_nearest_color (f
, cmap
, color
);
2171 #endif /* USE_X_TOOLKIT */
2173 #if 0 /* MAC_TODO */
2175 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2176 CMAP. If an exact match can't be allocated, try the nearest color
2177 available. Value is non-zero if successful. Set *COLOR to the
2181 x_alloc_nearest_color (f
, cmap
, color
)
2186 Display
*display
= FRAME_X_DISPLAY (f
);
2187 Screen
*screen
= FRAME_X_SCREEN (f
);
2190 gamma_correct (f
, color
);
2191 rc
= XAllocColor (display
, cmap
, color
);
2194 /* If we got to this point, the colormap is full, so we're going
2195 to try to get the next closest color. The algorithm used is
2196 a least-squares matching, which is what X uses for closest
2197 color matching with StaticColor visuals. */
2199 unsigned long nearest_delta
= ~0;
2200 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2201 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2203 for (i
= 0; i
< ncells
; ++i
)
2205 XQueryColors (display
, cmap
, cells
, ncells
);
2207 for (nearest
= i
= 0; i
< ncells
; ++i
)
2209 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2210 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2211 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2212 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2214 if (delta
< nearest_delta
)
2217 nearest_delta
= delta
;
2221 color
->red
= cells
[nearest
].red
;
2222 color
->green
= cells
[nearest
].green
;
2223 color
->blue
= cells
[nearest
].blue
;
2224 rc
= XAllocColor (display
, cmap
, color
);
2227 #ifdef DEBUG_X_COLORS
2229 register_color (color
->pixel
);
2230 #endif /* DEBUG_X_COLORS */
2236 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2237 It's necessary to do this instead of just using PIXEL directly to
2238 get color reference counts right. */
2241 x_copy_color (f
, pixel
)
2243 unsigned long pixel
;
2247 color
.pixel
= pixel
;
2249 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2250 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2252 #ifdef DEBUG_X_COLORS
2253 register_color (pixel
);
2259 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2260 It's necessary to do this instead of just using PIXEL directly to
2261 get color reference counts right. */
2264 x_copy_dpy_color (dpy
, cmap
, pixel
)
2267 unsigned long pixel
;
2271 color
.pixel
= pixel
;
2273 XQueryColor (dpy
, cmap
, &color
);
2274 XAllocColor (dpy
, cmap
, &color
);
2276 #ifdef DEBUG_X_COLORS
2277 register_color (pixel
);
2282 #endif /* MAC_TODO */
2285 /* Brightness beyond which a color won't have its highlight brightness
2288 Nominally, highlight colors for `3d' faces are calculated by
2289 brightening an object's color by a constant scale factor, but this
2290 doesn't yield good results for dark colors, so for colors who's
2291 brightness is less than this value (on a scale of 0-255) have to
2292 use an additional additive factor.
2294 The value here is set so that the default menu-bar/mode-line color
2295 (grey75) will not have its highlights changed at all. */
2296 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2299 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2300 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2301 If this produces the same color as COLOR, try a color where all RGB
2302 values have DELTA added. Return the allocated color in *COLOR.
2303 DISPLAY is the X display, CMAP is the colormap to operate on.
2304 Value is non-zero if successful. */
2307 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2309 unsigned long *color
;
2316 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2319 /* Change RGB values by specified FACTOR. Avoid overflow! */
2320 xassert (factor
>= 0);
2321 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2322 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2323 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2325 /* Calculate brightness of COLOR. */
2326 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2327 + BLUE_FROM_ULONG (*color
)) / 6;
2329 /* We only boost colors that are darker than
2330 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2331 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2332 /* Make an additive adjustment to NEW, because it's dark enough so
2333 that scaling by FACTOR alone isn't enough. */
2335 /* How far below the limit this color is (0 - 1, 1 being darker). */
2336 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2337 /* The additive adjustment. */
2338 int min_delta
= delta
* dimness
* factor
/ 2;
2341 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2342 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2343 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2345 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2346 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2347 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2351 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2352 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2353 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2355 /* MAC_TODO: Map to palette and retry with delta if same? */
2356 /* MAC_TODO: Free colors (if using palette)? */
2367 /* Set up the foreground color for drawing relief lines of glyph
2368 string S. RELIEF is a pointer to a struct relief containing the GC
2369 with which lines will be drawn. Use a color that is FACTOR or
2370 DELTA lighter or darker than the relief's background which is found
2371 in S->f->output_data.x->relief_background. If such a color cannot
2372 be allocated, use DEFAULT_PIXEL, instead. */
2375 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2377 struct relief
*relief
;
2380 unsigned long default_pixel
;
2383 struct mac_output
*di
= f
->output_data
.mac
;
2384 unsigned long mask
= GCForeground
;
2385 unsigned long pixel
;
2386 unsigned long background
= di
->relief_background
;
2387 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2389 /* MAC_TODO: Free colors (if using palette)? */
2391 /* Allocate new color. */
2392 xgcv
.foreground
= default_pixel
;
2394 if (dpyinfo
->n_planes
!= 1
2395 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2397 relief
->allocated_p
= 1;
2398 xgcv
.foreground
= relief
->pixel
= pixel
;
2401 if (relief
->gc
== 0)
2403 #if 0 /* MAC_TODO: stipple */
2404 xgcv
.stipple
= dpyinfo
->gray
;
2407 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2410 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2414 /* Set up colors for the relief lines around glyph string S. */
2417 x_setup_relief_colors (s
)
2418 struct glyph_string
*s
;
2420 struct mac_output
*di
= s
->f
->output_data
.mac
;
2421 unsigned long color
;
2423 if (s
->face
->use_box_color_for_shadows_p
)
2424 color
= s
->face
->box_color
;
2425 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2427 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2428 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2433 /* Get the background color of the face. */
2434 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2435 color
= xgcv
.background
;
2438 if (di
->white_relief
.gc
== 0
2439 || color
!= di
->relief_background
)
2441 di
->relief_background
= color
;
2442 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2443 WHITE_PIX_DEFAULT (s
->f
));
2444 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2445 BLACK_PIX_DEFAULT (s
->f
));
2450 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2451 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2452 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2453 relief. LEFT_P non-zero means draw a relief on the left side of
2454 the rectangle. RIGHT_P non-zero means draw a relief on the right
2455 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2459 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2460 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2462 int left_x
, top_y
, right_x
, bottom_y
, width
;
2463 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2466 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2467 Window window
= FRAME_MAC_WINDOW (f
);
2472 gc
= f
->output_data
.mac
->white_relief
.gc
;
2474 gc
= f
->output_data
.mac
->black_relief
.gc
;
2475 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2479 for (i
= 0; i
< width
; ++i
)
2480 XDrawLine (dpy
, window
, gc
,
2481 left_x
+ i
* left_p
, top_y
+ i
,
2482 right_x
- i
* right_p
, top_y
+ i
);
2486 for (i
= 0; i
< width
; ++i
)
2487 XDrawLine (dpy
, window
, gc
,
2488 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2490 mac_reset_clipping (dpy
, window
);
2492 gc
= f
->output_data
.mac
->black_relief
.gc
;
2494 gc
= f
->output_data
.mac
->white_relief
.gc
;
2495 mac_set_clip_rectangle (dpy
, window
,
2500 for (i
= 0; i
< width
; ++i
)
2501 XDrawLine (dpy
, window
, gc
,
2502 left_x
+ i
* left_p
, bottom_y
- i
,
2503 right_x
- i
* right_p
, bottom_y
- i
);
2507 for (i
= 0; i
< width
; ++i
)
2508 XDrawLine (dpy
, window
, gc
,
2509 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2511 mac_reset_clipping (dpy
, window
);
2515 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2516 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2517 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2518 left side of the rectangle. RIGHT_P non-zero means draw a line
2519 on the right side of the rectangle. CLIP_RECT is the clipping
2520 rectangle to use when drawing. */
2523 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2524 left_p
, right_p
, clip_rect
)
2525 struct glyph_string
*s
;
2526 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2531 xgcv
.foreground
= s
->face
->box_color
;
2532 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2535 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2536 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2540 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2541 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2544 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2545 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2549 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2550 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2552 mac_reset_clipping (s
->display
, s
->window
);
2556 /* Draw a box around glyph string S. */
2559 x_draw_glyph_string_box (s
)
2560 struct glyph_string
*s
;
2562 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2563 int left_p
, right_p
;
2564 struct glyph
*last_glyph
;
2567 last_x
= window_box_right (s
->w
, s
->area
);
2568 if (s
->row
->full_width_p
2569 && !s
->w
->pseudo_window_p
)
2571 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2572 if (s
->area
!= RIGHT_MARGIN_AREA
2573 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2574 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
2577 /* The glyph that may have a right box line. */
2578 last_glyph
= (s
->cmp
|| s
->img
2580 : s
->first_glyph
+ s
->nchars
- 1);
2582 width
= abs (s
->face
->box_line_width
);
2583 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2585 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2587 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2589 bottom_y
= top_y
+ s
->height
- 1;
2591 left_p
= (s
->first_glyph
->left_box_line_p
2592 || (s
->hl
== DRAW_MOUSE_FACE
2594 || s
->prev
->hl
!= s
->hl
)));
2595 right_p
= (last_glyph
->right_box_line_p
2596 || (s
->hl
== DRAW_MOUSE_FACE
2598 || s
->next
->hl
!= s
->hl
)));
2600 get_glyph_string_clip_rect (s
, &clip_rect
);
2602 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2603 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2604 left_p
, right_p
, &clip_rect
);
2607 x_setup_relief_colors (s
);
2608 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2609 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2614 /* Draw foreground of image glyph string S. */
2617 x_draw_image_foreground (s
)
2618 struct glyph_string
*s
;
2621 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2623 /* If first glyph of S has a left box line, start drawing it to the
2624 right of that line. */
2625 if (s
->face
->box
!= FACE_NO_BOX
2626 && s
->first_glyph
->left_box_line_p
2628 x
+= abs (s
->face
->box_line_width
);
2630 /* If there is a margin around the image, adjust x- and y-position
2632 if (s
->slice
.x
== 0)
2633 x
+= s
->img
->hmargin
;
2634 if (s
->slice
.y
== 0)
2635 y
+= s
->img
->vmargin
;
2639 x_set_glyph_string_clipping (s
);
2642 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2643 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2644 s
->slice
.width
, s
->slice
.height
, x
, y
);
2647 mac_copy_area (s
->display
, s
->img
->pixmap
,
2648 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2649 s
->slice
.width
, s
->slice
.height
, x
, y
);
2651 /* When the image has a mask, we can expect that at
2652 least part of a mouse highlight or a block cursor will
2653 be visible. If the image doesn't have a mask, make
2654 a block cursor visible by drawing a rectangle around
2655 the image. I believe it's looking better if we do
2656 nothing here for mouse-face. */
2657 if (s
->hl
== DRAW_CURSOR
)
2659 int r
= s
->img
->relief
;
2661 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
2663 s
->slice
.width
+ r
*2 - 1,
2664 s
->slice
.height
+ r
*2 - 1);
2669 /* Draw a rectangle if image could not be loaded. */
2670 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2671 s
->slice
.width
- 1, s
->slice
.height
- 1);
2675 /* Draw a relief around the image glyph string S. */
2678 x_draw_image_relief (s
)
2679 struct glyph_string
*s
;
2681 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2684 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2686 /* If first glyph of S has a left box line, start drawing it to the
2687 right of that line. */
2688 if (s
->face
->box
!= FACE_NO_BOX
2689 && s
->first_glyph
->left_box_line_p
2691 x
+= abs (s
->face
->box_line_width
);
2693 /* If there is a margin around the image, adjust x- and y-position
2695 if (s
->slice
.x
== 0)
2696 x
+= s
->img
->hmargin
;
2697 if (s
->slice
.y
== 0)
2698 y
+= s
->img
->vmargin
;
2700 if (s
->hl
== DRAW_IMAGE_SUNKEN
2701 || s
->hl
== DRAW_IMAGE_RAISED
)
2703 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2704 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2708 thick
= abs (s
->img
->relief
);
2709 raised_p
= s
->img
->relief
> 0;
2714 x1
= x
+ s
->slice
.width
+ thick
- 1;
2715 y1
= y
+ s
->slice
.height
+ thick
- 1;
2717 x_setup_relief_colors (s
);
2718 get_glyph_string_clip_rect (s
, &r
);
2719 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
2721 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
2723 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
2728 #if 0 /* TODO: figure out if we need to do this on Mac. */
2729 /* Draw the foreground of image glyph string S to PIXMAP. */
2732 x_draw_image_foreground_1 (s
, pixmap
)
2733 struct glyph_string
*s
;
2737 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2739 /* If first glyph of S has a left box line, start drawing it to the
2740 right of that line. */
2741 if (s
->face
->box
!= FACE_NO_BOX
2742 && s
->first_glyph
->left_box_line_p
2744 x
+= abs (s
->face
->box_line_width
);
2746 /* If there is a margin around the image, adjust x- and y-position
2748 if (s
->slice
.x
== 0)
2749 x
+= s
->img
->hmargin
;
2750 if (s
->slice
.y
== 0)
2751 y
+= s
->img
->vmargin
;
2756 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2757 s
->img
->mask
, pixmap
, s
->gc
,
2758 s
->slice
.x
, s
->slice
.y
,
2759 s
->slice
.width
, s
->slice
.height
,
2763 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2764 s
->slice
.x
, s
->slice
.y
,
2765 s
->slice
.width
, s
->slice
.height
,
2768 /* When the image has a mask, we can expect that at
2769 least part of a mouse highlight or a block cursor will
2770 be visible. If the image doesn't have a mask, make
2771 a block cursor visible by drawing a rectangle around
2772 the image. I believe it's looking better if we do
2773 nothing here for mouse-face. */
2774 if (s
->hl
== DRAW_CURSOR
)
2776 int r
= s
->img
->relief
;
2778 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2779 s
->slice
.width
+ r
*2 - 1,
2780 s
->slice
.height
+ r
*2 - 1);
2785 /* Draw a rectangle if image could not be loaded. */
2786 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2787 s
->slice
.width
- 1, s
->slice
.height
- 1);
2792 /* Draw part of the background of glyph string S. X, Y, W, and H
2793 give the rectangle to draw. */
2796 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2797 struct glyph_string
*s
;
2800 #if 0 /* MAC_TODO: stipple */
2803 /* Fill background with a stipple pattern. */
2804 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2805 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2806 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2809 #endif /* MAC_TODO */
2810 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2814 /* Draw image glyph string S.
2817 s->x +-------------------------
2820 | +-------------------------
2823 | | +-------------------
2829 x_draw_image_glyph_string (s
)
2830 struct glyph_string
*s
;
2833 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2834 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2838 height
= s
->height
- 2 * box_line_vwidth
;
2841 /* Fill background with face under the image. Do it only if row is
2842 taller than image or if image has a clip mask to reduce
2844 s
->stippled_p
= s
->face
->stipple
!= 0;
2845 if (height
> s
->slice
.height
2849 || s
->img
->pixmap
== 0
2850 || s
->width
!= s
->background_width
)
2853 if (s
->first_glyph
->left_box_line_p
2855 x
+= box_line_hwidth
;
2858 if (s
->slice
.y
== 0)
2859 y
+= box_line_vwidth
;
2861 #if 0 /* TODO: figure out if we need to do this on Mac. */
2864 /* Create a pixmap as large as the glyph string. Fill it
2865 with the background color. Copy the image to it, using
2866 its mask. Copy the temporary pixmap to the display. */
2867 int depth
= one_mac_display_info
.n_planes
;
2869 /* Create a pixmap as large as the glyph string. */
2870 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2871 s
->background_width
,
2874 /* Fill the pixmap with the background color/stipple. */
2875 #if 0 /* TODO: stipple */
2878 /* Fill background with a stipple pattern. */
2879 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2880 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2881 0, 0, s
->background_width
, s
->height
);
2882 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2888 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2890 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2891 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2892 0, 0, s
->background_width
,
2894 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2899 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2901 s
->background_filled_p
= 1;
2904 /* Draw the foreground. */
2905 #if 0 /* TODO: figure out if we need to do this on Mac. */
2908 x_draw_image_foreground_1 (s
, pixmap
);
2909 x_set_glyph_string_clipping (s
);
2910 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2911 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2912 mac_reset_clipping (s
->display
, s
->window
);
2913 XFreePixmap (s
->display
, pixmap
);
2917 x_draw_image_foreground (s
);
2919 /* If we must draw a relief around the image, do it. */
2921 || s
->hl
== DRAW_IMAGE_RAISED
2922 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2923 x_draw_image_relief (s
);
2927 /* Draw stretch glyph string S. */
2930 x_draw_stretch_glyph_string (s
)
2931 struct glyph_string
*s
;
2933 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2934 s
->stippled_p
= s
->face
->stipple
!= 0;
2936 if (s
->hl
== DRAW_CURSOR
2937 && !x_stretch_cursor_p
)
2939 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2940 as wide as the stretch glyph. */
2941 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2944 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2946 /* Clear rest using the GC of the original non-cursor face. */
2947 if (width
< s
->background_width
)
2949 int x
= s
->x
+ width
, y
= s
->y
;
2950 int w
= s
->background_width
- width
, h
= s
->height
;
2954 if (s
->row
->mouse_face_p
2955 && cursor_in_mouse_face_p (s
->w
))
2957 x_set_mouse_face_gc (s
);
2963 get_glyph_string_clip_rect (s
, &r
);
2964 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2966 #if 0 /* MAC_TODO: stipple */
2967 if (s
->face
->stipple
)
2969 /* Fill background with a stipple pattern. */
2970 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2971 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2972 XSetFillStyle (s
->display
, gc
, FillSolid
);
2975 #endif /* MAC_TODO */
2978 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
2979 XSetForeground (s
->display
, gc
, xgcv
.background
);
2980 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2981 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
2984 mac_reset_clipping (s
->display
, s
->window
);
2987 else if (!s
->background_filled_p
)
2988 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
2991 s
->background_filled_p
= 1;
2995 /* Draw glyph string S. */
2998 x_draw_glyph_string (s
)
2999 struct glyph_string
*s
;
3001 int relief_drawn_p
= 0;
3003 /* If S draws into the background of its successor, draw the
3004 background of the successor first so that S can draw into it.
3005 This makes S->next use XDrawString instead of XDrawImageString. */
3006 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3008 xassert (s
->next
->img
== NULL
);
3009 x_set_glyph_string_gc (s
->next
);
3010 x_set_glyph_string_clipping (s
->next
);
3011 x_draw_glyph_string_background (s
->next
, 1);
3014 /* Set up S->gc, set clipping and draw S. */
3015 x_set_glyph_string_gc (s
);
3017 /* Draw relief (if any) in advance for char/composition so that the
3018 glyph string can be drawn over it. */
3019 if (!s
->for_overlaps_p
3020 && s
->face
->box
!= FACE_NO_BOX
3021 && (s
->first_glyph
->type
== CHAR_GLYPH
3022 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3025 x_set_glyph_string_clipping (s
);
3026 x_draw_glyph_string_background (s
, 1);
3027 x_draw_glyph_string_box (s
);
3028 x_set_glyph_string_clipping (s
);
3032 x_set_glyph_string_clipping (s
);
3034 switch (s
->first_glyph
->type
)
3037 x_draw_image_glyph_string (s
);
3041 x_draw_stretch_glyph_string (s
);
3045 if (s
->for_overlaps_p
)
3046 s
->background_filled_p
= 1;
3048 x_draw_glyph_string_background (s
, 0);
3049 x_draw_glyph_string_foreground (s
);
3052 case COMPOSITE_GLYPH
:
3053 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3054 s
->background_filled_p
= 1;
3056 x_draw_glyph_string_background (s
, 1);
3057 x_draw_composite_glyph_string_foreground (s
);
3064 if (!s
->for_overlaps_p
)
3066 /* Draw underline. */
3067 if (s
->face
->underline_p
)
3069 unsigned long h
= 1;
3070 unsigned long dy
= s
->height
- h
;
3072 if (s
->face
->underline_defaulted_p
)
3073 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3078 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3079 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3080 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3082 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3086 /* Draw overline. */
3087 if (s
->face
->overline_p
)
3089 unsigned long dy
= 0, h
= 1;
3091 if (s
->face
->overline_color_defaulted_p
)
3092 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3097 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3098 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3099 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3101 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3105 /* Draw strike-through. */
3106 if (s
->face
->strike_through_p
)
3108 unsigned long h
= 1;
3109 unsigned long dy
= (s
->height
- h
) / 2;
3111 if (s
->face
->strike_through_color_defaulted_p
)
3112 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3117 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3118 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3119 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3121 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3125 /* Draw relief if not yet drawn. */
3126 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3127 x_draw_glyph_string_box (s
);
3130 /* Reset clipping. */
3131 mac_reset_clipping (s
->display
, s
->window
);
3134 /* Shift display to make room for inserted glyphs. */
3137 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3139 int x
, y
, width
, height
, shift_by
;
3141 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3142 f
->output_data
.mac
->normal_gc
,
3143 x
, y
, width
, height
,
3147 /* Delete N glyphs at the nominal cursor position. Not implemented
3158 /* Clear entire frame. If updating_frame is non-null, clear that
3159 frame. Otherwise clear the selected frame. */
3169 f
= SELECTED_FRAME ();
3171 /* Clearing the frame will erase any cursor, so mark them all as no
3173 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3174 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3175 output_cursor
.x
= -1;
3177 /* We don't set the output cursor here because there will always
3178 follow an explicit cursor_to. */
3180 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3182 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
3183 /* We have to clear the scroll bars, too. If we have changed
3184 colors or something like that, then they should be notified. */
3185 x_scroll_bar_clear (f
);
3188 XFlush (FRAME_MAC_DISPLAY (f
));
3194 /* Invert the middle quarter of the frame for .15 sec. */
3196 /* We use the select system call to do the waiting, so we have to make
3197 sure it's available. If it isn't, we just won't do visual bells. */
3199 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3202 /* Subtract the `struct timeval' values X and Y, storing the result in
3203 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3206 timeval_subtract (result
, x
, y
)
3207 struct timeval
*result
, x
, y
;
3209 /* Perform the carry for the later subtraction by updating y. This
3210 is safer because on some systems the tv_sec member is unsigned. */
3211 if (x
.tv_usec
< y
.tv_usec
)
3213 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3214 y
.tv_usec
-= 1000000 * nsec
;
3218 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3220 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3221 y
.tv_usec
+= 1000000 * nsec
;
3225 /* Compute the time remaining to wait. tv_usec is certainly
3227 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3228 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3230 /* Return indication of whether the result should be considered
3232 return x
.tv_sec
< y
.tv_sec
;
3244 struct timeval wakeup
;
3246 EMACS_GET_TIME (wakeup
);
3248 /* Compute time to wait until, propagating carry from usecs. */
3249 wakeup
.tv_usec
+= 150000;
3250 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3251 wakeup
.tv_usec
%= 1000000;
3253 /* Keep waiting until past the time wakeup. */
3256 struct timeval timeout
;
3258 EMACS_GET_TIME (timeout
);
3260 /* In effect, timeout = wakeup - timeout.
3261 Break if result would be negative. */
3262 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3265 /* Try to wait that long--but we might wake up sooner. */
3266 select (0, NULL
, NULL
, NULL
, &timeout
);
3275 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3278 /* Make audible bell. */
3283 struct frame
*f
= SELECTED_FRAME ();
3285 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3293 XFlush (FRAME_MAC_DISPLAY (f
));
3300 /* Specify how many text lines, from the top of the window,
3301 should be affected by insert-lines and delete-lines operations.
3302 This, and those operations, are used only within an update
3303 that is bounded by calls to x_update_begin and x_update_end. */
3306 XTset_terminal_window (n
)
3309 /* This function intentionally left blank. */
3314 /***********************************************************************
3316 ***********************************************************************/
3318 /* Perform an insert-lines or delete-lines operation, inserting N
3319 lines or deleting -N lines at vertical position VPOS. */
3322 x_ins_del_lines (vpos
, n
)
3329 /* Scroll part of the display as described by RUN. */
3332 x_scroll_run (w
, run
)
3336 struct frame
*f
= XFRAME (w
->frame
);
3337 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3339 /* Get frame-relative bounding box of the text display area of W,
3340 without mode lines. Include in this box the left and right
3342 window_box (w
, -1, &x
, &y
, &width
, &height
);
3344 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3345 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3346 bottom_y
= y
+ height
;
3350 /* Scrolling up. Make sure we don't copy part of the mode
3351 line at the bottom. */
3352 if (from_y
+ run
->height
> bottom_y
)
3353 height
= bottom_y
- from_y
;
3355 height
= run
->height
;
3359 /* Scolling down. Make sure we don't copy over the mode line.
3361 if (to_y
+ run
->height
> bottom_y
)
3362 height
= bottom_y
- to_y
;
3364 height
= run
->height
;
3369 /* Cursor off. Will be switched on again in x_update_window_end. */
3373 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3374 f
->output_data
.mac
->normal_gc
,
3384 /***********************************************************************
3386 ***********************************************************************/
3393 x_update_cursor (f
, 1);
3397 frame_unhighlight (f
)
3400 x_update_cursor (f
, 1);
3403 /* The focus has changed. Update the frames as necessary to reflect
3404 the new situation. Note that we can't change the selected frame
3405 here, because the Lisp code we are interrupting might become confused.
3406 Each event gets marked with the frame in which it occurred, so the
3407 Lisp code can tell when the switch took place by examining the events. */
3410 x_new_focus_frame (dpyinfo
, frame
)
3411 struct x_display_info
*dpyinfo
;
3412 struct frame
*frame
;
3414 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3416 if (frame
!= dpyinfo
->x_focus_frame
)
3418 /* Set this before calling other routines, so that they see
3419 the correct value of x_focus_frame. */
3420 dpyinfo
->x_focus_frame
= frame
;
3422 if (old_focus
&& old_focus
->auto_lower
)
3423 x_lower_frame (old_focus
);
3426 selected_frame
= frame
;
3427 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3429 Fselect_window (selected_frame
->selected_window
, Qnil
);
3430 choose_minibuf_frame ();
3433 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3434 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3436 pending_autoraise_frame
= 0;
3439 x_frame_rehighlight (dpyinfo
);
3442 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3445 x_mouse_leave (dpyinfo
)
3446 struct x_display_info
*dpyinfo
;
3448 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3451 /* The focus has changed, or we have redirected a frame's focus to
3452 another frame (this happens when a frame uses a surrogate
3453 mini-buffer frame). Shift the highlight as appropriate.
3455 The FRAME argument doesn't necessarily have anything to do with which
3456 frame is being highlighted or un-highlighted; we only use it to find
3457 the appropriate X display info. */
3460 XTframe_rehighlight (frame
)
3461 struct frame
*frame
;
3463 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3467 x_frame_rehighlight (dpyinfo
)
3468 struct x_display_info
*dpyinfo
;
3470 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3472 if (dpyinfo
->x_focus_frame
)
3474 dpyinfo
->x_highlight_frame
3475 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3476 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3477 : dpyinfo
->x_focus_frame
);
3478 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3480 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3481 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3485 dpyinfo
->x_highlight_frame
= 0;
3487 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3490 frame_unhighlight (old_highlight
);
3491 if (dpyinfo
->x_highlight_frame
)
3492 frame_highlight (dpyinfo
->x_highlight_frame
);
3498 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3500 #if 0 /* MAC_TODO */
3501 /* Initialize mode_switch_bit and modifier_meaning. */
3503 x_find_modifier_meanings (dpyinfo
)
3504 struct x_display_info
*dpyinfo
;
3506 int min_code
, max_code
;
3509 XModifierKeymap
*mods
;
3511 dpyinfo
->meta_mod_mask
= 0;
3512 dpyinfo
->shift_lock_mask
= 0;
3513 dpyinfo
->alt_mod_mask
= 0;
3514 dpyinfo
->super_mod_mask
= 0;
3515 dpyinfo
->hyper_mod_mask
= 0;
3518 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3520 min_code
= dpyinfo
->display
->min_keycode
;
3521 max_code
= dpyinfo
->display
->max_keycode
;
3524 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3525 min_code
, max_code
- min_code
+ 1,
3527 mods
= XGetModifierMapping (dpyinfo
->display
);
3529 /* Scan the modifier table to see which modifier bits the Meta and
3530 Alt keysyms are on. */
3532 int row
, col
; /* The row and column in the modifier table. */
3534 for (row
= 3; row
< 8; row
++)
3535 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3538 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3540 /* Zeroes are used for filler. Skip them. */
3544 /* Are any of this keycode's keysyms a meta key? */
3548 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3550 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3556 dpyinfo
->meta_mod_mask
|= (1 << row
);
3561 dpyinfo
->alt_mod_mask
|= (1 << row
);
3566 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3571 dpyinfo
->super_mod_mask
|= (1 << row
);
3575 /* Ignore this if it's not on the lock modifier. */
3576 if ((1 << row
) == LockMask
)
3577 dpyinfo
->shift_lock_mask
= LockMask
;
3585 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3586 if (! dpyinfo
->meta_mod_mask
)
3588 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3589 dpyinfo
->alt_mod_mask
= 0;
3592 /* If some keys are both alt and meta,
3593 make them just meta, not alt. */
3594 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3596 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3599 XFree ((char *) syms
);
3600 XFreeModifiermap (mods
);
3603 #endif /* MAC_TODO */
3605 /* Convert between the modifier bits X uses and the modifier bits
3609 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3610 struct x_display_info
*dpyinfo
;
3611 unsigned short state
;
3613 return (((state
& shiftKey
) ? shift_modifier
: 0)
3614 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3615 | ((state
& cmdKey
) ? meta_modifier
: 0)
3616 | ((state
& optionKey
) ? alt_modifier
: 0));
3619 #if 0 /* MAC_TODO */
3620 static unsigned short
3621 x_emacs_to_x_modifiers (dpyinfo
, state
)
3622 struct x_display_info
*dpyinfo
;
3625 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3626 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3627 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3628 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3629 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3630 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3632 #endif /* MAC_TODO */
3634 /* Convert a keysym to its name. */
3637 x_get_keysym_name (keysym
)
3644 value
= XKeysymToString (keysym
);
3655 /* Mouse clicks and mouse movement. Rah. */
3657 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3659 If the event is a button press, then note that we have grabbed
3663 construct_mouse_click (result
, event
, f
)
3664 struct input_event
*result
;
3670 result
->kind
= MOUSE_CLICK_EVENT
;
3671 result
->code
= 0; /* only one mouse button */
3672 result
->timestamp
= event
->when
;
3673 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3675 mouseLoc
= event
->where
;
3677 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
3679 GlobalToLocal (&mouseLoc
);
3680 XSETINT (result
->x
, mouseLoc
.h
);
3681 XSETINT (result
->y
, mouseLoc
.v
);
3683 XSETFRAME (result
->frame_or_window
, f
);
3690 /* Function to report a mouse movement to the mainstream Emacs code.
3691 The input handler calls this.
3693 We have received a mouse movement event, which is given in *event.
3694 If the mouse is over a different glyph than it was last time, tell
3695 the mainstream emacs code by setting mouse_moved. If not, ask for
3696 another motion event, so we can check again the next time it moves. */
3698 static Point last_mouse_motion_position
;
3699 static Lisp_Object last_mouse_motion_frame
;
3702 note_mouse_movement (frame
, pos
)
3706 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
3707 #if TARGET_API_MAC_CARBON
3711 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3712 last_mouse_motion_position
= *pos
;
3713 XSETFRAME (last_mouse_motion_frame
, frame
);
3715 #if TARGET_API_MAC_CARBON
3716 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3718 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3721 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
3722 /* This case corresponds to LeaveNotify in X11. */
3724 /* If we move outside the frame, then we're certainly no
3725 longer on any text in the frame. */
3726 clear_mouse_face (dpyinfo
);
3727 dpyinfo
->mouse_face_mouse_frame
= 0;
3728 if (!dpyinfo
->grabbed
)
3729 rif
->define_frame_cursor (frame
,
3730 frame
->output_data
.mac
->nontext_cursor
);
3733 /* Has the mouse moved off the glyph it was on at the last sighting? */
3734 else if (pos
->h
< last_mouse_glyph
.left
3735 || pos
->h
>= last_mouse_glyph
.right
3736 || pos
->v
< last_mouse_glyph
.top
3737 || pos
->v
>= last_mouse_glyph
.bottom
)
3739 frame
->mouse_moved
= 1;
3740 last_mouse_scroll_bar
= Qnil
;
3741 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3745 /* This is used for debugging, to turn off note_mouse_highlight. */
3747 int disable_mouse_highlight
;
3751 /************************************************************************
3753 ************************************************************************/
3755 static struct scroll_bar
*x_window_to_scroll_bar ();
3756 static void x_scroll_bar_report_motion ();
3757 static void x_check_fullscreen
P_ ((struct frame
*));
3758 static void x_check_fullscreen_move
P_ ((struct frame
*));
3759 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3762 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3765 redo_mouse_highlight ()
3767 if (!NILP (last_mouse_motion_frame
)
3768 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3769 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3770 last_mouse_motion_position
.h
,
3771 last_mouse_motion_position
.v
);
3775 /* Try to determine frame pixel position and size of the glyph under
3776 frame pixel coordinates X/Y on frame F . Return the position and
3777 size in *RECT. Value is non-zero if we could compute these
3781 glyph_rect (f
, x
, y
, rect
)
3788 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3792 struct window
*w
= XWINDOW (window
);
3793 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3794 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3796 for (; r
< end
&& r
->enabled_p
; ++r
)
3797 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3799 /* Found the row at y. */
3800 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3801 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3804 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3805 rect
->bottom
= rect
->top
+ r
->height
;
3809 /* x is to the left of the first glyph in the row. */
3810 /* Shouldn't this be a pixel value?
3811 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3813 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3814 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3818 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3819 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3821 /* x is on a glyph. */
3822 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3823 rect
->right
= rect
->left
+ g
->pixel_width
;
3827 /* x is to the right of the last glyph in the row. */
3828 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3829 /* Shouldn't this be a pixel value?
3830 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3832 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3837 /* The y is not on any row. */
3841 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3843 /* Record the position of the mouse in last_mouse_glyph. */
3845 remember_mouse_glyph (f1
, gx
, gy
)
3849 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3851 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3852 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3854 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3855 round down even for negative values. */
3861 /* This was the original code from XTmouse_position, but it seems
3862 to give the position of the glyph diagonally next to the one
3863 the mouse is over. */
3864 gx
= (gx
+ width
- 1) / width
* width
;
3865 gy
= (gy
+ height
- 1) / height
* height
;
3867 gx
= gx
/ width
* width
;
3868 gy
= gy
/ height
* height
;
3871 last_mouse_glyph
.left
= gx
;
3872 last_mouse_glyph
.top
= gy
;
3873 last_mouse_glyph
.right
= gx
+ width
;
3874 last_mouse_glyph
.bottom
= gy
+ height
;
3880 front_emacs_window ()
3882 #if TARGET_API_MAC_CARBON
3883 WindowPtr wp
= GetFrontWindowOfClass (kDocumentWindowClass
, true);
3885 while (wp
&& !is_emacs_window (wp
))
3886 wp
= GetNextWindowOfClass (wp
, kDocumentWindowClass
, true);
3888 WindowPtr wp
= FrontWindow ();
3890 while (wp
&& (wp
== tip_window
|| !is_emacs_window (wp
)))
3891 wp
= GetNextWindow (wp
);
3897 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
3899 /* Return the current position of the mouse.
3900 *fp should be a frame which indicates which display to ask about.
3902 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3903 and *part to the frame, window, and scroll bar part that the mouse
3904 is over. Set *x and *y to the portion and whole of the mouse's
3905 position on the scroll bar.
3907 If the mouse movement started elsewhere, set *fp to the frame the
3908 mouse is on, *bar_window to nil, and *x and *y to the character cell
3911 Set *time to the server time-stamp for the time at which the mouse
3912 was at this position.
3914 Don't store anything if we don't have a valid set of values to report.
3916 This clears the mouse_moved flag, so we can wait for the next mouse
3920 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3923 Lisp_Object
*bar_window
;
3924 enum scroll_bar_part
*part
;
3926 unsigned long *time
;
3929 int ignore1
, ignore2
;
3930 WindowPtr wp
= front_emacs_window ();
3932 Lisp_Object frame
, tail
;
3934 if (is_emacs_window(wp
))
3935 f
= mac_window_to_frame (wp
);
3939 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3940 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3943 /* Clear the mouse-moved flag for every frame on this display. */
3944 FOR_EACH_FRAME (tail
, frame
)
3945 XFRAME (frame
)->mouse_moved
= 0;
3947 last_mouse_scroll_bar
= Qnil
;
3949 SetPortWindowPort (wp
);
3951 GetMouse (&mouse_pos
);
3953 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3954 &last_mouse_glyph
, insist
);
3957 *part
= scroll_bar_handle
;
3959 XSETINT (*x
, mouse_pos
.h
);
3960 XSETINT (*y
, mouse_pos
.v
);
3961 *time
= last_mouse_movement_time
;
3968 /***********************************************************************
3970 ***********************************************************************/
3972 /* Handle mouse button event on the tool-bar of frame F, at
3973 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3977 mac_handle_tool_bar_click (f
, button_event
)
3979 EventRecord
*button_event
;
3981 int x
= button_event
->where
.h
;
3982 int y
= button_event
->where
.v
;
3984 if (button_event
->what
== mouseDown
)
3985 handle_tool_bar_click (f
, x
, y
, 1, 0);
3987 handle_tool_bar_click (f
, x
, y
, 0,
3988 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
3989 button_event
->modifiers
));
3993 /************************************************************************
3994 Scroll bars, general
3995 ************************************************************************/
3997 /* Create a scroll bar and return the scroll bar vector for it. W is
3998 the Emacs window on which to create the scroll bar. TOP, LEFT,
3999 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4002 static struct scroll_bar
*
4003 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4005 int top
, left
, width
, height
, disp_top
, disp_height
;
4007 struct frame
*f
= XFRAME (w
->frame
);
4008 struct scroll_bar
*bar
4009 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4017 r
.right
= left
+ width
;
4018 r
.bottom
= disp_top
+ disp_height
;
4020 #ifdef TARGET_API_MAC_CARBON
4021 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
4022 kControlScrollBarProc
, 0L);
4024 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
4027 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4028 SetControlReference (ch
, (long) bar
);
4030 XSETWINDOW (bar
->window
, w
);
4031 XSETINT (bar
->top
, top
);
4032 XSETINT (bar
->left
, left
);
4033 XSETINT (bar
->width
, width
);
4034 XSETINT (bar
->height
, height
);
4035 XSETINT (bar
->start
, 0);
4036 XSETINT (bar
->end
, 0);
4037 bar
->dragging
= Qnil
;
4039 /* Add bar to its frame's list of scroll bars. */
4040 bar
->next
= FRAME_SCROLL_BARS (f
);
4042 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4043 if (!NILP (bar
->next
))
4044 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4051 /* Draw BAR's handle in the proper position.
4053 If the handle is already drawn from START to END, don't bother
4054 redrawing it, unless REBUILD is non-zero; in that case, always
4055 redraw it. (REBUILD is handy for drawing the handle after expose
4058 Normally, we want to constrain the start and end of the handle to
4059 fit inside its rectangle, but if the user is dragging the scroll
4060 bar handle, we want to let them drag it down all the way, so that
4061 the bar's top is as far down as it goes; otherwise, there's no way
4062 to move to the very end of the buffer. */
4065 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4066 struct scroll_bar
*bar
;
4070 int dragging
= ! NILP (bar
->dragging
);
4071 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4072 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4073 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4074 int length
= end
- start
;
4076 /* If the display is already accurate, do nothing. */
4078 && start
== XINT (bar
->start
)
4079 && end
== XINT (bar
->end
))
4084 /* Make sure the values are reasonable, and try to preserve the
4085 distance between start and end. */
4088 else if (start
> top_range
)
4090 end
= start
+ length
;
4094 else if (end
> top_range
&& ! dragging
)
4097 /* Store the adjusted setting in the scroll bar. */
4098 XSETINT (bar
->start
, start
);
4099 XSETINT (bar
->end
, end
);
4101 /* Clip the end position, just for display. */
4102 if (end
> top_range
)
4105 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4106 top positions, to make sure the handle is always at least that
4107 many pixels tall. */
4108 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4110 SetControlMinimum (ch
, 0);
4111 /* Don't inadvertently activate deactivated scroll bars */
4112 if (GetControlMaximum (ch
) != -1)
4113 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4115 SetControlValue (ch
, start
);
4116 #if TARGET_API_MAC_CARBON
4117 SetControlViewSize (ch
, end
- start
);
4124 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4128 x_scroll_bar_remove (bar
)
4129 struct scroll_bar
*bar
;
4131 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4135 /* Destroy the Mac scroll bar control */
4136 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4138 /* Disassociate this scroll bar from its window. */
4139 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4144 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4145 that we are displaying PORTION characters out of a total of WHOLE
4146 characters, starting at POSITION. If WINDOW has no scroll bar,
4149 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4151 int portion
, whole
, position
;
4153 struct frame
*f
= XFRAME (w
->frame
);
4154 struct scroll_bar
*bar
;
4155 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4156 int window_y
, window_height
;
4158 /* Get window dimensions. */
4159 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4164 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4166 height
= window_height
;
4168 /* Compute the left edge of the scroll bar area. */
4169 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4171 /* Compute the width of the scroll bar which might be less than
4172 the width of the area reserved for the scroll bar. */
4173 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4174 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4178 /* Compute the left edge of the scroll bar. */
4179 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4180 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
4182 sb_left
= left
+ (width
- sb_width
) / 2;
4184 /* Adjustments according to Inside Macintosh to make it look nice */
4186 disp_height
= height
;
4192 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4198 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4201 /* Does the scroll bar exist yet? */
4202 if (NILP (w
->vertical_scroll_bar
))
4205 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4206 left
, top
, width
, height
, 0);
4208 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4210 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4214 /* It may just need to be moved and resized. */
4217 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4218 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4222 /* If already correctly positioned, do nothing. */
4223 if (XINT (bar
->left
) == sb_left
4224 && XINT (bar
->top
) == top
4225 && XINT (bar
->width
) == sb_width
4226 && XINT (bar
->height
) == height
)
4230 /* Clear areas not covered by the scroll bar because it's not as
4231 wide as the area reserved for it . This makes sure a
4232 previous mode line display is cleared after C-x 2 C-x 1, for
4234 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4235 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4236 left
, top
, area_width
, height
, 0);
4239 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4240 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4241 sb_left
- 1, top
, 1, height
, 0);
4245 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4246 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4250 /* Remember new settings. */
4251 XSETINT (bar
->left
, sb_left
);
4252 XSETINT (bar
->top
, top
);
4253 XSETINT (bar
->width
, sb_width
);
4254 XSETINT (bar
->height
, height
);
4260 /* Set the scroll bar's current state, unless we're currently being
4262 if (NILP (bar
->dragging
))
4264 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4267 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4270 int start
= ((double) position
* top_range
) / whole
;
4271 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4272 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4278 /* The following three hooks are used when we're doing a thorough
4279 redisplay of the frame. We don't explicitly know which scroll bars
4280 are going to be deleted, because keeping track of when windows go
4281 away is a real pain - "Can you say set-window-configuration, boys
4282 and girls?" Instead, we just assert at the beginning of redisplay
4283 that *all* scroll bars are to be removed, and then save a scroll bar
4284 from the fiery pit when we actually redisplay its window. */
4286 /* Arrange for all scroll bars on FRAME to be removed at the next call
4287 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4288 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4291 XTcondemn_scroll_bars (frame
)
4294 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4295 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4298 bar
= FRAME_SCROLL_BARS (frame
);
4299 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4300 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4301 XSCROLL_BAR (bar
)->prev
= Qnil
;
4302 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4303 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4304 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4309 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4310 Note that WINDOW isn't necessarily condemned at all. */
4313 XTredeem_scroll_bar (window
)
4314 struct window
*window
;
4316 struct scroll_bar
*bar
;
4318 /* We can't redeem this window's scroll bar if it doesn't have one. */
4319 if (NILP (window
->vertical_scroll_bar
))
4322 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4324 /* Unlink it from the condemned list. */
4326 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4328 if (NILP (bar
->prev
))
4330 /* If the prev pointer is nil, it must be the first in one of
4332 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4333 /* It's not condemned. Everything's fine. */
4335 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4336 window
->vertical_scroll_bar
))
4337 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4339 /* If its prev pointer is nil, it must be at the front of
4340 one or the other! */
4344 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4346 if (! NILP (bar
->next
))
4347 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4349 bar
->next
= FRAME_SCROLL_BARS (f
);
4351 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4352 if (! NILP (bar
->next
))
4353 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4357 /* Remove all scroll bars on FRAME that haven't been saved since the
4358 last call to `*condemn_scroll_bars_hook'. */
4361 XTjudge_scroll_bars (f
)
4364 Lisp_Object bar
, next
;
4366 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4368 /* Clear out the condemned list now so we won't try to process any
4369 more events on the hapless scroll bars. */
4370 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4372 for (; ! NILP (bar
); bar
= next
)
4374 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4376 x_scroll_bar_remove (b
);
4379 b
->next
= b
->prev
= Qnil
;
4382 /* Now there should be no references to the condemned scroll bars,
4383 and they should get garbage-collected. */
4388 activate_scroll_bars (frame
)
4394 bar
= FRAME_SCROLL_BARS (frame
);
4395 while (! NILP (bar
))
4397 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4398 #ifdef TARGET_API_MAC_CARBON
4399 ActivateControl (ch
);
4401 SetControlMaximum (ch
,
4402 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4403 XINT (XSCROLL_BAR (bar
)
4406 bar
= XSCROLL_BAR (bar
)->next
;
4412 deactivate_scroll_bars (frame
)
4418 bar
= FRAME_SCROLL_BARS (frame
);
4419 while (! NILP (bar
))
4421 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4422 #ifdef TARGET_API_MAC_CARBON
4423 DeactivateControl (ch
);
4425 SetControlMaximum (ch
, XINT (-1));
4427 bar
= XSCROLL_BAR (bar
)->next
;
4431 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4432 is set to something other than NO_EVENT, it is enqueued.
4434 This may be called from a signal handler, so we have to ignore GC
4438 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4439 struct scroll_bar
*bar
;
4442 struct input_event
*bufp
;
4444 int win_y
, top_range
;
4446 if (! GC_WINDOWP (bar
->window
))
4449 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4450 bufp
->frame_or_window
= bar
->window
;
4453 bar
->dragging
= Qnil
;
4457 case kControlUpButtonPart
:
4458 bufp
->part
= scroll_bar_up_arrow
;
4460 case kControlDownButtonPart
:
4461 bufp
->part
= scroll_bar_down_arrow
;
4463 case kControlPageUpPart
:
4464 bufp
->part
= scroll_bar_above_handle
;
4466 case kControlPageDownPart
:
4467 bufp
->part
= scroll_bar_below_handle
;
4469 #ifdef TARGET_API_MAC_CARBON
4472 case kControlIndicatorPart
:
4474 if (er
->what
== mouseDown
)
4475 bar
->dragging
= make_number (0);
4476 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4477 bufp
->part
= scroll_bar_handle
;
4481 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
4482 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
4484 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4488 if (! NILP (bar
->dragging
))
4489 win_y
-= XINT (bar
->dragging
);
4493 if (win_y
> top_range
)
4496 XSETINT (bufp
->x
, win_y
);
4497 XSETINT (bufp
->y
, top_range
);
4501 /* Handle some mouse motion while someone is dragging the scroll bar.
4503 This may be called from a signal handler, so we have to ignore GC
4507 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4508 struct scroll_bar
*bar
;
4512 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4514 last_mouse_movement_time
= t
;
4517 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4519 /* If we're dragging the bar, display it. */
4520 if (! GC_NILP (bar
->dragging
))
4522 /* Where should the handle be now? */
4523 int new_start
= y_pos
- 24;
4525 if (new_start
!= XINT (bar
->start
))
4527 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4529 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4535 /* Return information to the user about the current position of the
4536 mouse on the scroll bar. */
4539 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4541 Lisp_Object
*bar_window
;
4542 enum scroll_bar_part
*part
;
4544 unsigned long *time
;
4546 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4547 WindowPtr wp
= front_emacs_window ();
4549 struct frame
*f
= mac_window_to_frame (wp
);
4550 int win_y
, top_range
;
4552 SetPortWindowPort (wp
);
4554 GetMouse (&mouse_pos
);
4556 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4557 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4559 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4563 if (! NILP (bar
->dragging
))
4564 win_y
-= XINT (bar
->dragging
);
4568 if (win_y
> top_range
)
4572 *bar_window
= bar
->window
;
4574 if (! NILP (bar
->dragging
))
4575 *part
= scroll_bar_handle
;
4576 else if (win_y
< XINT (bar
->start
))
4577 *part
= scroll_bar_above_handle
;
4578 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4579 *part
= scroll_bar_handle
;
4581 *part
= scroll_bar_below_handle
;
4583 XSETINT (*x
, win_y
);
4584 XSETINT (*y
, top_range
);
4587 last_mouse_scroll_bar
= Qnil
;
4589 *time
= last_mouse_movement_time
;
4592 /***********************************************************************
4594 ***********************************************************************/
4596 /* Set clipping for output in glyph row ROW. W is the window in which
4597 we operate. GC is the graphics context to set clipping in.
4599 ROW may be a text row or, e.g., a mode line. Text rows must be
4600 clipped to the interior of the window dedicated to text display,
4601 mode lines must be clipped to the whole window. */
4604 x_clip_to_row (w
, row
, area
, gc
)
4606 struct glyph_row
*row
;
4610 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4612 int window_x
, window_y
, window_width
;
4614 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
4616 clip_rect
.left
= window_x
;
4617 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4618 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4619 clip_rect
.right
= clip_rect
.left
+ window_width
;
4620 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4622 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4626 /* Draw a hollow box cursor on window W in glyph row ROW. */
4629 x_draw_hollow_cursor (w
, row
)
4631 struct glyph_row
*row
;
4633 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4634 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4635 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4638 struct glyph
*cursor_glyph
;
4641 /* Get the glyph the cursor is on. If we can't tell because
4642 the current matrix is invalid or such, give up. */
4643 cursor_glyph
= get_phys_cursor_glyph (w
);
4644 if (cursor_glyph
== NULL
)
4647 /* Compute the width of the rectangle to draw. If on a stretch
4648 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4649 rectangle as wide as the glyph, but use a canonical character
4651 wd
= cursor_glyph
->pixel_width
- 1;
4652 if (cursor_glyph
->type
== STRETCH_GLYPH
4653 && !x_stretch_cursor_p
)
4654 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4655 w
->phys_cursor_width
= wd
;
4657 /* Compute frame-relative coordinates from window-relative
4659 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4660 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
);
4662 /* Compute the proper height and ascent of the rectangle, based
4663 on the actual glyph. Using the full height of the row looks
4664 bad when there are tall images on that row. */
4665 h
= max (min (FRAME_LINE_HEIGHT (f
), row
->height
),
4666 cursor_glyph
->ascent
+ cursor_glyph
->descent
);
4667 if (h
< row
->height
)
4668 y
+= row
->ascent
/* - w->phys_cursor_ascent */ + cursor_glyph
->descent
- h
;
4671 /* The foreground of cursor_gc is typically the same as the normal
4672 background color, which can cause the cursor box to be invisible. */
4673 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4674 if (dpyinfo
->scratch_cursor_gc
)
4675 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4677 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4678 GCForeground
, &xgcv
);
4679 gc
= dpyinfo
->scratch_cursor_gc
;
4681 /* Set clipping, draw the rectangle, and reset clipping again. */
4682 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4683 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4684 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4688 /* Draw a bar cursor on window W in glyph row ROW.
4690 Implementation note: One would like to draw a bar cursor with an
4691 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4692 Unfortunately, I didn't find a font yet that has this property set.
4696 x_draw_bar_cursor (w
, row
, width
, kind
)
4698 struct glyph_row
*row
;
4700 enum text_cursor_kinds kind
;
4702 struct frame
*f
= XFRAME (w
->frame
);
4703 struct glyph
*cursor_glyph
;
4705 /* If cursor is out of bounds, don't draw garbage. This can happen
4706 in mini-buffer windows when switching between echo area glyphs
4708 cursor_glyph
= get_phys_cursor_glyph (w
);
4709 if (cursor_glyph
== NULL
)
4712 /* If on an image, draw like a normal cursor. That's usually better
4713 visible than drawing a bar, esp. if the image is large so that
4714 the bar might not be in the window. */
4715 if (cursor_glyph
->type
== IMAGE_GLYPH
)
4717 struct glyph_row
*row
;
4718 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
4719 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
4723 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4724 Window window
= FRAME_MAC_WINDOW (f
);
4725 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4726 unsigned long mask
= GCForeground
| GCBackground
;
4727 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
4730 /* If the glyph's background equals the color we normally draw
4731 the bar cursor in, the bar cursor in its normal color is
4732 invisible. Use the glyph's foreground color instead in this
4733 case, on the assumption that the glyph's colors are chosen so
4734 that the glyph is legible. */
4735 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
4736 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
4738 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4741 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4744 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4745 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4749 width
= FRAME_CURSOR_WIDTH (f
);
4750 width
= min (cursor_glyph
->pixel_width
, width
);
4752 w
->phys_cursor_width
= width
;
4753 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4755 if (kind
== BAR_CURSOR
)
4756 XFillRectangle (dpy
, window
, gc
,
4757 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4758 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4759 width
, row
->height
);
4761 XFillRectangle (dpy
, window
, gc
,
4762 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4763 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
4764 row
->height
- width
),
4765 cursor_glyph
->pixel_width
,
4768 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4773 /* RIF: Define cursor CURSOR on frame F. */
4776 mac_define_frame_cursor (f
, cursor
)
4780 #if TARGET_API_MAC_CARBON
4781 SetThemeCursor (cursor
);
4783 SetCursor (*cursor
);
4788 /* RIF: Clear area on frame F. */
4791 mac_clear_frame_area (f
, x
, y
, width
, height
)
4793 int x
, y
, width
, height
;
4795 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4796 x
, y
, width
, height
, 0);
4800 /* RIF: Draw cursor on window W. */
4803 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4805 struct glyph_row
*glyph_row
;
4807 int cursor_type
, cursor_width
;
4812 w
->phys_cursor_type
= cursor_type
;
4813 w
->phys_cursor_on_p
= 1;
4815 if (glyph_row
->exact_window_width_line_p
4816 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4818 glyph_row
->cursor_in_fringe_p
= 1;
4819 draw_fringe_bitmap (w
, glyph_row
, 0);
4822 switch (cursor_type
)
4824 case HOLLOW_BOX_CURSOR
:
4825 x_draw_hollow_cursor (w
, glyph_row
);
4828 case FILLED_BOX_CURSOR
:
4829 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4833 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
4837 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
4841 w
->phys_cursor_width
= 0;
4853 #if 0 /* MAC_TODO: no icon support yet. */
4855 x_bitmap_icon (f
, icon
)
4861 if (FRAME_W32_WINDOW (f
) == 0)
4865 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4866 else if (STRINGP (icon
))
4867 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4868 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4869 else if (SYMBOLP (icon
))
4873 if (EQ (icon
, intern ("application")))
4874 name
= (LPCTSTR
) IDI_APPLICATION
;
4875 else if (EQ (icon
, intern ("hand")))
4876 name
= (LPCTSTR
) IDI_HAND
;
4877 else if (EQ (icon
, intern ("question")))
4878 name
= (LPCTSTR
) IDI_QUESTION
;
4879 else if (EQ (icon
, intern ("exclamation")))
4880 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4881 else if (EQ (icon
, intern ("asterisk")))
4882 name
= (LPCTSTR
) IDI_ASTERISK
;
4883 else if (EQ (icon
, intern ("winlogo")))
4884 name
= (LPCTSTR
) IDI_WINLOGO
;
4888 hicon
= LoadIcon (NULL
, name
);
4896 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4901 #endif /* MAC_TODO */
4903 /************************************************************************
4905 ************************************************************************/
4907 /* Display Error Handling functions not used on W32. Listing them here
4908 helps diff stay in step when comparing w32term.c with xterm.c.
4910 x_error_catcher (display, error)
4911 x_catch_errors (dpy)
4912 x_catch_errors_unwind (old_val)
4913 x_check_errors (dpy, format)
4914 x_had_errors_p (dpy)
4915 x_clear_errors (dpy)
4916 x_uncatch_errors (dpy, count)
4918 x_connection_signal (signalnum)
4919 x_connection_closed (dpy, error_message)
4920 x_error_quitter (display, error)
4921 x_error_handler (display, error)
4922 x_io_error_quitter (display)
4927 /* Changing the font of the frame. */
4929 /* Give frame F the font named FONTNAME as its default font, and
4930 return the full name of that font. FONTNAME may be a wildcard
4931 pattern; in that case, we choose some font that fits the pattern.
4932 The return value shows which font we chose. */
4935 x_new_font (f
, fontname
)
4937 register char *fontname
;
4939 struct font_info
*fontp
4940 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4945 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4946 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4947 FRAME_FONTSET (f
) = -1;
4949 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4950 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4952 compute_fringe_widths (f
, 1);
4954 /* Compute the scroll bar width in character columns. */
4955 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4957 int wid
= FRAME_COLUMN_WIDTH (f
);
4958 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4959 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4963 int wid
= FRAME_COLUMN_WIDTH (f
);
4964 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4967 /* Now make the frame display the given font. */
4968 if (FRAME_MAC_WINDOW (f
) != 0)
4970 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4972 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4974 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4977 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4978 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4981 return build_string (fontp
->full_name
);
4984 /* Give frame F the fontset named FONTSETNAME as its default font, and
4985 return the full name of that fontset. FONTSETNAME may be a wildcard
4986 pattern; in that case, we choose some fontset that fits the pattern.
4987 The return value shows which fontset we chose. */
4990 x_new_fontset (f
, fontsetname
)
4994 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5000 if (FRAME_FONTSET (f
) == fontset
)
5001 /* This fontset is already set in frame F. There's nothing more
5003 return fontset_name (fontset
);
5005 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5007 if (!STRINGP (result
))
5008 /* Can't load ASCII font. */
5011 /* Since x_new_font doesn't update any fontset information, do it now. */
5012 FRAME_FONTSET(f
) = fontset
;
5014 return build_string (fontsetname
);
5018 /***********************************************************************
5019 TODO: W32 Input Methods
5020 ***********************************************************************/
5021 /* Listing missing functions from xterm.c helps diff stay in step.
5023 xim_destroy_callback (xim, client_data, call_data)
5024 xim_open_dpy (dpyinfo, resource_name)
5026 xim_instantiate_callback (display, client_data, call_data)
5027 xim_initialize (dpyinfo, resource_name)
5028 xim_close_dpy (dpyinfo)
5034 mac_get_window_bounds (f
, inner
, outer
)
5036 Rect
*inner
, *outer
;
5038 #if TARGET_API_MAC_CARBON
5039 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5040 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5041 #else /* not TARGET_API_MAC_CARBON */
5042 RgnHandle region
= NewRgn ();
5044 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5045 *inner
= (*region
)->rgnBBox
;
5046 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5047 *outer
= (*region
)->rgnBBox
;
5048 DisposeRgn (region
);
5049 #endif /* not TARGET_API_MAC_CARBON */
5053 /* Calculate the absolute position in frame F
5054 from its current recorded position values and gravity. */
5057 x_calc_absolute_position (f
)
5060 int width_diff
= 0, height_diff
= 0;
5061 int flags
= f
->size_hint_flags
;
5064 /* We have nothing to do if the current position
5065 is already for the top-left corner. */
5066 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5069 /* Find the offsets of the outside upper-left corner of
5070 the inner window, with respect to the outer window. */
5071 mac_get_window_bounds (f
, &inner
, &outer
);
5073 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5074 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5076 /* Treat negative positions as relative to the leftmost bottommost
5077 position that fits on the screen. */
5078 if (flags
& XNegative
)
5079 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5081 - FRAME_PIXEL_WIDTH (f
)
5084 if (flags
& YNegative
)
5085 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5087 - FRAME_PIXEL_HEIGHT (f
)
5090 /* The left_pos and top_pos
5091 are now relative to the top and left screen edges,
5092 so the flags should correspond. */
5093 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5096 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5097 to really change the position, and 0 when calling from
5098 x_make_frame_visible (in that case, XOFF and YOFF are the current
5099 position values). It is -1 when calling from x_set_frame_parameters,
5100 which means, do adjust for borders but don't change the gravity. */
5103 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5105 register int xoff
, yoff
;
5108 if (change_gravity
> 0)
5112 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5114 f
->size_hint_flags
|= XNegative
;
5116 f
->size_hint_flags
|= YNegative
;
5117 f
->win_gravity
= NorthWestGravity
;
5119 x_calc_absolute_position (f
);
5122 x_wm_set_size_hint (f
, (long) 0, 0);
5124 #if TARGET_API_MAC_CARBON
5125 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5126 /* If the title bar is completely outside the screen, adjust the
5128 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5129 kWindowConstrainMoveRegardlessOfFit
5130 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5131 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5134 Rect inner
, outer
, screen_rect
, dummy
;
5135 RgnHandle region
= NewRgn ();
5137 mac_get_window_bounds (f
, &inner
, &outer
);
5138 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5139 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5140 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5141 f
->top_pos
+ f
->y_pixels_diff
, false);
5143 /* If the title bar is completely outside the screen, adjust the
5144 position. The variable `outer' holds the title bar rectangle.
5145 The variable `inner' holds slightly smaller one than `outer',
5146 so that the calculation of overlapping may not become too
5148 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5149 outer
= (*region
)->rgnBBox
;
5150 DisposeRgn (region
);
5152 InsetRect (&inner
, 8, 8);
5153 screen_rect
= qd
.screenBits
.bounds
;
5154 screen_rect
.top
+= GetMBarHeight ();
5156 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5158 if (inner
.right
<= screen_rect
.left
)
5159 f
->left_pos
= screen_rect
.left
;
5160 else if (inner
.left
>= screen_rect
.right
)
5161 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5163 if (inner
.bottom
<= screen_rect
.top
)
5164 f
->top_pos
= screen_rect
.top
;
5165 else if (inner
.top
>= screen_rect
.bottom
)
5166 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5168 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5169 f
->top_pos
+ f
->y_pixels_diff
, false);
5177 /* Call this to change the size of frame F's x-window.
5178 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5179 for this size change and subsequent size changes.
5180 Otherwise we leave the window gravity unchanged. */
5183 x_set_window_size (f
, change_gravity
, cols
, rows
)
5188 int pixelwidth
, pixelheight
;
5192 check_frame_size (f
, &rows
, &cols
);
5193 f
->scroll_bar_actual_width
5194 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5196 compute_fringe_widths (f
, 0);
5198 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5199 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5201 f
->win_gravity
= NorthWestGravity
;
5202 x_wm_set_size_hint (f
, (long) 0, 0);
5204 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5206 /* Now, strictly speaking, we can't be sure that this is accurate,
5207 but the window manager will get around to dealing with the size
5208 change request eventually, and we'll hear how it went when the
5209 ConfigureNotify event gets here.
5211 We could just not bother storing any of this information here,
5212 and let the ConfigureNotify event set everything up, but that
5213 might be kind of confusing to the Lisp code, since size changes
5214 wouldn't be reported in the frame parameters until some random
5215 point in the future when the ConfigureNotify event arrives.
5217 We pass 1 for DELAY since we can't run Lisp code inside of
5219 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5220 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5221 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5223 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5224 receive in the ConfigureNotify event; if we get what we asked
5225 for, then the event won't cause the screen to become garbaged, so
5226 we have to make sure to do it here. */
5227 SET_FRAME_GARBAGED (f
);
5229 XFlush (FRAME_X_DISPLAY (f
));
5231 /* If cursor was outside the new size, mark it as off. */
5232 mark_window_cursors_off (XWINDOW (f
->root_window
));
5234 /* Clear out any recollection of where the mouse highlighting was,
5235 since it might be in a place that's outside the new frame size.
5236 Actually checking whether it is outside is a pain in the neck,
5237 so don't try--just let the highlighting be done afresh with new size. */
5238 cancel_mouse_face (f
);
5243 /* Mouse warping. */
5245 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5248 x_set_mouse_position (f
, x
, y
)
5254 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5255 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5257 if (pix_x
< 0) pix_x
= 0;
5258 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5260 if (pix_y
< 0) pix_y
= 0;
5261 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5263 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5267 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5271 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5274 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5275 0, 0, 0, 0, pix_x
, pix_y
);
5281 /* focus shifting, raising and lowering. */
5284 x_focus_on_frame (f
)
5287 #if 0 /* This proves to be unpleasant. */
5291 /* I don't think that the ICCCM allows programs to do things like this
5292 without the interaction of the window manager. Whatever you end up
5293 doing with this code, do it to x_unfocus_frame too. */
5294 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5295 RevertToPointerRoot
, CurrentTime
);
5305 /* Raise frame F. */
5310 if (f
->async_visible
)
5313 SelectWindow (FRAME_MAC_WINDOW (f
));
5318 /* Lower frame F. */
5323 if (f
->async_visible
)
5326 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5332 XTframe_raise_lower (f
, raise_flag
)
5342 /* Change of visibility. */
5344 /* This tries to wait until the frame is really visible.
5345 However, if the window manager asks the user where to position
5346 the frame, this will return before the user finishes doing that.
5347 The frame will not actually be visible at that time,
5348 but it will become visible later when the window manager
5349 finishes with it. */
5352 x_make_frame_visible (f
)
5356 int original_top
, original_left
;
5360 if (! FRAME_VISIBLE_P (f
))
5362 /* We test FRAME_GARBAGED_P here to make sure we don't
5363 call x_set_offset a second time
5364 if we get to x_make_frame_visible a second time
5365 before the window gets really visible. */
5366 if (! FRAME_ICONIFIED_P (f
)
5367 && ! f
->output_data
.mac
->asked_for_visible
)
5368 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5370 f
->output_data
.mac
->asked_for_visible
= 1;
5372 ShowWindow (FRAME_MAC_WINDOW (f
));
5375 XFlush (FRAME_MAC_DISPLAY (f
));
5377 /* Synchronize to ensure Emacs knows the frame is visible
5378 before we do anything else. We do this loop with input not blocked
5379 so that incoming events are handled. */
5384 /* This must come after we set COUNT. */
5387 XSETFRAME (frame
, f
);
5389 /* Wait until the frame is visible. Process X events until a
5390 MapNotify event has been seen, or until we think we won't get a
5391 MapNotify at all.. */
5392 for (count
= input_signal_count
+ 10;
5393 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5395 /* Force processing of queued events. */
5398 /* Machines that do polling rather than SIGIO have been
5399 observed to go into a busy-wait here. So we'll fake an
5400 alarm signal to let the handler know that there's something
5401 to be read. We used to raise a real alarm, but it seems
5402 that the handler isn't always enabled here. This is
5404 if (input_polling_used ())
5406 /* It could be confusing if a real alarm arrives while
5407 processing the fake one. Turn it off and let the
5408 handler reset it. */
5409 extern void poll_for_input_1
P_ ((void));
5410 int old_poll_suppress_count
= poll_suppress_count
;
5411 poll_suppress_count
= 1;
5412 poll_for_input_1 ();
5413 poll_suppress_count
= old_poll_suppress_count
;
5416 /* See if a MapNotify event has been processed. */
5417 FRAME_SAMPLE_VISIBILITY (f
);
5422 /* Change from mapped state to withdrawn state. */
5424 /* Make the frame visible (mapped and not iconified). */
5427 x_make_frame_invisible (f
)
5430 /* Don't keep the highlight on an invisible frame. */
5431 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5432 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5436 HideWindow (FRAME_MAC_WINDOW (f
));
5438 /* We can't distinguish this from iconification
5439 just by the event that we get from the server.
5440 So we can't win using the usual strategy of letting
5441 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5442 and synchronize with the server to make sure we agree. */
5444 FRAME_ICONIFIED_P (f
) = 0;
5445 f
->async_visible
= 0;
5446 f
->async_iconified
= 0;
5451 /* Change window state from mapped to iconified. */
5457 /* Don't keep the highlight on an invisible frame. */
5458 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5459 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5462 /* Review: Since window is still visible in dock, still allow updates? */
5463 if (f
->async_iconified
)
5469 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5475 /* Free X resources of frame F. */
5478 x_free_frame_resources (f
)
5481 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5482 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5487 if (wp
== tip_window
)
5488 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5489 closed' event. So we reset tip_window here. */
5492 free_frame_menubar (f
);
5494 if (FRAME_FACE_CACHE (f
))
5495 free_frame_faces (f
);
5499 xfree (f
->output_data
.mac
);
5500 f
->output_data
.mac
= NULL
;
5502 if (f
== dpyinfo
->x_focus_frame
)
5503 dpyinfo
->x_focus_frame
= 0;
5504 if (f
== dpyinfo
->x_focus_event_frame
)
5505 dpyinfo
->x_focus_event_frame
= 0;
5506 if (f
== dpyinfo
->x_highlight_frame
)
5507 dpyinfo
->x_highlight_frame
= 0;
5509 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5511 dpyinfo
->mouse_face_beg_row
5512 = dpyinfo
->mouse_face_beg_col
= -1;
5513 dpyinfo
->mouse_face_end_row
5514 = dpyinfo
->mouse_face_end_col
= -1;
5515 dpyinfo
->mouse_face_window
= Qnil
;
5516 dpyinfo
->mouse_face_deferred_gc
= 0;
5517 dpyinfo
->mouse_face_mouse_frame
= 0;
5524 /* Destroy the X window of frame F. */
5527 x_destroy_window (f
)
5530 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5532 x_free_frame_resources (f
);
5534 dpyinfo
->reference_count
--;
5538 /* Setting window manager hints. */
5540 /* Set the normal size hints for the window manager, for frame F.
5541 FLAGS is the flags word to use--or 0 meaning preserve the flags
5542 that the window now has.
5543 If USER_POSITION is nonzero, we set the USPosition
5544 flag (this is useful when FLAGS is 0). */
5546 x_wm_set_size_hint (f
, flags
, user_position
)
5551 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5552 XSizeHints size_hints
;
5554 #ifdef USE_X_TOOLKIT
5557 Dimension widget_width
, widget_height
;
5558 Window window
= XtWindow (f
->output_data
.x
->widget
);
5559 #else /* not USE_X_TOOLKIT */
5560 Window window
= FRAME_X_WINDOW (f
);
5561 #endif /* not USE_X_TOOLKIT */
5563 /* Setting PMaxSize caused various problems. */
5564 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5566 size_hints
.x
= f
->left_pos
;
5567 size_hints
.y
= f
->top_pos
;
5569 #ifdef USE_X_TOOLKIT
5570 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5571 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5572 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5573 size_hints
.height
= widget_height
;
5574 size_hints
.width
= widget_width
;
5575 #else /* not USE_X_TOOLKIT */
5576 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5577 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5578 #endif /* not USE_X_TOOLKIT */
5580 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5581 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5582 size_hints
.max_width
5583 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5584 size_hints
.max_height
5585 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5587 /* Calculate the base and minimum sizes.
5589 (When we use the X toolkit, we don't do it here.
5590 Instead we copy the values that the widgets are using, below.) */
5591 #ifndef USE_X_TOOLKIT
5593 int base_width
, base_height
;
5594 int min_rows
= 0, min_cols
= 0;
5596 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5597 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5599 check_frame_size (f
, &min_rows
, &min_cols
);
5601 /* The window manager uses the base width hints to calculate the
5602 current number of rows and columns in the frame while
5603 resizing; min_width and min_height aren't useful for this
5604 purpose, since they might not give the dimensions for a
5605 zero-row, zero-column frame.
5607 We use the base_width and base_height members if we have
5608 them; otherwise, we set the min_width and min_height members
5609 to the size for a zero x zero frame. */
5612 size_hints
.flags
|= PBaseSize
;
5613 size_hints
.base_width
= base_width
;
5614 size_hints
.base_height
= base_height
;
5615 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5616 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5618 size_hints
.min_width
= base_width
;
5619 size_hints
.min_height
= base_height
;
5623 /* If we don't need the old flags, we don't need the old hint at all. */
5626 size_hints
.flags
|= flags
;
5629 #endif /* not USE_X_TOOLKIT */
5632 XSizeHints hints
; /* Sometimes I hate X Windows... */
5633 long supplied_return
;
5637 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5640 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5643 #ifdef USE_X_TOOLKIT
5644 size_hints
.base_height
= hints
.base_height
;
5645 size_hints
.base_width
= hints
.base_width
;
5646 size_hints
.min_height
= hints
.min_height
;
5647 size_hints
.min_width
= hints
.min_width
;
5651 size_hints
.flags
|= flags
;
5656 if (hints
.flags
& PSize
)
5657 size_hints
.flags
|= PSize
;
5658 if (hints
.flags
& PPosition
)
5659 size_hints
.flags
|= PPosition
;
5660 if (hints
.flags
& USPosition
)
5661 size_hints
.flags
|= USPosition
;
5662 if (hints
.flags
& USSize
)
5663 size_hints
.flags
|= USSize
;
5667 #ifndef USE_X_TOOLKIT
5672 size_hints
.win_gravity
= f
->win_gravity
;
5673 size_hints
.flags
|= PWinGravity
;
5677 size_hints
.flags
&= ~ PPosition
;
5678 size_hints
.flags
|= USPosition
;
5680 #endif /* PWinGravity */
5683 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5685 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5687 #endif /* MAC_TODO */
5690 #if 0 /* MAC_TODO: hide application instead of iconify? */
5691 /* Used for IconicState or NormalState */
5694 x_wm_set_window_state (f
, state
)
5698 #ifdef USE_X_TOOLKIT
5701 XtSetArg (al
[0], XtNinitialState
, state
);
5702 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5703 #else /* not USE_X_TOOLKIT */
5704 Window window
= FRAME_X_WINDOW (f
);
5706 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5707 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5709 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5710 #endif /* not USE_X_TOOLKIT */
5714 x_wm_set_icon_pixmap (f
, pixmap_id
)
5720 #ifndef USE_X_TOOLKIT
5721 Window window
= FRAME_X_WINDOW (f
);
5726 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5727 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5731 /* It seems there is no way to turn off use of an icon pixmap.
5732 The following line does it, only if no icon has yet been created,
5733 for some window managers. But with mwm it crashes.
5734 Some people say it should clear the IconPixmapHint bit in this case,
5735 but that doesn't work, and the X consortium said it isn't the
5736 right thing at all. Since there is no way to win,
5737 best to explicitly give up. */
5739 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5745 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5749 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5750 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5753 #else /* not USE_X_TOOLKIT */
5755 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5756 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5758 #endif /* not USE_X_TOOLKIT */
5761 #endif /* MAC_TODO */
5764 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5768 #if 0 /* MAC_TODO: no icons on Mac */
5769 #ifdef USE_X_TOOLKIT
5770 Window window
= XtWindow (f
->output_data
.x
->widget
);
5772 Window window
= FRAME_X_WINDOW (f
);
5775 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5776 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5777 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5779 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5780 #endif /* MAC_TODO */
5784 /***********************************************************************
5786 ***********************************************************************/
5788 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5791 x_get_font_info (f
, font_idx
)
5795 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5798 /* the global font name table */
5799 char **font_name_table
= NULL
;
5800 int font_name_table_size
= 0;
5801 int font_name_count
= 0;
5804 /* compare two strings ignoring case */
5806 stricmp (const char *s
, const char *t
)
5808 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5811 return tolower (*s
) - tolower (*t
);
5814 /* compare two strings ignoring case and handling wildcard */
5816 wildstrieq (char *s1
, char *s2
)
5818 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5821 return stricmp (s1
, s2
) == 0;
5824 /* Assume parameter 1 is fully qualified, no wildcards. */
5826 mac_font_pattern_match (fontname
, pattern
)
5830 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5831 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5834 /* Copy fontname so we can modify it during comparison. */
5835 strcpy (font_name_copy
, fontname
);
5840 /* Turn pattern into a regexp and do a regexp match. */
5841 for (; *pattern
; pattern
++)
5843 if (*pattern
== '?')
5845 else if (*pattern
== '*')
5856 return (fast_c_string_match_ignore_case (build_string (regex
),
5857 font_name_copy
) >= 0);
5860 /* Two font specs are considered to match if their foundry, family,
5861 weight, slant, and charset match. */
5863 mac_font_match (char *mf
, char *xf
)
5865 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5866 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5868 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5869 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5870 return mac_font_pattern_match (mf
, xf
);
5872 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5873 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5874 return mac_font_pattern_match (mf
, xf
);
5876 return (wildstrieq (m_foundry
, x_foundry
)
5877 && wildstrieq (m_family
, x_family
)
5878 && wildstrieq (m_weight
, x_weight
)
5879 && wildstrieq (m_slant
, x_slant
)
5880 && wildstrieq (m_charset
, x_charset
))
5881 || mac_font_pattern_match (mf
, xf
);
5885 static Lisp_Object Qbig5
, Qcn_gb
, Qsjis
, Qeuc_kr
;
5888 decode_mac_font_name (name
, size
, scriptcode
)
5891 #if TARGET_API_MAC_CARBON
5897 Lisp_Object coding_system
;
5898 struct coding_system coding
;
5904 coding_system
= Qbig5
;
5907 coding_system
= Qcn_gb
;
5910 coding_system
= Qsjis
;
5913 coding_system
= Qeuc_kr
;
5919 setup_coding_system (coding_system
, &coding
);
5920 coding
.src_multibyte
= 0;
5921 coding
.dst_multibyte
= 1;
5922 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5923 coding
.composing
= COMPOSITION_DISABLED
;
5924 buf
= (char *) alloca (size
);
5926 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
5927 bcopy (buf
, name
, coding
.produced
);
5928 name
[coding
.produced
] = '\0';
5933 mac_to_x_fontname (name
, size
, style
, scriptcode
, encoding_base
)
5937 #if TARGET_API_MAC_CARBON
5943 char foundry
[32], family
[32], cs
[32];
5944 char xf
[256], *result
, *p
;
5946 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5948 strcpy(foundry
, "Apple");
5949 strcpy(family
, name
);
5953 case smTradChinese
: /* == kTextEncodingMacChineseTrad */
5954 strcpy(cs
, "big5-0");
5956 case smSimpChinese
: /* == kTextEncodingMacChineseSimp */
5957 strcpy(cs
, "gb2312.1980-0");
5959 case smJapanese
: /* == kTextEncodingMacJapanese */
5960 strcpy(cs
, "jisx0208.1983-sjis");
5963 /* Each Apple Japanese font is entered into the font table
5964 twice: once as a jisx0208.1983-sjis font and once as a
5965 jisx0201.1976-0 font. The latter can be used to display
5966 the ascii charset and katakana-jisx0201 charset. A
5967 negative script code signals that the name of this latter
5968 font is being built. */
5969 strcpy(cs
, "jisx0201.1976-0");
5971 case smKorean
: /* == kTextEncodingMacKorean */
5972 strcpy(cs
, "ksc5601.1989-0");
5974 #if TARGET_API_MAC_CARBON
5975 case kTextEncodingMacCyrillic
:
5976 strcpy(cs
, "mac-cyrillic");
5978 case kTextEncodingMacCentralEurRoman
:
5979 strcpy(cs
, "mac-centraleurroman");
5981 case kTextEncodingMacSymbol
:
5982 case kTextEncodingMacDingbats
:
5983 strcpy(cs
, "adobe-fontspecific");
5987 strcpy(cs
, "mac-roman");
5992 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5993 foundry
, family
, style
& bold
? "bold" : "medium",
5994 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5996 result
= (char *) xmalloc (strlen (xf
) + 1);
5997 strcpy (result
, xf
);
5998 for (p
= result
; *p
; p
++)
6004 /* Convert an X font spec to the corresponding mac font name, which
6005 can then be passed to GetFNum after conversion to a Pascal string.
6006 For ordinary Mac fonts, this should just be their names, like
6007 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
6008 collection contain their charset designation in their names, like
6009 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
6010 names are handled accordingly. */
6012 x_font_name_to_mac_font_name (char *xf
, char *mf
)
6014 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
6015 Lisp_Object coding_system
= Qnil
;
6016 struct coding_system coding
;
6020 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6021 foundry
, family
, weight
, slant
, cs
) != 5 &&
6022 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6023 foundry
, family
, weight
, slant
, cs
) != 5)
6026 if (strcmp (cs
, "big5-0") == 0)
6027 coding_system
= Qbig5
;
6028 else if (strcmp (cs
, "gb2312.1980-0") == 0)
6029 coding_system
= Qcn_gb
;
6030 else if (strcmp (cs
, "jisx0208.1983-sjis") == 0
6031 || strcmp (cs
, "jisx0201.1976-0") == 0)
6032 coding_system
= Qsjis
;
6033 else if (strcmp (cs
, "ksc5601.1989-0") == 0)
6034 coding_system
= Qeuc_kr
;
6035 else if (strcmp (cs
, "mac-roman") == 0
6036 || strcmp (cs
, "mac-cyrillic") == 0
6037 || strcmp (cs
, "mac-centraleurroman") == 0
6038 || strcmp (cs
, "adobe-fontspecific") == 0)
6039 strcpy (mf
, family
);
6041 sprintf (mf
, "%s-%s-%s", foundry
, family
, cs
);
6043 if (!NILP (coding_system
))
6045 setup_coding_system (coding_system
, &coding
);
6046 coding
.src_multibyte
= 1;
6047 coding
.dst_multibyte
= 1;
6048 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6049 encode_coding (&coding
, family
, mf
, strlen (family
), sizeof (Str32
) - 1);
6050 mf
[coding
.produced
] = '\0';
6056 add_font_name_table_entry (char *font_name
)
6058 if (font_name_table_size
== 0)
6060 font_name_table_size
= 16;
6061 font_name_table
= (char **)
6062 xmalloc (font_name_table_size
* sizeof (char *));
6064 else if (font_name_count
+ 1 >= font_name_table_size
)
6066 font_name_table_size
+= 16;
6067 font_name_table
= (char **)
6068 xrealloc (font_name_table
,
6069 font_name_table_size
* sizeof (char *));
6072 font_name_table
[font_name_count
++] = font_name
;
6075 /* Sets up the table font_name_table to contain the list of all fonts
6076 in the system the first time the table is used so that the Resource
6077 Manager need not be accessed every time this information is
6081 init_font_name_table ()
6083 #if TARGET_API_MAC_CARBON
6086 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
6088 FMFontFamilyIterator ffi
;
6089 FMFontFamilyInstanceIterator ffii
;
6092 /* Create a dummy instance iterator here to avoid creating and
6093 destroying it in the loop. */
6094 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6096 /* Create an iterator to enumerate the font families. */
6097 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6100 FMDisposeFontFamilyInstanceIterator (&ffii
);
6104 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6110 TextEncoding encoding
;
6111 TextEncodingBase sc
;
6113 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6119 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
6121 sc
= GetTextEncodingBase (encoding
);
6122 decode_mac_font_name (name
, sizeof (name
), sc
);
6124 /* Point the instance iterator at the current font family. */
6125 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6128 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6131 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
6132 contained in Apple Japanese (SJIS) font. */
6136 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6138 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6140 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6142 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6147 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6149 if (sc
== smJapanese
)
6154 else if (sc
== -smJapanese
)
6159 /* Dispose of the iterators. */
6160 FMDisposeFontFamilyIterator (&ffi
);
6161 FMDisposeFontFamilyInstanceIterator (&ffii
);
6165 #endif /* TARGET_API_MAC_CARBON */
6167 SInt16 fontnum
, old_fontnum
;
6168 int num_mac_fonts
= CountResources('FOND');
6170 Handle font_handle
, font_handle_2
;
6171 short id
, scriptcode
;
6174 struct FontAssoc
*fat
;
6175 struct AsscEntry
*assc_entry
;
6177 GetPort (&port
); /* save the current font number used */
6178 #if TARGET_API_MAC_CARBON
6179 old_fontnum
= GetPortTextFont (port
);
6181 old_fontnum
= port
->txFont
;
6184 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6186 font_handle
= GetIndResource ('FOND', i
);
6190 GetResInfo (font_handle
, &id
, &type
, name
);
6191 GetFNum (name
, &fontnum
);
6197 scriptcode
= FontToScript (fontnum
);
6198 decode_mac_font_name (name
, sizeof (name
), scriptcode
);
6201 HLock (font_handle
);
6203 if (GetResourceSizeOnDisk (font_handle
)
6204 >= sizeof (struct FamRec
))
6206 fat
= (struct FontAssoc
*) (*font_handle
6207 + sizeof (struct FamRec
));
6209 = (struct AsscEntry
*) (*font_handle
6210 + sizeof (struct FamRec
)
6211 + sizeof (struct FontAssoc
));
6213 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6215 if (font_name_table_size
== 0)
6217 font_name_table_size
= 16;
6218 font_name_table
= (char **)
6219 xmalloc (font_name_table_size
* sizeof (char *));
6221 else if (font_name_count
>= font_name_table_size
)
6223 font_name_table_size
+= 16;
6224 font_name_table
= (char **)
6225 xrealloc (font_name_table
,
6226 font_name_table_size
* sizeof (char *));
6228 font_name_table
[font_name_count
++]
6229 = mac_to_x_fontname (name
,
6230 assc_entry
->fontSize
,
6231 assc_entry
->fontStyle
,
6233 /* Both jisx0208.1983-sjis and jisx0201.1976-0
6234 parts are contained in Apple Japanese (SJIS)
6236 if (smJapanese
== scriptcode
)
6238 font_name_table
[font_name_count
++]
6239 = mac_to_x_fontname (name
,
6240 assc_entry
->fontSize
,
6241 assc_entry
->fontStyle
,
6247 HUnlock (font_handle
);
6248 font_handle_2
= GetNextFOND (font_handle
);
6249 ReleaseResource (font_handle
);
6250 font_handle
= font_handle_2
;
6252 while (ResError () == noErr
&& font_handle
);
6255 TextFont (old_fontnum
);
6256 #if TARGET_API_MAC_CARBON
6258 #endif /* TARGET_API_MAC_CARBON */
6262 enum xlfd_scalable_field_index
6264 XLFD_SCL_PIXEL_SIZE
,
6265 XLFD_SCL_POINT_SIZE
,
6270 static int xlfd_scalable_fields
[] =
6279 mac_c_string_match (regexp
, string
, nonspecial
, exact
)
6281 const char *string
, *nonspecial
;
6286 if (strcmp (string
, nonspecial
) == 0)
6287 return build_string (string
);
6289 else if (strstr (string
, nonspecial
))
6291 Lisp_Object str
= build_string (string
);
6293 if (fast_string_match (regexp
, str
) >= 0)
6301 mac_do_list_fonts (pattern
, maxnames
)
6306 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6307 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6310 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6311 char *longest_start
, *cur_start
, *nonspecial
;
6312 int longest_len
, cur_len
, exact
;
6314 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6317 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6318 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6319 fonts are scaled according to the specified size. */
6322 field
= xlfd_scalable_fields
;
6330 if ('1' <= *ptr
&& *ptr
<= '9')
6332 *val
= *ptr
++ - '0';
6333 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6334 *val
= *val
* 10 + *ptr
++ - '0';
6341 ptr
= strchr (ptr
, '-');
6344 while (ptr
&& i
< 14);
6346 if (i
== 14 && ptr
== NULL
)
6348 if (scl_val
[XLFD_SCL_POINT_SIZE
] > 0)
6350 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_POINT_SIZE
] / 10;
6351 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_POINT_SIZE
];
6353 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0)
6355 scl_val
[XLFD_SCL_POINT_SIZE
] =
6356 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10;
6358 else if (scl_val
[XLFD_SCL_AVGWIDTH
] > 0)
6360 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
] / 10;
6361 scl_val
[XLFD_SCL_POINT_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
];
6365 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6370 longest_start
= cur_start
= ptr
;
6371 longest_len
= cur_len
= 0;
6374 /* Turn pattern into a regexp and do a regexp match. Also find the
6375 longest substring containing no special characters. */
6376 for (; *pattern
; pattern
++)
6378 if (*pattern
== '?' || *pattern
== '*')
6380 if (cur_len
> longest_len
)
6382 longest_start
= cur_start
;
6383 longest_len
= cur_len
;
6388 if (*pattern
== '?')
6390 else /* if (*pattern == '*') */
6402 *ptr
++ = tolower (*pattern
);
6406 if (cur_len
> longest_len
)
6408 longest_start
= cur_start
;
6409 longest_len
= cur_len
;
6415 nonspecial
= xmalloc (longest_len
+ 1);
6416 strncpy (nonspecial
, longest_start
, longest_len
);
6417 nonspecial
[longest_len
] = '\0';
6419 pattern_regex
= build_string (regex
);
6421 for (i
= 0; i
< font_name_count
; i
++)
6423 fontname
= mac_c_string_match (pattern_regex
, font_name_table
[i
],
6425 if (!NILP (fontname
))
6427 font_list
= Fcons (fontname
, font_list
);
6428 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
6431 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6432 && (ptr
= strstr (font_name_table
[i
], "-0-0-75-75-m-0-")))
6434 int former_len
= ptr
- font_name_table
[i
];
6436 memcpy (scaled
, font_name_table
[i
], former_len
);
6437 sprintf (scaled
+ former_len
,
6438 "-%d-%d-75-75-m-%d-%s",
6439 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6440 scl_val
[XLFD_SCL_POINT_SIZE
],
6441 scl_val
[XLFD_SCL_AVGWIDTH
],
6442 ptr
+ sizeof ("-0-0-75-75-m-0-") - 1);
6443 fontname
= mac_c_string_match (pattern_regex
, scaled
,
6445 if (!NILP (fontname
))
6447 font_list
= Fcons (fontname
, font_list
);
6448 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
6459 /* Return a list of at most MAXNAMES font specs matching the one in
6460 PATTERN. Cache matching fonts for patterns in
6461 dpyinfo->name_list_element to avoid looking them up again by
6462 calling mac_font_pattern_match (slow). Return as many matching
6463 fonts as possible if MAXNAMES = -1. */
6466 x_list_fonts (struct frame
*f
,
6467 Lisp_Object pattern
,
6471 Lisp_Object newlist
= Qnil
, tem
, key
;
6472 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
6474 if (font_name_table
== NULL
) /* Initialize when first used. */
6475 init_font_name_table ();
6479 tem
= XCDR (dpyinfo
->name_list_element
);
6480 key
= Fcons (pattern
, make_number (maxnames
));
6482 newlist
= Fassoc (key
, tem
);
6483 if (!NILP (newlist
))
6485 newlist
= Fcdr_safe (newlist
);
6490 newlist
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6492 /* MAC_TODO: add code for matching outline fonts here */
6496 XSETCDR (dpyinfo
->name_list_element
,
6497 Fcons (Fcons (key
, newlist
),
6498 XCDR (dpyinfo
->name_list_element
)));
6508 /* Check that FONT is valid on frame F. It is if it can be found in F's
6512 x_check_font (f
, font
)
6517 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6519 xassert (font
!= NULL
);
6521 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6522 if (dpyinfo
->font_table
[i
].name
6523 && font
== dpyinfo
->font_table
[i
].font
)
6526 xassert (i
< dpyinfo
->n_fonts
);
6529 #endif /* GLYPH_DEBUG != 0 */
6531 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6532 Note: There are (broken) X fonts out there with invalid XFontStruct
6533 min_bounds contents. For example, handa@etl.go.jp reports that
6534 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6535 have font->min_bounds.width == 0. */
6538 x_font_min_bounds (font
, w
, h
)
6539 MacFontStruct
*font
;
6543 * TODO: Windows does not appear to offer min bound, only
6544 * average and maximum width, and maximum height.
6546 *h
= FONT_HEIGHT (font
);
6547 *w
= FONT_WIDTH (font
);
6551 /* Compute the smallest character width and smallest font height over
6552 all fonts available on frame F. Set the members smallest_char_width
6553 and smallest_font_height in F's x_display_info structure to
6554 the values computed. Value is non-zero if smallest_font_height or
6555 smallest_char_width become smaller than they were before. */
6558 x_compute_min_glyph_bounds (f
)
6562 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6563 MacFontStruct
*font
;
6564 int old_width
= dpyinfo
->smallest_char_width
;
6565 int old_height
= dpyinfo
->smallest_font_height
;
6567 dpyinfo
->smallest_font_height
= 100000;
6568 dpyinfo
->smallest_char_width
= 100000;
6570 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6571 if (dpyinfo
->font_table
[i
].name
)
6573 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6576 font
= (MacFontStruct
*) fontp
->font
;
6577 xassert (font
!= (MacFontStruct
*) ~0);
6578 x_font_min_bounds (font
, &w
, &h
);
6580 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6581 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6584 xassert (dpyinfo
->smallest_char_width
> 0
6585 && dpyinfo
->smallest_font_height
> 0);
6587 return (dpyinfo
->n_fonts
== 1
6588 || dpyinfo
->smallest_char_width
< old_width
6589 || dpyinfo
->smallest_font_height
< old_height
);
6593 /* Determine whether given string is a fully-specified XLFD: all 14
6594 fields are present, none is '*'. */
6597 is_fully_specified_xlfd (char *p
)
6605 for (i
= 0; i
< 13; i
++)
6607 q
= strchr (p
+ 1, '-');
6610 if (q
- p
== 2 && *(p
+ 1) == '*')
6615 if (strchr (p
+ 1, '-') != NULL
)
6618 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6625 const int kDefaultFontSize
= 9;
6628 /* XLoadQueryFont creates and returns an internal representation for a
6629 font in a MacFontStruct struct. There is really no concept
6630 corresponding to "loading" a font on the Mac. But we check its
6631 existence and find the font number and all other information for it
6632 and store them in the returned MacFontStruct. */
6634 static MacFontStruct
*
6635 XLoadQueryFont (Display
*dpy
, char *fontname
)
6637 int i
, size
, is_two_byte_font
, char_width
;
6640 SInt16 old_fontnum
, old_fontsize
;
6644 Style fontface
= normal
;
6645 MacFontStruct
*font
;
6646 FontInfo the_fontinfo
;
6647 char s_weight
[7], c_slant
;
6649 if (is_fully_specified_xlfd (fontname
))
6653 Lisp_Object matched_fonts
;
6655 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6656 if (NILP (matched_fonts
))
6658 name
= SDATA (XCAR (matched_fonts
));
6661 GetPort (&port
); /* save the current font number used */
6662 #if TARGET_API_MAC_CARBON
6663 old_fontnum
= GetPortTextFont (port
);
6664 old_fontsize
= GetPortTextSize (port
);
6665 old_fontface
= GetPortTextFace (port
);
6667 old_fontnum
= port
->txFont
;
6668 old_fontsize
= port
->txSize
;
6669 old_fontface
= port
->txFace
;
6672 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6673 size
= kDefaultFontSize
;
6675 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6676 if (strcmp (s_weight
, "bold") == 0)
6679 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6683 x_font_name_to_mac_font_name (name
, mfontname
);
6685 GetFNum (mfontname
, &fontnum
);
6689 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6691 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6692 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6694 font
->mac_fontnum
= fontnum
;
6695 font
->mac_fontsize
= size
;
6696 font
->mac_fontface
= fontface
;
6697 font
->mac_scriptcode
= FontToScript (fontnum
);
6699 /* Apple Japanese (SJIS) font is listed as both
6700 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6701 (Roman script) in init_font_name_table (). The latter should be
6702 treated as a one-byte font. */
6707 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6709 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6710 font
->mac_scriptcode
= smRoman
;
6713 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6714 font
->mac_scriptcode
== smTradChinese
||
6715 font
->mac_scriptcode
== smSimpChinese
||
6716 font
->mac_scriptcode
== smKorean
;
6720 TextFace (fontface
);
6722 GetFontInfo (&the_fontinfo
);
6724 font
->ascent
= the_fontinfo
.ascent
;
6725 font
->descent
= the_fontinfo
.descent
;
6727 font
->min_byte1
= 0;
6728 if (is_two_byte_font
)
6729 font
->max_byte1
= 1;
6731 font
->max_byte1
= 0;
6732 font
->min_char_or_byte2
= 0x20;
6733 font
->max_char_or_byte2
= 0xff;
6735 if (is_two_byte_font
)
6737 /* Use the width of an "ideographic space" of that font because
6738 the_fontinfo.widMax returns the wrong width for some fonts. */
6739 switch (font
->mac_scriptcode
)
6742 char_width
= StringWidth("\p\x81\x40");
6745 char_width
= StringWidth("\p\xa1\x40");
6748 char_width
= StringWidth("\p\xa1\xa1");
6751 char_width
= StringWidth("\p\xa1\xa1");
6756 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6757 returns 15 for 12-point Monaco! */
6758 char_width
= CharWidth ('m');
6760 font
->max_bounds
.rbearing
= char_width
;
6761 font
->max_bounds
.lbearing
= 0;
6762 font
->max_bounds
.width
= char_width
;
6763 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6764 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6766 font
->min_bounds
= font
->max_bounds
;
6768 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6769 font
->per_char
= NULL
;
6772 font
->per_char
= (XCharStruct
*)
6773 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6777 for (c
= 0x20; c
<= 0xff; c
++)
6779 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6780 font
->per_char
[c
- 0x20].width
=
6781 font
->per_char
[c
- 0x20].rbearing
= CharWidth (c
);
6786 TextFont (old_fontnum
); /* restore previous font number, size and face */
6787 TextSize (old_fontsize
);
6788 TextFace (old_fontface
);
6794 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6795 pointer to the structure font_info while allocating it dynamically.
6796 If SIZE is 0, load any size of font.
6797 If loading is failed, return NULL. */
6800 x_load_font (f
, fontname
, size
)
6802 register char *fontname
;
6805 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6806 Lisp_Object font_names
;
6808 /* Get a list of all the fonts that match this name. Once we
6809 have a list of matching fonts, we compare them against the fonts
6810 we already have by comparing names. */
6811 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6813 if (!NILP (font_names
))
6818 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6819 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6820 if (dpyinfo
->font_table
[i
].name
6821 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6822 SDATA (XCAR (tail
)))
6823 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6824 SDATA (XCAR (tail
)))))
6825 return (dpyinfo
->font_table
+ i
);
6828 /* Load the font and add it to the table. */
6831 struct MacFontStruct
*font
;
6832 struct font_info
*fontp
;
6833 unsigned long value
;
6836 /* If we have found fonts by x_list_font, load one of them. If
6837 not, we still try to load a font by the name given as FONTNAME
6838 because XListFonts (called in x_list_font) of some X server has
6839 a bug of not finding a font even if the font surely exists and
6840 is loadable by XLoadQueryFont. */
6841 if (size
> 0 && !NILP (font_names
))
6842 fontname
= (char *) SDATA (XCAR (font_names
));
6844 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6848 /* Find a free slot in the font table. */
6849 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6850 if (dpyinfo
->font_table
[i
].name
== NULL
)
6853 /* If no free slot found, maybe enlarge the font table. */
6854 if (i
== dpyinfo
->n_fonts
6855 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6858 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6859 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6861 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6864 fontp
= dpyinfo
->font_table
+ i
;
6865 if (i
== dpyinfo
->n_fonts
)
6868 /* Now fill in the slots of *FONTP. */
6870 bzero (fontp
, sizeof (*fontp
));
6872 fontp
->font_idx
= i
;
6873 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6874 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6876 fontp
->full_name
= fontp
->name
;
6878 fontp
->size
= font
->max_bounds
.width
;
6879 fontp
->height
= FONT_HEIGHT (font
);
6881 /* For some font, ascent and descent in max_bounds field is
6882 larger than the above value. */
6883 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6884 if (max_height
> fontp
->height
)
6885 fontp
->height
= max_height
;
6888 /* The slot `encoding' specifies how to map a character
6889 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6890 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6891 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6892 2:0xA020..0xFF7F). For the moment, we don't know which charset
6893 uses this font. So, we set information in fontp->encoding[1]
6894 which is never used by any charset. If mapping can't be
6895 decided, set FONT_ENCODING_NOT_DECIDED. */
6896 if (font
->mac_scriptcode
== smJapanese
)
6897 fontp
->encoding
[1] = 4;
6901 = (font
->max_byte1
== 0
6903 ? (font
->min_char_or_byte2
< 0x80
6904 ? (font
->max_char_or_byte2
< 0x80
6905 ? 0 /* 0x20..0x7F */
6906 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6907 : 1) /* 0xA0..0xFF */
6909 : (font
->min_byte1
< 0x80
6910 ? (font
->max_byte1
< 0x80
6911 ? (font
->min_char_or_byte2
< 0x80
6912 ? (font
->max_char_or_byte2
< 0x80
6913 ? 0 /* 0x2020..0x7F7F */
6914 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6915 : 3) /* 0x20A0..0x7FFF */
6916 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6917 : (font
->min_char_or_byte2
< 0x80
6918 ? (font
->max_char_or_byte2
< 0x80
6919 ? 2 /* 0xA020..0xFF7F */
6920 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6921 : 1))); /* 0xA0A0..0xFFFF */
6924 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6925 fontp
->baseline_offset
6926 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6927 ? (long) value
: 0);
6928 fontp
->relative_compose
6929 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6930 ? (long) value
: 0);
6931 fontp
->default_ascent
6932 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6933 ? (long) value
: 0);
6935 fontp
->baseline_offset
= 0;
6936 fontp
->relative_compose
= 0;
6937 fontp
->default_ascent
= 0;
6940 /* Set global flag fonts_changed_p to non-zero if the font loaded
6941 has a character with a smaller width than any other character
6942 before, or if the font loaded has a smalle>r height than any
6943 other font loaded before. If this happens, it will make a
6944 glyph matrix reallocation necessary. */
6945 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6952 /* Return a pointer to struct font_info of a font named FONTNAME for
6953 frame F. If no such font is loaded, return NULL. */
6956 x_query_font (f
, fontname
)
6958 register char *fontname
;
6960 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6963 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6964 if (dpyinfo
->font_table
[i
].name
6965 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6966 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6967 return (dpyinfo
->font_table
+ i
);
6972 /* Find a CCL program for a font specified by FONTP, and set the member
6973 `encoder' of the structure. */
6976 x_find_ccl_program (fontp
)
6977 struct font_info
*fontp
;
6979 Lisp_Object list
, elt
;
6981 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6985 && STRINGP (XCAR (elt
))
6986 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6992 struct ccl_program
*ccl
6993 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6995 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6998 fontp
->font_encoder
= ccl
;
7004 /* The Mac Event loop code */
7008 #include <Quickdraw.h>
7009 #include <Balloons.h>
7010 #include <Devices.h>
7012 #include <Gestalt.h>
7014 #include <Processes.h>
7016 #include <ToolUtils.h>
7017 #include <TextUtils.h>
7018 #include <Dialogs.h>
7021 #include <TextEncodingConverter.h>
7022 #include <Resources.h>
7027 #endif /* ! MAC_OSX */
7032 #define WINDOW_RESOURCE 128
7033 #define TERM_WINDOW_RESOURCE 129
7035 #define DEFAULT_NUM_COLS 80
7037 #define MIN_DOC_SIZE 64
7038 #define MAX_DOC_SIZE 32767
7040 /* sleep time for WaitNextEvent */
7041 #define WNE_SLEEP_AT_SUSPEND 10
7042 #define WNE_SLEEP_AT_RESUME 1
7044 /* true when cannot handle any Mac OS events */
7045 static int handling_window_update
= 0;
7048 /* the flag appl_is_suspended is used both for determining the sleep
7049 time to be passed to WaitNextEvent and whether the cursor should be
7050 drawn when updating the display. The cursor is turned off when
7051 Emacs is suspended. Redrawing it is unnecessary and what needs to
7052 be done depends on whether the cursor lies inside or outside the
7053 redraw region. So we might as well skip drawing it when Emacs is
7055 static Boolean app_is_suspended
= false;
7056 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7059 #define EXTRA_STACK_ALLOC (256 * 1024)
7061 #define ARGV_STRING_LIST_ID 129
7062 #define ABOUT_ALERT_ID 128
7063 #define RAM_TOO_LARGE_ALERT_ID 129
7065 Boolean terminate_flag
= false;
7067 /* Contains the string "reverse", which is a constant for mouse button emu.*/
7068 Lisp_Object Qreverse
;
7070 /* True if using command key as meta key. */
7071 Lisp_Object Vmac_command_key_is_meta
;
7073 /* Modifier associated with the option key, or nil for normal behavior. */
7074 Lisp_Object Vmac_option_modifier
;
7076 /* True if the ctrl and meta keys should be reversed. */
7077 Lisp_Object Vmac_reverse_ctrl_meta
;
7079 /* True if the option and command modifiers should be used to emulate
7080 a three button mouse */
7081 Lisp_Object Vmac_emulate_three_button_mouse
;
7083 #if USE_CARBON_EVENTS
7084 /* True if the mouse wheel button (i.e. button 4) should map to
7085 mouse-2, instead of mouse-3. */
7086 Lisp_Object Vmac_wheel_button_is_mouse_2
;
7088 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
7089 for processing before Emacs sees it. */
7090 Lisp_Object Vmac_pass_command_to_system
;
7092 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
7093 for processing before Emacs sees it. */
7094 Lisp_Object Vmac_pass_control_to_system
;
7097 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
7098 to this text encoding */
7099 int mac_keyboard_text_encoding
;
7100 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
7102 /* Set in term/mac-win.el to indicate that event loop can now generate
7103 drag and drop events. */
7104 Lisp_Object Qmac_ready_for_drag_n_drop
;
7106 Lisp_Object drag_and_drop_file_list
;
7108 Point saved_menu_event_location
;
7110 #if !TARGET_API_MAC_CARBON
7111 /* Place holder for the default arrow cursor. */
7112 CursPtr arrow_cursor
;
7116 static void init_required_apple_events (void);
7118 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
7120 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
7121 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
7122 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
7125 static OSErr
init_mac_drag_n_drop ();
7126 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
7128 #if USE_CARBON_EVENTS
7129 /* Preliminary Support for the OSX Services Menu */
7130 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
7131 static void init_service_handler ();
7134 extern void init_emacs_passwd_dir ();
7135 extern int emacs_main (int, char **, char **);
7136 extern void check_alarm ();
7138 extern void initialize_applescript();
7139 extern void terminate_applescript();
7142 #if USE_CARBON_EVENTS
7143 mac_to_emacs_modifiers (UInt32 mods
)
7145 mac_to_emacs_modifiers (EventModifiers mods
)
7148 unsigned int result
= 0;
7149 if (mods
& macShiftKey
)
7150 result
|= shift_modifier
;
7151 if (mods
& macCtrlKey
)
7152 result
|= ctrl_modifier
;
7153 if (mods
& macMetaKey
)
7154 result
|= meta_modifier
;
7155 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
7156 result
|= alt_modifier
;
7157 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
7158 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
7160 result
|= XUINT(val
);
7167 mac_get_emulated_btn ( UInt32 modifiers
)
7170 if (!NILP (Vmac_emulate_three_button_mouse
)) {
7171 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
7172 if (modifiers
& cmdKey
)
7173 result
= cmdIs3
? 2 : 1;
7174 else if (modifiers
& optionKey
)
7175 result
= cmdIs3
? 1 : 2;
7180 #if USE_CARBON_EVENTS
7181 /* Obtains the event modifiers from the event ref and then calls
7182 mac_to_emacs_modifiers. */
7184 mac_event_to_emacs_modifiers (EventRef eventRef
)
7187 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7188 sizeof (UInt32
), NULL
, &mods
);
7189 if (!NILP (Vmac_emulate_three_button_mouse
) &&
7190 GetEventClass(eventRef
) == kEventClassMouse
)
7192 mods
&= ~(optionKey
| cmdKey
);
7194 return mac_to_emacs_modifiers (mods
);
7197 /* Given an event ref, return the code to use for the mouse button
7198 code in the emacs input_event. */
7200 mac_get_mouse_btn (EventRef ref
)
7202 EventMouseButton result
= kEventMouseButtonPrimary
;
7203 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7204 sizeof (EventMouseButton
), NULL
, &result
);
7207 case kEventMouseButtonPrimary
:
7208 if (NILP (Vmac_emulate_three_button_mouse
))
7212 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7213 sizeof (UInt32
), NULL
, &mods
);
7214 return mac_get_emulated_btn(mods
);
7216 case kEventMouseButtonSecondary
:
7217 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7218 case kEventMouseButtonTertiary
:
7219 case 4: /* 4 is the number for the mouse wheel button */
7220 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7226 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7227 events. However the click of the mouse wheel is not converted to a
7228 mouseDown or mouseUp event. This calls ConvertEventRef, but then
7229 checks to see if it is a mouse up or down carbon event that has not
7230 been converted, and if so, converts it by hand (to be picked up in
7231 the XTread_socket loop). */
7232 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7234 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7235 /* Do special case for mouse wheel button. */
7236 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
7238 UInt32 kind
= GetEventKind (eventRef
);
7239 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
7241 eventRec
->what
= mouseDown
;
7244 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
7246 eventRec
->what
= mouseUp
;
7251 /* Need where and when. */
7253 GetEventParameter (eventRef
, kEventParamMouseLocation
,
7254 typeQDPoint
, NULL
, sizeof (Point
),
7255 NULL
, &eventRec
->where
);
7256 /* Use two step process because new event modifiers are
7257 32-bit and old are 16-bit. Currently, only loss is
7259 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
7260 typeUInt32
, NULL
, sizeof (UInt32
),
7262 eventRec
->modifiers
= mods
;
7264 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7275 Handle menubar_handle
;
7276 MenuHandle menu_handle
;
7278 menubar_handle
= GetNewMBar (128);
7279 if(menubar_handle
== NULL
)
7281 SetMenuBar (menubar_handle
);
7284 menu_handle
= GetMenuHandle (M_APPLE
);
7285 if(menu_handle
!= NULL
)
7286 AppendResMenu (menu_handle
,'DRVR');
7293 do_init_managers (void)
7295 #if !TARGET_API_MAC_CARBON
7296 InitGraf (&qd
.thePort
);
7298 FlushEvents (everyEvent
, 0);
7303 #endif /* !TARGET_API_MAC_CARBON */
7306 #if !TARGET_API_MAC_CARBON
7307 arrow_cursor
= &qd
.arrow
;
7309 /* set up some extra stack space for use by emacs */
7310 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7312 /* MaxApplZone must be called for AppleScript to execute more
7313 complicated scripts */
7316 #endif /* !TARGET_API_MAC_CARBON */
7320 do_check_ram_size (void)
7322 SInt32 physical_ram_size
, logical_ram_size
;
7324 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7325 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7326 || physical_ram_size
> (1 << VALBITS
)
7327 || logical_ram_size
> (1 << VALBITS
))
7329 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7335 do_window_update (WindowPtr win
)
7337 struct frame
*f
= mac_window_to_frame (win
);
7339 if (win
== tip_window
)
7340 /* The tooltip has been drawn already. Avoid the
7341 SET_FRAME_GARBAGED below. */
7346 if (f
->async_visible
== 0)
7348 f
->async_visible
= 1;
7349 f
->async_iconified
= 0;
7350 SET_FRAME_GARBAGED (f
);
7352 /* An update event is equivalent to MapNotify on X, so report
7353 visibility changes properly. */
7354 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7355 /* Force a redisplay sooner or later to update the
7356 frame titles in case this is the second frame. */
7357 record_asynch_buffer_change ();
7362 handling_window_update
= 1;
7364 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
7366 expose_frame (f
, 0, 0, 0, 0);
7368 handling_window_update
= 0;
7375 is_emacs_window (WindowPtr win
)
7377 Lisp_Object tail
, frame
;
7382 FOR_EACH_FRAME (tail
, frame
)
7383 if (FRAME_MAC_P (XFRAME (frame
)))
7384 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7393 /* Window-activate events will do the job. */
7398 wp
= front_emacs_window ();
7401 f
= mac_window_to_frame (wp
);
7405 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7406 activate_scroll_bars (f
);
7410 app_is_suspended
= false;
7411 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7418 /* Window-deactivate events will do the job. */
7423 wp
= front_emacs_window ();
7426 f
= mac_window_to_frame (wp
);
7428 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7430 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7431 deactivate_scroll_bars (f
);
7435 app_is_suspended
= true;
7436 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
7442 do_mouse_moved (mouse_pos
, f
)
7446 WindowPtr wp
= front_emacs_window ();
7447 struct x_display_info
*dpyinfo
;
7451 *f
= mac_window_to_frame (wp
);
7452 dpyinfo
= FRAME_MAC_DISPLAY_INFO (*f
);
7454 if (dpyinfo
->mouse_face_hidden
)
7456 dpyinfo
->mouse_face_hidden
= 0;
7457 clear_mouse_face (dpyinfo
);
7460 SetPortWindowPort (wp
);
7462 GlobalToLocal (&mouse_pos
);
7464 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
7465 x_scroll_bar_note_movement (tracked_scroll_bar
,
7467 - XINT (tracked_scroll_bar
->top
),
7468 TickCount() * (1000 / 60));
7470 note_mouse_movement (*f
, &mouse_pos
);
7476 do_apple_menu (SInt16 menu_item
)
7478 #if !TARGET_API_MAC_CARBON
7480 SInt16 da_driver_refnum
;
7482 if (menu_item
== I_ABOUT
)
7483 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7486 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7487 da_driver_refnum
= OpenDeskAcc (item_name
);
7489 #endif /* !TARGET_API_MAC_CARBON */
7493 do_menu_choice (SInt32 menu_choice
)
7495 SInt16 menu_id
, menu_item
;
7497 menu_id
= HiWord (menu_choice
);
7498 menu_item
= LoWord (menu_choice
);
7506 do_apple_menu (menu_item
);
7511 struct frame
*f
= mac_window_to_frame (front_emacs_window ());
7512 MenuHandle menu
= GetMenuHandle (menu_id
);
7517 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7518 menubar_selection_callback (f
, refcon
);
7527 /* Handle drags in size box. Based on code contributed by Ben
7528 Mesander and IM - Window Manager A. */
7531 do_grow_window (WindowPtr w
, EventRecord
*e
)
7536 struct frame
*f
= mac_window_to_frame (w
);
7538 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7540 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7542 /* see if it really changed size */
7545 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7546 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7548 x_set_window_size (f
, 0, columns
, rows
);
7553 /* Handle clicks in zoom box. Calculation of "standard state" based
7554 on code in IM - Window Manager A and code contributed by Ben
7555 Mesander. The standard state of an Emacs window is 80-characters
7556 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7559 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7562 Rect zoom_rect
, port_rect
;
7564 int w_title_height
, columns
, rows
;
7565 struct frame
*f
= mac_window_to_frame (w
);
7567 #if TARGET_API_MAC_CARBON
7569 Point standard_size
;
7571 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7572 standard_size
.v
= FRAME_MAC_DISPLAY_INFO (f
)->height
;
7574 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
7575 zoom_in_or_out
= inZoomIn
;
7578 /* Adjust the standard size according to character boundaries. */
7580 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
7581 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7582 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
7583 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7584 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
7585 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
7586 && port_rect
.left
== zoom_rect
.left
7587 && port_rect
.top
== zoom_rect
.top
)
7588 zoom_in_or_out
= inZoomIn
;
7590 zoom_in_or_out
= inZoomOut
;
7593 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
7595 #else /* not TARGET_API_MAC_CARBON */
7596 GetPort (&save_port
);
7598 SetPortWindowPort (w
);
7600 /* Clear window to avoid flicker. */
7601 EraseRect (&(w
->portRect
));
7602 if (zoom_in_or_out
== inZoomOut
)
7604 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7605 LocalToGlobal (&top_left
);
7607 /* calculate height of window's title bar */
7608 w_title_height
= top_left
.v
- 1
7609 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7611 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7612 zoom_rect
= qd
.screenBits
.bounds
;
7613 zoom_rect
.top
+= w_title_height
;
7614 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7616 zoom_rect
.right
= zoom_rect
.left
7617 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7619 /* Adjust the standard size according to character boundaries. */
7620 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7622 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7624 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7628 ZoomWindow (w
, zoom_in_or_out
, w
== front_emacs_window ());
7630 SetPort (save_port
);
7631 #endif /* not TARGET_API_MAC_CARBON */
7633 /* retrieve window size and update application values */
7634 #if TARGET_API_MAC_CARBON
7635 GetWindowPortBounds (w
, &port_rect
);
7637 port_rect
= w
->portRect
;
7639 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7640 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7641 x_set_window_size (f
, 0, columns
, rows
);
7642 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
7645 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7647 init_mac_drag_n_drop ()
7649 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7653 /* Intialize AppleEvent dispatcher table for the required events. */
7655 init_required_apple_events ()
7660 /* Make sure we have apple events before starting. */
7661 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7665 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7668 #if TARGET_API_MAC_CARBON
7669 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7670 NewAEEventHandlerUPP
7671 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7674 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7675 NewAEEventHandlerProc
7676 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7682 #if TARGET_API_MAC_CARBON
7683 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7684 NewAEEventHandlerUPP
7685 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7688 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7689 NewAEEventHandlerProc
7690 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7696 #if TARGET_API_MAC_CARBON
7697 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7698 NewAEEventHandlerUPP
7699 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7702 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7703 NewAEEventHandlerProc
7704 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7710 #if TARGET_API_MAC_CARBON
7711 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7712 NewAEEventHandlerUPP
7713 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7716 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7717 NewAEEventHandlerProc
7718 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7725 #if USE_CARBON_EVENTS
7728 init_service_handler ()
7730 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7731 {kEventClassService
, kEventServiceCopy
},
7732 {kEventClassService
, kEventServicePaste
}};
7733 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7734 3, specs
, NULL
, NULL
);
7738 MAC_TODO: Check to see if this is called by AEProcessDesc...
7741 mac_handle_service_event (EventHandlerCallRef callRef
,
7742 EventRef event
, void *data
)
7744 OSStatus err
= noErr
;
7745 switch (GetEventKind (event
))
7747 case kEventServiceGetTypes
:
7749 CFMutableArrayRef copyTypes
, pasteTypes
;
7751 Boolean selection
= true;
7753 GetEventParameter(event, kEventParamServicePasteTypes,
7754 typeCFMutableArrayRef, NULL,
7755 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7757 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7758 typeCFMutableArrayRef
, NULL
,
7759 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7760 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7762 CFArrayAppendValue (copyTypes
, type
);
7763 //CFArrayAppendValue (pasteTypes, type);
7767 case kEventServiceCopy
:
7769 ScrapRef currentScrap
, specificScrap
;
7773 GetCurrentScrap (¤tScrap
);
7775 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7778 void *buffer
= xmalloc (byteCount
);
7781 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7782 sizeof (ScrapRef
), NULL
, &specificScrap
);
7784 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7785 &byteCount
, buffer
);
7787 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7788 kScrapFlavorMaskNone
, byteCount
, buffer
);
7794 case kEventServicePaste
:
7797 // Get the current location
7799 ScrapRef specificScrap;
7800 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7801 sizeof(ScrapRef), NULL, &specificScrap);
7802 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7804 void * buffer = xmalloc(byteCount);
7805 if (buffer != NULL ) {
7806 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7807 &byteCount, buffer);
7809 // Actually place in the buffer
7811 // Get the current "selection" string here
7824 /* Open Application Apple Event */
7826 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7832 /* Defined in mac.c. */
7834 path_from_vol_dir_name (char *, int, short, long, char *);
7837 /* Called when we receive an AppleEvent with an ID of
7838 "kAEOpenDocuments". This routine gets the direct parameter,
7839 extracts the FSSpecs in it, and puts their names on a list. */
7841 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7846 DescType actual_type
;
7849 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7851 goto descriptor_error_exit
;
7853 /* Check to see that we got all of the required parameters from the
7854 event descriptor. For an 'odoc' event this should just be the
7856 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7857 &actual_type
, (Ptr
) &keyword
,
7858 sizeof (keyword
), &actual_size
);
7859 /* No error means that we found some unused parameters.
7860 errAEDescNotFound means that there are no more parameters. If we
7861 get an error code other than that, flag it. */
7862 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7864 err
= errAEEventNotHandled
;
7869 /* Got all the parameters we need. Now, go through the direct
7870 object list and parse it up. */
7872 long num_files_to_open
;
7874 err
= AECountItems (&the_desc
, &num_files_to_open
);
7879 /* AE file list is one based so just use that for indexing here. */
7880 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7883 Str255 path_name
, unix_path_name
;
7888 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7889 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7890 if (err
!= noErr
) break;
7893 err
= FSpMakeFSRef (&fs
, &fref
);
7894 if (err
!= noErr
) break;
7896 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7898 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7900 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7902 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7903 drag_and_drop_file_list
);
7909 /* Nuke the coerced file list in any case */
7910 err2
= AEDisposeDesc(&the_desc
);
7912 descriptor_error_exit
:
7913 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7919 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7920 DragReference theDrag
)
7924 FlavorFlags theFlags
;
7927 ItemReference theItem
;
7930 Size size
= sizeof (HFSFlavor
);
7932 drag_and_drop_file_list
= Qnil
;
7933 GetDragMouse (theDrag
, &mouse
, 0L);
7934 CountDragItems (theDrag
, &items
);
7935 for (index
= 1; index
<= items
; index
++)
7937 /* Only handle file references. */
7938 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7939 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7940 if (result
== noErr
)
7947 Str255 unix_path_name
;
7948 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7950 /* Use Carbon routines, otherwise it converts the file name
7951 to /Macintosh HD/..., which is not correct. */
7952 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7953 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7955 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7956 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7957 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7959 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7960 drag_and_drop_file_list
);
7965 /* If there are items in the list, construct an event and post it to
7966 the queue like an interrupt using kbd_buffer_store_event. */
7967 if (!NILP (drag_and_drop_file_list
))
7969 struct input_event event
;
7971 struct frame
*f
= mac_window_to_frame (window
);
7972 SetPortWindowPort (window
);
7973 GlobalToLocal (&mouse
);
7975 event
.kind
= DRAG_N_DROP_EVENT
;
7977 event
.modifiers
= 0;
7978 event
.timestamp
= TickCount () * (1000 / 60);
7979 XSETINT (event
.x
, mouse
.h
);
7980 XSETINT (event
.y
, mouse
.v
);
7981 XSETFRAME (frame
, f
);
7982 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7984 /* Post to the interrupt queue */
7985 kbd_buffer_store_event (&event
);
7986 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7988 ProcessSerialNumber psn
;
7989 GetCurrentProcess (&psn
);
7990 SetFrontProcess (&psn
);
7996 /* Print Document Apple Event */
7998 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
8000 return errAEEventNotHandled
;
8005 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
8007 /* FixMe: Do we need an unwind-protect or something here? And what
8008 do we do about unsaved files. Currently just forces quit rather
8009 than doing recursive callback to get user input. */
8011 terminate_flag
= true;
8013 /* Fkill_emacs doesn't return. We have to return. (TI) */
8020 profiler_exit_proc ()
8022 ProfilerDump ("\pEmacs.prof");
8027 /* These few functions implement Emacs as a normal Mac application
8028 (almost): set up the heap and the Toolbox, handle necessary
8029 system events plus a few simple menu events. They also set up
8030 Emacs's access to functions defined in the rest of this file.
8031 Emacs uses function hooks to perform all its terminal I/O. A
8032 complete list of these functions appear in termhooks.h. For what
8033 they do, read the comments there and see also w32term.c and
8034 xterm.c. What's noticeably missing here is the event loop, which
8035 is normally present in most Mac application. After performing the
8036 necessary Mac initializations, main passes off control to
8037 emacs_main (corresponding to main in emacs.c). Emacs_main calls
8038 mac_read_socket (defined further below) to read input. This is
8039 where WaitNextEvent is called to process Mac events. This is also
8040 where check_alarm in sysdep.c is called to simulate alarm signals.
8041 This makes the cursor jump back to its correct position after
8042 briefly jumping to that of the matching parenthesis, print useful
8043 hints and prompts in the minibuffer after the user stops typing for
8046 #if !TARGET_API_MAC_CARBON
8051 #if __profile__ /* is the profiler on? */
8052 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
8057 /* set creator and type for files created by MSL */
8062 do_init_managers ();
8067 do_check_ram_size ();
8070 init_emacs_passwd_dir ();
8074 initialize_applescript ();
8076 init_required_apple_events ();
8082 /* set up argv array from STR# resource */
8083 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8087 /* free up AppleScript resources on exit */
8088 atexit (terminate_applescript
);
8090 #if __profile__ /* is the profiler on? */
8091 atexit (profiler_exit_proc
);
8094 /* 3rd param "envp" never used in emacs_main */
8095 (void) emacs_main (argc
, argv
, 0);
8098 /* Never reached - real exit in Fkill_emacs */
8103 /* Table for translating Mac keycode to X keysym values. Contributed
8104 by Sudhir Shenoy. */
8105 static unsigned char keycode_to_xkeysym_table
[] = {
8106 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8107 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8108 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8110 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8111 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
8112 /*0x38*/ 0, 0, 0, 0,
8113 /*0x3C*/ 0, 0, 0, 0,
8115 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8116 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
8117 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8118 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8120 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8121 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8122 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8123 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8125 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8126 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8127 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8128 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
8130 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
8131 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
8132 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8133 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8137 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8139 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8140 return *xKeySym
!= 0;
8143 /* Emacs calls this whenever it wants to read an input event from the
8146 XTread_socket (sd
, expected
, hold_quit
)
8148 struct input_event
*hold_quit
;
8150 struct input_event inev
;
8152 #if USE_CARBON_EVENTS
8154 EventTargetRef toolbox_dispatcher
= GetEventDispatcherTarget ();
8156 EventMask event_mask
;
8159 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8161 if (interrupt_input_blocked
)
8163 interrupt_input_pending
= 1;
8167 interrupt_input_pending
= 0;
8170 /* So people can tell when we have read the available input. */
8171 input_signal_count
++;
8173 /* Don't poll for events to process (specifically updateEvt) if
8174 window update currently already in progress. A call to redisplay
8175 (in do_window_update) can be preempted by another call to
8176 redisplay, causing blank regions to be left on the screen and the
8177 cursor to be left at strange places. */
8178 if (handling_window_update
)
8185 Fkill_emacs (make_number (1));
8187 #if !USE_CARBON_EVENTS
8188 event_mask
= everyEvent
;
8189 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8190 event_mask
-= highLevelEventMask
;
8192 while (WaitNextEvent (event_mask
, &er
, 0L, NULL
))
8193 #else /* USE_CARBON_EVENTS */
8194 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
8195 kEventRemoveFromQueue
, &eventRef
))
8196 #endif /* USE_CARBON_EVENTS */
8201 /* It is necessary to set this (additional) argument slot of an
8202 event to nil because keyboard.c protects incompletely
8203 processed event from being garbage collected by placing them
8204 in the kbd_buffer_gcpro vector. */
8206 inev
.kind
= NO_EVENT
;
8209 #if USE_CARBON_EVENTS
8210 /* Handle new events */
8211 if (!mac_convert_event_ref (eventRef
, &er
))
8212 switch (GetEventClass (eventRef
))
8214 case kEventClassWindow
:
8215 if (GetEventKind (eventRef
) == kEventWindowBoundsChanged
)
8217 WindowPtr window_ptr
;
8218 GetEventParameter(eventRef
, kEventParamDirectObject
,
8219 typeWindowRef
, NULL
, sizeof(WindowPtr
),
8221 f
= mac_window_to_frame (window_ptr
);
8222 if (f
&& !f
->async_iconified
)
8223 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8224 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8227 case kEventClassMouse
:
8228 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
8232 WindowPtr window_ptr
= front_emacs_window ();
8234 if (!IsValidWindowPtr (window_ptr
))
8240 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
8241 typeSInt32
, NULL
, sizeof (SInt32
),
8243 GetEventParameter(eventRef
, kEventParamMouseLocation
,
8244 typeQDPoint
, NULL
, sizeof (Point
),
8246 inev
.kind
= WHEEL_EVENT
;
8248 inev
.modifiers
= (mac_event_to_emacs_modifiers (eventRef
)
8249 | ((delta
< 0) ? down_modifier
8251 SetPortWindowPort (window_ptr
);
8252 GlobalToLocal (&point
);
8253 XSETINT (inev
.x
, point
.h
);
8254 XSETINT (inev
.y
, point
.v
);
8255 XSETFRAME (inev
.frame_or_window
,
8256 mac_window_to_frame (window_ptr
));
8257 inev
.timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
8260 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8264 /* Send the event to the appropriate receiver. */
8265 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8268 #endif /* USE_CARBON_EVENTS */
8274 WindowPtr window_ptr
;
8278 #if USE_CARBON_EVENTS
8279 /* This is needed to send mouse events like aqua window
8280 buttons to the correct handler. */
8281 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8282 != eventNotHandledErr
)
8286 if (dpyinfo
->grabbed
&& last_mouse_frame
8287 && FRAME_LIVE_P (last_mouse_frame
))
8289 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
8290 part_code
= inContent
;
8294 part_code
= FindWindow (er
.where
, &window_ptr
);
8295 if (tip_window
&& window_ptr
== tip_window
)
8297 HideWindow (tip_window
);
8298 part_code
= FindWindow (er
.where
, &window_ptr
);
8302 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
8308 f
= mac_window_to_frame (front_emacs_window ());
8309 saved_menu_event_location
= er
.where
;
8310 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8311 XSETFRAME (inev
.frame_or_window
, f
);
8315 if (window_ptr
!= front_emacs_window ())
8316 SelectWindow (window_ptr
);
8319 SInt16 control_part_code
;
8321 Point mouse_loc
= er
.where
;
8323 f
= mac_window_to_frame (window_ptr
);
8324 /* convert to local coordinates of new window */
8325 SetPortWindowPort (window_ptr
);
8327 GlobalToLocal (&mouse_loc
);
8328 #if TARGET_API_MAC_CARBON
8329 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8330 &control_part_code
);
8332 control_part_code
= FindControl (mouse_loc
, window_ptr
,
8336 #if USE_CARBON_EVENTS
8337 inev
.code
= mac_get_mouse_btn (eventRef
);
8338 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8340 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
8341 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8343 XSETINT (inev
.x
, mouse_loc
.h
);
8344 XSETINT (inev
.y
, mouse_loc
.v
);
8345 inev
.timestamp
= er
.when
* (1000 / 60);
8346 /* ticks to milliseconds */
8348 if (dpyinfo
->grabbed
&& tracked_scroll_bar
8349 #if TARGET_API_MAC_CARBON
8352 || control_part_code
!= 0
8356 struct scroll_bar
*bar
;
8358 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
8360 bar
= tracked_scroll_bar
;
8361 control_part_code
= kControlIndicatorPart
;
8364 bar
= (struct scroll_bar
*) GetControlReference (ch
);
8365 x_scroll_bar_handle_click (bar
, control_part_code
,
8367 if (er
.what
== mouseDown
8368 && control_part_code
== kControlIndicatorPart
)
8369 tracked_scroll_bar
= bar
;
8371 tracked_scroll_bar
= NULL
;
8376 int x
= mouse_loc
.h
;
8377 int y
= mouse_loc
.v
;
8379 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
8380 if (EQ (window
, f
->tool_bar_window
))
8382 if (er
.what
== mouseDown
)
8383 handle_tool_bar_click (f
, x
, y
, 1, 0);
8385 handle_tool_bar_click (f
, x
, y
, 0,
8391 XSETFRAME (inev
.frame_or_window
, f
);
8392 inev
.kind
= MOUSE_CLICK_EVENT
;
8396 if (er
.what
== mouseDown
)
8398 dpyinfo
->grabbed
|= (1 << inev
.code
);
8399 last_mouse_frame
= f
;
8400 /* Ignore any mouse motion that happened
8401 before this event; any subsequent
8402 mouse-movement Emacs events should reflect
8403 only motion after the ButtonPress. */
8408 last_tool_bar_item
= -1;
8412 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
8413 /* If a button is released though it was not
8414 previously pressed, that would be because
8415 of multi-button emulation. */
8416 dpyinfo
->grabbed
= 0;
8418 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
8424 inev
.modifiers
|= down_modifier
;
8427 inev
.modifiers
|= up_modifier
;
8434 #if TARGET_API_MAC_CARBON
8435 DragWindow (window_ptr
, er
.where
, NULL
);
8436 #else /* not TARGET_API_MAC_CARBON */
8437 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
8438 #endif /* not TARGET_API_MAC_CARBON */
8439 /* Update the frame parameters. */
8441 struct frame
*f
= mac_window_to_frame (window_ptr
);
8443 if (f
&& !f
->async_iconified
)
8444 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8449 if (TrackGoAway (window_ptr
, er
.where
))
8451 inev
.kind
= DELETE_WINDOW_EVENT
;
8452 XSETFRAME (inev
.frame_or_window
,
8453 mac_window_to_frame (window_ptr
));
8457 /* window resize handling added --ben */
8459 do_grow_window (window_ptr
, &er
);
8462 /* window zoom handling added --ben */
8465 if (TrackBox (window_ptr
, er
.where
, part_code
))
8466 do_zoom_window (window_ptr
, part_code
);
8476 #if USE_CARBON_EVENTS
8477 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8478 != eventNotHandledErr
)
8481 do_window_update ((WindowPtr
) er
.message
);
8485 #if USE_CARBON_EVENTS
8486 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8487 != eventNotHandledErr
)
8490 switch ((er
.message
>> 24) & 0x000000FF)
8492 case suspendResumeMessage
:
8493 if ((er
.message
& resumeFlag
) == 1)
8499 case mouseMovedMessage
:
8500 previous_help_echo_string
= help_echo_string
;
8501 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
8504 do_mouse_moved (er
.where
, &f
);
8506 /* If the contents of the global variable
8507 help_echo_string has changed, generate a
8509 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
8517 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
8519 #if USE_CARBON_EVENTS
8520 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8521 != eventNotHandledErr
)
8524 if (window_ptr
== tip_window
)
8526 HideWindow (tip_window
);
8530 if (!is_emacs_window (window_ptr
))
8533 f
= mac_window_to_frame (window_ptr
);
8535 if ((er
.modifiers
& activeFlag
) != 0)
8537 /* A window has been activated */
8538 Point mouse_loc
= er
.where
;
8540 x_new_focus_frame (dpyinfo
, f
);
8541 activate_scroll_bars (f
);
8543 SetPortWindowPort (window_ptr
);
8544 GlobalToLocal (&mouse_loc
);
8545 /* Window-activated event counts as mouse movement,
8546 so update things that depend on mouse position. */
8547 note_mouse_movement (mac_window_to_frame (window_ptr
),
8552 /* A window has been deactivated */
8553 dpyinfo
->grabbed
= 0;
8555 if (f
== dpyinfo
->x_focus_frame
)
8557 x_new_focus_frame (dpyinfo
, 0);
8558 deactivate_scroll_bars (f
);
8562 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8564 /* If we move outside the frame, then we're
8565 certainly no longer on any text in the
8567 clear_mouse_face (dpyinfo
);
8568 dpyinfo
->mouse_face_mouse_frame
= 0;
8571 /* Generate a nil HELP_EVENT to cancel a help-echo.
8572 Do it only if there's something to cancel.
8573 Otherwise, the startup message is cleared when the
8574 mouse leaves the frame. */
8575 if (any_help_event_p
)
8584 int keycode
= (er
.message
& keyCodeMask
) >> 8;
8587 #if USE_CARBON_EVENTS
8588 /* When using Carbon Events, we need to pass raw keyboard
8589 events to the TSM ourselves. If TSM handles it, it
8590 will pass back noErr, otherwise it will pass back
8591 "eventNotHandledErr" and we can process it
8593 if ((!NILP (Vmac_pass_command_to_system
)
8594 || !(er
.modifiers
& cmdKey
))
8595 && (!NILP (Vmac_pass_control_to_system
)
8596 || !(er
.modifiers
& controlKey
)))
8597 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8598 != eventNotHandledErr
)
8602 #if TARGET_API_MAC_CARBON
8603 if (!IsValidWindowPtr (front_emacs_window ()))
8612 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8614 clear_mouse_face (dpyinfo
);
8615 dpyinfo
->mouse_face_hidden
= 1;
8618 if (keycode_to_xkeysym (keycode
, &xkeysym
))
8620 inev
.code
= 0xff00 | xkeysym
;
8621 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
8625 if (er
.modifiers
& (controlKey
|
8626 (NILP (Vmac_command_key_is_meta
) ? optionKey
8629 /* This code comes from Keyboard Resource,
8630 Appendix C of IM - Text. This is necessary
8631 since shift is ignored in KCHR table
8632 translation when option or command is pressed.
8633 It also does not translate correctly
8634 control-shift chars like C-% so mask off shift
8636 int new_modifiers
= er
.modifiers
& 0xe600;
8637 /* mask off option and command */
8638 int new_keycode
= keycode
| new_modifiers
;
8639 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8640 unsigned long some_state
= 0;
8641 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8642 &some_state
) & 0xff;
8643 } else if (!NILP(Vmac_option_modifier
) && (er
.modifiers
& optionKey
))
8645 /* When using the option key as an emacs modifier, convert
8646 the pressed key code back to one without the Mac option
8647 modifier applied. */
8648 int new_modifiers
= er
.modifiers
& ~optionKey
;
8649 int new_keycode
= keycode
| new_modifiers
;
8650 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8651 unsigned long some_state
= 0;
8652 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8653 &some_state
) & 0xff;
8656 inev
.code
= er
.message
& charCodeMask
;
8657 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
8661 /* If variable mac-convert-keyboard-input-to-latin-1 is
8662 non-nil, convert non-ASCII characters typed at the Mac
8663 keyboard (presumed to be in the Mac Roman encoding) to
8664 iso-latin-1 encoding before they are passed to Emacs.
8665 This enables the Mac keyboard to be used to enter
8666 non-ASCII iso-latin-1 characters directly. */
8667 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8668 && inev
.kind
== ASCII_KEYSTROKE_EVENT
&& inev
.code
>= 128)
8670 static TECObjectRef converter
= NULL
;
8671 OSStatus the_err
= noErr
;
8672 OSStatus convert_status
= noErr
;
8674 if (converter
== NULL
)
8676 the_err
= TECCreateConverter (&converter
,
8677 kTextEncodingMacRoman
,
8678 mac_keyboard_text_encoding
);
8679 current_mac_keyboard_text_encoding
8680 = mac_keyboard_text_encoding
;
8682 else if (mac_keyboard_text_encoding
8683 != current_mac_keyboard_text_encoding
)
8685 /* Free the converter for the current encoding
8686 before creating a new one. */
8687 TECDisposeConverter (converter
);
8688 the_err
= TECCreateConverter (&converter
,
8689 kTextEncodingMacRoman
,
8690 mac_keyboard_text_encoding
);
8691 current_mac_keyboard_text_encoding
8692 = mac_keyboard_text_encoding
;
8695 if (the_err
== noErr
)
8697 unsigned char ch
= inev
.code
;
8698 ByteCount actual_input_length
, actual_output_length
;
8699 unsigned char outbuf
[32];
8701 convert_status
= TECConvertText (converter
, &ch
, 1,
8702 &actual_input_length
,
8704 &actual_output_length
);
8705 if (convert_status
== noErr
8706 && actual_input_length
== 1
8707 && actual_output_length
== 1)
8708 inev
.code
= *outbuf
;
8710 /* Reset internal states of the converter object.
8711 If it fails, create another one. */
8712 convert_status
= TECFlushText (converter
, outbuf
,
8714 &actual_output_length
);
8715 if (convert_status
!= noErr
)
8717 TECDisposeConverter (converter
);
8718 TECCreateConverter (&converter
,
8719 kTextEncodingMacRoman
,
8720 mac_keyboard_text_encoding
);
8725 #if USE_CARBON_EVENTS
8726 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8728 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8730 XSETFRAME (inev
.frame_or_window
,
8731 mac_window_to_frame (front_emacs_window ()));
8732 inev
.timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8735 case kHighLevelEvent
:
8736 drag_and_drop_file_list
= Qnil
;
8738 AEProcessAppleEvent(&er
);
8740 /* Build a DRAG_N_DROP_EVENT type event as is done in
8741 constuct_drag_n_drop in w32term.c. */
8742 if (!NILP (drag_and_drop_file_list
))
8744 struct frame
*f
= NULL
;
8748 wp
= front_emacs_window ();
8752 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8753 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8754 wp
= front_emacs_window ();
8758 f
= mac_window_to_frame (wp
);
8760 inev
.kind
= DRAG_N_DROP_EVENT
;
8762 inev
.timestamp
= er
.when
* (1000 / 60);
8763 /* ticks to milliseconds */
8764 #if USE_CARBON_EVENTS
8765 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8767 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8770 XSETINT (inev
.x
, 0);
8771 XSETINT (inev
.y
, 0);
8773 XSETFRAME (frame
, f
);
8774 inev
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8776 /* Regardless of whether Emacs was suspended or in the
8777 foreground, ask it to redraw its entire screen.
8778 Otherwise parts of the screen can be left in an
8779 inconsistent state. */
8781 #if TARGET_API_MAC_CARBON
8785 GetWindowPortBounds (wp
, &r
);
8786 InvalWindowRect (wp
, &r
);
8788 #else /* not TARGET_API_MAC_CARBON */
8789 InvalRect (&(wp
->portRect
));
8790 #endif /* not TARGET_API_MAC_CARBON */
8795 #if USE_CARBON_EVENTS
8796 ReleaseEvent (eventRef
);
8799 if (inev
.kind
!= NO_EVENT
)
8801 kbd_buffer_store_event_hold (&inev
, hold_quit
);
8806 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
8811 XSETFRAME (frame
, f
);
8817 any_help_event_p
= 1;
8818 gen_help_event (help_echo_string
, frame
, help_echo_window
,
8819 help_echo_object
, help_echo_pos
);
8823 help_echo_string
= Qnil
;
8824 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
8831 /* If the focus was just given to an autoraising frame,
8833 /* ??? This ought to be able to handle more than one such frame. */
8834 if (pending_autoraise_frame
)
8836 x_raise_frame (pending_autoraise_frame
);
8837 pending_autoraise_frame
= 0;
8840 #if !TARGET_API_MAC_CARBON
8841 check_alarm (); /* simulate the handling of a SIGALRM */
8849 /* Need to override CodeWarrior's input function so no conversion is
8850 done on newlines Otherwise compiled functions in .elc files will be
8851 read incorrectly. Defined in ...:MSL C:MSL
8852 Common:Source:buffer_io.c. */
8855 __convert_to_newlines (unsigned char * p
, size_t * n
)
8861 __convert_from_newlines (unsigned char * p
, size_t * n
)
8868 /* Initialize the struct pointed to by MW to represent a new COLS x
8869 ROWS Macintosh window, using font with name FONTNAME and size
8872 make_mac_frame (FRAME_PTR fp
)
8875 #if TARGET_API_MAC_CARBON
8876 static int making_terminal_window
= 0;
8878 static int making_terminal_window
= 1;
8881 mwp
= fp
->output_data
.mac
;
8884 if (making_terminal_window
)
8886 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8889 making_terminal_window
= 0;
8893 #if TARGET_API_MAC_CARBON
8896 SetRect (&r
, 0, 0, 1, 1);
8897 if (CreateNewWindow (kDocumentWindowClass
,
8898 kWindowStandardDocumentAttributes
8899 /* | kWindowToolbarButtonAttribute */,
8900 &r
, &mwp
->mWP
) != noErr
)
8902 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8907 SetWRefCon (mwp
->mWP
, (long) mwp
);
8908 /* so that update events can find this mac_output struct */
8909 mwp
->mFP
= fp
; /* point back to emacs frame */
8911 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8917 make_mac_terminal_frame (struct frame
*f
)
8921 XSETFRAME (frame
, f
);
8923 f
->output_method
= output_mac
;
8924 f
->output_data
.mac
= (struct mac_output
*)
8925 xmalloc (sizeof (struct mac_output
));
8926 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8928 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8930 FRAME_COLS (f
) = 96;
8931 FRAME_LINES (f
) = 4;
8933 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8934 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8936 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8938 f
->output_data
.mac
->cursor_pixel
= 0;
8939 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8940 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8941 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8943 FRAME_FONTSET (f
) = -1;
8944 f
->output_data
.mac
->explicit_parent
= 0;
8947 f
->border_width
= 0;
8949 f
->internal_border_width
= 0;
8954 f
->new_text_cols
= 0;
8955 f
->new_text_lines
= 0;
8961 /* Need to be initialized for unshow_buffer in window.c. */
8962 selected_window
= f
->selected_window
;
8964 Fmodify_frame_parameters (frame
,
8965 Fcons (Fcons (Qfont
,
8966 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8967 Fmodify_frame_parameters (frame
,
8968 Fcons (Fcons (Qforeground_color
,
8969 build_string ("black")), Qnil
));
8970 Fmodify_frame_parameters (frame
,
8971 Fcons (Fcons (Qbackground_color
,
8972 build_string ("white")), Qnil
));
8974 ShowWindow (f
->output_data
.mac
->mWP
);
8978 /***********************************************************************
8980 ***********************************************************************/
8982 int mac_initialized
= 0;
8985 mac_initialize_display_info ()
8987 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8988 GDHandle main_device_handle
;
8990 bzero (dpyinfo
, sizeof (*dpyinfo
));
8992 /* Put it on x_display_name_list. */
8993 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8994 x_display_name_list
);
8995 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8998 dpyinfo
->mac_id_name
8999 = (char *) xmalloc (SCHARS (Vinvocation_name
)
9000 + SCHARS (Vsystem_name
)
9002 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
9003 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
9005 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
9006 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
9009 main_device_handle
= LMGetMainDevice();
9011 dpyinfo
->reference_count
= 0;
9012 dpyinfo
->resx
= 75.0;
9013 dpyinfo
->resy
= 75.0;
9014 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
9016 /* HasDepth returns true if it is possible to have a 32 bit display,
9017 but this may not be what is actually used. Mac OSX can do better.
9018 CGMainDisplayID is only available on OSX 10.2 and higher, but the
9019 header for CGGetActiveDisplayList says that the first display returned
9020 is the active one, so we use that. */
9022 CGDirectDisplayID disp_id
[1];
9023 CGDisplayCount disp_count
;
9024 CGDisplayErr error_code
;
9026 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
9027 if (error_code
!= 0)
9028 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
9030 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
9033 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
9034 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
9035 gdDevType
, dpyinfo
->color_p
))
9038 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
9039 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
9040 dpyinfo
->grabbed
= 0;
9041 dpyinfo
->root_window
= NULL
;
9042 dpyinfo
->image_cache
= make_image_cache ();
9044 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9045 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9046 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9047 dpyinfo
->mouse_face_window
= Qnil
;
9048 dpyinfo
->mouse_face_overlay
= Qnil
;
9049 dpyinfo
->mouse_face_hidden
= 0;
9052 struct mac_display_info
*
9053 mac_term_init (display_name
, xrm_option
, resource_name
)
9054 Lisp_Object display_name
;
9056 char *resource_name
;
9058 struct mac_display_info
*dpyinfo
;
9059 GDHandle main_device_handle
;
9061 if (!mac_initialized
)
9064 mac_initialized
= 1;
9067 mac_initialize_display_info (display_name
);
9069 dpyinfo
= &one_mac_display_info
;
9071 main_device_handle
= LMGetMainDevice();
9073 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
9074 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
9083 extern int inhibit_window_system
;
9084 extern int noninteractive
;
9085 CFBundleRef appsBundle
;
9088 /* No need to test if already -nw*/
9089 if (inhibit_window_system
|| noninteractive
)
9092 appsBundle
= CFBundleGetMainBundle();
9093 if (appsBundle
!= NULL
)
9095 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
9096 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
9097 /* We found the bundle identifier, now we know we are valid. */
9104 /* MAC_TODO: Have this start the bundled executable */
9106 /* For now, prevent the fatal error by bringing it up in the terminal */
9107 inhibit_window_system
= 1;
9111 MakeMeTheFrontProcess ()
9113 ProcessSerialNumber psn
;
9116 err
= GetCurrentProcess (&psn
);
9118 (void) SetFrontProcess (&psn
);
9121 /***** Code to handle C-g testing *****/
9123 /* Contains the Mac modifier formed from quit_char */
9124 static mac_quit_char_modifiers
= 0;
9125 static mac_quit_char_keycode
;
9126 extern int quit_char
;
9129 mac_determine_quit_char_modifiers()
9131 /* Todo: Determine modifiers from quit_char. */
9132 UInt32 qc_modifiers
= ctrl_modifier
;
9135 mac_quit_char_modifiers
= 0;
9136 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
9137 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
9138 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
9139 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
9143 init_quit_char_handler ()
9145 /* TODO: Let this support keys other the 'g' */
9146 mac_quit_char_keycode
= 5;
9147 /* Look at <architecture/adb_kb_map.h> for details */
9148 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
9150 mac_determine_quit_char_modifiers();
9154 quit_char_comp (EventRef inEvent
, void *inCompData
)
9156 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
9158 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
9162 UInt32 keyModifiers
;
9163 GetEventParameter(inEvent
, kEventParamKeyCode
,
9164 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
9165 if (keyCode
!= mac_quit_char_keycode
)
9167 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
9168 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
9169 if (keyModifiers
!= mac_quit_char_modifiers
)
9176 mac_check_for_quit_char ()
9179 static EMACS_TIME last_check_time
= { 0, 0 };
9180 static EMACS_TIME one_second
= { 1, 0 };
9183 /* If windows are not initialized, return immediately (keep it bouncin'). */
9184 if (!mac_quit_char_modifiers
)
9187 /* Don't check if last check is less than a second ago. */
9188 EMACS_GET_TIME (now
);
9189 EMACS_SUB_TIME (t
, now
, last_check_time
);
9190 if (EMACS_TIME_LT (t
, one_second
))
9192 last_check_time
= now
;
9194 /* Redetermine modifiers because they are based on lisp variables */
9195 mac_determine_quit_char_modifiers ();
9197 /* Fill the queue with events */
9199 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
9200 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
9205 struct input_event e
;
9207 /* Use an input_event to emulate what the interrupt handler does. */
9209 e
.kind
= ASCII_KEYSTROKE_EVENT
;
9213 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
9214 XSETFRAME (e
.frame_or_window
, mac_window_to_frame (front_emacs_window ()));
9215 /* Remove event from queue to prevent looping. */
9216 RemoveEventFromQueue (GetMainEventQueue (), event
);
9217 ReleaseEvent (event
);
9218 kbd_buffer_store_event (&e
);
9222 #endif /* MAC_OSX */
9224 /* Set up use of X before we make the first connection. */
9226 extern frame_parm_handler mac_frame_parm_handlers
[];
9228 static struct redisplay_interface x_redisplay_interface
=
9230 mac_frame_parm_handlers
,
9234 x_clear_end_of_line
,
9236 x_after_update_window_line
,
9237 x_update_window_begin
,
9238 x_update_window_end
,
9241 0, /* flush_display_optional */
9242 x_clear_window_mouse_face
,
9243 x_get_glyph_overhangs
,
9244 x_fix_overlapping_area
,
9245 x_draw_fringe_bitmap
,
9246 0, /* define_fringe_bitmap */
9247 0, /* destroy_fringe_bitmap */
9248 mac_per_char_metric
,
9250 NULL
, /* mac_compute_glyph_string_overhangs */
9251 x_draw_glyph_string
,
9252 mac_define_frame_cursor
,
9253 mac_clear_frame_area
,
9254 mac_draw_window_cursor
,
9255 mac_draw_vertical_window_border
,
9256 mac_shift_glyphs_for_insert
9262 rif
= &x_redisplay_interface
;
9264 clear_frame_hook
= x_clear_frame
;
9265 ins_del_lines_hook
= x_ins_del_lines
;
9266 delete_glyphs_hook
= x_delete_glyphs
;
9267 ring_bell_hook
= XTring_bell
;
9268 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9269 set_terminal_modes_hook
= XTset_terminal_modes
;
9270 update_begin_hook
= x_update_begin
;
9271 update_end_hook
= x_update_end
;
9272 set_terminal_window_hook
= XTset_terminal_window
;
9273 read_socket_hook
= XTread_socket
;
9274 frame_up_to_date_hook
= XTframe_up_to_date
;
9275 mouse_position_hook
= XTmouse_position
;
9276 frame_rehighlight_hook
= XTframe_rehighlight
;
9277 frame_raise_lower_hook
= XTframe_raise_lower
;
9279 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9280 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9281 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9282 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9284 scroll_region_ok
= 1; /* we'll scroll partial frames */
9285 char_ins_del_ok
= 1;
9286 line_ins_del_ok
= 1; /* we'll just blt 'em */
9287 fast_clear_end_of_line
= 1; /* X does this well */
9288 memory_below_frame
= 0; /* we don't remember what scrolls
9293 last_tool_bar_item
= -1;
9294 any_help_event_p
= 0;
9296 /* Try to use interrupt input; if we can't, then start polling. */
9297 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9299 #ifdef USE_X_TOOLKIT
9300 XtToolkitInitialize ();
9301 Xt_app_con
= XtCreateApplicationContext ();
9302 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
9304 /* Install an asynchronous timer that processes Xt timeout events
9305 every 0.1s. This is necessary because some widget sets use
9306 timeouts internally, for example the LessTif menu bar, or the
9307 Xaw3d scroll bar. When Xt timouts aren't processed, these
9308 widgets don't behave normally. */
9310 EMACS_TIME interval
;
9311 EMACS_SET_SECS_USECS (interval
, 0, 100000);
9312 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
9316 #if USE_TOOLKIT_SCROLL_BARS
9317 xaw3d_arrow_scroll
= False
;
9318 xaw3d_pick_top
= True
;
9322 /* Note that there is no real way portable across R3/R4 to get the
9323 original error handler. */
9324 XSetErrorHandler (x_error_handler
);
9325 XSetIOErrorHandler (x_io_error_quitter
);
9327 /* Disable Window Change signals; they are handled by X events. */
9329 signal (SIGWINCH
, SIG_DFL
);
9330 #endif /* ! defined (SIGWINCH) */
9332 signal (SIGPIPE
, x_connection_signal
);
9336 mac_initialize_display_info ();
9338 #if TARGET_API_MAC_CARBON
9339 init_required_apple_events ();
9341 init_mac_drag_n_drop ();
9343 #if USE_CARBON_EVENTS
9344 init_service_handler ();
9346 init_quit_char_handler ();
9349 DisableMenuCommand (NULL
, kHICommandQuit
);
9351 if (!inhibit_window_system
)
9352 MakeMeTheFrontProcess ();
9362 staticpro (&x_error_message_string
);
9363 x_error_message_string
= Qnil
;
9366 Qmodifier_value
= intern ("modifier-value");
9367 Qalt
= intern ("alt");
9368 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
9369 Qhyper
= intern ("hyper");
9370 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
9371 Qsuper
= intern ("super");
9372 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
9374 Fprovide (intern ("mac-carbon"), Qnil
);
9376 staticpro (&Qreverse
);
9377 Qreverse
= intern ("reverse");
9379 staticpro (&x_display_name_list
);
9380 x_display_name_list
= Qnil
;
9382 staticpro (&last_mouse_scroll_bar
);
9383 last_mouse_scroll_bar
= Qnil
;
9385 staticpro (&Qvendor_specific_keysyms
);
9386 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9388 staticpro (&last_mouse_press_frame
);
9389 last_mouse_press_frame
= Qnil
;
9391 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
9392 staticpro (&Qmac_ready_for_drag_n_drop
);
9394 Qbig5
= intern ("big5");
9397 Qcn_gb
= intern ("cn-gb");
9398 staticpro (&Qcn_gb
);
9400 Qsjis
= intern ("sjis");
9403 Qeuc_kr
= intern ("euc-kr");
9404 staticpro (&Qeuc_kr
);
9406 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
9407 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
9408 x_autoselect_window_p
= 0;
9410 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9411 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9412 Vx_toolkit_scroll_bars
= Qt
;
9414 DEFVAR_BOOL ("x-use-underline-position-properties",
9415 &x_use_underline_position_properties
,
9416 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9417 nil means ignore them. If you encounter fonts with bogus
9418 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9419 to 4.1, set this to nil. */);
9420 x_use_underline_position_properties
= 0;
9422 staticpro (&last_mouse_motion_frame
);
9423 last_mouse_motion_frame
= Qnil
;
9425 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
9426 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
9427 Otherwise the option key is used. */);
9428 Vmac_command_key_is_meta
= Qt
;
9430 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
9431 doc
: /* Modifier to use for the Mac alt/option key. The value can
9432 be alt, hyper, or super for the respective modifier. If the value is
9433 nil then the key will act as the normal Mac option modifier. */);
9434 Vmac_option_modifier
= Qnil
;
9436 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
9437 doc
: /* Non-nil means that the control and meta keys are reversed. This is
9438 useful for non-standard keyboard layouts. */);
9439 Vmac_reverse_ctrl_meta
= Qnil
;
9441 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9442 &Vmac_emulate_three_button_mouse
,
9443 doc
: /* t means that when the option-key is held down while pressing the
9444 mouse button, the click will register as mouse-2 and while the
9445 command-key is held down, the click will register as mouse-3.
9446 'reverse means that the the option-key will register for mouse-3
9447 and the command-key will register for mouse-2. nil means that
9448 not emulation should be done and the modifiers should be placed
9449 on the mouse-1 event. */);
9450 Vmac_emulate_three_button_mouse
= Qnil
;
9452 #if USE_CARBON_EVENTS
9453 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
9454 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
9455 the right click will be mouse-3.
9456 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
9457 Vmac_wheel_button_is_mouse_2
= Qt
;
9459 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
9460 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
9461 Toolbox for processing before Emacs sees it. */);
9462 Vmac_pass_command_to_system
= Qt
;
9464 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
9465 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
9466 Toolbox for processing before Emacs sees it. */);
9467 Vmac_pass_control_to_system
= Qt
;
9470 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
9471 doc
: /* One of the Text Encoding Base constant values defined in the
9472 Basic Text Constants section of Inside Macintosh - Text Encoding
9473 Conversion Manager. Its value determines the encoding characters
9474 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
9475 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
9476 its default value, no conversion takes place. If it is set to
9477 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
9478 characters typed on Mac keyboard are first converted into the
9479 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
9480 passed to Emacs. Together with Emacs's set-keyboard-coding-system
9481 command, this enables the Mac keyboard to be used to enter non-ASCII
9482 characters directly. */);
9483 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
9486 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9487 (do not change this comment) */