1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
29 #include "blockinput.h"
37 #if TARGET_API_MAC_CARBON
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 TARGET_API_MAC_CARBON */
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 TARGET_API_MAC_CARBON */
70 #include <sys/param.h>
75 #include "dispextern.h"
77 #include "termhooks.h"
85 #include "intervals.h"
89 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
90 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
91 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
92 #define macShiftKey (shiftKey)
93 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
94 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
96 #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 /* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text. */
104 Lisp_Object Vmac_use_core_graphics
;
107 /* Non-zero means that a HELP_EVENT has been generated since Emacs
110 static int any_help_event_p
;
112 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
113 static Lisp_Object last_window
;
115 /* This is a chain of structures for all the X displays currently in
118 struct x_display_info
*x_display_list
;
120 /* This is a list of cons cells, each of the form (NAME
121 FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
122 x_display_list and in the same order. NAME is the name of the
123 frame. FONT-LIST-CACHE records previous values returned by
124 x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
125 equivalent, which is implemented with a Lisp object, for the
128 Lisp_Object x_display_name_list
;
130 /* This is display since Mac does not support multiple ones. */
131 struct mac_display_info one_mac_display_info
;
133 /* Frame being updated by update_frame. This is declared in term.c.
134 This is set by update_begin and looked at by all the XT functions.
135 It is zero while not inside an update. In that case, the XT
136 functions assume that `selected_frame' is the frame to apply to. */
138 extern struct frame
*updating_frame
;
140 /* This is a frame waiting to be auto-raised, within XTread_socket. */
142 struct frame
*pending_autoraise_frame
;
146 Formerly, we used PointerMotionHintMask (in standard_event_mask)
147 so that we would have to call XQueryPointer after each MotionNotify
148 event to ask for another such event. However, this made mouse tracking
149 slow, and there was a bug that made it eventually stop.
151 Simply asking for MotionNotify all the time seems to work better.
153 In order to avoid asking for motion events and then throwing most
154 of them away or busy-polling the server for mouse positions, we ask
155 the server for pointer motion hints. This means that we get only
156 one event per group of mouse movements. "Groups" are delimited by
157 other kinds of events (focus changes and button clicks, for
158 example), or by XQueryPointer calls; when one of these happens, we
159 get another MotionNotify event the next time the mouse moves. This
160 is at least as efficient as getting motion events when mouse
161 tracking is on, and I suspect only negligibly worse when tracking
164 /* Where the mouse was last time we reported a mouse event. */
166 static Rect last_mouse_glyph
;
168 /* The scroll bar in which the last X motion event occurred.
170 If the last X motion event occurred in a scroll bar, we set this so
171 XTmouse_position can know whether to report a scroll bar motion or
174 If the last X motion event didn't occur in a scroll bar, we set
175 this to Qnil, to tell XTmouse_position to return an ordinary motion
178 static Lisp_Object last_mouse_scroll_bar
;
180 /* This is a hack. We would really prefer that XTmouse_position would
181 return the time associated with the position it returns, but there
182 doesn't seem to be any way to wrest the time-stamp from the server
183 along with the position query. So, we just keep track of the time
184 of the last movement we received, and return that in hopes that
185 it's somewhat accurate. */
187 static Time last_mouse_movement_time
;
189 struct scroll_bar
*tracked_scroll_bar
= NULL
;
191 /* Incremented by XTread_socket whenever it really tries to read
195 static int volatile input_signal_count
;
197 static int input_signal_count
;
200 extern Lisp_Object Vsystem_name
;
202 /* A mask of extra modifier bits to put into every keyboard char. */
204 extern EMACS_INT extra_keyboard_modifiers
;
206 /* The keysyms to use for the various modifiers. */
208 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qmodifier_value
;
210 extern int inhibit_window_system
;
212 #if __MRC__ && !TARGET_API_MAC_CARBON
213 QDGlobals qd
; /* QuickDraw global information structure. */
216 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
218 struct mac_display_info
*mac_display_info_for_display (Display
*);
219 static void x_update_window_end
P_ ((struct window
*, int, int));
220 static int x_io_error_quitter
P_ ((Display
*));
221 int x_catch_errors
P_ ((Display
*));
222 void x_uncatch_errors
P_ ((Display
*, int));
223 void x_lower_frame
P_ ((struct frame
*));
224 void x_scroll_bar_clear
P_ ((struct frame
*));
225 int x_had_errors_p
P_ ((Display
*));
226 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
227 void x_raise_frame
P_ ((struct frame
*));
228 void x_set_window_size
P_ ((struct frame
*, int, int, int));
229 void x_wm_set_window_state
P_ ((struct frame
*, int));
230 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
231 void mac_initialize
P_ ((void));
232 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
233 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
234 static void x_update_end
P_ ((struct frame
*));
235 static void XTframe_up_to_date
P_ ((struct frame
*));
236 static void XTset_terminal_modes
P_ ((void));
237 static void XTreset_terminal_modes
P_ ((void));
238 static void x_clear_frame
P_ ((void));
239 static void frame_highlight
P_ ((struct frame
*));
240 static void frame_unhighlight
P_ ((struct frame
*));
241 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
242 static void mac_focus_changed
P_ ((int, struct mac_display_info
*,
243 struct frame
*, struct input_event
*));
244 static void x_detect_focus_change
P_ ((struct mac_display_info
*,
245 EventRecord
*, struct input_event
*));
246 static void XTframe_rehighlight
P_ ((struct frame
*));
247 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
248 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
249 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
250 enum text_cursor_kinds
));
252 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
253 static void x_flush
P_ ((struct frame
*f
));
254 static void x_update_begin
P_ ((struct frame
*));
255 static void x_update_window_begin
P_ ((struct window
*));
256 static void x_after_update_window_line
P_ ((struct glyph_row
*));
257 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
258 enum scroll_bar_part
*,
259 Lisp_Object
*, Lisp_Object
*,
262 static int is_emacs_window
P_ ((WindowPtr
));
264 static void XSetFont
P_ ((Display
*, GC
, XFontStruct
*));
266 /* Defined in macmenu.h. */
267 extern void menubar_selection_callback (FRAME_PTR
, int);
269 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
270 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
271 #define GC_FONT(gc) ((gc)->xgcv.font)
272 #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc)
275 /* X display function emulation */
278 XFreePixmap (display
, pixmap
)
279 Display
*display
; /* not used */
282 DisposeGWorld (pixmap
);
286 /* Mac version of XDrawLine. */
289 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
295 SetPortWindowPort (w
);
297 RGBForeColor (GC_FORE_COLOR (gc
));
304 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
313 GetGWorld (&old_port
, &old_gdh
);
316 RGBForeColor (GC_FORE_COLOR (gc
));
318 LockPixels (GetGWorldPixMap (p
));
321 UnlockPixels (GetGWorldPixMap (p
));
323 SetGWorld (old_port
, old_gdh
);
328 mac_erase_rectangle (w
, gc
, x
, y
, width
, height
)
332 unsigned int width
, height
;
336 SetPortWindowPort (w
);
338 RGBBackColor (GC_BACK_COLOR (gc
));
339 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
343 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
347 /* Mac version of XClearArea. */
350 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
354 unsigned int width
, height
;
357 mac_erase_rectangle (w
, MAC_WINDOW_NORMAL_GC (w
), x
, y
, width
, height
);
360 /* Mac version of XClearWindow. */
363 XClearWindow (display
, w
)
367 SetPortWindowPort (w
);
369 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
371 #if TARGET_API_MAC_CARBON
375 GetWindowPortBounds (w
, &r
);
378 #else /* not TARGET_API_MAC_CARBON */
379 EraseRect (&(w
->portRect
));
380 #endif /* not TARGET_API_MAC_CARBON */
384 /* Mac replacement for XCopyArea. */
387 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
391 int x
, y
, width
, height
;
392 unsigned short *bits
;
398 bitmap
.rowBytes
= sizeof(unsigned short);
399 bitmap
.baseAddr
= (char *)bits
;
400 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
402 SetPortWindowPort (w
);
404 RGBForeColor (GC_FORE_COLOR (gc
));
405 RGBBackColor (GC_BACK_COLOR (gc
));
406 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
408 #if TARGET_API_MAC_CARBON
409 LockPortBits (GetWindowPort (w
));
410 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
411 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
412 UnlockPortBits (GetWindowPort (w
));
413 #else /* not TARGET_API_MAC_CARBON */
414 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
415 overlay_p
? srcOr
: srcCopy
, 0);
416 #endif /* not TARGET_API_MAC_CARBON */
418 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
422 /* Mac replacement for XSetClipRectangles. */
425 mac_set_clip_rectangle (display
, w
, r
)
430 SetPortWindowPort (w
);
436 /* Mac replacement for XSetClipMask. */
439 mac_reset_clipping (display
, w
)
445 SetPortWindowPort (w
);
447 SetRect (&r
, -32767, -32767, 32767, 32767);
452 /* Mac replacement for XCreateBitmapFromBitmapData. */
455 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
460 static unsigned char swap_nibble
[16]
461 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
462 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
463 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
464 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
468 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
469 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
470 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
471 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
472 for (i
= 0; i
< h
; i
++)
474 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
475 for (j
= 0; j
< w1
; j
++)
477 /* Bitswap XBM bytes to match how Mac does things. */
478 unsigned char c
= *bits
++;
479 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
480 | (swap_nibble
[(c
>>4) & 0xf]));;
484 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
489 mac_free_bitmap (bitmap
)
492 xfree (bitmap
->baseAddr
);
497 XCreatePixmap (display
, w
, width
, height
, depth
)
498 Display
*display
; /* not used */
500 unsigned int width
, height
;
507 SetPortWindowPort (w
);
509 SetRect (&r
, 0, 0, width
, height
);
510 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
518 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
519 Display
*display
; /* not used */
522 unsigned int width
, height
;
523 unsigned long fg
, bg
;
530 static GC gc
= NULL
; /* not reentrant */
533 gc
= XCreateGC (display
, w
, 0, NULL
);
535 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
539 GetGWorld (&old_port
, &old_gdh
);
540 SetGWorld (pixmap
, NULL
);
541 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
542 XSetForeground (display
, gc
, fg
);
543 XSetBackground (display
, gc
, bg
);
544 RGBForeColor (GC_FORE_COLOR (gc
));
545 RGBBackColor (GC_BACK_COLOR (gc
));
546 LockPixels (GetGWorldPixMap (pixmap
));
547 #if TARGET_API_MAC_CARBON
548 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
549 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
550 #else /* not TARGET_API_MAC_CARBON */
551 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
552 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
553 #endif /* not TARGET_API_MAC_CARBON */
554 UnlockPixels (GetGWorldPixMap (pixmap
));
555 SetGWorld (old_port
, old_gdh
);
556 mac_free_bitmap (&bitmap
);
562 /* Mac replacement for XFillRectangle. */
565 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
570 unsigned int width
, height
;
574 SetPortWindowPort (w
);
576 RGBForeColor (GC_FORE_COLOR (gc
));
577 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
579 PaintRect (&r
); /* using foreground color of gc */
583 #if 0 /* TODO: figure out if we need to do this on Mac. */
585 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
590 unsigned int width
, height
;
596 GetGWorld (&old_port
, &old_gdh
);
598 RGBForeColor (GC_FORE_COLOR (gc
));
599 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
601 LockPixels (GetGWorldPixMap (p
));
602 PaintRect (&r
); /* using foreground color of gc */
603 UnlockPixels (GetGWorldPixMap (p
));
605 SetGWorld (old_port
, old_gdh
);
610 /* Mac replacement for XDrawRectangle: dest is a window. */
613 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
618 unsigned int width
, height
;
622 SetPortWindowPort (w
);
624 RGBForeColor (GC_FORE_COLOR (gc
));
625 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
627 FrameRect (&r
); /* using foreground color of gc */
631 #if 0 /* TODO: figure out if we need to do this on Mac. */
632 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
635 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
640 unsigned int width
, height
;
646 GetGWorld (&old_port
, &old_gdh
);
648 RGBForeColor (GC_FORE_COLOR (gc
));
649 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
651 LockPixels (GetGWorldPixMap (p
));
652 FrameRect (&r
); /* using foreground color of gc */
653 UnlockPixels (GetGWorldPixMap (p
));
655 SetGWorld (old_port
, old_gdh
);
661 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
668 int nchars
, mode
, bytes_per_char
;
670 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
671 UInt32 textFlags
, savedFlags
;
672 if (!NILP(Vmac_use_core_graphics
)) {
673 textFlags
= kQDUseCGTextRendering
;
674 savedFlags
= SwapQDTextFlags(textFlags
);
678 SetPortWindowPort (w
);
680 RGBForeColor (GC_FORE_COLOR (gc
));
682 RGBBackColor (GC_BACK_COLOR (gc
));
684 TextFont (GC_FONT (gc
)->mac_fontnum
);
685 TextSize (GC_FONT (gc
)->mac_fontsize
);
686 TextFace (GC_FONT (gc
)->mac_fontface
);
690 DrawText (buf
, 0, nchars
* bytes_per_char
);
693 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
694 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
695 if (!NILP(Vmac_use_core_graphics
))
696 SwapQDTextFlags(savedFlags
);
701 /* Mac replacement for XDrawString. */
704 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
712 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
716 /* Mac replacement for XDrawString16. */
719 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
727 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
732 /* Mac replacement for XDrawImageString. */
735 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
743 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
747 /* Mac replacement for XDrawString16. */
750 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
758 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
763 /* Mac replacement for XCopyArea: dest must be window. */
766 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
773 unsigned int width
, height
;
778 SetPortWindowPort (dest
);
780 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
781 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
783 ForeColor (blackColor
);
784 BackColor (whiteColor
);
786 LockPixels (GetGWorldPixMap (src
));
787 #if TARGET_API_MAC_CARBON
788 LockPortBits (GetWindowPort (dest
));
789 CopyBits (GetPortBitMapForCopyBits (src
),
790 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
791 &src_r
, &dest_r
, srcCopy
, 0);
792 UnlockPortBits (GetWindowPort (dest
));
793 #else /* not TARGET_API_MAC_CARBON */
794 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
795 &src_r
, &dest_r
, srcCopy
, 0);
796 #endif /* not TARGET_API_MAC_CARBON */
797 UnlockPixels (GetGWorldPixMap (src
));
802 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
803 width
, height
, dest_x
, dest_y
)
809 unsigned int width
, height
;
814 SetPortWindowPort (dest
);
816 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
817 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
819 ForeColor (blackColor
);
820 BackColor (whiteColor
);
822 LockPixels (GetGWorldPixMap (src
));
823 LockPixels (GetGWorldPixMap (mask
));
824 #if TARGET_API_MAC_CARBON
825 LockPortBits (GetWindowPort (dest
));
826 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
827 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
828 &src_r
, &src_r
, &dest_r
);
829 UnlockPortBits (GetWindowPort (dest
));
830 #else /* not TARGET_API_MAC_CARBON */
831 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
832 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
833 #endif /* not TARGET_API_MAC_CARBON */
834 UnlockPixels (GetGWorldPixMap (mask
));
835 UnlockPixels (GetGWorldPixMap (src
));
839 /* Mac replacement for XCopyArea: used only for scrolling. */
842 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
847 unsigned int width
, height
;
850 #if TARGET_API_MAC_CARBON
852 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
854 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
855 ScrollWindowRect (w
, &src_r
, dest_x
- src_x
, dest_y
- src_y
,
856 kScrollWindowNoOptions
, dummy
);
858 #else /* not TARGET_API_MAC_CARBON */
863 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
864 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
866 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
867 color mapping in CopyBits. Otherwise, it will be slow. */
868 ForeColor (blackColor
);
869 BackColor (whiteColor
);
870 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
872 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
873 #endif /* not TARGET_API_MAC_CARBON */
877 #if 0 /* TODO: figure out if we need to do this on Mac. */
878 /* Mac replacement for XCopyArea: dest must be Pixmap. */
881 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
887 unsigned int width
, height
;
894 GetGWorld (&old_port
, &old_gdh
);
895 SetGWorld (dest
, NULL
);
896 ForeColor (blackColor
);
897 BackColor (whiteColor
);
899 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
900 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
902 LockPixels (GetGWorldPixMap (src
));
903 LockPixels (GetGWorldPixMap (dest
));
904 #if TARGET_API_MAC_CARBON
905 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
906 &src_r
, &dest_r
, srcCopy
, 0);
907 #else /* not TARGET_API_MAC_CARBON */
908 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
909 &src_r
, &dest_r
, srcCopy
, 0);
910 #endif /* not TARGET_API_MAC_CARBON */
911 UnlockPixels (GetGWorldPixMap (dest
));
912 UnlockPixels (GetGWorldPixMap (src
));
914 SetGWorld (old_port
, old_gdh
);
919 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
920 width
, height
, dest_x
, dest_y
)
922 Pixmap src
, mask
, dest
;
925 unsigned int width
, height
;
932 GetGWorld (&old_port
, &old_gdh
);
933 SetGWorld (dest
, NULL
);
934 ForeColor (blackColor
);
935 BackColor (whiteColor
);
937 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
938 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
940 LockPixels (GetGWorldPixMap (src
));
941 LockPixels (GetGWorldPixMap (mask
));
942 LockPixels (GetGWorldPixMap (dest
));
943 #if TARGET_API_MAC_CARBON
944 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
945 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
946 #else /* not TARGET_API_MAC_CARBON */
947 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
948 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
949 #endif /* not TARGET_API_MAC_CARBON */
950 UnlockPixels (GetGWorldPixMap (dest
));
951 UnlockPixels (GetGWorldPixMap (mask
));
952 UnlockPixels (GetGWorldPixMap (src
));
954 SetGWorld (old_port
, old_gdh
);
959 /* Mac replacement for XChangeGC. */
962 XChangeGC (display
, gc
, mask
, xgcv
)
968 if (mask
& GCForeground
)
969 XSetForeground (display
, gc
, xgcv
->foreground
);
970 if (mask
& GCBackground
)
971 XSetBackground (display
, gc
, xgcv
->background
);
973 XSetFont (display
, gc
, xgcv
->font
);
977 /* Mac replacement for XCreateGC. */
980 XCreateGC (display
, window
, mask
, xgcv
)
986 GC gc
= xmalloc (sizeof (*gc
));
990 bzero (gc
, sizeof (*gc
));
991 XChangeGC (display
, gc
, mask
, xgcv
);
998 /* Used in xfaces.c. */
1001 XFreeGC (display
, gc
)
1009 /* Mac replacement for XGetGCValues. */
1012 XGetGCValues (display
, gc
, mask
, xgcv
)
1018 if (mask
& GCForeground
)
1019 xgcv
->foreground
= gc
->xgcv
.foreground
;
1020 if (mask
& GCBackground
)
1021 xgcv
->background
= gc
->xgcv
.background
;
1023 xgcv
->font
= gc
->xgcv
.font
;
1027 /* Mac replacement for XSetForeground. */
1030 XSetForeground (display
, gc
, color
)
1033 unsigned long color
;
1035 if (gc
->xgcv
.foreground
!= color
)
1037 gc
->xgcv
.foreground
= color
;
1038 gc
->fore_color
.red
= RED16_FROM_ULONG (color
);
1039 gc
->fore_color
.green
= GREEN16_FROM_ULONG (color
);
1040 gc
->fore_color
.blue
= BLUE16_FROM_ULONG (color
);
1045 /* Mac replacement for XSetBackground. */
1048 XSetBackground (display
, gc
, color
)
1051 unsigned long color
;
1053 if (gc
->xgcv
.background
!= color
)
1055 gc
->xgcv
.background
= color
;
1056 gc
->back_color
.red
= RED16_FROM_ULONG (color
);
1057 gc
->back_color
.green
= GREEN16_FROM_ULONG (color
);
1058 gc
->back_color
.blue
= BLUE16_FROM_ULONG (color
);
1063 /* Mac replacement for XSetFont. */
1066 XSetFont (display
, gc
, font
)
1071 gc
->xgcv
.font
= font
;
1075 /* Mac replacement for XSetWindowBackground. */
1078 XSetWindowBackground (display
, w
, color
)
1081 unsigned long color
;
1083 #if !TARGET_API_MAC_CARBON
1084 AuxWinHandle aw_handle
;
1085 CTabHandle ctab_handle
;
1086 ColorSpecPtr ct_table
;
1091 bg_color
.red
= RED16_FROM_ULONG (color
);
1092 bg_color
.green
= GREEN16_FROM_ULONG (color
);
1093 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
1095 #if TARGET_API_MAC_CARBON
1096 SetWindowContentColor (w
, &bg_color
);
1098 if (GetAuxWin (w
, &aw_handle
))
1100 ctab_handle
= (*aw_handle
)->awCTable
;
1101 HandToHand ((Handle
*) &ctab_handle
);
1102 ct_table
= (*ctab_handle
)->ctTable
;
1103 ct_size
= (*ctab_handle
)->ctSize
;
1104 while (ct_size
> -1)
1106 if (ct_table
->value
== 0)
1108 ct_table
->rgb
= bg_color
;
1109 CTabChanged (ctab_handle
);
1110 SetWinColor (w
, (WCTabHandle
) ctab_handle
);
1118 /* x_sync is a no-op on Mac. */
1126 /* Flush display of frame F, or of all frames if F is null. */
1132 #if TARGET_API_MAC_CARBON
1135 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1137 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1143 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1144 Calls to XFlush should be unnecessary because the X output buffer
1145 is flushed automatically as needed by calls to XPending,
1146 XNextEvent, or XWindowEvent according to the XFlush man page.
1147 XTread_socket calls XPending. Removing XFlush improves
1150 #define XFlush(DISPLAY) (void) 0
1153 /* Return the struct mac_display_info corresponding to DPY. There's
1156 struct mac_display_info
*
1157 mac_display_info_for_display (dpy
)
1160 return &one_mac_display_info
;
1165 /***********************************************************************
1166 Starting and ending an update
1167 ***********************************************************************/
1169 /* Start an update of frame F. This function is installed as a hook
1170 for update_begin, i.e. it is called when update_begin is called.
1171 This function is called prior to calls to x_update_window_begin for
1172 each window being updated. */
1178 #if TARGET_API_MAC_CARBON
1179 /* During update of a frame, availability of input events is
1180 periodically checked with ReceiveNextEvent if
1181 redisplay-dont-pause is nil. That normally flushes window buffer
1182 changes for every check, and thus screen update looks waving even
1183 if no input is available. So we disable screen updates during
1184 update of a frame. */
1186 DisableScreenUpdates ();
1192 /* Start update of window W. Set the global variable updated_window
1193 to the window being updated and set output_cursor to the cursor
1197 x_update_window_begin (w
)
1200 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1201 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1204 set_output_cursor (&w
->cursor
);
1208 if (f
== display_info
->mouse_face_mouse_frame
)
1210 /* Don't do highlighting for mouse motion during the update. */
1211 display_info
->mouse_face_defer
= 1;
1213 /* If F needs to be redrawn, simply forget about any prior mouse
1215 if (FRAME_GARBAGED_P (f
))
1216 display_info
->mouse_face_window
= Qnil
;
1218 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1219 their mouse_face_p flag set, which means that they are always
1220 unequal to rows in a desired matrix which never have that
1221 flag set. So, rows containing mouse-face glyphs are never
1222 scrolled, and we don't have to switch the mouse highlight off
1223 here to prevent it from being scrolled. */
1225 /* Can we tell that this update does not affect the window
1226 where the mouse highlight is? If so, no need to turn off.
1227 Likewise, don't do anything if the frame is garbaged;
1228 in that case, the frame's current matrix that we would use
1229 is all wrong, and we will redisplay that line anyway. */
1230 if (!NILP (display_info
->mouse_face_window
)
1231 && w
== XWINDOW (display_info
->mouse_face_window
))
1235 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1236 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1239 if (i
< w
->desired_matrix
->nrows
)
1240 clear_mouse_face (display_info
);
1249 /* Draw a vertical window border from (x,y0) to (x,y1) */
1252 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1256 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1259 face
= FACE_FROM_ID (f
, VERTICAL_BORDER_FACE_ID
);
1261 XSetForeground (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
1264 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1265 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1268 /* End update of window W (which is equal to updated_window).
1270 Draw vertical borders between horizontally adjacent windows, and
1271 display W's cursor if CURSOR_ON_P is non-zero.
1273 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1274 glyphs in mouse-face were overwritten. In that case we have to
1275 make sure that the mouse-highlight is properly redrawn.
1277 W may be a menu bar pseudo-window in case we don't have X toolkit
1278 support. Such windows don't have a cursor, so don't display it
1282 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1284 int cursor_on_p
, mouse_face_overwritten_p
;
1286 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1288 if (!w
->pseudo_window_p
)
1293 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1295 output_cursor
.x
, output_cursor
.y
);
1297 if (draw_window_fringes (w
, 1))
1298 x_draw_vertical_border (w
);
1303 /* If a row with mouse-face was overwritten, arrange for
1304 XTframe_up_to_date to redisplay the mouse highlight. */
1305 if (mouse_face_overwritten_p
)
1307 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1308 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1309 dpyinfo
->mouse_face_window
= Qnil
;
1312 updated_window
= NULL
;
1316 /* End update of frame F. This function is installed as a hook in
1323 /* Mouse highlight may be displayed again. */
1324 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1327 #if TARGET_API_MAC_CARBON
1328 EnableScreenUpdates ();
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
));
1398 /* Internal border is drawn below the tool bar. */
1399 if (WINDOWP (f
->tool_bar_window
)
1400 && 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
,
1414 /* Draw the bitmap WHICH in one of the left or right fringes of
1415 window W. ROW is the glyph row for which to display the bitmap; it
1416 determines the vertical position at which the bitmap has to be
1420 x_draw_fringe_bitmap (w
, row
, p
)
1422 struct glyph_row
*row
;
1423 struct draw_fringe_bitmap_params
*p
;
1425 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1426 Display
*display
= FRAME_MAC_DISPLAY (f
);
1427 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1428 GC gc
= f
->output_data
.mac
->normal_gc
;
1429 struct face
*face
= p
->face
;
1432 /* Must clip because of partially visible lines. */
1433 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1436 /* Adjust position of "bottom aligned" bitmap on partially
1437 visible last row. */
1439 int oldVH
= row
->visible_height
;
1440 row
->visible_height
= p
->h
;
1441 row
->y
-= rowY
- p
->y
;
1442 x_clip_to_row (w
, row
, -1, gc
);
1444 row
->visible_height
= oldVH
;
1447 x_clip_to_row (w
, row
, -1, gc
);
1449 if (p
->bx
>= 0 && !p
->overlay_p
)
1451 #if 0 /* MAC_TODO: stipple */
1452 /* In case the same realized face is used for fringes and
1453 for something displayed in the text (e.g. face `region' on
1454 mono-displays, the fill style may have been changed to
1455 FillSolid in x_draw_glyph_string_background. */
1457 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1459 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1462 mac_erase_rectangle (window
, face
->gc
, p
->bx
, p
->by
, p
->nx
, p
->ny
);
1464 #if 0 /* MAC_TODO: stipple */
1466 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1472 unsigned short *bits
= p
->bits
+ p
->dh
;
1475 XGetGCValues (display
, face
->gc
, GCForeground
, &gcv
);
1476 XSetForeground (display
, face
->gc
,
1478 ? (p
->overlay_p
? face
->background
1479 : f
->output_data
.mac
->cursor_pixel
)
1480 : face
->foreground
));
1481 mac_draw_bitmap (display
, window
, face
->gc
, p
->x
, p
->y
,
1482 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1483 XSetForeground (display
, face
->gc
, gcv
.foreground
);
1486 mac_reset_clipping (display
, window
);
1491 /* This is called when starting Emacs and when restarting after
1492 suspend. When starting Emacs, no window is mapped. And nothing
1493 must be done to Emacs's own window if it is suspended (though that
1497 XTset_terminal_modes ()
1501 /* This is called when exiting or suspending Emacs. Exiting will make
1502 the windows go away, and suspending requires no action. */
1505 XTreset_terminal_modes ()
1511 /***********************************************************************
1513 ***********************************************************************/
1515 /* Function prototypes of this page. */
1517 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1518 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1521 /* Return a pointer to per-char metric information in FONT of a
1522 character pointed by B which is a pointer to an XChar2b. */
1524 #define PER_CHAR_METRIC(font, b) \
1526 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1527 + (((font)->min_byte1 || (font)->max_byte1) \
1528 ? (((b)->byte1 - (font)->min_byte1) \
1529 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1531 : &((font)->max_bounds))
1534 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1535 is not contained in the font. */
1537 static INLINE XCharStruct
*
1538 x_per_char_metric (font
, char2b
)
1542 /* The result metric information. */
1543 XCharStruct
*pcm
= NULL
;
1545 xassert (font
&& char2b
);
1547 if (font
->per_char
!= NULL
)
1549 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1551 /* min_char_or_byte2 specifies the linear character index
1552 corresponding to the first element of the per_char array,
1553 max_char_or_byte2 is the index of the last character. A
1554 character with non-zero CHAR2B->byte1 is not in the font.
1555 A character with byte2 less than min_char_or_byte2 or
1556 greater max_char_or_byte2 is not in the font. */
1557 if (char2b
->byte1
== 0
1558 && char2b
->byte2
>= font
->min_char_or_byte2
1559 && char2b
->byte2
<= font
->max_char_or_byte2
)
1560 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1564 /* If either min_byte1 or max_byte1 are nonzero, both
1565 min_char_or_byte2 and max_char_or_byte2 are less than
1566 256, and the 2-byte character index values corresponding
1567 to the per_char array element N (counting from 0) are:
1569 byte1 = N/D + min_byte1
1570 byte2 = N\D + min_char_or_byte2
1574 D = max_char_or_byte2 - min_char_or_byte2 + 1
1575 / = integer division
1576 \ = integer modulus */
1577 if (char2b
->byte1
>= font
->min_byte1
1578 && char2b
->byte1
<= font
->max_byte1
1579 && char2b
->byte2
>= font
->min_char_or_byte2
1580 && char2b
->byte2
<= font
->max_char_or_byte2
)
1582 pcm
= (font
->per_char
1583 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1584 * (char2b
->byte1
- font
->min_byte1
))
1585 + (char2b
->byte2
- font
->min_char_or_byte2
));
1591 /* If the per_char pointer is null, all glyphs between the first
1592 and last character indexes inclusive have the same
1593 information, as given by both min_bounds and max_bounds. */
1594 if (char2b
->byte2
>= font
->min_char_or_byte2
1595 && char2b
->byte2
<= font
->max_char_or_byte2
)
1596 pcm
= &font
->max_bounds
;
1599 return ((pcm
== NULL
1600 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1607 static XCharStruct
*
1608 mac_per_char_metric (font
, char2b
, font_type
)
1613 return x_per_char_metric (font
, char2b
);
1617 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1618 the two-byte form of C. Encoding is returned in *CHAR2B. */
1621 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1624 struct font_info
*font_info
;
1627 int charset
= CHAR_CHARSET (c
);
1628 XFontStruct
*font
= font_info
->font
;
1630 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1631 This may be either a program in a special encoder language or a
1633 if (font_info
->font_encoder
)
1635 /* It's a program. */
1636 struct ccl_program
*ccl
= font_info
->font_encoder
;
1638 check_ccl_update (ccl
);
1639 if (CHARSET_DIMENSION (charset
) == 1)
1641 ccl
->reg
[0] = charset
;
1642 ccl
->reg
[1] = char2b
->byte2
;
1647 ccl
->reg
[0] = charset
;
1648 ccl
->reg
[1] = char2b
->byte1
;
1649 ccl
->reg
[2] = char2b
->byte2
;
1652 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1654 /* We assume that MSBs are appropriately set/reset by CCL
1656 if (font
->max_byte1
== 0) /* 1-byte font */
1657 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1659 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1661 else if (font_info
->encoding
[charset
])
1663 /* Fixed encoding scheme. See fontset.h for the meaning of the
1664 encoding numbers. */
1665 int enc
= font_info
->encoding
[charset
];
1667 if ((enc
== 1 || enc
== 2)
1668 && CHARSET_DIMENSION (charset
) == 2)
1669 char2b
->byte1
|= 0x80;
1671 if (enc
== 1 || enc
== 3)
1672 char2b
->byte2
|= 0x80;
1678 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1679 char2b
->byte1
= sjis1
;
1680 char2b
->byte2
= sjis2
;
1685 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1687 return FONT_TYPE_UNKNOWN
;
1692 /***********************************************************************
1694 ***********************************************************************/
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 mac_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
1707 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1708 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1709 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1710 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1711 unsigned long *, double, int));*/
1712 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1713 double, int, unsigned long));
1714 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1715 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1716 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1717 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1718 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1719 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1721 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1722 int, int, int, int, int, int,
1724 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1725 int, int, int, Rect
*));
1728 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1732 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1737 struct glyph_string
*s
;
1739 if (s
->font
== FRAME_FONT (s
->f
)
1740 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1741 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1743 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1746 /* Cursor on non-default face: must merge. */
1750 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1751 xgcv
.foreground
= s
->face
->background
;
1753 /* If the glyph would be invisible, try a different foreground. */
1754 if (xgcv
.foreground
== xgcv
.background
)
1755 xgcv
.foreground
= s
->face
->foreground
;
1756 if (xgcv
.foreground
== xgcv
.background
)
1757 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1758 if (xgcv
.foreground
== xgcv
.background
)
1759 xgcv
.foreground
= s
->face
->foreground
;
1761 /* Make sure the cursor is distinct from text in this face. */
1762 if (xgcv
.background
== s
->face
->background
1763 && xgcv
.foreground
== s
->face
->foreground
)
1765 xgcv
.background
= s
->face
->foreground
;
1766 xgcv
.foreground
= s
->face
->background
;
1769 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1770 xgcv
.font
= s
->font
;
1771 mask
= GCForeground
| GCBackground
| GCFont
;
1773 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1774 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1777 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1778 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1780 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1785 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1788 x_set_mouse_face_gc (s
)
1789 struct glyph_string
*s
;
1794 /* What face has to be used last for the mouse face? */
1795 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1796 face
= FACE_FROM_ID (s
->f
, face_id
);
1798 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1800 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1801 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1803 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1804 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1805 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1807 /* If font in this face is same as S->font, use it. */
1808 if (s
->font
== s
->face
->font
)
1809 s
->gc
= s
->face
->gc
;
1812 /* Otherwise construct scratch_cursor_gc with values from FACE
1817 xgcv
.background
= s
->face
->background
;
1818 xgcv
.foreground
= s
->face
->foreground
;
1819 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1820 xgcv
.font
= s
->font
;
1821 mask
= GCForeground
| GCBackground
| GCFont
;
1823 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1824 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1827 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1828 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1830 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1833 xassert (s
->gc
!= 0);
1837 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1838 Faces to use in the mode line have already been computed when the
1839 matrix was built, so there isn't much to do, here. */
1842 x_set_mode_line_face_gc (s
)
1843 struct glyph_string
*s
;
1845 s
->gc
= s
->face
->gc
;
1849 /* Set S->gc of glyph string S for drawing that glyph string. Set
1850 S->stippled_p to a non-zero value if the face of S has a stipple
1854 x_set_glyph_string_gc (s
)
1855 struct glyph_string
*s
;
1857 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1859 if (s
->hl
== DRAW_NORMAL_TEXT
)
1861 s
->gc
= s
->face
->gc
;
1862 s
->stippled_p
= s
->face
->stipple
!= 0;
1864 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1866 x_set_mode_line_face_gc (s
);
1867 s
->stippled_p
= s
->face
->stipple
!= 0;
1869 else if (s
->hl
== DRAW_CURSOR
)
1871 x_set_cursor_gc (s
);
1874 else if (s
->hl
== DRAW_MOUSE_FACE
)
1876 x_set_mouse_face_gc (s
);
1877 s
->stippled_p
= s
->face
->stipple
!= 0;
1879 else if (s
->hl
== DRAW_IMAGE_RAISED
1880 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1882 s
->gc
= s
->face
->gc
;
1883 s
->stippled_p
= s
->face
->stipple
!= 0;
1887 s
->gc
= s
->face
->gc
;
1888 s
->stippled_p
= s
->face
->stipple
!= 0;
1891 /* GC must have been set. */
1892 xassert (s
->gc
!= 0);
1896 /* Set clipping for output of glyph string S. S may be part of a mode
1897 line or menu if we don't have X toolkit support. */
1900 x_set_glyph_string_clipping (s
)
1901 struct glyph_string
*s
;
1904 get_glyph_string_clip_rect (s
, &r
);
1905 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1910 Compute left and right overhang of glyph string S. If S is a glyph
1911 string for a composition, assume overhangs don't exist. */
1914 mac_compute_glyph_string_overhangs (s
)
1915 struct glyph_string
*s
;
1918 && s
->first_glyph
->type
== CHAR_GLYPH
)
1921 MacFontStruct
*font
= s
->font
;
1923 TextFont (font
->mac_fontnum
);
1924 TextSize (font
->mac_fontsize
);
1925 TextFace (font
->mac_fontface
);
1928 QDTextBounds (s
->nchars
* 2, (char *)s
->char2b
, &r
);
1932 char *buf
= xmalloc (s
->nchars
);
1935 SetRect (&r
, 0, 0, 0, 0);
1938 for (i
= 0; i
< s
->nchars
; ++i
)
1939 buf
[i
] = s
->char2b
[i
].byte2
;
1940 QDTextBounds (s
->nchars
, buf
, &r
);
1945 s
->right_overhang
= r
.right
> s
->width
? r
.right
- s
->width
: 0;
1946 s
->left_overhang
= r
.left
< 0 ? -r
.left
: 0;
1951 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1954 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1955 struct glyph_string
*s
;
1958 mac_erase_rectangle (s
->window
, s
->gc
, x
, y
, w
, h
);
1962 /* We prefer not to use XDrawImageString (srcCopy text transfer mode)
1963 on Mac OS X because:
1964 - Screen is double-buffered. (In srcCopy mode, a text is drawn
1965 into an offscreen graphics world first. So performance gain
1966 cannot be expected.)
1967 - It lowers rendering quality.
1968 - Some fonts leave garbage on cursor movement. */
1970 /* Draw the background of glyph_string S. If S->background_filled_p
1971 is non-zero don't draw it. FORCE_P non-zero means draw the
1972 background even if it wouldn't be drawn normally. This is used
1973 when a string preceding S draws into the background of S, or S
1974 contains the first component of a composition. */
1977 x_draw_glyph_string_background (s
, force_p
)
1978 struct glyph_string
*s
;
1981 /* Nothing to do if background has already been drawn or if it
1982 shouldn't be drawn in the first place. */
1983 if (!s
->background_filled_p
)
1985 int box_line_width
= max (s
->face
->box_line_width
, 0);
1987 #if 0 /* MAC_TODO: stipple */
1990 /* Fill background with a stipple pattern. */
1991 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1992 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1993 s
->y
+ box_line_width
,
1994 s
->background_width
,
1995 s
->height
- 2 * box_line_width
);
1996 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1997 s
->background_filled_p
= 1;
2002 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2003 || s
->font_not_found_p
2004 || s
->extends_to_end_of_line_p
2008 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2009 s
->background_width
,
2010 s
->height
- 2 * box_line_width
);
2011 s
->background_filled_p
= 1;
2017 /* Draw the foreground of glyph string S. */
2020 x_draw_glyph_string_foreground (s
)
2021 struct glyph_string
*s
;
2025 /* If first glyph of S has a left box line, start drawing the text
2026 of S to the right of that box line. */
2027 if (s
->face
->box
!= FACE_NO_BOX
2028 && s
->first_glyph
->left_box_line_p
)
2029 x
= s
->x
+ abs (s
->face
->box_line_width
);
2033 /* Draw characters of S as rectangles if S's font could not be
2035 if (s
->font_not_found_p
)
2037 for (i
= 0; i
< s
->nchars
; ++i
)
2039 struct glyph
*g
= s
->first_glyph
+ i
;
2040 mac_draw_rectangle (s
->display
, s
->window
,
2041 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2043 x
+= g
->pixel_width
;
2048 char *char1b
= (char *) s
->char2b
;
2049 int boff
= s
->font_info
->baseline_offset
;
2051 if (s
->font_info
->vertical_centering
)
2052 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2054 /* If we can use 8-bit functions, condense S->char2b. */
2056 for (i
= 0; i
< s
->nchars
; ++i
)
2057 char1b
[i
] = s
->char2b
[i
].byte2
;
2060 /* Draw text with XDrawString if background has already been
2061 filled. Otherwise, use XDrawImageString. (Note that
2062 XDrawImageString is usually faster than XDrawString.) Always
2063 use XDrawImageString when drawing the cursor so that there is
2064 no chance that characters under a box cursor are invisible. */
2065 if (s
->for_overlaps_p
2066 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2069 /* Draw characters with 16-bit or 8-bit functions. */
2071 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2072 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2074 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2075 s
->ybase
- boff
, char1b
, s
->nchars
);
2081 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
2082 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2084 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
2085 s
->ybase
- boff
, char1b
, s
->nchars
);
2091 /* Draw the foreground of composite glyph string S. */
2094 x_draw_composite_glyph_string_foreground (s
)
2095 struct glyph_string
*s
;
2099 /* If first glyph of S has a left box line, start drawing the text
2100 of S to the right of that box line. */
2101 if (s
->face
->box
!= FACE_NO_BOX
2102 && s
->first_glyph
->left_box_line_p
)
2103 x
= s
->x
+ abs (s
->face
->box_line_width
);
2107 /* S is a glyph string for a composition. S->gidx is the index of
2108 the first character drawn for glyphs of this composition.
2109 S->gidx == 0 means we are drawing the very first character of
2110 this composition. */
2112 /* Draw a rectangle for the composition if the font for the very
2113 first character of the composition could not be loaded. */
2114 if (s
->font_not_found_p
)
2117 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2118 s
->width
- 1, s
->height
- 1);
2122 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2123 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2124 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2125 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2131 #ifdef USE_X_TOOLKIT
2133 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2136 /* Return the frame on which widget WIDGET is used.. Abort if frame
2137 cannot be determined. */
2139 static struct frame
*
2140 x_frame_of_widget (widget
)
2143 struct x_display_info
*dpyinfo
;
2147 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2149 /* Find the top-level shell of the widget. Note that this function
2150 can be called when the widget is not yet realized, so XtWindow
2151 (widget) == 0. That's the reason we can't simply use
2152 x_any_window_to_frame. */
2153 while (!XtIsTopLevelShell (widget
))
2154 widget
= XtParent (widget
);
2156 /* Look for a frame with that top-level widget. Allocate the color
2157 on that frame to get the right gamma correction value. */
2158 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2159 if (GC_FRAMEP (XCAR (tail
))
2160 && (f
= XFRAME (XCAR (tail
)),
2161 (f
->output_data
.nothing
!= 1
2162 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2163 && f
->output_data
.x
->widget
== widget
)
2170 /* Allocate the color COLOR->pixel on the screen and display of
2171 widget WIDGET in colormap CMAP. If an exact match cannot be
2172 allocated, try the nearest color available. Value is non-zero
2173 if successful. This is called from lwlib. */
2176 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2181 struct frame
*f
= x_frame_of_widget (widget
);
2182 return x_alloc_nearest_color (f
, cmap
, color
);
2186 #endif /* USE_X_TOOLKIT */
2188 #if 0 /* MAC_TODO */
2190 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2191 CMAP. If an exact match can't be allocated, try the nearest color
2192 available. Value is non-zero if successful. Set *COLOR to the
2196 x_alloc_nearest_color (f
, cmap
, color
)
2201 Display
*display
= FRAME_X_DISPLAY (f
);
2202 Screen
*screen
= FRAME_X_SCREEN (f
);
2205 gamma_correct (f
, color
);
2206 rc
= XAllocColor (display
, cmap
, color
);
2209 /* If we got to this point, the colormap is full, so we're going
2210 to try to get the next closest color. The algorithm used is
2211 a least-squares matching, which is what X uses for closest
2212 color matching with StaticColor visuals. */
2214 unsigned long nearest_delta
= ~0;
2215 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2216 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2218 for (i
= 0; i
< ncells
; ++i
)
2220 XQueryColors (display
, cmap
, cells
, ncells
);
2222 for (nearest
= i
= 0; i
< ncells
; ++i
)
2224 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2225 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2226 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2227 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2229 if (delta
< nearest_delta
)
2232 nearest_delta
= delta
;
2236 color
->red
= cells
[nearest
].red
;
2237 color
->green
= cells
[nearest
].green
;
2238 color
->blue
= cells
[nearest
].blue
;
2239 rc
= XAllocColor (display
, cmap
, color
);
2242 #ifdef DEBUG_X_COLORS
2244 register_color (color
->pixel
);
2245 #endif /* DEBUG_X_COLORS */
2251 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2252 It's necessary to do this instead of just using PIXEL directly to
2253 get color reference counts right. */
2256 x_copy_color (f
, pixel
)
2258 unsigned long pixel
;
2262 color
.pixel
= pixel
;
2264 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2265 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2267 #ifdef DEBUG_X_COLORS
2268 register_color (pixel
);
2274 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2275 It's necessary to do this instead of just using PIXEL directly to
2276 get color reference counts right. */
2279 x_copy_dpy_color (dpy
, cmap
, pixel
)
2282 unsigned long pixel
;
2286 color
.pixel
= pixel
;
2288 XQueryColor (dpy
, cmap
, &color
);
2289 XAllocColor (dpy
, cmap
, &color
);
2291 #ifdef DEBUG_X_COLORS
2292 register_color (pixel
);
2297 #endif /* MAC_TODO */
2300 /* Brightness beyond which a color won't have its highlight brightness
2303 Nominally, highlight colors for `3d' faces are calculated by
2304 brightening an object's color by a constant scale factor, but this
2305 doesn't yield good results for dark colors, so for colors who's
2306 brightness is less than this value (on a scale of 0-255) have to
2307 use an additional additive factor.
2309 The value here is set so that the default menu-bar/mode-line color
2310 (grey75) will not have its highlights changed at all. */
2311 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2314 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2315 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2316 If this produces the same color as COLOR, try a color where all RGB
2317 values have DELTA added. Return the allocated color in *COLOR.
2318 DISPLAY is the X display, CMAP is the colormap to operate on.
2319 Value is non-zero if successful. */
2322 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2324 unsigned long *color
;
2331 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2334 /* Change RGB values by specified FACTOR. Avoid overflow! */
2335 xassert (factor
>= 0);
2336 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2337 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2338 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2340 /* Calculate brightness of COLOR. */
2341 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2342 + BLUE_FROM_ULONG (*color
)) / 6;
2344 /* We only boost colors that are darker than
2345 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2346 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2347 /* Make an additive adjustment to NEW, because it's dark enough so
2348 that scaling by FACTOR alone isn't enough. */
2350 /* How far below the limit this color is (0 - 1, 1 being darker). */
2351 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2352 /* The additive adjustment. */
2353 int min_delta
= delta
* dimness
* factor
/ 2;
2356 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2357 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2358 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2360 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2361 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2362 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2366 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2367 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2368 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2370 /* MAC_TODO: Map to palette and retry with delta if same? */
2371 /* MAC_TODO: Free colors (if using palette)? */
2382 /* Set up the foreground color for drawing relief lines of glyph
2383 string S. RELIEF is a pointer to a struct relief containing the GC
2384 with which lines will be drawn. Use a color that is FACTOR or
2385 DELTA lighter or darker than the relief's background which is found
2386 in S->f->output_data.x->relief_background. If such a color cannot
2387 be allocated, use DEFAULT_PIXEL, instead. */
2390 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2392 struct relief
*relief
;
2395 unsigned long default_pixel
;
2398 struct mac_output
*di
= f
->output_data
.mac
;
2399 unsigned long mask
= GCForeground
;
2400 unsigned long pixel
;
2401 unsigned long background
= di
->relief_background
;
2402 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2404 /* MAC_TODO: Free colors (if using palette)? */
2406 /* Allocate new color. */
2407 xgcv
.foreground
= default_pixel
;
2409 if (dpyinfo
->n_planes
!= 1
2410 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2412 relief
->allocated_p
= 1;
2413 xgcv
.foreground
= relief
->pixel
= pixel
;
2416 if (relief
->gc
== 0)
2418 #if 0 /* MAC_TODO: stipple */
2419 xgcv
.stipple
= dpyinfo
->gray
;
2422 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2425 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2429 /* Set up colors for the relief lines around glyph string S. */
2432 x_setup_relief_colors (s
)
2433 struct glyph_string
*s
;
2435 struct mac_output
*di
= s
->f
->output_data
.mac
;
2436 unsigned long color
;
2438 if (s
->face
->use_box_color_for_shadows_p
)
2439 color
= s
->face
->box_color
;
2440 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2442 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2443 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2448 /* Get the background color of the face. */
2449 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2450 color
= xgcv
.background
;
2453 if (di
->white_relief
.gc
== 0
2454 || color
!= di
->relief_background
)
2456 di
->relief_background
= color
;
2457 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2458 WHITE_PIX_DEFAULT (s
->f
));
2459 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2460 BLACK_PIX_DEFAULT (s
->f
));
2465 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2466 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2467 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2468 relief. LEFT_P non-zero means draw a relief on the left side of
2469 the rectangle. RIGHT_P non-zero means draw a relief on the right
2470 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2474 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2475 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2477 int left_x
, top_y
, right_x
, bottom_y
, width
;
2478 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2481 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2482 Window window
= FRAME_MAC_WINDOW (f
);
2487 gc
= f
->output_data
.mac
->white_relief
.gc
;
2489 gc
= f
->output_data
.mac
->black_relief
.gc
;
2490 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2494 for (i
= 0; i
< width
; ++i
)
2495 XDrawLine (dpy
, window
, gc
,
2496 left_x
+ i
* left_p
, top_y
+ i
,
2497 right_x
- i
* right_p
, top_y
+ i
);
2501 for (i
= 0; i
< width
; ++i
)
2502 XDrawLine (dpy
, window
, gc
,
2503 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2505 mac_reset_clipping (dpy
, window
);
2507 gc
= f
->output_data
.mac
->black_relief
.gc
;
2509 gc
= f
->output_data
.mac
->white_relief
.gc
;
2510 mac_set_clip_rectangle (dpy
, window
,
2515 for (i
= 0; i
< width
; ++i
)
2516 XDrawLine (dpy
, window
, gc
,
2517 left_x
+ i
* left_p
, bottom_y
- i
,
2518 right_x
- i
* right_p
, bottom_y
- i
);
2522 for (i
= 0; i
< width
; ++i
)
2523 XDrawLine (dpy
, window
, gc
,
2524 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2526 mac_reset_clipping (dpy
, window
);
2530 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2531 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2532 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2533 left side of the rectangle. RIGHT_P non-zero means draw a line
2534 on the right side of the rectangle. CLIP_RECT is the clipping
2535 rectangle to use when drawing. */
2538 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2539 left_p
, right_p
, clip_rect
)
2540 struct glyph_string
*s
;
2541 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2546 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2547 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
2548 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2551 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2552 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2556 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2557 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2560 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2561 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2565 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2566 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2568 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2569 mac_reset_clipping (s
->display
, s
->window
);
2573 /* Draw a box around glyph string S. */
2576 x_draw_glyph_string_box (s
)
2577 struct glyph_string
*s
;
2579 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2580 int left_p
, right_p
;
2581 struct glyph
*last_glyph
;
2584 last_x
= ((s
->row
->full_width_p
&& !s
->w
->pseudo_window_p
)
2585 ? WINDOW_RIGHT_EDGE_X (s
->w
)
2586 : window_box_right (s
->w
, s
->area
));
2588 /* The glyph that may have a right box line. */
2589 last_glyph
= (s
->cmp
|| s
->img
2591 : s
->first_glyph
+ s
->nchars
- 1);
2593 width
= abs (s
->face
->box_line_width
);
2594 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2596 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2598 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2600 bottom_y
= top_y
+ s
->height
- 1;
2602 left_p
= (s
->first_glyph
->left_box_line_p
2603 || (s
->hl
== DRAW_MOUSE_FACE
2605 || s
->prev
->hl
!= s
->hl
)));
2606 right_p
= (last_glyph
->right_box_line_p
2607 || (s
->hl
== DRAW_MOUSE_FACE
2609 || s
->next
->hl
!= s
->hl
)));
2611 get_glyph_string_clip_rect (s
, &clip_rect
);
2613 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2614 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2615 left_p
, right_p
, &clip_rect
);
2618 x_setup_relief_colors (s
);
2619 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2620 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2625 /* Draw foreground of image glyph string S. */
2628 x_draw_image_foreground (s
)
2629 struct glyph_string
*s
;
2632 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2634 /* If first glyph of S has a left box line, start drawing it to the
2635 right of that line. */
2636 if (s
->face
->box
!= FACE_NO_BOX
2637 && s
->first_glyph
->left_box_line_p
2639 x
+= abs (s
->face
->box_line_width
);
2641 /* If there is a margin around the image, adjust x- and y-position
2643 if (s
->slice
.x
== 0)
2644 x
+= s
->img
->hmargin
;
2645 if (s
->slice
.y
== 0)
2646 y
+= s
->img
->vmargin
;
2650 x_set_glyph_string_clipping (s
);
2653 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2654 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2655 s
->slice
.width
, s
->slice
.height
, x
, y
);
2658 mac_copy_area (s
->display
, s
->img
->pixmap
,
2659 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2660 s
->slice
.width
, s
->slice
.height
, x
, y
);
2662 /* When the image has a mask, we can expect that at
2663 least part of a mouse highlight or a block cursor will
2664 be visible. If the image doesn't have a mask, make
2665 a block cursor visible by drawing a rectangle around
2666 the image. I believe it's looking better if we do
2667 nothing here for mouse-face. */
2668 if (s
->hl
== DRAW_CURSOR
)
2670 int r
= s
->img
->relief
;
2672 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
2674 s
->slice
.width
+ r
*2 - 1,
2675 s
->slice
.height
+ r
*2 - 1);
2680 /* Draw a rectangle if image could not be loaded. */
2681 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2682 s
->slice
.width
- 1, s
->slice
.height
- 1);
2686 /* Draw a relief around the image glyph string S. */
2689 x_draw_image_relief (s
)
2690 struct glyph_string
*s
;
2692 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2695 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2697 /* If first glyph of S has a left box line, start drawing it to the
2698 right of that line. */
2699 if (s
->face
->box
!= FACE_NO_BOX
2700 && s
->first_glyph
->left_box_line_p
2702 x
+= abs (s
->face
->box_line_width
);
2704 /* If there is a margin around the image, adjust x- and y-position
2706 if (s
->slice
.x
== 0)
2707 x
+= s
->img
->hmargin
;
2708 if (s
->slice
.y
== 0)
2709 y
+= s
->img
->vmargin
;
2711 if (s
->hl
== DRAW_IMAGE_SUNKEN
2712 || s
->hl
== DRAW_IMAGE_RAISED
)
2714 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2715 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2719 thick
= abs (s
->img
->relief
);
2720 raised_p
= s
->img
->relief
> 0;
2725 x1
= x
+ s
->slice
.width
+ thick
- 1;
2726 y1
= y
+ s
->slice
.height
+ thick
- 1;
2728 x_setup_relief_colors (s
);
2729 get_glyph_string_clip_rect (s
, &r
);
2730 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
2732 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
2734 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
2739 #if 0 /* TODO: figure out if we need to do this on Mac. */
2740 /* Draw the foreground of image glyph string S to PIXMAP. */
2743 x_draw_image_foreground_1 (s
, pixmap
)
2744 struct glyph_string
*s
;
2748 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2750 /* If first glyph of S has a left box line, start drawing it to the
2751 right of that line. */
2752 if (s
->face
->box
!= FACE_NO_BOX
2753 && s
->first_glyph
->left_box_line_p
2755 x
+= abs (s
->face
->box_line_width
);
2757 /* If there is a margin around the image, adjust x- and y-position
2759 if (s
->slice
.x
== 0)
2760 x
+= s
->img
->hmargin
;
2761 if (s
->slice
.y
== 0)
2762 y
+= s
->img
->vmargin
;
2767 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2768 s
->img
->mask
, pixmap
, s
->gc
,
2769 s
->slice
.x
, s
->slice
.y
,
2770 s
->slice
.width
, s
->slice
.height
,
2774 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2775 s
->slice
.x
, s
->slice
.y
,
2776 s
->slice
.width
, s
->slice
.height
,
2779 /* When the image has a mask, we can expect that at
2780 least part of a mouse highlight or a block cursor will
2781 be visible. If the image doesn't have a mask, make
2782 a block cursor visible by drawing a rectangle around
2783 the image. I believe it's looking better if we do
2784 nothing here for mouse-face. */
2785 if (s
->hl
== DRAW_CURSOR
)
2787 int r
= s
->img
->relief
;
2789 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2790 s
->slice
.width
+ r
*2 - 1,
2791 s
->slice
.height
+ r
*2 - 1);
2796 /* Draw a rectangle if image could not be loaded. */
2797 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2798 s
->slice
.width
- 1, s
->slice
.height
- 1);
2803 /* Draw part of the background of glyph string S. X, Y, W, and H
2804 give the rectangle to draw. */
2807 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2808 struct glyph_string
*s
;
2811 #if 0 /* MAC_TODO: stipple */
2814 /* Fill background with a stipple pattern. */
2815 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2816 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2817 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2820 #endif /* MAC_TODO */
2821 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2825 /* Draw image glyph string S.
2828 s->x +-------------------------
2831 | +-------------------------
2834 | | +-------------------
2840 x_draw_image_glyph_string (s
)
2841 struct glyph_string
*s
;
2844 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2845 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2849 height
= s
->height
- 2 * box_line_vwidth
;
2852 /* Fill background with face under the image. Do it only if row is
2853 taller than image or if image has a clip mask to reduce
2855 s
->stippled_p
= s
->face
->stipple
!= 0;
2856 if (height
> s
->slice
.height
2860 || s
->img
->pixmap
== 0
2861 || s
->width
!= s
->background_width
)
2864 if (s
->first_glyph
->left_box_line_p
2866 x
+= box_line_hwidth
;
2869 if (s
->slice
.y
== 0)
2870 y
+= box_line_vwidth
;
2872 #if 0 /* TODO: figure out if we need to do this on Mac. */
2875 /* Create a pixmap as large as the glyph string. Fill it
2876 with the background color. Copy the image to it, using
2877 its mask. Copy the temporary pixmap to the display. */
2878 int depth
= one_mac_display_info
.n_planes
;
2880 /* Create a pixmap as large as the glyph string. */
2881 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2882 s
->background_width
,
2885 /* Fill the pixmap with the background color/stipple. */
2886 #if 0 /* TODO: stipple */
2889 /* Fill background with a stipple pattern. */
2890 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2891 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2892 0, 0, s
->background_width
, s
->height
);
2893 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2899 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2901 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2902 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2903 0, 0, s
->background_width
,
2905 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2910 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2912 s
->background_filled_p
= 1;
2915 /* Draw the foreground. */
2916 #if 0 /* TODO: figure out if we need to do this on Mac. */
2919 x_draw_image_foreground_1 (s
, pixmap
);
2920 x_set_glyph_string_clipping (s
);
2921 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2922 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2923 mac_reset_clipping (s
->display
, s
->window
);
2924 XFreePixmap (s
->display
, pixmap
);
2928 x_draw_image_foreground (s
);
2930 /* If we must draw a relief around the image, do it. */
2932 || s
->hl
== DRAW_IMAGE_RAISED
2933 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2934 x_draw_image_relief (s
);
2938 /* Draw stretch glyph string S. */
2941 x_draw_stretch_glyph_string (s
)
2942 struct glyph_string
*s
;
2944 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2945 s
->stippled_p
= s
->face
->stipple
!= 0;
2947 if (s
->hl
== DRAW_CURSOR
2948 && !x_stretch_cursor_p
)
2950 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2951 as wide as the stretch glyph. */
2952 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2955 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2957 /* Clear rest using the GC of the original non-cursor face. */
2958 if (width
< s
->background_width
)
2960 int x
= s
->x
+ width
, y
= s
->y
;
2961 int w
= s
->background_width
- width
, h
= s
->height
;
2965 if (s
->row
->mouse_face_p
2966 && cursor_in_mouse_face_p (s
->w
))
2968 x_set_mouse_face_gc (s
);
2974 get_glyph_string_clip_rect (s
, &r
);
2975 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2977 #if 0 /* MAC_TODO: stipple */
2978 if (s
->face
->stipple
)
2980 /* Fill background with a stipple pattern. */
2981 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2982 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2983 XSetFillStyle (s
->display
, gc
, FillSolid
);
2986 #endif /* MAC_TODO */
2987 mac_erase_rectangle (s
->window
, gc
, x
, y
, w
, h
);
2989 mac_reset_clipping (s
->display
, s
->window
);
2992 else if (!s
->background_filled_p
)
2993 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
2996 s
->background_filled_p
= 1;
3000 /* Draw glyph string S. */
3003 x_draw_glyph_string (s
)
3004 struct glyph_string
*s
;
3006 int relief_drawn_p
= 0;
3008 /* If S draws into the background of its successor that does not
3009 draw a cursor, draw the background of the successor first so that
3010 S can draw into it. This makes S->next use XDrawString instead
3011 of XDrawImageString. */
3012 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
3013 && s
->next
->hl
!= DRAW_CURSOR
)
3015 xassert (s
->next
->img
== NULL
);
3016 x_set_glyph_string_gc (s
->next
);
3017 x_set_glyph_string_clipping (s
->next
);
3018 x_draw_glyph_string_background (s
->next
, 1);
3021 /* Set up S->gc, set clipping and draw S. */
3022 x_set_glyph_string_gc (s
);
3024 /* Draw relief (if any) in advance for char/composition so that the
3025 glyph string can be drawn over it. */
3026 if (!s
->for_overlaps_p
3027 && s
->face
->box
!= FACE_NO_BOX
3028 && (s
->first_glyph
->type
== CHAR_GLYPH
3029 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3032 x_set_glyph_string_clipping (s
);
3033 x_draw_glyph_string_background (s
, 1);
3034 x_draw_glyph_string_box (s
);
3035 x_set_glyph_string_clipping (s
);
3039 x_set_glyph_string_clipping (s
);
3041 switch (s
->first_glyph
->type
)
3044 x_draw_image_glyph_string (s
);
3048 x_draw_stretch_glyph_string (s
);
3052 if (s
->for_overlaps_p
)
3053 s
->background_filled_p
= 1;
3055 x_draw_glyph_string_background (s
, 0);
3056 x_draw_glyph_string_foreground (s
);
3059 case COMPOSITE_GLYPH
:
3060 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3061 s
->background_filled_p
= 1;
3063 x_draw_glyph_string_background (s
, 1);
3064 x_draw_composite_glyph_string_foreground (s
);
3071 if (!s
->for_overlaps_p
)
3073 /* Draw underline. */
3074 if (s
->face
->underline_p
)
3076 unsigned long h
= 1;
3077 unsigned long dy
= s
->height
- h
;
3079 if (s
->face
->underline_defaulted_p
)
3080 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3085 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3086 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3087 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3089 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3093 /* Draw overline. */
3094 if (s
->face
->overline_p
)
3096 unsigned long dy
= 0, h
= 1;
3098 if (s
->face
->overline_color_defaulted_p
)
3099 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3104 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3105 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3106 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3108 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3112 /* Draw strike-through. */
3113 if (s
->face
->strike_through_p
)
3115 unsigned long h
= 1;
3116 unsigned long dy
= (s
->height
- h
) / 2;
3118 if (s
->face
->strike_through_color_defaulted_p
)
3119 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3124 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3125 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3126 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3128 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3132 /* Draw relief if not yet drawn. */
3133 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3134 x_draw_glyph_string_box (s
);
3137 /* Reset clipping. */
3138 mac_reset_clipping (s
->display
, s
->window
);
3141 /* Shift display to make room for inserted glyphs. */
3144 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3146 int x
, y
, width
, height
, shift_by
;
3148 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3149 f
->output_data
.mac
->normal_gc
,
3150 x
, y
, width
, height
,
3154 /* Delete N glyphs at the nominal cursor position. Not implemented
3165 /* Clear entire frame. If updating_frame is non-null, clear that
3166 frame. Otherwise clear the selected frame. */
3176 f
= SELECTED_FRAME ();
3178 /* Clearing the frame will erase any cursor, so mark them all as no
3180 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3181 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3182 output_cursor
.x
= -1;
3184 /* We don't set the output cursor here because there will always
3185 follow an explicit cursor_to. */
3187 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3189 /* We have to clear the scroll bars, too. If we have changed
3190 colors or something like that, then they should be notified. */
3191 x_scroll_bar_clear (f
);
3193 XFlush (FRAME_MAC_DISPLAY (f
));
3199 /* Invert the middle quarter of the frame for .15 sec. */
3201 /* We use the select system call to do the waiting, so we have to make
3202 sure it's available. If it isn't, we just won't do visual bells. */
3204 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3207 /* Subtract the `struct timeval' values X and Y, storing the result in
3208 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3211 timeval_subtract (result
, x
, y
)
3212 struct timeval
*result
, x
, y
;
3214 /* Perform the carry for the later subtraction by updating y. This
3215 is safer because on some systems the tv_sec member is unsigned. */
3216 if (x
.tv_usec
< y
.tv_usec
)
3218 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3219 y
.tv_usec
-= 1000000 * nsec
;
3223 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3225 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3226 y
.tv_usec
+= 1000000 * nsec
;
3230 /* Compute the time remaining to wait. tv_usec is certainly
3232 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3233 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3235 /* Return indication of whether the result should be considered
3237 return x
.tv_sec
< y
.tv_sec
;
3249 struct timeval wakeup
;
3251 EMACS_GET_TIME (wakeup
);
3253 /* Compute time to wait until, propagating carry from usecs. */
3254 wakeup
.tv_usec
+= 150000;
3255 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3256 wakeup
.tv_usec
%= 1000000;
3258 /* Keep waiting until past the time wakeup. */
3261 struct timeval timeout
;
3263 EMACS_GET_TIME (timeout
);
3265 /* In effect, timeout = wakeup - timeout.
3266 Break if result would be negative. */
3267 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3270 /* Try to wait that long--but we might wake up sooner. */
3271 select (0, NULL
, NULL
, NULL
, &timeout
);
3280 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3283 /* Make audible bell. */
3288 struct frame
*f
= SELECTED_FRAME ();
3290 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3298 XFlush (FRAME_MAC_DISPLAY (f
));
3304 /* Specify how many text lines, from the top of the window,
3305 should be affected by insert-lines and delete-lines operations.
3306 This, and those operations, are used only within an update
3307 that is bounded by calls to x_update_begin and x_update_end. */
3310 XTset_terminal_window (n
)
3313 /* This function intentionally left blank. */
3318 /***********************************************************************
3320 ***********************************************************************/
3322 /* Perform an insert-lines or delete-lines operation, inserting N
3323 lines or deleting -N lines at vertical position VPOS. */
3326 x_ins_del_lines (vpos
, n
)
3333 /* Scroll part of the display as described by RUN. */
3336 x_scroll_run (w
, run
)
3340 struct frame
*f
= XFRAME (w
->frame
);
3341 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3343 /* Get frame-relative bounding box of the text display area of W,
3344 without mode lines. Include in this box the left and right
3346 window_box (w
, -1, &x
, &y
, &width
, &height
);
3348 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3349 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3350 bottom_y
= y
+ height
;
3354 /* Scrolling up. Make sure we don't copy part of the mode
3355 line at the bottom. */
3356 if (from_y
+ run
->height
> bottom_y
)
3357 height
= bottom_y
- from_y
;
3359 height
= run
->height
;
3363 /* Scolling down. Make sure we don't copy over the mode line.
3365 if (to_y
+ run
->height
> bottom_y
)
3366 height
= bottom_y
- to_y
;
3368 height
= run
->height
;
3373 /* Cursor off. Will be switched on again in x_update_window_end. */
3377 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3378 f
->output_data
.mac
->normal_gc
,
3388 /***********************************************************************
3390 ***********************************************************************/
3398 ControlRef root_control
;
3401 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
3403 ActivateControl (root_control
);
3405 x_update_cursor (f
, 1);
3409 frame_unhighlight (f
)
3413 ControlRef root_control
;
3416 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
3418 DeactivateControl (root_control
);
3420 x_update_cursor (f
, 1);
3423 /* The focus has changed. Update the frames as necessary to reflect
3424 the new situation. Note that we can't change the selected frame
3425 here, because the Lisp code we are interrupting might become confused.
3426 Each event gets marked with the frame in which it occurred, so the
3427 Lisp code can tell when the switch took place by examining the events. */
3430 x_new_focus_frame (dpyinfo
, frame
)
3431 struct x_display_info
*dpyinfo
;
3432 struct frame
*frame
;
3434 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3436 if (frame
!= dpyinfo
->x_focus_frame
)
3438 /* Set this before calling other routines, so that they see
3439 the correct value of x_focus_frame. */
3440 dpyinfo
->x_focus_frame
= frame
;
3442 if (old_focus
&& old_focus
->auto_lower
)
3443 x_lower_frame (old_focus
);
3446 selected_frame
= frame
;
3447 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3449 Fselect_window (selected_frame
->selected_window
, Qnil
);
3450 choose_minibuf_frame ();
3453 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3454 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3456 pending_autoraise_frame
= 0;
3459 x_frame_rehighlight (dpyinfo
);
3462 /* Handle FocusIn and FocusOut state changes for FRAME.
3463 If FRAME has focus and there exists more than one frame, puts
3464 a FOCUS_IN_EVENT into *BUFP. */
3467 mac_focus_changed (type
, dpyinfo
, frame
, bufp
)
3469 struct mac_display_info
*dpyinfo
;
3470 struct frame
*frame
;
3471 struct input_event
*bufp
;
3473 if (type
== activeFlag
)
3475 if (dpyinfo
->x_focus_event_frame
!= frame
)
3477 x_new_focus_frame (dpyinfo
, frame
);
3478 dpyinfo
->x_focus_event_frame
= frame
;
3480 /* Don't stop displaying the initial startup message
3481 for a switch-frame event we don't need. */
3482 if (GC_NILP (Vterminal_frame
)
3483 && GC_CONSP (Vframe_list
)
3484 && !GC_NILP (XCDR (Vframe_list
)))
3486 bufp
->kind
= FOCUS_IN_EVENT
;
3487 XSETFRAME (bufp
->frame_or_window
, frame
);
3493 if (dpyinfo
->x_focus_event_frame
== frame
)
3495 dpyinfo
->x_focus_event_frame
= 0;
3496 x_new_focus_frame (dpyinfo
, 0);
3501 /* The focus may have changed. Figure out if it is a real focus change,
3502 by checking both FocusIn/Out and Enter/LeaveNotify events.
3504 Returns FOCUS_IN_EVENT event in *BUFP. */
3507 x_detect_focus_change (dpyinfo
, event
, bufp
)
3508 struct mac_display_info
*dpyinfo
;
3510 struct input_event
*bufp
;
3512 struct frame
*frame
;
3514 frame
= mac_window_to_frame ((WindowPtr
) event
->message
);
3518 /* On Mac, this is only called from focus events, so no switch needed. */
3519 mac_focus_changed ((event
->modifiers
& activeFlag
),
3520 dpyinfo
, frame
, bufp
);
3524 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3527 x_mouse_leave (dpyinfo
)
3528 struct x_display_info
*dpyinfo
;
3530 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3533 /* The focus has changed, or we have redirected a frame's focus to
3534 another frame (this happens when a frame uses a surrogate
3535 mini-buffer frame). Shift the highlight as appropriate.
3537 The FRAME argument doesn't necessarily have anything to do with which
3538 frame is being highlighted or un-highlighted; we only use it to find
3539 the appropriate X display info. */
3542 XTframe_rehighlight (frame
)
3543 struct frame
*frame
;
3545 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3549 x_frame_rehighlight (dpyinfo
)
3550 struct x_display_info
*dpyinfo
;
3552 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3554 if (dpyinfo
->x_focus_frame
)
3556 dpyinfo
->x_highlight_frame
3557 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3558 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3559 : dpyinfo
->x_focus_frame
);
3560 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3562 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3563 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3567 dpyinfo
->x_highlight_frame
= 0;
3569 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3572 frame_unhighlight (old_highlight
);
3573 if (dpyinfo
->x_highlight_frame
)
3574 frame_highlight (dpyinfo
->x_highlight_frame
);
3580 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3582 #if 0 /* MAC_TODO */
3583 /* Initialize mode_switch_bit and modifier_meaning. */
3585 x_find_modifier_meanings (dpyinfo
)
3586 struct x_display_info
*dpyinfo
;
3588 int min_code
, max_code
;
3591 XModifierKeymap
*mods
;
3593 dpyinfo
->meta_mod_mask
= 0;
3594 dpyinfo
->shift_lock_mask
= 0;
3595 dpyinfo
->alt_mod_mask
= 0;
3596 dpyinfo
->super_mod_mask
= 0;
3597 dpyinfo
->hyper_mod_mask
= 0;
3600 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3602 min_code
= dpyinfo
->display
->min_keycode
;
3603 max_code
= dpyinfo
->display
->max_keycode
;
3606 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3607 min_code
, max_code
- min_code
+ 1,
3609 mods
= XGetModifierMapping (dpyinfo
->display
);
3611 /* Scan the modifier table to see which modifier bits the Meta and
3612 Alt keysyms are on. */
3614 int row
, col
; /* The row and column in the modifier table. */
3616 for (row
= 3; row
< 8; row
++)
3617 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3620 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3622 /* Zeroes are used for filler. Skip them. */
3626 /* Are any of this keycode's keysyms a meta key? */
3630 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3632 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3638 dpyinfo
->meta_mod_mask
|= (1 << row
);
3643 dpyinfo
->alt_mod_mask
|= (1 << row
);
3648 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3653 dpyinfo
->super_mod_mask
|= (1 << row
);
3657 /* Ignore this if it's not on the lock modifier. */
3658 if ((1 << row
) == LockMask
)
3659 dpyinfo
->shift_lock_mask
= LockMask
;
3667 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3668 if (! dpyinfo
->meta_mod_mask
)
3670 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3671 dpyinfo
->alt_mod_mask
= 0;
3674 /* If some keys are both alt and meta,
3675 make them just meta, not alt. */
3676 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3678 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3681 XFree ((char *) syms
);
3682 XFreeModifiermap (mods
);
3685 #endif /* MAC_TODO */
3687 /* Convert between the modifier bits X uses and the modifier bits
3691 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3692 struct x_display_info
*dpyinfo
;
3693 unsigned short state
;
3695 return (((state
& shiftKey
) ? shift_modifier
: 0)
3696 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3697 | ((state
& cmdKey
) ? meta_modifier
: 0)
3698 | ((state
& optionKey
) ? alt_modifier
: 0));
3701 #if 0 /* MAC_TODO */
3702 static unsigned short
3703 x_emacs_to_x_modifiers (dpyinfo
, state
)
3704 struct x_display_info
*dpyinfo
;
3707 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3708 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3709 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3710 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3711 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3712 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3714 #endif /* MAC_TODO */
3716 /* Convert a keysym to its name. */
3719 x_get_keysym_name (keysym
)
3726 value
= XKeysymToString (keysym
);
3737 /* Function to report a mouse movement to the mainstream Emacs code.
3738 The input handler calls this.
3740 We have received a mouse movement event, which is given in *event.
3741 If the mouse is over a different glyph than it was last time, tell
3742 the mainstream emacs code by setting mouse_moved. If not, ask for
3743 another motion event, so we can check again the next time it moves. */
3745 static Point last_mouse_motion_position
;
3746 static Lisp_Object last_mouse_motion_frame
;
3749 note_mouse_movement (frame
, pos
)
3753 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
3754 #if TARGET_API_MAC_CARBON
3758 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3759 last_mouse_motion_position
= *pos
;
3760 XSETFRAME (last_mouse_motion_frame
, frame
);
3762 #if TARGET_API_MAC_CARBON
3763 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3765 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3768 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
3769 /* This case corresponds to LeaveNotify in X11. */
3771 /* If we move outside the frame, then we're certainly no
3772 longer on any text in the frame. */
3773 clear_mouse_face (dpyinfo
);
3774 dpyinfo
->mouse_face_mouse_frame
= 0;
3775 if (!dpyinfo
->grabbed
)
3776 rif
->define_frame_cursor (frame
,
3777 frame
->output_data
.mac
->nontext_cursor
);
3780 /* Has the mouse moved off the glyph it was on at the last sighting? */
3781 else if (pos
->h
< last_mouse_glyph
.left
3782 || pos
->h
>= last_mouse_glyph
.right
3783 || pos
->v
< last_mouse_glyph
.top
3784 || pos
->v
>= last_mouse_glyph
.bottom
)
3786 frame
->mouse_moved
= 1;
3787 last_mouse_scroll_bar
= Qnil
;
3788 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3793 /************************************************************************
3795 ************************************************************************/
3797 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3800 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3803 redo_mouse_highlight ()
3805 if (!NILP (last_mouse_motion_frame
)
3806 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3807 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3808 last_mouse_motion_position
.h
,
3809 last_mouse_motion_position
.v
);
3813 /* Try to determine frame pixel position and size of the glyph under
3814 frame pixel coordinates X/Y on frame F . Return the position and
3815 size in *RECT. Value is non-zero if we could compute these
3819 glyph_rect (f
, x
, y
, rect
)
3826 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3830 struct window
*w
= XWINDOW (window
);
3831 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3832 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3834 for (; r
< end
&& r
->enabled_p
; ++r
)
3835 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3837 /* Found the row at y. */
3838 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3839 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3842 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3843 rect
->bottom
= rect
->top
+ r
->height
;
3847 /* x is to the left of the first glyph in the row. */
3848 /* Shouldn't this be a pixel value?
3849 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3851 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3852 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3856 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3857 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3859 /* x is on a glyph. */
3860 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3861 rect
->right
= rect
->left
+ g
->pixel_width
;
3865 /* x is to the right of the last glyph in the row. */
3866 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3867 /* Shouldn't this be a pixel value?
3868 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3870 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3875 /* The y is not on any row. */
3879 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3881 /* Record the position of the mouse in last_mouse_glyph. */
3883 remember_mouse_glyph (f1
, gx
, gy
)
3887 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3889 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3890 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3892 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3893 round down even for negative values. */
3899 /* This was the original code from XTmouse_position, but it seems
3900 to give the position of the glyph diagonally next to the one
3901 the mouse is over. */
3902 gx
= (gx
+ width
- 1) / width
* width
;
3903 gy
= (gy
+ height
- 1) / height
* height
;
3905 gx
= gx
/ width
* width
;
3906 gy
= gy
/ height
* height
;
3909 last_mouse_glyph
.left
= gx
;
3910 last_mouse_glyph
.top
= gy
;
3911 last_mouse_glyph
.right
= gx
+ width
;
3912 last_mouse_glyph
.bottom
= gy
+ height
;
3917 static struct frame
*
3918 mac_focus_frame (dpyinfo
)
3919 struct mac_display_info
*dpyinfo
;
3921 if (dpyinfo
->x_focus_frame
)
3922 return dpyinfo
->x_focus_frame
;
3924 /* Mac version may get events, such as a menu bar click, even when
3925 all the frames are invisible. In this case, we regard the
3926 event came to the selected frame. */
3927 return SELECTED_FRAME ();
3931 /* Return the current position of the mouse.
3932 *fp should be a frame which indicates which display to ask about.
3934 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3935 and *part to the frame, window, and scroll bar part that the mouse
3936 is over. Set *x and *y to the portion and whole of the mouse's
3937 position on the scroll bar.
3939 If the mouse movement started elsewhere, set *fp to the frame the
3940 mouse is on, *bar_window to nil, and *x and *y to the character cell
3943 Set *time to the server time-stamp for the time at which the mouse
3944 was at this position.
3946 Don't store anything if we don't have a valid set of values to report.
3948 This clears the mouse_moved flag, so we can wait for the next mouse
3952 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3955 Lisp_Object
*bar_window
;
3956 enum scroll_bar_part
*part
;
3958 unsigned long *time
;
3961 int ignore1
, ignore2
;
3962 struct frame
*f
= mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp
));
3963 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
3964 Lisp_Object frame
, tail
;
3968 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3969 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3972 /* Clear the mouse-moved flag for every frame on this display. */
3973 FOR_EACH_FRAME (tail
, frame
)
3974 XFRAME (frame
)->mouse_moved
= 0;
3976 last_mouse_scroll_bar
= Qnil
;
3978 SetPortWindowPort (wp
);
3980 GetMouse (&mouse_pos
);
3982 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3983 &last_mouse_glyph
, insist
);
3986 *part
= scroll_bar_handle
;
3988 XSETINT (*x
, mouse_pos
.h
);
3989 XSETINT (*y
, mouse_pos
.v
);
3990 *time
= last_mouse_movement_time
;
3997 /************************************************************************
3999 ************************************************************************/
4001 #ifdef USE_TOOLKIT_SCROLL_BARS
4003 static pascal void scroll_bar_timer_callback
P_ ((EventLoopTimerRef
, void *));
4004 static OSStatus install_scroll_bar_timer
P_ ((void));
4005 static OSStatus set_scroll_bar_timer
P_ ((EventTimerInterval
));
4006 static int control_part_code_to_scroll_bar_part
P_ ((ControlPartCode
));
4007 static void construct_scroll_bar_click
P_ ((struct scroll_bar
*, int,
4008 struct input_event
*));
4009 static OSErr get_control_part_bounds
P_ ((ControlHandle
, ControlPartCode
,
4011 static void x_scroll_bar_handle_press
P_ ((struct scroll_bar
*,
4013 struct input_event
*));
4014 static void x_scroll_bar_handle_release
P_ ((struct scroll_bar
*,
4015 struct input_event
*));
4016 static void x_scroll_bar_handle_drag
P_ ((WindowPtr
, struct scroll_bar
*,
4017 Point
, struct input_event
*));
4018 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
4021 /* Last scroll bar part sent in x_scroll_bar_handle_*. */
4023 static int last_scroll_bar_part
;
4025 static EventLoopTimerRef scroll_bar_timer
;
4027 static int scroll_bar_timer_event_posted_p
;
4029 #define SCROLL_BAR_FIRST_DELAY 0.5
4030 #define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
4033 scroll_bar_timer_callback (timer
, data
)
4034 EventLoopTimerRef timer
;
4037 EventRef event
= NULL
;
4040 err
= CreateEvent (NULL
, kEventClassMouse
, kEventMouseMoved
, 0,
4041 kEventAttributeNone
, &event
);
4046 GetMouse (&mouse_pos
);
4047 LocalToGlobal (&mouse_pos
);
4048 err
= SetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
4049 sizeof (Point
), &mouse_pos
);
4053 UInt32 modifiers
= GetCurrentKeyModifiers ();
4055 err
= SetEventParameter (event
, kEventParamKeyModifiers
, typeUInt32
,
4056 sizeof (UInt32
), &modifiers
);
4059 err
= PostEventToQueue (GetCurrentEventQueue (), event
,
4060 kEventPriorityStandard
);
4062 scroll_bar_timer_event_posted_p
= 1;
4065 ReleaseEvent (event
);
4069 install_scroll_bar_timer ()
4071 static EventLoopTimerUPP scroll_bar_timer_callbackUPP
= NULL
;
4073 if (scroll_bar_timer_callbackUPP
== NULL
)
4074 scroll_bar_timer_callbackUPP
=
4075 NewEventLoopTimerUPP (scroll_bar_timer_callback
);
4077 if (scroll_bar_timer
== NULL
)
4078 /* Mac OS X and CarbonLib 1.5 and later allow us to specify
4079 kEventDurationForever as delays. */
4081 InstallEventLoopTimer (GetCurrentEventLoop (),
4082 kEventDurationForever
, kEventDurationForever
,
4083 scroll_bar_timer_callbackUPP
, NULL
,
4088 set_scroll_bar_timer (delay
)
4089 EventTimerInterval delay
;
4091 if (scroll_bar_timer
== NULL
)
4092 install_scroll_bar_timer ();
4094 scroll_bar_timer_event_posted_p
= 0;
4096 return SetEventLoopTimerNextFireTime (scroll_bar_timer
, delay
);
4100 control_part_code_to_scroll_bar_part (part_code
)
4101 ControlPartCode part_code
;
4105 case kControlUpButtonPart
: return scroll_bar_up_arrow
;
4106 case kControlDownButtonPart
: return scroll_bar_down_arrow
;
4107 case kControlPageUpPart
: return scroll_bar_above_handle
;
4108 case kControlPageDownPart
: return scroll_bar_below_handle
;
4109 case kControlIndicatorPart
: return scroll_bar_handle
;
4116 construct_scroll_bar_click (bar
, part
, bufp
)
4117 struct scroll_bar
*bar
;
4119 struct input_event
*bufp
;
4121 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4122 bufp
->frame_or_window
= bar
->window
;
4126 XSETINT (bufp
->x
, 0);
4127 XSETINT (bufp
->y
, 0);
4128 bufp
->modifiers
= 0;
4132 get_control_part_bounds (ch
, part_code
, rect
)
4134 ControlPartCode part_code
;
4137 RgnHandle region
= NewRgn ();
4140 err
= GetControlRegion (ch
, part_code
, region
);
4142 GetRegionBounds (region
, rect
);
4143 DisposeRgn (region
);
4149 x_scroll_bar_handle_press (bar
, part_code
, bufp
)
4150 struct scroll_bar
*bar
;
4151 ControlPartCode part_code
;
4152 struct input_event
*bufp
;
4154 int part
= control_part_code_to_scroll_bar_part (part_code
);
4159 if (part
!= scroll_bar_handle
)
4161 construct_scroll_bar_click (bar
, part
, bufp
);
4162 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4163 set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY
);
4166 last_scroll_bar_part
= part
;
4167 bar
->dragging
= Qnil
;
4168 tracked_scroll_bar
= bar
;
4172 x_scroll_bar_handle_release (bar
, bufp
)
4173 struct scroll_bar
*bar
;
4174 struct input_event
*bufp
;
4176 if (last_scroll_bar_part
!= scroll_bar_handle
4177 || !GC_NILP (bar
->dragging
))
4178 construct_scroll_bar_click (bar
, scroll_bar_end_scroll
, bufp
);
4180 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4181 set_scroll_bar_timer (kEventDurationForever
);
4183 last_scroll_bar_part
= -1;
4184 bar
->dragging
= Qnil
;
4185 tracked_scroll_bar
= NULL
;
4189 x_scroll_bar_handle_drag (win
, bar
, mouse_pos
, bufp
)
4191 struct scroll_bar
*bar
;
4193 struct input_event
*bufp
;
4195 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4197 if (last_scroll_bar_part
== scroll_bar_handle
)
4202 get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar
),
4203 kControlIndicatorPart
, &r
);
4205 if (GC_NILP (bar
->dragging
))
4206 XSETINT (bar
->dragging
, mouse_pos
.v
- r
.top
);
4208 top
= mouse_pos
.v
- XINT (bar
->dragging
) - XINT (bar
->track_top
);
4209 top_range
= (XINT (bar
->track_height
) - (r
.bottom
- r
.top
)) *
4210 (1.0 + (float) GetControlViewSize (ch
) / GetControl32BitMaximum (ch
))
4215 if (top
> top_range
)
4218 construct_scroll_bar_click (bar
, scroll_bar_handle
, bufp
);
4219 XSETINT (bufp
->x
, top
);
4220 XSETINT (bufp
->y
, top_range
);
4224 ControlPartCode part_code
;
4225 int unhilite_p
= 0, part
;
4227 if (ch
!= FindControlUnderMouse (mouse_pos
, win
, &part_code
))
4231 part
= control_part_code_to_scroll_bar_part (part_code
);
4233 switch (last_scroll_bar_part
)
4235 case scroll_bar_above_handle
:
4236 case scroll_bar_below_handle
:
4237 if (part
!= scroll_bar_above_handle
4238 && part
!= scroll_bar_below_handle
)
4242 case scroll_bar_up_arrow
:
4243 case scroll_bar_down_arrow
:
4244 if (part
!= scroll_bar_up_arrow
4245 && part
!= scroll_bar_down_arrow
)
4252 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4253 else if (part
!= last_scroll_bar_part
4254 || scroll_bar_timer_event_posted_p
)
4256 construct_scroll_bar_click (bar
, part
, bufp
);
4257 last_scroll_bar_part
= part
;
4258 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4259 set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY
);
4264 /* Set the thumb size and position of scroll bar BAR. We are currently
4265 displaying PORTION out of a whole WHOLE, and our position POSITION. */
4268 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
4269 struct scroll_bar
*bar
;
4270 int portion
, position
, whole
;
4272 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4274 int value
, viewsize
, maximum
;
4276 if (whole
== 0 || XINT (bar
->track_height
) == 0)
4277 value
= 0, viewsize
= 1, maximum
= 0;
4282 maximum
= max (0, whole
- portion
);
4287 SetControl32BitMinimum (ch
, 0);
4288 SetControl32BitMaximum (ch
, maximum
);
4289 SetControl32BitValue (ch
, value
);
4290 SetControlViewSize (ch
, viewsize
);
4295 #endif /* USE_TOOLKIT_SCROLL_BARS */
4299 /************************************************************************
4300 Scroll bars, general
4301 ************************************************************************/
4303 /* Create a scroll bar and return the scroll bar vector for it. W is
4304 the Emacs window on which to create the scroll bar. TOP, LEFT,
4305 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4308 static struct scroll_bar
*
4309 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4311 int top
, left
, width
, height
, disp_top
, disp_height
;
4313 struct frame
*f
= XFRAME (w
->frame
);
4314 struct scroll_bar
*bar
4315 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4323 r
.right
= left
+ width
;
4324 r
.bottom
= disp_top
+ disp_height
;
4326 #if TARGET_API_MAC_CARBON
4327 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4328 0, 0, 0, kControlScrollBarProc
, (long) bar
);
4330 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4331 0, 0, 0, scrollBarProc
, (long) bar
);
4333 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4335 XSETWINDOW (bar
->window
, w
);
4336 XSETINT (bar
->top
, top
);
4337 XSETINT (bar
->left
, left
);
4338 XSETINT (bar
->width
, width
);
4339 XSETINT (bar
->height
, height
);
4340 XSETINT (bar
->start
, 0);
4341 XSETINT (bar
->end
, 0);
4342 bar
->dragging
= Qnil
;
4343 #ifdef USE_TOOLKIT_SCROLL_BARS
4344 bar
->track_top
= Qnil
;
4345 bar
->track_height
= Qnil
;
4348 /* Add bar to its frame's list of scroll bars. */
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
);
4360 /* Draw BAR's handle in the proper position.
4362 If the handle is already drawn from START to END, don't bother
4363 redrawing it, unless REBUILD is non-zero; in that case, always
4364 redraw it. (REBUILD is handy for drawing the handle after expose
4367 Normally, we want to constrain the start and end of the handle to
4368 fit inside its rectangle, but if the user is dragging the scroll
4369 bar handle, we want to let them drag it down all the way, so that
4370 the bar's top is as far down as it goes; otherwise, there's no way
4371 to move to the very end of the buffer. */
4373 #ifndef USE_TOOLKIT_SCROLL_BARS
4376 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4377 struct scroll_bar
*bar
;
4381 int dragging
= ! NILP (bar
->dragging
);
4382 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4383 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4384 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4385 int length
= end
- start
;
4387 /* If the display is already accurate, do nothing. */
4389 && start
== XINT (bar
->start
)
4390 && end
== XINT (bar
->end
))
4395 /* Make sure the values are reasonable, and try to preserve the
4396 distance between start and end. */
4399 else if (start
> top_range
)
4401 end
= start
+ length
;
4405 else if (end
> top_range
&& ! dragging
)
4408 /* Store the adjusted setting in the scroll bar. */
4409 XSETINT (bar
->start
, start
);
4410 XSETINT (bar
->end
, end
);
4412 /* Clip the end position, just for display. */
4413 if (end
> top_range
)
4416 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4417 top positions, to make sure the handle is always at least that
4418 many pixels tall. */
4419 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4421 SetControlMinimum (ch
, 0);
4422 /* Don't inadvertently activate deactivated scroll bars */
4423 if (GetControlMaximum (ch
) != -1)
4424 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4426 SetControlValue (ch
, start
);
4427 #if TARGET_API_MAC_CARBON
4428 SetControlViewSize (ch
, end
- start
);
4434 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4436 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4440 x_scroll_bar_remove (bar
)
4441 struct scroll_bar
*bar
;
4443 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4447 /* Destroy the Mac scroll bar control */
4448 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4450 /* Disassociate this scroll bar from its window. */
4451 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4457 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4458 that we are displaying PORTION characters out of a total of WHOLE
4459 characters, starting at POSITION. If WINDOW has no scroll bar,
4463 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4465 int portion
, whole
, position
;
4467 struct frame
*f
= XFRAME (w
->frame
);
4468 struct scroll_bar
*bar
;
4469 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4470 int window_y
, window_height
;
4472 /* Get window dimensions. */
4473 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4475 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4476 height
= window_height
;
4478 /* Compute the left edge of the scroll bar area. */
4479 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4481 /* Compute the width of the scroll bar which might be less than
4482 the width of the area reserved for the scroll bar. */
4483 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4484 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4488 /* Compute the left edge of the scroll bar. */
4489 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4492 sb_left
= left
+ width
- sb_width
;
4494 /* Adjustments according to Inside Macintosh to make it look nice */
4496 disp_height
= height
;
4502 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4508 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4511 /* Does the scroll bar exist yet? */
4512 if (NILP (w
->vertical_scroll_bar
))
4515 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4516 left
, top
, width
, height
, 0);
4518 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4520 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4524 /* It may just need to be moved and resized. */
4527 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4528 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4532 /* If already correctly positioned, do nothing. */
4533 if (!(XINT (bar
->left
) == sb_left
4534 && XINT (bar
->top
) == top
4535 && XINT (bar
->width
) == sb_width
4536 && XINT (bar
->height
) == height
))
4538 /* Since toolkit scroll bars are smaller than the space reserved
4539 for them on the frame, we have to clear "under" them. */
4540 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4541 left
, top
, width
, height
, 0);
4544 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4545 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4546 sb_left
- 1, top
, 1, height
, 0);
4550 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4551 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4553 if (sb_width
< disp_height
)
4556 /* Remember new settings. */
4557 XSETINT (bar
->left
, sb_left
);
4558 XSETINT (bar
->top
, top
);
4559 XSETINT (bar
->width
, sb_width
);
4560 XSETINT (bar
->height
, height
);
4561 #ifdef USE_TOOLKIT_SCROLL_BARS
4562 bar
->track_top
= Qnil
;
4563 bar
->track_height
= Qnil
;
4570 #ifdef USE_TOOLKIT_SCROLL_BARS
4571 if (NILP (bar
->track_top
))
4573 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4578 SetControl32BitMinimum (ch
, 0);
4579 SetControl32BitMaximum (ch
, 1);
4580 SetControlViewSize (ch
, 1);
4582 /* Move the scroll bar thumb to the top. */
4583 SetControl32BitValue (ch
, 0);
4584 get_control_part_bounds (ch
, kControlIndicatorPart
, &r0
);
4586 /* Move the scroll bar thumb to the bottom. */
4587 SetControl32BitValue (ch
, 1);
4588 get_control_part_bounds (ch
, kControlIndicatorPart
, &r1
);
4590 UnionRect (&r0
, &r1
, &r0
);
4591 XSETINT (bar
->track_top
, r0
.top
);
4592 XSETINT (bar
->track_height
, r0
.bottom
- r0
.top
);
4597 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
4598 #else /* not USE_TOOLKIT_SCROLL_BARS */
4599 /* Set the scroll bar's current state, unless we're currently being
4601 if (NILP (bar
->dragging
))
4603 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4606 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4609 int start
= ((double) position
* top_range
) / whole
;
4610 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4611 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4614 #endif /* not USE_TOOLKIT_SCROLL_BARS */
4618 /* The following three hooks are used when we're doing a thorough
4619 redisplay of the frame. We don't explicitly know which scroll bars
4620 are going to be deleted, because keeping track of when windows go
4621 away is a real pain - "Can you say set-window-configuration, boys
4622 and girls?" Instead, we just assert at the beginning of redisplay
4623 that *all* scroll bars are to be removed, and then save a scroll bar
4624 from the fiery pit when we actually redisplay its window. */
4626 /* Arrange for all scroll bars on FRAME to be removed at the next call
4627 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4628 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4631 XTcondemn_scroll_bars (frame
)
4634 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4635 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4638 bar
= FRAME_SCROLL_BARS (frame
);
4639 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4640 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4641 XSCROLL_BAR (bar
)->prev
= Qnil
;
4642 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4643 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4644 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4649 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4650 Note that WINDOW isn't necessarily condemned at all. */
4653 XTredeem_scroll_bar (window
)
4654 struct window
*window
;
4656 struct scroll_bar
*bar
;
4659 /* We can't redeem this window's scroll bar if it doesn't have one. */
4660 if (NILP (window
->vertical_scroll_bar
))
4663 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4665 /* Unlink it from the condemned list. */
4666 f
= XFRAME (WINDOW_FRAME (window
));
4667 if (NILP (bar
->prev
))
4669 /* If the prev pointer is nil, it must be the first in one of
4671 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4672 /* It's not condemned. Everything's fine. */
4674 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4675 window
->vertical_scroll_bar
))
4676 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4678 /* If its prev pointer is nil, it must be at the front of
4679 one or the other! */
4683 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4685 if (! NILP (bar
->next
))
4686 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4688 bar
->next
= FRAME_SCROLL_BARS (f
);
4690 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4691 if (! NILP (bar
->next
))
4692 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4695 /* Remove all scroll bars on FRAME that haven't been saved since the
4696 last call to `*condemn_scroll_bars_hook'. */
4699 XTjudge_scroll_bars (f
)
4702 Lisp_Object bar
, next
;
4704 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4706 /* Clear out the condemned list now so we won't try to process any
4707 more events on the hapless scroll bars. */
4708 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4710 for (; ! NILP (bar
); bar
= next
)
4712 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4714 x_scroll_bar_remove (b
);
4717 b
->next
= b
->prev
= Qnil
;
4720 /* Now there should be no references to the condemned scroll bars,
4721 and they should get garbage-collected. */
4725 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4726 is set to something other than NO_EVENT, it is enqueued.
4728 This may be called from a signal handler, so we have to ignore GC
4732 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4733 struct scroll_bar
*bar
;
4734 ControlPartCode part_code
;
4736 struct input_event
*bufp
;
4738 int win_y
, top_range
;
4740 if (! GC_WINDOWP (bar
->window
))
4743 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4744 bufp
->frame_or_window
= bar
->window
;
4747 bar
->dragging
= Qnil
;
4751 case kControlUpButtonPart
:
4752 bufp
->part
= scroll_bar_up_arrow
;
4754 case kControlDownButtonPart
:
4755 bufp
->part
= scroll_bar_down_arrow
;
4757 case kControlPageUpPart
:
4758 bufp
->part
= scroll_bar_above_handle
;
4760 case kControlPageDownPart
:
4761 bufp
->part
= scroll_bar_below_handle
;
4763 #if TARGET_API_MAC_CARBON
4766 case kControlIndicatorPart
:
4768 if (er
->what
== mouseDown
)
4769 bar
->dragging
= make_number (0);
4770 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4771 bufp
->part
= scroll_bar_handle
;
4775 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
4776 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
4778 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4782 if (! NILP (bar
->dragging
))
4783 win_y
-= XINT (bar
->dragging
);
4787 if (win_y
> top_range
)
4790 XSETINT (bufp
->x
, win_y
);
4791 XSETINT (bufp
->y
, top_range
);
4794 #ifndef USE_TOOLKIT_SCROLL_BARS
4796 /* Handle some mouse motion while someone is dragging the scroll bar.
4798 This may be called from a signal handler, so we have to ignore GC
4802 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4803 struct scroll_bar
*bar
;
4807 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4809 last_mouse_movement_time
= t
;
4812 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4814 /* If we're dragging the bar, display it. */
4815 if (! GC_NILP (bar
->dragging
))
4817 /* Where should the handle be now? */
4818 int new_start
= y_pos
- 24;
4820 if (new_start
!= XINT (bar
->start
))
4822 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4824 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4829 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4831 /* Return information to the user about the current position of the mouse
4832 on the scroll bar. */
4835 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4837 Lisp_Object
*bar_window
;
4838 enum scroll_bar_part
*part
;
4840 unsigned long *time
;
4842 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4843 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4844 #if TARGET_API_MAC_CARBON
4845 WindowPtr wp
= GetControlOwner (ch
);
4847 WindowPtr wp
= (*ch
)->contrlOwner
;
4850 struct frame
*f
= mac_window_to_frame (wp
);
4851 int win_y
, top_range
;
4853 SetPortWindowPort (wp
);
4855 GetMouse (&mouse_pos
);
4857 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4858 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4860 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4864 if (! NILP (bar
->dragging
))
4865 win_y
-= XINT (bar
->dragging
);
4869 if (win_y
> top_range
)
4873 *bar_window
= bar
->window
;
4875 if (! NILP (bar
->dragging
))
4876 *part
= scroll_bar_handle
;
4877 else if (win_y
< XINT (bar
->start
))
4878 *part
= scroll_bar_above_handle
;
4879 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4880 *part
= scroll_bar_handle
;
4882 *part
= scroll_bar_below_handle
;
4884 XSETINT (*x
, win_y
);
4885 XSETINT (*y
, top_range
);
4888 last_mouse_scroll_bar
= Qnil
;
4890 *time
= last_mouse_movement_time
;
4894 /* The screen has been cleared so we may have changed foreground or
4895 background colors, and the scroll bars may need to be redrawn.
4896 Clear out the scroll bars, and ask for expose events, so we can
4900 x_scroll_bar_clear (f
)
4903 XTcondemn_scroll_bars (f
);
4904 XTjudge_scroll_bars (f
);
4908 /***********************************************************************
4910 ***********************************************************************/
4912 /* Set clipping for output in glyph row ROW. W is the window in which
4913 we operate. GC is the graphics context to set clipping in.
4915 ROW may be a text row or, e.g., a mode line. Text rows must be
4916 clipped to the interior of the window dedicated to text display,
4917 mode lines must be clipped to the whole window. */
4920 x_clip_to_row (w
, row
, area
, gc
)
4922 struct glyph_row
*row
;
4926 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4928 int window_x
, window_y
, window_width
;
4930 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
4932 clip_rect
.left
= window_x
;
4933 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4934 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4935 clip_rect
.right
= clip_rect
.left
+ window_width
;
4936 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4938 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4942 /* Draw a hollow box cursor on window W in glyph row ROW. */
4945 x_draw_hollow_cursor (w
, row
)
4947 struct glyph_row
*row
;
4949 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4950 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4951 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4954 struct glyph
*cursor_glyph
;
4957 /* Get the glyph the cursor is on. If we can't tell because
4958 the current matrix is invalid or such, give up. */
4959 cursor_glyph
= get_phys_cursor_glyph (w
);
4960 if (cursor_glyph
== NULL
)
4963 /* Compute frame-relative coordinates for phys cursor. */
4964 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4965 y
= get_phys_cursor_geometry (w
, row
, cursor_glyph
, &h
);
4966 wd
= w
->phys_cursor_width
;
4968 /* The foreground of cursor_gc is typically the same as the normal
4969 background color, which can cause the cursor box to be invisible. */
4970 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4971 if (dpyinfo
->scratch_cursor_gc
)
4972 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4974 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4975 GCForeground
, &xgcv
);
4976 gc
= dpyinfo
->scratch_cursor_gc
;
4978 /* Set clipping, draw the rectangle, and reset clipping again. */
4979 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4980 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4981 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4985 /* Draw a bar cursor on window W in glyph row ROW.
4987 Implementation note: One would like to draw a bar cursor with an
4988 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4989 Unfortunately, I didn't find a font yet that has this property set.
4993 x_draw_bar_cursor (w
, row
, width
, kind
)
4995 struct glyph_row
*row
;
4997 enum text_cursor_kinds kind
;
4999 struct frame
*f
= XFRAME (w
->frame
);
5000 struct glyph
*cursor_glyph
;
5002 /* If cursor is out of bounds, don't draw garbage. This can happen
5003 in mini-buffer windows when switching between echo area glyphs
5005 cursor_glyph
= get_phys_cursor_glyph (w
);
5006 if (cursor_glyph
== NULL
)
5009 /* If on an image, draw like a normal cursor. That's usually better
5010 visible than drawing a bar, esp. if the image is large so that
5011 the bar might not be in the window. */
5012 if (cursor_glyph
->type
== IMAGE_GLYPH
)
5014 struct glyph_row
*row
;
5015 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5016 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
5020 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5021 Window window
= FRAME_MAC_WINDOW (f
);
5022 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
5023 unsigned long mask
= GCForeground
| GCBackground
;
5024 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
5027 /* If the glyph's background equals the color we normally draw
5028 the bar cursor in, the bar cursor in its normal color is
5029 invisible. Use the glyph's foreground color instead in this
5030 case, on the assumption that the glyph's colors are chosen so
5031 that the glyph is legible. */
5032 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
5033 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
5035 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5038 XChangeGC (dpy
, gc
, mask
, &xgcv
);
5041 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
5042 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
5046 width
= FRAME_CURSOR_WIDTH (f
);
5047 width
= min (cursor_glyph
->pixel_width
, width
);
5049 w
->phys_cursor_width
= width
;
5050 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5052 if (kind
== BAR_CURSOR
)
5053 XFillRectangle (dpy
, window
, gc
,
5054 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5055 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
5056 width
, row
->height
);
5058 XFillRectangle (dpy
, window
, gc
,
5059 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5060 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
5061 row
->height
- width
),
5062 cursor_glyph
->pixel_width
,
5065 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
5070 /* RIF: Define cursor CURSOR on frame F. */
5073 mac_define_frame_cursor (f
, cursor
)
5077 SetThemeCursor (cursor
);
5081 /* RIF: Clear area on frame F. */
5084 mac_clear_frame_area (f
, x
, y
, width
, height
)
5086 int x
, y
, width
, height
;
5088 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5089 x
, y
, width
, height
, 0);
5093 /* RIF: Draw cursor on window W. */
5096 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
5098 struct glyph_row
*glyph_row
;
5100 int cursor_type
, cursor_width
;
5105 w
->phys_cursor_type
= cursor_type
;
5106 w
->phys_cursor_on_p
= 1;
5108 if (glyph_row
->exact_window_width_line_p
5109 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
5111 glyph_row
->cursor_in_fringe_p
= 1;
5112 draw_fringe_bitmap (w
, glyph_row
, 0);
5115 switch (cursor_type
)
5117 case HOLLOW_BOX_CURSOR
:
5118 x_draw_hollow_cursor (w
, glyph_row
);
5121 case FILLED_BOX_CURSOR
:
5122 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
5126 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
5130 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
5134 w
->phys_cursor_width
= 0;
5146 #if 0 /* MAC_TODO: no icon support yet. */
5148 x_bitmap_icon (f
, icon
)
5154 if (FRAME_W32_WINDOW (f
) == 0)
5158 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
5159 else if (STRINGP (icon
))
5160 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
5161 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
5162 else if (SYMBOLP (icon
))
5166 if (EQ (icon
, intern ("application")))
5167 name
= (LPCTSTR
) IDI_APPLICATION
;
5168 else if (EQ (icon
, intern ("hand")))
5169 name
= (LPCTSTR
) IDI_HAND
;
5170 else if (EQ (icon
, intern ("question")))
5171 name
= (LPCTSTR
) IDI_QUESTION
;
5172 else if (EQ (icon
, intern ("exclamation")))
5173 name
= (LPCTSTR
) IDI_EXCLAMATION
;
5174 else if (EQ (icon
, intern ("asterisk")))
5175 name
= (LPCTSTR
) IDI_ASTERISK
;
5176 else if (EQ (icon
, intern ("winlogo")))
5177 name
= (LPCTSTR
) IDI_WINLOGO
;
5181 hicon
= LoadIcon (NULL
, name
);
5189 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
5194 #endif /* MAC_TODO */
5196 /************************************************************************
5198 ************************************************************************/
5200 /* Display Error Handling functions not used on W32. Listing them here
5201 helps diff stay in step when comparing w32term.c with xterm.c.
5203 x_error_catcher (display, error)
5204 x_catch_errors (dpy)
5205 x_catch_errors_unwind (old_val)
5206 x_check_errors (dpy, format)
5207 x_had_errors_p (dpy)
5208 x_clear_errors (dpy)
5209 x_uncatch_errors (dpy, count)
5211 x_connection_signal (signalnum)
5212 x_connection_closed (dpy, error_message)
5213 x_error_quitter (display, error)
5214 x_error_handler (display, error)
5215 x_io_error_quitter (display)
5220 /* Changing the font of the frame. */
5222 /* Give frame F the font named FONTNAME as its default font, and
5223 return the full name of that font. FONTNAME may be a wildcard
5224 pattern; in that case, we choose some font that fits the pattern.
5225 The return value shows which font we chose. */
5228 x_new_font (f
, fontname
)
5230 register char *fontname
;
5232 struct font_info
*fontp
5233 = FS_LOAD_FONT (f
, 0, fontname
, -1);
5238 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
5239 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
5240 FRAME_FONTSET (f
) = -1;
5242 FRAME_COLUMN_WIDTH (f
) = fontp
->average_width
;
5243 FRAME_SPACE_WIDTH (f
) = fontp
->space_width
;
5244 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
5246 compute_fringe_widths (f
, 1);
5248 /* Compute the scroll bar width in character columns. */
5249 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
5251 int wid
= FRAME_COLUMN_WIDTH (f
);
5252 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
5253 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
5257 int wid
= FRAME_COLUMN_WIDTH (f
);
5258 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
5261 /* Now make the frame display the given font. */
5262 if (FRAME_MAC_WINDOW (f
) != 0)
5264 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
5266 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
5268 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
5271 /* Don't change the size of a tip frame; there's no point in
5272 doing it because it's done in Fx_show_tip, and it leads to
5273 problems because the tip frame has no widget. */
5274 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
5275 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
5278 return build_string (fontp
->full_name
);
5281 /* Give frame F the fontset named FONTSETNAME as its default font, and
5282 return the full name of that fontset. FONTSETNAME may be a wildcard
5283 pattern; in that case, we choose some fontset that fits the pattern.
5284 The return value shows which fontset we chose. */
5287 x_new_fontset (f
, fontsetname
)
5291 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5297 if (FRAME_FONTSET (f
) == fontset
)
5298 /* This fontset is already set in frame F. There's nothing more
5300 return fontset_name (fontset
);
5302 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5304 if (!STRINGP (result
))
5305 /* Can't load ASCII font. */
5308 /* Since x_new_font doesn't update any fontset information, do it now. */
5309 FRAME_FONTSET (f
) = fontset
;
5311 return build_string (fontsetname
);
5315 /***********************************************************************
5316 TODO: W32 Input Methods
5317 ***********************************************************************/
5318 /* Listing missing functions from xterm.c helps diff stay in step.
5320 xim_destroy_callback (xim, client_data, call_data)
5321 xim_open_dpy (dpyinfo, resource_name)
5323 xim_instantiate_callback (display, client_data, call_data)
5324 xim_initialize (dpyinfo, resource_name)
5325 xim_close_dpy (dpyinfo)
5331 mac_get_window_bounds (f
, inner
, outer
)
5333 Rect
*inner
, *outer
;
5335 #if TARGET_API_MAC_CARBON
5336 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5337 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5338 #else /* not TARGET_API_MAC_CARBON */
5339 RgnHandle region
= NewRgn ();
5341 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5342 *inner
= (*region
)->rgnBBox
;
5343 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5344 *outer
= (*region
)->rgnBBox
;
5345 DisposeRgn (region
);
5346 #endif /* not TARGET_API_MAC_CARBON */
5351 /* Calculate the absolute position in frame F
5352 from its current recorded position values and gravity. */
5355 x_calc_absolute_position (f
)
5358 int width_diff
= 0, height_diff
= 0;
5359 int flags
= f
->size_hint_flags
;
5362 /* We have nothing to do if the current position
5363 is already for the top-left corner. */
5364 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5367 /* Find the offsets of the outside upper-left corner of
5368 the inner window, with respect to the outer window. */
5369 mac_get_window_bounds (f
, &inner
, &outer
);
5371 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5372 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5374 /* Treat negative positions as relative to the leftmost bottommost
5375 position that fits on the screen. */
5376 if (flags
& XNegative
)
5377 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5379 - FRAME_PIXEL_WIDTH (f
)
5382 if (flags
& YNegative
)
5383 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5385 - FRAME_PIXEL_HEIGHT (f
)
5388 /* The left_pos and top_pos
5389 are now relative to the top and left screen edges,
5390 so the flags should correspond. */
5391 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5394 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5395 to really change the position, and 0 when calling from
5396 x_make_frame_visible (in that case, XOFF and YOFF are the current
5397 position values). It is -1 when calling from x_set_frame_parameters,
5398 which means, do adjust for borders but don't change the gravity. */
5401 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5403 register int xoff
, yoff
;
5406 if (change_gravity
> 0)
5410 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5412 f
->size_hint_flags
|= XNegative
;
5414 f
->size_hint_flags
|= YNegative
;
5415 f
->win_gravity
= NorthWestGravity
;
5417 x_calc_absolute_position (f
);
5420 x_wm_set_size_hint (f
, (long) 0, 0);
5422 #if TARGET_API_MAC_CARBON
5423 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5424 /* If the title bar is completely outside the screen, adjust the
5426 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5427 kWindowConstrainMoveRegardlessOfFit
5428 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5429 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5432 Rect inner
, outer
, screen_rect
, dummy
;
5433 RgnHandle region
= NewRgn ();
5435 mac_get_window_bounds (f
, &inner
, &outer
);
5436 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5437 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5438 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5439 f
->top_pos
+ f
->y_pixels_diff
, false);
5441 /* If the title bar is completely outside the screen, adjust the
5442 position. The variable `outer' holds the title bar rectangle.
5443 The variable `inner' holds slightly smaller one than `outer',
5444 so that the calculation of overlapping may not become too
5446 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5447 outer
= (*region
)->rgnBBox
;
5448 DisposeRgn (region
);
5450 InsetRect (&inner
, 8, 8);
5451 screen_rect
= qd
.screenBits
.bounds
;
5452 screen_rect
.top
+= GetMBarHeight ();
5454 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5456 if (inner
.right
<= screen_rect
.left
)
5457 f
->left_pos
= screen_rect
.left
;
5458 else if (inner
.left
>= screen_rect
.right
)
5459 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5461 if (inner
.bottom
<= screen_rect
.top
)
5462 f
->top_pos
= screen_rect
.top
;
5463 else if (inner
.top
>= screen_rect
.bottom
)
5464 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5466 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5467 f
->top_pos
+ f
->y_pixels_diff
, false);
5475 /* Call this to change the size of frame F's x-window.
5476 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5477 for this size change and subsequent size changes.
5478 Otherwise we leave the window gravity unchanged. */
5481 x_set_window_size (f
, change_gravity
, cols
, rows
)
5486 int pixelwidth
, pixelheight
;
5490 check_frame_size (f
, &rows
, &cols
);
5491 f
->scroll_bar_actual_width
5492 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5494 compute_fringe_widths (f
, 0);
5496 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5497 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5499 f
->win_gravity
= NorthWestGravity
;
5500 x_wm_set_size_hint (f
, (long) 0, 0);
5502 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5503 #if TARGET_API_MAC_CARBON
5504 if (f
->output_data
.mac
->hourglass_control
)
5505 MoveControl (f
->output_data
.mac
->hourglass_control
,
5506 pixelwidth
- HOURGLASS_WIDTH
, 0);
5509 /* Now, strictly speaking, we can't be sure that this is accurate,
5510 but the window manager will get around to dealing with the size
5511 change request eventually, and we'll hear how it went when the
5512 ConfigureNotify event gets here.
5514 We could just not bother storing any of this information here,
5515 and let the ConfigureNotify event set everything up, but that
5516 might be kind of confusing to the Lisp code, since size changes
5517 wouldn't be reported in the frame parameters until some random
5518 point in the future when the ConfigureNotify event arrives.
5520 We pass 1 for DELAY since we can't run Lisp code inside of
5522 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5523 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5524 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5526 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5527 receive in the ConfigureNotify event; if we get what we asked
5528 for, then the event won't cause the screen to become garbaged, so
5529 we have to make sure to do it here. */
5530 SET_FRAME_GARBAGED (f
);
5532 XFlush (FRAME_X_DISPLAY (f
));
5534 /* If cursor was outside the new size, mark it as off. */
5535 mark_window_cursors_off (XWINDOW (f
->root_window
));
5537 /* Clear out any recollection of where the mouse highlighting was,
5538 since it might be in a place that's outside the new frame size.
5539 Actually checking whether it is outside is a pain in the neck,
5540 so don't try--just let the highlighting be done afresh with new size. */
5541 cancel_mouse_face (f
);
5546 /* Mouse warping. */
5548 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5551 x_set_mouse_position (f
, x
, y
)
5557 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5558 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5560 if (pix_x
< 0) pix_x
= 0;
5561 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5563 if (pix_y
< 0) pix_y
= 0;
5564 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5566 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5570 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5574 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5577 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5578 0, 0, 0, 0, pix_x
, pix_y
);
5583 /* focus shifting, raising and lowering. */
5586 x_focus_on_frame (f
)
5589 #if 0 /* This proves to be unpleasant. */
5593 /* I don't think that the ICCCM allows programs to do things like this
5594 without the interaction of the window manager. Whatever you end up
5595 doing with this code, do it to x_unfocus_frame too. */
5596 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5597 RevertToPointerRoot
, CurrentTime
);
5607 /* Raise frame F. */
5613 if (f
->async_visible
)
5616 SelectWindow (FRAME_MAC_WINDOW (f
));
5621 /* Lower frame F. */
5627 if (f
->async_visible
)
5630 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5636 XTframe_raise_lower (f
, raise_flag
)
5646 /* Change of visibility. */
5648 /* This tries to wait until the frame is really visible.
5649 However, if the window manager asks the user where to position
5650 the frame, this will return before the user finishes doing that.
5651 The frame will not actually be visible at that time,
5652 but it will become visible later when the window manager
5653 finishes with it. */
5656 x_make_frame_visible (f
)
5660 int original_top
, original_left
;
5664 if (! FRAME_VISIBLE_P (f
))
5666 /* We test FRAME_GARBAGED_P here to make sure we don't
5667 call x_set_offset a second time
5668 if we get to x_make_frame_visible a second time
5669 before the window gets really visible. */
5670 if (! FRAME_ICONIFIED_P (f
)
5671 && ! f
->output_data
.mac
->asked_for_visible
)
5672 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5674 f
->output_data
.mac
->asked_for_visible
= 1;
5676 #if TARGET_API_MAC_CARBON
5677 if (!(FRAME_SIZE_HINTS (f
)->flags
& (USPosition
| PPosition
)))
5679 struct frame
*sf
= SELECTED_FRAME ();
5680 if (!FRAME_MAC_P (sf
))
5681 RepositionWindow (FRAME_MAC_WINDOW (f
), NULL
,
5682 kWindowCenterOnMainScreen
);
5684 RepositionWindow (FRAME_MAC_WINDOW (f
),
5685 FRAME_MAC_WINDOW (sf
),
5686 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
5687 kWindowCascadeStartAtParentWindowScreen
5689 kWindowCascadeOnParentWindowScreen
5692 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5695 ShowWindow (FRAME_MAC_WINDOW (f
));
5698 XFlush (FRAME_MAC_DISPLAY (f
));
5700 /* Synchronize to ensure Emacs knows the frame is visible
5701 before we do anything else. We do this loop with input not blocked
5702 so that incoming events are handled. */
5707 /* This must come after we set COUNT. */
5710 XSETFRAME (frame
, f
);
5712 /* Wait until the frame is visible. Process X events until a
5713 MapNotify event has been seen, or until we think we won't get a
5714 MapNotify at all.. */
5715 for (count
= input_signal_count
+ 10;
5716 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5718 /* Force processing of queued events. */
5721 /* Machines that do polling rather than SIGIO have been
5722 observed to go into a busy-wait here. So we'll fake an
5723 alarm signal to let the handler know that there's something
5724 to be read. We used to raise a real alarm, but it seems
5725 that the handler isn't always enabled here. This is
5727 if (input_polling_used ())
5729 /* It could be confusing if a real alarm arrives while
5730 processing the fake one. Turn it off and let the
5731 handler reset it. */
5732 extern void poll_for_input_1
P_ ((void));
5733 int old_poll_suppress_count
= poll_suppress_count
;
5734 poll_suppress_count
= 1;
5735 poll_for_input_1 ();
5736 poll_suppress_count
= old_poll_suppress_count
;
5739 /* See if a MapNotify event has been processed. */
5740 FRAME_SAMPLE_VISIBILITY (f
);
5745 /* Change from mapped state to withdrawn state. */
5747 /* Make the frame visible (mapped and not iconified). */
5750 x_make_frame_invisible (f
)
5753 /* Don't keep the highlight on an invisible frame. */
5754 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5755 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5759 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
5760 that the current position of the window is user-specified, rather than
5761 program-specified, so that when the window is mapped again, it will be
5762 placed at the same location, without forcing the user to position it
5763 by hand again (they have already done that once for this window.) */
5764 x_wm_set_size_hint (f
, (long) 0, 1);
5766 HideWindow (FRAME_MAC_WINDOW (f
));
5768 /* We can't distinguish this from iconification
5769 just by the event that we get from the server.
5770 So we can't win using the usual strategy of letting
5771 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5772 and synchronize with the server to make sure we agree. */
5774 FRAME_ICONIFIED_P (f
) = 0;
5775 f
->async_visible
= 0;
5776 f
->async_iconified
= 0;
5781 /* Change window state from mapped to iconified. */
5787 /* Don't keep the highlight on an invisible frame. */
5788 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5789 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5792 /* Review: Since window is still visible in dock, still allow updates? */
5793 if (f
->async_iconified
)
5799 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5805 /* Free X resources of frame F. */
5808 x_free_frame_resources (f
)
5811 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5812 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5816 if (wp
!= tip_window
)
5817 remove_window_handler (wp
);
5820 if (wp
== tip_window
)
5821 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5822 closed' event. So we reset tip_window here. */
5825 free_frame_menubar (f
);
5827 if (FRAME_FACE_CACHE (f
))
5828 free_frame_faces (f
);
5832 if (FRAME_SIZE_HINTS (f
))
5833 xfree (FRAME_SIZE_HINTS (f
));
5835 xfree (f
->output_data
.mac
);
5836 f
->output_data
.mac
= NULL
;
5838 if (f
== dpyinfo
->x_focus_frame
)
5839 dpyinfo
->x_focus_frame
= 0;
5840 if (f
== dpyinfo
->x_focus_event_frame
)
5841 dpyinfo
->x_focus_event_frame
= 0;
5842 if (f
== dpyinfo
->x_highlight_frame
)
5843 dpyinfo
->x_highlight_frame
= 0;
5845 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5847 dpyinfo
->mouse_face_beg_row
5848 = dpyinfo
->mouse_face_beg_col
= -1;
5849 dpyinfo
->mouse_face_end_row
5850 = dpyinfo
->mouse_face_end_col
= -1;
5851 dpyinfo
->mouse_face_window
= Qnil
;
5852 dpyinfo
->mouse_face_deferred_gc
= 0;
5853 dpyinfo
->mouse_face_mouse_frame
= 0;
5860 /* Destroy the X window of frame F. */
5863 x_destroy_window (f
)
5866 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5868 x_free_frame_resources (f
);
5870 dpyinfo
->reference_count
--;
5874 /* Setting window manager hints. */
5876 /* Set the normal size hints for the window manager, for frame F.
5877 FLAGS is the flags word to use--or 0 meaning preserve the flags
5878 that the window now has.
5879 If USER_POSITION is nonzero, we set the USPosition
5880 flag (this is useful when FLAGS is 0). */
5882 x_wm_set_size_hint (f
, flags
, user_position
)
5887 int base_width
, base_height
, width_inc
, height_inc
;
5888 int min_rows
= 0, min_cols
= 0;
5889 XSizeHints
*size_hints
;
5891 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5892 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5893 width_inc
= FRAME_COLUMN_WIDTH (f
);
5894 height_inc
= FRAME_LINE_HEIGHT (f
);
5896 check_frame_size (f
, &min_rows
, &min_cols
);
5898 size_hints
= FRAME_SIZE_HINTS (f
);
5899 if (size_hints
== NULL
)
5901 size_hints
= FRAME_SIZE_HINTS (f
) = xmalloc (sizeof (XSizeHints
));
5902 bzero (size_hints
, sizeof (XSizeHints
));
5905 size_hints
->flags
|= PResizeInc
| PMinSize
| PBaseSize
;
5906 size_hints
->width_inc
= width_inc
;
5907 size_hints
->height_inc
= height_inc
;
5908 size_hints
->min_width
= base_width
+ min_cols
* width_inc
;
5909 size_hints
->min_height
= base_height
+ min_rows
* height_inc
;
5910 size_hints
->base_width
= base_width
;
5911 size_hints
->base_height
= base_height
;
5914 size_hints
->flags
= flags
;
5915 else if (user_position
)
5917 size_hints
->flags
&= ~ PPosition
;
5918 size_hints
->flags
|= USPosition
;
5922 #if 0 /* MAC_TODO: hide application instead of iconify? */
5923 /* Used for IconicState or NormalState */
5926 x_wm_set_window_state (f
, state
)
5930 #ifdef USE_X_TOOLKIT
5933 XtSetArg (al
[0], XtNinitialState
, state
);
5934 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5935 #else /* not USE_X_TOOLKIT */
5936 Window window
= FRAME_X_WINDOW (f
);
5938 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5939 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5941 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5942 #endif /* not USE_X_TOOLKIT */
5946 x_wm_set_icon_pixmap (f
, pixmap_id
)
5952 #ifndef USE_X_TOOLKIT
5953 Window window
= FRAME_X_WINDOW (f
);
5958 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5959 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5963 /* It seems there is no way to turn off use of an icon pixmap.
5964 The following line does it, only if no icon has yet been created,
5965 for some window managers. But with mwm it crashes.
5966 Some people say it should clear the IconPixmapHint bit in this case,
5967 but that doesn't work, and the X consortium said it isn't the
5968 right thing at all. Since there is no way to win,
5969 best to explicitly give up. */
5971 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5977 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5981 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5982 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5985 #else /* not USE_X_TOOLKIT */
5987 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5988 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5990 #endif /* not USE_X_TOOLKIT */
5993 #endif /* MAC_TODO */
5996 x_wm_set_icon_position (f
, icon_x
, icon_y
)
6000 #if 0 /* MAC_TODO: no icons on Mac */
6001 #ifdef USE_X_TOOLKIT
6002 Window window
= XtWindow (f
->output_data
.x
->widget
);
6004 Window window
= FRAME_X_WINDOW (f
);
6007 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
6008 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
6009 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
6011 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6012 #endif /* MAC_TODO */
6016 /***********************************************************************
6018 ***********************************************************************/
6020 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6023 x_get_font_info (f
, font_idx
)
6027 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
6030 /* the global font name table */
6031 static char **font_name_table
= NULL
;
6032 static int font_name_table_size
= 0;
6033 static int font_name_count
= 0;
6035 /* Alist linking character set strings to Mac text encoding and Emacs
6037 static Lisp_Object Vmac_charset_info_alist
;
6040 create_text_encoding_info_alist ()
6042 Lisp_Object result
= Qnil
, rest
;
6044 for (rest
= Vmac_charset_info_alist
; CONSP (rest
); rest
= XCDR (rest
))
6046 Lisp_Object charset_info
= XCAR (rest
);
6047 Lisp_Object charset
, coding_system
, text_encoding
;
6048 Lisp_Object existing_info
;
6050 if (!(CONSP (charset_info
)
6051 && STRINGP (charset
= XCAR (charset_info
))
6052 && CONSP (XCDR (charset_info
))
6053 && INTEGERP (text_encoding
= XCAR (XCDR (charset_info
)))
6054 && CONSP (XCDR (XCDR (charset_info
)))
6055 && SYMBOLP (coding_system
= XCAR (XCDR (XCDR (charset_info
))))))
6058 existing_info
= assq_no_quit (text_encoding
, result
);
6059 if (NILP (existing_info
))
6060 result
= Fcons (list3 (text_encoding
, coding_system
, charset
),
6063 if (NILP (Fmember (charset
, XCDR (XCDR (existing_info
)))))
6064 XSETCDR (XCDR (existing_info
),
6065 Fcons (charset
, XCDR (XCDR (existing_info
))));
6073 decode_mac_font_name (name
, size
, coding_system
)
6076 Lisp_Object coding_system
;
6078 struct coding_system coding
;
6081 for (p
= name
; *p
; p
++)
6082 if (!isascii (*p
) || iscntrl (*p
))
6086 || NILP (coding_system
) || NILP (Fcoding_system_p (coding_system
)))
6089 setup_coding_system (coding_system
, &coding
);
6090 coding
.src_multibyte
= 0;
6091 coding
.dst_multibyte
= 1;
6092 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6093 coding
.composing
= COMPOSITION_DISABLED
;
6094 buf
= (char *) alloca (size
);
6096 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
6097 bcopy (buf
, name
, coding
.produced
);
6098 name
[coding
.produced
] = '\0';
6103 mac_to_x_fontname (name
, size
, style
, charset
)
6111 char xf
[256], *result
, *p
;
6113 if (sscanf (name
, "%31[^-]-%255[^-]-%31s", foundry
, family
, cs
) == 3)
6117 strcpy(foundry
, "Apple");
6118 strcpy(family
, name
);
6121 sprintf (xf
, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
6122 style
& bold
? "bold" : "medium", style
& italic
? 'i' : 'r',
6123 size
, size
* 10, size
? 75 : 0, size
? 75 : 0, size
* 10, charset
);
6125 result
= xmalloc (strlen (foundry
) + strlen (family
) + strlen (xf
) + 3 + 1);
6126 sprintf (result
, "-%s-%s-%s", foundry
, family
, xf
);
6127 for (p
= result
; *p
; p
++)
6133 /* Convert an X font spec to the corresponding mac font name, which
6134 can then be passed to GetFNum after conversion to a Pascal string.
6135 For ordinary Mac fonts, this should just be their names, like
6136 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
6137 collection contain their charset designation in their names, like
6138 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
6139 names are handled accordingly. */
6141 x_font_name_to_mac_font_name (xf
, mf
, mf_decoded
, style
, cs
)
6142 char *xf
, *mf
, *mf_decoded
;
6148 char weight
[20], slant
[2], *p
;
6149 Lisp_Object charset_info
, coding_system
= Qnil
;
6150 struct coding_system coding
;
6154 if (sscanf (xf
, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6155 foundry
, family
, weight
, slant
, cs
) != 5 &&
6156 sscanf (xf
, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6157 foundry
, family
, weight
, slant
, cs
) != 5)
6161 if (strcmp (weight
, "bold") == 0)
6166 charset_info
= Fassoc (build_string (cs
), Vmac_charset_info_alist
);
6167 if (!NILP (charset_info
))
6169 strcpy (mf_decoded
, family
);
6170 coding_system
= Fcar (Fcdr (Fcdr (charset_info
)));
6173 sprintf (mf_decoded
, "%s-%s-%s", foundry
, family
, cs
);
6175 for (p
= mf_decoded
; *p
; p
++)
6176 if (!isascii (*p
) || iscntrl (*p
))
6180 || NILP (coding_system
) || NILP (Fcoding_system_p (coding_system
)))
6181 strcpy (mf
, mf_decoded
);
6184 setup_coding_system (coding_system
, &coding
);
6185 coding
.src_multibyte
= 1;
6186 coding
.dst_multibyte
= 1;
6187 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6188 encode_coding (&coding
, mf_decoded
, mf
,
6189 strlen (mf_decoded
), sizeof (Str255
) - 1);
6190 mf
[coding
.produced
] = '\0';
6196 add_font_name_table_entry (char *font_name
)
6198 if (font_name_table_size
== 0)
6200 font_name_table_size
= 16;
6201 font_name_table
= (char **)
6202 xmalloc (font_name_table_size
* sizeof (char *));
6204 else if (font_name_count
+ 1 >= font_name_table_size
)
6206 font_name_table_size
+= 16;
6207 font_name_table
= (char **)
6208 xrealloc (font_name_table
,
6209 font_name_table_size
* sizeof (char *));
6212 font_name_table
[font_name_count
++] = font_name
;
6215 /* Sets up the table font_name_table to contain the list of all fonts
6216 in the system the first time the table is used so that the Resource
6217 Manager need not be accessed every time this information is
6221 init_font_name_table ()
6223 #if TARGET_API_MAC_CARBON
6224 FMFontFamilyIterator ffi
;
6225 FMFontFamilyInstanceIterator ffii
;
6227 Lisp_Object text_encoding_info_alist
;
6228 struct gcpro gcpro1
;
6230 /* Create a dummy instance iterator here to avoid creating and
6231 destroying it in the loop. */
6232 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6234 /* Create an iterator to enumerate the font families. */
6235 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6238 FMDisposeFontFamilyInstanceIterator (&ffii
);
6242 text_encoding_info_alist
= create_text_encoding_info_alist ();
6244 GCPRO1 (text_encoding_info_alist
);
6246 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6252 TextEncoding encoding
;
6253 TextEncodingBase sc
;
6254 Lisp_Object text_encoding_info
;
6256 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6262 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
6264 sc
= GetTextEncodingBase (encoding
);
6265 text_encoding_info
= assq_no_quit (make_number (sc
),
6266 text_encoding_info_alist
);
6267 if (!NILP (text_encoding_info
))
6268 decode_mac_font_name (name
, sizeof (name
),
6269 XCAR (XCDR (text_encoding_info
)));
6271 text_encoding_info
= assq_no_quit (make_number (kTextEncodingMacRoman
),
6272 text_encoding_info_alist
);
6274 /* Point the instance iterator at the current font family. */
6275 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6278 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6281 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
6283 for (; !NILP (rest
); rest
= XCDR (rest
))
6285 char *cs
= SDATA (XCAR (rest
));
6289 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6291 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6293 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6295 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6301 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6310 /* Dispose of the iterators. */
6311 FMDisposeFontFamilyIterator (&ffi
);
6312 FMDisposeFontFamilyInstanceIterator (&ffii
);
6313 #else /* !TARGET_API_MAC_CARBON */
6315 SInt16 fontnum
, old_fontnum
;
6316 int num_mac_fonts
= CountResources('FOND');
6318 Handle font_handle
, font_handle_2
;
6319 short id
, scriptcode
;
6322 struct FontAssoc
*fat
;
6323 struct AsscEntry
*assc_entry
;
6324 Lisp_Object text_encoding_info_alist
, text_encoding_info
;
6325 struct gcpro gcpro1
;
6327 GetPort (&port
); /* save the current font number used */
6328 old_fontnum
= port
->txFont
;
6330 text_encoding_info_alist
= create_text_encoding_info_alist ();
6332 GCPRO1 (text_encoding_info_alist
);
6334 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6336 font_handle
= GetIndResource ('FOND', i
);
6340 GetResInfo (font_handle
, &id
, &type
, name
);
6341 GetFNum (name
, &fontnum
);
6347 scriptcode
= FontToScript (fontnum
);
6348 text_encoding_info
= assq_no_quit (make_number (scriptcode
),
6349 text_encoding_info_alist
);
6350 if (!NILP (text_encoding_info
))
6351 decode_mac_font_name (name
, sizeof (name
),
6352 XCAR (XCDR (text_encoding_info
)));
6354 text_encoding_info
= assq_no_quit (make_number (smRoman
),
6355 text_encoding_info_alist
);
6358 HLock (font_handle
);
6360 if (GetResourceSizeOnDisk (font_handle
)
6361 >= sizeof (struct FamRec
))
6363 fat
= (struct FontAssoc
*) (*font_handle
6364 + sizeof (struct FamRec
));
6366 = (struct AsscEntry
*) (*font_handle
6367 + sizeof (struct FamRec
)
6368 + sizeof (struct FontAssoc
));
6370 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6372 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
6374 for (; !NILP (rest
); rest
= XCDR (rest
))
6376 char *cs
= SDATA (XCAR (rest
));
6378 add_font_name_table_entry (mac_to_x_fontname (name
,
6379 assc_entry
->fontSize
,
6380 assc_entry
->fontStyle
,
6386 HUnlock (font_handle
);
6387 font_handle_2
= GetNextFOND (font_handle
);
6388 ReleaseResource (font_handle
);
6389 font_handle
= font_handle_2
;
6391 while (ResError () == noErr
&& font_handle
);
6396 TextFont (old_fontnum
);
6397 #endif /* !TARGET_API_MAC_CARBON */
6402 mac_clear_font_name_table ()
6406 for (i
= 0; i
< font_name_count
; i
++)
6407 xfree (font_name_table
[i
]);
6408 xfree (font_name_table
);
6409 font_name_table
= NULL
;
6410 font_name_table_size
= font_name_count
= 0;
6414 enum xlfd_scalable_field_index
6416 XLFD_SCL_PIXEL_SIZE
,
6417 XLFD_SCL_POINT_SIZE
,
6422 static int xlfd_scalable_fields
[] =
6431 mac_c_string_match (regexp
, string
, nonspecial
, exact
)
6433 const char *string
, *nonspecial
;
6438 if (strcmp (string
, nonspecial
) == 0)
6439 return build_string (string
);
6441 else if (strstr (string
, nonspecial
))
6443 Lisp_Object str
= build_string (string
);
6445 if (fast_string_match (regexp
, str
) >= 0)
6453 mac_do_list_fonts (pattern
, maxnames
)
6458 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6459 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6461 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6462 char *longest_start
, *cur_start
, *nonspecial
;
6463 int longest_len
, exact
;
6465 if (font_name_table
== NULL
) /* Initialize when first used. */
6466 init_font_name_table ();
6468 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6471 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6472 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6473 fonts are scaled according to the specified size. */
6476 field
= xlfd_scalable_fields
;
6484 if ('0' <= *ptr
&& *ptr
<= '9')
6486 *val
= *ptr
++ - '0';
6487 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6488 *val
= *val
* 10 + *ptr
++ - '0';
6495 ptr
= strchr (ptr
, '-');
6498 while (ptr
&& i
< 14);
6500 if (i
== 14 && ptr
== NULL
)
6502 if (scl_val
[XLFD_SCL_PIXEL_SIZE
] < 0)
6503 scl_val
[XLFD_SCL_PIXEL_SIZE
] =
6504 (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
] / 10
6505 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
] / 10
6507 if (scl_val
[XLFD_SCL_POINT_SIZE
] < 0)
6508 scl_val
[XLFD_SCL_POINT_SIZE
] =
6509 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
6510 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
]
6512 if (scl_val
[XLFD_SCL_AVGWIDTH
] < 0)
6513 scl_val
[XLFD_SCL_AVGWIDTH
] =
6514 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
6515 : (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
]
6519 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6524 longest_start
= cur_start
= ptr
;
6528 /* Turn pattern into a regexp and do a regexp match. Also find the
6529 longest substring containing no special characters. */
6530 for (; *pattern
; pattern
++)
6532 if (*pattern
== '?' || *pattern
== '*')
6534 if (ptr
- cur_start
> longest_len
)
6536 longest_start
= cur_start
;
6537 longest_len
= ptr
- cur_start
;
6541 if (*pattern
== '?')
6543 else /* if (*pattern == '*') */
6551 *ptr
++ = tolower (*pattern
);
6554 if (ptr
- cur_start
> longest_len
)
6556 longest_start
= cur_start
;
6557 longest_len
= ptr
- cur_start
;
6563 nonspecial
= xmalloc (longest_len
+ 1);
6564 strncpy (nonspecial
, longest_start
, longest_len
);
6565 nonspecial
[longest_len
] = '\0';
6567 pattern_regex
= build_string (regex
);
6569 for (i
= 0; i
< font_name_count
; i
++)
6571 fontname
= mac_c_string_match (pattern_regex
, font_name_table
[i
],
6573 if (!NILP (fontname
))
6575 font_list
= Fcons (fontname
, font_list
);
6576 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
6579 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6580 && (ptr
= strstr (font_name_table
[i
], "-0-0-0-0-m-0-")))
6582 int former_len
= ptr
- font_name_table
[i
];
6584 scaled
= xmalloc (strlen (font_name_table
[i
]) + 20 + 1);
6585 memcpy (scaled
, font_name_table
[i
], former_len
);
6586 sprintf (scaled
+ former_len
,
6587 "-%d-%d-75-75-m-%d-%s",
6588 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6589 scl_val
[XLFD_SCL_POINT_SIZE
],
6590 scl_val
[XLFD_SCL_AVGWIDTH
],
6591 ptr
+ sizeof ("-0-0-0-0-m-0-") - 1);
6592 fontname
= mac_c_string_match (pattern_regex
, scaled
,
6595 if (!NILP (fontname
))
6597 font_list
= Fcons (fontname
, font_list
);
6598 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
6609 /* Return a list of names of available fonts matching PATTERN on frame F.
6611 Frame F null means we have not yet created any frame on Mac, and
6612 consult the first display in x_display_list. MAXNAMES sets a limit
6613 on how many fonts to match. */
6616 x_list_fonts (f
, pattern
, size
, maxnames
)
6618 Lisp_Object pattern
;
6621 Lisp_Object list
= Qnil
, patterns
, tem
, key
;
6622 struct mac_display_info
*dpyinfo
6623 = f
? FRAME_MAC_DISPLAY_INFO (f
) : x_display_list
;
6625 xassert (size
<= 0);
6627 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
6628 if (NILP (patterns
))
6629 patterns
= Fcons (pattern
, Qnil
);
6631 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
6633 pattern
= XCAR (patterns
);
6635 if (!STRINGP (pattern
))
6638 tem
= XCAR (XCDR (dpyinfo
->name_list_element
));
6639 key
= Fcons (pattern
, make_number (maxnames
));
6641 list
= Fassoc (key
, tem
);
6644 list
= Fcdr_safe (list
);
6645 /* We have a cashed list. Don't have to get the list again. */
6650 list
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6653 /* MAC_TODO: add code for matching outline fonts here */
6655 /* Now store the result in the cache. */
6656 XSETCAR (XCDR (dpyinfo
->name_list_element
),
6657 Fcons (Fcons (key
, list
),
6658 XCAR (XCDR (dpyinfo
->name_list_element
))));
6661 if (NILP (list
)) continue; /* Try the remaining alternatives. */
6670 /* Check that FONT is valid on frame F. It is if it can be found in F's
6674 x_check_font (f
, font
)
6679 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6681 xassert (font
!= NULL
);
6683 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6684 if (dpyinfo
->font_table
[i
].name
6685 && font
== dpyinfo
->font_table
[i
].font
)
6688 xassert (i
< dpyinfo
->n_fonts
);
6691 #endif /* GLYPH_DEBUG != 0 */
6693 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6694 Note: There are (broken) X fonts out there with invalid XFontStruct
6695 min_bounds contents. For example, handa@etl.go.jp reports that
6696 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6697 have font->min_bounds.width == 0. */
6700 x_font_min_bounds (font
, w
, h
)
6701 MacFontStruct
*font
;
6704 *h
= FONT_HEIGHT (font
);
6705 *w
= font
->min_bounds
.width
;
6709 /* Compute the smallest character width and smallest font height over
6710 all fonts available on frame F. Set the members smallest_char_width
6711 and smallest_font_height in F's x_display_info structure to
6712 the values computed. Value is non-zero if smallest_font_height or
6713 smallest_char_width become smaller than they were before. */
6716 x_compute_min_glyph_bounds (f
)
6720 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6721 MacFontStruct
*font
;
6722 int old_width
= dpyinfo
->smallest_char_width
;
6723 int old_height
= dpyinfo
->smallest_font_height
;
6725 dpyinfo
->smallest_font_height
= 100000;
6726 dpyinfo
->smallest_char_width
= 100000;
6728 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6729 if (dpyinfo
->font_table
[i
].name
)
6731 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6734 font
= (MacFontStruct
*) fontp
->font
;
6735 xassert (font
!= (MacFontStruct
*) ~0);
6736 x_font_min_bounds (font
, &w
, &h
);
6738 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6739 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6742 xassert (dpyinfo
->smallest_char_width
> 0
6743 && dpyinfo
->smallest_font_height
> 0);
6745 return (dpyinfo
->n_fonts
== 1
6746 || dpyinfo
->smallest_char_width
< old_width
6747 || dpyinfo
->smallest_font_height
< old_height
);
6751 /* Determine whether given string is a fully-specified XLFD: all 14
6752 fields are present, none is '*'. */
6755 is_fully_specified_xlfd (char *p
)
6763 for (i
= 0; i
< 13; i
++)
6765 q
= strchr (p
+ 1, '-');
6768 if (q
- p
== 2 && *(p
+ 1) == '*')
6773 if (strchr (p
+ 1, '-') != NULL
)
6776 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6783 const int kDefaultFontSize
= 12;
6786 /* XLoadQueryFont creates and returns an internal representation for a
6787 font in a MacFontStruct struct. There is really no concept
6788 corresponding to "loading" a font on the Mac. But we check its
6789 existence and find the font number and all other information for it
6790 and store them in the returned MacFontStruct. */
6792 static MacFontStruct
*
6793 XLoadQueryFont (Display
*dpy
, char *fontname
)
6795 int i
, size
, point_size
, avgwidth
, is_two_byte_font
, char_width
;
6798 SInt16 old_fontnum
, old_fontsize
;
6800 Str255 mfontname
, mfontname_decoded
;
6804 #if TARGET_API_MAC_CARBON
6805 TextEncoding encoding
;
6810 MacFontStruct
*font
;
6811 FontInfo the_fontinfo
;
6813 UInt32 old_flags
, new_flags
;
6816 if (is_fully_specified_xlfd (fontname
))
6820 Lisp_Object matched_fonts
;
6822 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6823 if (NILP (matched_fonts
))
6825 name
= SDATA (XCAR (matched_fonts
));
6828 GetPort (&port
); /* save the current font number used */
6829 #if TARGET_API_MAC_CARBON
6830 old_fontnum
= GetPortTextFont (port
);
6831 old_fontsize
= GetPortTextSize (port
);
6832 old_fontface
= GetPortTextFace (port
);
6834 old_fontnum
= port
->txFont
;
6835 old_fontsize
= port
->txSize
;
6836 old_fontface
= port
->txFace
;
6839 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%*s", &size
, &point_size
, &avgwidth
) != 3)
6845 size
= point_size
/ 10;
6846 else if (avgwidth
> 0)
6847 size
= avgwidth
/ 10;
6850 size
= kDefaultFontSize
;
6852 x_font_name_to_mac_font_name (name
, mfontname
, mfontname_decoded
,
6853 &fontface
, charset
);
6855 #if TARGET_API_MAC_CARBON
6856 fontnum
= FMGetFontFamilyFromName (mfontname
);
6857 if (fontnum
== kInvalidFontFamily
6858 || FMGetFontFamilyTextEncoding (fontnum
, &encoding
) != noErr
)
6860 scriptcode
= GetTextEncodingBase (encoding
);
6862 GetFNum (mfontname
, &fontnum
);
6865 scriptcode
= FontToScript (fontnum
);
6868 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6870 font
->mac_fontnum
= fontnum
;
6871 font
->mac_fontsize
= size
;
6872 font
->mac_fontface
= fontface
;
6873 font
->mac_scriptcode
= scriptcode
;
6875 /* Apple Japanese (SJIS) font is listed as both
6876 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6877 (Roman script) in init_font_name_table (). The latter should be
6878 treated as a one-byte font. */
6879 if (scriptcode
== smJapanese
&& strcmp (charset
, "jisx0201.1976-0") == 0)
6880 font
->mac_scriptcode
= smRoman
;
6882 font
->full_name
= mac_to_x_fontname (mfontname_decoded
, size
, fontface
, charset
);
6884 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6885 font
->mac_scriptcode
== smTradChinese
||
6886 font
->mac_scriptcode
== smSimpChinese
||
6887 font
->mac_scriptcode
== smKorean
;
6891 TextFace (fontface
);
6893 GetFontInfo (&the_fontinfo
);
6895 font
->ascent
= the_fontinfo
.ascent
;
6896 font
->descent
= the_fontinfo
.descent
;
6898 font
->min_byte1
= 0;
6899 if (is_two_byte_font
)
6900 font
->max_byte1
= 1;
6902 font
->max_byte1
= 0;
6903 font
->min_char_or_byte2
= 0x20;
6904 font
->max_char_or_byte2
= 0xff;
6906 if (is_two_byte_font
)
6908 /* Use the width of an "ideographic space" of that font because
6909 the_fontinfo.widMax returns the wrong width for some fonts. */
6910 switch (font
->mac_scriptcode
)
6913 char_width
= StringWidth("\p\x81\x40");
6916 char_width
= StringWidth("\p\xa1\x40");
6919 char_width
= StringWidth("\p\xa1\xa1");
6922 char_width
= StringWidth("\p\xa1\xa1");
6927 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6928 returns 15 for 12-point Monaco! */
6929 char_width
= CharWidth ('m');
6931 if (is_two_byte_font
)
6933 font
->per_char
= NULL
;
6935 if (fontface
& italic
)
6936 font
->max_bounds
.rbearing
= char_width
+ 1;
6938 font
->max_bounds
.rbearing
= char_width
;
6939 font
->max_bounds
.lbearing
= 0;
6940 font
->max_bounds
.width
= char_width
;
6941 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6942 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6944 font
->min_bounds
= font
->max_bounds
;
6948 font
->per_char
= (XCharStruct
*)
6949 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6951 int c
, min_width
, max_width
;
6952 Rect char_bounds
, min_bounds
, max_bounds
;
6955 min_width
= max_width
= char_width
;
6956 SetRect (&min_bounds
, -32767, -32767, 32767, 32767);
6957 SetRect (&max_bounds
, 0, 0, 0, 0);
6958 for (c
= 0x20; c
<= 0xff; c
++)
6961 char_width
= CharWidth (ch
);
6962 QDTextBounds (1, &ch
, &char_bounds
);
6963 STORE_XCHARSTRUCT (font
->per_char
[c
- 0x20],
6964 char_width
, char_bounds
);
6965 /* Some Japanese fonts (in SJIS encoding) return 0 as the
6966 character width of 0x7f. */
6969 min_width
= min (min_width
, char_width
);
6970 max_width
= max (max_width
, char_width
);
6972 if (!EmptyRect (&char_bounds
))
6974 SetRect (&min_bounds
,
6975 max (min_bounds
.left
, char_bounds
.left
),
6976 max (min_bounds
.top
, char_bounds
.top
),
6977 min (min_bounds
.right
, char_bounds
.right
),
6978 min (min_bounds
.bottom
, char_bounds
.bottom
));
6979 UnionRect (&max_bounds
, &char_bounds
, &max_bounds
);
6982 STORE_XCHARSTRUCT (font
->min_bounds
, min_width
, min_bounds
);
6983 STORE_XCHARSTRUCT (font
->max_bounds
, max_width
, max_bounds
);
6984 if (min_width
== max_width
6985 && max_bounds
.left
>= 0 && max_bounds
.right
<= max_width
)
6987 /* Fixed width and no overhangs. */
6988 xfree (font
->per_char
);
6989 font
->per_char
= NULL
;
6994 TextFont (old_fontnum
); /* restore previous font number, size and face */
6995 TextSize (old_fontsize
);
6996 TextFace (old_fontface
);
7003 mac_unload_font (dpyinfo
, font
)
7004 struct mac_display_info
*dpyinfo
;
7007 xfree (font
->full_name
);
7009 xfree (font
->per_char
);
7014 /* Load font named FONTNAME of the size SIZE for frame F, and return a
7015 pointer to the structure font_info while allocating it dynamically.
7016 If SIZE is 0, load any size of font.
7017 If loading is failed, return NULL. */
7020 x_load_font (f
, fontname
, size
)
7022 register char *fontname
;
7025 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7026 Lisp_Object font_names
;
7028 /* Get a list of all the fonts that match this name. Once we
7029 have a list of matching fonts, we compare them against the fonts
7030 we already have by comparing names. */
7031 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
7033 if (!NILP (font_names
))
7038 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7039 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
7040 if (dpyinfo
->font_table
[i
].name
7041 && (!strcmp (dpyinfo
->font_table
[i
].name
,
7042 SDATA (XCAR (tail
)))
7043 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
7044 SDATA (XCAR (tail
)))))
7045 return (dpyinfo
->font_table
+ i
);
7050 /* Load the font and add it to the table. */
7053 struct MacFontStruct
*font
;
7054 struct font_info
*fontp
;
7055 unsigned long value
;
7058 fontname
= (char *) SDATA (XCAR (font_names
));
7061 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
7066 /* Find a free slot in the font table. */
7067 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7068 if (dpyinfo
->font_table
[i
].name
== NULL
)
7071 /* If no free slot found, maybe enlarge the font table. */
7072 if (i
== dpyinfo
->n_fonts
7073 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
7076 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
7077 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
7079 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
7082 fontp
= dpyinfo
->font_table
+ i
;
7083 if (i
== dpyinfo
->n_fonts
)
7086 /* Now fill in the slots of *FONTP. */
7088 bzero (fontp
, sizeof (*fontp
));
7090 fontp
->font_idx
= i
;
7091 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
7092 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
7094 if (font
->min_bounds
.width
== font
->max_bounds
.width
)
7096 /* Fixed width font. */
7097 fontp
->average_width
= fontp
->space_width
= font
->min_bounds
.width
;
7104 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
7105 pcm
= mac_per_char_metric (font
, &char2b
, 0);
7107 fontp
->space_width
= pcm
->width
;
7109 fontp
->space_width
= FONT_WIDTH (font
);
7113 int width
= pcm
->width
;
7114 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
7115 if ((pcm
= mac_per_char_metric (font
, &char2b
, 0)) != NULL
)
7116 width
+= pcm
->width
;
7117 fontp
->average_width
= width
/ 95;
7120 fontp
->average_width
= FONT_WIDTH (font
);
7123 fontp
->full_name
= (char *) xmalloc (strlen (font
->full_name
) + 1);
7124 bcopy (font
->full_name
, fontp
->full_name
, strlen (font
->full_name
) + 1);
7126 fontp
->size
= font
->max_bounds
.width
;
7127 fontp
->height
= FONT_HEIGHT (font
);
7129 /* For some font, ascent and descent in max_bounds field is
7130 larger than the above value. */
7131 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
7132 if (max_height
> fontp
->height
)
7133 fontp
->height
= max_height
;
7136 /* The slot `encoding' specifies how to map a character
7137 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
7138 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
7139 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
7140 2:0xA020..0xFF7F). For the moment, we don't know which charset
7141 uses this font. So, we set information in fontp->encoding[1]
7142 which is never used by any charset. If mapping can't be
7143 decided, set FONT_ENCODING_NOT_DECIDED. */
7144 if (font
->mac_scriptcode
== smJapanese
)
7145 fontp
->encoding
[1] = 4;
7149 = (font
->max_byte1
== 0
7151 ? (font
->min_char_or_byte2
< 0x80
7152 ? (font
->max_char_or_byte2
< 0x80
7153 ? 0 /* 0x20..0x7F */
7154 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
7155 : 1) /* 0xA0..0xFF */
7157 : (font
->min_byte1
< 0x80
7158 ? (font
->max_byte1
< 0x80
7159 ? (font
->min_char_or_byte2
< 0x80
7160 ? (font
->max_char_or_byte2
< 0x80
7161 ? 0 /* 0x2020..0x7F7F */
7162 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
7163 : 3) /* 0x20A0..0x7FFF */
7164 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
7165 : (font
->min_char_or_byte2
< 0x80
7166 ? (font
->max_char_or_byte2
< 0x80
7167 ? 2 /* 0xA020..0xFF7F */
7168 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
7169 : 1))); /* 0xA0A0..0xFFFF */
7172 #if 0 /* MAC_TODO: fill these out with more reasonably values */
7173 fontp
->baseline_offset
7174 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
7175 ? (long) value
: 0);
7176 fontp
->relative_compose
7177 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
7178 ? (long) value
: 0);
7179 fontp
->default_ascent
7180 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
7181 ? (long) value
: 0);
7183 fontp
->baseline_offset
= 0;
7184 fontp
->relative_compose
= 0;
7185 fontp
->default_ascent
= 0;
7188 /* Set global flag fonts_changed_p to non-zero if the font loaded
7189 has a character with a smaller width than any other character
7190 before, or if the font loaded has a smalle>r height than any
7191 other font loaded before. If this happens, it will make a
7192 glyph matrix reallocation necessary. */
7193 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
7200 /* Return a pointer to struct font_info of a font named FONTNAME for
7201 frame F. If no such font is loaded, return NULL. */
7204 x_query_font (f
, fontname
)
7206 register char *fontname
;
7208 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7211 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7212 if (dpyinfo
->font_table
[i
].name
7213 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
7214 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
7215 return (dpyinfo
->font_table
+ i
);
7220 /* Find a CCL program for a font specified by FONTP, and set the member
7221 `encoder' of the structure. */
7224 x_find_ccl_program (fontp
)
7225 struct font_info
*fontp
;
7227 Lisp_Object list
, elt
;
7229 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
7233 && STRINGP (XCAR (elt
))
7234 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
7240 struct ccl_program
*ccl
7241 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
7243 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
7246 fontp
->font_encoder
= ccl
;
7252 /* The Mac Event loop code */
7254 #if !TARGET_API_MAC_CARBON
7256 #include <Quickdraw.h>
7257 #include <Balloons.h>
7258 #include <Devices.h>
7260 #include <Gestalt.h>
7262 #include <Processes.h>
7264 #include <ToolUtils.h>
7265 #include <TextUtils.h>
7266 #include <Dialogs.h>
7269 #include <Resources.h>
7274 #endif /* ! TARGET_API_MAC_CARBON */
7279 #define WINDOW_RESOURCE 128
7280 #define TERM_WINDOW_RESOURCE 129
7282 #define DEFAULT_NUM_COLS 80
7284 #define MIN_DOC_SIZE 64
7285 #define MAX_DOC_SIZE 32767
7287 #define EXTRA_STACK_ALLOC (256 * 1024)
7289 #define ARGV_STRING_LIST_ID 129
7290 #define ABOUT_ALERT_ID 128
7291 #define RAM_TOO_LARGE_ALERT_ID 129
7293 /* Contains the string "reverse", which is a constant for mouse button emu.*/
7294 Lisp_Object Qreverse
;
7296 /* True if using command key as meta key. */
7297 Lisp_Object Vmac_command_key_is_meta
;
7299 /* Modifier associated with the option key, or nil for normal behavior. */
7300 Lisp_Object Vmac_option_modifier
;
7302 /* True if the ctrl and meta keys should be reversed. */
7303 Lisp_Object Vmac_reverse_ctrl_meta
;
7305 /* True if the option and command modifiers should be used to emulate
7306 a three button mouse */
7307 Lisp_Object Vmac_emulate_three_button_mouse
;
7309 #if USE_CARBON_EVENTS
7310 /* True if the mouse wheel button (i.e. button 4) should map to
7311 mouse-2, instead of mouse-3. */
7312 Lisp_Object Vmac_wheel_button_is_mouse_2
;
7314 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
7315 for processing before Emacs sees it. */
7316 Lisp_Object Vmac_pass_command_to_system
;
7318 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
7319 for processing before Emacs sees it. */
7320 Lisp_Object Vmac_pass_control_to_system
;
7322 /* Points to the variable `inev' in the function XTread_socket. It is
7323 used for passing an input event to the function back from
7324 Carbon/Apple event handlers. */
7325 static struct input_event
*read_socket_inev
= NULL
;
7328 /* Set in term/mac-win.el to indicate that event loop can now generate
7329 drag and drop events. */
7330 Lisp_Object Qmac_ready_for_drag_n_drop
;
7332 Point saved_menu_event_location
;
7335 static void init_required_apple_events (void);
7337 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
7339 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
7340 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
7341 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
7343 #if TARGET_API_MAC_CARBON
7345 static pascal OSErr
mac_do_track_drag (DragTrackingMessage
, WindowPtr
, void*, DragReference
);
7346 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
7347 static DragTrackingHandlerUPP mac_do_track_dragUPP
= NULL
;
7348 static DragReceiveHandlerUPP mac_do_receive_dragUPP
= NULL
;
7351 static Lisp_Object Qapplication
, Qabout
;
7352 #if USE_CARBON_EVENTS
7354 extern void init_service_handler ();
7355 static Lisp_Object Qpreferences
, Qservices
, Qpaste
, Qperform
;
7357 /* Window Event Handler */
7358 static pascal OSStatus
mac_handle_window_event (EventHandlerCallRef
,
7361 OSErr
install_window_handler (WindowPtr
);
7363 extern void init_emacs_passwd_dir ();
7364 extern int emacs_main (int, char **, char **);
7366 extern void initialize_applescript();
7367 extern void terminate_applescript();
7370 #if USE_CARBON_EVENTS
7371 mac_to_emacs_modifiers (UInt32 mods
)
7373 mac_to_emacs_modifiers (EventModifiers mods
)
7376 unsigned int result
= 0;
7377 if (mods
& macShiftKey
)
7378 result
|= shift_modifier
;
7379 if (mods
& macCtrlKey
)
7380 result
|= ctrl_modifier
;
7381 if (mods
& macMetaKey
)
7382 result
|= meta_modifier
;
7383 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
7384 result
|= alt_modifier
;
7385 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
7386 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
7388 result
|= XUINT(val
);
7395 mac_get_emulated_btn ( UInt32 modifiers
)
7398 if (!NILP (Vmac_emulate_three_button_mouse
)) {
7399 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
7400 if (modifiers
& cmdKey
)
7401 result
= cmdIs3
? 2 : 1;
7402 else if (modifiers
& optionKey
)
7403 result
= cmdIs3
? 1 : 2;
7408 #if USE_CARBON_EVENTS
7409 /* Obtains the event modifiers from the event ref and then calls
7410 mac_to_emacs_modifiers. */
7412 mac_event_to_emacs_modifiers (EventRef eventRef
)
7415 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7416 sizeof (UInt32
), NULL
, &mods
);
7417 if (!NILP (Vmac_emulate_three_button_mouse
) &&
7418 GetEventClass(eventRef
) == kEventClassMouse
)
7420 mods
&= ~(optionKey
| cmdKey
);
7422 return mac_to_emacs_modifiers (mods
);
7425 /* Given an event ref, return the code to use for the mouse button
7426 code in the emacs input_event. */
7428 mac_get_mouse_btn (EventRef ref
)
7430 EventMouseButton result
= kEventMouseButtonPrimary
;
7431 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7432 sizeof (EventMouseButton
), NULL
, &result
);
7435 case kEventMouseButtonPrimary
:
7436 if (NILP (Vmac_emulate_three_button_mouse
))
7440 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7441 sizeof (UInt32
), NULL
, &mods
);
7442 return mac_get_emulated_btn(mods
);
7444 case kEventMouseButtonSecondary
:
7445 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7446 case kEventMouseButtonTertiary
:
7447 case 4: /* 4 is the number for the mouse wheel button */
7448 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7454 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7455 events. However the click of the mouse wheel is not converted to a
7456 mouseDown or mouseUp event. Likewise for dead key down events.
7457 This calls ConvertEventRef, but then checks to see if it is a mouse
7458 up/down, or a dead key down carbon event that has not been
7459 converted, and if so, converts it by hand (to be picked up in the
7460 XTread_socket loop). */
7461 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7463 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7468 switch (GetEventClass (eventRef
))
7470 case kEventClassMouse
:
7471 switch (GetEventKind (eventRef
))
7473 case kEventMouseDown
:
7474 eventRec
->what
= mouseDown
;
7479 eventRec
->what
= mouseUp
;
7488 case kEventClassKeyboard
:
7489 switch (GetEventKind (eventRef
))
7491 case kEventRawKeyDown
:
7493 unsigned char char_codes
;
7496 eventRec
->what
= keyDown
;
7497 GetEventParameter (eventRef
, kEventParamKeyMacCharCodes
, typeChar
,
7498 NULL
, sizeof (char), NULL
, &char_codes
);
7499 GetEventParameter (eventRef
, kEventParamKeyCode
, typeUInt32
,
7500 NULL
, sizeof (UInt32
), NULL
, &key_code
);
7501 eventRec
->message
= char_codes
| ((key_code
& 0xff) << 8);
7517 /* Need where and when. */
7520 GetEventParameter (eventRef
, kEventParamMouseLocation
, typeQDPoint
,
7521 NULL
, sizeof (Point
), NULL
, &eventRec
->where
);
7522 /* Use two step process because new event modifiers are 32-bit
7523 and old are 16-bit. Currently, only loss is NumLock & Fn. */
7524 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
,
7525 NULL
, sizeof (UInt32
), NULL
, &mods
);
7526 eventRec
->modifiers
= mods
;
7528 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7539 Handle menubar_handle
;
7540 MenuHandle menu_handle
;
7542 menubar_handle
= GetNewMBar (128);
7543 if(menubar_handle
== NULL
)
7545 SetMenuBar (menubar_handle
);
7548 #if !TARGET_API_MAC_CARBON
7549 menu_handle
= GetMenuHandle (M_APPLE
);
7550 if(menu_handle
!= NULL
)
7551 AppendResMenu (menu_handle
,'DRVR');
7559 do_init_managers (void)
7561 #if !TARGET_API_MAC_CARBON
7562 InitGraf (&qd
.thePort
);
7564 FlushEvents (everyEvent
, 0);
7569 #endif /* !TARGET_API_MAC_CARBON */
7572 #if !TARGET_API_MAC_CARBON
7573 /* set up some extra stack space for use by emacs */
7574 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7576 /* MaxApplZone must be called for AppleScript to execute more
7577 complicated scripts */
7580 #endif /* !TARGET_API_MAC_CARBON */
7584 do_check_ram_size (void)
7586 SInt32 physical_ram_size
, logical_ram_size
;
7588 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7589 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7590 || physical_ram_size
> (1 << VALBITS
)
7591 || logical_ram_size
> (1 << VALBITS
))
7593 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7599 do_window_update (WindowPtr win
)
7601 struct frame
*f
= mac_window_to_frame (win
);
7605 /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
7607 if (win
!= tip_window
)
7609 if (f
->async_visible
== 0)
7611 f
->async_visible
= 1;
7612 f
->async_iconified
= 0;
7613 SET_FRAME_GARBAGED (f
);
7615 /* An update event is equivalent to MapNotify on X, so report
7616 visibility changes properly. */
7617 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7618 /* Force a redisplay sooner or later to update the
7619 frame titles in case this is the second frame. */
7620 record_asynch_buffer_change ();
7626 #if TARGET_API_MAC_CARBON
7628 RgnHandle region
= NewRgn ();
7630 GetPortVisibleRegion (GetWindowPort (win
), region
);
7631 GetRegionBounds (region
, &r
);
7632 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
7633 UpdateControls (win
, region
);
7634 DisposeRgn (region
);
7637 r
= (*win
->visRgn
)->rgnBBox
;
7638 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
7639 UpdateControls (win
, win
->visRgn
);
7648 is_emacs_window (WindowPtr win
)
7650 Lisp_Object tail
, frame
;
7655 FOR_EACH_FRAME (tail
, frame
)
7656 if (FRAME_MAC_P (XFRAME (frame
)))
7657 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7666 /* Window-activate events will do the job. */
7672 /* Window-deactivate events will do the job. */
7677 do_apple_menu (SInt16 menu_item
)
7679 #if !TARGET_API_MAC_CARBON
7681 SInt16 da_driver_refnum
;
7683 if (menu_item
== I_ABOUT
)
7684 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7687 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7688 da_driver_refnum
= OpenDeskAcc (item_name
);
7690 #endif /* !TARGET_API_MAC_CARBON */
7694 do_menu_choice (SInt32 menu_choice
)
7696 SInt16 menu_id
, menu_item
;
7698 menu_id
= HiWord (menu_choice
);
7699 menu_item
= LoWord (menu_choice
);
7707 do_apple_menu (menu_item
);
7712 struct frame
*f
= mac_focus_frame (&one_mac_display_info
);
7713 MenuHandle menu
= GetMenuHandle (menu_id
);
7718 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7719 menubar_selection_callback (f
, refcon
);
7728 /* Handle drags in size box. Based on code contributed by Ben
7729 Mesander and IM - Window Manager A. */
7732 do_grow_window (WindowPtr w
, EventRecord
*e
)
7735 int rows
, columns
, width
, height
;
7736 struct frame
*f
= mac_window_to_frame (w
);
7737 XSizeHints
*size_hints
= FRAME_SIZE_HINTS (f
);
7738 int min_width
= MIN_DOC_SIZE
, min_height
= MIN_DOC_SIZE
;
7739 #if TARGET_API_MAC_CARBON
7745 if (size_hints
->flags
& PMinSize
)
7747 min_width
= size_hints
->min_width
;
7748 min_height
= size_hints
->min_height
;
7750 SetRect (&limit_rect
, min_width
, min_height
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7752 #if TARGET_API_MAC_CARBON
7753 if (!ResizeWindow (w
, e
->where
, &limit_rect
, &new_rect
))
7755 height
= new_rect
.bottom
- new_rect
.top
;
7756 width
= new_rect
.right
- new_rect
.left
;
7758 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7759 /* see if it really changed size */
7762 height
= HiWord (grow_size
);
7763 width
= LoWord (grow_size
);
7766 if (width
!= FRAME_PIXEL_WIDTH (f
)
7767 || height
!= FRAME_PIXEL_HEIGHT (f
))
7769 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
7770 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
7772 x_set_window_size (f
, 0, columns
, rows
);
7777 /* Handle clicks in zoom box. Calculation of "standard state" based
7778 on code in IM - Window Manager A and code contributed by Ben
7779 Mesander. The standard state of an Emacs window is 80-characters
7780 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7783 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7786 Rect zoom_rect
, port_rect
;
7788 int w_title_height
, columns
, rows
, width
, height
;
7789 struct frame
*f
= mac_window_to_frame (w
);
7790 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7792 #if TARGET_API_MAC_CARBON
7794 Point standard_size
;
7796 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7797 standard_size
.v
= dpyinfo
->height
;
7799 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
7800 zoom_in_or_out
= inZoomIn
;
7803 /* Adjust the standard size according to character boundaries. */
7805 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
7806 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7807 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
7808 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7809 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
7810 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
7811 && port_rect
.left
== zoom_rect
.left
7812 && port_rect
.top
== zoom_rect
.top
)
7813 zoom_in_or_out
= inZoomIn
;
7815 zoom_in_or_out
= inZoomOut
;
7818 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
7820 #else /* not TARGET_API_MAC_CARBON */
7821 GetPort (&save_port
);
7823 SetPortWindowPort (w
);
7825 /* Clear window to avoid flicker. */
7826 EraseRect (&(w
->portRect
));
7827 if (zoom_in_or_out
== inZoomOut
)
7829 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7830 LocalToGlobal (&top_left
);
7832 /* calculate height of window's title bar */
7833 w_title_height
= top_left
.v
- 1
7834 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7836 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7837 zoom_rect
= qd
.screenBits
.bounds
;
7838 zoom_rect
.top
+= w_title_height
;
7839 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7841 zoom_rect
.right
= zoom_rect
.left
7842 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7844 /* Adjust the standard size according to character boundaries. */
7845 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7847 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7849 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7853 ZoomWindow (w
, zoom_in_or_out
, f
== mac_focus_frame (dpyinfo
));
7855 SetPort (save_port
);
7856 #endif /* not TARGET_API_MAC_CARBON */
7858 /* retrieve window size and update application values */
7859 #if TARGET_API_MAC_CARBON
7860 GetWindowPortBounds (w
, &port_rect
);
7862 port_rect
= w
->portRect
;
7864 height
= port_rect
.bottom
- port_rect
.top
;
7865 width
= port_rect
.right
- port_rect
.left
;
7867 if (width
!= FRAME_PIXEL_WIDTH (f
)
7868 || height
!= FRAME_PIXEL_HEIGHT (f
))
7870 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
7871 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
7873 change_frame_size (f
, rows
, columns
, 0, 1, 0);
7874 SET_FRAME_GARBAGED (f
);
7875 cancel_mouse_face (f
);
7877 FRAME_PIXEL_WIDTH (f
) = width
;
7878 FRAME_PIXEL_HEIGHT (f
) = height
;
7880 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
7883 /* Intialize AppleEvent dispatcher table for the required events. */
7885 init_required_apple_events ()
7890 /* Make sure we have apple events before starting. */
7891 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7895 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7898 #if TARGET_API_MAC_CARBON
7899 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7900 NewAEEventHandlerUPP
7901 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7904 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7905 NewAEEventHandlerProc
7906 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7912 #if TARGET_API_MAC_CARBON
7913 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7914 NewAEEventHandlerUPP
7915 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7918 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7919 NewAEEventHandlerProc
7920 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7926 #if TARGET_API_MAC_CARBON
7927 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7928 NewAEEventHandlerUPP
7929 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7932 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7933 NewAEEventHandlerProc
7934 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7940 #if TARGET_API_MAC_CARBON
7941 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7942 NewAEEventHandlerUPP
7943 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7946 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7947 NewAEEventHandlerProc
7948 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7956 mac_store_application_menu_event (event
)
7957 #if USE_CARBON_EVENTS
7963 struct input_event buf
;
7964 Lisp_Object frame
, entry
;
7968 XSETFRAME (frame
, mac_focus_frame (&one_mac_display_info
));
7969 buf
.kind
= MENU_BAR_EVENT
;
7970 buf
.frame_or_window
= frame
;
7972 kbd_buffer_store_event (&buf
);
7974 buf
.arg
= Qapplication
;
7975 kbd_buffer_store_event (&buf
);
7977 #if USE_CARBON_EVENTS
7978 switch (GetEventClass (event
))
7981 case kEventClassService
:
7982 buf
.arg
= Qservices
;
7983 kbd_buffer_store_event (&buf
);
7984 switch (GetEventKind (event
))
7986 case kEventServicePaste
:
7990 case kEventServicePerform
:
7993 CFStringRef message
;
7995 err
= GetEventParameter (event
, kEventParamServiceMessageName
,
7996 typeCFStringRef
, NULL
,
7997 sizeof (CFStringRef
), NULL
, &message
);
7999 kbd_buffer_store_event (&buf
);
8000 if (err
== noErr
&& message
)
8001 entry
= intern (SDATA (cfstring_to_lisp (message
)));
8011 #endif /* MAC_OSX */
8012 case kEventClassCommand
:
8016 GetEventParameter(event
, kEventParamDirectObject
, typeHICommand
,
8017 NULL
, sizeof (HICommand
), NULL
, &command
);
8018 switch (command
.commandID
)
8020 case kHICommandAbout
:
8024 case kHICommandPreferences
:
8025 entry
= Qpreferences
;
8027 #endif /* MAC_OSX */
8028 case kHICommandQuit
:
8040 #else /* USE_CARBON_EVENTS */
8043 case kHICommandAbout
:
8046 case kHICommandQuit
:
8055 kbd_buffer_store_event (&buf
);
8058 #if USE_CARBON_EVENTS
8059 static pascal OSStatus
8060 mac_handle_command_event (next_handler
, event
, data
)
8061 EventHandlerCallRef next_handler
;
8068 GetEventParameter(event
, kEventParamDirectObject
, typeHICommand
, NULL
,
8069 sizeof (HICommand
), NULL
, &command
);
8071 switch (command
.commandID
)
8073 case kHICommandAbout
:
8075 case kHICommandPreferences
:
8076 #endif /* MAC_OSX */
8077 result
= CallNextEventHandler (next_handler
, event
);
8078 if (result
!= eventNotHandledErr
)
8081 mac_store_application_menu_event (event
);
8088 return eventNotHandledErr
;
8092 init_command_handler ()
8095 EventTypeSpec specs
[] = {{kEventClassCommand
, kEventCommandProcess
}};
8096 static EventHandlerUPP handle_command_eventUPP
= NULL
;
8098 if (handle_command_eventUPP
== NULL
)
8099 handle_command_eventUPP
= NewEventHandlerUPP (mac_handle_command_event
);
8100 return InstallApplicationEventHandler (handle_command_eventUPP
,
8101 GetEventTypeCount (specs
), specs
,
8105 static pascal OSStatus
8106 mac_handle_window_event (next_handler
, event
, data
)
8107 EventHandlerCallRef next_handler
;
8114 XSizeHints
*size_hints
;
8116 GetEventParameter (event
, kEventParamDirectObject
, typeWindowRef
,
8117 NULL
, sizeof (WindowPtr
), NULL
, &wp
);
8119 switch (GetEventKind (event
))
8121 case kEventWindowUpdate
:
8122 result
= CallNextEventHandler (next_handler
, event
);
8123 if (result
!= eventNotHandledErr
)
8126 do_window_update (wp
);
8129 case kEventWindowBoundsChanging
:
8130 result
= CallNextEventHandler (next_handler
, event
);
8131 if (result
!= eventNotHandledErr
)
8134 GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
8135 NULL
, sizeof (UInt32
), NULL
, &attributes
);
8136 size_hints
= FRAME_SIZE_HINTS (mac_window_to_frame (wp
));
8137 if ((attributes
& kWindowBoundsChangeUserResize
)
8138 && ((size_hints
->flags
& (PResizeInc
| PBaseSize
| PMinSize
))
8139 == (PResizeInc
| PBaseSize
| PMinSize
)))
8144 GetEventParameter (event
, kEventParamCurrentBounds
,
8146 NULL
, sizeof (Rect
), NULL
, &bounds
);
8147 width
= bounds
.right
- bounds
.left
;
8148 height
= bounds
.bottom
- bounds
.top
;
8150 if (width
< size_hints
->min_width
)
8151 width
= size_hints
->min_width
;
8153 width
= size_hints
->base_width
8154 + (int) ((width
- size_hints
->base_width
)
8155 / (float) size_hints
->width_inc
+ .5)
8156 * size_hints
->width_inc
;
8158 if (height
< size_hints
->min_height
)
8159 height
= size_hints
->min_height
;
8161 height
= size_hints
->base_height
8162 + (int) ((height
- size_hints
->base_height
)
8163 / (float) size_hints
->height_inc
+ .5)
8164 * size_hints
->height_inc
;
8166 bounds
.right
= bounds
.left
+ width
;
8167 bounds
.bottom
= bounds
.top
+ height
;
8168 SetEventParameter (event
, kEventParamCurrentBounds
,
8169 typeQDRectangle
, sizeof (Rect
), &bounds
);
8175 return eventNotHandledErr
;
8178 static pascal OSStatus
8179 mac_handle_mouse_event (next_handler
, event
, data
)
8180 EventHandlerCallRef next_handler
;
8186 switch (GetEventKind (event
))
8188 case kEventMouseWheelMoved
:
8192 EventMouseWheelAxis axis
;
8196 result
= CallNextEventHandler (next_handler
, event
);
8197 if (result
!= eventNotHandledErr
|| read_socket_inev
== NULL
)
8200 GetEventParameter (event
, kEventParamWindowRef
, typeWindowRef
,
8201 NULL
, sizeof (WindowRef
), NULL
, &wp
);
8202 f
= mac_window_to_frame (wp
);
8203 if (f
!= mac_focus_frame (&one_mac_display_info
))
8206 GetEventParameter (event
, kEventParamMouseWheelAxis
,
8207 typeMouseWheelAxis
, NULL
,
8208 sizeof (EventMouseWheelAxis
), NULL
, &axis
);
8209 if (axis
!= kEventMouseWheelAxisY
)
8212 GetEventParameter (event
, kEventParamMouseWheelDelta
, typeSInt32
,
8213 NULL
, sizeof (SInt32
), NULL
, &delta
);
8214 GetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
8215 NULL
, sizeof (Point
), NULL
, &point
);
8216 read_socket_inev
->kind
= WHEEL_EVENT
;
8217 read_socket_inev
->code
= 0;
8218 read_socket_inev
->modifiers
=
8219 (mac_event_to_emacs_modifiers (event
)
8220 | ((delta
< 0) ? down_modifier
: up_modifier
));
8221 SetPortWindowPort (wp
);
8222 GlobalToLocal (&point
);
8223 XSETINT (read_socket_inev
->x
, point
.h
);
8224 XSETINT (read_socket_inev
->y
, point
.v
);
8225 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
8235 return eventNotHandledErr
;
8237 #endif /* USE_CARBON_EVENTS */
8241 install_window_handler (window
)
8245 #if USE_CARBON_EVENTS
8246 EventTypeSpec specs_window
[] =
8247 {{kEventClassWindow
, kEventWindowUpdate
},
8248 {kEventClassWindow
, kEventWindowBoundsChanging
}};
8249 EventTypeSpec specs_mouse
[] = {{kEventClassMouse
, kEventMouseWheelMoved
}};
8250 static EventHandlerUPP handle_window_eventUPP
= NULL
;
8251 static EventHandlerUPP handle_mouse_eventUPP
= NULL
;
8253 if (handle_window_eventUPP
== NULL
)
8254 handle_window_eventUPP
= NewEventHandlerUPP (mac_handle_window_event
);
8255 if (handle_mouse_eventUPP
== NULL
)
8256 handle_mouse_eventUPP
= NewEventHandlerUPP (mac_handle_mouse_event
);
8257 err
= InstallWindowEventHandler (window
, handle_window_eventUPP
,
8258 GetEventTypeCount (specs_window
),
8259 specs_window
, NULL
, NULL
);
8261 err
= InstallWindowEventHandler (window
, handle_mouse_eventUPP
,
8262 GetEventTypeCount (specs_mouse
),
8263 specs_mouse
, NULL
, NULL
);
8265 #if TARGET_API_MAC_CARBON
8266 if (mac_do_track_dragUPP
== NULL
)
8267 mac_do_track_dragUPP
= NewDragTrackingHandlerUPP (mac_do_track_drag
);
8268 if (mac_do_receive_dragUPP
== NULL
)
8269 mac_do_receive_dragUPP
= NewDragReceiveHandlerUPP (mac_do_receive_drag
);
8272 err
= InstallTrackingHandler (mac_do_track_dragUPP
, window
, NULL
);
8274 err
= InstallReceiveHandler (mac_do_receive_dragUPP
, window
, NULL
);
8280 remove_window_handler (window
)
8283 #if TARGET_API_MAC_CARBON
8284 if (mac_do_track_dragUPP
)
8285 RemoveTrackingHandler (mac_do_track_dragUPP
, window
);
8286 if (mac_do_receive_dragUPP
)
8287 RemoveReceiveHandler (mac_do_receive_dragUPP
, window
);
8291 /* Open Application Apple Event */
8293 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
8299 /* Called when we receive an AppleEvent with an ID of
8300 "kAEOpenDocuments". This routine gets the direct parameter,
8301 extracts the FSSpecs in it, and puts their names on a list. */
8302 #pragma options align=mac68k
8303 typedef struct SelectionRange
{
8304 short unused1
; // 0 (not used)
8305 short lineNum
; // line to select (<0 to specify range)
8306 long startRange
; // start of selection range (if line < 0)
8307 long endRange
; // end of selection range (if line < 0)
8308 long unused2
; // 0 (not used)
8309 long theDate
; // modification date/time
8311 #pragma options align=reset
8314 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
8319 DescType actual_type
;
8321 SelectionRange position
;
8322 Lisp_Object file_list
= Qnil
;
8324 xassert (read_socket_inev
);
8326 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
8328 goto descriptor_error_exit
;
8330 err
= AEGetParamPtr (message
, keyAEPosition
, typeChar
, &actual_type
, &position
, sizeof(SelectionRange
), &actual_size
);
8332 file_list
= Fcons (list3 (make_number (position
.lineNum
+ 1),
8333 make_number (position
.startRange
+ 1),
8334 make_number (position
.endRange
+ 1)),
8337 /* Check to see that we got all of the required parameters from the
8338 event descriptor. For an 'odoc' event this should just be the
8340 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
8341 &actual_type
, (Ptr
) &keyword
,
8342 sizeof (keyword
), &actual_size
);
8343 /* No error means that we found some unused parameters.
8344 errAEDescNotFound means that there are no more parameters. If we
8345 get an error code other than that, flag it. */
8346 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
8348 err
= errAEEventNotHandled
;
8353 /* Got all the parameters we need. Now, go through the direct
8354 object list and parse it up. */
8356 long num_files_to_open
;
8358 err
= AECountItems (&the_desc
, &num_files_to_open
);
8363 /* AE file list is one based so just use that for indexing here. */
8364 for (i
= 1; i
<= num_files_to_open
; i
++)
8366 char unix_path_name
[MAXPATHLEN
];
8370 err
= AEGetNthPtr (&the_desc
, i
, typeFSRef
, &keyword
,
8371 &actual_type
, &fref
, sizeof (FSRef
),
8373 if (err
!= noErr
|| actual_type
!= typeFSRef
)
8376 if (FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
))
8381 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
8382 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
8383 if (err
!= noErr
) continue;
8385 if (fsspec_to_posix_pathname (&fs
, unix_path_name
,
8386 sizeof (unix_path_name
) - 1) == noErr
)
8388 /* x-dnd functions expect undecoded filenames. */
8389 file_list
= Fcons (make_unibyte_string (unix_path_name
,
8390 strlen (unix_path_name
)),
8395 /* Build a DRAG_N_DROP_EVENT type event as is done in
8396 constuct_drag_n_drop in w32term.c. */
8397 if (!NILP (file_list
))
8399 struct frame
*f
= mac_focus_frame (&one_mac_display_info
);
8403 read_socket_inev
->kind
= DRAG_N_DROP_EVENT
;
8404 read_socket_inev
->code
= 0;
8405 read_socket_inev
->modifiers
= 0;
8407 XSETINT (read_socket_inev
->x
, 0);
8408 XSETINT (read_socket_inev
->y
, 0);
8410 XSETFRAME (frame
, f
);
8411 read_socket_inev
->frame_or_window
= Fcons (frame
, file_list
);
8414 /* Regardless of whether Emacs was suspended or in the
8415 foreground, ask it to redraw its entire screen. Otherwise
8416 parts of the screen can be left in an inconsistent
8418 wp
= FRAME_MAC_WINDOW (f
);
8420 #if TARGET_API_MAC_CARBON
8424 GetWindowPortBounds (wp
, &r
);
8425 InvalWindowRect (wp
, &r
);
8427 #else /* not TARGET_API_MAC_CARBON */
8428 InvalRect (&(wp
->portRect
));
8429 #endif /* not TARGET_API_MAC_CARBON */
8435 /* Nuke the coerced file list in any case */
8436 err2
= AEDisposeDesc(&the_desc
);
8438 descriptor_error_exit
:
8439 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
8444 #if TARGET_API_MAC_CARBON
8446 mac_do_track_drag (DragTrackingMessage message
, WindowPtr window
,
8447 void *handlerRefCon
, DragReference theDrag
)
8449 static int can_accept
;
8452 ItemReference theItem
;
8453 FlavorFlags theFlags
;
8456 if (GetFrontWindowOfClass (kMovableModalWindowClass
, false))
8457 return dragNotAcceptedErr
;
8461 case kDragTrackingEnterHandler
:
8462 CountDragItems (theDrag
, &items
);
8464 for (index
= 1; index
<= items
; index
++)
8466 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
8467 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
8468 if (result
== noErr
)
8476 case kDragTrackingEnterWindow
:
8479 RgnHandle hilite_rgn
= NewRgn ();
8481 struct frame
*f
= mac_window_to_frame (window
);
8483 GetWindowPortBounds (window
, &r
);
8484 OffsetRect (&r
, -r
.left
, -r
.top
);
8485 RectRgn (hilite_rgn
, &r
);
8486 ShowDragHilite (theDrag
, hilite_rgn
, true);
8487 DisposeRgn (hilite_rgn
);
8488 SetThemeCursor (kThemeCopyArrowCursor
);
8492 case kDragTrackingInWindow
:
8495 case kDragTrackingLeaveWindow
:
8498 struct frame
*f
= mac_window_to_frame (window
);
8500 HideDragHilite (theDrag
);
8501 SetThemeCursor (kThemeArrowCursor
);
8505 case kDragTrackingLeaveHandler
:
8513 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
8514 DragReference theDrag
)
8518 FlavorFlags theFlags
;
8521 ItemReference theItem
;
8523 Size size
= sizeof (HFSFlavor
);
8524 Lisp_Object file_list
;
8526 if (GetFrontWindowOfClass (kMovableModalWindowClass
, false))
8527 return dragNotAcceptedErr
;
8530 GetDragMouse (theDrag
, &mouse
, 0L);
8531 CountDragItems (theDrag
, &items
);
8532 for (index
= 1; index
<= items
; index
++)
8534 /* Only handle file references. */
8535 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
8536 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
8537 if (result
== noErr
)
8542 char unix_path_name
[MAXPATHLEN
];
8544 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
8546 /* Use Carbon routines, otherwise it converts the file name
8547 to /Macintosh HD/..., which is not correct. */
8548 FSpMakeFSRef (&data
.fileSpec
, &fref
);
8549 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
8551 if (fsspec_to_posix_pathname (&data
.fileSpec
, unix_path_name
,
8552 sizeof (unix_path_name
) - 1) == noErr
)
8554 /* x-dnd functions expect undecoded filenames. */
8555 file_list
= Fcons (make_unibyte_string (unix_path_name
,
8556 strlen (unix_path_name
)),
8560 /* If there are items in the list, construct an event and post it to
8561 the queue like an interrupt using kbd_buffer_store_event. */
8562 if (!NILP (file_list
))
8564 struct input_event event
;
8566 struct frame
*f
= mac_window_to_frame (window
);
8569 GlobalToLocal (&mouse
);
8570 GetDragModifiers (theDrag
, NULL
, NULL
, &modifiers
);
8572 event
.kind
= DRAG_N_DROP_EVENT
;
8574 event
.modifiers
= mac_to_emacs_modifiers (modifiers
);
8575 event
.timestamp
= TickCount () * (1000 / 60);
8576 XSETINT (event
.x
, mouse
.h
);
8577 XSETINT (event
.y
, mouse
.v
);
8578 XSETFRAME (frame
, f
);
8579 event
.frame_or_window
= Fcons (frame
, file_list
);
8581 /* Post to the interrupt queue */
8582 kbd_buffer_store_event (&event
);
8583 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
8585 ProcessSerialNumber psn
;
8586 GetCurrentProcess (&psn
);
8587 SetFrontProcess (&psn
);
8593 return dragNotAcceptedErr
;
8598 /* Print Document Apple Event */
8600 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
8602 return errAEEventNotHandled
;
8607 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
8609 #if USE_CARBON_EVENTS
8611 EventRef event
= NULL
;
8612 static const HICommand quit_command
= {kEventAttributeNone
, kHICommandQuit
};
8614 err
= CreateEvent (NULL
, kEventClassCommand
, kEventCommandProcess
, 0,
8615 kEventAttributeUserEvent
, &event
);
8617 err
= SetEventParameter (event
, kEventParamDirectObject
, typeHICommand
,
8618 sizeof (HICommand
), &quit_command
);
8620 mac_store_application_menu_event (event
);
8622 ReleaseEvent (event
);
8627 return errAEEventNotHandled
;
8629 mac_store_application_menu_event (kHICommandQuit
);
8638 profiler_exit_proc ()
8640 ProfilerDump ("\pEmacs.prof");
8645 /* These few functions implement Emacs as a normal Mac application
8646 (almost): set up the heap and the Toolbox, handle necessary system
8647 events plus a few simple menu events. They also set up Emacs's
8648 access to functions defined in the rest of this file. Emacs uses
8649 function hooks to perform all its terminal I/O. A complete list of
8650 these functions appear in termhooks.h. For what they do, read the
8651 comments there and see also w32term.c and xterm.c. What's
8652 noticeably missing here is the event loop, which is normally
8653 present in most Mac application. After performing the necessary
8654 Mac initializations, main passes off control to emacs_main
8655 (corresponding to main in emacs.c). Emacs_main calls XTread_socket
8656 (defined further below) to read input. This is where
8657 WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
8664 #if __profile__ /* is the profiler on? */
8665 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
8670 /* set creator and type for files created by MSL */
8675 do_init_managers ();
8680 do_check_ram_size ();
8683 init_emacs_passwd_dir ();
8687 initialize_applescript ();
8689 init_required_apple_events ();
8695 /* set up argv array from STR# resource */
8696 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8700 /* free up AppleScript resources on exit */
8701 atexit (terminate_applescript
);
8703 #if __profile__ /* is the profiler on? */
8704 atexit (profiler_exit_proc
);
8707 /* 3rd param "envp" never used in emacs_main */
8708 (void) emacs_main (argc
, argv
, 0);
8711 /* Never reached - real exit in Fkill_emacs */
8716 /* Table for translating Mac keycode to X keysym values. Contributed
8718 Mapping for special keys is now identical to that in Apple X11
8719 except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
8720 on the right of the Cmd key on laptops, and fn + `enter' (->
8722 static unsigned char keycode_to_xkeysym_table
[] = {
8723 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8724 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8725 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8727 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8728 /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
8729 /*0x38*/ 0, 0, 0, 0,
8730 /*0x3C*/ 0, 0, 0, 0,
8732 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8733 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x0b /*clear*/,
8734 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8735 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8737 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8738 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8739 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8740 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8742 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8743 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8744 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8745 /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
8747 /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
8748 /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
8749 /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8750 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8754 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8756 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8757 return *xKeySym
!= 0;
8760 #if !USE_CARBON_EVENTS
8761 static RgnHandle mouse_region
= NULL
;
8764 mac_wait_next_event (er
, sleep_time
, dequeue
)
8769 static EventRecord er_buf
= {nullEvent
};
8770 UInt32 target_tick
, current_tick
;
8771 EventMask event_mask
;
8773 if (mouse_region
== NULL
)
8774 mouse_region
= NewRgn ();
8776 event_mask
= everyEvent
;
8777 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8778 event_mask
-= highLevelEventMask
;
8780 current_tick
= TickCount ();
8781 target_tick
= current_tick
+ sleep_time
;
8783 if (er_buf
.what
== nullEvent
)
8784 while (!WaitNextEvent (event_mask
, &er_buf
,
8785 target_tick
- current_tick
, mouse_region
))
8787 current_tick
= TickCount ();
8788 if (target_tick
<= current_tick
)
8794 er_buf
.what
= nullEvent
;
8797 #endif /* not USE_CARBON_EVENTS */
8799 /* Emacs calls this whenever it wants to read an input event from the
8802 XTread_socket (sd
, expected
, hold_quit
)
8804 struct input_event
*hold_quit
;
8806 struct input_event inev
;
8808 #if USE_CARBON_EVENTS
8810 EventTargetRef toolbox_dispatcher
;
8813 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8815 if (interrupt_input_blocked
)
8817 interrupt_input_pending
= 1;
8821 interrupt_input_pending
= 0;
8824 /* So people can tell when we have read the available input. */
8825 input_signal_count
++;
8827 #if USE_CARBON_EVENTS
8828 toolbox_dispatcher
= GetEventDispatcherTarget ();
8830 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
8831 kEventRemoveFromQueue
, &eventRef
))
8832 #else /* !USE_CARBON_EVENTS */
8833 while (mac_wait_next_event (&er
, 0, true))
8834 #endif /* !USE_CARBON_EVENTS */
8838 unsigned long timestamp
;
8840 /* It is necessary to set this (additional) argument slot of an
8841 event to nil because keyboard.c protects incompletely
8842 processed event from being garbage collected by placing them
8843 in the kbd_buffer_gcpro vector. */
8845 inev
.kind
= NO_EVENT
;
8848 #if USE_CARBON_EVENTS
8849 timestamp
= GetEventTime (eventRef
) / kEventDurationMillisecond
;
8851 timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8854 #if USE_CARBON_EVENTS
8855 /* Handle new events */
8856 if (!mac_convert_event_ref (eventRef
, &er
))
8858 /* There used to be a handler for the kEventMouseWheelMoved
8859 event here. But as of Mac OS X 10.4, this kind of event
8860 is not directly posted to the main event queue by
8861 two-finger scrolling on the trackpad. Instead, some
8862 private event is posted and it is converted to a wheel
8863 event by the default handler for the application target.
8864 The converted one can be received by a Carbon event
8865 handler installed on a window target. */
8866 read_socket_inev
= &inev
;
8867 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8868 read_socket_inev
= NULL
;
8871 #endif /* USE_CARBON_EVENTS */
8877 WindowPtr window_ptr
;
8878 ControlPartCode part_code
;
8881 #if USE_CARBON_EVENTS
8882 /* This is needed to send mouse events like aqua window
8883 buttons to the correct handler. */
8884 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8885 != eventNotHandledErr
)
8889 if (dpyinfo
->grabbed
&& last_mouse_frame
8890 && FRAME_LIVE_P (last_mouse_frame
))
8892 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
8893 part_code
= inContent
;
8897 part_code
= FindWindow (er
.where
, &window_ptr
);
8898 if (tip_window
&& window_ptr
== tip_window
)
8900 HideWindow (tip_window
);
8901 part_code
= FindWindow (er
.where
, &window_ptr
);
8905 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
8911 f
= mac_focus_frame (dpyinfo
);
8912 saved_menu_event_location
= er
.where
;
8913 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8914 XSETFRAME (inev
.frame_or_window
, f
);
8918 if (window_ptr
!= FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo
)))
8919 SelectWindow (window_ptr
);
8922 ControlPartCode control_part_code
;
8924 Point mouse_loc
= er
.where
;
8926 ControlKind control_kind
;
8929 f
= mac_window_to_frame (window_ptr
);
8930 /* convert to local coordinates of new window */
8931 SetPortWindowPort (window_ptr
);
8933 GlobalToLocal (&mouse_loc
);
8934 #if TARGET_API_MAC_CARBON
8935 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8936 &control_part_code
);
8939 GetControlKind (ch
, &control_kind
);
8942 control_part_code
= FindControl (mouse_loc
, window_ptr
,
8946 #if USE_CARBON_EVENTS
8947 inev
.code
= mac_get_mouse_btn (eventRef
);
8948 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8950 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
8951 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8953 XSETINT (inev
.x
, mouse_loc
.h
);
8954 XSETINT (inev
.y
, mouse_loc
.v
);
8956 if (dpyinfo
->grabbed
&& tracked_scroll_bar
8958 #ifndef USE_TOOLKIT_SCROLL_BARS
8959 /* control_part_code becomes kControlNoPart if
8960 a progress indicator is clicked. */
8961 && control_part_code
!= kControlNoPart
8962 #else /* USE_TOOLKIT_SCROLL_BARS */
8964 && control_kind
.kind
== kControlKindScrollBar
8965 #endif /* MAC_OSX */
8966 #endif /* USE_TOOLKIT_SCROLL_BARS */
8969 struct scroll_bar
*bar
;
8971 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
8973 bar
= tracked_scroll_bar
;
8974 #ifndef USE_TOOLKIT_SCROLL_BARS
8975 control_part_code
= kControlIndicatorPart
;
8979 bar
= (struct scroll_bar
*) GetControlReference (ch
);
8980 #ifdef USE_TOOLKIT_SCROLL_BARS
8981 /* Make the "Ctrl-Mouse-2 splits window" work
8982 for toolkit scroll bars. */
8983 if (er
.modifiers
& controlKey
)
8984 x_scroll_bar_handle_click (bar
, control_part_code
,
8986 else if (er
.what
== mouseDown
)
8987 x_scroll_bar_handle_press (bar
, control_part_code
,
8990 x_scroll_bar_handle_release (bar
, &inev
);
8991 #else /* not USE_TOOLKIT_SCROLL_BARS */
8992 x_scroll_bar_handle_click (bar
, control_part_code
,
8994 if (er
.what
== mouseDown
8995 && control_part_code
== kControlIndicatorPart
)
8996 tracked_scroll_bar
= bar
;
8998 tracked_scroll_bar
= NULL
;
8999 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9004 int x
= mouse_loc
.h
;
9005 int y
= mouse_loc
.v
;
9007 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
9008 if (EQ (window
, f
->tool_bar_window
))
9010 if (er
.what
== mouseDown
)
9011 handle_tool_bar_click (f
, x
, y
, 1, 0);
9013 handle_tool_bar_click (f
, x
, y
, 0,
9019 XSETFRAME (inev
.frame_or_window
, f
);
9020 inev
.kind
= MOUSE_CLICK_EVENT
;
9024 if (er
.what
== mouseDown
)
9026 dpyinfo
->grabbed
|= (1 << inev
.code
);
9027 last_mouse_frame
= f
;
9028 /* Ignore any mouse motion that happened
9029 before this event; any subsequent
9030 mouse-movement Emacs events should reflect
9031 only motion after the ButtonPress. */
9036 last_tool_bar_item
= -1;
9040 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
9041 /* If a button is released though it was not
9042 previously pressed, that would be because
9043 of multi-button emulation. */
9044 dpyinfo
->grabbed
= 0;
9046 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
9049 #ifdef USE_TOOLKIT_SCROLL_BARS
9050 if (inev
.kind
== MOUSE_CLICK_EVENT
)
9055 inev
.modifiers
|= down_modifier
;
9058 inev
.modifiers
|= up_modifier
;
9065 #if TARGET_API_MAC_CARBON
9066 DragWindow (window_ptr
, er
.where
, NULL
);
9067 #else /* not TARGET_API_MAC_CARBON */
9068 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
9069 #endif /* not TARGET_API_MAC_CARBON */
9070 /* Update the frame parameters. */
9072 struct frame
*f
= mac_window_to_frame (window_ptr
);
9074 if (f
&& !f
->async_iconified
)
9075 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
9080 if (TrackGoAway (window_ptr
, er
.where
))
9082 inev
.kind
= DELETE_WINDOW_EVENT
;
9083 XSETFRAME (inev
.frame_or_window
,
9084 mac_window_to_frame (window_ptr
));
9088 /* window resize handling added --ben */
9090 do_grow_window (window_ptr
, &er
);
9093 /* window zoom handling added --ben */
9096 if (TrackBox (window_ptr
, er
.where
, part_code
))
9097 do_zoom_window (window_ptr
, part_code
);
9107 #if USE_CARBON_EVENTS
9108 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9109 != eventNotHandledErr
)
9112 do_window_update ((WindowPtr
) er
.message
);
9117 #if USE_CARBON_EVENTS
9118 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9119 != eventNotHandledErr
)
9122 switch ((er
.message
>> 24) & 0x000000FF)
9124 case suspendResumeMessage
:
9125 if ((er
.message
& resumeFlag
) == 1)
9131 case mouseMovedMessage
:
9132 #if !USE_CARBON_EVENTS
9133 SetRectRgn (mouse_region
, er
.where
.h
, er
.where
.v
,
9134 er
.where
.h
+ 1, er
.where
.v
+ 1);
9136 previous_help_echo_string
= help_echo_string
;
9137 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
9140 if (dpyinfo
->grabbed
&& last_mouse_frame
9141 && FRAME_LIVE_P (last_mouse_frame
))
9142 f
= last_mouse_frame
;
9144 f
= dpyinfo
->x_focus_frame
;
9146 if (dpyinfo
->mouse_face_hidden
)
9148 dpyinfo
->mouse_face_hidden
= 0;
9149 clear_mouse_face (dpyinfo
);
9154 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
9155 Point mouse_pos
= er
.where
;
9157 SetPortWindowPort (wp
);
9159 GlobalToLocal (&mouse_pos
);
9161 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
9162 #ifdef USE_TOOLKIT_SCROLL_BARS
9163 x_scroll_bar_handle_drag (wp
, tracked_scroll_bar
,
9165 #else /* not USE_TOOLKIT_SCROLL_BARS */
9166 x_scroll_bar_note_movement (tracked_scroll_bar
,
9168 - XINT (tracked_scroll_bar
->top
),
9169 er
.when
* (1000 / 60));
9170 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9173 /* Generate SELECT_WINDOW_EVENTs when needed. */
9174 if (mouse_autoselect_window
)
9178 window
= window_from_coordinates (f
,
9183 /* Window will be selected only when it is
9184 not selected now and last mouse movement
9185 event was not in it. Minibuffer window
9186 will be selected iff it is active. */
9187 if (WINDOWP (window
)
9188 && !EQ (window
, last_window
)
9189 && !EQ (window
, selected_window
))
9191 inev
.kind
= SELECT_WINDOW_EVENT
;
9192 inev
.frame_or_window
= window
;
9197 note_mouse_movement (f
, &mouse_pos
);
9201 /* If the contents of the global variable
9202 help_echo_string has changed, generate a
9204 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
9212 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
9214 #if USE_CARBON_EVENTS
9215 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9216 != eventNotHandledErr
)
9219 if (window_ptr
== tip_window
)
9221 HideWindow (tip_window
);
9225 if (!is_emacs_window (window_ptr
))
9228 if ((er
.modifiers
& activeFlag
) != 0)
9230 /* A window has been activated */
9231 Point mouse_loc
= er
.where
;
9233 x_detect_focus_change (dpyinfo
, &er
, &inev
);
9235 SetPortWindowPort (window_ptr
);
9236 GlobalToLocal (&mouse_loc
);
9237 /* Window-activated event counts as mouse movement,
9238 so update things that depend on mouse position. */
9239 note_mouse_movement (mac_window_to_frame (window_ptr
),
9244 /* A window has been deactivated */
9245 #if USE_TOOLKIT_SCROLL_BARS
9246 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
9248 struct input_event event
;
9251 event
.kind
= NO_EVENT
;
9252 x_scroll_bar_handle_release (tracked_scroll_bar
, &event
);
9253 if (event
.kind
!= NO_EVENT
)
9255 event
.timestamp
= timestamp
;
9256 kbd_buffer_store_event_hold (&event
, hold_quit
);
9261 dpyinfo
->grabbed
= 0;
9263 x_detect_focus_change (dpyinfo
, &er
, &inev
);
9265 f
= mac_window_to_frame (window_ptr
);
9266 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9268 /* If we move outside the frame, then we're
9269 certainly no longer on any text in the
9271 clear_mouse_face (dpyinfo
);
9272 dpyinfo
->mouse_face_mouse_frame
= 0;
9275 /* Generate a nil HELP_EVENT to cancel a help-echo.
9276 Do it only if there's something to cancel.
9277 Otherwise, the startup message is cleared when the
9278 mouse leaves the frame. */
9279 if (any_help_event_p
)
9288 int keycode
= (er
.message
& keyCodeMask
) >> 8;
9291 #if USE_CARBON_EVENTS && defined (MAC_OSX)
9292 /* When using Carbon Events, we need to pass raw keyboard
9293 events to the TSM ourselves. If TSM handles it, it
9294 will pass back noErr, otherwise it will pass back
9295 "eventNotHandledErr" and we can process it
9297 if ((!NILP (Vmac_pass_command_to_system
)
9298 || !(er
.modifiers
& cmdKey
))
9299 && (!NILP (Vmac_pass_control_to_system
)
9300 || !(er
.modifiers
& controlKey
))
9301 && (!NILP (Vmac_command_key_is_meta
)
9302 && NILP (Vmac_option_modifier
)
9303 || !(er
.modifiers
& optionKey
)))
9304 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9305 != eventNotHandledErr
)
9310 if (dpyinfo
->x_focus_frame
== NULL
)
9312 /* Beep if keyboard input occurs when all the frames
9320 static SInt16 last_key_script
= -1;
9321 SInt16 current_key_script
= GetScriptManagerVariable (smKeyScript
);
9323 if (last_key_script
!= current_key_script
)
9325 struct input_event event
;
9328 event
.kind
= LANGUAGE_CHANGE_EVENT
;
9330 event
.code
= current_key_script
;
9331 event
.timestamp
= timestamp
;
9332 kbd_buffer_store_event (&event
);
9335 last_key_script
= current_key_script
;
9340 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
9342 clear_mouse_face (dpyinfo
);
9343 dpyinfo
->mouse_face_hidden
= 1;
9346 if (keycode_to_xkeysym (keycode
, &xkeysym
))
9348 inev
.code
= 0xff00 | xkeysym
;
9349 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
9353 if (er
.modifiers
& (controlKey
|
9354 (NILP (Vmac_command_key_is_meta
) ? optionKey
9357 /* This code comes from Keyboard Resource,
9358 Appendix C of IM - Text. This is necessary
9359 since shift is ignored in KCHR table
9360 translation when option or command is pressed.
9361 It also does not translate correctly
9362 control-shift chars like C-% so mask off shift
9364 int new_modifiers
= er
.modifiers
& 0xe600;
9365 /* mask off option and command */
9366 int new_keycode
= keycode
| new_modifiers
;
9367 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
9368 unsigned long some_state
= 0;
9369 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
9370 &some_state
) & 0xff;
9372 else if (!NILP (Vmac_option_modifier
)
9373 && (er
.modifiers
& optionKey
))
9375 /* When using the option key as an emacs modifier,
9376 convert the pressed key code back to one
9377 without the Mac option modifier applied. */
9378 int new_modifiers
= er
.modifiers
& ~optionKey
;
9379 int new_keycode
= keycode
| new_modifiers
;
9380 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
9381 unsigned long some_state
= 0;
9382 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
9383 &some_state
) & 0xff;
9386 inev
.code
= er
.message
& charCodeMask
;
9387 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
9391 #if USE_CARBON_EVENTS
9392 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
9394 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
9396 inev
.modifiers
|= (extra_keyboard_modifiers
9397 & (meta_modifier
| alt_modifier
9398 | hyper_modifier
| super_modifier
));
9399 XSETFRAME (inev
.frame_or_window
, mac_focus_frame (dpyinfo
));
9402 case kHighLevelEvent
:
9403 read_socket_inev
= &inev
;
9404 AEProcessAppleEvent (&er
);
9405 read_socket_inev
= NULL
;
9411 #if USE_CARBON_EVENTS
9412 ReleaseEvent (eventRef
);
9415 if (inev
.kind
!= NO_EVENT
)
9417 inev
.timestamp
= timestamp
;
9418 kbd_buffer_store_event_hold (&inev
, hold_quit
);
9423 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
9428 XSETFRAME (frame
, f
);
9434 any_help_event_p
= 1;
9435 gen_help_event (help_echo_string
, frame
, help_echo_window
,
9436 help_echo_object
, help_echo_pos
);
9440 help_echo_string
= Qnil
;
9441 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
9448 /* If the focus was just given to an autoraising frame,
9450 /* ??? This ought to be able to handle more than one such frame. */
9451 if (pending_autoraise_frame
)
9453 x_raise_frame (pending_autoraise_frame
);
9454 pending_autoraise_frame
= 0;
9462 /* Need to override CodeWarrior's input function so no conversion is
9463 done on newlines Otherwise compiled functions in .elc files will be
9464 read incorrectly. Defined in ...:MSL C:MSL
9465 Common:Source:buffer_io.c. */
9468 __convert_to_newlines (unsigned char * p
, size_t * n
)
9474 __convert_from_newlines (unsigned char * p
, size_t * n
)
9482 make_mac_terminal_frame (struct frame
*f
)
9487 XSETFRAME (frame
, f
);
9489 f
->output_method
= output_mac
;
9490 f
->output_data
.mac
= (struct mac_output
*)
9491 xmalloc (sizeof (struct mac_output
));
9492 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
9494 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
9496 FRAME_COLS (f
) = 96;
9497 FRAME_LINES (f
) = 4;
9499 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
9500 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
9502 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
9504 f
->output_data
.mac
->cursor_pixel
= 0;
9505 f
->output_data
.mac
->border_pixel
= 0x00ff00;
9506 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
9507 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
9509 f
->output_data
.mac
->text_cursor
= kThemeIBeamCursor
;
9510 f
->output_data
.mac
->nontext_cursor
= kThemeArrowCursor
;
9511 f
->output_data
.mac
->modeline_cursor
= kThemeArrowCursor
;
9512 f
->output_data
.mac
->hand_cursor
= kThemePointingHandCursor
;
9513 f
->output_data
.mac
->hourglass_cursor
= kThemeWatchCursor
;
9514 f
->output_data
.mac
->horizontal_drag_cursor
= kThemeResizeLeftRightCursor
;
9516 FRAME_FONTSET (f
) = -1;
9517 f
->output_data
.mac
->explicit_parent
= 0;
9520 f
->border_width
= 0;
9522 f
->internal_border_width
= 0;
9527 f
->new_text_cols
= 0;
9528 f
->new_text_lines
= 0;
9530 SetRect (&r
, f
->left_pos
, f
->top_pos
,
9531 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
9532 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
9536 if (!(FRAME_MAC_WINDOW (f
) =
9537 NewCWindow (NULL
, &r
, "\p", true, dBoxProc
,
9538 (WindowPtr
) -1, 1, (long) f
->output_data
.mac
)))
9540 /* so that update events can find this mac_output struct */
9541 f
->output_data
.mac
->mFP
= f
; /* point back to emacs frame */
9547 /* Need to be initialized for unshow_buffer in window.c. */
9548 selected_window
= f
->selected_window
;
9550 Fmodify_frame_parameters (frame
,
9551 Fcons (Fcons (Qfont
,
9552 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
9553 Fmodify_frame_parameters (frame
,
9554 Fcons (Fcons (Qforeground_color
,
9555 build_string ("black")), Qnil
));
9556 Fmodify_frame_parameters (frame
,
9557 Fcons (Fcons (Qbackground_color
,
9558 build_string ("white")), Qnil
));
9563 /***********************************************************************
9565 ***********************************************************************/
9567 int mac_initialized
= 0;
9570 mac_initialize_display_info ()
9572 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
9573 GDHandle main_device_handle
;
9575 bzero (dpyinfo
, sizeof (*dpyinfo
));
9578 dpyinfo
->mac_id_name
9579 = (char *) xmalloc (SCHARS (Vinvocation_name
)
9580 + SCHARS (Vsystem_name
)
9582 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
9583 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
9585 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
9586 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
9589 main_device_handle
= LMGetMainDevice();
9591 dpyinfo
->reference_count
= 0;
9592 dpyinfo
->resx
= 75.0;
9593 dpyinfo
->resy
= 75.0;
9594 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
9596 /* HasDepth returns true if it is possible to have a 32 bit display,
9597 but this may not be what is actually used. Mac OSX can do better.
9598 CGMainDisplayID is only available on OSX 10.2 and higher, but the
9599 header for CGGetActiveDisplayList says that the first display returned
9600 is the active one, so we use that. */
9602 CGDirectDisplayID disp_id
[1];
9603 CGDisplayCount disp_count
;
9604 CGDisplayErr error_code
;
9606 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
9607 if (error_code
!= 0)
9608 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
9610 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
9613 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
9614 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
9615 gdDevType
, dpyinfo
->color_p
))
9618 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
9619 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
9620 dpyinfo
->grabbed
= 0;
9621 dpyinfo
->root_window
= NULL
;
9622 dpyinfo
->image_cache
= make_image_cache ();
9624 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9625 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9626 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9627 dpyinfo
->mouse_face_window
= Qnil
;
9628 dpyinfo
->mouse_face_overlay
= Qnil
;
9629 dpyinfo
->mouse_face_hidden
= 0;
9634 mac_make_rdb (xrm_option
)
9637 XrmDatabase database
;
9639 database
= xrm_get_preference_database (NULL
);
9641 xrm_merge_string_database (database
, xrm_option
);
9646 struct mac_display_info
*
9647 mac_term_init (display_name
, xrm_option
, resource_name
)
9648 Lisp_Object display_name
;
9650 char *resource_name
;
9652 struct mac_display_info
*dpyinfo
;
9656 if (!mac_initialized
)
9659 mac_initialized
= 1;
9663 error ("Sorry, this version can only handle one display");
9665 mac_initialize_display_info ();
9667 dpyinfo
= &one_mac_display_info
;
9669 dpyinfo
->xrdb
= mac_make_rdb (xrm_option
);
9671 /* Put this display on the chain. */
9672 dpyinfo
->next
= x_display_list
;
9673 x_display_list
= dpyinfo
;
9675 /* Put it on x_display_name_list. */
9676 x_display_name_list
= Fcons (Fcons (display_name
,
9677 Fcons (Qnil
, dpyinfo
->xrdb
)),
9678 x_display_name_list
);
9679 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
9685 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9688 x_delete_display (dpyinfo
)
9689 struct mac_display_info
*dpyinfo
;
9693 /* Discard this display from x_display_name_list and x_display_list.
9694 We can't use Fdelq because that can quit. */
9695 if (! NILP (x_display_name_list
)
9696 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
9697 x_display_name_list
= XCDR (x_display_name_list
);
9702 tail
= x_display_name_list
;
9703 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9705 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9707 XSETCDR (tail
, XCDR (XCDR (tail
)));
9714 if (x_display_list
== dpyinfo
)
9715 x_display_list
= dpyinfo
->next
;
9718 struct x_display_info
*tail
;
9720 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
9721 if (tail
->next
== dpyinfo
)
9722 tail
->next
= tail
->next
->next
;
9725 /* Free the font names in the font table. */
9726 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
9727 if (dpyinfo
->font_table
[i
].name
)
9729 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
9730 xfree (dpyinfo
->font_table
[i
].full_name
);
9731 xfree (dpyinfo
->font_table
[i
].name
);
9734 if (dpyinfo
->font_table
->font_encoder
)
9735 xfree (dpyinfo
->font_table
->font_encoder
);
9737 xfree (dpyinfo
->font_table
);
9738 xfree (dpyinfo
->mac_id_name
);
9740 if (x_display_list
== 0)
9742 mac_clear_font_name_table ();
9743 bzero (dpyinfo
, sizeof (*dpyinfo
));
9752 extern int inhibit_window_system
;
9753 extern int noninteractive
;
9754 CFBundleRef appsBundle
;
9757 /* No need to test if already -nw*/
9758 if (inhibit_window_system
|| noninteractive
)
9761 appsBundle
= CFBundleGetMainBundle();
9762 if (appsBundle
!= NULL
)
9764 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
9765 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
9766 /* We found the bundle identifier, now we know we are valid. */
9773 /* MAC_TODO: Have this start the bundled executable */
9775 /* For now, prevent the fatal error by bringing it up in the terminal */
9776 inhibit_window_system
= 1;
9780 MakeMeTheFrontProcess ()
9782 ProcessSerialNumber psn
;
9785 err
= GetCurrentProcess (&psn
);
9787 (void) SetFrontProcess (&psn
);
9790 /***** Code to handle C-g testing *****/
9792 /* Contains the Mac modifier formed from quit_char */
9793 int mac_quit_char_modifiers
= 0;
9794 int mac_quit_char_keycode
;
9795 extern int quit_char
;
9798 mac_determine_quit_char_modifiers()
9800 /* Todo: Determine modifiers from quit_char. */
9801 UInt32 qc_modifiers
= ctrl_modifier
;
9804 mac_quit_char_modifiers
= 0;
9805 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
9806 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
9807 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
9808 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
9812 init_quit_char_handler ()
9814 /* TODO: Let this support keys other the 'g' */
9815 mac_quit_char_keycode
= 5;
9816 /* Look at <architecture/adb_kb_map.h> for details */
9817 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
9819 mac_determine_quit_char_modifiers();
9823 quit_char_comp (EventRef inEvent
, void *inCompData
)
9825 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
9827 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
9831 UInt32 keyModifiers
;
9832 GetEventParameter(inEvent
, kEventParamKeyCode
,
9833 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
9834 if (keyCode
!= mac_quit_char_keycode
)
9836 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
9837 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
9838 if (keyModifiers
!= mac_quit_char_modifiers
)
9845 mac_check_for_quit_char ()
9848 static EMACS_TIME last_check_time
= { 0, 0 };
9849 static EMACS_TIME one_second
= { 1, 0 };
9852 /* If windows are not initialized, return immediately (keep it bouncin'). */
9853 if (!mac_quit_char_modifiers
)
9856 /* Don't check if last check is less than a second ago. */
9857 EMACS_GET_TIME (now
);
9858 EMACS_SUB_TIME (t
, now
, last_check_time
);
9859 if (EMACS_TIME_LT (t
, one_second
))
9861 last_check_time
= now
;
9863 /* Redetermine modifiers because they are based on lisp variables */
9864 mac_determine_quit_char_modifiers ();
9866 /* Fill the queue with events */
9868 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
9869 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
9874 struct input_event e
;
9876 /* Use an input_event to emulate what the interrupt handler does. */
9878 e
.kind
= ASCII_KEYSTROKE_EVENT
;
9882 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
9883 XSETFRAME (e
.frame_or_window
, mac_focus_frame (&one_mac_display_info
));
9884 /* Remove event from queue to prevent looping. */
9885 RemoveEventFromQueue (GetMainEventQueue (), event
);
9886 ReleaseEvent (event
);
9887 kbd_buffer_store_event (&e
);
9890 #endif /* MAC_OSX */
9898 MenuItemIndex menu_index
;
9900 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandQuit
, 1,
9901 &menu
, &menu_index
);
9903 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
9904 #if USE_CARBON_EVENTS
9905 EnableMenuCommand (NULL
, kHICommandPreferences
);
9906 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandPreferences
, 1,
9907 &menu
, &menu_index
);
9910 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
9911 InsertMenuItemTextWithCFString (menu
, NULL
,
9912 0, kMenuItemAttrSeparator
, 0);
9913 InsertMenuItemTextWithCFString (menu
, CFSTR ("About Emacs"),
9914 0, 0, kHICommandAbout
);
9916 #endif /* USE_CARBON_EVENTS */
9917 #else /* !MAC_OSX */
9918 #if USE_CARBON_EVENTS
9919 SetMenuItemCommandID (GetMenuHandle (M_APPLE
), I_ABOUT
, kHICommandAbout
);
9925 /* Set up use of X before we make the first connection. */
9927 extern frame_parm_handler mac_frame_parm_handlers
[];
9929 static struct redisplay_interface x_redisplay_interface
=
9931 mac_frame_parm_handlers
,
9935 x_clear_end_of_line
,
9937 x_after_update_window_line
,
9938 x_update_window_begin
,
9939 x_update_window_end
,
9942 0, /* flush_display_optional */
9943 x_clear_window_mouse_face
,
9944 x_get_glyph_overhangs
,
9945 x_fix_overlapping_area
,
9946 x_draw_fringe_bitmap
,
9947 0, /* define_fringe_bitmap */
9948 0, /* destroy_fringe_bitmap */
9949 mac_per_char_metric
,
9951 mac_compute_glyph_string_overhangs
,
9952 x_draw_glyph_string
,
9953 mac_define_frame_cursor
,
9954 mac_clear_frame_area
,
9955 mac_draw_window_cursor
,
9956 mac_draw_vertical_window_border
,
9957 mac_shift_glyphs_for_insert
9963 rif
= &x_redisplay_interface
;
9965 clear_frame_hook
= x_clear_frame
;
9966 ins_del_lines_hook
= x_ins_del_lines
;
9967 delete_glyphs_hook
= x_delete_glyphs
;
9968 ring_bell_hook
= XTring_bell
;
9969 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9970 set_terminal_modes_hook
= XTset_terminal_modes
;
9971 update_begin_hook
= x_update_begin
;
9972 update_end_hook
= x_update_end
;
9973 set_terminal_window_hook
= XTset_terminal_window
;
9974 read_socket_hook
= XTread_socket
;
9975 frame_up_to_date_hook
= XTframe_up_to_date
;
9976 mouse_position_hook
= XTmouse_position
;
9977 frame_rehighlight_hook
= XTframe_rehighlight
;
9978 frame_raise_lower_hook
= XTframe_raise_lower
;
9980 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9981 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9982 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9983 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9985 scroll_region_ok
= 1; /* we'll scroll partial frames */
9986 char_ins_del_ok
= 1;
9987 line_ins_del_ok
= 1; /* we'll just blt 'em */
9988 fast_clear_end_of_line
= 1; /* X does this well */
9989 memory_below_frame
= 0; /* we don't remember what scrolls
9993 last_tool_bar_item
= -1;
9994 any_help_event_p
= 0;
9996 /* Try to use interrupt input; if we can't, then start polling. */
9997 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
10001 #if TARGET_API_MAC_CARBON
10002 init_required_apple_events ();
10004 #if USE_CARBON_EVENTS
10006 init_service_handler ();
10008 init_quit_char_handler ();
10009 #endif /* MAC_OSX */
10011 init_command_handler ();
10014 #endif /* USE_CARBON_EVENTS */
10017 if (!inhibit_window_system
)
10018 MakeMeTheFrontProcess ();
10029 staticpro (&x_error_message_string
);
10030 x_error_message_string
= Qnil
;
10033 Qmodifier_value
= intern ("modifier-value");
10034 Qalt
= intern ("alt");
10035 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
10036 Qhyper
= intern ("hyper");
10037 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
10038 Qsuper
= intern ("super");
10039 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
10041 Qapplication
= intern ("application"); staticpro (&Qapplication
);
10042 Qabout
= intern ("about"); staticpro (&Qabout
);
10044 #if USE_CARBON_EVENTS && defined (MAC_OSX)
10045 Qpreferences
= intern ("preferences"); staticpro (&Qpreferences
);
10046 Qservices
= intern ("services"); staticpro (&Qservices
);
10047 Qpaste
= intern ("paste"); staticpro (&Qpaste
);
10048 Qperform
= intern ("perform"); staticpro (&Qperform
);
10052 Fprovide (intern ("mac-carbon"), Qnil
);
10055 staticpro (&Qreverse
);
10056 Qreverse
= intern ("reverse");
10058 staticpro (&x_display_name_list
);
10059 x_display_name_list
= Qnil
;
10061 staticpro (&last_mouse_scroll_bar
);
10062 last_mouse_scroll_bar
= Qnil
;
10064 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
10065 staticpro (&Qmac_ready_for_drag_n_drop
);
10067 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10068 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
10069 #ifdef USE_TOOLKIT_SCROLL_BARS
10070 Vx_toolkit_scroll_bars
= Qt
;
10072 Vx_toolkit_scroll_bars
= Qnil
;
10075 staticpro (&last_mouse_motion_frame
);
10076 last_mouse_motion_frame
= Qnil
;
10078 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
10079 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
10080 Otherwise the option key is used. */);
10081 Vmac_command_key_is_meta
= Qt
;
10083 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
10084 doc
: /* Modifier to use for the Mac alt/option key. The value can
10085 be alt, hyper, or super for the respective modifier. If the value is
10086 nil then the key will act as the normal Mac option modifier. */);
10087 Vmac_option_modifier
= Qnil
;
10089 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
10090 doc
: /* Non-nil means that the control and meta keys are reversed. This is
10091 useful for non-standard keyboard layouts. */);
10092 Vmac_reverse_ctrl_meta
= Qnil
;
10094 DEFVAR_LISP ("mac-emulate-three-button-mouse",
10095 &Vmac_emulate_three_button_mouse
,
10096 doc
: /* t means that when the option-key is held down while pressing the
10097 mouse button, the click will register as mouse-2 and while the
10098 command-key is held down, the click will register as mouse-3.
10099 'reverse means that the option-key will register for mouse-3
10100 and the command-key will register for mouse-2. nil means that
10101 no emulation should be done and the modifiers should be placed
10102 on the mouse-1 event. */);
10103 Vmac_emulate_three_button_mouse
= Qnil
;
10105 #if USE_CARBON_EVENTS
10106 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
10107 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
10108 the right click will be mouse-3.
10109 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
10110 Vmac_wheel_button_is_mouse_2
= Qt
;
10112 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
10113 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
10114 Toolbox for processing before Emacs sees it. */);
10115 Vmac_pass_command_to_system
= Qt
;
10117 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
10118 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
10119 Toolbox for processing before Emacs sees it. */);
10120 Vmac_pass_control_to_system
= Qt
;
10124 DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics
,
10125 doc
: /* If non-nil, allow anti-aliasing.
10126 The text will be rendered using Core Graphics text rendering which
10127 may anti-alias the text. */);
10128 Vmac_use_core_graphics
= Qnil
;
10130 /* Register an entry for `mac-roman' so that it can be used when
10131 creating the terminal frame on Mac OS 9 before loading
10132 term/mac-win.elc. */
10133 DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist
,
10134 doc
: /* Alist linking Emacs character sets to Mac text encoding and Emacs coding system.
10135 Each entry should be of the form:
10137 (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
10139 where CHARSET-NAME is a string used in font names to identify the
10140 charset, TEXT-ENCODING is a TextEncodingBase value, and CODING_SYSTEM
10141 is a coding system corresponding to TEXT-ENCODING. */);
10142 Vmac_charset_info_alist
=
10143 Fcons (list3 (build_string ("mac-roman"),
10144 make_number (smRoman
), Qnil
), Qnil
);
10147 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
10148 (do not change this comment) */