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
*,
248 struct input_event
*));
249 static void XTframe_rehighlight
P_ ((struct frame
*));
250 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
251 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
252 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
253 enum text_cursor_kinds
));
255 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
256 static void x_flush
P_ ((struct frame
*f
));
257 static void x_update_begin
P_ ((struct frame
*));
258 static void x_update_window_begin
P_ ((struct window
*));
259 static void x_after_update_window_line
P_ ((struct glyph_row
*));
260 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
261 enum scroll_bar_part
*,
262 Lisp_Object
*, Lisp_Object
*,
265 static int is_emacs_window
P_ ((WindowPtr
));
266 static XCharStruct
*mac_per_char_metric
P_ ((XFontStruct
*, XChar2b
*, int));
267 static void XSetFont
P_ ((Display
*, GC
, XFontStruct
*));
269 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
270 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
271 #define GC_FONT(gc) ((gc)->xgcv.font)
272 #define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc)
273 #define CG_SET_FILL_COLOR(context, color) \
274 CGContextSetRGBFillColor (context, \
275 RED_FROM_ULONG (color) / 255.0f, \
276 GREEN_FROM_ULONG (color) / 255.0f, \
277 BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
278 #define CG_SET_STROKE_COLOR(context, color) \
279 CGContextSetRGBStrokeColor (context, \
280 RED_FROM_ULONG (color) / 255.0f, \
281 GREEN_FROM_ULONG (color) / 255.0f, \
282 BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
284 #define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
286 /* Fringe bitmaps. */
288 static int max_fringe_bmp
= 0;
289 static CGImageRef
*fringe_bmp
= 0;
292 mac_begin_cg_clip (f
, gc
)
296 CGContextRef context
= FRAME_CG_CONTEXT (f
);
300 QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f
)), &context
);
301 FRAME_CG_CONTEXT (f
) = context
;
304 CGContextSaveGState (context
);
305 CGContextTranslateCTM (context
, 0, FRAME_PIXEL_HEIGHT (f
));
306 CGContextScaleCTM (context
, 1, -1);
307 if (gc
&& gc
->n_clip_rects
)
308 CGContextClipToRects (context
, gc
->clip_rects
, gc
->n_clip_rects
);
317 CGContextRestoreGState (FRAME_CG_CONTEXT (f
));
321 mac_prepare_for_quickdraw (f
)
326 Lisp_Object rest
, frame
;
327 FOR_EACH_FRAME (rest
, frame
)
328 if (FRAME_MAC_P (XFRAME (frame
)))
329 mac_prepare_for_quickdraw (XFRAME (frame
));
333 CGContextRef context
= FRAME_CG_CONTEXT (f
);
337 CGContextSynchronize (context
);
338 QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f
)),
339 &FRAME_CG_CONTEXT (f
));
345 static RgnHandle saved_port_clip_region
= NULL
;
351 static RgnHandle new_region
= NULL
;
353 if (saved_port_clip_region
== NULL
)
354 saved_port_clip_region
= NewRgn ();
355 if (new_region
== NULL
)
356 new_region
= NewRgn ();
358 if (gc
->n_clip_rects
)
360 GetClip (saved_port_clip_region
);
361 SectRgn (saved_port_clip_region
, gc
->clip_region
, new_region
);
362 SetClip (new_region
);
370 if (gc
->n_clip_rects
)
371 SetClip (saved_port_clip_region
);
375 /* X display function emulation */
378 XFreePixmap (display
, pixmap
)
379 Display
*display
; /* not used */
382 DisposeGWorld (pixmap
);
386 /* Mac version of XDrawLine. */
389 mac_draw_line (f
, gc
, x1
, y1
, x2
, y2
)
395 CGContextRef context
;
396 float gx1
= x1
, gy1
= y1
, gx2
= x2
, gy2
= y2
;
399 gx1
+= 0.5f
, gx2
+= 0.5f
;
401 gy1
+= 0.5f
, gy2
+= 0.5f
;
403 context
= mac_begin_cg_clip (f
, gc
);
404 CG_SET_STROKE_COLOR (context
, gc
->xgcv
.foreground
);
405 CGContextBeginPath (context
);
406 CGContextMoveToPoint (context
, gx1
, gy1
);
407 CGContextAddLineToPoint (context
, gx2
, gy2
);
408 CGContextClosePath (context
);
409 CGContextStrokePath (context
);
427 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
429 RGBForeColor (GC_FORE_COLOR (gc
));
439 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
463 GetGWorld (&old_port
, &old_gdh
);
466 RGBForeColor (GC_FORE_COLOR (gc
));
468 LockPixels (GetGWorldPixMap (p
));
471 UnlockPixels (GetGWorldPixMap (p
));
473 SetGWorld (old_port
, old_gdh
);
478 mac_erase_rectangle (f
, gc
, x
, y
, width
, height
)
482 unsigned int width
, height
;
485 CGContextRef context
;
487 context
= mac_begin_cg_clip (f
, gc
);
488 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
489 CGContextFillRect (context
, CGRectMake (x
, y
, width
, height
));
494 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
496 RGBBackColor (GC_BACK_COLOR (gc
));
497 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
503 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
508 /* Mac version of XClearArea. */
511 mac_clear_area (f
, x
, y
, width
, height
)
514 unsigned int width
, height
;
516 mac_erase_rectangle (f
, FRAME_NORMAL_GC (f
), x
, y
, width
, height
);
519 /* Mac version of XClearWindow. */
526 CGContextRef context
;
527 GC gc
= FRAME_NORMAL_GC (f
);
529 context
= mac_begin_cg_clip (f
, NULL
);
530 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
531 CGContextFillRect (context
, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f
),
532 FRAME_PIXEL_HEIGHT (f
)));
535 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
537 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
539 #if TARGET_API_MAC_CARBON
543 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
546 #else /* not TARGET_API_MAC_CARBON */
547 EraseRect (&(FRAME_MAC_WINDOW (f
)->portRect
));
548 #endif /* not TARGET_API_MAC_CARBON */
553 /* Mac replacement for XCopyArea. */
557 mac_draw_cg_image (image
, f
, gc
, src_x
, src_y
, width
, height
,
558 dest_x
, dest_y
, overlay_p
)
563 unsigned int width
, height
;
564 int dest_x
, dest_y
, overlay_p
;
566 CGContextRef context
;
567 float port_height
= FRAME_PIXEL_HEIGHT (f
);
568 CGRect dest_rect
= CGRectMake (dest_x
, dest_y
, width
, height
);
570 context
= mac_begin_cg_clip (f
, gc
);
573 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
574 CGContextFillRect (context
, dest_rect
);
576 CGContextClipToRect (context
, dest_rect
);
577 CGContextScaleCTM (context
, 1, -1);
578 CGContextTranslateCTM (context
, 0, -port_height
);
579 if (CGImageIsMask (image
))
580 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
581 CGContextDrawImage (context
,
582 CGRectMake (dest_x
- src_x
,
583 port_height
- (dest_y
- src_y
584 + CGImageGetHeight (image
)),
585 CGImageGetWidth (image
),
586 CGImageGetHeight (image
)),
591 #else /* !USE_CG_DRAWING */
594 mac_draw_bitmap (f
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
597 int x
, y
, width
, height
;
598 unsigned short *bits
;
604 bitmap
.rowBytes
= sizeof(unsigned short);
605 bitmap
.baseAddr
= (char *)bits
;
606 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
608 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
610 RGBForeColor (GC_FORE_COLOR (gc
));
611 RGBBackColor (GC_BACK_COLOR (gc
));
612 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
615 #if TARGET_API_MAC_CARBON
621 CopyBits (&bitmap
, GetPortBitMapForCopyBits (port
),
622 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
623 UnlockPortBits (port
);
625 #else /* not TARGET_API_MAC_CARBON */
626 CopyBits (&bitmap
, &(FRAME_MAC_WINDOW (f
)->portBits
), &(bitmap
.bounds
), &r
,
627 overlay_p
? srcOr
: srcCopy
, 0);
628 #endif /* not TARGET_API_MAC_CARBON */
631 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
633 #endif /* !USE_CG_DRAWING */
636 /* Mac replacement for XCreateBitmapFromBitmapData. */
639 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
644 static const unsigned char swap_nibble
[16]
645 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
646 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
647 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
648 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
652 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
653 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
654 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
655 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
656 for (i
= 0; i
< h
; i
++)
658 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
659 for (j
= 0; j
< w1
; j
++)
661 /* Bitswap XBM bytes to match how Mac does things. */
662 unsigned char c
= *bits
++;
663 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
664 | (swap_nibble
[(c
>>4) & 0xf]));;
668 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
673 mac_free_bitmap (bitmap
)
676 xfree (bitmap
->baseAddr
);
681 XCreatePixmap (display
, w
, width
, height
, depth
)
682 Display
*display
; /* not used */
684 unsigned int width
, height
;
691 SetPortWindowPort (w
);
693 SetRect (&r
, 0, 0, width
, height
);
694 #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
697 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
698 #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
700 /* CreateCGImageFromPixMaps requires ARGB format. */
701 err
= QTNewGWorld (&pixmap
, k32ARGBPixelFormat
, &r
, NULL
, NULL
, 0);
710 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
711 Display
*display
; /* not used */
714 unsigned int width
, height
;
715 unsigned long fg
, bg
;
722 static GC gc
= NULL
; /* not reentrant */
725 gc
= XCreateGC (display
, w
, 0, NULL
);
727 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
731 GetGWorld (&old_port
, &old_gdh
);
732 SetGWorld (pixmap
, NULL
);
733 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
734 XSetForeground (display
, gc
, fg
);
735 XSetBackground (display
, gc
, bg
);
736 RGBForeColor (GC_FORE_COLOR (gc
));
737 RGBBackColor (GC_BACK_COLOR (gc
));
738 LockPixels (GetGWorldPixMap (pixmap
));
739 #if TARGET_API_MAC_CARBON
740 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
741 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
742 #else /* not TARGET_API_MAC_CARBON */
743 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
744 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
745 #endif /* not TARGET_API_MAC_CARBON */
746 UnlockPixels (GetGWorldPixMap (pixmap
));
747 SetGWorld (old_port
, old_gdh
);
748 mac_free_bitmap (&bitmap
);
754 /* Mac replacement for XFillRectangle. */
757 mac_fill_rectangle (f
, gc
, x
, y
, width
, height
)
761 unsigned int width
, height
;
764 CGContextRef context
;
766 context
= mac_begin_cg_clip (f
, gc
);
767 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
768 CGContextFillRect (context
, CGRectMake (x
, y
, width
, height
));
773 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
775 RGBForeColor (GC_FORE_COLOR (gc
));
776 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
779 PaintRect (&r
); /* using foreground color of gc */
785 /* Mac replacement for XDrawRectangle: dest is a window. */
788 mac_draw_rectangle (f
, gc
, x
, y
, width
, height
)
792 unsigned int width
, height
;
795 CGContextRef context
;
797 context
= mac_begin_cg_clip (f
, gc
);
798 CG_SET_STROKE_COLOR (context
, gc
->xgcv
.foreground
);
799 CGContextStrokeRect (context
,
800 CGRectMake (x
+ 0.5f
, y
+ 0.5f
, width
, height
));
805 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
807 RGBForeColor (GC_FORE_COLOR (gc
));
808 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
811 FrameRect (&r
); /* using foreground color of gc */
819 atsu_get_text_layout_with_text_ptr (text
, text_length
, style
, text_layout
)
820 ConstUniCharArrayPtr text
;
821 UniCharCount text_length
;
823 ATSUTextLayout
*text_layout
;
826 static ATSUTextLayout saved_text_layout
= NULL
; /* not reentrant */
828 if (saved_text_layout
== NULL
)
830 static const UniCharCount lengths
[] = {kATSUToTextEnd
};
831 static const ATSUAttributeTag tags
[] = {kATSULineLayoutOptionsTag
};
832 static const ByteCount sizes
[] = {sizeof (ATSLineLayoutOptions
)};
833 static ATSLineLayoutOptions line_layout
=
834 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
835 kATSLineDisableAllLayoutOperations
| kATSLineUseDeviceMetrics
836 | kATSLineUseQDRendering
838 kATSLineIsDisplayOnly
| kATSLineFractDisable
841 static const ATSUAttributeValuePtr values
[] = {&line_layout
};
843 err
= ATSUCreateTextLayoutWithTextPtr (text
,
844 kATSUFromTextBeginning
,
850 err
= ATSUSetLayoutControls (saved_text_layout
,
851 sizeof (tags
) / sizeof (tags
[0]),
852 tags
, sizes
, values
);
853 /* XXX: Should we do this? */
855 err
= ATSUSetTransientFontMatching (saved_text_layout
, true);
859 err
= ATSUSetRunStyle (saved_text_layout
, style
,
860 kATSUFromTextBeginning
, kATSUToTextEnd
);
862 err
= ATSUSetTextPointerLocation (saved_text_layout
, text
,
863 kATSUFromTextBeginning
,
869 *text_layout
= saved_text_layout
;
876 mac_invert_rectangle (f
, x
, y
, width
, height
)
879 unsigned int width
, height
;
884 mac_prepare_for_quickdraw (f
);
886 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
888 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
895 mac_draw_string_common (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
896 overstrike_p
, bytes_per_char
)
901 int nchars
, bg_width
, overstrike_p
, bytes_per_char
;
903 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
906 if (GC_FONT (gc
)->mac_style
)
909 ATSUTextLayout text_layout
;
911 xassert (bytes_per_char
== 2);
913 #ifndef WORDS_BIG_ENDIAN
916 UniChar
*text
= (UniChar
*)buf
;
918 for (i
= 0; i
< nchars
; i
++)
919 text
[i
] = EndianU16_BtoN (text
[i
]);
922 err
= atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr
)buf
,
924 GC_FONT (gc
)->mac_style
,
929 if (!mac_use_core_graphics
)
933 mac_prepare_for_quickdraw (f
);
936 RGBForeColor (GC_FORE_COLOR (gc
));
941 SetRect (&r
, x
, y
- FONT_BASE (GC_FONT (gc
)),
942 x
+ bg_width
, y
+ FONT_DESCENT (GC_FONT (gc
)));
943 RGBBackColor (GC_BACK_COLOR (gc
));
945 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
948 ATSUDrawText (text_layout
,
949 kATSUFromTextBeginning
, kATSUToTextEnd
,
950 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
954 ATSUDrawText (text_layout
,
955 kATSUFromTextBeginning
, kATSUToTextEnd
,
956 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
964 static CGContextRef context
;
965 float port_height
= FRAME_PIXEL_HEIGHT (f
);
966 static const ATSUAttributeTag tags
[] = {kATSUCGContextTag
};
967 static const ByteCount sizes
[] = {sizeof (CGContextRef
)};
968 static const ATSUAttributeValuePtr values
[] = {&context
};
971 context
= mac_begin_cg_clip (f
, gc
);
974 QDBeginCGContext (port
, &context
);
975 if (gc
->n_clip_rects
|| bg_width
)
977 CGContextTranslateCTM (context
, 0, port_height
);
978 CGContextScaleCTM (context
, 1, -1);
979 if (gc
->n_clip_rects
)
980 CGContextClipToRects (context
, gc
->clip_rects
,
985 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
988 CGRectMake (x
, y
- FONT_BASE (GC_FONT (gc
)),
989 bg_width
, FONT_HEIGHT (GC_FONT (gc
))));
991 CGContextScaleCTM (context
, 1, -1);
992 CGContextTranslateCTM (context
, 0, -port_height
);
996 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
997 err
= ATSUSetLayoutControls (text_layout
,
998 sizeof (tags
) / sizeof (tags
[0]),
999 tags
, sizes
, values
);
1002 ATSUDrawText (text_layout
,
1003 kATSUFromTextBeginning
, kATSUToTextEnd
,
1004 Long2Fix (x
), Long2Fix (port_height
- y
));
1006 ATSUDrawText (text_layout
,
1007 kATSUFromTextBeginning
, kATSUToTextEnd
,
1008 Long2Fix (x
+ 1), Long2Fix (port_height
- y
));
1011 mac_end_cg_clip (f
);
1014 CGContextSynchronize (context
);
1015 QDEndCGContext (port
, &context
);
1018 /* This doesn't work on Mac OS X 10.1. */
1019 ATSUClearLayoutControls (text_layout
,
1020 sizeof (tags
) / sizeof (tags
[0]), tags
);
1022 ATSUSetLayoutControls (text_layout
,
1023 sizeof (tags
) / sizeof (tags
[0]),
1024 tags
, sizes
, values
);
1027 #endif /* MAC_OSX */
1030 #endif /* USE_ATSUI */
1032 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1035 if (mac_use_core_graphics
)
1036 savedFlags
= SwapQDTextFlags (kQDUseCGTextRendering
);
1039 mac_prepare_for_quickdraw (f
);
1041 mac_begin_clip (gc
);
1042 RGBForeColor (GC_FORE_COLOR (gc
));
1046 RGBBackColor (GC_BACK_COLOR (gc
));
1052 /* We prefer not to use srcCopy text transfer mode on Mac OS X
1054 - Screen is double-buffered. (In srcCopy mode, a text is
1055 drawn into an offscreen graphics world first. So
1056 performance gain cannot be expected.)
1057 - It lowers rendering quality.
1058 - Some fonts leave garbage on cursor movement. */
1063 RGBBackColor (GC_BACK_COLOR (gc
));
1064 SetRect (&r
, x
, y
- FONT_BASE (GC_FONT (gc
)),
1065 x
+ bg_width
, y
+ FONT_DESCENT (GC_FONT (gc
)));
1070 TextFont (GC_FONT (gc
)->mac_fontnum
);
1071 TextSize (GC_FONT (gc
)->mac_fontsize
);
1072 TextFace (GC_FONT (gc
)->mac_fontface
);
1074 DrawText (buf
, 0, nchars
* bytes_per_char
);
1079 DrawText (buf
, 0, nchars
* bytes_per_char
);
1082 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1085 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1086 if (mac_use_core_graphics
)
1087 SwapQDTextFlags(savedFlags
);
1093 /* Mac replacement for XDrawImageString. */
1096 mac_draw_image_string (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1101 int nchars
, bg_width
, overstrike_p
;
1103 mac_draw_string_common (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
1108 /* Mac replacement for XDrawImageString16. */
1111 mac_draw_image_string_16 (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1116 int nchars
, bg_width
, overstrike_p
;
1118 mac_draw_string_common (f
, gc
, x
, y
, (char *) buf
, nchars
, bg_width
,
1123 /* Mac replacement for XQueryTextExtents, but takes a character. If
1124 STYLE is NULL, measurement is done by QuickDraw Text routines for
1125 the font of the current graphics port. If CG_GLYPH is not NULL,
1126 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
1129 mac_query_char_extents (style
, c
,
1130 font_ascent_return
, font_descent_return
,
1131 overall_return
, cg_glyph
)
1138 int *font_ascent_return
, *font_descent_return
;
1139 XCharStruct
*overall_return
;
1140 #if USE_CG_TEXT_DRAWING
1146 OSStatus err
= noErr
;
1153 ATSUTextLayout text_layout
;
1156 err
= atsu_get_text_layout_with_text_ptr (&ch
, 1, style
, &text_layout
);
1159 ATSTrapezoid glyph_bounds
;
1161 err
= ATSUGetGlyphBounds (text_layout
, 0, 0,
1162 kATSUFromTextBeginning
, kATSUToTextEnd
,
1163 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1164 kATSUseFractionalOrigins
,
1166 kATSUseDeviceOrigins
,
1168 1, &glyph_bounds
, NULL
);
1171 xassert (glyph_bounds
.lowerRight
.x
- glyph_bounds
.lowerLeft
.x
1172 == glyph_bounds
.upperRight
.x
- glyph_bounds
.upperLeft
.x
);
1174 width
= Fix2Long (glyph_bounds
.upperRight
.x
1175 - glyph_bounds
.upperLeft
.x
);
1176 if (font_ascent_return
)
1177 *font_ascent_return
= -Fix2Long (glyph_bounds
.upperLeft
.y
);
1178 if (font_descent_return
)
1179 *font_descent_return
= Fix2Long (glyph_bounds
.lowerLeft
.y
);
1182 if (err
== noErr
&& overall_return
)
1184 err
= ATSUMeasureTextImage (text_layout
,
1185 kATSUFromTextBeginning
, kATSUToTextEnd
,
1186 0, 0, &char_bounds
);
1188 STORE_XCHARSTRUCT (*overall_return
, width
, char_bounds
);
1189 #if USE_CG_TEXT_DRAWING
1190 if (err
== noErr
&& cg_glyph
)
1193 ATSUGlyphInfoArray glyph_info_array
;
1194 ByteCount count
= sizeof (ATSUGlyphInfoArray
);
1196 err1
= ATSUMatchFontsToText (text_layout
, kATSUFromTextBeginning
,
1197 kATSUToTextEnd
, NULL
, NULL
, NULL
);
1199 err1
= ATSUGetGlyphInfo (text_layout
, kATSUFromTextBeginning
,
1200 kATSUToTextEnd
, &count
,
1203 /* Make sure that we don't have to make layout
1205 && glyph_info_array
.glyphs
[0].deltaY
== 0.0f
1206 && glyph_info_array
.glyphs
[0].idealX
== 0.0f
1207 && glyph_info_array
.glyphs
[0].screenX
== 0)
1209 xassert (glyph_info_array
.glyphs
[0].glyphID
);
1210 *cg_glyph
= glyph_info_array
.glyphs
[0].glyphID
;
1221 if (font_ascent_return
|| font_descent_return
)
1225 GetFontInfo (&font_info
);
1226 if (font_ascent_return
)
1227 *font_ascent_return
= font_info
.ascent
;
1228 if (font_descent_return
)
1229 *font_descent_return
= font_info
.descent
;
1235 width
= CharWidth (ch
);
1236 QDTextBounds (1, &ch
, &char_bounds
);
1237 STORE_XCHARSTRUCT (*overall_return
, width
, char_bounds
);
1245 /* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
1248 mac_text_extents_16 (font_struct
, string
, nchars
, overall_return
)
1249 XFontStruct
*font_struct
;
1252 XCharStruct
*overall_return
;
1255 short width
= 0, lbearing
= 0, rbearing
= 0;
1258 for (i
= 0; i
< nchars
; i
++)
1260 pcm
= mac_per_char_metric (font_struct
, string
, 0);
1262 width
+= FONT_WIDTH (font_struct
);
1265 lbearing
= min (lbearing
, width
+ pcm
->lbearing
);
1266 rbearing
= max (rbearing
, width
+ pcm
->rbearing
);
1267 width
+= pcm
->width
;
1272 overall_return
->lbearing
= lbearing
;
1273 overall_return
->rbearing
= rbearing
;
1274 overall_return
->width
= width
;
1276 /* What's the meaning of the return value of XTextExtents16? */
1280 #if USE_CG_TEXT_DRAWING
1281 static int cg_text_anti_aliasing_threshold
= 8;
1284 init_cg_text_anti_aliasing_threshold ()
1290 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
1291 kCFPreferencesCurrentApplication
,
1294 cg_text_anti_aliasing_threshold
= threshold
;
1298 mac_draw_image_string_cg (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1303 int nchars
, bg_width
, overstrike_p
;
1306 float port_height
, gx
, gy
;
1308 CGContextRef context
;
1312 if (!mac_use_core_graphics
|| GC_FONT (gc
)->cg_font
== NULL
)
1315 port
= GetWindowPort (FRAME_MAC_WINDOW (f
));
1316 port_height
= FRAME_PIXEL_HEIGHT (f
);
1318 gy
= port_height
- y
;
1319 glyphs
= (CGGlyph
*)buf
;
1320 advances
= alloca (sizeof (CGSize
) * nchars
);
1321 if (advances
== NULL
)
1323 for (i
= 0; i
< nchars
; i
++)
1325 XCharStruct
*pcm
= mac_per_char_metric (GC_FONT (gc
), buf
, 0);
1327 advances
[i
].width
= pcm
->width
;
1328 advances
[i
].height
= 0;
1329 glyphs
[i
] = GC_FONT (gc
)->cg_glyphs
[buf
->byte2
];
1334 context
= mac_begin_cg_clip (f
, gc
);
1336 QDBeginCGContext (port
, &context
);
1337 if (gc
->n_clip_rects
|| bg_width
)
1339 CGContextTranslateCTM (context
, 0, port_height
);
1340 CGContextScaleCTM (context
, 1, -1);
1341 if (gc
->n_clip_rects
)
1342 CGContextClipToRects (context
, gc
->clip_rects
, gc
->n_clip_rects
);
1346 CG_SET_FILL_COLOR (context
, gc
->xgcv
.background
);
1349 CGRectMake (gx
, y
- FONT_BASE (GC_FONT (gc
)),
1350 bg_width
, FONT_HEIGHT (GC_FONT (gc
))));
1352 CGContextScaleCTM (context
, 1, -1);
1353 CGContextTranslateCTM (context
, 0, -port_height
);
1357 CG_SET_FILL_COLOR (context
, gc
->xgcv
.foreground
);
1358 CGContextSetFont (context
, GC_FONT (gc
)->cg_font
);
1359 CGContextSetFontSize (context
, GC_FONT (gc
)->mac_fontsize
);
1360 if (GC_FONT (gc
)->mac_fontsize
<= cg_text_anti_aliasing_threshold
)
1361 CGContextSetShouldAntialias (context
, false);
1362 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1363 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1364 if (CGContextShowGlyphsWithAdvances
!= NULL
)
1367 CGContextSetTextPosition (context
, gx
, gy
);
1368 CGContextShowGlyphsWithAdvances (context
, glyphs
, advances
, nchars
);
1371 CGContextSetTextPosition (context
, gx
+ 1.0f
, gy
);
1372 CGContextShowGlyphsWithAdvances (context
, glyphs
, advances
, nchars
);
1375 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1378 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
1379 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1381 for (i
= 0; i
< nchars
; i
++)
1383 CGContextShowGlyphsAtPoint (context
, gx
, gy
, glyphs
+ i
, 1);
1385 CGContextShowGlyphsAtPoint (context
, gx
+ 1.0f
, gy
, glyphs
+ i
, 1);
1386 gx
+= advances
[i
].width
;
1391 mac_end_cg_clip (f
);
1393 CGContextSynchronize (context
);
1394 QDEndCGContext (port
, &context
);
1403 /* Mac replacement for XCopyArea: dest must be window. */
1406 mac_copy_area (src
, f
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1411 unsigned int width
, height
;
1416 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1418 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1419 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1421 ForeColor (blackColor
);
1422 BackColor (whiteColor
);
1424 mac_begin_clip (gc
);
1425 LockPixels (GetGWorldPixMap (src
));
1426 #if TARGET_API_MAC_CARBON
1431 LockPortBits (port
);
1432 CopyBits (GetPortBitMapForCopyBits (src
),
1433 GetPortBitMapForCopyBits (port
),
1434 &src_r
, &dest_r
, srcCopy
, 0);
1435 UnlockPortBits (port
);
1437 #else /* not TARGET_API_MAC_CARBON */
1438 CopyBits (&(((GrafPtr
)src
)->portBits
), &(FRAME_MAC_WINDOW (f
)->portBits
),
1439 &src_r
, &dest_r
, srcCopy
, 0);
1440 #endif /* not TARGET_API_MAC_CARBON */
1441 UnlockPixels (GetGWorldPixMap (src
));
1444 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1449 mac_copy_area_with_mask (src
, mask
, f
, gc
, src_x
, src_y
,
1450 width
, height
, dest_x
, dest_y
)
1455 unsigned int width
, height
;
1460 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1462 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1463 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1465 ForeColor (blackColor
);
1466 BackColor (whiteColor
);
1468 mac_begin_clip (gc
);
1469 LockPixels (GetGWorldPixMap (src
));
1470 LockPixels (GetGWorldPixMap (mask
));
1471 #if TARGET_API_MAC_CARBON
1476 LockPortBits (port
);
1477 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1478 GetPortBitMapForCopyBits (port
),
1479 &src_r
, &src_r
, &dest_r
);
1480 UnlockPortBits (port
);
1482 #else /* not TARGET_API_MAC_CARBON */
1483 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1484 &(FRAME_MAC_WINDOW (f
)->portBits
), &src_r
, &src_r
, &dest_r
);
1485 #endif /* not TARGET_API_MAC_CARBON */
1486 UnlockPixels (GetGWorldPixMap (mask
));
1487 UnlockPixels (GetGWorldPixMap (src
));
1490 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1492 #endif /* !USE_CG_DRAWING */
1495 /* Mac replacement for XCopyArea: used only for scrolling. */
1498 mac_scroll_area (f
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1502 unsigned int width
, height
;
1505 #if TARGET_API_MAC_CARBON
1507 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
1509 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1511 mac_prepare_for_quickdraw (f
);
1513 ScrollWindowRect (FRAME_MAC_WINDOW (f
),
1514 &src_r
, dest_x
- src_x
, dest_y
- src_y
,
1515 kScrollWindowNoOptions
, dummy
);
1517 #else /* not TARGET_API_MAC_CARBON */
1519 WindowPtr w
= FRAME_MAC_WINDOW (f
);
1523 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1524 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1526 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1527 color mapping in CopyBits. Otherwise, it will be slow. */
1528 ForeColor (blackColor
);
1529 BackColor (whiteColor
);
1530 mac_begin_clip (gc
);
1531 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1534 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1535 #endif /* not TARGET_API_MAC_CARBON */
1539 /* Mac replacement for XChangeGC. */
1542 XChangeGC (display
, gc
, mask
, xgcv
)
1548 if (mask
& GCForeground
)
1549 XSetForeground (display
, gc
, xgcv
->foreground
);
1550 if (mask
& GCBackground
)
1551 XSetBackground (display
, gc
, xgcv
->background
);
1553 XSetFont (display
, gc
, xgcv
->font
);
1557 /* Mac replacement for XCreateGC. */
1560 XCreateGC (display
, window
, mask
, xgcv
)
1566 GC gc
= xmalloc (sizeof (*gc
));
1568 bzero (gc
, sizeof (*gc
));
1569 XChangeGC (display
, gc
, mask
, xgcv
);
1575 /* Used in xfaces.c. */
1578 XFreeGC (display
, gc
)
1582 if (gc
->clip_region
)
1583 DisposeRgn (gc
->clip_region
);
1588 /* Mac replacement for XGetGCValues. */
1591 XGetGCValues (display
, gc
, mask
, xgcv
)
1597 if (mask
& GCForeground
)
1598 xgcv
->foreground
= gc
->xgcv
.foreground
;
1599 if (mask
& GCBackground
)
1600 xgcv
->background
= gc
->xgcv
.background
;
1602 xgcv
->font
= gc
->xgcv
.font
;
1606 /* Mac replacement for XSetForeground. */
1609 XSetForeground (display
, gc
, color
)
1612 unsigned long color
;
1614 if (gc
->xgcv
.foreground
!= color
)
1616 gc
->xgcv
.foreground
= color
;
1617 gc
->fore_color
.red
= RED16_FROM_ULONG (color
);
1618 gc
->fore_color
.green
= GREEN16_FROM_ULONG (color
);
1619 gc
->fore_color
.blue
= BLUE16_FROM_ULONG (color
);
1624 /* Mac replacement for XSetBackground. */
1627 XSetBackground (display
, gc
, color
)
1630 unsigned long color
;
1632 if (gc
->xgcv
.background
!= color
)
1634 gc
->xgcv
.background
= color
;
1635 gc
->back_color
.red
= RED16_FROM_ULONG (color
);
1636 gc
->back_color
.green
= GREEN16_FROM_ULONG (color
);
1637 gc
->back_color
.blue
= BLUE16_FROM_ULONG (color
);
1642 /* Mac replacement for XSetFont. */
1645 XSetFont (display
, gc
, font
)
1650 gc
->xgcv
.font
= font
;
1654 /* Mac replacement for XSetClipRectangles. */
1657 mac_set_clip_rectangles (display
, gc
, rectangles
, n
)
1665 xassert (n
>= 0 && n
<= MAX_CLIP_RECTS
);
1667 gc
->n_clip_rects
= n
;
1670 if (gc
->clip_region
== NULL
)
1671 gc
->clip_region
= NewRgn ();
1672 RectRgn (gc
->clip_region
, rectangles
);
1675 RgnHandle region
= NewRgn ();
1677 for (i
= 1; i
< n
; i
++)
1679 RectRgn (region
, rectangles
+ i
);
1680 UnionRgn (gc
->clip_region
, region
, gc
->clip_region
);
1682 DisposeRgn (region
);
1685 #if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING)
1686 for (i
= 0; i
< n
; i
++)
1688 Rect
*rect
= rectangles
+ i
;
1690 gc
->clip_rects
[i
] = CGRectMake (rect
->left
, rect
->top
,
1691 rect
->right
- rect
->left
,
1692 rect
->bottom
- rect
->top
);
1698 /* Mac replacement for XSetClipMask. */
1701 mac_reset_clip_rectangles (display
, gc
)
1705 gc
->n_clip_rects
= 0;
1709 /* Mac replacement for XSetWindowBackground. */
1712 XSetWindowBackground (display
, w
, color
)
1715 unsigned long color
;
1717 #if !TARGET_API_MAC_CARBON
1718 AuxWinHandle aw_handle
;
1719 CTabHandle ctab_handle
;
1720 ColorSpecPtr ct_table
;
1725 bg_color
.red
= RED16_FROM_ULONG (color
);
1726 bg_color
.green
= GREEN16_FROM_ULONG (color
);
1727 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
1729 #if TARGET_API_MAC_CARBON
1730 SetWindowContentColor (w
, &bg_color
);
1732 if (GetAuxWin (w
, &aw_handle
))
1734 ctab_handle
= (*aw_handle
)->awCTable
;
1735 HandToHand ((Handle
*) &ctab_handle
);
1736 ct_table
= (*ctab_handle
)->ctTable
;
1737 ct_size
= (*ctab_handle
)->ctSize
;
1738 while (ct_size
> -1)
1740 if (ct_table
->value
== 0)
1742 ct_table
->rgb
= bg_color
;
1743 CTabChanged (ctab_handle
);
1744 SetWinColor (w
, (WCTabHandle
) ctab_handle
);
1752 /* Flush display of frame F, or of all frames if F is null. */
1758 #if TARGET_API_MAC_CARBON
1761 mac_prepare_for_quickdraw (f
);
1764 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1766 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1772 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1773 Calls to XFlush should be unnecessary because the X output buffer
1774 is flushed automatically as needed by calls to XPending,
1775 XNextEvent, or XWindowEvent according to the XFlush man page.
1776 XTread_socket calls XPending. Removing XFlush improves
1779 #define XFlush(DISPLAY) (void) 0
1782 /* Return the struct mac_display_info corresponding to DPY. There's
1785 struct mac_display_info
*
1786 mac_display_info_for_display (dpy
)
1789 return &one_mac_display_info
;
1794 /***********************************************************************
1795 Starting and ending an update
1796 ***********************************************************************/
1798 /* Start an update of frame F. This function is installed as a hook
1799 for update_begin, i.e. it is called when update_begin is called.
1800 This function is called prior to calls to x_update_window_begin for
1801 each window being updated. */
1807 #if TARGET_API_MAC_CARBON
1808 /* During update of a frame, availability of input events is
1809 periodically checked with ReceiveNextEvent if
1810 redisplay-dont-pause is nil. That normally flushes window buffer
1811 changes for every check, and thus screen update looks waving even
1812 if no input is available. So we disable screen updates during
1813 update of a frame. */
1815 DisableScreenUpdates ();
1821 /* Start update of window W. Set the global variable updated_window
1822 to the window being updated and set output_cursor to the cursor
1826 x_update_window_begin (w
)
1829 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1830 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1833 set_output_cursor (&w
->cursor
);
1837 if (f
== display_info
->mouse_face_mouse_frame
)
1839 /* Don't do highlighting for mouse motion during the update. */
1840 display_info
->mouse_face_defer
= 1;
1842 /* If F needs to be redrawn, simply forget about any prior mouse
1844 if (FRAME_GARBAGED_P (f
))
1845 display_info
->mouse_face_window
= Qnil
;
1847 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1848 their mouse_face_p flag set, which means that they are always
1849 unequal to rows in a desired matrix which never have that
1850 flag set. So, rows containing mouse-face glyphs are never
1851 scrolled, and we don't have to switch the mouse highlight off
1852 here to prevent it from being scrolled. */
1854 /* Can we tell that this update does not affect the window
1855 where the mouse highlight is? If so, no need to turn off.
1856 Likewise, don't do anything if the frame is garbaged;
1857 in that case, the frame's current matrix that we would use
1858 is all wrong, and we will redisplay that line anyway. */
1859 if (!NILP (display_info
->mouse_face_window
)
1860 && w
== XWINDOW (display_info
->mouse_face_window
))
1864 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1865 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1868 if (i
< w
->desired_matrix
->nrows
)
1869 clear_mouse_face (display_info
);
1878 /* Draw a vertical window border from (x,y0) to (x,y1) */
1881 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1885 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1888 face
= FACE_FROM_ID (f
, VERTICAL_BORDER_FACE_ID
);
1890 XSetForeground (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
1893 mac_draw_line (f
, f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1896 /* End update of window W (which is equal to updated_window).
1898 Draw vertical borders between horizontally adjacent windows, and
1899 display W's cursor if CURSOR_ON_P is non-zero.
1901 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1902 glyphs in mouse-face were overwritten. In that case we have to
1903 make sure that the mouse-highlight is properly redrawn.
1905 W may be a menu bar pseudo-window in case we don't have X toolkit
1906 support. Such windows don't have a cursor, so don't display it
1910 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1912 int cursor_on_p
, mouse_face_overwritten_p
;
1914 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1916 if (!w
->pseudo_window_p
)
1921 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1923 output_cursor
.x
, output_cursor
.y
);
1925 if (draw_window_fringes (w
, 1))
1926 x_draw_vertical_border (w
);
1931 /* If a row with mouse-face was overwritten, arrange for
1932 XTframe_up_to_date to redisplay the mouse highlight. */
1933 if (mouse_face_overwritten_p
)
1935 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1936 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1937 dpyinfo
->mouse_face_window
= Qnil
;
1940 updated_window
= NULL
;
1944 /* End update of frame F. This function is installed as a hook in
1951 /* Mouse highlight may be displayed again. */
1952 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1955 #if TARGET_API_MAC_CARBON
1956 EnableScreenUpdates ();
1958 XFlush (FRAME_MAC_DISPLAY (f
));
1963 /* This function is called from various places in xdisp.c whenever a
1964 complete update has been performed. The global variable
1965 updated_window is not available here. */
1968 XTframe_up_to_date (f
)
1971 if (FRAME_MAC_P (f
))
1973 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1975 if (dpyinfo
->mouse_face_deferred_gc
1976 || f
== dpyinfo
->mouse_face_mouse_frame
)
1979 if (dpyinfo
->mouse_face_mouse_frame
)
1980 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1981 dpyinfo
->mouse_face_mouse_x
,
1982 dpyinfo
->mouse_face_mouse_y
);
1983 dpyinfo
->mouse_face_deferred_gc
= 0;
1990 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1991 arrow bitmaps, or clear the fringes if no bitmaps are required
1992 before DESIRED_ROW is made current. The window being updated is
1993 found in updated_window. This function is called from
1994 update_window_line only if it is known that there are differences
1995 between bitmaps to be drawn between current row and DESIRED_ROW. */
1998 x_after_update_window_line (desired_row
)
1999 struct glyph_row
*desired_row
;
2001 struct window
*w
= updated_window
;
2007 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
2008 desired_row
->redraw_fringe_bitmaps_p
= 1;
2010 /* When a window has disappeared, make sure that no rest of
2011 full-width rows stays visible in the internal border. Could
2012 check here if updated_window is the leftmost/rightmost window,
2013 but I guess it's not worth doing since vertically split windows
2014 are almost never used, internal border is rarely set, and the
2015 overhead is very small. */
2016 if (windows_or_buffers_changed
2017 && desired_row
->full_width_p
2018 && (f
= XFRAME (w
->frame
),
2019 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
2021 && (height
= desired_row
->visible_height
,
2024 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
2026 /* Internal border is drawn below the tool bar. */
2027 if (WINDOWP (f
->tool_bar_window
)
2028 && w
== XWINDOW (f
->tool_bar_window
))
2032 mac_clear_area (f
, 0, y
, width
, height
);
2033 mac_clear_area (f
, FRAME_PIXEL_WIDTH (f
) - width
, y
, width
, height
);
2039 /* Draw the bitmap WHICH in one of the left or right fringes of
2040 window W. ROW is the glyph row for which to display the bitmap; it
2041 determines the vertical position at which the bitmap has to be
2045 x_draw_fringe_bitmap (w
, row
, p
)
2047 struct glyph_row
*row
;
2048 struct draw_fringe_bitmap_params
*p
;
2050 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2051 Display
*display
= FRAME_MAC_DISPLAY (f
);
2052 struct face
*face
= p
->face
;
2055 /* Must clip because of partially visible lines. */
2056 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
2059 /* Adjust position of "bottom aligned" bitmap on partially
2060 visible last row. */
2062 int oldVH
= row
->visible_height
;
2063 row
->visible_height
= p
->h
;
2064 row
->y
-= rowY
- p
->y
;
2065 x_clip_to_row (w
, row
, -1, face
->gc
);
2067 row
->visible_height
= oldVH
;
2070 x_clip_to_row (w
, row
, -1, face
->gc
);
2072 if (p
->bx
>= 0 && !p
->overlay_p
)
2074 #if 0 /* MAC_TODO: stipple */
2075 /* In case the same realized face is used for fringes and
2076 for something displayed in the text (e.g. face `region' on
2077 mono-displays, the fill style may have been changed to
2078 FillSolid in x_draw_glyph_string_background. */
2080 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
2082 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
2085 mac_erase_rectangle (f
, face
->gc
, p
->bx
, p
->by
, p
->nx
, p
->ny
);
2087 #if 0 /* MAC_TODO: stipple */
2089 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
2095 && p
->which
< max_fringe_bmp
2101 XGetGCValues (display
, face
->gc
, GCForeground
, &gcv
);
2102 XSetForeground (display
, face
->gc
,
2104 ? (p
->overlay_p
? face
->background
2105 : f
->output_data
.mac
->cursor_pixel
)
2106 : face
->foreground
));
2108 mac_draw_cg_image (fringe_bmp
[p
->which
], f
, face
->gc
, 0, p
->dh
,
2109 p
->wd
, p
->h
, p
->x
, p
->y
, p
->overlay_p
);
2111 mac_draw_bitmap (f
, face
->gc
, p
->x
, p
->y
,
2112 p
->wd
, p
->h
, p
->bits
+ p
->dh
, p
->overlay_p
);
2114 XSetForeground (display
, face
->gc
, gcv
.foreground
);
2117 mac_reset_clip_rectangles (display
, face
->gc
);
2122 mac_define_fringe_bitmap (which
, bits
, h
, wd
)
2124 unsigned short *bits
;
2128 CGDataProviderRef provider
;
2130 if (which
>= max_fringe_bmp
)
2133 max_fringe_bmp
= which
+ 20;
2134 fringe_bmp
= (CGImageRef
*) xrealloc (fringe_bmp
, max_fringe_bmp
* sizeof (CGImageRef
));
2135 while (i
< max_fringe_bmp
)
2136 fringe_bmp
[i
++] = 0;
2139 for (i
= 0; i
< h
; i
++)
2141 provider
= CGDataProviderCreateWithData (NULL
, bits
,
2142 sizeof (unsigned short) * h
, NULL
);
2145 fringe_bmp
[which
] = CGImageMaskCreate (wd
, h
, 1, 1,
2146 sizeof (unsigned short),
2148 CGDataProviderRelease (provider
);
2153 mac_destroy_fringe_bitmap (which
)
2156 if (which
>= max_fringe_bmp
)
2159 if (fringe_bmp
[which
])
2160 CGImageRelease (fringe_bmp
[which
]);
2161 fringe_bmp
[which
] = 0;
2166 /* This is called when starting Emacs and when restarting after
2167 suspend. When starting Emacs, no window is mapped. And nothing
2168 must be done to Emacs's own window if it is suspended (though that
2172 XTset_terminal_modes ()
2176 /* This is called when exiting or suspending Emacs. Exiting will make
2177 the windows go away, and suspending requires no action. */
2180 XTreset_terminal_modes ()
2186 /***********************************************************************
2188 ***********************************************************************/
2190 /* Function prototypes of this page. */
2192 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
2193 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
2197 pcm_init (pcm
, count
)
2201 bzero (pcm
, sizeof (XCharStruct
) * count
);
2202 while (--count
>= 0)
2204 pcm
->descent
= PCM_INVALID
;
2209 static enum pcm_status
2210 pcm_get_status (pcm
)
2211 const XCharStruct
*pcm
;
2213 int height
= pcm
->ascent
+ pcm
->descent
;
2215 /* Negative height means some special status. */
2216 return height
>= 0 ? PCM_VALID
: height
;
2219 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
2220 is not contained in the font. */
2222 static INLINE XCharStruct
*
2223 x_per_char_metric (font
, char2b
)
2227 /* The result metric information. */
2228 XCharStruct
*pcm
= NULL
;
2230 xassert (font
&& char2b
);
2233 if (font
->mac_style
)
2235 XCharStruct
**row
= font
->bounds
.rows
+ char2b
->byte1
;
2239 *row
= xmalloc (sizeof (XCharStruct
) * 0x100);
2240 pcm_init (*row
, 0x100);
2242 pcm
= *row
+ char2b
->byte2
;
2243 if (pcm_get_status (pcm
) != PCM_VALID
)
2246 mac_query_char_extents (font
->mac_style
,
2247 (char2b
->byte1
<< 8) + char2b
->byte2
,
2248 NULL
, NULL
, pcm
, NULL
);
2255 if (font
->bounds
.per_char
!= NULL
)
2257 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
2259 /* min_char_or_byte2 specifies the linear character index
2260 corresponding to the first element of the per_char array,
2261 max_char_or_byte2 is the index of the last character. A
2262 character with non-zero CHAR2B->byte1 is not in the font.
2263 A character with byte2 less than min_char_or_byte2 or
2264 greater max_char_or_byte2 is not in the font. */
2265 if (char2b
->byte1
== 0
2266 && char2b
->byte2
>= font
->min_char_or_byte2
2267 && char2b
->byte2
<= font
->max_char_or_byte2
)
2268 pcm
= font
->bounds
.per_char
2269 + (char2b
->byte2
- font
->min_char_or_byte2
);
2273 /* If either min_byte1 or max_byte1 are nonzero, both
2274 min_char_or_byte2 and max_char_or_byte2 are less than
2275 256, and the 2-byte character index values corresponding
2276 to the per_char array element N (counting from 0) are:
2278 byte1 = N/D + min_byte1
2279 byte2 = N\D + min_char_or_byte2
2283 D = max_char_or_byte2 - min_char_or_byte2 + 1
2284 / = integer division
2285 \ = integer modulus */
2286 if (char2b
->byte1
>= font
->min_byte1
2287 && char2b
->byte1
<= font
->max_byte1
2288 && char2b
->byte2
>= font
->min_char_or_byte2
2289 && char2b
->byte2
<= font
->max_char_or_byte2
)
2291 pcm
= (font
->bounds
.per_char
2292 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
2293 * (char2b
->byte1
- font
->min_byte1
))
2294 + (char2b
->byte2
- font
->min_char_or_byte2
));
2300 /* If the per_char pointer is null, all glyphs between the first
2301 and last character indexes inclusive have the same
2302 information, as given by both min_bounds and max_bounds. */
2303 if (char2b
->byte2
>= font
->min_char_or_byte2
2304 && char2b
->byte2
<= font
->max_char_or_byte2
)
2305 pcm
= &font
->max_bounds
;
2311 return ((pcm
== NULL
2313 #if 0 /* Show hollow boxes for zero-width glyphs such as combining diacritics. */
2314 && (pcm
->rbearing
- pcm
->lbearing
) == 0
2323 static XCharStruct
*
2324 mac_per_char_metric (font
, char2b
, font_type
)
2329 return x_per_char_metric (font
, char2b
);
2333 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
2334 the two-byte form of C. Encoding is returned in *CHAR2B. */
2337 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
2340 struct font_info
*font_info
;
2343 int charset
= CHAR_CHARSET (c
);
2344 XFontStruct
*font
= font_info
->font
;
2346 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
2347 This may be either a program in a special encoder language or a
2349 if (font_info
->font_encoder
)
2351 /* It's a program. */
2352 struct ccl_program
*ccl
= font_info
->font_encoder
;
2354 check_ccl_update (ccl
);
2355 if (CHARSET_DIMENSION (charset
) == 1)
2357 ccl
->reg
[0] = charset
;
2358 ccl
->reg
[1] = char2b
->byte2
;
2363 ccl
->reg
[0] = charset
;
2364 ccl
->reg
[1] = char2b
->byte1
;
2365 ccl
->reg
[2] = char2b
->byte2
;
2368 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
2370 /* We assume that MSBs are appropriately set/reset by CCL
2372 if (font
->max_byte1
== 0) /* 1-byte font */
2373 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
2375 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
2377 else if (font_info
->encoding
[charset
])
2379 /* Fixed encoding scheme. See fontset.h for the meaning of the
2380 encoding numbers. */
2381 int enc
= font_info
->encoding
[charset
];
2383 if ((enc
== 1 || enc
== 2)
2384 && CHARSET_DIMENSION (charset
) == 2)
2385 char2b
->byte1
|= 0x80;
2387 if (enc
== 1 || enc
== 3)
2388 char2b
->byte2
|= 0x80;
2394 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
2395 char2b
->byte1
= sjis1
;
2396 char2b
->byte2
= sjis2
;
2401 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2403 return FONT_TYPE_UNKNOWN
;
2408 /***********************************************************************
2410 ***********************************************************************/
2414 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2415 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2416 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2418 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2419 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2420 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2421 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2422 static void mac_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2423 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2424 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2425 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2426 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
2427 unsigned long *, double, int));*/
2428 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2429 double, int, unsigned long));
2430 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2431 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2432 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2433 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2434 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2436 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2437 int, int, int, int, int, int,
2439 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2440 int, int, int, Rect
*));
2443 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2447 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2452 struct glyph_string
*s
;
2454 if (s
->font
== FRAME_FONT (s
->f
)
2455 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2456 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2458 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
2461 /* Cursor on non-default face: must merge. */
2465 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
2466 xgcv
.foreground
= s
->face
->background
;
2468 /* If the glyph would be invisible, try a different foreground. */
2469 if (xgcv
.foreground
== xgcv
.background
)
2470 xgcv
.foreground
= s
->face
->foreground
;
2471 if (xgcv
.foreground
== xgcv
.background
)
2472 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
2473 if (xgcv
.foreground
== xgcv
.background
)
2474 xgcv
.foreground
= s
->face
->foreground
;
2476 /* Make sure the cursor is distinct from text in this face. */
2477 if (xgcv
.background
== s
->face
->background
2478 && xgcv
.foreground
== s
->face
->foreground
)
2480 xgcv
.background
= s
->face
->foreground
;
2481 xgcv
.foreground
= s
->face
->background
;
2484 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2485 xgcv
.font
= s
->font
;
2486 mask
= GCForeground
| GCBackground
| GCFont
;
2488 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2489 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2492 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2493 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2495 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2500 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2503 x_set_mouse_face_gc (s
)
2504 struct glyph_string
*s
;
2509 /* What face has to be used last for the mouse face? */
2510 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2511 face
= FACE_FROM_ID (s
->f
, face_id
);
2513 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2515 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2516 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2518 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2519 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2520 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2522 /* If font in this face is same as S->font, use it. */
2523 if (s
->font
== s
->face
->font
)
2524 s
->gc
= s
->face
->gc
;
2527 /* Otherwise construct scratch_cursor_gc with values from FACE
2532 xgcv
.background
= s
->face
->background
;
2533 xgcv
.foreground
= s
->face
->foreground
;
2534 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2535 xgcv
.font
= s
->font
;
2536 mask
= GCForeground
| GCBackground
| GCFont
;
2538 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2539 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2542 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2543 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2545 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2548 xassert (s
->gc
!= 0);
2552 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2553 Faces to use in the mode line have already been computed when the
2554 matrix was built, so there isn't much to do, here. */
2557 x_set_mode_line_face_gc (s
)
2558 struct glyph_string
*s
;
2560 s
->gc
= s
->face
->gc
;
2564 /* Set S->gc of glyph string S for drawing that glyph string. Set
2565 S->stippled_p to a non-zero value if the face of S has a stipple
2569 x_set_glyph_string_gc (s
)
2570 struct glyph_string
*s
;
2572 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2574 if (s
->hl
== DRAW_NORMAL_TEXT
)
2576 s
->gc
= s
->face
->gc
;
2577 s
->stippled_p
= s
->face
->stipple
!= 0;
2579 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2581 x_set_mode_line_face_gc (s
);
2582 s
->stippled_p
= s
->face
->stipple
!= 0;
2584 else if (s
->hl
== DRAW_CURSOR
)
2586 x_set_cursor_gc (s
);
2589 else if (s
->hl
== DRAW_MOUSE_FACE
)
2591 x_set_mouse_face_gc (s
);
2592 s
->stippled_p
= s
->face
->stipple
!= 0;
2594 else if (s
->hl
== DRAW_IMAGE_RAISED
2595 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2597 s
->gc
= s
->face
->gc
;
2598 s
->stippled_p
= s
->face
->stipple
!= 0;
2602 s
->gc
= s
->face
->gc
;
2603 s
->stippled_p
= s
->face
->stipple
!= 0;
2606 /* GC must have been set. */
2607 xassert (s
->gc
!= 0);
2611 /* Set clipping for output of glyph string S. S may be part of a mode
2612 line or menu if we don't have X toolkit support. */
2615 x_set_glyph_string_clipping (s
)
2616 struct glyph_string
*s
;
2618 Rect rects
[MAX_CLIP_RECTS
];
2621 n
= get_glyph_string_clip_rects (s
, rects
, MAX_CLIP_RECTS
);
2622 mac_set_clip_rectangles (s
->display
, s
->gc
, rects
, n
);
2627 Compute left and right overhang of glyph string S. If S is a glyph
2628 string for a composition, assume overhangs don't exist. */
2631 mac_compute_glyph_string_overhangs (s
)
2632 struct glyph_string
*s
;
2634 if (!(s
->cmp
== NULL
2635 && s
->first_glyph
->type
== CHAR_GLYPH
))
2640 || s
->font
->mac_style
2646 mac_text_extents_16 (s
->font
, s
->char2b
, s
->nchars
, &cs
);
2647 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2648 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2653 MacFontStruct
*font
= s
->font
;
2656 mac_prepare_for_quickdraw (s
->f
);
2658 SetPortWindowPort (FRAME_MAC_WINDOW (s
->f
));
2660 TextFont (font
->mac_fontnum
);
2661 TextSize (font
->mac_fontsize
);
2662 TextFace (font
->mac_fontface
);
2664 QDTextBounds (s
->nchars
* 2, (char *)s
->char2b
, &r
);
2666 s
->right_overhang
= r
.right
> s
->width
? r
.right
- s
->width
: 0;
2667 s
->left_overhang
= r
.left
< 0 ? -r
.left
: 0;
2672 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2675 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2676 struct glyph_string
*s
;
2679 mac_erase_rectangle (s
->f
, s
->gc
, x
, y
, w
, h
);
2683 /* Draw the background of glyph_string S. If S->background_filled_p
2684 is non-zero don't draw it. FORCE_P non-zero means draw the
2685 background even if it wouldn't be drawn normally. This is used
2686 when a string preceding S draws into the background of S, or S
2687 contains the first component of a composition. */
2690 x_draw_glyph_string_background (s
, force_p
)
2691 struct glyph_string
*s
;
2694 /* Nothing to do if background has already been drawn or if it
2695 shouldn't be drawn in the first place. */
2696 if (!s
->background_filled_p
)
2698 int box_line_width
= max (s
->face
->box_line_width
, 0);
2700 #if 0 /* MAC_TODO: stipple */
2703 /* Fill background with a stipple pattern. */
2704 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2705 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2706 s
->y
+ box_line_width
,
2707 s
->background_width
,
2708 s
->height
- 2 * box_line_width
);
2709 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2710 s
->background_filled_p
= 1;
2714 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2715 || s
->font_not_found_p
2716 || s
->extends_to_end_of_line_p
2719 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2720 s
->background_width
,
2721 s
->height
- 2 * box_line_width
);
2722 s
->background_filled_p
= 1;
2728 /* Draw the foreground of glyph string S. */
2731 x_draw_glyph_string_foreground (s
)
2732 struct glyph_string
*s
;
2736 /* If first glyph of S has a left box line, start drawing the text
2737 of S to the right of that box line. */
2738 if (s
->face
->box
!= FACE_NO_BOX
2739 && s
->first_glyph
->left_box_line_p
)
2740 x
= s
->x
+ abs (s
->face
->box_line_width
);
2744 /* Draw characters of S as rectangles if S's font could not be
2746 if (s
->font_not_found_p
)
2748 for (i
= 0; i
< s
->nchars
; ++i
)
2750 struct glyph
*g
= s
->first_glyph
+ i
;
2751 mac_draw_rectangle (s
->f
, s
->gc
, x
, s
->y
,
2752 g
->pixel_width
- 1, s
->height
- 1);
2753 x
+= g
->pixel_width
;
2758 char *char1b
= (char *) s
->char2b
;
2759 int boff
= s
->font_info
->baseline_offset
;
2761 if (s
->font_info
->vertical_centering
)
2762 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2764 /* If we can use 8-bit functions, condense S->char2b. */
2767 && GC_FONT (s
->gc
)->mac_style
== NULL
2770 for (i
= 0; i
< s
->nchars
; ++i
)
2771 char1b
[i
] = s
->char2b
[i
].byte2
;
2773 /* Draw text with XDrawString if background has already been
2774 filled. Otherwise, use XDrawImageString. (Note that
2775 XDrawImageString is usually faster than XDrawString.) Always
2776 use XDrawImageString when drawing the cursor so that there is
2777 no chance that characters under a box cursor are invisible. */
2779 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2780 bg_width
= 0; /* Corresponds to XDrawString. */
2782 bg_width
= s
->background_width
; /* Corresponds to XDrawImageString. */
2786 || GC_FONT (s
->gc
)->mac_style
2789 #if USE_CG_TEXT_DRAWING
2791 && mac_draw_image_string_cg (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2792 s
->char2b
, s
->nchars
, bg_width
,
2793 s
->face
->overstrike
))
2797 mac_draw_image_string_16 (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2798 s
->char2b
, s
->nchars
, bg_width
,
2799 s
->face
->overstrike
);
2801 mac_draw_image_string (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2802 char1b
, s
->nchars
, bg_width
,
2803 s
->face
->overstrike
);
2807 /* Draw the foreground of composite glyph string S. */
2810 x_draw_composite_glyph_string_foreground (s
)
2811 struct glyph_string
*s
;
2815 /* If first glyph of S has a left box line, start drawing the text
2816 of S to the right of that box line. */
2817 if (s
->face
->box
!= FACE_NO_BOX
2818 && s
->first_glyph
->left_box_line_p
)
2819 x
= s
->x
+ abs (s
->face
->box_line_width
);
2823 /* S is a glyph string for a composition. S->gidx is the index of
2824 the first character drawn for glyphs of this composition.
2825 S->gidx == 0 means we are drawing the very first character of
2826 this composition. */
2828 /* Draw a rectangle for the composition if the font for the very
2829 first character of the composition could not be loaded. */
2830 if (s
->font_not_found_p
)
2833 mac_draw_rectangle (s
->f
, s
->gc
, x
, s
->y
,
2834 s
->width
- 1, s
->height
- 1);
2838 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2839 mac_draw_image_string_16 (s
->f
, s
->gc
,
2840 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2841 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2842 s
->char2b
+ i
, 1, 0, s
->face
->overstrike
);
2847 #ifdef USE_X_TOOLKIT
2849 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2852 /* Return the frame on which widget WIDGET is used.. Abort if frame
2853 cannot be determined. */
2855 static struct frame
*
2856 x_frame_of_widget (widget
)
2859 struct x_display_info
*dpyinfo
;
2863 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2865 /* Find the top-level shell of the widget. Note that this function
2866 can be called when the widget is not yet realized, so XtWindow
2867 (widget) == 0. That's the reason we can't simply use
2868 x_any_window_to_frame. */
2869 while (!XtIsTopLevelShell (widget
))
2870 widget
= XtParent (widget
);
2872 /* Look for a frame with that top-level widget. Allocate the color
2873 on that frame to get the right gamma correction value. */
2874 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2875 if (GC_FRAMEP (XCAR (tail
))
2876 && (f
= XFRAME (XCAR (tail
)),
2877 (f
->output_data
.nothing
!= 1
2878 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2879 && f
->output_data
.x
->widget
== widget
)
2886 /* Allocate the color COLOR->pixel on the screen and display of
2887 widget WIDGET in colormap CMAP. If an exact match cannot be
2888 allocated, try the nearest color available. Value is non-zero
2889 if successful. This is called from lwlib. */
2892 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2897 struct frame
*f
= x_frame_of_widget (widget
);
2898 return x_alloc_nearest_color (f
, cmap
, color
);
2902 #endif /* USE_X_TOOLKIT */
2904 #if 0 /* MAC_TODO */
2906 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2907 CMAP. If an exact match can't be allocated, try the nearest color
2908 available. Value is non-zero if successful. Set *COLOR to the
2912 x_alloc_nearest_color (f
, cmap
, color
)
2917 Display
*display
= FRAME_X_DISPLAY (f
);
2918 Screen
*screen
= FRAME_X_SCREEN (f
);
2921 gamma_correct (f
, color
);
2922 rc
= XAllocColor (display
, cmap
, color
);
2925 /* If we got to this point, the colormap is full, so we're going
2926 to try to get the next closest color. The algorithm used is
2927 a least-squares matching, which is what X uses for closest
2928 color matching with StaticColor visuals. */
2930 unsigned long nearest_delta
= ~0;
2931 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2932 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2934 for (i
= 0; i
< ncells
; ++i
)
2936 XQueryColors (display
, cmap
, cells
, ncells
);
2938 for (nearest
= i
= 0; i
< ncells
; ++i
)
2940 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2941 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2942 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2943 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2945 if (delta
< nearest_delta
)
2948 nearest_delta
= delta
;
2952 color
->red
= cells
[nearest
].red
;
2953 color
->green
= cells
[nearest
].green
;
2954 color
->blue
= cells
[nearest
].blue
;
2955 rc
= XAllocColor (display
, cmap
, color
);
2958 #ifdef DEBUG_X_COLORS
2960 register_color (color
->pixel
);
2961 #endif /* DEBUG_X_COLORS */
2967 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2968 It's necessary to do this instead of just using PIXEL directly to
2969 get color reference counts right. */
2972 x_copy_color (f
, pixel
)
2974 unsigned long pixel
;
2978 color
.pixel
= pixel
;
2980 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2981 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2983 #ifdef DEBUG_X_COLORS
2984 register_color (pixel
);
2990 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2991 It's necessary to do this instead of just using PIXEL directly to
2992 get color reference counts right. */
2995 x_copy_dpy_color (dpy
, cmap
, pixel
)
2998 unsigned long pixel
;
3002 color
.pixel
= pixel
;
3004 XQueryColor (dpy
, cmap
, &color
);
3005 XAllocColor (dpy
, cmap
, &color
);
3007 #ifdef DEBUG_X_COLORS
3008 register_color (pixel
);
3013 #endif /* MAC_TODO */
3016 /* Brightness beyond which a color won't have its highlight brightness
3019 Nominally, highlight colors for `3d' faces are calculated by
3020 brightening an object's color by a constant scale factor, but this
3021 doesn't yield good results for dark colors, so for colors who's
3022 brightness is less than this value (on a scale of 0-255) have to
3023 use an additional additive factor.
3025 The value here is set so that the default menu-bar/mode-line color
3026 (grey75) will not have its highlights changed at all. */
3027 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3030 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3031 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3032 If this produces the same color as COLOR, try a color where all RGB
3033 values have DELTA added. Return the allocated color in *COLOR.
3034 DISPLAY is the X display, CMAP is the colormap to operate on.
3035 Value is non-zero if successful. */
3038 mac_alloc_lighter_color (f
, color
, factor
, delta
)
3040 unsigned long *color
;
3047 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
3050 /* Change RGB values by specified FACTOR. Avoid overflow! */
3051 xassert (factor
>= 0);
3052 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
3053 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
3054 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
3056 /* Calculate brightness of COLOR. */
3057 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
3058 + BLUE_FROM_ULONG (*color
)) / 6;
3060 /* We only boost colors that are darker than
3061 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3062 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3063 /* Make an additive adjustment to NEW, because it's dark enough so
3064 that scaling by FACTOR alone isn't enough. */
3066 /* How far below the limit this color is (0 - 1, 1 being darker). */
3067 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3068 /* The additive adjustment. */
3069 int min_delta
= delta
* dimness
* factor
/ 2;
3072 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
3073 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
3074 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
3076 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
3077 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
3078 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
3082 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
3083 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
3084 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
3086 /* MAC_TODO: Map to palette and retry with delta if same? */
3087 /* MAC_TODO: Free colors (if using palette)? */
3098 /* Set up the foreground color for drawing relief lines of glyph
3099 string S. RELIEF is a pointer to a struct relief containing the GC
3100 with which lines will be drawn. Use a color that is FACTOR or
3101 DELTA lighter or darker than the relief's background which is found
3102 in S->f->output_data.x->relief_background. If such a color cannot
3103 be allocated, use DEFAULT_PIXEL, instead. */
3106 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3108 struct relief
*relief
;
3111 unsigned long default_pixel
;
3114 struct mac_output
*di
= f
->output_data
.mac
;
3115 unsigned long mask
= GCForeground
;
3116 unsigned long pixel
;
3117 unsigned long background
= di
->relief_background
;
3118 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
3120 /* MAC_TODO: Free colors (if using palette)? */
3122 /* Allocate new color. */
3123 xgcv
.foreground
= default_pixel
;
3125 if (dpyinfo
->n_planes
!= 1
3126 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3128 relief
->allocated_p
= 1;
3129 xgcv
.foreground
= relief
->pixel
= pixel
;
3132 if (relief
->gc
== 0)
3134 #if 0 /* MAC_TODO: stipple */
3135 xgcv
.stipple
= dpyinfo
->gray
;
3138 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
3141 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3145 /* Set up colors for the relief lines around glyph string S. */
3148 x_setup_relief_colors (s
)
3149 struct glyph_string
*s
;
3151 struct mac_output
*di
= s
->f
->output_data
.mac
;
3152 unsigned long color
;
3154 if (s
->face
->use_box_color_for_shadows_p
)
3155 color
= s
->face
->box_color
;
3156 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3158 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3159 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3164 /* Get the background color of the face. */
3165 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3166 color
= xgcv
.background
;
3169 if (di
->white_relief
.gc
== 0
3170 || color
!= di
->relief_background
)
3172 di
->relief_background
= color
;
3173 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3174 WHITE_PIX_DEFAULT (s
->f
));
3175 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3176 BLACK_PIX_DEFAULT (s
->f
));
3181 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3182 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3183 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3184 relief. LEFT_P non-zero means draw a relief on the left side of
3185 the rectangle. RIGHT_P non-zero means draw a relief on the right
3186 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3190 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3191 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
3193 int left_x
, top_y
, right_x
, bottom_y
, width
;
3194 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
3197 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
3202 gc
= f
->output_data
.mac
->white_relief
.gc
;
3204 gc
= f
->output_data
.mac
->black_relief
.gc
;
3205 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
3209 for (i
= 0; i
< width
; ++i
)
3210 mac_draw_line (f
, gc
,
3211 left_x
+ i
* left_p
, top_y
+ i
,
3212 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3216 for (i
= 0; i
< width
; ++i
)
3217 mac_draw_line (f
, gc
,
3218 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3220 mac_reset_clip_rectangles (dpy
, gc
);
3222 gc
= f
->output_data
.mac
->black_relief
.gc
;
3224 gc
= f
->output_data
.mac
->white_relief
.gc
;
3225 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
3229 for (i
= 0; i
< width
; ++i
)
3230 mac_draw_line (f
, gc
,
3231 left_x
+ i
* left_p
, bottom_y
- i
,
3232 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3236 for (i
= 0; i
< width
; ++i
)
3237 mac_draw_line (f
, gc
,
3238 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3240 mac_reset_clip_rectangles (dpy
, gc
);
3244 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3245 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3246 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3247 left side of the rectangle. RIGHT_P non-zero means draw a line
3248 on the right side of the rectangle. CLIP_RECT is the clipping
3249 rectangle to use when drawing. */
3252 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3253 left_p
, right_p
, clip_rect
)
3254 struct glyph_string
*s
;
3255 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3260 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3261 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3262 mac_set_clip_rectangles (s
->display
, s
->gc
, clip_rect
, 1);
3265 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, top_y
,
3266 right_x
- left_x
+ 1, width
);
3270 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, top_y
,
3271 width
, bottom_y
- top_y
+ 1);
3274 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, bottom_y
- width
+ 1,
3275 right_x
- left_x
+ 1, width
);
3279 mac_fill_rectangle (s
->f
, s
->gc
, right_x
- width
+ 1,
3280 top_y
, width
, bottom_y
- top_y
+ 1);
3282 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3283 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3287 /* Draw a box around glyph string S. */
3290 x_draw_glyph_string_box (s
)
3291 struct glyph_string
*s
;
3293 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3294 int left_p
, right_p
;
3295 struct glyph
*last_glyph
;
3298 last_x
= ((s
->row
->full_width_p
&& !s
->w
->pseudo_window_p
)
3299 ? WINDOW_RIGHT_EDGE_X (s
->w
)
3300 : window_box_right (s
->w
, s
->area
));
3302 /* The glyph that may have a right box line. */
3303 last_glyph
= (s
->cmp
|| s
->img
3305 : s
->first_glyph
+ s
->nchars
- 1);
3307 width
= abs (s
->face
->box_line_width
);
3308 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3310 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3312 : min (last_x
, s
->x
+ s
->background_width
) - 1);
3314 bottom_y
= top_y
+ s
->height
- 1;
3316 left_p
= (s
->first_glyph
->left_box_line_p
3317 || (s
->hl
== DRAW_MOUSE_FACE
3319 || s
->prev
->hl
!= s
->hl
)));
3320 right_p
= (last_glyph
->right_box_line_p
3321 || (s
->hl
== DRAW_MOUSE_FACE
3323 || s
->next
->hl
!= s
->hl
)));
3325 get_glyph_string_clip_rect (s
, &clip_rect
);
3327 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3328 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3329 left_p
, right_p
, &clip_rect
);
3332 x_setup_relief_colors (s
);
3333 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3334 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
3339 /* Draw foreground of image glyph string S. */
3342 x_draw_image_foreground (s
)
3343 struct glyph_string
*s
;
3346 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3348 /* If first glyph of S has a left box line, start drawing it to the
3349 right of that line. */
3350 if (s
->face
->box
!= FACE_NO_BOX
3351 && s
->first_glyph
->left_box_line_p
3353 x
+= abs (s
->face
->box_line_width
);
3355 /* If there is a margin around the image, adjust x- and y-position
3357 if (s
->slice
.x
== 0)
3358 x
+= s
->img
->hmargin
;
3359 if (s
->slice
.y
== 0)
3360 y
+= s
->img
->vmargin
;
3364 x_set_glyph_string_clipping (s
);
3367 mac_draw_cg_image (s
->img
->data
.ptr_val
,
3368 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3369 s
->slice
.width
, s
->slice
.height
, x
, y
, 1);
3373 mac_copy_area_with_mask (s
->img
->pixmap
, s
->img
->mask
,
3374 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3375 s
->slice
.width
, s
->slice
.height
, x
, y
);
3382 mac_copy_area (s
->img
->pixmap
,
3383 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3384 s
->slice
.width
, s
->slice
.height
, x
, y
);
3387 /* When the image has a mask, we can expect that at
3388 least part of a mouse highlight or a block cursor will
3389 be visible. If the image doesn't have a mask, make
3390 a block cursor visible by drawing a rectangle around
3391 the image. I believe it's looking better if we do
3392 nothing here for mouse-face. */
3393 if (s
->hl
== DRAW_CURSOR
)
3395 int r
= s
->img
->relief
;
3397 mac_draw_rectangle (s
->f
, s
->gc
, x
- r
, y
- r
,
3398 s
->slice
.width
+ r
*2 - 1,
3399 s
->slice
.height
+ r
*2 - 1);
3404 /* Draw a rectangle if image could not be loaded. */
3405 mac_draw_rectangle (s
->f
, s
->gc
, x
, y
,
3406 s
->slice
.width
- 1, s
->slice
.height
- 1);
3410 /* Draw a relief around the image glyph string S. */
3413 x_draw_image_relief (s
)
3414 struct glyph_string
*s
;
3416 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3419 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3421 /* If first glyph of S has a left box line, start drawing it to the
3422 right of that line. */
3423 if (s
->face
->box
!= FACE_NO_BOX
3424 && s
->first_glyph
->left_box_line_p
3426 x
+= abs (s
->face
->box_line_width
);
3428 /* If there is a margin around the image, adjust x- and y-position
3430 if (s
->slice
.x
== 0)
3431 x
+= s
->img
->hmargin
;
3432 if (s
->slice
.y
== 0)
3433 y
+= s
->img
->vmargin
;
3435 if (s
->hl
== DRAW_IMAGE_SUNKEN
3436 || s
->hl
== DRAW_IMAGE_RAISED
)
3438 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
3439 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3443 thick
= abs (s
->img
->relief
);
3444 raised_p
= s
->img
->relief
> 0;
3449 x1
= x
+ s
->slice
.width
+ thick
- 1;
3450 y1
= y
+ s
->slice
.height
+ thick
- 1;
3452 x_setup_relief_colors (s
);
3453 get_glyph_string_clip_rect (s
, &r
);
3454 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
3456 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
3458 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
3463 /* Draw part of the background of glyph string S. X, Y, W, and H
3464 give the rectangle to draw. */
3467 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3468 struct glyph_string
*s
;
3471 #if 0 /* MAC_TODO: stipple */
3474 /* Fill background with a stipple pattern. */
3475 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3476 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3477 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3480 #endif /* MAC_TODO */
3481 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3485 /* Draw image glyph string S.
3488 s->x +-------------------------
3491 | +-------------------------
3494 | | +-------------------
3500 x_draw_image_glyph_string (s
)
3501 struct glyph_string
*s
;
3504 int box_line_hwidth
= abs (s
->face
->box_line_width
);
3505 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
3508 height
= s
->height
- 2 * box_line_vwidth
;
3511 /* Fill background with face under the image. Do it only if row is
3512 taller than image or if image has a clip mask to reduce
3514 s
->stippled_p
= s
->face
->stipple
!= 0;
3515 if (height
> s
->slice
.height
3519 || s
->img
->pixmap
== 0
3520 || s
->width
!= s
->background_width
)
3523 if (s
->first_glyph
->left_box_line_p
3525 x
+= box_line_hwidth
;
3528 if (s
->slice
.y
== 0)
3529 y
+= box_line_vwidth
;
3531 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3533 s
->background_filled_p
= 1;
3536 /* Draw the foreground. */
3537 x_draw_image_foreground (s
);
3539 /* If we must draw a relief around the image, do it. */
3541 || s
->hl
== DRAW_IMAGE_RAISED
3542 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3543 x_draw_image_relief (s
);
3547 /* Draw stretch glyph string S. */
3550 x_draw_stretch_glyph_string (s
)
3551 struct glyph_string
*s
;
3553 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3554 s
->stippled_p
= s
->face
->stipple
!= 0;
3556 if (s
->hl
== DRAW_CURSOR
3557 && !x_stretch_cursor_p
)
3559 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3560 as wide as the stretch glyph. */
3561 int width
, background_width
= s
->background_width
;
3562 int x
= s
->x
, left_x
= window_box_left_offset (s
->w
, TEXT_AREA
);
3566 background_width
-= left_x
- x
;
3569 width
= min (FRAME_COLUMN_WIDTH (s
->f
), background_width
);
3572 x_draw_glyph_string_bg_rect (s
, x
, s
->y
, width
, s
->height
);
3574 /* Clear rest using the GC of the original non-cursor face. */
3575 if (width
< background_width
)
3578 int w
= background_width
- width
, h
= s
->height
;
3583 if (s
->row
->mouse_face_p
3584 && cursor_in_mouse_face_p (s
->w
))
3586 x_set_mouse_face_gc (s
);
3592 get_glyph_string_clip_rect (s
, &r
);
3593 mac_set_clip_rectangles (s
->display
, gc
, &r
, 1);
3595 #if 0 /* MAC_TODO: stipple */
3596 if (s
->face
->stipple
)
3598 /* Fill background with a stipple pattern. */
3599 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3600 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3601 XSetFillStyle (s
->display
, gc
, FillSolid
);
3604 #endif /* MAC_TODO */
3605 mac_erase_rectangle (s
->f
, gc
, x
, y
, w
, h
);
3608 else if (!s
->background_filled_p
)
3610 int background_width
= s
->background_width
;
3611 int x
= s
->x
, left_x
= window_box_left_offset (s
->w
, TEXT_AREA
);
3613 /* Don't draw into left margin, fringe or scrollbar area
3614 except for header line and mode line. */
3615 if (x
< left_x
&& !s
->row
->mode_line_p
)
3617 background_width
-= left_x
- x
;
3620 if (background_width
> 0)
3621 x_draw_glyph_string_bg_rect (s
, x
, s
->y
, background_width
, s
->height
);
3624 s
->background_filled_p
= 1;
3628 /* Draw glyph string S. */
3631 x_draw_glyph_string (s
)
3632 struct glyph_string
*s
;
3634 int relief_drawn_p
= 0;
3636 /* If S draws into the background of its successor that does not
3637 draw a cursor, draw the background of the successor first so that
3638 S can draw into it. This makes S->next use XDrawString instead
3639 of XDrawImageString. */
3640 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps
3641 && s
->next
->hl
!= DRAW_CURSOR
)
3643 xassert (s
->next
->img
== NULL
);
3644 x_set_glyph_string_gc (s
->next
);
3645 x_set_glyph_string_clipping (s
->next
);
3646 x_draw_glyph_string_background (s
->next
, 1);
3649 /* Set up S->gc, set clipping and draw S. */
3650 x_set_glyph_string_gc (s
);
3652 /* Draw relief (if any) in advance for char/composition so that the
3653 glyph string can be drawn over it. */
3654 if (!s
->for_overlaps
3655 && s
->face
->box
!= FACE_NO_BOX
3656 && (s
->first_glyph
->type
== CHAR_GLYPH
3657 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3660 x_set_glyph_string_clipping (s
);
3661 x_draw_glyph_string_background (s
, 1);
3662 x_draw_glyph_string_box (s
);
3663 x_set_glyph_string_clipping (s
);
3667 x_set_glyph_string_clipping (s
);
3669 switch (s
->first_glyph
->type
)
3672 x_draw_image_glyph_string (s
);
3676 x_draw_stretch_glyph_string (s
);
3680 if (s
->for_overlaps
)
3681 s
->background_filled_p
= 1;
3683 x_draw_glyph_string_background (s
, 0);
3684 x_draw_glyph_string_foreground (s
);
3687 case COMPOSITE_GLYPH
:
3688 if (s
->for_overlaps
|| s
->gidx
> 0)
3689 s
->background_filled_p
= 1;
3691 x_draw_glyph_string_background (s
, 1);
3692 x_draw_composite_glyph_string_foreground (s
);
3699 if (!s
->for_overlaps
)
3701 /* Draw underline. */
3702 if (s
->face
->underline_p
)
3704 unsigned long tem
, h
;
3708 /* Get the underline thickness. Default is 1 pixel. */
3709 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
3713 y
= s
->y
+ s
->height
- h
;
3714 if (!x_underline_at_descent_line
)
3716 /* Get the underline position. This is the recommended
3717 vertical offset in pixels from the baseline to the top of
3718 the underline. This is a signed value according to the
3719 specs, and its default is
3721 ROUND ((maximum descent) / 2), with
3722 ROUND(x) = floor (x + 0.5) */
3725 if (x_use_underline_position_properties
3726 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
3727 y
= s
->ybase
+ (long) tem
;
3731 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
3734 if (s
->face
->underline_defaulted_p
)
3735 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, y
,
3736 s
->background_width
, h
);
3740 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3741 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3742 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, y
,
3743 s
->background_width
, h
);
3744 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3748 /* Draw overline. */
3749 if (s
->face
->overline_p
)
3751 unsigned long dy
= 0, h
= 1;
3753 if (s
->face
->overline_color_defaulted_p
)
3754 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3755 s
->background_width
, h
);
3759 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3760 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3761 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3762 s
->background_width
, h
);
3763 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3767 /* Draw strike-through. */
3768 if (s
->face
->strike_through_p
)
3770 unsigned long h
= 1;
3771 unsigned long dy
= (s
->height
- h
) / 2;
3773 if (s
->face
->strike_through_color_defaulted_p
)
3774 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3779 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3780 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3781 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3783 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3787 /* Draw relief if not yet drawn. */
3788 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3789 x_draw_glyph_string_box (s
);
3792 /* Reset clipping. */
3793 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3796 /* Shift display to make room for inserted glyphs. */
3799 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3801 int x
, y
, width
, height
, shift_by
;
3803 mac_scroll_area (f
, f
->output_data
.mac
->normal_gc
,
3804 x
, y
, width
, height
,
3808 /* Delete N glyphs at the nominal cursor position. Not implemented
3819 /* Clear entire frame. If updating_frame is non-null, clear that
3820 frame. Otherwise clear the selected frame. */
3830 f
= SELECTED_FRAME ();
3832 /* Clearing the frame will erase any cursor, so mark them all as no
3834 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3835 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3836 output_cursor
.x
= -1;
3838 /* We don't set the output cursor here because there will always
3839 follow an explicit cursor_to. */
3841 mac_clear_window (f
);
3843 /* We have to clear the scroll bars, too. If we have changed
3844 colors or something like that, then they should be notified. */
3845 x_scroll_bar_clear (f
);
3847 XFlush (FRAME_MAC_DISPLAY (f
));
3853 /* Invert the middle quarter of the frame for .15 sec. */
3855 /* We use the select system call to do the waiting, so we have to make
3856 sure it's available. If it isn't, we just won't do visual bells. */
3858 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3861 /* Subtract the `struct timeval' values X and Y, storing the result in
3862 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3865 timeval_subtract (result
, x
, y
)
3866 struct timeval
*result
, x
, y
;
3868 /* Perform the carry for the later subtraction by updating y. This
3869 is safer because on some systems the tv_sec member is unsigned. */
3870 if (x
.tv_usec
< y
.tv_usec
)
3872 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3873 y
.tv_usec
-= 1000000 * nsec
;
3877 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3879 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3880 y
.tv_usec
+= 1000000 * nsec
;
3884 /* Compute the time remaining to wait. tv_usec is certainly
3886 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3887 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3889 /* Return indication of whether the result should be considered
3891 return x
.tv_sec
< y
.tv_sec
;
3898 /* Get the height not including a menu bar widget. */
3899 int height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, FRAME_LINES (f
));
3900 /* Height of each line to flash. */
3901 int flash_height
= FRAME_LINE_HEIGHT (f
);
3902 /* These will be the left and right margins of the rectangles. */
3903 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
3904 int flash_right
= FRAME_PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
3908 /* Don't flash the area between a scroll bar and the frame
3909 edge it is next to. */
3910 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
3912 case vertical_scroll_bar_left
:
3913 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3916 case vertical_scroll_bar_right
:
3917 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3924 width
= flash_right
- flash_left
;
3928 /* If window is tall, flash top and bottom line. */
3929 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3931 mac_invert_rectangle (f
, flash_left
,
3932 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3933 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3934 width
, flash_height
);
3935 mac_invert_rectangle (f
, flash_left
,
3936 (height
- flash_height
3937 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3938 width
, flash_height
);
3941 /* If it is short, flash it all. */
3942 mac_invert_rectangle (f
, flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3943 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
3948 struct timeval wakeup
;
3950 EMACS_GET_TIME (wakeup
);
3952 /* Compute time to wait until, propagating carry from usecs. */
3953 wakeup
.tv_usec
+= 150000;
3954 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3955 wakeup
.tv_usec
%= 1000000;
3957 /* Keep waiting until past the time wakeup or any input gets
3959 while (! detect_input_pending ())
3961 struct timeval current
;
3962 struct timeval timeout
;
3964 EMACS_GET_TIME (current
);
3966 /* Break if result would be negative. */
3967 if (timeval_subtract (¤t
, wakeup
, current
))
3970 /* How long `select' should wait. */
3972 timeout
.tv_usec
= 10000;
3974 /* Try to wait that long--but we might wake up sooner. */
3975 select (0, NULL
, NULL
, NULL
, &timeout
);
3979 /* If window is tall, flash top and bottom line. */
3980 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3982 mac_invert_rectangle (f
, flash_left
,
3983 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3984 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3985 width
, flash_height
);
3986 mac_invert_rectangle (f
, flash_left
,
3987 (height
- flash_height
3988 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3989 width
, flash_height
);
3992 /* If it is short, flash it all. */
3993 mac_invert_rectangle (f
, flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3994 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
4001 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
4004 /* Make audible bell. */
4009 struct frame
*f
= SELECTED_FRAME ();
4011 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
4019 XFlush (FRAME_MAC_DISPLAY (f
));
4025 /* Specify how many text lines, from the top of the window,
4026 should be affected by insert-lines and delete-lines operations.
4027 This, and those operations, are used only within an update
4028 that is bounded by calls to x_update_begin and x_update_end. */
4031 XTset_terminal_window (n
)
4034 /* This function intentionally left blank. */
4039 /***********************************************************************
4041 ***********************************************************************/
4043 /* Perform an insert-lines or delete-lines operation, inserting N
4044 lines or deleting -N lines at vertical position VPOS. */
4047 x_ins_del_lines (vpos
, n
)
4054 /* Scroll part of the display as described by RUN. */
4057 x_scroll_run (w
, run
)
4061 struct frame
*f
= XFRAME (w
->frame
);
4062 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4064 /* Get frame-relative bounding box of the text display area of W,
4065 without mode lines. Include in this box the left and right
4067 window_box (w
, -1, &x
, &y
, &width
, &height
);
4069 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4070 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4071 bottom_y
= y
+ height
;
4075 /* Scrolling up. Make sure we don't copy part of the mode
4076 line at the bottom. */
4077 if (from_y
+ run
->height
> bottom_y
)
4078 height
= bottom_y
- from_y
;
4080 height
= run
->height
;
4084 /* Scolling down. Make sure we don't copy over the mode line.
4086 if (to_y
+ run
->height
> bottom_y
)
4087 height
= bottom_y
- to_y
;
4089 height
= run
->height
;
4094 /* Cursor off. Will be switched on again in x_update_window_end. */
4098 mac_scroll_area (f
, f
->output_data
.mac
->normal_gc
,
4108 /***********************************************************************
4110 ***********************************************************************/
4118 ControlRef root_control
;
4121 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
4123 ActivateControl (root_control
);
4125 x_update_cursor (f
, 1);
4129 frame_unhighlight (f
)
4133 ControlRef root_control
;
4136 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
4138 DeactivateControl (root_control
);
4140 x_update_cursor (f
, 1);
4143 /* The focus has changed. Update the frames as necessary to reflect
4144 the new situation. Note that we can't change the selected frame
4145 here, because the Lisp code we are interrupting might become confused.
4146 Each event gets marked with the frame in which it occurred, so the
4147 Lisp code can tell when the switch took place by examining the events. */
4150 x_new_focus_frame (dpyinfo
, frame
)
4151 struct x_display_info
*dpyinfo
;
4152 struct frame
*frame
;
4154 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
4156 if (frame
!= dpyinfo
->x_focus_frame
)
4158 /* Set this before calling other routines, so that they see
4159 the correct value of x_focus_frame. */
4160 dpyinfo
->x_focus_frame
= frame
;
4162 if (old_focus
&& old_focus
->auto_lower
)
4163 x_lower_frame (old_focus
);
4166 selected_frame
= frame
;
4167 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
4169 Fselect_window (selected_frame
->selected_window
, Qnil
);
4170 choose_minibuf_frame ();
4173 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
4174 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
4176 pending_autoraise_frame
= 0;
4178 #if USE_MAC_FONT_PANEL
4180 mac_set_font_info_for_selection (frame
, DEFAULT_FACE_ID
, 0);
4184 x_frame_rehighlight (dpyinfo
);
4187 /* Handle FocusIn and FocusOut state changes for FRAME.
4188 If FRAME has focus and there exists more than one frame, puts
4189 a FOCUS_IN_EVENT into *BUFP. */
4192 mac_focus_changed (type
, dpyinfo
, frame
, bufp
)
4194 struct mac_display_info
*dpyinfo
;
4195 struct frame
*frame
;
4196 struct input_event
*bufp
;
4198 if (type
== activeFlag
)
4200 if (dpyinfo
->x_focus_event_frame
!= frame
)
4202 x_new_focus_frame (dpyinfo
, frame
);
4203 dpyinfo
->x_focus_event_frame
= frame
;
4205 /* Don't stop displaying the initial startup message
4206 for a switch-frame event we don't need. */
4207 if (GC_NILP (Vterminal_frame
)
4208 && GC_CONSP (Vframe_list
)
4209 && !GC_NILP (XCDR (Vframe_list
)))
4211 bufp
->kind
= FOCUS_IN_EVENT
;
4212 XSETFRAME (bufp
->frame_or_window
, frame
);
4218 if (dpyinfo
->x_focus_event_frame
== frame
)
4220 dpyinfo
->x_focus_event_frame
= 0;
4221 x_new_focus_frame (dpyinfo
, 0);
4226 /* The focus may have changed. Figure out if it is a real focus change,
4227 by checking both FocusIn/Out and Enter/LeaveNotify events.
4229 Returns FOCUS_IN_EVENT event in *BUFP. */
4232 x_detect_focus_change (dpyinfo
, event
, bufp
)
4233 struct mac_display_info
*dpyinfo
;
4234 const EventRecord
*event
;
4235 struct input_event
*bufp
;
4237 struct frame
*frame
;
4239 frame
= mac_window_to_frame ((WindowPtr
) event
->message
);
4243 /* On Mac, this is only called from focus events, so no switch needed. */
4244 mac_focus_changed ((event
->modifiers
& activeFlag
),
4245 dpyinfo
, frame
, bufp
);
4249 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4252 x_mouse_leave (dpyinfo
)
4253 struct x_display_info
*dpyinfo
;
4255 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
4258 /* The focus has changed, or we have redirected a frame's focus to
4259 another frame (this happens when a frame uses a surrogate
4260 mini-buffer frame). Shift the highlight as appropriate.
4262 The FRAME argument doesn't necessarily have anything to do with which
4263 frame is being highlighted or un-highlighted; we only use it to find
4264 the appropriate X display info. */
4267 XTframe_rehighlight (frame
)
4268 struct frame
*frame
;
4270 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
4274 x_frame_rehighlight (dpyinfo
)
4275 struct x_display_info
*dpyinfo
;
4277 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
4279 if (dpyinfo
->x_focus_frame
)
4281 dpyinfo
->x_highlight_frame
4282 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
4283 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
4284 : dpyinfo
->x_focus_frame
);
4285 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
4287 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
4288 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
4292 dpyinfo
->x_highlight_frame
= 0;
4294 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
4297 frame_unhighlight (old_highlight
);
4298 if (dpyinfo
->x_highlight_frame
)
4299 frame_highlight (dpyinfo
->x_highlight_frame
);
4305 /* Convert a keysym to its name. */
4308 x_get_keysym_name (keysym
)
4315 value
= XKeysymToString (keysym
);
4326 /* Function to report a mouse movement to the mainstream Emacs code.
4327 The input handler calls this.
4329 We have received a mouse movement event, which is given in *event.
4330 If the mouse is over a different glyph than it was last time, tell
4331 the mainstream emacs code by setting mouse_moved. If not, ask for
4332 another motion event, so we can check again the next time it moves. */
4334 static Point last_mouse_motion_position
;
4335 static Lisp_Object last_mouse_motion_frame
;
4338 note_mouse_movement (frame
, pos
)
4342 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4343 #if TARGET_API_MAC_CARBON
4347 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
4348 last_mouse_motion_position
= *pos
;
4349 XSETFRAME (last_mouse_motion_frame
, frame
);
4351 #if TARGET_API_MAC_CARBON
4352 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
4354 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
4357 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
4358 /* This case corresponds to LeaveNotify in X11. */
4360 /* If we move outside the frame, then we're certainly no
4361 longer on any text in the frame. */
4362 clear_mouse_face (dpyinfo
);
4363 dpyinfo
->mouse_face_mouse_frame
= 0;
4364 if (!dpyinfo
->grabbed
)
4365 rif
->define_frame_cursor (frame
,
4366 frame
->output_data
.mac
->nontext_cursor
);
4370 /* Has the mouse moved off the glyph it was on at the last sighting? */
4371 if (frame
!= last_mouse_glyph_frame
4372 || !PtInRect (*pos
, &last_mouse_glyph
))
4374 frame
->mouse_moved
= 1;
4375 last_mouse_scroll_bar
= Qnil
;
4376 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
4377 /* Remember which glyph we're now on. */
4378 remember_mouse_glyph (frame
, pos
->h
, pos
->v
, &last_mouse_glyph
);
4379 last_mouse_glyph_frame
= frame
;
4387 /************************************************************************
4389 ************************************************************************/
4391 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4394 redo_mouse_highlight ()
4396 if (!NILP (last_mouse_motion_frame
)
4397 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
4398 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
4399 last_mouse_motion_position
.h
,
4400 last_mouse_motion_position
.v
);
4404 static struct frame
*
4405 mac_focus_frame (dpyinfo
)
4406 struct mac_display_info
*dpyinfo
;
4408 if (dpyinfo
->x_focus_frame
)
4409 return dpyinfo
->x_focus_frame
;
4411 /* Mac version may get events, such as a menu bar click, even when
4412 all the frames are invisible. In this case, we regard the
4413 event came to the selected frame. */
4414 return SELECTED_FRAME ();
4418 /* Return the current position of the mouse.
4419 *FP should be a frame which indicates which display to ask about.
4421 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
4422 and *PART to the frame, window, and scroll bar part that the mouse
4423 is over. Set *X and *Y to the portion and whole of the mouse's
4424 position on the scroll bar.
4426 If the mouse movement started elsewhere, set *FP to the frame the
4427 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
4430 Set *TIME to the server time-stamp for the time at which the mouse
4431 was at this position.
4433 Don't store anything if we don't have a valid set of values to report.
4435 This clears the mouse_moved flag, so we can wait for the next mouse
4439 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
4442 Lisp_Object
*bar_window
;
4443 enum scroll_bar_part
*part
;
4445 unsigned long *time
;
4451 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
4452 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
4455 Lisp_Object frame
, tail
;
4457 /* Clear the mouse-moved flag for every frame on this display. */
4458 FOR_EACH_FRAME (tail
, frame
)
4459 XFRAME (frame
)->mouse_moved
= 0;
4461 last_mouse_scroll_bar
= Qnil
;
4463 if (FRAME_MAC_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
4464 && FRAME_LIVE_P (last_mouse_frame
))
4465 f1
= last_mouse_frame
;
4467 f1
= mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp
));
4471 /* Ok, we found a frame. Store all the values.
4472 last_mouse_glyph is a rectangle used to reduce the
4473 generation of mouse events. To not miss any motion
4474 events, we must divide the frame into rectangles of the
4475 size of the smallest character that could be displayed
4476 on it, i.e. into the same rectangles that matrices on
4477 the frame are divided into. */
4480 SetPortWindowPort (FRAME_MAC_WINDOW (f1
));
4481 GetMouse (&mouse_pos
);
4482 remember_mouse_glyph (f1
, mouse_pos
.h
, mouse_pos
.v
,
4484 last_mouse_glyph_frame
= f1
;
4489 XSETINT (*x
, mouse_pos
.h
);
4490 XSETINT (*y
, mouse_pos
.v
);
4491 *time
= last_mouse_movement_time
;
4499 /************************************************************************
4501 ************************************************************************/
4503 #ifdef USE_TOOLKIT_SCROLL_BARS
4505 static pascal void scroll_bar_timer_callback
P_ ((EventLoopTimerRef
, void *));
4506 static OSStatus install_scroll_bar_timer
P_ ((void));
4507 static OSStatus set_scroll_bar_timer
P_ ((EventTimerInterval
));
4508 static int control_part_code_to_scroll_bar_part
P_ ((ControlPartCode
));
4509 static void construct_scroll_bar_click
P_ ((struct scroll_bar
*, int,
4510 struct input_event
*));
4511 static OSStatus get_control_part_bounds
P_ ((ControlHandle
, ControlPartCode
,
4513 static void x_scroll_bar_handle_press
P_ ((struct scroll_bar
*,
4515 struct input_event
*));
4516 static void x_scroll_bar_handle_release
P_ ((struct scroll_bar
*,
4517 struct input_event
*));
4518 static void x_scroll_bar_handle_drag
P_ ((WindowPtr
, struct scroll_bar
*,
4519 Point
, struct input_event
*));
4520 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
4523 /* Last scroll bar part sent in x_scroll_bar_handle_*. */
4525 static int last_scroll_bar_part
;
4527 static EventLoopTimerRef scroll_bar_timer
;
4529 static int scroll_bar_timer_event_posted_p
;
4531 #define SCROLL_BAR_FIRST_DELAY 0.5
4532 #define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
4535 scroll_bar_timer_callback (timer
, data
)
4536 EventLoopTimerRef timer
;
4541 err
= mac_post_mouse_moved_event ();
4543 scroll_bar_timer_event_posted_p
= 1;
4547 install_scroll_bar_timer ()
4549 static EventLoopTimerUPP scroll_bar_timer_callbackUPP
= NULL
;
4551 if (scroll_bar_timer_callbackUPP
== NULL
)
4552 scroll_bar_timer_callbackUPP
=
4553 NewEventLoopTimerUPP (scroll_bar_timer_callback
);
4555 if (scroll_bar_timer
== NULL
)
4556 /* Mac OS X and CarbonLib 1.5 and later allow us to specify
4557 kEventDurationForever as delays. */
4559 InstallEventLoopTimer (GetCurrentEventLoop (),
4560 kEventDurationForever
, kEventDurationForever
,
4561 scroll_bar_timer_callbackUPP
, NULL
,
4566 set_scroll_bar_timer (delay
)
4567 EventTimerInterval delay
;
4569 if (scroll_bar_timer
== NULL
)
4570 install_scroll_bar_timer ();
4572 scroll_bar_timer_event_posted_p
= 0;
4574 return SetEventLoopTimerNextFireTime (scroll_bar_timer
, delay
);
4578 control_part_code_to_scroll_bar_part (part_code
)
4579 ControlPartCode part_code
;
4583 case kControlUpButtonPart
: return scroll_bar_up_arrow
;
4584 case kControlDownButtonPart
: return scroll_bar_down_arrow
;
4585 case kControlPageUpPart
: return scroll_bar_above_handle
;
4586 case kControlPageDownPart
: return scroll_bar_below_handle
;
4587 case kControlIndicatorPart
: return scroll_bar_handle
;
4594 construct_scroll_bar_click (bar
, part
, bufp
)
4595 struct scroll_bar
*bar
;
4597 struct input_event
*bufp
;
4599 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4600 bufp
->frame_or_window
= bar
->window
;
4604 XSETINT (bufp
->x
, 0);
4605 XSETINT (bufp
->y
, 0);
4606 bufp
->modifiers
= 0;
4610 get_control_part_bounds (ch
, part_code
, rect
)
4612 ControlPartCode part_code
;
4615 RgnHandle region
= NewRgn ();
4618 err
= GetControlRegion (ch
, part_code
, region
);
4620 GetRegionBounds (region
, rect
);
4621 DisposeRgn (region
);
4627 x_scroll_bar_handle_press (bar
, part_code
, bufp
)
4628 struct scroll_bar
*bar
;
4629 ControlPartCode part_code
;
4630 struct input_event
*bufp
;
4632 int part
= control_part_code_to_scroll_bar_part (part_code
);
4637 if (part
!= scroll_bar_handle
)
4639 construct_scroll_bar_click (bar
, part
, bufp
);
4640 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4641 set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY
);
4644 last_scroll_bar_part
= part
;
4645 bar
->dragging
= Qnil
;
4646 tracked_scroll_bar
= bar
;
4650 x_scroll_bar_handle_release (bar
, bufp
)
4651 struct scroll_bar
*bar
;
4652 struct input_event
*bufp
;
4654 if (last_scroll_bar_part
!= scroll_bar_handle
4655 || !GC_NILP (bar
->dragging
))
4656 construct_scroll_bar_click (bar
, scroll_bar_end_scroll
, bufp
);
4658 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4659 set_scroll_bar_timer (kEventDurationForever
);
4661 last_scroll_bar_part
= -1;
4662 bar
->dragging
= Qnil
;
4663 tracked_scroll_bar
= NULL
;
4667 x_scroll_bar_handle_drag (win
, bar
, mouse_pos
, bufp
)
4669 struct scroll_bar
*bar
;
4671 struct input_event
*bufp
;
4673 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4675 if (last_scroll_bar_part
== scroll_bar_handle
)
4680 get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar
),
4681 kControlIndicatorPart
, &r
);
4683 if (GC_NILP (bar
->dragging
))
4684 XSETINT (bar
->dragging
, mouse_pos
.v
- r
.top
);
4686 top
= mouse_pos
.v
- XINT (bar
->dragging
) - XINT (bar
->track_top
);
4687 top_range
= (XINT (bar
->track_height
) - (r
.bottom
- r
.top
)) *
4688 (1.0 + (float) GetControlViewSize (ch
) / GetControl32BitMaximum (ch
))
4693 if (top
> top_range
)
4696 construct_scroll_bar_click (bar
, scroll_bar_handle
, bufp
);
4697 XSETINT (bufp
->x
, top
);
4698 XSETINT (bufp
->y
, top_range
);
4702 ControlPartCode part_code
;
4703 int unhilite_p
= 0, part
;
4705 if (ch
!= FindControlUnderMouse (mouse_pos
, win
, &part_code
))
4709 part
= control_part_code_to_scroll_bar_part (part_code
);
4711 switch (last_scroll_bar_part
)
4713 case scroll_bar_above_handle
:
4714 case scroll_bar_below_handle
:
4715 if (part
!= scroll_bar_above_handle
4716 && part
!= scroll_bar_below_handle
)
4720 case scroll_bar_up_arrow
:
4721 case scroll_bar_down_arrow
:
4722 if (part
!= scroll_bar_up_arrow
4723 && part
!= scroll_bar_down_arrow
)
4730 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4731 else if (part
!= last_scroll_bar_part
4732 || scroll_bar_timer_event_posted_p
)
4734 construct_scroll_bar_click (bar
, part
, bufp
);
4735 last_scroll_bar_part
= part
;
4736 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4737 set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY
);
4742 /* Set the thumb size and position of scroll bar BAR. We are currently
4743 displaying PORTION out of a whole WHOLE, and our position POSITION. */
4746 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
4747 struct scroll_bar
*bar
;
4748 int portion
, position
, whole
;
4750 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4751 int value
, viewsize
, maximum
;
4753 if (XINT (bar
->track_height
) == 0)
4757 value
= 0, viewsize
= 1, maximum
= 0;
4762 maximum
= max (0, whole
- portion
);
4767 if (GetControlViewSize (ch
) != viewsize
4768 || GetControl32BitValue (ch
) != value
4769 || GetControl32BitMaximum (ch
) != maximum
)
4771 /* Temporarily hide the scroll bar to avoid multiple redraws. */
4772 SetControlVisibility (ch
, false, false);
4774 SetControl32BitMaximum (ch
, maximum
);
4775 SetControl32BitValue (ch
, value
);
4776 SetControlViewSize (ch
, viewsize
);
4778 SetControlVisibility (ch
, true, true);
4784 #endif /* USE_TOOLKIT_SCROLL_BARS */
4788 /************************************************************************
4789 Scroll bars, general
4790 ************************************************************************/
4792 /* Create a scroll bar and return the scroll bar vector for it. W is
4793 the Emacs window on which to create the scroll bar. TOP, LEFT,
4794 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4797 static struct scroll_bar
*
4798 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4800 int top
, left
, width
, height
, disp_top
, disp_height
;
4802 struct frame
*f
= XFRAME (w
->frame
);
4803 struct scroll_bar
*bar
4804 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4812 r
.right
= left
+ width
;
4813 r
.bottom
= disp_top
+ disp_height
;
4816 mac_prepare_for_quickdraw (f
);
4818 #if TARGET_API_MAC_CARBON
4819 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p",
4820 #if USE_TOOLKIT_SCROLL_BARS
4823 width
< disp_height
,
4825 0, 0, 0, kControlScrollBarProc
, (long) bar
);
4827 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4828 0, 0, 0, scrollBarProc
, (long) bar
);
4830 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4832 XSETWINDOW (bar
->window
, w
);
4833 XSETINT (bar
->top
, top
);
4834 XSETINT (bar
->left
, left
);
4835 XSETINT (bar
->width
, width
);
4836 XSETINT (bar
->height
, height
);
4837 XSETINT (bar
->start
, 0);
4838 XSETINT (bar
->end
, 0);
4839 bar
->dragging
= Qnil
;
4840 #ifdef USE_TOOLKIT_SCROLL_BARS
4841 bar
->track_top
= Qnil
;
4842 bar
->track_height
= Qnil
;
4845 /* Add bar to its frame's list of scroll bars. */
4846 bar
->next
= FRAME_SCROLL_BARS (f
);
4848 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4849 if (!NILP (bar
->next
))
4850 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4857 /* Draw BAR's handle in the proper position.
4859 If the handle is already drawn from START to END, don't bother
4860 redrawing it, unless REBUILD is non-zero; in that case, always
4861 redraw it. (REBUILD is handy for drawing the handle after expose
4864 Normally, we want to constrain the start and end of the handle to
4865 fit inside its rectangle, but if the user is dragging the scroll
4866 bar handle, we want to let them drag it down all the way, so that
4867 the bar's top is as far down as it goes; otherwise, there's no way
4868 to move to the very end of the buffer. */
4870 #ifndef USE_TOOLKIT_SCROLL_BARS
4873 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4874 struct scroll_bar
*bar
;
4878 int dragging
= ! NILP (bar
->dragging
);
4879 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4880 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4881 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4882 int length
= end
- start
;
4884 /* If the display is already accurate, do nothing. */
4886 && start
== XINT (bar
->start
)
4887 && end
== XINT (bar
->end
))
4892 /* Make sure the values are reasonable, and try to preserve the
4893 distance between start and end. */
4896 else if (start
> top_range
)
4898 end
= start
+ length
;
4902 else if (end
> top_range
&& ! dragging
)
4905 /* Store the adjusted setting in the scroll bar. */
4906 XSETINT (bar
->start
, start
);
4907 XSETINT (bar
->end
, end
);
4909 /* Clip the end position, just for display. */
4910 if (end
> top_range
)
4913 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4914 top positions, to make sure the handle is always at least that
4915 many pixels tall. */
4916 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4918 SetControlMinimum (ch
, 0);
4919 /* Don't inadvertently activate deactivated scroll bars */
4920 if (GetControlMaximum (ch
) != -1)
4921 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4923 SetControlValue (ch
, start
);
4924 #if TARGET_API_MAC_CARBON
4925 SetControlViewSize (ch
, end
- start
);
4931 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4933 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4937 x_scroll_bar_remove (bar
)
4938 struct scroll_bar
*bar
;
4940 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4945 mac_prepare_for_quickdraw (f
);
4947 /* Destroy the Mac scroll bar control */
4948 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4950 /* Disassociate this scroll bar from its window. */
4951 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4957 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4958 that we are displaying PORTION characters out of a total of WHOLE
4959 characters, starting at POSITION. If WINDOW has no scroll bar,
4963 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4965 int portion
, whole
, position
;
4967 struct frame
*f
= XFRAME (w
->frame
);
4968 struct scroll_bar
*bar
;
4969 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4970 int window_y
, window_height
;
4972 /* Get window dimensions. */
4973 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4975 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4976 height
= window_height
;
4978 /* Compute the left edge of the scroll bar area. */
4979 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4981 /* Compute the width of the scroll bar which might be less than
4982 the width of the area reserved for the scroll bar. */
4983 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4984 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4988 /* Compute the left edge of the scroll bar. */
4989 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4992 sb_left
= left
+ width
- sb_width
;
4994 /* Adjustments according to Inside Macintosh to make it look nice */
4996 disp_height
= height
;
5003 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
5009 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
5013 /* Does the scroll bar exist yet? */
5014 if (NILP (w
->vertical_scroll_bar
))
5017 mac_clear_area (f
, left
, top
, width
, height
);
5019 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
5021 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
5025 /* It may just need to be moved and resized. */
5028 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
5029 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5033 /* If already correctly positioned, do nothing. */
5034 if (!(XINT (bar
->left
) == sb_left
5035 && XINT (bar
->top
) == top
5036 && XINT (bar
->width
) == sb_width
5037 && XINT (bar
->height
) == height
))
5039 /* Since toolkit scroll bars are smaller than the space reserved
5040 for them on the frame, we have to clear "under" them. */
5041 mac_clear_area (f
, left
, top
, width
, height
);
5044 mac_prepare_for_quickdraw (f
);
5047 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
5048 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
5050 #ifndef USE_TOOLKIT_SCROLL_BARS
5051 if (sb_width
< disp_height
)
5055 /* Remember new settings. */
5056 XSETINT (bar
->left
, sb_left
);
5057 XSETINT (bar
->top
, top
);
5058 XSETINT (bar
->width
, sb_width
);
5059 XSETINT (bar
->height
, height
);
5060 #ifdef USE_TOOLKIT_SCROLL_BARS
5061 bar
->track_top
= Qnil
;
5062 bar
->track_height
= Qnil
;
5069 #ifdef USE_TOOLKIT_SCROLL_BARS
5070 if (NILP (bar
->track_top
))
5072 if (sb_width
>= disp_height
)
5074 XSETINT (bar
->track_top
, 0);
5075 XSETINT (bar
->track_height
, 0);
5079 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5084 SetControl32BitMinimum (ch
, 0);
5085 SetControl32BitMaximum (ch
, 1);
5086 SetControlViewSize (ch
, 1);
5088 /* Move the scroll bar thumb to the top. */
5089 SetControl32BitValue (ch
, 0);
5090 get_control_part_bounds (ch
, kControlIndicatorPart
, &r0
);
5092 /* Move the scroll bar thumb to the bottom. */
5093 SetControl32BitValue (ch
, 1);
5094 get_control_part_bounds (ch
, kControlIndicatorPart
, &r1
);
5096 UnionRect (&r0
, &r1
, &r0
);
5097 XSETINT (bar
->track_top
, r0
.top
);
5098 XSETINT (bar
->track_height
, r0
.bottom
- r0
.top
);
5100 /* Don't show the scroll bar if its height is not enough to
5101 display the scroll bar thumb. */
5102 if (r0
.bottom
- r0
.top
> 0)
5109 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
5110 #else /* not USE_TOOLKIT_SCROLL_BARS */
5111 /* Set the scroll bar's current state, unless we're currently being
5113 if (NILP (bar
->dragging
))
5115 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
5118 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
5121 int start
= ((double) position
* top_range
) / whole
;
5122 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
5123 x_scroll_bar_set_handle (bar
, start
, end
, 0);
5126 #endif /* not USE_TOOLKIT_SCROLL_BARS */
5130 /* The following three hooks are used when we're doing a thorough
5131 redisplay of the frame. We don't explicitly know which scroll bars
5132 are going to be deleted, because keeping track of when windows go
5133 away is a real pain - "Can you say set-window-configuration, boys
5134 and girls?" Instead, we just assert at the beginning of redisplay
5135 that *all* scroll bars are to be removed, and then save a scroll bar
5136 from the fiery pit when we actually redisplay its window. */
5138 /* Arrange for all scroll bars on FRAME to be removed at the next call
5139 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
5140 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
5143 XTcondemn_scroll_bars (frame
)
5146 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
5147 while (! NILP (FRAME_SCROLL_BARS (frame
)))
5150 bar
= FRAME_SCROLL_BARS (frame
);
5151 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
5152 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
5153 XSCROLL_BAR (bar
)->prev
= Qnil
;
5154 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
5155 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
5156 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
5161 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
5162 Note that WINDOW isn't necessarily condemned at all. */
5165 XTredeem_scroll_bar (window
)
5166 struct window
*window
;
5168 struct scroll_bar
*bar
;
5171 /* We can't redeem this window's scroll bar if it doesn't have one. */
5172 if (NILP (window
->vertical_scroll_bar
))
5175 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
5177 /* Unlink it from the condemned list. */
5178 f
= XFRAME (WINDOW_FRAME (window
));
5179 if (NILP (bar
->prev
))
5181 /* If the prev pointer is nil, it must be the first in one of
5183 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
5184 /* It's not condemned. Everything's fine. */
5186 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
5187 window
->vertical_scroll_bar
))
5188 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
5190 /* If its prev pointer is nil, it must be at the front of
5191 one or the other! */
5195 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
5197 if (! NILP (bar
->next
))
5198 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
5200 bar
->next
= FRAME_SCROLL_BARS (f
);
5202 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
5203 if (! NILP (bar
->next
))
5204 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
5207 /* Remove all scroll bars on FRAME that haven't been saved since the
5208 last call to `*condemn_scroll_bars_hook'. */
5211 XTjudge_scroll_bars (f
)
5214 Lisp_Object bar
, next
;
5216 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
5218 /* Clear out the condemned list now so we won't try to process any
5219 more events on the hapless scroll bars. */
5220 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
5222 for (; ! NILP (bar
); bar
= next
)
5224 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
5226 x_scroll_bar_remove (b
);
5229 b
->next
= b
->prev
= Qnil
;
5232 /* Now there should be no references to the condemned scroll bars,
5233 and they should get garbage-collected. */
5237 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
5238 is set to something other than NO_EVENT, it is enqueued.
5240 This may be called from a signal handler, so we have to ignore GC
5244 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
5245 struct scroll_bar
*bar
;
5246 ControlPartCode part_code
;
5247 const EventRecord
*er
;
5248 struct input_event
*bufp
;
5250 int win_y
, top_range
;
5252 if (! GC_WINDOWP (bar
->window
))
5255 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
5256 bufp
->frame_or_window
= bar
->window
;
5259 bar
->dragging
= Qnil
;
5263 case kControlUpButtonPart
:
5264 bufp
->part
= scroll_bar_up_arrow
;
5266 case kControlDownButtonPart
:
5267 bufp
->part
= scroll_bar_down_arrow
;
5269 case kControlPageUpPart
:
5270 bufp
->part
= scroll_bar_above_handle
;
5272 case kControlPageDownPart
:
5273 bufp
->part
= scroll_bar_below_handle
;
5275 #if TARGET_API_MAC_CARBON
5278 case kControlIndicatorPart
:
5280 if (er
->what
== mouseDown
)
5281 bar
->dragging
= make_number (0);
5282 XSETVECTOR (last_mouse_scroll_bar
, bar
);
5283 bufp
->part
= scroll_bar_handle
;
5287 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
5288 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
5290 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
5294 if (! NILP (bar
->dragging
))
5295 win_y
-= XINT (bar
->dragging
);
5299 if (win_y
> top_range
)
5302 XSETINT (bufp
->x
, win_y
);
5303 XSETINT (bufp
->y
, top_range
);
5306 #ifndef USE_TOOLKIT_SCROLL_BARS
5308 /* Handle some mouse motion while someone is dragging the scroll bar.
5310 This may be called from a signal handler, so we have to ignore GC
5314 x_scroll_bar_note_movement (bar
, y_pos
, t
)
5315 struct scroll_bar
*bar
;
5319 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
5321 last_mouse_movement_time
= t
;
5324 XSETVECTOR (last_mouse_scroll_bar
, bar
);
5326 /* If we're dragging the bar, display it. */
5327 if (! GC_NILP (bar
->dragging
))
5329 /* Where should the handle be now? */
5330 int new_start
= y_pos
- 24;
5332 if (new_start
!= XINT (bar
->start
))
5334 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
5336 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
5341 #endif /* !USE_TOOLKIT_SCROLL_BARS */
5343 /* Return information to the user about the current position of the mouse
5344 on the scroll bar. */
5347 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
5349 Lisp_Object
*bar_window
;
5350 enum scroll_bar_part
*part
;
5352 unsigned long *time
;
5354 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
5355 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5356 #if TARGET_API_MAC_CARBON
5357 WindowPtr wp
= GetControlOwner (ch
);
5359 WindowPtr wp
= (*ch
)->contrlOwner
;
5362 struct frame
*f
= mac_window_to_frame (wp
);
5363 int win_y
, top_range
;
5365 SetPortWindowPort (wp
);
5367 GetMouse (&mouse_pos
);
5369 win_y
= mouse_pos
.v
- XINT (bar
->top
);
5370 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
5372 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
5376 if (! NILP (bar
->dragging
))
5377 win_y
-= XINT (bar
->dragging
);
5381 if (win_y
> top_range
)
5385 *bar_window
= bar
->window
;
5387 if (! NILP (bar
->dragging
))
5388 *part
= scroll_bar_handle
;
5389 else if (win_y
< XINT (bar
->start
))
5390 *part
= scroll_bar_above_handle
;
5391 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
5392 *part
= scroll_bar_handle
;
5394 *part
= scroll_bar_below_handle
;
5396 XSETINT (*x
, win_y
);
5397 XSETINT (*y
, top_range
);
5400 last_mouse_scroll_bar
= Qnil
;
5402 *time
= last_mouse_movement_time
;
5406 /* The screen has been cleared so we may have changed foreground or
5407 background colors, and the scroll bars may need to be redrawn.
5408 Clear out the scroll bars, and ask for expose events, so we can
5412 x_scroll_bar_clear (f
)
5415 XTcondemn_scroll_bars (f
);
5416 XTjudge_scroll_bars (f
);
5420 /***********************************************************************
5422 ***********************************************************************/
5424 /* Set clipping for output in glyph row ROW. W is the window in which
5425 we operate. GC is the graphics context to set clipping in.
5427 ROW may be a text row or, e.g., a mode line. Text rows must be
5428 clipped to the interior of the window dedicated to text display,
5429 mode lines must be clipped to the whole window. */
5432 x_clip_to_row (w
, row
, area
, gc
)
5434 struct glyph_row
*row
;
5438 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5440 int window_x
, window_y
, window_width
;
5442 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
5444 clip_rect
.left
= window_x
;
5445 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5446 clip_rect
.top
= max (clip_rect
.top
, window_y
);
5447 clip_rect
.right
= clip_rect
.left
+ window_width
;
5448 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
5450 mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f
), gc
, &clip_rect
, 1);
5454 /* Draw a hollow box cursor on window W in glyph row ROW. */
5457 x_draw_hollow_cursor (w
, row
)
5459 struct glyph_row
*row
;
5461 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5462 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5463 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5466 struct glyph
*cursor_glyph
;
5469 /* Get the glyph the cursor is on. If we can't tell because
5470 the current matrix is invalid or such, give up. */
5471 cursor_glyph
= get_phys_cursor_glyph (w
);
5472 if (cursor_glyph
== NULL
)
5475 /* Compute frame-relative coordinates for phys cursor. */
5476 get_phys_cursor_geometry (w
, row
, cursor_glyph
, &x
, &y
, &h
);
5477 wd
= w
->phys_cursor_width
;
5479 /* The foreground of cursor_gc is typically the same as the normal
5480 background color, which can cause the cursor box to be invisible. */
5481 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5482 if (dpyinfo
->scratch_cursor_gc
)
5483 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
5485 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
5486 GCForeground
, &xgcv
);
5487 gc
= dpyinfo
->scratch_cursor_gc
;
5489 /* Set clipping, draw the rectangle, and reset clipping again. */
5490 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5491 mac_draw_rectangle (f
, gc
, x
, y
, wd
, h
- 1);
5492 mac_reset_clip_rectangles (dpy
, gc
);
5496 /* Draw a bar cursor on window W in glyph row ROW.
5498 Implementation note: One would like to draw a bar cursor with an
5499 angle equal to the one given by the font property XA_ITALIC_ANGLE.
5500 Unfortunately, I didn't find a font yet that has this property set.
5504 x_draw_bar_cursor (w
, row
, width
, kind
)
5506 struct glyph_row
*row
;
5508 enum text_cursor_kinds kind
;
5510 struct frame
*f
= XFRAME (w
->frame
);
5511 struct glyph
*cursor_glyph
;
5513 /* If cursor is out of bounds, don't draw garbage. This can happen
5514 in mini-buffer windows when switching between echo area glyphs
5516 cursor_glyph
= get_phys_cursor_glyph (w
);
5517 if (cursor_glyph
== NULL
)
5520 /* If on an image, draw like a normal cursor. That's usually better
5521 visible than drawing a bar, esp. if the image is large so that
5522 the bar might not be in the window. */
5523 if (cursor_glyph
->type
== IMAGE_GLYPH
)
5525 struct glyph_row
*row
;
5526 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5527 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
5531 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5532 Window window
= FRAME_MAC_WINDOW (f
);
5533 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
5534 unsigned long mask
= GCForeground
| GCBackground
;
5535 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
5538 /* If the glyph's background equals the color we normally draw
5539 the bar cursor in, the bar cursor in its normal color is
5540 invisible. Use the glyph's foreground color instead in this
5541 case, on the assumption that the glyph's colors are chosen so
5542 that the glyph is legible. */
5543 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
5544 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
5546 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5549 XChangeGC (dpy
, gc
, mask
, &xgcv
);
5552 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
5553 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
5557 width
= FRAME_CURSOR_WIDTH (f
);
5558 width
= min (cursor_glyph
->pixel_width
, width
);
5560 w
->phys_cursor_width
= width
;
5561 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5563 if (kind
== BAR_CURSOR
)
5564 mac_fill_rectangle (f
, gc
,
5565 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5566 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
5567 width
, row
->height
);
5569 mac_fill_rectangle (f
, gc
,
5570 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5571 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
5572 row
->height
- width
),
5573 cursor_glyph
->pixel_width
,
5576 mac_reset_clip_rectangles (dpy
, gc
);
5581 /* RIF: Define cursor CURSOR on frame F. */
5584 mac_define_frame_cursor (f
, cursor
)
5588 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5590 if (dpyinfo
->x_focus_frame
== f
)
5591 SetThemeCursor (cursor
);
5595 /* RIF: Clear area on frame F. */
5598 mac_clear_frame_area (f
, x
, y
, width
, height
)
5600 int x
, y
, width
, height
;
5602 mac_clear_area (f
, x
, y
, width
, height
);
5606 /* RIF: Draw cursor on window W. */
5609 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
5611 struct glyph_row
*glyph_row
;
5613 int cursor_type
, cursor_width
;
5618 w
->phys_cursor_type
= cursor_type
;
5619 w
->phys_cursor_on_p
= 1;
5621 if (glyph_row
->exact_window_width_line_p
5622 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
5624 glyph_row
->cursor_in_fringe_p
= 1;
5625 draw_fringe_bitmap (w
, glyph_row
, 0);
5628 switch (cursor_type
)
5630 case HOLLOW_BOX_CURSOR
:
5631 x_draw_hollow_cursor (w
, glyph_row
);
5634 case FILLED_BOX_CURSOR
:
5635 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
5639 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
5643 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
5647 w
->phys_cursor_width
= 0;
5659 #if 0 /* MAC_TODO: no icon support yet. */
5661 x_bitmap_icon (f
, icon
)
5667 if (FRAME_W32_WINDOW (f
) == 0)
5671 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
5672 else if (STRINGP (icon
))
5673 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
5674 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
5675 else if (SYMBOLP (icon
))
5679 if (EQ (icon
, intern ("application")))
5680 name
= (LPCTSTR
) IDI_APPLICATION
;
5681 else if (EQ (icon
, intern ("hand")))
5682 name
= (LPCTSTR
) IDI_HAND
;
5683 else if (EQ (icon
, intern ("question")))
5684 name
= (LPCTSTR
) IDI_QUESTION
;
5685 else if (EQ (icon
, intern ("exclamation")))
5686 name
= (LPCTSTR
) IDI_EXCLAMATION
;
5687 else if (EQ (icon
, intern ("asterisk")))
5688 name
= (LPCTSTR
) IDI_ASTERISK
;
5689 else if (EQ (icon
, intern ("winlogo")))
5690 name
= (LPCTSTR
) IDI_WINLOGO
;
5694 hicon
= LoadIcon (NULL
, name
);
5702 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
5707 #endif /* MAC_TODO */
5709 /************************************************************************
5711 ************************************************************************/
5713 /* Display Error Handling functions not used on W32. Listing them here
5714 helps diff stay in step when comparing w32term.c with xterm.c.
5716 x_error_catcher (display, error)
5717 x_catch_errors (dpy)
5718 x_catch_errors_unwind (old_val)
5719 x_check_errors (dpy, format)
5720 x_had_errors_p (dpy)
5721 x_clear_errors (dpy)
5722 x_uncatch_errors (dpy, count)
5724 x_connection_signal (signalnum)
5725 x_connection_closed (dpy, error_message)
5726 x_error_quitter (display, error)
5727 x_error_handler (display, error)
5728 x_io_error_quitter (display)
5733 /* Changing the font of the frame. */
5735 /* Give frame F the font named FONTNAME as its default font, and
5736 return the full name of that font. FONTNAME may be a wildcard
5737 pattern; in that case, we choose some font that fits the pattern.
5738 The return value shows which font we chose. */
5741 x_new_font (f
, fontname
)
5743 register char *fontname
;
5745 struct font_info
*fontp
5746 = FS_LOAD_FONT (f
, 0, fontname
, -1);
5751 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
5752 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
5753 FRAME_FONTSET (f
) = -1;
5755 FRAME_COLUMN_WIDTH (f
) = fontp
->average_width
;
5756 FRAME_SPACE_WIDTH (f
) = fontp
->space_width
;
5757 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
5759 compute_fringe_widths (f
, 1);
5761 /* Compute the scroll bar width in character columns. */
5762 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
5764 int wid
= FRAME_COLUMN_WIDTH (f
);
5765 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
5766 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
5770 int wid
= FRAME_COLUMN_WIDTH (f
);
5771 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
5774 /* Now make the frame display the given font. */
5775 if (FRAME_MAC_WINDOW (f
) != 0)
5777 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
5779 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
5781 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
5784 /* Don't change the size of a tip frame; there's no point in
5785 doing it because it's done in Fx_show_tip, and it leads to
5786 problems because the tip frame has no widget. */
5787 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
5788 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
5791 return build_string (fontp
->full_name
);
5794 /* Give frame F the fontset named FONTSETNAME as its default font, and
5795 return the full name of that fontset. FONTSETNAME may be a wildcard
5796 pattern; in that case, we choose some fontset that fits the pattern.
5797 The return value shows which fontset we chose. */
5800 x_new_fontset (f
, fontsetname
)
5804 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5810 if (FRAME_FONTSET (f
) == fontset
)
5811 /* This fontset is already set in frame F. There's nothing more
5813 return fontset_name (fontset
);
5815 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5817 if (!STRINGP (result
))
5818 /* Can't load ASCII font. */
5821 /* Since x_new_font doesn't update any fontset information, do it now. */
5822 FRAME_FONTSET (f
) = fontset
;
5824 return build_string (fontsetname
);
5828 /***********************************************************************
5829 TODO: W32 Input Methods
5830 ***********************************************************************/
5831 /* Listing missing functions from xterm.c helps diff stay in step.
5833 xim_destroy_callback (xim, client_data, call_data)
5834 xim_open_dpy (dpyinfo, resource_name)
5836 xim_instantiate_callback (display, client_data, call_data)
5837 xim_initialize (dpyinfo, resource_name)
5838 xim_close_dpy (dpyinfo)
5844 mac_get_window_bounds (f
, inner
, outer
)
5846 Rect
*inner
, *outer
;
5848 #if TARGET_API_MAC_CARBON
5849 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5850 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5851 #else /* not TARGET_API_MAC_CARBON */
5852 RgnHandle region
= NewRgn ();
5854 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5855 *inner
= (*region
)->rgnBBox
;
5856 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5857 *outer
= (*region
)->rgnBBox
;
5858 DisposeRgn (region
);
5859 #endif /* not TARGET_API_MAC_CARBON */
5863 mac_handle_origin_change (f
)
5866 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5870 mac_handle_size_change (f
, pixelwidth
, pixelheight
)
5872 int pixelwidth
, pixelheight
;
5876 cols
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, pixelwidth
);
5877 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, pixelheight
);
5879 if (cols
!= FRAME_COLS (f
)
5880 || rows
!= FRAME_LINES (f
)
5881 || pixelwidth
!= FRAME_PIXEL_WIDTH (f
)
5882 || pixelheight
!= FRAME_PIXEL_HEIGHT (f
))
5884 /* We pass 1 for DELAY since we can't run Lisp code inside of
5886 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5887 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5888 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5889 SET_FRAME_GARBAGED (f
);
5891 /* If cursor was outside the new size, mark it as off. */
5892 mark_window_cursors_off (XWINDOW (f
->root_window
));
5894 /* Clear out any recollection of where the mouse highlighting
5895 was, since it might be in a place that's outside the new
5896 frame size. Actually checking whether it is outside is a
5897 pain in the neck, so don't try--just let the highlighting be
5898 done afresh with new size. */
5899 cancel_mouse_face (f
);
5901 #if TARGET_API_MAC_CARBON
5902 if (f
->output_data
.mac
->hourglass_control
)
5905 mac_prepare_for_quickdraw (f
);
5907 MoveControl (f
->output_data
.mac
->hourglass_control
,
5908 pixelwidth
- HOURGLASS_WIDTH
, 0);
5915 /* Calculate the absolute position in frame F
5916 from its current recorded position values and gravity. */
5919 x_calc_absolute_position (f
)
5922 int width_diff
= 0, height_diff
= 0;
5923 int flags
= f
->size_hint_flags
;
5926 /* We have nothing to do if the current position
5927 is already for the top-left corner. */
5928 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5931 /* Find the offsets of the outside upper-left corner of
5932 the inner window, with respect to the outer window. */
5933 mac_get_window_bounds (f
, &inner
, &outer
);
5935 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5936 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5938 /* Treat negative positions as relative to the leftmost bottommost
5939 position that fits on the screen. */
5940 if (flags
& XNegative
)
5941 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5943 - FRAME_PIXEL_WIDTH (f
)
5946 if (flags
& YNegative
)
5947 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5949 - FRAME_PIXEL_HEIGHT (f
)
5952 /* The left_pos and top_pos
5953 are now relative to the top and left screen edges,
5954 so the flags should correspond. */
5955 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5958 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5959 to really change the position, and 0 when calling from
5960 x_make_frame_visible (in that case, XOFF and YOFF are the current
5961 position values). It is -1 when calling from x_set_frame_parameters,
5962 which means, do adjust for borders but don't change the gravity. */
5965 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5967 register int xoff
, yoff
;
5970 if (change_gravity
> 0)
5974 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5976 f
->size_hint_flags
|= XNegative
;
5978 f
->size_hint_flags
|= YNegative
;
5979 f
->win_gravity
= NorthWestGravity
;
5981 x_calc_absolute_position (f
);
5984 x_wm_set_size_hint (f
, (long) 0, 0);
5986 #if TARGET_API_MAC_CARBON
5987 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5988 /* If the title bar is completely outside the screen, adjust the
5990 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5991 kWindowConstrainMoveRegardlessOfFit
5992 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5993 #if USE_CARBON_EVENTS
5994 if (!NILP (tip_frame
) && XFRAME (tip_frame
) == f
)
5996 mac_handle_origin_change (f
);
5999 Rect inner
, outer
, screen_rect
, dummy
;
6000 RgnHandle region
= NewRgn ();
6002 mac_get_window_bounds (f
, &inner
, &outer
);
6003 f
->x_pixels_diff
= inner
.left
- outer
.left
;
6004 f
->y_pixels_diff
= inner
.top
- outer
.top
;
6005 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
6006 f
->top_pos
+ f
->y_pixels_diff
, false);
6008 /* If the title bar is completely outside the screen, adjust the
6009 position. The variable `outer' holds the title bar rectangle.
6010 The variable `inner' holds slightly smaller one than `outer',
6011 so that the calculation of overlapping may not become too
6013 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
6014 outer
= (*region
)->rgnBBox
;
6015 DisposeRgn (region
);
6017 InsetRect (&inner
, 8, 8);
6018 screen_rect
= qd
.screenBits
.bounds
;
6019 screen_rect
.top
+= GetMBarHeight ();
6021 if (!SectRect (&inner
, &screen_rect
, &dummy
))
6023 if (inner
.right
<= screen_rect
.left
)
6024 f
->left_pos
= screen_rect
.left
;
6025 else if (inner
.left
>= screen_rect
.right
)
6026 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
6028 if (inner
.bottom
<= screen_rect
.top
)
6029 f
->top_pos
= screen_rect
.top
;
6030 else if (inner
.top
>= screen_rect
.bottom
)
6031 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
6033 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
6034 f
->top_pos
+ f
->y_pixels_diff
, false);
6042 /* Call this to change the size of frame F's x-window.
6043 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
6044 for this size change and subsequent size changes.
6045 Otherwise we leave the window gravity unchanged. */
6048 x_set_window_size (f
, change_gravity
, cols
, rows
)
6053 int pixelwidth
, pixelheight
;
6057 check_frame_size (f
, &rows
, &cols
);
6058 f
->scroll_bar_actual_width
6059 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
6061 compute_fringe_widths (f
, 0);
6063 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
6064 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
6066 f
->win_gravity
= NorthWestGravity
;
6067 x_wm_set_size_hint (f
, (long) 0, 0);
6069 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
6071 #if USE_CARBON_EVENTS
6072 if (!NILP (tip_frame
) && f
== XFRAME (tip_frame
))
6074 mac_handle_size_change (f
, pixelwidth
, pixelheight
);
6079 /* Mouse warping. */
6081 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
6084 x_set_mouse_position (f
, x
, y
)
6090 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
6091 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
6093 if (pix_x
< 0) pix_x
= 0;
6094 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
6096 if (pix_y
< 0) pix_y
= 0;
6097 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
6099 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
6103 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
6112 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
6118 CGWarpMouseCursorPosition (point
);
6121 #if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
6124 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
6125 0, 0, 0, 0, pix_x
, pix_y
);
6131 /* focus shifting, raising and lowering. */
6134 x_focus_on_frame (f
)
6137 #if 0 /* This proves to be unpleasant. */
6141 /* I don't think that the ICCCM allows programs to do things like this
6142 without the interaction of the window manager. Whatever you end up
6143 doing with this code, do it to x_unfocus_frame too. */
6144 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6145 RevertToPointerRoot
, CurrentTime
);
6155 /* Raise frame F. */
6161 if (f
->async_visible
)
6164 BringToFront (FRAME_MAC_WINDOW (f
));
6169 /* Lower frame F. */
6175 if (f
->async_visible
)
6178 SendBehind (FRAME_MAC_WINDOW (f
), NULL
);
6184 XTframe_raise_lower (f
, raise_flag
)
6194 /* Change of visibility. */
6197 mac_handle_visibility_change (f
)
6200 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
6201 int visible
= 0, iconified
= 0;
6202 struct input_event buf
;
6204 if (IsWindowVisible (wp
))
6206 if (IsWindowCollapsed (wp
))
6212 if (!f
->async_visible
&& visible
)
6216 /* wait_reading_process_output will notice this and update
6217 the frame's display structures. If we were made
6218 invisible, we should not set garbaged, because that stops
6219 redrawing on Update events. */
6220 SET_FRAME_GARBAGED (f
);
6223 buf
.kind
= DEICONIFY_EVENT
;
6224 XSETFRAME (buf
.frame_or_window
, f
);
6226 kbd_buffer_store_event (&buf
);
6228 else if (! NILP (Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
6229 /* Force a redisplay sooner or later to update the
6230 frame titles in case this is the second frame. */
6231 record_asynch_buffer_change ();
6233 else if (f
->async_visible
&& !visible
)
6237 buf
.kind
= ICONIFY_EVENT
;
6238 XSETFRAME (buf
.frame_or_window
, f
);
6240 kbd_buffer_store_event (&buf
);
6243 f
->async_visible
= visible
;
6244 f
->async_iconified
= iconified
;
6247 /* This tries to wait until the frame is really visible.
6248 However, if the window manager asks the user where to position
6249 the frame, this will return before the user finishes doing that.
6250 The frame will not actually be visible at that time,
6251 but it will become visible later when the window manager
6252 finishes with it. */
6255 x_make_frame_visible (f
)
6260 if (! FRAME_VISIBLE_P (f
))
6262 /* We test FRAME_GARBAGED_P here to make sure we don't
6263 call x_set_offset a second time
6264 if we get to x_make_frame_visible a second time
6265 before the window gets really visible. */
6266 if (! FRAME_ICONIFIED_P (f
)
6267 && ! f
->output_data
.mac
->asked_for_visible
)
6269 #if TARGET_API_MAC_CARBON
6270 if (!(FRAME_SIZE_HINTS (f
)->flags
& (USPosition
| PPosition
)))
6272 struct frame
*sf
= SELECTED_FRAME ();
6273 if (!FRAME_MAC_P (sf
))
6274 RepositionWindow (FRAME_MAC_WINDOW (f
), NULL
,
6275 kWindowCenterOnMainScreen
);
6277 RepositionWindow (FRAME_MAC_WINDOW (f
),
6278 FRAME_MAC_WINDOW (sf
),
6279 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
6280 kWindowCascadeStartAtParentWindowScreen
6282 kWindowCascadeOnParentWindowScreen
6285 #if USE_CARBON_EVENTS
6286 if (!NILP (tip_frame
) && f
== XFRAME (tip_frame
))
6288 mac_handle_origin_change (f
);
6292 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
6295 f
->output_data
.mac
->asked_for_visible
= 1;
6297 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
6298 ShowWindow (FRAME_MAC_WINDOW (f
));
6301 XFlush (FRAME_MAC_DISPLAY (f
));
6303 /* Synchronize to ensure Emacs knows the frame is visible
6304 before we do anything else. We do this loop with input not blocked
6305 so that incoming events are handled. */
6310 /* This must come after we set COUNT. */
6313 XSETFRAME (frame
, f
);
6315 /* Wait until the frame is visible. Process X events until a
6316 MapNotify event has been seen, or until we think we won't get a
6317 MapNotify at all.. */
6318 for (count
= input_signal_count
+ 10;
6319 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
6321 /* Force processing of queued events. */
6324 /* Machines that do polling rather than SIGIO have been
6325 observed to go into a busy-wait here. So we'll fake an
6326 alarm signal to let the handler know that there's something
6327 to be read. We used to raise a real alarm, but it seems
6328 that the handler isn't always enabled here. This is
6330 if (input_polling_used ())
6332 /* It could be confusing if a real alarm arrives while
6333 processing the fake one. Turn it off and let the
6334 handler reset it. */
6335 extern void poll_for_input_1
P_ ((void));
6336 int old_poll_suppress_count
= poll_suppress_count
;
6337 poll_suppress_count
= 1;
6338 poll_for_input_1 ();
6339 poll_suppress_count
= old_poll_suppress_count
;
6342 /* See if a MapNotify event has been processed. */
6343 FRAME_SAMPLE_VISIBILITY (f
);
6348 /* Change from mapped state to withdrawn state. */
6350 /* Make the frame visible (mapped and not iconified). */
6353 x_make_frame_invisible (f
)
6356 /* A deactivate event does not occur when the last visible frame is
6357 made invisible. So if we clear the highlight here, it will not
6358 be rehighlighted when it is made visible. */
6360 /* Don't keep the highlight on an invisible frame. */
6361 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
6362 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
6367 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
6368 that the current position of the window is user-specified, rather than
6369 program-specified, so that when the window is mapped again, it will be
6370 placed at the same location, without forcing the user to position it
6371 by hand again (they have already done that once for this window.) */
6372 x_wm_set_size_hint (f
, (long) 0, 1);
6374 HideWindow (FRAME_MAC_WINDOW (f
));
6378 #if !USE_CARBON_EVENTS
6379 mac_handle_visibility_change (f
);
6383 /* Change window state from mapped to iconified. */
6391 /* A deactivate event does not occur when the last visible frame is
6392 iconified. So if we clear the highlight here, it will not be
6393 rehighlighted when it is deiconified. */
6395 /* Don't keep the highlight on an invisible frame. */
6396 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
6397 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
6400 if (f
->async_iconified
)
6405 FRAME_SAMPLE_VISIBILITY (f
);
6407 if (! FRAME_VISIBLE_P (f
))
6408 ShowWindow (FRAME_MAC_WINDOW (f
));
6410 err
= CollapseWindow (FRAME_MAC_WINDOW (f
), true);
6415 error ("Can't notify window manager of iconification");
6417 #if !USE_CARBON_EVENTS
6418 mac_handle_visibility_change (f
);
6423 /* Free X resources of frame F. */
6426 x_free_frame_resources (f
)
6429 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6430 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
6434 if (wp
!= tip_window
)
6435 remove_window_handler (wp
);
6438 if (wp
== tip_window
)
6439 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
6440 closed' event. So we reset tip_window here. */
6443 free_frame_menubar (f
);
6445 if (FRAME_FACE_CACHE (f
))
6446 free_frame_faces (f
);
6450 if (FRAME_SIZE_HINTS (f
))
6451 xfree (FRAME_SIZE_HINTS (f
));
6453 xfree (f
->output_data
.mac
);
6454 f
->output_data
.mac
= NULL
;
6456 if (f
== dpyinfo
->x_focus_frame
)
6458 dpyinfo
->x_focus_frame
= 0;
6459 #if USE_MAC_FONT_PANEL
6460 mac_set_font_info_for_selection (NULL
, DEFAULT_FACE_ID
, 0);
6463 if (f
== dpyinfo
->x_focus_event_frame
)
6464 dpyinfo
->x_focus_event_frame
= 0;
6465 if (f
== dpyinfo
->x_highlight_frame
)
6466 dpyinfo
->x_highlight_frame
= 0;
6468 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6470 dpyinfo
->mouse_face_beg_row
6471 = dpyinfo
->mouse_face_beg_col
= -1;
6472 dpyinfo
->mouse_face_end_row
6473 = dpyinfo
->mouse_face_end_col
= -1;
6474 dpyinfo
->mouse_face_window
= Qnil
;
6475 dpyinfo
->mouse_face_deferred_gc
= 0;
6476 dpyinfo
->mouse_face_mouse_frame
= 0;
6483 /* Destroy the X window of frame F. */
6486 x_destroy_window (f
)
6489 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6491 x_free_frame_resources (f
);
6493 dpyinfo
->reference_count
--;
6497 /* Setting window manager hints. */
6499 /* Set the normal size hints for the window manager, for frame F.
6500 FLAGS is the flags word to use--or 0 meaning preserve the flags
6501 that the window now has.
6502 If USER_POSITION is nonzero, we set the USPosition
6503 flag (this is useful when FLAGS is 0). */
6505 x_wm_set_size_hint (f
, flags
, user_position
)
6510 int base_width
, base_height
, width_inc
, height_inc
;
6511 int min_rows
= 0, min_cols
= 0;
6512 XSizeHints
*size_hints
;
6514 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
6515 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
6516 width_inc
= FRAME_COLUMN_WIDTH (f
);
6517 height_inc
= FRAME_LINE_HEIGHT (f
);
6519 check_frame_size (f
, &min_rows
, &min_cols
);
6521 size_hints
= FRAME_SIZE_HINTS (f
);
6522 if (size_hints
== NULL
)
6524 size_hints
= FRAME_SIZE_HINTS (f
) = xmalloc (sizeof (XSizeHints
));
6525 bzero (size_hints
, sizeof (XSizeHints
));
6528 size_hints
->flags
|= PResizeInc
| PMinSize
| PBaseSize
;
6529 size_hints
->width_inc
= width_inc
;
6530 size_hints
->height_inc
= height_inc
;
6531 size_hints
->min_width
= base_width
+ min_cols
* width_inc
;
6532 size_hints
->min_height
= base_height
+ min_rows
* height_inc
;
6533 size_hints
->base_width
= base_width
;
6534 size_hints
->base_height
= base_height
;
6537 size_hints
->flags
= flags
;
6538 else if (user_position
)
6540 size_hints
->flags
&= ~ PPosition
;
6541 size_hints
->flags
|= USPosition
;
6545 #if 0 /* MAC_TODO: hide application instead of iconify? */
6546 /* Used for IconicState or NormalState */
6549 x_wm_set_window_state (f
, state
)
6553 #ifdef USE_X_TOOLKIT
6556 XtSetArg (al
[0], XtNinitialState
, state
);
6557 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6558 #else /* not USE_X_TOOLKIT */
6559 Window window
= FRAME_X_WINDOW (f
);
6561 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
6562 f
->output_data
.x
->wm_hints
.initial_state
= state
;
6564 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6565 #endif /* not USE_X_TOOLKIT */
6569 x_wm_set_icon_pixmap (f
, pixmap_id
)
6575 #ifndef USE_X_TOOLKIT
6576 Window window
= FRAME_X_WINDOW (f
);
6581 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
6582 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
6586 /* It seems there is no way to turn off use of an icon pixmap.
6587 The following line does it, only if no icon has yet been created,
6588 for some window managers. But with mwm it crashes.
6589 Some people say it should clear the IconPixmapHint bit in this case,
6590 but that doesn't work, and the X consortium said it isn't the
6591 right thing at all. Since there is no way to win,
6592 best to explicitly give up. */
6594 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
6600 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
6604 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
6605 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6608 #else /* not USE_X_TOOLKIT */
6610 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
6611 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6613 #endif /* not USE_X_TOOLKIT */
6616 #endif /* MAC_TODO */
6619 x_wm_set_icon_position (f
, icon_x
, icon_y
)
6623 #if 0 /* MAC_TODO: no icons on Mac */
6624 #ifdef USE_X_TOOLKIT
6625 Window window
= XtWindow (f
->output_data
.x
->widget
);
6627 Window window
= FRAME_X_WINDOW (f
);
6630 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
6631 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
6632 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
6634 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6635 #endif /* MAC_TODO */
6639 /***********************************************************************
6641 ***********************************************************************/
6643 /* An XLFD pattern is divided into blocks delimited by '*'. This
6644 structure holds information for each block. */
6645 struct xlfdpat_block
6647 /* Length of the pattern string in this block. Non-zero except for
6648 the first and the last blocks. */
6651 /* Pattern string except the last character in this block. The last
6652 character is replaced with NUL in order to use it as a
6654 unsigned char *pattern
;
6656 /* Last character of the pattern string. Must not be '?'. */
6657 unsigned char last_char
;
6659 /* One of the tables for the Boyer-Moore string search. It
6660 specifies the number of positions to proceed for each character
6661 with which the match fails. */
6664 /* The skip value for the last character in the above `skip' is
6665 assigned to `infinity' in order to simplify a loop condition.
6666 The original value is saved here. */
6672 /* Normalized pattern string. "Normalized" means that capital
6673 letters are lowered, blocks are not empty except the first and
6674 the last ones, and trailing '?'s in a block that is not the last
6675 one are moved to the next one. The last character in each block
6676 is replaced with NUL. */
6679 /* Number of characters except '*'s and trailing '?'s in the
6680 normalized pattern string. */
6683 /* Number of trailing '?'s in the normalized pattern string. */
6684 int trailing_anychars
;
6686 /* Number of blocks and information for each block. The latter is
6687 NULL if the pattern is exact (no '*' or '?' in it). */
6689 struct xlfdpat_block
*blocks
;
6693 xlfdpat_destroy (pat
)
6694 struct xlfdpat
*pat
;
6701 xfree (pat
->blocks
);
6708 static struct xlfdpat
*
6709 xlfdpat_create (pattern
)
6710 const char *pattern
;
6712 struct xlfdpat
*pat
;
6713 int nblocks
, i
, skip
;
6714 unsigned char last_char
, *p
, *q
, *anychar_head
;
6715 const unsigned char *ptr
;
6716 struct xlfdpat_block
*blk
;
6718 pat
= xmalloc (sizeof (struct xlfdpat
));
6719 pat
->buf
= xmalloc (strlen (pattern
) + 1);
6721 /* Normalize the pattern string and store it to `pat->buf'. */
6723 anychar_head
= NULL
;
6726 for (ptr
= pattern
; *ptr
; ptr
++)
6728 unsigned char c
= *ptr
;
6731 if (last_char
== '*')
6732 /* ...a** -> ...a* */
6736 if (last_char
== '?')
6738 if (anychar_head
> pat
->buf
&& *(anychar_head
- 1) == '*')
6739 /* ...*??* -> ...*?? */
6742 /* ...a??* -> ...a*?? */
6744 *anychar_head
++ = '*';
6752 if (last_char
!= '?')
6756 /* On Mac OS X 10.3, tolower also converts non-ASCII
6757 characters for some locales. */
6761 *q
++ = last_char
= c
;
6765 pat
->nblocks
= nblocks
;
6766 if (last_char
!= '?')
6767 pat
->trailing_anychars
= 0;
6770 pat
->trailing_anychars
= q
- anychar_head
;
6773 pat
->nchars
= q
- pat
->buf
- (nblocks
- 1);
6775 if (anychar_head
== NULL
&& nblocks
== 1)
6777 /* The pattern is exact. */
6782 pat
->blocks
= xmalloc (sizeof (struct xlfdpat_block
) * nblocks
);
6784 /* Divide the normalized pattern into blocks. */
6786 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
- 1; blk
++)
6791 blk
->len
= p
- blk
->pattern
;
6795 blk
->len
= q
- blk
->pattern
;
6797 /* Setup a table for the Boyer-Moore string search. */
6798 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
; blk
++)
6801 blk
->last_char
= blk
->pattern
[blk
->len
- 1];
6802 blk
->pattern
[blk
->len
- 1] = '\0';
6804 for (skip
= 1; skip
< blk
->len
; skip
++)
6805 if (blk
->pattern
[blk
->len
- skip
- 1] == '?')
6808 for (i
= 0; i
< 256; i
++)
6809 blk
->skip
[i
] = skip
;
6811 p
= blk
->pattern
+ (blk
->len
- skip
);
6813 blk
->skip
[*p
++] = skip
;
6815 blk
->last_char_skip
= blk
->skip
[blk
->last_char
];
6822 xlfdpat_exact_p (pat
)
6823 struct xlfdpat
*pat
;
6825 return pat
->blocks
== NULL
;
6828 /* Return the first string in STRING + 0, ..., STRING + START_MAX such
6829 that the pattern in *BLK matches with its prefix. Return NULL
6830 there is no such strings. STRING must be lowered in advance. */
6833 xlfdpat_block_match_1 (blk
, string
, start_max
)
6834 struct xlfdpat_block
*blk
;
6835 const unsigned char *string
;
6838 int start
, infinity
;
6840 const unsigned char *s
;
6842 xassert (blk
->len
> 0);
6843 xassert (start_max
+ blk
->len
<= strlen (string
));
6844 xassert (blk
->last_char
!= '?');
6846 /* See the comments in the function `boyer_moore' (search.c) for the
6847 use of `infinity'. */
6848 infinity
= start_max
+ blk
->len
+ 1;
6849 blk
->skip
[blk
->last_char
] = infinity
;
6854 /* Check the last character of the pattern. */
6855 s
= string
+ blk
->len
- 1;
6858 start
+= blk
->skip
[*(s
+ start
)];
6860 while (start
<= start_max
);
6862 if (start
< infinity
)
6863 /* Couldn't find the last character. */
6866 /* No less than `infinity' means we could find the last
6867 character at `s[start - infinity]'. */
6870 /* Check the remaining characters. We prefer making no-'?'
6871 cases faster because the use of '?' is really rare. */
6876 while (*p
++ == *s
++)
6879 while (*(p
- 1) == '?');
6881 if (*(p
- 1) == '\0')
6883 return string
+ start
;
6886 start
+= blk
->last_char_skip
;
6888 while (start
<= start_max
);
6893 #define xlfdpat_block_match(b, s, m) \
6894 ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
6895 : xlfdpat_block_match_1 (b, s, m))
6897 /* Check if XLFD pattern PAT, which is generated by `xlfdpat_create',
6898 matches with STRING. STRING must be lowered in advance. */
6901 xlfdpat_match (pat
, string
)
6902 struct xlfdpat
*pat
;
6903 const unsigned char *string
;
6905 int str_len
, nblocks
, i
, start_max
;
6906 struct xlfdpat_block
*blk
;
6907 const unsigned char *s
;
6909 xassert (pat
->nblocks
> 0);
6911 if (xlfdpat_exact_p (pat
))
6912 return strcmp (pat
->buf
, string
) == 0;
6914 /* The number of the characters in the string must not be smaller
6915 than that in the pattern. */
6916 str_len
= strlen (string
);
6917 if (str_len
< pat
->nchars
+ pat
->trailing_anychars
)
6920 /* Chop off the trailing '?'s. */
6921 str_len
-= pat
->trailing_anychars
;
6923 /* The last block. When it is non-empty, it must match at the end
6925 nblocks
= pat
->nblocks
;
6926 blk
= pat
->blocks
+ (nblocks
- 1);
6928 /* The last block is also the first one. */
6929 return (str_len
== blk
->len
6930 && (blk
->len
== 0 || xlfdpat_block_match (blk
, string
, 0)));
6931 else if (blk
->len
!= 0)
6932 if (!xlfdpat_block_match (blk
, string
+ (str_len
- blk
->len
), 0))
6935 /* The first block. When it is non-empty, it must match at the
6936 beginning of the string. */
6940 s
= xlfdpat_block_match (blk
, string
, 0);
6943 string
= s
+ blk
->len
;
6946 /* The rest of the blocks. */
6947 start_max
= str_len
- pat
->nchars
;
6948 for (i
= 1, blk
++; i
< nblocks
- 1; i
++, blk
++)
6950 s
= xlfdpat_block_match (blk
, string
, start_max
);
6953 start_max
-= s
- string
;
6954 string
= s
+ blk
->len
;
6961 /***********************************************************************
6963 ***********************************************************************/
6965 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6968 x_get_font_info (f
, font_idx
)
6972 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
6975 /* the global font name table */
6976 static char **font_name_table
= NULL
;
6977 static int font_name_table_size
= 0;
6978 static int font_name_count
= 0;
6980 /* Alist linking font family names to Font Manager font family
6981 references (which can also be used as QuickDraw font IDs). We use
6982 an alist because hash tables are not ready when the terminal frame
6983 for Mac OS Classic is created. */
6984 static Lisp_Object fm_font_family_alist
;
6986 /* Hash table linking font family names to ATSU font IDs. */
6987 static Lisp_Object atsu_font_id_hash
;
6988 /* Alist linking Font Manager style to face attributes. */
6989 static Lisp_Object fm_style_face_attributes_alist
;
6990 static Lisp_Object Vmac_atsu_font_table
;
6991 extern Lisp_Object QCfamily
, QCweight
, QCslant
, Qnormal
, Qbold
, Qitalic
;
6994 /* Alist linking character set strings to Mac text encoding and Emacs
6996 static Lisp_Object Vmac_charset_info_alist
;
6999 create_text_encoding_info_alist ()
7001 Lisp_Object result
= Qnil
, rest
;
7003 for (rest
= Vmac_charset_info_alist
; CONSP (rest
); rest
= XCDR (rest
))
7005 Lisp_Object charset_info
= XCAR (rest
);
7006 Lisp_Object charset
, coding_system
, text_encoding
;
7007 Lisp_Object existing_info
;
7009 if (!(CONSP (charset_info
)
7010 && STRINGP (charset
= XCAR (charset_info
))
7011 && CONSP (XCDR (charset_info
))
7012 && INTEGERP (text_encoding
= XCAR (XCDR (charset_info
)))
7013 && CONSP (XCDR (XCDR (charset_info
)))
7014 && SYMBOLP (coding_system
= XCAR (XCDR (XCDR (charset_info
))))))
7017 existing_info
= assq_no_quit (text_encoding
, result
);
7018 if (NILP (existing_info
))
7019 result
= Fcons (list3 (text_encoding
, coding_system
, charset
),
7022 if (NILP (Fmember (charset
, XCDR (XCDR (existing_info
)))))
7023 XSETCDR (XCDR (existing_info
),
7024 Fcons (charset
, XCDR (XCDR (existing_info
))));
7032 decode_mac_font_name (name
, size
, coding_system
)
7035 Lisp_Object coding_system
;
7037 struct coding_system coding
;
7040 if (!NILP (coding_system
) && !NILP (Fcoding_system_p (coding_system
)))
7042 for (p
= name
; *p
; p
++)
7043 if (!isascii (*p
) || iscntrl (*p
))
7048 setup_coding_system (coding_system
, &coding
);
7049 coding
.src_multibyte
= 0;
7050 coding
.dst_multibyte
= 1;
7051 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
7052 coding
.composing
= COMPOSITION_DISABLED
;
7053 buf
= (char *) alloca (size
);
7055 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
7056 bcopy (buf
, name
, coding
.produced
);
7057 name
[coding
.produced
] = '\0';
7061 /* If there's just one occurrence of '-' in the family name, it is
7062 replaced with '_'. (More than one occurrence of '-' means a
7063 "FOUNDRY-FAMILY-CHARSET"-style name.) */
7064 p
= strchr (name
, '-');
7065 if (p
&& strchr (p
+ 1, '-') == NULL
)
7068 for (p
= name
; *p
; p
++)
7069 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
7070 for some locales. */
7077 mac_to_x_fontname (name
, size
, style
, charset
)
7085 char xf
[256], *result
;
7088 if (sscanf (name
, "%31[^-]-%255[^-]-%31s", foundry
, family
, cs
) == 3)
7092 strcpy(foundry
, "Apple");
7093 strcpy(family
, name
);
7096 sprintf (xf
, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
7097 style
& bold
? "bold" : "medium", style
& italic
? 'i' : 'r',
7098 size
, size
* 10, size
? 72 : 0, size
? 72 : 0, size
* 10, charset
);
7100 result
= xmalloc (strlen (foundry
) + strlen (family
) + strlen (xf
) + 3 + 1);
7101 sprintf (result
, "-%s-%s-%s", foundry
, family
, xf
);
7102 for (p
= result
; *p
; p
++)
7103 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
7104 for some locales. */
7111 /* Parse fully-specified and instantiated X11 font spec XF, and store
7112 the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the
7113 parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the
7114 caller must allocate at least 256 and 32 bytes respectively. For
7115 ordinary Mac fonts, the value stored to FAMILY should just be their
7116 names, like "monaco", "Taipei", etc. Fonts converted from the GNU
7117 intlfonts collection contain their charset designation in their
7118 names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both
7119 types of font names are handled accordingly. */
7121 const int kDefaultFontSize
= 12;
7124 parse_x_font_name (xf
, family
, size
, style
, charset
)
7131 Str31 foundry
, weight
;
7132 int point_size
, avgwidth
;
7135 if (sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
7136 foundry
, family
, weight
, slant
, size
,
7137 &point_size
, &avgwidth
, charset
) != 8
7138 && sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
7139 foundry
, family
, weight
, slant
, size
,
7140 &point_size
, &avgwidth
, charset
) != 8)
7146 *size
= point_size
/ 10;
7147 else if (avgwidth
> 0)
7148 *size
= avgwidth
/ 10;
7151 *size
= kDefaultFontSize
;
7154 if (strcmp (weight
, "bold") == 0)
7159 if (NILP (Fassoc (build_string (charset
), Vmac_charset_info_alist
)))
7161 int foundry_len
= strlen (foundry
), family_len
= strlen (family
);
7163 if (foundry_len
+ family_len
+ strlen (charset
) + 2 < sizeof (Str255
))
7165 /* Like sprintf (family, "%s-%s-%s", foundry, family, charset),
7166 but take overlap into account. */
7167 memmove (family
+ foundry_len
+ 1, family
, family_len
);
7168 memcpy (family
, foundry
, foundry_len
);
7169 family
[foundry_len
] = '-';
7170 family
[foundry_len
+ 1 + family_len
] = '-';
7171 strcpy (family
+ foundry_len
+ 1 + family_len
+ 1, charset
);
7177 for (p
= family
; *p
; p
++)
7178 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
7179 for some locales. */
7188 add_font_name_table_entry (char *font_name
)
7190 if (font_name_table_size
== 0)
7192 font_name_table_size
= 256;
7193 font_name_table
= (char **)
7194 xmalloc (font_name_table_size
* sizeof (char *));
7196 else if (font_name_count
+ 1 >= font_name_table_size
)
7198 font_name_table_size
*= 2;
7199 font_name_table
= (char **)
7200 xrealloc (font_name_table
,
7201 font_name_table_size
* sizeof (char *));
7204 font_name_table
[font_name_count
++] = font_name
;
7208 add_mac_font_name (name
, size
, style
, charset
)
7212 const char *charset
;
7215 add_font_name_table_entry (mac_to_x_fontname (name
, size
, style
, charset
));
7218 add_font_name_table_entry (mac_to_x_fontname (name
, 0, style
, charset
));
7219 add_font_name_table_entry (mac_to_x_fontname (name
, 0, italic
, charset
));
7220 add_font_name_table_entry (mac_to_x_fontname (name
, 0, bold
, charset
));
7221 add_font_name_table_entry (mac_to_x_fontname (name
, 0, italic
| bold
,
7228 fm_style_to_face_attributes (fm_style
)
7229 FMFontStyle fm_style
;
7233 fm_style
&= (bold
| italic
);
7234 tem
= assq_no_quit (make_number (fm_style
),
7235 fm_style_face_attributes_alist
);
7239 tem
= list4 (QCweight
, fm_style
& bold
? Qbold
: Qnormal
,
7240 QCslant
, fm_style
& italic
? Qitalic
: Qnormal
);
7241 fm_style_face_attributes_alist
=
7242 Fcons (Fcons (make_number (fm_style
), tem
),
7243 fm_style_face_attributes_alist
);
7249 /* Sets up the table font_name_table to contain the list of all fonts
7250 in the system the first time the table is used so that the Resource
7251 Manager need not be accessed every time this information is
7255 init_font_name_table ()
7257 #if TARGET_API_MAC_CARBON
7258 FMFontFamilyIterator ffi
;
7259 FMFontFamilyInstanceIterator ffii
;
7261 Lisp_Object text_encoding_info_alist
;
7262 struct gcpro gcpro1
;
7264 text_encoding_info_alist
= create_text_encoding_info_alist ();
7267 #if USE_CG_TEXT_DRAWING
7268 init_cg_text_anti_aliasing_threshold ();
7270 if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode
),
7271 text_encoding_info_alist
)))
7274 struct Lisp_Hash_Table
*h
;
7276 ItemCount nfonts
, i
;
7277 ATSUFontID
*font_ids
= NULL
;
7283 make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
7284 make_float (DEFAULT_REHASH_SIZE
),
7285 make_float (DEFAULT_REHASH_THRESHOLD
),
7287 h
= XHASH_TABLE (atsu_font_id_hash
);
7289 err
= ATSUFontCount (&nfonts
);
7292 font_ids
= xmalloc (sizeof (ATSUFontID
) * nfonts
);
7293 err
= ATSUGetFontIDs (font_ids
, nfonts
, NULL
);
7296 for (i
= 0; i
< nfonts
; i
++)
7298 err
= ATSUFindFontName (font_ids
[i
], kFontFamilyName
,
7299 kFontMacintoshPlatform
, kFontNoScript
,
7300 kFontNoLanguage
, 0, NULL
, &name_len
, NULL
);
7303 name
= xmalloc (name_len
+ 1);
7304 name
[name_len
] = '\0';
7305 err
= ATSUFindFontName (font_ids
[i
], kFontFamilyName
,
7306 kFontMacintoshPlatform
, kFontNoScript
,
7307 kFontNoLanguage
, name_len
, name
,
7312 FMFontStyle style
= normal
;
7314 decode_mac_font_name (name
, name_len
+ 1, Qnil
);
7315 family
= make_unibyte_string (name
, name_len
);
7316 FMGetFontFamilyInstanceFromFont (font_ids
[i
], &ff
, &style
);
7317 Fputhash ((font_ids
[i
] > MOST_POSITIVE_FIXNUM
7318 ? make_float (font_ids
[i
])
7319 : make_number (font_ids
[i
])),
7322 fm_style_to_face_attributes (style
))),
7323 Vmac_atsu_font_table
);
7325 && hash_lookup (h
, family
, &hash_code
) < 0)
7327 add_mac_font_name (name
, 0, normal
, "iso10646-1");
7328 hash_put (h
, family
, long_to_cons (font_ids
[i
]),
7339 /* Create a dummy instance iterator here to avoid creating and
7340 destroying it in the loop. */
7341 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
7343 /* Create an iterator to enumerate the font families. */
7344 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
7347 FMDisposeFontFamilyInstanceIterator (&ffii
);
7351 GCPRO1 (text_encoding_info_alist
);
7353 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
7359 TextEncoding encoding
;
7360 TextEncodingBase sc
;
7361 Lisp_Object text_encoding_info
, family
;
7363 if (FMGetFontFamilyName (ff
, name
) != noErr
)
7369 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
7371 sc
= GetTextEncodingBase (encoding
);
7372 text_encoding_info
= assq_no_quit (make_number (sc
),
7373 text_encoding_info_alist
);
7374 if (NILP (text_encoding_info
))
7375 text_encoding_info
= assq_no_quit (make_number (kTextEncodingMacRoman
),
7376 text_encoding_info_alist
);
7377 decode_mac_font_name (name
, sizeof (name
),
7378 XCAR (XCDR (text_encoding_info
)));
7379 family
= build_string (name
);
7380 if (!NILP (Fassoc (family
, fm_font_family_alist
)))
7382 fm_font_family_alist
= Fcons (Fcons (family
, make_number (ff
)),
7383 fm_font_family_alist
);
7385 /* Point the instance iterator at the current font family. */
7386 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
7389 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
7392 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7394 if (size
> 0 || style
== normal
)
7395 for (; !NILP (rest
); rest
= XCDR (rest
))
7396 add_mac_font_name (name
, size
, style
, SDATA (XCAR (rest
)));
7402 /* Dispose of the iterators. */
7403 FMDisposeFontFamilyIterator (&ffi
);
7404 FMDisposeFontFamilyInstanceIterator (&ffii
);
7405 #else /* !TARGET_API_MAC_CARBON */
7407 SInt16 fontnum
, old_fontnum
;
7408 int num_mac_fonts
= CountResources('FOND');
7410 Handle font_handle
, font_handle_2
;
7411 short id
, scriptcode
;
7414 struct FontAssoc
*fat
;
7415 struct AsscEntry
*assc_entry
;
7416 Lisp_Object text_encoding_info_alist
, text_encoding_info
, family
;
7417 struct gcpro gcpro1
;
7419 GetPort (&port
); /* save the current font number used */
7420 old_fontnum
= port
->txFont
;
7422 text_encoding_info_alist
= create_text_encoding_info_alist ();
7424 GCPRO1 (text_encoding_info_alist
);
7426 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
7428 font_handle
= GetIndResource ('FOND', i
);
7432 GetResInfo (font_handle
, &id
, &type
, name
);
7433 GetFNum (name
, &fontnum
);
7435 if (fontnum
== 0 || *name
== '.')
7439 scriptcode
= FontToScript (fontnum
);
7440 text_encoding_info
= assq_no_quit (make_number (scriptcode
),
7441 text_encoding_info_alist
);
7442 if (NILP (text_encoding_info
))
7443 text_encoding_info
= assq_no_quit (make_number (smRoman
),
7444 text_encoding_info_alist
);
7445 decode_mac_font_name (name
, sizeof (name
),
7446 XCAR (XCDR (text_encoding_info
)));
7447 family
= build_string (name
);
7448 if (!NILP (Fassoc (family
, fm_font_family_alist
)))
7450 fm_font_family_alist
= Fcons (Fcons (family
, make_number (fontnum
)),
7451 fm_font_family_alist
);
7454 HLock (font_handle
);
7456 if (GetResourceSizeOnDisk (font_handle
)
7457 >= sizeof (struct FamRec
))
7459 fat
= (struct FontAssoc
*) (*font_handle
7460 + sizeof (struct FamRec
));
7462 = (struct AsscEntry
*) (*font_handle
7463 + sizeof (struct FamRec
)
7464 + sizeof (struct FontAssoc
));
7466 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
7468 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7470 for (; !NILP (rest
); rest
= XCDR (rest
))
7471 add_mac_font_name (name
, assc_entry
->fontSize
,
7472 assc_entry
->fontStyle
,
7473 SDATA (XCAR (rest
)));
7477 HUnlock (font_handle
);
7478 font_handle_2
= GetNextFOND (font_handle
);
7479 ReleaseResource (font_handle
);
7480 font_handle
= font_handle_2
;
7482 while (ResError () == noErr
&& font_handle
);
7487 TextFont (old_fontnum
);
7488 #endif /* !TARGET_API_MAC_CARBON */
7493 mac_clear_font_name_table ()
7497 for (i
= 0; i
< font_name_count
; i
++)
7498 xfree (font_name_table
[i
]);
7499 xfree (font_name_table
);
7500 font_name_table
= NULL
;
7501 font_name_table_size
= font_name_count
= 0;
7502 fm_font_family_alist
= Qnil
;
7506 enum xlfd_scalable_field_index
7508 XLFD_SCL_PIXEL_SIZE
,
7509 XLFD_SCL_POINT_SIZE
,
7514 static const int xlfd_scalable_fields
[] =
7523 mac_do_list_fonts (pattern
, maxnames
)
7524 const char *pattern
;
7528 Lisp_Object font_list
= Qnil
;
7529 struct xlfdpat
*pat
;
7532 int scl_val
[XLFD_SCL_LAST
], *val
;
7536 if (font_name_table
== NULL
) /* Initialize when first used. */
7537 init_font_name_table ();
7539 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
7542 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
7543 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
7544 fonts are scaled according to the specified size. */
7547 field
= xlfd_scalable_fields
;
7555 if ('0' <= *ptr
&& *ptr
<= '9')
7557 *val
= *ptr
++ - '0';
7558 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
7559 *val
= *val
* 10 + *ptr
++ - '0';
7566 ptr
= strchr (ptr
, '-');
7569 while (ptr
&& i
< 14);
7571 if (i
== 14 && ptr
== NULL
)
7573 if (scl_val
[XLFD_SCL_PIXEL_SIZE
] < 0)
7574 scl_val
[XLFD_SCL_PIXEL_SIZE
] =
7575 (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
] / 10
7576 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
] / 10
7578 if (scl_val
[XLFD_SCL_POINT_SIZE
] < 0)
7579 scl_val
[XLFD_SCL_POINT_SIZE
] =
7580 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7581 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
]
7583 if (scl_val
[XLFD_SCL_AVGWIDTH
] < 0)
7584 scl_val
[XLFD_SCL_AVGWIDTH
] =
7585 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7586 : (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
]
7590 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
7592 pat
= xlfdpat_create (pattern
);
7596 exact
= xlfdpat_exact_p (pat
);
7598 for (i
= 0; i
< font_name_count
; i
++)
7600 if (xlfdpat_match (pat
, font_name_table
[i
]))
7602 font_list
= Fcons (build_string (font_name_table
[i
]), font_list
);
7603 if (exact
|| (maxnames
> 0 && ++n_fonts
>= maxnames
))
7606 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
7607 && (ptr
= strstr (font_name_table
[i
], "-0-0-0-0-m-0-")))
7609 int former_len
= ptr
- font_name_table
[i
];
7611 scaled
= xmalloc (strlen (font_name_table
[i
]) + 20 + 1);
7612 memcpy (scaled
, font_name_table
[i
], former_len
);
7613 sprintf (scaled
+ former_len
,
7614 "-%d-%d-72-72-m-%d-%s",
7615 scl_val
[XLFD_SCL_PIXEL_SIZE
],
7616 scl_val
[XLFD_SCL_POINT_SIZE
],
7617 scl_val
[XLFD_SCL_AVGWIDTH
],
7618 ptr
+ sizeof ("-0-0-0-0-m-0-") - 1);
7620 if (xlfdpat_match (pat
, scaled
))
7622 font_list
= Fcons (build_string (scaled
), font_list
);
7624 if (exact
|| (maxnames
> 0 && ++n_fonts
>= maxnames
))
7632 xlfdpat_destroy (pat
);
7637 /* Return a list of names of available fonts matching PATTERN on frame F.
7639 Frame F null means we have not yet created any frame on Mac, and
7640 consult the first display in x_display_list. MAXNAMES sets a limit
7641 on how many fonts to match. */
7644 x_list_fonts (f
, pattern
, size
, maxnames
)
7646 Lisp_Object pattern
;
7649 Lisp_Object list
= Qnil
, patterns
, tem
, key
;
7650 struct mac_display_info
*dpyinfo
7651 = f
? FRAME_MAC_DISPLAY_INFO (f
) : x_display_list
;
7653 xassert (size
<= 0);
7655 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
7656 if (NILP (patterns
))
7657 patterns
= Fcons (pattern
, Qnil
);
7659 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
7661 pattern
= XCAR (patterns
);
7663 if (!STRINGP (pattern
))
7666 tem
= XCAR (XCDR (dpyinfo
->name_list_element
));
7667 key
= Fcons (pattern
, make_number (maxnames
));
7669 list
= Fassoc (key
, tem
);
7672 list
= Fcdr_safe (list
);
7673 /* We have a cashed list. Don't have to get the list again. */
7678 list
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
7681 /* MAC_TODO: add code for matching outline fonts here */
7683 /* Now store the result in the cache. */
7684 XSETCAR (XCDR (dpyinfo
->name_list_element
),
7685 Fcons (Fcons (key
, list
),
7686 XCAR (XCDR (dpyinfo
->name_list_element
))));
7689 if (NILP (list
)) continue; /* Try the remaining alternatives. */
7698 /* Check that FONT is valid on frame F. It is if it can be found in F's
7702 x_check_font (f
, font
)
7707 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7709 xassert (font
!= NULL
);
7711 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7712 if (dpyinfo
->font_table
[i
].name
7713 && font
== dpyinfo
->font_table
[i
].font
)
7716 xassert (i
< dpyinfo
->n_fonts
);
7719 #endif /* GLYPH_DEBUG != 0 */
7721 /* Set *W to the minimum width, *H to the minimum font height of FONT.
7722 Note: There are (broken) X fonts out there with invalid XFontStruct
7723 min_bounds contents. For example, handa@etl.go.jp reports that
7724 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
7725 have font->min_bounds.width == 0. */
7728 x_font_min_bounds (font
, w
, h
)
7729 MacFontStruct
*font
;
7732 *h
= FONT_HEIGHT (font
);
7733 *w
= font
->min_bounds
.width
;
7737 /* Compute the smallest character width and smallest font height over
7738 all fonts available on frame F. Set the members smallest_char_width
7739 and smallest_font_height in F's x_display_info structure to
7740 the values computed. Value is non-zero if smallest_font_height or
7741 smallest_char_width become smaller than they were before. */
7744 x_compute_min_glyph_bounds (f
)
7748 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7749 MacFontStruct
*font
;
7750 int old_width
= dpyinfo
->smallest_char_width
;
7751 int old_height
= dpyinfo
->smallest_font_height
;
7753 dpyinfo
->smallest_font_height
= 100000;
7754 dpyinfo
->smallest_char_width
= 100000;
7756 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7757 if (dpyinfo
->font_table
[i
].name
)
7759 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
7762 font
= (MacFontStruct
*) fontp
->font
;
7763 xassert (font
!= (MacFontStruct
*) ~0);
7764 x_font_min_bounds (font
, &w
, &h
);
7766 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
7767 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
7770 xassert (dpyinfo
->smallest_char_width
> 0
7771 && dpyinfo
->smallest_font_height
> 0);
7773 return (dpyinfo
->n_fonts
== 1
7774 || dpyinfo
->smallest_char_width
< old_width
7775 || dpyinfo
->smallest_font_height
< old_height
);
7779 /* Determine whether given string is a fully-specified XLFD: all 14
7780 fields are present, none is '*'. */
7783 is_fully_specified_xlfd (p
)
7792 for (i
= 0; i
< 13; i
++)
7794 q
= strchr (p
+ 1, '-');
7797 if (q
- p
== 2 && *(p
+ 1) == '*')
7802 if (strchr (p
+ 1, '-') != NULL
)
7805 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
7812 /* mac_load_query_font creates and returns an internal representation
7813 for a font in a MacFontStruct struct. There is really no concept
7814 corresponding to "loading" a font on the Mac. But we check its
7815 existence and find the font number and all other information for it
7816 and store them in the returned MacFontStruct. */
7818 static MacFontStruct
*
7819 mac_load_query_font (f
, fontname
)
7829 static ATSUFontID font_id
;
7830 ATSUStyle mac_style
= NULL
;
7833 #if TARGET_API_MAC_CARBON
7834 TextEncoding encoding
;
7839 MacFontStruct
*font
;
7840 XCharStruct
*space_bounds
= NULL
, *pcm
;
7842 if (is_fully_specified_xlfd (fontname
))
7846 Lisp_Object matched_fonts
;
7848 matched_fonts
= mac_do_list_fonts (fontname
, 1);
7849 if (NILP (matched_fonts
))
7851 name
= SDATA (XCAR (matched_fonts
));
7854 if (parse_x_font_name (name
, family
, &size
, &fontface
, charset
) == 0)
7858 if (strcmp (charset
, "iso10646-1") == 0) /* XXX */
7861 static const ATSUAttributeTag tags
[] =
7862 {kATSUFontTag
, kATSUSizeTag
,
7863 kATSUQDBoldfaceTag
, kATSUQDItalicTag
};
7864 static const ByteCount sizes
[] =
7865 {sizeof (ATSUFontID
), sizeof (Fixed
),
7866 sizeof (Boolean
), sizeof (Boolean
)};
7867 static Fixed size_fixed
;
7868 static Boolean bold_p
, italic_p
;
7869 static const ATSUAttributeValuePtr values
[] =
7870 {&font_id
, &size_fixed
,
7871 &bold_p
, &italic_p
};
7872 static const ATSUFontFeatureType types
[] =
7873 {kAllTypographicFeaturesType
, kDiacriticsType
};
7874 static const ATSUFontFeatureSelector selectors
[] =
7875 {kAllTypeFeaturesOffSelector
, kDecomposeDiacriticsSelector
};
7876 Lisp_Object font_id_cons
;
7879 font_id_cons
= Fgethash (make_unibyte_string (family
, strlen (family
)),
7880 atsu_font_id_hash
, Qnil
);
7881 if (NILP (font_id_cons
))
7883 font_id
= cons_to_long (font_id_cons
);
7884 size_fixed
= Long2Fix (size
);
7885 bold_p
= (fontface
& bold
) != 0;
7886 italic_p
= (fontface
& italic
) != 0;
7887 err
= ATSUCreateStyle (&mac_style
);
7890 err
= ATSUSetFontFeatures (mac_style
, sizeof (types
) / sizeof (types
[0]),
7894 err
= ATSUSetAttributes (mac_style
, sizeof (tags
) / sizeof (tags
[0]),
7895 tags
, sizes
, values
);
7898 err
= FMGetFontFamilyInstanceFromFont (font_id
, &fontnum
, &style
);
7901 scriptcode
= kTextEncodingMacUnicode
;
7906 Lisp_Object tmp
= Fassoc (build_string (family
), fm_font_family_alist
);
7910 fontnum
= XINT (XCDR (tmp
));
7911 #if TARGET_API_MAC_CARBON
7912 if (FMGetFontFamilyTextEncoding (fontnum
, &encoding
) != noErr
)
7914 scriptcode
= GetTextEncodingBase (encoding
);
7916 scriptcode
= FontToScript (fontnum
);
7920 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
7922 font
->mac_fontnum
= fontnum
;
7923 font
->mac_fontsize
= size
;
7924 font
->mac_fontface
= fontface
;
7925 font
->mac_scriptcode
= scriptcode
;
7927 font
->mac_style
= mac_style
;
7928 #if USE_CG_TEXT_DRAWING
7929 font
->cg_font
= NULL
;
7930 font
->cg_glyphs
= NULL
;
7934 /* Apple Japanese (SJIS) font is listed as both
7935 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
7936 (Roman script) in init_font_name_table (). The latter should be
7937 treated as a one-byte font. */
7938 if (scriptcode
== smJapanese
&& strcmp (charset
, "jisx0201.1976-0") == 0)
7939 font
->mac_scriptcode
= smRoman
;
7941 font
->full_name
= mac_to_x_fontname (family
, size
, fontface
, charset
);
7944 if (font
->mac_style
)
7949 font
->min_byte1
= 0;
7950 font
->max_byte1
= 0xff;
7951 font
->min_char_or_byte2
= 0;
7952 font
->max_char_or_byte2
= 0xff;
7954 font
->bounds
.rows
= xmalloc (sizeof (XCharStruct
*) * 0x100);
7955 bzero (font
->bounds
.rows
, sizeof (XCharStruct
*) * 0x100);
7956 font
->bounds
.rows
[0] = xmalloc (sizeof (XCharStruct
) * 0x100);
7957 pcm_init (font
->bounds
.rows
[0], 0x100);
7959 #if USE_CG_TEXT_DRAWING
7963 ATSFontRef ats_font
;
7965 err
= FMGetFontFromFontFamilyInstance (fontnum
, fontface
,
7967 /* Use CG text drawing if italic/bold is not synthesized. */
7968 if (err
== noErr
&& style
== fontface
)
7970 ats_font
= FMGetATSFontRefFromFont (font_id
);
7971 font
->cg_font
= CGFontCreateWithPlatformFont (&ats_font
);
7977 font
->cg_glyphs
= xmalloc (sizeof (CGGlyph
) * 0x100);
7978 bzero (font
->cg_glyphs
, sizeof (CGGlyph
) * 0x100);
7981 space_bounds
= font
->bounds
.rows
[0] + 0x20;
7982 err
= mac_query_char_extents (font
->mac_style
, 0x20,
7983 &font
->ascent
, &font
->descent
,
7985 #if USE_CG_TEXT_DRAWING
7986 (font
->cg_glyphs
? font
->cg_glyphs
+ 0x20
7993 || space_bounds
->width
<= 0 || FONT_HEIGHT (font
) <= 0)
7995 mac_unload_font (&one_mac_display_info
, font
);
7999 pcm
= font
->bounds
.rows
[0];
8000 for (c
= 0x21; c
<= 0xff; c
++)
8003 /* Soft hyphen is not supported in ATSUI. */
8011 mac_query_char_extents (font
->mac_style
, c
, NULL
, NULL
, pcm
+ c
,
8012 #if USE_CG_TEXT_DRAWING
8013 (font
->cg_glyphs
? font
->cg_glyphs
+ c
8020 #if USE_CG_TEXT_DRAWING
8021 if (font
->cg_glyphs
&& font
->cg_glyphs
[c
] == 0)
8023 /* Don't use CG text drawing if font substitution occurs in
8024 ASCII or Latin-1 characters. */
8025 CGFontRelease (font
->cg_font
);
8026 font
->cg_font
= NULL
;
8027 xfree (font
->cg_glyphs
);
8028 font
->cg_glyphs
= NULL
;
8036 FontInfo the_fontinfo
;
8037 int is_two_byte_font
;
8040 mac_prepare_for_quickdraw (f
);
8042 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
8046 TextFace (fontface
);
8048 GetFontInfo (&the_fontinfo
);
8050 font
->ascent
= the_fontinfo
.ascent
;
8051 font
->descent
= the_fontinfo
.descent
;
8053 is_two_byte_font
= (font
->mac_scriptcode
== smJapanese
8054 || font
->mac_scriptcode
== smTradChinese
8055 || font
->mac_scriptcode
== smSimpChinese
8056 || font
->mac_scriptcode
== smKorean
);
8058 if (is_two_byte_font
)
8062 font
->min_byte1
= 0xa1;
8063 font
->max_byte1
= 0xfe;
8064 font
->min_char_or_byte2
= 0xa1;
8065 font
->max_char_or_byte2
= 0xfe;
8067 /* Use the width of an "ideographic space" of that font
8068 because the_fontinfo.widMax returns the wrong width for
8070 switch (font
->mac_scriptcode
)
8073 font
->min_byte1
= 0x81;
8074 font
->max_byte1
= 0xfc;
8075 font
->min_char_or_byte2
= 0x40;
8076 font
->max_char_or_byte2
= 0xfc;
8077 char_width
= StringWidth("\p\x81\x40");
8080 font
->min_char_or_byte2
= 0x40;
8081 char_width
= StringWidth("\p\xa1\x40");
8084 char_width
= StringWidth("\p\xa1\xa1");
8087 char_width
= StringWidth("\p\xa1\xa1");
8091 font
->bounds
.per_char
= NULL
;
8093 if (fontface
& italic
)
8094 font
->max_bounds
.rbearing
= char_width
+ 1;
8096 font
->max_bounds
.rbearing
= char_width
;
8097 font
->max_bounds
.lbearing
= 0;
8098 font
->max_bounds
.width
= char_width
;
8099 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
8100 font
->max_bounds
.descent
= the_fontinfo
.descent
;
8102 font
->min_bounds
= font
->max_bounds
;
8108 font
->min_byte1
= font
->max_byte1
= 0;
8109 font
->min_char_or_byte2
= 0x20;
8110 font
->max_char_or_byte2
= 0xff;
8112 font
->bounds
.per_char
=
8113 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
8114 bzero (font
->bounds
.per_char
,
8115 sizeof (XCharStruct
) * (0xff - 0x20 + 1));
8117 space_bounds
= font
->bounds
.per_char
;
8118 mac_query_char_extents (NULL
, 0x20, &font
->ascent
, &font
->descent
,
8119 space_bounds
, NULL
);
8121 for (c
= 0x21, pcm
= space_bounds
+ 1; c
<= 0xff; c
++, pcm
++)
8122 mac_query_char_extents (NULL
, c
, NULL
, NULL
, pcm
, NULL
);
8130 font
->min_bounds
= font
->max_bounds
= *space_bounds
;
8131 for (c
= 0x21, pcm
= space_bounds
+ 1; c
<= 0x7f; c
++, pcm
++)
8134 font
->min_bounds
.lbearing
= min (font
->min_bounds
.lbearing
,
8136 font
->min_bounds
.rbearing
= min (font
->min_bounds
.rbearing
,
8138 font
->min_bounds
.width
= min (font
->min_bounds
.width
,
8140 font
->min_bounds
.ascent
= min (font
->min_bounds
.ascent
,
8142 font
->min_bounds
.descent
= min (font
->min_bounds
.descent
,
8145 font
->max_bounds
.lbearing
= max (font
->max_bounds
.lbearing
,
8147 font
->max_bounds
.rbearing
= max (font
->max_bounds
.rbearing
,
8149 font
->max_bounds
.width
= max (font
->max_bounds
.width
,
8151 font
->max_bounds
.ascent
= max (font
->max_bounds
.ascent
,
8153 font
->max_bounds
.descent
= max (font
->max_bounds
.descent
,
8158 font
->mac_style
== NULL
&&
8160 font
->max_bounds
.width
== font
->min_bounds
.width
8161 && font
->min_bounds
.lbearing
>= 0
8162 && font
->max_bounds
.rbearing
<= font
->max_bounds
.width
)
8164 /* Fixed width and no overhangs. */
8165 xfree (font
->bounds
.per_char
);
8166 font
->bounds
.per_char
= NULL
;
8170 #if !defined (MAC_OS8) || USE_ATSUI
8171 /* AppKit and WebKit do some adjustment to the heights of Courier,
8172 Helvetica, and Times. This only works on the environments where
8173 srcCopy text transfer mode is never used. */
8175 #ifdef MAC_OS8 /* implies USE_ATSUI */
8178 (strcmp (family
, "courier") == 0 || strcmp (family
, "helvetica") == 0
8179 || strcmp (family
, "times") == 0))
8180 font
->ascent
+= (font
->ascent
+ font
->descent
) * .15 + 0.5;
8188 mac_unload_font (dpyinfo
, font
)
8189 struct mac_display_info
*dpyinfo
;
8192 xfree (font
->full_name
);
8194 if (font
->mac_style
)
8198 for (i
= font
->min_byte1
; i
<= font
->max_byte1
; i
++)
8199 if (font
->bounds
.rows
[i
])
8200 xfree (font
->bounds
.rows
[i
]);
8201 xfree (font
->bounds
.rows
);
8202 ATSUDisposeStyle (font
->mac_style
);
8206 if (font
->bounds
.per_char
)
8207 xfree (font
->bounds
.per_char
);
8208 #if USE_CG_TEXT_DRAWING
8210 CGFontRelease (font
->cg_font
);
8211 if (font
->cg_glyphs
)
8212 xfree (font
->cg_glyphs
);
8218 /* Load font named FONTNAME of the size SIZE for frame F, and return a
8219 pointer to the structure font_info while allocating it dynamically.
8220 If SIZE is 0, load any size of font.
8221 If loading is failed, return NULL. */
8224 x_load_font (f
, fontname
, size
)
8226 register char *fontname
;
8229 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8230 Lisp_Object font_names
;
8232 /* Get a list of all the fonts that match this name. Once we
8233 have a list of matching fonts, we compare them against the fonts
8234 we already have by comparing names. */
8235 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
8237 if (!NILP (font_names
))
8242 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8243 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
8244 if (dpyinfo
->font_table
[i
].name
8245 && (!strcmp (dpyinfo
->font_table
[i
].name
,
8246 SDATA (XCAR (tail
)))
8247 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
8248 SDATA (XCAR (tail
)))))
8249 return (dpyinfo
->font_table
+ i
);
8254 /* Load the font and add it to the table. */
8256 struct MacFontStruct
*font
;
8257 struct font_info
*fontp
;
8260 fontname
= (char *) SDATA (XCAR (font_names
));
8263 font
= mac_load_query_font (f
, fontname
);
8268 /* Find a free slot in the font table. */
8269 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8270 if (dpyinfo
->font_table
[i
].name
== NULL
)
8273 /* If no free slot found, maybe enlarge the font table. */
8274 if (i
== dpyinfo
->n_fonts
8275 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
8278 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
8279 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
8281 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
8284 fontp
= dpyinfo
->font_table
+ i
;
8285 if (i
== dpyinfo
->n_fonts
)
8288 /* Now fill in the slots of *FONTP. */
8290 bzero (fontp
, sizeof (*fontp
));
8292 fontp
->font_idx
= i
;
8293 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
8294 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
8296 if (font
->min_bounds
.width
== font
->max_bounds
.width
)
8298 /* Fixed width font. */
8299 fontp
->average_width
= fontp
->space_width
= font
->min_bounds
.width
;
8306 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
8307 pcm
= mac_per_char_metric (font
, &char2b
, 0);
8309 fontp
->space_width
= pcm
->width
;
8311 fontp
->space_width
= FONT_WIDTH (font
);
8315 int width
= pcm
->width
;
8316 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
8317 if ((pcm
= mac_per_char_metric (font
, &char2b
, 0)) != NULL
)
8318 width
+= pcm
->width
;
8319 fontp
->average_width
= width
/ 95;
8322 fontp
->average_width
= FONT_WIDTH (font
);
8325 fontp
->full_name
= (char *) xmalloc (strlen (font
->full_name
) + 1);
8326 bcopy (font
->full_name
, fontp
->full_name
, strlen (font
->full_name
) + 1);
8328 fontp
->size
= font
->max_bounds
.width
;
8329 fontp
->height
= FONT_HEIGHT (font
);
8331 /* For some font, ascent and descent in max_bounds field is
8332 larger than the above value. */
8333 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
8334 if (max_height
> fontp
->height
)
8335 fontp
->height
= max_height
;
8338 /* The slot `encoding' specifies how to map a character
8339 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
8340 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
8341 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
8342 2:0xA020..0xFF7F). For the moment, we don't know which charset
8343 uses this font. So, we set information in fontp->encoding[1]
8344 which is never used by any charset. If mapping can't be
8345 decided, set FONT_ENCODING_NOT_DECIDED. */
8346 if (font
->mac_scriptcode
== smJapanese
)
8347 fontp
->encoding
[1] = 4;
8351 = (font
->max_byte1
== 0
8353 ? (font
->min_char_or_byte2
< 0x80
8354 ? (font
->max_char_or_byte2
< 0x80
8355 ? 0 /* 0x20..0x7F */
8356 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
8357 : 1) /* 0xA0..0xFF */
8359 : (font
->min_byte1
< 0x80
8360 ? (font
->max_byte1
< 0x80
8361 ? (font
->min_char_or_byte2
< 0x80
8362 ? (font
->max_char_or_byte2
< 0x80
8363 ? 0 /* 0x2020..0x7F7F */
8364 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
8365 : 3) /* 0x20A0..0x7FFF */
8366 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
8367 : (font
->min_char_or_byte2
< 0x80
8368 ? (font
->max_char_or_byte2
< 0x80
8369 ? 2 /* 0xA020..0xFF7F */
8370 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
8371 : 1))); /* 0xA0A0..0xFFFF */
8374 #if 0 /* MAC_TODO: fill these out with more reasonably values */
8375 fontp
->baseline_offset
8376 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
8377 ? (long) value
: 0);
8378 fontp
->relative_compose
8379 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
8380 ? (long) value
: 0);
8381 fontp
->default_ascent
8382 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
8383 ? (long) value
: 0);
8385 fontp
->baseline_offset
= 0;
8386 fontp
->relative_compose
= 0;
8387 fontp
->default_ascent
= 0;
8390 /* Set global flag fonts_changed_p to non-zero if the font loaded
8391 has a character with a smaller width than any other character
8392 before, or if the font loaded has a smaller height than any
8393 other font loaded before. If this happens, it will make a
8394 glyph matrix reallocation necessary. */
8395 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
8402 /* Return a pointer to struct font_info of a font named FONTNAME for
8403 frame F. If no such font is loaded, return NULL. */
8406 x_query_font (f
, fontname
)
8408 register char *fontname
;
8410 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8413 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8414 if (dpyinfo
->font_table
[i
].name
8415 && (!xstricmp (dpyinfo
->font_table
[i
].name
, fontname
)
8416 || !xstricmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
8417 return (dpyinfo
->font_table
+ i
);
8422 /* Find a CCL program for a font specified by FONTP, and set the member
8423 `encoder' of the structure. */
8426 x_find_ccl_program (fontp
)
8427 struct font_info
*fontp
;
8429 Lisp_Object list
, elt
;
8431 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
8435 && STRINGP (XCAR (elt
))
8436 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
8442 struct ccl_program
*ccl
8443 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
8445 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
8448 fontp
->font_encoder
= ccl
;
8452 #if USE_MAC_FONT_PANEL
8453 /* Whether Font Panel has been shown before. The first call to font
8454 panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
8455 slow. This variable is used for deferring such a call as much as
8457 static int font_panel_shown_p
= 0;
8460 mac_font_panel_visible_p ()
8462 return font_panel_shown_p
&& FPIsFontPanelVisible ();
8466 mac_show_hide_font_panel ()
8468 font_panel_shown_p
= 1;
8470 return FPShowHideFontPanel ();
8474 mac_set_font_info_for_selection (f
, face_id
, c
)
8479 EventTargetRef target
= NULL
;
8480 XFontStruct
*font
= NULL
;
8482 if (!mac_font_panel_visible_p ())
8487 target
= GetWindowEventTarget (FRAME_MAC_WINDOW (f
));
8489 if (FRAME_FACE_CACHE (f
) && CHAR_VALID_P (c
, 0))
8493 face_id
= FACE_FOR_CHAR (f
, FACE_FROM_ID (f
, face_id
), c
);
8494 face
= FACE_FROM_ID (f
, face_id
);
8500 err
= SetFontInfoForSelection (kFontSelectionATSUIType
, 0, NULL
, target
);
8503 if (font
->mac_fontnum
!= -1)
8505 FontSelectionQDStyle qd_style
;
8507 qd_style
.version
= kFontSelectionQDStyleVersionZero
;
8508 qd_style
.instance
.fontFamily
= font
->mac_fontnum
;
8509 qd_style
.instance
.fontStyle
= font
->mac_fontface
;
8510 qd_style
.size
= font
->mac_fontsize
;
8511 qd_style
.hasColor
= false;
8513 err
= SetFontInfoForSelection (kFontSelectionQDType
,
8514 1, &qd_style
, target
);
8517 err
= SetFontInfoForSelection (kFontSelectionATSUIType
,
8518 1, &font
->mac_style
, target
);
8526 /* The Mac Event loop code */
8528 #if !TARGET_API_MAC_CARBON
8530 #include <Quickdraw.h>
8531 #include <Balloons.h>
8532 #include <Devices.h>
8534 #include <Gestalt.h>
8536 #include <Processes.h>
8538 #include <ToolUtils.h>
8539 #include <TextUtils.h>
8540 #include <Dialogs.h>
8543 #include <Resources.h>
8548 #endif /* ! TARGET_API_MAC_CARBON */
8553 #define WINDOW_RESOURCE 128
8554 #define TERM_WINDOW_RESOURCE 129
8556 #define DEFAULT_NUM_COLS 80
8558 #define MIN_DOC_SIZE 64
8559 #define MAX_DOC_SIZE 32767
8561 #define EXTRA_STACK_ALLOC (256 * 1024)
8563 #define ARGV_STRING_LIST_ID 129
8564 #define ABOUT_ALERT_ID 128
8565 #define RAM_TOO_LARGE_ALERT_ID 129
8567 /* Contains the string "reverse", which is a constant for mouse button emu.*/
8568 Lisp_Object Qreverse
;
8571 /* Modifier associated with the control key, or nil to ignore. */
8572 Lisp_Object Vmac_control_modifier
;
8574 /* Modifier associated with the option key, or nil to ignore. */
8575 Lisp_Object Vmac_option_modifier
;
8577 /* Modifier associated with the command key, or nil to ignore. */
8578 Lisp_Object Vmac_command_modifier
;
8580 /* Modifier associated with the function key, or nil to ignore. */
8581 Lisp_Object Vmac_function_modifier
;
8583 /* True if the option and command modifiers should be used to emulate
8584 a three button mouse */
8585 Lisp_Object Vmac_emulate_three_button_mouse
;
8587 #if USE_CARBON_EVENTS
8588 /* Non-zero if the mouse wheel button (i.e. button 4) should map to
8589 mouse-2, instead of mouse-3. */
8590 int mac_wheel_button_is_mouse_2
;
8592 /* If non-zero, the Mac "Command" key is passed on to the Mac Toolbox
8593 for processing before Emacs sees it. */
8594 int mac_pass_command_to_system
;
8596 /* If non-zero, the Mac "Control" key is passed on to the Mac Toolbox
8597 for processing before Emacs sees it. */
8598 int mac_pass_control_to_system
;
8601 /* Points to the variable `inev' in the function XTread_socket. It is
8602 used for passing an input event to the function back from
8603 Carbon/Apple event handlers. */
8604 static struct input_event
*read_socket_inev
= NULL
;
8606 Point saved_menu_event_location
;
8609 #if USE_CARBON_EVENTS
8610 static Lisp_Object Qhi_command
;
8612 extern Lisp_Object Qwindow
;
8613 static Lisp_Object Qtoolbar_switch_mode
;
8615 #if USE_MAC_FONT_PANEL
8616 extern Lisp_Object Qfont
;
8617 static Lisp_Object Qpanel_closed
, Qselection
;
8620 static TSMDocumentID tsm_document_id
;
8621 static Lisp_Object Qtext_input
;
8622 static Lisp_Object Qupdate_active_input_area
, Qunicode_for_key_event
;
8623 static Lisp_Object Vmac_ts_active_input_overlay
;
8624 extern Lisp_Object Qbefore_string
;
8625 static Lisp_Object Vmac_ts_script_language_on_focus
;
8626 static Lisp_Object saved_ts_script_language_on_focus
;
8627 static ScriptLanguageRecord saved_ts_language
;
8628 static Component saved_ts_component
;
8631 extern int mac_ready_for_apple_events
;
8632 extern Lisp_Object Qundefined
;
8633 extern void init_apple_event_handler
P_ ((void));
8634 extern void mac_find_apple_event_spec
P_ ((AEEventClass
, AEEventID
,
8635 Lisp_Object
*, Lisp_Object
*,
8637 extern OSErr init_coercion_handler
P_ ((void));
8640 OSErr install_drag_handler
P_ ((WindowRef
));
8641 void remove_drag_handler
P_ ((WindowRef
));
8643 #if USE_CARBON_EVENTS
8645 extern void init_service_handler ();
8646 static Lisp_Object Qservice
, Qpaste
, Qperform
;
8648 /* Window Event Handler */
8649 static pascal OSStatus
mac_handle_window_event (EventHandlerCallRef
,
8652 OSStatus
install_window_handler (WindowPtr
);
8654 extern void init_emacs_passwd_dir ();
8655 extern int emacs_main (int, char **, char **);
8657 extern void initialize_applescript();
8658 extern void terminate_applescript();
8660 /* Table for translating Mac keycode to X keysym values. Contributed
8662 Mapping for special keys is now identical to that in Apple X11
8663 except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
8664 on the right of the Cmd key on laptops, and fn + `enter' (->
8666 static const unsigned char keycode_to_xkeysym_table
[] = {
8667 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8668 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8669 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8671 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8672 /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
8673 /*0x38*/ 0, 0, 0, 0,
8674 /*0x3C*/ 0, 0, 0, 0,
8676 /*0x40*/ 0, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
8677 /*0x44*/ 0, 0xab /*kp-add*/, 0, 0x0b /*clear*/,
8678 /*0x48*/ 0, 0, 0, 0xaf /*kp-divide*/,
8679 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0,
8681 /*0x50*/ 0, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8682 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8683 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8684 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8686 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8687 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8688 /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
8689 /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
8691 /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
8692 /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
8693 /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8694 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8698 /* Table for translating Mac keycode with the laptop `fn' key to that
8699 without it. Destination symbols in comments are keys on US
8700 keyboard, and they may not be the same on other types of keyboards.
8701 If the destination is identical to the source (f1 ... f12), it
8702 doesn't map `fn' key to a modifier. */
8703 static const unsigned char fn_keycode_to_keycode_table
[] = {
8704 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8705 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8706 /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8708 /*0x30*/ 0, 0, 0, 0,
8709 /*0x34*/ 0, 0, 0, 0,
8710 /*0x38*/ 0, 0, 0, 0,
8711 /*0x3C*/ 0, 0, 0, 0,
8713 /*0x40*/ 0, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
8714 /*0x44*/ 0, 0x2c /*kp-add -> '/'*/, 0, 0x16 /*clear -> '6'*/,
8715 /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
8716 /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0,
8718 /*0x50*/ 0, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
8719 /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
8720 /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
8721 /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
8723 /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
8724 /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
8725 /*0x68*/ 0, 0, 0, 0,
8726 /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
8728 /*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
8729 /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
8730 /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 0,
8733 #endif /* MAC_OSX */
8736 #if USE_CARBON_EVENTS
8737 mac_to_emacs_modifiers (UInt32 mods
)
8739 mac_to_emacs_modifiers (EventModifiers mods
)
8742 unsigned int result
= 0;
8743 if (mods
& shiftKey
)
8744 result
|= shift_modifier
;
8746 /* Deactivated to simplify configuration:
8747 if Vmac_option_modifier is non-NIL, we fully process the Option
8748 key. Otherwise, we only process it if an additional Ctrl or Command
8749 is pressed. That way the system may convert the character to a
8751 if ((mods & optionKey) &&
8752 (( !NILP(Vmac_option_modifier) ||
8753 ((mods & cmdKey) || (mods & controlKey))))) */
8755 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
8756 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
8758 result
|= XUINT(val
);
8760 if (!NILP (Vmac_command_modifier
) && (mods
& cmdKey
)) {
8761 Lisp_Object val
= Fget(Vmac_command_modifier
, Qmodifier_value
);
8763 result
|= XUINT(val
);
8765 if (!NILP (Vmac_control_modifier
) && (mods
& controlKey
)) {
8766 Lisp_Object val
= Fget(Vmac_control_modifier
, Qmodifier_value
);
8768 result
|= XUINT(val
);
8772 if (!NILP (Vmac_function_modifier
) && (mods
& kEventKeyModifierFnMask
)) {
8773 Lisp_Object val
= Fget(Vmac_function_modifier
, Qmodifier_value
);
8775 result
|= XUINT(val
);
8783 mac_get_emulated_btn ( UInt32 modifiers
)
8786 if (!NILP (Vmac_emulate_three_button_mouse
)) {
8787 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
8788 if (modifiers
& cmdKey
)
8789 result
= cmdIs3
? 2 : 1;
8790 else if (modifiers
& optionKey
)
8791 result
= cmdIs3
? 1 : 2;
8796 #if USE_CARBON_EVENTS
8797 /* Obtains the event modifiers from the event ref and then calls
8798 mac_to_emacs_modifiers. */
8800 mac_event_to_emacs_modifiers (EventRef eventRef
)
8803 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
8804 sizeof (UInt32
), NULL
, &mods
);
8805 if (!NILP (Vmac_emulate_three_button_mouse
) &&
8806 GetEventClass(eventRef
) == kEventClassMouse
)
8808 mods
&= ~(optionKey
| cmdKey
);
8810 return mac_to_emacs_modifiers (mods
);
8813 /* Given an event ref, return the code to use for the mouse button
8814 code in the emacs input_event. */
8816 mac_get_mouse_btn (EventRef ref
)
8818 EventMouseButton result
= kEventMouseButtonPrimary
;
8819 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
8820 sizeof (EventMouseButton
), NULL
, &result
);
8823 case kEventMouseButtonPrimary
:
8824 if (NILP (Vmac_emulate_three_button_mouse
))
8828 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
8829 sizeof (UInt32
), NULL
, &mods
);
8830 return mac_get_emulated_btn(mods
);
8832 case kEventMouseButtonSecondary
:
8833 return mac_wheel_button_is_mouse_2
? 2 : 1;
8834 case kEventMouseButtonTertiary
:
8835 case 4: /* 4 is the number for the mouse wheel button */
8836 return mac_wheel_button_is_mouse_2
? 1 : 2;
8842 /* Normally, ConvertEventRefToEventRecord will correctly handle all
8843 events. However the click of the mouse wheel is not converted to a
8844 mouseDown or mouseUp event. Likewise for dead key down events.
8845 This calls ConvertEventRef, but then checks to see if it is a mouse
8846 up/down, or a dead key down carbon event that has not been
8847 converted, and if so, converts it by hand (to be picked up in the
8848 XTread_socket loop). */
8849 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
8852 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
8857 switch (GetEventClass (eventRef
))
8859 case kEventClassMouse
:
8860 switch (GetEventKind (eventRef
))
8862 case kEventMouseDown
:
8863 eventRec
->what
= mouseDown
;
8868 eventRec
->what
= mouseUp
;
8877 case kEventClassKeyboard
:
8878 switch (GetEventKind (eventRef
))
8880 case kEventRawKeyDown
:
8882 unsigned char char_codes
;
8885 err
= GetEventParameter (eventRef
, kEventParamKeyMacCharCodes
,
8886 typeChar
, NULL
, sizeof (char),
8889 err
= GetEventParameter (eventRef
, kEventParamKeyCode
,
8890 typeUInt32
, NULL
, sizeof (UInt32
),
8894 eventRec
->what
= keyDown
;
8895 eventRec
->message
= char_codes
| ((key_code
& 0xff) << 8);
8912 /* Need where and when. */
8915 GetEventParameter (eventRef
, kEventParamMouseLocation
, typeQDPoint
,
8916 NULL
, sizeof (Point
), NULL
, &eventRec
->where
);
8917 /* Use two step process because new event modifiers are 32-bit
8918 and old are 16-bit. Currently, only loss is NumLock & Fn. */
8919 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
,
8920 NULL
, sizeof (UInt32
), NULL
, &mods
);
8921 eventRec
->modifiers
= mods
;
8923 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
8935 Handle menubar_handle
;
8936 MenuHandle menu_handle
;
8938 menubar_handle
= GetNewMBar (128);
8939 if(menubar_handle
== NULL
)
8941 SetMenuBar (menubar_handle
);
8944 #if !TARGET_API_MAC_CARBON
8945 menu_handle
= GetMenuHandle (M_APPLE
);
8946 if(menu_handle
!= NULL
)
8947 AppendResMenu (menu_handle
,'DRVR');
8955 do_init_managers (void)
8957 #if !TARGET_API_MAC_CARBON
8958 InitGraf (&qd
.thePort
);
8960 FlushEvents (everyEvent
, 0);
8965 #endif /* !TARGET_API_MAC_CARBON */
8968 #if !TARGET_API_MAC_CARBON
8969 /* set up some extra stack space for use by emacs */
8970 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
8972 /* MaxApplZone must be called for AppleScript to execute more
8973 complicated scripts */
8976 #endif /* !TARGET_API_MAC_CARBON */
8980 do_check_ram_size (void)
8982 SInt32 physical_ram_size
, logical_ram_size
;
8984 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
8985 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
8986 || physical_ram_size
> (1 << VALBITS
)
8987 || logical_ram_size
> (1 << VALBITS
))
8989 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
8993 #endif /* MAC_OS8 */
8996 do_window_update (WindowPtr win
)
8998 struct frame
*f
= mac_window_to_frame (win
);
9002 /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
9004 if (win
!= tip_window
)
9006 if (f
->async_visible
== 0)
9008 /* Update events may occur when a frame gets iconified. */
9010 f
->async_visible
= 1;
9011 f
->async_iconified
= 0;
9012 SET_FRAME_GARBAGED (f
);
9018 #if TARGET_API_MAC_CARBON
9019 RgnHandle region
= NewRgn ();
9021 GetPortVisibleRegion (GetWindowPort (win
), region
);
9022 GetRegionBounds (region
, &r
);
9023 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
9024 UpdateControls (win
, region
);
9025 DisposeRgn (region
);
9027 r
= (*win
->visRgn
)->rgnBBox
;
9028 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
9029 UpdateControls (win
, win
->visRgn
);
9038 is_emacs_window (WindowPtr win
)
9040 Lisp_Object tail
, frame
;
9045 FOR_EACH_FRAME (tail
, frame
)
9046 if (FRAME_MAC_P (XFRAME (frame
)))
9047 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
9058 ScriptLanguageRecord slrec
, *slptr
= NULL
;
9060 err
= ActivateTSMDocument (tsm_document_id
);
9064 if (EQ (Vmac_ts_script_language_on_focus
, Qt
)
9065 && EQ (saved_ts_script_language_on_focus
, Qt
))
9066 slptr
= &saved_ts_language
;
9067 else if (CONSP (Vmac_ts_script_language_on_focus
)
9068 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus
))
9069 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus
))
9070 && CONSP (saved_ts_script_language_on_focus
)
9071 && EQ (XCAR (saved_ts_script_language_on_focus
),
9072 XCAR (Vmac_ts_script_language_on_focus
))
9073 && EQ (XCDR (saved_ts_script_language_on_focus
),
9074 XCDR (Vmac_ts_script_language_on_focus
)))
9076 slrec
.fScript
= XINT (XCAR (Vmac_ts_script_language_on_focus
));
9077 slrec
.fLanguage
= XINT (XCDR (Vmac_ts_script_language_on_focus
));
9084 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
9085 err
= SetDefaultInputMethodOfClass (saved_ts_component
, slptr
,
9086 kKeyboardInputMethodClass
);
9088 err
= SetDefaultInputMethod (saved_ts_component
, slptr
);
9091 err
= SetTextServiceLanguage (slptr
);
9093 /* Seems to be needed on Mac OS X 10.2. */
9095 KeyScript (slptr
->fScript
| smKeyForceKeyScriptMask
);
9105 ScriptLanguageRecord slrec
, *slptr
= NULL
;
9107 saved_ts_script_language_on_focus
= Vmac_ts_script_language_on_focus
;
9109 if (EQ (Vmac_ts_script_language_on_focus
, Qt
))
9111 err
= GetTextServiceLanguage (&saved_ts_language
);
9113 slptr
= &saved_ts_language
;
9115 else if (CONSP (Vmac_ts_script_language_on_focus
)
9116 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus
))
9117 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus
)))
9119 slrec
.fScript
= XINT (XCAR (Vmac_ts_script_language_on_focus
));
9120 slrec
.fLanguage
= XINT (XCDR (Vmac_ts_script_language_on_focus
));
9126 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
9127 GetDefaultInputMethodOfClass (&saved_ts_component
, slptr
,
9128 kKeyboardInputMethodClass
);
9130 GetDefaultInputMethod (&saved_ts_component
, slptr
);
9134 err
= DeactivateTSMDocument (tsm_document_id
);
9140 #if !TARGET_API_MAC_CARBON
9142 do_apple_menu (SInt16 menu_item
)
9145 SInt16 da_driver_refnum
;
9147 if (menu_item
== I_ABOUT
)
9148 NoteAlert (ABOUT_ALERT_ID
, NULL
);
9151 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
9152 da_driver_refnum
= OpenDeskAcc (item_name
);
9155 #endif /* !TARGET_API_MAC_CARBON */
9157 /* Handle drags in size box. Based on code contributed by Ben
9158 Mesander and IM - Window Manager A. */
9161 do_grow_window (w
, e
)
9163 const EventRecord
*e
;
9166 int rows
, columns
, width
, height
;
9167 struct frame
*f
= mac_window_to_frame (w
);
9168 XSizeHints
*size_hints
= FRAME_SIZE_HINTS (f
);
9169 int min_width
= MIN_DOC_SIZE
, min_height
= MIN_DOC_SIZE
;
9170 #if TARGET_API_MAC_CARBON
9176 if (size_hints
->flags
& PMinSize
)
9178 min_width
= size_hints
->min_width
;
9179 min_height
= size_hints
->min_height
;
9181 SetRect (&limit_rect
, min_width
, min_height
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
9183 #if TARGET_API_MAC_CARBON
9184 if (!ResizeWindow (w
, e
->where
, &limit_rect
, &new_rect
))
9186 height
= new_rect
.bottom
- new_rect
.top
;
9187 width
= new_rect
.right
- new_rect
.left
;
9189 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
9190 /* see if it really changed size */
9193 height
= HiWord (grow_size
);
9194 width
= LoWord (grow_size
);
9197 if (width
!= FRAME_PIXEL_WIDTH (f
)
9198 || height
!= FRAME_PIXEL_HEIGHT (f
))
9200 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
9201 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
9203 x_set_window_size (f
, 0, columns
, rows
);
9208 #if TARGET_API_MAC_CARBON
9210 mac_get_ideal_size (f
)
9213 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9214 WindowPtr w
= FRAME_MAC_WINDOW (f
);
9217 int height
, width
, columns
, rows
;
9219 ideal_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
9220 ideal_size
.v
= dpyinfo
->height
;
9221 IsWindowInStandardState (w
, &ideal_size
, &standard_rect
);
9222 /* Adjust the standard size according to character boundaries. */
9223 width
= standard_rect
.right
- standard_rect
.left
;
9224 height
= standard_rect
.bottom
- standard_rect
.top
;
9225 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
9226 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
9227 ideal_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
9228 ideal_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
9234 /* Handle clicks in zoom box. Calculation of "standard state" based
9235 on code in IM - Window Manager A and code contributed by Ben
9236 Mesander. The standard state of an Emacs window is 80-characters
9237 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
9240 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
9242 Rect zoom_rect
, port_rect
;
9244 struct frame
*f
= mac_window_to_frame (w
);
9245 #if TARGET_API_MAC_CARBON
9246 Point ideal_size
= mac_get_ideal_size (f
);
9248 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
9249 if (IsWindowInStandardState (w
, &ideal_size
, &zoom_rect
)
9250 && port_rect
.left
== zoom_rect
.left
9251 && port_rect
.top
== zoom_rect
.top
)
9252 zoom_in_or_out
= inZoomIn
;
9254 zoom_in_or_out
= inZoomOut
;
9257 mac_clear_window (f
);
9259 ZoomWindowIdeal (w
, zoom_in_or_out
, &ideal_size
);
9260 #else /* not TARGET_API_MAC_CARBON */
9263 int w_title_height
, rows
;
9264 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9266 GetPort (&save_port
);
9268 SetPortWindowPort (w
);
9270 /* Clear window to avoid flicker. */
9271 EraseRect (&(w
->portRect
));
9272 if (zoom_in_or_out
== inZoomOut
)
9274 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
9275 LocalToGlobal (&top_left
);
9277 /* calculate height of window's title bar */
9278 w_title_height
= top_left
.v
- 1
9279 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
9281 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
9282 zoom_rect
= qd
.screenBits
.bounds
;
9283 zoom_rect
.top
+= w_title_height
;
9284 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
9286 zoom_rect
.right
= zoom_rect
.left
9287 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
9289 /* Adjust the standard size according to character boundaries. */
9290 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
9292 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
9294 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
9298 ZoomWindow (w
, zoom_in_or_out
, f
== mac_focus_frame (dpyinfo
));
9300 SetPort (save_port
);
9301 #endif /* not TARGET_API_MAC_CARBON */
9303 #if !USE_CARBON_EVENTS
9304 /* retrieve window size and update application values */
9305 #if TARGET_API_MAC_CARBON
9306 GetWindowPortBounds (w
, &port_rect
);
9308 port_rect
= w
->portRect
;
9310 height
= port_rect
.bottom
- port_rect
.top
;
9311 width
= port_rect
.right
- port_rect
.left
;
9313 mac_handle_size_change (f
, width
, height
);
9314 mac_handle_origin_change (f
);
9319 mac_store_apple_event (class, id
, desc
)
9320 Lisp_Object
class, id
;
9323 struct input_event buf
;
9327 buf
.kind
= MAC_APPLE_EVENT
;
9330 XSETFRAME (buf
.frame_or_window
,
9331 mac_focus_frame (&one_mac_display_info
));
9332 /* Now that Lisp object allocations are protected by BLOCK_INPUT, it
9333 is safe to use them during read_socket_hook. */
9334 buf
.arg
= mac_aedesc_to_lisp (desc
);
9335 kbd_buffer_store_event (&buf
);
9338 #if TARGET_API_MAC_CARBON
9340 mac_store_event_ref_as_apple_event (class, id
, class_key
, id_key
,
9341 event
, num_params
, names
, types
)
9344 Lisp_Object class_key
, id_key
;
9347 const EventParamName
*names
;
9348 const EventParamType
*types
;
9350 OSStatus err
= eventNotHandledErr
;
9351 Lisp_Object binding
;
9353 mac_find_apple_event_spec (class, id
, &class_key
, &id_key
, &binding
);
9354 if (!NILP (binding
) && !EQ (binding
, Qundefined
))
9356 if (INTEGERP (binding
))
9357 err
= XINT (binding
);
9360 AppleEvent apple_event
;
9361 err
= create_apple_event_from_event_ref (event
, num_params
,
9366 mac_store_apple_event (class_key
, id_key
, &apple_event
);
9367 AEDisposeDesc (&apple_event
);
9368 /* Post a harmless event so as to wake up from
9369 ReceiveNextEvent. */
9370 mac_post_mouse_moved_event ();
9379 mac_store_drag_event (window
, mouse_pos
, modifiers
, desc
)
9385 struct input_event buf
;
9389 buf
.kind
= DRAG_N_DROP_EVENT
;
9390 buf
.modifiers
= mac_to_emacs_modifiers (modifiers
);
9391 buf
.timestamp
= TickCount () * (1000 / 60);
9392 XSETINT (buf
.x
, mouse_pos
.h
);
9393 XSETINT (buf
.y
, mouse_pos
.v
);
9394 XSETFRAME (buf
.frame_or_window
, mac_window_to_frame (window
));
9395 buf
.arg
= mac_aedesc_to_lisp (desc
);
9396 kbd_buffer_store_event (&buf
);
9400 #if USE_CARBON_EVENTS
9401 static pascal OSStatus
9402 mac_handle_command_event (next_handler
, event
, data
)
9403 EventHandlerCallRef next_handler
;
9407 OSStatus result
, err
;
9409 static const EventParamName names
[] =
9410 {kEventParamDirectObject
, kEventParamKeyModifiers
};
9411 static const EventParamType types
[] =
9412 {typeHICommand
, typeUInt32
};
9413 int num_params
= sizeof (names
) / sizeof (names
[0]);
9415 result
= CallNextEventHandler (next_handler
, event
);
9416 if (result
!= eventNotHandledErr
)
9419 err
= GetEventParameter (event
, kEventParamDirectObject
, typeHICommand
,
9420 NULL
, sizeof (HICommand
), NULL
, &command
);
9422 if (err
!= noErr
|| command
.commandID
== 0)
9423 return eventNotHandledErr
;
9425 /* A HI command event is mapped to an Apple event whose event class
9426 symbol is `hi-command' and event ID is its command ID. */
9427 err
= mac_store_event_ref_as_apple_event (0, command
.commandID
,
9429 event
, num_params
, names
, types
);
9430 return err
== noErr
? noErr
: eventNotHandledErr
;
9434 init_command_handler ()
9436 static const EventTypeSpec specs
[] =
9437 {{kEventClassCommand
, kEventCommandProcess
}};
9438 static EventHandlerUPP handle_command_eventUPP
= NULL
;
9440 if (handle_command_eventUPP
== NULL
)
9441 handle_command_eventUPP
= NewEventHandlerUPP (mac_handle_command_event
);
9442 return InstallApplicationEventHandler (handle_command_eventUPP
,
9443 GetEventTypeCount (specs
), specs
,
9447 static pascal OSStatus
9448 mac_handle_window_event (next_handler
, event
, data
)
9449 EventHandlerCallRef next_handler
;
9454 OSStatus result
, err
;
9457 XSizeHints
*size_hints
;
9459 err
= GetEventParameter (event
, kEventParamDirectObject
, typeWindowRef
,
9460 NULL
, sizeof (WindowPtr
), NULL
, &wp
);
9462 return eventNotHandledErr
;
9464 f
= mac_window_to_frame (wp
);
9465 switch (GetEventKind (event
))
9467 case kEventWindowUpdate
:
9468 result
= CallNextEventHandler (next_handler
, event
);
9469 if (result
!= eventNotHandledErr
)
9472 do_window_update (wp
);
9475 case kEventWindowGetIdealSize
:
9476 result
= CallNextEventHandler (next_handler
, event
);
9477 if (result
!= eventNotHandledErr
)
9481 Point ideal_size
= mac_get_ideal_size (f
);
9483 err
= SetEventParameter (event
, kEventParamDimensions
,
9484 typeQDPoint
, sizeof (Point
), &ideal_size
);
9490 case kEventWindowBoundsChanging
:
9491 result
= CallNextEventHandler (next_handler
, event
);
9492 if (result
!= eventNotHandledErr
)
9495 err
= GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
9496 NULL
, sizeof (UInt32
), NULL
, &attributes
);
9500 size_hints
= FRAME_SIZE_HINTS (f
);
9501 if ((attributes
& kWindowBoundsChangeUserResize
)
9502 && ((size_hints
->flags
& (PResizeInc
| PBaseSize
| PMinSize
))
9503 == (PResizeInc
| PBaseSize
| PMinSize
)))
9508 err
= GetEventParameter (event
, kEventParamCurrentBounds
,
9509 typeQDRectangle
, NULL
, sizeof (Rect
),
9514 width
= bounds
.right
- bounds
.left
;
9515 height
= bounds
.bottom
- bounds
.top
;
9517 if (width
< size_hints
->min_width
)
9518 width
= size_hints
->min_width
;
9520 width
= size_hints
->base_width
9521 + (int) ((width
- size_hints
->base_width
)
9522 / (float) size_hints
->width_inc
+ .5)
9523 * size_hints
->width_inc
;
9525 if (height
< size_hints
->min_height
)
9526 height
= size_hints
->min_height
;
9528 height
= size_hints
->base_height
9529 + (int) ((height
- size_hints
->base_height
)
9530 / (float) size_hints
->height_inc
+ .5)
9531 * size_hints
->height_inc
;
9533 bounds
.right
= bounds
.left
+ width
;
9534 bounds
.bottom
= bounds
.top
+ height
;
9535 SetEventParameter (event
, kEventParamCurrentBounds
,
9536 typeQDRectangle
, sizeof (Rect
), &bounds
);
9541 case kEventWindowBoundsChanged
:
9542 err
= GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
9543 NULL
, sizeof (UInt32
), NULL
, &attributes
);
9547 if (attributes
& kWindowBoundsChangeSizeChanged
)
9551 err
= GetEventParameter (event
, kEventParamCurrentBounds
,
9552 typeQDRectangle
, NULL
, sizeof (Rect
),
9558 width
= bounds
.right
- bounds
.left
;
9559 height
= bounds
.bottom
- bounds
.top
;
9560 mac_handle_size_change (f
, width
, height
);
9564 if (attributes
& kWindowBoundsChangeOriginChanged
)
9565 mac_handle_origin_change (f
);
9569 case kEventWindowShown
:
9570 case kEventWindowHidden
:
9571 case kEventWindowExpanded
:
9572 case kEventWindowCollapsed
:
9573 result
= CallNextEventHandler (next_handler
, event
);
9575 mac_handle_visibility_change (f
);
9580 case kEventWindowClose
:
9581 result
= CallNextEventHandler (next_handler
, event
);
9583 struct input_event buf
;
9586 buf
.kind
= DELETE_WINDOW_EVENT
;
9587 XSETFRAME (buf
.frame_or_window
, f
);
9589 kbd_buffer_store_event (&buf
);
9594 case kEventWindowToolbarSwitchMode
:
9595 result
= CallNextEventHandler (next_handler
, event
);
9597 static const EventParamName names
[] = {kEventParamDirectObject
,
9598 kEventParamWindowMouseLocation
,
9599 kEventParamKeyModifiers
,
9600 kEventParamMouseButton
,
9601 kEventParamClickCount
,
9602 kEventParamMouseChord
};
9603 static const EventParamType types
[] = {typeWindowRef
,
9609 int num_params
= sizeof (names
) / sizeof (names
[0]);
9611 err
= mac_store_event_ref_as_apple_event (0, 0,
9613 Qtoolbar_switch_mode
,
9617 return err
== noErr
? noErr
: result
;
9621 case kEventWindowFocusAcquired
:
9622 result
= CallNextEventHandler (next_handler
, event
);
9623 err
= mac_tsm_resume ();
9624 return err
== noErr
? noErr
: result
;
9626 case kEventWindowFocusRelinquish
:
9627 result
= CallNextEventHandler (next_handler
, event
);
9628 err
= mac_tsm_suspend ();
9629 return err
== noErr
? noErr
: result
;
9633 return eventNotHandledErr
;
9636 static pascal OSStatus
9637 mac_handle_mouse_event (next_handler
, event
, data
)
9638 EventHandlerCallRef next_handler
;
9642 OSStatus result
, err
;
9644 switch (GetEventKind (event
))
9646 case kEventMouseWheelMoved
:
9650 EventMouseWheelAxis axis
;
9654 result
= CallNextEventHandler (next_handler
, event
);
9655 if (result
!= eventNotHandledErr
|| read_socket_inev
== NULL
)
9658 err
= GetEventParameter (event
, kEventParamWindowRef
, typeWindowRef
,
9659 NULL
, sizeof (WindowRef
), NULL
, &wp
);
9663 f
= mac_window_to_frame (wp
);
9664 if (f
!= mac_focus_frame (&one_mac_display_info
))
9667 err
= GetEventParameter (event
, kEventParamMouseWheelAxis
,
9668 typeMouseWheelAxis
, NULL
,
9669 sizeof (EventMouseWheelAxis
), NULL
, &axis
);
9670 if (err
!= noErr
|| axis
!= kEventMouseWheelAxisY
)
9673 err
= GetEventParameter (event
, kEventParamMouseWheelDelta
,
9674 typeSInt32
, NULL
, sizeof (SInt32
),
9678 err
= GetEventParameter (event
, kEventParamMouseLocation
,
9679 typeQDPoint
, NULL
, sizeof (Point
),
9683 read_socket_inev
->kind
= WHEEL_EVENT
;
9684 read_socket_inev
->code
= 0;
9685 read_socket_inev
->modifiers
=
9686 (mac_event_to_emacs_modifiers (event
)
9687 | ((delta
< 0) ? down_modifier
: up_modifier
));
9688 SetPortWindowPort (wp
);
9689 GlobalToLocal (&point
);
9690 XSETINT (read_socket_inev
->x
, point
.h
);
9691 XSETINT (read_socket_inev
->y
, point
.v
);
9692 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
9702 return eventNotHandledErr
;
9705 #if USE_MAC_FONT_PANEL
9706 static pascal OSStatus
9707 mac_handle_font_event (next_handler
, event
, data
)
9708 EventHandlerCallRef next_handler
;
9712 OSStatus result
, err
;
9715 const EventParamName
*names
;
9716 const EventParamType
*types
;
9717 static const EventParamName names_sel
[] = {kEventParamATSUFontID
,
9718 kEventParamATSUFontSize
,
9719 kEventParamFMFontFamily
,
9720 kEventParamFMFontSize
,
9721 kEventParamFontColor
};
9722 static const EventParamType types_sel
[] = {typeATSUFontID
,
9728 result
= CallNextEventHandler (next_handler
, event
);
9729 if (result
!= eventNotHandledErr
)
9732 switch (GetEventKind (event
))
9734 case kEventFontPanelClosed
:
9735 id_key
= Qpanel_closed
;
9741 case kEventFontSelection
:
9742 id_key
= Qselection
;
9743 num_params
= sizeof (names_sel
) / sizeof (names_sel
[0]);
9749 err
= mac_store_event_ref_as_apple_event (0, 0, Qfont
, id_key
,
9753 return err
== noErr
? noErr
: eventNotHandledErr
;
9758 static pascal OSStatus
9759 mac_handle_text_input_event (next_handler
, event
, data
)
9760 EventHandlerCallRef next_handler
;
9764 OSStatus result
, err
= noErr
;
9765 Lisp_Object id_key
= Qnil
;
9767 const EventParamName
*names
;
9768 const EventParamType
*types
;
9769 static UInt32 seqno_uaia
= 0;
9770 static const EventParamName names_uaia
[] =
9771 {kEventParamTextInputSendComponentInstance
,
9772 kEventParamTextInputSendRefCon
,
9773 kEventParamTextInputSendSLRec
,
9774 kEventParamTextInputSendFixLen
,
9775 kEventParamTextInputSendText
,
9776 kEventParamTextInputSendUpdateRng
,
9777 kEventParamTextInputSendHiliteRng
,
9778 kEventParamTextInputSendClauseRng
,
9779 kEventParamTextInputSendPinRng
,
9780 kEventParamTextInputSendTextServiceEncoding
,
9781 kEventParamTextInputSendTextServiceMacEncoding
,
9782 EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER
};
9783 static const EventParamType types_uaia
[] =
9784 {typeComponentInstance
,
9786 typeIntlWritingCode
,
9800 static const EventParamName names_ufke
[] =
9801 {kEventParamTextInputSendComponentInstance
,
9802 kEventParamTextInputSendRefCon
,
9803 kEventParamTextInputSendSLRec
,
9804 kEventParamTextInputSendText
};
9805 static const EventParamType types_ufke
[] =
9806 {typeComponentInstance
,
9808 typeIntlWritingCode
,
9811 result
= CallNextEventHandler (next_handler
, event
);
9813 switch (GetEventKind (event
))
9815 case kEventTextInputUpdateActiveInputArea
:
9816 id_key
= Qupdate_active_input_area
;
9817 num_params
= sizeof (names_uaia
) / sizeof (names_uaia
[0]);
9820 SetEventParameter (event
, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER
,
9821 typeUInt32
, sizeof (UInt32
), &seqno_uaia
);
9825 case kEventTextInputUnicodeForKeyEvent
:
9828 UInt32 actual_size
, modifiers
, mapped_modifiers
;
9830 err
= GetEventParameter (event
, kEventParamTextInputSendKeyboardEvent
,
9831 typeEventRef
, NULL
, sizeof (EventRef
), NULL
,
9834 err
= GetEventParameter (kbd_event
, kEventParamKeyModifiers
,
9836 sizeof (UInt32
), NULL
, &modifiers
);
9840 (NILP (Vmac_control_modifier
) ? 0 : controlKey
)
9841 | (NILP (Vmac_option_modifier
) ? 0 : optionKey
)
9842 | (NILP (Vmac_command_modifier
) ? 0 : cmdKey
);
9845 (NILP (Vmac_function_modifier
) ? 0 : kEventKeyModifierFnMask
);
9847 if (modifiers
& mapped_modifiers
)
9848 /* There're mapped modifier keys. Process it in
9850 return eventNotHandledErr
;
9853 err
= GetEventParameter (kbd_event
, kEventParamKeyUnicodes
,
9854 typeUnicodeText
, NULL
, 0, &actual_size
,
9856 if (err
== noErr
&& actual_size
== sizeof (UniChar
))
9860 err
= GetEventParameter (kbd_event
, kEventParamKeyUnicodes
,
9861 typeUnicodeText
, NULL
,
9862 sizeof (UniChar
), NULL
, &code
);
9863 if (err
== noErr
&& code
< 0x80)
9865 /* ASCII character. Process it in XTread_socket. */
9866 if (read_socket_inev
&& code
>= 0x20 && code
<= 0x7e)
9870 err
= GetEventParameter (kbd_event
, kEventParamKeyCode
,
9871 typeUInt32
, NULL
, sizeof (UInt32
),
9873 if (!(err
== noErr
&& key_code
<= 0x7f
9874 && keycode_to_xkeysym_table
[key_code
]))
9877 mac_focus_frame (&one_mac_display_info
);
9879 read_socket_inev
->kind
= ASCII_KEYSTROKE_EVENT
;
9880 read_socket_inev
->code
= code
;
9881 read_socket_inev
->modifiers
=
9882 mac_to_emacs_modifiers (modifiers
);
9883 read_socket_inev
->modifiers
|=
9884 (extra_keyboard_modifiers
9885 & (meta_modifier
| alt_modifier
9886 | hyper_modifier
| super_modifier
));
9887 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
9890 return eventNotHandledErr
;
9894 /* Non-ASCII keystrokes without mapped modifiers are processed
9895 at the Lisp level. */
9896 id_key
= Qunicode_for_key_event
;
9897 num_params
= sizeof (names_ufke
) / sizeof (names_ufke
[0]);
9902 case kEventTextInputOffsetToPos
:
9908 if (!OVERLAYP (Vmac_ts_active_input_overlay
))
9909 return eventNotHandledErr
;
9911 /* Strictly speaking, this is not always correct because
9912 previous events may change some states about display. */
9913 if (NILP (Foverlay_get (Vmac_ts_active_input_overlay
, Qbefore_string
)))
9915 /* Active input area is displayed in the echo area. */
9916 w
= XWINDOW (echo_area_window
);
9917 f
= WINDOW_XFRAME (w
);
9921 /* Active input area is displayed around the current point. */
9922 f
= SELECTED_FRAME ();
9923 w
= XWINDOW (f
->selected_window
);
9926 p
.h
= (WINDOW_TO_FRAME_PIXEL_X (w
, w
->cursor
.x
)
9927 + WINDOW_LEFT_FRINGE_WIDTH (w
));
9928 p
.v
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->cursor
.y
)
9929 + FONT_BASE (FRAME_FONT (f
)));
9930 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
9932 err
= SetEventParameter (event
, kEventParamTextInputReplyPoint
,
9933 typeQDPoint
, sizeof (typeQDPoint
), &p
);
9942 err
= mac_store_event_ref_as_apple_event (0, 0, Qtext_input
, id_key
,
9946 return err
== noErr
? noErr
: result
;
9952 mac_store_service_event (event
)
9958 const EventParamName
*names
;
9959 const EventParamType
*types
;
9960 static const EventParamName names_pfm
[] =
9961 {kEventParamServiceMessageName
, kEventParamServiceUserData
};
9962 static const EventParamType types_pfm
[] =
9963 {typeCFStringRef
, typeCFStringRef
};
9965 switch (GetEventKind (event
))
9967 case kEventServicePaste
:
9974 case kEventServicePerform
:
9976 num_params
= sizeof (names_pfm
) / sizeof (names_pfm
[0]);
9985 err
= mac_store_event_ref_as_apple_event (0, 0, Qservice
, id_key
,
9991 #endif /* MAC_OSX */
9992 #endif /* USE_CARBON_EVENTS */
9996 install_window_handler (window
)
9999 OSStatus err
= noErr
;
10000 #if USE_CARBON_EVENTS
10001 static const EventTypeSpec specs_window
[] =
10002 {{kEventClassWindow
, kEventWindowUpdate
},
10003 {kEventClassWindow
, kEventWindowGetIdealSize
},
10004 {kEventClassWindow
, kEventWindowBoundsChanging
},
10005 {kEventClassWindow
, kEventWindowBoundsChanged
},
10006 {kEventClassWindow
, kEventWindowShown
},
10007 {kEventClassWindow
, kEventWindowHidden
},
10008 {kEventClassWindow
, kEventWindowExpanded
},
10009 {kEventClassWindow
, kEventWindowCollapsed
},
10010 {kEventClassWindow
, kEventWindowClose
},
10012 {kEventClassWindow
, kEventWindowToolbarSwitchMode
},
10015 {kEventClassWindow
, kEventWindowFocusAcquired
},
10016 {kEventClassWindow
, kEventWindowFocusRelinquish
},
10019 static const EventTypeSpec specs_mouse
[] =
10020 {{kEventClassMouse
, kEventMouseWheelMoved
}};
10021 static EventHandlerUPP handle_window_eventUPP
= NULL
;
10022 static EventHandlerUPP handle_mouse_eventUPP
= NULL
;
10023 #if USE_MAC_FONT_PANEL
10024 static const EventTypeSpec specs_font
[] =
10025 {{kEventClassFont
, kEventFontPanelClosed
},
10026 {kEventClassFont
, kEventFontSelection
}};
10027 static EventHandlerUPP handle_font_eventUPP
= NULL
;
10030 static const EventTypeSpec specs_text_input
[] =
10031 {{kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
},
10032 {kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
},
10033 {kEventClassTextInput
, kEventTextInputOffsetToPos
}};
10034 static EventHandlerUPP handle_text_input_eventUPP
= NULL
;
10037 if (handle_window_eventUPP
== NULL
)
10038 handle_window_eventUPP
= NewEventHandlerUPP (mac_handle_window_event
);
10039 if (handle_mouse_eventUPP
== NULL
)
10040 handle_mouse_eventUPP
= NewEventHandlerUPP (mac_handle_mouse_event
);
10041 #if USE_MAC_FONT_PANEL
10042 if (handle_font_eventUPP
== NULL
)
10043 handle_font_eventUPP
= NewEventHandlerUPP (mac_handle_font_event
);
10046 if (handle_text_input_eventUPP
== NULL
)
10047 handle_text_input_eventUPP
=
10048 NewEventHandlerUPP (mac_handle_text_input_event
);
10050 err
= InstallWindowEventHandler (window
, handle_window_eventUPP
,
10051 GetEventTypeCount (specs_window
),
10052 specs_window
, NULL
, NULL
);
10054 err
= InstallWindowEventHandler (window
, handle_mouse_eventUPP
,
10055 GetEventTypeCount (specs_mouse
),
10056 specs_mouse
, NULL
, NULL
);
10057 #if USE_MAC_FONT_PANEL
10059 err
= InstallWindowEventHandler (window
, handle_font_eventUPP
,
10060 GetEventTypeCount (specs_font
),
10061 specs_font
, NULL
, NULL
);
10065 err
= InstallWindowEventHandler (window
, handle_text_input_eventUPP
,
10066 GetEventTypeCount (specs_text_input
),
10067 specs_text_input
, window
, NULL
);
10071 err
= install_drag_handler (window
);
10077 remove_window_handler (window
)
10080 remove_drag_handler (window
);
10086 profiler_exit_proc ()
10088 ProfilerDump ("\pEmacs.prof");
10093 /* These few functions implement Emacs as a normal Mac application
10094 (almost): set up the heap and the Toolbox, handle necessary system
10095 events plus a few simple menu events. They also set up Emacs's
10096 access to functions defined in the rest of this file. Emacs uses
10097 function hooks to perform all its terminal I/O. A complete list of
10098 these functions appear in termhooks.h. For what they do, read the
10099 comments there and see also w32term.c and xterm.c. What's
10100 noticeably missing here is the event loop, which is normally
10101 present in most Mac application. After performing the necessary
10102 Mac initializations, main passes off control to emacs_main
10103 (corresponding to main in emacs.c). Emacs_main calls XTread_socket
10104 (defined further below) to read input. This is where
10105 WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
10112 #if __profile__ /* is the profiler on? */
10113 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
10118 /* set creator and type for files created by MSL */
10119 _fcreator
= 'EMAx';
10123 do_init_managers ();
10127 #ifndef USE_LSB_TAG
10128 do_check_ram_size ();
10131 init_emacs_passwd_dir ();
10135 init_coercion_handler ();
10137 initialize_applescript ();
10139 init_apple_event_handler ();
10145 /* set up argv array from STR# resource */
10146 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
10150 /* free up AppleScript resources on exit */
10151 atexit (terminate_applescript
);
10153 #if __profile__ /* is the profiler on? */
10154 atexit (profiler_exit_proc
);
10157 /* 3rd param "envp" never used in emacs_main */
10158 (void) emacs_main (argc
, argv
, 0);
10161 /* Never reached - real exit in Fkill_emacs */
10166 #if !USE_CARBON_EVENTS
10167 static RgnHandle mouse_region
= NULL
;
10170 mac_wait_next_event (er
, sleep_time
, dequeue
)
10175 static EventRecord er_buf
= {nullEvent
};
10176 UInt32 target_tick
, current_tick
;
10177 EventMask event_mask
;
10179 if (mouse_region
== NULL
)
10180 mouse_region
= NewRgn ();
10182 event_mask
= everyEvent
;
10183 if (!mac_ready_for_apple_events
)
10184 event_mask
-= highLevelEventMask
;
10186 current_tick
= TickCount ();
10187 target_tick
= current_tick
+ sleep_time
;
10189 if (er_buf
.what
== nullEvent
)
10190 while (!WaitNextEvent (event_mask
, &er_buf
,
10191 target_tick
- current_tick
, mouse_region
))
10193 current_tick
= TickCount ();
10194 if (target_tick
<= current_tick
)
10200 er_buf
.what
= nullEvent
;
10203 #endif /* not USE_CARBON_EVENTS */
10205 #if TARGET_API_MAC_CARBON
10207 mac_post_mouse_moved_event ()
10209 EventRef event
= NULL
;
10212 err
= CreateEvent (NULL
, kEventClassMouse
, kEventMouseMoved
, 0,
10213 kEventAttributeNone
, &event
);
10218 GetMouse (&mouse_pos
);
10219 LocalToGlobal (&mouse_pos
);
10220 err
= SetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
10221 sizeof (Point
), &mouse_pos
);
10225 UInt32 modifiers
= GetCurrentKeyModifiers ();
10227 err
= SetEventParameter (event
, kEventParamKeyModifiers
, typeUInt32
,
10228 sizeof (UInt32
), &modifiers
);
10231 err
= PostEventToQueue (GetCurrentEventQueue (), event
,
10232 kEventPriorityStandard
);
10234 ReleaseEvent (event
);
10240 mac_set_unicode_keystroke_event (code
, buf
)
10242 struct input_event
*buf
;
10244 int charset_id
, c1
, c2
;
10248 buf
->kind
= ASCII_KEYSTROKE_EVENT
;
10251 else if (code
< 0x100)
10254 charset_id
= CHARSET_8_BIT_CONTROL
;
10256 charset_id
= charset_latin_iso8859_1
;
10257 buf
->kind
= MULTIBYTE_CHAR_KEYSTROKE_EVENT
;
10258 buf
->code
= MAKE_CHAR (charset_id
, code
, 0);
10263 charset_id
= charset_mule_unicode_0100_24ff
,
10265 else if (code
< 0x33FF)
10266 charset_id
= charset_mule_unicode_2500_33ff
,
10268 else if (code
>= 0xE000)
10269 charset_id
= charset_mule_unicode_e000_ffff
,
10271 c1
= (code
/ 96) + 32, c2
= (code
% 96) + 32;
10272 buf
->kind
= MULTIBYTE_CHAR_KEYSTROKE_EVENT
;
10273 buf
->code
= MAKE_CHAR (charset_id
, c1
, c2
);
10278 /* Emacs calls this whenever it wants to read an input event from the
10281 XTread_socket (sd
, expected
, hold_quit
)
10283 struct input_event
*hold_quit
;
10285 struct input_event inev
;
10287 #if USE_CARBON_EVENTS
10289 EventTargetRef toolbox_dispatcher
;
10292 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
10294 if (interrupt_input_blocked
)
10296 interrupt_input_pending
= 1;
10300 interrupt_input_pending
= 0;
10303 /* So people can tell when we have read the available input. */
10304 input_signal_count
++;
10308 #if USE_CARBON_EVENTS
10309 toolbox_dispatcher
= GetEventDispatcherTarget ();
10313 mac_prepare_for_quickdraw (NULL
),
10315 !ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
10316 kEventRemoveFromQueue
, &eventRef
))
10317 #else /* !USE_CARBON_EVENTS */
10318 while (mac_wait_next_event (&er
, 0, true))
10319 #endif /* !USE_CARBON_EVENTS */
10323 unsigned long timestamp
;
10326 inev
.kind
= NO_EVENT
;
10329 #if USE_CARBON_EVENTS
10330 timestamp
= GetEventTime (eventRef
) / kEventDurationMillisecond
;
10332 timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
10335 #if USE_CARBON_EVENTS
10336 /* Handle new events */
10337 if (!mac_convert_event_ref (eventRef
, &er
))
10339 /* There used to be a handler for the kEventMouseWheelMoved
10340 event here. But as of Mac OS X 10.4, this kind of event
10341 is not directly posted to the main event queue by
10342 two-finger scrolling on the trackpad. Instead, some
10343 private event is posted and it is converted to a wheel
10344 event by the default handler for the application target.
10345 The converted one can be received by a Carbon event
10346 handler installed on a window target. */
10347 read_socket_inev
= &inev
;
10348 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
10349 read_socket_inev
= NULL
;
10352 #endif /* USE_CARBON_EVENTS */
10358 WindowPtr window_ptr
;
10359 ControlPartCode part_code
;
10360 int tool_bar_p
= 0;
10362 #if USE_CARBON_EVENTS
10363 /* This is needed to send mouse events like aqua window
10364 buttons to the correct handler. */
10365 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10366 != eventNotHandledErr
)
10369 last_mouse_glyph_frame
= 0;
10371 if (dpyinfo
->grabbed
&& last_mouse_frame
10372 && FRAME_LIVE_P (last_mouse_frame
))
10374 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
10375 part_code
= inContent
;
10379 part_code
= FindWindow (er
.where
, &window_ptr
);
10380 if (tip_window
&& window_ptr
== tip_window
)
10382 HideWindow (tip_window
);
10383 part_code
= FindWindow (er
.where
, &window_ptr
);
10387 if (er
.what
!= mouseDown
&&
10388 (part_code
!= inContent
|| dpyinfo
->grabbed
== 0))
10394 f
= mac_focus_frame (dpyinfo
);
10395 saved_menu_event_location
= er
.where
;
10396 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
10397 XSETFRAME (inev
.frame_or_window
, f
);
10402 #if TARGET_API_MAC_CARBON
10403 FrontNonFloatingWindow ()
10408 SelectWindow (window_ptr
);
10411 ControlPartCode control_part_code
;
10413 Point mouse_loc
= er
.where
;
10415 ControlKind control_kind
;
10418 f
= mac_window_to_frame (window_ptr
);
10419 /* convert to local coordinates of new window */
10420 SetPortWindowPort (window_ptr
);
10422 GlobalToLocal (&mouse_loc
);
10423 #if TARGET_API_MAC_CARBON
10424 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
10425 &control_part_code
);
10428 GetControlKind (ch
, &control_kind
);
10431 control_part_code
= FindControl (mouse_loc
, window_ptr
,
10435 #if USE_CARBON_EVENTS
10436 inev
.code
= mac_get_mouse_btn (eventRef
);
10437 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
10439 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
10440 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
10442 XSETINT (inev
.x
, mouse_loc
.h
);
10443 XSETINT (inev
.y
, mouse_loc
.v
);
10445 if ((dpyinfo
->grabbed
&& tracked_scroll_bar
)
10447 #ifndef USE_TOOLKIT_SCROLL_BARS
10448 /* control_part_code becomes kControlNoPart if
10449 a progress indicator is clicked. */
10450 && control_part_code
!= kControlNoPart
10451 #else /* USE_TOOLKIT_SCROLL_BARS */
10453 && control_kind
.kind
== kControlKindScrollBar
10454 #endif /* MAC_OSX */
10455 #endif /* USE_TOOLKIT_SCROLL_BARS */
10458 struct scroll_bar
*bar
;
10460 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10462 bar
= tracked_scroll_bar
;
10463 #ifndef USE_TOOLKIT_SCROLL_BARS
10464 control_part_code
= kControlIndicatorPart
;
10468 bar
= (struct scroll_bar
*) GetControlReference (ch
);
10469 #ifdef USE_TOOLKIT_SCROLL_BARS
10470 /* Make the "Ctrl-Mouse-2 splits window" work
10471 for toolkit scroll bars. */
10472 if (er
.modifiers
& controlKey
)
10473 x_scroll_bar_handle_click (bar
, control_part_code
,
10475 else if (er
.what
== mouseDown
)
10476 x_scroll_bar_handle_press (bar
, control_part_code
,
10479 x_scroll_bar_handle_release (bar
, &inev
);
10480 #else /* not USE_TOOLKIT_SCROLL_BARS */
10481 x_scroll_bar_handle_click (bar
, control_part_code
,
10483 if (er
.what
== mouseDown
10484 && control_part_code
== kControlIndicatorPart
)
10485 tracked_scroll_bar
= bar
;
10487 tracked_scroll_bar
= NULL
;
10488 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10492 Lisp_Object window
;
10493 int x
= mouse_loc
.h
;
10494 int y
= mouse_loc
.v
;
10496 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
10497 if (EQ (window
, f
->tool_bar_window
))
10499 if (er
.what
== mouseDown
)
10500 handle_tool_bar_click (f
, x
, y
, 1, 0);
10502 handle_tool_bar_click (f
, x
, y
, 0,
10508 XSETFRAME (inev
.frame_or_window
, f
);
10509 inev
.kind
= MOUSE_CLICK_EVENT
;
10513 if (er
.what
== mouseDown
)
10515 dpyinfo
->grabbed
|= (1 << inev
.code
);
10516 last_mouse_frame
= f
;
10519 last_tool_bar_item
= -1;
10523 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
10524 /* If a button is released though it was not
10525 previously pressed, that would be because
10526 of multi-button emulation. */
10527 dpyinfo
->grabbed
= 0;
10529 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
10532 /* Ignore any mouse motion that happened before
10533 this event; any subsequent mouse-movement Emacs
10534 events should reflect only motion after the
10537 f
->mouse_moved
= 0;
10539 #ifdef USE_TOOLKIT_SCROLL_BARS
10540 if (inev
.kind
== MOUSE_CLICK_EVENT
)
10545 inev
.modifiers
|= down_modifier
;
10548 inev
.modifiers
|= up_modifier
;
10555 #if TARGET_API_MAC_CARBON
10557 if (IsWindowPathSelectClick (window_ptr
, &er
))
10559 WindowPathSelect (window_ptr
, NULL
, NULL
);
10562 if (part_code
== inProxyIcon
10563 && (TrackWindowProxyDrag (window_ptr
, er
.where
)
10564 != errUserWantsToDragWindow
))
10566 DragWindow (window_ptr
, er
.where
, NULL
);
10567 #else /* not TARGET_API_MAC_CARBON */
10568 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
10569 #endif /* not TARGET_API_MAC_CARBON */
10570 /* Update the frame parameters. */
10571 #if !USE_CARBON_EVENTS
10573 struct frame
*f
= mac_window_to_frame (window_ptr
);
10575 if (f
&& !f
->async_iconified
)
10576 mac_handle_origin_change (f
);
10582 if (TrackGoAway (window_ptr
, er
.where
))
10584 inev
.kind
= DELETE_WINDOW_EVENT
;
10585 XSETFRAME (inev
.frame_or_window
,
10586 mac_window_to_frame (window_ptr
));
10590 /* window resize handling added --ben */
10592 do_grow_window (window_ptr
, &er
);
10595 /* window zoom handling added --ben */
10598 if (TrackBox (window_ptr
, er
.where
, part_code
))
10599 do_zoom_window (window_ptr
, part_code
);
10609 #if USE_CARBON_EVENTS
10610 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10611 != eventNotHandledErr
)
10614 do_window_update ((WindowPtr
) er
.message
);
10619 #if USE_CARBON_EVENTS
10620 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10621 != eventNotHandledErr
)
10624 switch ((er
.message
>> 24) & 0x000000FF)
10626 case suspendResumeMessage
:
10628 if (er
.message
& resumeFlag
)
10631 mac_tsm_suspend ();
10635 case mouseMovedMessage
:
10636 #if !USE_CARBON_EVENTS
10637 SetRectRgn (mouse_region
, er
.where
.h
, er
.where
.v
,
10638 er
.where
.h
+ 1, er
.where
.v
+ 1);
10640 previous_help_echo_string
= help_echo_string
;
10641 help_echo_string
= Qnil
;
10643 if (dpyinfo
->grabbed
&& last_mouse_frame
10644 && FRAME_LIVE_P (last_mouse_frame
))
10645 f
= last_mouse_frame
;
10647 f
= dpyinfo
->x_focus_frame
;
10649 if (dpyinfo
->mouse_face_hidden
)
10651 dpyinfo
->mouse_face_hidden
= 0;
10652 clear_mouse_face (dpyinfo
);
10657 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
10658 Point mouse_pos
= er
.where
;
10660 SetPortWindowPort (wp
);
10662 GlobalToLocal (&mouse_pos
);
10664 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10665 #ifdef USE_TOOLKIT_SCROLL_BARS
10666 x_scroll_bar_handle_drag (wp
, tracked_scroll_bar
,
10668 #else /* not USE_TOOLKIT_SCROLL_BARS */
10669 x_scroll_bar_note_movement (tracked_scroll_bar
,
10671 - XINT (tracked_scroll_bar
->top
),
10672 er
.when
* (1000 / 60));
10673 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10676 /* Generate SELECT_WINDOW_EVENTs when needed. */
10677 if (!NILP (Vmouse_autoselect_window
))
10679 Lisp_Object window
;
10681 window
= window_from_coordinates (f
,
10686 /* Window will be selected only when it is
10687 not selected now and last mouse movement
10688 event was not in it. Minibuffer window
10689 will be selected iff it is active. */
10690 if (WINDOWP (window
)
10691 && !EQ (window
, last_window
)
10692 && !EQ (window
, selected_window
))
10694 inev
.kind
= SELECT_WINDOW_EVENT
;
10695 inev
.frame_or_window
= window
;
10698 last_window
=window
;
10700 if (!note_mouse_movement (f
, &mouse_pos
))
10701 help_echo_string
= previous_help_echo_string
;
10705 /* If the contents of the global variable
10706 help_echo_string has changed, generate a
10708 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
10716 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
10718 #if USE_CARBON_EVENTS
10719 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10720 != eventNotHandledErr
)
10723 if (window_ptr
== tip_window
)
10725 HideWindow (tip_window
);
10729 if (!is_emacs_window (window_ptr
))
10732 if ((er
.modifiers
& activeFlag
) != 0)
10734 /* A window has been activated */
10735 Point mouse_loc
= er
.where
;
10737 x_detect_focus_change (dpyinfo
, &er
, &inev
);
10739 SetPortWindowPort (window_ptr
);
10740 GlobalToLocal (&mouse_loc
);
10741 /* Window-activated event counts as mouse movement,
10742 so update things that depend on mouse position. */
10743 note_mouse_movement (mac_window_to_frame (window_ptr
),
10748 /* A window has been deactivated */
10749 #if USE_TOOLKIT_SCROLL_BARS
10750 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10752 struct input_event event
;
10754 EVENT_INIT (event
);
10755 event
.kind
= NO_EVENT
;
10756 x_scroll_bar_handle_release (tracked_scroll_bar
, &event
);
10757 if (event
.kind
!= NO_EVENT
)
10759 event
.timestamp
= timestamp
;
10760 kbd_buffer_store_event_hold (&event
, hold_quit
);
10765 dpyinfo
->grabbed
= 0;
10767 x_detect_focus_change (dpyinfo
, &er
, &inev
);
10769 f
= mac_window_to_frame (window_ptr
);
10770 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10772 /* If we move outside the frame, then we're
10773 certainly no longer on any text in the
10775 clear_mouse_face (dpyinfo
);
10776 dpyinfo
->mouse_face_mouse_frame
= 0;
10779 /* Generate a nil HELP_EVENT to cancel a help-echo.
10780 Do it only if there's something to cancel.
10781 Otherwise, the startup message is cleared when the
10782 mouse leaves the frame. */
10783 if (any_help_event_p
)
10793 int keycode
= (er
.message
& keyCodeMask
) >> 8;
10794 static SInt16 last_key_script
= -1;
10795 SInt16 current_key_script
;
10796 UInt32 modifiers
= er
.modifiers
, mapped_modifiers
;
10799 (NILP (Vmac_control_modifier
) ? 0 : controlKey
)
10800 | (NILP (Vmac_option_modifier
) ? 0 : optionKey
)
10801 | (NILP (Vmac_command_modifier
) ? 0 : cmdKey
);
10803 #if USE_CARBON_EVENTS && defined (MAC_OSX)
10804 mapped_modifiers
|=
10805 (NILP (Vmac_function_modifier
) ? 0 : kEventKeyModifierFnMask
);
10807 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
10809 sizeof (UInt32
), NULL
, &modifiers
);
10811 mapped_modifiers
&= modifiers
;
10813 #if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
10814 /* When using Carbon Events, we need to pass raw keyboard
10815 events to the TSM ourselves. If TSM handles it, it
10816 will pass back noErr, otherwise it will pass back
10817 "eventNotHandledErr" and we can process it
10819 if (!(mapped_modifiers
10820 & ~(mac_pass_command_to_system
? cmdKey
: 0)
10821 & ~(mac_pass_control_to_system
? controlKey
: 0)))
10825 read_socket_inev
= &inev
;
10826 err
= SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
10827 read_socket_inev
= NULL
;
10828 if (err
!= eventNotHandledErr
)
10832 if (er
.what
== keyUp
)
10837 f
= mac_focus_frame (dpyinfo
);
10839 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
)
10840 && !EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
))
10842 clear_mouse_face (dpyinfo
);
10843 dpyinfo
->mouse_face_hidden
= 1;
10846 current_key_script
= GetScriptManagerVariable (smKeyScript
);
10847 if (last_key_script
!= current_key_script
)
10849 struct input_event event
;
10851 EVENT_INIT (event
);
10852 event
.kind
= LANGUAGE_CHANGE_EVENT
;
10854 event
.code
= current_key_script
;
10855 event
.timestamp
= timestamp
;
10856 kbd_buffer_store_event (&event
);
10858 last_key_script
= current_key_script
;
10862 if (inev
.kind
!= NO_EVENT
)
10867 if (mapped_modifiers
& kEventKeyModifierFnMask
10869 && fn_keycode_to_keycode_table
[keycode
])
10870 keycode
= fn_keycode_to_keycode_table
[keycode
];
10872 if (keycode
<= 0x7f && keycode_to_xkeysym_table
[keycode
])
10874 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
10875 inev
.code
= 0xff00 | keycode_to_xkeysym_table
[keycode
];
10877 if (modifiers
& kEventKeyModifierFnMask
10879 && fn_keycode_to_keycode_table
[keycode
] == keycode
)
10880 modifiers
&= ~kEventKeyModifierFnMask
;
10883 else if (mapped_modifiers
)
10885 /* translate the keycode back to determine the
10888 static SInt16 last_key_layout_id
= 0;
10889 static Handle uchr_handle
= (Handle
)-1;
10890 SInt16 current_key_layout_id
=
10891 GetScriptVariable (current_key_script
, smScriptKeys
);
10893 if (uchr_handle
== (Handle
)-1
10894 || last_key_layout_id
!= current_key_layout_id
)
10896 uchr_handle
= GetResource ('uchr', current_key_layout_id
);
10897 last_key_layout_id
= current_key_layout_id
;
10903 UInt16 key_action
= er
.what
- keyDown
;
10904 UInt32 modifier_key_state
=
10905 (modifiers
& ~mapped_modifiers
) >> 8;
10906 UInt32 keyboard_type
= LMGetKbdType ();
10907 SInt32 dead_key_state
= 0;
10909 UniCharCount actual_length
;
10911 status
= UCKeyTranslate ((UCKeyboardLayout
*)*uchr_handle
,
10912 keycode
, key_action
,
10913 modifier_key_state
,
10915 kUCKeyTranslateNoDeadKeysMask
,
10917 1, &actual_length
, &code
);
10918 if (status
== noErr
&& actual_length
== 1)
10919 mac_set_unicode_keystroke_event (code
, &inev
);
10921 #endif /* MAC_OSX */
10923 if (inev
.kind
== NO_EVENT
)
10925 /* This code comes from Keyboard Resource,
10926 Appendix C of IM - Text. This is necessary
10927 since shift is ignored in KCHR table
10928 translation when option or command is pressed.
10929 It also does not translate correctly
10930 control-shift chars like C-% so mask off shift
10932 /* Mask off modifier keys that are mapped to some
10933 Emacs modifiers. */
10934 int new_modifiers
= er
.modifiers
& ~mapped_modifiers
;
10935 /* set high byte of keycode to modifier high byte*/
10936 int new_keycode
= keycode
| new_modifiers
;
10937 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
10938 unsigned long some_state
= 0;
10939 UInt32 new_char_code
;
10941 new_char_code
= KeyTranslate (kchr_ptr
, new_keycode
,
10943 if (new_char_code
== 0)
10944 /* Seems like a dead key. Append up-stroke. */
10945 new_char_code
= KeyTranslate (kchr_ptr
,
10946 new_keycode
| 0x80,
10950 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
10951 inev
.code
= new_char_code
& 0xff;
10956 if (inev
.kind
== NO_EVENT
)
10958 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
10959 inev
.code
= er
.message
& charCodeMask
;
10962 inev
.modifiers
= mac_to_emacs_modifiers (modifiers
);
10963 inev
.modifiers
|= (extra_keyboard_modifiers
10964 & (meta_modifier
| alt_modifier
10965 | hyper_modifier
| super_modifier
));
10966 XSETFRAME (inev
.frame_or_window
, f
);
10968 #if TARGET_API_MAC_CARBON
10969 if (inev
.kind
== ASCII_KEYSTROKE_EVENT
10970 && inev
.code
>= 0x80 && inev
.modifiers
)
10973 TextEncoding encoding
= kTextEncodingMacRoman
;
10974 TextToUnicodeInfo ttu_info
;
10976 UpgradeScriptInfoToTextEncoding (current_key_script
,
10977 kTextLanguageDontCare
,
10978 kTextRegionDontCare
,
10980 err
= CreateTextToUnicodeInfoByEncoding (encoding
, &ttu_info
);
10985 ByteCount unicode_len
;
10988 pstr
[1] = inev
.code
;
10989 err
= ConvertFromPStringToUnicode (ttu_info
, pstr
,
10991 &unicode_len
, &code
);
10992 if (err
== noErr
&& unicode_len
== sizeof (UniChar
))
10993 mac_set_unicode_keystroke_event (code
, &inev
);
10994 DisposeTextToUnicodeInfo (&ttu_info
);
11001 case kHighLevelEvent
:
11002 AEProcessAppleEvent (&er
);
11008 #if USE_CARBON_EVENTS
11009 ReleaseEvent (eventRef
);
11012 if (inev
.kind
!= NO_EVENT
)
11014 inev
.timestamp
= timestamp
;
11015 kbd_buffer_store_event_hold (&inev
, hold_quit
);
11020 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
11025 XSETFRAME (frame
, f
);
11031 any_help_event_p
= 1;
11032 gen_help_event (help_echo_string
, frame
, help_echo_window
,
11033 help_echo_object
, help_echo_pos
);
11037 help_echo_string
= Qnil
;
11038 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
11045 /* If the focus was just given to an autoraising frame,
11047 /* ??? This ought to be able to handle more than one such frame. */
11048 if (pending_autoraise_frame
)
11050 x_raise_frame (pending_autoraise_frame
);
11051 pending_autoraise_frame
= 0;
11054 #if !USE_CARBON_EVENTS
11055 /* Check which frames are still visible. We do this here because
11056 there doesn't seem to be any direct notification from the Window
11057 Manager that the visibility of a window has changed (at least,
11058 not in all cases). */
11060 Lisp_Object tail
, frame
;
11062 FOR_EACH_FRAME (tail
, frame
)
11064 struct frame
*f
= XFRAME (frame
);
11066 /* The tooltip has been drawn already. Avoid the
11067 SET_FRAME_GARBAGED in mac_handle_visibility_change. */
11068 if (EQ (frame
, tip_frame
))
11071 if (FRAME_MAC_P (f
))
11072 mac_handle_visibility_change (f
);
11083 /* Need to override CodeWarrior's input function so no conversion is
11084 done on newlines Otherwise compiled functions in .elc files will be
11085 read incorrectly. Defined in ...:MSL C:MSL
11086 Common:Source:buffer_io.c. */
11089 __convert_to_newlines (unsigned char * p
, size_t * n
)
11091 #pragma unused(p,n)
11095 __convert_from_newlines (unsigned char * p
, size_t * n
)
11097 #pragma unused(p,n)
11103 make_mac_terminal_frame (struct frame
*f
)
11108 XSETFRAME (frame
, f
);
11110 f
->output_method
= output_mac
;
11111 f
->output_data
.mac
= (struct mac_output
*)
11112 xmalloc (sizeof (struct mac_output
));
11113 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
11115 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
11117 FRAME_COLS (f
) = 96;
11118 FRAME_LINES (f
) = 4;
11120 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
11121 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
11123 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
11125 f
->output_data
.mac
->cursor_pixel
= 0;
11126 f
->output_data
.mac
->border_pixel
= 0x00ff00;
11127 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
11128 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
11130 f
->output_data
.mac
->text_cursor
= kThemeIBeamCursor
;
11131 f
->output_data
.mac
->nontext_cursor
= kThemeArrowCursor
;
11132 f
->output_data
.mac
->modeline_cursor
= kThemeArrowCursor
;
11133 f
->output_data
.mac
->hand_cursor
= kThemePointingHandCursor
;
11134 f
->output_data
.mac
->hourglass_cursor
= kThemeWatchCursor
;
11135 f
->output_data
.mac
->horizontal_drag_cursor
= kThemeResizeLeftRightCursor
;
11137 FRAME_FONTSET (f
) = -1;
11138 f
->output_data
.mac
->explicit_parent
= 0;
11141 f
->border_width
= 0;
11143 f
->internal_border_width
= 0;
11148 f
->new_text_cols
= 0;
11149 f
->new_text_lines
= 0;
11151 SetRect (&r
, f
->left_pos
, f
->top_pos
,
11152 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
11153 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
11157 if (!(FRAME_MAC_WINDOW (f
) =
11158 NewCWindow (NULL
, &r
, "\p", true, dBoxProc
,
11159 (WindowPtr
) -1, 1, (long) f
->output_data
.mac
)))
11161 /* so that update events can find this mac_output struct */
11162 f
->output_data
.mac
->mFP
= f
; /* point back to emacs frame */
11168 /* Need to be initialized for unshow_buffer in window.c. */
11169 selected_window
= f
->selected_window
;
11171 Fmodify_frame_parameters (frame
,
11172 Fcons (Fcons (Qfont
,
11173 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
11174 Fmodify_frame_parameters (frame
,
11175 Fcons (Fcons (Qforeground_color
,
11176 build_string ("black")), Qnil
));
11177 Fmodify_frame_parameters (frame
,
11178 Fcons (Fcons (Qbackground_color
,
11179 build_string ("white")), Qnil
));
11184 /***********************************************************************
11186 ***********************************************************************/
11188 int mac_initialized
= 0;
11191 mac_initialize_display_info ()
11193 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
11195 bzero (dpyinfo
, sizeof (*dpyinfo
));
11198 dpyinfo
->mac_id_name
11199 = (char *) xmalloc (SCHARS (Vinvocation_name
)
11200 + SCHARS (Vsystem_name
)
11202 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
11203 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
11205 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
11206 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
11209 dpyinfo
->reference_count
= 0;
11210 dpyinfo
->resx
= 72.0;
11211 dpyinfo
->resy
= 72.0;
11213 /* HasDepth returns true if it is possible to have a 32 bit display,
11214 but this may not be what is actually used. Mac OSX can do better. */
11215 dpyinfo
->color_p
= CGDisplaySamplesPerPixel (kCGDirectMainDisplay
) > 1;
11216 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (kCGDirectMainDisplay
);
11217 dpyinfo
->height
= CGDisplayPixelsHigh (kCGDirectMainDisplay
);
11218 dpyinfo
->width
= CGDisplayPixelsWide (kCGDirectMainDisplay
);
11221 GDHandle main_device_handle
= LMGetMainDevice();
11223 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
11224 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
11225 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
11226 gdDevType
, dpyinfo
->color_p
))
11228 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
11229 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
11232 dpyinfo
->grabbed
= 0;
11233 dpyinfo
->root_window
= NULL
;
11234 dpyinfo
->image_cache
= make_image_cache ();
11236 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
11237 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
11238 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
11239 dpyinfo
->mouse_face_window
= Qnil
;
11240 dpyinfo
->mouse_face_overlay
= Qnil
;
11241 dpyinfo
->mouse_face_hidden
= 0;
11246 mac_make_rdb (xrm_option
)
11247 const char *xrm_option
;
11249 XrmDatabase database
;
11251 database
= xrm_get_preference_database (NULL
);
11253 xrm_merge_string_database (database
, xrm_option
);
11258 struct mac_display_info
*
11259 mac_term_init (display_name
, xrm_option
, resource_name
)
11260 Lisp_Object display_name
;
11262 char *resource_name
;
11264 struct mac_display_info
*dpyinfo
;
11268 if (!mac_initialized
)
11271 mac_initialized
= 1;
11274 if (x_display_list
)
11275 error ("Sorry, this version can only handle one display");
11277 mac_initialize_display_info ();
11279 dpyinfo
= &one_mac_display_info
;
11281 dpyinfo
->xrdb
= mac_make_rdb (xrm_option
);
11283 /* Put this display on the chain. */
11284 dpyinfo
->next
= x_display_list
;
11285 x_display_list
= dpyinfo
;
11287 /* Put it on x_display_name_list. */
11288 x_display_name_list
= Fcons (Fcons (display_name
,
11289 Fcons (Qnil
, dpyinfo
->xrdb
)),
11290 x_display_name_list
);
11291 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
11297 /* Get rid of display DPYINFO, assuming all frames are already gone. */
11300 x_delete_display (dpyinfo
)
11301 struct mac_display_info
*dpyinfo
;
11305 /* Discard this display from x_display_name_list and x_display_list.
11306 We can't use Fdelq because that can quit. */
11307 if (! NILP (x_display_name_list
)
11308 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
11309 x_display_name_list
= XCDR (x_display_name_list
);
11314 tail
= x_display_name_list
;
11315 while (CONSP (tail
) && CONSP (XCDR (tail
)))
11317 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
11319 XSETCDR (tail
, XCDR (XCDR (tail
)));
11322 tail
= XCDR (tail
);
11326 if (x_display_list
== dpyinfo
)
11327 x_display_list
= dpyinfo
->next
;
11330 struct x_display_info
*tail
;
11332 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
11333 if (tail
->next
== dpyinfo
)
11334 tail
->next
= tail
->next
->next
;
11337 /* Free the font names in the font table. */
11338 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11339 if (dpyinfo
->font_table
[i
].name
)
11341 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
11342 xfree (dpyinfo
->font_table
[i
].full_name
);
11343 xfree (dpyinfo
->font_table
[i
].name
);
11346 if (dpyinfo
->font_table
)
11348 if (dpyinfo
->font_table
->font_encoder
)
11349 xfree (dpyinfo
->font_table
->font_encoder
);
11350 xfree (dpyinfo
->font_table
);
11352 if (dpyinfo
->mac_id_name
)
11353 xfree (dpyinfo
->mac_id_name
);
11355 if (x_display_list
== 0)
11357 mac_clear_font_name_table ();
11358 bzero (dpyinfo
, sizeof (*dpyinfo
));
11367 extern int inhibit_window_system
;
11368 extern int noninteractive
;
11369 CFBundleRef appsBundle
;
11371 /* No need to test if already -nw*/
11372 if (inhibit_window_system
|| noninteractive
)
11375 appsBundle
= CFBundleGetMainBundle();
11376 if (appsBundle
!= NULL
)
11378 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
11379 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
11380 /* We found the bundle identifier, now we know we are valid. */
11387 /* MAC_TODO: Have this start the bundled executable */
11389 /* For now, prevent the fatal error by bringing it up in the terminal */
11390 inhibit_window_system
= 1;
11394 MakeMeTheFrontProcess ()
11396 ProcessSerialNumber psn
;
11399 err
= GetCurrentProcess (&psn
);
11401 (void) SetFrontProcess (&psn
);
11404 /***** Code to handle C-g testing *****/
11406 /* Contains the Mac modifier formed from quit_char */
11407 int mac_quit_char_modifiers
= 0;
11408 int mac_quit_char_keycode
;
11409 extern int quit_char
;
11412 mac_determine_quit_char_modifiers()
11414 /* Todo: Determine modifiers from quit_char. */
11415 UInt32 qc_modifiers
= ctrl_modifier
;
11417 /* Map modifiers */
11418 mac_quit_char_modifiers
= 0;
11419 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= controlKey
;
11420 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= shiftKey
;
11421 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= optionKey
;
11425 init_quit_char_handler ()
11427 /* TODO: Let this support keys other the 'g' */
11428 mac_quit_char_keycode
= 5;
11429 /* Look at <architecture/adb_kb_map.h> for details */
11430 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
11432 mac_determine_quit_char_modifiers();
11434 #endif /* MAC_OSX */
11442 MenuItemIndex menu_index
;
11444 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandQuit
, 1,
11445 &menu
, &menu_index
);
11447 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
11448 #if USE_CARBON_EVENTS
11449 EnableMenuCommand (NULL
, kHICommandPreferences
);
11450 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandPreferences
, 1,
11451 &menu
, &menu_index
);
11454 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
11455 InsertMenuItemTextWithCFString (menu
, NULL
,
11456 0, kMenuItemAttrSeparator
, 0);
11457 InsertMenuItemTextWithCFString (menu
, CFSTR ("About Emacs"),
11458 0, 0, kHICommandAbout
);
11460 #endif /* USE_CARBON_EVENTS */
11461 #else /* !MAC_OSX */
11462 #if USE_CARBON_EVENTS
11463 SetMenuItemCommandID (GetMenuHandle (M_APPLE
), I_ABOUT
, kHICommandAbout
);
11473 static InterfaceTypeList types
= {kUnicodeDocument
};
11475 static InterfaceTypeList types
= {kTextService
};
11478 NewTSMDocument (sizeof (types
) / sizeof (types
[0]), types
,
11479 &tsm_document_id
, 0);
11483 /* Set up use of X before we make the first connection. */
11485 extern frame_parm_handler mac_frame_parm_handlers
[];
11487 static struct redisplay_interface x_redisplay_interface
=
11489 mac_frame_parm_handlers
,
11493 x_clear_end_of_line
,
11495 x_after_update_window_line
,
11496 x_update_window_begin
,
11497 x_update_window_end
,
11500 0, /* flush_display_optional */
11501 x_clear_window_mouse_face
,
11502 x_get_glyph_overhangs
,
11503 x_fix_overlapping_area
,
11504 x_draw_fringe_bitmap
,
11506 mac_define_fringe_bitmap
,
11507 mac_destroy_fringe_bitmap
,
11509 0, /* define_fringe_bitmap */
11510 0, /* destroy_fringe_bitmap */
11512 mac_per_char_metric
,
11514 mac_compute_glyph_string_overhangs
,
11515 x_draw_glyph_string
,
11516 mac_define_frame_cursor
,
11517 mac_clear_frame_area
,
11518 mac_draw_window_cursor
,
11519 mac_draw_vertical_window_border
,
11520 mac_shift_glyphs_for_insert
11526 rif
= &x_redisplay_interface
;
11528 clear_frame_hook
= x_clear_frame
;
11529 ins_del_lines_hook
= x_ins_del_lines
;
11530 delete_glyphs_hook
= x_delete_glyphs
;
11531 ring_bell_hook
= XTring_bell
;
11532 reset_terminal_modes_hook
= XTreset_terminal_modes
;
11533 set_terminal_modes_hook
= XTset_terminal_modes
;
11534 update_begin_hook
= x_update_begin
;
11535 update_end_hook
= x_update_end
;
11536 set_terminal_window_hook
= XTset_terminal_window
;
11537 read_socket_hook
= XTread_socket
;
11538 frame_up_to_date_hook
= XTframe_up_to_date
;
11539 mouse_position_hook
= XTmouse_position
;
11540 frame_rehighlight_hook
= XTframe_rehighlight
;
11541 frame_raise_lower_hook
= XTframe_raise_lower
;
11543 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
11544 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
11545 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
11546 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
11548 TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
11549 TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
11550 TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
11551 TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
11552 TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
11557 last_tool_bar_item
= -1;
11558 any_help_event_p
= 0;
11560 /* Try to use interrupt input; if we can't, then start polling. */
11561 Fset_input_interrupt_mode (Qt
);
11565 #if TARGET_API_MAC_CARBON
11567 #if USE_CARBON_EVENTS
11569 init_service_handler ();
11571 init_quit_char_handler ();
11572 #endif /* MAC_OSX */
11574 init_command_handler ();
11581 #endif /* USE_CARBON_EVENTS */
11584 init_coercion_handler ();
11586 init_apple_event_handler ();
11588 if (!inhibit_window_system
)
11589 MakeMeTheFrontProcess ();
11594 mac_init_fringe ();
11605 staticpro (&x_error_message_string
);
11606 x_error_message_string
= Qnil
;
11609 Qcontrol
= intern ("control"); staticpro (&Qcontrol
);
11610 Qmeta
= intern ("meta"); staticpro (&Qmeta
);
11611 Qalt
= intern ("alt"); staticpro (&Qalt
);
11612 Qhyper
= intern ("hyper"); staticpro (&Qhyper
);
11613 Qsuper
= intern ("super"); staticpro (&Qsuper
);
11614 Qmodifier_value
= intern ("modifier-value");
11615 staticpro (&Qmodifier_value
);
11617 Fput (Qcontrol
, Qmodifier_value
, make_number (ctrl_modifier
));
11618 Fput (Qmeta
, Qmodifier_value
, make_number (meta_modifier
));
11619 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
11620 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
11621 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
11623 #if USE_CARBON_EVENTS
11624 Qhi_command
= intern ("hi-command"); staticpro (&Qhi_command
);
11626 Qtoolbar_switch_mode
= intern ("toolbar-switch-mode");
11627 staticpro (&Qtoolbar_switch_mode
);
11628 #if USE_MAC_FONT_PANEL
11629 Qpanel_closed
= intern ("panel-closed"); staticpro (&Qpanel_closed
);
11630 Qselection
= intern ("selection"); staticpro (&Qselection
);
11633 Qservice
= intern ("service"); staticpro (&Qservice
);
11634 Qpaste
= intern ("paste"); staticpro (&Qpaste
);
11635 Qperform
= intern ("perform"); staticpro (&Qperform
);
11638 Qtext_input
= intern ("text-input"); staticpro (&Qtext_input
);
11639 Qupdate_active_input_area
= intern ("update-active-input-area");
11640 staticpro (&Qupdate_active_input_area
);
11641 Qunicode_for_key_event
= intern ("unicode-for-key-event");
11642 staticpro (&Qunicode_for_key_event
);
11647 Fprovide (intern ("mac-carbon"), Qnil
);
11650 staticpro (&Qreverse
);
11651 Qreverse
= intern ("reverse");
11653 staticpro (&x_display_name_list
);
11654 x_display_name_list
= Qnil
;
11656 staticpro (&last_mouse_scroll_bar
);
11657 last_mouse_scroll_bar
= Qnil
;
11659 staticpro (&fm_font_family_alist
);
11660 fm_font_family_alist
= Qnil
;
11663 staticpro (&atsu_font_id_hash
);
11664 atsu_font_id_hash
= Qnil
;
11666 staticpro (&fm_style_face_attributes_alist
);
11667 fm_style_face_attributes_alist
= Qnil
;
11671 staticpro (&saved_ts_script_language_on_focus
);
11672 saved_ts_script_language_on_focus
= Qnil
;
11675 /* We don't yet support this, but defining this here avoids whining
11676 from cus-start.el and other places, like "M-x set-variable". */
11677 DEFVAR_BOOL ("x-use-underline-position-properties",
11678 &x_use_underline_position_properties
,
11679 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11680 nil means ignore them. If you encounter fonts with bogus
11681 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11682 to 4.1, set this to nil.
11684 NOTE: Not supported on Mac yet. */);
11685 x_use_underline_position_properties
= 0;
11687 DEFVAR_BOOL ("x-underline-at-descent-line",
11688 &x_underline_at_descent_line
,
11689 doc
: /* *Non-nil means to draw the underline at the same place as the descent line.
11690 nil means to draw the underline according to the value of the variable
11691 `x-use-underline-position-properties', which is usually at the baseline
11692 level. The default value is nil. */);
11693 x_underline_at_descent_line
= 0;
11695 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11696 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11697 #ifdef USE_TOOLKIT_SCROLL_BARS
11698 Vx_toolkit_scroll_bars
= Qt
;
11700 Vx_toolkit_scroll_bars
= Qnil
;
11703 staticpro (&last_mouse_motion_frame
);
11704 last_mouse_motion_frame
= Qnil
;
11706 /* Variables to configure modifier key assignment. */
11708 DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier
,
11709 doc
: /* *Modifier key assumed when the Mac control key is pressed.
11710 The value can be `control', `meta', `alt', `hyper', or `super' for the
11711 respective modifier. The default is `control'. */);
11712 Vmac_control_modifier
= Qcontrol
;
11714 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
11715 doc
: /* *Modifier key assumed when the Mac alt/option key is pressed.
11716 The value can be `control', `meta', `alt', `hyper', or `super' for the
11717 respective modifier. If the value is nil then the key will act as the
11718 normal Mac control modifier, and the option key can be used to compose
11719 characters depending on the chosen Mac keyboard setting. */);
11720 Vmac_option_modifier
= Qnil
;
11722 DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier
,
11723 doc
: /* *Modifier key assumed when the Mac command key is pressed.
11724 The value can be `control', `meta', `alt', `hyper', or `super' for the
11725 respective modifier. The default is `meta'. */);
11726 Vmac_command_modifier
= Qmeta
;
11728 DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier
,
11729 doc
: /* *Modifier key assumed when the Mac function key is pressed.
11730 The value can be `control', `meta', `alt', `hyper', or `super' for the
11731 respective modifier. Note that remapping the function key may lead to
11732 unexpected results for some keys on non-US/GB keyboards. */);
11733 Vmac_function_modifier
= Qnil
;
11735 DEFVAR_LISP ("mac-emulate-three-button-mouse",
11736 &Vmac_emulate_three_button_mouse
,
11737 doc
: /* *Specify a way of three button mouse emulation.
11738 The value can be nil, t, or the symbol `reverse'.
11739 nil means that no emulation should be done and the modifiers should be
11740 placed on the mouse-1 event.
11741 t means that when the option-key is held down while pressing the mouse
11742 button, the click will register as mouse-2 and while the command-key
11743 is held down, the click will register as mouse-3.
11744 The symbol `reverse' means that the option-key will register for
11745 mouse-3 and the command-key will register for mouse-2. */);
11746 Vmac_emulate_three_button_mouse
= Qnil
;
11748 #if USE_CARBON_EVENTS
11749 DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2
,
11750 doc
: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
11751 Otherwise, the right click will be treated as mouse-2 and the wheel
11752 button will be mouse-3. */);
11753 mac_wheel_button_is_mouse_2
= 1;
11755 DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system
,
11756 doc
: /* *Non-nil if command key presses are passed on to the Mac Toolbox. */);
11757 mac_pass_command_to_system
= 1;
11759 DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system
,
11760 doc
: /* *Non-nil if control key presses are passed on to the Mac Toolbox. */);
11761 mac_pass_control_to_system
= 1;
11765 DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics
,
11766 doc
: /* *If non-nil, allow anti-aliasing.
11767 The text will be rendered using Core Graphics text rendering which
11768 may anti-alias the text. */);
11770 mac_use_core_graphics
= 1;
11772 mac_use_core_graphics
= 0;
11775 /* Register an entry for `mac-roman' so that it can be used when
11776 creating the terminal frame on Mac OS 9 before loading
11777 term/mac-win.elc. */
11778 DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist
,
11779 doc
: /* Alist of Emacs character sets vs text encodings and coding systems.
11780 Each entry should be of the form:
11782 (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
11784 where CHARSET-NAME is a string used in font names to identify the
11785 charset, TEXT-ENCODING is a TextEncodingBase value in Mac, and
11786 CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING. */);
11787 Vmac_charset_info_alist
=
11788 Fcons (list3 (build_string ("mac-roman"),
11789 make_number (smRoman
), Qnil
), Qnil
);
11792 DEFVAR_LISP ("mac-atsu-font-table", &Vmac_atsu_font_table
,
11793 doc
: /* Hash table of ATSU font IDs vs plist of attributes and values. */);
11794 Vmac_atsu_font_table
=
11795 make_hash_table (Qeql
, make_number (DEFAULT_HASH_SIZE
),
11796 make_float (DEFAULT_REHASH_SIZE
),
11797 make_float (DEFAULT_REHASH_THRESHOLD
),
11801 DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay
,
11802 doc
: /* Overlay used to display Mac TSM active input area. */);
11803 Vmac_ts_active_input_overlay
= Qnil
;
11805 DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus
,
11806 doc
: /* *How to change Mac TSM script/language when a frame gets focus.
11807 If the value is t, the input script and language are restored to those
11808 used in the last focus frame. If the value is a pair of integers, the
11809 input script and language codes, which are defined in the Script
11810 Manager, are set to its car and cdr parts, respectively. Otherwise,
11811 Emacs doesn't set them and thus follows the system default behavior. */);
11812 Vmac_ts_script_language_on_focus
= Qnil
;
11816 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
11817 (do not change this comment) */