1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* Contributed by Andrew Choi (akochoi@mac.com). */
30 #include "blockinput.h"
38 #if TARGET_API_MAC_CARBON
39 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
40 obtain events from the event queue. If set to 0, WaitNextEvent is
42 #define USE_CARBON_EVENTS 1
43 #else /* not TARGET_API_MAC_CARBON */
44 #include <Quickdraw.h>
45 #include <ToolUtils.h>
49 #include <Resources.h>
51 #include <TextUtils.h>
55 #if defined (__MRC__) || (__MSL__ >= 0x6000)
56 #include <ControlDefinitions.h>
62 #endif /* not TARGET_API_MAC_CARBON */
71 #include <sys/param.h>
76 #include "dispextern.h"
78 #include "termhooks.h"
86 #include "intervals.h"
90 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
91 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
92 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
93 #define macShiftKey (shiftKey)
94 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
95 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
97 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
100 /* Non-nil means Emacs uses toolkit scroll bars. */
102 Lisp_Object Vx_toolkit_scroll_bars
;
104 /* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text. */
105 Lisp_Object Vmac_use_core_graphics
;
108 /* Non-zero means that a HELP_EVENT has been generated since Emacs
111 static int any_help_event_p
;
113 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
114 static Lisp_Object last_window
;
116 /* This is a chain of structures for all the X displays currently in
119 struct x_display_info
*x_display_list
;
121 /* This is a list of cons cells, each of the form (NAME
122 FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
123 x_display_list and in the same order. NAME is the name of the
124 frame. FONT-LIST-CACHE records previous values returned by
125 x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
126 equivalent, which is implemented with a Lisp object, for the
129 Lisp_Object x_display_name_list
;
131 /* This is display since Mac does not support multiple ones. */
132 struct mac_display_info one_mac_display_info
;
134 /* Frame being updated by update_frame. This is declared in term.c.
135 This is set by update_begin and looked at by all the XT functions.
136 It is zero while not inside an update. In that case, the XT
137 functions assume that `selected_frame' is the frame to apply to. */
139 extern struct frame
*updating_frame
;
141 /* This is a frame waiting to be auto-raised, within XTread_socket. */
143 struct frame
*pending_autoraise_frame
;
147 Formerly, we used PointerMotionHintMask (in standard_event_mask)
148 so that we would have to call XQueryPointer after each MotionNotify
149 event to ask for another such event. However, this made mouse tracking
150 slow, and there was a bug that made it eventually stop.
152 Simply asking for MotionNotify all the time seems to work better.
154 In order to avoid asking for motion events and then throwing most
155 of them away or busy-polling the server for mouse positions, we ask
156 the server for pointer motion hints. This means that we get only
157 one event per group of mouse movements. "Groups" are delimited by
158 other kinds of events (focus changes and button clicks, for
159 example), or by XQueryPointer calls; when one of these happens, we
160 get another MotionNotify event the next time the mouse moves. This
161 is at least as efficient as getting motion events when mouse
162 tracking is on, and I suspect only negligibly worse when tracking
165 /* Where the mouse was last time we reported a mouse event. */
167 static Rect last_mouse_glyph
;
169 /* The scroll bar in which the last X motion event occurred.
171 If the last X motion event occurred in a scroll bar, we set this so
172 XTmouse_position can know whether to report a scroll bar motion or
175 If the last X motion event didn't occur in a scroll bar, we set
176 this to Qnil, to tell XTmouse_position to return an ordinary motion
179 static Lisp_Object last_mouse_scroll_bar
;
181 /* This is a hack. We would really prefer that XTmouse_position would
182 return the time associated with the position it returns, but there
183 doesn't seem to be any way to wrest the time-stamp from the server
184 along with the position query. So, we just keep track of the time
185 of the last movement we received, and return that in hopes that
186 it's somewhat accurate. */
188 static Time last_mouse_movement_time
;
190 struct scroll_bar
*tracked_scroll_bar
= NULL
;
192 /* Incremented by XTread_socket whenever it really tries to read
196 static int volatile input_signal_count
;
198 static int input_signal_count
;
201 extern Lisp_Object Vsystem_name
;
203 /* A mask of extra modifier bits to put into every keyboard char. */
205 extern EMACS_INT extra_keyboard_modifiers
;
207 /* The keysyms to use for the various modifiers. */
209 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qmodifier_value
;
211 extern int inhibit_window_system
;
213 #if __MRC__ && !TARGET_API_MAC_CARBON
214 QDGlobals qd
; /* QuickDraw global information structure. */
217 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
219 struct mac_display_info
*mac_display_info_for_display (Display
*);
220 static void x_update_window_end
P_ ((struct window
*, int, int));
221 static int x_io_error_quitter
P_ ((Display
*));
222 int x_catch_errors
P_ ((Display
*));
223 void x_uncatch_errors
P_ ((Display
*, int));
224 void x_lower_frame
P_ ((struct frame
*));
225 void x_scroll_bar_clear
P_ ((struct frame
*));
226 int x_had_errors_p
P_ ((Display
*));
227 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
228 void x_raise_frame
P_ ((struct frame
*));
229 void x_set_window_size
P_ ((struct frame
*, int, int, int));
230 void x_wm_set_window_state
P_ ((struct frame
*, int));
231 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
232 void mac_initialize
P_ ((void));
233 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
234 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
235 static void x_update_end
P_ ((struct frame
*));
236 static void XTframe_up_to_date
P_ ((struct frame
*));
237 static void XTset_terminal_modes
P_ ((void));
238 static void XTreset_terminal_modes
P_ ((void));
239 static void x_clear_frame
P_ ((void));
240 static void frame_highlight
P_ ((struct frame
*));
241 static void frame_unhighlight
P_ ((struct frame
*));
242 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
243 static void mac_focus_changed
P_ ((int, struct mac_display_info
*,
244 struct frame
*, struct input_event
*));
245 static void x_detect_focus_change
P_ ((struct mac_display_info
*,
246 EventRecord
*, struct input_event
*));
247 static void XTframe_rehighlight
P_ ((struct frame
*));
248 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
249 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
250 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
251 enum text_cursor_kinds
));
253 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
254 static void x_flush
P_ ((struct frame
*f
));
255 static void x_update_begin
P_ ((struct frame
*));
256 static void x_update_window_begin
P_ ((struct window
*));
257 static void x_after_update_window_line
P_ ((struct glyph_row
*));
258 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
259 enum scroll_bar_part
*,
260 Lisp_Object
*, Lisp_Object
*,
263 static int is_emacs_window
P_ ((WindowPtr
));
265 static void XSetFont
P_ ((Display
*, GC
, XFontStruct
*));
267 /* Defined in macmenu.h. */
268 extern void menubar_selection_callback (FRAME_PTR
, int);
270 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
271 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
272 #define GC_FONT(gc) ((gc)->xgcv.font)
273 #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc)
276 /* X display function emulation */
279 XFreePixmap (display
, pixmap
)
280 Display
*display
; /* not used */
283 DisposeGWorld (pixmap
);
287 /* Mac version of XDrawLine. */
290 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
296 SetPortWindowPort (w
);
298 RGBForeColor (GC_FORE_COLOR (gc
));
305 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
314 GetGWorld (&old_port
, &old_gdh
);
317 RGBForeColor (GC_FORE_COLOR (gc
));
319 LockPixels (GetGWorldPixMap (p
));
322 UnlockPixels (GetGWorldPixMap (p
));
324 SetGWorld (old_port
, old_gdh
);
329 mac_erase_rectangle (w
, gc
, x
, y
, width
, height
)
333 unsigned int width
, height
;
337 SetPortWindowPort (w
);
339 RGBBackColor (GC_BACK_COLOR (gc
));
340 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
344 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
348 /* Mac version of XClearArea. */
351 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
355 unsigned int width
, height
;
358 mac_erase_rectangle (w
, MAC_WINDOW_NORMAL_GC (w
), x
, y
, width
, height
);
361 /* Mac version of XClearWindow. */
364 XClearWindow (display
, w
)
368 SetPortWindowPort (w
);
370 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
372 #if TARGET_API_MAC_CARBON
376 GetWindowPortBounds (w
, &r
);
379 #else /* not TARGET_API_MAC_CARBON */
380 EraseRect (&(w
->portRect
));
381 #endif /* not TARGET_API_MAC_CARBON */
385 /* Mac replacement for XCopyArea. */
388 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
392 int x
, y
, width
, height
;
393 unsigned short *bits
;
399 bitmap
.rowBytes
= sizeof(unsigned short);
400 bitmap
.baseAddr
= (char *)bits
;
401 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
403 SetPortWindowPort (w
);
405 RGBForeColor (GC_FORE_COLOR (gc
));
406 RGBBackColor (GC_BACK_COLOR (gc
));
407 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
409 #if TARGET_API_MAC_CARBON
410 LockPortBits (GetWindowPort (w
));
411 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
412 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
413 UnlockPortBits (GetWindowPort (w
));
414 #else /* not TARGET_API_MAC_CARBON */
415 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
416 overlay_p
? srcOr
: srcCopy
, 0);
417 #endif /* not TARGET_API_MAC_CARBON */
419 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
423 /* Mac replacement for XSetClipRectangles. */
426 mac_set_clip_rectangle (display
, w
, r
)
431 SetPortWindowPort (w
);
437 /* Mac replacement for XSetClipMask. */
440 mac_reset_clipping (display
, w
)
446 SetPortWindowPort (w
);
448 SetRect (&r
, -32767, -32767, 32767, 32767);
453 /* Mac replacement for XCreateBitmapFromBitmapData. */
456 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
461 static unsigned char swap_nibble
[16]
462 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
463 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
464 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
465 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
469 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
470 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
471 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
472 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
473 for (i
= 0; i
< h
; i
++)
475 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
476 for (j
= 0; j
< w1
; j
++)
478 /* Bitswap XBM bytes to match how Mac does things. */
479 unsigned char c
= *bits
++;
480 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
481 | (swap_nibble
[(c
>>4) & 0xf]));;
485 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
490 mac_free_bitmap (bitmap
)
493 xfree (bitmap
->baseAddr
);
498 XCreatePixmap (display
, w
, width
, height
, depth
)
499 Display
*display
; /* not used */
501 unsigned int width
, height
;
508 SetPortWindowPort (w
);
510 SetRect (&r
, 0, 0, width
, height
);
511 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
519 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
520 Display
*display
; /* not used */
523 unsigned int width
, height
;
524 unsigned long fg
, bg
;
531 static GC gc
= NULL
; /* not reentrant */
534 gc
= XCreateGC (display
, w
, 0, NULL
);
536 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
540 GetGWorld (&old_port
, &old_gdh
);
541 SetGWorld (pixmap
, NULL
);
542 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
543 XSetForeground (display
, gc
, fg
);
544 XSetBackground (display
, gc
, bg
);
545 RGBForeColor (GC_FORE_COLOR (gc
));
546 RGBBackColor (GC_BACK_COLOR (gc
));
547 LockPixels (GetGWorldPixMap (pixmap
));
548 #if TARGET_API_MAC_CARBON
549 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
550 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
551 #else /* not TARGET_API_MAC_CARBON */
552 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
553 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
554 #endif /* not TARGET_API_MAC_CARBON */
555 UnlockPixels (GetGWorldPixMap (pixmap
));
556 SetGWorld (old_port
, old_gdh
);
557 mac_free_bitmap (&bitmap
);
563 /* Mac replacement for XFillRectangle. */
566 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
571 unsigned int width
, height
;
575 SetPortWindowPort (w
);
577 RGBForeColor (GC_FORE_COLOR (gc
));
578 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
580 PaintRect (&r
); /* using foreground color of gc */
584 #if 0 /* TODO: figure out if we need to do this on Mac. */
586 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
591 unsigned int width
, height
;
597 GetGWorld (&old_port
, &old_gdh
);
599 RGBForeColor (GC_FORE_COLOR (gc
));
600 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
602 LockPixels (GetGWorldPixMap (p
));
603 PaintRect (&r
); /* using foreground color of gc */
604 UnlockPixels (GetGWorldPixMap (p
));
606 SetGWorld (old_port
, old_gdh
);
611 /* Mac replacement for XDrawRectangle: dest is a window. */
614 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
619 unsigned int width
, height
;
623 SetPortWindowPort (w
);
625 RGBForeColor (GC_FORE_COLOR (gc
));
626 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
628 FrameRect (&r
); /* using foreground color of gc */
632 #if 0 /* TODO: figure out if we need to do this on Mac. */
633 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
636 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
641 unsigned int width
, height
;
647 GetGWorld (&old_port
, &old_gdh
);
649 RGBForeColor (GC_FORE_COLOR (gc
));
650 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
652 LockPixels (GetGWorldPixMap (p
));
653 FrameRect (&r
); /* using foreground color of gc */
654 UnlockPixels (GetGWorldPixMap (p
));
656 SetGWorld (old_port
, old_gdh
);
662 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
669 int nchars
, mode
, bytes_per_char
;
671 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
672 UInt32 textFlags
, savedFlags
;
673 if (!NILP(Vmac_use_core_graphics
)) {
674 textFlags
= kQDUseCGTextRendering
;
675 savedFlags
= SwapQDTextFlags(textFlags
);
679 SetPortWindowPort (w
);
681 RGBForeColor (GC_FORE_COLOR (gc
));
683 RGBBackColor (GC_BACK_COLOR (gc
));
685 TextFont (GC_FONT (gc
)->mac_fontnum
);
686 TextSize (GC_FONT (gc
)->mac_fontsize
);
687 TextFace (GC_FONT (gc
)->mac_fontface
);
691 DrawText (buf
, 0, nchars
* bytes_per_char
);
694 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
695 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
696 if (!NILP(Vmac_use_core_graphics
))
697 SwapQDTextFlags(savedFlags
);
702 /* Mac replacement for XDrawString. */
705 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
713 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
717 /* Mac replacement for XDrawString16. */
720 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
728 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
733 /* Mac replacement for XDrawImageString. */
736 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
744 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
748 /* Mac replacement for XDrawString16. */
751 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
759 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
764 /* Mac replacement for XCopyArea: dest must be window. */
767 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
774 unsigned int width
, height
;
779 SetPortWindowPort (dest
);
781 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
782 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
784 ForeColor (blackColor
);
785 BackColor (whiteColor
);
787 LockPixels (GetGWorldPixMap (src
));
788 #if TARGET_API_MAC_CARBON
789 LockPortBits (GetWindowPort (dest
));
790 CopyBits (GetPortBitMapForCopyBits (src
),
791 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
792 &src_r
, &dest_r
, srcCopy
, 0);
793 UnlockPortBits (GetWindowPort (dest
));
794 #else /* not TARGET_API_MAC_CARBON */
795 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
796 &src_r
, &dest_r
, srcCopy
, 0);
797 #endif /* not TARGET_API_MAC_CARBON */
798 UnlockPixels (GetGWorldPixMap (src
));
803 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
804 width
, height
, dest_x
, dest_y
)
810 unsigned int width
, height
;
815 SetPortWindowPort (dest
);
817 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
818 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
820 ForeColor (blackColor
);
821 BackColor (whiteColor
);
823 LockPixels (GetGWorldPixMap (src
));
824 LockPixels (GetGWorldPixMap (mask
));
825 #if TARGET_API_MAC_CARBON
826 LockPortBits (GetWindowPort (dest
));
827 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
828 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
829 &src_r
, &src_r
, &dest_r
);
830 UnlockPortBits (GetWindowPort (dest
));
831 #else /* not TARGET_API_MAC_CARBON */
832 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
833 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
834 #endif /* not TARGET_API_MAC_CARBON */
835 UnlockPixels (GetGWorldPixMap (mask
));
836 UnlockPixels (GetGWorldPixMap (src
));
840 /* Mac replacement for XCopyArea: used only for scrolling. */
843 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
848 unsigned int width
, height
;
851 #if TARGET_API_MAC_CARBON
853 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
855 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
856 ScrollWindowRect (w
, &src_r
, dest_x
- src_x
, dest_y
- src_y
,
857 kScrollWindowNoOptions
, dummy
);
859 #else /* not TARGET_API_MAC_CARBON */
864 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
865 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
867 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
868 color mapping in CopyBits. Otherwise, it will be slow. */
869 ForeColor (blackColor
);
870 BackColor (whiteColor
);
871 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
873 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
874 #endif /* not TARGET_API_MAC_CARBON */
878 #if 0 /* TODO: figure out if we need to do this on Mac. */
879 /* Mac replacement for XCopyArea: dest must be Pixmap. */
882 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
888 unsigned int width
, height
;
895 GetGWorld (&old_port
, &old_gdh
);
896 SetGWorld (dest
, NULL
);
897 ForeColor (blackColor
);
898 BackColor (whiteColor
);
900 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
901 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
903 LockPixels (GetGWorldPixMap (src
));
904 LockPixels (GetGWorldPixMap (dest
));
905 #if TARGET_API_MAC_CARBON
906 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
907 &src_r
, &dest_r
, srcCopy
, 0);
908 #else /* not TARGET_API_MAC_CARBON */
909 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
910 &src_r
, &dest_r
, srcCopy
, 0);
911 #endif /* not TARGET_API_MAC_CARBON */
912 UnlockPixels (GetGWorldPixMap (dest
));
913 UnlockPixels (GetGWorldPixMap (src
));
915 SetGWorld (old_port
, old_gdh
);
920 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
921 width
, height
, dest_x
, dest_y
)
923 Pixmap src
, mask
, dest
;
926 unsigned int width
, height
;
933 GetGWorld (&old_port
, &old_gdh
);
934 SetGWorld (dest
, NULL
);
935 ForeColor (blackColor
);
936 BackColor (whiteColor
);
938 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
939 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
941 LockPixels (GetGWorldPixMap (src
));
942 LockPixels (GetGWorldPixMap (mask
));
943 LockPixels (GetGWorldPixMap (dest
));
944 #if TARGET_API_MAC_CARBON
945 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
946 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
947 #else /* not TARGET_API_MAC_CARBON */
948 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
949 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
950 #endif /* not TARGET_API_MAC_CARBON */
951 UnlockPixels (GetGWorldPixMap (dest
));
952 UnlockPixels (GetGWorldPixMap (mask
));
953 UnlockPixels (GetGWorldPixMap (src
));
955 SetGWorld (old_port
, old_gdh
);
960 /* Mac replacement for XChangeGC. */
963 XChangeGC (display
, gc
, mask
, xgcv
)
969 if (mask
& GCForeground
)
970 XSetForeground (display
, gc
, xgcv
->foreground
);
971 if (mask
& GCBackground
)
972 XSetBackground (display
, gc
, xgcv
->background
);
974 XSetFont (display
, gc
, xgcv
->font
);
978 /* Mac replacement for XCreateGC. */
981 XCreateGC (display
, window
, mask
, xgcv
)
987 GC gc
= xmalloc (sizeof (*gc
));
991 bzero (gc
, sizeof (*gc
));
992 XChangeGC (display
, gc
, mask
, xgcv
);
999 /* Used in xfaces.c. */
1002 XFreeGC (display
, gc
)
1010 /* Mac replacement for XGetGCValues. */
1013 XGetGCValues (display
, gc
, mask
, xgcv
)
1019 if (mask
& GCForeground
)
1020 xgcv
->foreground
= gc
->xgcv
.foreground
;
1021 if (mask
& GCBackground
)
1022 xgcv
->background
= gc
->xgcv
.background
;
1024 xgcv
->font
= gc
->xgcv
.font
;
1028 /* Mac replacement for XSetForeground. */
1031 XSetForeground (display
, gc
, color
)
1034 unsigned long color
;
1036 if (gc
->xgcv
.foreground
!= color
)
1038 gc
->xgcv
.foreground
= color
;
1039 gc
->fore_color
.red
= RED16_FROM_ULONG (color
);
1040 gc
->fore_color
.green
= GREEN16_FROM_ULONG (color
);
1041 gc
->fore_color
.blue
= BLUE16_FROM_ULONG (color
);
1046 /* Mac replacement for XSetBackground. */
1049 XSetBackground (display
, gc
, color
)
1052 unsigned long color
;
1054 if (gc
->xgcv
.background
!= color
)
1056 gc
->xgcv
.background
= color
;
1057 gc
->back_color
.red
= RED16_FROM_ULONG (color
);
1058 gc
->back_color
.green
= GREEN16_FROM_ULONG (color
);
1059 gc
->back_color
.blue
= BLUE16_FROM_ULONG (color
);
1064 /* Mac replacement for XSetFont. */
1067 XSetFont (display
, gc
, font
)
1072 gc
->xgcv
.font
= font
;
1076 /* Mac replacement for XSetWindowBackground. */
1079 XSetWindowBackground (display
, w
, color
)
1082 unsigned long color
;
1084 #if !TARGET_API_MAC_CARBON
1085 AuxWinHandle aw_handle
;
1086 CTabHandle ctab_handle
;
1087 ColorSpecPtr ct_table
;
1092 bg_color
.red
= RED16_FROM_ULONG (color
);
1093 bg_color
.green
= GREEN16_FROM_ULONG (color
);
1094 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
1096 #if TARGET_API_MAC_CARBON
1097 SetWindowContentColor (w
, &bg_color
);
1099 if (GetAuxWin (w
, &aw_handle
))
1101 ctab_handle
= (*aw_handle
)->awCTable
;
1102 HandToHand ((Handle
*) &ctab_handle
);
1103 ct_table
= (*ctab_handle
)->ctTable
;
1104 ct_size
= (*ctab_handle
)->ctSize
;
1105 while (ct_size
> -1)
1107 if (ct_table
->value
== 0)
1109 ct_table
->rgb
= bg_color
;
1110 CTabChanged (ctab_handle
);
1111 SetWinColor (w
, (WCTabHandle
) ctab_handle
);
1119 /* x_sync is a no-op on Mac. */
1127 /* Flush display of frame F, or of all frames if F is null. */
1133 #if TARGET_API_MAC_CARBON
1136 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1138 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1144 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1145 Calls to XFlush should be unnecessary because the X output buffer
1146 is flushed automatically as needed by calls to XPending,
1147 XNextEvent, or XWindowEvent according to the XFlush man page.
1148 XTread_socket calls XPending. Removing XFlush improves
1151 #define XFlush(DISPLAY) (void) 0
1154 /* Return the struct mac_display_info corresponding to DPY. There's
1157 struct mac_display_info
*
1158 mac_display_info_for_display (dpy
)
1161 return &one_mac_display_info
;
1166 /***********************************************************************
1167 Starting and ending an update
1168 ***********************************************************************/
1170 /* Start an update of frame F. This function is installed as a hook
1171 for update_begin, i.e. it is called when update_begin is called.
1172 This function is called prior to calls to x_update_window_begin for
1173 each window being updated. */
1179 #if TARGET_API_MAC_CARBON
1180 /* During update of a frame, availability of input events is
1181 periodically checked with ReceiveNextEvent if
1182 redisplay-dont-pause is nil. That normally flushes window buffer
1183 changes for every check, and thus screen update looks waving even
1184 if no input is available. So we disable screen updates during
1185 update of a frame. */
1187 DisableScreenUpdates ();
1193 /* Start update of window W. Set the global variable updated_window
1194 to the window being updated and set output_cursor to the cursor
1198 x_update_window_begin (w
)
1201 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1202 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1205 set_output_cursor (&w
->cursor
);
1209 if (f
== display_info
->mouse_face_mouse_frame
)
1211 /* Don't do highlighting for mouse motion during the update. */
1212 display_info
->mouse_face_defer
= 1;
1214 /* If F needs to be redrawn, simply forget about any prior mouse
1216 if (FRAME_GARBAGED_P (f
))
1217 display_info
->mouse_face_window
= Qnil
;
1219 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1220 their mouse_face_p flag set, which means that they are always
1221 unequal to rows in a desired matrix which never have that
1222 flag set. So, rows containing mouse-face glyphs are never
1223 scrolled, and we don't have to switch the mouse highlight off
1224 here to prevent it from being scrolled. */
1226 /* Can we tell that this update does not affect the window
1227 where the mouse highlight is? If so, no need to turn off.
1228 Likewise, don't do anything if the frame is garbaged;
1229 in that case, the frame's current matrix that we would use
1230 is all wrong, and we will redisplay that line anyway. */
1231 if (!NILP (display_info
->mouse_face_window
)
1232 && w
== XWINDOW (display_info
->mouse_face_window
))
1236 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1237 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1240 if (i
< w
->desired_matrix
->nrows
)
1241 clear_mouse_face (display_info
);
1250 /* Draw a vertical window border from (x,y0) to (x,y1) */
1253 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1257 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1260 face
= FACE_FROM_ID (f
, VERTICAL_BORDER_FACE_ID
);
1262 XSetForeground (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
1265 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1266 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1269 /* End update of window W (which is equal to updated_window).
1271 Draw vertical borders between horizontally adjacent windows, and
1272 display W's cursor if CURSOR_ON_P is non-zero.
1274 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1275 glyphs in mouse-face were overwritten. In that case we have to
1276 make sure that the mouse-highlight is properly redrawn.
1278 W may be a menu bar pseudo-window in case we don't have X toolkit
1279 support. Such windows don't have a cursor, so don't display it
1283 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1285 int cursor_on_p
, mouse_face_overwritten_p
;
1287 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1289 if (!w
->pseudo_window_p
)
1294 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1296 output_cursor
.x
, output_cursor
.y
);
1298 if (draw_window_fringes (w
, 1))
1299 x_draw_vertical_border (w
);
1304 /* If a row with mouse-face was overwritten, arrange for
1305 XTframe_up_to_date to redisplay the mouse highlight. */
1306 if (mouse_face_overwritten_p
)
1308 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1309 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1310 dpyinfo
->mouse_face_window
= Qnil
;
1313 updated_window
= NULL
;
1317 /* End update of frame F. This function is installed as a hook in
1324 /* Mouse highlight may be displayed again. */
1325 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1328 #if TARGET_API_MAC_CARBON
1329 EnableScreenUpdates ();
1331 XFlush (FRAME_MAC_DISPLAY (f
));
1336 /* This function is called from various places in xdisp.c whenever a
1337 complete update has been performed. The global variable
1338 updated_window is not available here. */
1341 XTframe_up_to_date (f
)
1344 if (FRAME_MAC_P (f
))
1346 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1348 if (dpyinfo
->mouse_face_deferred_gc
1349 || f
== dpyinfo
->mouse_face_mouse_frame
)
1352 if (dpyinfo
->mouse_face_mouse_frame
)
1353 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1354 dpyinfo
->mouse_face_mouse_x
,
1355 dpyinfo
->mouse_face_mouse_y
);
1356 dpyinfo
->mouse_face_deferred_gc
= 0;
1363 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1364 arrow bitmaps, or clear the fringes if no bitmaps are required
1365 before DESIRED_ROW is made current. The window being updated is
1366 found in updated_window. This function is called from
1367 update_window_line only if it is known that there are differences
1368 between bitmaps to be drawn between current row and DESIRED_ROW. */
1371 x_after_update_window_line (desired_row
)
1372 struct glyph_row
*desired_row
;
1374 struct window
*w
= updated_window
;
1380 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1381 desired_row
->redraw_fringe_bitmaps_p
= 1;
1383 /* When a window has disappeared, make sure that no rest of
1384 full-width rows stays visible in the internal border. Could
1385 check here if updated_window is the leftmost/rightmost window,
1386 but I guess it's not worth doing since vertically split windows
1387 are almost never used, internal border is rarely set, and the
1388 overhead is very small. */
1389 if (windows_or_buffers_changed
1390 && desired_row
->full_width_p
1391 && (f
= XFRAME (w
->frame
),
1392 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1394 && (height
= desired_row
->visible_height
,
1397 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1399 /* Internal border is drawn below the tool bar. */
1400 if (WINDOWP (f
->tool_bar_window
)
1401 && w
== XWINDOW (f
->tool_bar_window
))
1405 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1406 0, y
, width
, height
, 0);
1407 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1408 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1415 /* Draw the bitmap WHICH in one of the left or right fringes of
1416 window W. ROW is the glyph row for which to display the bitmap; it
1417 determines the vertical position at which the bitmap has to be
1421 x_draw_fringe_bitmap (w
, row
, p
)
1423 struct glyph_row
*row
;
1424 struct draw_fringe_bitmap_params
*p
;
1426 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1427 Display
*display
= FRAME_MAC_DISPLAY (f
);
1428 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1429 GC gc
= f
->output_data
.mac
->normal_gc
;
1430 struct face
*face
= p
->face
;
1433 /* Must clip because of partially visible lines. */
1434 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1437 /* Adjust position of "bottom aligned" bitmap on partially
1438 visible last row. */
1440 int oldVH
= row
->visible_height
;
1441 row
->visible_height
= p
->h
;
1442 row
->y
-= rowY
- p
->y
;
1443 x_clip_to_row (w
, row
, -1, gc
);
1445 row
->visible_height
= oldVH
;
1448 x_clip_to_row (w
, row
, -1, gc
);
1450 if (p
->bx
>= 0 && !p
->overlay_p
)
1452 #if 0 /* MAC_TODO: stipple */
1453 /* In case the same realized face is used for fringes and
1454 for something displayed in the text (e.g. face `region' on
1455 mono-displays, the fill style may have been changed to
1456 FillSolid in x_draw_glyph_string_background. */
1458 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1460 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1463 mac_erase_rectangle (window
, face
->gc
, p
->bx
, p
->by
, p
->nx
, p
->ny
);
1465 #if 0 /* MAC_TODO: stipple */
1467 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1473 unsigned short *bits
= p
->bits
+ p
->dh
;
1476 XGetGCValues (display
, face
->gc
, GCForeground
, &gcv
);
1477 XSetForeground (display
, face
->gc
,
1479 ? (p
->overlay_p
? face
->background
1480 : f
->output_data
.mac
->cursor_pixel
)
1481 : face
->foreground
));
1482 mac_draw_bitmap (display
, window
, face
->gc
, p
->x
, p
->y
,
1483 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1484 XSetForeground (display
, face
->gc
, gcv
.foreground
);
1487 mac_reset_clipping (display
, window
);
1492 /* This is called when starting Emacs and when restarting after
1493 suspend. When starting Emacs, no window is mapped. And nothing
1494 must be done to Emacs's own window if it is suspended (though that
1498 XTset_terminal_modes ()
1502 /* This is called when exiting or suspending Emacs. Exiting will make
1503 the windows go away, and suspending requires no action. */
1506 XTreset_terminal_modes ()
1512 /***********************************************************************
1514 ***********************************************************************/
1516 /* Function prototypes of this page. */
1518 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1519 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1522 /* Return a pointer to per-char metric information in FONT of a
1523 character pointed by B which is a pointer to an XChar2b. */
1525 #define PER_CHAR_METRIC(font, b) \
1527 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1528 + (((font)->min_byte1 || (font)->max_byte1) \
1529 ? (((b)->byte1 - (font)->min_byte1) \
1530 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1532 : &((font)->max_bounds))
1535 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1536 is not contained in the font. */
1538 static INLINE XCharStruct
*
1539 x_per_char_metric (font
, char2b
)
1543 /* The result metric information. */
1544 XCharStruct
*pcm
= NULL
;
1546 xassert (font
&& char2b
);
1548 if (font
->per_char
!= NULL
)
1550 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1552 /* min_char_or_byte2 specifies the linear character index
1553 corresponding to the first element of the per_char array,
1554 max_char_or_byte2 is the index of the last character. A
1555 character with non-zero CHAR2B->byte1 is not in the font.
1556 A character with byte2 less than min_char_or_byte2 or
1557 greater max_char_or_byte2 is not in the font. */
1558 if (char2b
->byte1
== 0
1559 && char2b
->byte2
>= font
->min_char_or_byte2
1560 && char2b
->byte2
<= font
->max_char_or_byte2
)
1561 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1565 /* If either min_byte1 or max_byte1 are nonzero, both
1566 min_char_or_byte2 and max_char_or_byte2 are less than
1567 256, and the 2-byte character index values corresponding
1568 to the per_char array element N (counting from 0) are:
1570 byte1 = N/D + min_byte1
1571 byte2 = N\D + min_char_or_byte2
1575 D = max_char_or_byte2 - min_char_or_byte2 + 1
1576 / = integer division
1577 \ = integer modulus */
1578 if (char2b
->byte1
>= font
->min_byte1
1579 && char2b
->byte1
<= font
->max_byte1
1580 && char2b
->byte2
>= font
->min_char_or_byte2
1581 && char2b
->byte2
<= font
->max_char_or_byte2
)
1583 pcm
= (font
->per_char
1584 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1585 * (char2b
->byte1
- font
->min_byte1
))
1586 + (char2b
->byte2
- font
->min_char_or_byte2
));
1592 /* If the per_char pointer is null, all glyphs between the first
1593 and last character indexes inclusive have the same
1594 information, as given by both min_bounds and max_bounds. */
1595 if (char2b
->byte2
>= font
->min_char_or_byte2
1596 && char2b
->byte2
<= font
->max_char_or_byte2
)
1597 pcm
= &font
->max_bounds
;
1600 return ((pcm
== NULL
1601 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1608 static XCharStruct
*
1609 mac_per_char_metric (font
, char2b
, font_type
)
1614 return x_per_char_metric (font
, char2b
);
1618 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1619 the two-byte form of C. Encoding is returned in *CHAR2B. */
1622 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1625 struct font_info
*font_info
;
1628 int charset
= CHAR_CHARSET (c
);
1629 XFontStruct
*font
= font_info
->font
;
1631 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1632 This may be either a program in a special encoder language or a
1634 if (font_info
->font_encoder
)
1636 /* It's a program. */
1637 struct ccl_program
*ccl
= font_info
->font_encoder
;
1639 check_ccl_update (ccl
);
1640 if (CHARSET_DIMENSION (charset
) == 1)
1642 ccl
->reg
[0] = charset
;
1643 ccl
->reg
[1] = char2b
->byte2
;
1648 ccl
->reg
[0] = charset
;
1649 ccl
->reg
[1] = char2b
->byte1
;
1650 ccl
->reg
[2] = char2b
->byte2
;
1653 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1655 /* We assume that MSBs are appropriately set/reset by CCL
1657 if (font
->max_byte1
== 0) /* 1-byte font */
1658 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1660 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1662 else if (font_info
->encoding
[charset
])
1664 /* Fixed encoding scheme. See fontset.h for the meaning of the
1665 encoding numbers. */
1666 int enc
= font_info
->encoding
[charset
];
1668 if ((enc
== 1 || enc
== 2)
1669 && CHARSET_DIMENSION (charset
) == 2)
1670 char2b
->byte1
|= 0x80;
1672 if (enc
== 1 || enc
== 3)
1673 char2b
->byte2
|= 0x80;
1679 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1680 char2b
->byte1
= sjis1
;
1681 char2b
->byte2
= sjis2
;
1686 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1688 return FONT_TYPE_UNKNOWN
;
1693 /***********************************************************************
1695 ***********************************************************************/
1699 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1700 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1701 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1703 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1704 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1705 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1706 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1707 static void mac_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
1708 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1709 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1710 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1711 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1712 unsigned long *, double, int));*/
1713 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1714 double, int, unsigned long));
1715 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1716 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1717 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1718 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1719 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1720 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1722 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1723 int, int, int, int, int, int,
1725 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1726 int, int, int, Rect
*));
1729 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1733 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1738 struct glyph_string
*s
;
1740 if (s
->font
== FRAME_FONT (s
->f
)
1741 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1742 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1744 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1747 /* Cursor on non-default face: must merge. */
1751 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1752 xgcv
.foreground
= s
->face
->background
;
1754 /* If the glyph would be invisible, try a different foreground. */
1755 if (xgcv
.foreground
== xgcv
.background
)
1756 xgcv
.foreground
= s
->face
->foreground
;
1757 if (xgcv
.foreground
== xgcv
.background
)
1758 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1759 if (xgcv
.foreground
== xgcv
.background
)
1760 xgcv
.foreground
= s
->face
->foreground
;
1762 /* Make sure the cursor is distinct from text in this face. */
1763 if (xgcv
.background
== s
->face
->background
1764 && xgcv
.foreground
== s
->face
->foreground
)
1766 xgcv
.background
= s
->face
->foreground
;
1767 xgcv
.foreground
= s
->face
->background
;
1770 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1771 xgcv
.font
= s
->font
;
1772 mask
= GCForeground
| GCBackground
| GCFont
;
1774 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1775 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1778 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1779 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1781 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1786 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1789 x_set_mouse_face_gc (s
)
1790 struct glyph_string
*s
;
1795 /* What face has to be used last for the mouse face? */
1796 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1797 face
= FACE_FROM_ID (s
->f
, face_id
);
1799 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1801 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1802 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1804 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1805 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1806 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1808 /* If font in this face is same as S->font, use it. */
1809 if (s
->font
== s
->face
->font
)
1810 s
->gc
= s
->face
->gc
;
1813 /* Otherwise construct scratch_cursor_gc with values from FACE
1818 xgcv
.background
= s
->face
->background
;
1819 xgcv
.foreground
= s
->face
->foreground
;
1820 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1821 xgcv
.font
= s
->font
;
1822 mask
= GCForeground
| GCBackground
| GCFont
;
1824 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1825 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1828 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1829 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1831 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1834 xassert (s
->gc
!= 0);
1838 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1839 Faces to use in the mode line have already been computed when the
1840 matrix was built, so there isn't much to do, here. */
1843 x_set_mode_line_face_gc (s
)
1844 struct glyph_string
*s
;
1846 s
->gc
= s
->face
->gc
;
1850 /* Set S->gc of glyph string S for drawing that glyph string. Set
1851 S->stippled_p to a non-zero value if the face of S has a stipple
1855 x_set_glyph_string_gc (s
)
1856 struct glyph_string
*s
;
1858 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1860 if (s
->hl
== DRAW_NORMAL_TEXT
)
1862 s
->gc
= s
->face
->gc
;
1863 s
->stippled_p
= s
->face
->stipple
!= 0;
1865 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1867 x_set_mode_line_face_gc (s
);
1868 s
->stippled_p
= s
->face
->stipple
!= 0;
1870 else if (s
->hl
== DRAW_CURSOR
)
1872 x_set_cursor_gc (s
);
1875 else if (s
->hl
== DRAW_MOUSE_FACE
)
1877 x_set_mouse_face_gc (s
);
1878 s
->stippled_p
= s
->face
->stipple
!= 0;
1880 else if (s
->hl
== DRAW_IMAGE_RAISED
1881 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1883 s
->gc
= s
->face
->gc
;
1884 s
->stippled_p
= s
->face
->stipple
!= 0;
1888 s
->gc
= s
->face
->gc
;
1889 s
->stippled_p
= s
->face
->stipple
!= 0;
1892 /* GC must have been set. */
1893 xassert (s
->gc
!= 0);
1897 /* Set clipping for output of glyph string S. S may be part of a mode
1898 line or menu if we don't have X toolkit support. */
1901 x_set_glyph_string_clipping (s
)
1902 struct glyph_string
*s
;
1905 get_glyph_string_clip_rect (s
, &r
);
1906 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1911 Compute left and right overhang of glyph string S. If S is a glyph
1912 string for a composition, assume overhangs don't exist. */
1915 mac_compute_glyph_string_overhangs (s
)
1916 struct glyph_string
*s
;
1919 && s
->first_glyph
->type
== CHAR_GLYPH
)
1922 MacFontStruct
*font
= s
->font
;
1924 TextFont (font
->mac_fontnum
);
1925 TextSize (font
->mac_fontsize
);
1926 TextFace (font
->mac_fontface
);
1929 QDTextBounds (s
->nchars
* 2, (char *)s
->char2b
, &r
);
1933 char *buf
= xmalloc (s
->nchars
);
1936 SetRect (&r
, 0, 0, 0, 0);
1939 for (i
= 0; i
< s
->nchars
; ++i
)
1940 buf
[i
] = s
->char2b
[i
].byte2
;
1941 QDTextBounds (s
->nchars
, buf
, &r
);
1946 s
->right_overhang
= r
.right
> s
->width
? r
.right
- s
->width
: 0;
1947 s
->left_overhang
= r
.left
< 0 ? -r
.left
: 0;
1952 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1955 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1956 struct glyph_string
*s
;
1959 mac_erase_rectangle (s
->window
, s
->gc
, x
, y
, w
, h
);
1963 /* We prefer not to use XDrawImageString (srcCopy text transfer mode)
1964 on Mac OS X because:
1965 - Screen is double-buffered. (In srcCopy mode, a text is drawn
1966 into an offscreen graphics world first. So performance gain
1967 cannot be expected.)
1968 - It lowers rendering quality.
1969 - Some fonts leave garbage on cursor movement. */
1971 /* Draw the background of glyph_string S. If S->background_filled_p
1972 is non-zero don't draw it. FORCE_P non-zero means draw the
1973 background even if it wouldn't be drawn normally. This is used
1974 when a string preceding S draws into the background of S, or S
1975 contains the first component of a composition. */
1978 x_draw_glyph_string_background (s
, force_p
)
1979 struct glyph_string
*s
;
1982 /* Nothing to do if background has already been drawn or if it
1983 shouldn't be drawn in the first place. */
1984 if (!s
->background_filled_p
)
1986 int box_line_width
= max (s
->face
->box_line_width
, 0);
1988 #if 0 /* MAC_TODO: stipple */
1991 /* Fill background with a stipple pattern. */
1992 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1993 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1994 s
->y
+ box_line_width
,
1995 s
->background_width
,
1996 s
->height
- 2 * box_line_width
);
1997 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1998 s
->background_filled_p
= 1;
2003 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2004 || s
->font_not_found_p
2005 || s
->extends_to_end_of_line_p
2009 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2010 s
->background_width
,
2011 s
->height
- 2 * box_line_width
);
2012 s
->background_filled_p
= 1;
2018 /* Draw the foreground of glyph string S. */
2021 x_draw_glyph_string_foreground (s
)
2022 struct glyph_string
*s
;
2026 /* If first glyph of S has a left box line, start drawing the text
2027 of S to the right of that box line. */
2028 if (s
->face
->box
!= FACE_NO_BOX
2029 && s
->first_glyph
->left_box_line_p
)
2030 x
= s
->x
+ abs (s
->face
->box_line_width
);
2034 /* Draw characters of S as rectangles if S's font could not be
2036 if (s
->font_not_found_p
)
2038 for (i
= 0; i
< s
->nchars
; ++i
)
2040 struct glyph
*g
= s
->first_glyph
+ i
;
2041 mac_draw_rectangle (s
->display
, s
->window
,
2042 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2044 x
+= g
->pixel_width
;
2049 char *char1b
= (char *) s
->char2b
;
2050 int boff
= s
->font_info
->baseline_offset
;
2052 if (s
->font_info
->vertical_centering
)
2053 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2055 /* If we can use 8-bit functions, condense S->char2b. */
2057 for (i
= 0; i
< s
->nchars
; ++i
)
2058 char1b
[i
] = s
->char2b
[i
].byte2
;
2061 /* Draw text with XDrawString if background has already been
2062 filled. Otherwise, use XDrawImageString. (Note that
2063 XDrawImageString is usually faster than XDrawString.) Always
2064 use XDrawImageString when drawing the cursor so that there is
2065 no chance that characters under a box cursor are invisible. */
2066 if (s
->for_overlaps_p
2067 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2070 /* Draw characters with 16-bit or 8-bit functions. */
2072 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2073 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2075 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2076 s
->ybase
- boff
, char1b
, s
->nchars
);
2082 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
2083 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2085 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
2086 s
->ybase
- boff
, char1b
, s
->nchars
);
2092 /* Draw the foreground of composite glyph string S. */
2095 x_draw_composite_glyph_string_foreground (s
)
2096 struct glyph_string
*s
;
2100 /* If first glyph of S has a left box line, start drawing the text
2101 of S to the right of that box line. */
2102 if (s
->face
->box
!= FACE_NO_BOX
2103 && s
->first_glyph
->left_box_line_p
)
2104 x
= s
->x
+ abs (s
->face
->box_line_width
);
2108 /* S is a glyph string for a composition. S->gidx is the index of
2109 the first character drawn for glyphs of this composition.
2110 S->gidx == 0 means we are drawing the very first character of
2111 this composition. */
2113 /* Draw a rectangle for the composition if the font for the very
2114 first character of the composition could not be loaded. */
2115 if (s
->font_not_found_p
)
2118 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2119 s
->width
- 1, s
->height
- 1);
2123 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2124 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2125 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2126 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2132 #ifdef USE_X_TOOLKIT
2134 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2137 /* Return the frame on which widget WIDGET is used.. Abort if frame
2138 cannot be determined. */
2140 static struct frame
*
2141 x_frame_of_widget (widget
)
2144 struct x_display_info
*dpyinfo
;
2148 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2150 /* Find the top-level shell of the widget. Note that this function
2151 can be called when the widget is not yet realized, so XtWindow
2152 (widget) == 0. That's the reason we can't simply use
2153 x_any_window_to_frame. */
2154 while (!XtIsTopLevelShell (widget
))
2155 widget
= XtParent (widget
);
2157 /* Look for a frame with that top-level widget. Allocate the color
2158 on that frame to get the right gamma correction value. */
2159 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2160 if (GC_FRAMEP (XCAR (tail
))
2161 && (f
= XFRAME (XCAR (tail
)),
2162 (f
->output_data
.nothing
!= 1
2163 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2164 && f
->output_data
.x
->widget
== widget
)
2171 /* Allocate the color COLOR->pixel on the screen and display of
2172 widget WIDGET in colormap CMAP. If an exact match cannot be
2173 allocated, try the nearest color available. Value is non-zero
2174 if successful. This is called from lwlib. */
2177 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2182 struct frame
*f
= x_frame_of_widget (widget
);
2183 return x_alloc_nearest_color (f
, cmap
, color
);
2187 #endif /* USE_X_TOOLKIT */
2189 #if 0 /* MAC_TODO */
2191 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2192 CMAP. If an exact match can't be allocated, try the nearest color
2193 available. Value is non-zero if successful. Set *COLOR to the
2197 x_alloc_nearest_color (f
, cmap
, color
)
2202 Display
*display
= FRAME_X_DISPLAY (f
);
2203 Screen
*screen
= FRAME_X_SCREEN (f
);
2206 gamma_correct (f
, color
);
2207 rc
= XAllocColor (display
, cmap
, color
);
2210 /* If we got to this point, the colormap is full, so we're going
2211 to try to get the next closest color. The algorithm used is
2212 a least-squares matching, which is what X uses for closest
2213 color matching with StaticColor visuals. */
2215 unsigned long nearest_delta
= ~0;
2216 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2217 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2219 for (i
= 0; i
< ncells
; ++i
)
2221 XQueryColors (display
, cmap
, cells
, ncells
);
2223 for (nearest
= i
= 0; i
< ncells
; ++i
)
2225 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2226 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2227 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2228 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2230 if (delta
< nearest_delta
)
2233 nearest_delta
= delta
;
2237 color
->red
= cells
[nearest
].red
;
2238 color
->green
= cells
[nearest
].green
;
2239 color
->blue
= cells
[nearest
].blue
;
2240 rc
= XAllocColor (display
, cmap
, color
);
2243 #ifdef DEBUG_X_COLORS
2245 register_color (color
->pixel
);
2246 #endif /* DEBUG_X_COLORS */
2252 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2253 It's necessary to do this instead of just using PIXEL directly to
2254 get color reference counts right. */
2257 x_copy_color (f
, pixel
)
2259 unsigned long pixel
;
2263 color
.pixel
= pixel
;
2265 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2266 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2268 #ifdef DEBUG_X_COLORS
2269 register_color (pixel
);
2275 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2276 It's necessary to do this instead of just using PIXEL directly to
2277 get color reference counts right. */
2280 x_copy_dpy_color (dpy
, cmap
, pixel
)
2283 unsigned long pixel
;
2287 color
.pixel
= pixel
;
2289 XQueryColor (dpy
, cmap
, &color
);
2290 XAllocColor (dpy
, cmap
, &color
);
2292 #ifdef DEBUG_X_COLORS
2293 register_color (pixel
);
2298 #endif /* MAC_TODO */
2301 /* Brightness beyond which a color won't have its highlight brightness
2304 Nominally, highlight colors for `3d' faces are calculated by
2305 brightening an object's color by a constant scale factor, but this
2306 doesn't yield good results for dark colors, so for colors who's
2307 brightness is less than this value (on a scale of 0-255) have to
2308 use an additional additive factor.
2310 The value here is set so that the default menu-bar/mode-line color
2311 (grey75) will not have its highlights changed at all. */
2312 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2315 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2316 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2317 If this produces the same color as COLOR, try a color where all RGB
2318 values have DELTA added. Return the allocated color in *COLOR.
2319 DISPLAY is the X display, CMAP is the colormap to operate on.
2320 Value is non-zero if successful. */
2323 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2325 unsigned long *color
;
2332 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2335 /* Change RGB values by specified FACTOR. Avoid overflow! */
2336 xassert (factor
>= 0);
2337 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2338 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2339 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2341 /* Calculate brightness of COLOR. */
2342 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2343 + BLUE_FROM_ULONG (*color
)) / 6;
2345 /* We only boost colors that are darker than
2346 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2347 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2348 /* Make an additive adjustment to NEW, because it's dark enough so
2349 that scaling by FACTOR alone isn't enough. */
2351 /* How far below the limit this color is (0 - 1, 1 being darker). */
2352 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2353 /* The additive adjustment. */
2354 int min_delta
= delta
* dimness
* factor
/ 2;
2357 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2358 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2359 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2361 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2362 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2363 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2367 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2368 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2369 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2371 /* MAC_TODO: Map to palette and retry with delta if same? */
2372 /* MAC_TODO: Free colors (if using palette)? */
2383 /* Set up the foreground color for drawing relief lines of glyph
2384 string S. RELIEF is a pointer to a struct relief containing the GC
2385 with which lines will be drawn. Use a color that is FACTOR or
2386 DELTA lighter or darker than the relief's background which is found
2387 in S->f->output_data.x->relief_background. If such a color cannot
2388 be allocated, use DEFAULT_PIXEL, instead. */
2391 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2393 struct relief
*relief
;
2396 unsigned long default_pixel
;
2399 struct mac_output
*di
= f
->output_data
.mac
;
2400 unsigned long mask
= GCForeground
;
2401 unsigned long pixel
;
2402 unsigned long background
= di
->relief_background
;
2403 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2405 /* MAC_TODO: Free colors (if using palette)? */
2407 /* Allocate new color. */
2408 xgcv
.foreground
= default_pixel
;
2410 if (dpyinfo
->n_planes
!= 1
2411 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2413 relief
->allocated_p
= 1;
2414 xgcv
.foreground
= relief
->pixel
= pixel
;
2417 if (relief
->gc
== 0)
2419 #if 0 /* MAC_TODO: stipple */
2420 xgcv
.stipple
= dpyinfo
->gray
;
2423 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2426 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2430 /* Set up colors for the relief lines around glyph string S. */
2433 x_setup_relief_colors (s
)
2434 struct glyph_string
*s
;
2436 struct mac_output
*di
= s
->f
->output_data
.mac
;
2437 unsigned long color
;
2439 if (s
->face
->use_box_color_for_shadows_p
)
2440 color
= s
->face
->box_color
;
2441 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2443 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2444 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2449 /* Get the background color of the face. */
2450 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2451 color
= xgcv
.background
;
2454 if (di
->white_relief
.gc
== 0
2455 || color
!= di
->relief_background
)
2457 di
->relief_background
= color
;
2458 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2459 WHITE_PIX_DEFAULT (s
->f
));
2460 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2461 BLACK_PIX_DEFAULT (s
->f
));
2466 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2467 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2468 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2469 relief. LEFT_P non-zero means draw a relief on the left side of
2470 the rectangle. RIGHT_P non-zero means draw a relief on the right
2471 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2475 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2476 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2478 int left_x
, top_y
, right_x
, bottom_y
, width
;
2479 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2482 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2483 Window window
= FRAME_MAC_WINDOW (f
);
2488 gc
= f
->output_data
.mac
->white_relief
.gc
;
2490 gc
= f
->output_data
.mac
->black_relief
.gc
;
2491 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2495 for (i
= 0; i
< width
; ++i
)
2496 XDrawLine (dpy
, window
, gc
,
2497 left_x
+ i
* left_p
, top_y
+ i
,
2498 right_x
- i
* right_p
, top_y
+ i
);
2502 for (i
= 0; i
< width
; ++i
)
2503 XDrawLine (dpy
, window
, gc
,
2504 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2506 mac_reset_clipping (dpy
, window
);
2508 gc
= f
->output_data
.mac
->black_relief
.gc
;
2510 gc
= f
->output_data
.mac
->white_relief
.gc
;
2511 mac_set_clip_rectangle (dpy
, window
,
2516 for (i
= 0; i
< width
; ++i
)
2517 XDrawLine (dpy
, window
, gc
,
2518 left_x
+ i
* left_p
, bottom_y
- i
,
2519 right_x
- i
* right_p
, bottom_y
- i
);
2523 for (i
= 0; i
< width
; ++i
)
2524 XDrawLine (dpy
, window
, gc
,
2525 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2527 mac_reset_clipping (dpy
, window
);
2531 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2532 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2533 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2534 left side of the rectangle. RIGHT_P non-zero means draw a line
2535 on the right side of the rectangle. CLIP_RECT is the clipping
2536 rectangle to use when drawing. */
2539 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2540 left_p
, right_p
, clip_rect
)
2541 struct glyph_string
*s
;
2542 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2547 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2548 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
2549 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2552 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2553 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2557 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2558 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2561 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2562 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2566 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2567 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2569 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2570 mac_reset_clipping (s
->display
, s
->window
);
2574 /* Draw a box around glyph string S. */
2577 x_draw_glyph_string_box (s
)
2578 struct glyph_string
*s
;
2580 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2581 int left_p
, right_p
;
2582 struct glyph
*last_glyph
;
2585 last_x
= ((s
->row
->full_width_p
&& !s
->w
->pseudo_window_p
)
2586 ? WINDOW_RIGHT_EDGE_X (s
->w
)
2587 : window_box_right (s
->w
, s
->area
));
2589 /* The glyph that may have a right box line. */
2590 last_glyph
= (s
->cmp
|| s
->img
2592 : s
->first_glyph
+ s
->nchars
- 1);
2594 width
= abs (s
->face
->box_line_width
);
2595 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2597 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2599 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2601 bottom_y
= top_y
+ s
->height
- 1;
2603 left_p
= (s
->first_glyph
->left_box_line_p
2604 || (s
->hl
== DRAW_MOUSE_FACE
2606 || s
->prev
->hl
!= s
->hl
)));
2607 right_p
= (last_glyph
->right_box_line_p
2608 || (s
->hl
== DRAW_MOUSE_FACE
2610 || s
->next
->hl
!= s
->hl
)));
2612 get_glyph_string_clip_rect (s
, &clip_rect
);
2614 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2615 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2616 left_p
, right_p
, &clip_rect
);
2619 x_setup_relief_colors (s
);
2620 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2621 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2626 /* Draw foreground of image glyph string S. */
2629 x_draw_image_foreground (s
)
2630 struct glyph_string
*s
;
2633 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2635 /* If first glyph of S has a left box line, start drawing it to the
2636 right of that line. */
2637 if (s
->face
->box
!= FACE_NO_BOX
2638 && s
->first_glyph
->left_box_line_p
2640 x
+= abs (s
->face
->box_line_width
);
2642 /* If there is a margin around the image, adjust x- and y-position
2644 if (s
->slice
.x
== 0)
2645 x
+= s
->img
->hmargin
;
2646 if (s
->slice
.y
== 0)
2647 y
+= s
->img
->vmargin
;
2651 x_set_glyph_string_clipping (s
);
2654 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2655 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2656 s
->slice
.width
, s
->slice
.height
, x
, y
);
2659 mac_copy_area (s
->display
, s
->img
->pixmap
,
2660 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2661 s
->slice
.width
, s
->slice
.height
, x
, y
);
2663 /* When the image has a mask, we can expect that at
2664 least part of a mouse highlight or a block cursor will
2665 be visible. If the image doesn't have a mask, make
2666 a block cursor visible by drawing a rectangle around
2667 the image. I believe it's looking better if we do
2668 nothing here for mouse-face. */
2669 if (s
->hl
== DRAW_CURSOR
)
2671 int r
= s
->img
->relief
;
2673 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
2675 s
->slice
.width
+ r
*2 - 1,
2676 s
->slice
.height
+ r
*2 - 1);
2681 /* Draw a rectangle if image could not be loaded. */
2682 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2683 s
->slice
.width
- 1, s
->slice
.height
- 1);
2687 /* Draw a relief around the image glyph string S. */
2690 x_draw_image_relief (s
)
2691 struct glyph_string
*s
;
2693 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2696 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2698 /* If first glyph of S has a left box line, start drawing it to the
2699 right of that line. */
2700 if (s
->face
->box
!= FACE_NO_BOX
2701 && s
->first_glyph
->left_box_line_p
2703 x
+= abs (s
->face
->box_line_width
);
2705 /* If there is a margin around the image, adjust x- and y-position
2707 if (s
->slice
.x
== 0)
2708 x
+= s
->img
->hmargin
;
2709 if (s
->slice
.y
== 0)
2710 y
+= s
->img
->vmargin
;
2712 if (s
->hl
== DRAW_IMAGE_SUNKEN
2713 || s
->hl
== DRAW_IMAGE_RAISED
)
2715 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2716 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2720 thick
= abs (s
->img
->relief
);
2721 raised_p
= s
->img
->relief
> 0;
2726 x1
= x
+ s
->slice
.width
+ thick
- 1;
2727 y1
= y
+ s
->slice
.height
+ thick
- 1;
2729 x_setup_relief_colors (s
);
2730 get_glyph_string_clip_rect (s
, &r
);
2731 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
2733 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
2735 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
2740 #if 0 /* TODO: figure out if we need to do this on Mac. */
2741 /* Draw the foreground of image glyph string S to PIXMAP. */
2744 x_draw_image_foreground_1 (s
, pixmap
)
2745 struct glyph_string
*s
;
2749 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2751 /* If first glyph of S has a left box line, start drawing it to the
2752 right of that line. */
2753 if (s
->face
->box
!= FACE_NO_BOX
2754 && s
->first_glyph
->left_box_line_p
2756 x
+= abs (s
->face
->box_line_width
);
2758 /* If there is a margin around the image, adjust x- and y-position
2760 if (s
->slice
.x
== 0)
2761 x
+= s
->img
->hmargin
;
2762 if (s
->slice
.y
== 0)
2763 y
+= s
->img
->vmargin
;
2768 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2769 s
->img
->mask
, pixmap
, s
->gc
,
2770 s
->slice
.x
, s
->slice
.y
,
2771 s
->slice
.width
, s
->slice
.height
,
2775 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2776 s
->slice
.x
, s
->slice
.y
,
2777 s
->slice
.width
, s
->slice
.height
,
2780 /* When the image has a mask, we can expect that at
2781 least part of a mouse highlight or a block cursor will
2782 be visible. If the image doesn't have a mask, make
2783 a block cursor visible by drawing a rectangle around
2784 the image. I believe it's looking better if we do
2785 nothing here for mouse-face. */
2786 if (s
->hl
== DRAW_CURSOR
)
2788 int r
= s
->img
->relief
;
2790 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2791 s
->slice
.width
+ r
*2 - 1,
2792 s
->slice
.height
+ r
*2 - 1);
2797 /* Draw a rectangle if image could not be loaded. */
2798 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2799 s
->slice
.width
- 1, s
->slice
.height
- 1);
2804 /* Draw part of the background of glyph string S. X, Y, W, and H
2805 give the rectangle to draw. */
2808 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2809 struct glyph_string
*s
;
2812 #if 0 /* MAC_TODO: stipple */
2815 /* Fill background with a stipple pattern. */
2816 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2817 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2818 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2821 #endif /* MAC_TODO */
2822 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2826 /* Draw image glyph string S.
2829 s->x +-------------------------
2832 | +-------------------------
2835 | | +-------------------
2841 x_draw_image_glyph_string (s
)
2842 struct glyph_string
*s
;
2845 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2846 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2850 height
= s
->height
- 2 * box_line_vwidth
;
2853 /* Fill background with face under the image. Do it only if row is
2854 taller than image or if image has a clip mask to reduce
2856 s
->stippled_p
= s
->face
->stipple
!= 0;
2857 if (height
> s
->slice
.height
2861 || s
->img
->pixmap
== 0
2862 || s
->width
!= s
->background_width
)
2865 if (s
->first_glyph
->left_box_line_p
2867 x
+= box_line_hwidth
;
2870 if (s
->slice
.y
== 0)
2871 y
+= box_line_vwidth
;
2873 #if 0 /* TODO: figure out if we need to do this on Mac. */
2876 /* Create a pixmap as large as the glyph string. Fill it
2877 with the background color. Copy the image to it, using
2878 its mask. Copy the temporary pixmap to the display. */
2879 int depth
= one_mac_display_info
.n_planes
;
2881 /* Create a pixmap as large as the glyph string. */
2882 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2883 s
->background_width
,
2886 /* Fill the pixmap with the background color/stipple. */
2887 #if 0 /* TODO: stipple */
2890 /* Fill background with a stipple pattern. */
2891 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2892 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2893 0, 0, s
->background_width
, s
->height
);
2894 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2900 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2902 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2903 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2904 0, 0, s
->background_width
,
2906 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2911 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2913 s
->background_filled_p
= 1;
2916 /* Draw the foreground. */
2917 #if 0 /* TODO: figure out if we need to do this on Mac. */
2920 x_draw_image_foreground_1 (s
, pixmap
);
2921 x_set_glyph_string_clipping (s
);
2922 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2923 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2924 mac_reset_clipping (s
->display
, s
->window
);
2925 XFreePixmap (s
->display
, pixmap
);
2929 x_draw_image_foreground (s
);
2931 /* If we must draw a relief around the image, do it. */
2933 || s
->hl
== DRAW_IMAGE_RAISED
2934 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2935 x_draw_image_relief (s
);
2939 /* Draw stretch glyph string S. */
2942 x_draw_stretch_glyph_string (s
)
2943 struct glyph_string
*s
;
2945 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2946 s
->stippled_p
= s
->face
->stipple
!= 0;
2948 if (s
->hl
== DRAW_CURSOR
2949 && !x_stretch_cursor_p
)
2951 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2952 as wide as the stretch glyph. */
2953 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2956 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2958 /* Clear rest using the GC of the original non-cursor face. */
2959 if (width
< s
->background_width
)
2961 int x
= s
->x
+ width
, y
= s
->y
;
2962 int w
= s
->background_width
- width
, h
= s
->height
;
2966 if (s
->row
->mouse_face_p
2967 && cursor_in_mouse_face_p (s
->w
))
2969 x_set_mouse_face_gc (s
);
2975 get_glyph_string_clip_rect (s
, &r
);
2976 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2978 #if 0 /* MAC_TODO: stipple */
2979 if (s
->face
->stipple
)
2981 /* Fill background with a stipple pattern. */
2982 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2983 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2984 XSetFillStyle (s
->display
, gc
, FillSolid
);
2987 #endif /* MAC_TODO */
2988 mac_erase_rectangle (s
->window
, gc
, x
, y
, w
, h
);
2990 mac_reset_clipping (s
->display
, s
->window
);
2993 else if (!s
->background_filled_p
)
2994 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
2997 s
->background_filled_p
= 1;
3001 /* Draw glyph string S. */
3004 x_draw_glyph_string (s
)
3005 struct glyph_string
*s
;
3007 int relief_drawn_p
= 0;
3009 /* If S draws into the background of its successor that does not
3010 draw a cursor, draw the background of the successor first so that
3011 S can draw into it. This makes S->next use XDrawString instead
3012 of XDrawImageString. */
3013 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
3014 && s
->next
->hl
!= DRAW_CURSOR
)
3016 xassert (s
->next
->img
== NULL
);
3017 x_set_glyph_string_gc (s
->next
);
3018 x_set_glyph_string_clipping (s
->next
);
3019 x_draw_glyph_string_background (s
->next
, 1);
3022 /* Set up S->gc, set clipping and draw S. */
3023 x_set_glyph_string_gc (s
);
3025 /* Draw relief (if any) in advance for char/composition so that the
3026 glyph string can be drawn over it. */
3027 if (!s
->for_overlaps_p
3028 && s
->face
->box
!= FACE_NO_BOX
3029 && (s
->first_glyph
->type
== CHAR_GLYPH
3030 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3033 x_set_glyph_string_clipping (s
);
3034 x_draw_glyph_string_background (s
, 1);
3035 x_draw_glyph_string_box (s
);
3036 x_set_glyph_string_clipping (s
);
3040 x_set_glyph_string_clipping (s
);
3042 switch (s
->first_glyph
->type
)
3045 x_draw_image_glyph_string (s
);
3049 x_draw_stretch_glyph_string (s
);
3053 if (s
->for_overlaps_p
)
3054 s
->background_filled_p
= 1;
3056 x_draw_glyph_string_background (s
, 0);
3057 x_draw_glyph_string_foreground (s
);
3060 case COMPOSITE_GLYPH
:
3061 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3062 s
->background_filled_p
= 1;
3064 x_draw_glyph_string_background (s
, 1);
3065 x_draw_composite_glyph_string_foreground (s
);
3072 if (!s
->for_overlaps_p
)
3074 /* Draw underline. */
3075 if (s
->face
->underline_p
)
3077 unsigned long h
= 1;
3078 unsigned long dy
= s
->height
- h
;
3080 if (s
->face
->underline_defaulted_p
)
3081 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3086 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3087 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3088 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3090 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3094 /* Draw overline. */
3095 if (s
->face
->overline_p
)
3097 unsigned long dy
= 0, h
= 1;
3099 if (s
->face
->overline_color_defaulted_p
)
3100 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3105 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3106 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3107 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3109 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3113 /* Draw strike-through. */
3114 if (s
->face
->strike_through_p
)
3116 unsigned long h
= 1;
3117 unsigned long dy
= (s
->height
- h
) / 2;
3119 if (s
->face
->strike_through_color_defaulted_p
)
3120 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3125 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3126 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3127 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3129 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3133 /* Draw relief if not yet drawn. */
3134 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3135 x_draw_glyph_string_box (s
);
3138 /* Reset clipping. */
3139 mac_reset_clipping (s
->display
, s
->window
);
3142 /* Shift display to make room for inserted glyphs. */
3145 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3147 int x
, y
, width
, height
, shift_by
;
3149 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3150 f
->output_data
.mac
->normal_gc
,
3151 x
, y
, width
, height
,
3155 /* Delete N glyphs at the nominal cursor position. Not implemented
3166 /* Clear entire frame. If updating_frame is non-null, clear that
3167 frame. Otherwise clear the selected frame. */
3177 f
= SELECTED_FRAME ();
3179 /* Clearing the frame will erase any cursor, so mark them all as no
3181 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3182 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3183 output_cursor
.x
= -1;
3185 /* We don't set the output cursor here because there will always
3186 follow an explicit cursor_to. */
3188 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3190 /* We have to clear the scroll bars, too. If we have changed
3191 colors or something like that, then they should be notified. */
3192 x_scroll_bar_clear (f
);
3194 XFlush (FRAME_MAC_DISPLAY (f
));
3200 /* Invert the middle quarter of the frame for .15 sec. */
3202 /* We use the select system call to do the waiting, so we have to make
3203 sure it's available. If it isn't, we just won't do visual bells. */
3205 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3208 /* Subtract the `struct timeval' values X and Y, storing the result in
3209 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3212 timeval_subtract (result
, x
, y
)
3213 struct timeval
*result
, x
, y
;
3215 /* Perform the carry for the later subtraction by updating y. This
3216 is safer because on some systems the tv_sec member is unsigned. */
3217 if (x
.tv_usec
< y
.tv_usec
)
3219 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3220 y
.tv_usec
-= 1000000 * nsec
;
3224 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3226 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3227 y
.tv_usec
+= 1000000 * nsec
;
3231 /* Compute the time remaining to wait. tv_usec is certainly
3233 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3234 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3236 /* Return indication of whether the result should be considered
3238 return x
.tv_sec
< y
.tv_sec
;
3250 struct timeval wakeup
;
3252 EMACS_GET_TIME (wakeup
);
3254 /* Compute time to wait until, propagating carry from usecs. */
3255 wakeup
.tv_usec
+= 150000;
3256 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3257 wakeup
.tv_usec
%= 1000000;
3259 /* Keep waiting until past the time wakeup. */
3262 struct timeval timeout
;
3264 EMACS_GET_TIME (timeout
);
3266 /* In effect, timeout = wakeup - timeout.
3267 Break if result would be negative. */
3268 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3271 /* Try to wait that long--but we might wake up sooner. */
3272 select (0, NULL
, NULL
, NULL
, &timeout
);
3281 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3284 /* Make audible bell. */
3289 struct frame
*f
= SELECTED_FRAME ();
3291 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3299 XFlush (FRAME_MAC_DISPLAY (f
));
3305 /* Specify how many text lines, from the top of the window,
3306 should be affected by insert-lines and delete-lines operations.
3307 This, and those operations, are used only within an update
3308 that is bounded by calls to x_update_begin and x_update_end. */
3311 XTset_terminal_window (n
)
3314 /* This function intentionally left blank. */
3319 /***********************************************************************
3321 ***********************************************************************/
3323 /* Perform an insert-lines or delete-lines operation, inserting N
3324 lines or deleting -N lines at vertical position VPOS. */
3327 x_ins_del_lines (vpos
, n
)
3334 /* Scroll part of the display as described by RUN. */
3337 x_scroll_run (w
, run
)
3341 struct frame
*f
= XFRAME (w
->frame
);
3342 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3344 /* Get frame-relative bounding box of the text display area of W,
3345 without mode lines. Include in this box the left and right
3347 window_box (w
, -1, &x
, &y
, &width
, &height
);
3349 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3350 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3351 bottom_y
= y
+ height
;
3355 /* Scrolling up. Make sure we don't copy part of the mode
3356 line at the bottom. */
3357 if (from_y
+ run
->height
> bottom_y
)
3358 height
= bottom_y
- from_y
;
3360 height
= run
->height
;
3364 /* Scolling down. Make sure we don't copy over the mode line.
3366 if (to_y
+ run
->height
> bottom_y
)
3367 height
= bottom_y
- to_y
;
3369 height
= run
->height
;
3374 /* Cursor off. Will be switched on again in x_update_window_end. */
3378 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3379 f
->output_data
.mac
->normal_gc
,
3389 /***********************************************************************
3391 ***********************************************************************/
3399 ControlRef root_control
;
3402 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
3404 ActivateControl (root_control
);
3406 x_update_cursor (f
, 1);
3410 frame_unhighlight (f
)
3414 ControlRef root_control
;
3417 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
3419 DeactivateControl (root_control
);
3421 x_update_cursor (f
, 1);
3424 /* The focus has changed. Update the frames as necessary to reflect
3425 the new situation. Note that we can't change the selected frame
3426 here, because the Lisp code we are interrupting might become confused.
3427 Each event gets marked with the frame in which it occurred, so the
3428 Lisp code can tell when the switch took place by examining the events. */
3431 x_new_focus_frame (dpyinfo
, frame
)
3432 struct x_display_info
*dpyinfo
;
3433 struct frame
*frame
;
3435 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3437 if (frame
!= dpyinfo
->x_focus_frame
)
3439 /* Set this before calling other routines, so that they see
3440 the correct value of x_focus_frame. */
3441 dpyinfo
->x_focus_frame
= frame
;
3443 if (old_focus
&& old_focus
->auto_lower
)
3444 x_lower_frame (old_focus
);
3447 selected_frame
= frame
;
3448 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3450 Fselect_window (selected_frame
->selected_window
, Qnil
);
3451 choose_minibuf_frame ();
3454 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3455 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3457 pending_autoraise_frame
= 0;
3460 x_frame_rehighlight (dpyinfo
);
3463 /* Handle FocusIn and FocusOut state changes for FRAME.
3464 If FRAME has focus and there exists more than one frame, puts
3465 a FOCUS_IN_EVENT into *BUFP. */
3468 mac_focus_changed (type
, dpyinfo
, frame
, bufp
)
3470 struct mac_display_info
*dpyinfo
;
3471 struct frame
*frame
;
3472 struct input_event
*bufp
;
3474 if (type
== activeFlag
)
3476 if (dpyinfo
->x_focus_event_frame
!= frame
)
3478 x_new_focus_frame (dpyinfo
, frame
);
3479 dpyinfo
->x_focus_event_frame
= frame
;
3481 /* Don't stop displaying the initial startup message
3482 for a switch-frame event we don't need. */
3483 if (GC_NILP (Vterminal_frame
)
3484 && GC_CONSP (Vframe_list
)
3485 && !GC_NILP (XCDR (Vframe_list
)))
3487 bufp
->kind
= FOCUS_IN_EVENT
;
3488 XSETFRAME (bufp
->frame_or_window
, frame
);
3494 if (dpyinfo
->x_focus_event_frame
== frame
)
3496 dpyinfo
->x_focus_event_frame
= 0;
3497 x_new_focus_frame (dpyinfo
, 0);
3502 /* The focus may have changed. Figure out if it is a real focus change,
3503 by checking both FocusIn/Out and Enter/LeaveNotify events.
3505 Returns FOCUS_IN_EVENT event in *BUFP. */
3508 x_detect_focus_change (dpyinfo
, event
, bufp
)
3509 struct mac_display_info
*dpyinfo
;
3511 struct input_event
*bufp
;
3513 struct frame
*frame
;
3515 frame
= mac_window_to_frame ((WindowPtr
) event
->message
);
3519 /* On Mac, this is only called from focus events, so no switch needed. */
3520 mac_focus_changed ((event
->modifiers
& activeFlag
),
3521 dpyinfo
, frame
, bufp
);
3525 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3528 x_mouse_leave (dpyinfo
)
3529 struct x_display_info
*dpyinfo
;
3531 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3534 /* The focus has changed, or we have redirected a frame's focus to
3535 another frame (this happens when a frame uses a surrogate
3536 mini-buffer frame). Shift the highlight as appropriate.
3538 The FRAME argument doesn't necessarily have anything to do with which
3539 frame is being highlighted or un-highlighted; we only use it to find
3540 the appropriate X display info. */
3543 XTframe_rehighlight (frame
)
3544 struct frame
*frame
;
3546 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3550 x_frame_rehighlight (dpyinfo
)
3551 struct x_display_info
*dpyinfo
;
3553 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3555 if (dpyinfo
->x_focus_frame
)
3557 dpyinfo
->x_highlight_frame
3558 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3559 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3560 : dpyinfo
->x_focus_frame
);
3561 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3563 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3564 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3568 dpyinfo
->x_highlight_frame
= 0;
3570 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3573 frame_unhighlight (old_highlight
);
3574 if (dpyinfo
->x_highlight_frame
)
3575 frame_highlight (dpyinfo
->x_highlight_frame
);
3581 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3583 #if 0 /* MAC_TODO */
3584 /* Initialize mode_switch_bit and modifier_meaning. */
3586 x_find_modifier_meanings (dpyinfo
)
3587 struct x_display_info
*dpyinfo
;
3589 int min_code
, max_code
;
3592 XModifierKeymap
*mods
;
3594 dpyinfo
->meta_mod_mask
= 0;
3595 dpyinfo
->shift_lock_mask
= 0;
3596 dpyinfo
->alt_mod_mask
= 0;
3597 dpyinfo
->super_mod_mask
= 0;
3598 dpyinfo
->hyper_mod_mask
= 0;
3601 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3603 min_code
= dpyinfo
->display
->min_keycode
;
3604 max_code
= dpyinfo
->display
->max_keycode
;
3607 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3608 min_code
, max_code
- min_code
+ 1,
3610 mods
= XGetModifierMapping (dpyinfo
->display
);
3612 /* Scan the modifier table to see which modifier bits the Meta and
3613 Alt keysyms are on. */
3615 int row
, col
; /* The row and column in the modifier table. */
3617 for (row
= 3; row
< 8; row
++)
3618 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3621 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3623 /* Zeroes are used for filler. Skip them. */
3627 /* Are any of this keycode's keysyms a meta key? */
3631 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3633 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3639 dpyinfo
->meta_mod_mask
|= (1 << row
);
3644 dpyinfo
->alt_mod_mask
|= (1 << row
);
3649 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3654 dpyinfo
->super_mod_mask
|= (1 << row
);
3658 /* Ignore this if it's not on the lock modifier. */
3659 if ((1 << row
) == LockMask
)
3660 dpyinfo
->shift_lock_mask
= LockMask
;
3668 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3669 if (! dpyinfo
->meta_mod_mask
)
3671 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3672 dpyinfo
->alt_mod_mask
= 0;
3675 /* If some keys are both alt and meta,
3676 make them just meta, not alt. */
3677 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3679 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3682 XFree ((char *) syms
);
3683 XFreeModifiermap (mods
);
3686 #endif /* MAC_TODO */
3688 /* Convert between the modifier bits X uses and the modifier bits
3692 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3693 struct x_display_info
*dpyinfo
;
3694 unsigned short state
;
3696 return (((state
& shiftKey
) ? shift_modifier
: 0)
3697 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3698 | ((state
& cmdKey
) ? meta_modifier
: 0)
3699 | ((state
& optionKey
) ? alt_modifier
: 0));
3702 #if 0 /* MAC_TODO */
3703 static unsigned short
3704 x_emacs_to_x_modifiers (dpyinfo
, state
)
3705 struct x_display_info
*dpyinfo
;
3708 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3709 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3710 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3711 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3712 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3713 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3715 #endif /* MAC_TODO */
3717 /* Convert a keysym to its name. */
3720 x_get_keysym_name (keysym
)
3727 value
= XKeysymToString (keysym
);
3738 /* Function to report a mouse movement to the mainstream Emacs code.
3739 The input handler calls this.
3741 We have received a mouse movement event, which is given in *event.
3742 If the mouse is over a different glyph than it was last time, tell
3743 the mainstream emacs code by setting mouse_moved. If not, ask for
3744 another motion event, so we can check again the next time it moves. */
3746 static Point last_mouse_motion_position
;
3747 static Lisp_Object last_mouse_motion_frame
;
3750 note_mouse_movement (frame
, pos
)
3754 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
3755 #if TARGET_API_MAC_CARBON
3759 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3760 last_mouse_motion_position
= *pos
;
3761 XSETFRAME (last_mouse_motion_frame
, frame
);
3763 #if TARGET_API_MAC_CARBON
3764 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3766 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3769 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
3770 /* This case corresponds to LeaveNotify in X11. */
3772 /* If we move outside the frame, then we're certainly no
3773 longer on any text in the frame. */
3774 clear_mouse_face (dpyinfo
);
3775 dpyinfo
->mouse_face_mouse_frame
= 0;
3776 if (!dpyinfo
->grabbed
)
3777 rif
->define_frame_cursor (frame
,
3778 frame
->output_data
.mac
->nontext_cursor
);
3781 /* Has the mouse moved off the glyph it was on at the last sighting? */
3782 else if (pos
->h
< last_mouse_glyph
.left
3783 || pos
->h
>= last_mouse_glyph
.right
3784 || pos
->v
< last_mouse_glyph
.top
3785 || pos
->v
>= last_mouse_glyph
.bottom
)
3787 frame
->mouse_moved
= 1;
3788 last_mouse_scroll_bar
= Qnil
;
3789 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3794 /************************************************************************
3796 ************************************************************************/
3798 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3801 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3804 redo_mouse_highlight ()
3806 if (!NILP (last_mouse_motion_frame
)
3807 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3808 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3809 last_mouse_motion_position
.h
,
3810 last_mouse_motion_position
.v
);
3814 /* Try to determine frame pixel position and size of the glyph under
3815 frame pixel coordinates X/Y on frame F . Return the position and
3816 size in *RECT. Value is non-zero if we could compute these
3820 glyph_rect (f
, x
, y
, rect
)
3827 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3831 struct window
*w
= XWINDOW (window
);
3832 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3833 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3835 for (; r
< end
&& r
->enabled_p
; ++r
)
3836 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3838 /* Found the row at y. */
3839 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3840 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3843 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3844 rect
->bottom
= rect
->top
+ r
->height
;
3848 /* x is to the left of the first glyph in the row. */
3849 /* Shouldn't this be a pixel value?
3850 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3852 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3853 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3857 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3858 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3860 /* x is on a glyph. */
3861 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3862 rect
->right
= rect
->left
+ g
->pixel_width
;
3866 /* x is to the right of the last glyph in the row. */
3867 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3868 /* Shouldn't this be a pixel value?
3869 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3871 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3876 /* The y is not on any row. */
3880 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3882 /* Record the position of the mouse in last_mouse_glyph. */
3884 remember_mouse_glyph (f1
, gx
, gy
)
3888 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3890 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3891 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3893 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3894 round down even for negative values. */
3900 /* This was the original code from XTmouse_position, but it seems
3901 to give the position of the glyph diagonally next to the one
3902 the mouse is over. */
3903 gx
= (gx
+ width
- 1) / width
* width
;
3904 gy
= (gy
+ height
- 1) / height
* height
;
3906 gx
= gx
/ width
* width
;
3907 gy
= gy
/ height
* height
;
3910 last_mouse_glyph
.left
= gx
;
3911 last_mouse_glyph
.top
= gy
;
3912 last_mouse_glyph
.right
= gx
+ width
;
3913 last_mouse_glyph
.bottom
= gy
+ height
;
3918 static struct frame
*
3919 mac_focus_frame (dpyinfo
)
3920 struct mac_display_info
*dpyinfo
;
3922 if (dpyinfo
->x_focus_frame
)
3923 return dpyinfo
->x_focus_frame
;
3925 /* Mac version may get events, such as a menu bar click, even when
3926 all the frames are invisible. In this case, we regard the
3927 event came to the selected frame. */
3928 return SELECTED_FRAME ();
3932 /* Return the current position of the mouse.
3933 *fp should be a frame which indicates which display to ask about.
3935 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3936 and *part to the frame, window, and scroll bar part that the mouse
3937 is over. Set *x and *y to the portion and whole of the mouse's
3938 position on the scroll bar.
3940 If the mouse movement started elsewhere, set *fp to the frame the
3941 mouse is on, *bar_window to nil, and *x and *y to the character cell
3944 Set *time to the server time-stamp for the time at which the mouse
3945 was at this position.
3947 Don't store anything if we don't have a valid set of values to report.
3949 This clears the mouse_moved flag, so we can wait for the next mouse
3953 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3956 Lisp_Object
*bar_window
;
3957 enum scroll_bar_part
*part
;
3959 unsigned long *time
;
3962 int ignore1
, ignore2
;
3963 struct frame
*f
= mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp
));
3964 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
3965 Lisp_Object frame
, tail
;
3969 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3970 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3973 /* Clear the mouse-moved flag for every frame on this display. */
3974 FOR_EACH_FRAME (tail
, frame
)
3975 XFRAME (frame
)->mouse_moved
= 0;
3977 last_mouse_scroll_bar
= Qnil
;
3979 SetPortWindowPort (wp
);
3981 GetMouse (&mouse_pos
);
3983 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3984 &last_mouse_glyph
, insist
);
3987 *part
= scroll_bar_handle
;
3989 XSETINT (*x
, mouse_pos
.h
);
3990 XSETINT (*y
, mouse_pos
.v
);
3991 *time
= last_mouse_movement_time
;
3998 /************************************************************************
4000 ************************************************************************/
4002 #ifdef USE_TOOLKIT_SCROLL_BARS
4004 static pascal void scroll_bar_timer_callback
P_ ((EventLoopTimerRef
, void *));
4005 static OSStatus install_scroll_bar_timer
P_ ((void));
4006 static OSStatus set_scroll_bar_timer
P_ ((EventTimerInterval
));
4007 static int control_part_code_to_scroll_bar_part
P_ ((ControlPartCode
));
4008 static void construct_scroll_bar_click
P_ ((struct scroll_bar
*, int,
4009 struct input_event
*));
4010 static OSErr get_control_part_bounds
P_ ((ControlHandle
, ControlPartCode
,
4012 static void x_scroll_bar_handle_press
P_ ((struct scroll_bar
*,
4014 struct input_event
*));
4015 static void x_scroll_bar_handle_release
P_ ((struct scroll_bar
*,
4016 struct input_event
*));
4017 static void x_scroll_bar_handle_drag
P_ ((WindowPtr
, struct scroll_bar
*,
4018 Point
, struct input_event
*));
4019 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
4022 /* Last scroll bar part sent in x_scroll_bar_handle_*. */
4024 static int last_scroll_bar_part
;
4026 static EventLoopTimerRef scroll_bar_timer
;
4028 static int scroll_bar_timer_event_posted_p
;
4030 #define SCROLL_BAR_FIRST_DELAY 0.5
4031 #define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
4034 scroll_bar_timer_callback (timer
, data
)
4035 EventLoopTimerRef timer
;
4038 EventRef event
= NULL
;
4041 err
= CreateEvent (NULL
, kEventClassMouse
, kEventMouseMoved
, 0,
4042 kEventAttributeNone
, &event
);
4047 GetMouse (&mouse_pos
);
4048 LocalToGlobal (&mouse_pos
);
4049 err
= SetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
4050 sizeof (Point
), &mouse_pos
);
4054 UInt32 modifiers
= GetCurrentKeyModifiers ();
4056 err
= SetEventParameter (event
, kEventParamKeyModifiers
, typeUInt32
,
4057 sizeof (UInt32
), &modifiers
);
4060 err
= PostEventToQueue (GetCurrentEventQueue (), event
,
4061 kEventPriorityStandard
);
4063 scroll_bar_timer_event_posted_p
= 1;
4066 ReleaseEvent (event
);
4070 install_scroll_bar_timer ()
4072 static EventLoopTimerUPP scroll_bar_timer_callbackUPP
= NULL
;
4074 if (scroll_bar_timer_callbackUPP
== NULL
)
4075 scroll_bar_timer_callbackUPP
=
4076 NewEventLoopTimerUPP (scroll_bar_timer_callback
);
4078 if (scroll_bar_timer
== NULL
)
4079 /* Mac OS X and CarbonLib 1.5 and later allow us to specify
4080 kEventDurationForever as delays. */
4082 InstallEventLoopTimer (GetCurrentEventLoop (),
4083 kEventDurationForever
, kEventDurationForever
,
4084 scroll_bar_timer_callbackUPP
, NULL
,
4089 set_scroll_bar_timer (delay
)
4090 EventTimerInterval delay
;
4092 if (scroll_bar_timer
== NULL
)
4093 install_scroll_bar_timer ();
4095 scroll_bar_timer_event_posted_p
= 0;
4097 return SetEventLoopTimerNextFireTime (scroll_bar_timer
, delay
);
4101 control_part_code_to_scroll_bar_part (part_code
)
4102 ControlPartCode part_code
;
4106 case kControlUpButtonPart
: return scroll_bar_up_arrow
;
4107 case kControlDownButtonPart
: return scroll_bar_down_arrow
;
4108 case kControlPageUpPart
: return scroll_bar_above_handle
;
4109 case kControlPageDownPart
: return scroll_bar_below_handle
;
4110 case kControlIndicatorPart
: return scroll_bar_handle
;
4117 construct_scroll_bar_click (bar
, part
, bufp
)
4118 struct scroll_bar
*bar
;
4120 struct input_event
*bufp
;
4122 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4123 bufp
->frame_or_window
= bar
->window
;
4127 XSETINT (bufp
->x
, 0);
4128 XSETINT (bufp
->y
, 0);
4129 bufp
->modifiers
= 0;
4133 get_control_part_bounds (ch
, part_code
, rect
)
4135 ControlPartCode part_code
;
4138 RgnHandle region
= NewRgn ();
4141 err
= GetControlRegion (ch
, part_code
, region
);
4143 GetRegionBounds (region
, rect
);
4144 DisposeRgn (region
);
4150 x_scroll_bar_handle_press (bar
, part_code
, bufp
)
4151 struct scroll_bar
*bar
;
4152 ControlPartCode part_code
;
4153 struct input_event
*bufp
;
4155 int part
= control_part_code_to_scroll_bar_part (part_code
);
4160 if (part
!= scroll_bar_handle
)
4162 construct_scroll_bar_click (bar
, part
, bufp
);
4163 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4164 set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY
);
4167 last_scroll_bar_part
= part
;
4168 bar
->dragging
= Qnil
;
4169 tracked_scroll_bar
= bar
;
4173 x_scroll_bar_handle_release (bar
, bufp
)
4174 struct scroll_bar
*bar
;
4175 struct input_event
*bufp
;
4177 if (last_scroll_bar_part
!= scroll_bar_handle
4178 || !GC_NILP (bar
->dragging
))
4179 construct_scroll_bar_click (bar
, scroll_bar_end_scroll
, bufp
);
4181 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4182 set_scroll_bar_timer (kEventDurationForever
);
4184 last_scroll_bar_part
= -1;
4185 bar
->dragging
= Qnil
;
4186 tracked_scroll_bar
= NULL
;
4190 x_scroll_bar_handle_drag (win
, bar
, mouse_pos
, bufp
)
4192 struct scroll_bar
*bar
;
4194 struct input_event
*bufp
;
4196 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4198 if (last_scroll_bar_part
== scroll_bar_handle
)
4203 get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar
),
4204 kControlIndicatorPart
, &r
);
4206 if (GC_NILP (bar
->dragging
))
4207 XSETINT (bar
->dragging
, mouse_pos
.v
- r
.top
);
4209 top
= mouse_pos
.v
- XINT (bar
->dragging
) - XINT (bar
->track_top
);
4210 top_range
= (XINT (bar
->track_height
) - (r
.bottom
- r
.top
)) *
4211 (1.0 + (float) GetControlViewSize (ch
) / GetControl32BitMaximum (ch
))
4216 if (top
> top_range
)
4219 construct_scroll_bar_click (bar
, scroll_bar_handle
, bufp
);
4220 XSETINT (bufp
->x
, top
);
4221 XSETINT (bufp
->y
, top_range
);
4225 ControlPartCode part_code
;
4226 int unhilite_p
= 0, part
;
4228 if (ch
!= FindControlUnderMouse (mouse_pos
, win
, &part_code
))
4232 part
= control_part_code_to_scroll_bar_part (part_code
);
4234 switch (last_scroll_bar_part
)
4236 case scroll_bar_above_handle
:
4237 case scroll_bar_below_handle
:
4238 if (part
!= scroll_bar_above_handle
4239 && part
!= scroll_bar_below_handle
)
4243 case scroll_bar_up_arrow
:
4244 case scroll_bar_down_arrow
:
4245 if (part
!= scroll_bar_up_arrow
4246 && part
!= scroll_bar_down_arrow
)
4253 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4254 else if (part
!= last_scroll_bar_part
4255 || scroll_bar_timer_event_posted_p
)
4257 construct_scroll_bar_click (bar
, part
, bufp
);
4258 last_scroll_bar_part
= part
;
4259 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4260 set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY
);
4265 /* Set the thumb size and position of scroll bar BAR. We are currently
4266 displaying PORTION out of a whole WHOLE, and our position POSITION. */
4269 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
4270 struct scroll_bar
*bar
;
4271 int portion
, position
, whole
;
4273 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4275 int value
, viewsize
, maximum
;
4277 if (whole
== 0 || XINT (bar
->track_height
) == 0)
4278 value
= 0, viewsize
= 1, maximum
= 0;
4283 maximum
= max (0, whole
- portion
);
4288 SetControl32BitMinimum (ch
, 0);
4289 SetControl32BitMaximum (ch
, maximum
);
4290 SetControl32BitValue (ch
, value
);
4291 SetControlViewSize (ch
, viewsize
);
4296 #endif /* USE_TOOLKIT_SCROLL_BARS */
4300 /************************************************************************
4301 Scroll bars, general
4302 ************************************************************************/
4304 /* Create a scroll bar and return the scroll bar vector for it. W is
4305 the Emacs window on which to create the scroll bar. TOP, LEFT,
4306 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4309 static struct scroll_bar
*
4310 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4312 int top
, left
, width
, height
, disp_top
, disp_height
;
4314 struct frame
*f
= XFRAME (w
->frame
);
4315 struct scroll_bar
*bar
4316 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4324 r
.right
= left
+ width
;
4325 r
.bottom
= disp_top
+ disp_height
;
4327 #if TARGET_API_MAC_CARBON
4328 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4329 0, 0, 0, kControlScrollBarProc
, (long) bar
);
4331 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4332 0, 0, 0, scrollBarProc
, (long) bar
);
4334 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4336 XSETWINDOW (bar
->window
, w
);
4337 XSETINT (bar
->top
, top
);
4338 XSETINT (bar
->left
, left
);
4339 XSETINT (bar
->width
, width
);
4340 XSETINT (bar
->height
, height
);
4341 XSETINT (bar
->start
, 0);
4342 XSETINT (bar
->end
, 0);
4343 bar
->dragging
= Qnil
;
4344 #ifdef USE_TOOLKIT_SCROLL_BARS
4345 bar
->track_top
= Qnil
;
4346 bar
->track_height
= Qnil
;
4349 /* Add bar to its frame's list of scroll bars. */
4350 bar
->next
= FRAME_SCROLL_BARS (f
);
4352 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4353 if (!NILP (bar
->next
))
4354 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4361 /* Draw BAR's handle in the proper position.
4363 If the handle is already drawn from START to END, don't bother
4364 redrawing it, unless REBUILD is non-zero; in that case, always
4365 redraw it. (REBUILD is handy for drawing the handle after expose
4368 Normally, we want to constrain the start and end of the handle to
4369 fit inside its rectangle, but if the user is dragging the scroll
4370 bar handle, we want to let them drag it down all the way, so that
4371 the bar's top is as far down as it goes; otherwise, there's no way
4372 to move to the very end of the buffer. */
4374 #ifndef USE_TOOLKIT_SCROLL_BARS
4377 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4378 struct scroll_bar
*bar
;
4382 int dragging
= ! NILP (bar
->dragging
);
4383 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4384 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4385 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4386 int length
= end
- start
;
4388 /* If the display is already accurate, do nothing. */
4390 && start
== XINT (bar
->start
)
4391 && end
== XINT (bar
->end
))
4396 /* Make sure the values are reasonable, and try to preserve the
4397 distance between start and end. */
4400 else if (start
> top_range
)
4402 end
= start
+ length
;
4406 else if (end
> top_range
&& ! dragging
)
4409 /* Store the adjusted setting in the scroll bar. */
4410 XSETINT (bar
->start
, start
);
4411 XSETINT (bar
->end
, end
);
4413 /* Clip the end position, just for display. */
4414 if (end
> top_range
)
4417 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4418 top positions, to make sure the handle is always at least that
4419 many pixels tall. */
4420 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4422 SetControlMinimum (ch
, 0);
4423 /* Don't inadvertently activate deactivated scroll bars */
4424 if (GetControlMaximum (ch
) != -1)
4425 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4427 SetControlValue (ch
, start
);
4428 #if TARGET_API_MAC_CARBON
4429 SetControlViewSize (ch
, end
- start
);
4435 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4437 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4441 x_scroll_bar_remove (bar
)
4442 struct scroll_bar
*bar
;
4444 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4448 /* Destroy the Mac scroll bar control */
4449 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4451 /* Disassociate this scroll bar from its window. */
4452 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4458 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4459 that we are displaying PORTION characters out of a total of WHOLE
4460 characters, starting at POSITION. If WINDOW has no scroll bar,
4464 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4466 int portion
, whole
, position
;
4468 struct frame
*f
= XFRAME (w
->frame
);
4469 struct scroll_bar
*bar
;
4470 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4471 int window_y
, window_height
;
4473 /* Get window dimensions. */
4474 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4476 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4477 height
= window_height
;
4479 /* Compute the left edge of the scroll bar area. */
4480 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4482 /* Compute the width of the scroll bar which might be less than
4483 the width of the area reserved for the scroll bar. */
4484 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4485 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4489 /* Compute the left edge of the scroll bar. */
4490 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4493 sb_left
= left
+ width
- sb_width
;
4495 /* Adjustments according to Inside Macintosh to make it look nice */
4497 disp_height
= height
;
4503 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4509 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4512 /* Does the scroll bar exist yet? */
4513 if (NILP (w
->vertical_scroll_bar
))
4516 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4517 left
, top
, width
, height
, 0);
4519 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4521 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4525 /* It may just need to be moved and resized. */
4528 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4529 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4533 /* If already correctly positioned, do nothing. */
4534 if (!(XINT (bar
->left
) == sb_left
4535 && XINT (bar
->top
) == top
4536 && XINT (bar
->width
) == sb_width
4537 && XINT (bar
->height
) == height
))
4539 /* Since toolkit scroll bars are smaller than the space reserved
4540 for them on the frame, we have to clear "under" them. */
4541 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4542 left
, top
, width
, height
, 0);
4545 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4546 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4547 sb_left
- 1, top
, 1, height
, 0);
4551 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4552 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4554 if (sb_width
< disp_height
)
4557 /* Remember new settings. */
4558 XSETINT (bar
->left
, sb_left
);
4559 XSETINT (bar
->top
, top
);
4560 XSETINT (bar
->width
, sb_width
);
4561 XSETINT (bar
->height
, height
);
4562 #ifdef USE_TOOLKIT_SCROLL_BARS
4563 bar
->track_top
= Qnil
;
4564 bar
->track_height
= Qnil
;
4571 #ifdef USE_TOOLKIT_SCROLL_BARS
4572 if (NILP (bar
->track_top
))
4574 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4579 SetControl32BitMinimum (ch
, 0);
4580 SetControl32BitMaximum (ch
, 1);
4581 SetControlViewSize (ch
, 1);
4583 /* Move the scroll bar thumb to the top. */
4584 SetControl32BitValue (ch
, 0);
4585 get_control_part_bounds (ch
, kControlIndicatorPart
, &r0
);
4587 /* Move the scroll bar thumb to the bottom. */
4588 SetControl32BitValue (ch
, 1);
4589 get_control_part_bounds (ch
, kControlIndicatorPart
, &r1
);
4591 UnionRect (&r0
, &r1
, &r0
);
4592 XSETINT (bar
->track_top
, r0
.top
);
4593 XSETINT (bar
->track_height
, r0
.bottom
- r0
.top
);
4598 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
4599 #else /* not USE_TOOLKIT_SCROLL_BARS */
4600 /* Set the scroll bar's current state, unless we're currently being
4602 if (NILP (bar
->dragging
))
4604 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4607 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4610 int start
= ((double) position
* top_range
) / whole
;
4611 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4612 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4615 #endif /* not USE_TOOLKIT_SCROLL_BARS */
4619 /* The following three hooks are used when we're doing a thorough
4620 redisplay of the frame. We don't explicitly know which scroll bars
4621 are going to be deleted, because keeping track of when windows go
4622 away is a real pain - "Can you say set-window-configuration, boys
4623 and girls?" Instead, we just assert at the beginning of redisplay
4624 that *all* scroll bars are to be removed, and then save a scroll bar
4625 from the fiery pit when we actually redisplay its window. */
4627 /* Arrange for all scroll bars on FRAME to be removed at the next call
4628 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4629 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4632 XTcondemn_scroll_bars (frame
)
4635 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4636 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4639 bar
= FRAME_SCROLL_BARS (frame
);
4640 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4641 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4642 XSCROLL_BAR (bar
)->prev
= Qnil
;
4643 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4644 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4645 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4650 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4651 Note that WINDOW isn't necessarily condemned at all. */
4654 XTredeem_scroll_bar (window
)
4655 struct window
*window
;
4657 struct scroll_bar
*bar
;
4660 /* We can't redeem this window's scroll bar if it doesn't have one. */
4661 if (NILP (window
->vertical_scroll_bar
))
4664 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4666 /* Unlink it from the condemned list. */
4667 f
= XFRAME (WINDOW_FRAME (window
));
4668 if (NILP (bar
->prev
))
4670 /* If the prev pointer is nil, it must be the first in one of
4672 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4673 /* It's not condemned. Everything's fine. */
4675 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4676 window
->vertical_scroll_bar
))
4677 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4679 /* If its prev pointer is nil, it must be at the front of
4680 one or the other! */
4684 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4686 if (! NILP (bar
->next
))
4687 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4689 bar
->next
= FRAME_SCROLL_BARS (f
);
4691 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4692 if (! NILP (bar
->next
))
4693 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4696 /* Remove all scroll bars on FRAME that haven't been saved since the
4697 last call to `*condemn_scroll_bars_hook'. */
4700 XTjudge_scroll_bars (f
)
4703 Lisp_Object bar
, next
;
4705 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4707 /* Clear out the condemned list now so we won't try to process any
4708 more events on the hapless scroll bars. */
4709 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4711 for (; ! NILP (bar
); bar
= next
)
4713 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4715 x_scroll_bar_remove (b
);
4718 b
->next
= b
->prev
= Qnil
;
4721 /* Now there should be no references to the condemned scroll bars,
4722 and they should get garbage-collected. */
4726 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4727 is set to something other than NO_EVENT, it is enqueued.
4729 This may be called from a signal handler, so we have to ignore GC
4733 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4734 struct scroll_bar
*bar
;
4735 ControlPartCode part_code
;
4737 struct input_event
*bufp
;
4739 int win_y
, top_range
;
4741 if (! GC_WINDOWP (bar
->window
))
4744 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4745 bufp
->frame_or_window
= bar
->window
;
4748 bar
->dragging
= Qnil
;
4752 case kControlUpButtonPart
:
4753 bufp
->part
= scroll_bar_up_arrow
;
4755 case kControlDownButtonPart
:
4756 bufp
->part
= scroll_bar_down_arrow
;
4758 case kControlPageUpPart
:
4759 bufp
->part
= scroll_bar_above_handle
;
4761 case kControlPageDownPart
:
4762 bufp
->part
= scroll_bar_below_handle
;
4764 #if TARGET_API_MAC_CARBON
4767 case kControlIndicatorPart
:
4769 if (er
->what
== mouseDown
)
4770 bar
->dragging
= make_number (0);
4771 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4772 bufp
->part
= scroll_bar_handle
;
4776 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
4777 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
4779 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4783 if (! NILP (bar
->dragging
))
4784 win_y
-= XINT (bar
->dragging
);
4788 if (win_y
> top_range
)
4791 XSETINT (bufp
->x
, win_y
);
4792 XSETINT (bufp
->y
, top_range
);
4795 #ifndef USE_TOOLKIT_SCROLL_BARS
4797 /* Handle some mouse motion while someone is dragging the scroll bar.
4799 This may be called from a signal handler, so we have to ignore GC
4803 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4804 struct scroll_bar
*bar
;
4808 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4810 last_mouse_movement_time
= t
;
4813 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4815 /* If we're dragging the bar, display it. */
4816 if (! GC_NILP (bar
->dragging
))
4818 /* Where should the handle be now? */
4819 int new_start
= y_pos
- 24;
4821 if (new_start
!= XINT (bar
->start
))
4823 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4825 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4830 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4832 /* Return information to the user about the current position of the mouse
4833 on the scroll bar. */
4836 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4838 Lisp_Object
*bar_window
;
4839 enum scroll_bar_part
*part
;
4841 unsigned long *time
;
4843 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4844 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4845 #if TARGET_API_MAC_CARBON
4846 WindowPtr wp
= GetControlOwner (ch
);
4848 WindowPtr wp
= (*ch
)->contrlOwner
;
4851 struct frame
*f
= mac_window_to_frame (wp
);
4852 int win_y
, top_range
;
4854 SetPortWindowPort (wp
);
4856 GetMouse (&mouse_pos
);
4858 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4859 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4861 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4865 if (! NILP (bar
->dragging
))
4866 win_y
-= XINT (bar
->dragging
);
4870 if (win_y
> top_range
)
4874 *bar_window
= bar
->window
;
4876 if (! NILP (bar
->dragging
))
4877 *part
= scroll_bar_handle
;
4878 else if (win_y
< XINT (bar
->start
))
4879 *part
= scroll_bar_above_handle
;
4880 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4881 *part
= scroll_bar_handle
;
4883 *part
= scroll_bar_below_handle
;
4885 XSETINT (*x
, win_y
);
4886 XSETINT (*y
, top_range
);
4889 last_mouse_scroll_bar
= Qnil
;
4891 *time
= last_mouse_movement_time
;
4895 /* The screen has been cleared so we may have changed foreground or
4896 background colors, and the scroll bars may need to be redrawn.
4897 Clear out the scroll bars, and ask for expose events, so we can
4901 x_scroll_bar_clear (f
)
4904 XTcondemn_scroll_bars (f
);
4905 XTjudge_scroll_bars (f
);
4909 /***********************************************************************
4911 ***********************************************************************/
4913 /* Set clipping for output in glyph row ROW. W is the window in which
4914 we operate. GC is the graphics context to set clipping in.
4916 ROW may be a text row or, e.g., a mode line. Text rows must be
4917 clipped to the interior of the window dedicated to text display,
4918 mode lines must be clipped to the whole window. */
4921 x_clip_to_row (w
, row
, area
, gc
)
4923 struct glyph_row
*row
;
4927 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4929 int window_x
, window_y
, window_width
;
4931 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
4933 clip_rect
.left
= window_x
;
4934 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4935 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4936 clip_rect
.right
= clip_rect
.left
+ window_width
;
4937 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4939 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4943 /* Draw a hollow box cursor on window W in glyph row ROW. */
4946 x_draw_hollow_cursor (w
, row
)
4948 struct glyph_row
*row
;
4950 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4951 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4952 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4955 struct glyph
*cursor_glyph
;
4958 /* Get the glyph the cursor is on. If we can't tell because
4959 the current matrix is invalid or such, give up. */
4960 cursor_glyph
= get_phys_cursor_glyph (w
);
4961 if (cursor_glyph
== NULL
)
4964 /* Compute frame-relative coordinates for phys cursor. */
4965 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4966 y
= get_phys_cursor_geometry (w
, row
, cursor_glyph
, &h
);
4967 wd
= w
->phys_cursor_width
;
4969 /* The foreground of cursor_gc is typically the same as the normal
4970 background color, which can cause the cursor box to be invisible. */
4971 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4972 if (dpyinfo
->scratch_cursor_gc
)
4973 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4975 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4976 GCForeground
, &xgcv
);
4977 gc
= dpyinfo
->scratch_cursor_gc
;
4979 /* Set clipping, draw the rectangle, and reset clipping again. */
4980 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4981 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4982 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4986 /* Draw a bar cursor on window W in glyph row ROW.
4988 Implementation note: One would like to draw a bar cursor with an
4989 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4990 Unfortunately, I didn't find a font yet that has this property set.
4994 x_draw_bar_cursor (w
, row
, width
, kind
)
4996 struct glyph_row
*row
;
4998 enum text_cursor_kinds kind
;
5000 struct frame
*f
= XFRAME (w
->frame
);
5001 struct glyph
*cursor_glyph
;
5003 /* If cursor is out of bounds, don't draw garbage. This can happen
5004 in mini-buffer windows when switching between echo area glyphs
5006 cursor_glyph
= get_phys_cursor_glyph (w
);
5007 if (cursor_glyph
== NULL
)
5010 /* If on an image, draw like a normal cursor. That's usually better
5011 visible than drawing a bar, esp. if the image is large so that
5012 the bar might not be in the window. */
5013 if (cursor_glyph
->type
== IMAGE_GLYPH
)
5015 struct glyph_row
*row
;
5016 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5017 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
5021 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5022 Window window
= FRAME_MAC_WINDOW (f
);
5023 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
5024 unsigned long mask
= GCForeground
| GCBackground
;
5025 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
5028 /* If the glyph's background equals the color we normally draw
5029 the bar cursor in, the bar cursor in its normal color is
5030 invisible. Use the glyph's foreground color instead in this
5031 case, on the assumption that the glyph's colors are chosen so
5032 that the glyph is legible. */
5033 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
5034 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
5036 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5039 XChangeGC (dpy
, gc
, mask
, &xgcv
);
5042 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
5043 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
5047 width
= FRAME_CURSOR_WIDTH (f
);
5048 width
= min (cursor_glyph
->pixel_width
, width
);
5050 w
->phys_cursor_width
= width
;
5051 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5053 if (kind
== BAR_CURSOR
)
5054 XFillRectangle (dpy
, window
, gc
,
5055 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5056 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
5057 width
, row
->height
);
5059 XFillRectangle (dpy
, window
, gc
,
5060 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5061 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
5062 row
->height
- width
),
5063 cursor_glyph
->pixel_width
,
5066 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
5071 /* RIF: Define cursor CURSOR on frame F. */
5074 mac_define_frame_cursor (f
, cursor
)
5078 SetThemeCursor (cursor
);
5082 /* RIF: Clear area on frame F. */
5085 mac_clear_frame_area (f
, x
, y
, width
, height
)
5087 int x
, y
, width
, height
;
5089 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5090 x
, y
, width
, height
, 0);
5094 /* RIF: Draw cursor on window W. */
5097 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
5099 struct glyph_row
*glyph_row
;
5101 int cursor_type
, cursor_width
;
5106 w
->phys_cursor_type
= cursor_type
;
5107 w
->phys_cursor_on_p
= 1;
5109 if (glyph_row
->exact_window_width_line_p
5110 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
5112 glyph_row
->cursor_in_fringe_p
= 1;
5113 draw_fringe_bitmap (w
, glyph_row
, 0);
5116 switch (cursor_type
)
5118 case HOLLOW_BOX_CURSOR
:
5119 x_draw_hollow_cursor (w
, glyph_row
);
5122 case FILLED_BOX_CURSOR
:
5123 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
5127 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
5131 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
5135 w
->phys_cursor_width
= 0;
5147 #if 0 /* MAC_TODO: no icon support yet. */
5149 x_bitmap_icon (f
, icon
)
5155 if (FRAME_W32_WINDOW (f
) == 0)
5159 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
5160 else if (STRINGP (icon
))
5161 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
5162 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
5163 else if (SYMBOLP (icon
))
5167 if (EQ (icon
, intern ("application")))
5168 name
= (LPCTSTR
) IDI_APPLICATION
;
5169 else if (EQ (icon
, intern ("hand")))
5170 name
= (LPCTSTR
) IDI_HAND
;
5171 else if (EQ (icon
, intern ("question")))
5172 name
= (LPCTSTR
) IDI_QUESTION
;
5173 else if (EQ (icon
, intern ("exclamation")))
5174 name
= (LPCTSTR
) IDI_EXCLAMATION
;
5175 else if (EQ (icon
, intern ("asterisk")))
5176 name
= (LPCTSTR
) IDI_ASTERISK
;
5177 else if (EQ (icon
, intern ("winlogo")))
5178 name
= (LPCTSTR
) IDI_WINLOGO
;
5182 hicon
= LoadIcon (NULL
, name
);
5190 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
5195 #endif /* MAC_TODO */
5197 /************************************************************************
5199 ************************************************************************/
5201 /* Display Error Handling functions not used on W32. Listing them here
5202 helps diff stay in step when comparing w32term.c with xterm.c.
5204 x_error_catcher (display, error)
5205 x_catch_errors (dpy)
5206 x_catch_errors_unwind (old_val)
5207 x_check_errors (dpy, format)
5208 x_had_errors_p (dpy)
5209 x_clear_errors (dpy)
5210 x_uncatch_errors (dpy, count)
5212 x_connection_signal (signalnum)
5213 x_connection_closed (dpy, error_message)
5214 x_error_quitter (display, error)
5215 x_error_handler (display, error)
5216 x_io_error_quitter (display)
5221 /* Changing the font of the frame. */
5223 /* Give frame F the font named FONTNAME as its default font, and
5224 return the full name of that font. FONTNAME may be a wildcard
5225 pattern; in that case, we choose some font that fits the pattern.
5226 The return value shows which font we chose. */
5229 x_new_font (f
, fontname
)
5231 register char *fontname
;
5233 struct font_info
*fontp
5234 = FS_LOAD_FONT (f
, 0, fontname
, -1);
5239 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
5240 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
5241 FRAME_FONTSET (f
) = -1;
5243 FRAME_COLUMN_WIDTH (f
) = fontp
->average_width
;
5244 FRAME_SPACE_WIDTH (f
) = fontp
->space_width
;
5245 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
5247 compute_fringe_widths (f
, 1);
5249 /* Compute the scroll bar width in character columns. */
5250 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
5252 int wid
= FRAME_COLUMN_WIDTH (f
);
5253 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
5254 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
5258 int wid
= FRAME_COLUMN_WIDTH (f
);
5259 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
5262 /* Now make the frame display the given font. */
5263 if (FRAME_MAC_WINDOW (f
) != 0)
5265 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
5267 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
5269 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
5272 /* Don't change the size of a tip frame; there's no point in
5273 doing it because it's done in Fx_show_tip, and it leads to
5274 problems because the tip frame has no widget. */
5275 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
5276 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
5279 return build_string (fontp
->full_name
);
5282 /* Give frame F the fontset named FONTSETNAME as its default font, and
5283 return the full name of that fontset. FONTSETNAME may be a wildcard
5284 pattern; in that case, we choose some fontset that fits the pattern.
5285 The return value shows which fontset we chose. */
5288 x_new_fontset (f
, fontsetname
)
5292 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5298 if (FRAME_FONTSET (f
) == fontset
)
5299 /* This fontset is already set in frame F. There's nothing more
5301 return fontset_name (fontset
);
5303 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5305 if (!STRINGP (result
))
5306 /* Can't load ASCII font. */
5309 /* Since x_new_font doesn't update any fontset information, do it now. */
5310 FRAME_FONTSET (f
) = fontset
;
5312 return build_string (fontsetname
);
5316 /***********************************************************************
5317 TODO: W32 Input Methods
5318 ***********************************************************************/
5319 /* Listing missing functions from xterm.c helps diff stay in step.
5321 xim_destroy_callback (xim, client_data, call_data)
5322 xim_open_dpy (dpyinfo, resource_name)
5324 xim_instantiate_callback (display, client_data, call_data)
5325 xim_initialize (dpyinfo, resource_name)
5326 xim_close_dpy (dpyinfo)
5332 mac_get_window_bounds (f
, inner
, outer
)
5334 Rect
*inner
, *outer
;
5336 #if TARGET_API_MAC_CARBON
5337 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5338 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5339 #else /* not TARGET_API_MAC_CARBON */
5340 RgnHandle region
= NewRgn ();
5342 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5343 *inner
= (*region
)->rgnBBox
;
5344 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5345 *outer
= (*region
)->rgnBBox
;
5346 DisposeRgn (region
);
5347 #endif /* not TARGET_API_MAC_CARBON */
5352 /* Calculate the absolute position in frame F
5353 from its current recorded position values and gravity. */
5356 x_calc_absolute_position (f
)
5359 int width_diff
= 0, height_diff
= 0;
5360 int flags
= f
->size_hint_flags
;
5363 /* We have nothing to do if the current position
5364 is already for the top-left corner. */
5365 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5368 /* Find the offsets of the outside upper-left corner of
5369 the inner window, with respect to the outer window. */
5370 mac_get_window_bounds (f
, &inner
, &outer
);
5372 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5373 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5375 /* Treat negative positions as relative to the leftmost bottommost
5376 position that fits on the screen. */
5377 if (flags
& XNegative
)
5378 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5380 - FRAME_PIXEL_WIDTH (f
)
5383 if (flags
& YNegative
)
5384 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5386 - FRAME_PIXEL_HEIGHT (f
)
5389 /* The left_pos and top_pos
5390 are now relative to the top and left screen edges,
5391 so the flags should correspond. */
5392 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5395 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5396 to really change the position, and 0 when calling from
5397 x_make_frame_visible (in that case, XOFF and YOFF are the current
5398 position values). It is -1 when calling from x_set_frame_parameters,
5399 which means, do adjust for borders but don't change the gravity. */
5402 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5404 register int xoff
, yoff
;
5407 if (change_gravity
> 0)
5411 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5413 f
->size_hint_flags
|= XNegative
;
5415 f
->size_hint_flags
|= YNegative
;
5416 f
->win_gravity
= NorthWestGravity
;
5418 x_calc_absolute_position (f
);
5421 x_wm_set_size_hint (f
, (long) 0, 0);
5423 #if TARGET_API_MAC_CARBON
5424 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5425 /* If the title bar is completely outside the screen, adjust the
5427 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5428 kWindowConstrainMoveRegardlessOfFit
5429 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5430 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5433 Rect inner
, outer
, screen_rect
, dummy
;
5434 RgnHandle region
= NewRgn ();
5436 mac_get_window_bounds (f
, &inner
, &outer
);
5437 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5438 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5439 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5440 f
->top_pos
+ f
->y_pixels_diff
, false);
5442 /* If the title bar is completely outside the screen, adjust the
5443 position. The variable `outer' holds the title bar rectangle.
5444 The variable `inner' holds slightly smaller one than `outer',
5445 so that the calculation of overlapping may not become too
5447 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5448 outer
= (*region
)->rgnBBox
;
5449 DisposeRgn (region
);
5451 InsetRect (&inner
, 8, 8);
5452 screen_rect
= qd
.screenBits
.bounds
;
5453 screen_rect
.top
+= GetMBarHeight ();
5455 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5457 if (inner
.right
<= screen_rect
.left
)
5458 f
->left_pos
= screen_rect
.left
;
5459 else if (inner
.left
>= screen_rect
.right
)
5460 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5462 if (inner
.bottom
<= screen_rect
.top
)
5463 f
->top_pos
= screen_rect
.top
;
5464 else if (inner
.top
>= screen_rect
.bottom
)
5465 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5467 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5468 f
->top_pos
+ f
->y_pixels_diff
, false);
5476 /* Call this to change the size of frame F's x-window.
5477 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5478 for this size change and subsequent size changes.
5479 Otherwise we leave the window gravity unchanged. */
5482 x_set_window_size (f
, change_gravity
, cols
, rows
)
5487 int pixelwidth
, pixelheight
;
5491 check_frame_size (f
, &rows
, &cols
);
5492 f
->scroll_bar_actual_width
5493 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5495 compute_fringe_widths (f
, 0);
5497 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5498 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5500 f
->win_gravity
= NorthWestGravity
;
5501 x_wm_set_size_hint (f
, (long) 0, 0);
5503 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5504 #if TARGET_API_MAC_CARBON
5505 if (f
->output_data
.mac
->hourglass_control
)
5506 MoveControl (f
->output_data
.mac
->hourglass_control
,
5507 pixelwidth
- HOURGLASS_WIDTH
, 0);
5510 /* Now, strictly speaking, we can't be sure that this is accurate,
5511 but the window manager will get around to dealing with the size
5512 change request eventually, and we'll hear how it went when the
5513 ConfigureNotify event gets here.
5515 We could just not bother storing any of this information here,
5516 and let the ConfigureNotify event set everything up, but that
5517 might be kind of confusing to the Lisp code, since size changes
5518 wouldn't be reported in the frame parameters until some random
5519 point in the future when the ConfigureNotify event arrives.
5521 We pass 1 for DELAY since we can't run Lisp code inside of
5523 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5524 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5525 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5527 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5528 receive in the ConfigureNotify event; if we get what we asked
5529 for, then the event won't cause the screen to become garbaged, so
5530 we have to make sure to do it here. */
5531 SET_FRAME_GARBAGED (f
);
5533 XFlush (FRAME_X_DISPLAY (f
));
5535 /* If cursor was outside the new size, mark it as off. */
5536 mark_window_cursors_off (XWINDOW (f
->root_window
));
5538 /* Clear out any recollection of where the mouse highlighting was,
5539 since it might be in a place that's outside the new frame size.
5540 Actually checking whether it is outside is a pain in the neck,
5541 so don't try--just let the highlighting be done afresh with new size. */
5542 cancel_mouse_face (f
);
5547 /* Mouse warping. */
5549 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5552 x_set_mouse_position (f
, x
, y
)
5558 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5559 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5561 if (pix_x
< 0) pix_x
= 0;
5562 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5564 if (pix_y
< 0) pix_y
= 0;
5565 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5567 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5571 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5575 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5578 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5579 0, 0, 0, 0, pix_x
, pix_y
);
5584 /* focus shifting, raising and lowering. */
5587 x_focus_on_frame (f
)
5590 #if 0 /* This proves to be unpleasant. */
5594 /* I don't think that the ICCCM allows programs to do things like this
5595 without the interaction of the window manager. Whatever you end up
5596 doing with this code, do it to x_unfocus_frame too. */
5597 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5598 RevertToPointerRoot
, CurrentTime
);
5608 /* Raise frame F. */
5614 if (f
->async_visible
)
5617 SelectWindow (FRAME_MAC_WINDOW (f
));
5622 /* Lower frame F. */
5628 if (f
->async_visible
)
5631 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5637 XTframe_raise_lower (f
, raise_flag
)
5647 /* Change of visibility. */
5649 /* This tries to wait until the frame is really visible.
5650 However, if the window manager asks the user where to position
5651 the frame, this will return before the user finishes doing that.
5652 The frame will not actually be visible at that time,
5653 but it will become visible later when the window manager
5654 finishes with it. */
5657 x_make_frame_visible (f
)
5661 int original_top
, original_left
;
5665 if (! FRAME_VISIBLE_P (f
))
5667 /* We test FRAME_GARBAGED_P here to make sure we don't
5668 call x_set_offset a second time
5669 if we get to x_make_frame_visible a second time
5670 before the window gets really visible. */
5671 if (! FRAME_ICONIFIED_P (f
)
5672 && ! f
->output_data
.mac
->asked_for_visible
)
5673 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5675 f
->output_data
.mac
->asked_for_visible
= 1;
5677 #if TARGET_API_MAC_CARBON
5678 if (!(FRAME_SIZE_HINTS (f
)->flags
& (USPosition
| PPosition
)))
5680 struct frame
*sf
= SELECTED_FRAME ();
5681 if (!FRAME_MAC_P (sf
))
5682 RepositionWindow (FRAME_MAC_WINDOW (f
), NULL
,
5683 kWindowCenterOnMainScreen
);
5685 RepositionWindow (FRAME_MAC_WINDOW (f
),
5686 FRAME_MAC_WINDOW (sf
),
5687 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
5688 kWindowCascadeStartAtParentWindowScreen
5690 kWindowCascadeOnParentWindowScreen
5693 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5696 ShowWindow (FRAME_MAC_WINDOW (f
));
5699 XFlush (FRAME_MAC_DISPLAY (f
));
5701 /* Synchronize to ensure Emacs knows the frame is visible
5702 before we do anything else. We do this loop with input not blocked
5703 so that incoming events are handled. */
5708 /* This must come after we set COUNT. */
5711 XSETFRAME (frame
, f
);
5713 /* Wait until the frame is visible. Process X events until a
5714 MapNotify event has been seen, or until we think we won't get a
5715 MapNotify at all.. */
5716 for (count
= input_signal_count
+ 10;
5717 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5719 /* Force processing of queued events. */
5722 /* Machines that do polling rather than SIGIO have been
5723 observed to go into a busy-wait here. So we'll fake an
5724 alarm signal to let the handler know that there's something
5725 to be read. We used to raise a real alarm, but it seems
5726 that the handler isn't always enabled here. This is
5728 if (input_polling_used ())
5730 /* It could be confusing if a real alarm arrives while
5731 processing the fake one. Turn it off and let the
5732 handler reset it. */
5733 extern void poll_for_input_1
P_ ((void));
5734 int old_poll_suppress_count
= poll_suppress_count
;
5735 poll_suppress_count
= 1;
5736 poll_for_input_1 ();
5737 poll_suppress_count
= old_poll_suppress_count
;
5740 /* See if a MapNotify event has been processed. */
5741 FRAME_SAMPLE_VISIBILITY (f
);
5746 /* Change from mapped state to withdrawn state. */
5748 /* Make the frame visible (mapped and not iconified). */
5751 x_make_frame_invisible (f
)
5754 /* Don't keep the highlight on an invisible frame. */
5755 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5756 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5760 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
5761 that the current position of the window is user-specified, rather than
5762 program-specified, so that when the window is mapped again, it will be
5763 placed at the same location, without forcing the user to position it
5764 by hand again (they have already done that once for this window.) */
5765 x_wm_set_size_hint (f
, (long) 0, 1);
5767 HideWindow (FRAME_MAC_WINDOW (f
));
5769 /* We can't distinguish this from iconification
5770 just by the event that we get from the server.
5771 So we can't win using the usual strategy of letting
5772 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5773 and synchronize with the server to make sure we agree. */
5775 FRAME_ICONIFIED_P (f
) = 0;
5776 f
->async_visible
= 0;
5777 f
->async_iconified
= 0;
5782 /* Change window state from mapped to iconified. */
5788 /* Don't keep the highlight on an invisible frame. */
5789 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5790 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5793 /* Review: Since window is still visible in dock, still allow updates? */
5794 if (f
->async_iconified
)
5800 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5806 /* Free X resources of frame F. */
5809 x_free_frame_resources (f
)
5812 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5813 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5817 if (wp
!= tip_window
)
5818 remove_window_handler (wp
);
5821 if (wp
== tip_window
)
5822 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5823 closed' event. So we reset tip_window here. */
5826 free_frame_menubar (f
);
5828 if (FRAME_FACE_CACHE (f
))
5829 free_frame_faces (f
);
5833 if (FRAME_SIZE_HINTS (f
))
5834 xfree (FRAME_SIZE_HINTS (f
));
5836 xfree (f
->output_data
.mac
);
5837 f
->output_data
.mac
= NULL
;
5839 if (f
== dpyinfo
->x_focus_frame
)
5840 dpyinfo
->x_focus_frame
= 0;
5841 if (f
== dpyinfo
->x_focus_event_frame
)
5842 dpyinfo
->x_focus_event_frame
= 0;
5843 if (f
== dpyinfo
->x_highlight_frame
)
5844 dpyinfo
->x_highlight_frame
= 0;
5846 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5848 dpyinfo
->mouse_face_beg_row
5849 = dpyinfo
->mouse_face_beg_col
= -1;
5850 dpyinfo
->mouse_face_end_row
5851 = dpyinfo
->mouse_face_end_col
= -1;
5852 dpyinfo
->mouse_face_window
= Qnil
;
5853 dpyinfo
->mouse_face_deferred_gc
= 0;
5854 dpyinfo
->mouse_face_mouse_frame
= 0;
5861 /* Destroy the X window of frame F. */
5864 x_destroy_window (f
)
5867 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5869 x_free_frame_resources (f
);
5871 dpyinfo
->reference_count
--;
5875 /* Setting window manager hints. */
5877 /* Set the normal size hints for the window manager, for frame F.
5878 FLAGS is the flags word to use--or 0 meaning preserve the flags
5879 that the window now has.
5880 If USER_POSITION is nonzero, we set the USPosition
5881 flag (this is useful when FLAGS is 0). */
5883 x_wm_set_size_hint (f
, flags
, user_position
)
5888 int base_width
, base_height
, width_inc
, height_inc
;
5889 int min_rows
= 0, min_cols
= 0;
5890 XSizeHints
*size_hints
;
5892 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5893 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5894 width_inc
= FRAME_COLUMN_WIDTH (f
);
5895 height_inc
= FRAME_LINE_HEIGHT (f
);
5897 check_frame_size (f
, &min_rows
, &min_cols
);
5899 size_hints
= FRAME_SIZE_HINTS (f
);
5900 if (size_hints
== NULL
)
5902 size_hints
= FRAME_SIZE_HINTS (f
) = xmalloc (sizeof (XSizeHints
));
5903 bzero (size_hints
, sizeof (XSizeHints
));
5906 size_hints
->flags
|= PResizeInc
| PMinSize
| PBaseSize
;
5907 size_hints
->width_inc
= width_inc
;
5908 size_hints
->height_inc
= height_inc
;
5909 size_hints
->min_width
= base_width
+ min_cols
* width_inc
;
5910 size_hints
->min_height
= base_height
+ min_rows
* height_inc
;
5911 size_hints
->base_width
= base_width
;
5912 size_hints
->base_height
= base_height
;
5915 size_hints
->flags
= flags
;
5916 else if (user_position
)
5918 size_hints
->flags
&= ~ PPosition
;
5919 size_hints
->flags
|= USPosition
;
5923 #if 0 /* MAC_TODO: hide application instead of iconify? */
5924 /* Used for IconicState or NormalState */
5927 x_wm_set_window_state (f
, state
)
5931 #ifdef USE_X_TOOLKIT
5934 XtSetArg (al
[0], XtNinitialState
, state
);
5935 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5936 #else /* not USE_X_TOOLKIT */
5937 Window window
= FRAME_X_WINDOW (f
);
5939 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5940 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5942 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5943 #endif /* not USE_X_TOOLKIT */
5947 x_wm_set_icon_pixmap (f
, pixmap_id
)
5953 #ifndef USE_X_TOOLKIT
5954 Window window
= FRAME_X_WINDOW (f
);
5959 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5960 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5964 /* It seems there is no way to turn off use of an icon pixmap.
5965 The following line does it, only if no icon has yet been created,
5966 for some window managers. But with mwm it crashes.
5967 Some people say it should clear the IconPixmapHint bit in this case,
5968 but that doesn't work, and the X consortium said it isn't the
5969 right thing at all. Since there is no way to win,
5970 best to explicitly give up. */
5972 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5978 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5982 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5983 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5986 #else /* not USE_X_TOOLKIT */
5988 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5989 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5991 #endif /* not USE_X_TOOLKIT */
5994 #endif /* MAC_TODO */
5997 x_wm_set_icon_position (f
, icon_x
, icon_y
)
6001 #if 0 /* MAC_TODO: no icons on Mac */
6002 #ifdef USE_X_TOOLKIT
6003 Window window
= XtWindow (f
->output_data
.x
->widget
);
6005 Window window
= FRAME_X_WINDOW (f
);
6008 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
6009 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
6010 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
6012 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6013 #endif /* MAC_TODO */
6017 /***********************************************************************
6019 ***********************************************************************/
6021 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6024 x_get_font_info (f
, font_idx
)
6028 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
6031 /* the global font name table */
6032 static char **font_name_table
= NULL
;
6033 static int font_name_table_size
= 0;
6034 static int font_name_count
= 0;
6036 /* Alist linking character set strings to Mac text encoding and Emacs
6038 static Lisp_Object Vmac_charset_info_alist
;
6041 create_text_encoding_info_alist ()
6043 Lisp_Object result
= Qnil
, rest
;
6045 for (rest
= Vmac_charset_info_alist
; CONSP (rest
); rest
= XCDR (rest
))
6047 Lisp_Object charset_info
= XCAR (rest
);
6048 Lisp_Object charset
, coding_system
, text_encoding
;
6049 Lisp_Object existing_info
;
6051 if (!(CONSP (charset_info
)
6052 && STRINGP (charset
= XCAR (charset_info
))
6053 && CONSP (XCDR (charset_info
))
6054 && INTEGERP (text_encoding
= XCAR (XCDR (charset_info
)))
6055 && CONSP (XCDR (XCDR (charset_info
)))
6056 && SYMBOLP (coding_system
= XCAR (XCDR (XCDR (charset_info
))))))
6059 existing_info
= assq_no_quit (text_encoding
, result
);
6060 if (NILP (existing_info
))
6061 result
= Fcons (list3 (text_encoding
, coding_system
, charset
),
6064 if (NILP (Fmember (charset
, XCDR (XCDR (existing_info
)))))
6065 XSETCDR (XCDR (existing_info
),
6066 Fcons (charset
, XCDR (XCDR (existing_info
))));
6074 decode_mac_font_name (name
, size
, coding_system
)
6077 Lisp_Object coding_system
;
6079 struct coding_system coding
;
6082 for (p
= name
; *p
; p
++)
6083 if (!isascii (*p
) || iscntrl (*p
))
6087 || NILP (coding_system
) || NILP (Fcoding_system_p (coding_system
)))
6090 setup_coding_system (coding_system
, &coding
);
6091 coding
.src_multibyte
= 0;
6092 coding
.dst_multibyte
= 1;
6093 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6094 coding
.composing
= COMPOSITION_DISABLED
;
6095 buf
= (char *) alloca (size
);
6097 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
6098 bcopy (buf
, name
, coding
.produced
);
6099 name
[coding
.produced
] = '\0';
6104 mac_to_x_fontname (name
, size
, style
, charset
)
6112 char xf
[256], *result
, *p
;
6114 if (sscanf (name
, "%31[^-]-%255[^-]-%31s", foundry
, family
, cs
) == 3)
6118 strcpy(foundry
, "Apple");
6119 strcpy(family
, name
);
6122 sprintf (xf
, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
6123 style
& bold
? "bold" : "medium", style
& italic
? 'i' : 'r',
6124 size
, size
* 10, size
? 75 : 0, size
? 75 : 0, size
* 10, charset
);
6126 result
= xmalloc (strlen (foundry
) + strlen (family
) + strlen (xf
) + 3 + 1);
6127 sprintf (result
, "-%s-%s-%s", foundry
, family
, xf
);
6128 for (p
= result
; *p
; p
++)
6134 /* Convert an X font spec to the corresponding mac font name, which
6135 can then be passed to GetFNum after conversion to a Pascal string.
6136 For ordinary Mac fonts, this should just be their names, like
6137 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
6138 collection contain their charset designation in their names, like
6139 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
6140 names are handled accordingly. */
6142 x_font_name_to_mac_font_name (xf
, mf
, mf_decoded
, style
, cs
)
6143 char *xf
, *mf
, *mf_decoded
;
6149 char weight
[20], slant
[2], *p
;
6150 Lisp_Object charset_info
, coding_system
= Qnil
;
6151 struct coding_system coding
;
6155 if (sscanf (xf
, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6156 foundry
, family
, weight
, slant
, cs
) != 5 &&
6157 sscanf (xf
, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6158 foundry
, family
, weight
, slant
, cs
) != 5)
6162 if (strcmp (weight
, "bold") == 0)
6167 charset_info
= Fassoc (build_string (cs
), Vmac_charset_info_alist
);
6168 if (!NILP (charset_info
))
6170 strcpy (mf_decoded
, family
);
6171 coding_system
= Fcar (Fcdr (Fcdr (charset_info
)));
6174 sprintf (mf_decoded
, "%s-%s-%s", foundry
, family
, cs
);
6176 for (p
= mf_decoded
; *p
; p
++)
6177 if (!isascii (*p
) || iscntrl (*p
))
6181 || NILP (coding_system
) || NILP (Fcoding_system_p (coding_system
)))
6182 strcpy (mf
, mf_decoded
);
6185 setup_coding_system (coding_system
, &coding
);
6186 coding
.src_multibyte
= 1;
6187 coding
.dst_multibyte
= 1;
6188 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6189 encode_coding (&coding
, mf_decoded
, mf
,
6190 strlen (mf_decoded
), sizeof (Str255
) - 1);
6191 mf
[coding
.produced
] = '\0';
6197 add_font_name_table_entry (char *font_name
)
6199 if (font_name_table_size
== 0)
6201 font_name_table_size
= 16;
6202 font_name_table
= (char **)
6203 xmalloc (font_name_table_size
* sizeof (char *));
6205 else if (font_name_count
+ 1 >= font_name_table_size
)
6207 font_name_table_size
+= 16;
6208 font_name_table
= (char **)
6209 xrealloc (font_name_table
,
6210 font_name_table_size
* sizeof (char *));
6213 font_name_table
[font_name_count
++] = font_name
;
6216 /* Sets up the table font_name_table to contain the list of all fonts
6217 in the system the first time the table is used so that the Resource
6218 Manager need not be accessed every time this information is
6222 init_font_name_table ()
6224 #if TARGET_API_MAC_CARBON
6225 FMFontFamilyIterator ffi
;
6226 FMFontFamilyInstanceIterator ffii
;
6228 Lisp_Object text_encoding_info_alist
;
6229 struct gcpro gcpro1
;
6231 /* Create a dummy instance iterator here to avoid creating and
6232 destroying it in the loop. */
6233 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6235 /* Create an iterator to enumerate the font families. */
6236 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6239 FMDisposeFontFamilyInstanceIterator (&ffii
);
6243 text_encoding_info_alist
= create_text_encoding_info_alist ();
6245 GCPRO1 (text_encoding_info_alist
);
6247 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6253 TextEncoding encoding
;
6254 TextEncodingBase sc
;
6255 Lisp_Object text_encoding_info
;
6257 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6263 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
6265 sc
= GetTextEncodingBase (encoding
);
6266 text_encoding_info
= assq_no_quit (make_number (sc
),
6267 text_encoding_info_alist
);
6268 if (!NILP (text_encoding_info
))
6269 decode_mac_font_name (name
, sizeof (name
),
6270 XCAR (XCDR (text_encoding_info
)));
6272 text_encoding_info
= assq_no_quit (make_number (kTextEncodingMacRoman
),
6273 text_encoding_info_alist
);
6275 /* Point the instance iterator at the current font family. */
6276 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6279 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6282 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
6284 for (; !NILP (rest
); rest
= XCDR (rest
))
6286 char *cs
= SDATA (XCAR (rest
));
6290 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6292 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6294 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6296 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6302 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6311 /* Dispose of the iterators. */
6312 FMDisposeFontFamilyIterator (&ffi
);
6313 FMDisposeFontFamilyInstanceIterator (&ffii
);
6314 #else /* !TARGET_API_MAC_CARBON */
6316 SInt16 fontnum
, old_fontnum
;
6317 int num_mac_fonts
= CountResources('FOND');
6319 Handle font_handle
, font_handle_2
;
6320 short id
, scriptcode
;
6323 struct FontAssoc
*fat
;
6324 struct AsscEntry
*assc_entry
;
6325 Lisp_Object text_encoding_info_alist
, text_encoding_info
;
6326 struct gcpro gcpro1
;
6328 GetPort (&port
); /* save the current font number used */
6329 old_fontnum
= port
->txFont
;
6331 text_encoding_info_alist
= create_text_encoding_info_alist ();
6333 GCPRO1 (text_encoding_info_alist
);
6335 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6337 font_handle
= GetIndResource ('FOND', i
);
6341 GetResInfo (font_handle
, &id
, &type
, name
);
6342 GetFNum (name
, &fontnum
);
6348 scriptcode
= FontToScript (fontnum
);
6349 text_encoding_info
= assq_no_quit (make_number (scriptcode
),
6350 text_encoding_info_alist
);
6351 if (!NILP (text_encoding_info
))
6352 decode_mac_font_name (name
, sizeof (name
),
6353 XCAR (XCDR (text_encoding_info
)));
6355 text_encoding_info
= assq_no_quit (make_number (smRoman
),
6356 text_encoding_info_alist
);
6359 HLock (font_handle
);
6361 if (GetResourceSizeOnDisk (font_handle
)
6362 >= sizeof (struct FamRec
))
6364 fat
= (struct FontAssoc
*) (*font_handle
6365 + sizeof (struct FamRec
));
6367 = (struct AsscEntry
*) (*font_handle
6368 + sizeof (struct FamRec
)
6369 + sizeof (struct FontAssoc
));
6371 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6373 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
6375 for (; !NILP (rest
); rest
= XCDR (rest
))
6377 char *cs
= SDATA (XCAR (rest
));
6379 add_font_name_table_entry (mac_to_x_fontname (name
,
6380 assc_entry
->fontSize
,
6381 assc_entry
->fontStyle
,
6387 HUnlock (font_handle
);
6388 font_handle_2
= GetNextFOND (font_handle
);
6389 ReleaseResource (font_handle
);
6390 font_handle
= font_handle_2
;
6392 while (ResError () == noErr
&& font_handle
);
6397 TextFont (old_fontnum
);
6398 #endif /* !TARGET_API_MAC_CARBON */
6403 mac_clear_font_name_table ()
6407 for (i
= 0; i
< font_name_count
; i
++)
6408 xfree (font_name_table
[i
]);
6409 xfree (font_name_table
);
6410 font_name_table
= NULL
;
6411 font_name_table_size
= font_name_count
= 0;
6415 enum xlfd_scalable_field_index
6417 XLFD_SCL_PIXEL_SIZE
,
6418 XLFD_SCL_POINT_SIZE
,
6423 static int xlfd_scalable_fields
[] =
6432 mac_c_string_match (regexp
, string
, nonspecial
, exact
)
6434 const char *string
, *nonspecial
;
6439 if (strcmp (string
, nonspecial
) == 0)
6440 return build_string (string
);
6442 else if (strstr (string
, nonspecial
))
6444 Lisp_Object str
= build_string (string
);
6446 if (fast_string_match (regexp
, str
) >= 0)
6454 mac_do_list_fonts (pattern
, maxnames
)
6459 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6460 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6462 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6463 char *longest_start
, *cur_start
, *nonspecial
;
6464 int longest_len
, exact
;
6466 if (font_name_table
== NULL
) /* Initialize when first used. */
6467 init_font_name_table ();
6469 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6472 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6473 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6474 fonts are scaled according to the specified size. */
6477 field
= xlfd_scalable_fields
;
6485 if ('0' <= *ptr
&& *ptr
<= '9')
6487 *val
= *ptr
++ - '0';
6488 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6489 *val
= *val
* 10 + *ptr
++ - '0';
6496 ptr
= strchr (ptr
, '-');
6499 while (ptr
&& i
< 14);
6501 if (i
== 14 && ptr
== NULL
)
6503 if (scl_val
[XLFD_SCL_PIXEL_SIZE
] < 0)
6504 scl_val
[XLFD_SCL_PIXEL_SIZE
] =
6505 (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
] / 10
6506 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
] / 10
6508 if (scl_val
[XLFD_SCL_POINT_SIZE
] < 0)
6509 scl_val
[XLFD_SCL_POINT_SIZE
] =
6510 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
6511 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
]
6513 if (scl_val
[XLFD_SCL_AVGWIDTH
] < 0)
6514 scl_val
[XLFD_SCL_AVGWIDTH
] =
6515 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
6516 : (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
]
6520 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6525 longest_start
= cur_start
= ptr
;
6529 /* Turn pattern into a regexp and do a regexp match. Also find the
6530 longest substring containing no special characters. */
6531 for (; *pattern
; pattern
++)
6533 if (*pattern
== '?' || *pattern
== '*')
6535 if (ptr
- cur_start
> longest_len
)
6537 longest_start
= cur_start
;
6538 longest_len
= ptr
- cur_start
;
6542 if (*pattern
== '?')
6544 else /* if (*pattern == '*') */
6552 *ptr
++ = tolower (*pattern
);
6555 if (ptr
- cur_start
> longest_len
)
6557 longest_start
= cur_start
;
6558 longest_len
= ptr
- cur_start
;
6564 nonspecial
= xmalloc (longest_len
+ 1);
6565 strncpy (nonspecial
, longest_start
, longest_len
);
6566 nonspecial
[longest_len
] = '\0';
6568 pattern_regex
= build_string (regex
);
6570 for (i
= 0; i
< font_name_count
; i
++)
6572 fontname
= mac_c_string_match (pattern_regex
, font_name_table
[i
],
6574 if (!NILP (fontname
))
6576 font_list
= Fcons (fontname
, font_list
);
6577 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
6580 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6581 && (ptr
= strstr (font_name_table
[i
], "-0-0-0-0-m-0-")))
6583 int former_len
= ptr
- font_name_table
[i
];
6585 scaled
= xmalloc (strlen (font_name_table
[i
]) + 20 + 1);
6586 memcpy (scaled
, font_name_table
[i
], former_len
);
6587 sprintf (scaled
+ former_len
,
6588 "-%d-%d-75-75-m-%d-%s",
6589 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6590 scl_val
[XLFD_SCL_POINT_SIZE
],
6591 scl_val
[XLFD_SCL_AVGWIDTH
],
6592 ptr
+ sizeof ("-0-0-0-0-m-0-") - 1);
6593 fontname
= mac_c_string_match (pattern_regex
, scaled
,
6596 if (!NILP (fontname
))
6598 font_list
= Fcons (fontname
, font_list
);
6599 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
6610 /* Return a list of names of available fonts matching PATTERN on frame F.
6612 Frame F null means we have not yet created any frame on Mac, and
6613 consult the first display in x_display_list. MAXNAMES sets a limit
6614 on how many fonts to match. */
6617 x_list_fonts (f
, pattern
, size
, maxnames
)
6619 Lisp_Object pattern
;
6622 Lisp_Object list
= Qnil
, patterns
, tem
, key
;
6623 struct mac_display_info
*dpyinfo
6624 = f
? FRAME_MAC_DISPLAY_INFO (f
) : x_display_list
;
6626 xassert (size
<= 0);
6628 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
6629 if (NILP (patterns
))
6630 patterns
= Fcons (pattern
, Qnil
);
6632 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
6634 pattern
= XCAR (patterns
);
6636 if (!STRINGP (pattern
))
6639 tem
= XCAR (XCDR (dpyinfo
->name_list_element
));
6640 key
= Fcons (pattern
, make_number (maxnames
));
6642 list
= Fassoc (key
, tem
);
6645 list
= Fcdr_safe (list
);
6646 /* We have a cashed list. Don't have to get the list again. */
6651 list
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6654 /* MAC_TODO: add code for matching outline fonts here */
6656 /* Now store the result in the cache. */
6657 XSETCAR (XCDR (dpyinfo
->name_list_element
),
6658 Fcons (Fcons (key
, list
),
6659 XCAR (XCDR (dpyinfo
->name_list_element
))));
6662 if (NILP (list
)) continue; /* Try the remaining alternatives. */
6671 /* Check that FONT is valid on frame F. It is if it can be found in F's
6675 x_check_font (f
, font
)
6680 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6682 xassert (font
!= NULL
);
6684 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6685 if (dpyinfo
->font_table
[i
].name
6686 && font
== dpyinfo
->font_table
[i
].font
)
6689 xassert (i
< dpyinfo
->n_fonts
);
6692 #endif /* GLYPH_DEBUG != 0 */
6694 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6695 Note: There are (broken) X fonts out there with invalid XFontStruct
6696 min_bounds contents. For example, handa@etl.go.jp reports that
6697 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6698 have font->min_bounds.width == 0. */
6701 x_font_min_bounds (font
, w
, h
)
6702 MacFontStruct
*font
;
6705 *h
= FONT_HEIGHT (font
);
6706 *w
= font
->min_bounds
.width
;
6710 /* Compute the smallest character width and smallest font height over
6711 all fonts available on frame F. Set the members smallest_char_width
6712 and smallest_font_height in F's x_display_info structure to
6713 the values computed. Value is non-zero if smallest_font_height or
6714 smallest_char_width become smaller than they were before. */
6717 x_compute_min_glyph_bounds (f
)
6721 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6722 MacFontStruct
*font
;
6723 int old_width
= dpyinfo
->smallest_char_width
;
6724 int old_height
= dpyinfo
->smallest_font_height
;
6726 dpyinfo
->smallest_font_height
= 100000;
6727 dpyinfo
->smallest_char_width
= 100000;
6729 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6730 if (dpyinfo
->font_table
[i
].name
)
6732 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6735 font
= (MacFontStruct
*) fontp
->font
;
6736 xassert (font
!= (MacFontStruct
*) ~0);
6737 x_font_min_bounds (font
, &w
, &h
);
6739 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6740 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6743 xassert (dpyinfo
->smallest_char_width
> 0
6744 && dpyinfo
->smallest_font_height
> 0);
6746 return (dpyinfo
->n_fonts
== 1
6747 || dpyinfo
->smallest_char_width
< old_width
6748 || dpyinfo
->smallest_font_height
< old_height
);
6752 /* Determine whether given string is a fully-specified XLFD: all 14
6753 fields are present, none is '*'. */
6756 is_fully_specified_xlfd (char *p
)
6764 for (i
= 0; i
< 13; i
++)
6766 q
= strchr (p
+ 1, '-');
6769 if (q
- p
== 2 && *(p
+ 1) == '*')
6774 if (strchr (p
+ 1, '-') != NULL
)
6777 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6784 const int kDefaultFontSize
= 12;
6787 /* XLoadQueryFont creates and returns an internal representation for a
6788 font in a MacFontStruct struct. There is really no concept
6789 corresponding to "loading" a font on the Mac. But we check its
6790 existence and find the font number and all other information for it
6791 and store them in the returned MacFontStruct. */
6793 static MacFontStruct
*
6794 XLoadQueryFont (Display
*dpy
, char *fontname
)
6796 int i
, size
, point_size
, avgwidth
, is_two_byte_font
, char_width
;
6799 SInt16 old_fontnum
, old_fontsize
;
6801 Str255 mfontname
, mfontname_decoded
;
6805 #if TARGET_API_MAC_CARBON
6806 TextEncoding encoding
;
6811 MacFontStruct
*font
;
6812 FontInfo the_fontinfo
;
6814 UInt32 old_flags
, new_flags
;
6817 if (is_fully_specified_xlfd (fontname
))
6821 Lisp_Object matched_fonts
;
6823 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6824 if (NILP (matched_fonts
))
6826 name
= SDATA (XCAR (matched_fonts
));
6829 GetPort (&port
); /* save the current font number used */
6830 #if TARGET_API_MAC_CARBON
6831 old_fontnum
= GetPortTextFont (port
);
6832 old_fontsize
= GetPortTextSize (port
);
6833 old_fontface
= GetPortTextFace (port
);
6835 old_fontnum
= port
->txFont
;
6836 old_fontsize
= port
->txSize
;
6837 old_fontface
= port
->txFace
;
6840 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%*s", &size
, &point_size
, &avgwidth
) != 3)
6846 size
= point_size
/ 10;
6847 else if (avgwidth
> 0)
6848 size
= avgwidth
/ 10;
6851 size
= kDefaultFontSize
;
6853 x_font_name_to_mac_font_name (name
, mfontname
, mfontname_decoded
,
6854 &fontface
, charset
);
6856 #if TARGET_API_MAC_CARBON
6857 fontnum
= FMGetFontFamilyFromName (mfontname
);
6858 if (fontnum
== kInvalidFontFamily
6859 || FMGetFontFamilyTextEncoding (fontnum
, &encoding
) != noErr
)
6861 scriptcode
= GetTextEncodingBase (encoding
);
6863 GetFNum (mfontname
, &fontnum
);
6866 scriptcode
= FontToScript (fontnum
);
6869 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6871 font
->mac_fontnum
= fontnum
;
6872 font
->mac_fontsize
= size
;
6873 font
->mac_fontface
= fontface
;
6874 font
->mac_scriptcode
= scriptcode
;
6876 /* Apple Japanese (SJIS) font is listed as both
6877 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6878 (Roman script) in init_font_name_table (). The latter should be
6879 treated as a one-byte font. */
6880 if (scriptcode
== smJapanese
&& strcmp (charset
, "jisx0201.1976-0") == 0)
6881 font
->mac_scriptcode
= smRoman
;
6883 font
->full_name
= mac_to_x_fontname (mfontname_decoded
, size
, fontface
, charset
);
6885 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6886 font
->mac_scriptcode
== smTradChinese
||
6887 font
->mac_scriptcode
== smSimpChinese
||
6888 font
->mac_scriptcode
== smKorean
;
6892 TextFace (fontface
);
6894 GetFontInfo (&the_fontinfo
);
6896 font
->ascent
= the_fontinfo
.ascent
;
6897 font
->descent
= the_fontinfo
.descent
;
6899 font
->min_byte1
= 0;
6900 if (is_two_byte_font
)
6901 font
->max_byte1
= 1;
6903 font
->max_byte1
= 0;
6904 font
->min_char_or_byte2
= 0x20;
6905 font
->max_char_or_byte2
= 0xff;
6907 if (is_two_byte_font
)
6909 /* Use the width of an "ideographic space" of that font because
6910 the_fontinfo.widMax returns the wrong width for some fonts. */
6911 switch (font
->mac_scriptcode
)
6914 char_width
= StringWidth("\p\x81\x40");
6917 char_width
= StringWidth("\p\xa1\x40");
6920 char_width
= StringWidth("\p\xa1\xa1");
6923 char_width
= StringWidth("\p\xa1\xa1");
6928 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6929 returns 15 for 12-point Monaco! */
6930 char_width
= CharWidth ('m');
6932 if (is_two_byte_font
)
6934 font
->per_char
= NULL
;
6936 if (fontface
& italic
)
6937 font
->max_bounds
.rbearing
= char_width
+ 1;
6939 font
->max_bounds
.rbearing
= char_width
;
6940 font
->max_bounds
.lbearing
= 0;
6941 font
->max_bounds
.width
= char_width
;
6942 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6943 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6945 font
->min_bounds
= font
->max_bounds
;
6949 font
->per_char
= (XCharStruct
*)
6950 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6952 int c
, min_width
, max_width
;
6953 Rect char_bounds
, min_bounds
, max_bounds
;
6956 min_width
= max_width
= char_width
;
6957 SetRect (&min_bounds
, -32767, -32767, 32767, 32767);
6958 SetRect (&max_bounds
, 0, 0, 0, 0);
6959 for (c
= 0x20; c
<= 0xff; c
++)
6962 char_width
= CharWidth (ch
);
6963 QDTextBounds (1, &ch
, &char_bounds
);
6964 STORE_XCHARSTRUCT (font
->per_char
[c
- 0x20],
6965 char_width
, char_bounds
);
6966 /* Some Japanese fonts (in SJIS encoding) return 0 as the
6967 character width of 0x7f. */
6970 min_width
= min (min_width
, char_width
);
6971 max_width
= max (max_width
, char_width
);
6973 if (!EmptyRect (&char_bounds
))
6975 SetRect (&min_bounds
,
6976 max (min_bounds
.left
, char_bounds
.left
),
6977 max (min_bounds
.top
, char_bounds
.top
),
6978 min (min_bounds
.right
, char_bounds
.right
),
6979 min (min_bounds
.bottom
, char_bounds
.bottom
));
6980 UnionRect (&max_bounds
, &char_bounds
, &max_bounds
);
6983 STORE_XCHARSTRUCT (font
->min_bounds
, min_width
, min_bounds
);
6984 STORE_XCHARSTRUCT (font
->max_bounds
, max_width
, max_bounds
);
6985 if (min_width
== max_width
6986 && max_bounds
.left
>= 0 && max_bounds
.right
<= max_width
)
6988 /* Fixed width and no overhangs. */
6989 xfree (font
->per_char
);
6990 font
->per_char
= NULL
;
6995 TextFont (old_fontnum
); /* restore previous font number, size and face */
6996 TextSize (old_fontsize
);
6997 TextFace (old_fontface
);
7004 mac_unload_font (dpyinfo
, font
)
7005 struct mac_display_info
*dpyinfo
;
7008 xfree (font
->full_name
);
7010 xfree (font
->per_char
);
7015 /* Load font named FONTNAME of the size SIZE for frame F, and return a
7016 pointer to the structure font_info while allocating it dynamically.
7017 If SIZE is 0, load any size of font.
7018 If loading is failed, return NULL. */
7021 x_load_font (f
, fontname
, size
)
7023 register char *fontname
;
7026 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7027 Lisp_Object font_names
;
7029 /* Get a list of all the fonts that match this name. Once we
7030 have a list of matching fonts, we compare them against the fonts
7031 we already have by comparing names. */
7032 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
7034 if (!NILP (font_names
))
7039 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7040 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
7041 if (dpyinfo
->font_table
[i
].name
7042 && (!strcmp (dpyinfo
->font_table
[i
].name
,
7043 SDATA (XCAR (tail
)))
7044 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
7045 SDATA (XCAR (tail
)))))
7046 return (dpyinfo
->font_table
+ i
);
7051 /* Load the font and add it to the table. */
7054 struct MacFontStruct
*font
;
7055 struct font_info
*fontp
;
7056 unsigned long value
;
7059 fontname
= (char *) SDATA (XCAR (font_names
));
7062 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
7067 /* Find a free slot in the font table. */
7068 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7069 if (dpyinfo
->font_table
[i
].name
== NULL
)
7072 /* If no free slot found, maybe enlarge the font table. */
7073 if (i
== dpyinfo
->n_fonts
7074 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
7077 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
7078 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
7080 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
7083 fontp
= dpyinfo
->font_table
+ i
;
7084 if (i
== dpyinfo
->n_fonts
)
7087 /* Now fill in the slots of *FONTP. */
7089 bzero (fontp
, sizeof (*fontp
));
7091 fontp
->font_idx
= i
;
7092 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
7093 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
7095 if (font
->min_bounds
.width
== font
->max_bounds
.width
)
7097 /* Fixed width font. */
7098 fontp
->average_width
= fontp
->space_width
= font
->min_bounds
.width
;
7105 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
7106 pcm
= mac_per_char_metric (font
, &char2b
, 0);
7108 fontp
->space_width
= pcm
->width
;
7110 fontp
->space_width
= FONT_WIDTH (font
);
7114 int width
= pcm
->width
;
7115 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
7116 if ((pcm
= mac_per_char_metric (font
, &char2b
, 0)) != NULL
)
7117 width
+= pcm
->width
;
7118 fontp
->average_width
= width
/ 95;
7121 fontp
->average_width
= FONT_WIDTH (font
);
7124 fontp
->full_name
= (char *) xmalloc (strlen (font
->full_name
) + 1);
7125 bcopy (font
->full_name
, fontp
->full_name
, strlen (font
->full_name
) + 1);
7127 fontp
->size
= font
->max_bounds
.width
;
7128 fontp
->height
= FONT_HEIGHT (font
);
7130 /* For some font, ascent and descent in max_bounds field is
7131 larger than the above value. */
7132 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
7133 if (max_height
> fontp
->height
)
7134 fontp
->height
= max_height
;
7137 /* The slot `encoding' specifies how to map a character
7138 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
7139 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
7140 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
7141 2:0xA020..0xFF7F). For the moment, we don't know which charset
7142 uses this font. So, we set information in fontp->encoding[1]
7143 which is never used by any charset. If mapping can't be
7144 decided, set FONT_ENCODING_NOT_DECIDED. */
7145 if (font
->mac_scriptcode
== smJapanese
)
7146 fontp
->encoding
[1] = 4;
7150 = (font
->max_byte1
== 0
7152 ? (font
->min_char_or_byte2
< 0x80
7153 ? (font
->max_char_or_byte2
< 0x80
7154 ? 0 /* 0x20..0x7F */
7155 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
7156 : 1) /* 0xA0..0xFF */
7158 : (font
->min_byte1
< 0x80
7159 ? (font
->max_byte1
< 0x80
7160 ? (font
->min_char_or_byte2
< 0x80
7161 ? (font
->max_char_or_byte2
< 0x80
7162 ? 0 /* 0x2020..0x7F7F */
7163 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
7164 : 3) /* 0x20A0..0x7FFF */
7165 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
7166 : (font
->min_char_or_byte2
< 0x80
7167 ? (font
->max_char_or_byte2
< 0x80
7168 ? 2 /* 0xA020..0xFF7F */
7169 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
7170 : 1))); /* 0xA0A0..0xFFFF */
7173 #if 0 /* MAC_TODO: fill these out with more reasonably values */
7174 fontp
->baseline_offset
7175 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
7176 ? (long) value
: 0);
7177 fontp
->relative_compose
7178 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
7179 ? (long) value
: 0);
7180 fontp
->default_ascent
7181 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
7182 ? (long) value
: 0);
7184 fontp
->baseline_offset
= 0;
7185 fontp
->relative_compose
= 0;
7186 fontp
->default_ascent
= 0;
7189 /* Set global flag fonts_changed_p to non-zero if the font loaded
7190 has a character with a smaller width than any other character
7191 before, or if the font loaded has a smalle>r height than any
7192 other font loaded before. If this happens, it will make a
7193 glyph matrix reallocation necessary. */
7194 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
7201 /* Return a pointer to struct font_info of a font named FONTNAME for
7202 frame F. If no such font is loaded, return NULL. */
7205 x_query_font (f
, fontname
)
7207 register char *fontname
;
7209 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7212 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7213 if (dpyinfo
->font_table
[i
].name
7214 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
7215 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
7216 return (dpyinfo
->font_table
+ i
);
7221 /* Find a CCL program for a font specified by FONTP, and set the member
7222 `encoder' of the structure. */
7225 x_find_ccl_program (fontp
)
7226 struct font_info
*fontp
;
7228 Lisp_Object list
, elt
;
7230 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
7234 && STRINGP (XCAR (elt
))
7235 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
7241 struct ccl_program
*ccl
7242 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
7244 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
7247 fontp
->font_encoder
= ccl
;
7253 /* The Mac Event loop code */
7255 #if !TARGET_API_MAC_CARBON
7257 #include <Quickdraw.h>
7258 #include <Balloons.h>
7259 #include <Devices.h>
7261 #include <Gestalt.h>
7263 #include <Processes.h>
7265 #include <ToolUtils.h>
7266 #include <TextUtils.h>
7267 #include <Dialogs.h>
7270 #include <Resources.h>
7275 #endif /* ! TARGET_API_MAC_CARBON */
7280 #define WINDOW_RESOURCE 128
7281 #define TERM_WINDOW_RESOURCE 129
7283 #define DEFAULT_NUM_COLS 80
7285 #define MIN_DOC_SIZE 64
7286 #define MAX_DOC_SIZE 32767
7288 #define EXTRA_STACK_ALLOC (256 * 1024)
7290 #define ARGV_STRING_LIST_ID 129
7291 #define ABOUT_ALERT_ID 128
7292 #define RAM_TOO_LARGE_ALERT_ID 129
7294 /* Contains the string "reverse", which is a constant for mouse button emu.*/
7295 Lisp_Object Qreverse
;
7297 /* True if using command key as meta key. */
7298 Lisp_Object Vmac_command_key_is_meta
;
7300 /* Modifier associated with the option key, or nil for normal behavior. */
7301 Lisp_Object Vmac_option_modifier
;
7303 /* True if the ctrl and meta keys should be reversed. */
7304 Lisp_Object Vmac_reverse_ctrl_meta
;
7306 /* True if the option and command modifiers should be used to emulate
7307 a three button mouse */
7308 Lisp_Object Vmac_emulate_three_button_mouse
;
7310 #if USE_CARBON_EVENTS
7311 /* True if the mouse wheel button (i.e. button 4) should map to
7312 mouse-2, instead of mouse-3. */
7313 Lisp_Object Vmac_wheel_button_is_mouse_2
;
7315 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
7316 for processing before Emacs sees it. */
7317 Lisp_Object Vmac_pass_command_to_system
;
7319 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
7320 for processing before Emacs sees it. */
7321 Lisp_Object Vmac_pass_control_to_system
;
7323 /* Points to the variable `inev' in the function XTread_socket. It is
7324 used for passing an input event to the function back from
7325 Carbon/Apple event handlers. */
7326 static struct input_event
*read_socket_inev
= NULL
;
7329 /* Set in term/mac-win.el to indicate that event loop can now generate
7330 drag and drop events. */
7331 Lisp_Object Qmac_ready_for_drag_n_drop
;
7333 Point saved_menu_event_location
;
7336 static void init_required_apple_events (void);
7338 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
7340 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
7341 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
7342 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
7344 #if TARGET_API_MAC_CARBON
7346 static pascal OSErr
mac_do_track_drag (DragTrackingMessage
, WindowPtr
, void*, DragReference
);
7347 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
7348 static DragTrackingHandlerUPP mac_do_track_dragUPP
= NULL
;
7349 static DragReceiveHandlerUPP mac_do_receive_dragUPP
= NULL
;
7352 static Lisp_Object Qapplication
, Qabout
;
7353 #if USE_CARBON_EVENTS
7355 extern void init_service_handler ();
7356 static Lisp_Object Qpreferences
, Qservices
, Qpaste
, Qperform
;
7358 /* Window Event Handler */
7359 static pascal OSStatus
mac_handle_window_event (EventHandlerCallRef
,
7362 OSErr
install_window_handler (WindowPtr
);
7364 extern void init_emacs_passwd_dir ();
7365 extern int emacs_main (int, char **, char **);
7367 extern void initialize_applescript();
7368 extern void terminate_applescript();
7371 #if USE_CARBON_EVENTS
7372 mac_to_emacs_modifiers (UInt32 mods
)
7374 mac_to_emacs_modifiers (EventModifiers mods
)
7377 unsigned int result
= 0;
7378 if (mods
& macShiftKey
)
7379 result
|= shift_modifier
;
7380 if (mods
& macCtrlKey
)
7381 result
|= ctrl_modifier
;
7382 if (mods
& macMetaKey
)
7383 result
|= meta_modifier
;
7384 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
7385 result
|= alt_modifier
;
7386 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
7387 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
7389 result
|= XUINT(val
);
7396 mac_get_emulated_btn ( UInt32 modifiers
)
7399 if (!NILP (Vmac_emulate_three_button_mouse
)) {
7400 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
7401 if (modifiers
& cmdKey
)
7402 result
= cmdIs3
? 2 : 1;
7403 else if (modifiers
& optionKey
)
7404 result
= cmdIs3
? 1 : 2;
7409 #if USE_CARBON_EVENTS
7410 /* Obtains the event modifiers from the event ref and then calls
7411 mac_to_emacs_modifiers. */
7413 mac_event_to_emacs_modifiers (EventRef eventRef
)
7416 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7417 sizeof (UInt32
), NULL
, &mods
);
7418 if (!NILP (Vmac_emulate_three_button_mouse
) &&
7419 GetEventClass(eventRef
) == kEventClassMouse
)
7421 mods
&= ~(optionKey
| cmdKey
);
7423 return mac_to_emacs_modifiers (mods
);
7426 /* Given an event ref, return the code to use for the mouse button
7427 code in the emacs input_event. */
7429 mac_get_mouse_btn (EventRef ref
)
7431 EventMouseButton result
= kEventMouseButtonPrimary
;
7432 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7433 sizeof (EventMouseButton
), NULL
, &result
);
7436 case kEventMouseButtonPrimary
:
7437 if (NILP (Vmac_emulate_three_button_mouse
))
7441 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7442 sizeof (UInt32
), NULL
, &mods
);
7443 return mac_get_emulated_btn(mods
);
7445 case kEventMouseButtonSecondary
:
7446 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7447 case kEventMouseButtonTertiary
:
7448 case 4: /* 4 is the number for the mouse wheel button */
7449 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7455 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7456 events. However the click of the mouse wheel is not converted to a
7457 mouseDown or mouseUp event. Likewise for dead key down events.
7458 This calls ConvertEventRef, but then checks to see if it is a mouse
7459 up/down, or a dead key down carbon event that has not been
7460 converted, and if so, converts it by hand (to be picked up in the
7461 XTread_socket loop). */
7462 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7464 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7469 switch (GetEventClass (eventRef
))
7471 case kEventClassMouse
:
7472 switch (GetEventKind (eventRef
))
7474 case kEventMouseDown
:
7475 eventRec
->what
= mouseDown
;
7480 eventRec
->what
= mouseUp
;
7489 case kEventClassKeyboard
:
7490 switch (GetEventKind (eventRef
))
7492 case kEventRawKeyDown
:
7494 unsigned char char_codes
;
7497 eventRec
->what
= keyDown
;
7498 GetEventParameter (eventRef
, kEventParamKeyMacCharCodes
, typeChar
,
7499 NULL
, sizeof (char), NULL
, &char_codes
);
7500 GetEventParameter (eventRef
, kEventParamKeyCode
, typeUInt32
,
7501 NULL
, sizeof (UInt32
), NULL
, &key_code
);
7502 eventRec
->message
= char_codes
| ((key_code
& 0xff) << 8);
7518 /* Need where and when. */
7521 GetEventParameter (eventRef
, kEventParamMouseLocation
, typeQDPoint
,
7522 NULL
, sizeof (Point
), NULL
, &eventRec
->where
);
7523 /* Use two step process because new event modifiers are 32-bit
7524 and old are 16-bit. Currently, only loss is NumLock & Fn. */
7525 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
,
7526 NULL
, sizeof (UInt32
), NULL
, &mods
);
7527 eventRec
->modifiers
= mods
;
7529 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7540 Handle menubar_handle
;
7541 MenuHandle menu_handle
;
7543 menubar_handle
= GetNewMBar (128);
7544 if(menubar_handle
== NULL
)
7546 SetMenuBar (menubar_handle
);
7549 #if !TARGET_API_MAC_CARBON
7550 menu_handle
= GetMenuHandle (M_APPLE
);
7551 if(menu_handle
!= NULL
)
7552 AppendResMenu (menu_handle
,'DRVR');
7560 do_init_managers (void)
7562 #if !TARGET_API_MAC_CARBON
7563 InitGraf (&qd
.thePort
);
7565 FlushEvents (everyEvent
, 0);
7570 #endif /* !TARGET_API_MAC_CARBON */
7573 #if !TARGET_API_MAC_CARBON
7574 /* set up some extra stack space for use by emacs */
7575 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7577 /* MaxApplZone must be called for AppleScript to execute more
7578 complicated scripts */
7581 #endif /* !TARGET_API_MAC_CARBON */
7585 do_check_ram_size (void)
7587 SInt32 physical_ram_size
, logical_ram_size
;
7589 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7590 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7591 || physical_ram_size
> (1 << VALBITS
)
7592 || logical_ram_size
> (1 << VALBITS
))
7594 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7600 do_window_update (WindowPtr win
)
7602 struct frame
*f
= mac_window_to_frame (win
);
7606 /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
7608 if (win
!= tip_window
)
7610 if (f
->async_visible
== 0)
7612 f
->async_visible
= 1;
7613 f
->async_iconified
= 0;
7614 SET_FRAME_GARBAGED (f
);
7616 /* An update event is equivalent to MapNotify on X, so report
7617 visibility changes properly. */
7618 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7619 /* Force a redisplay sooner or later to update the
7620 frame titles in case this is the second frame. */
7621 record_asynch_buffer_change ();
7627 #if TARGET_API_MAC_CARBON
7629 RgnHandle region
= NewRgn ();
7631 GetPortVisibleRegion (GetWindowPort (win
), region
);
7632 GetRegionBounds (region
, &r
);
7633 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
7634 UpdateControls (win
, region
);
7635 DisposeRgn (region
);
7638 r
= (*win
->visRgn
)->rgnBBox
;
7639 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
7640 UpdateControls (win
, win
->visRgn
);
7649 is_emacs_window (WindowPtr win
)
7651 Lisp_Object tail
, frame
;
7656 FOR_EACH_FRAME (tail
, frame
)
7657 if (FRAME_MAC_P (XFRAME (frame
)))
7658 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7667 /* Window-activate events will do the job. */
7673 /* Window-deactivate events will do the job. */
7678 do_apple_menu (SInt16 menu_item
)
7680 #if !TARGET_API_MAC_CARBON
7682 SInt16 da_driver_refnum
;
7684 if (menu_item
== I_ABOUT
)
7685 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7688 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7689 da_driver_refnum
= OpenDeskAcc (item_name
);
7691 #endif /* !TARGET_API_MAC_CARBON */
7695 do_menu_choice (SInt32 menu_choice
)
7697 SInt16 menu_id
, menu_item
;
7699 menu_id
= HiWord (menu_choice
);
7700 menu_item
= LoWord (menu_choice
);
7708 do_apple_menu (menu_item
);
7713 struct frame
*f
= mac_focus_frame (&one_mac_display_info
);
7714 MenuHandle menu
= GetMenuHandle (menu_id
);
7719 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7720 menubar_selection_callback (f
, refcon
);
7729 /* Handle drags in size box. Based on code contributed by Ben
7730 Mesander and IM - Window Manager A. */
7733 do_grow_window (WindowPtr w
, EventRecord
*e
)
7736 int rows
, columns
, width
, height
;
7737 struct frame
*f
= mac_window_to_frame (w
);
7738 XSizeHints
*size_hints
= FRAME_SIZE_HINTS (f
);
7739 int min_width
= MIN_DOC_SIZE
, min_height
= MIN_DOC_SIZE
;
7740 #if TARGET_API_MAC_CARBON
7746 if (size_hints
->flags
& PMinSize
)
7748 min_width
= size_hints
->min_width
;
7749 min_height
= size_hints
->min_height
;
7751 SetRect (&limit_rect
, min_width
, min_height
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7753 #if TARGET_API_MAC_CARBON
7754 if (!ResizeWindow (w
, e
->where
, &limit_rect
, &new_rect
))
7756 height
= new_rect
.bottom
- new_rect
.top
;
7757 width
= new_rect
.right
- new_rect
.left
;
7759 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7760 /* see if it really changed size */
7763 height
= HiWord (grow_size
);
7764 width
= LoWord (grow_size
);
7767 if (width
!= FRAME_PIXEL_WIDTH (f
)
7768 || height
!= FRAME_PIXEL_HEIGHT (f
))
7770 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
7771 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
7773 x_set_window_size (f
, 0, columns
, rows
);
7778 /* Handle clicks in zoom box. Calculation of "standard state" based
7779 on code in IM - Window Manager A and code contributed by Ben
7780 Mesander. The standard state of an Emacs window is 80-characters
7781 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7784 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7787 Rect zoom_rect
, port_rect
;
7789 int w_title_height
, columns
, rows
, width
, height
;
7790 struct frame
*f
= mac_window_to_frame (w
);
7791 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7793 #if TARGET_API_MAC_CARBON
7795 Point standard_size
;
7797 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7798 standard_size
.v
= dpyinfo
->height
;
7800 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
7801 zoom_in_or_out
= inZoomIn
;
7804 /* Adjust the standard size according to character boundaries. */
7806 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
7807 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7808 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
7809 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7810 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
7811 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
7812 && port_rect
.left
== zoom_rect
.left
7813 && port_rect
.top
== zoom_rect
.top
)
7814 zoom_in_or_out
= inZoomIn
;
7816 zoom_in_or_out
= inZoomOut
;
7819 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
7821 #else /* not TARGET_API_MAC_CARBON */
7822 GetPort (&save_port
);
7824 SetPortWindowPort (w
);
7826 /* Clear window to avoid flicker. */
7827 EraseRect (&(w
->portRect
));
7828 if (zoom_in_or_out
== inZoomOut
)
7830 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7831 LocalToGlobal (&top_left
);
7833 /* calculate height of window's title bar */
7834 w_title_height
= top_left
.v
- 1
7835 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7837 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7838 zoom_rect
= qd
.screenBits
.bounds
;
7839 zoom_rect
.top
+= w_title_height
;
7840 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7842 zoom_rect
.right
= zoom_rect
.left
7843 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7845 /* Adjust the standard size according to character boundaries. */
7846 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7848 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7850 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7854 ZoomWindow (w
, zoom_in_or_out
, f
== mac_focus_frame (dpyinfo
));
7856 SetPort (save_port
);
7857 #endif /* not TARGET_API_MAC_CARBON */
7859 /* retrieve window size and update application values */
7860 #if TARGET_API_MAC_CARBON
7861 GetWindowPortBounds (w
, &port_rect
);
7863 port_rect
= w
->portRect
;
7865 height
= port_rect
.bottom
- port_rect
.top
;
7866 width
= port_rect
.right
- port_rect
.left
;
7868 if (width
!= FRAME_PIXEL_WIDTH (f
)
7869 || height
!= FRAME_PIXEL_HEIGHT (f
))
7871 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
7872 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
7874 change_frame_size (f
, rows
, columns
, 0, 1, 0);
7875 SET_FRAME_GARBAGED (f
);
7876 cancel_mouse_face (f
);
7878 FRAME_PIXEL_WIDTH (f
) = width
;
7879 FRAME_PIXEL_HEIGHT (f
) = height
;
7881 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
7884 /* Intialize AppleEvent dispatcher table for the required events. */
7886 init_required_apple_events ()
7891 /* Make sure we have apple events before starting. */
7892 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7896 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7899 #if TARGET_API_MAC_CARBON
7900 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7901 NewAEEventHandlerUPP
7902 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7905 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7906 NewAEEventHandlerProc
7907 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7913 #if TARGET_API_MAC_CARBON
7914 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7915 NewAEEventHandlerUPP
7916 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7919 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7920 NewAEEventHandlerProc
7921 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7927 #if TARGET_API_MAC_CARBON
7928 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7929 NewAEEventHandlerUPP
7930 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7933 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7934 NewAEEventHandlerProc
7935 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7941 #if TARGET_API_MAC_CARBON
7942 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7943 NewAEEventHandlerUPP
7944 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7947 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7948 NewAEEventHandlerProc
7949 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7957 mac_store_application_menu_event (event
)
7958 #if USE_CARBON_EVENTS
7964 struct input_event buf
;
7965 Lisp_Object frame
, entry
;
7969 XSETFRAME (frame
, mac_focus_frame (&one_mac_display_info
));
7970 buf
.kind
= MENU_BAR_EVENT
;
7971 buf
.frame_or_window
= frame
;
7973 kbd_buffer_store_event (&buf
);
7975 buf
.arg
= Qapplication
;
7976 kbd_buffer_store_event (&buf
);
7978 #if USE_CARBON_EVENTS
7979 switch (GetEventClass (event
))
7982 case kEventClassService
:
7983 buf
.arg
= Qservices
;
7984 kbd_buffer_store_event (&buf
);
7985 switch (GetEventKind (event
))
7987 case kEventServicePaste
:
7991 case kEventServicePerform
:
7994 CFStringRef message
;
7996 err
= GetEventParameter (event
, kEventParamServiceMessageName
,
7997 typeCFStringRef
, NULL
,
7998 sizeof (CFStringRef
), NULL
, &message
);
8000 kbd_buffer_store_event (&buf
);
8001 if (err
== noErr
&& message
)
8002 entry
= intern (SDATA (cfstring_to_lisp (message
)));
8012 #endif /* MAC_OSX */
8013 case kEventClassCommand
:
8017 GetEventParameter(event
, kEventParamDirectObject
, typeHICommand
,
8018 NULL
, sizeof (HICommand
), NULL
, &command
);
8019 switch (command
.commandID
)
8021 case kHICommandAbout
:
8025 case kHICommandPreferences
:
8026 entry
= Qpreferences
;
8028 #endif /* MAC_OSX */
8029 case kHICommandQuit
:
8041 #else /* USE_CARBON_EVENTS */
8044 case kHICommandAbout
:
8047 case kHICommandQuit
:
8056 kbd_buffer_store_event (&buf
);
8059 #if USE_CARBON_EVENTS
8060 static pascal OSStatus
8061 mac_handle_command_event (next_handler
, event
, data
)
8062 EventHandlerCallRef next_handler
;
8069 GetEventParameter(event
, kEventParamDirectObject
, typeHICommand
, NULL
,
8070 sizeof (HICommand
), NULL
, &command
);
8072 switch (command
.commandID
)
8074 case kHICommandAbout
:
8076 case kHICommandPreferences
:
8077 #endif /* MAC_OSX */
8078 result
= CallNextEventHandler (next_handler
, event
);
8079 if (result
!= eventNotHandledErr
)
8082 mac_store_application_menu_event (event
);
8089 return eventNotHandledErr
;
8093 init_command_handler ()
8096 EventTypeSpec specs
[] = {{kEventClassCommand
, kEventCommandProcess
}};
8097 static EventHandlerUPP handle_command_eventUPP
= NULL
;
8099 if (handle_command_eventUPP
== NULL
)
8100 handle_command_eventUPP
= NewEventHandlerUPP (mac_handle_command_event
);
8101 return InstallApplicationEventHandler (handle_command_eventUPP
,
8102 GetEventTypeCount (specs
), specs
,
8106 static pascal OSStatus
8107 mac_handle_window_event (next_handler
, event
, data
)
8108 EventHandlerCallRef next_handler
;
8115 XSizeHints
*size_hints
;
8117 GetEventParameter (event
, kEventParamDirectObject
, typeWindowRef
,
8118 NULL
, sizeof (WindowPtr
), NULL
, &wp
);
8120 switch (GetEventKind (event
))
8122 case kEventWindowUpdate
:
8123 result
= CallNextEventHandler (next_handler
, event
);
8124 if (result
!= eventNotHandledErr
)
8127 do_window_update (wp
);
8130 case kEventWindowBoundsChanging
:
8131 result
= CallNextEventHandler (next_handler
, event
);
8132 if (result
!= eventNotHandledErr
)
8135 GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
8136 NULL
, sizeof (UInt32
), NULL
, &attributes
);
8137 size_hints
= FRAME_SIZE_HINTS (mac_window_to_frame (wp
));
8138 if ((attributes
& kWindowBoundsChangeUserResize
)
8139 && ((size_hints
->flags
& (PResizeInc
| PBaseSize
| PMinSize
))
8140 == (PResizeInc
| PBaseSize
| PMinSize
)))
8145 GetEventParameter (event
, kEventParamCurrentBounds
,
8147 NULL
, sizeof (Rect
), NULL
, &bounds
);
8148 width
= bounds
.right
- bounds
.left
;
8149 height
= bounds
.bottom
- bounds
.top
;
8151 if (width
< size_hints
->min_width
)
8152 width
= size_hints
->min_width
;
8154 width
= size_hints
->base_width
8155 + (int) ((width
- size_hints
->base_width
)
8156 / (float) size_hints
->width_inc
+ .5)
8157 * size_hints
->width_inc
;
8159 if (height
< size_hints
->min_height
)
8160 height
= size_hints
->min_height
;
8162 height
= size_hints
->base_height
8163 + (int) ((height
- size_hints
->base_height
)
8164 / (float) size_hints
->height_inc
+ .5)
8165 * size_hints
->height_inc
;
8167 bounds
.right
= bounds
.left
+ width
;
8168 bounds
.bottom
= bounds
.top
+ height
;
8169 SetEventParameter (event
, kEventParamCurrentBounds
,
8170 typeQDRectangle
, sizeof (Rect
), &bounds
);
8176 return eventNotHandledErr
;
8179 static pascal OSStatus
8180 mac_handle_mouse_event (next_handler
, event
, data
)
8181 EventHandlerCallRef next_handler
;
8187 switch (GetEventKind (event
))
8189 case kEventMouseWheelMoved
:
8193 EventMouseWheelAxis axis
;
8197 result
= CallNextEventHandler (next_handler
, event
);
8198 if (result
!= eventNotHandledErr
|| read_socket_inev
== NULL
)
8201 GetEventParameter (event
, kEventParamWindowRef
, typeWindowRef
,
8202 NULL
, sizeof (WindowRef
), NULL
, &wp
);
8203 f
= mac_window_to_frame (wp
);
8204 if (f
!= mac_focus_frame (&one_mac_display_info
))
8207 GetEventParameter (event
, kEventParamMouseWheelAxis
,
8208 typeMouseWheelAxis
, NULL
,
8209 sizeof (EventMouseWheelAxis
), NULL
, &axis
);
8210 if (axis
!= kEventMouseWheelAxisY
)
8213 GetEventParameter (event
, kEventParamMouseWheelDelta
, typeSInt32
,
8214 NULL
, sizeof (SInt32
), NULL
, &delta
);
8215 GetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
8216 NULL
, sizeof (Point
), NULL
, &point
);
8217 read_socket_inev
->kind
= WHEEL_EVENT
;
8218 read_socket_inev
->code
= 0;
8219 read_socket_inev
->modifiers
=
8220 (mac_event_to_emacs_modifiers (event
)
8221 | ((delta
< 0) ? down_modifier
: up_modifier
));
8222 SetPortWindowPort (wp
);
8223 GlobalToLocal (&point
);
8224 XSETINT (read_socket_inev
->x
, point
.h
);
8225 XSETINT (read_socket_inev
->y
, point
.v
);
8226 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
8236 return eventNotHandledErr
;
8238 #endif /* USE_CARBON_EVENTS */
8242 install_window_handler (window
)
8246 #if USE_CARBON_EVENTS
8247 EventTypeSpec specs_window
[] =
8248 {{kEventClassWindow
, kEventWindowUpdate
},
8249 {kEventClassWindow
, kEventWindowBoundsChanging
}};
8250 EventTypeSpec specs_mouse
[] = {{kEventClassMouse
, kEventMouseWheelMoved
}};
8251 static EventHandlerUPP handle_window_eventUPP
= NULL
;
8252 static EventHandlerUPP handle_mouse_eventUPP
= NULL
;
8254 if (handle_window_eventUPP
== NULL
)
8255 handle_window_eventUPP
= NewEventHandlerUPP (mac_handle_window_event
);
8256 if (handle_mouse_eventUPP
== NULL
)
8257 handle_mouse_eventUPP
= NewEventHandlerUPP (mac_handle_mouse_event
);
8258 err
= InstallWindowEventHandler (window
, handle_window_eventUPP
,
8259 GetEventTypeCount (specs_window
),
8260 specs_window
, NULL
, NULL
);
8262 err
= InstallWindowEventHandler (window
, handle_mouse_eventUPP
,
8263 GetEventTypeCount (specs_mouse
),
8264 specs_mouse
, NULL
, NULL
);
8266 #if TARGET_API_MAC_CARBON
8267 if (mac_do_track_dragUPP
== NULL
)
8268 mac_do_track_dragUPP
= NewDragTrackingHandlerUPP (mac_do_track_drag
);
8269 if (mac_do_receive_dragUPP
== NULL
)
8270 mac_do_receive_dragUPP
= NewDragReceiveHandlerUPP (mac_do_receive_drag
);
8273 err
= InstallTrackingHandler (mac_do_track_dragUPP
, window
, NULL
);
8275 err
= InstallReceiveHandler (mac_do_receive_dragUPP
, window
, NULL
);
8281 remove_window_handler (window
)
8284 #if TARGET_API_MAC_CARBON
8285 if (mac_do_track_dragUPP
)
8286 RemoveTrackingHandler (mac_do_track_dragUPP
, window
);
8287 if (mac_do_receive_dragUPP
)
8288 RemoveReceiveHandler (mac_do_receive_dragUPP
, window
);
8292 /* Open Application Apple Event */
8294 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
8300 /* Called when we receive an AppleEvent with an ID of
8301 "kAEOpenDocuments". This routine gets the direct parameter,
8302 extracts the FSSpecs in it, and puts their names on a list. */
8303 #pragma options align=mac68k
8304 typedef struct SelectionRange
{
8305 short unused1
; // 0 (not used)
8306 short lineNum
; // line to select (<0 to specify range)
8307 long startRange
; // start of selection range (if line < 0)
8308 long endRange
; // end of selection range (if line < 0)
8309 long unused2
; // 0 (not used)
8310 long theDate
; // modification date/time
8312 #pragma options align=reset
8315 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
8320 DescType actual_type
;
8322 SelectionRange position
;
8323 Lisp_Object file_list
= Qnil
;
8325 xassert (read_socket_inev
);
8327 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
8329 goto descriptor_error_exit
;
8331 err
= AEGetParamPtr (message
, keyAEPosition
, typeChar
, &actual_type
, &position
, sizeof(SelectionRange
), &actual_size
);
8333 file_list
= Fcons (list3 (make_number (position
.lineNum
+ 1),
8334 make_number (position
.startRange
+ 1),
8335 make_number (position
.endRange
+ 1)),
8338 /* Check to see that we got all of the required parameters from the
8339 event descriptor. For an 'odoc' event this should just be the
8341 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
8342 &actual_type
, (Ptr
) &keyword
,
8343 sizeof (keyword
), &actual_size
);
8344 /* No error means that we found some unused parameters.
8345 errAEDescNotFound means that there are no more parameters. If we
8346 get an error code other than that, flag it. */
8347 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
8349 err
= errAEEventNotHandled
;
8354 /* Got all the parameters we need. Now, go through the direct
8355 object list and parse it up. */
8357 long num_files_to_open
;
8359 err
= AECountItems (&the_desc
, &num_files_to_open
);
8364 /* AE file list is one based so just use that for indexing here. */
8365 for (i
= 1; i
<= num_files_to_open
; i
++)
8367 char unix_path_name
[MAXPATHLEN
];
8371 err
= AEGetNthPtr (&the_desc
, i
, typeFSRef
, &keyword
,
8372 &actual_type
, &fref
, sizeof (FSRef
),
8374 if (err
!= noErr
|| actual_type
!= typeFSRef
)
8377 if (FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
))
8382 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
8383 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
8384 if (err
!= noErr
) continue;
8386 if (fsspec_to_posix_pathname (&fs
, unix_path_name
,
8387 sizeof (unix_path_name
) - 1) == noErr
)
8389 /* x-dnd functions expect undecoded filenames. */
8390 file_list
= Fcons (make_unibyte_string (unix_path_name
,
8391 strlen (unix_path_name
)),
8396 /* Build a DRAG_N_DROP_EVENT type event as is done in
8397 constuct_drag_n_drop in w32term.c. */
8398 if (!NILP (file_list
))
8400 struct frame
*f
= mac_focus_frame (&one_mac_display_info
);
8404 read_socket_inev
->kind
= DRAG_N_DROP_EVENT
;
8405 read_socket_inev
->code
= 0;
8406 read_socket_inev
->modifiers
= 0;
8408 XSETINT (read_socket_inev
->x
, 0);
8409 XSETINT (read_socket_inev
->y
, 0);
8411 XSETFRAME (frame
, f
);
8412 read_socket_inev
->frame_or_window
= Fcons (frame
, file_list
);
8415 /* Regardless of whether Emacs was suspended or in the
8416 foreground, ask it to redraw its entire screen. Otherwise
8417 parts of the screen can be left in an inconsistent
8419 wp
= FRAME_MAC_WINDOW (f
);
8421 #if TARGET_API_MAC_CARBON
8425 GetWindowPortBounds (wp
, &r
);
8426 InvalWindowRect (wp
, &r
);
8428 #else /* not TARGET_API_MAC_CARBON */
8429 InvalRect (&(wp
->portRect
));
8430 #endif /* not TARGET_API_MAC_CARBON */
8436 /* Nuke the coerced file list in any case */
8437 err2
= AEDisposeDesc(&the_desc
);
8439 descriptor_error_exit
:
8440 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
8445 #if TARGET_API_MAC_CARBON
8447 mac_do_track_drag (DragTrackingMessage message
, WindowPtr window
,
8448 void *handlerRefCon
, DragReference theDrag
)
8450 static int can_accept
;
8453 ItemReference theItem
;
8454 FlavorFlags theFlags
;
8457 if (GetFrontWindowOfClass (kMovableModalWindowClass
, false))
8458 return dragNotAcceptedErr
;
8462 case kDragTrackingEnterHandler
:
8463 CountDragItems (theDrag
, &items
);
8465 for (index
= 1; index
<= items
; index
++)
8467 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
8468 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
8469 if (result
== noErr
)
8477 case kDragTrackingEnterWindow
:
8480 RgnHandle hilite_rgn
= NewRgn ();
8482 struct frame
*f
= mac_window_to_frame (window
);
8484 GetWindowPortBounds (window
, &r
);
8485 OffsetRect (&r
, -r
.left
, -r
.top
);
8486 RectRgn (hilite_rgn
, &r
);
8487 ShowDragHilite (theDrag
, hilite_rgn
, true);
8488 DisposeRgn (hilite_rgn
);
8489 SetThemeCursor (kThemeCopyArrowCursor
);
8493 case kDragTrackingInWindow
:
8496 case kDragTrackingLeaveWindow
:
8499 struct frame
*f
= mac_window_to_frame (window
);
8501 HideDragHilite (theDrag
);
8502 SetThemeCursor (kThemeArrowCursor
);
8506 case kDragTrackingLeaveHandler
:
8514 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
8515 DragReference theDrag
)
8519 FlavorFlags theFlags
;
8522 ItemReference theItem
;
8524 Size size
= sizeof (HFSFlavor
);
8525 Lisp_Object file_list
;
8527 if (GetFrontWindowOfClass (kMovableModalWindowClass
, false))
8528 return dragNotAcceptedErr
;
8531 GetDragMouse (theDrag
, &mouse
, 0L);
8532 CountDragItems (theDrag
, &items
);
8533 for (index
= 1; index
<= items
; index
++)
8535 /* Only handle file references. */
8536 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
8537 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
8538 if (result
== noErr
)
8543 char unix_path_name
[MAXPATHLEN
];
8545 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
8547 /* Use Carbon routines, otherwise it converts the file name
8548 to /Macintosh HD/..., which is not correct. */
8549 FSpMakeFSRef (&data
.fileSpec
, &fref
);
8550 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
8552 if (fsspec_to_posix_pathname (&data
.fileSpec
, unix_path_name
,
8553 sizeof (unix_path_name
) - 1) == noErr
)
8555 /* x-dnd functions expect undecoded filenames. */
8556 file_list
= Fcons (make_unibyte_string (unix_path_name
,
8557 strlen (unix_path_name
)),
8561 /* If there are items in the list, construct an event and post it to
8562 the queue like an interrupt using kbd_buffer_store_event. */
8563 if (!NILP (file_list
))
8565 struct input_event event
;
8567 struct frame
*f
= mac_window_to_frame (window
);
8570 GlobalToLocal (&mouse
);
8571 GetDragModifiers (theDrag
, NULL
, NULL
, &modifiers
);
8573 event
.kind
= DRAG_N_DROP_EVENT
;
8575 event
.modifiers
= mac_to_emacs_modifiers (modifiers
);
8576 event
.timestamp
= TickCount () * (1000 / 60);
8577 XSETINT (event
.x
, mouse
.h
);
8578 XSETINT (event
.y
, mouse
.v
);
8579 XSETFRAME (frame
, f
);
8580 event
.frame_or_window
= Fcons (frame
, file_list
);
8582 /* Post to the interrupt queue */
8583 kbd_buffer_store_event (&event
);
8584 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
8586 ProcessSerialNumber psn
;
8587 GetCurrentProcess (&psn
);
8588 SetFrontProcess (&psn
);
8594 return dragNotAcceptedErr
;
8599 /* Print Document Apple Event */
8601 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
8603 return errAEEventNotHandled
;
8608 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
8610 #if USE_CARBON_EVENTS
8612 EventRef event
= NULL
;
8613 static const HICommand quit_command
= {kEventAttributeNone
, kHICommandQuit
};
8615 err
= CreateEvent (NULL
, kEventClassCommand
, kEventCommandProcess
, 0,
8616 kEventAttributeUserEvent
, &event
);
8618 err
= SetEventParameter (event
, kEventParamDirectObject
, typeHICommand
,
8619 sizeof (HICommand
), &quit_command
);
8621 mac_store_application_menu_event (event
);
8623 ReleaseEvent (event
);
8628 return errAEEventNotHandled
;
8630 mac_store_application_menu_event (kHICommandQuit
);
8639 profiler_exit_proc ()
8641 ProfilerDump ("\pEmacs.prof");
8646 /* These few functions implement Emacs as a normal Mac application
8647 (almost): set up the heap and the Toolbox, handle necessary system
8648 events plus a few simple menu events. They also set up Emacs's
8649 access to functions defined in the rest of this file. Emacs uses
8650 function hooks to perform all its terminal I/O. A complete list of
8651 these functions appear in termhooks.h. For what they do, read the
8652 comments there and see also w32term.c and xterm.c. What's
8653 noticeably missing here is the event loop, which is normally
8654 present in most Mac application. After performing the necessary
8655 Mac initializations, main passes off control to emacs_main
8656 (corresponding to main in emacs.c). Emacs_main calls XTread_socket
8657 (defined further below) to read input. This is where
8658 WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
8665 #if __profile__ /* is the profiler on? */
8666 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
8671 /* set creator and type for files created by MSL */
8676 do_init_managers ();
8681 do_check_ram_size ();
8684 init_emacs_passwd_dir ();
8688 initialize_applescript ();
8690 init_required_apple_events ();
8696 /* set up argv array from STR# resource */
8697 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8701 /* free up AppleScript resources on exit */
8702 atexit (terminate_applescript
);
8704 #if __profile__ /* is the profiler on? */
8705 atexit (profiler_exit_proc
);
8708 /* 3rd param "envp" never used in emacs_main */
8709 (void) emacs_main (argc
, argv
, 0);
8712 /* Never reached - real exit in Fkill_emacs */
8717 /* Table for translating Mac keycode to X keysym values. Contributed
8719 Mapping for special keys is now identical to that in Apple X11
8720 except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
8721 on the right of the Cmd key on laptops, and fn + `enter' (->
8723 static unsigned char keycode_to_xkeysym_table
[] = {
8724 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8725 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8726 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8728 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8729 /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
8730 /*0x38*/ 0, 0, 0, 0,
8731 /*0x3C*/ 0, 0, 0, 0,
8733 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8734 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x0b /*clear*/,
8735 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8736 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8738 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8739 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8740 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8741 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8743 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8744 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8745 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8746 /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
8748 /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
8749 /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
8750 /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8751 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8755 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8757 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8758 return *xKeySym
!= 0;
8761 #if !USE_CARBON_EVENTS
8762 static RgnHandle mouse_region
= NULL
;
8765 mac_wait_next_event (er
, sleep_time
, dequeue
)
8770 static EventRecord er_buf
= {nullEvent
};
8771 UInt32 target_tick
, current_tick
;
8772 EventMask event_mask
;
8774 if (mouse_region
== NULL
)
8775 mouse_region
= NewRgn ();
8777 event_mask
= everyEvent
;
8778 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8779 event_mask
-= highLevelEventMask
;
8781 current_tick
= TickCount ();
8782 target_tick
= current_tick
+ sleep_time
;
8784 if (er_buf
.what
== nullEvent
)
8785 while (!WaitNextEvent (event_mask
, &er_buf
,
8786 target_tick
- current_tick
, mouse_region
))
8788 current_tick
= TickCount ();
8789 if (target_tick
<= current_tick
)
8795 er_buf
.what
= nullEvent
;
8798 #endif /* not USE_CARBON_EVENTS */
8800 /* Emacs calls this whenever it wants to read an input event from the
8803 XTread_socket (sd
, expected
, hold_quit
)
8805 struct input_event
*hold_quit
;
8807 struct input_event inev
;
8809 #if USE_CARBON_EVENTS
8811 EventTargetRef toolbox_dispatcher
;
8814 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8816 if (interrupt_input_blocked
)
8818 interrupt_input_pending
= 1;
8822 interrupt_input_pending
= 0;
8825 /* So people can tell when we have read the available input. */
8826 input_signal_count
++;
8828 #if USE_CARBON_EVENTS
8829 toolbox_dispatcher
= GetEventDispatcherTarget ();
8831 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
8832 kEventRemoveFromQueue
, &eventRef
))
8833 #else /* !USE_CARBON_EVENTS */
8834 while (mac_wait_next_event (&er
, 0, true))
8835 #endif /* !USE_CARBON_EVENTS */
8839 unsigned long timestamp
;
8841 /* It is necessary to set this (additional) argument slot of an
8842 event to nil because keyboard.c protects incompletely
8843 processed event from being garbage collected by placing them
8844 in the kbd_buffer_gcpro vector. */
8846 inev
.kind
= NO_EVENT
;
8849 #if USE_CARBON_EVENTS
8850 timestamp
= GetEventTime (eventRef
) / kEventDurationMillisecond
;
8852 timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8855 #if USE_CARBON_EVENTS
8856 /* Handle new events */
8857 if (!mac_convert_event_ref (eventRef
, &er
))
8859 /* There used to be a handler for the kEventMouseWheelMoved
8860 event here. But as of Mac OS X 10.4, this kind of event
8861 is not directly posted to the main event queue by
8862 two-finger scrolling on the trackpad. Instead, some
8863 private event is posted and it is converted to a wheel
8864 event by the default handler for the application target.
8865 The converted one can be received by a Carbon event
8866 handler installed on a window target. */
8867 read_socket_inev
= &inev
;
8868 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8869 read_socket_inev
= NULL
;
8872 #endif /* USE_CARBON_EVENTS */
8878 WindowPtr window_ptr
;
8879 ControlPartCode part_code
;
8882 #if USE_CARBON_EVENTS
8883 /* This is needed to send mouse events like aqua window
8884 buttons to the correct handler. */
8885 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8886 != eventNotHandledErr
)
8890 if (dpyinfo
->grabbed
&& last_mouse_frame
8891 && FRAME_LIVE_P (last_mouse_frame
))
8893 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
8894 part_code
= inContent
;
8898 part_code
= FindWindow (er
.where
, &window_ptr
);
8899 if (tip_window
&& window_ptr
== tip_window
)
8901 HideWindow (tip_window
);
8902 part_code
= FindWindow (er
.where
, &window_ptr
);
8906 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
8912 f
= mac_focus_frame (dpyinfo
);
8913 saved_menu_event_location
= er
.where
;
8914 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8915 XSETFRAME (inev
.frame_or_window
, f
);
8919 if (window_ptr
!= FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo
)))
8920 SelectWindow (window_ptr
);
8923 ControlPartCode control_part_code
;
8925 Point mouse_loc
= er
.where
;
8927 ControlKind control_kind
;
8930 f
= mac_window_to_frame (window_ptr
);
8931 /* convert to local coordinates of new window */
8932 SetPortWindowPort (window_ptr
);
8934 GlobalToLocal (&mouse_loc
);
8935 #if TARGET_API_MAC_CARBON
8936 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8937 &control_part_code
);
8940 GetControlKind (ch
, &control_kind
);
8943 control_part_code
= FindControl (mouse_loc
, window_ptr
,
8947 #if USE_CARBON_EVENTS
8948 inev
.code
= mac_get_mouse_btn (eventRef
);
8949 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8951 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
8952 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8954 XSETINT (inev
.x
, mouse_loc
.h
);
8955 XSETINT (inev
.y
, mouse_loc
.v
);
8957 if (dpyinfo
->grabbed
&& tracked_scroll_bar
8959 #ifndef USE_TOOLKIT_SCROLL_BARS
8960 /* control_part_code becomes kControlNoPart if
8961 a progress indicator is clicked. */
8962 && control_part_code
!= kControlNoPart
8963 #else /* USE_TOOLKIT_SCROLL_BARS */
8965 && control_kind
.kind
== kControlKindScrollBar
8966 #endif /* MAC_OSX */
8967 #endif /* USE_TOOLKIT_SCROLL_BARS */
8970 struct scroll_bar
*bar
;
8972 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
8974 bar
= tracked_scroll_bar
;
8975 #ifndef USE_TOOLKIT_SCROLL_BARS
8976 control_part_code
= kControlIndicatorPart
;
8980 bar
= (struct scroll_bar
*) GetControlReference (ch
);
8981 #ifdef USE_TOOLKIT_SCROLL_BARS
8982 /* Make the "Ctrl-Mouse-2 splits window" work
8983 for toolkit scroll bars. */
8984 if (er
.modifiers
& controlKey
)
8985 x_scroll_bar_handle_click (bar
, control_part_code
,
8987 else if (er
.what
== mouseDown
)
8988 x_scroll_bar_handle_press (bar
, control_part_code
,
8991 x_scroll_bar_handle_release (bar
, &inev
);
8992 #else /* not USE_TOOLKIT_SCROLL_BARS */
8993 x_scroll_bar_handle_click (bar
, control_part_code
,
8995 if (er
.what
== mouseDown
8996 && control_part_code
== kControlIndicatorPart
)
8997 tracked_scroll_bar
= bar
;
8999 tracked_scroll_bar
= NULL
;
9000 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9005 int x
= mouse_loc
.h
;
9006 int y
= mouse_loc
.v
;
9008 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
9009 if (EQ (window
, f
->tool_bar_window
))
9011 if (er
.what
== mouseDown
)
9012 handle_tool_bar_click (f
, x
, y
, 1, 0);
9014 handle_tool_bar_click (f
, x
, y
, 0,
9020 XSETFRAME (inev
.frame_or_window
, f
);
9021 inev
.kind
= MOUSE_CLICK_EVENT
;
9025 if (er
.what
== mouseDown
)
9027 dpyinfo
->grabbed
|= (1 << inev
.code
);
9028 last_mouse_frame
= f
;
9029 /* Ignore any mouse motion that happened
9030 before this event; any subsequent
9031 mouse-movement Emacs events should reflect
9032 only motion after the ButtonPress. */
9037 last_tool_bar_item
= -1;
9041 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
9042 /* If a button is released though it was not
9043 previously pressed, that would be because
9044 of multi-button emulation. */
9045 dpyinfo
->grabbed
= 0;
9047 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
9050 #ifdef USE_TOOLKIT_SCROLL_BARS
9051 if (inev
.kind
== MOUSE_CLICK_EVENT
)
9056 inev
.modifiers
|= down_modifier
;
9059 inev
.modifiers
|= up_modifier
;
9066 #if TARGET_API_MAC_CARBON
9067 DragWindow (window_ptr
, er
.where
, NULL
);
9068 #else /* not TARGET_API_MAC_CARBON */
9069 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
9070 #endif /* not TARGET_API_MAC_CARBON */
9071 /* Update the frame parameters. */
9073 struct frame
*f
= mac_window_to_frame (window_ptr
);
9075 if (f
&& !f
->async_iconified
)
9076 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
9081 if (TrackGoAway (window_ptr
, er
.where
))
9083 inev
.kind
= DELETE_WINDOW_EVENT
;
9084 XSETFRAME (inev
.frame_or_window
,
9085 mac_window_to_frame (window_ptr
));
9089 /* window resize handling added --ben */
9091 do_grow_window (window_ptr
, &er
);
9094 /* window zoom handling added --ben */
9097 if (TrackBox (window_ptr
, er
.where
, part_code
))
9098 do_zoom_window (window_ptr
, part_code
);
9108 #if USE_CARBON_EVENTS
9109 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9110 != eventNotHandledErr
)
9113 do_window_update ((WindowPtr
) er
.message
);
9118 #if USE_CARBON_EVENTS
9119 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9120 != eventNotHandledErr
)
9123 switch ((er
.message
>> 24) & 0x000000FF)
9125 case suspendResumeMessage
:
9126 if ((er
.message
& resumeFlag
) == 1)
9132 case mouseMovedMessage
:
9133 #if !USE_CARBON_EVENTS
9134 SetRectRgn (mouse_region
, er
.where
.h
, er
.where
.v
,
9135 er
.where
.h
+ 1, er
.where
.v
+ 1);
9137 previous_help_echo_string
= help_echo_string
;
9138 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
9141 if (dpyinfo
->grabbed
&& last_mouse_frame
9142 && FRAME_LIVE_P (last_mouse_frame
))
9143 f
= last_mouse_frame
;
9145 f
= dpyinfo
->x_focus_frame
;
9147 if (dpyinfo
->mouse_face_hidden
)
9149 dpyinfo
->mouse_face_hidden
= 0;
9150 clear_mouse_face (dpyinfo
);
9155 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
9156 Point mouse_pos
= er
.where
;
9158 SetPortWindowPort (wp
);
9160 GlobalToLocal (&mouse_pos
);
9162 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
9163 #ifdef USE_TOOLKIT_SCROLL_BARS
9164 x_scroll_bar_handle_drag (wp
, tracked_scroll_bar
,
9166 #else /* not USE_TOOLKIT_SCROLL_BARS */
9167 x_scroll_bar_note_movement (tracked_scroll_bar
,
9169 - XINT (tracked_scroll_bar
->top
),
9170 er
.when
* (1000 / 60));
9171 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9174 /* Generate SELECT_WINDOW_EVENTs when needed. */
9175 if (mouse_autoselect_window
)
9179 window
= window_from_coordinates (f
,
9184 /* Window will be selected only when it is
9185 not selected now and last mouse movement
9186 event was not in it. Minibuffer window
9187 will be selected iff it is active. */
9188 if (WINDOWP (window
)
9189 && !EQ (window
, last_window
)
9190 && !EQ (window
, selected_window
))
9192 inev
.kind
= SELECT_WINDOW_EVENT
;
9193 inev
.frame_or_window
= window
;
9198 note_mouse_movement (f
, &mouse_pos
);
9202 /* If the contents of the global variable
9203 help_echo_string has changed, generate a
9205 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
9213 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
9215 #if USE_CARBON_EVENTS
9216 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9217 != eventNotHandledErr
)
9220 if (window_ptr
== tip_window
)
9222 HideWindow (tip_window
);
9226 if (!is_emacs_window (window_ptr
))
9229 if ((er
.modifiers
& activeFlag
) != 0)
9231 /* A window has been activated */
9232 Point mouse_loc
= er
.where
;
9234 x_detect_focus_change (dpyinfo
, &er
, &inev
);
9236 SetPortWindowPort (window_ptr
);
9237 GlobalToLocal (&mouse_loc
);
9238 /* Window-activated event counts as mouse movement,
9239 so update things that depend on mouse position. */
9240 note_mouse_movement (mac_window_to_frame (window_ptr
),
9245 /* A window has been deactivated */
9246 #if USE_TOOLKIT_SCROLL_BARS
9247 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
9249 struct input_event event
;
9252 event
.kind
= NO_EVENT
;
9253 x_scroll_bar_handle_release (tracked_scroll_bar
, &event
);
9254 if (event
.kind
!= NO_EVENT
)
9256 event
.timestamp
= timestamp
;
9257 kbd_buffer_store_event_hold (&event
, hold_quit
);
9262 dpyinfo
->grabbed
= 0;
9264 x_detect_focus_change (dpyinfo
, &er
, &inev
);
9266 f
= mac_window_to_frame (window_ptr
);
9267 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9269 /* If we move outside the frame, then we're
9270 certainly no longer on any text in the
9272 clear_mouse_face (dpyinfo
);
9273 dpyinfo
->mouse_face_mouse_frame
= 0;
9276 /* Generate a nil HELP_EVENT to cancel a help-echo.
9277 Do it only if there's something to cancel.
9278 Otherwise, the startup message is cleared when the
9279 mouse leaves the frame. */
9280 if (any_help_event_p
)
9289 int keycode
= (er
.message
& keyCodeMask
) >> 8;
9292 #if USE_CARBON_EVENTS && defined (MAC_OSX)
9293 /* When using Carbon Events, we need to pass raw keyboard
9294 events to the TSM ourselves. If TSM handles it, it
9295 will pass back noErr, otherwise it will pass back
9296 "eventNotHandledErr" and we can process it
9298 if ((!NILP (Vmac_pass_command_to_system
)
9299 || !(er
.modifiers
& cmdKey
))
9300 && (!NILP (Vmac_pass_control_to_system
)
9301 || !(er
.modifiers
& controlKey
))
9302 && (!NILP (Vmac_command_key_is_meta
)
9303 && NILP (Vmac_option_modifier
)
9304 || !(er
.modifiers
& optionKey
)))
9305 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9306 != eventNotHandledErr
)
9311 if (dpyinfo
->x_focus_frame
== NULL
)
9313 /* Beep if keyboard input occurs when all the frames
9321 static SInt16 last_key_script
= -1;
9322 SInt16 current_key_script
= GetScriptManagerVariable (smKeyScript
);
9324 if (last_key_script
!= current_key_script
)
9326 struct input_event event
;
9329 event
.kind
= LANGUAGE_CHANGE_EVENT
;
9331 event
.code
= current_key_script
;
9332 event
.timestamp
= timestamp
;
9333 kbd_buffer_store_event (&event
);
9336 last_key_script
= current_key_script
;
9341 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
9343 clear_mouse_face (dpyinfo
);
9344 dpyinfo
->mouse_face_hidden
= 1;
9347 if (keycode_to_xkeysym (keycode
, &xkeysym
))
9349 inev
.code
= 0xff00 | xkeysym
;
9350 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
9354 if (er
.modifiers
& (controlKey
|
9355 (NILP (Vmac_command_key_is_meta
) ? optionKey
9358 /* This code comes from Keyboard Resource,
9359 Appendix C of IM - Text. This is necessary
9360 since shift is ignored in KCHR table
9361 translation when option or command is pressed.
9362 It also does not translate correctly
9363 control-shift chars like C-% so mask off shift
9365 int new_modifiers
= er
.modifiers
& 0xe600;
9366 /* mask off option and command */
9367 int new_keycode
= keycode
| new_modifiers
;
9368 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
9369 unsigned long some_state
= 0;
9370 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
9371 &some_state
) & 0xff;
9373 else if (!NILP (Vmac_option_modifier
)
9374 && (er
.modifiers
& optionKey
))
9376 /* When using the option key as an emacs modifier,
9377 convert the pressed key code back to one
9378 without the Mac option modifier applied. */
9379 int new_modifiers
= er
.modifiers
& ~optionKey
;
9380 int new_keycode
= keycode
| new_modifiers
;
9381 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
9382 unsigned long some_state
= 0;
9383 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
9384 &some_state
) & 0xff;
9387 inev
.code
= er
.message
& charCodeMask
;
9388 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
9392 #if USE_CARBON_EVENTS
9393 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
9395 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
9397 inev
.modifiers
|= (extra_keyboard_modifiers
9398 & (meta_modifier
| alt_modifier
9399 | hyper_modifier
| super_modifier
));
9400 XSETFRAME (inev
.frame_or_window
, mac_focus_frame (dpyinfo
));
9403 case kHighLevelEvent
:
9404 read_socket_inev
= &inev
;
9405 AEProcessAppleEvent (&er
);
9406 read_socket_inev
= NULL
;
9412 #if USE_CARBON_EVENTS
9413 ReleaseEvent (eventRef
);
9416 if (inev
.kind
!= NO_EVENT
)
9418 inev
.timestamp
= timestamp
;
9419 kbd_buffer_store_event_hold (&inev
, hold_quit
);
9424 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
9429 XSETFRAME (frame
, f
);
9435 any_help_event_p
= 1;
9436 gen_help_event (help_echo_string
, frame
, help_echo_window
,
9437 help_echo_object
, help_echo_pos
);
9441 help_echo_string
= Qnil
;
9442 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
9449 /* If the focus was just given to an autoraising frame,
9451 /* ??? This ought to be able to handle more than one such frame. */
9452 if (pending_autoraise_frame
)
9454 x_raise_frame (pending_autoraise_frame
);
9455 pending_autoraise_frame
= 0;
9463 /* Need to override CodeWarrior's input function so no conversion is
9464 done on newlines Otherwise compiled functions in .elc files will be
9465 read incorrectly. Defined in ...:MSL C:MSL
9466 Common:Source:buffer_io.c. */
9469 __convert_to_newlines (unsigned char * p
, size_t * n
)
9475 __convert_from_newlines (unsigned char * p
, size_t * n
)
9483 make_mac_terminal_frame (struct frame
*f
)
9488 XSETFRAME (frame
, f
);
9490 f
->output_method
= output_mac
;
9491 f
->output_data
.mac
= (struct mac_output
*)
9492 xmalloc (sizeof (struct mac_output
));
9493 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
9495 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
9497 FRAME_COLS (f
) = 96;
9498 FRAME_LINES (f
) = 4;
9500 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
9501 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
9503 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
9505 f
->output_data
.mac
->cursor_pixel
= 0;
9506 f
->output_data
.mac
->border_pixel
= 0x00ff00;
9507 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
9508 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
9510 f
->output_data
.mac
->text_cursor
= kThemeIBeamCursor
;
9511 f
->output_data
.mac
->nontext_cursor
= kThemeArrowCursor
;
9512 f
->output_data
.mac
->modeline_cursor
= kThemeArrowCursor
;
9513 f
->output_data
.mac
->hand_cursor
= kThemePointingHandCursor
;
9514 f
->output_data
.mac
->hourglass_cursor
= kThemeWatchCursor
;
9515 f
->output_data
.mac
->horizontal_drag_cursor
= kThemeResizeLeftRightCursor
;
9517 FRAME_FONTSET (f
) = -1;
9518 f
->output_data
.mac
->explicit_parent
= 0;
9521 f
->border_width
= 0;
9523 f
->internal_border_width
= 0;
9528 f
->new_text_cols
= 0;
9529 f
->new_text_lines
= 0;
9531 SetRect (&r
, f
->left_pos
, f
->top_pos
,
9532 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
9533 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
9537 if (!(FRAME_MAC_WINDOW (f
) =
9538 NewCWindow (NULL
, &r
, "\p", true, dBoxProc
,
9539 (WindowPtr
) -1, 1, (long) f
->output_data
.mac
)))
9541 /* so that update events can find this mac_output struct */
9542 f
->output_data
.mac
->mFP
= f
; /* point back to emacs frame */
9548 /* Need to be initialized for unshow_buffer in window.c. */
9549 selected_window
= f
->selected_window
;
9551 Fmodify_frame_parameters (frame
,
9552 Fcons (Fcons (Qfont
,
9553 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
9554 Fmodify_frame_parameters (frame
,
9555 Fcons (Fcons (Qforeground_color
,
9556 build_string ("black")), Qnil
));
9557 Fmodify_frame_parameters (frame
,
9558 Fcons (Fcons (Qbackground_color
,
9559 build_string ("white")), Qnil
));
9564 /***********************************************************************
9566 ***********************************************************************/
9568 int mac_initialized
= 0;
9571 mac_initialize_display_info ()
9573 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
9574 GDHandle main_device_handle
;
9576 bzero (dpyinfo
, sizeof (*dpyinfo
));
9579 dpyinfo
->mac_id_name
9580 = (char *) xmalloc (SCHARS (Vinvocation_name
)
9581 + SCHARS (Vsystem_name
)
9583 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
9584 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
9586 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
9587 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
9590 main_device_handle
= LMGetMainDevice();
9592 dpyinfo
->reference_count
= 0;
9593 dpyinfo
->resx
= 75.0;
9594 dpyinfo
->resy
= 75.0;
9595 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
9597 /* HasDepth returns true if it is possible to have a 32 bit display,
9598 but this may not be what is actually used. Mac OSX can do better.
9599 CGMainDisplayID is only available on OSX 10.2 and higher, but the
9600 header for CGGetActiveDisplayList says that the first display returned
9601 is the active one, so we use that. */
9603 CGDirectDisplayID disp_id
[1];
9604 CGDisplayCount disp_count
;
9605 CGDisplayErr error_code
;
9607 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
9608 if (error_code
!= 0)
9609 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
9611 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
9614 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
9615 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
9616 gdDevType
, dpyinfo
->color_p
))
9619 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
9620 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
9621 dpyinfo
->grabbed
= 0;
9622 dpyinfo
->root_window
= NULL
;
9623 dpyinfo
->image_cache
= make_image_cache ();
9625 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9626 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9627 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9628 dpyinfo
->mouse_face_window
= Qnil
;
9629 dpyinfo
->mouse_face_overlay
= Qnil
;
9630 dpyinfo
->mouse_face_hidden
= 0;
9635 mac_make_rdb (xrm_option
)
9638 XrmDatabase database
;
9640 database
= xrm_get_preference_database (NULL
);
9642 xrm_merge_string_database (database
, xrm_option
);
9647 struct mac_display_info
*
9648 mac_term_init (display_name
, xrm_option
, resource_name
)
9649 Lisp_Object display_name
;
9651 char *resource_name
;
9653 struct mac_display_info
*dpyinfo
;
9657 if (!mac_initialized
)
9660 mac_initialized
= 1;
9664 error ("Sorry, this version can only handle one display");
9666 mac_initialize_display_info ();
9668 dpyinfo
= &one_mac_display_info
;
9670 dpyinfo
->xrdb
= mac_make_rdb (xrm_option
);
9672 /* Put this display on the chain. */
9673 dpyinfo
->next
= x_display_list
;
9674 x_display_list
= dpyinfo
;
9676 /* Put it on x_display_name_list. */
9677 x_display_name_list
= Fcons (Fcons (display_name
,
9678 Fcons (Qnil
, dpyinfo
->xrdb
)),
9679 x_display_name_list
);
9680 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
9686 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9689 x_delete_display (dpyinfo
)
9690 struct mac_display_info
*dpyinfo
;
9694 /* Discard this display from x_display_name_list and x_display_list.
9695 We can't use Fdelq because that can quit. */
9696 if (! NILP (x_display_name_list
)
9697 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
9698 x_display_name_list
= XCDR (x_display_name_list
);
9703 tail
= x_display_name_list
;
9704 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9706 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9708 XSETCDR (tail
, XCDR (XCDR (tail
)));
9715 if (x_display_list
== dpyinfo
)
9716 x_display_list
= dpyinfo
->next
;
9719 struct x_display_info
*tail
;
9721 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
9722 if (tail
->next
== dpyinfo
)
9723 tail
->next
= tail
->next
->next
;
9726 /* Free the font names in the font table. */
9727 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
9728 if (dpyinfo
->font_table
[i
].name
)
9730 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
9731 xfree (dpyinfo
->font_table
[i
].full_name
);
9732 xfree (dpyinfo
->font_table
[i
].name
);
9735 if (dpyinfo
->font_table
->font_encoder
)
9736 xfree (dpyinfo
->font_table
->font_encoder
);
9738 xfree (dpyinfo
->font_table
);
9739 xfree (dpyinfo
->mac_id_name
);
9741 if (x_display_list
== 0)
9743 mac_clear_font_name_table ();
9744 bzero (dpyinfo
, sizeof (*dpyinfo
));
9753 extern int inhibit_window_system
;
9754 extern int noninteractive
;
9755 CFBundleRef appsBundle
;
9758 /* No need to test if already -nw*/
9759 if (inhibit_window_system
|| noninteractive
)
9762 appsBundle
= CFBundleGetMainBundle();
9763 if (appsBundle
!= NULL
)
9765 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
9766 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
9767 /* We found the bundle identifier, now we know we are valid. */
9774 /* MAC_TODO: Have this start the bundled executable */
9776 /* For now, prevent the fatal error by bringing it up in the terminal */
9777 inhibit_window_system
= 1;
9781 MakeMeTheFrontProcess ()
9783 ProcessSerialNumber psn
;
9786 err
= GetCurrentProcess (&psn
);
9788 (void) SetFrontProcess (&psn
);
9791 /***** Code to handle C-g testing *****/
9793 /* Contains the Mac modifier formed from quit_char */
9794 int mac_quit_char_modifiers
= 0;
9795 int mac_quit_char_keycode
;
9796 extern int quit_char
;
9799 mac_determine_quit_char_modifiers()
9801 /* Todo: Determine modifiers from quit_char. */
9802 UInt32 qc_modifiers
= ctrl_modifier
;
9805 mac_quit_char_modifiers
= 0;
9806 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
9807 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
9808 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
9809 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
9813 init_quit_char_handler ()
9815 /* TODO: Let this support keys other the 'g' */
9816 mac_quit_char_keycode
= 5;
9817 /* Look at <architecture/adb_kb_map.h> for details */
9818 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
9820 mac_determine_quit_char_modifiers();
9824 quit_char_comp (EventRef inEvent
, void *inCompData
)
9826 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
9828 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
9832 UInt32 keyModifiers
;
9833 GetEventParameter(inEvent
, kEventParamKeyCode
,
9834 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
9835 if (keyCode
!= mac_quit_char_keycode
)
9837 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
9838 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
9839 if (keyModifiers
!= mac_quit_char_modifiers
)
9846 mac_check_for_quit_char ()
9849 static EMACS_TIME last_check_time
= { 0, 0 };
9850 static EMACS_TIME one_second
= { 1, 0 };
9853 /* If windows are not initialized, return immediately (keep it bouncin'). */
9854 if (!mac_quit_char_modifiers
)
9857 /* Don't check if last check is less than a second ago. */
9858 EMACS_GET_TIME (now
);
9859 EMACS_SUB_TIME (t
, now
, last_check_time
);
9860 if (EMACS_TIME_LT (t
, one_second
))
9862 last_check_time
= now
;
9864 /* Redetermine modifiers because they are based on lisp variables */
9865 mac_determine_quit_char_modifiers ();
9867 /* Fill the queue with events */
9869 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
9870 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
9875 struct input_event e
;
9877 /* Use an input_event to emulate what the interrupt handler does. */
9879 e
.kind
= ASCII_KEYSTROKE_EVENT
;
9883 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
9884 XSETFRAME (e
.frame_or_window
, mac_focus_frame (&one_mac_display_info
));
9885 /* Remove event from queue to prevent looping. */
9886 RemoveEventFromQueue (GetMainEventQueue (), event
);
9887 ReleaseEvent (event
);
9888 kbd_buffer_store_event (&e
);
9891 #endif /* MAC_OSX */
9899 MenuItemIndex menu_index
;
9901 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandQuit
, 1,
9902 &menu
, &menu_index
);
9904 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
9905 #if USE_CARBON_EVENTS
9906 EnableMenuCommand (NULL
, kHICommandPreferences
);
9907 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandPreferences
, 1,
9908 &menu
, &menu_index
);
9911 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
9912 InsertMenuItemTextWithCFString (menu
, NULL
,
9913 0, kMenuItemAttrSeparator
, 0);
9914 InsertMenuItemTextWithCFString (menu
, CFSTR ("About Emacs"),
9915 0, 0, kHICommandAbout
);
9917 #endif /* USE_CARBON_EVENTS */
9918 #else /* !MAC_OSX */
9919 #if USE_CARBON_EVENTS
9920 SetMenuItemCommandID (GetMenuHandle (M_APPLE
), I_ABOUT
, kHICommandAbout
);
9926 /* Set up use of X before we make the first connection. */
9928 extern frame_parm_handler mac_frame_parm_handlers
[];
9930 static struct redisplay_interface x_redisplay_interface
=
9932 mac_frame_parm_handlers
,
9936 x_clear_end_of_line
,
9938 x_after_update_window_line
,
9939 x_update_window_begin
,
9940 x_update_window_end
,
9943 0, /* flush_display_optional */
9944 x_clear_window_mouse_face
,
9945 x_get_glyph_overhangs
,
9946 x_fix_overlapping_area
,
9947 x_draw_fringe_bitmap
,
9948 0, /* define_fringe_bitmap */
9949 0, /* destroy_fringe_bitmap */
9950 mac_per_char_metric
,
9952 mac_compute_glyph_string_overhangs
,
9953 x_draw_glyph_string
,
9954 mac_define_frame_cursor
,
9955 mac_clear_frame_area
,
9956 mac_draw_window_cursor
,
9957 mac_draw_vertical_window_border
,
9958 mac_shift_glyphs_for_insert
9964 rif
= &x_redisplay_interface
;
9966 clear_frame_hook
= x_clear_frame
;
9967 ins_del_lines_hook
= x_ins_del_lines
;
9968 delete_glyphs_hook
= x_delete_glyphs
;
9969 ring_bell_hook
= XTring_bell
;
9970 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9971 set_terminal_modes_hook
= XTset_terminal_modes
;
9972 update_begin_hook
= x_update_begin
;
9973 update_end_hook
= x_update_end
;
9974 set_terminal_window_hook
= XTset_terminal_window
;
9975 read_socket_hook
= XTread_socket
;
9976 frame_up_to_date_hook
= XTframe_up_to_date
;
9977 mouse_position_hook
= XTmouse_position
;
9978 frame_rehighlight_hook
= XTframe_rehighlight
;
9979 frame_raise_lower_hook
= XTframe_raise_lower
;
9981 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9982 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9983 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9984 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9986 scroll_region_ok
= 1; /* we'll scroll partial frames */
9987 char_ins_del_ok
= 1;
9988 line_ins_del_ok
= 1; /* we'll just blt 'em */
9989 fast_clear_end_of_line
= 1; /* X does this well */
9990 memory_below_frame
= 0; /* we don't remember what scrolls
9994 last_tool_bar_item
= -1;
9995 any_help_event_p
= 0;
9997 /* Try to use interrupt input; if we can't, then start polling. */
9998 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
10002 #if TARGET_API_MAC_CARBON
10003 init_required_apple_events ();
10005 #if USE_CARBON_EVENTS
10007 init_service_handler ();
10009 init_quit_char_handler ();
10010 #endif /* MAC_OSX */
10012 init_command_handler ();
10015 #endif /* USE_CARBON_EVENTS */
10018 if (!inhibit_window_system
)
10019 MakeMeTheFrontProcess ();
10030 staticpro (&x_error_message_string
);
10031 x_error_message_string
= Qnil
;
10034 Qmodifier_value
= intern ("modifier-value");
10035 Qalt
= intern ("alt");
10036 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
10037 Qhyper
= intern ("hyper");
10038 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
10039 Qsuper
= intern ("super");
10040 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
10042 Qapplication
= intern ("application"); staticpro (&Qapplication
);
10043 Qabout
= intern ("about"); staticpro (&Qabout
);
10045 #if USE_CARBON_EVENTS && defined (MAC_OSX)
10046 Qpreferences
= intern ("preferences"); staticpro (&Qpreferences
);
10047 Qservices
= intern ("services"); staticpro (&Qservices
);
10048 Qpaste
= intern ("paste"); staticpro (&Qpaste
);
10049 Qperform
= intern ("perform"); staticpro (&Qperform
);
10053 Fprovide (intern ("mac-carbon"), Qnil
);
10056 staticpro (&Qreverse
);
10057 Qreverse
= intern ("reverse");
10059 staticpro (&x_display_name_list
);
10060 x_display_name_list
= Qnil
;
10062 staticpro (&last_mouse_scroll_bar
);
10063 last_mouse_scroll_bar
= Qnil
;
10065 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
10066 staticpro (&Qmac_ready_for_drag_n_drop
);
10068 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10069 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
10070 #ifdef USE_TOOLKIT_SCROLL_BARS
10071 Vx_toolkit_scroll_bars
= Qt
;
10073 Vx_toolkit_scroll_bars
= Qnil
;
10076 staticpro (&last_mouse_motion_frame
);
10077 last_mouse_motion_frame
= Qnil
;
10079 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
10080 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
10081 Otherwise the option key is used. */);
10082 Vmac_command_key_is_meta
= Qt
;
10084 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
10085 doc
: /* Modifier to use for the Mac alt/option key. The value can
10086 be alt, hyper, or super for the respective modifier. If the value is
10087 nil then the key will act as the normal Mac option modifier. */);
10088 Vmac_option_modifier
= Qnil
;
10090 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
10091 doc
: /* Non-nil means that the control and meta keys are reversed. This is
10092 useful for non-standard keyboard layouts. */);
10093 Vmac_reverse_ctrl_meta
= Qnil
;
10095 DEFVAR_LISP ("mac-emulate-three-button-mouse",
10096 &Vmac_emulate_three_button_mouse
,
10097 doc
: /* t means that when the option-key is held down while pressing the
10098 mouse button, the click will register as mouse-2 and while the
10099 command-key is held down, the click will register as mouse-3.
10100 'reverse means that the option-key will register for mouse-3
10101 and the command-key will register for mouse-2. nil means that
10102 no emulation should be done and the modifiers should be placed
10103 on the mouse-1 event. */);
10104 Vmac_emulate_three_button_mouse
= Qnil
;
10106 #if USE_CARBON_EVENTS
10107 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
10108 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
10109 the right click will be mouse-3.
10110 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
10111 Vmac_wheel_button_is_mouse_2
= Qt
;
10113 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
10114 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
10115 Toolbox for processing before Emacs sees it. */);
10116 Vmac_pass_command_to_system
= Qt
;
10118 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
10119 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
10120 Toolbox for processing before Emacs sees it. */);
10121 Vmac_pass_control_to_system
= Qt
;
10125 DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics
,
10126 doc
: /* If non-nil, allow anti-aliasing.
10127 The text will be rendered using Core Graphics text rendering which
10128 may anti-alias the text. */);
10129 Vmac_use_core_graphics
= Qnil
;
10131 /* Register an entry for `mac-roman' so that it can be used when
10132 creating the terminal frame on Mac OS 9 before loading
10133 term/mac-win.elc. */
10134 DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist
,
10135 doc
: /* Alist linking Emacs character sets to Mac text encoding and Emacs coding system.
10136 Each entry should be of the form:
10138 (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
10140 where CHARSET-NAME is a string used in font names to identify the
10141 charset, TEXT-ENCODING is a TextEncodingBase value, and CODING_SYSTEM
10142 is a coding system corresponding to TEXT-ENCODING. */);
10143 Vmac_charset_info_alist
=
10144 Fcons (list3 (build_string ("mac-roman"),
10145 make_number (smRoman
), Qnil
), Qnil
);
10148 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
10149 (do not change this comment) */