1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005, 2006 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 */
75 #include "dispextern.h"
77 #include "termhooks.h"
84 #include "intervals.h"
90 /* Non-nil means Emacs uses toolkit scroll bars. */
92 Lisp_Object Vx_toolkit_scroll_bars
;
94 /* If non-zero, the text will be rendered using Core Graphics text
95 rendering which may anti-alias the text. */
96 int mac_use_core_graphics
;
99 /* Non-zero means that a HELP_EVENT has been generated since Emacs
102 static int any_help_event_p
;
104 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
105 static Lisp_Object last_window
;
107 /* Non-zero means make use of UNDERLINE_POSITION font properties.
108 (Not yet supported.) */
109 int x_use_underline_position_properties
;
111 /* Non-zero means to draw the underline at the same place as the descent line. */
113 int x_underline_at_descent_line
;
115 /* This is a chain of structures for all the X displays currently in
118 struct x_display_info
*x_display_list
;
120 /* This is a list of cons cells, each of the form (NAME
121 FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
122 x_display_list and in the same order. NAME is the name of the
123 frame. FONT-LIST-CACHE records previous values returned by
124 x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
125 equivalent, which is implemented with a Lisp object, for the
128 Lisp_Object x_display_name_list
;
130 /* This is display since Mac does not support multiple ones. */
131 struct mac_display_info one_mac_display_info
;
133 /* Frame being updated by update_frame. This is declared in term.c.
134 This is set by update_begin and looked at by all the XT functions.
135 It is zero while not inside an update. In that case, the XT
136 functions assume that `selected_frame' is the frame to apply to. */
138 extern struct frame
*updating_frame
;
140 /* This is a frame waiting to be auto-raised, within XTread_socket. */
142 struct frame
*pending_autoraise_frame
;
146 Formerly, we used PointerMotionHintMask (in standard_event_mask)
147 so that we would have to call XQueryPointer after each MotionNotify
148 event to ask for another such event. However, this made mouse tracking
149 slow, and there was a bug that made it eventually stop.
151 Simply asking for MotionNotify all the time seems to work better.
153 In order to avoid asking for motion events and then throwing most
154 of them away or busy-polling the server for mouse positions, we ask
155 the server for pointer motion hints. This means that we get only
156 one event per group of mouse movements. "Groups" are delimited by
157 other kinds of events (focus changes and button clicks, for
158 example), or by XQueryPointer calls; when one of these happens, we
159 get another MotionNotify event the next time the mouse moves. This
160 is at least as efficient as getting motion events when mouse
161 tracking is on, and I suspect only negligibly worse when tracking
164 /* Where the mouse was last time we reported a mouse event. */
166 static Rect last_mouse_glyph
;
167 static FRAME_PTR last_mouse_glyph_frame
;
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 extern Lisp_Object Qeql
;
205 /* A mask of extra modifier bits to put into every keyboard char. */
207 extern EMACS_INT extra_keyboard_modifiers
;
209 /* The keysyms to use for the various modifiers. */
211 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qcontrol
, Qmeta
, Qmodifier_value
;
213 extern int inhibit_window_system
;
215 #if __MRC__ && !TARGET_API_MAC_CARBON
216 QDGlobals qd
; /* QuickDraw global information structure. */
219 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
221 struct mac_display_info
*mac_display_info_for_display (Display
*);
222 static void x_update_window_end
P_ ((struct window
*, int, int));
223 int x_catch_errors
P_ ((Display
*));
224 void x_uncatch_errors
P_ ((Display
*, int));
225 void x_lower_frame
P_ ((struct frame
*));
226 void x_scroll_bar_clear
P_ ((struct frame
*));
227 int x_had_errors_p
P_ ((Display
*));
228 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
229 void x_raise_frame
P_ ((struct frame
*));
230 void x_set_window_size
P_ ((struct frame
*, int, int, int));
231 void x_wm_set_window_state
P_ ((struct frame
*, int));
232 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
233 void mac_initialize
P_ ((void));
234 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
235 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
236 static void x_update_end
P_ ((struct frame
*));
237 static void XTframe_up_to_date
P_ ((struct frame
*));
238 static void XTset_terminal_modes
P_ ((void));
239 static void XTreset_terminal_modes
P_ ((void));
240 static void x_clear_frame
P_ ((void));
241 static void frame_highlight
P_ ((struct frame
*));
242 static void frame_unhighlight
P_ ((struct frame
*));
243 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
244 static void mac_focus_changed
P_ ((int, struct mac_display_info
*,
245 struct frame
*, struct input_event
*));
246 static void x_detect_focus_change
P_ ((struct mac_display_info
*,
247 EventRecord
*, struct input_event
*));
248 static void XTframe_rehighlight
P_ ((struct frame
*));
249 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
250 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
251 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
252 enum text_cursor_kinds
));
254 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
255 static void x_flush
P_ ((struct frame
*f
));
256 static void x_update_begin
P_ ((struct frame
*));
257 static void x_update_window_begin
P_ ((struct window
*));
258 static void x_after_update_window_line
P_ ((struct glyph_row
*));
259 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
260 enum scroll_bar_part
*,
261 Lisp_Object
*, Lisp_Object
*,
264 static int is_emacs_window
P_ ((WindowPtr
));
265 static XCharStruct
*mac_per_char_metric
P_ ((XFontStruct
*, XChar2b
*, int));
266 static void XSetFont
P_ ((Display
*, GC
, XFontStruct
*));
268 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
269 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
270 #define GC_FONT(gc) ((gc)->xgcv.font)
271 #define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc)
272 #define CG_SET_FILL_COLOR(context, color) \
273 CGContextSetRGBFillColor (context, \
274 RED_FROM_ULONG (color) / 255.0f, \
275 GREEN_FROM_ULONG (color) / 255.0f, \
276 BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
277 #define CG_SET_STROKE_COLOR(context, color) \
278 CGContextSetRGBStrokeColor (context, \
279 RED_FROM_ULONG (color) / 255.0f, \
280 GREEN_FROM_ULONG (color) / 255.0f, \
281 BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
283 #define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
285 /* Fringe bitmaps. */
287 static int max_fringe_bmp
= 0;
288 static CGImageRef
*fringe_bmp
= 0;
291 mac_begin_cg_clip (f
, gc
)
295 CGContextRef context
= FRAME_CG_CONTEXT (f
);
299 QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f
)), &context
);
300 FRAME_CG_CONTEXT (f
) = context
;
303 CGContextSaveGState (context
);
304 CGContextTranslateCTM (context
, 0, FRAME_PIXEL_HEIGHT (f
));
305 CGContextScaleCTM (context
, 1, -1);
306 if (gc
&& gc
->n_clip_rects
)
307 CGContextClipToRects (context
, gc
->clip_rects
, gc
->n_clip_rects
);
316 CGContextRestoreGState (FRAME_CG_CONTEXT (f
));
320 mac_prepare_for_quickdraw (f
)
325 Lisp_Object rest
, frame
;
326 FOR_EACH_FRAME (rest
, frame
)
327 if (FRAME_MAC_P (XFRAME (frame
)))
328 mac_prepare_for_quickdraw (XFRAME (frame
));
332 CGContextRef context
= FRAME_CG_CONTEXT (f
);
336 CGContextSynchronize (context
);
337 QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f
)),
338 &FRAME_CG_CONTEXT (f
));
344 static RgnHandle saved_port_clip_region
= NULL
;
350 static RgnHandle new_region
= NULL
;
352 if (saved_port_clip_region
== NULL
)
353 saved_port_clip_region
= NewRgn ();
354 if (new_region
== NULL
)
355 new_region
= NewRgn ();
357 if (gc
->n_clip_rects
)
359 GetClip (saved_port_clip_region
);
360 SectRgn (saved_port_clip_region
, gc
->clip_region
, new_region
);
361 SetClip (new_region
);
369 if (gc
->n_clip_rects
)
370 SetClip (saved_port_clip_region
);
374 /* X display function emulation */
377 XFreePixmap (display
, pixmap
)
378 Display
*display
; /* not used */
381 DisposeGWorld (pixmap
);
385 /* Mac version of XDrawLine. */
388 mac_draw_line (f
, gc
, x1
, y1
, x2
, y2
)
394 CGContextRef context
;
395 float gx1
= x1
, gy1
= y1
, gx2
= x2
, gy2
= y2
;
398 gx1
+= 0.5f
, gx2
+= 0.5f
;
400 gy1
+= 0.5f
, gy2
+= 0.5f
;
402 context
= mac_begin_cg_clip (f
, gc
);
403 CG_SET_STROKE_COLOR (context
, gc
->xgcv
.foreground
);
404 CGContextBeginPath (context
);
405 CGContextMoveToPoint (context
, gx1
, gy1
);
406 CGContextAddLineToPoint (context
, gx2
, gy2
);
407 CGContextClosePath (context
);
408 CGContextStrokePath (context
);
426 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
428 RGBForeColor (GC_FORE_COLOR (gc
));
438 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
462 GetGWorld (&old_port
, &old_gdh
);
465 RGBForeColor (GC_FORE_COLOR (gc
));
467 LockPixels (GetGWorldPixMap (p
));
470 UnlockPixels (GetGWorldPixMap (p
));
472 SetGWorld (old_port
, old_gdh
);
477 mac_erase_rectangle (f
, gc
, x
, y
, width
, height
)
481 unsigned int width
, height
;
484 CGContextRef context
;
486 context
= mac_begin_cg_clip (f
, gc
);
487 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
488 CGContextFillRect (context
, CGRectMake (x
, y
, width
, height
));
493 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
495 RGBBackColor (GC_BACK_COLOR (gc
));
496 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
502 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
507 /* Mac version of XClearArea. */
510 mac_clear_area (f
, x
, y
, width
, height
)
513 unsigned int width
, height
;
515 mac_erase_rectangle (f
, FRAME_NORMAL_GC (f
), x
, y
, width
, height
);
518 /* Mac version of XClearWindow. */
525 CGContextRef context
;
526 GC gc
= FRAME_NORMAL_GC (f
);
528 context
= mac_begin_cg_clip (f
, NULL
);
529 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
530 CGContextFillRect (context
, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f
),
531 FRAME_PIXEL_HEIGHT (f
)));
534 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
536 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
538 #if TARGET_API_MAC_CARBON
542 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
545 #else /* not TARGET_API_MAC_CARBON */
546 EraseRect (&(FRAME_MAC_WINDOW (f
)->portRect
));
547 #endif /* not TARGET_API_MAC_CARBON */
552 /* Mac replacement for XCopyArea. */
556 mac_draw_cg_image (image
, f
, gc
, src_x
, src_y
, width
, height
,
557 dest_x
, dest_y
, overlay_p
)
562 unsigned int width
, height
;
563 int dest_x
, dest_y
, overlay_p
;
565 CGContextRef context
;
566 float port_height
= FRAME_PIXEL_HEIGHT (f
);
567 CGRect dest_rect
= CGRectMake (dest_x
, dest_y
, width
, height
);
569 context
= mac_begin_cg_clip (f
, gc
);
572 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
573 CGContextFillRect (context
, dest_rect
);
575 CGContextClipToRect (context
, dest_rect
);
576 CGContextScaleCTM (context
, 1, -1);
577 CGContextTranslateCTM (context
, 0, -port_height
);
578 if (CGImageIsMask (image
))
579 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
580 CGContextDrawImage (context
,
581 CGRectMake (dest_x
- src_x
,
582 port_height
- (dest_y
- src_y
583 + CGImageGetHeight (image
)),
584 CGImageGetWidth (image
),
585 CGImageGetHeight (image
)),
590 #else /* !USE_CG_DRAWING */
593 mac_draw_bitmap (f
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
596 int x
, y
, width
, height
;
597 unsigned short *bits
;
603 bitmap
.rowBytes
= sizeof(unsigned short);
604 bitmap
.baseAddr
= (char *)bits
;
605 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
607 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
609 RGBForeColor (GC_FORE_COLOR (gc
));
610 RGBBackColor (GC_BACK_COLOR (gc
));
611 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
614 #if TARGET_API_MAC_CARBON
620 CopyBits (&bitmap
, GetPortBitMapForCopyBits (port
),
621 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
622 UnlockPortBits (port
);
624 #else /* not TARGET_API_MAC_CARBON */
625 CopyBits (&bitmap
, &(FRAME_MAC_WINDOW (f
)->portBits
), &(bitmap
.bounds
), &r
,
626 overlay_p
? srcOr
: srcCopy
, 0);
627 #endif /* not TARGET_API_MAC_CARBON */
630 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
632 #endif /* !USE_CG_DRAWING */
635 /* Mac replacement for XCreateBitmapFromBitmapData. */
638 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
643 static unsigned char swap_nibble
[16]
644 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
645 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
646 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
647 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
651 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
652 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
653 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
654 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
655 for (i
= 0; i
< h
; i
++)
657 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
658 for (j
= 0; j
< w1
; j
++)
660 /* Bitswap XBM bytes to match how Mac does things. */
661 unsigned char c
= *bits
++;
662 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
663 | (swap_nibble
[(c
>>4) & 0xf]));;
667 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
672 mac_free_bitmap (bitmap
)
675 xfree (bitmap
->baseAddr
);
680 XCreatePixmap (display
, w
, width
, height
, depth
)
681 Display
*display
; /* not used */
683 unsigned int width
, height
;
690 SetPortWindowPort (w
);
692 SetRect (&r
, 0, 0, width
, height
);
693 #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
696 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
697 #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
699 /* CreateCGImageFromPixMaps requires ARGB format. */
700 err
= QTNewGWorld (&pixmap
, k32ARGBPixelFormat
, &r
, NULL
, NULL
, 0);
709 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
710 Display
*display
; /* not used */
713 unsigned int width
, height
;
714 unsigned long fg
, bg
;
721 static GC gc
= NULL
; /* not reentrant */
724 gc
= XCreateGC (display
, w
, 0, NULL
);
726 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
730 GetGWorld (&old_port
, &old_gdh
);
731 SetGWorld (pixmap
, NULL
);
732 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
733 XSetForeground (display
, gc
, fg
);
734 XSetBackground (display
, gc
, bg
);
735 RGBForeColor (GC_FORE_COLOR (gc
));
736 RGBBackColor (GC_BACK_COLOR (gc
));
737 LockPixels (GetGWorldPixMap (pixmap
));
738 #if TARGET_API_MAC_CARBON
739 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
740 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
741 #else /* not TARGET_API_MAC_CARBON */
742 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
743 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
744 #endif /* not TARGET_API_MAC_CARBON */
745 UnlockPixels (GetGWorldPixMap (pixmap
));
746 SetGWorld (old_port
, old_gdh
);
747 mac_free_bitmap (&bitmap
);
753 /* Mac replacement for XFillRectangle. */
756 mac_fill_rectangle (f
, gc
, x
, y
, width
, height
)
760 unsigned int width
, height
;
763 CGContextRef context
;
765 context
= mac_begin_cg_clip (f
, gc
);
766 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
767 CGContextFillRect (context
, CGRectMake (x
, y
, width
, height
));
772 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
774 RGBForeColor (GC_FORE_COLOR (gc
));
775 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
778 PaintRect (&r
); /* using foreground color of gc */
784 /* Mac replacement for XDrawRectangle: dest is a window. */
787 mac_draw_rectangle (f
, gc
, x
, y
, width
, height
)
791 unsigned int width
, height
;
794 CGContextRef context
;
796 context
= mac_begin_cg_clip (f
, gc
);
797 CG_SET_STROKE_COLOR (context
, gc
->xgcv
.foreground
);
798 CGContextStrokeRect (context
,
799 CGRectMake (x
+ 0.5f
, y
+ 0.5f
, width
, height
));
804 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
806 RGBForeColor (GC_FORE_COLOR (gc
));
807 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
810 FrameRect (&r
); /* using foreground color of gc */
818 atsu_get_text_layout_with_text_ptr (text
, text_length
, style
, text_layout
)
819 ConstUniCharArrayPtr text
;
820 UniCharCount text_length
;
822 ATSUTextLayout
*text_layout
;
825 static ATSUTextLayout saved_text_layout
= NULL
; /* not reentrant */
827 if (saved_text_layout
== NULL
)
829 UniCharCount lengths
[] = {kATSUToTextEnd
};
830 ATSUAttributeTag tags
[] = {kATSULineLayoutOptionsTag
};
831 ByteCount sizes
[] = {sizeof (ATSLineLayoutOptions
)};
832 static ATSLineLayoutOptions line_layout
=
833 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
834 kATSLineDisableAllLayoutOperations
| kATSLineUseDeviceMetrics
835 | kATSLineUseQDRendering
837 kATSLineIsDisplayOnly
| kATSLineFractDisable
840 ATSUAttributeValuePtr values
[] = {&line_layout
};
842 err
= ATSUCreateTextLayoutWithTextPtr (text
,
843 kATSUFromTextBeginning
,
849 err
= ATSUSetLayoutControls (saved_text_layout
,
850 sizeof (tags
) / sizeof (tags
[0]),
851 tags
, sizes
, values
);
852 /* XXX: Should we do this? */
854 err
= ATSUSetTransientFontMatching (saved_text_layout
, true);
858 err
= ATSUSetRunStyle (saved_text_layout
, style
,
859 kATSUFromTextBeginning
, kATSUToTextEnd
);
861 err
= ATSUSetTextPointerLocation (saved_text_layout
, text
,
862 kATSUFromTextBeginning
,
868 *text_layout
= saved_text_layout
;
875 mac_invert_rectangle (f
, x
, y
, width
, height
)
878 unsigned int width
, height
;
883 mac_prepare_for_quickdraw (f
);
885 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
887 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
894 mac_draw_string_common (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
895 overstrike_p
, bytes_per_char
)
900 int nchars
, bg_width
, overstrike_p
, bytes_per_char
;
902 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
905 if (GC_FONT (gc
)->mac_style
)
908 ATSUTextLayout text_layout
;
910 xassert (bytes_per_char
== 2);
912 #ifndef WORDS_BIG_ENDIAN
915 UniChar
*text
= (UniChar
*)buf
;
917 for (i
= 0; i
< nchars
; i
++)
918 text
[i
] = EndianU16_BtoN (text
[i
]);
921 err
= atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr
)buf
,
923 GC_FONT (gc
)->mac_style
,
928 if (!mac_use_core_graphics
)
932 mac_prepare_for_quickdraw (f
);
935 RGBForeColor (GC_FORE_COLOR (gc
));
940 SetRect (&r
, x
, y
- FONT_BASE (GC_FONT (gc
)),
941 x
+ bg_width
, y
+ FONT_DESCENT (GC_FONT (gc
)));
942 RGBBackColor (GC_BACK_COLOR (gc
));
944 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
947 ATSUDrawText (text_layout
,
948 kATSUFromTextBeginning
, kATSUToTextEnd
,
949 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
953 ATSUDrawText (text_layout
,
954 kATSUFromTextBeginning
, kATSUToTextEnd
,
955 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
963 CGContextRef context
;
964 float port_height
= FRAME_PIXEL_HEIGHT (f
);
965 ATSUAttributeTag tags
[] = {kATSUCGContextTag
};
966 ByteCount sizes
[] = {sizeof (CGContextRef
)};
967 ATSUAttributeValuePtr values
[] = {&context
};
970 context
= mac_begin_cg_clip (f
, gc
);
973 QDBeginCGContext (port
, &context
);
974 if (gc
->n_clip_rects
|| bg_width
)
976 CGContextTranslateCTM (context
, 0, port_height
);
977 CGContextScaleCTM (context
, 1, -1);
978 if (gc
->n_clip_rects
)
979 CGContextClipToRects (context
, gc
->clip_rects
,
984 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
987 CGRectMake (x
, y
- FONT_BASE (GC_FONT (gc
)),
988 bg_width
, FONT_HEIGHT (GC_FONT (gc
))));
990 CGContextScaleCTM (context
, 1, -1);
991 CGContextTranslateCTM (context
, 0, -port_height
);
995 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
996 err
= ATSUSetLayoutControls (text_layout
,
997 sizeof (tags
) / sizeof (tags
[0]),
998 tags
, sizes
, values
);
1001 ATSUDrawText (text_layout
,
1002 kATSUFromTextBeginning
, kATSUToTextEnd
,
1003 Long2Fix (x
), Long2Fix (port_height
- y
));
1005 ATSUDrawText (text_layout
,
1006 kATSUFromTextBeginning
, kATSUToTextEnd
,
1007 Long2Fix (x
+ 1), Long2Fix (port_height
- y
));
1010 mac_end_cg_clip (f
);
1013 CGContextSynchronize (context
);
1014 QDEndCGContext (port
, &context
);
1017 /* This doesn't work on Mac OS X 10.1. */
1018 ATSUClearLayoutControls (text_layout
,
1019 sizeof (tags
) / sizeof (tags
[0]), tags
);
1021 ATSUSetLayoutControls (text_layout
,
1022 sizeof (tags
) / sizeof (tags
[0]),
1023 tags
, sizes
, values
);
1026 #endif /* MAC_OSX */
1029 #endif /* USE_ATSUI */
1031 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1034 if (mac_use_core_graphics
)
1035 savedFlags
= SwapQDTextFlags (kQDUseCGTextRendering
);
1038 mac_prepare_for_quickdraw (f
);
1040 mac_begin_clip (gc
);
1041 RGBForeColor (GC_FORE_COLOR (gc
));
1045 RGBBackColor (GC_BACK_COLOR (gc
));
1051 /* We prefer not to use srcCopy text transfer mode on Mac OS X
1053 - Screen is double-buffered. (In srcCopy mode, a text is
1054 drawn into an offscreen graphics world first. So
1055 performance gain cannot be expected.)
1056 - It lowers rendering quality.
1057 - Some fonts leave garbage on cursor movement. */
1062 RGBBackColor (GC_BACK_COLOR (gc
));
1063 SetRect (&r
, x
, y
- FONT_BASE (GC_FONT (gc
)),
1064 x
+ bg_width
, y
+ FONT_DESCENT (GC_FONT (gc
)));
1069 TextFont (GC_FONT (gc
)->mac_fontnum
);
1070 TextSize (GC_FONT (gc
)->mac_fontsize
);
1071 TextFace (GC_FONT (gc
)->mac_fontface
);
1073 DrawText (buf
, 0, nchars
* bytes_per_char
);
1078 DrawText (buf
, 0, nchars
* bytes_per_char
);
1081 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1084 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1085 if (mac_use_core_graphics
)
1086 SwapQDTextFlags(savedFlags
);
1092 /* Mac replacement for XDrawImageString. */
1095 mac_draw_image_string (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1100 int nchars
, bg_width
, overstrike_p
;
1102 mac_draw_string_common (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
1107 /* Mac replacement for XDrawImageString16. */
1110 mac_draw_image_string_16 (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1115 int nchars
, bg_width
, overstrike_p
;
1117 mac_draw_string_common (f
, gc
, x
, y
, (char *) buf
, nchars
, bg_width
,
1122 /* Mac replacement for XQueryTextExtents, but takes a character. If
1123 STYLE is NULL, measurement is done by QuickDraw Text routines for
1124 the font of the current graphics port. If CG_GLYPH is not NULL,
1125 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
1128 mac_query_char_extents (style
, c
,
1129 font_ascent_return
, font_descent_return
,
1130 overall_return
, cg_glyph
)
1137 int *font_ascent_return
, *font_descent_return
;
1138 XCharStruct
*overall_return
;
1139 #if USE_CG_TEXT_DRAWING
1145 OSStatus err
= noErr
;
1152 ATSUTextLayout text_layout
;
1155 err
= atsu_get_text_layout_with_text_ptr (&ch
, 1, style
, &text_layout
);
1158 ATSTrapezoid glyph_bounds
;
1160 err
= ATSUGetGlyphBounds (text_layout
, 0, 0,
1161 kATSUFromTextBeginning
, kATSUToTextEnd
,
1162 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1163 kATSUseFractionalOrigins
,
1165 kATSUseDeviceOrigins
,
1167 1, &glyph_bounds
, NULL
);
1170 xassert (glyph_bounds
.lowerRight
.x
- glyph_bounds
.lowerLeft
.x
1171 == glyph_bounds
.upperRight
.x
- glyph_bounds
.upperLeft
.x
);
1173 width
= Fix2Long (glyph_bounds
.upperRight
.x
1174 - glyph_bounds
.upperLeft
.x
);
1175 if (font_ascent_return
)
1176 *font_ascent_return
= -Fix2Long (glyph_bounds
.upperLeft
.y
);
1177 if (font_descent_return
)
1178 *font_descent_return
= Fix2Long (glyph_bounds
.lowerLeft
.y
);
1181 if (err
== noErr
&& overall_return
)
1183 err
= ATSUMeasureTextImage (text_layout
,
1184 kATSUFromTextBeginning
, kATSUToTextEnd
,
1185 0, 0, &char_bounds
);
1187 STORE_XCHARSTRUCT (*overall_return
, width
, char_bounds
);
1188 #if USE_CG_TEXT_DRAWING
1189 if (err
== noErr
&& cg_glyph
)
1192 ATSUGlyphInfoArray glyph_info_array
;
1193 ByteCount count
= sizeof (ATSUGlyphInfoArray
);
1195 err1
= ATSUMatchFontsToText (text_layout
, kATSUFromTextBeginning
,
1196 kATSUToTextEnd
, NULL
, NULL
, NULL
);
1198 err1
= ATSUGetGlyphInfo (text_layout
, kATSUFromTextBeginning
,
1199 kATSUToTextEnd
, &count
,
1202 /* Make sure that we don't have to make layout
1204 && glyph_info_array
.glyphs
[0].deltaY
== 0.0f
1205 && glyph_info_array
.glyphs
[0].idealX
== 0.0f
1206 && glyph_info_array
.glyphs
[0].screenX
== 0)
1208 xassert (glyph_info_array
.glyphs
[0].glyphID
);
1209 *cg_glyph
= glyph_info_array
.glyphs
[0].glyphID
;
1220 if (font_ascent_return
|| font_descent_return
)
1224 GetFontInfo (&font_info
);
1225 if (font_ascent_return
)
1226 *font_ascent_return
= font_info
.ascent
;
1227 if (font_descent_return
)
1228 *font_descent_return
= font_info
.descent
;
1234 width
= CharWidth (ch
);
1235 QDTextBounds (1, &ch
, &char_bounds
);
1236 STORE_XCHARSTRUCT (*overall_return
, width
, char_bounds
);
1244 /* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
1247 mac_text_extents_16 (font_struct
, string
, nchars
, overall_return
)
1248 XFontStruct
*font_struct
;
1251 XCharStruct
*overall_return
;
1254 short width
= 0, lbearing
= 0, rbearing
= 0;
1257 for (i
= 0; i
< nchars
; i
++)
1259 pcm
= mac_per_char_metric (font_struct
, string
, 0);
1261 width
+= FONT_WIDTH (font_struct
);
1264 lbearing
= min (lbearing
, width
+ pcm
->lbearing
);
1265 rbearing
= max (rbearing
, width
+ pcm
->rbearing
);
1266 width
+= pcm
->width
;
1271 overall_return
->lbearing
= lbearing
;
1272 overall_return
->rbearing
= rbearing
;
1273 overall_return
->width
= width
;
1275 /* What's the meaning of the return value of XTextExtents16? */
1279 #if USE_CG_TEXT_DRAWING
1280 static int cg_text_anti_aliasing_threshold
= 8;
1283 init_cg_text_anti_aliasing_threshold ()
1289 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
1290 kCFPreferencesCurrentApplication
,
1293 cg_text_anti_aliasing_threshold
= threshold
;
1297 mac_draw_image_string_cg (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1302 int nchars
, bg_width
, overstrike_p
;
1305 float port_height
, gx
, gy
;
1307 CGContextRef context
;
1311 if (!mac_use_core_graphics
|| GC_FONT (gc
)->cg_font
== NULL
)
1314 port
= GetWindowPort (FRAME_MAC_WINDOW (f
));
1315 port_height
= FRAME_PIXEL_HEIGHT (f
);
1317 gy
= port_height
- y
;
1318 glyphs
= (CGGlyph
*)buf
;
1319 advances
= alloca (sizeof (CGSize
) * nchars
);
1320 if (advances
== NULL
)
1322 for (i
= 0; i
< nchars
; i
++)
1324 XCharStruct
*pcm
= mac_per_char_metric (GC_FONT (gc
), buf
, 0);
1326 advances
[i
].width
= pcm
->width
;
1327 advances
[i
].height
= 0;
1328 glyphs
[i
] = GC_FONT (gc
)->cg_glyphs
[buf
->byte2
];
1333 context
= mac_begin_cg_clip (f
, gc
);
1335 QDBeginCGContext (port
, &context
);
1336 if (gc
->n_clip_rects
|| bg_width
)
1338 CGContextTranslateCTM (context
, 0, port_height
);
1339 CGContextScaleCTM (context
, 1, -1);
1340 if (gc
->n_clip_rects
)
1341 CGContextClipToRects (context
, gc
->clip_rects
, gc
->n_clip_rects
);
1345 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
1348 CGRectMake (gx
, y
- FONT_BASE (GC_FONT (gc
)),
1349 bg_width
, FONT_HEIGHT (GC_FONT (gc
))));
1351 CGContextScaleCTM (context
, 1, -1);
1352 CGContextTranslateCTM (context
, 0, -port_height
);
1356 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
1357 CGContextSetFont (context
, GC_FONT (gc
)->cg_font
);
1358 CGContextSetFontSize (context
, GC_FONT (gc
)->mac_fontsize
);
1359 if (GC_FONT (gc
)->mac_fontsize
<= cg_text_anti_aliasing_threshold
)
1360 CGContextSetShouldAntialias (context
, false);
1361 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1362 CGContextSetTextPosition (context
, gx
, gy
);
1363 CGContextShowGlyphsWithAdvances (context
, glyphs
, advances
, nchars
);
1366 CGContextSetTextPosition (context
, gx
+ 1.0f
, gy
);
1367 CGContextShowGlyphsWithAdvances (context
, glyphs
, advances
, nchars
);
1370 for (i
= 0; i
< nchars
; i
++)
1372 CGContextShowGlyphsAtPoint (context
, gx
, gy
, glyphs
+ i
, 1);
1374 CGContextShowGlyphsAtPoint (context
, gx
+ 1.0f
, gy
, glyphs
+ i
, 1);
1375 gx
+= advances
[i
].width
;
1379 mac_end_cg_clip (f
);
1381 CGContextSynchronize (context
);
1382 QDEndCGContext (port
, &context
);
1391 /* Mac replacement for XCopyArea: dest must be window. */
1394 mac_copy_area (src
, f
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1399 unsigned int width
, height
;
1404 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1406 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1407 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1409 ForeColor (blackColor
);
1410 BackColor (whiteColor
);
1412 mac_begin_clip (gc
);
1413 LockPixels (GetGWorldPixMap (src
));
1414 #if TARGET_API_MAC_CARBON
1419 LockPortBits (port
);
1420 CopyBits (GetPortBitMapForCopyBits (src
),
1421 GetPortBitMapForCopyBits (port
),
1422 &src_r
, &dest_r
, srcCopy
, 0);
1423 UnlockPortBits (port
);
1425 #else /* not TARGET_API_MAC_CARBON */
1426 CopyBits (&(((GrafPtr
)src
)->portBits
), &(FRAME_MAC_WINDOW (f
)->portBits
),
1427 &src_r
, &dest_r
, srcCopy
, 0);
1428 #endif /* not TARGET_API_MAC_CARBON */
1429 UnlockPixels (GetGWorldPixMap (src
));
1432 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1437 mac_copy_area_with_mask (src
, mask
, f
, gc
, src_x
, src_y
,
1438 width
, height
, dest_x
, dest_y
)
1443 unsigned int width
, height
;
1448 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1450 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1451 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1453 ForeColor (blackColor
);
1454 BackColor (whiteColor
);
1456 mac_begin_clip (gc
);
1457 LockPixels (GetGWorldPixMap (src
));
1458 LockPixels (GetGWorldPixMap (mask
));
1459 #if TARGET_API_MAC_CARBON
1464 LockPortBits (port
);
1465 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1466 GetPortBitMapForCopyBits (port
),
1467 &src_r
, &src_r
, &dest_r
);
1468 UnlockPortBits (port
);
1470 #else /* not TARGET_API_MAC_CARBON */
1471 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1472 &(FRAME_MAC_WINDOW (f
)->portBits
), &src_r
, &src_r
, &dest_r
);
1473 #endif /* not TARGET_API_MAC_CARBON */
1474 UnlockPixels (GetGWorldPixMap (mask
));
1475 UnlockPixels (GetGWorldPixMap (src
));
1478 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1480 #endif /* !USE_CG_DRAWING */
1483 /* Mac replacement for XCopyArea: used only for scrolling. */
1486 mac_scroll_area (f
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1490 unsigned int width
, height
;
1493 #if TARGET_API_MAC_CARBON
1495 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
1497 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1499 mac_prepare_for_quickdraw (f
);
1501 ScrollWindowRect (FRAME_MAC_WINDOW (f
),
1502 &src_r
, dest_x
- src_x
, dest_y
- src_y
,
1503 kScrollWindowNoOptions
, dummy
);
1505 #else /* not TARGET_API_MAC_CARBON */
1507 WindowPtr w
= FRAME_MAC_WINDOW (f
);
1511 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1512 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1514 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1515 color mapping in CopyBits. Otherwise, it will be slow. */
1516 ForeColor (blackColor
);
1517 BackColor (whiteColor
);
1518 mac_begin_clip (gc
);
1519 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1522 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1523 #endif /* not TARGET_API_MAC_CARBON */
1527 /* Mac replacement for XChangeGC. */
1530 XChangeGC (display
, gc
, mask
, xgcv
)
1536 if (mask
& GCForeground
)
1537 XSetForeground (display
, gc
, xgcv
->foreground
);
1538 if (mask
& GCBackground
)
1539 XSetBackground (display
, gc
, xgcv
->background
);
1541 XSetFont (display
, gc
, xgcv
->font
);
1545 /* Mac replacement for XCreateGC. */
1548 XCreateGC (display
, window
, mask
, xgcv
)
1554 GC gc
= xmalloc (sizeof (*gc
));
1556 bzero (gc
, sizeof (*gc
));
1557 XChangeGC (display
, gc
, mask
, xgcv
);
1563 /* Used in xfaces.c. */
1566 XFreeGC (display
, gc
)
1570 if (gc
->clip_region
)
1571 DisposeRgn (gc
->clip_region
);
1576 /* Mac replacement for XGetGCValues. */
1579 XGetGCValues (display
, gc
, mask
, xgcv
)
1585 if (mask
& GCForeground
)
1586 xgcv
->foreground
= gc
->xgcv
.foreground
;
1587 if (mask
& GCBackground
)
1588 xgcv
->background
= gc
->xgcv
.background
;
1590 xgcv
->font
= gc
->xgcv
.font
;
1594 /* Mac replacement for XSetForeground. */
1597 XSetForeground (display
, gc
, color
)
1600 unsigned long color
;
1602 if (gc
->xgcv
.foreground
!= color
)
1604 gc
->xgcv
.foreground
= color
;
1605 gc
->fore_color
.red
= RED16_FROM_ULONG (color
);
1606 gc
->fore_color
.green
= GREEN16_FROM_ULONG (color
);
1607 gc
->fore_color
.blue
= BLUE16_FROM_ULONG (color
);
1612 /* Mac replacement for XSetBackground. */
1615 XSetBackground (display
, gc
, color
)
1618 unsigned long color
;
1620 if (gc
->xgcv
.background
!= color
)
1622 gc
->xgcv
.background
= color
;
1623 gc
->back_color
.red
= RED16_FROM_ULONG (color
);
1624 gc
->back_color
.green
= GREEN16_FROM_ULONG (color
);
1625 gc
->back_color
.blue
= BLUE16_FROM_ULONG (color
);
1630 /* Mac replacement for XSetFont. */
1633 XSetFont (display
, gc
, font
)
1638 gc
->xgcv
.font
= font
;
1642 /* Mac replacement for XSetClipRectangles. */
1645 mac_set_clip_rectangles (display
, gc
, rectangles
, n
)
1653 xassert (n
>= 0 && n
<= MAX_CLIP_RECTS
);
1655 gc
->n_clip_rects
= n
;
1658 if (gc
->clip_region
== NULL
)
1659 gc
->clip_region
= NewRgn ();
1660 RectRgn (gc
->clip_region
, rectangles
);
1663 RgnHandle region
= NewRgn ();
1665 for (i
= 1; i
< n
; i
++)
1667 RectRgn (region
, rectangles
+ i
);
1668 UnionRgn (gc
->clip_region
, region
, gc
->clip_region
);
1670 DisposeRgn (region
);
1673 #if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING)
1674 for (i
= 0; i
< n
; i
++)
1676 Rect
*rect
= rectangles
+ i
;
1678 gc
->clip_rects
[i
] = CGRectMake (rect
->left
, rect
->top
,
1679 rect
->right
- rect
->left
,
1680 rect
->bottom
- rect
->top
);
1686 /* Mac replacement for XSetClipMask. */
1689 mac_reset_clip_rectangles (display
, gc
)
1693 gc
->n_clip_rects
= 0;
1697 /* Mac replacement for XSetWindowBackground. */
1700 XSetWindowBackground (display
, w
, color
)
1703 unsigned long color
;
1705 #if !TARGET_API_MAC_CARBON
1706 AuxWinHandle aw_handle
;
1707 CTabHandle ctab_handle
;
1708 ColorSpecPtr ct_table
;
1713 bg_color
.red
= RED16_FROM_ULONG (color
);
1714 bg_color
.green
= GREEN16_FROM_ULONG (color
);
1715 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
1717 #if TARGET_API_MAC_CARBON
1718 SetWindowContentColor (w
, &bg_color
);
1720 if (GetAuxWin (w
, &aw_handle
))
1722 ctab_handle
= (*aw_handle
)->awCTable
;
1723 HandToHand ((Handle
*) &ctab_handle
);
1724 ct_table
= (*ctab_handle
)->ctTable
;
1725 ct_size
= (*ctab_handle
)->ctSize
;
1726 while (ct_size
> -1)
1728 if (ct_table
->value
== 0)
1730 ct_table
->rgb
= bg_color
;
1731 CTabChanged (ctab_handle
);
1732 SetWinColor (w
, (WCTabHandle
) ctab_handle
);
1740 /* Flush display of frame F, or of all frames if F is null. */
1746 #if TARGET_API_MAC_CARBON
1749 mac_prepare_for_quickdraw (f
);
1752 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1754 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1760 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1761 Calls to XFlush should be unnecessary because the X output buffer
1762 is flushed automatically as needed by calls to XPending,
1763 XNextEvent, or XWindowEvent according to the XFlush man page.
1764 XTread_socket calls XPending. Removing XFlush improves
1767 #define XFlush(DISPLAY) (void) 0
1770 /* Return the struct mac_display_info corresponding to DPY. There's
1773 struct mac_display_info
*
1774 mac_display_info_for_display (dpy
)
1777 return &one_mac_display_info
;
1782 /***********************************************************************
1783 Starting and ending an update
1784 ***********************************************************************/
1786 /* Start an update of frame F. This function is installed as a hook
1787 for update_begin, i.e. it is called when update_begin is called.
1788 This function is called prior to calls to x_update_window_begin for
1789 each window being updated. */
1795 #if TARGET_API_MAC_CARBON
1796 /* During update of a frame, availability of input events is
1797 periodically checked with ReceiveNextEvent if
1798 redisplay-dont-pause is nil. That normally flushes window buffer
1799 changes for every check, and thus screen update looks waving even
1800 if no input is available. So we disable screen updates during
1801 update of a frame. */
1803 DisableScreenUpdates ();
1809 /* Start update of window W. Set the global variable updated_window
1810 to the window being updated and set output_cursor to the cursor
1814 x_update_window_begin (w
)
1817 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1818 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1821 set_output_cursor (&w
->cursor
);
1825 if (f
== display_info
->mouse_face_mouse_frame
)
1827 /* Don't do highlighting for mouse motion during the update. */
1828 display_info
->mouse_face_defer
= 1;
1830 /* If F needs to be redrawn, simply forget about any prior mouse
1832 if (FRAME_GARBAGED_P (f
))
1833 display_info
->mouse_face_window
= Qnil
;
1835 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1836 their mouse_face_p flag set, which means that they are always
1837 unequal to rows in a desired matrix which never have that
1838 flag set. So, rows containing mouse-face glyphs are never
1839 scrolled, and we don't have to switch the mouse highlight off
1840 here to prevent it from being scrolled. */
1842 /* Can we tell that this update does not affect the window
1843 where the mouse highlight is? If so, no need to turn off.
1844 Likewise, don't do anything if the frame is garbaged;
1845 in that case, the frame's current matrix that we would use
1846 is all wrong, and we will redisplay that line anyway. */
1847 if (!NILP (display_info
->mouse_face_window
)
1848 && w
== XWINDOW (display_info
->mouse_face_window
))
1852 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1853 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1856 if (i
< w
->desired_matrix
->nrows
)
1857 clear_mouse_face (display_info
);
1866 /* Draw a vertical window border from (x,y0) to (x,y1) */
1869 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1873 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1876 face
= FACE_FROM_ID (f
, VERTICAL_BORDER_FACE_ID
);
1878 XSetForeground (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
1881 mac_draw_line (f
, f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1884 /* End update of window W (which is equal to updated_window).
1886 Draw vertical borders between horizontally adjacent windows, and
1887 display W's cursor if CURSOR_ON_P is non-zero.
1889 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1890 glyphs in mouse-face were overwritten. In that case we have to
1891 make sure that the mouse-highlight is properly redrawn.
1893 W may be a menu bar pseudo-window in case we don't have X toolkit
1894 support. Such windows don't have a cursor, so don't display it
1898 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1900 int cursor_on_p
, mouse_face_overwritten_p
;
1902 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1904 if (!w
->pseudo_window_p
)
1909 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1911 output_cursor
.x
, output_cursor
.y
);
1913 if (draw_window_fringes (w
, 1))
1914 x_draw_vertical_border (w
);
1919 /* If a row with mouse-face was overwritten, arrange for
1920 XTframe_up_to_date to redisplay the mouse highlight. */
1921 if (mouse_face_overwritten_p
)
1923 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1924 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1925 dpyinfo
->mouse_face_window
= Qnil
;
1928 updated_window
= NULL
;
1932 /* End update of frame F. This function is installed as a hook in
1939 /* Mouse highlight may be displayed again. */
1940 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1943 #if TARGET_API_MAC_CARBON
1944 EnableScreenUpdates ();
1946 XFlush (FRAME_MAC_DISPLAY (f
));
1951 /* This function is called from various places in xdisp.c whenever a
1952 complete update has been performed. The global variable
1953 updated_window is not available here. */
1956 XTframe_up_to_date (f
)
1959 if (FRAME_MAC_P (f
))
1961 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1963 if (dpyinfo
->mouse_face_deferred_gc
1964 || f
== dpyinfo
->mouse_face_mouse_frame
)
1967 if (dpyinfo
->mouse_face_mouse_frame
)
1968 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1969 dpyinfo
->mouse_face_mouse_x
,
1970 dpyinfo
->mouse_face_mouse_y
);
1971 dpyinfo
->mouse_face_deferred_gc
= 0;
1978 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1979 arrow bitmaps, or clear the fringes if no bitmaps are required
1980 before DESIRED_ROW is made current. The window being updated is
1981 found in updated_window. This function is called from
1982 update_window_line only if it is known that there are differences
1983 between bitmaps to be drawn between current row and DESIRED_ROW. */
1986 x_after_update_window_line (desired_row
)
1987 struct glyph_row
*desired_row
;
1989 struct window
*w
= updated_window
;
1995 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1996 desired_row
->redraw_fringe_bitmaps_p
= 1;
1998 /* When a window has disappeared, make sure that no rest of
1999 full-width rows stays visible in the internal border. Could
2000 check here if updated_window is the leftmost/rightmost window,
2001 but I guess it's not worth doing since vertically split windows
2002 are almost never used, internal border is rarely set, and the
2003 overhead is very small. */
2004 if (windows_or_buffers_changed
2005 && desired_row
->full_width_p
2006 && (f
= XFRAME (w
->frame
),
2007 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
2009 && (height
= desired_row
->visible_height
,
2012 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
2014 /* Internal border is drawn below the tool bar. */
2015 if (WINDOWP (f
->tool_bar_window
)
2016 && w
== XWINDOW (f
->tool_bar_window
))
2020 mac_clear_area (f
, 0, y
, width
, height
);
2021 mac_clear_area (f
, FRAME_PIXEL_WIDTH (f
) - width
, y
, width
, height
);
2027 /* Draw the bitmap WHICH in one of the left or right fringes of
2028 window W. ROW is the glyph row for which to display the bitmap; it
2029 determines the vertical position at which the bitmap has to be
2033 x_draw_fringe_bitmap (w
, row
, p
)
2035 struct glyph_row
*row
;
2036 struct draw_fringe_bitmap_params
*p
;
2038 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2039 Display
*display
= FRAME_MAC_DISPLAY (f
);
2040 struct face
*face
= p
->face
;
2043 /* Must clip because of partially visible lines. */
2044 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
2047 /* Adjust position of "bottom aligned" bitmap on partially
2048 visible last row. */
2050 int oldVH
= row
->visible_height
;
2051 row
->visible_height
= p
->h
;
2052 row
->y
-= rowY
- p
->y
;
2053 x_clip_to_row (w
, row
, -1, face
->gc
);
2055 row
->visible_height
= oldVH
;
2058 x_clip_to_row (w
, row
, -1, face
->gc
);
2060 if (p
->bx
>= 0 && !p
->overlay_p
)
2062 #if 0 /* MAC_TODO: stipple */
2063 /* In case the same realized face is used for fringes and
2064 for something displayed in the text (e.g. face `region' on
2065 mono-displays, the fill style may have been changed to
2066 FillSolid in x_draw_glyph_string_background. */
2068 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
2070 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
2073 mac_erase_rectangle (f
, face
->gc
, p
->bx
, p
->by
, p
->nx
, p
->ny
);
2075 #if 0 /* MAC_TODO: stipple */
2077 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
2083 && p
->which
< max_fringe_bmp
2089 XGetGCValues (display
, face
->gc
, GCForeground
, &gcv
);
2090 XSetForeground (display
, face
->gc
,
2092 ? (p
->overlay_p
? face
->background
2093 : f
->output_data
.mac
->cursor_pixel
)
2094 : face
->foreground
));
2096 mac_draw_cg_image (fringe_bmp
[p
->which
], f
, face
->gc
, 0, p
->dh
,
2097 p
->wd
, p
->h
, p
->x
, p
->y
, p
->overlay_p
);
2099 mac_draw_bitmap (f
, face
->gc
, p
->x
, p
->y
,
2100 p
->wd
, p
->h
, p
->bits
+ p
->dh
, p
->overlay_p
);
2102 XSetForeground (display
, face
->gc
, gcv
.foreground
);
2105 mac_reset_clip_rectangles (display
, face
->gc
);
2110 mac_define_fringe_bitmap (which
, bits
, h
, wd
)
2112 unsigned short *bits
;
2116 CGDataProviderRef provider
;
2118 if (which
>= max_fringe_bmp
)
2121 max_fringe_bmp
= which
+ 20;
2122 fringe_bmp
= (CGImageRef
*) xrealloc (fringe_bmp
, max_fringe_bmp
* sizeof (CGImageRef
));
2123 while (i
< max_fringe_bmp
)
2124 fringe_bmp
[i
++] = 0;
2127 for (i
= 0; i
< h
; i
++)
2129 provider
= CGDataProviderCreateWithData (NULL
, bits
,
2130 sizeof (unsigned short) * h
, NULL
);
2133 fringe_bmp
[which
] = CGImageMaskCreate (wd
, h
, 1, 1,
2134 sizeof (unsigned short),
2136 CGDataProviderRelease (provider
);
2141 mac_destroy_fringe_bitmap (which
)
2144 if (which
>= max_fringe_bmp
)
2147 if (fringe_bmp
[which
])
2148 CGImageRelease (fringe_bmp
[which
]);
2149 fringe_bmp
[which
] = 0;
2154 /* This is called when starting Emacs and when restarting after
2155 suspend. When starting Emacs, no window is mapped. And nothing
2156 must be done to Emacs's own window if it is suspended (though that
2160 XTset_terminal_modes ()
2164 /* This is called when exiting or suspending Emacs. Exiting will make
2165 the windows go away, and suspending requires no action. */
2168 XTreset_terminal_modes ()
2174 /***********************************************************************
2176 ***********************************************************************/
2178 /* Function prototypes of this page. */
2180 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
2181 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
2185 pcm_init (pcm
, count
)
2189 bzero (pcm
, sizeof (XCharStruct
) * count
);
2190 while (--count
>= 0)
2192 pcm
->descent
= PCM_INVALID
;
2197 static enum pcm_status
2198 pcm_get_status (pcm
)
2201 int height
= pcm
->ascent
+ pcm
->descent
;
2203 /* Negative height means some special status. */
2204 return height
>= 0 ? PCM_VALID
: height
;
2207 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
2208 is not contained in the font. */
2210 static INLINE XCharStruct
*
2211 x_per_char_metric (font
, char2b
)
2215 /* The result metric information. */
2216 XCharStruct
*pcm
= NULL
;
2218 xassert (font
&& char2b
);
2221 if (font
->mac_style
)
2223 XCharStruct
**row
= font
->bounds
.rows
+ char2b
->byte1
;
2227 *row
= xmalloc (sizeof (XCharStruct
) * 0x100);
2228 pcm_init (*row
, 0x100);
2230 pcm
= *row
+ char2b
->byte2
;
2231 if (pcm_get_status (pcm
) != PCM_VALID
)
2234 mac_query_char_extents (font
->mac_style
,
2235 (char2b
->byte1
<< 8) + char2b
->byte2
,
2236 NULL
, NULL
, pcm
, NULL
);
2243 if (font
->bounds
.per_char
!= NULL
)
2245 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
2247 /* min_char_or_byte2 specifies the linear character index
2248 corresponding to the first element of the per_char array,
2249 max_char_or_byte2 is the index of the last character. A
2250 character with non-zero CHAR2B->byte1 is not in the font.
2251 A character with byte2 less than min_char_or_byte2 or
2252 greater max_char_or_byte2 is not in the font. */
2253 if (char2b
->byte1
== 0
2254 && char2b
->byte2
>= font
->min_char_or_byte2
2255 && char2b
->byte2
<= font
->max_char_or_byte2
)
2256 pcm
= font
->bounds
.per_char
2257 + (char2b
->byte2
- font
->min_char_or_byte2
);
2261 /* If either min_byte1 or max_byte1 are nonzero, both
2262 min_char_or_byte2 and max_char_or_byte2 are less than
2263 256, and the 2-byte character index values corresponding
2264 to the per_char array element N (counting from 0) are:
2266 byte1 = N/D + min_byte1
2267 byte2 = N\D + min_char_or_byte2
2271 D = max_char_or_byte2 - min_char_or_byte2 + 1
2272 / = integer division
2273 \ = integer modulus */
2274 if (char2b
->byte1
>= font
->min_byte1
2275 && char2b
->byte1
<= font
->max_byte1
2276 && char2b
->byte2
>= font
->min_char_or_byte2
2277 && char2b
->byte2
<= font
->max_char_or_byte2
)
2279 pcm
= (font
->bounds
.per_char
2280 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
2281 * (char2b
->byte1
- font
->min_byte1
))
2282 + (char2b
->byte2
- font
->min_char_or_byte2
));
2288 /* If the per_char pointer is null, all glyphs between the first
2289 and last character indexes inclusive have the same
2290 information, as given by both min_bounds and max_bounds. */
2291 if (char2b
->byte2
>= font
->min_char_or_byte2
2292 && char2b
->byte2
<= font
->max_char_or_byte2
)
2293 pcm
= &font
->max_bounds
;
2299 return ((pcm
== NULL
2301 #if 0 /* Show hollow boxes for zero-width glyphs such as combining diacritics. */
2302 && (pcm
->rbearing
- pcm
->lbearing
) == 0
2311 static XCharStruct
*
2312 mac_per_char_metric (font
, char2b
, font_type
)
2317 return x_per_char_metric (font
, char2b
);
2321 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
2322 the two-byte form of C. Encoding is returned in *CHAR2B. */
2325 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
2328 struct font_info
*font_info
;
2331 int charset
= CHAR_CHARSET (c
);
2332 XFontStruct
*font
= font_info
->font
;
2334 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
2335 This may be either a program in a special encoder language or a
2337 if (font_info
->font_encoder
)
2339 /* It's a program. */
2340 struct ccl_program
*ccl
= font_info
->font_encoder
;
2342 check_ccl_update (ccl
);
2343 if (CHARSET_DIMENSION (charset
) == 1)
2345 ccl
->reg
[0] = charset
;
2346 ccl
->reg
[1] = char2b
->byte2
;
2351 ccl
->reg
[0] = charset
;
2352 ccl
->reg
[1] = char2b
->byte1
;
2353 ccl
->reg
[2] = char2b
->byte2
;
2356 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
2358 /* We assume that MSBs are appropriately set/reset by CCL
2360 if (font
->max_byte1
== 0) /* 1-byte font */
2361 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
2363 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
2365 else if (font_info
->encoding
[charset
])
2367 /* Fixed encoding scheme. See fontset.h for the meaning of the
2368 encoding numbers. */
2369 int enc
= font_info
->encoding
[charset
];
2371 if ((enc
== 1 || enc
== 2)
2372 && CHARSET_DIMENSION (charset
) == 2)
2373 char2b
->byte1
|= 0x80;
2375 if (enc
== 1 || enc
== 3)
2376 char2b
->byte2
|= 0x80;
2382 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
2383 char2b
->byte1
= sjis1
;
2384 char2b
->byte2
= sjis2
;
2389 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2391 return FONT_TYPE_UNKNOWN
;
2396 /***********************************************************************
2398 ***********************************************************************/
2402 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2403 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2404 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2406 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2407 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2408 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2409 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2410 static void mac_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2411 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2412 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2413 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2414 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
2415 unsigned long *, double, int));*/
2416 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2417 double, int, unsigned long));
2418 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2419 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2420 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2421 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2422 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2424 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2425 int, int, int, int, int, int,
2427 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2428 int, int, int, Rect
*));
2431 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2435 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2440 struct glyph_string
*s
;
2442 if (s
->font
== FRAME_FONT (s
->f
)
2443 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2444 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2446 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
2449 /* Cursor on non-default face: must merge. */
2453 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
2454 xgcv
.foreground
= s
->face
->background
;
2456 /* If the glyph would be invisible, try a different foreground. */
2457 if (xgcv
.foreground
== xgcv
.background
)
2458 xgcv
.foreground
= s
->face
->foreground
;
2459 if (xgcv
.foreground
== xgcv
.background
)
2460 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
2461 if (xgcv
.foreground
== xgcv
.background
)
2462 xgcv
.foreground
= s
->face
->foreground
;
2464 /* Make sure the cursor is distinct from text in this face. */
2465 if (xgcv
.background
== s
->face
->background
2466 && xgcv
.foreground
== s
->face
->foreground
)
2468 xgcv
.background
= s
->face
->foreground
;
2469 xgcv
.foreground
= s
->face
->background
;
2472 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2473 xgcv
.font
= s
->font
;
2474 mask
= GCForeground
| GCBackground
| GCFont
;
2476 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2477 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2480 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2481 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2483 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2488 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2491 x_set_mouse_face_gc (s
)
2492 struct glyph_string
*s
;
2497 /* What face has to be used last for the mouse face? */
2498 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2499 face
= FACE_FROM_ID (s
->f
, face_id
);
2501 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2503 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2504 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2506 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2507 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2508 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2510 /* If font in this face is same as S->font, use it. */
2511 if (s
->font
== s
->face
->font
)
2512 s
->gc
= s
->face
->gc
;
2515 /* Otherwise construct scratch_cursor_gc with values from FACE
2520 xgcv
.background
= s
->face
->background
;
2521 xgcv
.foreground
= s
->face
->foreground
;
2522 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2523 xgcv
.font
= s
->font
;
2524 mask
= GCForeground
| GCBackground
| GCFont
;
2526 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2527 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2530 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2531 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2533 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2536 xassert (s
->gc
!= 0);
2540 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2541 Faces to use in the mode line have already been computed when the
2542 matrix was built, so there isn't much to do, here. */
2545 x_set_mode_line_face_gc (s
)
2546 struct glyph_string
*s
;
2548 s
->gc
= s
->face
->gc
;
2552 /* Set S->gc of glyph string S for drawing that glyph string. Set
2553 S->stippled_p to a non-zero value if the face of S has a stipple
2557 x_set_glyph_string_gc (s
)
2558 struct glyph_string
*s
;
2560 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2562 if (s
->hl
== DRAW_NORMAL_TEXT
)
2564 s
->gc
= s
->face
->gc
;
2565 s
->stippled_p
= s
->face
->stipple
!= 0;
2567 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2569 x_set_mode_line_face_gc (s
);
2570 s
->stippled_p
= s
->face
->stipple
!= 0;
2572 else if (s
->hl
== DRAW_CURSOR
)
2574 x_set_cursor_gc (s
);
2577 else if (s
->hl
== DRAW_MOUSE_FACE
)
2579 x_set_mouse_face_gc (s
);
2580 s
->stippled_p
= s
->face
->stipple
!= 0;
2582 else if (s
->hl
== DRAW_IMAGE_RAISED
2583 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2585 s
->gc
= s
->face
->gc
;
2586 s
->stippled_p
= s
->face
->stipple
!= 0;
2590 s
->gc
= s
->face
->gc
;
2591 s
->stippled_p
= s
->face
->stipple
!= 0;
2594 /* GC must have been set. */
2595 xassert (s
->gc
!= 0);
2599 /* Set clipping for output of glyph string S. S may be part of a mode
2600 line or menu if we don't have X toolkit support. */
2603 x_set_glyph_string_clipping (s
)
2604 struct glyph_string
*s
;
2606 Rect rects
[MAX_CLIP_RECTS
];
2609 n
= get_glyph_string_clip_rects (s
, rects
, MAX_CLIP_RECTS
);
2610 mac_set_clip_rectangles (s
->display
, s
->gc
, rects
, n
);
2615 Compute left and right overhang of glyph string S. If S is a glyph
2616 string for a composition, assume overhangs don't exist. */
2619 mac_compute_glyph_string_overhangs (s
)
2620 struct glyph_string
*s
;
2622 if (!(s
->cmp
== NULL
2623 && s
->first_glyph
->type
== CHAR_GLYPH
))
2628 || s
->font
->mac_style
2634 mac_text_extents_16 (s
->font
, s
->char2b
, s
->nchars
, &cs
);
2635 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2636 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2641 MacFontStruct
*font
= s
->font
;
2644 mac_prepare_for_quickdraw (s
->f
);
2646 SetPortWindowPort (FRAME_MAC_WINDOW (s
->f
));
2648 TextFont (font
->mac_fontnum
);
2649 TextSize (font
->mac_fontsize
);
2650 TextFace (font
->mac_fontface
);
2652 QDTextBounds (s
->nchars
* 2, (char *)s
->char2b
, &r
);
2654 s
->right_overhang
= r
.right
> s
->width
? r
.right
- s
->width
: 0;
2655 s
->left_overhang
= r
.left
< 0 ? -r
.left
: 0;
2660 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2663 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2664 struct glyph_string
*s
;
2667 mac_erase_rectangle (s
->f
, s
->gc
, x
, y
, w
, h
);
2671 /* Draw the background of glyph_string S. If S->background_filled_p
2672 is non-zero don't draw it. FORCE_P non-zero means draw the
2673 background even if it wouldn't be drawn normally. This is used
2674 when a string preceding S draws into the background of S, or S
2675 contains the first component of a composition. */
2678 x_draw_glyph_string_background (s
, force_p
)
2679 struct glyph_string
*s
;
2682 /* Nothing to do if background has already been drawn or if it
2683 shouldn't be drawn in the first place. */
2684 if (!s
->background_filled_p
)
2686 int box_line_width
= max (s
->face
->box_line_width
, 0);
2688 #if 0 /* MAC_TODO: stipple */
2691 /* Fill background with a stipple pattern. */
2692 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2693 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2694 s
->y
+ box_line_width
,
2695 s
->background_width
,
2696 s
->height
- 2 * box_line_width
);
2697 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2698 s
->background_filled_p
= 1;
2702 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2703 || s
->font_not_found_p
2704 || s
->extends_to_end_of_line_p
2707 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2708 s
->background_width
,
2709 s
->height
- 2 * box_line_width
);
2710 s
->background_filled_p
= 1;
2716 /* Draw the foreground of glyph string S. */
2719 x_draw_glyph_string_foreground (s
)
2720 struct glyph_string
*s
;
2724 /* If first glyph of S has a left box line, start drawing the text
2725 of S to the right of that box line. */
2726 if (s
->face
->box
!= FACE_NO_BOX
2727 && s
->first_glyph
->left_box_line_p
)
2728 x
= s
->x
+ abs (s
->face
->box_line_width
);
2732 /* Draw characters of S as rectangles if S's font could not be
2734 if (s
->font_not_found_p
)
2736 for (i
= 0; i
< s
->nchars
; ++i
)
2738 struct glyph
*g
= s
->first_glyph
+ i
;
2739 mac_draw_rectangle (s
->f
, s
->gc
, x
, s
->y
,
2740 g
->pixel_width
- 1, s
->height
- 1);
2741 x
+= g
->pixel_width
;
2746 char *char1b
= (char *) s
->char2b
;
2747 int boff
= s
->font_info
->baseline_offset
;
2749 if (s
->font_info
->vertical_centering
)
2750 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2752 /* If we can use 8-bit functions, condense S->char2b. */
2755 && GC_FONT (s
->gc
)->mac_style
== NULL
2758 for (i
= 0; i
< s
->nchars
; ++i
)
2759 char1b
[i
] = s
->char2b
[i
].byte2
;
2761 /* Draw text with XDrawString if background has already been
2762 filled. Otherwise, use XDrawImageString. (Note that
2763 XDrawImageString is usually faster than XDrawString.) Always
2764 use XDrawImageString when drawing the cursor so that there is
2765 no chance that characters under a box cursor are invisible. */
2767 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2768 bg_width
= 0; /* Corresponds to XDrawString. */
2770 bg_width
= s
->background_width
; /* Corresponds to XDrawImageString. */
2774 || GC_FONT (s
->gc
)->mac_style
2777 #if USE_CG_TEXT_DRAWING
2779 && mac_draw_image_string_cg (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2780 s
->char2b
, s
->nchars
, bg_width
,
2781 s
->face
->overstrike
))
2785 mac_draw_image_string_16 (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2786 s
->char2b
, s
->nchars
, bg_width
,
2787 s
->face
->overstrike
);
2789 mac_draw_image_string (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2790 char1b
, s
->nchars
, bg_width
,
2791 s
->face
->overstrike
);
2795 /* Draw the foreground of composite glyph string S. */
2798 x_draw_composite_glyph_string_foreground (s
)
2799 struct glyph_string
*s
;
2803 /* If first glyph of S has a left box line, start drawing the text
2804 of S to the right of that box line. */
2805 if (s
->face
->box
!= FACE_NO_BOX
2806 && s
->first_glyph
->left_box_line_p
)
2807 x
= s
->x
+ abs (s
->face
->box_line_width
);
2811 /* S is a glyph string for a composition. S->gidx is the index of
2812 the first character drawn for glyphs of this composition.
2813 S->gidx == 0 means we are drawing the very first character of
2814 this composition. */
2816 /* Draw a rectangle for the composition if the font for the very
2817 first character of the composition could not be loaded. */
2818 if (s
->font_not_found_p
)
2821 mac_draw_rectangle (s
->f
, s
->gc
, x
, s
->y
,
2822 s
->width
- 1, s
->height
- 1);
2826 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2827 mac_draw_image_string_16 (s
->f
, s
->gc
,
2828 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2829 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2830 s
->char2b
+ i
, 1, 0, s
->face
->overstrike
);
2835 #ifdef USE_X_TOOLKIT
2837 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2840 /* Return the frame on which widget WIDGET is used.. Abort if frame
2841 cannot be determined. */
2843 static struct frame
*
2844 x_frame_of_widget (widget
)
2847 struct x_display_info
*dpyinfo
;
2851 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2853 /* Find the top-level shell of the widget. Note that this function
2854 can be called when the widget is not yet realized, so XtWindow
2855 (widget) == 0. That's the reason we can't simply use
2856 x_any_window_to_frame. */
2857 while (!XtIsTopLevelShell (widget
))
2858 widget
= XtParent (widget
);
2860 /* Look for a frame with that top-level widget. Allocate the color
2861 on that frame to get the right gamma correction value. */
2862 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2863 if (GC_FRAMEP (XCAR (tail
))
2864 && (f
= XFRAME (XCAR (tail
)),
2865 (f
->output_data
.nothing
!= 1
2866 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2867 && f
->output_data
.x
->widget
== widget
)
2874 /* Allocate the color COLOR->pixel on the screen and display of
2875 widget WIDGET in colormap CMAP. If an exact match cannot be
2876 allocated, try the nearest color available. Value is non-zero
2877 if successful. This is called from lwlib. */
2880 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2885 struct frame
*f
= x_frame_of_widget (widget
);
2886 return x_alloc_nearest_color (f
, cmap
, color
);
2890 #endif /* USE_X_TOOLKIT */
2892 #if 0 /* MAC_TODO */
2894 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2895 CMAP. If an exact match can't be allocated, try the nearest color
2896 available. Value is non-zero if successful. Set *COLOR to the
2900 x_alloc_nearest_color (f
, cmap
, color
)
2905 Display
*display
= FRAME_X_DISPLAY (f
);
2906 Screen
*screen
= FRAME_X_SCREEN (f
);
2909 gamma_correct (f
, color
);
2910 rc
= XAllocColor (display
, cmap
, color
);
2913 /* If we got to this point, the colormap is full, so we're going
2914 to try to get the next closest color. The algorithm used is
2915 a least-squares matching, which is what X uses for closest
2916 color matching with StaticColor visuals. */
2918 unsigned long nearest_delta
= ~0;
2919 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2920 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2922 for (i
= 0; i
< ncells
; ++i
)
2924 XQueryColors (display
, cmap
, cells
, ncells
);
2926 for (nearest
= i
= 0; i
< ncells
; ++i
)
2928 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2929 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2930 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2931 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2933 if (delta
< nearest_delta
)
2936 nearest_delta
= delta
;
2940 color
->red
= cells
[nearest
].red
;
2941 color
->green
= cells
[nearest
].green
;
2942 color
->blue
= cells
[nearest
].blue
;
2943 rc
= XAllocColor (display
, cmap
, color
);
2946 #ifdef DEBUG_X_COLORS
2948 register_color (color
->pixel
);
2949 #endif /* DEBUG_X_COLORS */
2955 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2956 It's necessary to do this instead of just using PIXEL directly to
2957 get color reference counts right. */
2960 x_copy_color (f
, pixel
)
2962 unsigned long pixel
;
2966 color
.pixel
= pixel
;
2968 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2969 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2971 #ifdef DEBUG_X_COLORS
2972 register_color (pixel
);
2978 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2979 It's necessary to do this instead of just using PIXEL directly to
2980 get color reference counts right. */
2983 x_copy_dpy_color (dpy
, cmap
, pixel
)
2986 unsigned long pixel
;
2990 color
.pixel
= pixel
;
2992 XQueryColor (dpy
, cmap
, &color
);
2993 XAllocColor (dpy
, cmap
, &color
);
2995 #ifdef DEBUG_X_COLORS
2996 register_color (pixel
);
3001 #endif /* MAC_TODO */
3004 /* Brightness beyond which a color won't have its highlight brightness
3007 Nominally, highlight colors for `3d' faces are calculated by
3008 brightening an object's color by a constant scale factor, but this
3009 doesn't yield good results for dark colors, so for colors who's
3010 brightness is less than this value (on a scale of 0-255) have to
3011 use an additional additive factor.
3013 The value here is set so that the default menu-bar/mode-line color
3014 (grey75) will not have its highlights changed at all. */
3015 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3018 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3019 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3020 If this produces the same color as COLOR, try a color where all RGB
3021 values have DELTA added. Return the allocated color in *COLOR.
3022 DISPLAY is the X display, CMAP is the colormap to operate on.
3023 Value is non-zero if successful. */
3026 mac_alloc_lighter_color (f
, color
, factor
, delta
)
3028 unsigned long *color
;
3035 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
3038 /* Change RGB values by specified FACTOR. Avoid overflow! */
3039 xassert (factor
>= 0);
3040 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
3041 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
3042 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
3044 /* Calculate brightness of COLOR. */
3045 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
3046 + BLUE_FROM_ULONG (*color
)) / 6;
3048 /* We only boost colors that are darker than
3049 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3050 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3051 /* Make an additive adjustment to NEW, because it's dark enough so
3052 that scaling by FACTOR alone isn't enough. */
3054 /* How far below the limit this color is (0 - 1, 1 being darker). */
3055 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3056 /* The additive adjustment. */
3057 int min_delta
= delta
* dimness
* factor
/ 2;
3060 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
3061 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
3062 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
3064 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
3065 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
3066 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
3070 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
3071 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
3072 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
3074 /* MAC_TODO: Map to palette and retry with delta if same? */
3075 /* MAC_TODO: Free colors (if using palette)? */
3086 /* Set up the foreground color for drawing relief lines of glyph
3087 string S. RELIEF is a pointer to a struct relief containing the GC
3088 with which lines will be drawn. Use a color that is FACTOR or
3089 DELTA lighter or darker than the relief's background which is found
3090 in S->f->output_data.x->relief_background. If such a color cannot
3091 be allocated, use DEFAULT_PIXEL, instead. */
3094 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3096 struct relief
*relief
;
3099 unsigned long default_pixel
;
3102 struct mac_output
*di
= f
->output_data
.mac
;
3103 unsigned long mask
= GCForeground
;
3104 unsigned long pixel
;
3105 unsigned long background
= di
->relief_background
;
3106 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
3108 /* MAC_TODO: Free colors (if using palette)? */
3110 /* Allocate new color. */
3111 xgcv
.foreground
= default_pixel
;
3113 if (dpyinfo
->n_planes
!= 1
3114 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3116 relief
->allocated_p
= 1;
3117 xgcv
.foreground
= relief
->pixel
= pixel
;
3120 if (relief
->gc
== 0)
3122 #if 0 /* MAC_TODO: stipple */
3123 xgcv
.stipple
= dpyinfo
->gray
;
3126 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
3129 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3133 /* Set up colors for the relief lines around glyph string S. */
3136 x_setup_relief_colors (s
)
3137 struct glyph_string
*s
;
3139 struct mac_output
*di
= s
->f
->output_data
.mac
;
3140 unsigned long color
;
3142 if (s
->face
->use_box_color_for_shadows_p
)
3143 color
= s
->face
->box_color
;
3144 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3146 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3147 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3152 /* Get the background color of the face. */
3153 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3154 color
= xgcv
.background
;
3157 if (di
->white_relief
.gc
== 0
3158 || color
!= di
->relief_background
)
3160 di
->relief_background
= color
;
3161 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3162 WHITE_PIX_DEFAULT (s
->f
));
3163 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3164 BLACK_PIX_DEFAULT (s
->f
));
3169 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3170 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3171 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3172 relief. LEFT_P non-zero means draw a relief on the left side of
3173 the rectangle. RIGHT_P non-zero means draw a relief on the right
3174 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3178 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3179 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
3181 int left_x
, top_y
, right_x
, bottom_y
, width
;
3182 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
3185 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
3190 gc
= f
->output_data
.mac
->white_relief
.gc
;
3192 gc
= f
->output_data
.mac
->black_relief
.gc
;
3193 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
3197 for (i
= 0; i
< width
; ++i
)
3198 mac_draw_line (f
, gc
,
3199 left_x
+ i
* left_p
, top_y
+ i
,
3200 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3204 for (i
= 0; i
< width
; ++i
)
3205 mac_draw_line (f
, gc
,
3206 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3208 mac_reset_clip_rectangles (dpy
, gc
);
3210 gc
= f
->output_data
.mac
->black_relief
.gc
;
3212 gc
= f
->output_data
.mac
->white_relief
.gc
;
3213 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
3217 for (i
= 0; i
< width
; ++i
)
3218 mac_draw_line (f
, gc
,
3219 left_x
+ i
* left_p
, bottom_y
- i
,
3220 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3224 for (i
= 0; i
< width
; ++i
)
3225 mac_draw_line (f
, gc
,
3226 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3228 mac_reset_clip_rectangles (dpy
, gc
);
3232 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3233 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3234 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3235 left side of the rectangle. RIGHT_P non-zero means draw a line
3236 on the right side of the rectangle. CLIP_RECT is the clipping
3237 rectangle to use when drawing. */
3240 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3241 left_p
, right_p
, clip_rect
)
3242 struct glyph_string
*s
;
3243 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3248 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3249 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3250 mac_set_clip_rectangles (s
->display
, s
->gc
, clip_rect
, 1);
3253 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, top_y
,
3254 right_x
- left_x
+ 1, width
);
3258 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, top_y
,
3259 width
, bottom_y
- top_y
+ 1);
3262 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, bottom_y
- width
+ 1,
3263 right_x
- left_x
+ 1, width
);
3267 mac_fill_rectangle (s
->f
, s
->gc
, right_x
- width
+ 1,
3268 top_y
, width
, bottom_y
- top_y
+ 1);
3270 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3271 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3275 /* Draw a box around glyph string S. */
3278 x_draw_glyph_string_box (s
)
3279 struct glyph_string
*s
;
3281 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3282 int left_p
, right_p
;
3283 struct glyph
*last_glyph
;
3286 last_x
= ((s
->row
->full_width_p
&& !s
->w
->pseudo_window_p
)
3287 ? WINDOW_RIGHT_EDGE_X (s
->w
)
3288 : window_box_right (s
->w
, s
->area
));
3290 /* The glyph that may have a right box line. */
3291 last_glyph
= (s
->cmp
|| s
->img
3293 : s
->first_glyph
+ s
->nchars
- 1);
3295 width
= abs (s
->face
->box_line_width
);
3296 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3298 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3300 : min (last_x
, s
->x
+ s
->background_width
) - 1);
3302 bottom_y
= top_y
+ s
->height
- 1;
3304 left_p
= (s
->first_glyph
->left_box_line_p
3305 || (s
->hl
== DRAW_MOUSE_FACE
3307 || s
->prev
->hl
!= s
->hl
)));
3308 right_p
= (last_glyph
->right_box_line_p
3309 || (s
->hl
== DRAW_MOUSE_FACE
3311 || s
->next
->hl
!= s
->hl
)));
3313 get_glyph_string_clip_rect (s
, &clip_rect
);
3315 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3316 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3317 left_p
, right_p
, &clip_rect
);
3320 x_setup_relief_colors (s
);
3321 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3322 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
3327 /* Draw foreground of image glyph string S. */
3330 x_draw_image_foreground (s
)
3331 struct glyph_string
*s
;
3334 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3336 /* If first glyph of S has a left box line, start drawing it to the
3337 right of that line. */
3338 if (s
->face
->box
!= FACE_NO_BOX
3339 && s
->first_glyph
->left_box_line_p
3341 x
+= abs (s
->face
->box_line_width
);
3343 /* If there is a margin around the image, adjust x- and y-position
3345 if (s
->slice
.x
== 0)
3346 x
+= s
->img
->hmargin
;
3347 if (s
->slice
.y
== 0)
3348 y
+= s
->img
->vmargin
;
3352 x_set_glyph_string_clipping (s
);
3355 mac_draw_cg_image (s
->img
->data
.ptr_val
,
3356 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3357 s
->slice
.width
, s
->slice
.height
, x
, y
, 1);
3361 mac_copy_area_with_mask (s
->img
->pixmap
, s
->img
->mask
,
3362 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3363 s
->slice
.width
, s
->slice
.height
, x
, y
);
3370 mac_copy_area (s
->img
->pixmap
,
3371 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3372 s
->slice
.width
, s
->slice
.height
, x
, y
);
3375 /* When the image has a mask, we can expect that at
3376 least part of a mouse highlight or a block cursor will
3377 be visible. If the image doesn't have a mask, make
3378 a block cursor visible by drawing a rectangle around
3379 the image. I believe it's looking better if we do
3380 nothing here for mouse-face. */
3381 if (s
->hl
== DRAW_CURSOR
)
3383 int r
= s
->img
->relief
;
3385 mac_draw_rectangle (s
->f
, s
->gc
, x
- r
, y
- r
,
3386 s
->slice
.width
+ r
*2 - 1,
3387 s
->slice
.height
+ r
*2 - 1);
3392 /* Draw a rectangle if image could not be loaded. */
3393 mac_draw_rectangle (s
->f
, s
->gc
, x
, y
,
3394 s
->slice
.width
- 1, s
->slice
.height
- 1);
3398 /* Draw a relief around the image glyph string S. */
3401 x_draw_image_relief (s
)
3402 struct glyph_string
*s
;
3404 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3407 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3409 /* If first glyph of S has a left box line, start drawing it to the
3410 right of that line. */
3411 if (s
->face
->box
!= FACE_NO_BOX
3412 && s
->first_glyph
->left_box_line_p
3414 x
+= abs (s
->face
->box_line_width
);
3416 /* If there is a margin around the image, adjust x- and y-position
3418 if (s
->slice
.x
== 0)
3419 x
+= s
->img
->hmargin
;
3420 if (s
->slice
.y
== 0)
3421 y
+= s
->img
->vmargin
;
3423 if (s
->hl
== DRAW_IMAGE_SUNKEN
3424 || s
->hl
== DRAW_IMAGE_RAISED
)
3426 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
3427 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3431 thick
= abs (s
->img
->relief
);
3432 raised_p
= s
->img
->relief
> 0;
3437 x1
= x
+ s
->slice
.width
+ thick
- 1;
3438 y1
= y
+ s
->slice
.height
+ thick
- 1;
3440 x_setup_relief_colors (s
);
3441 get_glyph_string_clip_rect (s
, &r
);
3442 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
3444 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
3446 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
3451 /* Draw part of the background of glyph string S. X, Y, W, and H
3452 give the rectangle to draw. */
3455 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3456 struct glyph_string
*s
;
3459 #if 0 /* MAC_TODO: stipple */
3462 /* Fill background with a stipple pattern. */
3463 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3464 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3465 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3468 #endif /* MAC_TODO */
3469 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3473 /* Draw image glyph string S.
3476 s->x +-------------------------
3479 | +-------------------------
3482 | | +-------------------
3488 x_draw_image_glyph_string (s
)
3489 struct glyph_string
*s
;
3492 int box_line_hwidth
= abs (s
->face
->box_line_width
);
3493 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
3496 height
= s
->height
- 2 * box_line_vwidth
;
3499 /* Fill background with face under the image. Do it only if row is
3500 taller than image or if image has a clip mask to reduce
3502 s
->stippled_p
= s
->face
->stipple
!= 0;
3503 if (height
> s
->slice
.height
3507 || s
->img
->pixmap
== 0
3508 || s
->width
!= s
->background_width
)
3511 if (s
->first_glyph
->left_box_line_p
3513 x
+= box_line_hwidth
;
3516 if (s
->slice
.y
== 0)
3517 y
+= box_line_vwidth
;
3519 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3521 s
->background_filled_p
= 1;
3524 /* Draw the foreground. */
3525 x_draw_image_foreground (s
);
3527 /* If we must draw a relief around the image, do it. */
3529 || s
->hl
== DRAW_IMAGE_RAISED
3530 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3531 x_draw_image_relief (s
);
3535 /* Draw stretch glyph string S. */
3538 x_draw_stretch_glyph_string (s
)
3539 struct glyph_string
*s
;
3541 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3542 s
->stippled_p
= s
->face
->stipple
!= 0;
3544 if (s
->hl
== DRAW_CURSOR
3545 && !x_stretch_cursor_p
)
3547 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3548 as wide as the stretch glyph. */
3549 int width
, background_width
= s
->background_width
;
3550 int x
= s
->x
, left_x
= window_box_left_offset (s
->w
, TEXT_AREA
);
3554 background_width
-= left_x
- x
;
3557 width
= min (FRAME_COLUMN_WIDTH (s
->f
), background_width
);
3560 x_draw_glyph_string_bg_rect (s
, x
, s
->y
, width
, s
->height
);
3562 /* Clear rest using the GC of the original non-cursor face. */
3563 if (width
< background_width
)
3566 int w
= background_width
- width
, h
= s
->height
;
3571 if (s
->row
->mouse_face_p
3572 && cursor_in_mouse_face_p (s
->w
))
3574 x_set_mouse_face_gc (s
);
3580 get_glyph_string_clip_rect (s
, &r
);
3581 mac_set_clip_rectangles (s
->display
, gc
, &r
, 1);
3583 #if 0 /* MAC_TODO: stipple */
3584 if (s
->face
->stipple
)
3586 /* Fill background with a stipple pattern. */
3587 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3588 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3589 XSetFillStyle (s
->display
, gc
, FillSolid
);
3592 #endif /* MAC_TODO */
3593 mac_erase_rectangle (s
->f
, gc
, x
, y
, w
, h
);
3596 else if (!s
->background_filled_p
)
3598 int background_width
= s
->background_width
;
3599 int x
= s
->x
, left_x
= window_box_left_offset (s
->w
, TEXT_AREA
);
3601 /* Don't draw into left margin, fringe or scrollbar area
3602 except for header line and mode line. */
3603 if (x
< left_x
&& !s
->row
->mode_line_p
)
3605 background_width
-= left_x
- x
;
3608 if (background_width
> 0)
3609 x_draw_glyph_string_bg_rect (s
, x
, s
->y
, background_width
, s
->height
);
3612 s
->background_filled_p
= 1;
3616 /* Draw glyph string S. */
3619 x_draw_glyph_string (s
)
3620 struct glyph_string
*s
;
3622 int relief_drawn_p
= 0;
3624 /* If S draws into the background of its successor that does not
3625 draw a cursor, draw the background of the successor first so that
3626 S can draw into it. This makes S->next use XDrawString instead
3627 of XDrawImageString. */
3628 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps
3629 && s
->next
->hl
!= DRAW_CURSOR
)
3631 xassert (s
->next
->img
== NULL
);
3632 x_set_glyph_string_gc (s
->next
);
3633 x_set_glyph_string_clipping (s
->next
);
3634 x_draw_glyph_string_background (s
->next
, 1);
3637 /* Set up S->gc, set clipping and draw S. */
3638 x_set_glyph_string_gc (s
);
3640 /* Draw relief (if any) in advance for char/composition so that the
3641 glyph string can be drawn over it. */
3642 if (!s
->for_overlaps
3643 && s
->face
->box
!= FACE_NO_BOX
3644 && (s
->first_glyph
->type
== CHAR_GLYPH
3645 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3648 x_set_glyph_string_clipping (s
);
3649 x_draw_glyph_string_background (s
, 1);
3650 x_draw_glyph_string_box (s
);
3651 x_set_glyph_string_clipping (s
);
3655 x_set_glyph_string_clipping (s
);
3657 switch (s
->first_glyph
->type
)
3660 x_draw_image_glyph_string (s
);
3664 x_draw_stretch_glyph_string (s
);
3668 if (s
->for_overlaps
)
3669 s
->background_filled_p
= 1;
3671 x_draw_glyph_string_background (s
, 0);
3672 x_draw_glyph_string_foreground (s
);
3675 case COMPOSITE_GLYPH
:
3676 if (s
->for_overlaps
|| s
->gidx
> 0)
3677 s
->background_filled_p
= 1;
3679 x_draw_glyph_string_background (s
, 1);
3680 x_draw_composite_glyph_string_foreground (s
);
3687 if (!s
->for_overlaps
)
3689 /* Draw underline. */
3690 if (s
->face
->underline_p
)
3692 unsigned long tem
, h
;
3696 /* Get the underline thickness. Default is 1 pixel. */
3697 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
3701 y
= s
->y
+ s
->height
- h
;
3702 if (!x_underline_at_descent_line
)
3704 /* Get the underline position. This is the recommended
3705 vertical offset in pixels from the baseline to the top of
3706 the underline. This is a signed value according to the
3707 specs, and its default is
3709 ROUND ((maximum descent) / 2), with
3710 ROUND(x) = floor (x + 0.5) */
3713 if (x_use_underline_position_properties
3714 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
3715 y
= s
->ybase
+ (long) tem
;
3719 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
3722 if (s
->face
->underline_defaulted_p
)
3723 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, y
,
3724 s
->background_width
, h
);
3728 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3729 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3730 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, y
,
3731 s
->background_width
, h
);
3732 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3736 /* Draw overline. */
3737 if (s
->face
->overline_p
)
3739 unsigned long dy
= 0, h
= 1;
3741 if (s
->face
->overline_color_defaulted_p
)
3742 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3743 s
->background_width
, h
);
3747 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3748 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3749 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3750 s
->background_width
, h
);
3751 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3755 /* Draw strike-through. */
3756 if (s
->face
->strike_through_p
)
3758 unsigned long h
= 1;
3759 unsigned long dy
= (s
->height
- h
) / 2;
3761 if (s
->face
->strike_through_color_defaulted_p
)
3762 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3767 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3768 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3769 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3771 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3775 /* Draw relief if not yet drawn. */
3776 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3777 x_draw_glyph_string_box (s
);
3780 /* Reset clipping. */
3781 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3784 /* Shift display to make room for inserted glyphs. */
3787 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3789 int x
, y
, width
, height
, shift_by
;
3791 mac_scroll_area (f
, f
->output_data
.mac
->normal_gc
,
3792 x
, y
, width
, height
,
3796 /* Delete N glyphs at the nominal cursor position. Not implemented
3807 /* Clear entire frame. If updating_frame is non-null, clear that
3808 frame. Otherwise clear the selected frame. */
3818 f
= SELECTED_FRAME ();
3820 /* Clearing the frame will erase any cursor, so mark them all as no
3822 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3823 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3824 output_cursor
.x
= -1;
3826 /* We don't set the output cursor here because there will always
3827 follow an explicit cursor_to. */
3829 mac_clear_window (f
);
3831 /* We have to clear the scroll bars, too. If we have changed
3832 colors or something like that, then they should be notified. */
3833 x_scroll_bar_clear (f
);
3835 XFlush (FRAME_MAC_DISPLAY (f
));
3841 /* Invert the middle quarter of the frame for .15 sec. */
3843 /* We use the select system call to do the waiting, so we have to make
3844 sure it's available. If it isn't, we just won't do visual bells. */
3846 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3849 /* Subtract the `struct timeval' values X and Y, storing the result in
3850 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3853 timeval_subtract (result
, x
, y
)
3854 struct timeval
*result
, x
, y
;
3856 /* Perform the carry for the later subtraction by updating y. This
3857 is safer because on some systems the tv_sec member is unsigned. */
3858 if (x
.tv_usec
< y
.tv_usec
)
3860 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3861 y
.tv_usec
-= 1000000 * nsec
;
3865 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3867 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3868 y
.tv_usec
+= 1000000 * nsec
;
3872 /* Compute the time remaining to wait. tv_usec is certainly
3874 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3875 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3877 /* Return indication of whether the result should be considered
3879 return x
.tv_sec
< y
.tv_sec
;
3886 /* Get the height not including a menu bar widget. */
3887 int height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, FRAME_LINES (f
));
3888 /* Height of each line to flash. */
3889 int flash_height
= FRAME_LINE_HEIGHT (f
);
3890 /* These will be the left and right margins of the rectangles. */
3891 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
3892 int flash_right
= FRAME_PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
3896 /* Don't flash the area between a scroll bar and the frame
3897 edge it is next to. */
3898 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
3900 case vertical_scroll_bar_left
:
3901 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3904 case vertical_scroll_bar_right
:
3905 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3912 width
= flash_right
- flash_left
;
3916 /* If window is tall, flash top and bottom line. */
3917 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3919 mac_invert_rectangle (f
, flash_left
,
3920 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3921 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3922 width
, flash_height
);
3923 mac_invert_rectangle (f
, flash_left
,
3924 (height
- flash_height
3925 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3926 width
, flash_height
);
3929 /* If it is short, flash it all. */
3930 mac_invert_rectangle (f
, flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3931 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
3936 struct timeval wakeup
;
3938 EMACS_GET_TIME (wakeup
);
3940 /* Compute time to wait until, propagating carry from usecs. */
3941 wakeup
.tv_usec
+= 150000;
3942 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3943 wakeup
.tv_usec
%= 1000000;
3945 /* Keep waiting until past the time wakeup or any input gets
3947 while (! detect_input_pending ())
3949 struct timeval current
;
3950 struct timeval timeout
;
3952 EMACS_GET_TIME (current
);
3954 /* Break if result would be negative. */
3955 if (timeval_subtract (¤t
, wakeup
, current
))
3958 /* How long `select' should wait. */
3960 timeout
.tv_usec
= 10000;
3962 /* Try to wait that long--but we might wake up sooner. */
3963 select (0, NULL
, NULL
, NULL
, &timeout
);
3967 /* If window is tall, flash top and bottom line. */
3968 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3970 mac_invert_rectangle (f
, flash_left
,
3971 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3972 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3973 width
, flash_height
);
3974 mac_invert_rectangle (f
, flash_left
,
3975 (height
- flash_height
3976 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3977 width
, flash_height
);
3980 /* If it is short, flash it all. */
3981 mac_invert_rectangle (f
, flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3982 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
3989 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3992 /* Make audible bell. */
3997 struct frame
*f
= SELECTED_FRAME ();
3999 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
4007 XFlush (FRAME_MAC_DISPLAY (f
));
4013 /* Specify how many text lines, from the top of the window,
4014 should be affected by insert-lines and delete-lines operations.
4015 This, and those operations, are used only within an update
4016 that is bounded by calls to x_update_begin and x_update_end. */
4019 XTset_terminal_window (n
)
4022 /* This function intentionally left blank. */
4027 /***********************************************************************
4029 ***********************************************************************/
4031 /* Perform an insert-lines or delete-lines operation, inserting N
4032 lines or deleting -N lines at vertical position VPOS. */
4035 x_ins_del_lines (vpos
, n
)
4042 /* Scroll part of the display as described by RUN. */
4045 x_scroll_run (w
, run
)
4049 struct frame
*f
= XFRAME (w
->frame
);
4050 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4052 /* Get frame-relative bounding box of the text display area of W,
4053 without mode lines. Include in this box the left and right
4055 window_box (w
, -1, &x
, &y
, &width
, &height
);
4057 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4058 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4059 bottom_y
= y
+ height
;
4063 /* Scrolling up. Make sure we don't copy part of the mode
4064 line at the bottom. */
4065 if (from_y
+ run
->height
> bottom_y
)
4066 height
= bottom_y
- from_y
;
4068 height
= run
->height
;
4072 /* Scolling down. Make sure we don't copy over the mode line.
4074 if (to_y
+ run
->height
> bottom_y
)
4075 height
= bottom_y
- to_y
;
4077 height
= run
->height
;
4082 /* Cursor off. Will be switched on again in x_update_window_end. */
4086 mac_scroll_area (f
, f
->output_data
.mac
->normal_gc
,
4096 /***********************************************************************
4098 ***********************************************************************/
4106 ControlRef root_control
;
4109 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
4111 ActivateControl (root_control
);
4113 x_update_cursor (f
, 1);
4117 frame_unhighlight (f
)
4121 ControlRef root_control
;
4124 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
4126 DeactivateControl (root_control
);
4128 x_update_cursor (f
, 1);
4131 /* The focus has changed. Update the frames as necessary to reflect
4132 the new situation. Note that we can't change the selected frame
4133 here, because the Lisp code we are interrupting might become confused.
4134 Each event gets marked with the frame in which it occurred, so the
4135 Lisp code can tell when the switch took place by examining the events. */
4138 x_new_focus_frame (dpyinfo
, frame
)
4139 struct x_display_info
*dpyinfo
;
4140 struct frame
*frame
;
4142 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
4144 if (frame
!= dpyinfo
->x_focus_frame
)
4146 /* Set this before calling other routines, so that they see
4147 the correct value of x_focus_frame. */
4148 dpyinfo
->x_focus_frame
= frame
;
4150 if (old_focus
&& old_focus
->auto_lower
)
4151 x_lower_frame (old_focus
);
4154 selected_frame
= frame
;
4155 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
4157 Fselect_window (selected_frame
->selected_window
, Qnil
);
4158 choose_minibuf_frame ();
4161 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
4162 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
4164 pending_autoraise_frame
= 0;
4166 #if USE_MAC_FONT_PANEL
4168 mac_set_font_info_for_selection (frame
, DEFAULT_FACE_ID
, 0);
4172 x_frame_rehighlight (dpyinfo
);
4175 /* Handle FocusIn and FocusOut state changes for FRAME.
4176 If FRAME has focus and there exists more than one frame, puts
4177 a FOCUS_IN_EVENT into *BUFP. */
4180 mac_focus_changed (type
, dpyinfo
, frame
, bufp
)
4182 struct mac_display_info
*dpyinfo
;
4183 struct frame
*frame
;
4184 struct input_event
*bufp
;
4186 if (type
== activeFlag
)
4188 if (dpyinfo
->x_focus_event_frame
!= frame
)
4190 x_new_focus_frame (dpyinfo
, frame
);
4191 dpyinfo
->x_focus_event_frame
= frame
;
4193 /* Don't stop displaying the initial startup message
4194 for a switch-frame event we don't need. */
4195 if (GC_NILP (Vterminal_frame
)
4196 && GC_CONSP (Vframe_list
)
4197 && !GC_NILP (XCDR (Vframe_list
)))
4199 bufp
->kind
= FOCUS_IN_EVENT
;
4200 XSETFRAME (bufp
->frame_or_window
, frame
);
4206 if (dpyinfo
->x_focus_event_frame
== frame
)
4208 dpyinfo
->x_focus_event_frame
= 0;
4209 x_new_focus_frame (dpyinfo
, 0);
4214 /* The focus may have changed. Figure out if it is a real focus change,
4215 by checking both FocusIn/Out and Enter/LeaveNotify events.
4217 Returns FOCUS_IN_EVENT event in *BUFP. */
4220 x_detect_focus_change (dpyinfo
, event
, bufp
)
4221 struct mac_display_info
*dpyinfo
;
4223 struct input_event
*bufp
;
4225 struct frame
*frame
;
4227 frame
= mac_window_to_frame ((WindowPtr
) event
->message
);
4231 /* On Mac, this is only called from focus events, so no switch needed. */
4232 mac_focus_changed ((event
->modifiers
& activeFlag
),
4233 dpyinfo
, frame
, bufp
);
4237 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4240 x_mouse_leave (dpyinfo
)
4241 struct x_display_info
*dpyinfo
;
4243 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
4246 /* The focus has changed, or we have redirected a frame's focus to
4247 another frame (this happens when a frame uses a surrogate
4248 mini-buffer frame). Shift the highlight as appropriate.
4250 The FRAME argument doesn't necessarily have anything to do with which
4251 frame is being highlighted or un-highlighted; we only use it to find
4252 the appropriate X display info. */
4255 XTframe_rehighlight (frame
)
4256 struct frame
*frame
;
4258 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
4262 x_frame_rehighlight (dpyinfo
)
4263 struct x_display_info
*dpyinfo
;
4265 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
4267 if (dpyinfo
->x_focus_frame
)
4269 dpyinfo
->x_highlight_frame
4270 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
4271 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
4272 : dpyinfo
->x_focus_frame
);
4273 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
4275 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
4276 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
4280 dpyinfo
->x_highlight_frame
= 0;
4282 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
4285 frame_unhighlight (old_highlight
);
4286 if (dpyinfo
->x_highlight_frame
)
4287 frame_highlight (dpyinfo
->x_highlight_frame
);
4293 /* Convert a keysym to its name. */
4296 x_get_keysym_name (keysym
)
4303 value
= XKeysymToString (keysym
);
4314 /* Function to report a mouse movement to the mainstream Emacs code.
4315 The input handler calls this.
4317 We have received a mouse movement event, which is given in *event.
4318 If the mouse is over a different glyph than it was last time, tell
4319 the mainstream emacs code by setting mouse_moved. If not, ask for
4320 another motion event, so we can check again the next time it moves. */
4322 static Point last_mouse_motion_position
;
4323 static Lisp_Object last_mouse_motion_frame
;
4326 note_mouse_movement (frame
, pos
)
4330 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4331 #if TARGET_API_MAC_CARBON
4335 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
4336 last_mouse_motion_position
= *pos
;
4337 XSETFRAME (last_mouse_motion_frame
, frame
);
4339 #if TARGET_API_MAC_CARBON
4340 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
4342 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
4345 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
4346 /* This case corresponds to LeaveNotify in X11. */
4348 /* If we move outside the frame, then we're certainly no
4349 longer on any text in the frame. */
4350 clear_mouse_face (dpyinfo
);
4351 dpyinfo
->mouse_face_mouse_frame
= 0;
4352 if (!dpyinfo
->grabbed
)
4353 rif
->define_frame_cursor (frame
,
4354 frame
->output_data
.mac
->nontext_cursor
);
4358 /* Has the mouse moved off the glyph it was on at the last sighting? */
4359 if (frame
!= last_mouse_glyph_frame
4360 || !PtInRect (*pos
, &last_mouse_glyph
))
4362 frame
->mouse_moved
= 1;
4363 last_mouse_scroll_bar
= Qnil
;
4364 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
4365 /* Remember which glyph we're now on. */
4366 remember_mouse_glyph (frame
, pos
->h
, pos
->v
, &last_mouse_glyph
);
4367 last_mouse_glyph_frame
= frame
;
4375 /************************************************************************
4377 ************************************************************************/
4379 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4382 redo_mouse_highlight ()
4384 if (!NILP (last_mouse_motion_frame
)
4385 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
4386 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
4387 last_mouse_motion_position
.h
,
4388 last_mouse_motion_position
.v
);
4392 static struct frame
*
4393 mac_focus_frame (dpyinfo
)
4394 struct mac_display_info
*dpyinfo
;
4396 if (dpyinfo
->x_focus_frame
)
4397 return dpyinfo
->x_focus_frame
;
4399 /* Mac version may get events, such as a menu bar click, even when
4400 all the frames are invisible. In this case, we regard the
4401 event came to the selected frame. */
4402 return SELECTED_FRAME ();
4406 /* Return the current position of the mouse.
4407 *FP should be a frame which indicates which display to ask about.
4409 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
4410 and *PART to the frame, window, and scroll bar part that the mouse
4411 is over. Set *X and *Y to the portion and whole of the mouse's
4412 position on the scroll bar.
4414 If the mouse movement started elsewhere, set *FP to the frame the
4415 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
4418 Set *TIME to the server time-stamp for the time at which the mouse
4419 was at this position.
4421 Don't store anything if we don't have a valid set of values to report.
4423 This clears the mouse_moved flag, so we can wait for the next mouse
4427 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
4430 Lisp_Object
*bar_window
;
4431 enum scroll_bar_part
*part
;
4433 unsigned long *time
;
4439 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
4440 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
4443 Lisp_Object frame
, tail
;
4445 /* Clear the mouse-moved flag for every frame on this display. */
4446 FOR_EACH_FRAME (tail
, frame
)
4447 XFRAME (frame
)->mouse_moved
= 0;
4449 last_mouse_scroll_bar
= Qnil
;
4451 if (FRAME_MAC_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
4452 && FRAME_LIVE_P (last_mouse_frame
))
4453 f1
= last_mouse_frame
;
4455 f1
= mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp
));
4459 /* Ok, we found a frame. Store all the values.
4460 last_mouse_glyph is a rectangle used to reduce the
4461 generation of mouse events. To not miss any motion
4462 events, we must divide the frame into rectangles of the
4463 size of the smallest character that could be displayed
4464 on it, i.e. into the same rectangles that matrices on
4465 the frame are divided into. */
4468 SetPortWindowPort (FRAME_MAC_WINDOW (f1
));
4469 GetMouse (&mouse_pos
);
4470 remember_mouse_glyph (f1
, mouse_pos
.h
, mouse_pos
.v
,
4472 last_mouse_glyph_frame
= f1
;
4477 XSETINT (*x
, mouse_pos
.h
);
4478 XSETINT (*y
, mouse_pos
.v
);
4479 *time
= last_mouse_movement_time
;
4487 /************************************************************************
4489 ************************************************************************/
4491 #ifdef USE_TOOLKIT_SCROLL_BARS
4493 static pascal void scroll_bar_timer_callback
P_ ((EventLoopTimerRef
, void *));
4494 static OSStatus install_scroll_bar_timer
P_ ((void));
4495 static OSStatus set_scroll_bar_timer
P_ ((EventTimerInterval
));
4496 static int control_part_code_to_scroll_bar_part
P_ ((ControlPartCode
));
4497 static void construct_scroll_bar_click
P_ ((struct scroll_bar
*, int,
4498 struct input_event
*));
4499 static OSStatus get_control_part_bounds
P_ ((ControlHandle
, ControlPartCode
,
4501 static void x_scroll_bar_handle_press
P_ ((struct scroll_bar
*,
4503 struct input_event
*));
4504 static void x_scroll_bar_handle_release
P_ ((struct scroll_bar
*,
4505 struct input_event
*));
4506 static void x_scroll_bar_handle_drag
P_ ((WindowPtr
, struct scroll_bar
*,
4507 Point
, struct input_event
*));
4508 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
4511 /* Last scroll bar part sent in x_scroll_bar_handle_*. */
4513 static int last_scroll_bar_part
;
4515 static EventLoopTimerRef scroll_bar_timer
;
4517 static int scroll_bar_timer_event_posted_p
;
4519 #define SCROLL_BAR_FIRST_DELAY 0.5
4520 #define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
4523 scroll_bar_timer_callback (timer
, data
)
4524 EventLoopTimerRef timer
;
4529 err
= mac_post_mouse_moved_event ();
4531 scroll_bar_timer_event_posted_p
= 1;
4535 install_scroll_bar_timer ()
4537 static EventLoopTimerUPP scroll_bar_timer_callbackUPP
= NULL
;
4539 if (scroll_bar_timer_callbackUPP
== NULL
)
4540 scroll_bar_timer_callbackUPP
=
4541 NewEventLoopTimerUPP (scroll_bar_timer_callback
);
4543 if (scroll_bar_timer
== NULL
)
4544 /* Mac OS X and CarbonLib 1.5 and later allow us to specify
4545 kEventDurationForever as delays. */
4547 InstallEventLoopTimer (GetCurrentEventLoop (),
4548 kEventDurationForever
, kEventDurationForever
,
4549 scroll_bar_timer_callbackUPP
, NULL
,
4554 set_scroll_bar_timer (delay
)
4555 EventTimerInterval delay
;
4557 if (scroll_bar_timer
== NULL
)
4558 install_scroll_bar_timer ();
4560 scroll_bar_timer_event_posted_p
= 0;
4562 return SetEventLoopTimerNextFireTime (scroll_bar_timer
, delay
);
4566 control_part_code_to_scroll_bar_part (part_code
)
4567 ControlPartCode part_code
;
4571 case kControlUpButtonPart
: return scroll_bar_up_arrow
;
4572 case kControlDownButtonPart
: return scroll_bar_down_arrow
;
4573 case kControlPageUpPart
: return scroll_bar_above_handle
;
4574 case kControlPageDownPart
: return scroll_bar_below_handle
;
4575 case kControlIndicatorPart
: return scroll_bar_handle
;
4582 construct_scroll_bar_click (bar
, part
, bufp
)
4583 struct scroll_bar
*bar
;
4585 struct input_event
*bufp
;
4587 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4588 bufp
->frame_or_window
= bar
->window
;
4592 XSETINT (bufp
->x
, 0);
4593 XSETINT (bufp
->y
, 0);
4594 bufp
->modifiers
= 0;
4598 get_control_part_bounds (ch
, part_code
, rect
)
4600 ControlPartCode part_code
;
4603 RgnHandle region
= NewRgn ();
4606 err
= GetControlRegion (ch
, part_code
, region
);
4608 GetRegionBounds (region
, rect
);
4609 DisposeRgn (region
);
4615 x_scroll_bar_handle_press (bar
, part_code
, bufp
)
4616 struct scroll_bar
*bar
;
4617 ControlPartCode part_code
;
4618 struct input_event
*bufp
;
4620 int part
= control_part_code_to_scroll_bar_part (part_code
);
4625 if (part
!= scroll_bar_handle
)
4627 construct_scroll_bar_click (bar
, part
, bufp
);
4628 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4629 set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY
);
4632 last_scroll_bar_part
= part
;
4633 bar
->dragging
= Qnil
;
4634 tracked_scroll_bar
= bar
;
4638 x_scroll_bar_handle_release (bar
, bufp
)
4639 struct scroll_bar
*bar
;
4640 struct input_event
*bufp
;
4642 if (last_scroll_bar_part
!= scroll_bar_handle
4643 || !GC_NILP (bar
->dragging
))
4644 construct_scroll_bar_click (bar
, scroll_bar_end_scroll
, bufp
);
4646 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4647 set_scroll_bar_timer (kEventDurationForever
);
4649 last_scroll_bar_part
= -1;
4650 bar
->dragging
= Qnil
;
4651 tracked_scroll_bar
= NULL
;
4655 x_scroll_bar_handle_drag (win
, bar
, mouse_pos
, bufp
)
4657 struct scroll_bar
*bar
;
4659 struct input_event
*bufp
;
4661 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4663 if (last_scroll_bar_part
== scroll_bar_handle
)
4668 get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar
),
4669 kControlIndicatorPart
, &r
);
4671 if (GC_NILP (bar
->dragging
))
4672 XSETINT (bar
->dragging
, mouse_pos
.v
- r
.top
);
4674 top
= mouse_pos
.v
- XINT (bar
->dragging
) - XINT (bar
->track_top
);
4675 top_range
= (XINT (bar
->track_height
) - (r
.bottom
- r
.top
)) *
4676 (1.0 + (float) GetControlViewSize (ch
) / GetControl32BitMaximum (ch
))
4681 if (top
> top_range
)
4684 construct_scroll_bar_click (bar
, scroll_bar_handle
, bufp
);
4685 XSETINT (bufp
->x
, top
);
4686 XSETINT (bufp
->y
, top_range
);
4690 ControlPartCode part_code
;
4691 int unhilite_p
= 0, part
;
4693 if (ch
!= FindControlUnderMouse (mouse_pos
, win
, &part_code
))
4697 part
= control_part_code_to_scroll_bar_part (part_code
);
4699 switch (last_scroll_bar_part
)
4701 case scroll_bar_above_handle
:
4702 case scroll_bar_below_handle
:
4703 if (part
!= scroll_bar_above_handle
4704 && part
!= scroll_bar_below_handle
)
4708 case scroll_bar_up_arrow
:
4709 case scroll_bar_down_arrow
:
4710 if (part
!= scroll_bar_up_arrow
4711 && part
!= scroll_bar_down_arrow
)
4718 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4719 else if (part
!= last_scroll_bar_part
4720 || scroll_bar_timer_event_posted_p
)
4722 construct_scroll_bar_click (bar
, part
, bufp
);
4723 last_scroll_bar_part
= part
;
4724 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4725 set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY
);
4730 /* Set the thumb size and position of scroll bar BAR. We are currently
4731 displaying PORTION out of a whole WHOLE, and our position POSITION. */
4734 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
4735 struct scroll_bar
*bar
;
4736 int portion
, position
, whole
;
4738 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4739 int value
, viewsize
, maximum
;
4741 if (XINT (bar
->track_height
) == 0)
4745 value
= 0, viewsize
= 1, maximum
= 0;
4750 maximum
= max (0, whole
- portion
);
4755 if (GetControlViewSize (ch
) != viewsize
4756 || GetControl32BitValue (ch
) != value
4757 || GetControl32BitMaximum (ch
) != maximum
)
4759 /* Temporarily hide the scroll bar to avoid multiple redraws. */
4760 SetControlVisibility (ch
, false, false);
4762 SetControl32BitMaximum (ch
, maximum
);
4763 SetControl32BitValue (ch
, value
);
4764 SetControlViewSize (ch
, viewsize
);
4766 SetControlVisibility (ch
, true, true);
4772 #endif /* USE_TOOLKIT_SCROLL_BARS */
4776 /************************************************************************
4777 Scroll bars, general
4778 ************************************************************************/
4780 /* Create a scroll bar and return the scroll bar vector for it. W is
4781 the Emacs window on which to create the scroll bar. TOP, LEFT,
4782 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4785 static struct scroll_bar
*
4786 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4788 int top
, left
, width
, height
, disp_top
, disp_height
;
4790 struct frame
*f
= XFRAME (w
->frame
);
4791 struct scroll_bar
*bar
4792 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4800 r
.right
= left
+ width
;
4801 r
.bottom
= disp_top
+ disp_height
;
4804 mac_prepare_for_quickdraw (f
);
4806 #if TARGET_API_MAC_CARBON
4807 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p",
4808 #if USE_TOOLKIT_SCROLL_BARS
4811 width
< disp_height
,
4813 0, 0, 0, kControlScrollBarProc
, (long) bar
);
4815 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4816 0, 0, 0, scrollBarProc
, (long) bar
);
4818 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4820 XSETWINDOW (bar
->window
, w
);
4821 XSETINT (bar
->top
, top
);
4822 XSETINT (bar
->left
, left
);
4823 XSETINT (bar
->width
, width
);
4824 XSETINT (bar
->height
, height
);
4825 XSETINT (bar
->start
, 0);
4826 XSETINT (bar
->end
, 0);
4827 bar
->dragging
= Qnil
;
4828 #ifdef USE_TOOLKIT_SCROLL_BARS
4829 bar
->track_top
= Qnil
;
4830 bar
->track_height
= Qnil
;
4833 /* Add bar to its frame's list of scroll bars. */
4834 bar
->next
= FRAME_SCROLL_BARS (f
);
4836 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4837 if (!NILP (bar
->next
))
4838 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4845 /* Draw BAR's handle in the proper position.
4847 If the handle is already drawn from START to END, don't bother
4848 redrawing it, unless REBUILD is non-zero; in that case, always
4849 redraw it. (REBUILD is handy for drawing the handle after expose
4852 Normally, we want to constrain the start and end of the handle to
4853 fit inside its rectangle, but if the user is dragging the scroll
4854 bar handle, we want to let them drag it down all the way, so that
4855 the bar's top is as far down as it goes; otherwise, there's no way
4856 to move to the very end of the buffer. */
4858 #ifndef USE_TOOLKIT_SCROLL_BARS
4861 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4862 struct scroll_bar
*bar
;
4866 int dragging
= ! NILP (bar
->dragging
);
4867 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4868 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4869 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4870 int length
= end
- start
;
4872 /* If the display is already accurate, do nothing. */
4874 && start
== XINT (bar
->start
)
4875 && end
== XINT (bar
->end
))
4880 /* Make sure the values are reasonable, and try to preserve the
4881 distance between start and end. */
4884 else if (start
> top_range
)
4886 end
= start
+ length
;
4890 else if (end
> top_range
&& ! dragging
)
4893 /* Store the adjusted setting in the scroll bar. */
4894 XSETINT (bar
->start
, start
);
4895 XSETINT (bar
->end
, end
);
4897 /* Clip the end position, just for display. */
4898 if (end
> top_range
)
4901 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4902 top positions, to make sure the handle is always at least that
4903 many pixels tall. */
4904 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4906 SetControlMinimum (ch
, 0);
4907 /* Don't inadvertently activate deactivated scroll bars */
4908 if (GetControlMaximum (ch
) != -1)
4909 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4911 SetControlValue (ch
, start
);
4912 #if TARGET_API_MAC_CARBON
4913 SetControlViewSize (ch
, end
- start
);
4919 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4921 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4925 x_scroll_bar_remove (bar
)
4926 struct scroll_bar
*bar
;
4928 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4933 mac_prepare_for_quickdraw (f
);
4935 /* Destroy the Mac scroll bar control */
4936 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4938 /* Disassociate this scroll bar from its window. */
4939 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4945 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4946 that we are displaying PORTION characters out of a total of WHOLE
4947 characters, starting at POSITION. If WINDOW has no scroll bar,
4951 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4953 int portion
, whole
, position
;
4955 struct frame
*f
= XFRAME (w
->frame
);
4956 struct scroll_bar
*bar
;
4957 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4958 int window_y
, window_height
;
4960 /* Get window dimensions. */
4961 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4963 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4964 height
= window_height
;
4966 /* Compute the left edge of the scroll bar area. */
4967 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4969 /* Compute the width of the scroll bar which might be less than
4970 the width of the area reserved for the scroll bar. */
4971 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4972 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4976 /* Compute the left edge of the scroll bar. */
4977 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4980 sb_left
= left
+ width
- sb_width
;
4982 /* Adjustments according to Inside Macintosh to make it look nice */
4984 disp_height
= height
;
4991 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4997 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
5001 /* Does the scroll bar exist yet? */
5002 if (NILP (w
->vertical_scroll_bar
))
5005 mac_clear_area (f
, left
, top
, width
, height
);
5007 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
5009 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
5013 /* It may just need to be moved and resized. */
5016 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
5017 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5021 /* If already correctly positioned, do nothing. */
5022 if (!(XINT (bar
->left
) == sb_left
5023 && XINT (bar
->top
) == top
5024 && XINT (bar
->width
) == sb_width
5025 && XINT (bar
->height
) == height
))
5027 /* Since toolkit scroll bars are smaller than the space reserved
5028 for them on the frame, we have to clear "under" them. */
5029 mac_clear_area (f
, left
, top
, width
, height
);
5032 mac_prepare_for_quickdraw (f
);
5035 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
5036 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
5038 #ifndef USE_TOOLKIT_SCROLL_BARS
5039 if (sb_width
< disp_height
)
5043 /* Remember new settings. */
5044 XSETINT (bar
->left
, sb_left
);
5045 XSETINT (bar
->top
, top
);
5046 XSETINT (bar
->width
, sb_width
);
5047 XSETINT (bar
->height
, height
);
5048 #ifdef USE_TOOLKIT_SCROLL_BARS
5049 bar
->track_top
= Qnil
;
5050 bar
->track_height
= Qnil
;
5057 #ifdef USE_TOOLKIT_SCROLL_BARS
5058 if (NILP (bar
->track_top
))
5060 if (sb_width
>= disp_height
)
5062 XSETINT (bar
->track_top
, 0);
5063 XSETINT (bar
->track_height
, 0);
5067 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5072 SetControl32BitMinimum (ch
, 0);
5073 SetControl32BitMaximum (ch
, 1);
5074 SetControlViewSize (ch
, 1);
5076 /* Move the scroll bar thumb to the top. */
5077 SetControl32BitValue (ch
, 0);
5078 get_control_part_bounds (ch
, kControlIndicatorPart
, &r0
);
5080 /* Move the scroll bar thumb to the bottom. */
5081 SetControl32BitValue (ch
, 1);
5082 get_control_part_bounds (ch
, kControlIndicatorPart
, &r1
);
5084 UnionRect (&r0
, &r1
, &r0
);
5085 XSETINT (bar
->track_top
, r0
.top
);
5086 XSETINT (bar
->track_height
, r0
.bottom
- r0
.top
);
5088 /* Don't show the scroll bar if its height is not enough to
5089 display the scroll bar thumb. */
5090 if (r0
.bottom
- r0
.top
> 0)
5097 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
5098 #else /* not USE_TOOLKIT_SCROLL_BARS */
5099 /* Set the scroll bar's current state, unless we're currently being
5101 if (NILP (bar
->dragging
))
5103 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
5106 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
5109 int start
= ((double) position
* top_range
) / whole
;
5110 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
5111 x_scroll_bar_set_handle (bar
, start
, end
, 0);
5114 #endif /* not USE_TOOLKIT_SCROLL_BARS */
5118 /* The following three hooks are used when we're doing a thorough
5119 redisplay of the frame. We don't explicitly know which scroll bars
5120 are going to be deleted, because keeping track of when windows go
5121 away is a real pain - "Can you say set-window-configuration, boys
5122 and girls?" Instead, we just assert at the beginning of redisplay
5123 that *all* scroll bars are to be removed, and then save a scroll bar
5124 from the fiery pit when we actually redisplay its window. */
5126 /* Arrange for all scroll bars on FRAME to be removed at the next call
5127 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
5128 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
5131 XTcondemn_scroll_bars (frame
)
5134 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
5135 while (! NILP (FRAME_SCROLL_BARS (frame
)))
5138 bar
= FRAME_SCROLL_BARS (frame
);
5139 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
5140 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
5141 XSCROLL_BAR (bar
)->prev
= Qnil
;
5142 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
5143 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
5144 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
5149 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
5150 Note that WINDOW isn't necessarily condemned at all. */
5153 XTredeem_scroll_bar (window
)
5154 struct window
*window
;
5156 struct scroll_bar
*bar
;
5159 /* We can't redeem this window's scroll bar if it doesn't have one. */
5160 if (NILP (window
->vertical_scroll_bar
))
5163 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
5165 /* Unlink it from the condemned list. */
5166 f
= XFRAME (WINDOW_FRAME (window
));
5167 if (NILP (bar
->prev
))
5169 /* If the prev pointer is nil, it must be the first in one of
5171 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
5172 /* It's not condemned. Everything's fine. */
5174 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
5175 window
->vertical_scroll_bar
))
5176 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
5178 /* If its prev pointer is nil, it must be at the front of
5179 one or the other! */
5183 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
5185 if (! NILP (bar
->next
))
5186 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
5188 bar
->next
= FRAME_SCROLL_BARS (f
);
5190 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
5191 if (! NILP (bar
->next
))
5192 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
5195 /* Remove all scroll bars on FRAME that haven't been saved since the
5196 last call to `*condemn_scroll_bars_hook'. */
5199 XTjudge_scroll_bars (f
)
5202 Lisp_Object bar
, next
;
5204 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
5206 /* Clear out the condemned list now so we won't try to process any
5207 more events on the hapless scroll bars. */
5208 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
5210 for (; ! NILP (bar
); bar
= next
)
5212 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
5214 x_scroll_bar_remove (b
);
5217 b
->next
= b
->prev
= Qnil
;
5220 /* Now there should be no references to the condemned scroll bars,
5221 and they should get garbage-collected. */
5225 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
5226 is set to something other than NO_EVENT, it is enqueued.
5228 This may be called from a signal handler, so we have to ignore GC
5232 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
5233 struct scroll_bar
*bar
;
5234 ControlPartCode part_code
;
5236 struct input_event
*bufp
;
5238 int win_y
, top_range
;
5240 if (! GC_WINDOWP (bar
->window
))
5243 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
5244 bufp
->frame_or_window
= bar
->window
;
5247 bar
->dragging
= Qnil
;
5251 case kControlUpButtonPart
:
5252 bufp
->part
= scroll_bar_up_arrow
;
5254 case kControlDownButtonPart
:
5255 bufp
->part
= scroll_bar_down_arrow
;
5257 case kControlPageUpPart
:
5258 bufp
->part
= scroll_bar_above_handle
;
5260 case kControlPageDownPart
:
5261 bufp
->part
= scroll_bar_below_handle
;
5263 #if TARGET_API_MAC_CARBON
5266 case kControlIndicatorPart
:
5268 if (er
->what
== mouseDown
)
5269 bar
->dragging
= make_number (0);
5270 XSETVECTOR (last_mouse_scroll_bar
, bar
);
5271 bufp
->part
= scroll_bar_handle
;
5275 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
5276 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
5278 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
5282 if (! NILP (bar
->dragging
))
5283 win_y
-= XINT (bar
->dragging
);
5287 if (win_y
> top_range
)
5290 XSETINT (bufp
->x
, win_y
);
5291 XSETINT (bufp
->y
, top_range
);
5294 #ifndef USE_TOOLKIT_SCROLL_BARS
5296 /* Handle some mouse motion while someone is dragging the scroll bar.
5298 This may be called from a signal handler, so we have to ignore GC
5302 x_scroll_bar_note_movement (bar
, y_pos
, t
)
5303 struct scroll_bar
*bar
;
5307 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
5309 last_mouse_movement_time
= t
;
5312 XSETVECTOR (last_mouse_scroll_bar
, bar
);
5314 /* If we're dragging the bar, display it. */
5315 if (! GC_NILP (bar
->dragging
))
5317 /* Where should the handle be now? */
5318 int new_start
= y_pos
- 24;
5320 if (new_start
!= XINT (bar
->start
))
5322 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
5324 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
5329 #endif /* !USE_TOOLKIT_SCROLL_BARS */
5331 /* Return information to the user about the current position of the mouse
5332 on the scroll bar. */
5335 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
5337 Lisp_Object
*bar_window
;
5338 enum scroll_bar_part
*part
;
5340 unsigned long *time
;
5342 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
5343 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5344 #if TARGET_API_MAC_CARBON
5345 WindowPtr wp
= GetControlOwner (ch
);
5347 WindowPtr wp
= (*ch
)->contrlOwner
;
5350 struct frame
*f
= mac_window_to_frame (wp
);
5351 int win_y
, top_range
;
5353 SetPortWindowPort (wp
);
5355 GetMouse (&mouse_pos
);
5357 win_y
= mouse_pos
.v
- XINT (bar
->top
);
5358 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
5360 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
5364 if (! NILP (bar
->dragging
))
5365 win_y
-= XINT (bar
->dragging
);
5369 if (win_y
> top_range
)
5373 *bar_window
= bar
->window
;
5375 if (! NILP (bar
->dragging
))
5376 *part
= scroll_bar_handle
;
5377 else if (win_y
< XINT (bar
->start
))
5378 *part
= scroll_bar_above_handle
;
5379 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
5380 *part
= scroll_bar_handle
;
5382 *part
= scroll_bar_below_handle
;
5384 XSETINT (*x
, win_y
);
5385 XSETINT (*y
, top_range
);
5388 last_mouse_scroll_bar
= Qnil
;
5390 *time
= last_mouse_movement_time
;
5394 /* The screen has been cleared so we may have changed foreground or
5395 background colors, and the scroll bars may need to be redrawn.
5396 Clear out the scroll bars, and ask for expose events, so we can
5400 x_scroll_bar_clear (f
)
5403 XTcondemn_scroll_bars (f
);
5404 XTjudge_scroll_bars (f
);
5408 /***********************************************************************
5410 ***********************************************************************/
5412 /* Set clipping for output in glyph row ROW. W is the window in which
5413 we operate. GC is the graphics context to set clipping in.
5415 ROW may be a text row or, e.g., a mode line. Text rows must be
5416 clipped to the interior of the window dedicated to text display,
5417 mode lines must be clipped to the whole window. */
5420 x_clip_to_row (w
, row
, area
, gc
)
5422 struct glyph_row
*row
;
5426 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5428 int window_x
, window_y
, window_width
;
5430 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
5432 clip_rect
.left
= window_x
;
5433 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5434 clip_rect
.top
= max (clip_rect
.top
, window_y
);
5435 clip_rect
.right
= clip_rect
.left
+ window_width
;
5436 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
5438 mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f
), gc
, &clip_rect
, 1);
5442 /* Draw a hollow box cursor on window W in glyph row ROW. */
5445 x_draw_hollow_cursor (w
, row
)
5447 struct glyph_row
*row
;
5449 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5450 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5451 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5454 struct glyph
*cursor_glyph
;
5457 /* Get the glyph the cursor is on. If we can't tell because
5458 the current matrix is invalid or such, give up. */
5459 cursor_glyph
= get_phys_cursor_glyph (w
);
5460 if (cursor_glyph
== NULL
)
5463 /* Compute frame-relative coordinates for phys cursor. */
5464 get_phys_cursor_geometry (w
, row
, cursor_glyph
, &x
, &y
, &h
);
5465 wd
= w
->phys_cursor_width
;
5467 /* The foreground of cursor_gc is typically the same as the normal
5468 background color, which can cause the cursor box to be invisible. */
5469 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5470 if (dpyinfo
->scratch_cursor_gc
)
5471 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
5473 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
5474 GCForeground
, &xgcv
);
5475 gc
= dpyinfo
->scratch_cursor_gc
;
5477 /* Set clipping, draw the rectangle, and reset clipping again. */
5478 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5479 mac_draw_rectangle (f
, gc
, x
, y
, wd
, h
- 1);
5480 mac_reset_clip_rectangles (dpy
, gc
);
5484 /* Draw a bar cursor on window W in glyph row ROW.
5486 Implementation note: One would like to draw a bar cursor with an
5487 angle equal to the one given by the font property XA_ITALIC_ANGLE.
5488 Unfortunately, I didn't find a font yet that has this property set.
5492 x_draw_bar_cursor (w
, row
, width
, kind
)
5494 struct glyph_row
*row
;
5496 enum text_cursor_kinds kind
;
5498 struct frame
*f
= XFRAME (w
->frame
);
5499 struct glyph
*cursor_glyph
;
5501 /* If cursor is out of bounds, don't draw garbage. This can happen
5502 in mini-buffer windows when switching between echo area glyphs
5504 cursor_glyph
= get_phys_cursor_glyph (w
);
5505 if (cursor_glyph
== NULL
)
5508 /* If on an image, draw like a normal cursor. That's usually better
5509 visible than drawing a bar, esp. if the image is large so that
5510 the bar might not be in the window. */
5511 if (cursor_glyph
->type
== IMAGE_GLYPH
)
5513 struct glyph_row
*row
;
5514 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5515 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
5519 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5520 Window window
= FRAME_MAC_WINDOW (f
);
5521 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
5522 unsigned long mask
= GCForeground
| GCBackground
;
5523 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
5526 /* If the glyph's background equals the color we normally draw
5527 the bar cursor in, the bar cursor in its normal color is
5528 invisible. Use the glyph's foreground color instead in this
5529 case, on the assumption that the glyph's colors are chosen so
5530 that the glyph is legible. */
5531 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
5532 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
5534 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5537 XChangeGC (dpy
, gc
, mask
, &xgcv
);
5540 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
5541 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
5545 width
= FRAME_CURSOR_WIDTH (f
);
5546 width
= min (cursor_glyph
->pixel_width
, width
);
5548 w
->phys_cursor_width
= width
;
5549 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5551 if (kind
== BAR_CURSOR
)
5552 mac_fill_rectangle (f
, gc
,
5553 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5554 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
5555 width
, row
->height
);
5557 mac_fill_rectangle (f
, gc
,
5558 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5559 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
5560 row
->height
- width
),
5561 cursor_glyph
->pixel_width
,
5564 mac_reset_clip_rectangles (dpy
, gc
);
5569 /* RIF: Define cursor CURSOR on frame F. */
5572 mac_define_frame_cursor (f
, cursor
)
5576 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5578 if (dpyinfo
->x_focus_frame
== f
)
5579 SetThemeCursor (cursor
);
5583 /* RIF: Clear area on frame F. */
5586 mac_clear_frame_area (f
, x
, y
, width
, height
)
5588 int x
, y
, width
, height
;
5590 mac_clear_area (f
, x
, y
, width
, height
);
5594 /* RIF: Draw cursor on window W. */
5597 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
5599 struct glyph_row
*glyph_row
;
5601 int cursor_type
, cursor_width
;
5606 w
->phys_cursor_type
= cursor_type
;
5607 w
->phys_cursor_on_p
= 1;
5609 if (glyph_row
->exact_window_width_line_p
5610 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
5612 glyph_row
->cursor_in_fringe_p
= 1;
5613 draw_fringe_bitmap (w
, glyph_row
, 0);
5616 switch (cursor_type
)
5618 case HOLLOW_BOX_CURSOR
:
5619 x_draw_hollow_cursor (w
, glyph_row
);
5622 case FILLED_BOX_CURSOR
:
5623 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
5627 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
5631 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
5635 w
->phys_cursor_width
= 0;
5647 #if 0 /* MAC_TODO: no icon support yet. */
5649 x_bitmap_icon (f
, icon
)
5655 if (FRAME_W32_WINDOW (f
) == 0)
5659 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
5660 else if (STRINGP (icon
))
5661 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
5662 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
5663 else if (SYMBOLP (icon
))
5667 if (EQ (icon
, intern ("application")))
5668 name
= (LPCTSTR
) IDI_APPLICATION
;
5669 else if (EQ (icon
, intern ("hand")))
5670 name
= (LPCTSTR
) IDI_HAND
;
5671 else if (EQ (icon
, intern ("question")))
5672 name
= (LPCTSTR
) IDI_QUESTION
;
5673 else if (EQ (icon
, intern ("exclamation")))
5674 name
= (LPCTSTR
) IDI_EXCLAMATION
;
5675 else if (EQ (icon
, intern ("asterisk")))
5676 name
= (LPCTSTR
) IDI_ASTERISK
;
5677 else if (EQ (icon
, intern ("winlogo")))
5678 name
= (LPCTSTR
) IDI_WINLOGO
;
5682 hicon
= LoadIcon (NULL
, name
);
5690 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
5695 #endif /* MAC_TODO */
5697 /************************************************************************
5699 ************************************************************************/
5701 /* Display Error Handling functions not used on W32. Listing them here
5702 helps diff stay in step when comparing w32term.c with xterm.c.
5704 x_error_catcher (display, error)
5705 x_catch_errors (dpy)
5706 x_catch_errors_unwind (old_val)
5707 x_check_errors (dpy, format)
5708 x_had_errors_p (dpy)
5709 x_clear_errors (dpy)
5710 x_uncatch_errors (dpy, count)
5712 x_connection_signal (signalnum)
5713 x_connection_closed (dpy, error_message)
5714 x_error_quitter (display, error)
5715 x_error_handler (display, error)
5716 x_io_error_quitter (display)
5721 /* Changing the font of the frame. */
5723 /* Give frame F the font named FONTNAME as its default font, and
5724 return the full name of that font. FONTNAME may be a wildcard
5725 pattern; in that case, we choose some font that fits the pattern.
5726 The return value shows which font we chose. */
5729 x_new_font (f
, fontname
)
5731 register char *fontname
;
5733 struct font_info
*fontp
5734 = FS_LOAD_FONT (f
, 0, fontname
, -1);
5739 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
5740 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
5741 FRAME_FONTSET (f
) = -1;
5743 FRAME_COLUMN_WIDTH (f
) = fontp
->average_width
;
5744 FRAME_SPACE_WIDTH (f
) = fontp
->space_width
;
5745 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
5747 compute_fringe_widths (f
, 1);
5749 /* Compute the scroll bar width in character columns. */
5750 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
5752 int wid
= FRAME_COLUMN_WIDTH (f
);
5753 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
5754 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
5758 int wid
= FRAME_COLUMN_WIDTH (f
);
5759 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
5762 /* Now make the frame display the given font. */
5763 if (FRAME_MAC_WINDOW (f
) != 0)
5765 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
5767 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
5769 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
5772 /* Don't change the size of a tip frame; there's no point in
5773 doing it because it's done in Fx_show_tip, and it leads to
5774 problems because the tip frame has no widget. */
5775 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
5776 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
5779 return build_string (fontp
->full_name
);
5782 /* Give frame F the fontset named FONTSETNAME as its default font, and
5783 return the full name of that fontset. FONTSETNAME may be a wildcard
5784 pattern; in that case, we choose some fontset that fits the pattern.
5785 The return value shows which fontset we chose. */
5788 x_new_fontset (f
, fontsetname
)
5792 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5798 if (FRAME_FONTSET (f
) == fontset
)
5799 /* This fontset is already set in frame F. There's nothing more
5801 return fontset_name (fontset
);
5803 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5805 if (!STRINGP (result
))
5806 /* Can't load ASCII font. */
5809 /* Since x_new_font doesn't update any fontset information, do it now. */
5810 FRAME_FONTSET (f
) = fontset
;
5812 return build_string (fontsetname
);
5816 /***********************************************************************
5817 TODO: W32 Input Methods
5818 ***********************************************************************/
5819 /* Listing missing functions from xterm.c helps diff stay in step.
5821 xim_destroy_callback (xim, client_data, call_data)
5822 xim_open_dpy (dpyinfo, resource_name)
5824 xim_instantiate_callback (display, client_data, call_data)
5825 xim_initialize (dpyinfo, resource_name)
5826 xim_close_dpy (dpyinfo)
5832 mac_get_window_bounds (f
, inner
, outer
)
5834 Rect
*inner
, *outer
;
5836 #if TARGET_API_MAC_CARBON
5837 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5838 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5839 #else /* not TARGET_API_MAC_CARBON */
5840 RgnHandle region
= NewRgn ();
5842 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5843 *inner
= (*region
)->rgnBBox
;
5844 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5845 *outer
= (*region
)->rgnBBox
;
5846 DisposeRgn (region
);
5847 #endif /* not TARGET_API_MAC_CARBON */
5851 mac_handle_origin_change (f
)
5854 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5858 mac_handle_size_change (f
, pixelwidth
, pixelheight
)
5860 int pixelwidth
, pixelheight
;
5864 cols
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, pixelwidth
);
5865 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, pixelheight
);
5867 if (cols
!= FRAME_COLS (f
)
5868 || rows
!= FRAME_LINES (f
)
5869 || pixelwidth
!= FRAME_PIXEL_WIDTH (f
)
5870 || pixelheight
!= FRAME_PIXEL_HEIGHT (f
))
5872 /* We pass 1 for DELAY since we can't run Lisp code inside of
5874 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5875 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5876 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5877 SET_FRAME_GARBAGED (f
);
5879 /* If cursor was outside the new size, mark it as off. */
5880 mark_window_cursors_off (XWINDOW (f
->root_window
));
5882 /* Clear out any recollection of where the mouse highlighting
5883 was, since it might be in a place that's outside the new
5884 frame size. Actually checking whether it is outside is a
5885 pain in the neck, so don't try--just let the highlighting be
5886 done afresh with new size. */
5887 cancel_mouse_face (f
);
5889 #if TARGET_API_MAC_CARBON
5890 if (f
->output_data
.mac
->hourglass_control
)
5893 mac_prepare_for_quickdraw (f
);
5895 MoveControl (f
->output_data
.mac
->hourglass_control
,
5896 pixelwidth
- HOURGLASS_WIDTH
, 0);
5903 /* Calculate the absolute position in frame F
5904 from its current recorded position values and gravity. */
5907 x_calc_absolute_position (f
)
5910 int width_diff
= 0, height_diff
= 0;
5911 int flags
= f
->size_hint_flags
;
5914 /* We have nothing to do if the current position
5915 is already for the top-left corner. */
5916 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5919 /* Find the offsets of the outside upper-left corner of
5920 the inner window, with respect to the outer window. */
5921 mac_get_window_bounds (f
, &inner
, &outer
);
5923 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5924 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5926 /* Treat negative positions as relative to the leftmost bottommost
5927 position that fits on the screen. */
5928 if (flags
& XNegative
)
5929 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5931 - FRAME_PIXEL_WIDTH (f
)
5934 if (flags
& YNegative
)
5935 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5937 - FRAME_PIXEL_HEIGHT (f
)
5940 /* The left_pos and top_pos
5941 are now relative to the top and left screen edges,
5942 so the flags should correspond. */
5943 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5946 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5947 to really change the position, and 0 when calling from
5948 x_make_frame_visible (in that case, XOFF and YOFF are the current
5949 position values). It is -1 when calling from x_set_frame_parameters,
5950 which means, do adjust for borders but don't change the gravity. */
5953 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5955 register int xoff
, yoff
;
5958 if (change_gravity
> 0)
5962 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5964 f
->size_hint_flags
|= XNegative
;
5966 f
->size_hint_flags
|= YNegative
;
5967 f
->win_gravity
= NorthWestGravity
;
5969 x_calc_absolute_position (f
);
5972 x_wm_set_size_hint (f
, (long) 0, 0);
5974 #if TARGET_API_MAC_CARBON
5975 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5976 /* If the title bar is completely outside the screen, adjust the
5978 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5979 kWindowConstrainMoveRegardlessOfFit
5980 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5981 #if USE_CARBON_EVENTS
5982 if (!NILP (tip_frame
) && XFRAME (tip_frame
) == f
)
5984 mac_handle_origin_change (f
);
5987 Rect inner
, outer
, screen_rect
, dummy
;
5988 RgnHandle region
= NewRgn ();
5990 mac_get_window_bounds (f
, &inner
, &outer
);
5991 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5992 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5993 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5994 f
->top_pos
+ f
->y_pixels_diff
, false);
5996 /* If the title bar is completely outside the screen, adjust the
5997 position. The variable `outer' holds the title bar rectangle.
5998 The variable `inner' holds slightly smaller one than `outer',
5999 so that the calculation of overlapping may not become too
6001 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
6002 outer
= (*region
)->rgnBBox
;
6003 DisposeRgn (region
);
6005 InsetRect (&inner
, 8, 8);
6006 screen_rect
= qd
.screenBits
.bounds
;
6007 screen_rect
.top
+= GetMBarHeight ();
6009 if (!SectRect (&inner
, &screen_rect
, &dummy
))
6011 if (inner
.right
<= screen_rect
.left
)
6012 f
->left_pos
= screen_rect
.left
;
6013 else if (inner
.left
>= screen_rect
.right
)
6014 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
6016 if (inner
.bottom
<= screen_rect
.top
)
6017 f
->top_pos
= screen_rect
.top
;
6018 else if (inner
.top
>= screen_rect
.bottom
)
6019 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
6021 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
6022 f
->top_pos
+ f
->y_pixels_diff
, false);
6030 /* Call this to change the size of frame F's x-window.
6031 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
6032 for this size change and subsequent size changes.
6033 Otherwise we leave the window gravity unchanged. */
6036 x_set_window_size (f
, change_gravity
, cols
, rows
)
6041 int pixelwidth
, pixelheight
;
6045 check_frame_size (f
, &rows
, &cols
);
6046 f
->scroll_bar_actual_width
6047 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
6049 compute_fringe_widths (f
, 0);
6051 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
6052 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
6054 f
->win_gravity
= NorthWestGravity
;
6055 x_wm_set_size_hint (f
, (long) 0, 0);
6057 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
6059 #if USE_CARBON_EVENTS
6060 if (!NILP (tip_frame
) && f
== XFRAME (tip_frame
))
6062 mac_handle_size_change (f
, pixelwidth
, pixelheight
);
6067 /* Mouse warping. */
6069 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
6072 x_set_mouse_position (f
, x
, y
)
6078 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
6079 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
6081 if (pix_x
< 0) pix_x
= 0;
6082 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
6084 if (pix_y
< 0) pix_y
= 0;
6085 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
6087 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
6091 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
6100 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
6106 CGWarpMouseCursorPosition (point
);
6109 #if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
6112 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
6113 0, 0, 0, 0, pix_x
, pix_y
);
6119 /* focus shifting, raising and lowering. */
6122 x_focus_on_frame (f
)
6125 #if 0 /* This proves to be unpleasant. */
6129 /* I don't think that the ICCCM allows programs to do things like this
6130 without the interaction of the window manager. Whatever you end up
6131 doing with this code, do it to x_unfocus_frame too. */
6132 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6133 RevertToPointerRoot
, CurrentTime
);
6143 /* Raise frame F. */
6149 if (f
->async_visible
)
6152 BringToFront (FRAME_MAC_WINDOW (f
));
6157 /* Lower frame F. */
6163 if (f
->async_visible
)
6166 SendBehind (FRAME_MAC_WINDOW (f
), NULL
);
6172 XTframe_raise_lower (f
, raise_flag
)
6182 /* Change of visibility. */
6185 mac_handle_visibility_change (f
)
6188 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
6189 int visible
= 0, iconified
= 0;
6190 struct input_event buf
;
6192 if (IsWindowVisible (wp
))
6194 if (IsWindowCollapsed (wp
))
6200 if (!f
->async_visible
&& visible
)
6204 /* wait_reading_process_output will notice this and update
6205 the frame's display structures. If we were made
6206 invisible, we should not set garbaged, because that stops
6207 redrawing on Update events. */
6208 SET_FRAME_GARBAGED (f
);
6211 buf
.kind
= DEICONIFY_EVENT
;
6212 XSETFRAME (buf
.frame_or_window
, f
);
6214 kbd_buffer_store_event (&buf
);
6216 else if (! NILP (Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
6217 /* Force a redisplay sooner or later to update the
6218 frame titles in case this is the second frame. */
6219 record_asynch_buffer_change ();
6221 else if (f
->async_visible
&& !visible
)
6225 buf
.kind
= ICONIFY_EVENT
;
6226 XSETFRAME (buf
.frame_or_window
, f
);
6228 kbd_buffer_store_event (&buf
);
6231 f
->async_visible
= visible
;
6232 f
->async_iconified
= iconified
;
6235 /* This tries to wait until the frame is really visible.
6236 However, if the window manager asks the user where to position
6237 the frame, this will return before the user finishes doing that.
6238 The frame will not actually be visible at that time,
6239 but it will become visible later when the window manager
6240 finishes with it. */
6243 x_make_frame_visible (f
)
6248 if (! FRAME_VISIBLE_P (f
))
6250 /* We test FRAME_GARBAGED_P here to make sure we don't
6251 call x_set_offset a second time
6252 if we get to x_make_frame_visible a second time
6253 before the window gets really visible. */
6254 if (! FRAME_ICONIFIED_P (f
)
6255 && ! f
->output_data
.mac
->asked_for_visible
)
6257 #if TARGET_API_MAC_CARBON
6258 if (!(FRAME_SIZE_HINTS (f
)->flags
& (USPosition
| PPosition
)))
6260 struct frame
*sf
= SELECTED_FRAME ();
6261 if (!FRAME_MAC_P (sf
))
6262 RepositionWindow (FRAME_MAC_WINDOW (f
), NULL
,
6263 kWindowCenterOnMainScreen
);
6265 RepositionWindow (FRAME_MAC_WINDOW (f
),
6266 FRAME_MAC_WINDOW (sf
),
6267 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
6268 kWindowCascadeStartAtParentWindowScreen
6270 kWindowCascadeOnParentWindowScreen
6273 #if USE_CARBON_EVENTS
6274 if (!NILP (tip_frame
) && f
== XFRAME (tip_frame
))
6276 mac_handle_origin_change (f
);
6280 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
6283 f
->output_data
.mac
->asked_for_visible
= 1;
6285 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
6286 ShowWindow (FRAME_MAC_WINDOW (f
));
6289 XFlush (FRAME_MAC_DISPLAY (f
));
6291 /* Synchronize to ensure Emacs knows the frame is visible
6292 before we do anything else. We do this loop with input not blocked
6293 so that incoming events are handled. */
6298 /* This must come after we set COUNT. */
6301 XSETFRAME (frame
, f
);
6303 /* Wait until the frame is visible. Process X events until a
6304 MapNotify event has been seen, or until we think we won't get a
6305 MapNotify at all.. */
6306 for (count
= input_signal_count
+ 10;
6307 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
6309 /* Force processing of queued events. */
6312 /* Machines that do polling rather than SIGIO have been
6313 observed to go into a busy-wait here. So we'll fake an
6314 alarm signal to let the handler know that there's something
6315 to be read. We used to raise a real alarm, but it seems
6316 that the handler isn't always enabled here. This is
6318 if (input_polling_used ())
6320 /* It could be confusing if a real alarm arrives while
6321 processing the fake one. Turn it off and let the
6322 handler reset it. */
6323 extern void poll_for_input_1
P_ ((void));
6324 int old_poll_suppress_count
= poll_suppress_count
;
6325 poll_suppress_count
= 1;
6326 poll_for_input_1 ();
6327 poll_suppress_count
= old_poll_suppress_count
;
6330 /* See if a MapNotify event has been processed. */
6331 FRAME_SAMPLE_VISIBILITY (f
);
6336 /* Change from mapped state to withdrawn state. */
6338 /* Make the frame visible (mapped and not iconified). */
6341 x_make_frame_invisible (f
)
6344 /* A deactivate event does not occur when the last visible frame is
6345 made invisible. So if we clear the highlight here, it will not
6346 be rehighlighted when it is made visible. */
6348 /* Don't keep the highlight on an invisible frame. */
6349 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
6350 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
6355 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
6356 that the current position of the window is user-specified, rather than
6357 program-specified, so that when the window is mapped again, it will be
6358 placed at the same location, without forcing the user to position it
6359 by hand again (they have already done that once for this window.) */
6360 x_wm_set_size_hint (f
, (long) 0, 1);
6362 HideWindow (FRAME_MAC_WINDOW (f
));
6366 #if !USE_CARBON_EVENTS
6367 mac_handle_visibility_change (f
);
6371 /* Change window state from mapped to iconified. */
6379 /* A deactivate event does not occur when the last visible frame is
6380 iconified. So if we clear the highlight here, it will not be
6381 rehighlighted when it is deiconified. */
6383 /* Don't keep the highlight on an invisible frame. */
6384 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
6385 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
6388 if (f
->async_iconified
)
6393 FRAME_SAMPLE_VISIBILITY (f
);
6395 if (! FRAME_VISIBLE_P (f
))
6396 ShowWindow (FRAME_MAC_WINDOW (f
));
6398 err
= CollapseWindow (FRAME_MAC_WINDOW (f
), true);
6403 error ("Can't notify window manager of iconification");
6405 #if !USE_CARBON_EVENTS
6406 mac_handle_visibility_change (f
);
6411 /* Free X resources of frame F. */
6414 x_free_frame_resources (f
)
6417 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6418 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
6422 if (wp
!= tip_window
)
6423 remove_window_handler (wp
);
6426 if (wp
== tip_window
)
6427 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
6428 closed' event. So we reset tip_window here. */
6431 free_frame_menubar (f
);
6433 if (FRAME_FACE_CACHE (f
))
6434 free_frame_faces (f
);
6438 if (FRAME_SIZE_HINTS (f
))
6439 xfree (FRAME_SIZE_HINTS (f
));
6441 xfree (f
->output_data
.mac
);
6442 f
->output_data
.mac
= NULL
;
6444 if (f
== dpyinfo
->x_focus_frame
)
6446 dpyinfo
->x_focus_frame
= 0;
6447 #if USE_MAC_FONT_PANEL
6448 mac_set_font_info_for_selection (NULL
, DEFAULT_FACE_ID
, 0);
6451 if (f
== dpyinfo
->x_focus_event_frame
)
6452 dpyinfo
->x_focus_event_frame
= 0;
6453 if (f
== dpyinfo
->x_highlight_frame
)
6454 dpyinfo
->x_highlight_frame
= 0;
6456 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6458 dpyinfo
->mouse_face_beg_row
6459 = dpyinfo
->mouse_face_beg_col
= -1;
6460 dpyinfo
->mouse_face_end_row
6461 = dpyinfo
->mouse_face_end_col
= -1;
6462 dpyinfo
->mouse_face_window
= Qnil
;
6463 dpyinfo
->mouse_face_deferred_gc
= 0;
6464 dpyinfo
->mouse_face_mouse_frame
= 0;
6471 /* Destroy the X window of frame F. */
6474 x_destroy_window (f
)
6477 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6479 x_free_frame_resources (f
);
6481 dpyinfo
->reference_count
--;
6485 /* Setting window manager hints. */
6487 /* Set the normal size hints for the window manager, for frame F.
6488 FLAGS is the flags word to use--or 0 meaning preserve the flags
6489 that the window now has.
6490 If USER_POSITION is nonzero, we set the USPosition
6491 flag (this is useful when FLAGS is 0). */
6493 x_wm_set_size_hint (f
, flags
, user_position
)
6498 int base_width
, base_height
, width_inc
, height_inc
;
6499 int min_rows
= 0, min_cols
= 0;
6500 XSizeHints
*size_hints
;
6502 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
6503 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
6504 width_inc
= FRAME_COLUMN_WIDTH (f
);
6505 height_inc
= FRAME_LINE_HEIGHT (f
);
6507 check_frame_size (f
, &min_rows
, &min_cols
);
6509 size_hints
= FRAME_SIZE_HINTS (f
);
6510 if (size_hints
== NULL
)
6512 size_hints
= FRAME_SIZE_HINTS (f
) = xmalloc (sizeof (XSizeHints
));
6513 bzero (size_hints
, sizeof (XSizeHints
));
6516 size_hints
->flags
|= PResizeInc
| PMinSize
| PBaseSize
;
6517 size_hints
->width_inc
= width_inc
;
6518 size_hints
->height_inc
= height_inc
;
6519 size_hints
->min_width
= base_width
+ min_cols
* width_inc
;
6520 size_hints
->min_height
= base_height
+ min_rows
* height_inc
;
6521 size_hints
->base_width
= base_width
;
6522 size_hints
->base_height
= base_height
;
6525 size_hints
->flags
= flags
;
6526 else if (user_position
)
6528 size_hints
->flags
&= ~ PPosition
;
6529 size_hints
->flags
|= USPosition
;
6533 #if 0 /* MAC_TODO: hide application instead of iconify? */
6534 /* Used for IconicState or NormalState */
6537 x_wm_set_window_state (f
, state
)
6541 #ifdef USE_X_TOOLKIT
6544 XtSetArg (al
[0], XtNinitialState
, state
);
6545 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6546 #else /* not USE_X_TOOLKIT */
6547 Window window
= FRAME_X_WINDOW (f
);
6549 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
6550 f
->output_data
.x
->wm_hints
.initial_state
= state
;
6552 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6553 #endif /* not USE_X_TOOLKIT */
6557 x_wm_set_icon_pixmap (f
, pixmap_id
)
6563 #ifndef USE_X_TOOLKIT
6564 Window window
= FRAME_X_WINDOW (f
);
6569 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
6570 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
6574 /* It seems there is no way to turn off use of an icon pixmap.
6575 The following line does it, only if no icon has yet been created,
6576 for some window managers. But with mwm it crashes.
6577 Some people say it should clear the IconPixmapHint bit in this case,
6578 but that doesn't work, and the X consortium said it isn't the
6579 right thing at all. Since there is no way to win,
6580 best to explicitly give up. */
6582 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
6588 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
6592 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
6593 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6596 #else /* not USE_X_TOOLKIT */
6598 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
6599 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6601 #endif /* not USE_X_TOOLKIT */
6604 #endif /* MAC_TODO */
6607 x_wm_set_icon_position (f
, icon_x
, icon_y
)
6611 #if 0 /* MAC_TODO: no icons on Mac */
6612 #ifdef USE_X_TOOLKIT
6613 Window window
= XtWindow (f
->output_data
.x
->widget
);
6615 Window window
= FRAME_X_WINDOW (f
);
6618 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
6619 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
6620 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
6622 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6623 #endif /* MAC_TODO */
6627 /***********************************************************************
6629 ***********************************************************************/
6631 /* An XLFD pattern is divided into blocks delimited by '*'. This
6632 structure holds information for each block. */
6633 struct xlfdpat_block
6635 /* Length of the pattern string in this block. Non-zero except for
6636 the first and the last blocks. */
6639 /* Pattern string except the last character in this block. The last
6640 character is replaced with NUL in order to use it as a
6642 unsigned char *pattern
;
6644 /* Last character of the pattern string. Must not be '?'. */
6645 unsigned char last_char
;
6647 /* One of the tables for the Boyer-Moore string search. It
6648 specifies the number of positions to proceed for each character
6649 with which the match fails. */
6652 /* The skip value for the last character in the above `skip' is
6653 assigned to `infinity' in order to simplify a loop condition.
6654 The original value is saved here. */
6660 /* Normalized pattern string. "Normalized" means that capital
6661 letters are lowered, blocks are not empty except the first and
6662 the last ones, and trailing '?'s in a block that is not the last
6663 one are moved to the next one. The last character in each block
6664 is replaced with NUL. */
6667 /* Number of characters except '*'s and trailing '?'s in the
6668 normalized pattern string. */
6671 /* Number of trailing '?'s in the normalized pattern string. */
6672 int trailing_anychars
;
6674 /* Number of blocks and information for each block. The latter is
6675 NULL if the pattern is exact (no '*' or '?' in it). */
6677 struct xlfdpat_block
*blocks
;
6681 xlfdpat_destroy (pat
)
6682 struct xlfdpat
*pat
;
6689 xfree (pat
->blocks
);
6696 static struct xlfdpat
*
6697 xlfdpat_create (pattern
)
6700 struct xlfdpat
*pat
;
6701 int nblocks
, i
, skip
;
6702 unsigned char last_char
, *p
, *q
, *anychar_head
;
6703 struct xlfdpat_block
*blk
;
6705 pat
= xmalloc (sizeof (struct xlfdpat
));
6706 pat
->buf
= xmalloc (strlen (pattern
) + 1);
6708 /* Normalize the pattern string and store it to `pat->buf'. */
6710 anychar_head
= NULL
;
6713 for (p
= pattern
; *p
; p
++)
6715 unsigned char c
= *p
;
6718 if (last_char
== '*')
6719 /* ...a** -> ...a* */
6723 if (last_char
== '?')
6725 if (anychar_head
> pat
->buf
&& *(anychar_head
- 1) == '*')
6726 /* ...*??* -> ...*?? */
6729 /* ...a??* -> ...a*?? */
6731 *anychar_head
++ = '*';
6739 if (last_char
!= '?')
6743 /* On Mac OS X 10.3, tolower also converts non-ASCII
6744 characters for some locales. */
6748 *q
++ = last_char
= c
;
6752 pat
->nblocks
= nblocks
;
6753 if (last_char
!= '?')
6754 pat
->trailing_anychars
= 0;
6757 pat
->trailing_anychars
= q
- anychar_head
;
6760 pat
->nchars
= q
- pat
->buf
- (nblocks
- 1);
6762 if (anychar_head
== NULL
&& nblocks
== 1)
6764 /* The pattern is exact. */
6769 pat
->blocks
= xmalloc (sizeof (struct xlfdpat_block
) * nblocks
);
6771 /* Divide the normalized pattern into blocks. */
6773 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
- 1; blk
++)
6778 blk
->len
= p
- blk
->pattern
;
6782 blk
->len
= q
- blk
->pattern
;
6784 /* Setup a table for the Boyer-Moore string search. */
6785 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
; blk
++)
6788 blk
->last_char
= blk
->pattern
[blk
->len
- 1];
6789 blk
->pattern
[blk
->len
- 1] = '\0';
6791 for (skip
= 1; skip
< blk
->len
; skip
++)
6792 if (blk
->pattern
[blk
->len
- skip
- 1] == '?')
6795 for (i
= 0; i
< 256; i
++)
6796 blk
->skip
[i
] = skip
;
6798 p
= blk
->pattern
+ (blk
->len
- skip
);
6800 blk
->skip
[*p
++] = skip
;
6802 blk
->last_char_skip
= blk
->skip
[blk
->last_char
];
6809 xlfdpat_exact_p (pat
)
6810 struct xlfdpat
*pat
;
6812 return pat
->blocks
== NULL
;
6815 /* Return the first string in STRING + 0, ..., STRING + START_MAX such
6816 that the pattern in *BLK matches with its prefix. Return NULL
6817 there is no such strings. STRING must be lowered in advance. */
6820 xlfdpat_block_match_1 (blk
, string
, start_max
)
6821 struct xlfdpat_block
*blk
;
6822 unsigned char *string
;
6825 int start
, infinity
;
6826 unsigned char *p
, *s
;
6828 xassert (blk
->len
> 0);
6829 xassert (start_max
+ blk
->len
<= strlen (string
));
6830 xassert (blk
->last_char
!= '?');
6832 /* See the comments in the function `boyer_moore' (search.c) for the
6833 use of `infinity'. */
6834 infinity
= start_max
+ blk
->len
+ 1;
6835 blk
->skip
[blk
->last_char
] = infinity
;
6840 /* Check the last character of the pattern. */
6841 s
= string
+ blk
->len
- 1;
6844 start
+= blk
->skip
[*(s
+ start
)];
6846 while (start
<= start_max
);
6848 if (start
< infinity
)
6849 /* Couldn't find the last character. */
6852 /* No less than `infinity' means we could find the last
6853 character at `s[start - infinity]'. */
6856 /* Check the remaining characters. We prefer making no-'?'
6857 cases faster because the use of '?' is really rare. */
6862 while (*p
++ == *s
++)
6865 while (*(p
- 1) == '?');
6867 if (*(p
- 1) == '\0')
6869 return string
+ start
;
6872 start
+= blk
->last_char_skip
;
6874 while (start
<= start_max
);
6879 #define xlfdpat_block_match(b, s, m) \
6880 ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
6881 : xlfdpat_block_match_1 (b, s, m))
6883 /* Check if XLFD pattern PAT, which is generated by `xfldpat_create',
6884 matches with STRING. STRING must be lowered in advance. */
6887 xlfdpat_match (pat
, string
)
6888 struct xlfdpat
*pat
;
6889 unsigned char *string
;
6891 int str_len
, nblocks
, i
, start_max
;
6892 struct xlfdpat_block
*blk
;
6895 xassert (pat
->nblocks
> 0);
6897 if (xlfdpat_exact_p (pat
))
6898 return strcmp (pat
->buf
, string
) == 0;
6900 /* The number of the characters in the string must not be smaller
6901 than that in the pattern. */
6902 str_len
= strlen (string
);
6903 if (str_len
< pat
->nchars
+ pat
->trailing_anychars
)
6906 /* Chop off the trailing '?'s. */
6907 str_len
-= pat
->trailing_anychars
;
6909 /* The last block. When it is non-empty, it must match at the end
6911 nblocks
= pat
->nblocks
;
6912 blk
= pat
->blocks
+ (nblocks
- 1);
6914 /* The last block is also the first one. */
6915 return (str_len
== blk
->len
6916 && (blk
->len
== 0 || xlfdpat_block_match (blk
, string
, 0)));
6917 else if (blk
->len
!= 0)
6918 if (!xlfdpat_block_match (blk
, string
+ (str_len
- blk
->len
), 0))
6921 /* The first block. When it is non-empty, it must match at the
6922 beginning of the string. */
6926 s
= xlfdpat_block_match (blk
, string
, 0);
6929 string
= s
+ blk
->len
;
6932 /* The rest of the blocks. */
6933 start_max
= str_len
- pat
->nchars
;
6934 for (i
= 1, blk
++; i
< nblocks
- 1; i
++, blk
++)
6936 s
= xlfdpat_block_match (blk
, string
, start_max
);
6939 start_max
-= s
- string
;
6940 string
= s
+ blk
->len
;
6947 /***********************************************************************
6949 ***********************************************************************/
6951 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6954 x_get_font_info (f
, font_idx
)
6958 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
6961 /* the global font name table */
6962 static char **font_name_table
= NULL
;
6963 static int font_name_table_size
= 0;
6964 static int font_name_count
= 0;
6966 /* Alist linking font family names to Font Manager font family
6967 references (which can also be used as QuickDraw font IDs). We use
6968 an alist because hash tables are not ready when the terminal frame
6969 for Mac OS Classic is created. */
6970 static Lisp_Object fm_font_family_alist
;
6972 /* Hash table linking font family names to ATSU font IDs. */
6973 static Lisp_Object atsu_font_id_hash
;
6974 /* Alist linking Font Manager style to face attributes. */
6975 static Lisp_Object fm_style_face_attributes_alist
;
6976 static Lisp_Object Vmac_atsu_font_table
;
6977 extern Lisp_Object QCfamily
, QCweight
, QCslant
, Qnormal
, Qbold
, Qitalic
;
6980 /* Alist linking character set strings to Mac text encoding and Emacs
6982 static Lisp_Object Vmac_charset_info_alist
;
6985 create_text_encoding_info_alist ()
6987 Lisp_Object result
= Qnil
, rest
;
6989 for (rest
= Vmac_charset_info_alist
; CONSP (rest
); rest
= XCDR (rest
))
6991 Lisp_Object charset_info
= XCAR (rest
);
6992 Lisp_Object charset
, coding_system
, text_encoding
;
6993 Lisp_Object existing_info
;
6995 if (!(CONSP (charset_info
)
6996 && STRINGP (charset
= XCAR (charset_info
))
6997 && CONSP (XCDR (charset_info
))
6998 && INTEGERP (text_encoding
= XCAR (XCDR (charset_info
)))
6999 && CONSP (XCDR (XCDR (charset_info
)))
7000 && SYMBOLP (coding_system
= XCAR (XCDR (XCDR (charset_info
))))))
7003 existing_info
= assq_no_quit (text_encoding
, result
);
7004 if (NILP (existing_info
))
7005 result
= Fcons (list3 (text_encoding
, coding_system
, charset
),
7008 if (NILP (Fmember (charset
, XCDR (XCDR (existing_info
)))))
7009 XSETCDR (XCDR (existing_info
),
7010 Fcons (charset
, XCDR (XCDR (existing_info
))));
7018 decode_mac_font_name (name
, size
, coding_system
)
7021 Lisp_Object coding_system
;
7023 struct coding_system coding
;
7026 if (!NILP (coding_system
) && !NILP (Fcoding_system_p (coding_system
)))
7028 for (p
= name
; *p
; p
++)
7029 if (!isascii (*p
) || iscntrl (*p
))
7034 setup_coding_system (coding_system
, &coding
);
7035 coding
.src_multibyte
= 0;
7036 coding
.dst_multibyte
= 1;
7037 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
7038 coding
.composing
= COMPOSITION_DISABLED
;
7039 buf
= (char *) alloca (size
);
7041 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
7042 bcopy (buf
, name
, coding
.produced
);
7043 name
[coding
.produced
] = '\0';
7047 /* If there's just one occurrence of '-' in the family name, it is
7048 replaced with '_'. (More than one occurrence of '-' means a
7049 "FOUNDRY-FAMILY-CHARSET"-style name.) */
7050 p
= strchr (name
, '-');
7051 if (p
&& strchr (p
+ 1, '-') == NULL
)
7054 for (p
= name
; *p
; p
++)
7055 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
7056 for some locales. */
7063 mac_to_x_fontname (name
, size
, style
, charset
)
7071 char xf
[256], *result
;
7074 if (sscanf (name
, "%31[^-]-%255[^-]-%31s", foundry
, family
, cs
) == 3)
7078 strcpy(foundry
, "Apple");
7079 strcpy(family
, name
);
7082 sprintf (xf
, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
7083 style
& bold
? "bold" : "medium", style
& italic
? 'i' : 'r',
7084 size
, size
* 10, size
? 72 : 0, size
? 72 : 0, size
* 10, charset
);
7086 result
= xmalloc (strlen (foundry
) + strlen (family
) + strlen (xf
) + 3 + 1);
7087 sprintf (result
, "-%s-%s-%s", foundry
, family
, xf
);
7088 for (p
= result
; *p
; p
++)
7089 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
7090 for some locales. */
7097 /* Parse fully-specified and instantiated X11 font spec XF, and store
7098 the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the
7099 parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the
7100 caller must allocate at least 256 and 32 bytes respectively. For
7101 ordinary Mac fonts, the value stored to FAMILY should just be their
7102 names, like "monaco", "Taipei", etc. Fonts converted from the GNU
7103 intlfonts collection contain their charset designation in their
7104 names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both
7105 types of font names are handled accordingly. */
7107 const int kDefaultFontSize
= 12;
7110 parse_x_font_name (xf
, family
, size
, style
, charset
)
7116 Str31 foundry
, weight
;
7117 int point_size
, avgwidth
;
7120 if (sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
7121 foundry
, family
, weight
, slant
, size
,
7122 &point_size
, &avgwidth
, charset
) != 8
7123 && sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
7124 foundry
, family
, weight
, slant
, size
,
7125 &point_size
, &avgwidth
, charset
) != 8)
7131 *size
= point_size
/ 10;
7132 else if (avgwidth
> 0)
7133 *size
= avgwidth
/ 10;
7136 *size
= kDefaultFontSize
;
7139 if (strcmp (weight
, "bold") == 0)
7144 if (NILP (Fassoc (build_string (charset
), Vmac_charset_info_alist
)))
7146 int foundry_len
= strlen (foundry
), family_len
= strlen (family
);
7148 if (foundry_len
+ family_len
+ strlen (charset
) + 2 < sizeof (Str255
))
7150 /* Like sprintf (family, "%s-%s-%s", foundry, family, charset),
7151 but take overlap into account. */
7152 memmove (family
+ foundry_len
+ 1, family
, family_len
);
7153 memcpy (family
, foundry
, foundry_len
);
7154 family
[foundry_len
] = '-';
7155 family
[foundry_len
+ 1 + family_len
] = '-';
7156 strcpy (family
+ foundry_len
+ 1 + family_len
+ 1, charset
);
7162 for (p
= family
; *p
; p
++)
7163 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
7164 for some locales. */
7173 add_font_name_table_entry (char *font_name
)
7175 if (font_name_table_size
== 0)
7177 font_name_table_size
= 256;
7178 font_name_table
= (char **)
7179 xmalloc (font_name_table_size
* sizeof (char *));
7181 else if (font_name_count
+ 1 >= font_name_table_size
)
7183 font_name_table_size
*= 2;
7184 font_name_table
= (char **)
7185 xrealloc (font_name_table
,
7186 font_name_table_size
* sizeof (char *));
7189 font_name_table
[font_name_count
++] = font_name
;
7193 add_mac_font_name (name
, size
, style
, charset
)
7200 add_font_name_table_entry (mac_to_x_fontname (name
, size
, style
, charset
));
7203 add_font_name_table_entry (mac_to_x_fontname (name
, 0, style
, charset
));
7204 add_font_name_table_entry (mac_to_x_fontname (name
, 0, italic
, charset
));
7205 add_font_name_table_entry (mac_to_x_fontname (name
, 0, bold
, charset
));
7206 add_font_name_table_entry (mac_to_x_fontname (name
, 0, italic
| bold
,
7213 fm_style_to_face_attributes (fm_style
)
7214 FMFontStyle fm_style
;
7218 fm_style
&= (bold
| italic
);
7219 tem
= assq_no_quit (make_number (fm_style
),
7220 fm_style_face_attributes_alist
);
7224 tem
= list4 (QCweight
, fm_style
& bold
? Qbold
: Qnormal
,
7225 QCslant
, fm_style
& italic
? Qitalic
: Qnormal
);
7226 fm_style_face_attributes_alist
=
7227 Fcons (Fcons (make_number (fm_style
), tem
),
7228 fm_style_face_attributes_alist
);
7234 /* Sets up the table font_name_table to contain the list of all fonts
7235 in the system the first time the table is used so that the Resource
7236 Manager need not be accessed every time this information is
7240 init_font_name_table ()
7242 #if TARGET_API_MAC_CARBON
7243 FMFontFamilyIterator ffi
;
7244 FMFontFamilyInstanceIterator ffii
;
7246 Lisp_Object text_encoding_info_alist
;
7247 struct gcpro gcpro1
;
7249 text_encoding_info_alist
= create_text_encoding_info_alist ();
7252 #if USE_CG_TEXT_DRAWING
7253 init_cg_text_anti_aliasing_threshold ();
7255 if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode
),
7256 text_encoding_info_alist
)))
7259 struct Lisp_Hash_Table
*h
;
7261 ItemCount nfonts
, i
;
7262 ATSUFontID
*font_ids
= NULL
;
7268 make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
7269 make_float (DEFAULT_REHASH_SIZE
),
7270 make_float (DEFAULT_REHASH_THRESHOLD
),
7272 h
= XHASH_TABLE (atsu_font_id_hash
);
7274 err
= ATSUFontCount (&nfonts
);
7277 font_ids
= xmalloc (sizeof (ATSUFontID
) * nfonts
);
7278 err
= ATSUGetFontIDs (font_ids
, nfonts
, NULL
);
7281 for (i
= 0; i
< nfonts
; i
++)
7283 err
= ATSUFindFontName (font_ids
[i
], kFontFamilyName
,
7284 kFontMacintoshPlatform
, kFontNoScript
,
7285 kFontNoLanguage
, 0, NULL
, &name_len
, NULL
);
7288 name
= xmalloc (name_len
+ 1);
7289 name
[name_len
] = '\0';
7290 err
= ATSUFindFontName (font_ids
[i
], kFontFamilyName
,
7291 kFontMacintoshPlatform
, kFontNoScript
,
7292 kFontNoLanguage
, name_len
, name
,
7297 FMFontStyle style
= normal
;
7299 decode_mac_font_name (name
, name_len
+ 1, Qnil
);
7300 family
= make_unibyte_string (name
, name_len
);
7301 FMGetFontFamilyInstanceFromFont (font_ids
[i
], &ff
, &style
);
7302 Fputhash ((font_ids
[i
] > MOST_POSITIVE_FIXNUM
7303 ? make_float (font_ids
[i
])
7304 : make_number (font_ids
[i
])),
7307 fm_style_to_face_attributes (style
))),
7308 Vmac_atsu_font_table
);
7310 && hash_lookup (h
, family
, &hash_code
) < 0)
7312 add_mac_font_name (name
, 0, normal
, "iso10646-1");
7313 hash_put (h
, family
, long_to_cons (font_ids
[i
]),
7324 /* Create a dummy instance iterator here to avoid creating and
7325 destroying it in the loop. */
7326 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
7328 /* Create an iterator to enumerate the font families. */
7329 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
7332 FMDisposeFontFamilyInstanceIterator (&ffii
);
7336 GCPRO1 (text_encoding_info_alist
);
7338 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
7344 TextEncoding encoding
;
7345 TextEncodingBase sc
;
7346 Lisp_Object text_encoding_info
, family
;
7348 if (FMGetFontFamilyName (ff
, name
) != noErr
)
7354 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
7356 sc
= GetTextEncodingBase (encoding
);
7357 text_encoding_info
= assq_no_quit (make_number (sc
),
7358 text_encoding_info_alist
);
7359 if (NILP (text_encoding_info
))
7360 text_encoding_info
= assq_no_quit (make_number (kTextEncodingMacRoman
),
7361 text_encoding_info_alist
);
7362 decode_mac_font_name (name
, sizeof (name
),
7363 XCAR (XCDR (text_encoding_info
)));
7364 family
= build_string (name
);
7365 if (!NILP (Fassoc (family
, fm_font_family_alist
)))
7367 fm_font_family_alist
= Fcons (Fcons (family
, make_number (ff
)),
7368 fm_font_family_alist
);
7370 /* Point the instance iterator at the current font family. */
7371 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
7374 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
7377 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7379 if (size
> 0 || style
== normal
)
7380 for (; !NILP (rest
); rest
= XCDR (rest
))
7381 add_mac_font_name (name
, size
, style
, SDATA (XCAR (rest
)));
7387 /* Dispose of the iterators. */
7388 FMDisposeFontFamilyIterator (&ffi
);
7389 FMDisposeFontFamilyInstanceIterator (&ffii
);
7390 #else /* !TARGET_API_MAC_CARBON */
7392 SInt16 fontnum
, old_fontnum
;
7393 int num_mac_fonts
= CountResources('FOND');
7395 Handle font_handle
, font_handle_2
;
7396 short id
, scriptcode
;
7399 struct FontAssoc
*fat
;
7400 struct AsscEntry
*assc_entry
;
7401 Lisp_Object text_encoding_info_alist
, text_encoding_info
, family
;
7402 struct gcpro gcpro1
;
7404 GetPort (&port
); /* save the current font number used */
7405 old_fontnum
= port
->txFont
;
7407 text_encoding_info_alist
= create_text_encoding_info_alist ();
7409 GCPRO1 (text_encoding_info_alist
);
7411 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
7413 font_handle
= GetIndResource ('FOND', i
);
7417 GetResInfo (font_handle
, &id
, &type
, name
);
7418 GetFNum (name
, &fontnum
);
7420 if (fontnum
== 0 || *name
== '.')
7424 scriptcode
= FontToScript (fontnum
);
7425 text_encoding_info
= assq_no_quit (make_number (scriptcode
),
7426 text_encoding_info_alist
);
7427 if (NILP (text_encoding_info
))
7428 text_encoding_info
= assq_no_quit (make_number (smRoman
),
7429 text_encoding_info_alist
);
7430 decode_mac_font_name (name
, sizeof (name
),
7431 XCAR (XCDR (text_encoding_info
)));
7432 family
= build_string (name
);
7433 if (!NILP (Fassoc (family
, fm_font_family_alist
)))
7435 fm_font_family_alist
= Fcons (Fcons (family
, make_number (fontnum
)),
7436 fm_font_family_alist
);
7439 HLock (font_handle
);
7441 if (GetResourceSizeOnDisk (font_handle
)
7442 >= sizeof (struct FamRec
))
7444 fat
= (struct FontAssoc
*) (*font_handle
7445 + sizeof (struct FamRec
));
7447 = (struct AsscEntry
*) (*font_handle
7448 + sizeof (struct FamRec
)
7449 + sizeof (struct FontAssoc
));
7451 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
7453 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7455 for (; !NILP (rest
); rest
= XCDR (rest
))
7456 add_mac_font_name (name
, assc_entry
->fontSize
,
7457 assc_entry
->fontStyle
,
7458 SDATA (XCAR (rest
)));
7462 HUnlock (font_handle
);
7463 font_handle_2
= GetNextFOND (font_handle
);
7464 ReleaseResource (font_handle
);
7465 font_handle
= font_handle_2
;
7467 while (ResError () == noErr
&& font_handle
);
7472 TextFont (old_fontnum
);
7473 #endif /* !TARGET_API_MAC_CARBON */
7478 mac_clear_font_name_table ()
7482 for (i
= 0; i
< font_name_count
; i
++)
7483 xfree (font_name_table
[i
]);
7484 xfree (font_name_table
);
7485 font_name_table
= NULL
;
7486 font_name_table_size
= font_name_count
= 0;
7487 fm_font_family_alist
= Qnil
;
7491 enum xlfd_scalable_field_index
7493 XLFD_SCL_PIXEL_SIZE
,
7494 XLFD_SCL_POINT_SIZE
,
7499 static int xlfd_scalable_fields
[] =
7508 mac_do_list_fonts (pattern
, maxnames
)
7513 Lisp_Object font_list
= Qnil
;
7514 struct xlfdpat
*pat
;
7516 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
7519 if (font_name_table
== NULL
) /* Initialize when first used. */
7520 init_font_name_table ();
7522 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
7525 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
7526 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
7527 fonts are scaled according to the specified size. */
7530 field
= xlfd_scalable_fields
;
7538 if ('0' <= *ptr
&& *ptr
<= '9')
7540 *val
= *ptr
++ - '0';
7541 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
7542 *val
= *val
* 10 + *ptr
++ - '0';
7549 ptr
= strchr (ptr
, '-');
7552 while (ptr
&& i
< 14);
7554 if (i
== 14 && ptr
== NULL
)
7556 if (scl_val
[XLFD_SCL_PIXEL_SIZE
] < 0)
7557 scl_val
[XLFD_SCL_PIXEL_SIZE
] =
7558 (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
] / 10
7559 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
] / 10
7561 if (scl_val
[XLFD_SCL_POINT_SIZE
] < 0)
7562 scl_val
[XLFD_SCL_POINT_SIZE
] =
7563 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7564 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
]
7566 if (scl_val
[XLFD_SCL_AVGWIDTH
] < 0)
7567 scl_val
[XLFD_SCL_AVGWIDTH
] =
7568 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7569 : (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
]
7573 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
7575 pat
= xlfdpat_create (pattern
);
7579 exact
= xlfdpat_exact_p (pat
);
7581 for (i
= 0; i
< font_name_count
; i
++)
7583 if (xlfdpat_match (pat
, font_name_table
[i
]))
7585 font_list
= Fcons (build_string (font_name_table
[i
]), font_list
);
7586 if (exact
|| (maxnames
> 0 && ++n_fonts
>= maxnames
))
7589 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
7590 && (ptr
= strstr (font_name_table
[i
], "-0-0-0-0-m-0-")))
7592 int former_len
= ptr
- font_name_table
[i
];
7594 scaled
= xmalloc (strlen (font_name_table
[i
]) + 20 + 1);
7595 memcpy (scaled
, font_name_table
[i
], former_len
);
7596 sprintf (scaled
+ former_len
,
7597 "-%d-%d-72-72-m-%d-%s",
7598 scl_val
[XLFD_SCL_PIXEL_SIZE
],
7599 scl_val
[XLFD_SCL_POINT_SIZE
],
7600 scl_val
[XLFD_SCL_AVGWIDTH
],
7601 ptr
+ sizeof ("-0-0-0-0-m-0-") - 1);
7603 if (xlfdpat_match (pat
, scaled
))
7605 font_list
= Fcons (build_string (scaled
), font_list
);
7607 if (exact
|| (maxnames
> 0 && ++n_fonts
>= maxnames
))
7615 xlfdpat_destroy (pat
);
7620 /* Return a list of names of available fonts matching PATTERN on frame F.
7622 Frame F null means we have not yet created any frame on Mac, and
7623 consult the first display in x_display_list. MAXNAMES sets a limit
7624 on how many fonts to match. */
7627 x_list_fonts (f
, pattern
, size
, maxnames
)
7629 Lisp_Object pattern
;
7632 Lisp_Object list
= Qnil
, patterns
, tem
, key
;
7633 struct mac_display_info
*dpyinfo
7634 = f
? FRAME_MAC_DISPLAY_INFO (f
) : x_display_list
;
7636 xassert (size
<= 0);
7638 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
7639 if (NILP (patterns
))
7640 patterns
= Fcons (pattern
, Qnil
);
7642 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
7644 pattern
= XCAR (patterns
);
7646 if (!STRINGP (pattern
))
7649 tem
= XCAR (XCDR (dpyinfo
->name_list_element
));
7650 key
= Fcons (pattern
, make_number (maxnames
));
7652 list
= Fassoc (key
, tem
);
7655 list
= Fcdr_safe (list
);
7656 /* We have a cashed list. Don't have to get the list again. */
7661 list
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
7664 /* MAC_TODO: add code for matching outline fonts here */
7666 /* Now store the result in the cache. */
7667 XSETCAR (XCDR (dpyinfo
->name_list_element
),
7668 Fcons (Fcons (key
, list
),
7669 XCAR (XCDR (dpyinfo
->name_list_element
))));
7672 if (NILP (list
)) continue; /* Try the remaining alternatives. */
7681 /* Check that FONT is valid on frame F. It is if it can be found in F's
7685 x_check_font (f
, font
)
7690 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7692 xassert (font
!= NULL
);
7694 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7695 if (dpyinfo
->font_table
[i
].name
7696 && font
== dpyinfo
->font_table
[i
].font
)
7699 xassert (i
< dpyinfo
->n_fonts
);
7702 #endif /* GLYPH_DEBUG != 0 */
7704 /* Set *W to the minimum width, *H to the minimum font height of FONT.
7705 Note: There are (broken) X fonts out there with invalid XFontStruct
7706 min_bounds contents. For example, handa@etl.go.jp reports that
7707 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
7708 have font->min_bounds.width == 0. */
7711 x_font_min_bounds (font
, w
, h
)
7712 MacFontStruct
*font
;
7715 *h
= FONT_HEIGHT (font
);
7716 *w
= font
->min_bounds
.width
;
7720 /* Compute the smallest character width and smallest font height over
7721 all fonts available on frame F. Set the members smallest_char_width
7722 and smallest_font_height in F's x_display_info structure to
7723 the values computed. Value is non-zero if smallest_font_height or
7724 smallest_char_width become smaller than they were before. */
7727 x_compute_min_glyph_bounds (f
)
7731 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7732 MacFontStruct
*font
;
7733 int old_width
= dpyinfo
->smallest_char_width
;
7734 int old_height
= dpyinfo
->smallest_font_height
;
7736 dpyinfo
->smallest_font_height
= 100000;
7737 dpyinfo
->smallest_char_width
= 100000;
7739 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7740 if (dpyinfo
->font_table
[i
].name
)
7742 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
7745 font
= (MacFontStruct
*) fontp
->font
;
7746 xassert (font
!= (MacFontStruct
*) ~0);
7747 x_font_min_bounds (font
, &w
, &h
);
7749 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
7750 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
7753 xassert (dpyinfo
->smallest_char_width
> 0
7754 && dpyinfo
->smallest_font_height
> 0);
7756 return (dpyinfo
->n_fonts
== 1
7757 || dpyinfo
->smallest_char_width
< old_width
7758 || dpyinfo
->smallest_font_height
< old_height
);
7762 /* Determine whether given string is a fully-specified XLFD: all 14
7763 fields are present, none is '*'. */
7766 is_fully_specified_xlfd (char *p
)
7774 for (i
= 0; i
< 13; i
++)
7776 q
= strchr (p
+ 1, '-');
7779 if (q
- p
== 2 && *(p
+ 1) == '*')
7784 if (strchr (p
+ 1, '-') != NULL
)
7787 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
7794 /* mac_load_query_font creates and returns an internal representation
7795 for a font in a MacFontStruct struct. There is really no concept
7796 corresponding to "loading" a font on the Mac. But we check its
7797 existence and find the font number and all other information for it
7798 and store them in the returned MacFontStruct. */
7800 static MacFontStruct
*
7801 mac_load_query_font (f
, fontname
)
7811 static ATSUFontID font_id
;
7812 ATSUStyle mac_style
= NULL
;
7815 #if TARGET_API_MAC_CARBON
7816 TextEncoding encoding
;
7821 MacFontStruct
*font
;
7822 XCharStruct
*space_bounds
= NULL
, *pcm
;
7824 if (is_fully_specified_xlfd (fontname
))
7828 Lisp_Object matched_fonts
;
7830 matched_fonts
= mac_do_list_fonts (fontname
, 1);
7831 if (NILP (matched_fonts
))
7833 name
= SDATA (XCAR (matched_fonts
));
7836 if (parse_x_font_name (name
, family
, &size
, &fontface
, charset
) == 0)
7840 if (strcmp (charset
, "iso10646-1") == 0) /* XXX */
7843 ATSUAttributeTag tags
[] = {kATSUFontTag
, kATSUSizeTag
,
7844 kATSUQDBoldfaceTag
, kATSUQDItalicTag
};
7845 ByteCount sizes
[] = {sizeof (ATSUFontID
), sizeof (Fixed
),
7846 sizeof (Boolean
), sizeof (Boolean
)};
7847 static Fixed size_fixed
;
7848 static Boolean bold_p
, italic_p
;
7849 ATSUAttributeValuePtr values
[] = {&font_id
, &size_fixed
,
7850 &bold_p
, &italic_p
};
7851 ATSUFontFeatureType types
[] = {kAllTypographicFeaturesType
,
7853 ATSUFontFeatureSelector selectors
[] = {kAllTypeFeaturesOffSelector
,
7854 kDecomposeDiacriticsSelector
};
7855 Lisp_Object font_id_cons
;
7858 font_id_cons
= Fgethash (make_unibyte_string (family
, strlen (family
)),
7859 atsu_font_id_hash
, Qnil
);
7860 if (NILP (font_id_cons
))
7862 font_id
= cons_to_long (font_id_cons
);
7863 size_fixed
= Long2Fix (size
);
7864 bold_p
= (fontface
& bold
) != 0;
7865 italic_p
= (fontface
& italic
) != 0;
7866 err
= ATSUCreateStyle (&mac_style
);
7869 err
= ATSUSetFontFeatures (mac_style
, sizeof (types
) / sizeof (types
[0]),
7873 err
= ATSUSetAttributes (mac_style
, sizeof (tags
) / sizeof (tags
[0]),
7874 tags
, sizes
, values
);
7877 err
= FMGetFontFamilyInstanceFromFont (font_id
, &fontnum
, &style
);
7880 scriptcode
= kTextEncodingMacUnicode
;
7885 Lisp_Object tmp
= Fassoc (build_string (family
), fm_font_family_alist
);
7889 fontnum
= XINT (XCDR (tmp
));
7890 #if TARGET_API_MAC_CARBON
7891 if (FMGetFontFamilyTextEncoding (fontnum
, &encoding
) != noErr
)
7893 scriptcode
= GetTextEncodingBase (encoding
);
7895 scriptcode
= FontToScript (fontnum
);
7899 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
7901 font
->mac_fontnum
= fontnum
;
7902 font
->mac_fontsize
= size
;
7903 font
->mac_fontface
= fontface
;
7904 font
->mac_scriptcode
= scriptcode
;
7906 font
->mac_style
= mac_style
;
7907 #if USE_CG_TEXT_DRAWING
7908 font
->cg_font
= NULL
;
7909 font
->cg_glyphs
= NULL
;
7913 /* Apple Japanese (SJIS) font is listed as both
7914 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
7915 (Roman script) in init_font_name_table (). The latter should be
7916 treated as a one-byte font. */
7917 if (scriptcode
== smJapanese
&& strcmp (charset
, "jisx0201.1976-0") == 0)
7918 font
->mac_scriptcode
= smRoman
;
7920 font
->full_name
= mac_to_x_fontname (family
, size
, fontface
, charset
);
7923 if (font
->mac_style
)
7928 font
->min_byte1
= 0;
7929 font
->max_byte1
= 0xff;
7930 font
->min_char_or_byte2
= 0;
7931 font
->max_char_or_byte2
= 0xff;
7933 font
->bounds
.rows
= xmalloc (sizeof (XCharStruct
*) * 0x100);
7934 bzero (font
->bounds
.rows
, sizeof (XCharStruct
*) * 0x100);
7935 font
->bounds
.rows
[0] = xmalloc (sizeof (XCharStruct
) * 0x100);
7936 pcm_init (font
->bounds
.rows
[0], 0x100);
7938 #if USE_CG_TEXT_DRAWING
7942 ATSFontRef ats_font
;
7944 err
= FMGetFontFromFontFamilyInstance (fontnum
, fontface
,
7946 /* Use CG text drawing if italic/bold is not synthesized. */
7947 if (err
== noErr
&& style
== fontface
)
7949 ats_font
= FMGetATSFontRefFromFont (font_id
);
7950 font
->cg_font
= CGFontCreateWithPlatformFont (&ats_font
);
7956 font
->cg_glyphs
= xmalloc (sizeof (CGGlyph
) * 0x100);
7957 bzero (font
->cg_glyphs
, sizeof (CGGlyph
) * 0x100);
7960 space_bounds
= font
->bounds
.rows
[0] + 0x20;
7961 err
= mac_query_char_extents (font
->mac_style
, 0x20,
7962 &font
->ascent
, &font
->descent
,
7964 #if USE_CG_TEXT_DRAWING
7965 (font
->cg_glyphs
? font
->cg_glyphs
+ 0x20
7972 || space_bounds
->width
<= 0 || FONT_HEIGHT (font
) <= 0)
7974 mac_unload_font (&one_mac_display_info
, font
);
7978 pcm
= font
->bounds
.rows
[0];
7979 for (c
= 0x21; c
<= 0xff; c
++)
7982 /* Soft hyphen is not supported in ATSUI. */
7990 mac_query_char_extents (font
->mac_style
, c
, NULL
, NULL
, pcm
+ c
,
7991 #if USE_CG_TEXT_DRAWING
7992 (font
->cg_glyphs
? font
->cg_glyphs
+ c
7999 #if USE_CG_TEXT_DRAWING
8000 if (font
->cg_glyphs
&& font
->cg_glyphs
[c
] == 0)
8002 /* Don't use CG text drawing if font substitution occurs in
8003 ASCII or Latin-1 characters. */
8004 CGFontRelease (font
->cg_font
);
8005 font
->cg_font
= NULL
;
8006 xfree (font
->cg_glyphs
);
8007 font
->cg_glyphs
= NULL
;
8015 FontInfo the_fontinfo
;
8016 int is_two_byte_font
;
8019 mac_prepare_for_quickdraw (f
);
8021 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
8025 TextFace (fontface
);
8027 GetFontInfo (&the_fontinfo
);
8029 font
->ascent
= the_fontinfo
.ascent
;
8030 font
->descent
= the_fontinfo
.descent
;
8032 is_two_byte_font
= (font
->mac_scriptcode
== smJapanese
8033 || font
->mac_scriptcode
== smTradChinese
8034 || font
->mac_scriptcode
== smSimpChinese
8035 || font
->mac_scriptcode
== smKorean
);
8037 if (is_two_byte_font
)
8041 font
->min_byte1
= 0xa1;
8042 font
->max_byte1
= 0xfe;
8043 font
->min_char_or_byte2
= 0xa1;
8044 font
->max_char_or_byte2
= 0xfe;
8046 /* Use the width of an "ideographic space" of that font
8047 because the_fontinfo.widMax returns the wrong width for
8049 switch (font
->mac_scriptcode
)
8052 font
->min_byte1
= 0x81;
8053 font
->max_byte1
= 0xfc;
8054 font
->min_char_or_byte2
= 0x40;
8055 font
->max_char_or_byte2
= 0xfc;
8056 char_width
= StringWidth("\p\x81\x40");
8059 font
->min_char_or_byte2
= 0x40;
8060 char_width
= StringWidth("\p\xa1\x40");
8063 char_width
= StringWidth("\p\xa1\xa1");
8066 char_width
= StringWidth("\p\xa1\xa1");
8070 font
->bounds
.per_char
= NULL
;
8072 if (fontface
& italic
)
8073 font
->max_bounds
.rbearing
= char_width
+ 1;
8075 font
->max_bounds
.rbearing
= char_width
;
8076 font
->max_bounds
.lbearing
= 0;
8077 font
->max_bounds
.width
= char_width
;
8078 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
8079 font
->max_bounds
.descent
= the_fontinfo
.descent
;
8081 font
->min_bounds
= font
->max_bounds
;
8087 font
->min_byte1
= font
->max_byte1
= 0;
8088 font
->min_char_or_byte2
= 0x20;
8089 font
->max_char_or_byte2
= 0xff;
8091 font
->bounds
.per_char
=
8092 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
8093 bzero (font
->bounds
.per_char
,
8094 sizeof (XCharStruct
) * (0xff - 0x20 + 1));
8096 space_bounds
= font
->bounds
.per_char
;
8097 mac_query_char_extents (NULL
, 0x20, &font
->ascent
, &font
->descent
,
8098 space_bounds
, NULL
);
8100 for (c
= 0x21, pcm
= space_bounds
+ 1; c
<= 0xff; c
++, pcm
++)
8101 mac_query_char_extents (NULL
, c
, NULL
, NULL
, pcm
, NULL
);
8109 font
->min_bounds
= font
->max_bounds
= *space_bounds
;
8110 for (c
= 0x21, pcm
= space_bounds
+ 1; c
<= 0x7f; c
++, pcm
++)
8113 font
->min_bounds
.lbearing
= min (font
->min_bounds
.lbearing
,
8115 font
->min_bounds
.rbearing
= min (font
->min_bounds
.rbearing
,
8117 font
->min_bounds
.width
= min (font
->min_bounds
.width
,
8119 font
->min_bounds
.ascent
= min (font
->min_bounds
.ascent
,
8121 font
->min_bounds
.descent
= min (font
->min_bounds
.descent
,
8124 font
->max_bounds
.lbearing
= max (font
->max_bounds
.lbearing
,
8126 font
->max_bounds
.rbearing
= max (font
->max_bounds
.rbearing
,
8128 font
->max_bounds
.width
= max (font
->max_bounds
.width
,
8130 font
->max_bounds
.ascent
= max (font
->max_bounds
.ascent
,
8132 font
->max_bounds
.descent
= max (font
->max_bounds
.descent
,
8137 font
->mac_style
== NULL
&&
8139 font
->max_bounds
.width
== font
->min_bounds
.width
8140 && font
->min_bounds
.lbearing
>= 0
8141 && font
->max_bounds
.rbearing
<= font
->max_bounds
.width
)
8143 /* Fixed width and no overhangs. */
8144 xfree (font
->bounds
.per_char
);
8145 font
->bounds
.per_char
= NULL
;
8149 #if !defined (MAC_OS8) || USE_ATSUI
8150 /* AppKit and WebKit do some adjustment to the heights of Courier,
8151 Helvetica, and Times. This only works on the environments where
8152 srcCopy text transfer mode is never used. */
8154 #ifdef MAC_OS8 /* implies USE_ATSUI */
8157 (strcmp (family
, "courier") == 0 || strcmp (family
, "helvetica") == 0
8158 || strcmp (family
, "times") == 0))
8159 font
->ascent
+= (font
->ascent
+ font
->descent
) * .15 + 0.5;
8167 mac_unload_font (dpyinfo
, font
)
8168 struct mac_display_info
*dpyinfo
;
8171 xfree (font
->full_name
);
8173 if (font
->mac_style
)
8177 for (i
= font
->min_byte1
; i
<= font
->max_byte1
; i
++)
8178 if (font
->bounds
.rows
[i
])
8179 xfree (font
->bounds
.rows
[i
]);
8180 xfree (font
->bounds
.rows
);
8181 ATSUDisposeStyle (font
->mac_style
);
8185 if (font
->bounds
.per_char
)
8186 xfree (font
->bounds
.per_char
);
8187 #if USE_CG_TEXT_DRAWING
8189 CGFontRelease (font
->cg_font
);
8190 if (font
->cg_glyphs
)
8191 xfree (font
->cg_glyphs
);
8197 /* Load font named FONTNAME of the size SIZE for frame F, and return a
8198 pointer to the structure font_info while allocating it dynamically.
8199 If SIZE is 0, load any size of font.
8200 If loading is failed, return NULL. */
8203 x_load_font (f
, fontname
, size
)
8205 register char *fontname
;
8208 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8209 Lisp_Object font_names
;
8211 /* Get a list of all the fonts that match this name. Once we
8212 have a list of matching fonts, we compare them against the fonts
8213 we already have by comparing names. */
8214 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
8216 if (!NILP (font_names
))
8221 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8222 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
8223 if (dpyinfo
->font_table
[i
].name
8224 && (!strcmp (dpyinfo
->font_table
[i
].name
,
8225 SDATA (XCAR (tail
)))
8226 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
8227 SDATA (XCAR (tail
)))))
8228 return (dpyinfo
->font_table
+ i
);
8233 /* Load the font and add it to the table. */
8235 struct MacFontStruct
*font
;
8236 struct font_info
*fontp
;
8239 fontname
= (char *) SDATA (XCAR (font_names
));
8242 font
= mac_load_query_font (f
, fontname
);
8247 /* Find a free slot in the font table. */
8248 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8249 if (dpyinfo
->font_table
[i
].name
== NULL
)
8252 /* If no free slot found, maybe enlarge the font table. */
8253 if (i
== dpyinfo
->n_fonts
8254 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
8257 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
8258 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
8260 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
8263 fontp
= dpyinfo
->font_table
+ i
;
8264 if (i
== dpyinfo
->n_fonts
)
8267 /* Now fill in the slots of *FONTP. */
8269 bzero (fontp
, sizeof (*fontp
));
8271 fontp
->font_idx
= i
;
8272 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
8273 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
8275 if (font
->min_bounds
.width
== font
->max_bounds
.width
)
8277 /* Fixed width font. */
8278 fontp
->average_width
= fontp
->space_width
= font
->min_bounds
.width
;
8285 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
8286 pcm
= mac_per_char_metric (font
, &char2b
, 0);
8288 fontp
->space_width
= pcm
->width
;
8290 fontp
->space_width
= FONT_WIDTH (font
);
8294 int width
= pcm
->width
;
8295 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
8296 if ((pcm
= mac_per_char_metric (font
, &char2b
, 0)) != NULL
)
8297 width
+= pcm
->width
;
8298 fontp
->average_width
= width
/ 95;
8301 fontp
->average_width
= FONT_WIDTH (font
);
8304 fontp
->full_name
= (char *) xmalloc (strlen (font
->full_name
) + 1);
8305 bcopy (font
->full_name
, fontp
->full_name
, strlen (font
->full_name
) + 1);
8307 fontp
->size
= font
->max_bounds
.width
;
8308 fontp
->height
= FONT_HEIGHT (font
);
8310 /* For some font, ascent and descent in max_bounds field is
8311 larger than the above value. */
8312 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
8313 if (max_height
> fontp
->height
)
8314 fontp
->height
= max_height
;
8317 /* The slot `encoding' specifies how to map a character
8318 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
8319 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
8320 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
8321 2:0xA020..0xFF7F). For the moment, we don't know which charset
8322 uses this font. So, we set information in fontp->encoding[1]
8323 which is never used by any charset. If mapping can't be
8324 decided, set FONT_ENCODING_NOT_DECIDED. */
8325 if (font
->mac_scriptcode
== smJapanese
)
8326 fontp
->encoding
[1] = 4;
8330 = (font
->max_byte1
== 0
8332 ? (font
->min_char_or_byte2
< 0x80
8333 ? (font
->max_char_or_byte2
< 0x80
8334 ? 0 /* 0x20..0x7F */
8335 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
8336 : 1) /* 0xA0..0xFF */
8338 : (font
->min_byte1
< 0x80
8339 ? (font
->max_byte1
< 0x80
8340 ? (font
->min_char_or_byte2
< 0x80
8341 ? (font
->max_char_or_byte2
< 0x80
8342 ? 0 /* 0x2020..0x7F7F */
8343 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
8344 : 3) /* 0x20A0..0x7FFF */
8345 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
8346 : (font
->min_char_or_byte2
< 0x80
8347 ? (font
->max_char_or_byte2
< 0x80
8348 ? 2 /* 0xA020..0xFF7F */
8349 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
8350 : 1))); /* 0xA0A0..0xFFFF */
8353 #if 0 /* MAC_TODO: fill these out with more reasonably values */
8354 fontp
->baseline_offset
8355 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
8356 ? (long) value
: 0);
8357 fontp
->relative_compose
8358 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
8359 ? (long) value
: 0);
8360 fontp
->default_ascent
8361 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
8362 ? (long) value
: 0);
8364 fontp
->baseline_offset
= 0;
8365 fontp
->relative_compose
= 0;
8366 fontp
->default_ascent
= 0;
8369 /* Set global flag fonts_changed_p to non-zero if the font loaded
8370 has a character with a smaller width than any other character
8371 before, or if the font loaded has a smaller height than any
8372 other font loaded before. If this happens, it will make a
8373 glyph matrix reallocation necessary. */
8374 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
8381 /* Return a pointer to struct font_info of a font named FONTNAME for
8382 frame F. If no such font is loaded, return NULL. */
8385 x_query_font (f
, fontname
)
8387 register char *fontname
;
8389 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8392 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8393 if (dpyinfo
->font_table
[i
].name
8394 && (!xstricmp (dpyinfo
->font_table
[i
].name
, fontname
)
8395 || !xstricmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
8396 return (dpyinfo
->font_table
+ i
);
8401 /* Find a CCL program for a font specified by FONTP, and set the member
8402 `encoder' of the structure. */
8405 x_find_ccl_program (fontp
)
8406 struct font_info
*fontp
;
8408 Lisp_Object list
, elt
;
8410 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
8414 && STRINGP (XCAR (elt
))
8415 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
8421 struct ccl_program
*ccl
8422 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
8424 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
8427 fontp
->font_encoder
= ccl
;
8431 #if USE_MAC_FONT_PANEL
8432 /* Whether Font Panel has been shown before. The first call to font
8433 panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
8434 slow. This variable is used for deferring such a call as much as
8436 static int font_panel_shown_p
= 0;
8439 mac_font_panel_visible_p ()
8441 return font_panel_shown_p
&& FPIsFontPanelVisible ();
8445 mac_show_hide_font_panel ()
8447 font_panel_shown_p
= 1;
8449 return FPShowHideFontPanel ();
8453 mac_set_font_info_for_selection (f
, face_id
, c
)
8458 EventTargetRef target
= NULL
;
8459 XFontStruct
*font
= NULL
;
8461 if (!mac_font_panel_visible_p ())
8466 target
= GetWindowEventTarget (FRAME_MAC_WINDOW (f
));
8468 if (FRAME_FACE_CACHE (f
) && CHAR_VALID_P (c
, 0))
8472 face_id
= FACE_FOR_CHAR (f
, FACE_FROM_ID (f
, face_id
), c
);
8473 face
= FACE_FROM_ID (f
, face_id
);
8479 err
= SetFontInfoForSelection (kFontSelectionATSUIType
, 0, NULL
, target
);
8482 if (font
->mac_fontnum
!= -1)
8484 FontSelectionQDStyle qd_style
;
8486 qd_style
.version
= kFontSelectionQDStyleVersionZero
;
8487 qd_style
.instance
.fontFamily
= font
->mac_fontnum
;
8488 qd_style
.instance
.fontStyle
= font
->mac_fontface
;
8489 qd_style
.size
= font
->mac_fontsize
;
8490 qd_style
.hasColor
= false;
8492 err
= SetFontInfoForSelection (kFontSelectionQDType
,
8493 1, &qd_style
, target
);
8496 err
= SetFontInfoForSelection (kFontSelectionATSUIType
,
8497 1, &font
->mac_style
, target
);
8505 /* The Mac Event loop code */
8507 #if !TARGET_API_MAC_CARBON
8509 #include <Quickdraw.h>
8510 #include <Balloons.h>
8511 #include <Devices.h>
8513 #include <Gestalt.h>
8515 #include <Processes.h>
8517 #include <ToolUtils.h>
8518 #include <TextUtils.h>
8519 #include <Dialogs.h>
8522 #include <Resources.h>
8527 #endif /* ! TARGET_API_MAC_CARBON */
8532 #define WINDOW_RESOURCE 128
8533 #define TERM_WINDOW_RESOURCE 129
8535 #define DEFAULT_NUM_COLS 80
8537 #define MIN_DOC_SIZE 64
8538 #define MAX_DOC_SIZE 32767
8540 #define EXTRA_STACK_ALLOC (256 * 1024)
8542 #define ARGV_STRING_LIST_ID 129
8543 #define ABOUT_ALERT_ID 128
8544 #define RAM_TOO_LARGE_ALERT_ID 129
8546 /* Contains the string "reverse", which is a constant for mouse button emu.*/
8547 Lisp_Object Qreverse
;
8550 /* Modifier associated with the control key, or nil to ignore. */
8551 Lisp_Object Vmac_control_modifier
;
8553 /* Modifier associated with the option key, or nil to ignore. */
8554 Lisp_Object Vmac_option_modifier
;
8556 /* Modifier associated with the command key, or nil to ignore. */
8557 Lisp_Object Vmac_command_modifier
;
8559 /* Modifier associated with the function key, or nil to ignore. */
8560 Lisp_Object Vmac_function_modifier
;
8562 /* True if the option and command modifiers should be used to emulate
8563 a three button mouse */
8564 Lisp_Object Vmac_emulate_three_button_mouse
;
8566 #if USE_CARBON_EVENTS
8567 /* Non-zero if the mouse wheel button (i.e. button 4) should map to
8568 mouse-2, instead of mouse-3. */
8569 int mac_wheel_button_is_mouse_2
;
8571 /* If non-zero, the Mac "Command" key is passed on to the Mac Toolbox
8572 for processing before Emacs sees it. */
8573 int mac_pass_command_to_system
;
8575 /* If non-zero, the Mac "Control" key is passed on to the Mac Toolbox
8576 for processing before Emacs sees it. */
8577 int mac_pass_control_to_system
;
8580 /* Points to the variable `inev' in the function XTread_socket. It is
8581 used for passing an input event to the function back from
8582 Carbon/Apple event handlers. */
8583 static struct input_event
*read_socket_inev
= NULL
;
8585 Point saved_menu_event_location
;
8588 #if USE_CARBON_EVENTS
8589 static Lisp_Object Qhi_command
;
8591 extern Lisp_Object Qwindow
;
8592 static Lisp_Object Qtoolbar_switch_mode
;
8594 #if USE_MAC_FONT_PANEL
8595 extern Lisp_Object Qfont
;
8596 static Lisp_Object Qpanel_closed
, Qselection
;
8599 static TSMDocumentID tsm_document_id
;
8600 static Lisp_Object Qtext_input
;
8601 static Lisp_Object Qupdate_active_input_area
, Qunicode_for_key_event
;
8602 static Lisp_Object Vmac_ts_active_input_overlay
;
8603 extern Lisp_Object Qbefore_string
;
8604 static Lisp_Object Vmac_ts_script_language_on_focus
;
8605 static Lisp_Object saved_ts_script_language_on_focus
;
8606 static ScriptLanguageRecord saved_ts_language
;
8607 static Component saved_ts_component
;
8610 extern int mac_ready_for_apple_events
;
8611 extern Lisp_Object Qundefined
;
8612 extern void init_apple_event_handler
P_ ((void));
8613 extern void mac_find_apple_event_spec
P_ ((AEEventClass
, AEEventID
,
8614 Lisp_Object
*, Lisp_Object
*,
8616 extern OSErr init_coercion_handler
P_ ((void));
8619 OSErr install_drag_handler
P_ ((WindowRef
));
8620 void remove_drag_handler
P_ ((WindowRef
));
8622 #if USE_CARBON_EVENTS
8624 extern void init_service_handler ();
8625 static Lisp_Object Qservice
, Qpaste
, Qperform
;
8627 /* Window Event Handler */
8628 static pascal OSStatus
mac_handle_window_event (EventHandlerCallRef
,
8631 OSStatus
install_window_handler (WindowPtr
);
8633 extern void init_emacs_passwd_dir ();
8634 extern int emacs_main (int, char **, char **);
8636 extern void initialize_applescript();
8637 extern void terminate_applescript();
8639 /* Table for translating Mac keycode to X keysym values. Contributed
8641 Mapping for special keys is now identical to that in Apple X11
8642 except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
8643 on the right of the Cmd key on laptops, and fn + `enter' (->
8645 static unsigned char keycode_to_xkeysym_table
[] = {
8646 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8647 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8648 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8650 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8651 /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
8652 /*0x38*/ 0, 0, 0, 0,
8653 /*0x3C*/ 0, 0, 0, 0,
8655 /*0x40*/ 0, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
8656 /*0x44*/ 0, 0xab /*kp-add*/, 0, 0x0b /*clear*/,
8657 /*0x48*/ 0, 0, 0, 0xaf /*kp-divide*/,
8658 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0,
8660 /*0x50*/ 0, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8661 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8662 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8663 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8665 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8666 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8667 /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
8668 /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
8670 /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
8671 /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
8672 /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8673 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8677 /* Table for translating Mac keycode with the laptop `fn' key to that
8678 without it. Destination symbols in comments are keys on US
8679 keyboard, and they may not be the same on other types of keyboards.
8680 If the destination is identical to the source (f1 ... f12), it
8681 doesn't map `fn' key to a modifier. */
8682 static unsigned char fn_keycode_to_keycode_table
[] = {
8683 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8684 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8685 /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8687 /*0x30*/ 0, 0, 0, 0,
8688 /*0x34*/ 0, 0, 0, 0,
8689 /*0x38*/ 0, 0, 0, 0,
8690 /*0x3C*/ 0, 0, 0, 0,
8692 /*0x40*/ 0, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
8693 /*0x44*/ 0, 0x2c /*kp-add -> '/'*/, 0, 0x16 /*clear -> '6'*/,
8694 /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
8695 /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0,
8697 /*0x50*/ 0, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
8698 /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
8699 /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
8700 /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
8702 /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
8703 /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
8704 /*0x68*/ 0, 0, 0, 0,
8705 /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
8707 /*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
8708 /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
8709 /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 0,
8712 #endif /* MAC_OSX */
8715 #if USE_CARBON_EVENTS
8716 mac_to_emacs_modifiers (UInt32 mods
)
8718 mac_to_emacs_modifiers (EventModifiers mods
)
8721 unsigned int result
= 0;
8722 if (mods
& shiftKey
)
8723 result
|= shift_modifier
;
8725 /* Deactivated to simplify configuration:
8726 if Vmac_option_modifier is non-NIL, we fully process the Option
8727 key. Otherwise, we only process it if an additional Ctrl or Command
8728 is pressed. That way the system may convert the character to a
8730 if ((mods & optionKey) &&
8731 (( !NILP(Vmac_option_modifier) ||
8732 ((mods & cmdKey) || (mods & controlKey))))) */
8734 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
8735 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
8737 result
|= XUINT(val
);
8739 if (!NILP (Vmac_command_modifier
) && (mods
& cmdKey
)) {
8740 Lisp_Object val
= Fget(Vmac_command_modifier
, Qmodifier_value
);
8742 result
|= XUINT(val
);
8744 if (!NILP (Vmac_control_modifier
) && (mods
& controlKey
)) {
8745 Lisp_Object val
= Fget(Vmac_control_modifier
, Qmodifier_value
);
8747 result
|= XUINT(val
);
8751 if (!NILP (Vmac_function_modifier
) && (mods
& kEventKeyModifierFnMask
)) {
8752 Lisp_Object val
= Fget(Vmac_function_modifier
, Qmodifier_value
);
8754 result
|= XUINT(val
);
8762 mac_get_emulated_btn ( UInt32 modifiers
)
8765 if (!NILP (Vmac_emulate_three_button_mouse
)) {
8766 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
8767 if (modifiers
& cmdKey
)
8768 result
= cmdIs3
? 2 : 1;
8769 else if (modifiers
& optionKey
)
8770 result
= cmdIs3
? 1 : 2;
8775 #if USE_CARBON_EVENTS
8776 /* Obtains the event modifiers from the event ref and then calls
8777 mac_to_emacs_modifiers. */
8779 mac_event_to_emacs_modifiers (EventRef eventRef
)
8782 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
8783 sizeof (UInt32
), NULL
, &mods
);
8784 if (!NILP (Vmac_emulate_three_button_mouse
) &&
8785 GetEventClass(eventRef
) == kEventClassMouse
)
8787 mods
&= ~(optionKey
| cmdKey
);
8789 return mac_to_emacs_modifiers (mods
);
8792 /* Given an event ref, return the code to use for the mouse button
8793 code in the emacs input_event. */
8795 mac_get_mouse_btn (EventRef ref
)
8797 EventMouseButton result
= kEventMouseButtonPrimary
;
8798 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
8799 sizeof (EventMouseButton
), NULL
, &result
);
8802 case kEventMouseButtonPrimary
:
8803 if (NILP (Vmac_emulate_three_button_mouse
))
8807 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
8808 sizeof (UInt32
), NULL
, &mods
);
8809 return mac_get_emulated_btn(mods
);
8811 case kEventMouseButtonSecondary
:
8812 return mac_wheel_button_is_mouse_2
? 2 : 1;
8813 case kEventMouseButtonTertiary
:
8814 case 4: /* 4 is the number for the mouse wheel button */
8815 return mac_wheel_button_is_mouse_2
? 1 : 2;
8821 /* Normally, ConvertEventRefToEventRecord will correctly handle all
8822 events. However the click of the mouse wheel is not converted to a
8823 mouseDown or mouseUp event. Likewise for dead key down events.
8824 This calls ConvertEventRef, but then checks to see if it is a mouse
8825 up/down, or a dead key down carbon event that has not been
8826 converted, and if so, converts it by hand (to be picked up in the
8827 XTread_socket loop). */
8828 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
8831 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
8836 switch (GetEventClass (eventRef
))
8838 case kEventClassMouse
:
8839 switch (GetEventKind (eventRef
))
8841 case kEventMouseDown
:
8842 eventRec
->what
= mouseDown
;
8847 eventRec
->what
= mouseUp
;
8856 case kEventClassKeyboard
:
8857 switch (GetEventKind (eventRef
))
8859 case kEventRawKeyDown
:
8861 unsigned char char_codes
;
8864 err
= GetEventParameter (eventRef
, kEventParamKeyMacCharCodes
,
8865 typeChar
, NULL
, sizeof (char),
8868 err
= GetEventParameter (eventRef
, kEventParamKeyCode
,
8869 typeUInt32
, NULL
, sizeof (UInt32
),
8873 eventRec
->what
= keyDown
;
8874 eventRec
->message
= char_codes
| ((key_code
& 0xff) << 8);
8891 /* Need where and when. */
8894 GetEventParameter (eventRef
, kEventParamMouseLocation
, typeQDPoint
,
8895 NULL
, sizeof (Point
), NULL
, &eventRec
->where
);
8896 /* Use two step process because new event modifiers are 32-bit
8897 and old are 16-bit. Currently, only loss is NumLock & Fn. */
8898 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
,
8899 NULL
, sizeof (UInt32
), NULL
, &mods
);
8900 eventRec
->modifiers
= mods
;
8902 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
8914 Handle menubar_handle
;
8915 MenuHandle menu_handle
;
8917 menubar_handle
= GetNewMBar (128);
8918 if(menubar_handle
== NULL
)
8920 SetMenuBar (menubar_handle
);
8923 #if !TARGET_API_MAC_CARBON
8924 menu_handle
= GetMenuHandle (M_APPLE
);
8925 if(menu_handle
!= NULL
)
8926 AppendResMenu (menu_handle
,'DRVR');
8934 do_init_managers (void)
8936 #if !TARGET_API_MAC_CARBON
8937 InitGraf (&qd
.thePort
);
8939 FlushEvents (everyEvent
, 0);
8944 #endif /* !TARGET_API_MAC_CARBON */
8947 #if !TARGET_API_MAC_CARBON
8948 /* set up some extra stack space for use by emacs */
8949 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
8951 /* MaxApplZone must be called for AppleScript to execute more
8952 complicated scripts */
8955 #endif /* !TARGET_API_MAC_CARBON */
8959 do_check_ram_size (void)
8961 SInt32 physical_ram_size
, logical_ram_size
;
8963 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
8964 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
8965 || physical_ram_size
> (1 << VALBITS
)
8966 || logical_ram_size
> (1 << VALBITS
))
8968 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
8972 #endif /* MAC_OS8 */
8975 do_window_update (WindowPtr win
)
8977 struct frame
*f
= mac_window_to_frame (win
);
8981 /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
8983 if (win
!= tip_window
)
8985 if (f
->async_visible
== 0)
8987 /* Update events may occur when a frame gets iconified. */
8989 f
->async_visible
= 1;
8990 f
->async_iconified
= 0;
8991 SET_FRAME_GARBAGED (f
);
8997 #if TARGET_API_MAC_CARBON
8998 RgnHandle region
= NewRgn ();
9000 GetPortVisibleRegion (GetWindowPort (win
), region
);
9001 GetRegionBounds (region
, &r
);
9002 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
9003 UpdateControls (win
, region
);
9004 DisposeRgn (region
);
9006 r
= (*win
->visRgn
)->rgnBBox
;
9007 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
9008 UpdateControls (win
, win
->visRgn
);
9017 is_emacs_window (WindowPtr win
)
9019 Lisp_Object tail
, frame
;
9024 FOR_EACH_FRAME (tail
, frame
)
9025 if (FRAME_MAC_P (XFRAME (frame
)))
9026 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
9037 ScriptLanguageRecord slrec
, *slptr
= NULL
;
9039 err
= ActivateTSMDocument (tsm_document_id
);
9043 if (EQ (Vmac_ts_script_language_on_focus
, Qt
)
9044 && EQ (saved_ts_script_language_on_focus
, Qt
))
9045 slptr
= &saved_ts_language
;
9046 else if (CONSP (Vmac_ts_script_language_on_focus
)
9047 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus
))
9048 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus
))
9049 && CONSP (saved_ts_script_language_on_focus
)
9050 && EQ (XCAR (saved_ts_script_language_on_focus
),
9051 XCAR (Vmac_ts_script_language_on_focus
))
9052 && EQ (XCDR (saved_ts_script_language_on_focus
),
9053 XCDR (Vmac_ts_script_language_on_focus
)))
9055 slrec
.fScript
= XINT (XCAR (Vmac_ts_script_language_on_focus
));
9056 slrec
.fLanguage
= XINT (XCDR (Vmac_ts_script_language_on_focus
));
9063 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
9064 err
= SetDefaultInputMethodOfClass (saved_ts_component
, slptr
,
9065 kKeyboardInputMethodClass
);
9067 err
= SetDefaultInputMethod (saved_ts_component
, slptr
);
9070 err
= SetTextServiceLanguage (slptr
);
9072 /* Seems to be needed on Mac OS X 10.2. */
9074 KeyScript (slptr
->fScript
| smKeyForceKeyScriptMask
);
9084 ScriptLanguageRecord slrec
, *slptr
= NULL
;
9086 saved_ts_script_language_on_focus
= Vmac_ts_script_language_on_focus
;
9088 if (EQ (Vmac_ts_script_language_on_focus
, Qt
))
9090 err
= GetTextServiceLanguage (&saved_ts_language
);
9092 slptr
= &saved_ts_language
;
9094 else if (CONSP (Vmac_ts_script_language_on_focus
)
9095 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus
))
9096 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus
)))
9098 slrec
.fScript
= XINT (XCAR (Vmac_ts_script_language_on_focus
));
9099 slrec
.fLanguage
= XINT (XCDR (Vmac_ts_script_language_on_focus
));
9105 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
9106 GetDefaultInputMethodOfClass (&saved_ts_component
, slptr
,
9107 kKeyboardInputMethodClass
);
9109 GetDefaultInputMethod (&saved_ts_component
, slptr
);
9113 err
= DeactivateTSMDocument (tsm_document_id
);
9119 #if !TARGET_API_MAC_CARBON
9121 do_apple_menu (SInt16 menu_item
)
9124 SInt16 da_driver_refnum
;
9126 if (menu_item
== I_ABOUT
)
9127 NoteAlert (ABOUT_ALERT_ID
, NULL
);
9130 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
9131 da_driver_refnum
= OpenDeskAcc (item_name
);
9134 #endif /* !TARGET_API_MAC_CARBON */
9136 /* Handle drags in size box. Based on code contributed by Ben
9137 Mesander and IM - Window Manager A. */
9140 do_grow_window (WindowPtr w
, EventRecord
*e
)
9143 int rows
, columns
, width
, height
;
9144 struct frame
*f
= mac_window_to_frame (w
);
9145 XSizeHints
*size_hints
= FRAME_SIZE_HINTS (f
);
9146 int min_width
= MIN_DOC_SIZE
, min_height
= MIN_DOC_SIZE
;
9147 #if TARGET_API_MAC_CARBON
9153 if (size_hints
->flags
& PMinSize
)
9155 min_width
= size_hints
->min_width
;
9156 min_height
= size_hints
->min_height
;
9158 SetRect (&limit_rect
, min_width
, min_height
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
9160 #if TARGET_API_MAC_CARBON
9161 if (!ResizeWindow (w
, e
->where
, &limit_rect
, &new_rect
))
9163 height
= new_rect
.bottom
- new_rect
.top
;
9164 width
= new_rect
.right
- new_rect
.left
;
9166 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
9167 /* see if it really changed size */
9170 height
= HiWord (grow_size
);
9171 width
= LoWord (grow_size
);
9174 if (width
!= FRAME_PIXEL_WIDTH (f
)
9175 || height
!= FRAME_PIXEL_HEIGHT (f
))
9177 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
9178 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
9180 x_set_window_size (f
, 0, columns
, rows
);
9185 #if TARGET_API_MAC_CARBON
9187 mac_get_ideal_size (f
)
9190 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9191 WindowPtr w
= FRAME_MAC_WINDOW (f
);
9194 int height
, width
, columns
, rows
;
9196 ideal_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
9197 ideal_size
.v
= dpyinfo
->height
;
9198 IsWindowInStandardState (w
, &ideal_size
, &standard_rect
);
9199 /* Adjust the standard size according to character boundaries. */
9200 width
= standard_rect
.right
- standard_rect
.left
;
9201 height
= standard_rect
.bottom
- standard_rect
.top
;
9202 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
9203 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
9204 ideal_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
9205 ideal_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
9211 /* Handle clicks in zoom box. Calculation of "standard state" based
9212 on code in IM - Window Manager A and code contributed by Ben
9213 Mesander. The standard state of an Emacs window is 80-characters
9214 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
9217 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
9219 Rect zoom_rect
, port_rect
;
9221 struct frame
*f
= mac_window_to_frame (w
);
9222 #if TARGET_API_MAC_CARBON
9223 Point ideal_size
= mac_get_ideal_size (f
);
9225 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
9226 if (IsWindowInStandardState (w
, &ideal_size
, &zoom_rect
)
9227 && port_rect
.left
== zoom_rect
.left
9228 && port_rect
.top
== zoom_rect
.top
)
9229 zoom_in_or_out
= inZoomIn
;
9231 zoom_in_or_out
= inZoomOut
;
9234 mac_clear_window (f
);
9236 ZoomWindowIdeal (w
, zoom_in_or_out
, &ideal_size
);
9237 #else /* not TARGET_API_MAC_CARBON */
9240 int w_title_height
, rows
;
9241 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9243 GetPort (&save_port
);
9245 SetPortWindowPort (w
);
9247 /* Clear window to avoid flicker. */
9248 EraseRect (&(w
->portRect
));
9249 if (zoom_in_or_out
== inZoomOut
)
9251 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
9252 LocalToGlobal (&top_left
);
9254 /* calculate height of window's title bar */
9255 w_title_height
= top_left
.v
- 1
9256 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
9258 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
9259 zoom_rect
= qd
.screenBits
.bounds
;
9260 zoom_rect
.top
+= w_title_height
;
9261 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
9263 zoom_rect
.right
= zoom_rect
.left
9264 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
9266 /* Adjust the standard size according to character boundaries. */
9267 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
9269 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
9271 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
9275 ZoomWindow (w
, zoom_in_or_out
, f
== mac_focus_frame (dpyinfo
));
9277 SetPort (save_port
);
9278 #endif /* not TARGET_API_MAC_CARBON */
9280 #if !USE_CARBON_EVENTS
9281 /* retrieve window size and update application values */
9282 #if TARGET_API_MAC_CARBON
9283 GetWindowPortBounds (w
, &port_rect
);
9285 port_rect
= w
->portRect
;
9287 height
= port_rect
.bottom
- port_rect
.top
;
9288 width
= port_rect
.right
- port_rect
.left
;
9290 mac_handle_size_change (f
, width
, height
);
9291 mac_handle_origin_change (f
);
9296 mac_store_apple_event (class, id
, desc
)
9297 Lisp_Object
class, id
;
9300 struct input_event buf
;
9304 buf
.kind
= MAC_APPLE_EVENT
;
9307 XSETFRAME (buf
.frame_or_window
,
9308 mac_focus_frame (&one_mac_display_info
));
9309 /* Now that Lisp object allocations are protected by BLOCK_INPUT, it
9310 is safe to use them during read_socket_hook. */
9311 buf
.arg
= mac_aedesc_to_lisp (desc
);
9312 kbd_buffer_store_event (&buf
);
9315 #if TARGET_API_MAC_CARBON
9317 mac_store_event_ref_as_apple_event (class, id
, class_key
, id_key
,
9318 event
, num_params
, names
, types
)
9321 Lisp_Object class_key
, id_key
;
9324 EventParamName
*names
;
9325 EventParamType
*types
;
9327 OSStatus err
= eventNotHandledErr
;
9328 Lisp_Object binding
;
9330 mac_find_apple_event_spec (class, id
, &class_key
, &id_key
, &binding
);
9331 if (!NILP (binding
) && !EQ (binding
, Qundefined
))
9333 if (INTEGERP (binding
))
9334 err
= XINT (binding
);
9337 AppleEvent apple_event
;
9338 err
= create_apple_event_from_event_ref (event
, num_params
,
9343 mac_store_apple_event (class_key
, id_key
, &apple_event
);
9344 AEDisposeDesc (&apple_event
);
9345 /* Post a harmless event so as to wake up from
9346 ReceiveNextEvent. */
9347 mac_post_mouse_moved_event ();
9356 mac_store_drag_event (window
, mouse_pos
, modifiers
, desc
)
9362 struct input_event buf
;
9366 buf
.kind
= DRAG_N_DROP_EVENT
;
9367 buf
.modifiers
= mac_to_emacs_modifiers (modifiers
);
9368 buf
.timestamp
= TickCount () * (1000 / 60);
9369 XSETINT (buf
.x
, mouse_pos
.h
);
9370 XSETINT (buf
.y
, mouse_pos
.v
);
9371 XSETFRAME (buf
.frame_or_window
, mac_window_to_frame (window
));
9372 buf
.arg
= mac_aedesc_to_lisp (desc
);
9373 kbd_buffer_store_event (&buf
);
9377 #if USE_CARBON_EVENTS
9378 static pascal OSStatus
9379 mac_handle_command_event (next_handler
, event
, data
)
9380 EventHandlerCallRef next_handler
;
9384 OSStatus result
, err
;
9386 static EventParamName names
[] = {kEventParamDirectObject
,
9387 kEventParamKeyModifiers
};
9388 static EventParamType types
[] = {typeHICommand
,
9390 int num_params
= sizeof (names
) / sizeof (names
[0]);
9392 result
= CallNextEventHandler (next_handler
, event
);
9393 if (result
!= eventNotHandledErr
)
9396 err
= GetEventParameter (event
, kEventParamDirectObject
, typeHICommand
,
9397 NULL
, sizeof (HICommand
), NULL
, &command
);
9399 if (err
!= noErr
|| command
.commandID
== 0)
9400 return eventNotHandledErr
;
9402 /* A HI command event is mapped to an Apple event whose event class
9403 symbol is `hi-command' and event ID is its command ID. */
9404 err
= mac_store_event_ref_as_apple_event (0, command
.commandID
,
9406 event
, num_params
, names
, types
);
9407 return err
== noErr
? noErr
: eventNotHandledErr
;
9411 init_command_handler ()
9413 EventTypeSpec specs
[] = {{kEventClassCommand
, kEventCommandProcess
}};
9414 static EventHandlerUPP handle_command_eventUPP
= NULL
;
9416 if (handle_command_eventUPP
== NULL
)
9417 handle_command_eventUPP
= NewEventHandlerUPP (mac_handle_command_event
);
9418 return InstallApplicationEventHandler (handle_command_eventUPP
,
9419 GetEventTypeCount (specs
), specs
,
9423 static pascal OSStatus
9424 mac_handle_window_event (next_handler
, event
, data
)
9425 EventHandlerCallRef next_handler
;
9430 OSStatus result
, err
;
9433 XSizeHints
*size_hints
;
9435 err
= GetEventParameter (event
, kEventParamDirectObject
, typeWindowRef
,
9436 NULL
, sizeof (WindowPtr
), NULL
, &wp
);
9438 return eventNotHandledErr
;
9440 f
= mac_window_to_frame (wp
);
9441 switch (GetEventKind (event
))
9443 case kEventWindowUpdate
:
9444 result
= CallNextEventHandler (next_handler
, event
);
9445 if (result
!= eventNotHandledErr
)
9448 do_window_update (wp
);
9451 case kEventWindowGetIdealSize
:
9452 result
= CallNextEventHandler (next_handler
, event
);
9453 if (result
!= eventNotHandledErr
)
9457 Point ideal_size
= mac_get_ideal_size (f
);
9459 err
= SetEventParameter (event
, kEventParamDimensions
,
9460 typeQDPoint
, sizeof (Point
), &ideal_size
);
9466 case kEventWindowBoundsChanging
:
9467 result
= CallNextEventHandler (next_handler
, event
);
9468 if (result
!= eventNotHandledErr
)
9471 err
= GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
9472 NULL
, sizeof (UInt32
), NULL
, &attributes
);
9476 size_hints
= FRAME_SIZE_HINTS (f
);
9477 if ((attributes
& kWindowBoundsChangeUserResize
)
9478 && ((size_hints
->flags
& (PResizeInc
| PBaseSize
| PMinSize
))
9479 == (PResizeInc
| PBaseSize
| PMinSize
)))
9484 err
= GetEventParameter (event
, kEventParamCurrentBounds
,
9485 typeQDRectangle
, NULL
, sizeof (Rect
),
9490 width
= bounds
.right
- bounds
.left
;
9491 height
= bounds
.bottom
- bounds
.top
;
9493 if (width
< size_hints
->min_width
)
9494 width
= size_hints
->min_width
;
9496 width
= size_hints
->base_width
9497 + (int) ((width
- size_hints
->base_width
)
9498 / (float) size_hints
->width_inc
+ .5)
9499 * size_hints
->width_inc
;
9501 if (height
< size_hints
->min_height
)
9502 height
= size_hints
->min_height
;
9504 height
= size_hints
->base_height
9505 + (int) ((height
- size_hints
->base_height
)
9506 / (float) size_hints
->height_inc
+ .5)
9507 * size_hints
->height_inc
;
9509 bounds
.right
= bounds
.left
+ width
;
9510 bounds
.bottom
= bounds
.top
+ height
;
9511 SetEventParameter (event
, kEventParamCurrentBounds
,
9512 typeQDRectangle
, sizeof (Rect
), &bounds
);
9517 case kEventWindowBoundsChanged
:
9518 err
= GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
9519 NULL
, sizeof (UInt32
), NULL
, &attributes
);
9523 if (attributes
& kWindowBoundsChangeSizeChanged
)
9527 err
= GetEventParameter (event
, kEventParamCurrentBounds
,
9528 typeQDRectangle
, NULL
, sizeof (Rect
),
9534 width
= bounds
.right
- bounds
.left
;
9535 height
= bounds
.bottom
- bounds
.top
;
9536 mac_handle_size_change (f
, width
, height
);
9540 if (attributes
& kWindowBoundsChangeOriginChanged
)
9541 mac_handle_origin_change (f
);
9545 case kEventWindowShown
:
9546 case kEventWindowHidden
:
9547 case kEventWindowExpanded
:
9548 case kEventWindowCollapsed
:
9549 result
= CallNextEventHandler (next_handler
, event
);
9551 mac_handle_visibility_change (f
);
9556 case kEventWindowClose
:
9557 result
= CallNextEventHandler (next_handler
, event
);
9559 struct input_event buf
;
9562 buf
.kind
= DELETE_WINDOW_EVENT
;
9563 XSETFRAME (buf
.frame_or_window
, f
);
9565 kbd_buffer_store_event (&buf
);
9570 case kEventWindowToolbarSwitchMode
:
9571 result
= CallNextEventHandler (next_handler
, event
);
9573 static EventParamName names
[] = {kEventParamDirectObject
,
9574 kEventParamWindowMouseLocation
,
9575 kEventParamKeyModifiers
,
9576 kEventParamMouseButton
,
9577 kEventParamClickCount
,
9578 kEventParamMouseChord
};
9579 static EventParamType types
[] = {typeWindowRef
,
9585 int num_params
= sizeof (names
) / sizeof (names
[0]);
9587 err
= mac_store_event_ref_as_apple_event (0, 0,
9589 Qtoolbar_switch_mode
,
9593 return err
== noErr
? noErr
: result
;
9597 case kEventWindowFocusAcquired
:
9598 result
= CallNextEventHandler (next_handler
, event
);
9599 err
= mac_tsm_resume ();
9600 return err
== noErr
? noErr
: result
;
9602 case kEventWindowFocusRelinquish
:
9603 result
= CallNextEventHandler (next_handler
, event
);
9604 err
= mac_tsm_suspend ();
9605 return err
== noErr
? noErr
: result
;
9609 return eventNotHandledErr
;
9612 static pascal OSStatus
9613 mac_handle_mouse_event (next_handler
, event
, data
)
9614 EventHandlerCallRef next_handler
;
9618 OSStatus result
, err
;
9620 switch (GetEventKind (event
))
9622 case kEventMouseWheelMoved
:
9626 EventMouseWheelAxis axis
;
9630 result
= CallNextEventHandler (next_handler
, event
);
9631 if (result
!= eventNotHandledErr
|| read_socket_inev
== NULL
)
9634 err
= GetEventParameter (event
, kEventParamWindowRef
, typeWindowRef
,
9635 NULL
, sizeof (WindowRef
), NULL
, &wp
);
9639 f
= mac_window_to_frame (wp
);
9640 if (f
!= mac_focus_frame (&one_mac_display_info
))
9643 err
= GetEventParameter (event
, kEventParamMouseWheelAxis
,
9644 typeMouseWheelAxis
, NULL
,
9645 sizeof (EventMouseWheelAxis
), NULL
, &axis
);
9646 if (err
!= noErr
|| axis
!= kEventMouseWheelAxisY
)
9649 err
= GetEventParameter (event
, kEventParamMouseWheelDelta
,
9650 typeSInt32
, NULL
, sizeof (SInt32
),
9654 err
= GetEventParameter (event
, kEventParamMouseLocation
,
9655 typeQDPoint
, NULL
, sizeof (Point
),
9659 read_socket_inev
->kind
= WHEEL_EVENT
;
9660 read_socket_inev
->code
= 0;
9661 read_socket_inev
->modifiers
=
9662 (mac_event_to_emacs_modifiers (event
)
9663 | ((delta
< 0) ? down_modifier
: up_modifier
));
9664 SetPortWindowPort (wp
);
9665 GlobalToLocal (&point
);
9666 XSETINT (read_socket_inev
->x
, point
.h
);
9667 XSETINT (read_socket_inev
->y
, point
.v
);
9668 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
9678 return eventNotHandledErr
;
9681 #if USE_MAC_FONT_PANEL
9682 static pascal OSStatus
9683 mac_handle_font_event (next_handler
, event
, data
)
9684 EventHandlerCallRef next_handler
;
9688 OSStatus result
, err
;
9691 EventParamName
*names
;
9692 EventParamType
*types
;
9693 static EventParamName names_sel
[] = {kEventParamATSUFontID
,
9694 kEventParamATSUFontSize
,
9695 kEventParamFMFontFamily
,
9696 kEventParamFMFontSize
,
9697 kEventParamFontColor
};
9698 static EventParamType types_sel
[] = {typeATSUFontID
,
9704 result
= CallNextEventHandler (next_handler
, event
);
9705 if (result
!= eventNotHandledErr
)
9708 switch (GetEventKind (event
))
9710 case kEventFontPanelClosed
:
9711 id_key
= Qpanel_closed
;
9717 case kEventFontSelection
:
9718 id_key
= Qselection
;
9719 num_params
= sizeof (names_sel
) / sizeof (names_sel
[0]);
9725 err
= mac_store_event_ref_as_apple_event (0, 0, Qfont
, id_key
,
9729 return err
== noErr
? noErr
: eventNotHandledErr
;
9734 static pascal OSStatus
9735 mac_handle_text_input_event (next_handler
, event
, data
)
9736 EventHandlerCallRef next_handler
;
9740 OSStatus result
, err
= noErr
;
9741 Lisp_Object id_key
= Qnil
;
9743 EventParamName
*names
;
9744 EventParamType
*types
;
9745 static UInt32 seqno_uaia
= 0;
9746 static EventParamName names_uaia
[] =
9747 {kEventParamTextInputSendComponentInstance
,
9748 kEventParamTextInputSendRefCon
,
9749 kEventParamTextInputSendSLRec
,
9750 kEventParamTextInputSendFixLen
,
9751 kEventParamTextInputSendText
,
9752 kEventParamTextInputSendUpdateRng
,
9753 kEventParamTextInputSendHiliteRng
,
9754 kEventParamTextInputSendClauseRng
,
9755 kEventParamTextInputSendPinRng
,
9756 kEventParamTextInputSendTextServiceEncoding
,
9757 kEventParamTextInputSendTextServiceMacEncoding
,
9758 EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER
};
9759 static EventParamType types_uaia
[] =
9760 {typeComponentInstance
,
9762 typeIntlWritingCode
,
9776 static EventParamName names_ufke
[] =
9777 {kEventParamTextInputSendComponentInstance
,
9778 kEventParamTextInputSendRefCon
,
9779 kEventParamTextInputSendSLRec
,
9780 kEventParamTextInputSendText
};
9781 static EventParamType types_ufke
[] =
9782 {typeComponentInstance
,
9784 typeIntlWritingCode
,
9787 result
= CallNextEventHandler (next_handler
, event
);
9789 switch (GetEventKind (event
))
9791 case kEventTextInputUpdateActiveInputArea
:
9792 id_key
= Qupdate_active_input_area
;
9793 num_params
= sizeof (names_uaia
) / sizeof (names_uaia
[0]);
9796 SetEventParameter (event
, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER
,
9797 typeUInt32
, sizeof (UInt32
), &seqno_uaia
);
9801 case kEventTextInputUnicodeForKeyEvent
:
9804 UInt32 actual_size
, modifiers
, mapped_modifiers
;
9806 err
= GetEventParameter (event
, kEventParamTextInputSendKeyboardEvent
,
9807 typeEventRef
, NULL
, sizeof (EventRef
), NULL
,
9810 err
= GetEventParameter (kbd_event
, kEventParamKeyModifiers
,
9812 sizeof (UInt32
), NULL
, &modifiers
);
9816 (NILP (Vmac_control_modifier
) ? 0 : controlKey
)
9817 | (NILP (Vmac_option_modifier
) ? 0 : optionKey
)
9818 | (NILP (Vmac_command_modifier
) ? 0 : cmdKey
);
9821 (NILP (Vmac_function_modifier
) ? 0 : kEventKeyModifierFnMask
);
9823 if (modifiers
& mapped_modifiers
)
9824 /* There're mapped modifier keys. Process it in
9826 return eventNotHandledErr
;
9829 err
= GetEventParameter (kbd_event
, kEventParamKeyUnicodes
,
9830 typeUnicodeText
, NULL
, 0, &actual_size
,
9832 if (err
== noErr
&& actual_size
== sizeof (UniChar
))
9836 err
= GetEventParameter (kbd_event
, kEventParamKeyUnicodes
,
9837 typeUnicodeText
, NULL
,
9838 sizeof (UniChar
), NULL
, &code
);
9839 if (err
== noErr
&& code
< 0x80)
9841 /* ASCII character. Process it in XTread_socket. */
9842 if (read_socket_inev
&& code
>= 0x20 && code
<= 0x7e)
9846 err
= GetEventParameter (kbd_event
, kEventParamKeyCode
,
9847 typeUInt32
, NULL
, sizeof (UInt32
),
9849 if (!(err
== noErr
&& key_code
<= 0x7f
9850 && keycode_to_xkeysym_table
[key_code
]))
9853 mac_focus_frame (&one_mac_display_info
);
9855 read_socket_inev
->kind
= ASCII_KEYSTROKE_EVENT
;
9856 read_socket_inev
->code
= code
;
9857 read_socket_inev
->modifiers
=
9858 mac_to_emacs_modifiers (modifiers
);
9859 read_socket_inev
->modifiers
|=
9860 (extra_keyboard_modifiers
9861 & (meta_modifier
| alt_modifier
9862 | hyper_modifier
| super_modifier
));
9863 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
9866 return eventNotHandledErr
;
9870 /* Non-ASCII keystrokes without mapped modifiers are processed
9871 at the Lisp level. */
9872 id_key
= Qunicode_for_key_event
;
9873 num_params
= sizeof (names_ufke
) / sizeof (names_ufke
[0]);
9878 case kEventTextInputOffsetToPos
:
9884 if (!OVERLAYP (Vmac_ts_active_input_overlay
))
9885 return eventNotHandledErr
;
9887 /* Strictly speaking, this is not always correct because
9888 previous events may change some states about display. */
9889 if (NILP (Foverlay_get (Vmac_ts_active_input_overlay
, Qbefore_string
)))
9891 /* Active input area is displayed in the echo area. */
9892 w
= XWINDOW (echo_area_window
);
9893 f
= WINDOW_XFRAME (w
);
9897 /* Active input area is displayed around the current point. */
9898 f
= SELECTED_FRAME ();
9899 w
= XWINDOW (f
->selected_window
);
9902 p
.h
= (WINDOW_TO_FRAME_PIXEL_X (w
, w
->cursor
.x
)
9903 + WINDOW_LEFT_FRINGE_WIDTH (w
));
9904 p
.v
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->cursor
.y
)
9905 + FONT_BASE (FRAME_FONT (f
)));
9906 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
9908 err
= SetEventParameter (event
, kEventParamTextInputReplyPoint
,
9909 typeQDPoint
, sizeof (typeQDPoint
), &p
);
9918 err
= mac_store_event_ref_as_apple_event (0, 0, Qtext_input
, id_key
,
9922 return err
== noErr
? noErr
: result
;
9928 mac_store_service_event (event
)
9934 EventParamName
*names
;
9935 EventParamType
*types
;
9936 static EventParamName names_pfm
[] = {kEventParamServiceMessageName
,
9937 kEventParamServiceUserData
};
9938 static EventParamType types_pfm
[] = {typeCFStringRef
,
9941 switch (GetEventKind (event
))
9943 case kEventServicePaste
:
9950 case kEventServicePerform
:
9952 num_params
= sizeof (names_pfm
) / sizeof (names_pfm
[0]);
9961 err
= mac_store_event_ref_as_apple_event (0, 0, Qservice
, id_key
,
9967 #endif /* MAC_OSX */
9968 #endif /* USE_CARBON_EVENTS */
9972 install_window_handler (window
)
9975 OSStatus err
= noErr
;
9976 #if USE_CARBON_EVENTS
9977 EventTypeSpec specs_window
[] =
9978 {{kEventClassWindow
, kEventWindowUpdate
},
9979 {kEventClassWindow
, kEventWindowGetIdealSize
},
9980 {kEventClassWindow
, kEventWindowBoundsChanging
},
9981 {kEventClassWindow
, kEventWindowBoundsChanged
},
9982 {kEventClassWindow
, kEventWindowShown
},
9983 {kEventClassWindow
, kEventWindowHidden
},
9984 {kEventClassWindow
, kEventWindowExpanded
},
9985 {kEventClassWindow
, kEventWindowCollapsed
},
9986 {kEventClassWindow
, kEventWindowClose
},
9988 {kEventClassWindow
, kEventWindowToolbarSwitchMode
},
9991 {kEventClassWindow
, kEventWindowFocusAcquired
},
9992 {kEventClassWindow
, kEventWindowFocusRelinquish
},
9995 EventTypeSpec specs_mouse
[] = {{kEventClassMouse
, kEventMouseWheelMoved
}};
9996 static EventHandlerUPP handle_window_eventUPP
= NULL
;
9997 static EventHandlerUPP handle_mouse_eventUPP
= NULL
;
9998 #if USE_MAC_FONT_PANEL
9999 EventTypeSpec specs_font
[] = {{kEventClassFont
, kEventFontPanelClosed
},
10000 {kEventClassFont
, kEventFontSelection
}};
10001 static EventHandlerUPP handle_font_eventUPP
= NULL
;
10004 EventTypeSpec specs_text_input
[] =
10005 {{kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
},
10006 {kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
},
10007 {kEventClassTextInput
, kEventTextInputOffsetToPos
}};
10008 static EventHandlerUPP handle_text_input_eventUPP
= NULL
;
10011 if (handle_window_eventUPP
== NULL
)
10012 handle_window_eventUPP
= NewEventHandlerUPP (mac_handle_window_event
);
10013 if (handle_mouse_eventUPP
== NULL
)
10014 handle_mouse_eventUPP
= NewEventHandlerUPP (mac_handle_mouse_event
);
10015 #if USE_MAC_FONT_PANEL
10016 if (handle_font_eventUPP
== NULL
)
10017 handle_font_eventUPP
= NewEventHandlerUPP (mac_handle_font_event
);
10020 if (handle_text_input_eventUPP
== NULL
)
10021 handle_text_input_eventUPP
=
10022 NewEventHandlerUPP (mac_handle_text_input_event
);
10024 err
= InstallWindowEventHandler (window
, handle_window_eventUPP
,
10025 GetEventTypeCount (specs_window
),
10026 specs_window
, NULL
, NULL
);
10028 err
= InstallWindowEventHandler (window
, handle_mouse_eventUPP
,
10029 GetEventTypeCount (specs_mouse
),
10030 specs_mouse
, NULL
, NULL
);
10031 #if USE_MAC_FONT_PANEL
10033 err
= InstallWindowEventHandler (window
, handle_font_eventUPP
,
10034 GetEventTypeCount (specs_font
),
10035 specs_font
, NULL
, NULL
);
10039 err
= InstallWindowEventHandler (window
, handle_text_input_eventUPP
,
10040 GetEventTypeCount (specs_text_input
),
10041 specs_text_input
, window
, NULL
);
10045 err
= install_drag_handler (window
);
10051 remove_window_handler (window
)
10054 remove_drag_handler (window
);
10060 profiler_exit_proc ()
10062 ProfilerDump ("\pEmacs.prof");
10067 /* These few functions implement Emacs as a normal Mac application
10068 (almost): set up the heap and the Toolbox, handle necessary system
10069 events plus a few simple menu events. They also set up Emacs's
10070 access to functions defined in the rest of this file. Emacs uses
10071 function hooks to perform all its terminal I/O. A complete list of
10072 these functions appear in termhooks.h. For what they do, read the
10073 comments there and see also w32term.c and xterm.c. What's
10074 noticeably missing here is the event loop, which is normally
10075 present in most Mac application. After performing the necessary
10076 Mac initializations, main passes off control to emacs_main
10077 (corresponding to main in emacs.c). Emacs_main calls XTread_socket
10078 (defined further below) to read input. This is where
10079 WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
10086 #if __profile__ /* is the profiler on? */
10087 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
10092 /* set creator and type for files created by MSL */
10093 _fcreator
= 'EMAx';
10097 do_init_managers ();
10101 #ifndef USE_LSB_TAG
10102 do_check_ram_size ();
10105 init_emacs_passwd_dir ();
10109 init_coercion_handler ();
10111 initialize_applescript ();
10113 init_apple_event_handler ();
10119 /* set up argv array from STR# resource */
10120 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
10124 /* free up AppleScript resources on exit */
10125 atexit (terminate_applescript
);
10127 #if __profile__ /* is the profiler on? */
10128 atexit (profiler_exit_proc
);
10131 /* 3rd param "envp" never used in emacs_main */
10132 (void) emacs_main (argc
, argv
, 0);
10135 /* Never reached - real exit in Fkill_emacs */
10140 #if !USE_CARBON_EVENTS
10141 static RgnHandle mouse_region
= NULL
;
10144 mac_wait_next_event (er
, sleep_time
, dequeue
)
10149 static EventRecord er_buf
= {nullEvent
};
10150 UInt32 target_tick
, current_tick
;
10151 EventMask event_mask
;
10153 if (mouse_region
== NULL
)
10154 mouse_region
= NewRgn ();
10156 event_mask
= everyEvent
;
10157 if (!mac_ready_for_apple_events
)
10158 event_mask
-= highLevelEventMask
;
10160 current_tick
= TickCount ();
10161 target_tick
= current_tick
+ sleep_time
;
10163 if (er_buf
.what
== nullEvent
)
10164 while (!WaitNextEvent (event_mask
, &er_buf
,
10165 target_tick
- current_tick
, mouse_region
))
10167 current_tick
= TickCount ();
10168 if (target_tick
<= current_tick
)
10174 er_buf
.what
= nullEvent
;
10177 #endif /* not USE_CARBON_EVENTS */
10179 #if TARGET_API_MAC_CARBON
10181 mac_post_mouse_moved_event ()
10183 EventRef event
= NULL
;
10186 err
= CreateEvent (NULL
, kEventClassMouse
, kEventMouseMoved
, 0,
10187 kEventAttributeNone
, &event
);
10192 GetMouse (&mouse_pos
);
10193 LocalToGlobal (&mouse_pos
);
10194 err
= SetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
10195 sizeof (Point
), &mouse_pos
);
10199 UInt32 modifiers
= GetCurrentKeyModifiers ();
10201 err
= SetEventParameter (event
, kEventParamKeyModifiers
, typeUInt32
,
10202 sizeof (UInt32
), &modifiers
);
10205 err
= PostEventToQueue (GetCurrentEventQueue (), event
,
10206 kEventPriorityStandard
);
10208 ReleaseEvent (event
);
10214 mac_set_unicode_keystroke_event (code
, buf
)
10216 struct input_event
*buf
;
10218 int charset_id
, c1
, c2
;
10222 buf
->kind
= ASCII_KEYSTROKE_EVENT
;
10225 else if (code
< 0x100)
10228 charset_id
= CHARSET_8_BIT_CONTROL
;
10230 charset_id
= charset_latin_iso8859_1
;
10231 buf
->kind
= MULTIBYTE_CHAR_KEYSTROKE_EVENT
;
10232 buf
->code
= MAKE_CHAR (charset_id
, code
, 0);
10237 charset_id
= charset_mule_unicode_0100_24ff
,
10239 else if (code
< 0x33FF)
10240 charset_id
= charset_mule_unicode_2500_33ff
,
10242 else if (code
>= 0xE000)
10243 charset_id
= charset_mule_unicode_e000_ffff
,
10245 c1
= (code
/ 96) + 32, c2
= (code
% 96) + 32;
10246 buf
->kind
= MULTIBYTE_CHAR_KEYSTROKE_EVENT
;
10247 buf
->code
= MAKE_CHAR (charset_id
, c1
, c2
);
10252 /* Emacs calls this whenever it wants to read an input event from the
10255 XTread_socket (sd
, expected
, hold_quit
)
10257 struct input_event
*hold_quit
;
10259 struct input_event inev
;
10261 #if USE_CARBON_EVENTS
10263 EventTargetRef toolbox_dispatcher
;
10266 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
10268 if (interrupt_input_blocked
)
10270 interrupt_input_pending
= 1;
10274 interrupt_input_pending
= 0;
10277 /* So people can tell when we have read the available input. */
10278 input_signal_count
++;
10282 #if USE_CARBON_EVENTS
10283 toolbox_dispatcher
= GetEventDispatcherTarget ();
10287 mac_prepare_for_quickdraw (NULL
),
10289 !ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
10290 kEventRemoveFromQueue
, &eventRef
))
10291 #else /* !USE_CARBON_EVENTS */
10292 while (mac_wait_next_event (&er
, 0, true))
10293 #endif /* !USE_CARBON_EVENTS */
10297 unsigned long timestamp
;
10300 inev
.kind
= NO_EVENT
;
10303 #if USE_CARBON_EVENTS
10304 timestamp
= GetEventTime (eventRef
) / kEventDurationMillisecond
;
10306 timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
10309 #if USE_CARBON_EVENTS
10310 /* Handle new events */
10311 if (!mac_convert_event_ref (eventRef
, &er
))
10313 /* There used to be a handler for the kEventMouseWheelMoved
10314 event here. But as of Mac OS X 10.4, this kind of event
10315 is not directly posted to the main event queue by
10316 two-finger scrolling on the trackpad. Instead, some
10317 private event is posted and it is converted to a wheel
10318 event by the default handler for the application target.
10319 The converted one can be received by a Carbon event
10320 handler installed on a window target. */
10321 read_socket_inev
= &inev
;
10322 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
10323 read_socket_inev
= NULL
;
10326 #endif /* USE_CARBON_EVENTS */
10332 WindowPtr window_ptr
;
10333 ControlPartCode part_code
;
10334 int tool_bar_p
= 0;
10336 #if USE_CARBON_EVENTS
10337 /* This is needed to send mouse events like aqua window
10338 buttons to the correct handler. */
10339 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10340 != eventNotHandledErr
)
10343 last_mouse_glyph_frame
= 0;
10345 if (dpyinfo
->grabbed
&& last_mouse_frame
10346 && FRAME_LIVE_P (last_mouse_frame
))
10348 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
10349 part_code
= inContent
;
10353 part_code
= FindWindow (er
.where
, &window_ptr
);
10354 if (tip_window
&& window_ptr
== tip_window
)
10356 HideWindow (tip_window
);
10357 part_code
= FindWindow (er
.where
, &window_ptr
);
10361 if (er
.what
!= mouseDown
&&
10362 (part_code
!= inContent
|| dpyinfo
->grabbed
== 0))
10368 f
= mac_focus_frame (dpyinfo
);
10369 saved_menu_event_location
= er
.where
;
10370 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
10371 XSETFRAME (inev
.frame_or_window
, f
);
10376 #if TARGET_API_MAC_CARBON
10377 FrontNonFloatingWindow ()
10382 SelectWindow (window_ptr
);
10385 ControlPartCode control_part_code
;
10387 Point mouse_loc
= er
.where
;
10389 ControlKind control_kind
;
10392 f
= mac_window_to_frame (window_ptr
);
10393 /* convert to local coordinates of new window */
10394 SetPortWindowPort (window_ptr
);
10396 GlobalToLocal (&mouse_loc
);
10397 #if TARGET_API_MAC_CARBON
10398 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
10399 &control_part_code
);
10402 GetControlKind (ch
, &control_kind
);
10405 control_part_code
= FindControl (mouse_loc
, window_ptr
,
10409 #if USE_CARBON_EVENTS
10410 inev
.code
= mac_get_mouse_btn (eventRef
);
10411 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
10413 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
10414 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
10416 XSETINT (inev
.x
, mouse_loc
.h
);
10417 XSETINT (inev
.y
, mouse_loc
.v
);
10419 if ((dpyinfo
->grabbed
&& tracked_scroll_bar
)
10421 #ifndef USE_TOOLKIT_SCROLL_BARS
10422 /* control_part_code becomes kControlNoPart if
10423 a progress indicator is clicked. */
10424 && control_part_code
!= kControlNoPart
10425 #else /* USE_TOOLKIT_SCROLL_BARS */
10427 && control_kind
.kind
== kControlKindScrollBar
10428 #endif /* MAC_OSX */
10429 #endif /* USE_TOOLKIT_SCROLL_BARS */
10432 struct scroll_bar
*bar
;
10434 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10436 bar
= tracked_scroll_bar
;
10437 #ifndef USE_TOOLKIT_SCROLL_BARS
10438 control_part_code
= kControlIndicatorPart
;
10442 bar
= (struct scroll_bar
*) GetControlReference (ch
);
10443 #ifdef USE_TOOLKIT_SCROLL_BARS
10444 /* Make the "Ctrl-Mouse-2 splits window" work
10445 for toolkit scroll bars. */
10446 if (er
.modifiers
& controlKey
)
10447 x_scroll_bar_handle_click (bar
, control_part_code
,
10449 else if (er
.what
== mouseDown
)
10450 x_scroll_bar_handle_press (bar
, control_part_code
,
10453 x_scroll_bar_handle_release (bar
, &inev
);
10454 #else /* not USE_TOOLKIT_SCROLL_BARS */
10455 x_scroll_bar_handle_click (bar
, control_part_code
,
10457 if (er
.what
== mouseDown
10458 && control_part_code
== kControlIndicatorPart
)
10459 tracked_scroll_bar
= bar
;
10461 tracked_scroll_bar
= NULL
;
10462 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10466 Lisp_Object window
;
10467 int x
= mouse_loc
.h
;
10468 int y
= mouse_loc
.v
;
10470 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
10471 if (EQ (window
, f
->tool_bar_window
))
10473 if (er
.what
== mouseDown
)
10474 handle_tool_bar_click (f
, x
, y
, 1, 0);
10476 handle_tool_bar_click (f
, x
, y
, 0,
10482 XSETFRAME (inev
.frame_or_window
, f
);
10483 inev
.kind
= MOUSE_CLICK_EVENT
;
10487 if (er
.what
== mouseDown
)
10489 dpyinfo
->grabbed
|= (1 << inev
.code
);
10490 last_mouse_frame
= f
;
10493 last_tool_bar_item
= -1;
10497 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
10498 /* If a button is released though it was not
10499 previously pressed, that would be because
10500 of multi-button emulation. */
10501 dpyinfo
->grabbed
= 0;
10503 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
10506 /* Ignore any mouse motion that happened before
10507 this event; any subsequent mouse-movement Emacs
10508 events should reflect only motion after the
10511 f
->mouse_moved
= 0;
10513 #ifdef USE_TOOLKIT_SCROLL_BARS
10514 if (inev
.kind
== MOUSE_CLICK_EVENT
)
10519 inev
.modifiers
|= down_modifier
;
10522 inev
.modifiers
|= up_modifier
;
10529 #if TARGET_API_MAC_CARBON
10531 if (IsWindowPathSelectClick (window_ptr
, &er
))
10533 WindowPathSelect (window_ptr
, NULL
, NULL
);
10536 if (part_code
== inProxyIcon
10537 && (TrackWindowProxyDrag (window_ptr
, er
.where
)
10538 != errUserWantsToDragWindow
))
10540 DragWindow (window_ptr
, er
.where
, NULL
);
10541 #else /* not TARGET_API_MAC_CARBON */
10542 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
10543 #endif /* not TARGET_API_MAC_CARBON */
10544 /* Update the frame parameters. */
10545 #if !USE_CARBON_EVENTS
10547 struct frame
*f
= mac_window_to_frame (window_ptr
);
10549 if (f
&& !f
->async_iconified
)
10550 mac_handle_origin_change (f
);
10556 if (TrackGoAway (window_ptr
, er
.where
))
10558 inev
.kind
= DELETE_WINDOW_EVENT
;
10559 XSETFRAME (inev
.frame_or_window
,
10560 mac_window_to_frame (window_ptr
));
10564 /* window resize handling added --ben */
10566 do_grow_window (window_ptr
, &er
);
10569 /* window zoom handling added --ben */
10572 if (TrackBox (window_ptr
, er
.where
, part_code
))
10573 do_zoom_window (window_ptr
, part_code
);
10583 #if USE_CARBON_EVENTS
10584 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10585 != eventNotHandledErr
)
10588 do_window_update ((WindowPtr
) er
.message
);
10593 #if USE_CARBON_EVENTS
10594 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10595 != eventNotHandledErr
)
10598 switch ((er
.message
>> 24) & 0x000000FF)
10600 case suspendResumeMessage
:
10602 if (er
.message
& resumeFlag
)
10605 mac_tsm_suspend ();
10609 case mouseMovedMessage
:
10610 #if !USE_CARBON_EVENTS
10611 SetRectRgn (mouse_region
, er
.where
.h
, er
.where
.v
,
10612 er
.where
.h
+ 1, er
.where
.v
+ 1);
10614 previous_help_echo_string
= help_echo_string
;
10615 help_echo_string
= Qnil
;
10617 if (dpyinfo
->grabbed
&& last_mouse_frame
10618 && FRAME_LIVE_P (last_mouse_frame
))
10619 f
= last_mouse_frame
;
10621 f
= dpyinfo
->x_focus_frame
;
10623 if (dpyinfo
->mouse_face_hidden
)
10625 dpyinfo
->mouse_face_hidden
= 0;
10626 clear_mouse_face (dpyinfo
);
10631 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
10632 Point mouse_pos
= er
.where
;
10634 SetPortWindowPort (wp
);
10636 GlobalToLocal (&mouse_pos
);
10638 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10639 #ifdef USE_TOOLKIT_SCROLL_BARS
10640 x_scroll_bar_handle_drag (wp
, tracked_scroll_bar
,
10642 #else /* not USE_TOOLKIT_SCROLL_BARS */
10643 x_scroll_bar_note_movement (tracked_scroll_bar
,
10645 - XINT (tracked_scroll_bar
->top
),
10646 er
.when
* (1000 / 60));
10647 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10650 /* Generate SELECT_WINDOW_EVENTs when needed. */
10651 if (!NILP (Vmouse_autoselect_window
))
10653 Lisp_Object window
;
10655 window
= window_from_coordinates (f
,
10660 /* Window will be selected only when it is
10661 not selected now and last mouse movement
10662 event was not in it. Minibuffer window
10663 will be selected iff it is active. */
10664 if (WINDOWP (window
)
10665 && !EQ (window
, last_window
)
10666 && !EQ (window
, selected_window
))
10668 inev
.kind
= SELECT_WINDOW_EVENT
;
10669 inev
.frame_or_window
= window
;
10672 last_window
=window
;
10674 if (!note_mouse_movement (f
, &mouse_pos
))
10675 help_echo_string
= previous_help_echo_string
;
10679 /* If the contents of the global variable
10680 help_echo_string has changed, generate a
10682 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
10690 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
10692 #if USE_CARBON_EVENTS
10693 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10694 != eventNotHandledErr
)
10697 if (window_ptr
== tip_window
)
10699 HideWindow (tip_window
);
10703 if (!is_emacs_window (window_ptr
))
10706 if ((er
.modifiers
& activeFlag
) != 0)
10708 /* A window has been activated */
10709 Point mouse_loc
= er
.where
;
10711 x_detect_focus_change (dpyinfo
, &er
, &inev
);
10713 SetPortWindowPort (window_ptr
);
10714 GlobalToLocal (&mouse_loc
);
10715 /* Window-activated event counts as mouse movement,
10716 so update things that depend on mouse position. */
10717 note_mouse_movement (mac_window_to_frame (window_ptr
),
10722 /* A window has been deactivated */
10723 #if USE_TOOLKIT_SCROLL_BARS
10724 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10726 struct input_event event
;
10728 EVENT_INIT (event
);
10729 event
.kind
= NO_EVENT
;
10730 x_scroll_bar_handle_release (tracked_scroll_bar
, &event
);
10731 if (event
.kind
!= NO_EVENT
)
10733 event
.timestamp
= timestamp
;
10734 kbd_buffer_store_event_hold (&event
, hold_quit
);
10739 dpyinfo
->grabbed
= 0;
10741 x_detect_focus_change (dpyinfo
, &er
, &inev
);
10743 f
= mac_window_to_frame (window_ptr
);
10744 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10746 /* If we move outside the frame, then we're
10747 certainly no longer on any text in the
10749 clear_mouse_face (dpyinfo
);
10750 dpyinfo
->mouse_face_mouse_frame
= 0;
10753 /* Generate a nil HELP_EVENT to cancel a help-echo.
10754 Do it only if there's something to cancel.
10755 Otherwise, the startup message is cleared when the
10756 mouse leaves the frame. */
10757 if (any_help_event_p
)
10767 int keycode
= (er
.message
& keyCodeMask
) >> 8;
10768 static SInt16 last_key_script
= -1;
10769 SInt16 current_key_script
;
10770 UInt32 modifiers
= er
.modifiers
, mapped_modifiers
;
10773 (NILP (Vmac_control_modifier
) ? 0 : controlKey
)
10774 | (NILP (Vmac_option_modifier
) ? 0 : optionKey
)
10775 | (NILP (Vmac_command_modifier
) ? 0 : cmdKey
);
10777 #if USE_CARBON_EVENTS && defined (MAC_OSX)
10778 mapped_modifiers
|=
10779 (NILP (Vmac_function_modifier
) ? 0 : kEventKeyModifierFnMask
);
10781 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
10783 sizeof (UInt32
), NULL
, &modifiers
);
10785 mapped_modifiers
&= modifiers
;
10787 #if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
10788 /* When using Carbon Events, we need to pass raw keyboard
10789 events to the TSM ourselves. If TSM handles it, it
10790 will pass back noErr, otherwise it will pass back
10791 "eventNotHandledErr" and we can process it
10793 if (!(mapped_modifiers
10794 & ~(mac_pass_command_to_system
? cmdKey
: 0)
10795 & ~(mac_pass_control_to_system
? controlKey
: 0)))
10799 read_socket_inev
= &inev
;
10800 err
= SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
10801 read_socket_inev
= NULL
;
10802 if (err
!= eventNotHandledErr
)
10806 if (er
.what
== keyUp
)
10811 f
= mac_focus_frame (dpyinfo
);
10813 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
)
10814 && !EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
))
10816 clear_mouse_face (dpyinfo
);
10817 dpyinfo
->mouse_face_hidden
= 1;
10820 current_key_script
= GetScriptManagerVariable (smKeyScript
);
10821 if (last_key_script
!= current_key_script
)
10823 struct input_event event
;
10825 EVENT_INIT (event
);
10826 event
.kind
= LANGUAGE_CHANGE_EVENT
;
10828 event
.code
= current_key_script
;
10829 event
.timestamp
= timestamp
;
10830 kbd_buffer_store_event (&event
);
10832 last_key_script
= current_key_script
;
10836 if (inev
.kind
!= NO_EVENT
)
10841 if (mapped_modifiers
& kEventKeyModifierFnMask
10843 && fn_keycode_to_keycode_table
[keycode
])
10844 keycode
= fn_keycode_to_keycode_table
[keycode
];
10846 if (keycode
<= 0x7f && keycode_to_xkeysym_table
[keycode
])
10848 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
10849 inev
.code
= 0xff00 | keycode_to_xkeysym_table
[keycode
];
10851 if (modifiers
& kEventKeyModifierFnMask
10853 && fn_keycode_to_keycode_table
[keycode
] == keycode
)
10854 modifiers
&= ~kEventKeyModifierFnMask
;
10857 else if (mapped_modifiers
)
10859 /* translate the keycode back to determine the
10862 static SInt16 last_key_layout_id
= 0;
10863 static Handle uchr_handle
= (Handle
)-1;
10864 SInt16 current_key_layout_id
=
10865 GetScriptVariable (current_key_script
, smScriptKeys
);
10867 if (uchr_handle
== (Handle
)-1
10868 || last_key_layout_id
!= current_key_layout_id
)
10870 uchr_handle
= GetResource ('uchr', current_key_layout_id
);
10871 last_key_layout_id
= current_key_layout_id
;
10877 UInt16 key_action
= er
.what
- keyDown
;
10878 UInt32 modifier_key_state
=
10879 (modifiers
& ~mapped_modifiers
) >> 8;
10880 UInt32 keyboard_type
= LMGetKbdType ();
10881 SInt32 dead_key_state
= 0;
10883 UniCharCount actual_length
;
10885 status
= UCKeyTranslate ((UCKeyboardLayout
*)*uchr_handle
,
10886 keycode
, key_action
,
10887 modifier_key_state
,
10889 kUCKeyTranslateNoDeadKeysMask
,
10891 1, &actual_length
, &code
);
10892 if (status
== noErr
&& actual_length
== 1)
10893 mac_set_unicode_keystroke_event (code
, &inev
);
10895 #endif /* MAC_OSX */
10897 if (inev
.kind
== NO_EVENT
)
10899 /* This code comes from Keyboard Resource,
10900 Appendix C of IM - Text. This is necessary
10901 since shift is ignored in KCHR table
10902 translation when option or command is pressed.
10903 It also does not translate correctly
10904 control-shift chars like C-% so mask off shift
10906 /* Mask off modifier keys that are mapped to some
10907 Emacs modifiers. */
10908 int new_modifiers
= er
.modifiers
& ~mapped_modifiers
;
10909 /* set high byte of keycode to modifier high byte*/
10910 int new_keycode
= keycode
| new_modifiers
;
10911 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
10912 unsigned long some_state
= 0;
10913 UInt32 new_char_code
;
10915 new_char_code
= KeyTranslate (kchr_ptr
, new_keycode
,
10917 if (new_char_code
== 0)
10918 /* Seems like a dead key. Append up-stroke. */
10919 new_char_code
= KeyTranslate (kchr_ptr
,
10920 new_keycode
| 0x80,
10924 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
10925 inev
.code
= new_char_code
& 0xff;
10930 if (inev
.kind
== NO_EVENT
)
10932 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
10933 inev
.code
= er
.message
& charCodeMask
;
10936 inev
.modifiers
= mac_to_emacs_modifiers (modifiers
);
10937 inev
.modifiers
|= (extra_keyboard_modifiers
10938 & (meta_modifier
| alt_modifier
10939 | hyper_modifier
| super_modifier
));
10940 XSETFRAME (inev
.frame_or_window
, f
);
10942 #if TARGET_API_MAC_CARBON
10943 if (inev
.kind
== ASCII_KEYSTROKE_EVENT
10944 && inev
.code
>= 0x80 && inev
.modifiers
)
10947 TextEncoding encoding
= kTextEncodingMacRoman
;
10948 TextToUnicodeInfo ttu_info
;
10950 UpgradeScriptInfoToTextEncoding (current_key_script
,
10951 kTextLanguageDontCare
,
10952 kTextRegionDontCare
,
10954 err
= CreateTextToUnicodeInfoByEncoding (encoding
, &ttu_info
);
10959 ByteCount unicode_len
;
10962 pstr
[1] = inev
.code
;
10963 err
= ConvertFromPStringToUnicode (ttu_info
, pstr
,
10965 &unicode_len
, &code
);
10966 if (err
== noErr
&& unicode_len
== sizeof (UniChar
))
10967 mac_set_unicode_keystroke_event (code
, &inev
);
10968 DisposeTextToUnicodeInfo (&ttu_info
);
10975 case kHighLevelEvent
:
10976 AEProcessAppleEvent (&er
);
10982 #if USE_CARBON_EVENTS
10983 ReleaseEvent (eventRef
);
10986 if (inev
.kind
!= NO_EVENT
)
10988 inev
.timestamp
= timestamp
;
10989 kbd_buffer_store_event_hold (&inev
, hold_quit
);
10994 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
10999 XSETFRAME (frame
, f
);
11005 any_help_event_p
= 1;
11006 gen_help_event (help_echo_string
, frame
, help_echo_window
,
11007 help_echo_object
, help_echo_pos
);
11011 help_echo_string
= Qnil
;
11012 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
11019 /* If the focus was just given to an autoraising frame,
11021 /* ??? This ought to be able to handle more than one such frame. */
11022 if (pending_autoraise_frame
)
11024 x_raise_frame (pending_autoraise_frame
);
11025 pending_autoraise_frame
= 0;
11028 #if !USE_CARBON_EVENTS
11029 /* Check which frames are still visible. We do this here because
11030 there doesn't seem to be any direct notification from the Window
11031 Manager that the visibility of a window has changed (at least,
11032 not in all cases). */
11034 Lisp_Object tail
, frame
;
11036 FOR_EACH_FRAME (tail
, frame
)
11038 struct frame
*f
= XFRAME (frame
);
11040 /* The tooltip has been drawn already. Avoid the
11041 SET_FRAME_GARBAGED in mac_handle_visibility_change. */
11042 if (EQ (frame
, tip_frame
))
11045 if (FRAME_MAC_P (f
))
11046 mac_handle_visibility_change (f
);
11057 /* Need to override CodeWarrior's input function so no conversion is
11058 done on newlines Otherwise compiled functions in .elc files will be
11059 read incorrectly. Defined in ...:MSL C:MSL
11060 Common:Source:buffer_io.c. */
11063 __convert_to_newlines (unsigned char * p
, size_t * n
)
11065 #pragma unused(p,n)
11069 __convert_from_newlines (unsigned char * p
, size_t * n
)
11071 #pragma unused(p,n)
11077 make_mac_terminal_frame (struct frame
*f
)
11082 XSETFRAME (frame
, f
);
11084 f
->output_method
= output_mac
;
11085 f
->output_data
.mac
= (struct mac_output
*)
11086 xmalloc (sizeof (struct mac_output
));
11087 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
11089 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
11091 FRAME_COLS (f
) = 96;
11092 FRAME_LINES (f
) = 4;
11094 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
11095 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
11097 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
11099 f
->output_data
.mac
->cursor_pixel
= 0;
11100 f
->output_data
.mac
->border_pixel
= 0x00ff00;
11101 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
11102 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
11104 f
->output_data
.mac
->text_cursor
= kThemeIBeamCursor
;
11105 f
->output_data
.mac
->nontext_cursor
= kThemeArrowCursor
;
11106 f
->output_data
.mac
->modeline_cursor
= kThemeArrowCursor
;
11107 f
->output_data
.mac
->hand_cursor
= kThemePointingHandCursor
;
11108 f
->output_data
.mac
->hourglass_cursor
= kThemeWatchCursor
;
11109 f
->output_data
.mac
->horizontal_drag_cursor
= kThemeResizeLeftRightCursor
;
11111 FRAME_FONTSET (f
) = -1;
11112 f
->output_data
.mac
->explicit_parent
= 0;
11115 f
->border_width
= 0;
11117 f
->internal_border_width
= 0;
11122 f
->new_text_cols
= 0;
11123 f
->new_text_lines
= 0;
11125 SetRect (&r
, f
->left_pos
, f
->top_pos
,
11126 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
11127 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
11131 if (!(FRAME_MAC_WINDOW (f
) =
11132 NewCWindow (NULL
, &r
, "\p", true, dBoxProc
,
11133 (WindowPtr
) -1, 1, (long) f
->output_data
.mac
)))
11135 /* so that update events can find this mac_output struct */
11136 f
->output_data
.mac
->mFP
= f
; /* point back to emacs frame */
11142 /* Need to be initialized for unshow_buffer in window.c. */
11143 selected_window
= f
->selected_window
;
11145 Fmodify_frame_parameters (frame
,
11146 Fcons (Fcons (Qfont
,
11147 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
11148 Fmodify_frame_parameters (frame
,
11149 Fcons (Fcons (Qforeground_color
,
11150 build_string ("black")), Qnil
));
11151 Fmodify_frame_parameters (frame
,
11152 Fcons (Fcons (Qbackground_color
,
11153 build_string ("white")), Qnil
));
11158 /***********************************************************************
11160 ***********************************************************************/
11162 int mac_initialized
= 0;
11165 mac_initialize_display_info ()
11167 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
11169 bzero (dpyinfo
, sizeof (*dpyinfo
));
11172 dpyinfo
->mac_id_name
11173 = (char *) xmalloc (SCHARS (Vinvocation_name
)
11174 + SCHARS (Vsystem_name
)
11176 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
11177 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
11179 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
11180 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
11183 dpyinfo
->reference_count
= 0;
11184 dpyinfo
->resx
= 72.0;
11185 dpyinfo
->resy
= 72.0;
11187 /* HasDepth returns true if it is possible to have a 32 bit display,
11188 but this may not be what is actually used. Mac OSX can do better. */
11189 dpyinfo
->color_p
= CGDisplaySamplesPerPixel (kCGDirectMainDisplay
) > 1;
11190 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (kCGDirectMainDisplay
);
11191 dpyinfo
->height
= CGDisplayPixelsHigh (kCGDirectMainDisplay
);
11192 dpyinfo
->width
= CGDisplayPixelsWide (kCGDirectMainDisplay
);
11195 GDHandle main_device_handle
= LMGetMainDevice();
11197 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
11198 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
11199 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
11200 gdDevType
, dpyinfo
->color_p
))
11202 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
11203 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
11206 dpyinfo
->grabbed
= 0;
11207 dpyinfo
->root_window
= NULL
;
11208 dpyinfo
->image_cache
= make_image_cache ();
11210 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
11211 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
11212 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
11213 dpyinfo
->mouse_face_window
= Qnil
;
11214 dpyinfo
->mouse_face_overlay
= Qnil
;
11215 dpyinfo
->mouse_face_hidden
= 0;
11220 mac_make_rdb (xrm_option
)
11223 XrmDatabase database
;
11225 database
= xrm_get_preference_database (NULL
);
11227 xrm_merge_string_database (database
, xrm_option
);
11232 struct mac_display_info
*
11233 mac_term_init (display_name
, xrm_option
, resource_name
)
11234 Lisp_Object display_name
;
11236 char *resource_name
;
11238 struct mac_display_info
*dpyinfo
;
11242 if (!mac_initialized
)
11245 mac_initialized
= 1;
11248 if (x_display_list
)
11249 error ("Sorry, this version can only handle one display");
11251 mac_initialize_display_info ();
11253 dpyinfo
= &one_mac_display_info
;
11255 dpyinfo
->xrdb
= mac_make_rdb (xrm_option
);
11257 /* Put this display on the chain. */
11258 dpyinfo
->next
= x_display_list
;
11259 x_display_list
= dpyinfo
;
11261 /* Put it on x_display_name_list. */
11262 x_display_name_list
= Fcons (Fcons (display_name
,
11263 Fcons (Qnil
, dpyinfo
->xrdb
)),
11264 x_display_name_list
);
11265 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
11271 /* Get rid of display DPYINFO, assuming all frames are already gone. */
11274 x_delete_display (dpyinfo
)
11275 struct mac_display_info
*dpyinfo
;
11279 /* Discard this display from x_display_name_list and x_display_list.
11280 We can't use Fdelq because that can quit. */
11281 if (! NILP (x_display_name_list
)
11282 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
11283 x_display_name_list
= XCDR (x_display_name_list
);
11288 tail
= x_display_name_list
;
11289 while (CONSP (tail
) && CONSP (XCDR (tail
)))
11291 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
11293 XSETCDR (tail
, XCDR (XCDR (tail
)));
11296 tail
= XCDR (tail
);
11300 if (x_display_list
== dpyinfo
)
11301 x_display_list
= dpyinfo
->next
;
11304 struct x_display_info
*tail
;
11306 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
11307 if (tail
->next
== dpyinfo
)
11308 tail
->next
= tail
->next
->next
;
11311 /* Free the font names in the font table. */
11312 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11313 if (dpyinfo
->font_table
[i
].name
)
11315 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
11316 xfree (dpyinfo
->font_table
[i
].full_name
);
11317 xfree (dpyinfo
->font_table
[i
].name
);
11320 if (dpyinfo
->font_table
)
11322 if (dpyinfo
->font_table
->font_encoder
)
11323 xfree (dpyinfo
->font_table
->font_encoder
);
11324 xfree (dpyinfo
->font_table
);
11326 if (dpyinfo
->mac_id_name
)
11327 xfree (dpyinfo
->mac_id_name
);
11329 if (x_display_list
== 0)
11331 mac_clear_font_name_table ();
11332 bzero (dpyinfo
, sizeof (*dpyinfo
));
11341 extern int inhibit_window_system
;
11342 extern int noninteractive
;
11343 CFBundleRef appsBundle
;
11345 /* No need to test if already -nw*/
11346 if (inhibit_window_system
|| noninteractive
)
11349 appsBundle
= CFBundleGetMainBundle();
11350 if (appsBundle
!= NULL
)
11352 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
11353 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
11354 /* We found the bundle identifier, now we know we are valid. */
11361 /* MAC_TODO: Have this start the bundled executable */
11363 /* For now, prevent the fatal error by bringing it up in the terminal */
11364 inhibit_window_system
= 1;
11368 MakeMeTheFrontProcess ()
11370 ProcessSerialNumber psn
;
11373 err
= GetCurrentProcess (&psn
);
11375 (void) SetFrontProcess (&psn
);
11378 /***** Code to handle C-g testing *****/
11380 /* Contains the Mac modifier formed from quit_char */
11381 int mac_quit_char_modifiers
= 0;
11382 int mac_quit_char_keycode
;
11383 extern int quit_char
;
11386 mac_determine_quit_char_modifiers()
11388 /* Todo: Determine modifiers from quit_char. */
11389 UInt32 qc_modifiers
= ctrl_modifier
;
11391 /* Map modifiers */
11392 mac_quit_char_modifiers
= 0;
11393 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= controlKey
;
11394 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= shiftKey
;
11395 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= optionKey
;
11399 init_quit_char_handler ()
11401 /* TODO: Let this support keys other the 'g' */
11402 mac_quit_char_keycode
= 5;
11403 /* Look at <architecture/adb_kb_map.h> for details */
11404 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
11406 mac_determine_quit_char_modifiers();
11408 #endif /* MAC_OSX */
11416 MenuItemIndex menu_index
;
11418 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandQuit
, 1,
11419 &menu
, &menu_index
);
11421 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
11422 #if USE_CARBON_EVENTS
11423 EnableMenuCommand (NULL
, kHICommandPreferences
);
11424 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandPreferences
, 1,
11425 &menu
, &menu_index
);
11428 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
11429 InsertMenuItemTextWithCFString (menu
, NULL
,
11430 0, kMenuItemAttrSeparator
, 0);
11431 InsertMenuItemTextWithCFString (menu
, CFSTR ("About Emacs"),
11432 0, 0, kHICommandAbout
);
11434 #endif /* USE_CARBON_EVENTS */
11435 #else /* !MAC_OSX */
11436 #if USE_CARBON_EVENTS
11437 SetMenuItemCommandID (GetMenuHandle (M_APPLE
), I_ABOUT
, kHICommandAbout
);
11447 static InterfaceTypeList types
= {kUnicodeDocument
};
11449 static InterfaceTypeList types
= {kTextService
};
11452 NewTSMDocument (sizeof (types
) / sizeof (types
[0]), types
,
11453 &tsm_document_id
, 0);
11457 /* Set up use of X before we make the first connection. */
11459 extern frame_parm_handler mac_frame_parm_handlers
[];
11461 static struct redisplay_interface x_redisplay_interface
=
11463 mac_frame_parm_handlers
,
11467 x_clear_end_of_line
,
11469 x_after_update_window_line
,
11470 x_update_window_begin
,
11471 x_update_window_end
,
11474 0, /* flush_display_optional */
11475 x_clear_window_mouse_face
,
11476 x_get_glyph_overhangs
,
11477 x_fix_overlapping_area
,
11478 x_draw_fringe_bitmap
,
11480 mac_define_fringe_bitmap
,
11481 mac_destroy_fringe_bitmap
,
11483 0, /* define_fringe_bitmap */
11484 0, /* destroy_fringe_bitmap */
11486 mac_per_char_metric
,
11488 mac_compute_glyph_string_overhangs
,
11489 x_draw_glyph_string
,
11490 mac_define_frame_cursor
,
11491 mac_clear_frame_area
,
11492 mac_draw_window_cursor
,
11493 mac_draw_vertical_window_border
,
11494 mac_shift_glyphs_for_insert
11500 rif
= &x_redisplay_interface
;
11502 clear_frame_hook
= x_clear_frame
;
11503 ins_del_lines_hook
= x_ins_del_lines
;
11504 delete_glyphs_hook
= x_delete_glyphs
;
11505 ring_bell_hook
= XTring_bell
;
11506 reset_terminal_modes_hook
= XTreset_terminal_modes
;
11507 set_terminal_modes_hook
= XTset_terminal_modes
;
11508 update_begin_hook
= x_update_begin
;
11509 update_end_hook
= x_update_end
;
11510 set_terminal_window_hook
= XTset_terminal_window
;
11511 read_socket_hook
= XTread_socket
;
11512 frame_up_to_date_hook
= XTframe_up_to_date
;
11513 mouse_position_hook
= XTmouse_position
;
11514 frame_rehighlight_hook
= XTframe_rehighlight
;
11515 frame_raise_lower_hook
= XTframe_raise_lower
;
11517 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
11518 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
11519 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
11520 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
11522 TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
11523 TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
11524 TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
11525 TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
11526 TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
11531 last_tool_bar_item
= -1;
11532 any_help_event_p
= 0;
11534 /* Try to use interrupt input; if we can't, then start polling. */
11535 Fset_input_interrupt_mode (Qt
);
11539 #if TARGET_API_MAC_CARBON
11541 #if USE_CARBON_EVENTS
11543 init_service_handler ();
11545 init_quit_char_handler ();
11546 #endif /* MAC_OSX */
11548 init_command_handler ();
11555 #endif /* USE_CARBON_EVENTS */
11558 init_coercion_handler ();
11560 init_apple_event_handler ();
11562 if (!inhibit_window_system
)
11563 MakeMeTheFrontProcess ();
11568 mac_init_fringe ();
11579 staticpro (&x_error_message_string
);
11580 x_error_message_string
= Qnil
;
11583 Qcontrol
= intern ("control"); staticpro (&Qcontrol
);
11584 Qmeta
= intern ("meta"); staticpro (&Qmeta
);
11585 Qalt
= intern ("alt"); staticpro (&Qalt
);
11586 Qhyper
= intern ("hyper"); staticpro (&Qhyper
);
11587 Qsuper
= intern ("super"); staticpro (&Qsuper
);
11588 Qmodifier_value
= intern ("modifier-value");
11589 staticpro (&Qmodifier_value
);
11591 Fput (Qcontrol
, Qmodifier_value
, make_number (ctrl_modifier
));
11592 Fput (Qmeta
, Qmodifier_value
, make_number (meta_modifier
));
11593 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
11594 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
11595 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
11597 #if USE_CARBON_EVENTS
11598 Qhi_command
= intern ("hi-command"); staticpro (&Qhi_command
);
11600 Qtoolbar_switch_mode
= intern ("toolbar-switch-mode");
11601 staticpro (&Qtoolbar_switch_mode
);
11602 #if USE_MAC_FONT_PANEL
11603 Qpanel_closed
= intern ("panel-closed"); staticpro (&Qpanel_closed
);
11604 Qselection
= intern ("selection"); staticpro (&Qselection
);
11607 Qservice
= intern ("service"); staticpro (&Qservice
);
11608 Qpaste
= intern ("paste"); staticpro (&Qpaste
);
11609 Qperform
= intern ("perform"); staticpro (&Qperform
);
11612 Qtext_input
= intern ("text-input"); staticpro (&Qtext_input
);
11613 Qupdate_active_input_area
= intern ("update-active-input-area");
11614 staticpro (&Qupdate_active_input_area
);
11615 Qunicode_for_key_event
= intern ("unicode-for-key-event");
11616 staticpro (&Qunicode_for_key_event
);
11621 Fprovide (intern ("mac-carbon"), Qnil
);
11624 staticpro (&Qreverse
);
11625 Qreverse
= intern ("reverse");
11627 staticpro (&x_display_name_list
);
11628 x_display_name_list
= Qnil
;
11630 staticpro (&last_mouse_scroll_bar
);
11631 last_mouse_scroll_bar
= Qnil
;
11633 staticpro (&fm_font_family_alist
);
11634 fm_font_family_alist
= Qnil
;
11637 staticpro (&atsu_font_id_hash
);
11638 atsu_font_id_hash
= Qnil
;
11640 staticpro (&fm_style_face_attributes_alist
);
11641 fm_style_face_attributes_alist
= Qnil
;
11645 staticpro (&saved_ts_script_language_on_focus
);
11646 saved_ts_script_language_on_focus
= Qnil
;
11649 /* We don't yet support this, but defining this here avoids whining
11650 from cus-start.el and other places, like "M-x set-variable". */
11651 DEFVAR_BOOL ("x-use-underline-position-properties",
11652 &x_use_underline_position_properties
,
11653 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11654 nil means ignore them. If you encounter fonts with bogus
11655 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11656 to 4.1, set this to nil.
11658 NOTE: Not supported on Mac yet. */);
11659 x_use_underline_position_properties
= 0;
11661 DEFVAR_BOOL ("x-underline-at-descent-line",
11662 &x_underline_at_descent_line
,
11663 doc
: /* *Non-nil means to draw the underline at the same place as the descent line.
11664 nil means to draw the underline according to the value of the variable
11665 `x-use-underline-position-properties', which is usually at the baseline
11666 level. The default value is nil. */);
11667 x_underline_at_descent_line
= 0;
11669 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11670 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11671 #ifdef USE_TOOLKIT_SCROLL_BARS
11672 Vx_toolkit_scroll_bars
= Qt
;
11674 Vx_toolkit_scroll_bars
= Qnil
;
11677 staticpro (&last_mouse_motion_frame
);
11678 last_mouse_motion_frame
= Qnil
;
11680 /* Variables to configure modifier key assignment. */
11682 DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier
,
11683 doc
: /* *Modifier key assumed when the Mac control key is pressed.
11684 The value can be `control', `meta', `alt', `hyper', or `super' for the
11685 respective modifier. The default is `control'. */);
11686 Vmac_control_modifier
= Qcontrol
;
11688 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
11689 doc
: /* *Modifier key assumed when the Mac alt/option key is pressed.
11690 The value can be `control', `meta', `alt', `hyper', or `super' for the
11691 respective modifier. If the value is nil then the key will act as the
11692 normal Mac control modifier, and the option key can be used to compose
11693 characters depending on the chosen Mac keyboard setting. */);
11694 Vmac_option_modifier
= Qnil
;
11696 DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier
,
11697 doc
: /* *Modifier key assumed when the Mac command key is pressed.
11698 The value can be `control', `meta', `alt', `hyper', or `super' for the
11699 respective modifier. The default is `meta'. */);
11700 Vmac_command_modifier
= Qmeta
;
11702 DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier
,
11703 doc
: /* *Modifier key assumed when the Mac function key is pressed.
11704 The value can be `control', `meta', `alt', `hyper', or `super' for the
11705 respective modifier. Note that remapping the function key may lead to
11706 unexpected results for some keys on non-US/GB keyboards. */);
11707 Vmac_function_modifier
= Qnil
;
11709 DEFVAR_LISP ("mac-emulate-three-button-mouse",
11710 &Vmac_emulate_three_button_mouse
,
11711 doc
: /* *Specify a way of three button mouse emulation.
11712 The value can be nil, t, or the symbol `reverse'.
11713 nil means that no emulation should be done and the modifiers should be
11714 placed on the mouse-1 event.
11715 t means that when the option-key is held down while pressing the mouse
11716 button, the click will register as mouse-2 and while the command-key
11717 is held down, the click will register as mouse-3.
11718 The symbol `reverse' means that the option-key will register for
11719 mouse-3 and the command-key will register for mouse-2. */);
11720 Vmac_emulate_three_button_mouse
= Qnil
;
11722 #if USE_CARBON_EVENTS
11723 DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2
,
11724 doc
: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
11725 Otherwise, the right click will be treated as mouse-2 and the wheel
11726 button will be mouse-3. */);
11727 mac_wheel_button_is_mouse_2
= 1;
11729 DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system
,
11730 doc
: /* *Non-nil if command key presses are passed on to the Mac Toolbox. */);
11731 mac_pass_command_to_system
= 1;
11733 DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system
,
11734 doc
: /* *Non-nil if control key presses are passed on to the Mac Toolbox. */);
11735 mac_pass_control_to_system
= 1;
11739 DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics
,
11740 doc
: /* *If non-nil, allow anti-aliasing.
11741 The text will be rendered using Core Graphics text rendering which
11742 may anti-alias the text. */);
11744 mac_use_core_graphics
= 1;
11746 mac_use_core_graphics
= 0;
11749 /* Register an entry for `mac-roman' so that it can be used when
11750 creating the terminal frame on Mac OS 9 before loading
11751 term/mac-win.elc. */
11752 DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist
,
11753 doc
: /* Alist of Emacs character sets vs text encodings and coding systems.
11754 Each entry should be of the form:
11756 (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
11758 where CHARSET-NAME is a string used in font names to identify the
11759 charset, TEXT-ENCODING is a TextEncodingBase value in Mac, and
11760 CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING. */);
11761 Vmac_charset_info_alist
=
11762 Fcons (list3 (build_string ("mac-roman"),
11763 make_number (smRoman
), Qnil
), Qnil
);
11766 DEFVAR_LISP ("mac-atsu-font-table", &Vmac_atsu_font_table
,
11767 doc
: /* Hash table of ATSU font IDs vs plist of attributes and values. */);
11768 Vmac_atsu_font_table
=
11769 make_hash_table (Qeql
, make_number (DEFAULT_HASH_SIZE
),
11770 make_float (DEFAULT_REHASH_SIZE
),
11771 make_float (DEFAULT_REHASH_THRESHOLD
),
11775 DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay
,
11776 doc
: /* Overlay used to display Mac TSM active input area. */);
11777 Vmac_ts_active_input_overlay
= Qnil
;
11779 DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus
,
11780 doc
: /* *How to change Mac TSM script/language when a frame gets focus.
11781 If the value is t, the input script and language are restored to those
11782 used in the last focus frame. If the value is a pair of integers, the
11783 input script and language codes, which are defined in the Script
11784 Manager, are set to its car and cdr parts, respectively. Otherwise,
11785 Emacs doesn't set them and thus follows the system default behavior. */);
11786 Vmac_ts_script_language_on_focus
= Qnil
;
11790 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
11791 (do not change this comment) */